@arnilo/prism 0.0.15 → 0.0.17

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 (119) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/dist/agent-definitions.js +2 -3
  3. package/dist/agent-loops.js +12 -7
  4. package/dist/agent-run-lifecycle.d.ts +1 -2
  5. package/dist/agent-run-lifecycle.js +1 -1
  6. package/dist/agent-run-state.js +29 -4
  7. package/dist/agents.d.ts +1 -1
  8. package/dist/agents.js +163 -61
  9. package/dist/cache-helpers.js +18 -9
  10. package/dist/checkpoints.d.ts +4 -0
  11. package/dist/checkpoints.js +17 -9
  12. package/dist/cli-init.js +3 -7
  13. package/dist/cli-runner.d.ts +2 -6
  14. package/dist/cli-runner.js +71 -33
  15. package/dist/compaction.js +5 -4
  16. package/dist/config.js +7 -4
  17. package/dist/content.js +26 -24
  18. package/dist/context-budget.js +18 -11
  19. package/dist/contracts.d.ts +16 -3
  20. package/dist/contracts.js +4 -1
  21. package/dist/contribution-parsing.js +6 -2
  22. package/dist/contributions.d.ts +2 -0
  23. package/dist/contributions.js +3 -0
  24. package/dist/conversations.js +2 -1
  25. package/dist/credentials.d.ts +8 -2
  26. package/dist/credentials.js +9 -3
  27. package/dist/event-multiplexer.js +18 -4
  28. package/dist/extensions.d.ts +7 -1
  29. package/dist/extensions.js +64 -6
  30. package/dist/feedback.js +12 -10
  31. package/dist/guardrails.d.ts +1 -1
  32. package/dist/guardrails.js +26 -17
  33. package/dist/identity.js +10 -2
  34. package/dist/index.d.ts +82 -83
  35. package/dist/index.js +42 -42
  36. package/dist/input.d.ts +2 -2
  37. package/dist/input.js +50 -27
  38. package/dist/instruction-injection.d.ts +1 -1
  39. package/dist/middleware.js +9 -1
  40. package/dist/models.d.ts +2 -0
  41. package/dist/models.js +3 -0
  42. package/dist/node/agent-definitions.js +16 -8
  43. package/dist/node/contribution-discovery.d.ts +1 -2
  44. package/dist/node/contribution-discovery.js +3 -3
  45. package/dist/node/session-store-jsonl.js +10 -7
  46. package/dist/node/settings.d.ts +1 -1
  47. package/dist/node/settings.js +1 -1
  48. package/dist/node/system-project-prompts.js +2 -4
  49. package/dist/node/trust.js +1 -1
  50. package/dist/persistence-lifecycle.js +1 -3
  51. package/dist/provider-events.js +3 -1
  52. package/dist/provider-request-policy.js +3 -4
  53. package/dist/providers/media.d.ts +1 -1
  54. package/dist/providers/openai-compatible.d.ts +42 -1
  55. package/dist/providers/openai-compatible.js +110 -49
  56. package/dist/providers/openai-primitives.js +7 -7
  57. package/dist/providers/transport.d.ts +6 -0
  58. package/dist/providers/transport.js +21 -0
  59. package/dist/providers.d.ts +2 -0
  60. package/dist/providers.js +3 -0
  61. package/dist/redaction.d.ts +1 -0
  62. package/dist/redaction.js +26 -9
  63. package/dist/resources.d.ts +2 -2
  64. package/dist/resources.js +2 -2
  65. package/dist/retry.d.ts +5 -0
  66. package/dist/retry.js +8 -1
  67. package/dist/rpc.js +42 -9
  68. package/dist/run-ledger.d.ts +6 -0
  69. package/dist/run-ledger.js +16 -13
  70. package/dist/run-limits.js +49 -10
  71. package/dist/secure-agent.js +1 -1
  72. package/dist/security.js +7 -2
  73. package/dist/session-stores.d.ts +1 -1
  74. package/dist/session-stores.js +28 -24
  75. package/dist/structured-output.js +2 -2
  76. package/dist/system-prompts.js +7 -2
  77. package/dist/testing/compaction-conformance.js +5 -1
  78. package/dist/testing/extension-conformance.js +15 -3
  79. package/dist/testing/feedback.d.ts +1 -3
  80. package/dist/testing/feedback.js +1 -1
  81. package/dist/testing/persistence-schema.js +206 -37
  82. package/dist/testing/provider-conformance.js +3 -3
  83. package/dist/testing/run-ledger-conformance.js +1 -1
  84. package/dist/testing/session-store-conformance.js +1 -1
  85. package/dist/testing/tool-conformance.js +30 -5
  86. package/dist/thinking.js +4 -1
  87. package/dist/tools.d.ts +2 -2
  88. package/dist/tools.js +24 -5
  89. package/docs/0.1.0-readiness.md +139 -0
  90. package/docs/agent-events.md +2 -1
  91. package/docs/agent-session-runtime.md +2 -2
  92. package/docs/cli-rpc.md +1 -5
  93. package/docs/coding-agent-tools.md +2 -0
  94. package/docs/compaction-and-retry.md +3 -1
  95. package/docs/contribution-registries.md +1 -0
  96. package/docs/credentials-and-redaction.md +1 -1
  97. package/docs/extensions.md +1 -1
  98. package/docs/guardrails.md +13 -2
  99. package/docs/index.md +4 -2
  100. package/docs/input-and-prompt-assembly.md +3 -3
  101. package/docs/middleware-hooks.md +2 -2
  102. package/docs/migration.md +40 -0
  103. package/docs/performance.md +33 -0
  104. package/docs/providers/openai-compatible.md +28 -1
  105. package/docs/public-contracts.md +2 -2
  106. package/docs/release-and-install.md +127 -17
  107. package/docs/session-stores.md +1 -1
  108. package/package.json +14 -6
  109. package/docs/review-coverage-2026-07-14.md +0 -260
  110. package/docs/review-coverage-2026-07-15.md +0 -193
  111. package/docs/review-coverage-2026-07-17-provider-validation.md +0 -192
  112. package/docs/review-coverage-2026-07-19-phase-3.md +0 -174
  113. package/docs/review-coverage-2026-07-20-phase-4.md +0 -175
  114. package/docs/review-coverage-2026-07-21-phase-5.md +0 -172
  115. package/docs/review-coverage-2026-07-22-phase-6.md +0 -209
  116. package/docs/review-coverage-2026-07-22-phase-7.md +0 -173
  117. package/docs/review-coverage-2026-07-23-phase-8.md +0 -245
  118. package/docs/review-coverage-2026-07-25-phase-9.md +0 -256
  119. package/docs/review-coverage-2026-07-26-phase-10.md +0 -132
