Review fix (ds-review-bot critical #2 on #623): the first-turn event stamp
had a durability hole no turn anchoring can close — an idle SessionStart-
style injection persists a complete one-shot turn before any prompt turn
opens, so a crash in that window left a resumable-looking child with no
inherited policy, falling back to a possibly wider deployment default.
The captured overrides now ride the child's creation meta into its
immutable SessionHeader (sandboxMode/approvalPolicy, neutral strings at the
session boundary — the delegationDepth precedent), durable from the moment
the session exists: no listener ordering can starve the baseline and no
crash window can lose it. overrideOf(session) on both policy services
resolves fold(events past header.seedLength) ?? header baseline, validating
against the closed vocabulary on read; stampOverride and the prompt-submit
listener machinery are deleted. The header field rides both persistence
backends (JSONL header line; SQLite sessions columns, SCHEMA_VERSION 11 —
pre-release, no migration). pty-local reads through overrideOf so PTY
spawns see the baseline too.
Red-first: header-durability-before-any-turn test (the injection crash
window shape), baseline/seed-boundary/closed-vocabulary contract tests in
both service suites; the real-wall suite (race, veto, fork stale-seed,
grandchild) re-anchored on header assertions and green. The Agent Note's
Alternatives now records the superseded event-stamping iteration with the
review evidence; bilingual docs updated.
Conflict resolution: drainDispatches composes both sides — the reworked
single-lane driver's drive() (ordered stages, mid-flight commit drain)
followed by this branch's logWork drain, so every shaped settle append
still lands inside the open run_code turn.
Responding to ds-review-bot round 2 on #658 (three critical findings, one
warning — all rooted in the pump/commit split racing ordered stages):
- ONE driver lane now owns every ordered stage: the start append, prepare
(pre-execute/guards), and the head-of-line commit (post-execute, context
deferral, settle append). start() is awaited before the next entry can
start, so concurrent submissions can no longer run pre-execute pipelines
concurrently; only the around-dispatch/body stage overlaps, matching the
native loop's fillPool sequencing.
- An exclusive call's barrier now holds through its COMMIT: later starts
wait for the exclusive pipeline (post-execute included) to finish, the
native exclusive-group semantics.
- drainDispatches() awaits the driver run itself, so a commit already
mid-flight when the program returns is drained before run_code closes
the turn — the settle event and deferred contexts land inside it.
- maxParallelSubCalls is resolved and validated at construction (positive
integer), so direct construction can no longer wedge the pool with 0.
New tests: overlapping-submission ordered-prepare, barrier-through-commit,
drain-mid-commit, cap rejection. 96 keyless snapshots replay unchanged;
Agent Note updated (both languages).
CI's full-tree coverage flagged three untaken paths this PR introduced:
- shapeDispatchLog's catch (a throwing tools/code-dispatch-log listener
must be contained — the settle event logs the unshaped content);
- the spill listener's flatten-decline arm (non-text sub-result content
passes through unchanged);
- the generated scope-key extractor row for tools/code-dispatch-log
(registered in the scope invariant matrix like the other tools events).
The coverage gate flagged three untaken paths in the bridge scheduler:
- the exclusive-head inFlight re-check was dead (the shared guard above
already returns for an exclusive head with any in-flight sibling) — removed;
- the commit-cursor undefined-dispatched break was structurally unreachable
once entries join commitQueue only after start() ran synchronously —
reordered the pump so the invariant holds by construction, annotated;
- the finish (final-result) commit arm and the pump re-entry guard gain a
covering test (throwing tools/pre-execute listener) and a defensive
annotation respectively; mid-run unregistration test renamed to match its
actual post-result settlement path.
Also covers the direct-construction maxParallelSubCalls default (index.ts)
and commits the regenerated persistence catalog for the new dispatch pair.
ds-review-bot findings on the parallel bridge: sub-dispatches now run
through the registry's staged scheduler view (the loop's own seam) —
ordered prepare (pre-execute/guards) at submission-ordered start time,
only the dispatch/body stage overlapping, and a head-of-line commit
cursor running post-execute, context deferral, and the settle event in
submission order (new spec pins post order + context order under
out-of-order completion). Queued dispatches reclassify via
executionMode() immediately before starting, so a registry mutation
while queued flips them exclusive (native lazy-reclassification
semantics). Config and tool catalogs regenerated; the tool-catalog
metadata now names the start/settle pair and the scheduling contract.
The bridge replaces its serialization queue with a pool that reuses the
native concurrency contract: submissions classify through
registry.executionMode (fail-closed isConcurrencySafe), start strictly in
submission order, overlap up to the validated maxParallelSubCalls config
(default 10; 1 restores serial), and exclusive calls drain the pool, run
alone, and bar later calls. Each started sub-call logs a
tool/code-dispatch-start event at pool entry; the existing
tool/code-dispatch settles the pair (started ⇔ settles exactly once;
abandoned queued calls log neither). SDK prompt guidance now states the
true Promise.all contract — re-recorded across every code/both-mode
snapshot (plus the stale cordis-dynamic-toolchain fixture gaining the
required description arg).
Client: CodeSubCall widens to RunningToolCall | ToolResultNode — starts
land the running shape (rows wear the native running ring), settles
replace in place preserving start order, callTime pairs to the start
time. Fixture emits start/settle pairs; jsdom pins the running sub-row;
runtime specs pin in-place settlement and out-of-order completion.
run_code gains a required bash-style description parameter: presentCall
titles the card with it and moves the program to rawInput, so every
surface gets a readable label. tool/code-dispatch now logs each
sub-call's complete content/isError (the tool/result vocabulary),
replacing the bounded resultSummary and deleting the summarize/cwd
machinery — a UI renders sub-calls through the identical path as native
results. The dsh config tree mounts the worker code runtime and reads
DSH_TOOLS_MODE (temporary seam until per-session mode selection lands).
Session format stays v0 (pre-release churn). Code-mode ACP/TUI fixtures
re-recorded; TUI presenter pin refreshed; catalogs regenerated. Keyless
web smoke pins the code-mode wire contract (tools=[run_code] + SDK
prompt section).
Master PR #263 (scoped-layers-store): one conflict in the regenerated
docs/architecture.i18n.yaml pairing record — took master's and re-recorded
the pair over both sides' merged architecture.md/zh.md (the ctx.modes rows
merged cleanly on both).
Master arrivals re-grafted onto the plan-mode surfaces:
- Package invariant runtime contracts: every package owns ./invariant —
added the dsh-mode companion (mode/set payload validation: non-empty
trimmed name), its unit spec, exports/peer wiring, and the mode group in
the tsconfig invariant paths glob.
- Interception waterfalls gained an AbortSignal parameter
(agent/prompt-submit, agent/turn-continuation) and ToolExecutionInput.signal
became required: listeners and test dispatch updated; the exit tool now
forwards exec.signal unconditionally.
- TUI question dialog: master's position/unanswered header layout kept,
the plan-review detail block re-grafted between question and answers.
- LSP capability family arrived: lsp tool joins the catalog pin, dsh-lsp
examples deps beside dsh-mode; lsp-definition snapshot refreshed with
the mode command and modes advertisement.
- docs/architecture.md and packages/README.md regenerated tables re-grafted
(ctx.modes row, mode package row) and condensed within word ceilings.
- examples/acp-agent cordis.yml: kept the deployment-owned plan instructions
(incl. the conversational-agreement sentence) beside master's routed-model
compaction comment; snapshot expected outputs refreshed keyless and noise
fixtures restored.