docs: make technical prose concrete

This commit is contained in:
Turtle
2026-08-09 15:27:21 +08:00
parent 673e7cddc5
commit a27efdef36
459 changed files with 1342 additions and 1329 deletions

View File

@@ -1,20 +1,21 @@
/**
* Plan mode is logged per-agent collaboration state: while active, a
* deployment-owned guidance section shapes each model request, and
* deployment-owned guidance section is included in each model request, and
* `exit_plan_mode` presents the completed plan for user review, while the
* `/plan off` command lets a user leave directly. Plan mode is independent of
* sandbox mode and approval policy; those enforcement axes do not read or
* write plan state.
* `/plan off` command lets a user leave directly. Sandbox mode and approval
* policy enforce restrictions independently and do not read or write plan
* state.
*
* The state in force is folded from the session log (`plan/mode`, last one
* wins), so resume and fork restore it without a live mirror. User selections
* are held as pending intent until an in-turn step boundary. The service
* projects pending intent into the proposed step assembly, then flushes it
* remain pending until the next accepted in-turn pre-step. The service includes
* the selected state in the proposed step assembly, then appends `plan/mode`
* from `agent/pre-step` only when the step is accepted. Same-step request
* retries reuse their assembly.
*
* The exit tool remains registered while plan mode is inactive so crossing a
* boundary changes only the prompt section, not the request tool catalog.
* The exit tool remains registered while plan mode is inactive, so entering
* or leaving plan mode changes only the prompt section, not the request tool
* catalog.
*
* Agent Note:
* - .agents/notes/implemented/simplification/2026-07-22-plan-specific-collaboration-state.md
@@ -97,7 +98,7 @@ function firstHeading(plan: string): string | undefined {
/**
* Validate deployment-owned plan guidance. Missing, blank, non-string, or
* unknown fields fail at plugin load rather than silently shaping nothing.
* unknown fields fail at plugin load rather than being ignored.
*
* @param config Raw plugin config.
* @returns A detached validated config.
@@ -176,7 +177,7 @@ function planModeAtLastHeader(events: readonly SessionEvent[]): boolean | undefi
}
/**
* `ctx.planMode`: owns logged plan state, boundary application and narration,
* `ctx.planMode`: owns logged plan state, applies and narrates selected state at step start,
* the `plan:policy` section, the `/plan` command, and the stable exit tool.
* UIs observe committed flips through `session/event`; there is no live mirror.
*/
@@ -187,7 +188,7 @@ export class PlanModeService extends Service {
private readonly section: string
/**
* Latest selection per session awaiting an in-turn request-boundary flush.
* Latest selection per session awaiting the next accepted in-turn pre-step.
* `narrate` is true for user selections and false for the exit tool, whose
* result already narrates the transition.
*/
@@ -197,10 +198,10 @@ export class PlanModeService extends Service {
super(ctx, 'planMode')
this.section = resolveConfig(config).section
let disposed = false
// Pre-step is outside Session.append publication, so its log-only mode
// event can land between turns or inside an open turn without re-entering
// the session. A failed append remains pending for a later boundary, and
// policy cannot block the step.
// Pre-step is outside Session.append publication, so it can append the
// log-only mode event inside an open turn without re-entering the session.
// A failed append remains pending for a later accepted in-turn pre-step,
// and policy cannot block the step.
ctx.on('agent/pre-step', async (
{ agent, signal },
next,
@@ -212,7 +213,7 @@ export class PlanModeService extends Service {
try {
this.onBoundary(agent.session)
} catch (error) {
ctx.logger.warn('dsh-plan-mode: boundary flush failed: %o', error)
ctx.logger.warn('dsh-plan-mode: failed to append selected plan mode at step start: %o', error)
return decision
}
return !pending.narrate || narration === undefined
@@ -234,8 +235,9 @@ export class PlanModeService extends Service {
// The plan projection unit (session-projection RFC): a pure double-event
// fold serving clients the whole {active, pending} value. `command/run`
// records the user's logged /plan selection (the handler calls `set()`
// before any failing path, so log and run-plane cannot fork); `plan/mode`
// is the boundary commit that resolves it. Pending is thereby a pure
// before any failing path, so a failed handler cannot leave the recorded
// command without its plan selection); `plan/mode` records that selection
// and clears it. Pending is thereby a pure
// replay quantity: host restarts, other tabs, and cold reads all recover
// it from the log alone. The unit child activates only when a projection
// registry is composed (headless assemblies stay unaffected).
@@ -280,8 +282,9 @@ export class PlanModeService extends Service {
case 'cancelled':
return { kind: 'success', text: 'Plan mode entry cancelled.' }
case 'noop':
// Repeat the queued wording while an exit still awaits its
// boundary; only a truly inactive session reads idempotent.
// Repeat the queued wording while an exit still awaits the
// next accepted pre-step; only a truly inactive session reads
// idempotent.
return foldPlanMode(agent.session.events)
? { kind: 'success', text: 'Leaving plan mode (applies from the next step).' }
: { kind: 'success', text: 'Plan mode is already inactive.' }
@@ -357,8 +360,8 @@ export class PlanModeService extends Service {
}
throw cause
})
// A review may outlive this plugin fiber. Without boundary listeners,
// an approved result could never land, so fail and keep planning.
// A review may outlive this plugin fiber. Without its pre-step listener,
// an approved selection could never be appended, so fail and keep planning.
if (disposed) {
throw new Error('the plan-mode service was reloaded while the plan was under review; present the plan again')
}
@@ -371,7 +374,8 @@ export class PlanModeService extends Service {
: `The user chose to keep planning; their feedback: ${feedback}`)
}
// Keep plan guidance for the rest of this assistant tool batch. The
// silent intent flushes after the step, before the next assembly.
// silent selection is appended at the next accepted in-turn pre-step,
// before its request assembly.
this.pendingIntents.set(agent.session, { active: false, narrate: false })
return { approved: true }
},
@@ -390,7 +394,8 @@ export class PlanModeService extends Service {
}
/**
* Read the logged plan state and any selected state awaiting a boundary.
* Read the logged plan state and any selected state awaiting the next
* accepted in-turn pre-step.
*
* @param agent The agent to read.
* @returns Current logged state plus a pending selection, when present.
@@ -402,20 +407,20 @@ export class PlanModeService extends Service {
}
/**
* Select whether plan mode should be active. Between turns the change
* commits immediately — no request boundary would arrive until the next
* prompt, so a queued intent would hang (the open-turn fold is the idle
* signal: agent status stays `running` through post-turn checkpointing,
* where a boundary equally never comes). During an open turn the
* selection is held as pending intent for the next in-turn request
* boundary. Repeated selection of the current or already-pending state is
* a no-op.
* Select whether plan mode should be active. Between turns the method
* appends the change immediately because no in-turn pre-step will run until
* another prompt starts a turn. The open-turn fold is the idle signal:
* agent status stays `running` through post-turn checkpointing, when no
* further in-turn pre-step runs. During an open turn the selection remains
* pending until the next accepted in-turn pre-step. Repeated selection of
* the current or already-pending state is a no-op.
*
* @param agent The agent to switch.
* @param active Whether plan mode should be active.
* @returns what happened: `committed` (logged now), `queued` (awaiting the
* next boundary), `cancelled` (an opposite pending selection was cleared;
* the logged state already matches), or `noop` (already in that state).
* next accepted in-turn pre-step), `cancelled` (an opposite pending selection
* was cleared; the logged state already matches), or `noop` (already in that
* state).
*/
set(agent: Agent, active: boolean): 'committed' | 'queued' | 'cancelled' | 'noop' {
const session = agent.session
@@ -439,7 +444,7 @@ export class PlanModeService extends Service {
return 'committed'
}
/** Flush one pending selection before the next request assembly. */
/** Append one pending selection before the next request assembly. */
private onBoundary(session: Session): void {
const pending = this.pendingIntents.get(session)
if (pending === undefined) return
@@ -449,8 +454,8 @@ export class PlanModeService extends Service {
return
}
session.append('plan/mode', { active: target })
// Delete only after append succeeds so a later boundary can retry a failed
// durable write.
// Delete only after append succeeds so a later accepted in-turn pre-step
// can retry a failed durable write.
this.pendingIntents.delete(session)
}

View File

@@ -11,8 +11,8 @@
/**
* The plan projection's wire value. `active` is the logged state in force
* (the last `plan/mode`, inactive before the first); `pending` is true while
* a logged `/plan` selection (`command/run`) awaits its request-boundary
* `plan/mode` commit and targets a state other than `active`. Capability
* a logged `/plan` selection (`command/run`) targets a state other than
* `active` and no later `plan/mode` event has recorded that state. Capability
* absence (plan-mode not composed) is the key's absence, never a value.
*/
export interface PlanProjection {