@@ -2,13 +2,13 @@
2
2
 
3
3
  ## What it does
4
4
 
5
- Prism is published as one core package, thirty-six first-party capability packages, and six pure-manifest family/profile packages (**43** publishable manifests total). This page describes how they are packed, what each tarball contains, how to install them, the required `@arnilo/prism` peer dependency, the release workflow, and the offline test budget.
5
+ Prism is published as one core package, thirty-seven first-party capability packages, and six pure-manifest family/profile packages (**44** publishable manifests total). This page describes how they are packed, what each tarball contains, how to install them, the required `@arnilo/prism` peer dependency, the release workflow, and the offline test budget. The measurable 1.0 readiness gates (command-per-gate) live in [`0.1.0-readiness.md`](./0.1.0-readiness.md).
6
6
 
7
7
  Core package:
8
8
 
9
9
  - `@arnilo/prism` — the runtime, contracts, registries, streaming events, CLI (including `prism init`), and the `/docs` hub. `files`: `dist` (with `!dist/__tests__` and `!dist/**/*.map` negations), `docs`, `templates`, `CHANGELOG.md`. `bin`: `prism` -> `dist/cli.js`. `sideEffects`: `["dist/cli.js"]`.
10
10
 
11
- First-party workspace packages (each has non-optional `@arnilo/prism@0.0.15` peer and `sideEffects: false`; RAG also peers on memory, and server also peers on workflows):
11
+ First-party workspace packages (each has non-optional `@arnilo/prism@0.0.17` peer and `sideEffects: false`; RAG also peers on memory, and server also peers on workflows):
12
12
 
13
13
  - `@arnilo/prism-provider-anthropic`, `@arnilo/prism-provider-google`, `@arnilo/prism-provider-openai`, `@arnilo/prism-provider-openrouter`, `@arnilo/prism-provider-kimi`, `@arnilo/prism-provider-zai`, `@arnilo/prism-provider-opencode-go`, `@arnilo/prism-provider-neuralwatt` — provider adapters.
14
14
  - `@arnilo/prism-provider-azure`, `@arnilo/prism-provider-bedrock`, `@arnilo/prism-provider-vertex` — optional enterprise-cloud adapters (Entra/IAM/ADC; separate from consumer Anthropic/Google).
