Merge remote-tracking branch 'origin/master' into codex/pr48-repo-hardening-rfcs

# Conflicts:
#	docs/adr/README.md
#	docs/rfc/009-session-persistence-and-resumability.md
#	docs/rfc/README.md
#	docs/rfc/implemented/2026-06-11-doc-sync-enforcement.md
#	docs/rfc/proposed/2026-06-14-acp-agent-client-protocol.md
#	examples/acp-agent/tests/acp.e2e.ts
#	packages/acp/README.md
#	packages/acp/src/index.ts
#	packages/acp/tests/stream-update.spec.ts
#	packages/agent-loop/src/loop.ts
#	packages/tools/src/index.ts
This commit is contained in:
Tianyi Cui
2026-06-18 23:41:14 +08:00
104 changed files with 2586 additions and 590 deletions

View File

@@ -10,7 +10,7 @@
* taxonomy: the assertions below ARE the contract.
*
* Why runtime assertions instead of compile-time deep-readonly types? See
* ADR 0012. Briefly: a `DeepReadonly<SessionEvent>` is high type-noise across
* the dev-invariants RFC. Briefly: a `DeepReadonly<SessionEvent>` is high type-noise across
* every log consumer and a plugin casts straight through it; a dev-mode freeze
* + assertions catch real corruption at zero production cost and zero type
* noise. The always-on half of that defense (cloning derived messages) lives
@@ -75,7 +75,7 @@ interface SessionTrace {
* frozen: `Session.append()` accepts event data from arbitrary plugins/tools,
* so a caller can hand us a SHALLOW-frozen object whose descendants are still
* mutable. Skipping an already-frozen node (the obvious idempotence shortcut)
* would leave exactly the kind of mutable history ADR 0012 means to catch. A
* would leave exactly the kind of mutable history the dev-invariants RFC means to catch. A
* `WeakSet` of visited objects keeps it terminating on cycles and avoids
* re-walking shared subtrees / already-processed seed events.
*/
@@ -111,7 +111,7 @@ function checkEvent(trace: SessionTrace, event: SessionEvent): void {
// Boundary/step-scoped events have explicit cases; every OTHER event type —
// including plugin-added (merge-extensible) SessionEventMap keys — is caught
// by the `default` and must be turn-enclosed (ADR 0017). No assertNever: an
// by the `default` and must be turn-enclosed (the turn-enclosure RFC). No assertNever: an
// unknown variant is valid, not a compile error.
switch (event.type) {
case 'turn/start': {
@@ -182,7 +182,7 @@ function checkEvent(trace: SessionTrace, event: SessionEvent): void {
}
break
}
// Turn-enclosure (ADR 0017): EVERY session event not handled by a boundary
// Turn-enclosure (the turn-enclosure RFC): EVERY session event not handled by a boundary
// case above must sit inside an open turn. The durable session log uses the
// turn as its commit/replay boundary (the JSONL backend treats anything
// after the last turn/end as a crash tail), so a bare event between turns is