# Conflicts: # docs/adr/README.md # docs/rfc/009-session-persistence-and-resumability.md # docs/rfc/README.md # docs/rfc/implemented/2026-06-11-doc-sync-enforcement.md # docs/rfc/proposed/2026-06-14-acp-agent-client-protocol.md # examples/acp-agent/tests/acp.e2e.ts # packages/acp/README.md # packages/acp/src/index.ts # packages/acp/tests/stream-update.spec.ts # packages/agent-loop/src/loop.ts # packages/tools/src/index.ts
2.4 KiB
RFC: Agent lifecycle and ownership seams
Status: proposed
Problem
Several ACP and tool-bash limitations are symptoms of the same missing seam: plugins can create or resume agents through ctx.agents, but they cannot own and dispose one agent independently, and long-running bash tasks carry no stable owner in the executor itself. ACP currently aborts and awaits agents on disconnect, but cannot unregister just that session's agent; session/cancel cannot cancel queued-but-not-yet-started work; and tool-bash keeps task ownership in a plugin-local Map, so an HMR reload can make an old task look unowned.
Proposal
Add explicit lifecycle ownership to the agent factory and explicit ownership metadata to background tasks.
ctx.agents.create/resumeshould return anAgentHandle(or add an adjacent method) that exposes theAgentplus an async disposer. The disposer unregisters the agent, aborts queued/running work, and resolves only when the driver loop reaches quiescence.- Add a queue-aware cancel primitive to the
Agentinterface. It must clear queued work that has not started, abort the current step if one exists, and makewhenIdle()wait for the post-cancel quiescent state. ACPsession/canceland bridge teardown then become honest cancellation, not best-effort pre-step cancellation. - Move background task ownership into the bash seam.
BashExecSpecorBashTaskshould carry a stable owner token, preferably the session id rather than theAgentobject identity.bash_output/bash_killthen ask the executor for ownership rather than relying on atool-bashinstance-local map.
Acceptance Criteria
- ACP disconnect/session close leaves no registered agent for that session, even when
session/loadraces teardown. session/cancelbefore a queued prompt starts prevents that prompt from running and cannot batch the next prompt into the cancelled turn.- A
tool-bashHMR reload does not make an existing background task readable or killable by a different session. - Existing non-ACP demos still work without managing handles explicitly; config-created agents remain owned by the
AgentLoopplugin fiber.
Risks
This touches public interfaces (Agent, AgentFactory, and the bash seam), so it should not be smuggled into a local ACP patch. The compatibility trap is preserving the simple synchronous Agent.send() ergonomics while adding a robust async lifecycle path for owners that need it.