record plan mode as built, and what to watch on the first run

This commit is contained in:
2026-08-17 20:50:49 +00:00
parent 1b811dfa28
commit 4125949468
+27 -10
View File
@@ -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:<key>] 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.
---