Preserve current-main threaded workflow replies while binding owner-signed doorbells to durable, exclusive agent deliveries with lease-safe finalization. Co-authored-by: Larry <larry@buzz.local> Signed-off-by: Logan Johnson <loganj@squareup.com>
1.9 KiB
Managed-agent workflow delivery
A workflow send_message step has two separate outputs when it addresses a managed agent:
- The relay signs and persists an ordinary kind
9channel message. Its content is the rendered, human-visible step text. The event carries the channel, exact kind30620definition revision and step, workflow owner, semantic cause, and signed-template-derivedprecipients. Private webhook fields and prior-step state are never copied into this event. - The relay creates a durable
workflow_agent_deliveriesrow for each signed routing target, bound by foreign key to the exact partitioned kind9event. It then publishes an ephemeral kind24620wake hint containing only identifiers. Kind24620isp-gated; it is an accelerator rather than the source of truth.
The managed agent claims a delivery through the authenticated relay endpoint. Claiming is scoped to the host-derived community and authenticated agent pubkey, returns a fenced lease token, and includes the private trigger and execution snapshot. Before dispatch, ACP independently fetches and verifies the exact definition and visible message, immutable NIP-OA ownership, channel and workflow/run/step bindings, semantic cause, and locally rendered text. A stale or unverifiable delivery fails closed.
ACP also polls for pending deliveries, so an offline agent does not depend on receiving the ephemeral wake. Completion uses the lease token. Only an authenticated, token-fenced retryable finish returns a live claim to pending with bounded backoff. Once claimed, ACP is the sole retry authority: lease expiry is terminal and never redelivers, choosing at-most-once execution over potentially duplicating successful agent side effects after an uncertain finish or runtime exit. Pending rows that expire before claim also become terminal. The uniqueness key (community_id, run_id, step_id, target_pubkey) collapses a true replay while preserving distinct steps in the same run.