@arnilo/prism 0.0.7 → 0.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/CHANGELOG.md +50 -2
  2. package/README.md +3 -1
  3. package/dist/agent-loops.js +14 -8
  4. package/dist/agents.js +37 -3
  5. package/dist/contracts.d.ts +17 -0
  6. package/dist/index.d.ts +4 -2
  7. package/dist/index.js +3 -2
  8. package/dist/provider-events.d.ts +2 -0
  9. package/dist/provider-events.js +21 -13
  10. package/dist/providers/openai-compatible.js +8 -5
  11. package/dist/providers/transport.d.ts +10 -1
  12. package/dist/providers/transport.js +24 -8
  13. package/dist/run-ledger.d.ts +21 -0
  14. package/dist/run-ledger.js +115 -0
  15. package/dist/tools.js +2 -0
  16. package/docs/a2a.md +61 -42
  17. package/docs/agent-events.md +5 -4
  18. package/docs/agent-loops.md +2 -2
  19. package/docs/agent-session-runtime.md +1 -0
  20. package/docs/browser-automation.md +124 -0
  21. package/docs/coding-agent-tools.md +111 -14
  22. package/docs/coding-security.md +84 -11
  23. package/docs/credential-storage.md +9 -0
  24. package/docs/database-persistence.md +1 -1
  25. package/docs/evaluations.md +38 -4
  26. package/docs/guardrails.md +3 -2
  27. package/docs/host-security.md +29 -4
  28. package/docs/index.md +20 -15
  29. package/docs/mcp-tools.md +29 -5
  30. package/docs/migration.md +104 -0
  31. package/docs/observability.md +26 -14
  32. package/docs/performance.md +54 -0
  33. package/docs/postgres-persistence.md +1 -0
  34. package/docs/provider-conformance.md +1 -1
  35. package/docs/provider-primitives.md +7 -1
  36. package/docs/providers/kimi.md +16 -2
  37. package/docs/providers/opencode-go.md +43 -2
  38. package/docs/release-and-install.md +117 -62
  39. package/docs/resource-loading.md +4 -0
  40. package/docs/review-coverage-2026-07-19-phase-3.md +174 -0
  41. package/docs/review-coverage-2026-07-20-phase-4.md +175 -0
  42. package/docs/review-coverage-2026-07-21-phase-5.md +172 -0
  43. package/docs/run-ledger-conformance.md +1 -0
  44. package/docs/runs-and-usage.md +17 -2
  45. package/docs/sqlite-persistence.md +1 -0
  46. package/docs/structured-output.md +2 -2
  47. package/docs/supervisors.md +2 -2
  48. package/docs/tools.md +5 -1
  49. package/docs/web-tools.md +78 -0
  50. package/docs/workflows.md +2 -0
  51. package/package.json +6 -4