@@ -36,7 +36,7 @@ First-party workspace packages (each has non-optional `@arnilo/prism@0.0.15` pee
36
36
 
37
37
  ### 0.0.12 AG-UI package boundary
38
38
 
39
- `@arnilo/prism-ag-ui` is a publishable optional code package with root AG-UI exports and stable `./acp` sibling, peer `@arnilo/prism@0.0.15`, pinned `@ag-ui/core@0.0.57` / `@agentclientprotocol/sdk@1.3.0`, and no import-time network/listener/run. It is included by `@arnilo/prism-all` only—not `@arnilo/prism-code` or `@arnilo/prism-sdk`—so coding and SDK profiles stay free of UI protocol dependencies.
39
+ `@arnilo/prism-ag-ui` is a publishable optional code package with root AG-UI exports and stable `./acp` sibling, peer `@arnilo/prism@0.0.17`, pinned `@ag-ui/core@0.0.57` / `@agentclientprotocol/sdk@1.3.0`, and no import-time network/listener/run. It is included by `@arnilo/prism-all` only—not `@arnilo/prism-code` or `@arnilo/prism-sdk`—so coding and SDK profiles stay free of UI protocol dependencies.
40
40
 
41
41
  Family/profile packages (pure manifests, no code or `dist`; ship `README.md` and `CHANGELOG.md`; use exact hard `dependencies`):
42
42
 
@@ -66,6 +66,7 @@ Consumers install the core package for the runtime and add first-party packages
66
66
  | Scaffold a minimal project | `npx --package @arnilo/prism prism init my-agent [--provider openai] [--with-workflows] [--with-evals]` |
67
67
  | Install core + all providers | `npm install @arnilo/prism @arnilo/prism-providers` |
68
68
  | Install minimal safe profile | `npm install @arnilo/prism-base` |
69
+ | Install compaction strategies only | `npm install @arnilo/prism @arnilo/prism-compaction` |
69
70
  | Install coding-agent profile | `npm install @arnilo/prism-code @arnilo/prism-provider-openai` |
70
71
  | Install application SDK profile | `npm install @arnilo/prism-sdk @arnilo/prism-provider-openai @arnilo/prism-session-store-sqlite` |
71
72
  | Install everything | `npm install @arnilo/prism-all` |
@@ -77,9 +78,9 @@ Consumers install the core package for the runtime and add first-party packages
77
78
  | Run the default (network-free) test suite | `npm test` |
78
79
  | Dry-run pack core + every package | `npm run pack:dry-run` |
79
80
  | Local mirror of the release verify gate | `npm run release:dry-run` |
80
- | Validate clean tag/version/ranges and reject registry collisions | `npm run release:check -- --version 0.0.15` |
81
- | Preview deterministic publish order | `npm run release:publish -- --version 0.0.15 --dry-run --allow-dirty --allow-untagged` |
82
- | Resume interrupted tagged publication | `npm run release:publish -- --version 0.0.15 --resume --report release-artifacts/publish-report.json` |
81
+ | Validate clean tag/version/ranges and reject registry collisions | `npm run release:check -- --version 0.0.17` |
82
+ | Preview deterministic publish order | `npm run release:publish -- --version 0.0.17 --dry-run --allow-dirty --allow-untagged` |
83
+ | Resume interrupted tagged publication | `npm run release:publish -- --version 0.0.17 --resume --report release-artifacts/publish-report.json` |
83
84
  | Full SDK readiness gate (typecheck + offline tests + pack) | `npm run sdk:ready` |
84
85
 
85
86
  Public core import specifiers (from the root `exports` map):
@@ -116,7 +117,7 @@ A packed tarball contains only public compiled output and release files:
116
117
  - Code packages ship `README.md`, `LICENSE`, and `CHANGELOG.md`; family/profile packages ship `README.md` and `CHANGELOG.md`.
117
118
  - The core tarball additionally ships the full `docs/` directory (the docs hub) and `templates/init/` used by `prism init`.
118
119
  - `dist/cli.js` and the `bin` link in core.
119
- - **Tarball filenames.** npm strips the `@scope/` prefix, so the core package `@arnilo/prism` produces a tarball named `arnilo-prism-0.0.15.tgz`; first-party packages produce `arnilo-prism-provider-<name>-0.0.15.tgz` / `arnilo-prism-compaction-<name>-0.0.15.tgz` / `arnilo-prism-coding-agent-0.0.15.tgz`; family/profile packages produce `arnilo-prism-{providers,compaction,base,code,sdk,all}-0.0.15.tgz`. The CLI bin name `prism` is unaffected by the package name (`npx prism` still works; npm allows the bin field to differ from the package name).
120
+ - **Tarball filenames.** npm strips the `@scope/` prefix, so the core package `@arnilo/prism` produces a tarball named `arnilo-prism-0.0.17.tgz`; first-party packages produce `arnilo-prism-provider-<name>-0.0.17.tgz` / `arnilo-prism-compaction-<name>-0.0.17.tgz` / `arnilo-prism-coding-agent-0.0.17.tgz`; family/profile packages produce `arnilo-prism-{providers,compaction,base,code,sdk,all}-0.0.17.tgz`. The CLI bin name `prism` is unaffected by the package name (`npx prism` still works; npm allows the bin field to differ from the package name).
120
121
 
121
122
  Excluded from every tarball by `files` negation:
122
123
 
@@ -135,9 +136,9 @@ Excluded from every tarball by `files` negation:
135
136
  "name": "host-app",
136
137
  "type": "module",
137
138
  "dependencies": {
138
- "@arnilo/prism": "0.0.15",
139
- "@arnilo/prism-provider-openai": "0.0.15",
140
- "@arnilo/prism-compaction-observational-memory": "0.0.15"
139
+ "@arnilo/prism": "0.0.17",
140
+ "@arnilo/prism-provider-openai": "0.0.17",
141
+ "@arnilo/prism-compaction-observational-memory": "0.0.17"
141
142
  }
142
143
  }
143
144
  ```
@@ -147,7 +148,7 @@ Installing the provider/compaction packages without `@arnilo/prism` present prod
147
148
  ```text
148
149
  npm error code ERESOLVE
149
150
  npm error Could not resolve dependency:
150
- npm error peer @arnilo/prism@"0.0.15" from @arnilo/prism-provider-openai@0.0.15
151
+ npm error peer @arnilo/prism@"0.0.17" from @arnilo/prism-provider-openai@0.0.17
151
152
  ```
152
153
 
153
154
  ## Implementation example
@@ -180,11 +181,11 @@ For SDK readiness, run the same one-command gate directly. It composes existing
180
181
  npm run sdk:ready
181
182
  ```
182
183
 
183
- Release publication derives all **43** manifests from the workspace once, validates exact `0.0.15` manifest/lockfile/internal ranges, then uses deterministic dependency order. `release:check` requires a clean commit tagged `v0.0.15` and rejects any existing registry version. `release:publish --resume` skips only registry versions whose internal dependency fingerprint matches the local manifest; conflicting versions fail closed. Each attempted package is written immediately to the JSON report, so a failed job can rerun safely. `--dry-run` performs registry availability checks and invokes `npm publish --dry-run` with explicit public access, provenance, and `latest` tag, but does not publish.
184
+ Release publication derives all **44** manifests from the workspace once, validates exact `0.0.16` manifest/lockfile/internal ranges, then uses deterministic dependency order. `release:check` requires a clean commit tagged `v0.0.16` and rejects any existing registry version. `release:publish --resume` skips only registry versions whose internal dependency fingerprint matches the local manifest; conflicting versions fail closed. Each attempted package is written immediately to the JSON report, so a failed job can rerun safely. `--dry-run` performs registry availability checks and invokes `npm publish --dry-run` with explicit public access, provenance, and `latest` tag, but does not publish.
184
185
 
185
186
  ```bash
186
- npm run release:check -- --version 0.0.15
187
- npm run release:publish -- --version 0.0.15 --dry-run --allow-dirty --allow-untagged
187
+ npm run release:check -- --version 0.0.17
188
+ npm run release:publish -- --version 0.0.17 --dry-run --allow-dirty --allow-untagged
188
189
  ```
189
190
 
190
191
  `--allow-dirty` and `--allow-untagged` exist only for local preview; real publication and CI never pass them. npm registry calls occur only in these release preflight/publication commands, never build/test/package discovery.
@@ -195,6 +196,55 @@ Optional live smoke tests stay separate from SDK readiness because they require
195
196
  PRISM_LIVE_PROVIDER_TESTS=1 npm run test --workspaces --if-present
196
197
  ```
197
198
 
199
+ ### 0.0.17 publish handoff
200
+
201
+ **Decision: GO after protected operator prerequisites below.** Release 0.0.17 implements the 2026-07-29 full implementation review (plan 081, twenty fixes): durable run-state load bound, explicit resume-as-approval, unconditional `input_assembly` middleware, same-session parent enforcement, jitter + `Retry-After`-aware retries with provider error wiring, O(n) context-budget eviction, fingerprint coverage of instructions/system prompt/skills, stage-named guardrail interrupts with `metadata.error`, `steer_rejected`, middleware double-`next()` detection, parked-consumer sorted multiplexer delivery, checkpoint-store bounds, strict credential opt-in, extension `unregister`/dispose handles with failed-setup unwind, loud CLI rejection of inert flags, capability-conditional tool listing, and the C8 nit bundle. The exact graph stays **44 publishable manifests**; no package added or retired. Intentional pre-1.0 breaks are documented in [migration](migration.md): inert CLI flags rejected (`CliOptions` dead fields removed) and `ExtensionKernel.load()` now resolves to `LoadedExtension[]`. The compat baseline was refreshed with `--allow-break` + migration note. Provider HTTP errors now carry numeric codes and `Retry-After` hints across anthropic/google/kimi/openai/opencode-go and the shared OpenAI-compatible transport — wire behavior is additive (more retries of genuinely transient failures), so the 0.0.15 protected live-canary matrix below still applies and no new live row is introduced.
202
+
203
+ ```bash
204
+ git diff --check
205
+ npm ci
206
+ npm run sdk:ready
207
+ node --test scripts/budget-gate.test.mjs
208
+ node scripts/scan-secrets.mjs && node scripts/verify-sbom.mjs
209
+ npm audit --audit-level=high
210
+ npm run release:gate
211
+ npm run release:check -- --version 0.0.17 --allow-dirty --allow-untagged --report /tmp/prism-0.0.17-preflight.json
212
+ npm run release:publish -- --version 0.0.17 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.0.17-dry-run.json
213
+ git tag -s v0.0.17 -m "Prism 0.0.17"
214
+ git verify-tag v0.0.17
215
+ git push origin v0.0.17
216
+ ```
217
+
218
+ The dry-run checks every registry collision and executes npm's non-publishing tarball validation for each dependency-ordered manifest. The protected tag workflow alone publishes through `npm run release:publish -- --version "${GITHUB_REF_NAME#v}" --resume --report release-artifacts/publish-report.json`; re-run a failed job for the same tag. `npm audit signatures --json --include-attestations` and artifact checksums remain post-publish checks.
219
+
220
+ ### 0.0.16 publish handoff
221
+
222
+ **Decision: GO after protected operator prerequisites below.** Phase 11 (plan 079) is a simplification/readiness release: no runtime behavior changes and no package retired. The exact graph is **44 publishable manifests** — Phase 11 Task 3 added one internal implementation package, `@arnilo/prism-session-store-codecs` (shared SQLite/Postgres row codecs, not enrolled in any profile family). The only public-surface change is the additive `resolveRedactor` export from `@arnilo/prism`; provider `cleanJson` was deliberately left per-package (wire-shape variants). All six profiles (`prism-all`, `prism-base`, `prism-code`, `prism-compaction`, `prism-providers`, `prism-sdk`) are retained on adoption evidence (zero retirements). The root tarball dropped the historical `docs/review-coverage-*.md` (659,478 → ≈575,680 packed bytes, 281 → 270 files). New offline release gates (`npm run release:gate`: API-surface `.d.ts` diff, tarball deny-list, exact ranges) run inside `sdk:ready`, and performance budgets (`scripts/budgets.json`) are enforced by `scripts/budget-gate.test.mjs` + `scripts/benchmark-0.0.16.mjs`. No Studio, Office, remote-browser vendor, additional vector-store, Slack/Teams, voice/desktop-control, internal-auth, or queue package ships. Protected CI, signed tag, npm authentication, OIDC attestation, and protected live-canary evidence remain operator/workflow prerequisites; no package is published by this handoff.
223
+
224
+ ```bash
225
+ git diff --check
226
+ npm ci
227
+ npm run sdk:ready
228
+ node scripts/benchmark-0.0.16.mjs
229
+ node --test scripts/budget-gate.test.mjs
230
+ node scripts/scan-secrets.mjs && node scripts/verify-sbom.mjs
231
+ npm audit --audit-level=high
232
+ npm run release:gate
233
+ npm run release:check -- --version 0.0.17 --allow-dirty --allow-untagged --report /tmp/prism-0.0.16-preflight.json
234
+ npm run release:publish -- --version 0.0.17 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.0.16-dry-run.json
235
+ git tag -s v0.0.16 -m "Prism 0.0.16"
236
+ git verify-tag v0.0.16
237
+ git push origin v0.0.16
238
+ ```
239
+
240
+ The dry-run checks every registry collision and executes npm's non-publishing tarball validation for each dependency-ordered manifest. The protected tag workflow alone publishes through `npm run release:publish -- --version "${GITHUB_REF_NAME#v}" --resume --report release-artifacts/publish-report.json`; re-run a failed job for the same tag. `npm audit signatures --json --include-attestations` and artifact checksums remain post-publish checks. The 0.0.15 protected live-canary matrix below still applies; 0.0.16 changes no provider/protocol/tenant surface, so no new live row is introduced.
241
+
242
+ #### Rollback limitations
243
+
244
+ npm publication is immutable: partial publication is a resume case, and a confirmed defect requires deprecation plus a fixed version rather than rollback.
245
+
246
+ The 0.0.16 package set is the canonical **44-package** list below (the 0.0.15 set plus `@arnilo/prism-session-store-codecs`); `release:check` derives it from the workspace and rejects missing, private, version-skewed, or internally mismatched manifests.
247
+
198
248
  ### 0.0.15 protected live-canary matrix
199
249
 
200
250
  Default `npm test`, `npm run sdk:ready`, and `benchmark-0.0.15` are network-free. Run live rows only from a protected scheduled/release environment (or an explicitly authorized operator workstation); never place credentials in fixtures, benchmark JSON, pull-request jobs, or package scripts. Use least-privilege keys, one bounded request, and retain only redacted aggregate status. A blank **checked-in gate** means Prism deliberately has no generic credential fixture: host owns that provider/account compatibility probe.
@@ -219,7 +269,7 @@ The scheduled/manual `live-canaries` workflow uses protected environment `live-c
219
269
 
