Requirements Index
Status: Draft
This index makes the specification executable by a large implementation project. Each normative requirement has a stable ID. Issues, pull requests, tests, and release evidence reference those IDs.
Families
| Prefix | Area | Normative source |
|---|---|---|
AUTH | Agent and Tool authoring | Authoring |
RUN | Interpreter and event runtime | Runtime |
MODEL | Model drivers and routing | Providers |
CAP | Optional capabilities | Capabilities |
SUB | Subagent delegation and child lifecycle | Subagents |
STORE | Persistence and adapters | Persistence |
DUR | Accepted work and recovery | Durability |
DEPLOY | Hosts and deployment classes | Deployment |
SEC, OPS | Security and operations | Security and operations |
TEST | Verification | Testing |
COMPAT | Interoperability, boundaries, and versions | Compatibility |
Requirement lifecycle
A requirement is:
- specified when its normative source defines behavior and failure semantics;
- planned when it is accepted for implementation but not yet built;
- implemented when code and public documentation exist;
- verified when automated evidence covers it;
- released when a compatibility manifest names the package/adapter version.
Implementation status belongs in generated project tracking, not by editing the normative wording from “must” to “done.”
Traceability record
Each implementation issue includes:
requirements:
- RUN-004
- TEST-003
decision_dependencies:
- (none)
adrs:
- (none)
packages:
- packages/engine
verification:
- packages/engine/test/tool-scheduling.test.ts2
3
4
5
6
7
8
9
10
11
Each pull request states which requirement behavior changed and which test provides evidence. A requirement without an executable test must have a documented reason, owner, and future gate.
Coverage
bun run requirements:coverage (scripts/requirements-coverage.ts) is the generated coverage gate for TEST-011. It extracts every requirement ID defined in docs/spec/*.md, collects the IDs referenced by executable test titles (string literals in each workspace's test tree plus the shared adapter conformance suites whose case names run as adapter test titles), and requires every remaining ID to have exactly one row in the coverage exceptions table below. The gate fails on duplicate or unknown IDs, on undocumented gaps, and on stale exception rows whose ID a test title now references. Comments never count as coverage — only test titles do.
Exception statuses are honest dispositions, not waivers:
- evidence — executable tests demonstrably cover the behavior but no test title carries the ID yet; the row cites the covering test files (each cited path must exist).
- deferred — no executable evidence exists yet; the row names the owner and future gate.
- process — the requirement is a governance/structural rule that no runtime test can discharge; the row documents the reason and the review point that owns it.
Coverage exceptions
| ID | Status | Evidence or reason | Owner / future gate |
|---|---|---|---|
| AUTH-001 | evidence | packages/testing/test/travel-planner.compile.test.ts, packages/core/test/core.test.ts — every public fixture authors schemas with Effect Schema only | — |
| AUTH-002 | evidence | packages/core/test/agent-types.test.ts — separates the immutable Definition from the Model Binding | — |
| AUTH-003 | evidence | packages/engine/test/agent-runtime.test.ts — native Effect AI Toolkit flows drive the deterministic Turn suite | — |
| AUTH-004 | evidence | packages/core/test/agent-types.test.ts, packages/engine/test/agent-runtime.test.ts — E/R inference proofs | — |
| AUTH-005 | evidence | packages/engine/test/agent-runtime.test.ts — steering and follow-up land only at the documented Turn seams | — |
| AUTH-006 | evidence | packages/core/test/core.test.ts — constructs finite policies and rejects invalid bounds | — |
| AUTH-007 | evidence | packages/engine/test/agent-runtime.test.ts — never starts a handler while approval is unresolved | — |
| AUTH-008 | evidence | packages/engine/test/agent-runtime.test.ts — output decode failures stay typed; no undecoded success | — |
| AUTH-009 | evidence | packages/testing/test/travel-planner.compile.test.ts, examples/providers/test/profiles.test.ts — public examples compile against the pinned Effect | — |
| AUTH-010 | process | the authoring surface deliberately ships no hook API, so no render-state probe exists to write | open-source preparation API review re-checks before any hook-like surface lands |
| AUTH-011 | evidence | packages/testing/test/toolchain.test.ts — manifest audits keep Effect AI primitives upstream-only | — |
| AUTH-012 | evidence | packages/core/test/agent-types.test.ts, examples/providers/test/profiles.test.ts — Definitions stay model-agnostic; only explicit Bindings run | — |
| RUN-002 | evidence | packages/engine/test/agent-runtime.test.ts — run reduces the same semantic trace exposed by stream; one terminal per Run across the suite | — |
| RUN-003 | evidence | packages/engine/test/agent-runtime.test.ts — handlers receive decoded class-shaped parameters | — |
| RUN-005 | evidence | packages/engine/test/agent-runtime.test.ts — preflights the complete Tool batch before starting any handler | — |
| RUN-006 | evidence | packages/engine/test/agent-runtime.test.ts — deterministic scheduler and batch commit order | — |
| RUN-007 | evidence | packages/engine/test/agent-runtime.test.ts — interrupts native model and Tool resources with the Run Scope | — |
| RUN-008 | evidence | packages/testing/test/travel-planner-subagents.test.ts — interrupting the parent mid-child finalizes children and settles reservations | — |
| RUN-009 | evidence | packages/capabilities/test/capabilities.test.ts, packages/engine/test/agent-runtime.test.ts — finite scheduler and exclusivity tests | — |
| RUN-010 | evidence | packages/engine/test/agent-runtime.test.ts — does not let a slow detached observer determine completion | — |
| RUN-012 | evidence | packages/session/test/session.test.ts, packages/core/test/core.test.ts — closed canonical unions reject non-schema payloads | — |
| RUN-013 | evidence | packages/platform-node/test/crash/crash.test.ts — Unknown blocks the lane until authorized resolution; never blind replay | — |
| RUN-014 | evidence | packages/engine/test/agent-runtime.test.ts — delivers steering offered during Tool execution only before the next model request | — |
| RUN-015 | evidence | packages/engine/test/agent-runtime.test.ts — buffers follow-up until the otherwise-stop seam | — |
| MODEL-001 | evidence | packages/engine/test/agent-runtime.test.ts, examples/providers/test/profiles.test.ts — Effect AI Toolkit/Model used directly | — |
| MODEL-002 | evidence | examples/providers/test/profiles.test.ts — upstream Models bind directly; no wrapper hierarchy exists | — |
| MODEL-003 | evidence | packages/engine/test/agent-runtime.test.ts — rejects malformed streaming part lifecycles; validates complete Tool Calls | — |
| MODEL-004 | evidence | packages/engine/test/durable-tool-seam.test.ts, packages/engine/test/agent-runtime.test.ts — Toolkit handlers under engine scheduling and durable boundaries | — |
| MODEL-005 | evidence | packages/session/test/session.test.ts — canonical schemas reject non-canonical shapes | — |
| MODEL-006 | evidence | packages/engine/test/agent-runtime.test.ts — Effect AI interruption propagates through the Run Scope | — |
| MODEL-007 | process | the framework ships no provider retry layer; repeated-failure stops are Agent policy (packages/engine/test/agent-runtime.test.ts), so nothing exists to conflate | revisit when a framework retry layer lands |
| MODEL-008 | evidence | examples/providers/test/profiles.test.ts — OpenAI/Anthropic integration binds upstream Model Layers | — |
| MODEL-009 | process | upgrade procedure is TOOLCHAIN policy; the pin agreement itself is executable (packages/testing/test/toolchain.test.ts) | TEST-013 CI machinery gates each upgrade |
| MODEL-010 | evidence | packages/core/test/agent-types.test.ts, examples/providers/test/profiles.test.ts — model selection is explicit in the Binding | — |
| CAP-001 | evidence | packages/capabilities/test/capabilities.test.ts — every capability adapter is an Effect service under test | — |
| CAP-002 | evidence | packages/core/test/agent-types.test.ts — missing capabilities stay visible in R and fail Layer assembly | — |
| CAP-003 | evidence | packages/engine/test/durable-tool-seam.test.ts — the engine owns durable Tool scheduling through its seam | — |
| CAP-004 | evidence | packages/engine/test/agent-runtime.test.ts — schema boundaries on every Tool input and output path | — |
| CAP-005 | evidence | packages/engine/test/agent-runtime.test.ts — deterministic Tool batch commit order | — |
| CAP-006 | evidence | packages/capabilities/test/capabilities.test.ts — approval request/decision audit reservations; packages/testing/test/durable-approval.test.ts — canonical approval records | — |
| CAP-007 | evidence | packages/engine/test/agent-runtime.test.ts — source history stays authoritative under compaction; packages/capabilities/test/capabilities.test.ts — exact-digest compaction provenance | — |
| CAP-008 | deferred | no Skill repository/activation capability is implemented yet; the capabilities spec section is design-only | first Skill implementation phase records loaded identity/version |
| CAP-011 | evidence | packages/capabilities/test/subagent.test.ts, packages/testing/test/travel-planner-subagents.test.ts — declared delegation Tools under parent-Scope structured concurrency | — |
| CAP-012 | deferred | no persistent agent-state capability exists; Conversation history is the only persisted state | first persistent-state capability phase |
| CAP-013 | evidence | packages/capabilities/test/capabilities.test.ts — structural approval-input redaction; packages/core/test/core.test.ts — bounded Subagent event text; adversarial coverage in packages/testing/test/security/redteam-child-exfiltration.test.ts | — |
| SUB-001 | evidence | packages/capabilities/test/subagent.test.ts — delegation Tools are Effect AI Tools, recognizable at preflight | — |
| SUB-002 | evidence | packages/capabilities/test/subagent.test.ts — establishment requests assemble from construction-fixed declaration values; Subagent.define validation | — |
| SUB-003 | evidence | packages/capabilities/test/subagent.test.ts — explicit child Binding; fails closed without a construction declaration | — |
| SUB-004 | evidence | packages/core/test/core.test.ts — Parent Link round-trip and invalid-lineage rejection; packages/testing/test/travel-planner-subagents.test.ts — fresh distinct child identity | — |
| SUB-005 | evidence | packages/core/test/core.test.ts — Subagent lifecycle unions round-trip and reject malformed payloads | — |
| SUB-006 | evidence | packages/testing/test/travel-planner-subagents.test.ts — child/parent prompt isolation; packages/capabilities/test/subagent.test.ts — grant ceiling denies outside Tools | — |
| SUB-007 | evidence | packages/capabilities/test/subagent.test.ts — a denied establishment fails typed without joining; grant checks precede any budget | — |
| SUB-008 | evidence | packages/capabilities/test/subagent.test.ts — a narrowed grant denies the resumed action before establishment replay; adversarial coverage in packages/testing/test/security/redteam-idor-sweep.test.ts | — |
| SUB-009 | evidence | packages/capabilities/test/subagent-reservation.test.ts — finite bounded dimensions; packages/capabilities/test/subagent.test.ts — duration and children caps | — |
| SUB-010 | evidence | packages/capabilities/test/subagent-reservation.test.ts — conservation, no oversubscription, exactly-once release | — |
| SUB-011 | evidence | packages/testing/test/travel-planner-subagents.test.ts — parent interruption finalizes children and reservations | — |
| SUB-012 | evidence | packages/capabilities/test/subagent.test.ts — durable mode never spawns an in-process child fiber; Scope-owned slot gate | — |
| SUB-013 | evidence | packages/testing/test/durable-subagents.test.ts — settled sibling results commit before suspension; packages/platform-cloudflare/test/subagents-cross-do.test.ts — sibling injection row | — |
| SUB-014 | evidence | packages/capabilities/test/subagent.test.ts — fails closed when the projected result escapes the success Schema | — |
| SUB-019 | evidence | packages/testing/test/durable-subagents.test.ts — verified Settlement joins; packages/platform-cloudflare/test/subagents-cross-do.test.ts — join append replays its accounting | — |
| SUB-023 | evidence | packages/testing/test/durable-subagents.test.ts — binding-free recovery from canonical requests; packages/platform-node/test/crash/crash-subagents.test.ts — exact-digest resolution under process kills | — |
| SUB-024 | evidence | packages/core/test/core.test.ts — bounded lifecycle summaries; packages/testing/test/security/redteam-idor-sweep.test.ts — observe denies foreign lanes; packages/testing/test/security/redteam-child-exfiltration.test.ts — child payload redaction | — |
| SUB-025 | process | the per-class suites exist (S1/S2/DN/DC); release gating is a process rule, not a runtime behavior | release checklist at open-source prep |
| SUB-026 | deferred | no adversarial test yet pins non-transitive parent approval against child actions, siblings, retries, or descendants; the P7 review found the approval path sound via conformance idempotency (docs/security/FINDINGS.md) | open-source preparation security pass |
| SUB-027 | deferred | no artifact port exists, so artifact reference semantics cannot be exercised | future artifact capability phase; the P7 threat model records the explicit N/A |
| SUB-028 | evidence | packages/capabilities/test/subagent.test.ts — expected child failures total-map to the declared Tool failure; defects stay defects | — |
| SUB-032 | evidence | packages/capabilities/test/subagent.test.ts — aborted children and compatibility failures classify distinctly; packages/testing/test/durable-subagents.test.ts — no newer-code substitution | — |
| STORE-001 | evidence | packages/session/src/conformance.ts, packages/session/src/ledger-conformance.ts — two distinct port suites run against every adapter pairing | — |
| STORE-002 | evidence | packages/session/src/ledger-conformance.ts — duplicate admission, terminal retry, and settlement idempotency cases | — |
| STORE-003 | evidence | packages/storage-sqlite/test/sqlite-ledger.test.ts — reopen reads committed state; packages/storage-cloudflare/test/do-ledger.test.ts — a fresh incarnation reads the committed admission | — |
| STORE-004 | evidence | packages/session/src/conformance.ts — duplicate batch, divergent batch, stale tail, and fence cases | — |
| STORE-005 | evidence | packages/session/test/session.test.ts — versioned envelope round-trip and unsupported-version rejection | — |
| STORE-006 | evidence | packages/storage-sqlite/test/sqlite-storage.test.ts — fails clearly on corrupt current-version rows without mutating the log | — |
| STORE-007 | evidence | packages/session/src/conformance.ts — checkpoint digest binding and corruption cases; packages/session/test/session.test.ts — checkpoint replay equivalence | — |
| STORE-008 | evidence | packages/session/test/session.test.ts — phase-N checkpoint rejection rows force rebuild from canonical records | — |
| STORE-009 | deferred | no digest-addressed artifact store exists (AttachmentStore is deferred); oversized DC payloads are refused typed (packages/platform-cloudflare/test/limits.test.ts) | future artifact capability phase |
| STORE-011 | evidence | packages/storage-sqlite/test/sqlite-ledger.test.ts — typed v1/v2 reset guidance; packages/platform-node/test/layers.test.ts — startup refusal without mutation | — |
| STORE-012 | process | no deletion or retention path exists by design during private development; nothing to exercise | open-source preparation retention/deletion design |
| DUR-003 | evidence | packages/platform-node/test/crash/crash.test.ts — honest at-least-once re-execution; packages/testing/test/travel-planner-phase5.test.ts — duplicate supplier calls asserted, never hidden | — |
| DUR-005 | evidence | packages/testing/test/travel-planner-phase4.test.ts — only the lane head is claimable; packages/session/src/ledger-conformance.ts — claim cases | — |
| DUR-006 | evidence | packages/session/src/ledger-conformance.ts — stale fence cases; packages/platform-cloudflare/test/eviction.test.ts — higher-epoch reclaim after lease expiry | — |
| DUR-007 | evidence | packages/session/src/conformance.ts — atomic idempotent batch append cases | — |
| DUR-008 | evidence | packages/engine/test/agent-runtime.test.ts — incomplete streams never execute Tools; packages/session/test/run-journal.test.ts — response/results batch split | — |
| DUR-010 | evidence | packages/platform-node/test/crash/crash.test.ts — step 1 replays from its record while step 2 executes once; packages/testing/test/durable-tools.test.ts | — |
| DUR-011 | evidence | packages/platform-node/test/crash/crash.test.ts — terminalize rows; packages/session/test/recovery-classifier.test.ts — reserve/append/finalize matrix | — |
| DUR-013 | evidence | packages/session/test/recovery-classifier.test.ts — every decision derives from persisted state; packages/testing/test/durable-runtime.test.ts — recovery rows | — |
| DUR-014 | evidence | packages/session/test/recovery-classifier.test.ts — every nonterminal persisted state classifies to a repair/defer/unknown decision, never silence; packages/testing/test/admin-operations.test.ts — the aging signal | — |
| DEPLOY-001 | evidence | packages/testing/test/travel-planner-phase4.test.ts (DN), packages/platform-cloudflare/test/travel-planner-dc.test.ts (DC) — profiles declare their deployment class | — |
| DEPLOY-002 | evidence | packages/platform-node/test/layers.test.ts, packages/platform-node/test/crash/crash.test.ts — Node host assembly and crash matrix | — |
| DEPLOY-003 | evidence | packages/platform-node/test/layers.test.ts — refuses out-of-bounds configuration with a typed error | — |
| DEPLOY-004 | deferred | no role-specific readiness probe exists on either host | open-source preparation host/deployment surface |
| DEPLOY-005 | evidence | packages/platform-node/test/layers.test.ts — shutdown closes admission and releases ownership for the next host | — |
| DEPLOY-006 | evidence | packages/platform-node/test/crash/crash.test.ts — real process kills; packages/platform-cloudflare/test/eviction.test.ts — forced DO abort matrix | — |
| DEPLOY-007 | evidence | packages/platform-cloudflare/test/limits.test.ts — typed quota/overload refusals before any ledger row | — |
| DEPLOY-008 | evidence | packages/platform-node/test/layers.test.ts — v1 refusal without mutation; packages/storage-sqlite/test/sqlite-ledger.test.ts — reset guidance | — |
| DEPLOY-010 | evidence | packages/platform-cloudflare/test/eviction.test.ts, packages/storage-cloudflare/test/do-ledger.test.ts — bindings supplied as Layers pass the shared durability suites in workerd | — |
| SEC-001 | evidence | packages/session/src/ledger-conformance.ts — admission requires a typed Principal with principal-scoped idempotency | hosts own caller authentication; the P7 threat model states the boundary |
| SEC-003 | evidence | packages/testing/test/security/redteam-idor-sweep.test.ts — every operation reaches the authorization seam at action time under a non-default authorizer; packages/testing/test/admin-operations.test.ts — fail-closed | — |
| SEC-004 | evidence | packages/capabilities/test/subagent.test.ts — grant ceilings deny out-of-grant Tools; packages/testing/test/travel-planner-subagents.test.ts — child authority isolation | — |
| SEC-005 | deferred | the idempotency class and approval requirement are explicit and honored honestly (packages/platform-node/test/crash/crash.test.ts); the P7 review filed no gap, but a unified risk/redaction metadata surface stays open | open-source preparation API review |
| SEC-006 | evidence | packages/sandbox/test/sandbox.test.ts — requests round-trip without embedding raw secret values | — |
| SEC-009 | deferred | reasoning parts flow through Effect AI but no test pins their sensitive-canonical handling; the P7 review filed no finding against the persisted-content path | open-source preparation security pass; live reasoning profiles stay opt-in |
| SEC-010 | evidence | packages/sandbox-local/test/local-sandbox.test.ts — the unisolated adapter rejects unenforceable policy and labels itself development-only | — |
| SEC-012 | evidence | packages/capabilities/test/capabilities.test.ts — hierarchical budget guard; packages/capabilities/test/subagent-reservation.test.ts — ancestor-atomic consumption | — |
| SEC-013 | evidence | packages/capabilities/test/capabilities.test.ts — MCP discovery bounds; packages/sandbox-local/test/local-sandbox.test.ts — output limits; packages/platform-cloudflare/test/limits.test.ts — admission byte bounds | — |
| SEC-014 | evidence | packages/platform-cloudflare/test/code-mode/code-mode-executor.test.ts — generated code in the real isolated executor is denied ambient network and reaches host Tools only through the brokered RPC surface; packages/testing/test/code-mode-e2e.test.ts — the brokered allowlist boundary end to end | — |
| OPS-001 | evidence | packages/testing/test/admin-operations.test.ts — scanObligations ages and severities deterministically under TestClock; hosts own the alert loop per docs/guides/operations.md | — |
| OPS-002 | evidence | packages/testing/test/admin-operations.test.ts — unknown-blocked lanes surface as obligation rows; packages/testing/test/chaos-memory.test.ts — every converged plan asserts a zero-entry obligation report | — |
| OPS-003 | evidence | packages/platform-node/test/restore-drill.test.ts — the executable DN restore drill; docs/guides/operations.md — incident/backup/restore runbooks, the DC PITR half honestly a manual runbook | — |
| TEST-001 | evidence | packages/core/test/core.test.ts, packages/session/test/session.test.ts — round-trip, invalid-input, and limit suites for public schemas | — |
| TEST-003 | evidence | packages/testing/test/chaos-memory.test.ts, packages/testing/test/chaos-sqlite.test.ts — seeded generated fault/abort interleavings converge to verified invariants (CHAOS_SEED replays) | — |
| TEST-005 | evidence | packages/platform-node/test/crash/crash.test.ts — real process kills; packages/platform-cloudflare/test/eviction.test.ts — real DO eviction | — |
| TEST-006 | evidence | packages/session/test/recovery-classifier.test.ts — the crash-matrix rows; packages/storage-sqlite/test/sqlite-ledger.test.ts — failpoint sweeps at every ledger boundary | — |
| TEST-007 | deferred | provider integration is compile-proven (examples/providers/test/profiles.test.ts) and the opt-in live smoke suite exists and gate-skips without credentials (examples/providers/test/live-smoke.test.ts) | live execution is a release-lane action (testing.md §13); no live run gates PRs |
| TEST-008 | evidence | packages/testing/test/security/redteam-supplier-injection.test.ts, packages/testing/test/security/redteam-child-exfiltration.test.ts, packages/testing/test/security/redteam-idor-sweep.test.ts | — |
| TEST-010 | evidence | packages/testing/test/toolchain.test.ts — manifest audits and dependency-boundary checks | — |
| TEST-011 | evidence | scripts/requirements-coverage.ts — this gate; run bun run requirements:coverage | — |
| TEST-012 | process | no durability test in the tree is skipped; skip-gating is a release-process rule (testing.md §13) | release checklist at open-source prep |
| TEST-013 | evidence | packages/testing/test/toolchain.test.ts — catalog, lockfile, and source-checkout agreement | — |
| COMPAT-001 | evidence | packages/engine/test/agent-runtime.test.ts, examples/providers/test/profiles.test.ts — Effect AI primitives used directly in public authoring | — |
| COMPAT-002 | process | normative behavior lives in docs/spec; reference projects are attributed research | spec governance at open-source preparation |
| COMPAT-003 | process | attribution and pinned snapshots are repository facts (repos/ submodules), not runtime behavior | open-source preparation licensing review |
| COMPAT-004 | process | source-research citations live in the native specifications | spec governance |
| COMPAT-005 | process | upstream-first policy is a design rule applied at review time | open-source preparation re-checks |
| COMPAT-006 | evidence | packages/testing/test/toolchain.test.ts — one exact pinned Effect v4 across the workspace | — |
| COMPAT-007 | process | the upgrade procedure is TOOLCHAIN policy; pin agreement is executable (packages/testing/test/toolchain.test.ts) | TEST-013 CI machinery gates each upgrade |
| COMPAT-008 | evidence | packages/storage-sqlite/test/sqlite-ledger.test.ts — typed reset guidance; no migration promise | — |
| COMPAT-009 | process | distribution decisions are explicitly deferred (README status) | open-source preparation |
| COMPAT-010 | evidence | packages/testing/test/toolchain.test.ts — catalog, lockfile, and source-checkout resolve one exact release | — |
Cross-cutting release claims
Effect-native core
Evidence must cover all AUTH, the P1 subset of RUN, the base MODEL contract, Scope finalization, type inference, and COMPAT-001 through COMPAT-005.
Persistent conversation
Evidence must cover STORE replay/checkpoint requirements. It must explicitly state that persistence is not durable accepted work.
Durable Node/SQLite (DN)
Evidence must cover all applicable DUR, SQLite STORE conformance, process-kill tests, Node DEPLOY requirements, SEC, and operational runbooks.
Durable Cloudflare (DC)
Evidence additionally covers Durable Object eviction, alarm retry, SQLite-backed storage, Effect service boundaries around bindings, and Cloudflare fault scenarios.
Change control
- Do not reuse a retired requirement ID.
- Semantic changes update the normative source and relevant ADR.
- Splitting a requirement creates new IDs and retires the old ID with a pointer.
- Pure editorial changes retain the ID.
- Generated coverage tooling fails on duplicate or unknown IDs.