Store the captured validation error as unknown in a wrapper object and
rethrow it directly: the instanceof-Error normalization added an
un-inducible false branch that failed harness.ts's 100% branch gate.
- proposed/testing -> implemented/testing with the lifecycle rewrite
(Proposal->Decision in present tense, Acceptance criteria + Risks
folded into Consequences); zh counterpart mirrored and both pairs
re-recorded.
- the rejected NIH-audit roll-up pair now links the implemented/ path.
- loader-smoke README: captured output is bounded by execa's default
100 MB maxBuffer, no longer unbounded.
- acp-snapshot README: harness.ts now also imports vitest (vi.waitFor),
so the vitest-run-only constraint names both modules.
- jsonrpc keyless smoke: raise the invalid-env case's subprocess
deadline to 25s (the 9s pick starved a cold tsx boot on slow NFS).
Validate replay sidecars and cross-copy failure facts, make browser console tripwires and macOS temp paths deterministic, and wait for asynchronous TUI resume details. Keep the owning docs, translations, and generated catalog aligned.
Implements the execa Agent Note's four sub-changes:
- execa (root devDep + loader-smoke dep) replaces the hand-rolled
spawn-collect-timeout choreography in loader-smoke, apps/cli and
cli-demo/acp-demo built-bin e2e, lsp-local and code-runtime-worker
built-lib e2e, the tui pty-harness outer collector, the jsonrpc
keyless smoke, and crash-recovery's child spawn. Genuinely custom
parts stay custom: cli-demo's interrupt-on-marker, jsonrpc's
line-predicate protocol driving, crash-recovery's SIGKILL-at-failpoint.
The two loader-smoke /* v8 ignore */ OS-error branches are gone.
- llm-mock-server CLI tokenizes via node:util parseArgs; numeric
coercion/bounds/cross-option constraints stay manual; pinned
error-message tests updated to the parseArgs texts.
- both loadRootEnv copies in apps/web/tests are deleted: the owning
vitest configs (web unconditionally, snapshot in record mode)
already load the repo-root .env before these files run.
- the four poll loops (acp-snapshot harness waits + crash-recovery
waitForFile) ride vi.waitFor with explicit {interval, timeout}.
Downstream packages lost the tests that exercised their agent-loop-facing
edges when the loop was rewritten. Restore 100% per-file coverage with
behavior tests through public seams: llm-retry config validation and
cancellation races, goal replay drift/staleness/teardown edges, plan-mode
disposed-flush, workspace-context empty-change commits, api-proxy
synchronous send failures, acp-snapshot spill-path extraction and refresh
write-back, ACP injection-triggered turns, cli-demo and tui inbox
lifecycle edges, and agent-loop retry/settlement/lifecycle branches.
The only source changes are narrowly-justified v8 ignore annotations on
invariant guards and one redundant-guard removal (workspace-context).
The branch edited the English side of 17 doc pairs without their Chinese
counterparts. Bring every .zh.md up to date (loop.ts references now point
at agent.ts, send/steer/inject unification, context/message folded into
user/message, HookContext replaced by UserMessageData in tool decision
blocks, plan/skill delivery moved to agent/step) and re-record the pairing
hashes. Deduplicate type-equiv.manifest.json entries duplicated by the
master merge and drop entries for symbols the refactor removed. Complete
the missing JSDoc on extractSnapshotSpillPaths.
macOS symlinks /tmp → /private/tmp; when the session header cwd lacks
the /private prefix but fs tools resolve symlinks, tool result paths
get the prefix and the cwd replacement never matches. Strip the prefix
before cwd→{{cwd}} replacement so both forms normalize identically.
Also extend refreshFixtureReplacements to match spill paths by filename
suffix, preventing raw fixture churn when a refresh runs from a
different session directory.
ACP v1 requires every agent to accept text AND resource_link prompt
content; the automation rewrite dropped the resource_link half of that
baseline. Restore the old bracketed-reference flattening in the codec,
reject only beyond-baseline blocks, and update the package contract and
Agent Note.
Also release the per-session prompt slot when agent.send() throws
synchronously (an agent disposed outside the bridge would otherwise
wedge the session into permanent 'already in flight' rejections),
drop the tautological version-negotiation branch, prove the scenario
env layer reaches the snapshot subprocess, pin bridge-side fail-closed
permission errors, and correct two overpromising test names.
testing.md gains the web browser snapshot tier entry (divergent
DSH_SNAPSHOT=... test:web commands) and names apps/web/tests/snapshots/
as the web surface's snapshot home. The GUI testing note's tier map and
lane map gain the e2e scenarios (both languages, pair re-recorded) and
drop the stale verify-session-real references (those scripts left with
the missions/ tree). packages/client/AGENTS.md check ladder covers the
wire-carriage trigger and refresh/record commands. acp-snapshot README
stops claiming the whole package is ACP-specific — its normalizers are
transport-neutral with three consumers now. vitest.web.config.ts header
carries TODO(ci-browser) with the staged-reversal pointer.
The design-study Agent Note moves proposed/ -> implemented/ rewritten in
present tense: all review decisions recorded (llm:false seam over the
placeholder-key hack, providers-mode replay, whenIdle barrier stack,
single aria golden + anchors, TUI-style inline modes over a suite
factory, scrub-only header stance, CI deferral) with re-entry triggers
under Deferred.
Master removed the stdio demo (#702c8cc30) — accept the deletion; this
branch's packChunks passthrough survives in acp-demo (auto-merged), and
cli-demo/tui-demo arrived from master without one (the follow-up snapshot
PR decides which demos expose the switch). Generated catalogs regenerated
over merged sources; the hand-written session.md durability paragraph
re-weaves this branch's lossless-encoding wording with master's invariant-
companion sentence.