220
270
  ### 0.0.15 publish handoff
221
271
 
222
- **Decision: GO after protected operator prerequisites below.** Phase 10 closes provider, memory, and RAG ecosystem parity without changing the Task 0 package freeze: the exact graph remains **43 publishable manifests**. It adds OpenAI hosted-tool attribution, bounded Responses continuation and Realtime; exact AI SDK V4 mapping; bounded RAG source lifecycle/document adapters/reranking/provenance/trust/status; and memory export/rebuild production conformance. No Studio, Office, remote-browser vendor, additional vector-store, Slack/Teams, voice/desktop-control, internal-auth, or queue package ships. Protected CI, signed tag, npm authentication, OIDC attestation, and protected live-canary evidence remain operator/workflow prerequisites; no package is published by this handoff.
272
+ **Decision: GO after protected operator prerequisites below.** Phase 10 closes provider, memory, and RAG ecosystem parity without changing the Task 0 package freeze: the exact graph remains **43 publishable manifests**. It adds OpenAI hosted-tool attribution, bounded Responses continuation and Realtime; exact AI SDK V4 mapping; bounded RAG source lifecycle/document adapters/reranking/provenance/trust/status; and memory export/rebuild production conformance. No Studio, Office, remote-browser vendor, additional vector-store, Slack/Teams, voice/desktop-control, internal-auth, or queue package ships. Phase 11 (plan 079, Task 3) adds one internal implementation package, `@arnilo/prism-session-store-codecs` (shared session-store row codecs, not enrolled in any family), bringing the exact graph to **44 publishable manifests**. Protected CI, signed tag, npm authentication, OIDC attestation, and protected live-canary evidence remain operator/workflow prerequisites; no package is published by this handoff.
223
273
 
