The bridge now holds each session's `AgentHandle` disposer in its `SessionRecord` and runs it on teardown (client disconnect or fiber dispose) instead of the old `abort()` + `whenIdle()` drain that left agents registered. A bare client disconnect now leaves NO registered agent and NO session-store entry — not an idled-but-still-registered one. The queue-aware `cancel()` inside the disposer also closes the former pre-step best-effort window (a turn about to start is dropped), so teardown reaches true quiescence. The `session/load`-races-teardown leak is fixed: if the bridge closed while `resume()` was pending, the just-resumed handle is disposed before throwing, so it leaves no orphan (it has no SessionRecord, so quiesce() never sees it). Tests: the disconnect test now asserts (through the SAME memoized teardown) that the agent is unregistered AND its session removed; a durability test re-loads the persisted log after dispose and asserts the closing turn/end is on disk (guards the teardown-order contract); a sibling-isolation test proves one handle's dispose() leaves other agents untouched. Docs: agent / agent-loop / acp READMEs, architecture.md, and the stale in-code quiesce() ownership comment updated to the per-agent disposal model; the now-resolved TODO(rfc010-agent-disposal) / TODO(rfc010-cancel-prestep) teardown notes removed.
RFCs
One kind of design doc lives here. An RFC records a decision or proposal that shapes this codebase — the why and what we gave up, the parts code and docs can't carry. (Earlier this split into separate "ADR" and "RFC" trees; they were unified, since most ADRs were simply implemented RFCs.)
Layout and naming
Files are grouped by lifecycle into three folders, and an RFC moves between them as its status changes:
proposed/— proposals reviewed before implementation; not yet built (or only partly).implemented/— the decision shipped. The file records what was decided and what was rejected, and is kept current with what actually shipped: when the code later moves a file, renames a package, or changes a key/default, the RFC is updated in the same change to match (facts only — paths, names, structure — not the decision itself). See implemented/AGENTS.md.rejected/— the proposal was considered and declined. Kept for the record so the rejection isn't re-litigated.
Each file is named yyyy-mm-dd-topic-title.md, where the date is when the topic was first proposed (per git history). Cross-references between RFCs use relative markdown links ([topic](../implemented/2026-…-….md)) — never bare prose or numbers — so they are mechanically checkable and survive moves between folders.
When to write one
Write an RFC when a decision is durable (it shapes the codebase beyond a single function or package), contested (there was a real alternative a reasonable engineer might have chosen), and surprising (a future reader would otherwise ask "why on earth is it done this way?"). A proposal for substantial future work starts in proposed/; a decision already made starts in implemented/.
Do NOT write one for a mechanical or local choice (a variable name, a one-file refactor), for anything already enforced and explained by a gate or a convention in AGENTS.md, or for a still-provisional decision tagged TODO(...) in the code — record those as TODOs and promote to an RFC only once they settle. An RFC is never edited into a different decision: supersede it with a new one and cross-link. (Editing an implemented/ RFC to track where its already-made decision now lives — a moved file, a renamed package — is not a different decision and is required, not forbidden; see implemented/AGENTS.md.)
Proposed
| Title | First proposed |
|---|---|
| Mutation testing as the coverage counterweight | 2026-06-11 |
| Deterministic tests, the replay invariant fixture, and race stress | 2026-06-11 |
| Architectural conformance — dependency rules and the adapter kit | 2026-06-11 |
| API extractor reports | 2026-06-11 |
| Supply chain checks and vendor drift verification | 2026-06-11 |
| Agent Client Protocol (ACP) support for external editors | 2026-06-14 |
| Multiplex concurrent ACP sessions over one connection | 2026-06-14 |
| Optional Code Mode — model writes TypeScript against an SDK of all tools | 2026-06-15 |
| Runtime schemas for the event vocabulary (Zod vs the merge-extensible-map pattern) | 2026-06-16 |
| Agent lifecycle and ownership seams | 2026-06-18 |
Implemented
Rejected
| Title | First proposed |
|---|---|
| Deep-readonly public surfaces | 2026-06-11 |