Skip to content

Always-on conductor: create at boot and add a heartbeat wake source #280

Description

@saucam

From conductor-design.md §7 (landed in #275). Small, and a precondition for both the front doors (#279) and routines (#54).

Current state

The conductor is created lazily on the first session.create with role: "conductor" — in practice, the first codeoid attach conductor. It is durable and resumable once created (resumeSessions reloads it with its role, provider, and identity, so the WIMSE URI is stable across restarts), but:

  • No boot-time ensure. A fresh daemon has no conductor until a human attaches one.
  • No heartbeat. The design lists three wake sources — owner message, child completion, scheduled tick. Only child completion exists, as the <fleet_events> injection.

So "always on" is not true today, which matters as soon as anything is supposed to happen without the owner initiating it.

Scope

  • Ensure the conductor at daemon boot when config.conductor.enabled (default true), per tenant, reusing the existing idempotent #createConductor path and its singleton TOCTOU re-check
  • Heartbeat backstop with exponential backoff — the design's cost story depends on the daemon absorbing benign events and waking a turn only on actionable ones, so the heartbeat is a safety net against a missed event, not a poll loop
  • Durable event queue for actionable events so a crash mid-event does not lose the wake (build plan P4 lists this; verify what dispatch_events already covers)
  • Keep the sentinel/out-of-band marker discipline: daemon-injected digests must never be confusable with owner messages. <fleet_events> already does this — extend the same pattern to heartbeat-triggered turns

Care needed

Boot-time creation touches the identity path: #createConductor mints the conductor's token by owner delegation and needs the caller's raw bearer token as the RFC 8693 subject. At boot there is no caller. Either the conductor comes up with metadata-only attribution and upgrades on first owner contact, or boot-ensure is deferred until a token is available. The first is probably right, but it must not silently produce a conductor whose actions are unattributable — the daemon already logs the delegation-failure case, and that log should be loud here.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions