The claimed-message refactor changed Inbox.claim(target, turn) and added
InboxNotifications.claimed, so the cordis_inspect tool output embedded in
the cordis-inspect-jsdoc replay fixture now carries the new declarations.
The react-loop simplification enters the workspace baseline with the first
request instead of queueing it for a second step, and the acp-agent sandbox
scenarios now replay the branch's inbox event flow. Update the agent-spine-demo
assertions to the single-request shape (workspace rule ahead of the skill
catalog, matching registration order) and refresh the two keyless sandbox
snapshots against the merged runtime.
The boundary marker row is a 0-height hairline except at the table tail;
the marker button is absolutely positioned and visible anywhere, so the
terminal-marker e2e waits on the button. Also refresh the
cordis-inspect-jsdoc fixture to the typed error reason (LlmFailure).
TurnEndReasonMap.error now carries a single `error: LlmFailure` field:
an LlmError keeps its structured facts, any other error flattens to
errorChain text under the UNKNOWN code. Consumers read message/code
directly instead of defending against an unknown union — this also fixes
errorChain() rendering structured failures as '[object Object]' in the
TUI and ACP error paths. Document the turn-stopping contract: a
concludesTurn result never short-circuits already-submitted next-step
work (same-step additionalContexts or racing steering still runs), data
decides.
Steer, inject, and followup now land as durable user/message events on the
session surface; the steering/message event type and its ConversationNode
kind are removed from the client projection. Update tests, docs, generated
catalogs, and agent notes to match, and align the steering e2e fixture and
prompt inventory assertions with the durable user/message landing.
- scrubbedParentEnv folds case before the DSH_ prefix check (Windows env
names are case-insensitive; a parent dsh_* entry read back as \*
in the child) and the service spec pins the lowercase probe.
- The acp.snapshot.ts pwsh probe follows resolvePwshPath() like the package
suites, so a Windows host with only an install-location pwsh still runs
the scenario.
- pwsh-tool-turn is re-recorded around [Console]::Out.Write('PWSH_OK'):
the fixture carries no platform newline, so one recording replays on
Windows and POSIX alike (record + refresh; replay-verified keyless).
- The pwsh-local Known Limitations bullet drops the self-defeating no-op
advice: & { } is scoped to param(...), using/#requires scripts run from a
file (both languages, pairing re-recorded).
- The capability-seams graph moves ctx.bashEnv ownership to bash-env and
lists pwsh-local/tool-pwsh on the ctx.bash seam (source updated,
docs regenerated).
- The tool-bash presenter fixture retires the stale 'command aborted'
literal for the shipped 'tool call aborted' message.
The hand-edit in 348ab41151 put the seq-17 abort error inside the tool-result
message and dropped a closing brace, breaking every JSONL consumer; tool-calls.ts
appends 'error' as a data-level sibling of 'message' (the seq-19 shape), so the
fixture now matches the emitter.
Coverage: pwsh-local's executor suites self-skip without a real pwsh, which left
per-file 100% unreachable on pwsh-less contributor hosts (mirror of the existing
windowsCoverageExclusions contract). A PATH-only probe exempts only
pwsh-local/src/index.ts; CI runners ship pwsh and still enforce the full bar.
docs/testing.md (+zh, pairing re-recorded) names the prerequisite; the testing.md
budget rises 1120->1150 because the coverage-gate contract genuinely grew.
- listChildren() takes an optional AbortSignal and rechecks it after every
un-signalled session-query await (the cold-resume cooperative-cancellation
boundary); list_agents forwards exec.signal so the registry's drain of
started tool bodies cannot block on a slow or large catalog.
- The list_agents description now presents running/complete as a stored-record
snapshot and defers deliverability to send_message, matching the ownership-
conflict semantics the service tests pin.
Implements the durable-subagent-catalog RFC: SubagentControlService.listChildren()
enumerates a parent's direct continuable children from one sessionQuery trace,
validates each child's sole subagent/descriptor event (now carrying the durable
creation label), and returns one ordered SubagentListEntry[] with per-child
corrupt/unsupported/unavailable diagnostics. The list_agents tool ships as a
separately loadable plugin of dsh-tool-subagent-control requiring sessionQuery
at load; send_message stays usable without it.
- Make host-user authority unforgeable. `{ kind: 'user' }` was a bare
discriminant, so any plugin holding `ctx.subagents` — including
model-generated cordis_mount code, which the advanced ACP composition ships
alongside continuable subagents — could construct it and skip the
direct-parent check for any known child id. It now carries an opaque grant
that only SubagentService.userAuthority() mints, which composition hands to
trusted host adapters; a model-facing tool uses parent authority from its own
execution context.
- Reconcile a delivery discarded inside its own admission window. An enqueue
listener that cancels fires the discard before followup() returns, so the
discard listener could not clear an id it had not seen; submit() retained it
and residency stayed `running` until an explicit drain.
- Recheck the caller signal after materialization. An abort landing between
publication and inbox acceptance still submitted the prompt and returned both
ids; it now rolls the child back.
- Stop promising the model transcript access that no shipped continuable config
mounts. The tools now state only that a background child does not report back.
- Restate the implemented note as shipped state rather than a proposal, so it
works as current authority.
Every scenario compares its live tool schemas and system prompt against the
shared header pins, so the Task-free subagent and send_message descriptions
change all 14 pin sidecars. The diff is only that wording plus the tools'
output-type shapes.
The authored transcript drove task_output, which no longer exists for a
continuable child and is not registered in this config, so the scenario hung.
It now demonstrates the RFC criteria directly: a delegation returning only the
durable subagent id, two send_message follow-ups queueing as later FIFO turns on
one inbox, an unknown id failing without delivery, and child-first disposal
despite a failed final durability checkpoint.
The snapshot-only overlay remaps the transcript's placeholder child id onto the
randomly minted live child, since the scripted model cannot know that id.
Also drops probe logging accidentally committed in cf0138258.
A continuable Activation outlives the turn that started it and owns descendant
teardown, so the bridge must drain that forest child-first before releasing the
top-level agents whose runtime the descendants depend on.
Also rewrites the authored continuable snapshot transcript for the Task-free
tool surface; the scenario's keyless replay is still under diagnosis.
Rewrites the service API table, authority-versus-provenance contract, residency
routing, and deferred-work list; scopes the in-process driver README to one-shot
runs; and restates both model-facing tools' outputs, which no longer carry a
task id.