224
274
  ```bash
225
275
  git diff --check
@@ -304,6 +354,7 @@ Package set (43):
304
354
  @arnilo/prism-provider-zai
305
355
  @arnilo/prism-rag
306
356
  @arnilo/prism-server
357
+ @arnilo/prism-session-store-codecs
307
358
  @arnilo/prism-session-store-postgres
308
359
  @arnilo/prism-session-store-sqlite
309
360
  @arnilo/prism-supervisor
@@ -721,7 +772,7 @@ npm publication is not transactional and published versions are immutable. Parti
721
772
 
722
773
  ## Extension and configuration notes
723
774
 
724
- - **Required `@arnilo/prism` peer.** Every first-party code package declares a non-optional `@arnilo/prism@0.0.15` peer (`peerDependenciesMeta` must not mark `@arnilo/prism` optional; other peers such as `playwright-core` may be optional). The range stays pinned to `0.0.15` for the current 0.x release and will widen to `^1.0.0` at the 1.x stable release. Inside the workspace each package also declares `"@arnilo/prism": "file:../.."` in `devDependencies` so `npm install` resolves the peer locally; that devDependency is stripped from consumer installs and is not a runtime dependency.
775
+ - **Required `@arnilo/prism` peer.** Every first-party code package declares a non-optional `@arnilo/prism@0.0.17` peer (`peerDependenciesMeta` must not mark `@arnilo/prism` optional; other peers such as `playwright-core` may be optional). The range stays pinned to `0.0.17` for the current 0.x release and will widen to `^1.0.0` at the 1.x stable release. Inside the workspace each package also declares `"@arnilo/prism": "file:../.."` in `devDependencies` so `npm install` resolves the peer locally; that devDependency is stripped from consumer installs and is not a runtime dependency.
725
776
  - **Public access.** All 43 manifests (37 code packages + 6 family/profile packages) declare `"publishConfig": { "access": "public" }`; the publisher also passes `--access public` explicitly because scoped packages otherwise default to restricted on first publish.
726
777
  - **Map retention knob.** Source maps are emitted locally but stripped from tarballs by `!dist/**/*.map`. Removing that `files` negation ships maps in releases (larger tarballs, better consumer stack traces).
727
778
  - **Release workflow.** `.github/workflows/release.yml` has six jobs. `verify` runs network-free SDK readiness on Node 24; `node20-compat` builds/imports every public root `exports` default target on Node 20 for declared `engines.node >=20` (docs examples need Node >=22.6 native TypeScript stripping); `postgres-integration` uses `pgvector/pgvector:pg16`; `supply-chain` runs high-severity audit, SPDX/license policy, and tracked-source secret scanning; and tag-only `codeql-release` runs SAST. Tag-only `publish` needs all five gates, preserves clean exact-tag/version/topological publication, and alone receives `NPM_TOKEN`, `id-token: write`, and `attestations: write`. Before npm publish it packs all current tarballs, generates checksums plus SPDX, scans unpacked public artifacts, creates GitHub attestations for tarballs and SBOM, then retains artifacts for 30 days. Registry state remains the resumable journal. Local `npm run release:dry-run` remains network-free SDK readiness; local PostgreSQL coverage is `PRISM_TEST_POSTGRES_URL=... npm run test:postgres`.
@@ -782,9 +833,56 @@ A deleted tracked feature-request markdown was intentionally not restored by rel
782
833
  | Registry/order | Public `release:check` found all 34 `@arnilo/*@0.0.11` versions available. Dependency-ordered `release:publish --dry-run --allow-dirty --allow-untagged` completed 34/34 dry-run with explicit public/latest/provenance; no commit, tag, or publication created. |
783
834
 
784
835
 
836
+ ## Formatting, linting, and coverage
837
+
838
+ Prism uses one tool for formatting and linting — [Biome](https://biomejs.dev) — configured once at the repo root (`biome.json`) and inherited by every workspace. Coverage uses Node's built-in test coverage; there is no third-party coverage service.
839
+
840
+ | Command | What it does |
841
+ | --- | --- |
842
+ | `npm run lint` | `biome lint .` — fails on any lint error (warnings are non-fatal). |
843
+ | `npm run format:check` | `biome format .` — fails if any file is unformatted. |
844
+ | `npm run format` | `biome format --write .` — normalizes formatting in place. |
845
+ | `npm run test:coverage` | `node --test --experimental-test-coverage` over the core suite with enforced minimums: **lines 60%**, **functions 70%**, **branches 75%** (current baseline ≈ 64 / 72 / 79). Excludes `__tests__/`, `node_modules/`, and `scripts/` from the report. |
846
+
847
+ All four gates run inside `npm run sdk:ready` (after `typecheck`, before `pack:dry-run`). A few rules are disabled in `biome.json` because they are false positives for this codebase: `noControlCharactersInRegex` and `noAssignInExpressions` (security/redaction code intentionally matches control characters and uses `while ((m = re.exec(…)))` loops), `noShadowRestrictedNames`, `noThenProperty` (the workflow DSL has a legitimate `then` branch field), `noExplicitAny`, `noVoidTypeReturn`, and `useYield`. Raise the coverage thresholds in `package.json` `test:coverage` as the baseline climbs.
848
+
849
+ ## Dependency major-upgrade isolation
850
+
851
+ Major dependency upgrades are **isolated, compatibility-tested changes — never bundled into a feature release.** A major bump (TypeScript, `@types/node`, `diff`, or any third-party runtime dependency and its successors) ships as its own commit/PR that runs `npm run sdk:ready` plus packed-install evidence, and is reviewed separately from feature work. Release commits contain no unreviewed major bumps.
852
+
853
+ **Current third-party upgrade surface** (internal `@arnilo/prism-*` ranges are version-managed by the release tooling, not dependency upgrades; the core `@arnilo/prism` package has **zero** runtime dependencies, asserted by `core-boundaries.test.ts`):
854
+
855
+ | Dependency | Range | Resolved (lockfile) | Used by |
856
+ | --- | --- | --- | --- |
857
+ | `typescript` (dev) | `^7.0.2` | 7.0.2 | root build |
858
+ | `@types/node` (dev) | `^26.1.1` | 26.1.1 | root build |
859
+ | `@biomejs/biome` (dev) | `^2.5.5` | 2.5.5 | lint/format (Task 6) |
860
+ | `diff` | `^9.0.0` | 9.0.0 | `@arnilo/prism-coding-agent` |
861
+ | `pg` | `^8.22.0` | 8.22.0 | `@arnilo/prism-memory`, `@arnilo/prism-session-store-postgres` |
862
+ | `better-sqlite3` | `^12.11.1` | 12.11.1 | `@arnilo/prism-session-store-sqlite` |
863
+ | `ajv` | `^8.17.1` | 8.20.0 | `@arnilo/prism-tool-validator-json-schema` |
864
+ | `zod` | `^4.4.3` | 4.4.3 | `@arnilo/prism-mcp` |
865
+ | `@napi-rs/keyring` | `^1.3.0` | 1.3.0 | `@arnilo/prism-credentials-node` |
866
+ | `@modelcontextprotocol/sdk` | `1.29.0` | 1.29.0 | `@arnilo/prism-mcp` |
867
+ | `@ag-ui/core` | `0.0.57` | 0.0.57 | `@arnilo/prism-ag-ui` |
868
+ | `@agentclientprotocol/sdk` | `1.3.0` | 1.3.0 | `@arnilo/prism-ag-ui` |
869
+
870
+ **Recorded compatibility matrix (2026-07-26, release 0.0.16):**
871
+
872
+ | Leg | Node | Result |
873
+ | --- | --- | --- |
874
+ | Full SDK readiness (`npm run sdk:ready`: typecheck, lint, format, test, coverage, pack, release:gate) | 24.18.0 (current) | ✅ green — 1312/1312 tests, lint 0 errors, format clean, coverage 64/72/79 vs 60/70/75 thresholds. |
875
+ | Build toolchain (`tsc` 7.0.2, `biome` 2.5.5) | 20.20.2 (LTS iron) | ✅ both run under Node 20. |
876
+ | Public surface import smoke (all 21 root `exports` default targets) | 20.20.2 | ✅ all import cleanly. |
877
+ | Full core test suite | 20.20.2 | 1311/1312 — the single failure is `examples_demos_run_to_completion_and_emit_no_secret`, which executes `examples/*.ts` via Node's native TypeScript stripping (Node 22.6+). This is a test-harness capability, not an SDK runtime incompatibility, and is exactly why CI scopes Node 20 to build + import smoke. |
878
+
879
+ **CI enforcement** (`.github/workflows/release.yml`): the `verify` job runs `npm run sdk:ready` on Node 24; `node20-compat` runs `npm ci`, `npm run build`, and the public-import smoke on Node 20; `supply-chain` runs audit, SPDX/license checks, SBOM, and source-secret scans; `publish` `needs:` all of `verify`, `node20-compat`, `postgres-integration`, `codeql-release`, and `supply-chain`, so nothing publishes unless every leg — including the audit/SBOM gates — passes.
880
+
881
+ **Process for a major-upgrade PR:** (1) bump exactly one dependency major in its own branch; (2) `npm run sdk:ready` green; (3) packed-install evidence (`npm run pack:dry-run`, or a scratch `npm install <tarball>` import smoke for native deps like `better-sqlite3`); (4) review lockfile churn line-by-line; (5) the `supply-chain` job supplies audit/SBOM; (6) confirm no build-time regression beyond measured noise on the matrix above; (7) merge separately from any feature work.
882
+
785
883
  ## Release checklist
786
884
 
787
- Every release gate maps to an exact enforcement test or command, so the checklist is executable rather than manual. Run `npm run sdk:ready` for the full local SDK readiness gate: `npm run typecheck`, network-free `npm test`, and `npm run pack:dry-run`. `npm run release:dry-run` is an alias for the same gate. The GitHub Actions `verify` job runs `npm ci` and `npm run sdk:ready` on Node 24; `node20-compat` runs `npm ci`, `npm run build`, and public export imports on Node 20; `postgres-integration` runs the opt-in PostgreSQL adapter suite against a CI Postgres service.
885
+ Every release gate maps to an exact enforcement test or command, so the checklist is executable rather than manual. Run `npm run sdk:ready` for the full local SDK readiness gate: `npm run typecheck`, `npm run lint`, `npm run format:check`, network-free `npm test`, `npm run test:coverage`, `npm run pack:dry-run`, and `npm run release:gate`. `npm run release:dry-run` is an alias for the same gate. The GitHub Actions `verify` job runs `npm ci` and `npm run sdk:ready` on Node 24; `node20-compat` runs `npm ci`, `npm run build`, and public export imports on Node 20; `postgres-integration` runs the opt-in PostgreSQL adapter suite against a CI Postgres service.
788
886
 
789
887
  | Gate | Enforcement |
790
888
  | --- | --- |
@@ -797,12 +895,24 @@ Every release gate maps to an exact enforcement test or command, so the checklis
797
895
  | Tarball excludes built tests, source maps, and source | `packaging.test.ts` rejects `dist/__tests__/`, `*.map`, `src/`, `plans/`, and internal files; confirms every package ships README/changelog (and code packages ship LICENSE), core ships docs + CLI, exported targets exist (`dist/index.js` + `dist/index.d.ts` for NeuralWatt), and `prism-all` transitively reaches all 32 published first-party manifests. |
798
896
  | NeuralWatt package/docs/examples release gate | `packaging.test.ts` pins `@arnilo/prism-provider-neuralwatt` package exports/type declarations and `@arnilo/prism-providers`/`@arnilo/prism-all` membership; `docs.test.ts` asserts `docs/index.md` links `providers/neuralwatt.md` and `provider-caching.md`, and that `examples/cache-aware-prompt-assembly.ts` plus `examples/neuralwatt-agent-run.ts` exist and are listed. |
799
897
  | Version graph and resumable publication | `release.test.ts` covers exact package/lock/range validation, topological order, registry collisions, dry-run, interrupted reports/resume, clean tagged git state, provenance/public/tag arguments, and token-safe errors. `release:check` and `release:publish` derive the workspace graph without a manual package list. |
898
+ | Pre-publish compatibility gates | `release:gate` (in `sdk:ready`) fails on removed/changed `.d.ts` exports vs `scripts/compat-baseline/` (unless `--allow-break` + migration note), version-range/lockfile drift, and tarball deny-list violations (`plans/`, `code-reviews/`, `docs/review-coverage-*`, `*.map`, `__tests__/`); unit-tested in `scripts/release-gate.test.mjs`. |
899
+ | Formatting, linting, and coverage thresholds | `npm run lint` and `npm run format:check` run Biome (single root `biome.json`, workspaces inherit) and fail on any lint error or unformatted file; `npm run test:coverage` uses Node's built-in `--experimental-test-coverage` with enforced minimums (lines 60 / functions 70 / branches 75) and no third-party service. All three run inside `sdk:ready`. |
800
900
  | Supply-chain and live-canary policy | `supply-chain-security.test.ts` verifies SPDX allow/deny behavior, bounded source/artifact secret detection, credential-free canary reports, timeout/redacted failures, immutable action revisions, no `pull_request_target`, protected live environment, attestation paths, and publish dependency on `supply-chain`; CI adds CodeQL and PR dependency review. |
801
901
  | Network-free + offline test budget | `network-free-guard.test.ts` keeps the default suite network-free; budget pinned `< 60s` (measured baseline above). Install-smoke is offline (`--offline --no-audit --no-fund`, zero registry fetches). |
802
902
  | Core security invariants reaffirmed | Runtime/docs tests hold the trust boundary: **no built-in app tools** (hosts register tools; the core ships only the mock provider and contract helpers), **no hidden provider/credential globals** (providers/credentials are host-owned `AgentConfig` fields, resolved via explicit `providerSource`/`CredentialResolver`), **no auto package discovery** (provider/tool/skill packages are opt-in and individually installed; contribution discovery is realpath-contained and emits inert envelopes the host registers), and **no secret persistence in core** (redaction applies before any `RunLedger`/`SessionStore` append; the ledger gate asserts each message event is written exactly once and redacted). |
803
903
 
804
904
  A change that adds a public persistence/runtime surface, a new package, or a new example must extend the matching row's enforcement (add the page to `apiPages`, the package to the `packages` array, or the example to the demos list) so the checklist stays self-maintaining.
805
905
 
906
+ ## Pre-publish compatibility gates (`release:gate`)
907
+
908
+ `npm run release:gate` (also run inside `npm run sdk:ready`) is the offline gate that must pass before `release:check`/`release:publish`. It runs three stages over the exact version graph (version defaults to the root manifest; no git or registry access):
909
+
910
+ - **ranges**: reuses `validateRelease` — exact internal version ranges and lockfile entries.
911
+ - **compat**: diffs every package's packed `.d.ts` surface (exported names + normalized declaration signatures, `export *` resolved within the package) against `scripts/compat-baseline/<pkg>.txt`. Removed or changed exports fail unless `--allow-break` is passed **and** `docs/migration.md` mentions the target version. Manifest-only profiles (no `main`/`types`/`exports`) are skipped. Regenerate baselines after a deliberate reviewed change with `node scripts/release.mjs gate --update-baseline`.
912
+ - **tarball**: `npm pack --dry-run --json` file lists must not match the deny list (`code-reviews/`, `bug-reports/`, `plans/`, `scripts/benchmark-*`, `docs/review-coverage-*`, `__tests__/`, `*.map`). Root `files` excludes `docs/review-coverage-*` historical reviews.
913
+
914
+ Gate behavior is unit-tested in `scripts/release-gate.test.mjs`. Signature diff is name + normalized first-declaration-line level; full structural `.d.ts` diffing (api-extractor or equivalent) is the recorded upgrade path if line-level proves insufficient.
915
+
806
916
  ## Related APIs
807
917
 
808
918
  - [`docs/provider-packages.md`](provider-packages.md): first-party provider package layout and setup.
@@ -100,7 +100,7 @@ await store.append(entry, options);
100
100
  }
101
101
  ```
102
102
 
103
- Recognize it with `isSessionAppendConflict(error)`, not message text. Built-in stores reject duplicate entry ids, dangling `expectedParentId` values, and exact idempotency retries. They allow two distinct children of the same existing parent because that is a branch/fork, not parent-order corruption. Production stores may add a stricter branch-tip compare-and-swap when a host wants one-writer linear branches.
103
+ Recognize it with `isSessionAppendConflict(error)`, not message text. Built-in stores reject duplicate entry ids, dangling `expectedParentId` values, and `expectedParentId` pointing at another session's entry (the parent must exist in the same session — a cross-session parent would be a write no per-session branch walk could read back), and exact idempotency retries. They allow two distinct children of the same existing parent because that is a branch/fork, not parent-order corruption. Production stores may add a stricter branch-tip compare-and-swap when a host wants one-writer linear branches.
104
104
 
105
105
  ## Extension and configuration notes
106
106
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arnilo/prism",
3
- "version": "0.0.15",
3
+ "version": "0.0.17",
4
4
  "description": "Agent harness for AI providers, agents, sessions, and tools.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -99,6 +99,7 @@
99
99
  "!dist/__tests__",
100
100
  "!dist/**/*.map",
