- fs-sandbox: delegate the mutation with the freshly re-canonicalized target
(not the stale one), so the checked identity is the mutated identity — a
symlink swapped in after resolve() can no longer escape workspace-write.
- tool-fs: map a denial to an FsError carrying FS_SANDBOX_DENIED (not a plain
Error), so ToolRegistry keeps the structured code on result.error for
retry/observers while the message stays the shared marker.
- sandbox-local: derive the Seatbelt writable set from the shared
writableRoots() helper, so the profile and the fs fence cannot drift.
- gen-doc-graphs: ctx.sandboxPolicy is owned by dsh-sandbox-policy and read only
by the sandboxed executor/provider (the tool layers use the pure fold).
- docs: bash-sandbox/bash/permission READMEs and bash.md reflect the relocated
policy home and the sandbox/mode rename; drop the stale stdout.golden.jsonl.
Declare the tool-result pruning plugin in the examples workspace so the repl Cordis configuration resolves through plain Node and the Loader metadata gate.
Express the validated single-node surface rewrite without a non-null assertion or an unreachable defensive branch, preserving both the runtime contract and per-file 100% coverage.
Retarget the pruning feature onto the merged compaction foundation.
Adapt content-only tool-result rewrite validation to the session-owned surface manager, migrate the demo wiring to repl-agent, and refresh generated type, catalog, and website contracts while preserving pressure and overflow pruning behavior.
Adopt initiator-derived private loop and session plumbing while preserving post-step recovery and balanced synthetic tool-call results after cancellation.
Keep the architecture map within its existing budget while documenting ambient Agent ownership and explicit cross-boundary identities.
Combine agent initiator scoping and exact Cordis JSDoc inspection with post-step compaction and bounded request recovery.
Regenerate the Cordis and website API catalogs, and classify the recovery and compaction types required by the current catalog link-coverage gate.
Replace the process-wide adapter-failure WeakSet with a per-call scope bound to the exact AsyncIterable returned by LlmService.stream(). Give every call a unique wrapper so waterfall middleware can reuse an iterable without sharing provenance.
Move agent-loop recovery classification to the model-stream boundary. Only the final adapter behind that exact call can become an agent/request-error; nested llm/stream calls remain ordinary outer middleware failures while preserving the original Error.
Cover nested calls, reused middleware iterables, and end-to-end agent-loop recovery. Update the package and RFC contracts, bilingual pairing record, and generated API and catalog references.
Document every context-window path returned by mapStopReason: recognized provider error wording, successful stop usage beyond the resolved window, and zero-output length stops that fill the window.
This keeps the public return contract aligned with usage-based overflow classification without duplicating the provider-specific detection table owned by pi-ai.
Dispatch RequestErrorDecision and CompactionTrigger through explicit discriminant switches. End each closed union with assertNever so new variants fail compilation instead of silently inheriting fail or pressure behavior.
This preserves the current retry, fail, pressure, and overflow semantics while aligning the new recovery seams with the repository closed-union contract.