@@ -0,0 +1,174 @@
1
+ # Review coverage — 2026-07-19 Phase 3
2
+
3
+ Working evidence for Plan 070 Task 0. This page freezes Phase 3’s source revision, supported capability boundary, shared-primitive decision, finite-limit targets, and release evidence before public implementation begins.
4
+
5
+ **Evidence frozen:** 2026-07-20. **Prism source:** `6048e82db212303f4f072ff70539830b779f35cf` (`Phase 0.0.7 completed`). **Default test rule:** all default tests use local fakes; a credential-gated live suite is separate.
6
+
7
+ ## Status legend
8
+
9
+ | Status | Meaning |
10
+ | --- | --- |
11
+ | `existing` | Current contract already covers this part. |
12
+ | `extend` | Owning task extends an existing optional package/primitive. |
13
+ | `new-package` | New optional package only; core stays unchanged unless a later two-consumer review proves a generic gap. |
14
+ | `unsupported` | Deliberate 0.0.8 absence. Return a stable explicit error when a declared protocol operation is unavailable. |
15
+
16
+ ## Frozen external references
17
+
18
+ | Surface | Pinned reference | Compatibility decision |
19
+ | --- | --- | --- |
20
+ | OTel GenAI | [`semantic-conventions-genai@c26a2c21d1ee70d5231bd440c7b48d3c94ee506a`](https://github.com/open-telemetry/semantic-conventions-genai/tree/c26a2c21d1ee70d5231bd440c7b48d3c94ee506a/docs/gen-ai) | Development-status spans/metrics/events are adopted only where Prism has source data. Content attributes and evaluation explanations stay off by default. |
21
+ | MCP specification | [2025-11-25](https://modelcontextprotocol.io/specification/2025-11-25) | JSON-RPC over stdio and Streamable HTTP only. Capability is declared only after SDK compatibility tests. |
22
+ | MCP TypeScript SDK | [`@modelcontextprotocol/sdk@1.29.0`](https://github.com/modelcontextprotocol/typescript-sdk/tree/v1.29.0), lock integrity `sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ==` | Current bridge is 1.29.0. Context7 verified client capability declaration, roots handlers, server capability inspection, and Streamable HTTP session construction. Task 4 pins the manifest to the tested SDK version; no untested upgrade. |
23
+ | A2A | [A2A v1.0.0 `173695755607e884aa9acf8ce4feed90e32727a1`](https://github.com/a2aproject/A2A/tree/173695755607e884aa9acf8ce4feed90e32727a1) and [specification](https://a2a-protocol.org/v1.0.0/specification) | JSON-RPC/HTTPS only. Tasks, subscription, rich parts, and optional push hooks are added behind host lifecycle/auth adapters. |
24
+ | Exa | [Search](https://exa.ai/docs/reference/search), [contents retrieval](https://exa.ai/docs/reference/contents-retrieval), retrieved 2026-07-20 | Direct API only, `POST /search` with requested contents. Docs have no immutable revision, so URL plus retrieval date and adapter request/response fixtures are release evidence. |
25
+ | Brave | [Web Search `GET /res/v1/web/search`](https://api-dashboard.search.brave.com/api-reference/web/search/get), [versioning](https://api-dashboard.search.brave.com/documentation/guides/versioning), retrieved 2026-07-20 | Direct API only. Prism limits results to 20, matching documented maximum; token is late-bound `X-Subscription-Token`. |
26
+ | Firecrawl | [v2 introduction](https://docs.firecrawl.dev/api-reference/v2-introduction), [search](https://docs.firecrawl.dev/api-reference/endpoint/search), [scrape](https://docs.firecrawl.dev/api-reference/endpoint/scrape), [extract](https://docs.firecrawl.dev/api-reference/endpoint/extract), retrieved 2026-07-20 | Direct v2 API only: `/v2/search`, `/v2/scrape`, `/v2/extract`. Markdown and returned schema data are untrusted. |
27
+ | Release security | [Dependency review](https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review), [SBOM](https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-software-bill-of-materials), [secret scanning](https://docs.github.com/en/code-security/secret-scanning/introduction/about-secret-scanning), [artifact attestations](https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds) | Prefer GitHub-native gates, immutable action revisions, minimal tokens, and protected-environment canaries. |
28
+
29
+ ### External behavior relied on
30
+
31
+ - GenAI inference and tool spans are `CLIENT` and `INTERNAL` respectively; `gen_ai.evaluation.result` is an event. Inputs, outputs, system instructions, and tool definitions are opt-in content fields, not default telemetry.
32
+ - MCP 1.29.0 clients declare capabilities at construction; undeclared use is rejected by SDK. Roots use `roots/list` plus optional `notifications/roots/list_changed`; server capabilities are inspected after connect.
33
+ - A2A v1.0 defines task get/list/cancel/subscribe, `text`/`raw`/`url`/`data` parts, ordered task updates, authenticated push configuration, and `A2A-Version` negotiation.
34
+ - Brave documents a 400-character/50-word query maximum, `count <= 20`, and `offset <= 9`; Prism never expands those provider maxima.
35
+ - Firecrawl documents `search.limit <= 100`, `query <= 500` characters and bearer authentication. Prism uses tighter portable defaults and validates returned Markdown/JSON itself.
36
+
37
+ ## Capability traceability matrix
38
+
39
+ | Roadmap criterion | Current surface | Minimum 0.0.8 gap | Owner | Required proof | Docs | Release gate |
40
+ | --- | --- | --- | --- | --- | --- | --- |
41
+ | Parent OTel agent/provider/tool hierarchy and context | Event-derived independent `prism.*` spans in `packages/observability-opentelemetry` | Active parent/context lifecycle; semantic map; trace reference | 1 | parent/error/detach/exporter-failure matrix | `observability.md`, `agent-events.md` | offline OTel conformance |
42
+ | Metadata-safe GenAI/MCP telemetry and low-cardinality metrics | `AgentEvent`, redactor, safe counters | Convention mapping and label allow-list | 1 | secret/content/ID label-negative tests | `observability.md`, `host-security.md` | tarball/secret scan |
43
+ | Final-result/trace grading, judges, pairwise, thresholds | `@arnilo/prism-evals` result scorers/datasets/experiments | Bounded owner-scoped trace resolver, optional judge, report/gate | 2 | fake judge, trace cap, deterministic threshold failure | `evaluations.md`, `runs-and-usage.md` | offline eval gate |
44
+ | Batched ledger, snapshot cache, benchmarks | Serialized write-through `RunLedger`; repeated session rebuild | Optional flush/ack batch wrapper and leaf cache | 3 | order/crash/terminal flush/cache-read count benchmarks | `runs-and-usage.md`, `performance.md`, persistence pages | offline persistence + published bench |
45
+ | MCP tools/resources/prompts/roots/sampling/elicitation/notifications | Tool bridge, tool-list notification, server tools, stateless Streamable HTTP | SDK-pinned capability facades/session handling | 4 | fake SDK/server capability, session, origin, overflow matrix | `mcp-tools.md`, `resource-loading.md` | offline MCP conformance |
46
+ | Host-owned MCP OAuth/auth | `resolveAuthInfo`, authorizer, exact-origin pinned client transport | Exact request/session/ownership binding and host OAuth callback | 4 | wrong origin/session/owner/token-redaction cases | `mcp-tools.md`, `credential-storage.md`, `host-security.md` | secret scan + MCP conformance |
47
+ | A2A durable task/cancel/reconnect/rich parts/push | Text-only immediate session execution, bounded SSE, card verification | Host task lifecycle adapter, part mapping, bounded replay/push | 5 | fake lifecycle/card/task/reconnect/push matrix | `a2a.md`, `agent-session-runtime.md`, `workflows.md` | offline A2A conformance |
48
+ | Narrow web search/fetch/extract package | Tool dispatch, credentials, media SSRF bounds, bounded response reader | Optional direct-adapter package and normalized public result types | 6 | fake Brave/Exa/Firecrawl normalization/overflow/security matrix | `web-tools.md`, `tools.md` | pack/install + offline conformance |
49
+ | Citation identity and schema-validated untrusted external results | `ToolResult`, `ContentBlock`, resource/media bounds | Package-local citation/document/extraction contracts | 6 | citation/schema/prompt-injection fixtures | `web-tools.md`, `host-security.md` | offline web conformance |
50
+ | Official Exa/Firecrawl MCP prototype guidance only | Existing hardened MCP bridge | Documentation-only prototype boundary | 4, 6 | docs assertion: no generic remote passthrough | `mcp-tools.md`, `web-tools.md` | docs review |
51
+ | SAST/dependency/secret/SBOM/license/attestation/updates/live canaries | `release.yml` readiness, pack, provenance publish | Native GitHub security workflows and protected live jobs | 7 | workflow policy/negative secret/license/SBOM fixtures | `release-and-install.md`, `host-security.md` | required PR/release jobs |
52
+ | Reusable conformance and bounded performance evidence | Provider/session/tool/ledger helpers and 0.0.7 benchmark tables | Package-local protocol/web helpers plus Phase 3 benchmark script | 1–7 | each fake suite and dated benchmark output | `performance.md` | `sdk:ready` + documented live prerequisites |
53
+
54
+ ## Primitive and caller inventory
55
+
56
+ | Primitive | Existing contract and callers | Phase 3 disposition |
57
+ | --- | --- | --- |
58
+ | `AgentEvent` | `src/agents.ts` emits provider/tool/guardrail/limit events; subscribers, `RunLedger`, OTel adapter consume them | Reuse as telemetry source. Task 1 adds parent/context only; no second event bus. |
59
+ | `RunLedger` / `RunLedgerRecord` | Four ordered append methods; `RuntimeAgentSession.ledgerChain` serializes appends; SQLite/PostgreSQL implement it | Task 3 may add one optional wrapper with flush/ack. Default remains write-through; no persistence schema. |
60
+ | `ProductionPersistenceStore` | Cursor/ownership-scoped `queryRuns`, `queryEvents`, `queryToolCalls`, `queryUsage`; optional checkpoints/leases/feedback | Task 2 reads a bounded host-selected trace. Task 5 adapts host lifecycle/checkpoints. No generic task table. |
61
+ | `RunLimits` / `RunLimitTracker` | Runtime/provider/tool limits charge before provider/tool work | Reuse for run work. Package-specific external operations get package-local finite limits until a second equal consumer exists. |
62
+ | Guardrails/redaction/permission/trust | `runGuardrails`, `dispatchToolCall`, `redact*`, `assertPermission`, `assertTrusted` | All tool/protocol/web outputs route through existing dispatch/redaction. No protocol-specific security bypass. |
63
+ | Durable agent/workflow state | `CheckpointStore`, `AgentRunLifecycle`, durable agent run state, workflow status/cancel | Task 5 projects host-selected lifecycle into A2A. No new worker/queue/runtime. |
64
+ | `ResourceLoader` | `loadTextResource`, `loadJsonResource`, `loadBinaryResource`; permission/trust context | Task 4 maps resources only through a narrow adapter; Task 6 does not pretend remote web fetch is a generic resource loader. |
65
+ | `CredentialResolver` | `resolveCredentialValue`, explicit/chained/env resolvers, OAuth store | Tasks 4–6 resolve at adapter request edge. Credentials never enter tool schemas/results/telemetry. |
66
+ | Media URL/SSRF primitives | `assertSsrfAllowedUrl`, address-pinned `requestUrl`, media MIME/byte/time bounds | Reuse policy/validation semantics. Generalize pinned transport only if Task 6 proves identical requirements with media and MCP; otherwise package-local provider fetch. |
67
+ | Provider transport | `readSseEvents`, `readBoundedResponseText`, bounded JSON argument parsing | Reuse bounded response/redaction semantics where shape fits. Do not force non-SSE vendor APIs through provider types. |
68
+ | Tool dispatch | `ToolDefinition`, registry, schema validation, permissions, guardrails, ledger, limit tracker | Web tools and mapped MCP tools use this path; models never choose adapter/provider credentials. |
69
+ | OTel adapter | Optional event projection with in-memory fixture and exporter-error isolation | Extend in place in Task 1; OTel API remains optional-package only. |
70
+ | Evals package | Immutable dataset, function scorer, bounded experiment pool, package-local store | Extend in place in Task 2; judge stays host callback, not core/provider dependency. |
71
+ | MCP package | Official SDK bridge, bounded tool discovery/result conversion, DNS-pinned Streamable HTTP, authorized server helper | Extend in place in Task 4; capability facades remain package-local. |
72
+ | Supervisor A2A package | Card/JWS, bounded JSON-RPC/SSE, exact-origin client | Extend in place in Task 5; task/push adapters remain package-local. |
73
+
74
+ ### Core primitive decision
75
+
76
+ No new core primitive is authorized by Task 0. The only conditional candidates are:
77
+
78
+ 1. **Trace-context carrier:** Task 1 may add one only if OTel, supervisor delegation, and another core consumer require the same dependency-free propagation shape.
79
+ 2. **Flushable ledger capability:** Task 3 may add one only if one adapter wraps memory, SQLite, PostgreSQL, and host ledgers without changing `RunLedger` ordering.
80
+ 3. **Pinned bounded HTTP request:** Task 6 may extract one only if media and web adapters use identical DNS-pinning, redirect, byte, abort, and error-redaction semantics.
81
+
82
+ Otherwise code stays in its optional package. One-consumer interfaces, vendor types, protocol vocabularies, and task queues are rejected.
83
+
84
+ ## Frozen capability boundary
85
+
86
+ | Surface | Supported in 0.0.8 | Explicitly unsupported / deferred |
87
+ | --- | --- | --- |
88
+ | Telemetry | Optional OTel API adapter; agent/inference/tool/guardrail/delegation hierarchy; safe traces/metrics/evaluation events | Exporter registration, hosted backend, default content capture, per-delta spans, ID/content metric labels |
89
+ | Evaluations | Function scorers, bounded trace target, host-supplied judge, pairwise comparison, datasets, reports, threshold assertion | Mandatory LLM/provider, evaluation service/database, automatic production grading |
90
+ | MCP | Pinned-SDK tools/resources/prompts/roots/sampling/elicitation/notifications and Streamable HTTP only when SDK test proves each | Server discovery, arbitrary remote capability proxy, raw SDK callback/tool exposure, automatic OAuth/token forwarding |
91
+ | A2A | v1.0 JSON-RPC/HTTPS card/task/status/list/cancel/subscribe, rich parts, bounded replay, optional host push hook | gRPC, REST/HTTP+JSON binding, endpoint discovery, JWK fetching, second durable engine |
92
+ | Web tools | Host-selected Brave or Exa discovery; Firecrawl Markdown/schema extraction; direct native fetch adapters | Browser automation, vendor SDK dependency, model-selected provider, generic web/MCP passthrough |
93
+ | Release | Native CI security gates and scheduled/manual protected canaries | Secrets in PR/default jobs, public-network default tests, hosted security service |
94
+
95
+ ## Frozen limits and charging points
96
+
97
+ Values in this table are target defaults/hard caps for later tasks, not active 0.0.7 APIs. Every count/byte/time/concurrency check happens before retaining data or starting the next request. Existing stricter package limits remain authoritative until changed with tests.
98
+
99
+ | Surface | Default / hard cap | Charge before | Owner |
100
+ | --- | --- | --- | --- |
101
+ | OTel active spans | one agent span per run; provider/tool/guardrail/delegation only from existing bounded run work | `startSpan`; no span for deltas | 1 |
102
+ | OTel content buffering | `0 / 0` by default | copying any prompt/content | 1 |
103
+ | Eval trace pages | `20 / 100` per record kind | next persistence page | 2 |
104
+ | Eval trace records | `1,000 / 5,000` events, tool calls, and usage records each | append snapshot item | 2 |
105
+ | Eval judge request/response | `256 KiB / 1 MiB` each | serialization/body retention | 2 |
106
+ | Eval judge attempts/time | `1 / 3`; `60 s / 30 min` | request attempt/timer | 2 |
107
+ | Eval worker concurrency | `1 / 32` (existing) | start worker | 2 |
108
+ | Ledger batch entries/bytes | `128 / 4,096`; `512 KiB / 16 MiB` | enqueue | 3 |
109
+ | Ledger batch delay/in-flight flushes | `25 ms / 1 s`; `1 / 8` | timer/flush dispatch | 3 |
110
+ | Snapshot cache | one current leaf snapshot per active session/run; no cross-session cache | store/reuse snapshot | 3 |
111
+ | MCP existing tool bridge | existing `20/100` pages, `500/5,000` tools, `4 MiB/16 MiB` aggregate schemas, `10 MB/16 MiB` result | page/schema/result retention | 4 |
112
+ | MCP resources/prompts | `20 / 100` pages; `500 / 5,000` items; `1 MiB / 8 MiB` item content | page/item conversion | 4 |
113
+ | MCP roots/sampling/elicitation | `32 / 128` roots; `32 / 128` messages; `64 KiB / 1 MiB` arguments/schema | callback/request dispatch | 4 |
114
+ | MCP HTTP sessions/replay | `128 / 1,024` active sessions; `1,024 / 10,000` replay events; `64 KiB / 1 MiB` event | session/replay allocation | 4 |
115
+ | A2A existing request/response/stream | `64 KiB/1 MiB` request/response; `64 KiB/1 MiB` event; `10 MiB/64 MiB` stream; `10k/100k` events | body/frame/event retention | 5 |
116
+ | A2A task pages/parts/artifacts | `100 / 1,000` tasks; `32 / 256` parts per message/artifact; `1 MiB / 8 MiB` raw/data part; `8 MiB / 64 MiB` aggregate artifacts | parse/decode/store/replay | 5 |
117
+ | A2A push | `32 / 256` registrations; `3 / 10` attempts; `30 s / 5 min` delivery | persist/deliver/retry | 5 |
118
+ | Web query/results/URLs | `4 KiB / 16 KiB`; `10 / 20` results; `5 / 20` URLs | request construction | 6 |
119
+ | Web provider request/output | `256 KiB / 1 MiB` request; `2 MiB / 16 MiB` response; `1 MiB / 8 MiB` Markdown; `256 KiB / 1 MiB` extracted JSON | request/body/output retention | 6 |
120
+ | Web schema/concurrency/time | `64 KiB / 256 KiB` schema; `4 / 16` active calls; `60 s / 30 min`; `2 / 4` retries | schema compile/call/retry | 6 |
121
+ | CI/live canaries | default suite `0` remote calls; protected live job one bounded scenario/provider | credential resolution/network call | 7 |
122
+
123
+ ### Network and credential rules
124
+
125
+ 1. Provider API origins are exact allow-lists and provider API redirects are rejected. Native `fetch` uses `redirect: "error"` or equivalent pinned transport.
126
+ 2. A fetched target URL is absolute HTTP(S), has no userinfo, and passes the host’s public/private policy before sending it to Firecrawl. Firecrawl-side redirects are provider behavior; Prism does not claim DNS pinning after handing a URL to Firecrawl. Hosts that need that guarantee use a controlled fetch adapter instead.
127
+ 3. MCP client requests pin a validated DNS address and reject redirects today; Task 4 extends session/auth behavior without weakening that boundary.
128
+ 4. A2A and MCP authorization run on every request and bind exact origin, session, and ownership. Missing/foreign resources/tasks resolve as authorized-not-found, not disclosure.
129
+ 5. Credentials are resolved immediately before adapter I/O, redacted in errors before ledger/export, excluded from tool inputs/outputs/telemetry, and never forwarded automatically between MCP/A2A/provider/web surfaces.
130
+ 6. Search snippets, Markdown, HTML, extracted JSON, A2A artifacts, MCP resources/prompts, and remote protocol errors are untrusted data. They cannot modify system instructions, tools, permissions, credential selection, or provider routing.
131
+
132
+ ## Web normalization and external-operation ownership
133
+
134
+ | Tool / adapter | Host-selected request | Normalized public output | Credential owner and redaction point |
135
+ | --- | --- | --- | --- |
136
+ | `web_search` / Exa | `POST https://api.exa.ai/search`; query plus explicitly requested bounded `contents` only | `title`, canonical `url`, bounded `snippet`/`highlights`, provider result ID, publication/retrieval time, provider/cost/rate metadata, citation identity | Adapter resolves `{ provider: "exa", name: "api_key" }` at request edge; redact key from headers, response/error, telemetry, and `ToolResult`. |
137
+ | `web_search` / Brave | `GET https://api.search.brave.com/res/v1/web/search`; query/count/offset only | Same normalized search result; source fields missing from Brave stay absent, never guessed | Adapter resolves `{ provider: "brave", name: "subscription_token" }` at request edge; redact `X-Subscription-Token` and all error echoes. |
138
+ | `web_fetch` / Firecrawl | `POST https://api.firecrawl.dev/v2/scrape`; one prevalidated public URL and Markdown format | `url`, canonical/source URL, bounded Markdown, selected metadata, retrieval time, provider/cost/rate metadata, `untrusted: true`, citation identity | Adapter resolves `{ provider: "firecrawl", name: "api_key" }` at request edge; redact bearer header/body/error echoes. |
139
+ | `web_extract` / Firecrawl | `POST https://api.firecrawl.dev/v2/extract`; bounded URL list plus host-supplied JSON Schema | Same document attribution plus schema-validated bounded JSON value and `untrusted: true` | Same Firecrawl resolver/redaction rule; schema/value never influence tool permissions or system instructions. |
140
+
141
+ `citationId` is deterministic: `web:<provider>:<providerResultId>` when provider returns a stable result ID, otherwise `web:<provider>:sha256(<canonicalUrl>)`. `canonicalUrl` removes fragment and normalizes only URL syntax; Prism does not follow target redirects to manufacture identity. Provider-specific fields remain under bounded metadata and never replace normalized fields.
142
+
143
+ | External operation | Authorization/credential owner | Required boundary |
144
+ | --- | --- | --- |
145
+ | OTel export | Host exporter SDK; Prism adapter receives tracer/meter only | Exporter failure isolated; Prism receives no exporter credential. |
146
+ | Model judge | Host-supplied judge callback | Judge receives bounded redacted evaluation target; no resolver/tools/workspace. |
147
+ | MCP HTTP/OAuth | Host auth resolver; Task 4 session binding | Every request binds exact origin/session/ownership; no token forwarding to model/tool content. |
148
+ | A2A invoke/card/push | Host authorizer/client auth/push delivery callback | Every task/push action is owner-scoped; card keys are explicitly pinned. |
149
+ | Web adapters | Host `CredentialResolver` or explicit callback | Exact provider API origin, no provider API redirects, late credential resolution. |
150
+ | Live canary | Protected CI environment only | Least-privilege key, redacted aggregate report, no PR/default-job secret. |
151
+
152
+ ## Required test evidence by task
153
+
154
+ | Task | Network-free evidence | Restricted live evidence |
155
+ | --- | --- | --- |
156
+ | 1 | Parent graph, context, cleanup, semantic attributes, no-content/no-ID-label, exporter isolation | Host OTel exporter smoke only if configured |
157
+ | 2 | Fake trace reader/judge, redaction/cap/threshold/pairwise deterministic reports | Explicit host judge/model smoke |
158
+ | 3 | Fake ledger order/flush/crash/cache invalidation; reproducible local benchmark | PostgreSQL benchmark when service exists |
159
+ | 4 | Fake SDK/server capabilities, roots/resources/prompts/sampling/elicitation, sessions, auth/origin/SSRF/overflow | Configured MCP endpoint smoke |
160
+ | 5 | Fake lifecycle/card/push, rich parts, cancel/reconnect/replay/owner isolation | Configured A2A endpoint smoke |
161
+ | 6 | Fake Brave/Exa/Firecrawl normalization, schema, redirect/SSRF, credential/prompt-injection fixtures | Protected least-privilege Exa/Brave/Firecrawl smoke |
162
+ | 7 | Workflow policy, SBOM/license/attestation, secret-negative and skipped-canary tests | Scheduled/manual protected credentials only |
163
+
164
+ ## Release evidence checklist
165
+
166
+ - `npm run sdk:ready`, Node 20/current import check, every workspace pack, packed offline consumer, `npm audit --audit-level=high`, tarball deny-list/secret check, and `git diff --check`.
167
+ - Focused OTel/eval/ledger/MCP/A2A/web fake-server conformance suites pass without public network.
168
+ - SAST, dependency review, secret scanning, SPDX SBOM/license policy, and artifact attestation jobs pass with pinned actions/minimal permissions.
169
+ - Protected live canaries either pass with least-privilege credentials or are recorded as an explicit release-host prerequisite; skipped canaries never make the default suite appear live-tested.
170
+ - Benchmarks publish machine/runtime, workload, p50/p95, throughput, memory, disk, cost metadata when supplied, backpressure observations, and no portability claim.
171
+
172
+ ## Current exclusions
173
+
174
+ No browser, coding, Office, SaaS connector, hosted observability, generic proxy, provider SDK, remote discovery, automatic token forwarding, background task worker, or new core persistence schema is authorized by this phase. Those belong to later roadmap phases or require a new evidence review.
@@ -0,0 +1,175 @@
1
+ # Review coverage — 2026-07-20 Phase 4
2
+
3
+ Working evidence for Plan 072 Task 0. This page freezes revised Phase 4 scope, source/external revisions, primitive ownership, finite-limit targets, threats, tests, docs, and release gates before implementation.
4
+
5
+ **Evidence frozen:** 2026-07-20. **Prism source:** `0d109989b4892e3fe4378ab782044ceadc460277` (`Release 0.0.8`). **Release target:** 0.0.9. **Default test rule:** local fakes and fixtures only; Docker/Playwright execution is a separate protected gate.
6
+
7
+ ## Revised product decision
8
+
9
+ 0.0.9 contains production coding and browser execution only. Office document execution is host-selected skill/instruction work outside Prism packaging. Prism will not ship `@arnilo/prism-work-tools/officecli`, an OfficeCLI binary/SDK/wrapper, Office-specific runtime contracts, generic Office MCP/CLI passthrough, Office tests/docs, or an Office release gate. This is a removed product criterion, not deferred 0.0.9 implementation.
10
+
11
+ Cloud Microsoft 365 and Google Workspace connectors remain a separate later roadmap decision. They cannot depend on or imply local OfficeCLI execution.
12
+
13
+ ## Status legend
14
+
15
+ | Status | Meaning |
16
+ | --- | --- |
17
+ | `existing` | Current public contract covers the requirement. |
18
+ | `extend` | Owning task extends an existing optional package/contract. |
19
+ | `new-package` | New optional package; core remains dependency-free. |
20
+ | `compose` | Existing public primitives are sufficient; only example/docs or package-local glue may be needed. |
21
+ | `removed` | Deliberately outside Prism product/release scope. |
22
+
23
+ ## Frozen external revisions
24
+
25
+ | Surface | Frozen reference | Compatibility decision |
26
+ | --- | --- | --- |
27
+ | Prism | [`0d109989b4892e3fe4378ab782044ceadc460277`](../plans/072-release-0-0-9-production-coding-and-browser-execution.md) | All primitive/caller claims below were checked against the 0.0.8 release tree. |
28
+ | Node.js | Local reference `v24.18.0`; Prism release support remains Node 20 and current | Use `node:child_process`, `node:fs`, streams, `AbortSignal`, `URL`, crypto hashes, and path APIs only. Node 20/current tests own compatibility. |
29
+ | Playwright | [`playwright-core@1.61.0`](https://github.com/microsoft/playwright/tree/v1.61.0), npm integrity `sha512-caX7TrY3Ml6egyDX0WUcTHDxodl/b51y5wJOdCEA36QviK/s2g081hvmGs8eaE3DWb6NYZQ6BjO/QkNRPenoPA==` | Task 5 tests this exact compatibility line. Browser binary remains host supplied; package install performs no browser download. Only documented Browser/BrowserContext/Page/Locator/Download APIs are allowed. |
30
+ | Playwright context/locator/snapshot/network docs | [BrowserContext](https://playwright.dev/docs/api/class-browsercontext), [Locator](https://playwright.dev/docs/api/class-locator), [locators](https://playwright.dev/docs/locators), [ARIA snapshots](https://playwright.dev/docs/aria-snapshots), [network](https://playwright.dev/docs/network), retrieved 2026-07-20 | Non-persistent contexts; role/label/test-id and snapshot refs before CSS; `ariaSnapshot({ mode: "ai" })`; service workers blocked when routing must observe requests. Request routing is defense in depth, not DNS containment. |
31
+ | Docker CLI/Engine | Local reference client/server `29.6.1`; [container run](https://docs.docker.com/reference/cli/docker/container/run/), [resource constraints](https://docs.docker.com/engine/containers/run/), [default seccomp](https://docs.docker.com/engine/security/seccomp/), retrieved 2026-07-20 | Task 1 uses an absolute host-selected Docker executable, digest-pinned preloaded image, `--pull=never`, typed arguments, read-only root/source, finite tmpfs workspace, non-root user, dropped capabilities, default seccomp, no-new-privileges, and network none. Exact supported-version floor follows tested flag preflight; 29.6.1 is reference evidence. |
32
+ | Git | Local reference `git version 2.55.0`; [official manuals](https://git-scm.com/docs), retrieved 2026-07-20 | Task 3 uses porcelain/plumbing argument arrays: `status --porcelain=v2 -z`, `diff --no-ext-diff --no-textconv`, `check-ref-format`, `worktree`, `apply --check`, `commit`, and `bundle`. Exact supported-version floor follows fixture/live conformance; 2.55.0 is reference evidence. |
33
+
34
+ No Office executable, SDK, repository, schema, or version is pinned because Office execution is outside the release boundary.
35
+
36
+ ## Capability traceability matrix
37
+
38
+ | Revised roadmap criterion | Current surface | Minimum 0.0.9 gap | Status / owner | Required proof | Docs | Release gate |
39
+ | --- | --- | --- | --- | --- | --- | --- |
40
+ | Disposable read-only-base sandbox; writable bounded workspace; deny-default network; CPU/memory/PID/disk/time/secret/termination controls | `SandboxAdapter.exec(command)` maps only shell operations; coding tools have local operation seams | Typed process/lifecycle/import/export Docker reference with real limits and cleanup | `extend` / Task 1 | fake CLI matrix plus protected filesystem/network/process/resource escape tests | `coding-security.md`, `host-security.md`, `performance.md` | protected Docker gate + offline adapter tests |
41
+ | Native bounded repository list/search | `createReadOnlyTools()` contains only `read`; read already has path, byte, line, image, abort bounds | Streaming stdlib list/search and sandbox operation wiring | `extend` / Task 2 | traversal/search ordering, symlink, binary, regex, byte/time/abort tests | `coding-agent-tools.md`, `performance.md` | offline coding conformance |
42
+ | Structured Git status/diff/branch/worktree/patch/commit | Shell can invoke Git but has coarse operation policy | Typed arguments, bounded parsers/results, safe repo config, rollback, artifacts | `extend` / Task 3 | hostile path/ref/config/hook, dirty-tree, rollback, worktree tests | `coding-agent-tools.md`, `coding-security.md` | offline Git conformance + protected sandbox |
43
+ | Named test/lint/typecheck/security commands and diagnostics | Shell operation backend, output accumulator, execution policy, progress events | Host-declared name → fixed executable/args map; bounded summaries/artifacts | `extend` / Task 3 | unknown name, fixed args/env, timeout/output/secret tests | `coding-agent-tools.md`, `performance.md` | offline command conformance |
44
+ | Durable plans/todos/checkpoints/approvals/background branches/restart | Workspace files; `CheckpointStore`; workflow state/suspend/resume/coordinator/leases/events | Reference composition and immutable workspace artifact metadata; no second runtime | `compose` / Task 4 | restart/revision/owner/hash/lease/cancel/stale-worker matrix | `workflows.md`, `coding-agent-tools.md` | offline durable workflow journey |
45
+ | Host-owned PR creation | No repository host API; workflow results can return bounded data | PR handoff metadata + patch/bundle reference only | `extend` / Task 3, composed by Task 4 | deterministic bounded handoff; prove no push/network/credential use | `coding-agent-tools.md`, `workflows.md` | offline handoff conformance |
46
+ | Four Playwright browser tools with one run-owned isolated context and ordered actions | Core tool dispatch/exclusive flag, execution policy, guardrails, run identity; no browser package | Optional package and finite context/page/snapshot/action manager | `new-package` / Task 5 | fake API lifecycle, isolation, stale-ref, ordered-action, cleanup tests | `browser-automation.md`, `tools.md` | package/pack/install + protected Playwright |
47
+ | Browser egress/side-effect/artifact policy | Execution/permission policy, guardrails, path containment, `ImageContent`, redaction | Context routing + host firewall/proxy requirement; upload/download/screenshot quarantine | `new-package` / Task 6 | redirects/private/DNS/service-worker, approval, artifact, secret tests | `browser-automation.md`, `host-security.md` | protected egress/browser gate |
48
+ | Adversarial coding/browser evals and reproducible benchmarks | `@arnilo/prism-evals`, network-free fixtures, current benchmark/live workflow patterns | Package datasets, one 0.0.9 benchmark, protected real gate | `extend` / Task 7 | deterministic score thresholds and benchmark schema/cleanup | `evaluations.md`, `performance.md` | default eval gate + protected live gate |
49
+ | 0.0.9 package/docs/release evidence | 31-package 0.0.8 graph and deterministic release pipeline | Add at most browser package; version/docs/pack/install/audit evidence | `extend` / Task 8 | `sdk:ready`, Node 20/current, pack/install, supply chain, release dry-run | `release-and-install.md`, `migration.md` | complete 0.0.9 release gate |
50
+ | OfficeCLI/Office package/runtime/tests/docs/release criterion | Roadmap-only proposal; no current package | None | `removed` / product decision | docs assertion: absent from Phase 4/package graph/release checklist | this page, `roadmap.md` | explicit absence check |
51
+
52
+ ## Primitive and caller inventory
53
+
54
+ | Primitive | Existing contract/callers at frozen revision | Phase 4 disposition |
55
+ | --- | --- | --- |
56
+ | `ToolDefinition` / tool dispatch | `src/contracts.ts` defines name/schema/static `exclusive`/execute; `src/tools.ts` applies registry filter, trust, permission, validation, `beforeExecute`, guardrails, run-limit charge, events, ledger, and redaction. Coding, web, MCP, workflows, providers, examples, and tests consume it. | Reuse for list/search/Git/check/browser tools. Browser tools set static `exclusive: true` and also queue per run. No browser-specific dispatch runtime. |
57
+ | `ExecutionPolicy` | String-extensible `ExecutionAction.kind`, operation/paths/command/risk/metadata and allow/modify/deny check in `src/execution-policy.ts`; coding tools enforce immediately before operations; workflow tool nodes can define actions and durable approval. | Reuse. Add package-local `git`, `check`, and `browser` action kinds/metadata; no core enum or approval engine. Policy is authorization, not containment. |
58
+ | `PermissionPolicy` / trust | `src/security.ts`; `dispatchToolCall` and resource loading check host policies before execution/load. MCP/supervisor/extensions also consume permission/trust contracts. | Reuse at dispatch/resource boundaries. Do not duplicate permission logic in sandbox/browser managers. |
59
+ | Guardrails / redaction | `src/tools.ts` runs tool-input/output guardrails and redacts results/events/ledger; `src/agents.ts` handles agent/provider stages. | Reuse for untrusted repository/browser content. Secrets remain host-known redactor inputs; sandbox/browser internals must redact before errors/artifact metadata too. |
60
+ | `RunLimits` / `RunLimitTracker` | Defaults/hard caps in `src/run-limits.ts`; runtime charges turns, provider attempts, tool rounds/calls, wall time, request/response bytes, tokens, cost. MCP/workflow types accept limits. | Reuse for total agent work. Package-local external-resource limits below charge before work/retention; no expansion of `RunLimits` until another domain needs identical counters. |
61
+ | `CheckpointStore` / leases | Generic owner-scoped versioned CAS/fencing contract; memory, SQLite, PostgreSQL, agent lifecycle/state, workflows, and schedules consume it. | Reuse for durable workflow metadata. Store artifact URI/hash/bytes and summaries, never repository/browser state blobs or credentials. |
62
+ | Workflow state/suspend/coordinator | Workflow revision hash, bounded state/history/checkpoints, tool approval suspension, background enqueue, lease renewal/fencing/cancel, finite coordinator concurrency/pages. | Compose coding plan/todo files and branch artifact references. No `CodingRun`, todo DB, scheduler, or second workflow engine. |
63
+ | Coding operation backends | `ReadOperations`, `WriteOperations`, `EditOperations`, `BashOperations`; local defaults; `SandboxAdapter` currently maps shell only. | Task 1 extends coding-security with typed `execFile`/lifecycle; Task 2 wires bounded repository operations. Preserve current custom/local contracts unless tests prove one shared addition is required. |
64
+ | `withFileMutationQueue` | Process-wide map keyed by resolved realpath; used by write/edit; serializes same real path and releases on error. | Reuse for local same-path mutation. Git disposable worktree/patch transaction owns multi-file rollback; do not turn queue into transaction manager. |
65
+ | `ResourceLoader` | Optional load/list with abort, trust, permission; bounded binary helper exists; inputs/contributions/extensions consume it. | May rehydrate a host-owned immutable artifact reference. It is not an artifact store, workspace transport, browser downloader, or network-containment bypass. Task 1/3 use narrow host callbacks for export. |
66
+ | `ImageContent` / media bounds | Core content contract; coding read returns bounded images and can require host transform. | Reuse for bounded screenshots. Browser package enforces pixel/encoded-byte caps before returning content; no new image type. |
67
+ | Agent/workflow events | Tool progress/start/finish/error/block, guardrail/limit events, workflow ordered events and finite buffers. | Reuse for diagnostics/progress/cleanup evidence. No coding/browser event bus or hook registry. |
68
+ | `@arnilo/prism-evals` | Immutable datasets, bounded experiments/concurrency, function scorers, trace/judge/comparison/report limits. | Extend with package-local coding/browser datasets/scorers only; no mandatory model/network/service. |
69
+ | `SandboxAdapter` | One `exec({ command, cwd, env, onData, signal, timeout })` contract and `createSandboxBashOperations`; no lifecycle, typed arguments, transfer, status, or containment implementation. | Extend in coding-security Task 1. Generic core sandbox contract is not authorized. |
70
+
71
+ ### Primitive decision
72
+
73
+ No new core primitive is authorized by Task 0.
74
+
75
+ Authorized package-local work:
76
+
77
+ 1. `@arnilo/prism-coding-security`: minimal typed executable, disposable lifecycle, import/export, status, and cleanup contracts implemented by the real Docker reference. Preserve current `SandboxAdapter.exec` compatibility.
78
+ 2. `@arnilo/prism-coding-agent`: repository/Git/check/artifact types and operation overrides only where local and sandbox implementations both consume them.
79
+ 3. `@arnilo/prism-browser`: run/context/action/artifact manager and Playwright types stay entirely optional-package local.
80
+
81
+ A shared primitive can be promoted later only with two concrete non-test consumers and migration/conformance evidence. One-consumer interfaces, artifact databases, browser planners, Git libraries, proxy/firewall implementations, Office types, and remote worker/control-plane contracts are rejected.
82
+
83
+ ## Frozen capability boundary
84
+
85
+ | Surface | Supported in 0.0.9 | Explicitly unsupported |
86
+ | --- | --- | --- |
87
+ | Sandbox | Host-invoked Docker CLI reference; digest-pinned preloaded image; disposable container; finite tmpfs workspace; typed execution; bounded import/export; deterministic cleanup; default network none | Docker daemon provisioning, image build/pull/update, Kubernetes/remote scheduler, bundled image/proxy, host Docker-socket exposure, claim that command policy equals containment |
88
+ | Coding | Native list/literal-or-bounded-regex search; structured Git/status/diff/branch/worktree/patch/commit; named fixed checks; workspace plan/todos; rollback/discard; background workflow composition; PR handoff | Language server/index/watch service, arbitrary model-created commands, implicit repo hook execution, GitHub/GitLab authentication/push/PR client, second coding runtime |
89
+ | Browser | Four model tools; host-supplied Playwright 1.61-compatible browser; non-persistent context; ARIA snapshot/refs and user-facing locators; bounded screenshots/uploads/downloads/popups/dialogs | `evaluate`, arbitrary JavaScript/CSS/XPath, CDP/devtools, extensions, persistent/local profiles, browser binary download, generic MCP proxy, visual/coordinate planner |
90
+ | Network | Network none by default; real browsing only behind host-contained proxy/firewall plus Playwright route checks | DNS rebinding protection by URL regex/routing alone; in-package firewall/proxy; public-network default tests |
91
+ | Artifacts | Bounded host callbacks/references/hashes; download quarantine; screenshot `ImageContent`; patch/bundle/PR handoff | Artifact SaaS/database, unrestricted host paths, checkpointing credentials/storage state/full workspace, automatic upload/push |
92
+ | Office | Host-selected skills/instructions may guide external user-owned work | Any Prism Office executable, SDK, wrapper, package, protocol, tool, test, doc page, binary, or release gate |
93
+
94
+ ## Frozen finite limits and charging points
95
+
96
+ Values are target defaults / hard caps for Tasks 1–7, not active 0.0.8 APIs. Existing stricter limits remain authoritative. Validate host configuration before starting work; charge count/declared bytes before each operation and stream-count actual bytes before retention/export.
97
+
98
+ ### Sandbox and workspace
99
+
100
+ | Resource | Default / hard cap | Charge/check point | Failure and cleanup owner |
101
+ | --- | --- | --- | --- |
102
+ | Startup / run wall / idle | 30 s / 120 s; 20 min / 30 min; 5 min / 15 min | Before create; absolute deadline starts before Docker invocation; idle resets only on accepted operation | Task 1 stops, then kills and removes recorded container |
103
+ | CPU / memory+swap / PIDs | 2 / 8 CPUs; 2 GiB / 16 GiB; swap equal to memory; 256 / 1,024 PIDs | Validated before `docker run`; enforced by container/cgroup flags | Task 1 aborts run on limit exit and cleans container |
104
+ | File descriptors | 1,024 / 8,192 | Validated before `docker run`; `nofile` ulimit | Task 1 |
105
+ | Workspace / temp / download tmpfs | 1 GiB / 8 GiB; 256 MiB / 2 GiB; 64 MiB / 512 MiB | Size option validated before create; kernel tmpfs cap enforces writes | Task 1/6 discard on overflow |
106
+ | Commands / concurrent exec | 100 / 256; 1 / 8 | Before queue/start; total also remains under run tool-call/wall limits | Task 1 rejects/aborts; close drains finite queue then kills |
107
+ | Command output | existing 64 MiB / 1 GiB total; model result spill remains separately bounded | Stream byte count before append/write | Coding output accumulator + Task 1 termination |
108
+ | Environment/secrets | 64 names / 256; 64 KiB / 256 KiB aggregate values | Validate exact host allow-list before create/exec; inherit none | Task 1 redacts errors and never exports environment |
109
+ | Import/export | 50,000 / 250,000 entries; 256 MiB / 2 GiB bytes; 16 / 64 retained artifacts | Count headers/entries and stream bytes before write/retain; verify real path/type/hash | Task 1 aborts export, removes partial host artifact, source remains unchanged |
110
+ | Stop grace / forced cleanup | 5 s / 30 s; one stop then one kill; cleanup deadline 30 s / 120 s | Terminal/abort/timeout/lease loss/browser crash | Task 1 records unresolved cleanup as release-blocking error |
111
+
112
+ ### Repository, Git, checks, and durable work
113
+
114
+ | Resource | Default / hard cap | Charge/check point | Owner |
115
+ | --- | --- | --- | --- |
116
+ | Repository depth / entries / files | 32 / 128; 10,000 / 100,000; 10,000 / 100,000 | Before descending/retaining next entry/file | Task 2 |
117
+ | Search scan/file/matches | 64 MiB / 1 GiB aggregate; 8 MiB / 64 MiB per file; 1,000 / 10,000 matches | Prefix/binary check then stream bytes; check aggregate before next file/match | Task 2 |
118
+ | Search pattern/line/context/time | 512 / 4,096 UTF-8 bytes; 50 KiB / 1 MiB line; 5 / 20 context lines; 30 s / 300 s | Before regex compile; before line/context retention; absolute deadline | Task 2 |
119
+ | Repository concurrency | 8 / 32 open/read workers | Before opening next directory/file | Task 2 |
120
+ | Git paths/refs/message | 1,000 / 10,000 paths; 1 KiB / 4 KiB ref; 64 KiB / 256 KiB commit message | Validate before process/temp-file creation | Task 3 |
121
+ | Git output/diff/patch | 4 MiB / 64 MiB inline output; 10,000 / 100,000 diff lines; 1,000 / 10,000 changed files; 16 MiB / 64 MiB patch input | Stream before retain; spill only through bounded artifact callback | Task 3 |
122
+ | Worktrees/background runs | 4 / 16 per parent run; coordinator default remains 4 and hard cap 256 | Before create/lease claim; exact branch/root ownership recorded | Task 3/4 |
123
+ | Named checks | 8 / 32 names per host config; 1 / 4 concurrent; 10 min / 60 min each; 2,000 / 100,000 diagnostic lines; 4 MiB / 64 MiB inline output | Validate config at construction; charge before start/line retention | Task 3 |
124
+ | Workflow state/checkpoint/history | Existing 64 KiB / 512 KiB state; 1 MiB / 8 MiB checkpoint; 32 / 128 history revisions | Existing workflow adapter checks before save | Task 4 |
125
+ | Workspace checkpoint artifacts | 16 / 64 references; 256 MiB / 2 GiB each, also sandbox export aggregate | Hash/size verify before checkpoint metadata/import | Task 4 with host artifact owner |
126
+ | Plan/todo and PR handoff | 256 KiB / 1 MiB plan; 1,000 / 10,000 todos; 256 KiB / 1 MiB handoff JSON | Before write/checkpoint/result exposure | Task 4 / Task 3 handoff |
127
+
128
+ ### Browser
129
+
130
+ | Resource | Default / hard cap | Charge/check point | Owner |
131
+ | --- | --- | --- | --- |
132
+ | Contexts/pages/actions/queued actions | exactly 1 context per run; 4 / 16 pages; 100 / 256 actions; 16 / 64 queued | Before context/page/action/queue creation; invalidate refs on mutation | Task 5 |
133
+ | Snapshot refs/depth/bytes | 2,000 / 10,000 refs; depth 30 / 100; 256 KiB / 2 MiB encoded YAML | Before retaining each ref/node and before result exposure | Task 5 |
134
+ | Navigation/action/wait/run time | 30 s / 120 s navigation; 10 s / 60 s action; 30 s / 120 s explicit wait; sandbox 20 min / 30 min run | Absolute deadline before Playwright call; no timeout retries unless action budget charged | Task 5 |
135
+ | Popups/dialogs/listeners | 4 / 16 popups; 16 / 64 dialogs; 64 / 256 registered listeners | Before accepting/retaining; deterministic deny/dismiss after cap | Task 5/6 |
136
+ | Network requests/redirects/WebSockets | 1,000 / 10,000 requests; 10 / 32 redirects/request; 8 / 32 WebSockets | Before route continuation/redirect/socket acceptance | Task 6; host firewall/proxy owns actual egress |
137
+ | Screenshots | 16 / 64 megapixels; existing 10 MB / 32 MiB encoded image cap; 16 / 64 per run | Validate clip/viewport before capture and bytes before result/artifact | Task 6 |
138
+ | Uploads | 8 / 32 files; 16 MiB / 64 MiB each; 64 MiB / 256 MiB aggregate | Realpath/type/size/approval before Playwright receives path | Task 6 |
139
+ | Downloads | 8 / 32 files; 32 MiB / 256 MiB each; 64 MiB / 512 MiB aggregate | Stream to quarantine with count/hash; approval before export | Task 6 |
140
+ | Browser cleanup | 5 s / 30 s close grace, then sandbox kill; 0 retained context/storage-state objects | Abort, terminal run, explicit close, browser crash, lease loss | Task 5 manager and Task 1 sandbox |
141
+
142
+ ## Threat and authority matrix
143
+
144
+ | Boundary | Trusted authority | Untrusted input | Mandatory control | Default/unsupported behavior |
145
+ | --- | --- | --- | --- | --- |
146
+ | Docker daemon/executable/image | Host operator supplies absolute CLI, daemon, digest, non-root image UID and policy | Model/repository/container output | Typed args; preflight; `--pull=never`; no socket/device/privileged/host namespaces; labels/recorded IDs | Missing/mutable/untrusted input fails before create; daemon compromise is outside Prism containment |
147
+ | Source/workspace import/export | Host selects source and artifact callback | Paths, links, repository entries, archive headers/content | Read-only source; finite tmpfs; realpath/type checks; no devices; stream bounds; hash; atomic partial cleanup | No direct write-back; failed run discards workspace |
148
+ | Process/environment/secrets | Host declares named checks and exact env allow-list | Model command text, repo scripts/config/hooks, process output | Typed exec for first-party tools; shell explicit; inherited env empty; noninteractive Git; redaction; limits | Unknown command/check/env denied; no implicit hooks/credentials |
149
+ | Network/DNS | Host firewall/proxy/network policy | URLs, redirects, DNS, page scripts/service workers/WebSockets | Network none default; isolated proxy/firewall for browse; route validation and service-worker block in depth | No proxy attestation means no external browser network; private/local/file/devtools denied |
150
+ | Playwright/browser endpoint | Host owns pinned browser launch/control endpoint | Pages, DOM/a11y text, refs, popups, downloads | One non-persistent context/run; short-lived host-only endpoint; ordered actions; no evaluate/CDP/profile | Endpoint/browser mismatch fails construction; import is inert |
151
+ | Side effects/approval | Host `PermissionPolicy`, `ExecutionPolicy`, workflow approval | Model/page instructions and action metadata | Dispatch permission/guardrails then immediate operation policy; high-impact durable approval | Page text cannot authorize; denial produces bounded stable result |
152
+ | Browser storage/secrets | Host injects at context/request edge | Cookies/storage state/page content/errors | Never return/persist/log storage state; redact known secret canaries; close context | No local profile; no checkpointed browser internals |
153
+ | Upload/download/screenshot | Host roots, artifact callback, approval | Filenames, MIME, bytes, page pixels, symlinks | Realpath containment; quarantine; stream/pixel/byte caps; hashes; explicit release | Overflow/unknown type stays quarantined then deleted |
154
+ | Durable checkpoint/resume | Host-owned checkpoint/lease/artifact stores and ownership scope | Persisted metadata, stale workers, artifact URI/content | CAS/fencing; workflow revision; image/tool/policy fingerprints; artifact hash/size; current approval | Wrong owner/revision/hash/fence fails before import/action |
155
+ | Office work | User/host-selected external skill/tool | Office files/commands | Outside Prism runtime | No package, executable, schema, docs, test, or release claim |
156
+
157
+ ## Validation matrix for Task 0
158
+
159
+ | Check | Frozen assertion |
160
+ | --- | --- |
161
+ | Traceability | Every retained Phase 4 criterion above has one primary owner Task 1–8; cross-task composition is explicit. Removed Office criterion has product-decision owner and no implementation task. |
162
+ | Primitive reuse | No new core primitive. Package-local additions have concrete local+sandbox or coding+browser consumers where shared; otherwise remain in owning package. |
163
+ | Finite resources | Every external start/read/write/retain/queue/export path above has default/hard caps, pre-charge point, abort behavior, and cleanup owner. |
164
+ | Security claims | Sandbox containment is Docker/host policy, not regex; browser DNS containment is host proxy/firewall, not Playwright routing; daemon, image, credentials, network, artifacts, and approvals stay host-owned. |
165
+ | Scope absence | Revised roadmap Phase 4, package ledger, persona outcomes, and release checklist contain no OfficeCLI/Office runtime/package gate. |
166
+
167
+ ## Documentation and release ownership
168
+
169
+ - Task 1: `docs/coding-security.md`, `docs/host-security.md`, `docs/performance.md`, protected Docker gate.
170
+ - Tasks 2–4: `docs/coding-agent-tools.md`, `docs/workflows.md`, `docs/evaluations.md`, offline coding/Git/durable-workflow gates.
171
+ - Tasks 5–6: new `docs/browser-automation.md`, plus tools/guardrails/security/performance docs, package/install and protected Playwright gate.
172
+ - Task 7: eval, benchmark, and protected-gate evidence — completed network-free coding/browser adversarial fixtures (`eval-fixtures.test.ts`), `scripts/benchmark-0.0.9.mjs` (+ schema test), protected Playwright live matrix, expanded Docker protected matrix, and `.github/workflows/sandbox-browser.yml`.
173
+ - Task 8: migration/release docs, package graph, Node/pack/install/supply-chain/release dry-run evidence — completed 32-package exact `0.0.9` graph (`@arnilo/prism-browser` in `prism-all` only), finalized docs/changelogs/migration/release handoff, dated `benchmark-0.0.9` evidence, and release-candidate gates recorded in Plan 072.
174
+
175
+ No public implementation API changed in Task 0. This page and `roadmap.md` are the authoritative pre-implementation boundary; later tasks may tighten defaults but cannot raise hard caps or broaden authority without updating tests, docs, and this evidence.
@@ -0,0 +1,172 @@
1
+ # Review coverage — 2026-07-21 Phase 5
2
+
3
+ Working evidence for Plan 073 Task 0. Freezes Phase 5 / Release **0.0.10** scope, workspace-mode contract, primitive ownership, reused finite limits, threats, tests, docs, and release gates before implementation.
4
+
5
+ **Evidence frozen:** 2026-07-21. **Prism source:** `5fc05437224f347b00fb6124d1783eb2cd3a9b25` (Task 0 freeze). **Release target:** 0.0.10 (Task 7 retargeted graph from post-ship `0.0.96` → exact `0.0.10`). **Default test rule:** network-free fakes/fixtures; real Docker remains `PRISM_TEST_DOCKER_SANDBOX=1` protected gate.
6
+
7
+ ## Status legend
8
+
9
+ | Status | Meaning |
10
+ | --- | --- |
11
+ | `existing` | Current public contract covers the requirement. |
12
+ | `extend` | Owning task extends an existing optional package/contract. |
13
+ | `compose` | Existing public primitives suffice; package-local glue / docs / examples only. |
14
+ | `out-of-scope` | Coding-harness P1/P2 or later release; must not land in 0.0.10 tasks. |
15
+
16
+ ## Frozen product decision
17
+
18
+ 0.0.10 closes **coding-harness P0 correctness** only: one explicit workspace mode so disposable sandbox shell and filesystem tools share one tree, fail-closed mixed wiring, tree-identity metadata on import/export/resume, docs that forbid treating host mode as containment.
19
+
20
+ **Not in 0.0.10** (owned by later phases — do not implement here):
21
+
22
+ | Deferred item | Owner phase |
23
+ | --- | --- |
24
+ | Session search/index | 0.0.11 Phase 6 |
25
+ | Token/context budgeting + omission reporting | 0.0.11 Phase 6 |
26
+ | Native Anthropic provider | 0.0.11 Phase 6 |
27
+ | Native Google provider | 0.0.11 Phase 6 |
28
+ | Goal→verify coding loop helper/example | 0.0.11 Phase 6 |
29
+ | Additional subscription OAuth adapters | 0.0.12 Phase 7 |
30
+ | AG-UI/ACP-facing event adapter | 0.0.12 Phase 7 |
31
+ | Coding-aware compaction preset | 0.0.12 Phase 7 |
32
+ | Enterprise identity / work connectors | 0.0.13+ |
33
+ | New sandbox runtime, K8s/remote scheduler, automatic image pull, writable bind-mount as a third named mode | never in 0.0.10 |
34
+
35
+ ## Frozen external revisions
36
+
37
+ | Surface | Frozen reference | Compatibility decision |
38
+ | --- | --- | --- |
39
+ | Prism | [`5fc05437224f347b00fb6124d1783eb2cd3a9b25`](../plans/073-release-0-0-10-coding-harness-unified-workspace.md) | Caller/limit claims below checked against post-0.0.9 tree. |
40
+ | Node.js | Local reference `v24.18.0`; release support remains Node 20 and current | FS/exec backends use `node:child_process` argument arrays, streams, `AbortSignal`, path, crypto hashes only. |
41
+ | Docker CLI/Engine | Local reference client/server `29.6.1`; same Phase 4 docs | Reuse `createDockerSandbox` flags/limits; no new daemon features required for FS backends. |
42
+ | Git | Local reference `git version 2.55.0` | Reuse `createGitTools` + `execFile` binder; same cwd/tree as sandbox mode. |
43
+
44
+ ## Frozen workspace-mode contract
45
+
46
+ | Decision | Frozen choice |
47
+ | --- | --- |
48
+ | Modes in 0.0.10 | Exactly `"host" \| "sandbox"`. No `"shared_mount"` / future aliases until a later release updates this page. |
49
+ | `workspaceMode` default | **Required.** Missing/undefined throws at construction. No soft-default to host (would preserve the footgun for Docker users). |
50
+ | Escape hatch | `allowMixedWorkspaceWiring: true` (name frozen). Without it, sandbox shell + host-mutating FS/list/search backends throw. With it, composition records explicit warnings; containment claim is false. |
51
+ | Sandbox auto-wire prerequisite | Auto FS/repo backends (Task 2) require `DisposableSandbox` (`execFile`). Bare `SandboxAdapter` (exec-only) may be used in sandbox mode **only** when the host supplies agreeing custom `read`/`write`/`edit`/`repository.operations`. |
52
+ | Host mode shell | May still use `options.sandbox` for shell only when FS backends are local host ops — that is **mixed wiring** and needs the escape hatch, **or** host mode with **no** sandbox (local shell + local FS). Preferred host mode: no sandbox adapter. |
53
+ | Same-tree bind-mount | Host responsibility under escape hatch; Prism does **not** claim disposable containment for that wiring in 0.0.10. |
54
+ | Construction API | Package-local `createSandboxCodingComposition(cwd, options) → { tools, composition }` is the authoritative path. `createSandboxCodingTools` / `createSandboxReadOnlyTools` remain thin wrappers returning `tools` only (compat). |
55
+ | Composition metadata | `ToolDefinition` has **no** metadata field. Warnings/mode/containment live on `SandboxCodingComposition` (`workspaceMode`, `containmentClaim: boolean`, `mixedWiringAllowed: boolean`, `warnings: readonly string[]`, `workspaceRoot`, optional `treeIdentity`). Do not add core `ToolDefinition.metadata`. |
56
+ | Containment claim | `containmentClaim === true` only when `workspaceMode === "sandbox"`, mixed wiring is denied, and FS/repo backends target the disposable tree. Host mode and escape-hatch mixed wiring always `false`. |
57
+
58
+ ## Capability traceability matrix
59
+
60
+ | Phase 5 roadmap criterion | Current 0.0.9 surface | Minimum 0.0.10 gap | Status / owner | Required proof | Docs | Release gate |
61
+ | --- | --- | --- | --- | --- | --- | --- |
62
+ | Explicit workspace mode; default sandboxed composition no longer silently pairs container shell with host FS mutations | `createSandboxCodingTools` wires shell via `createSandboxBashOperations`; read/write/edit/list/search keep host `cwd` (documented split) | Required `workspaceMode`; sandbox mode auto-wires FS/repo or fails closed | `extend` / Task 1 (+ Task 2 backends) | construction matrix: missing mode throws; sandbox without capable backends throws | `coding-security.md`, `migration.md` | offline coding-security tests |
63
+ | Sandbox mode: shell + read/write/edit/repo_list/repo_search share one tree | Pluggable `*Operations` exist; no sandbox FS/repo defaults | Exec-backed (or host-supplied) FS + repository ops rooted at sandbox workspace | `extend` / Task 2 | write↔shell byte agreement; list/search agree with shell on same tree | `coding-security.md`, `coding-agent-tools.md` | fake sandbox + opt-in Docker |
64
+ | Host mode: all tools on host workspace; no containment claim | `createCodingTools` local defaults; sandbox helper still claims “sandbox” by name while FS is host | Host mode local ops + `containmentClaim: false` | `extend` / Task 1 | host mutations land on host cwd; composition metadata non-isolating | `coding-security.md`, `host-security.md` | offline tests |
65
+ | Import/export/close/resume preserve tree identity | `SandboxExportMetadata` `{ sha256, entryCount, byteCount, format }`; export two-pass; import tar summarize; no import hash retained on session; composition cannot refuse unbound FS | Retain/import identity on disposable session/status; composition refuses containment claim when backends unbound | `extend` / Task 4 | import→mutate→export hash change; export continuity; unbound backends fail closed | `coding-security.md`, `host-security.md` | fake CLI + protected Docker |
66
+ | Reject unsafe mixed wiring unless escape hatch + surfaced metadata | Split composition is the silent default; no guard | Fail-closed check + `allowMixedWorkspaceWiring` + `composition.warnings` | `extend` / Task 1 | throw without hatch; warn with hatch | `coding-security.md`, `migration.md` | offline tests |
67
+ | Performance: no unbounded host↔container sync; reuse entry/byte/time caps; host vs sandbox benchmarks | Existing sandbox/repo/coding hard caps; `scripts/benchmark-0.0.9.mjs` | Reuse caps for FS backends; forbid sync loops; `benchmark-0.0.10` both modes | `extend` / Task 5 | schema/bounds + consistency under caps; concurrent exec still enforced | `performance.md` | benchmark schema test + offline suite |
68
+ | One construction path; pluggable backends; no second coding runtime | Aggregators + `*Operations` seams | Composition helper only; no new agent/runtime | `compose` / Tasks 1–3 | package stays optional; core dependency-free | `coding-security.md` | pack/install |
69
+ | Git/check runners same tree/cwd in sandbox mode | `createGitTools({ execFile: sandbox.execFile })` documented; not auto-bundled | Documented/binder wiring + consistency test | `compose` / Task 3 | write then git status/diff sees file in sandbox | `coding-agent-tools.md`, `coding-security.md` | offline + fake execFile |
70
+ | Security: path containment, policy, digest-pinned non-root Docker remain mandatory for advertised sandbox mode; forbid host-as-contained | Phase 4 Docker reference + approval policy | Docs + `containmentClaim` enforcement; host mode language | `extend` / Tasks 1, 6 | escape/path tests; docs assert host ≠ contained | `host-security.md`, `coding-security.md` | offline + protected Docker |
71
+ | Docs/migration: 0.0.9 split superseded | Docs describe split as current | Replace guidance; migration note | `extend` / Task 6 | docs.test / migration assertions | `migration.md`, index summaries | docs tests |
72
+ | Version/release 0.0.10 evidence | 32-package `0.0.9` (working tree may show `0.0.10`) | Bump graph, changelogs, `sdk:ready`, release dry-run | `extend` / Task 7 | full release gate | `release-and-install.md` | `sdk:ready` + dry-run |
73
+
74
+ ## Primitive and caller inventory
75
+
76
+ Frozen at `5fc05437224f347b00fb6124d1783eb2cd3a9b25` (+ this evidence page).
77
+
78
+ | Primitive / symbol | Existing contract / callers | Phase 5 disposition |
79
+ | --- | --- | --- |
80
+ | `createSandboxCodingTools` / `createSandboxReadOnlyTools` | Defined `packages/coding-security/src/sandbox-coding-operations.ts`; exported from package index; **callers:** package tests only (no examples/src production caller yet) | Extend with required `workspaceMode`, mixed-wiring guard, sandbox auto-wire; wrappers over composition helper |
81
+ | `createSandboxBashOperations` | `sandbox.ts`; used by composition, approval tests, sandbox-coding tests | Reuse for shell wiring; unchanged contract |
82
+ | `SandboxAdapter` / `DisposableSandbox` / `createDockerSandbox` | `sandbox.ts`, `docker-sandbox.ts`; Docker tests | Reuse. Sandbox-mode auto FS requires `DisposableSandbox.execFile`. No new core sandbox type |
83
+ | `SandboxExportMetadata` | `{ sha256, entryCount, byteCount, format: "tar" }` on close export | Reuse shape for tree identity; Task 4 may expose import/last-export on status/composition |
84
+ | `ReadOperations` / `WriteOperations` / `EditOperations` | `packages/coding-agent/src/{read,write,edit}.ts`; local defaults; custom ops optional | Reuse contracts. Task 2 implements sandbox-backed adapters in **coding-security** only |
85
+ | `RepositoryOperations` / `createLocalRepositoryOperations` | `repository.ts`; list/search tools | Reuse. Task 2 adds sandbox-backed repo ops in coding-security |
86
+ | `BashOperations` / `createLocalBashOperations` | `shell.ts` | Reuse |
87
+ | `createGitTools` / `resolveGitRunner` / `execFile` option | `git-tools.ts`, `git-exec.ts`; coding-agent git tests | Reuse. Task 3 documents/binds same workspace root; optional thin coding-security binder only if ≥2 non-test call sites |
88
+ | `ExecutionPolicy` / path containment / approval | coding-security + coding-agent | Reuse; mandatory for advertised sandbox mode |
89
+ | `ToolDefinition` | Core `src/contracts.ts` — name/description/parameters/exclusive/execute only | **No** new metadata field. Composition descriptor stays package-local |
90
+ | Core agent/session/workflow runtimes | Unchanged | **No** second coding runtime; no core primitive promotion |
91
+
92
+ ### Primitive decision
93
+
94
+ **No new core primitive authorized.**
95
+
96
+ Authorized package-local work (`@arnilo/prism-coding-security` unless noted):
97
+
98
+ 1. `workspaceMode` + `allowMixedWorkspaceWiring` + `SandboxCodingComposition` + `createSandboxCodingComposition`.
99
+ 2. `createSandboxFilesystemOperations` / `createSandboxRepositoryOperations` (names may shorten in impl; stay package-local).
100
+ 3. Optional `bindSandboxGitOptions` only if examples + package tests both need identical wiring (else docs-only).
101
+ 4. Minimal `DisposableSandbox` status/identity fields for import/export continuity (Task 4) — still coding-security local.
102
+
103
+ Promote to core only with ≥2 non-test consumers outside coding-security **and** migration/conformance evidence. One-consumer interfaces, sync daemons, Merkle indexes, and third workspace modes are rejected for 0.0.10.
104
+
105
+ ## Frozen capability boundary
106
+
107
+ | Surface | Supported in 0.0.10 | Explicitly unsupported |
108
+ | --- | --- | --- |
109
+ | Workspace modes | `host`, `sandbox`; required option; fail-closed mixed wiring; escape hatch with warnings | Soft-default mode; silent split-brain; named `shared_mount` mode; claiming containment for host/escape-hatch |
110
+ | Sandbox FS | ExecFile-backed read/write/edit/list/search against disposable tree; host-supplied custom ops | Unbounded bidirectional sync loops; new transport protocol; automatic host write-back |
111
+ | Docker reference | Existing digest-pinned, non-root, network-none, finite tmpfs, import/export | Image pull/build, daemon provisioning, K8s, Docker socket exposure |
112
+ | Git/checks | Same-tree via `execFile` + cwd; optional binder | Auto-include Git in default coding tool set; push/PR/network |
113
+ | Artifacts / identity | Existing export metadata + retained import/export hashes for resume checks | Full workspace in checkpoints; secret-bearing identity blobs |
114
+
115
+ ## Frozen finite limits and charging points
116
+
117
+ **Rule:** Reuse Phase 4 / shipped coding-security and coding-agent defaults and hard caps. Task 2–5 **must not** raise hard caps or add unbounded sync. Charge before each sandbox FS/repo/exec operation against the same counters.
118
+
119
+ ### Sandbox and workspace (reuse `sandbox-limits.ts`)
120
+
121
+ | Resource | Default / hard cap | Charge/check point | Failure/cleanup owner |
122
+ | --- | --- | --- | --- |
123
+ | Startup / wall / idle | 30 s / 120 s; 20 min / 30 min; 5 min / 15 min | Existing create/exec | Task 4/Docker session |
124
+ | CPU / memory / PIDs / FDs | 2 / 8; 2 GiB / 16 GiB; 256 / 1,024; 1,024 / 8,192 | Before `docker run` | existing |
125
+ | Workspace / tmp / download tmpfs | 1 GiB / 8 GiB; 256 MiB / 2 GiB; 64 MiB / 512 MiB | Before create / write overflow | existing |
126
+ | Commands / concurrent execs | 100 / 256; 1 / 8 | Before each exec **including FS-backend execFile** | Task 2 must share queue |
127
+ | Command/FS output | 64 MiB / 1 GiB | Stream before retain | Task 2 + output accumulator |
128
+ | Import/export entries/bytes / retained artifacts | 50,000 / 250,000; 256 MiB / 2 GiB; 16 / 64 | Before retain; two-pass hash verify | Task 4 |
129
+ | Stop grace / cleanup | 5 s / 30 s; 30 s / 120 s cleanup | Terminal paths | existing |
130
+
131
+ **Forbidden:** background host↔container watchers, periodic full-tree sync, unbounded `docker cp` retry loops, retaining more than `maxExport*` without export API.
132
+
133
+ ### Repository / read / write / edit (reuse `packages/coding-agent/src/limits.ts`)
134
+
135
+ | Resource | Default / hard cap | Owner for sandbox backends |
136
+ | --- | --- | --- |
137
+ | Repo depth / entries / files / results / concurrency | 32 / 128; 10k / 100k; 10k / 100k; 1k / 10k; 8 / 32 | Task 2 |
138
+ | Search scan/file/matches/pattern/line/context/time | 64 MiB / 1 GiB; 8 MiB / 64 MiB; 1k / 10k; 512 / 4,096 B; 50 KiB / 1 MiB; 5 / 20; 30 s / 300 s | Task 2 |
139
+ | Read text/image; write; edit file/input/edits | existing coding-agent ceilings | Task 2 |
140
+ | Git paths/refs/message/output | existing git ceilings | Task 3 |
141
+
142
+ ## Threat and authority matrix
143
+
144
+ | Boundary | Trusted authority | Untrusted input | Mandatory control | Default / unsupported |
145
+ | --- | --- | --- | --- | --- |
146
+ | Workspace mode selection | Host sets `workspaceMode` explicitly | Model/tool args cannot change mode | Construction throws if missing; mixed wiring throws without hatch | Silent split-brain unsupported |
147
+ | Sandbox containment claim | Host + composition when backends agree on disposable tree | Model claims, host cwd edits under sandbox advertising | `containmentClaim` only when mode=sandbox and backends bound; path containment + Docker policy | Host mode / escape hatch never claim containment |
148
+ | Sandbox FS backends | Host-supplied `DisposableSandbox` or custom ops | Paths, symlink targets, archive/exec output | Workspace-root realpath/containment; byte/entry/time caps; share concurrent exec limits | Escape outside `/workspace` denied |
149
+ | Mixed wiring escape hatch | Host sets `allowMixedWorkspaceWiring` | Accidental omitted ops | Explicit option + `composition.warnings` | Undocumented mixed wiring unsupported |
150
+ | Import/export identity | Host artifact callback + hash verify | Tar headers/content | Existing type checks + two-pass hash; resume compares hashes | Advertise sandboxed coding on unbound host root unsupported |
151
+ | Docker/image/secrets | Host digest/CLI/allow-list | Model env/commands | Phase 4 Docker controls unchanged | Pull/build/socket unsupported |
152
+ | Git in sandbox | Host `commitIdentity` + `execFile` | Refs/pathspecs/hooks | Existing safe git config; same workspace root | Push/PR/credentials unsupported |
153
+
154
+ ## Validation matrix for Task 0
155
+
156
+ | Check | Frozen assertion |
157
+ | --- | --- |
158
+ | Traceability | Every Phase 5 roadmap criterion maps to exactly one primary owner among Tasks 1–7; 0.0.11+ items listed only under out-of-scope. |
159
+ | Primitive reuse | No new core primitive. FS/repo helpers stay coding-security-local unless a second non-test consumer appears. |
160
+ | Finite resources | Sandbox FS/repo paths reuse existing defaults/hard caps; concurrent exec shared; no sync loops. |
161
+ | Security claims | Containment is Docker/host policy + bound backends, not regex; host mode and escape hatch are non-containing by contract. |
162
+ | Mode API | `workspaceMode` required; modes `{host,sandbox}` only; escape hatch name `allowMixedWorkspaceWiring`; metadata on `SandboxCodingComposition`, not `ToolDefinition`. |
163
+
164
+ ## Documentation and release ownership
165
+
166
+ - Task 0 (this page): scope freeze, index link, docs.test evidence assertions.
167
+ - Tasks 1–4: implementation; API docs deferred to Task 6 except in-code JSDoc.
168
+ - Task 5: adversarial tests, `scripts/benchmark-0.0.10.mjs`, protected Docker extensions.
169
+ - Task 6: `docs/coding-security.md`, `docs/coding-agent-tools.md`, `docs/migration.md`, `docs/host-security.md`, `docs/performance.md`, package READMEs/changelogs, index summary tweaks.
170
+ - Task 7: version `0.0.10`, `sdk:ready`, pack/install/supply-chain, release dry-run — **done** (1,963 tests / 1,934 pass / 29 skip; 32/32 dry-run; no tag/publish).
171
+
172
+ No public implementation API changes in Task 0. This page, `roadmap.md` Phase 5, and Plan 073 are the authoritative pre-implementation boundary; later tasks may tighten defaults but cannot raise hard caps, add sync loops, introduce a third mode, or claim host-mode containment without updating tests, docs, and this evidence.
@@ -80,6 +80,7 @@ await assertRunLedgerConforms({ ledger, readRuns: () => runs, readEvents: () =>
80
80
 
81
81
  - `read*` callbacks are optional for smoke tests but required for ordering, tenant, and reopen probes.
82
82
  - `RunLedger` is write-only from Prism's perspective; replay/query APIs live on `ProductionPersistenceStore` or host-owned reads.
83
+ - Run conformance against the underlying write-through adapter. Test `createBatchedRunLedger()` separately for FIFO, bounds, terminal/manual flush, retained failure, and documented buffered crash loss; batching does not weaken adapter conformance.
83
84
  - Redaction is not asserted here — the runtime calls `redactRunLedgerRecord()` before writes when a `SecretRedactor` is active.
84
85
 
85
86
  ## Security and performance notes