101
101
  "docs",
102
+ "!docs/review-coverage-*",
102
103
  "templates",
103
104
  "CHANGELOG.md"
104
105
  ],
@@ -128,19 +129,26 @@
128
129
  ],
129
130
  "scripts": {
130
131
  "build:core": "tsc",
131
- "build": "npm run build:core && npm run build --workspaces --if-present",
132
+ "clean": "rm -rf dist packages/*/dist",
133
+ "build": "npm run clean && npm run build:core && npm run build --workspaces --if-present",
132
134
  "typecheck": "npm run build && npm run typecheck --workspaces --if-present && tsc -p examples --noEmit",
133
- "test": "npm run build && node --test dist/__tests__/*.test.js && npm run test --workspaces --if-present",
135
+ "test": "npm run build && node --test dist/__tests__/*.test.js && node --test scripts/release-gate.test.mjs scripts/tooling-gate.test.mjs scripts/budget-gate.test.mjs && npm run test --workspaces --if-present",
136
+ "test:coverage": "node --test --experimental-test-coverage --test-coverage-lines=60 --test-coverage-functions=70 --test-coverage-branches=75 --test-coverage-exclude='**/__tests__/**' --test-coverage-exclude='**/node_modules/**' --test-coverage-exclude='**/scripts/**' dist/__tests__/*.test.js",
137
+ "lint": "biome lint .",
138
+ "format": "biome format --write .",
139
+ "format:check": "biome format .",
134
140
  "pack:dry-run": "npm pack --dry-run && npm run pack:dry-run --workspaces --if-present",
135
141
  "test:postgres": "npm run test:postgres --workspace @arnilo/prism-session-store-postgres && npm run test:postgres --workspace @arnilo/prism-memory",
136
142
  "release:dry-run": "npm run sdk:ready",
137
143
  "release:check": "node scripts/release.mjs check",
138
144
  "release:publish": "node scripts/release.mjs publish",
139
- "sdk:ready": "npm run typecheck && npm test && npm run pack:dry-run"
145
+ "sdk:ready": "npm run typecheck && npm run lint && npm run format:check && npm test && npm run test:coverage && npm run pack:dry-run && npm run release:gate",
146
+ "release:gate": "node scripts/release.mjs gate"
140
147
  },
141
148
  "devDependencies": {
142
- "typescript": "^7.0.2",
143
- "@types/node": "^26.1.1"
149
+ "@biomejs/biome": "^2.5.5",
150
+ "@types/node": "^26.1.1",
151
+ "typescript": "^7.0.2"
144
152
  },
145
153
  "engines": {
146
154
  "node": ">=20"