diff --git a/docs/chat-plan-mode.md b/docs/chat-plan-mode.md index b5513979..6f62af86 100644 --- a/docs/chat-plan-mode.md +++ b/docs/chat-plan-mode.md @@ -3,8 +3,8 @@ Agreed with the owner on 2026-08-17, immediately before a context compaction. Written so the build can start from here with nothing re-derived. -**Status: step 1 verified against a real `claude` (SDK 0.3.233), nothing built yet.** The mechanism works and -the open question below is answered — see "Verified" before implementing. +**Status: built in `1b811dfa`, not yet run.** Needs `pm2 restart officer` and `pm2 restart officer-claude-code` +before it does anything — see "Sequence" at the end for what to watch on the first plan. --- @@ -139,15 +139,32 @@ exactly this class of thing; a `session.permissionMode` beside it keeps `applyMo --- -## Sequence +## Sequence — all landed in `1b811dfa` -1. ~~Verify the `canUseTool` question~~ — **done**, see "Verified" above. -2. `session.permissionMode` on `PersistentSession`, plus `applyPermissionModeChange` mirroring - `applyModelChange` — control request, effective-not-requested, durable event on success and on refusal. -3. `plan:entered` / `plan:proposed` / `plan:exited` durable events through the five files `model:switched` - already travels. -4. Composer toggle, and a plan card in the transcript with Approve / Reject. -5. Return to `bypassPermissions` on approval, rejection, and turn end. +1. ~~Verify the `canUseTool` question~~ — see "Verified" above. +2. ~~`session.planMode` on `PersistentSession`, plus `applyPlanModeChange` mirroring `applyModelChange`~~ — + control request, effective-not-requested, durable event on success and on refusal. +3. ~~`plan:mode` / `plan:proposed` / `plan:decided` durable events~~ through the same path `model:switched` + travels. +4. ~~Composer toggle, and a plan card in the transcript with Approve / Reject~~ — rejection takes a reason + and sends it as the denial message, which the harness turns into a revision request. +5. ~~Return to `bypassPermissions` on approval~~ — fired from inside `planGate`, not at turn end. + +**Not yet run.** Everything above is on disk and typechecks; none of it has executed on this machine. It +needs `pm2 restart officer` AND `pm2 restart officer-claude-code` — the sidecar holds all of the interesting +half, and restarting only the server would leave the old one running with no `canUseTool` at all. + +Worth watching on the first real plan, in this order: + +- the composer's clipboard icon lights, and `[claude:plan:] plan mode on` appears in + `pm2 logs officer-claude-code` +- the agent researches and refuses to edit — a `Write` in plan mode should reach neither disk nor the gate +- the plan card renders with Approve / Reject, and **the turn is genuinely parked** while it sits there +- approving continues the same turn, and `plan mode off` follows immediately rather than at turn end +- refreshing mid-plan replays the card with its decision, rather than a conversation that stops dead + +The one failure mode to watch for is a turn that never ends after a plan is answered: that would mean a +`canUseTool` promise was left unresolved, and `settleAllPlans` is what is meant to make it impossible. ---