@arnilo/prism 0.5.4 → 0.5.6

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 (41) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +10 -10
  3. package/dist/cli-runner.d.ts +8 -1
  4. package/dist/cli-runner.js +97 -7
  5. package/dist/extensions.d.ts +18 -1
  6. package/dist/extensions.js +10 -0
  7. package/dist/index.d.ts +3 -3
  8. package/dist/index.js +2 -2
  9. package/dist/run-limits.js +7 -2
  10. package/docs/cli-rpc.md +15 -1
  11. package/docs/credential-storage.md +1 -1
  12. package/docs/extension-authoring.md +8 -9
  13. package/docs/extensions.md +13 -1
  14. package/docs/graft.md +27 -5
  15. package/docs/{0.1.0-readiness.md → history/0.1.0-readiness.md} +6 -6
  16. package/docs/history/README.md +11 -0
  17. package/docs/{migrate-to-0.4.md → history/migrate-to-0.4.md} +4 -4
  18. package/docs/history/migration-0.0.md +738 -0
  19. package/docs/history/migration-0.1.md +151 -0
  20. package/docs/history/migration-0.2.md +173 -0
  21. package/docs/history/migration-0.3.md +39 -0
  22. package/docs/history/migration-0.4.md +6 -0
  23. package/docs/{persistence-credentials-multimodality-primitives.md → history/persistence-credentials-multimodality-primitives.md} +13 -13
  24. package/docs/history/release-handoffs.md +848 -0
  25. package/docs/{workflow-orchestration-primitives.md → history/workflow-orchestration-primitives.md} +11 -11
  26. package/docs/host-security.md +1 -1
  27. package/docs/index.md +160 -143
  28. package/docs/migrate-to-0.5.md +1 -1
  29. package/docs/migration.md +15 -1042
  30. package/docs/multimodal-content.md +1 -1
  31. package/docs/performance.md +1 -1
  32. package/docs/postgres-persistence.md +1 -1
  33. package/docs/provider-packages.md +20 -20
  34. package/docs/release-and-install.md +57 -842
  35. package/docs/runs-and-usage.md +2 -2
  36. package/docs/session-stores-and-branching.md +1 -122
  37. package/docs/sqlite-persistence.md +1 -1
  38. package/docs/wiki.md +46 -2
  39. package/docs/workflows.md +1 -1
  40. package/package.json +1 -1
  41. /package/docs/{workflow-tui-primitives.md → history/workflow-tui-primitives.md} +0 -0
@@ -1,8 +1,11 @@
1
1
  # Release and install
2
2
 
3
+ > Release-by-release publish handoffs (0.0.x–0.4.x) moved to [history/release-handoffs.md](history/release-handoffs.md).
4
+
3
5
  ## What it does
4
6
 
5
- Prism's current **0.5.x** line has **10 publishable manifests**: the root `@arnilo/prism` core package plus **9 workspace packages** — **19 provider adapters** (19 provider adapter subpaths inside the `@arnilo/prism-providers` family), 3 `prism-*` family/profile packages, and 6 capability packages. (Generated by `node scripts/package-truth.mjs` → `scripts/package-truth.json` — the manifest-derived single source for counts, provider membership, umbrella closures, and profile closures.) The last lockstep cut was 0.3.0; Decision B now publishes changed packages independently inside `^0.3.0` — the plan 039 changed-package cut moved root `@arnilo/prism` and every plan-035+ changed package to **0.3.1**, and the plan 050 changed-package cut moved root plus four changed packages to **0.3.2**; the plan 041-044 changed-package cut moves root to **0.3.3** with `@arnilo/prism-memory@0.3.2` (composite recall scoring), `@arnilo/prism-evals@0.3.1` (trace-to-dataset curation), the three session-store packages at **0.3.1** (run-ledger `promptVersion` provenance), and the initial `@arnilo/prism-prompts@0.0.1` (independent opt-in, outside `prism-all`); plan 054 consolidation then folded `@arnilo/prism-browser` and `@arnilo/prism-obscura` into the `@arnilo/prism-web-tools` family as `/browser` and `/obscura` subpaths, folded `@arnilo/prism-rag`, both compaction strategies, `@arnilo/prism-graft`, and `@arnilo/prism-wiki` into the `@arnilo/prism-memory` family as `/rag`, `/compaction/llm`, `/compaction/observational-memory`, `/graft`, and `/wiki` subpaths (deleting the `@arnilo/prism-compaction` profile), and folded all 17 `@arnilo/prism-provider-*` packages into the `@arnilo/prism-providers` family as `/<adapter>` subpaths (Azure/Bedrock/Vertex stop being special all-only manifests); independent publication continues inside `^0.3.0` ranges (which satisfy 0.3.1, 0.3.2, and 0.3.3). This page describes how they are packed, what each tarball contains, how to install them, the required non-optional **caret** `@arnilo/prism@^0.5.4` peer range, 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).
7
+
8
+ Prism's current **0.5.x** line has **10 publishable manifests**: the root `@arnilo/prism` core package plus **9 workspace packages** — **19 provider adapters** (19 provider adapter subpaths inside the `@arnilo/prism-providers` family), 3 `prism-*` family/profile packages, and 6 capability packages. (Generated by `node scripts/package-truth.mjs` → `scripts/package-truth.json` — the manifest-derived single source for counts, provider membership, umbrella closures, and profile closures.) The last lockstep cut was 0.3.0; Decision B now publishes changed packages independently inside `^0.3.0` — the plan 039 changed-package cut moved root `@arnilo/prism` and every plan-035+ changed package to **0.3.1**, and the plan 050 changed-package cut moved root plus four changed packages to **0.3.2**; the plan 041-044 changed-package cut moves root to **0.3.3** with `@arnilo/prism-memory@0.3.2` (composite recall scoring), `@arnilo/prism-evals@0.3.1` (trace-to-dataset curation), the three session-store packages at **0.3.1** (run-ledger `promptVersion` provenance), and the initial `@arnilo/prism-prompts@0.0.1` (independent opt-in, outside `prism-all`); plan 054 consolidation then folded `@arnilo/prism-browser` and `@arnilo/prism-obscura` into the `@arnilo/prism-web-tools` family as `/browser` and `/obscura` subpaths, folded `@arnilo/prism-rag`, both compaction strategies, `@arnilo/prism-graft`, and `@arnilo/prism-wiki` into the `@arnilo/prism-memory` family as `/rag`, `/compaction/llm`, `/compaction/observational-memory`, `/graft`, and `/wiki` subpaths (deleting the `@arnilo/prism-compaction` profile), and folded all 17 `@arnilo/prism-provider-*` packages into the `@arnilo/prism-providers` family as `/<adapter>` subpaths (Azure/Bedrock/Vertex stop being special all-only manifests); independent publication continues inside `^0.3.0` ranges (which satisfy 0.3.1, 0.3.2, and 0.3.3). This page describes how they are packed, what each tarball contains, how to install them, the required non-optional **caret** `@arnilo/prism@^0.5.6` peer range, the release workflow, and the offline test budget. The measurable 1.0 readiness gates (command-per-gate) live in [`0.1.0-readiness.md`](history/./0.1.0-readiness.md).
6
9
 
7
10
  Core `@arnilo/prism` ships runtime, CLI, templates, and docs. Every code package has a required `@arnilo/prism` peer inside the Decision B window — the caret current spec is `@arnilo/prism@^0.3.3` and every declared window peer satisfies it: packages republishing in the plan 050 cut carry `^0.3.2`; the plan 039 set keeps `^0.3.1`; unchanged packages keep their `^0.3.0` peer; profiles are pure manifests. The plan 050 republished set declares the required `@arnilo/prism@^0.3.2` peer; the plan 041-044 republished set keeps its existing `^0.3.0` window peer; unchanged packages keep their prior window. Installation activates no provider, listener, database, browser, credential, or tool capability.
8
11
 
@@ -11,16 +14,16 @@ Core `@arnilo/prism` ships runtime, CLI, templates, and docs. Every code package
11
14
 
12
15
  | package | version | notes |
13
16
  | --- | --- | --- |
14
- | `@arnilo/prism` | 0.5.4 | core — runtime, CLI/RPC, templates, docs |
15
- | `@arnilo/prism-coding-tools` | 0.5.4 | family — /agent, /security, /document-reader, /openapi, /computer-use-linux, /dev, /caveman, /ponytail, /impeccable subpaths |
16
- | `@arnilo/prism-core` | 0.5.4 | family — /runtime, /sessions, /governance, /credentials, /enterprise, /work, /validation subpaths |
17
- | `@arnilo/prism-providers` | 0.5.4 | family — all provider adapters as `/<adapter>` subpaths |
18
- | `@arnilo/prism-acp-agent` | 0.5.4 | capability — ACP adapter |
19
- | `@arnilo/prism-ag-ui` | 0.5.4 | capability — AG-UI/A2A/A2UI adapter |
20
- | `@arnilo/prism-mcp` | 0.5.4 | capability — MCP client/server/OAuth interop |
21
- | `@arnilo/prism-memory` | 0.5.4 | capability — memory plus /rag, /compaction/*, /graft, /wiki subpaths |
22
- | `@arnilo/prism-office` | 0.5.4 | capability — /documents, /sheets, /diagrams subpaths |
23
- | `@arnilo/prism-web-tools` | 0.5.4 | capability — Brave/Exa/Firecrawl plus peer-gated /browser and /obscura subpaths |
17
+ | `@arnilo/prism` | 0.5.6 | core — runtime, CLI/RPC, templates, docs |
18
+ | `@arnilo/prism-coding-tools` | 0.5.6 | family — /agent, /security, /document-reader, /openapi, /computer-use-linux, /dev, /caveman, /ponytail, /impeccable subpaths |
19
+ | `@arnilo/prism-core` | 0.5.6 | family — /runtime, /sessions, /governance, /credentials, /enterprise, /work, /validation subpaths |
20
+ | `@arnilo/prism-providers` | 0.5.6 | family — all provider adapters as `/<adapter>` subpaths |
21
+ | `@arnilo/prism-acp-agent` | 0.5.6 | capability — ACP adapter |
22
+ | `@arnilo/prism-ag-ui` | 0.5.6 | capability — AG-UI/A2A/A2UI adapter |
23
+ | `@arnilo/prism-mcp` | 0.5.6 | capability — MCP client/server/OAuth interop |
24
+ | `@arnilo/prism-memory` | 0.5.6 | capability — memory plus /rag, /compaction/*, /graft, /wiki subpaths |
25
+ | `@arnilo/prism-office` | 0.5.6 | capability — /documents, /sheets, /diagrams subpaths |
26
+ | `@arnilo/prism-web-tools` | 0.5.6 | capability — Brave/Exa/Firecrawl plus peer-gated /browser and /obscura subpaths |
24
27
  <!-- generated:package-truth:inventory end -->
25
28
 
26
29
 
@@ -29,26 +32,26 @@ Core `@arnilo/prism` ships runtime, CLI, templates, and docs. Every code package
29
32
 
30
33
  | adapter package | version |
31
34
  | --- | --- |
32
- | `@arnilo/prism-providers/ai-sdk` | 0.5.4 |
33
- | `@arnilo/prism-providers/alibaba` | 0.5.4 |
34
- | `@arnilo/prism-providers/anthropic` | 0.5.4 |
35
- | `@arnilo/prism-providers/azure` | 0.5.4 |
36
- | `@arnilo/prism-providers/bedrock` | 0.5.4 |
37
- | `@arnilo/prism-providers/clinepass` | 0.5.4 |
38
- | `@arnilo/prism-providers/commandcode` | 0.5.4 |
39
- | `@arnilo/prism-providers/deepseek` | 0.5.4 |
40
- | `@arnilo/prism-providers/google` | 0.5.4 |
41
- | `@arnilo/prism-providers/hyper` | 0.5.4 |
42
- | `@arnilo/prism-providers/kimi` | 0.5.4 |
43
- | `@arnilo/prism-providers/model-discovery` | 0.5.4 |
44
- | `@arnilo/prism-providers/neuralwatt` | 0.5.4 |
45
- | `@arnilo/prism-providers/ollama` | 0.5.4 |
46
- | `@arnilo/prism-providers/openai` | 0.5.4 |
47
- | `@arnilo/prism-providers/opencode-go` | 0.5.4 |
48
- | `@arnilo/prism-providers/openrouter` | 0.5.4 |
49
- | `@arnilo/prism-providers/vertex` | 0.5.4 |
50
- | `@arnilo/prism-providers/xai` | 0.5.4 |
51
- | `@arnilo/prism-providers/zai` | 0.5.4 |
35
+ | `@arnilo/prism-providers/ai-sdk` | 0.5.6 |
36
+ | `@arnilo/prism-providers/alibaba` | 0.5.6 |
37
+ | `@arnilo/prism-providers/anthropic` | 0.5.6 |
38
+ | `@arnilo/prism-providers/azure` | 0.5.6 |
39
+ | `@arnilo/prism-providers/bedrock` | 0.5.6 |
40
+ | `@arnilo/prism-providers/clinepass` | 0.5.6 |
41
+ | `@arnilo/prism-providers/commandcode` | 0.5.6 |
42
+ | `@arnilo/prism-providers/deepseek` | 0.5.6 |
43
+ | `@arnilo/prism-providers/google` | 0.5.6 |
44
+ | `@arnilo/prism-providers/hyper` | 0.5.6 |
45
+ | `@arnilo/prism-providers/kimi` | 0.5.6 |
46
+ | `@arnilo/prism-providers/model-discovery` | 0.5.6 |
47
+ | `@arnilo/prism-providers/neuralwatt` | 0.5.6 |
48
+ | `@arnilo/prism-providers/ollama` | 0.5.6 |
49
+ | `@arnilo/prism-providers/openai` | 0.5.6 |
50
+ | `@arnilo/prism-providers/opencode-go` | 0.5.6 |
51
+ | `@arnilo/prism-providers/openrouter` | 0.5.6 |
52
+ | `@arnilo/prism-providers/vertex` | 0.5.6 |
53
+ | `@arnilo/prism-providers/xai` | 0.5.6 |
54
+ | `@arnilo/prism-providers/zai` | 0.5.6 |
52
55
  <!-- generated:package-truth:providers end -->
53
56
 
54
57
 
@@ -56,12 +59,14 @@ Core ships `dist`, docs, templates, and `CHANGELOG.md`; code packages ship compi
56
59
 
57
60
  ## When to use it
58
61
 
62
+
59
63
  Use this page when installing Prism into a host app, when adding a first-party package, when cutting a release, or when investigating why a tarball contains (or excludes) a file.
60
64
 
61
65
  Consumers install the core package for the runtime and add first-party packages for provider adapters or compaction strategies. Each first-party package requires the `@arnilo/prism` peer at its declared version; install `@arnilo/prism` alongside them or npm will report an unmet peer.
62
66
 
63
67
  ## Inputs / request
64
68
 
69
+
65
70
  | Operation | Command |
66
71
  | --- | --- |
67
72
  | Install core only | `npm install @arnilo/prism` |
@@ -131,13 +136,14 @@ Run `npm run clean` explicitly after deleting source files or switching branches
131
136
 
132
137
  ## Outputs / response / events
133
138
 
139
+
134
140
  A packed tarball contains only public compiled output and release files:
135
141
 
136
142
  - `dist/**` compiled `.js` and `.d.ts` for every exported subpath.
137
143
  - Code packages ship `README.md`, `LICENSE`, and `CHANGELOG.md`; family/profile packages ship `README.md` and `CHANGELOG.md`.
138
144
  - The core tarball additionally ships the full `docs/` directory (the docs hub), `templates/init/`, and the `templates/` gallery (e.g. `deep-research`) used by `prism init`.
139
145
  - `dist/cli.js` and the `bin` link in core.
140
- - **Tarball filenames.** npm strips the `@scope/` prefix, so the core package `@arnilo/prism` produces a tarball named `arnilo-prism-0.5.4.tgz`; family packages produce `arnilo-prism-core-0.5.4.tgz`, `arnilo-prism-coding-tools-0.5.4.tgz`, `arnilo-prism-providers-0.5.4.tgz` (all 19 adapters inside), `arnilo-prism-memory-0.5.4.tgz`, `arnilo-prism-web-tools-0.5.4.tgz`, and `arnilo-prism-office-0.5.4.tgz`; capability packages like `arnilo-prism-mcp-0.5.4.tgz` carry their own package version. Independent-package tags carry their own version. 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).
146
+ - **Tarball filenames.** npm strips the `@scope/` prefix, so the core package `@arnilo/prism` produces a tarball named `arnilo-prism-0.5.6.tgz`; family packages produce `arnilo-prism-core-0.5.6.tgz`, `arnilo-prism-coding-tools-0.5.6.tgz`, `arnilo-prism-providers-0.5.6.tgz` (all 19 adapters inside), `arnilo-prism-memory-0.5.6.tgz`, `arnilo-prism-web-tools-0.5.6.tgz`, and `arnilo-prism-office-0.5.6.tgz`; capability packages like `arnilo-prism-mcp-0.5.6.tgz` carry their own package version. Independent-package tags carry their own version. 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).
141
147
 
142
148
  Excluded from every tarball by `files` negation:
143
149
 
@@ -149,9 +155,9 @@ Excluded from every tarball by `files` negation:
149
155
 
150
156
  `prism init` generates a private TypeScript project. The default dependency set for standard `init` is only `@arnilo/prism` (plus TypeScript tooling as `devDependencies`). Provider and `--with-workflows` / `--with-evals` flags add only the selected optional packages. Using `--template deep-research` scaffolds a multi-step research agent wired with `@arnilo/prism-web-tools`, `@arnilo/prism-memory`, and `@arnilo/prism-core/runtime/workflows`. All templates ship inside the `@arnilo/prism` tarball (`templates/`), have zero credentials at init, contain no postinstall scripts, and pass secret scans. Measured default clean install is ~27.5 MB versus the Mastra scaffold baseline of 439 MB.
151
157
 
152
-
153
158
  ## Request/response example
154
159
 
160
+
155
161
  ```json
156
162
  {
157
163
  "name": "host-app",
@@ -174,6 +180,7 @@ npm error peer @arnilo/prism@"^0.5.1" from @arnilo/prism-providers/openai@0.5.1
174
180
 
175
181
  ## Implementation example
176
182
 
183
+
177
184
  ```ts
178
185
  import { createAgent, createAgentSession, type ModelConfig } from "@arnilo/prism";
179
186
  import { createOpenAICompatibleProvider } from "@arnilo/prism/providers/openai-compatible";
@@ -209,157 +216,9 @@ npm run release:check -- --allow-dirty --allow-untagged
209
216
  npm run release:publish -- --dry-run --allow-dirty --allow-untagged
210
217
  ```
211
218
 
212
- ### 0.3.2 independent workflow patch (plan 045)
213
-
214
- `@arnilo/prism-workflows@0.3.2` is the independent bounded-loop release: durable iteration checkpoints, tool-body resume, replay events, redaction/bounds, and the frozen `maxNodes`/`maxIterations` accounting rule. The root remains `@arnilo/prism@0.3.3`; no generic checkpoint-store or SQL migration is required. Publish from a clean commit tagged `@arnilo/prism-workflows@0.3.2` after the independent release gate; local preview is:
215
-
216
- ```bash
217
- npm run release:check -- --allow-dirty --allow-untagged
218
- npm run release:publish -- --dry-run --allow-dirty --allow-untagged
219
- ```
220
-
221
- Rollback restores `@arnilo/prism-workflows@0.3.1`; persisted checkpoints remain readable because iteration records are additive.
222
-
223
- `--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.
224
-
225
- Optional live smoke tests stay separate from SDK readiness because they require credentials and network access:
226
-
227
- ```bash
228
- PRISM_LIVE_PROVIDER_TESTS=1 npm run test --workspaces --if-present
229
- ```
230
-
231
- ### GitHub Actions pipeline (0.0.27+)
232
-
233
- `.github/workflows/release.yml` is the single pipeline: **push to `main`** runs CI (`verify` = `npm run sdk:ready`, `node20-compat`, `postgres-integration`, `supply-chain`), **`v0.3.0` or `@arnilo/*@*` package tags** additionally run `codeql-release` and the `publish` job (deterministic `release:publish` in dependency order with provenance attestation). `security.yml` adds CodeQL/dependency-review/SBOM on push and PR; `live-canaries.yml` and `sandbox-browser.yml` are scheduled. All actions are SHA-pinned (2026-08-06 fix: CodeQL pins were invalid 404 refs and `workflow_dispatch` was missing — re-verified every pin against its upstream repo). Prerequisites outside the repo: Actions enabled in repository settings, and the `NPM_TOKEN` secret (with `id-token: write` for provenance). To re-cut a tag after a fix commit, delete and recreate it (`git push origin :v0.0.28 && git push origin v0.0.28`) so the tag creation event fires.
234
-
235
- ### 0.1.0 publish handoff (plan 012 Task 7)
236
-
237
- **Decision: GO when the operator prerequisites below are recorded.** Release **0.1.0** (Phase 12, plan 012) is the release-candidate hardening cut of the **0.0.28** graph: no new packages, public exports, schema migrations, or runtime dependencies (freeze manifest `scripts/phase12-freeze-manifest.json`). At this line the canonical statement read **49 publishable manifests**: the root `@arnilo/prism` core package plus **48 workspace packages** — 14 provider adapters, 9 `prism-*` family/profile packages, and 25 capability packages. Publishable graph stays **49** publishable manifests (root + 48 workspace packages) at exact **0.1.0**. Store compatibility with 0.0.28: **compatible, no migration** ([migration](migration.md) `0.0.28 → 0.1.0`); the full `0.0.17 → 0.1.0` upgrade matrix is in the same page. All evidence for the tree under publication is recorded in [0.1.0 readiness](0.1.0-readiness.md) (capacity envelopes, restart-recovery, e2e journeys, threat-suites leg, audit at moderate).
238
-
239
- ```bash
240
- # Operator prerequisites (each a named blocked gate — none may be skipped):
241
- # 1. protected live-canary matrix green (live-canaries.yml, canary-report.json retained)
242
- # 2. PostgreSQL + keychain protected suites green (test:postgres, keychain suite)
243
- # 3. CodeQL SAST green on the release commit (security.yml / release.yml codeql-release)
244
- # 4. npm OIDC trusted publishing identity authenticated (NPM_TOKEN with id-token, provenance)
245
-
246
- git diff --check
247
- npm ci
248
- npm run sdk:ready # includes typecheck, lint, format, full test, coverage, pack, release:gate
249
- npm run security:threat-suites
250
- PRISM_TEST_POSTGRES_URL="$DATABASE_URL" npm run test:postgres # Phase 7 + Phase 12 restart-recovery
251
- node --test scripts/benchmark-0.1.0.test.mjs # frozen 0.1.0 capacity envelope contract
252
- node scripts/scan-secrets.mjs && node scripts/verify-sbom.mjs
253
- npm audit --audit-level=moderate
254
- npm run release:check -- --version 0.1.0 --report /tmp/prism-0.1.0-preflight.json
255
- npm run release:publish -- --version 0.1.0 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.1.0-dry-run.json
256
- # run the dry-run twice and diff the reports: deterministic, byte-identical
257
-
258
- # Sign the release on the clean tagged tree (operator GPG key):
259
- git tag -s v0.1.0 -m "Prism 0.1.0"
260
- git verify-tag v0.1.0
261
- git push origin v0.1.0 # tag push triggers release.yml publish job (provenance, attestations)
262
-
263
- # Real publication never bypasses the gates: release.mjs refuses
264
- # --allow-dirty/--allow-untagged without --dry-run.
265
- ```
266
-
267
- **Rollback notes.** `release:publish --version 0.1.0 --resume --report release-artifacts/publish-report.json` resumes an interrupted publication and skips only registry versions whose internal dependency fingerprint matches the local manifest. A failed package aborts the run with its status written to the report; re-run after fixing the cause. npm cannot unpublish the `0.1.0` line after 72 hours — a post-publication defect ships as a `0.1.x` patch (additive-only compat promise, `release:gate` enforced), or as a documented break in the next line with a `docs/migration.md` entry. `0.1.0` is store-compatible with `0.0.28` in both directions (no migration ran), so an operator may defer adoption of `0.1.0` without a database rollback.
268
-
269
- ### 0.1.1 publish handoff (plan 013 Task 6)
270
-
271
- **Decision: GO when the operator prerequisites below are recorded.** Release **0.1.1** (plan 013) is the post-release hardening patch on the frozen 0.1.x line: five scoped fixes — build single-flight (clean removed from `npm run build`; standalone `npm run clean`), deterministic MCP SSE relay test (`relayStatelessBody` internal export in `@arnilo/prism-mcp`, not in the package entry surface), combined core + workspace coverage summary (`scripts/coverage-summary.mjs`, appended to `test:coverage`), canonical manifest-count narrative (49 publishable manifests = root + 48 workspace packages), and ACP modes/config ownership-scoped persistence guidance (the agent never persists them; host stores MUST key by `sessions.ownership`). Publishable graph stays **49** manifests (root + 48 workspace) at exact **0.1.1**. Store compatibility with 0.1.0: **compatible, no migration** ([migration](migration.md) `0.1.0 → 0.1.1`); declaration surface additive-only vs the frozen 0.1.x contract (`scripts/compat-baseline` regenerated at 0.1.1 with zero breaking deltas).
272
-
273
- ```bash
274
- # Operator prerequisites (each a named blocked gate — none may be skipped):
275
- # 1. protected live-canary matrix green (live-canaries.yml, canary-report.json retained)
276
- # 2. PostgreSQL + keychain protected suites green (test:postgres, keychain suite)
277
- # 3. CodeQL SAST green on the release commit (security.yml / release.yml codeql-release)
278
- # 4. npm OIDC trusted publishing identity authenticated (NPM_TOKEN with id-token, provenance)
279
-
280
- git diff --check
281
- npm ci
282
- npm run sdk:ready # includes typecheck, lint, format, full test, coverage, pack, release:gate
283
- npm run security:threat-suites
284
- PRISM_TEST_POSTGRES_URL="$DATABASE_URL" npm run test:postgres # Phase 7 + Phase 12 restart-recovery
285
- npm audit --audit-level=moderate
286
- npm run release:check -- --version 0.1.1 --report /tmp/prism-0.1.1-preflight.json
287
- npm run release:publish -- --version 0.1.1 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.1.1-dry-run.json
288
- # run the dry-run twice and diff the reports: deterministic, byte-identical
289
-
290
- # Sign the release on the clean tagged tree (operator GPG key):
291
- git tag -s v0.1.1 -m "Prism 0.1.1"
292
- git verify-tag v0.1.1
293
- git push origin v0.1.1 # tag push triggers release.yml publish job (provenance, attestations)
294
-
295
- # Real publication never bypasses the gates: release.mjs refuses
296
- # --allow-dirty/--allow-untagged without --dry-run.
297
- ```
298
-
299
- **Rollback notes.** `release:publish --version 0.1.1 --resume --report release-artifacts/publish-report.json` resumes an interrupted publication and skips only registry versions whose internal dependency fingerprint matches the local manifest. A failed package aborts the run with its status written to the report; re-run after fixing the cause. npm cannot unpublish the `0.1.1` line after 72 hours — a post-publication defect ships as a `0.1.x` patch (additive-only compat promise, `release:gate` enforced), or as a documented break in the next line with a `docs/migration.md` entry. `0.1.1` is store-compatible with `0.1.0` in **both directions** (no migration ran — same checksum-protected contract), so an operator may defer or roll back the patch without a database rollback.
300
-
301
- ### 0.1.2 publish handoff (plan 014 Task 6)
302
-
303
- **Decision: GO when the operator prerequisites below are recorded.** Release **0.1.2** (plan 014) is the Alibaba Cloud provider enrichment patch on the frozen 0.1.x line: `createAlibabaEmbedder` over the OpenAI-compatible `POST {base}/embeddings` (structural `Embedder`, no new dependency), video input via `video_url` content parts on Qwen-VL models (gated on the `file` input capability), a verified compatible-mode surface decision table in [providers/alibaba.md](providers/alibaba.md) (document input and rerank deferred as demand-gated follow-ups), and an opt-in `PRISM_LIVE_DASHSCOPE_KEY` live probe. Publishable graph stays **49** manifests (root + 48 workspace) at exact **0.1.2**. Store compatibility with 0.1.1: **compatible, no migration**; declaration surface additive-only vs the frozen 0.1.x contract (`scripts/compat-baseline` regenerated at 0.1.2 with zero breaking deltas).
304
-
305
- ```bash
306
- # Operator prerequisites (each a named blocked gate — none may be skipped):
307
- # 1. protected live-canary matrix green (live-canaries.yml, canary-report.json retained)
308
- # 2. PostgreSQL + keychain protected suites green (test:postgres, keychain suite)
309
- # 3. CodeQL SAST green on the release commit (security.yml / release.yml codeql-release)
310
- # 4. npm OIDC trusted publishing identity authenticated (NPM_TOKEN with id-token, provenance)
311
-
312
- git diff --check
313
- npm ci
314
- npm run sdk:ready # includes typecheck, lint, format, full test, coverage, pack, release:gate
315
- npm run security:threat-suites
316
- PRISM_TEST_POSTGRES_URL="$DATABASE_URL" npm run test:postgres # Phase 7 + Phase 12 restart-recovery
317
- npm audit --audit-level=moderate
318
- npm run release:check -- --version 0.1.2 --report /tmp/prism-0.1.2-preflight.json
319
- npm run release:publish -- --version 0.1.2 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.1.2-dry-run.json
320
- # run the dry-run twice and diff the reports: deterministic, byte-identical
321
-
322
- # Sign the release on the clean tagged tree (operator GPG key):
323
- git tag -s v0.1.2 -m "Prism 0.1.2"
324
- git verify-tag v0.1.2
325
- git push origin v0.1.2 # tag push triggers release.yml publish job (provenance, attestations)
326
-
327
- # Real publication never bypasses the gates: release.mjs refuses
328
- # --allow-dirty/--allow-untagged without --dry-run.
329
- ```
330
-
331
- **Rollback notes.** `release:publish --version 0.1.2 --resume --report release-artifacts/publish-report.json` resumes an interrupted publication and skips only registry versions whose internal dependency fingerprint matches the local manifest. A failed package aborts the run with its status written to the report; re-run after fixing the cause. npm cannot unpublish the `0.1.2` line after 72 hours — a post-publication defect ships as a `0.1.x` patch (additive-only compat promise, `release:gate` enforced), or as a documented break in the next line with a `docs/migration.md` entry. `0.1.2` is store-compatible with `0.1.1` in **both directions** (no migration ran — same checksum-protected contract), so an operator may defer or roll back the patch without a database rollback.
332
-
333
- ### 0.2.4 publish handoff (plan 024 Task 6)
334
-
335
- **Decision: GO when the operator prerequisites below are recorded.** Release **0.2.4** (plan 024) is the package-documentation-and-compatibility-truth cut on the 0.2.x review-remediation line. API surface **additive-only** (plain reviewed compat gate at 0.2.4: delta is the version literal only — no export changes; baselines regenerated with `--update-baseline`, no `--allow-break`; freeze manifest `scripts/phase24-freeze-manifest.json`). Documentation/compatibility truth, **no runtime contract change and no migration**: (1) **umbrella wording matches manifests** — before: `@arnilo/prism-providers` claimed to install every one of the 14 first-party provider adapters while its `dependencies` shipped 11, and `@arnilo/prism-all` claimed to install every first-party package while 5 packages were unreachable from its install set. After: `prism-providers` states **11 of 14** (Azure, Bedrock, Vertex are added separately by `prism-all`; its install list was corrected from 9 to the full 11 — alibaba and ollama were missing from the docs), and `prism-all` states **20 direct / 43 transitive** packages with the complete omission set named (document-reader, OpenAPI tools, NATS, Caveman, Ponytail). **No `dependencies` array changed in 0.2.4** — the manifests were already truthful; only the claims were wrong. Membership itself is 0.3.0 scope (§0.3.0 "Umbrella membership fix"). (2) **generated tables from one source of truth** — `node scripts/package-truth.mjs` reads every manifest and emits `scripts/package-truth.json` (counts 50/49/14/9/26, provider/family/capability membership, umbrella + profile closures, peer policy); all count/closure/current-line docs literals are derived from it and the gates fail on drift (plain JS consumer example):
336
-
337
- ```js
338
- import { readFileSync } from "node:fs";
339
- const truth = JSON.parse(readFileSync("scripts/package-truth.json", "utf8"));
340
- console.log(truth.counts.publishable, truth.umbrella["prism-all"].closure); // 50 43
341
- ```
342
-
343
- (3) **peer-version policy Decision A (exact pins)** — every code package peers the bare exact current version `@arnilo/prism@0.2.4` (no `~`/`^`/`>=`/`*`) through 0.2.x with the atomic-upgrade rule: all `@arnilo/prism-*` packages move at the same version; a partial upgrade fails clearly at install time with `ERESOLVE unable to resolve dependency tree` naming the conflicting peer (never a silent install of a pair that was never tested); the range widens to `^1.0.0` at the 1.x stable release after the 1.0 readiness gates go operator-green. Third-party `@arnilo/prism-*` adapters declare the same exact peer on the documented current version. (4) **docs semantic, not phrase-only** — the structural docs tests derive every count/closure/current-line assert from the generated artifact (an editorial reword that keeps the derived value passes; a wrong value fails), the stale `0.2.8` stray roadmap section was removed, and `docs/0.1.0-readiness.md`/`docs/index.md` current-line blocks advance to 0.2.4 with **0.1.7** recorded as the terminal 0.1.x baseline (0.1.1/0.1.0 tables demoted to historical record). Release graph stays **50** publishable manifests at exact **0.2.4**; zero new runtime dependency names (core remains dependency-free); 43 code packages + 6 pure-manifest family/profile. Regression surface: `phase24-truth` (12, incl. built-dist version + docs current-line + umbrella wording freeze + gate accounting), packed plain-JS truth conformance in install-smoke (providers tarball = exactly 11 provider deps; prism-all tarball = generated 20 deps + 43-member closure; packed current-line equals docs), and the Task 3 packed ERESOLVE refusal proof. Exit gate green: npm test core + workspace + script gates, `sdk:ready` exit 0, audit 0 moderate, secret scans 0 findings, pack dry-run 50/50 twice byte-identical, plain reviewed compat gate at 0.2.4 (version literal only), release-evidence manifest with zero blocked surfaces; evidence in `scripts/phase24-baseline.json` `exitGate`. **Rollback notes.** Rollback = restore the 0.2.3 manifests/tag. Nothing persisted changes shape and no runtime behavior changed, so downgrade is store-safe; the only visible deltas are the version literal and the corrected docs wording (the old umbrella claims reappear if you revert the docs — the truth tests fail red until the wording is restored).
344
-
345
- ```bash
346
- # Operator prerequisites recorded: clean tree at the v0.2.4 tag candidate, GPG key, npm OIDC publisher.
347
- node scripts/release.mjs bump --from 0.2.3 --to 0.2.4 # already applied by Task 6; idempotent
348
- npm test # core + workspace suites + all script gates (incl. phase24-truth)
349
- npm run security:threat-suites # phase8-11 + phase20 + phase21 + phase22 + phase23 public-entry conformance
350
- PRISM_TEST_POSTGRES_URL=postgres://postgres:prism@127.0.0.1:54329/prism_test npm run sdk:ready
351
- node scripts/release.mjs gate --version 0.2.4 # plain reviewed gate at 0.2.4: version literal only, 0 breaking deltas
352
- npm run pack:dry-run # twice; diff reports — deterministic
353
- npm audit --audit-level=moderate
354
- npm run release:check -- --version 0.2.4 --report /tmp/prism-0.2.4-preflight.json
355
- npm run release:publish -- --version 0.2.4 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.2.4-dry-run.json
356
- # run the dry-run twice and diff the reports: deterministic, byte-identical
357
- ```
358
-
359
- Protected evidence (never a passing skip): the durable state-concurrency legs (Postgres `prism_phase24_*` schemas — `npm run test:postgres` under `PRISM_TEST_POSTGRES_URL`; absent credentials record **blocked** per the release skip manifest), the phase24 package-truth conformance over built dist + packed tarballs, and the live canaries (provider OIDC/OPA, MCP, A2A, Brave — always `protected` rows in the manifest, never `pass`). The release skip manifest names every skip class with its required env; missing protected evidence records 0.2.4 as **blocked**, never a passing skip.
360
-
361
219
  ## Protected coding journey (0.2.6, plan 026 Task 7)
362
220
 
221
+
363
222
  The 0.2.6 protected release profile requires real end-to-end coding-agent evidence, never a passing skip. `scripts/phase26-coding-journey.test.mjs` packs the published packages into a fresh consumer, installs the pinned host browser, and runs `scripts/fixtures/phase26-coding-journey.mjs` against real host services: a real LLM provider call through the Prism `AIProvider` contract (host adapter module), a digest-pinned Docker sandbox (`PRISM_TEST_DOCKER_IMAGE` must be `name@sha256:...`), the durable worktree lifecycle over real Postgres checkpoints/leases, a provider-driven edit through ACP with policy approval, a named check with a host parser and `diagnosticDelta`, a patch review composed over the server `ArtifactService` (accepted then superseded), process recovery across replicas (attach-if-attested, never re-spawn), durable ACP cancellation (terminal-idempotent, never replays tools), real GitHub push + lookup-before-create PR + reconcile + cleanup, host Playwright browser inspection, and the host PTY adapter when in the frozen profile.
364
223
 
365
224
  ```bash
@@ -378,646 +237,14 @@ node --test scripts/phase26-coding-journey.test.mjs
378
237
 
379
238
  Every side effect carries the run suffix and is cleaned up idempotently (PR closed, branch deleted, worktree removed, containers/children/browser context closed); unknown cleanup blocks the journey. The retained report `scripts/phase26-coding-journey-report.json` is regenerated on every real run — `journey.state` pass records the surface `pass` in release evidence; blocked/partial reports record `blocked` (fail closed); `not_run`/missing records are documented protected gaps (`requiredEnv PRISM_CODING_JOURNEY`). The CI profile runs in `.github/workflows/coding-journey.yml` (scheduled + dispatch; Postgres service, host Docker, pinned Chromium, provider + forge secrets from the `coding-journey` environment) and uploads the report artifact. Leak scans cover journey stdout/stderr and the report against every credential-looking env value — the report records env names only. Frozen ceilings: journey wall 20 min (hard 40 min), cleanup 5 min (hard 15 min).
380
239
 
381
- ### 0.2.6 publish handoff (plan 026 Task 8)
382
-
383
- **Decision: GO when the operator prerequisites below are recorded.** Release **0.2.6** (plan 026) is the fully-featured coding-agent-readiness cut on the 0.2.x review-remediation line. API surface **additive-only** (plain reviewed compat gate at 0.2.6: expected deltas are the version literal plus the Task 1–6 additive exports — PTY backend/handle types, indexed-search seam, workspace lifecycle, process/ACP recovery, review manifest + diagnostics; zero removals; baselines regenerated with `--update-baseline`, no `--allow-break`; freeze manifest `scripts/phase26-freeze-manifest.json` records per-task evidence tokens, state machines, caps, the demand registry, and deviations D-T3-1/D-T5-1/D-T7-1). Seven roadmap items, **no runtime contract change, additive migration**: (1) **host-selected PTY/interactive terminal backend** (`pty-backend`) — `createProcessSessions` gains an optional `ptyBackend` with explicit `capabilities.resize`; `pty: true` without a backend fails byte-compatibly with `ERR_PRISM_PROCESS_PTY_UNSUPPORTED` before spawn; bounded geometry/TERM/attach/resize-rate/metadata caps, generic backend errors that never leak backend text, NUL rejected as a policy error, backend loss surfaces as `unknown` with `exitCode: null`; the protected PTY leg (`scripts/phase26-pty-protected.test.mjs`, gated by `PRISM_TEST_PTY_BACKEND`) passed 4/4 against a real PTY host (python3 `pty.fork` + `TIOCSWINSZ`). (2) **scalable indexed code-search seam** (`indexed-search`) — `createIndexedRepositoryOperations` composes a host-owned incremental index with bounded literal search as the unchanged default; `indexed_literal`/`semantic` fail closed on stale/failed/unsupported/untrusted indexes (`ERR_PRISM_INDEX_*`), no silent semantic-to-literal downgrade, results labeled `untrusted_index`; 100k-entry benchmark p95 ≤ 250 ms, 1k-file update ≤ 1 s, heap ≤ 64 MiB. (3) **ownership-scoped multi-repository/worktree lifecycle** (`workspace-lifecycle`) — `createCodingWorkspaceLifecycle` over CheckpointStore CAS + LeaseStore fencing (`prism.coding-agent.workspace.v1`), locked worktrees with `prism-workspace:` reasons, credential-free remote fingerprints, idempotent create, verify revalidation, cleanup refusal matrix, `ERR_PRISM_WORKSPACE_*`; `GitOperations` gains worktree `lock`/`unlock` + `fingerprint()`. (4) **forge breadth demand-gated** (`forge-breadth`) — GitLab/Bitbucket stay **deferred** in the demand registry with no named consumer; no adapter source ships; activation requires a recorded named consumer/date/use case. (5) **durable ACP/live-task and managed-process recovery** (`durable-recovery`) — bounded process intent/metadata persisted before spawn (`prism.coding-agent.process.v1`), serialized per-record CAS transition writes, attach-if-attested `recover()` reporting `attached|terminal|unknown` with no fabricated exit code and no PID probing; per-record leases fence replicas (memory + real Postgres two-replica conformance 8/8); ACP `activeRun` refs (additive optional, 0.2.5 records stay readable) + `createAcpRunRecovery` status re-resolution and durable fence-checked cancellation (`prism.coding-agent.cancel.v1`) that never replays a pending/dispatched tool. (6) **bounded patch review and incremental diagnostics** (`review-diagnostics`) — `createCodingPatchReviewManifest` + `assertCodingPatchAccepted` (pending/accepted/rejected/superseded bound to digest + revision + identity, stale acceptance refused, never auto-applies/commits/pushes/merges) composed over the server `ArtifactService`; `normalizeDiagnostics`/`diagnosticDelta` with deterministic added/removed/unchanged deltas and host-supplied check parsers; opt-in LSP `syncDocument`/`diagnosticDelta` (monotonic versions, resultId reuse) — LSP stays strictly opt-in, nothing spawns from tool factories or agent assembly. (7) **protected real coding journey** (`coding-journey`) — `scripts/phase26-coding-journey.test.mjs` packs 10 packages into a fresh consumer and drives real host services (provider call, digest-pinned Docker sandbox, Postgres worktree lifecycle, provider-driven ACP edit with policy approval, named check + `diagnosticDelta`, patch review over the server artifact store, cross-replica process recovery, durable cancellation, real GitHub push/lookup-before-create PR/reconcile/cleanup, host Playwright inspection, host PTY adapter in the frozen profile) under frozen wall/cleanup ceilings with run-suffix side effects and per-step idempotent cleanup; missing credentials/services or skipped substeps record **blocked**, never a passing skip; the retained `scripts/phase26-coding-journey-report.json` (timings/states/ids only) gates release evidence (pass/blocked/protected). Release graph stays **50** publishable manifests at exact **0.2.6**; zero new runtime dependency names (core remains dependency-free); 43 code packages + 6 pure-manifest family/profile.
384
-
385
- **Measured reductions and deltas (recorded in `scripts/phase26-baseline.json` `exitGate`).** New error families: `ERR_PRISM_PROCESS_PTY_*`, `ERR_PRISM_INDEX_*`, `ERR_PRISM_WORKSPACE_*`, `ERR_PRISM_RECOVERY_*`, `ERR_PRISM_REVIEW_*` — all additive, all fail closed. New protected env names (never values): `PRISM_TEST_PTY_BACKEND`, `PRISM_TEST_POSTGRES_URL`, `PRISM_TEST_DOCKER_BIN`, `PRISM_TEST_DOCKER_IMAGE`, `PRISM_LIVE_PLAYWRIGHT`, `PRISM_CODING_FORGE_REPOSITORY`, `PRISM_CODING_FORGE_TOKEN`, `PRISM_CODING_PROVIDER`, `PRISM_CODING_JOURNEY`. Coverage stayed above the recorded 0.2.5 floors. **Rollback notes.** Rollback = restore the 0.2.5 manifests/tag. Three new versioned checkpoint namespaces exist (`prism.coding-agent.process.v1`, `prism.coding-agent.workspace.v1`, `prism.coding-agent.cancel.v1`) plus the additive optional ACP `activeRun` ref; before downgrading, stop all 0.2.6 workers and mark active PTY/process/recovery records unknown (a crashed 0.2.6 replica that resumes on 0.2.5 fails closed — recovery never fabricates an exit code or re-spawns without host attestation). No 0.2.5 persisted shape changed, so an ordinary downgrade is store-safe; the added exports simply disappear.
386
-
387
- ```bash
388
- # Operator prerequisites recorded: clean tree at the v0.2.6 tag candidate, GPG key, npm OIDC publisher.
389
- node scripts/release.mjs bump --from 0.2.5 --to 0.2.6 # already applied by Task 8; idempotent
390
- npm test # core + workspace suites + all script gates (incl. phase26-freeze + phase26-index-benchmark)
391
- npm run security:threat-suites # phase8-11 + phase20-25 public-entry conformance
392
- PRISM_TEST_POSTGRES_URL=postgres://postgres:prism@127.0.0.1:54329/prism_test npm run test:postgres
393
- node --test scripts/phase26-recovery-conformance.test.mjs # protected: memory + real Postgres two-replica recovery/workspace conformance
394
- node --test scripts/phase26-pty-protected.test.mjs # protected: real PTY host (PRISM_TEST_PTY_BACKEND)
395
- PRISM_TEST_POSTGRES_URL=postgres://postgres:prism@127.0.0.1:54329/prism_test npm run sdk:ready
396
- node scripts/release.mjs gate --version 0.2.6 # plain reviewed gate at 0.2.6: version literal + additive exports only, 0 breaking deltas
397
- npm run pack:dry-run # twice; diff reports — deterministic
398
- npm audit --audit-level=moderate
399
- npm run release:check -- --version 0.2.6 --report /tmp/prism-0.2.6-preflight.json
400
- npm run release:publish -- --version 0.2.6 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.2.6-dry-run.json
401
- # run the dry-run twice and diff the reports: deterministic, byte-identical
402
- ```
403
-
404
- Protected evidence (never a passing skip): the durable recovery/workspace conformance legs (real Postgres two-replica split-brain fence, cross-replica cancellation, terminal-before-recovery), the protected PTY leg (real PTY host adapter), the protected real coding journey (`scripts/phase26-coding-journey-report.json` — pass/blocked/protected, never a passing skip; runs in `.github/workflows/coding-journey.yml` with real provider/Docker/Playwright/GitHub/Postgres/PTY services), and the live canaries (provider OIDC/OPA, MCP, A2A, Brave — always `protected` rows in the manifest, never `pass`). The release skip manifest names every skip class with its required env; missing protected evidence records 0.2.6 as **blocked**, never a passing skip.
405
-
406
- ### 0.3.0 lockstep cut and independent publication (plan 030 Task 9)
407
-
408
- **Decision: GO when the operator prerequisites below are recorded.** Release **0.3.0** is the last lockstep cut: all **56** publishable manifests are `0.3.0`, and every internal `@arnilo/*` dependency, optional dependency, and peer dependency uses `^0.3.0`. This cut adds the optional host-owned `@arnilo/prism-computer-use-linux` wrapper, `read.findText`, loud edit fuzzy matches/miss context, and ACP editor-buffer wiring; the desktop package stays outside umbrella profiles. Peer policy is now **Decision B**: packages may move independently inside the 0.x caret window (`>=0.3.0 <0.4.0`).
409
-
410
- After the signed `v0.3.0` cut, publication is package-tag driven: `@arnilo/<package>@<version>` publishes only changed packages at that version. The lockstep core artifact is `arnilo-prism-0.3.0.tgz`; later package artifacts carry their own name and version. A generic `v*` tag is not a publication trigger after this cut. The one emergency lockstep path remains explicit: `--lockstep --version 0.3.0`.
411
-
412
- ```bash
413
- # one manifest bump + one lockfile regeneration for the final cut
414
- node scripts/release.mjs bump --from 0.2.9 --to 0.3.0 --ranges caret
415
- node scripts/package-truth.mjs
416
- node scripts/release.mjs check --lockstep --version 0.3.0 --allow-dirty --allow-untagged
417
- # later checks default to independent mode
418
- npm run release:check -- --allow-dirty --allow-untagged
419
- ```
420
-
421
- For a later coding-agent-only patch, bump its manifest with `bump --package @arnilo/prism-coding-agent --type patch`, regenerate the lockfile, commit, and push `@arnilo/prism-coding-agent@0.3.1`. The default independent check validates the mixed graph; the package tag publishes only that package in dependency order. Resume skips only a matching already-published manifest and refuses a same-version registry collision with different internal release fields.
422
-
423
- **Rollback notes.** Before publication, restore the 0.2.9 manifests/tag. After publication, roll forward with an additive 0.3.x package patch; npm unpublish is not a rollback strategy.
424
-
425
- ### 0.3.1 independent RAG engine patch (plan 034 Task 12)
426
-
427
- **Decision: GO when the operator prerequisites below are recorded.** Release **0.3.1** is the first Decision B independent patch: only `@arnilo/prism-memory`, `@arnilo/prism-rag`, and `@arnilo/prism-observability-opentelemetry` move `0.3.0 → 0.3.1`. Internal `^0.3.0` ranges stay. Root current line remains **0.3.0**.
428
-
429
- ```bash
430
- node scripts/release.mjs bump --package @arnilo/prism-memory --type patch
431
- node scripts/release.mjs bump --package @arnilo/prism-memory/rag --type patch
432
- node scripts/release.mjs bump --package @arnilo/prism-core/governance/observability --type patch
433
- node scripts/release.mjs gate --update-baseline --skip-tarball # review Embedder.id; scanner is additive-only
434
- node scripts/release.mjs check --allow-dirty --allow-untagged
435
- # publish tags (operator handoff; not this task):
436
- # git tag @arnilo/prism-memory@0.3.1 && git tag @arnilo/prism-memory/rag@0.3.1
437
- # git tag @arnilo/prism-observability-opentelemetry@0.3.1 && git push --tags
438
- ```
439
-
440
- **Compat.** Baselines regenerated with `--update-baseline`. Expected deltas are additive exports (`createPostgresVectorStore`, `createTeiReranker`, `createRagTelemetry`, multi-scope `scopes`, `HARD_RETRIEVE_SCOPE_CAP`, fusion/hash/generation helpers). `Embedder.id` is a TypeScript implementer break documented in `docs/migration.md` `0.3.0 → 0.3.1`; the name-level scanner does not see interface members, so `--allow-break` is not required. `RagProvenance` gained `tenantId`/`resourceId`/`corpusId` (additive interface members, invisible to scanner). **Store:** additive Postgres DDL; 0.3.0 rows remain readable. **Rollback:** restore the 0.3.0 package versions. Publication remains the operator handoff — this task does not publish.
441
-
442
- ### 0.3.1 changed-package cut (plan 039 Task 8)
443
-
444
- **Decision: GO when the operator prerequisites below are recorded.** The plan 039 cut is the first Decision B **root** patch: the baseline is the plan 035 completion parent `c600eaa`; 30 packages publish in dependency order — root `@arnilo/prism` plus 27 changed workspace packages move to **0.3.1** (`@arnilo/prism-rag` moves 0.3.1 → 0.3.2), and `@arnilo/prism-obscura` publishes new at its reviewed initial **0.3.0**. Every unchanged package stays byte-identical (peers keep the `^0.3.0` window; republished packages carry `^0.3.1` root peers — both satisfy the root). Additive-only compat (version literal + plan 036/037 additive exports + the obscura CDP/browser surface; baselines regenerated with `--update-baseline`, no `--allow-break`, no migration).
445
-
446
- ```bash
447
- node scripts/release.mjs changed --baseline c600eaa18f65b56764ec2fb408ec813536eff6f7 # 30 packages
448
- # per-package: node scripts/release.mjs bump --package <name> --type patch (applied by plan 039 task 8)
449
- node scripts/release.mjs gate --update-baseline --skip-tarball
450
- node scripts/release.mjs check --independent --baseline c600eaa18f65b56764ec2fb408ec813536eff6f7
451
- node scripts/release.mjs publish --independent --baseline c600eaa18f65b56764ec2fb408ec813536eff6f7 --dry-run
452
- # publish tags (operator handoff; not this task): push the 30 annotated
453
- # `<name>@<version>` package tags (e.g. @arnilo/prism@0.3.1,
454
- # @arnilo/prism-obscura@0.3.0, @arnilo/prism-rag@0.3.2) — release.yml's publish
455
- # job runs deterministic release:publish in dependency order with OIDC provenance.
456
- ```
457
-
458
- **Compat.** Baselines regenerated (`--update-baseline`): version literal, obscura `connectObscuraCdp`/`createObscuraWebTools` types, plan 036/037 additive exports. **Rollback:** restore the pre-cut manifests/tags. Publication remains the operator handoff — this task does not publish.
459
-
460
- ### 0.3.2 changed-package cut (plan 050 Task 12)
461
-
462
- **Decision: GO when the operator prerequisites below are recorded.** The plan 050 cut covers the clay-integration-findings remediation and the OKF wiki adoption: baseline `edb4fcf` (the parent of the plan 050 implementation work); five packages publish in dependency order — root `@arnilo/prism` (FEATURE-1 agent-definition model override fallback, FEATURE-3 command driver hooks, FEATURE-2/6 docs+example, DOCS-1 contracts), `@arnilo/prism-coding-agent` (BUG-1 `allowCustom` default + optional `toolCallId`), `@arnilo/prism-supervisor` (BUG-2 child-factory `Agent` guard, FEATURE-4 opt-in child event passthrough), `@arnilo/prism-wiki` (OKF v0.2 bundle emission, 0.0.2 → 0.0.3), and `@arnilo/prism-acp-agent` (sqlite `:memory:` pass-through fix, 0.0.x-style patch 0.3.1 → 0.3.2). Every unchanged package stays byte-identical; docs-only packages (`@arnilo/prism-workflows`, `@arnilo/prism-compaction-observational-memory`) do not bump. Republished packages carry `^0.3.2` root peers; unchanged packages keep their window peers. Docs-only change on the root: none of the deltas are breaking (additive fields and fail-closed guards), compat additive-only, no migration.
463
-
464
- ```bash
465
- node scripts/release.mjs changed --baseline edb4fcf # 5 packages
466
- # per-package: node scripts/release.mjs bump --package <name> --type patch (regenerates the lockfile)
467
- npm run sdk:ready # blocked only by the protected PRISM_TEST_POSTGRES_URL row (pre-existing)
468
- node scripts/release.mjs check --independent --baseline edb4fcf --allow-dirty --allow-untagged
469
- node scripts/release.mjs publish --independent --baseline edb4fcf --dry-run
470
- # publish tags (operator handoff; not this task): push the 5 annotated
471
- # `<name>@<version>` package tags (e.g. @arnilo/prism@0.3.2,
472
- # @arnilo/prism-wiki@0.0.3) — release.yml's publish job runs deterministic
473
- # release:publish in dependency order with OIDC provenance.
474
- ```
475
-
476
- **Rollback:** restore the pre-cut manifests/tags. No persisted shape changed (BUG-1/BUG-2 guards and the acp-agent `:memory:` fix are fail-closed tightenings). Publication remains the operator handoff — this task does not publish.
477
-
478
- ### 0.4.0 publish handoff (plan 054 Task 9)
479
-
480
- **Decision: GO when the operator prerequisites below are recorded.** Release **0.4.0** is the package-consolidation lockstep cut: 10 active manifests (root + 9 workspace families/interop/office) at **0.4.0** with `@arnilo/prism@^0.4.0` peers. 55 retired 0.3 names are not republished as shims. After the 0.4 tarballs and `docs/migrate-to-0.4.md` are public, `node scripts/phase54-legacy-registry.mjs --apply --confirm` tags each retired name `legacy` and deprecates `<0.4.0`. Store compatibility with 0.3.3: **compatible, no persisted-shape migration**. Rollback = exact 0.3 pins.
481
-
482
- ```bash
483
- npm run sdk:ready
484
- npm run release:check -- --lockstep --version 0.4.0 --allow-dirty --allow-untagged
485
- npm run release:publish -- --lockstep --version 0.4.0 --dry-run --allow-dirty --allow-untagged --report release-artifacts/publish-dry-run.json
486
- node scripts/phase54-legacy-registry.mjs --dry-run
487
- # operator: clean tree, tag v0.4.0, publish, then --apply --confirm
488
- ```
489
-
490
- **Rollback notes.** Rollback = restore 0.3.x exact pins. No store migration.
491
-
492
- ### 0.3.3 publish handoff (plans 041-044 Task 3)
493
-
494
- **Decision: GO when the operator prerequisites below are recorded.** The plan 041-044 cut covers the four outstanding feature plans on the 0.3.x line: baseline `1171575` (the plan-040 commit, parent of all four plans' uncommitted implementation work). Six publishable changes in dependency order — root `@arnilo/prism` **0.3.2 → 0.3.3** (progressive tool loading `search_tools` disclosure + `toolsSearch`/`toolsDisclosure` config, run-ledger `promptVersion` ref with `PERSISTENCE_SCHEMA_VERSION` 8 → 9, docs for the prompt registry and composite memory scoring, memory package truth), `@arnilo/prism-session-store-codecs` / `@arnilo/prism-session-store-sqlite` / `@arnilo/prism-session-store-postgres` **0.3.0 → 0.3.1** (nullable `prompt_version` column + additive checked migrations), `@arnilo/prism-evals` **0.3.0 → 0.3.1** (trace-to-dataset curation `datasetFromRuns`), and `@arnilo/prism-memory` **0.3.1 → 0.3.2** (composite recall scoring `RecallOptions.scoring`, `importance` record field + ADD COLUMN, `importanceFrom` write hook). `@arnilo/prism-prompts` publishes new at its reviewed initial **0.0.1** (independent host opt-in like the versioned prompt registry — not in `prism-all`, no first-party dependency). Unchanged packages stay byte-identical; `@arnilo/prism-dev`/`@arnilo/prism-graft`/`@arnilo/prism-ponytail` stay at their reviewed initial versions. Republished set keeps the `^0.3.0` Decision B root-peer window; unchanged packages keep their window peers. Additive-only compat (new exports + the two documented literal changes: `PERSISTENCE_SCHEMA_VERSION` literal and the CLI `usage` string; baselines regenerated with `--update-baseline`, no `--allow-break`, no migration).
495
-
496
- ```bash
497
- node scripts/release.mjs changed --baseline 1171575 # root + memory + evals + 3 stores (+ prompts as new)
498
- PRISM_TEST_POSTGRES_URL=... node scripts/release-skip-manifest.mjs
499
- PRISM_TEST_POSTGRES_URL=... npm run release:gate
500
- node scripts/release.mjs check --independent --baseline 1171575 --allow-dirty --allow-untagged
501
- node scripts/release.mjs publish --independent --baseline 1171575 --dry-run --allow-dirty --allow-untagged
502
- # publish tags (operator handoff; not this task): push the annotated
503
- # `<name>@<version>` package tags — release.yml's publish job runs
504
- # deterministic release:publish in dependency order with OIDC provenance.
505
- ```
506
-
507
- ### 0.2.9 publish handoff (plan 029 Task 10)
508
-
509
- **Decision: GO when the operator prerequisites below are recorded.** Release **0.2.9** (plan 029) is the provider-adoption and behavior-packages cut on the 0.2.x review-remediation line. API surface **additive-only** (plain reviewed compat gate at 0.2.9: expected deltas are the version literal plus the new provider/OAuth/impeccable exports and the form-urlencoded `pollDeviceCodeToken` options; zero removals; baselines regenerated with `--update-baseline`, no `--allow-break`). Ships `@arnilo/prism-providers/deepseek`, `@arnilo/prism-providers/xai` (API key + SuperGrok RFC 8628), `@arnilo/prism-providers/clinepass`, and `@arnilo/prism-impeccable`. Ponytail peer `^4.9.0` (bare `/ponytail` reports status). Caveman registers extra `SKILL.md`. SuperGrok is host-invoked; Cline WorkOS, DeepSeek `/anthropic`, grok-cli file scan, harness/Cordis/Muse, Caveman 2 engine, and Impeccable live detector stay out. Release graph is **55** publishable manifests at exact **0.2.9** (root + 54 workspace). Store compatibility with 0.2.8: **compatible, no migration**.
510
-
511
- **Rollback notes.** Rollback = restore the 0.2.8 manifests/tag. No persisted 0.2.8 shape changed; the added packages simply disappear.
512
-
513
- ```bash
514
- node scripts/release.mjs bump --from 0.2.8 --to 0.2.9 # already applied by Task 10; idempotent
515
- npm test
516
- PRISM_CLIENT_NAMES=<names> node scripts/check-client-neutrality.mjs
517
- npm run sdk:ready
518
- node scripts/release.mjs gate --version 0.2.9
519
- npm run pack:dry-run
520
- npm audit --audit-level=moderate
521
- node scripts/scan-secrets.mjs && npm sbom --sbom-format spdx > security-artifacts/sbom.spdx.json && node scripts/verify-sbom.mjs
522
- npm run release:check -- --version 0.2.9 --report /tmp/prism-0.2.9-preflight.json
523
- npm run release:publish -- --version 0.2.9 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.2.9-dry-run.json
524
- ```
525
-
526
- Protected evidence stays the same classes as 0.2.8 plus SuperGrok live login (`PRISM_LIVE_XAI_OAUTH`) — always `protected`, never a silent pass. Publication remains the operator handoff (signed `v0.2.9` tag + npm OIDC).
527
-
528
- ### 0.2.8 publish handoff (plan 028 Task 18)
529
-
530
- **Decision: GO when the operator prerequisites below are recorded.** Release **0.2.8** (plan 028) is the ACP adoption-fixes cut on the 0.2.x review-remediation line. API surface **additive-only** (plain reviewed compat gate at 0.2.8: expected deltas are the version literal plus the plan 028 additive exports — `ToolKind`/`kind` on `ToolDefinition`, `AgentFinishReason`, `createCodingToolProjection`/`AgUiProjectedImage`/`AgUiProjectedToolResult`, `AcpCommand`/`AcpCommandsSeam`, `ERR_PRISM_ACP_RUN`, `acpImageBytes`/`acpCommandsPerUpdate`, and the new `@arnilo/prism-acp-agent` package; zero removals; baselines regenerated with `--update-baseline`, no `--allow-break`). Client names are scrubbed; `scripts/check-client-neutrality.mjs` is part of `release:gate`. ACP B1–B5 and F1–F10 as recorded in `plans/028-Release-0-2-8-ACP-Adoption-Fixes.md`. Release graph is **51** publishable manifests at exact **0.2.8** (root + 50 workspace). Store compatibility with 0.2.7: **compatible, no migration**.
531
-
532
- **Rollback notes.** Rollback = restore the 0.2.7 manifests/tag. No persisted 0.2.7 shape changed; the added exports and `@arnilo/prism-acp-agent` simply disappear.
533
-
534
- ```bash
535
- node scripts/release.mjs bump --from 0.2.7 --to 0.2.8 # already applied by Task 18; idempotent
536
- npm test
537
- PRISM_CLIENT_NAMES=<names> node scripts/check-client-neutrality.mjs
538
- npm run sdk:ready
539
- node scripts/release.mjs gate --version 0.2.8
540
- npm run pack:dry-run
541
- npm audit --audit-level=moderate
542
- node scripts/scan-secrets.mjs && npm sbom --sbom-format spdx > security-artifacts/sbom.spdx.json && node scripts/verify-sbom.mjs
543
- npm run release:check -- --version 0.2.8 --report /tmp/prism-0.2.8-preflight.json
544
- npm run release:publish -- --version 0.2.8 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.2.8-dry-run.json
545
- ```
546
-
547
- Protected evidence stays the same classes as 0.2.7 (Postgres durable legs, live canaries). Missing protected evidence records **blocked**, never a passing skip. Publication remains the operator handoff (signed `v0.2.8` tag + npm OIDC).
548
-
549
- ### 0.2.7 publish handoff (plan 027 Task 10)
550
-
551
- **Decision: GO when the operator prerequisites below are recorded.** Release **0.2.7** (plan 027) is the enterprise ERP production-readiness cut on the 0.2.x review-remediation line. API surface **additive-only** (plain reviewed compat gate at 0.2.7: expected deltas are the version literal plus the plan 027 additive exports — ERP outbox/inbox + dispatcher, saga engine, SoD approvals, audit export, field policy, ERP invariant evals; zero removals; baselines regenerated with `--update-baseline`, no `--allow-break`; freeze manifest `scripts/phase27-freeze-manifest.json` records per-task evidence tokens, state machines, caps, the demand registry, measured HA/DR/classification/journey numbers, and the explicit 0.3.0 blocker). Nine roadmap items, **no exactly-once claim, additive forward-only migrations**: (1) **transactional outbox/inbox** (`erp-messaging`, Task 1) — `ErpOutboxStore`/`ErpInboxStore` + bounded `ErpOutboxDispatcher` with claim-token CAS, `FOR UPDATE SKIP LOCKED`, `ON CONFLICT DO NOTHING` idempotent append, at-least-once delivery with explicit unknown-outcome, dead-letter/replay requiring verified tenant `AgentIdentity`; migration `004_erp_messaging` (`prism_erp_outbox`/`prism_erp_inbox`, 14+4 columns, 3 partial indexes). (2) **saga compensation and reconciliation** (`saga`, Task 2) — `defineSaga`/`runSaga`/`resumeSaga` over existing CheckpointStore + LeaseStore (`prism.workflow.saga`), reverse-order compensation, unknown-outcome detection, manual resolution requiring verified identity + bounded reason + audit ref, stable tenant-scoped operation keys, redacted snapshots, `MAX_SAGA_STEPS=100`. (3) **multi-party and separation-of-duties approvals** (`approvals`, Task 3) — `ApprovalStore` with role/quorum rules, requester/approver separation, any-party-veto rejection, delegated authority (max depth 8), expiry checked at every protected transition, atomic grant consumption in the host transaction, `policyRevision` pin denying on mismatch; migration `005_erp_approvals` (`prism_erp_approvals`, JSONB decisions, `FOR UPDATE` row lock). (4) **tamper-evident audit export** (`audit-export`, Task 4) — `createAuditExporter` with WORM-then-SIEM ordering, hash-chained record envelopes (genesis 0x64 zeros), `verifyAuditBatch` independent verification, `AuditCursorStore` CAS, SIEM best-effort pending replay (8-entry cap), legal-hold flag preservation, RFC 8785 canonical JSON for digests; Prism does not certify NIST/SIEM/WORM compliance programs. (5) **secret-manager adapters demand-gated** (Task 5) — Vault/AWS/Azure/GCP stay **deferred** behind the demand gate (no named consumer; no adapter ships; `scripts/phase27-demand-gate.mjs` enforces zero ambient discovery). (6) **HA registries and recovery** (`ha-dr`, Task 6) — two-replica drill on real Postgres proves failover within lease TTL+5s (measured 4100 ms vs 9000 ms ceiling), idempotent outbox re-append on uncertain-commit replay, stale fence/revision write rejection, exactly-one lease owner, tenant isolation fail-closed. (7) **backup, restore, and migration rollback evidence** (Task 7) — `pg_dump`/`pg_restore` custom-format backup (108,291 B / 122 ms / 382 ms restore), 0.2.6→0.2.7 migration forward+rollback rehearsed (5 migrations), PITR RPO 0 s / RTO 1 s (recovery 1163 ms); production rollback is roll-forward repair only (no down migrations). (8) **field-level data classification and redaction** (`field-policy`, Task 8) — `applyFieldPolicy`/`FieldPolicy`/`createProtectedFieldPolicy` at the redaction, audit-export, and OpenTelemetry seams; unknown-label deny-on-outbound fail-closed default, sparse-copy walker, measured overhead peak 99.8% of the redactor-walk baseline (cap 110%). (9) **ERP release journey** (`erp-evals`, Task 9) — `erpInvariantDataset` + `createErpInvariantScorers` (8 hard 0/1 gates consuming structured facts only) + `scripts/phase27-erp-journey.test.mjs` exercising identity/policy/budget/SoD-approval/outbox/saga-compensation/audit-export/legal-hold/classification/failover/restore end-to-end (4815 ms, all 8 invariants pass). Release graph stays **50** publishable manifests at exact **0.2.7**; zero new runtime dependency names (core remains dependency-free); 43 code packages + 6 pure-manifest family/profile.
552
-
553
- **Measured reductions and deltas (recorded in `scripts/phase27-release-evidence.json`).** New error families: `ERR_PRISM_ENTERPRISE_POSTGRES_CONFLICT` (outbox), `ERR_PRISM_SAGA_*`, `ERR_PRISM_FIELD_POLICY` — all additive, all fail closed. New protected env names (never values): `PRISM_TEST_POSTGRES_URL` (HA/DR/journey), `PRISM_DR_TARGET_URL` + `PRISM_PITR_URL` (DR drill). Coverage stayed above the recorded floors (policy 92.66% vs 90.78% threshold, evals 91.75% vs 87.63%, core 91.09%). **Rollback notes.** Rollback = restore the 0.2.6 manifests/tag. The two new ERP migrations (`004_erp_messaging`, `005_erp_approvals`) are forward-only; before downgrading, stop all 0.2.7 workers (outbox dispatcher, saga engine, audit exporter) and drop the `prism_erp_outbox`/`prism_erp_inbox`/`prism_erp_approvals` tables (they hold no 0.2.6 data). No 0.2.6 persisted shape changed, so an ordinary downgrade is store-safe; the added exports and ERP tables simply disappear. **"ERP production ready" remains blocked until the 0.3.0 live-service matrix is recorded** — passing 0.2.7 gates unblocks the release cut, not the 0.3.0 live-service matrix.
554
-
555
- ```bash
556
- # Operator prerequisites recorded: clean tree at the v0.2.7 tag candidate, GPG key, npm OIDC publisher.
557
- node scripts/release.mjs bump --from 0.2.6 --to 0.2.7 # already applied by Task 10; idempotent
558
- npm test # core + workspace suites + all script gates (incl. phase27-freeze + phase27-release + phase27-ha/erp-journey protected legs)
559
- npm run security:threat-suites # phase8-11 + phase20-26 public-entry conformance
560
- PRISM_TEST_POSTGRES_URL=postgres://postgres:prism@127.0.0.1:54329/prism_test npm run test:postgres
561
- node --test scripts/phase27-ha.test.mjs # protected: real Postgres two-replica failover drill
562
- node --test scripts/phase27-dr.test.mjs # protected: backup/restore/PITR + 0.2.6->0.2.7 migration rehearsal (PRISM_DR_TARGET_URL + PRISM_PITR_URL)
563
- node --test scripts/phase27-erp-journey.test.mjs # protected: ERP release journey (8 invariant scorers)
564
- PRISM_TEST_POSTGRES_URL=postgres://postgres:prism@127.0.0.1:54329/prism_test npm run sdk:ready
565
- node scripts/release.mjs gate --version 0.2.7 # plain reviewed gate at 0.2.7: version literal + additive exports only, 0 breaking deltas
566
- npm run pack:dry-run # twice; diff reports — deterministic
567
- npm audit --audit-level=moderate
568
- npm run release:check -- --version 0.2.7 --report /tmp/prism-0.2.7-preflight.json
569
- npm run release:publish -- --version 0.2.7 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.2.7-dry-run.json
570
- # run the dry-run twice and diff the reports: deterministic, byte-identical
571
- ```
572
-
573
- Protected evidence (never a passing skip): the HA failover drill (real Postgres two-replica split-brain fence, idempotent outbox replay, stale-write rejection), the DR drill (pg_dump/restore + PITR + 0.2.6→0.2.7 migration rehearsal), the ERP release journey (`docs/_evidence/phase27-erp-journey.json` — 8 invariant scorers, pass/blocked/protected, never a passing skip), the protected Postgres enterprise-state legs, and the live canaries (provider OIDC/OPA, MCP, A2A, Brave — always `protected` rows in the manifest, never `pass`). The release skip manifest names every skip class with its required env; missing protected evidence records 0.2.7 as **blocked**, never a passing skip. The final evidence manifest `scripts/phase27-release-evidence.json` records commit, tool versions, test totals, coverage, timings, budgets, known limitations, and the explicit 0.3.0 blocker + pending operator sign-off.
574
-
575
- ### 0.2.5 publish handoff (plan 025 Task 6)
576
-
577
- **Decision: GO when the operator prerequisites below are recorded.** Release **0.2.5** (plan 025) is the maintainability-and-bounded-performance cut on the 0.2.x review-remediation line. API surface **additive-only** (plain reviewed compat gate at 0.2.5: expected deltas are the version literal plus 105 additive internal-helper exports from the splits/dedup — 84 Task 1 cross-family helpers across `@arnilo/prism`/`prism-coding-agent`/`prism-workflows`/`prism-server`/`prism-ag-ui` and 21 `prism-session-store-codecs` helpers — zero removals; baselines regenerated with `--update-baseline`, no `--allow-break`; freeze manifest `scripts/phase25-freeze-manifest.json`). Internal-only refactoring and bounded-performance work, **no runtime contract change and no migration**: (1) **god-module splits, compat-preserving** — the six remaining implementation god-modules split along cohesive boundaries into internal family files behind preserved barrels (0.1.4 precedent): `src/contracts-core.ts` (1,719 L → 10 families, max 403 L), `src/agent-session.ts` (2,049 L → 4 modules; the 1,686-L `RuntimeAgentSession` class is kept intact — a single TS class cannot span files without exporting private methods, recorded reason), `packages/workflows/src/run.ts` (1,227 L → 6 families, max 417 L), `packages/server/src/handler.ts` (1,005 L → 8 families, max 444 L), `packages/coding-agent/src/repository.ts` (974 L → 7 families, max 299 L), `packages/ag-ui/src/acp/agent.ts` (836 L → 8 families, max 386 L). No `exports` map gained a subpath; `ponytail:` comments preserved verbatim; every package verified with **zero breaking compat deltas** (`scripts/phase25-compat-diff.mjs`). (2) **persistence-mechanics dedup** — 21 pure helpers (ownership scope/assertion, checkpoint stale/encode/decode, branch cursors, lifecycle quota/reason/page-limit, search metadata/clipping, deepFreeze/string-array/throwIfAborted, feedback row mapping) moved into the dependency-free `packages/session-store-codecs` (426 → 624 L, stdlib only, no SQL dialect leakage); the adapters shrank 273 lines total (postgres 1,104 → 1,041, sqlite 1,088 → 1,010); SQL fragments, DDL templates, and query execution stay per-adapter; no persisted-shape change; cross-store conformance proves identical semantics before/after. (3) **quadratic accumulation removed** — the per-push `Buffer.concat` loops in language framing (`LspFrameReader`) and tar parsing (`summarizeTarStream`) became chunk-array readers (two-phase header parse + offset-advance `drop`, `take`/`drop` sliding window); caps and fail-closed overflow behavior byte-identical; framing measured **~100–200× faster at N=4000 chunks** (1,298.4 ms → 11.2 ms) and tar linear at 8 MiB; CLI capture (`collectOutput`) audited — already linear since plan 020; the near-limit probe `scripts/phase25-bounded-accumulation.test.mjs` (10 tests) is wired into the npm test gate segment and asserts linear copying by byte-count instrumentation. (4) **dead-code cleanup, internal-only** — the 62 `dead-exports.mjs` candidates triaged into 2 removals (`PostgresPersistenceCloseOptions`, `SqlitePersistenceCloseOptions` — internal type aliases never re-exported from their adapter indexes) + 60 allow-listed with reasons in `docs/_evidence/phase25-dead-exports-triage.md` (37 test-used false positives, 20 dead-but-compat-tracked deferred to the 0.3.0 breaking cut, 3 public type aliases deferred); the named-internal audit (`agent-session`/`cache-telemetry`/`skill-load`) recorded as clean at 0.2.4; no public export removed, so **no `docs/migration.md` removal note is required** (this section records the no-runtime-contract-delta statement instead). (5) **coverage close, behavior-backed** — 76 focused regressions (approval 43 — the untested `agent-approval.ts` resolve/validate/pending paths; conversations 22 — cursor codec + thread projection; artifacts 6 — approval-state/checkpoint-key/error codes; tool-effect-store conformance 5 — violation throws + option defaults; compaction relies on its 17 existing package suites); core coverage rose **90.53/84.20/90.54 → 91.43/84.80/91.60** lines/branches/functions (gate 60/70/75; all 39 non-protected packages above their evidence thresholds). Release graph stays **50** publishable manifests at exact **0.2.5**; zero new runtime dependency names (core remains dependency-free); 43 code packages + 6 pure-manifest family/profile.
578
-
579
- **Measured reductions and deltas (recorded in `scripts/phase25-baseline.json` `exitGate`).** File-size/complexity: the six monoliths (totaling ~8.2 kL) split into families with max sizes 299–444 L (the 1,686-L class exception recorded); the adapters shrank 273 L (net −75 with the codecs growth). Tree-shaking/startup: no regression — root packed bytes unchanged (800,042), startup `importMs` within the 250 ms ceiling, the +30 root `fileCount` (326 → 356) is Task 1 split `dist` files (`.map` excluded) re-baselined with a dated `$comment`. Near-limit perf: framing linear at 4,000 chunks (~100–200× faster), tar linear at 8 MiB, both with byte-identical caps and fail-closed overflow. Coverage: core +0.90/+0.60/+1.06 lines/branches/functions with 76 behavior-backed tests (no line-count padding). **Rollback notes.** Rollback = restore the 0.2.4 manifests/tag. Nothing persisted changes shape, no default or behavior changed, and the only public-surface deltas are additive; downgrade is store-safe and code-safe — the only visible deltas are the version literal and the extra exports (a 0.2.4 consumer can downgrade without code changes; the added helpers simply disappear).
580
-
581
- ```bash
582
- # Operator prerequisites recorded: clean tree at the v0.2.5 tag candidate, GPG key, npm OIDC publisher.
583
- node scripts/release.mjs bump --from 0.2.4 --to 0.2.5 # already applied by Task 6; idempotent
584
- npm test # core + workspace suites + all script gates (incl. phase24-truth + phase25-bounded-accumulation)
585
- npm run security:threat-suites # phase8-11 + phase20-24 public-entry conformance
586
- PRISM_TEST_POSTGRES_URL=postgres://postgres:prism@127.0.0.1:54329/prism_test npm run test:postgres # incl. the cross-store conformance legs
587
- PRISM_TEST_POSTGRES_URL=postgres://postgres:prism@127.0.0.1:54329/prism_test npm run sdk:ready
588
- node scripts/release.mjs gate --version 0.2.5 # plain reviewed gate at 0.2.5: version literal + additive exports only, 0 breaking deltas
589
- npm run pack:dry-run # twice; diff reports — deterministic
590
- npm audit --audit-level=moderate
591
- npm run release:check -- --version 0.2.5 --report /tmp/prism-0.2.5-preflight.json
592
- npm run release:publish -- --version 0.2.5 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.2.5-dry-run.json
593
- # run the dry-run twice and diff the reports: deterministic, byte-identical
594
- ```
595
-
596
- Protected evidence (never a passing skip): the durable state-concurrency legs + the Task 2 **cross-store conformance** legs (Postgres `prism_phase25_*` schemas — `npm run test:postgres` under `PRISM_TEST_POSTGRES_URL`; absent credentials record **blocked** per the release skip manifest), the phase25 bounded-accumulation near-limit probe over built dist, and the live canaries (provider OIDC/OPA, MCP, A2A, Brave — always `protected` rows in the manifest, never `pass`). The release skip manifest names every skip class with its required env; missing protected evidence records 0.2.5 as **blocked**, never a passing skip.
597
-
598
- ### 0.2.3 publish handoff (plan 023 Task 6)
599
-
600
- **Decision: GO when the operator prerequisites below are recorded.** Release **0.2.3** (plan 023) is the build-coverage-and-release-evidence-integrity cut on the 0.2.x review-remediation line. API surface **additive-only** (plain reviewed compat gate at 0.2.3: delta is the version literal only — no export changes; baselines regenerated with `--update-baseline`, no `--allow-break`; freeze manifest `scripts/phase23-freeze-manifest.json`). Four tooling/evidence fixes, **no runtime contract change and no migration**: (1) **build serialization** — dependency-free `scripts/with-build-lock.mjs` serializes every emit/test leaf with one `O_EXCL` lockfile at `node_modules/.prism-build.lock` (pid + startedAt, read-back verified, stale-PID reclaim, `PRISM_BUILD_LOCK_TIMEOUT_MS` env override, fail-closed exit 1), so concurrent compilers can never expose a partial live `dist/`; the lock is never held by orchestrator scripts and `PRISM_BUILD_LOCK_HELD=1` prevents accidental nesting. **Caveat:** the lock only guards the wrapped leaves — a direct `tsc` invoked outside the wrapper can still race an importer, exactly like any external writer. (2) **corrected workspace coverage denominators** — workspace coverage runs use package-local `--test-coverage-include=dist/**` (imported core `dist` no longer pollutes package rows), the 60/70/75 core gate is unchanged, per-package line thresholds in `scripts/coverage-thresholds.json` are evidence-based (freeze-run minus 3 pp), env-gated durable-leg packages (`session-store-postgres`, `enterprise-postgres`, `memory`, `session-store-nats`) are `protectedException` rows shown separately, and `scripts/coverage-summary.json` is the machine-readable artifact the release gate reads. (3) **release skip manifest** — `scripts/release-skip-manifest.mjs` records every surface (`pass`/`skip`/`blocked`/`protected`, reason, required env names only) into `scripts/release-evidence.json`; a required surface with absent evidence records `blocked` and `release.mjs gate` fails closed — missing credentials/services can never convert into a green release. (4) **stabilized quality gates** — Biome 2.x `preset` config migration with zero lint diagnostics, the racy 150 ms MCP bridge timing assert replaced by a deterministic barrier, load-sensitive guards carry documented `ponytail:` ceilings, and `lint-report.sarif` + `unused-report.json` are machine-readable and CI-retained. Regression surface: `phase23-build-race` (8), `phase23-coverage` (4), `phase23-skip-manifest` (6), `phase23-quality-gates` (5), `phase23-security` (3, matrix items 4 and 12 by name) + packed plain-JS `security23.mjs` consumer. Exit gate green: npm test core + workspace + script gates, `sdk:ready` exit 0, audit 0 moderate, secret scans 0 findings, pack dry-run 50/50 twice byte-identical, plain reviewed compat gate at 0.2.3, protected Postgres durable conformance evidence, release-evidence manifest with zero blocked surfaces; evidence in `scripts/phase23-baseline.json` `exitGate`. **Rollback notes.** Rollback = restore the 0.2.2 manifests/tag — but that reopens the partial-`dist` race window and the polluted coverage denominator, so prefer fixing the failing host on 0.2.3. Nothing persisted changes shape, so downgrade is store-safe. (CI remediation 2026-08-14: `coding-security` joined the `protectedException` rows — its native-sandbox legs probe `unshare --net` NETNS at load and skip on GitHub Actions runners, so the host-captured freeze threshold can never be met in CI; measured 72.80 lines in CI vs 80.18 on a NETNS-capable host.)
601
-
602
- ```bash
603
- # Operator prerequisites recorded: clean tree at the v0.2.3 tag candidate, GPG key, npm OIDC publisher.
604
- node scripts/release.mjs bump --from 0.2.2 --to 0.2.3 # already applied by Task 6; idempotent
605
- npm test # core + workspace suites + all script gates (incl. phase23 suites)
606
- npm run security:threat-suites # phase8-11 + phase20 + phase21 + phase22 + phase23 public-entry conformance
607
- PRISM_TEST_POSTGRES_URL=postgres://postgres:prism@127.0.0.1:54329/prism_test npm run sdk:ready
608
- node scripts/release.mjs gate --version 0.2.3 # plain reviewed gate at 0.2.3: version literal only, 0 breaking deltas
609
- npm run pack:dry-run # twice; diff reports — deterministic
610
- npm audit --audit-level=moderate
611
- npm run release:check -- --version 0.2.3 --report /tmp/prism-0.2.3-preflight.json
612
- npm run release:publish -- --version 0.2.3 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.2.3-dry-run.json
613
- # run the dry-run twice and diff the reports: deterministic, byte-identical
614
- ```
615
-
616
- Protected evidence (never a passing skip): the durable state-concurrency legs (Postgres `prism_phase23_*` schemas for sessions/checkpoints/events + enterprise router reservations/idempotency — `npm run test:postgres` under `PRISM_TEST_POSTGRES_URL`), the phase23 public-entry build-race + coverage-denominator conformance, and the live canaries (provider OIDC/OPA, MCP, A2A, Brave — always `protected` rows in the manifest, never `pass`). The release skip manifest names every skip class with its required env; missing protected evidence records 0.2.3 as **blocked**, never a passing skip.
617
-
618
- ### 0.2.2 publish handoff (plan 022 Task 6)
619
-
620
- **Decision: GO when the operator prerequisites below are recorded.** Release **0.2.2** (plan 022) is the concurrent-state-and-durability-integrity cut on the 0.2.x review-remediation line. API surface **additive-only** vs 0.2.1 (plain reviewed compat gate at 0.2.2: deltas are the version literal plus `ModelRouterStateStore.reserveBudget`/`commitBudget`/`releaseBudget`, `ModelRouterReservation`, `ModelRouterBudgets.reservationTtlMs`, `ModelRouterLimits.maxRateKeys`/`maxBudgetKeys`, `SessionRecord.version` with `appendSession` `expectedVersion`, `EventMultiplexerError`, and the `@arnilo/prism/testing/state-concurrency-conformance` subpath — no removal; baselines regenerated with `--update-baseline`, no `--allow-break`; freeze manifest `scripts/phase22-freeze-manifest.json` records per-task evidence tokens). Four behavior tightenings documented in `docs/migration.md` `0.2.1 → 0.2.2`: (1) **atomic model-budget reservation** — `reserveBudget` at admission (used + reserved + requested <= window max, `{reservationId, fencingToken, admitted, retryAfterMs?}`), `commitBudget`/`releaseBudget` at outcome, TTL expiry (default 60 s) with late commits reconciled as `unknownUsage: true`; rate/budget key maps capped (4,096 default / 65,536 hard) with LRU eviction that never drops a held-reservation row; durable reservations live in a new `reservations` JSONB column (enterprise migration 003). (2) **atomic conversation metadata** — `SessionRecord.version` + `appendSession` `expectedVersion` (`0` create-only, `N>0` exact-CAS update-only, omitted = legacy last-write-wins); stale writes throw `SessionMetadataConflictError` `metadata_conflict` (versions only, HTTP 409); concurrent create/branch/archive single-statement with branch caps inside the CAS, archive wins, deleted rows never resurrect (migration 008). (3) **single-consumer EventMultiplexer** — second concurrent `subscribe()` throws `EventMultiplexerError` `ERR_PRISM_EVENT_MULTIPLEXER_SINGLE_CONSUMER`. (4) **restart-stable NATS durable identity + bounded non-durable active-run registries** — durable name exactly `prism_<hmac16>`, crash-resume continues from the last ack, orphaned 0.2.1 random-suffixed consumers reclaimed on clean stop; workflow active-run registry sweeps aborted entries and fails closed at the 512 cap. New regression surface: `scripts/phase22-security.test.mjs` (4 blockers + gate accounting over built public entrypoints, wired into `security:threat-suites`), packed plain-JS `security22.mjs` consumer in install-smoke, the `@arnilo/prism/testing/state-concurrency-conformance` harness (7 probes; memory leg in npm test, durable legs in `test:postgres` and the NATS seam; zero timing-only sleeps), and the `scripts/phase22-conformance.test.mjs` gate in the `test:postgres` chain. Store compatibility with 0.2.1: **forward-only migrations** (008 + 003), see `docs/migration.md` for rollback risk. Exit gate green: npm test core + workspace + script gates (incl. phase21-freeze done-phase + phase22 conformance), `sdk:ready` exit 0, audit 0 moderate, secret scans 0 findings, pack dry-run 50/50 twice byte-identical, plain reviewed compat gate at 0.2.2, protected OIDC/OPA evidence + durable state-concurrency evidence; evidence in `scripts/phase22-baseline.json` `exitGate`. Rollback = restore the 0.2.1 manifests/tag — but that reopens all four race windows, so prefer fixing the failing host on 0.2.2.
621
-
622
- ```bash
623
- # Operator prerequisites recorded: clean tree at the v0.2.2 tag candidate, GPG key, npm OIDC publisher.
624
- npm test # core + workspace suites + all script gates (incl. phase22 conformance)
625
- npm run security:threat-suites # phase8-11 + phase20 + phase21 + phase22 public-entry conformance
626
- npm run sdk:ready # typecheck, lint, format, test, coverage, pack, release:gate
627
- node scripts/release.mjs gate --version 0.2.2 # plain reviewed additive gate, 0 breaking deltas
628
- npm run pack:dry-run # twice; diff reports — deterministic
629
- npm audit --audit-level=moderate
630
- npm run release:check -- --version 0.2.2 --report /tmp/prism-0.2.2-preflight.json
631
- npm run release:publish -- --version 0.2.2 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.2.2-dry-run.json
632
- # run the dry-run twice and diff the reports: deterministic, byte-identical
633
- ```
634
-
635
- Protected evidence (never a passing skip): live OIDC JWKS through the default pinned path (`createOidcIdentityVerifier` against a real public IdP — real DNS/TLS/JWKS document, e.g. `https://login.microsoftonline.com/common/discovery/v2.0/keys`, success proven by a key-lookup miss after a 200 fetch), live OPA (dockerized `openpolicyagent/opa`, default pinned path fails closed `ssrf_denied`), and the durable state-concurrency legs (Postgres `prism_phase22_*` schemas for sessions/checkpoints/events + enterprise router reservations/idempotency, NATS restart-durable resume against the seam). Missing protected evidence records 0.2.2 as **blocked**, never a passing skip.
636
-
637
- ### 0.2.1 publish handoff (plan 021 Task 8)
638
-
639
- **Decision: GO when the operator prerequisites below are recorded.** Release **0.2.1** (plan 021) is the provider-completion and outbound-trust-boundaries cut on the 0.2.x review-remediation line. API surface **additive-only** vs 0.2.0 (plain reviewed compat gate at 0.2.1: the only deltas are the version literal and `@arnilo/prism-mcp` transport helpers `boundResponse`/`defaultResolver`/`isLoopbackAddress`/`isLoopbackHostname`/`normalizeHostname`/`raceAbort`/`requestPinned`/`resolvePinnedAddress` becoming re-exports of the lifted core primitives — same names/signatures, no removal; baselines regenerated with `--update-baseline`, no `--allow-break`; freeze manifest `scripts/phase21-freeze-manifest.json` machine-checks each task's diff and the preserved surface). Five documented security-motivated behavior tightenings in `docs/migration.md` `0.2.0 → 0.2.1`: (1) **strict stream completion is the shared default** (`strictCompletion: true` in `createOpenAICompatibleProvider`; explicit `false` stays the documented opt-out; truncated streams fail `ProviderTransportError` `incomplete_delta` instead of a successful `providerDone`; applies to Azure/Bedrock/Vertex/OpenRouter/ZAI/NeuralWatt); (2) **bounded success bodies** — additive `readBoundedResponseJson` (65,536-byte ceiling, depth 32, properties 4096, shape gate, abort, redacted errors, `response_body_shape` code) replaces unbounded `response.json()` on all ten model-discovery sites plus NeuralWatt quota, Alibaba embeddings, OpenAI uploads, and both OAuth success paths; (3) **DNS-pinned OIDC JWKS/OPA/content fetch, redirects rejected** — core `pinnedFetch` (one resolve, 1–32 bound, per-candidate SSRF validation, pinned-lookup socket) serves the default JWKS, OPA decision, and content/media paths; 3xx fails `MediaContentError` `redirect`; private/metadata/loopback fails `ssrf_denied`; MCP re-exports the lifted helpers byte-identically; (4) **shared bounded OAuth device/token polling** — core `pollDeviceCodeToken` serves provider-openai and credentials-node with equivalent cadence/backoff/redaction; (5) **edge fixes** — Azure/Vertex credential-once, Bedrock duplicate-case/repeated-query SigV4 canonicalization, OpenAI upload failed-DELETE retention, cache `__overflow__` tokens-only. New regression surface: `scripts/phase21-security.test.mjs` (10 conformance tests over built public entrypoints, wired into `security:threat-suites`) and a packed plain-JS `security21.mjs` consumer in install-smoke. Store compatibility with 0.2.0: **compatible, no migration**. Exit gate green: npm test core + script gates (incl. phase21-freeze done-phase), `sdk:ready` exit 0, audit 0 moderate, pack dry-run 50/50 twice byte-identical, plain reviewed compat gate at 0.2.1, live OIDC JWKS + live OPA protected evidence; evidence in `scripts/phase21-baseline.json` `exitGate`. Rollback = restore the 0.2.0 manifests/tag — but rollback restores the five boundary gaps, so hosts should disable truncated-stream acceptance, unbounded-body endpoints, redirect-following fetches, rotating-credential reuse, and upload cleanup at their own boundary if rollback is unavoidable.
640
-
641
- ```bash
642
- # Operator prerequisites recorded: clean tree at the v0.2.1 tag candidate, GPG key, npm OIDC publisher.
643
- npm test # core + workspace suites + all script gates
644
- npm run security:threat-suites # phase8-11 + phase20 + phase21 public-entry conformance
645
- npm run sdk:ready # typecheck, lint, format, test, coverage, pack, release:gate
646
- node scripts/release.mjs gate --version 0.2.1 # plain reviewed additive gate, 0 breaking deltas
647
- npm run pack:dry-run # twice; diff reports — deterministic
648
- npm audit --audit-level=moderate
649
- npm run release:check -- --version 0.2.1 --report /tmp/prism-0.2.1-preflight.json
650
- npm run release:publish -- --version 0.2.1 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.2.1-dry-run.json
651
- # run the dry-run twice and diff the reports: deterministic, byte-identical
652
- ```
653
-
654
- Protected evidence (never a passing skip): live OIDC JWKS through the default pinned path (`createOidcIdentityVerifier` against a real public IdP — real DNS/TLS/JWKS document, e.g. `https://login.microsoftonline.com/common/discovery/v2.0/keys`, success proven by a key-lookup miss after a 200 fetch) and live OPA (`docker run -p 127.0.0.1:8181:8181 openpolicyagent/opa run --server`, push a policy, then prove the default pinned path fails closed `ssrf_denied` against the real server; decision-success behavior is covered by the built public conformance suite since the pinned path refuses private addresses by design). Missing protected evidence records 0.2.1 as **blocked**, never a passing skip.
655
-
656
- ### 0.2.0 publish handoff (plan 020 Task 6)
657
-
658
- **Decision: GO when the operator prerequisites below are recorded.** Release **0.2.0** (plan 020) is the first cut of the 0.2.x review-remediation line — fail-closed runtime and sandbox security. API surface **additive-only** vs 0.1.7 (plain compat gate at 0.2.0: 0 breaking declaration deltas — the three blockers are behavior tightenings, not removals; `containmentClaim` retained deprecated; baseline text regenerated with `--update-baseline`, no `--allow-break` anywhere; freeze manifest `scripts/phase20-freeze-manifest.json` machine-checks each task's diff stayed inside its allowed files). Shipped: (1) **durable-resume input validation** — `assertValidAgentRunResume` at the top of `prepareAgentRunResume` covers all four public resume entrypoints; unknown legacy decisions (`"sideways"`), malformed batches, oversized reasons/elicitation, duplicate approval ids fail closed `ERR_PRISM_DECISION_*` with zero checkpoint writes/tool calls (server parser stays defense in depth); (2) **work-tool environment isolation** — `createCliRunner` children get a fixed base allow-list + explicit env + forced HOME/telemetry controls + late-bound per-identity tokens, 64-name/64-KiB caps `ERR_PRISM_WORK_ENV`, absolute binary/configDir, linear output capture; (3) **explicit sandbox capabilities** — `SandboxAdapter.capabilities` (six immutable booleans, omission/malformed ⇒ all false), composition capabilities from verified wiring, `containmentClaim` deprecated as the conservative projection; Docker reports only verified controls, native reports filesystem/process/privilege false; docs/coding-security.md capability table, docs/host-security.md authorization guidance. New regression surface: `scripts/phase20-security.test.mjs` (public built entrypoints, wired into `security:threat-suites`), packed plain-JS consumer regressions in install-smoke, and the sandbox-browser workflow's fail-loud 0.2.0 blocker gate recording Docker/native capability evidence — **0.2.0 does not ship while any blocker is skipped**. Store compatibility with 0.1.7: **compatible, no migration** (no persisted-shape change; `docs/migration.md` `0.1.7 → 0.2.0` section). Exit gate green: npm test core + script gates (incl. phase20-freeze done-phase), `sdk:ready` exit 0, audit 0 moderate, pack dry-run 50/50 twice byte-identical, plain reviewed compat gate at 0.2.0, Docker daemon + native netns protected evidence; evidence in `scripts/phase20-baseline.json` `exitGate`. Rollback = restore the 0.1.7 manifests/tag — but rollback restores the three defects, so hosts should disable resume side effects and work-tool execution at their own boundary if rollback is unavoidable.
659
-
660
- ```bash
661
- # Operator prerequisites recorded: clean tree at the v0.2.0 tag candidate, GPG key, npm OIDC publisher.
662
- npm test # core + workspace suites + all script gates
663
- npm run security:threat-suites # phase8-11 + phase20 public-entry conformance
664
- npm run sdk:ready # typecheck, lint, format, test, coverage, pack, release:gate
665
- node scripts/release.mjs gate --version 0.2.0 # plain reviewed additive gate, 0 breaking deltas
666
- npm run pack:dry-run # twice; diff reports — deterministic
667
- npm audit --audit-level=moderate
668
- npm run release:check -- --version 0.2.0 --report /tmp/prism-0.2.0-preflight.json
669
- npm run release:publish -- --version 0.2.0 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.2.0-dry-run.json
670
- # run the dry-run twice and diff the reports: deterministic, byte-identical
671
- ```
672
-
673
- Protected evidence (never a passing skip): `docker info` + digest-pinned image (e.g. `PRISM_TEST_DOCKER_SANDBOX=1 PRISM_TEST_DOCKER_BIN=/usr/bin/docker PRISM_TEST_DOCKER_IMAGE=ubuntu@sha256:... npm test -w @arnilo/prism-coding-tools/security -- --test-name-pattern "protected Docker"`) and native netns capability (`unshare --net` / `--net --map-root-user` must succeed; T9 native capability test runs, not skips). The sandbox-browser workflow fails loudly when this evidence is missing.
674
-
675
- ### 0.1.7 publish handoff (plan 019 Task 6)
676
-
677
- **Decision: GO when the operator prerequisites below are recorded.** Release **0.1.7** (plan 019) is the performance-and-DX patch on the frozen 0.1.x line — **additive-only** vs 0.1.6 (plain compat gate at 0.1.7 passed with 0 breaking declaration deltas; the baseline text was regenerated with `--update-baseline` for the version literal only, no `--allow-break` anywhere; freeze manifest `scripts/phase19-freeze-manifest.json` machine-checks each task's diff stayed inside its allowed files). Shipped: (1) **prompt-cache telemetry surface** — dependency-free `createCacheTelemetry()` aggregator in core, host-activated, per-provider/model request counts + aggregate hit rate + cache-read/write token totals + estimated savings, bounded cardinality (cap 256 distinct keys, `__overflow__` bucket), token counters/rates only (never prompt content, cache keys, or identity), O(1) `record()`; (2) **model-router selection policies** — additive `ModelRouterSelectionPolicy` on `createModelRouter` (default ordered behavior byte-identical) with the reference `createCostLatencySelection` ranking by `ModelCost` then in-memory latency EMA fed from `recordOutcome({ latencyMs })`, permutation-only reorder of already-allowed candidates, misbehavior fails closed `ERR_PRISM_MODEL_ROUTER_POLICY`; (3) **async AgUiProjection closeout** — plan 009 Task 15 surface verified with evidence (`asyncHooks: {verified: true, gapFound: false}` in `scripts/phase19-baseline.json`), no new code; (4) **`prism providers add <name>` scaffold** — new CLI subcommand generating an OpenAI-compatible provider package (manifest, provider via `createOpenAICompatibleProvider`, starter models, cache helpers, offline conformance test, docs stub) with npm-name/traversal/symlink-escape validation and placeholders only — never secrets; scaffold output is host-chosen and never auto-registered. Store compatibility with 0.1.6: **compatible, no migration** (additive-only; no persisted-shape change; `docs/migration.md` gains no entries). Exit gate green: npm test core + script gates (incl. phase19-freeze done-phase), `sdk:ready` exit 0, audit 0 moderate, pack dry-run 50/50 twice byte-identical, budget/benchmark gates green; evidence in `scripts/phase19-baseline.json` `exitGate`. Rollback = restore the 0.1.6 manifests/tag.
678
-
679
- ```bash
680
- # Operator prerequisites recorded: clean tree at the v0.1.7 tag candidate, GPG key, npm OIDC publisher.
681
- npm test # core + workspace suites + all script gates
682
- npm run sdk:ready # typecheck, lint, format, test, pack, release:gate
683
- node scripts/release.mjs gate --version 0.1.7 # plain additive gate, 0 breaking deltas
684
- npm run pack:dry-run # twice; diff reports — deterministic
685
- npm audit --audit-level=moderate
686
- npm run release:check -- --version 0.1.7 --report /tmp/prism-0.1.7-preflight.json
687
- npm run release:publish -- --version 0.1.7 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.1.7-dry-run.json
688
- # run the dry-run twice and diff the reports: deterministic, byte-identical
689
-
690
- # Sign the release on the clean tagged tree (operator GPG key):
691
- git tag -s v0.1.7 -m "Prism 0.1.7 — performance and DX (additive)"
692
- git verify-tag v0.1.7
693
- git push origin v0.1.7 # tag push triggers release.yml publish job (provenance, attestations)
694
-
695
- # Real publication never bypasses the gates: release.mjs refuses
696
- # --allow-dirty/--allow-untagged without --dry-run.
697
- ```
698
-
699
- ### 0.1.6 publish handoff (plan 018 Task 7)
700
-
701
- **Decision: GO when the operator prerequisites below are recorded.** Release **0.1.6** (plan 018) is the coding-agent capability-closeouts patch on the frozen 0.1.x line — **additive-only** vs 0.1.5 (plain compat gate at 0.1.6 passed with 0 breaking declaration deltas; the baseline text was regenerated with `--update-baseline` for the version literal only, no `--allow-break` anywhere). Five demand-gated closeouts shipped, each flipped to `demanded` by named demand evidence (operator `arn` for native-sandbox/doc-reader/delete-glob/checkpoint-bodies, a consuming-app user for acp-session-store) before its task landed; the demand-gate registry (`scripts/phase18-freeze-manifest.json`) machine-checks demanded ⇒ implemented, deferred ⇒ untouched. Shipped: (1) **durable ACP session store** — `@arnilo/prism-ag-ui` `AcpSessionStore` host seam (`save`/`loadAll`/`evict`), persisted `{sessionId, ownership, modeId, configValues, cwd, additionalDirectories, updatedAt}`, lazy ownership-scoped restore, fail-closed drops, absent seam = 0.1.5 behavior; (2) **network-free native sandbox** — `createNativeSandbox` in `@arnilo/prism-coding-security` (fresh netns per command via the OS `unshare` binary, chained ulimits with `|| exit 126`, argv-only exec, cwd containment, process-group kill, env allow-list, Linux-only fail-closed); (3) **bounded PDF/Office document reader** — new optional package `@arnilo/prism-document-reader` (the 50th manifest, graph 49 → 50) with optional `pdf-parse`/`mammoth` peers fail-closed at creation, magic-byte gating, null fall-through, caps + redaction at the adapter boundary; (4) **recursive delete + brace-expanding glob** — per-call `recursive: true` with fan-out cap and symlink-unlink-not-follow, host-selected/per-call `braceExpansion` bounded to 128 alternatives / 4096 expanded bytes, fail-closed on overflow/malformed braces; (5) **checkpoint persistence for loaded-skill bodies** — opt-in `includeSkillBodies` on run + resume options (names-only stays default, 0.1.3 shapes byte-identical), ≤64 bodies / ≤256-char names / ≤262144-byte bodies / ≤1 MiB total, `maxStateBytes` refusal, redacted at rest, registry-independent resume render. Store compatibility with 0.1.5: **compatible, no migration** (additive-only; no persisted-shape change; `docs/migration.md` gains no entries). Exit gate green: npm test core 1,433/1,433 + 190 script gates (incl. phase18-freeze done-phase), `sdk:ready` exit 0, audit 0 moderate, pack dry-run 50/50 twice byte-identical, budget/benchmark gates green; evidence in `scripts/phase18-baseline.json` `exitGate`. Rollback = restore the 0.1.5 manifests/tag.
702
-
703
- ```bash
704
- # Operator prerequisites recorded: clean tree at the v0.1.6 tag candidate, GPG key, npm OIDC publisher.
705
- npm test # core + workspace suites + all script gates
706
- npm run sdk:ready # typecheck, lint, format, test, pack, release:gate
707
- node scripts/release.mjs gate --version 0.1.6 # plain additive gate, 0 breaking deltas
708
- npm run pack:dry-run # twice; diff reports — deterministic
709
- npm audit --audit-level=moderate
710
- npm run release:check -- --version 0.1.6 --report /tmp/prism-0.1.6-preflight.json
711
- npm run release:publish -- --version 0.1.6 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.1.6-dry-run.json
712
- # run the dry-run twice and diff the reports: deterministic, byte-identical
713
-
714
- # Sign the release on the clean tagged tree (operator GPG key):
715
- git tag -s v0.1.6 -m "Prism 0.1.6 — coding-agent capability closeouts (additive)"
716
- git verify-tag v0.1.6
717
- git push origin v0.1.6 # tag push triggers release.yml publish job (provenance, attestations)
718
-
719
- # Real publication never bypasses the gates: release.mjs refuses
720
- # --allow-dirty/--allow-untagged without --dry-run.
721
- ```
722
-
723
- **Rollback notes.** `release:publish --version 0.1.6 --resume --report release-artifacts/publish-report.json` resumes an interrupted publication and skips only registry versions whose internal dependency fingerprint matches the local manifest. A failed package aborts the run with its status written to the report; re-run after fixing the cause. npm cannot unpublish the `0.1.6` line after 72 hours — a post-publication defect ships as a `0.1.x` patch (additive-only compat promise, `release:gate` enforced), or as a documented break in the next line with a `docs/migration.md` entry. `0.1.6` is store-compatible with `0.1.5` in **both directions** (no migration ran — same checksum-protected contract), so an operator may defer or roll back the patch without a database rollback. The next line **0.1.7** continues the frozen 0.1.x additive promise; the 0.2.0 module line (delegated agents, agent-owned persistence, host-owned seam expansions) is the next documented cut.
724
-
725
- ### 0.1.5 publish handoff (plan 017 Task 4)
726
-
727
- **Decision: GO when the operator prerequisites below are recorded.** Release **0.1.5** (plan 017) is the **documented breaking cut** on the frozen 0.1.x line — deprecated-option removal, with the removed-symbols list, replacements, before/after examples, dynamic-config refusal behavior, store compatibility, and rollback in the top `docs/migration.md` `0.1.4 → 0.1.5` section. Removed: `ProviderRequestOptions.timeoutMs`/`maxRetries`/`maxRetryDelayMs` (inert in first-party providers; abort/retry lives at the host layer — replacements `RunOptions.signal`/`AgentConfig.retry`/`RunOptions.retry`), `RunOptions.maxToolRounds` (→ `limits.maxToolRounds`; CLI `--max-tool-rounds` unchanged), `ObservationalMemorySettingsInput` pre-0.0.19 flat keys and top-level `workerProvider`/`workerModel` aliases (→ nested `observation`/`reflection`/`dropper` configs; `sessionModel` fallback unchanged), `ReadToolOptions.autoResizeImages` (→ `transformImage`), and `INIT_PROVIDERS` (→ `listInitProviders()`). Every removal **fails closed** for untyped callers with a `TypeError` naming the replacement before any provider call, tool call, filesystem access, compaction, or session append. Compat baselines were regenerated only after the reviewed `--allow-break` break report: `arnilo__prism.txt` (removed `INIT_PROVIDERS` const + `maxToolRounds`/provider-knob member lines — interface members are not baseline text, so the delta is the `INIT_PROVIDERS` line), `arnilo__prism-coding-agent.txt` (`autoResizeImages` is an interface member — baseline delta limited to statement/re-export text if any), `arnilo__prism-compaction-observational-memory.txt` (flat keys and worker aliases are interface members — no baseline line delta expected). Publishable graph stays **49** manifests (root + 48 workspace) at exact **0.1.5**. Store compatibility with 0.1.4: **compatible, no migration** (removed options were inert aliases; nested replacements resolve to the same active values; `DEFAULT_RUN_LIMITS.maxToolRounds` 8 / hard cap 64 unchanged); zero new dependencies (lockfile name-set unchanged).
728
-
729
- ```bash
730
- # Operator prerequisites (each a named blocked gate — none may be skipped):
731
- # 1. protected live-canary matrix green (live-canaries.yml, canary-report.json retained)
732
- # 2. PostgreSQL + keychain protected suites green (test:postgres, keychain suite)
733
- # 3. CodeQL SAST green on the release commit (security.yml / release.yml codeql-release)
734
- # 4. npm OIDC trusted publishing identity authenticated (NPM_TOKEN with id-token, provenance)
735
-
736
- git diff --check
737
- npm ci
738
- npm run sdk:ready # includes typecheck, lint, format, full test, coverage, pack, release:gate
739
- npm run security:threat-suites
740
- PRISM_TEST_POSTGRES_URL="$DATABASE_URL" npm run test:postgres # Phase 7 + Phase 12 restart-recovery
741
- npm audit --audit-level=moderate
742
- npm run release:check -- --version 0.1.5 --report /tmp/prism-0.1.5-preflight.json
743
- npm run release:publish -- --version 0.1.5 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.1.5-dry-run.json
744
- # run the dry-run twice and diff the reports: deterministic, byte-identical
745
-
746
- # Sign the release on the clean tagged tree (operator GPG key):
747
- git tag -s v0.1.5 -m "Prism 0.1.5 — documented breaking cut: deprecated-option removal"
748
- git verify-tag v0.1.5
749
- git push origin v0.1.5 # tag push triggers release.yml publish job (provenance, attestations)
750
-
751
- # Real publication never bypasses the gates: release.mjs refuses
752
- # --allow-dirty/--allow-untagged without --dry-run.
753
- ```
754
-
755
- **Rollback notes.** `release:publish --version 0.1.5 --resume --report release-artifacts/publish-report.json` resumes an interrupted publication and skips only registry versions whose internal dependency fingerprint matches the local manifest. A failed package aborts the run with its status written to the report; re-run after fixing the cause. npm cannot unpublish the `0.1.5` line after 72 hours — a post-publication defect ships as a `0.1.x` patch (additive-only compat promise, `release:gate` enforced), or as a documented break in the next line with a `docs/migration.md` entry. `0.1.5` is store-compatible with `0.1.4` in **both directions** (no migration ran — same checksum-protected contract), so an operator may defer or roll back the cut without a database rollback; code/config using removed keys must be migrated first (removed keys fail closed on 0.1.5).
756
-
757
- ### 0.1.4 publish handoff (plan 016 Task 6)
758
-
759
- **Decision: GO when the operator prerequisites below are recorded.** Release **0.1.4** (plan 016) is the internal god-module split, compat-preserving on the frozen 0.1.x line: `src/agents.ts` and `src/contracts.ts` reorganized by concern behind barrel re-exports (`contracts-core`/`contracts-run-state`/`contracts-protocol`; `agent-session`/`agent-run-lifecycle`/`agent-approval`/`agent-tool-dispatch` reusing `agent-run-state`/`agent-loops`/`compaction`) with a **byte-identical public entry surface** (0 added/0 removed/0 changed vs the 0.1.3 baseline; the 14 additive union-surface helpers are internal cross-module exports, not consumer-importable — deviation #1), measured tree-shaking improvement (111,049 → 982 B `dist/agents.js`, 9,420 → 418 B `dist/contracts.js`, module count 64 → 70; evidence in `scripts/phase16-baseline.json`), and additive **`@arnilo/prism-browser` Chrome DevTools Protocol capabilities** (Tasks 4-5): `browser_evaluate`, `browser_observe`, `block_urls`/`unblock_urls`/`throttle`/`emulate` act actions, and `{ css }`/`{ xpath }` targets on Chromium hosts — 41 added / 0 removed / 18 changed declaration texts (15 re-export-statement artifacts + 3 optional-member/signature widenings), the documented deviation #2 carve-out; root `arnilo__prism.txt` regenerated with zero breaking deltas. Publishable graph stays **49** manifests (root + 48 workspace) at exact **0.1.4**. Store compatibility with 0.1.3: **compatible, no migration**; zero new dependencies (lockfile name-set unchanged).
760
-
761
- ```bash
762
- # Operator prerequisites (each a named blocked gate — none may be skipped):
763
- # 1. protected live-canary matrix green (live-canaries.yml, canary-report.json retained)
764
- # 2. PostgreSQL + keychain protected suites green (test:postgres, keychain suite)
765
- # 3. CodeQL SAST green on the release commit (security.yml / release.yml codeql-release)
766
- # 4. npm OIDC trusted publishing identity authenticated (NPM_TOKEN with id-token, provenance)
767
-
768
- git diff --check
769
- npm ci
770
- npm run sdk:ready # includes typecheck, lint, format, full test, coverage, pack, release:gate
771
- npm run security:threat-suites
772
- PRISM_TEST_POSTGRES_URL="$DATABASE_URL" npm run test:postgres # Phase 7 + Phase 12 restart-recovery
773
- npm audit --audit-level=moderate
774
- npm run release:check -- --version 0.1.4 --report /tmp/prism-0.1.4-preflight.json
775
- npm run release:publish -- --version 0.1.4 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.1.4-dry-run.json
776
- # run the dry-run twice and diff the reports: deterministic, byte-identical
777
-
778
- # Sign the release on the clean tagged tree (operator GPG key):
779
- git tag -s v0.1.4 -m "Prism 0.1.4"
780
- git verify-tag v0.1.4
781
- git push origin v0.1.4 # tag push triggers release.yml publish job (provenance, attestations)
782
-
783
- # Real publication never bypasses the gates: release.mjs refuses
784
- # --allow-dirty/--allow-untagged without --dry-run.
785
- ```
786
-
787
- **Rollback notes.** `release:publish --version 0.1.4 --resume --report release-artifacts/publish-report.json` resumes an interrupted publication and skips only registry versions whose internal dependency fingerprint matches the local manifest. A failed package aborts the run with its status written to the report; re-run after fixing the cause. npm cannot unpublish the `0.1.4` line after 72 hours — a post-publication defect ships as a `0.1.x` patch (additive-only compat promise, `release:gate` enforced), or as a documented break in the next line with a `docs/migration.md` entry. `0.1.4` is store-compatible with `0.1.3` in **both directions** (no migration ran — same checksum-protected contract), so an operator may defer or roll back the patch without a database rollback. The next line, **0.1.5**, is the documented breaking cut (deprecated-option removal) with its removed-symbols list landing in `docs/migration.md`.
788
-
789
- ### 0.1.3 publish handoff (plan 015 Task 5)
790
-
791
- **Decision: GO when the operator prerequisites below are recorded.** Release **0.1.3** (plan 015) is the dead-code and deprecation hygiene patch on the frozen 0.1.x line: one parameterized benchmark runner `scripts/benchmark.mjs --scenario <name>` replaces the per-version runners (16 orphaned `benchmark-0.0.{8..16}` runner/test files removed, evidence JSON kept; the CI schema leg runs `scripts/benchmark.test.mjs`), the 12 `docs/review-coverage-2026-07-*.md` evidence files moved to the tarball-excluded `docs/_evidence/` archive, a non-blocking unused-code sweep (`npm run sweep:unused` — tsc `noUnusedLocals`/`noUnusedParameters` over core + all workspace tsconfigs plus a zero-dep dead-export scan; always exits 0, report to `scripts/unused-sweep-report.txt`), and opt-in checkpoint persistence (`persistSessionState: true` on durable run/resume options — loaded-skill name catalog ≤64 names rides the run-state checkpoint and restores on resume, bodies re-resolve from the live registry; `createReadPathSetPersistence` in `@arnilo/prism-coding-agent` persists the read-before-write path set through the host `CheckpointStore`, ≤1024 paths, ownership-scoped). Publishable graph stays **49** manifests (root + 48 workspace) at exact **0.1.3**. Store compatibility with 0.1.2: **compatible, no migration**; declaration surface additive-only vs the frozen 0.1.x contract (`scripts/compat-baseline` regenerated at 0.1.3 with zero breaking deltas).
792
-
793
- ```bash
794
- # Operator prerequisites (each a named blocked gate — none may be skipped):
795
- # 1. protected live-canary matrix green (live-canaries.yml, canary-report.json retained)
796
- # 2. PostgreSQL + keychain protected suites green (test:postgres, keychain suite)
797
- # 3. CodeQL SAST green on the release commit (security.yml / release.yml codeql-release)
798
- # 4. npm OIDC trusted publishing identity authenticated (NPM_TOKEN with id-token, provenance)
799
-
800
- git diff --check
801
- npm ci
802
- npm run sdk:ready # includes typecheck, lint, format, full test, coverage, pack, release:gate
803
- npm run security:threat-suites
804
- PRISM_TEST_POSTGRES_URL="$DATABASE_URL" npm run test:postgres # Phase 7 + Phase 12 restart-recovery
805
- npm audit --audit-level=moderate
806
- npm run release:check -- --version 0.1.3 --report /tmp/prism-0.1.3-preflight.json
807
- npm run release:publish -- --version 0.1.3 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.1.3-dry-run.json
808
- # run the dry-run twice and diff the reports: deterministic, byte-identical
809
-
810
- # Sign the release on the clean tagged tree (operator GPG key):
811
- git tag -s v0.1.3 -m "Prism 0.1.3"
812
- git verify-tag v0.1.3
813
- git push origin v0.1.3 # tag push triggers release.yml publish job (provenance, attestations)
814
-
815
- # Real publication never bypasses the gates: release.mjs refuses
816
- # --allow-dirty/--allow-untagged without --dry-run.
817
- ```
818
-
819
- **Rollback notes.** `release:publish --version 0.1.3 --resume --report release-artifacts/publish-report.json` resumes an interrupted publication and skips only registry versions whose internal dependency fingerprint matches the local manifest. A failed package aborts the run with its status written to the report; re-run after fixing the cause. npm cannot unpublish the `0.1.3` line after 72 hours — a post-publication defect ships as a `0.1.x` patch (additive-only compat promise, `release:gate` enforced), or as a documented break in the next line with a `docs/migration.md` entry. `0.1.3` is store-compatible with `0.1.2` in **both directions** (no migration ran — same checksum-protected contract), so an operator may defer or roll back the patch without a database rollback.
820
-
821
- ### 0.0.28 publish handoff (historical)
822
-
823
- **Decision: GO after protected operator prerequisites below.** Release **0.0.28** (Phase 11, plan 011) ships the optional enterprise adapter seams: OIDC/JWKS identity verification (`@arnilo/prism-credentials-node/oidc`), OPA policy evaluation into the durable ledger (`@arnilo/prism-policy/opa`), MCP OAuth client/server support (`@arnilo/prism-mcp`), host-selected OpenAPI operations as effect-gated tools (`@arnilo/prism-openapi-tools`), and an S3-compatible artifact body store behind the new core body contract (`@arnilo/prism-server/artifact-bodies`). Every seam is opt-in and fail-closed; hosts that wire none keep exact prior behavior. Publishable graph stays **49** publishable manifests (root + 48 workspace packages; `prism-openapi-tools` joined the graph in this release). See [migration](migration.md) `0.0.27 → 0.0.28`.
824
-
825
- ```bash
826
- git diff --check
827
- npm ci
828
- npm run sdk:ready
829
- node --test scripts/phase11-conformance.test.mjs
830
- node scripts/benchmark-0.0.28.mjs > scripts/benchmark-0.0.28.json
831
- node --test scripts/budget-gate.test.mjs scripts/tooling-gate.test.mjs
832
- node scripts/scan-secrets.mjs && node scripts/verify-sbom.mjs
833
- npm audit --audit-level=moderate
834
- npm run release:gate -- --version 0.0.28 --allow-break --allow-dirty --allow-untagged
835
- npm run release:check -- --version 0.0.28 --allow-dirty --allow-untagged --report /tmp/prism-0.0.28-preflight.json
836
- npm run release:publish -- --version 0.0.28 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.0.28-dry-run.json
837
- git tag -s v0.0.28 -m "Prism 0.0.28"
838
- git verify-tag v0.0.28
839
- git push origin v0.0.28
840
- ```
841
-
842
- ### 0.0.27 publish handoff
843
-
844
- **Decision: GO after protected operator prerequisites below.** Release **0.0.27** (Phase 10, plan 010) ships complete ACP coding-host interop in `@arnilo/prism-ag-ui/acp`: seam-based capability advertisement, session persistence, modes/config overlays, client fs/terminal adapters, MCP select gate, `CodingLifecycleEvent` → ACP update mapping, four-outcome approvals with elicitation, and frozen caps. Publishable graph stays **48** manifests. See [migration](migration.md) `0.0.26 → 0.0.27` and [ACP coding-host interop](acp.md).
845
-
846
- ```bash
847
- git diff --check
848
- npm ci
849
- npm run sdk:ready
850
- node --test scripts/phase10-conformance.test.mjs
851
- node scripts/benchmark-0.0.27.mjs > scripts/benchmark-0.0.27.json
852
- node --test scripts/budget-gate.test.mjs scripts/tooling-gate.test.mjs
853
- node scripts/scan-secrets.mjs && node scripts/verify-sbom.mjs
854
- npm audit --audit-level=moderate
855
- npm run release:gate -- --version 0.0.27 --allow-break --allow-dirty --allow-untagged
856
- npm run release:check -- --version 0.0.27 --allow-dirty --allow-untagged --report /tmp/prism-0.0.27-preflight.json
857
- npm run release:publish -- --version 0.0.27 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.0.27-dry-run.json
858
- git tag -s v0.0.27 -m "Prism 0.0.27"
859
- git verify-tag v0.0.27
860
- git push origin v0.0.27
861
- ```
862
-
863
- ### 0.0.24 publish handoff
864
-
865
- **Decision: GO after protected operator prerequisites below.** Release **0.0.24** (Phase 7, plan 007) ships durable `AgentEventSource`, recoverable `ToolEffectStore`, AG-UI 0.0.57 compatibility, and AG-UI MCP/MCP Apps/A2A fronting. Publishable graph stays **47** manifests. Core remains dependency-free; PostgreSQL event source and enterprise `toolEffects` stay opt-in. Delivery is at-least-once — not exactly-once. See [migration](migration.md) `0.0.23 → 0.0.24` and [tool effects](tool-effects.md).
866
-
867
- ```bash
868
- git diff --check
869
- npm ci
870
- npm run sdk:ready
871
- PRISM_TEST_POSTGRES_URL="$DATABASE_URL" npm run test:postgres
872
- PRISM_TEST_POSTGRES_URL="$DATABASE_URL" node scripts/benchmark-0.0.24.mjs > scripts/benchmark-0.0.24.json
873
- node --test scripts/budget-gate.test.mjs scripts/tooling-gate.test.mjs
874
- node scripts/scan-secrets.mjs && node scripts/verify-sbom.mjs
875
- npm audit --audit-level=moderate
876
- npm run release:gate
877
- npm run release:check -- --version 0.0.24 --allow-dirty --allow-untagged --report /tmp/prism-0.0.24-preflight.json
878
- npm run release:publish -- --version 0.0.24 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.0.24-dry-run.json
879
- git tag -s v0.0.24 -m "Prism 0.0.24"
880
- git verify-tag v0.0.24
881
- git push origin v0.0.24
882
- ```
883
-
884
- ### 0.0.23 publish handoff
885
-
886
- **Decision: GO after protected operator prerequisites below.** Release **0.0.23** (Phase 6, plan 006) adds `@arnilo/prism-enterprise-postgres`, the optional PostgreSQL composition for policy decisions, evaluation records, work-mutation claim/CAS state, and cross-replica model-router rate/budget/circuit state. The publish graph is **47 manifests** (41 code + 6 family/profile; +1 package). `@arnilo/prism-all` includes it; core remains dependency-free. See [migration](migration.md#0022--0023-production-enterprise-state-adapters-intentional-pre-10-contract-changes) and [enterprise PostgreSQL state](enterprise-postgres-state.md).
887
-
888
- Intentional pre-1.0 migration points: work idempotency now uses `begin`/CAS transitions and never automatically replays `unknown`; durable router state requires awaited methods plus verified identity and disables `providerSource`. Policy/evaluation/work/router data remain opt-in. No Redis, queue, event delivery, exactly-once effect claim, worker, migration CLI, ORM, or new core API ships.
889
-
890
- ```bash
891
- git diff --check
892
- npm ci
893
- npm run sdk:ready
894
- PRISM_TEST_POSTGRES_URL="$DATABASE_URL" npm run test:postgres
895
- PRISM_TEST_POSTGRES_URL="$DATABASE_URL" node scripts/benchmark-0.0.23.mjs
896
- node --test scripts/budget-gate.test.mjs scripts/tooling-gate.test.mjs
897
- node scripts/scan-secrets.mjs && node scripts/verify-sbom.mjs
898
- npm audit --audit-level=moderate
899
- npm run release:gate
900
- npm run release:check -- --version 0.0.23 --allow-dirty --allow-untagged --report /tmp/prism-0.0.23-preflight.json
901
- npm run release:publish -- --version 0.0.23 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.0.23-dry-run.json
902
- git tag -s v0.0.23 -m "Prism 0.0.23"
903
- git verify-tag v0.0.23
904
- git push origin v0.0.23
905
- ```
906
-
907
- `npm publish --dry-run` is non-publishing and applies `publishConfig.access`; the real protected tag workflow is the only publication path, with provenance and resume report. It must run the PostgreSQL suite using a protected, disposable database URL. The recorded benchmark is local/CI comparison evidence, not a portable SLO. npm publication is immutable: a partial publish resumes from the same tag; a confirmed defect requires deprecation plus a fixed version.
908
-
909
- ### 0.0.22 publish handoff
910
-
911
- **Decision: GO after protected operator prerequisites below.** Release **0.0.22** (Phase 5 third-party behavior integrations, plan 005) ships `@arnilo/prism-caveman` and `@arnilo/prism-ponytail` as opt-in behavior packages (upstream Caveman/Ponytail wiring, session mode persistence, progressive disclosure + injector split). Core `@arnilo/prism` runtime is unchanged. The publish graph is **46 manifests** (+2). No intentional pre-1.0 breaks for hosts that do not install the new packages — see [migration](migration.md) under `0.0.21 → 0.0.22 third-party behavior integrations`.
912
-
913
- ```bash
914
- git diff --check
915
- npm ci
916
- npm run sdk:ready
917
- node --test scripts/budget-gate.test.mjs
918
- node scripts/scan-secrets.mjs && node scripts/verify-sbom.mjs
919
- npm audit --audit-level=moderate
920
- npm run release:gate
921
- npm run release:check -- --version 0.0.22 --allow-dirty --allow-untagged --report /tmp/prism-0.0.22-preflight.json
922
- npm run release:publish -- --version 0.0.22 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.0.22-dry-run.json
923
- git tag -s v0.0.22 -m "Prism 0.0.22"
924
- git verify-tag v0.0.22
925
- git push origin v0.0.22
926
- ```
927
-
928
- ### Historical release handoffs
929
-
930
- Release-specific migration detail lives in [migration](migration.md). The current handoff plus the retained protected matrix below supersede 0.0.16–0.0.21 command transcripts.
931
-
932
- ### Release-integrity evidence matrix (0.0.18 → 0.1.0)
933
-
934
- Phase 12 Task 2 (plan 012) closes roadmap defect #4: every release from 0.0.18 onward has a signed tag or a **documented publication-evidence pointer**. Tags below were created as lightweight refs (no GPG signature was available in this environment); each release therefore carries a documented evidence pointer: the roadmap phase completion evidence, benchmark JSON, conformance suite, and/or migration section that records what shipped. The 0.1.0 cut requires the **signed** tag + provenance publication procedure (operator action, see [0.1.0 readiness](0.1.0-readiness.md) "Remaining for 1.0").
935
-
936
- | Release | Tag | Evidence pointer |
937
- | --- | --- | --- |
938
- | 0.0.18 | `v0.0.18` (lightweight, at `f627752`) | Roadmap Phase 1 completion evidence; `docs/migration.md` `0.0.17 → 0.0.18`; docs tripwire Phase 1 |
939
- | 0.0.19 | `v0.0.19` (lightweight, at `7574e50`) | Roadmap Phase 2 completion evidence; migration `0.0.18 → 0.0.19` |
940
- | 0.0.20 | `v0.0.20` (lightweight, at `b2cdb2e`) | Roadmap Phase 3 completion evidence; migration `0.0.19 → 0.0.20` |
941
- | 0.0.21 | **no tag** | Roadmap Phase 4 completion evidence (workspace 0.0.21 / 44 manifests, sdk:ready green); migration `0.0.20 → 0.0.21` |
942
- | 0.0.22 | `v0.0.22` (lightweight, at `f9902ed`) | Roadmap Phase 5 completion evidence; 0.0.22 publish handoff above; migration `0.0.21 → 0.0.22` |
943
- | 0.0.23 | `v0.0.23` (lightweight, at `1401b6b`) | Roadmap Phase 6 completion evidence; 0.0.23 publish handoff above; `scripts/benchmark-0.0.23.json`; migration `0.0.22 → 0.0.23` |
944
- | 0.0.24 | `v0.0.24` (lightweight, at `55c4b0e`) | Roadmap Phase 7 completion evidence; 0.0.24 publish handoff above; `scripts/benchmark-0.0.24.json`; `scripts/phase7-conformance.test.mjs`; migration `0.0.23 → 0.0.24` |
945
- | 0.0.25 | `v0.0.25` (lightweight, at `24d7ac0`) | Roadmap Phase 8 completion evidence; `scripts/benchmark-0.0.25.json`; `scripts/phase8-conformance.test.mjs`; migration `0.0.24 → 0.0.25` |
946
- | 0.0.26 | `v0.0.26` (lightweight, at `77fac7e`) | Roadmap Phase 9 completion evidence; `scripts/benchmark-0.0.26.json`; `scripts/phase9-conformance.test.mjs`; migration `0.0.25 → 0.0.26` |
947
- | 0.0.27 | `v0.0.27` (lightweight, at `9d49625`) | Roadmap Phase 10 completion evidence; `scripts/benchmark-0.0.27.json`; `scripts/phase10-conformance.test.mjs`; migration `0.0.26 → 0.0.27` |
948
- | 0.0.28 | **no tag (HEAD is 0.0.28 scope)** | Roadmap Phase 11 completion evidence; 0.0.28 publish handoff above; `scripts/benchmark-0.0.28.json`; `scripts/phase11-conformance.test.mjs`; migration `0.0.27 → 0.0.28` |
949
- | 0.1.0 | `v0.1.0` **signed** (operator action at publication) | Phase 12 plan 012 records; `node scripts/release.mjs publish --version 0.1.0 --dry-run --allow-untagged` semantics verified (dry-run proceeds untagged; real publication refuses `--allow-untagged`/`--allow-dirty`) |
950
-
951
- Machine check: `git tag --points-at <commit>` and the roadmap phase completion blocks above are the evidence trail; `node scripts/release.mjs check --version 0.1.0` validates the exact version graph at bump time (plan 012 Task 7).
952
-
953
- ### 0.0.15 protected live-canary matrix
954
-
955
- 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.
956
-
957
- | Surface | Gate and credential | Checked-in/protected command | Canary scope |
958
- | --- | --- | --- | --- |
959
- | OpenAI Responses baseline | `PRISM_LIVE_PROVIDER_TESTS=1` + `OPENAI_API_KEY` | `npm test -w @arnilo/prism-providers/openai` | Bounded text/tool/abort smoke; key never enters events. |
960
- | OpenAI hosted tools + Realtime | `OPENAI_API_KEY`; protected release harness additionally supplies host-owned safety identifier and hosted-tool entitlement | No generic fixture; record result with the release evidence | Provider-hosted `web_search`/similar execution and Realtime audio/interruption need account-specific availability, so fake transport coverage remains default gate. |
961
- | AI SDK adapter | Host-selected AI SDK v4 model factory plus its provider credential | No generic fixture; run host integration in protected release environment | Exact `@ai-sdk/provider@4.0.10` mapping/version check; Prism does not own upstream model credentials. |
962
- | Kimi / Moonshot | `PRISM_LIVE_PROVIDER_TESTS=1` + `KIMI_API_KEY` | `npm test -w @arnilo/prism-providers/kimi` | Coding route; Moonshot entitlement is account-specific. |
963
- | Z.AI | `PRISM_LIVE_PROVIDER_TESTS=1` + `ZAI_API_KEY` | `npm test -w @arnilo/prism-providers/zai` | GLM stream/tool/reasoning smoke. |
964
- | OpenRouter | `PRISM_LIVE_PROVIDER_TESTS=1` + `OPENROUTER_API_KEY` | `npm test -w @arnilo/prism-providers/openrouter` | Routed stream/model metadata smoke; host chooses permitted route. |
965
- | OpenCode Go | `PRISM_LIVE_PROVIDER_TESTS=1` + `OPENCODE_API_KEY` | `npm test -w @arnilo/prism-providers/opencode-go` | OpenAI/Anthropic route selection smoke. |
966
- | Hyper | `PRISM_LIVE_PROVIDER_TESTS=1` + `HYPER_API_KEY` | `npm test -w @arnilo/prism-providers` | Dual-route text/tool/abort smoke + warm-prefix/messages-cache/reasoning-effort probes; bounded to cheap models (plan 055 Task 3). |
967
- | Command Code | `PRISM_LIVE_PROVIDER_TESTS=1` + `COMMAND_CODE_API_KEY` | `npm test -w @arnilo/prism-providers` | Dual-route text/tool/abort smoke + cache/ZDR/reasoning probes; bounded to cheap models (plan 055 Task 5). |
968
- | Alibaba DashScope | Alibaba least-privilege API key | No generic fixture; host compatibility probe in protected release environment | Region/preset/catalog entitlement varies; offline serializer and catalog tests remain default gate. |
969
- | Ollama Cloud/local | Cloud API key or host-local authenticated endpoint | No generic fixture; host compatibility probe in protected release environment | Cloud account and local daemon/model availability are host-owned; no daemon starts during Prism tests. |
970
- | NeuralWatt | `PRISM_LIVE_PROVIDER_TESTS=1` + `NEURALWATT_API_KEY` | `npm test -w @arnilo/prism-providers/neuralwatt` | Stream/retry/quota telemetry smoke. |
971
- | Anthropic | `PRISM_LIVE_PROVIDER_TESTS=1` + `ANTHROPIC_API_KEY` | `npm test -w @arnilo/prism-providers/anthropic` | Restricted one-turn provider smoke. |
972
- | Google | `PRISM_LIVE_PROVIDER_TESTS=1` + `GOOGLE_API_KEY` or `GEMINI_API_KEY` | `npm test -w @arnilo/prism-providers/google` | Restricted one-turn provider smoke. |
973
- | Memory PostgreSQL/pgvector | `PRISM_TEST_POSTGRES_URL` with `vector` extension | `npm run test:postgres -w @arnilo/prism-memory` | Shared memory conformance, export/rebuild pagination, and finite-vector boundary. |
974
-
975
- The scheduled/manual `live-canaries` workflow uses protected environment `live-canaries`; release validation uses its protected release environment. Neither workflow receives a broad workspace key. A successful offline benchmark is never evidence that a live row ran; each protected invocation must record its enabled matrix rows and skipped/missing prerequisites.
976
-
977
- ### Historical release notes
978
-
979
- Older 0.0.10–0.0.15 handoffs are summarized in [migration](migration.md); historical 43-package evidence remains there. The publishable package catalog includes `@arnilo/prism-providers/alibaba`, `@arnilo/prism-providers/ollama`, and `@arnilo/prism-session-store-codecs`; current publication uses the 47-manifest handoff above.
980
-
981
240
  ## 0.1.x compatibility and support matrix
982
241
 
983
- Frozen by Phase 12 Task 0 in `scripts/phase12-freeze-manifest.json` (schema gate `node --test scripts/phase12-freeze.test.mjs`; docs agreement tripwired in the docs test suite). Any change requires a recorded freeze deviation in plan 012.
984
242
 
985
- ### Supported and measured
986
-
987
- | Dimension | Supported | Measured evidence |
988
- | --- | --- | --- |
989
- | Node | 20, 24 (`engines.node >=20`) | `release.yml`: `verify` runs SDK readiness on Node 24; `node20-compat` builds and imports every public root export on Node 20. Docs examples need Node >=22.6 native TypeScript stripping. Node 22 is engines-supported but not measured in CI at freeze. |
990
- | PostgreSQL | 16 | `release.yml` `postgres-integration` job with image `pgvector/pgvector:pg16`; driver `pg@^8.22.0`; schema version 6. The pgvector extension is required only by the `@arnilo/prism-memory` path. Range claims beyond 16 need an added protected leg before they may be documented. |
991
- | Platform | linux-x64 | Every CI leg runs on `ubuntu-latest` (x64). All other OS/arch combinations are untested: run `npm run sdk:ready` on the target platform before production adoption. |
992
- | Providers | all `@arnilo/prism-providers/<adapter>` subpaths plus the OpenAI-compatible transport | Per-package conformance suites in the default network-free `npm test`; live canaries stay credential-gated (`PRISM_LIVE_PROVIDER_TESTS=1`). |
993
- | Protocol SDKs | exact pins below | MCP 38-test suite, AG-UI/ACP/A2A protocol conformance, NATS JetStream event-source conformance. |
994
-
995
- | Package | Frozen pin |
996
- | --- | --- |
997
- | `@modelcontextprotocol/client` | `2.0.0` |
998
- | `@modelcontextprotocol/server` | `2.0.0` |
999
- | `@agentclientprotocol/sdk` | `1.3.0` |
1000
- | `@ag-ui/core` | `0.0.59` |
1001
- | `@nats-io/jetstream` | `^3.4.0` |
1002
- | `@nats-io/transport-node` | `^3.4.0` |
1003
-
1004
- ### Unsupported combinations
1005
-
1006
- - Node below 20 (engines floor).
1007
- - PostgreSQL server majors outside the supported list (only 16 measured at freeze).
1008
- - ACP v2 experimental APIs — stable v1 only.
1009
- - Cedar policy engine — OPA adapter only.
1010
- - Redis/Kafka queues or backplanes — PostgreSQL and NATS JetStream event sources only.
1011
- - Forges beyond GitHub.
1012
- - Object stores beyond the S3-compatible reference adapter.
1013
- - Remote-browser vendors, hosted cloud, Studio/control plane, and channel catalogs (Phase 13 demand-gated).
1014
-
1015
- ### Security-support boundary
1016
-
1017
- Audit fixes, dependency updates, and security patches land only for the supported lines above. The 0.1.0 audit target is moderate-or-higher (`releasePolicy.auditLevelTarget` in the freeze manifest); since plan 012 Task 6 both `security.yml` and the `release.yml` supply-chain job enforce `npm audit --audit-level=moderate` (0 vulnerabilities at every severity recorded for the 0.1.0 tree). Unsupported combinations receive no fixes. Supply-chain gates are listed in [host security](host-security.md).
243
+ Frozen by Phase 12 Task 0 in `scripts/phase12-freeze-manifest.json` (schema gate `node --test scripts/phase12-freeze.test.mjs`; docs agreement tripwired in the docs test suite). Any change requires a recorded freeze deviation in plan 012.
1018
244
 
1019
245
  ## Extension and configuration notes
1020
246
 
247
+
1021
248
  - **Required `@arnilo/prism` peer.** Every first-party code package declares a non-optional **caret** `@arnilo/prism@^0.3.3` peer (plan 041-044 republished set; the plan 039 set keeps `^0.3.1` and unchanged packages keep the prior `^0.3.0` window peer — all satisfy the root) (`peerDependenciesMeta` must not mark `@arnilo/prism` optional; other peers such as `playwright-core` may be optional). **Peer-version policy (plan 030, Decision B — independent packages):** internal ranges stay inside the 0.x `^0.3.0` window, so a package may patch independently while consumers remain on a compatible 0.3.x line. A package outside that window (for example `0.4.0`) is refused by the release gate until the next coordinated peer bump. 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.
1022
249
  - **Public access.** All 56 manifests (root + 55 workspace packages: 49 code packages + 6 pure-manifest family/profile packages — the 10 `prism-*` family/profile set is the 6 pure-manifest profiles plus the 4 code packages `prism-caveman`, `prism-impeccable`, `prism-openapi-tools`, `prism-ponytail`) declare `"publishConfig": { "access": "public" }`; the publisher also passes `--access public` explicitly because scoped packages otherwise default to restricted on first publish.
1023
250
  - **Shipped vs repository docs.** The npm tarball ships `docs/` pages linked from `docs/index.md` (public API, security, migration, providers, install). It excludes `docs/_evidence/` (per-phase evidence freezes, including `release-0.2.7-evidence.md`), `docs/release-*-evidence.md`, and `docs/api-page-template.md`. Those files remain in git for audit. `dist/__tests__` and `*.map` stay excluded.
@@ -1035,13 +262,14 @@ Audit fixes, dependency updates, and security patches land only for the supporte
1035
262
 
1036
263
  **Required checks (owner action).** Branch protection is not yet configured on this repo; after the workflows land on `main`, mark these check names required on `main` (Settings → Branches → required status checks): `postgres (sessions + enterprise)`, `nats (events + cursor + restart)`, `office golden (packed artifacts)`, `protected-matrix` (sandbox/browser job id). The canary and its `report` job are deliberately not required (nightly, issue-on-failure). Verify each registered workflow with one dispatch: `gh workflow run integration-postgres.yml --ref main` (likewise `integration-nats.yml`, `integration-office.yml`); dispatch 404s until the file exists on the default branch.
1037
264
 
1038
- **Release evidence links.** At release time, link the latest green run of each workflow from the release evidence page: `https://github.com/ashiqrniloy/prism/actions/workflows/<workflow-file>`. Evidence snapshots in [0.1.0 readiness](0.1.0-readiness.md) and `docs/_evidence/` stay frozen at recording time; the workflow-run link is the live pointer.
265
+ **Release evidence links.** At release time, link the latest green run of each workflow from the release evidence page: `https://github.com/ashiqrniloy/prism/actions/workflows/<workflow-file>`. Evidence snapshots in [0.1.0 readiness](history/0.1.0-readiness.md) and `docs/_evidence/` stay frozen at recording time; the workflow-run link is the live pointer.
1039
266
 
1040
267
  **Secrets inventory.** The integration jobs need no repo secrets: postgres/nats URLs are generated in-job from their service containers (`localhost`, masked via `::add-mask::`), and the office job is network-free. `sandbox-browser.yml` uses repo **variables** only (environment `sandbox-browser`): `PRISM_TEST_DOCKER_IMAGE`, `PRISM_ENABLE_PLAYWRIGHT_GATE`, `PRISM_ENABLE_OBSCURA_GATE`, `PRISM_OBSCURA_BIN`, `PRISM_ENABLE_DRAWIO_GATE`, `PRISM_TEST_DRAWIO_URL`. Only `canary-providers.yml` uses secrets — the nine provider API keys (anthropic/google/gemini/openai/opencode/openrouter/zai/kimi/neuralwatt) in the `live-canaries` environment, plus the `PRISM_CANARY_PROVIDERS` repo variable.
1041
268
  - **Adding a package.** New workspace packages are picked up automatically by `npm run build --workspaces`, `npm test --workspaces`, `npm run pack:dry-run`, the packaging guard (`src/__tests__/packaging.test.ts`), and the install-smoke test (`src/__tests__/install-smoke.test.ts`) via the workspace glob; add the package to both tests' config arrays for explicit per-package assertions.
1042
269
 
1043
270
  ## Security and performance notes
1044
271
 
272
+
1045
273
  - **Export-count budget.** `scripts/budget-gate.test.mjs` counts each publishable package's public exports (same name classes as `scripts/dead-exports.mjs`) and fails CI when any exceed the `exportCounts` ceilings in `scripts/budgets.json` (plan 066 post-0.5.1-cut baselines); the failure names the package and the exact delta. Growth requires removing exports or rebaselining with a recorded reason.
1046
274
  - **No secrets or fixtures in tarballs.** Tests, fixtures, `src/`, `plans/`, `.agents/`, `roadmap.md`, and `tsconfig` files are excluded. The `docs avoid real-looking secret examples` docs check and the packaging guard's deny list prevent secret-bearing fixtures from shipping.
1047
275
  - **Live tests stay opt-in.** The default `npm test` is network-free by construction and never sets these vars. Provider/compaction live gates stay credential-gated and are not set by default or during `sdk:ready`. The PostgreSQL adapter live matrix is the exception that runs in CI via the dedicated `postgres-integration` job (still skipped in the default suite).
@@ -1071,36 +299,14 @@ Audit fixes, dependency updates, and security patches land only for the supporte
1071
299
  - **Protected restart-recovery leg (plan 012 Task 4).** `scripts/phase12-restart-recovery.test.mjs` (run by `npm run test:postgres` after the Phase 7 suite) spawns two real processes against one PostgreSQL schema: replica A runs a durable agent, suspends on a batched tool approval, appends durable events and is then SIGKILLed by the driver; replica B reconnects and resumes. Operators re-run the leg with `PRISM_TEST_POSTGRES_URL="postgresql://…" npm run test:postgres` against a disposable PostgreSQL 16 (e.g. `pgvector/pgvector:pg16`). Without the URL the gate records a named `BLOCKED GATE` failure instead of skipping. Reconnect p95 and 16-worker append contention p95 are asserted against the frozen `reconnectP95Ms` / `pointOpP95Ms` ceilings; set `PRISM_PHASE12_RECORD_EVIDENCE=1` to refresh the checked-in evidence file `scripts/phase12-restart-recovery.json`.
1072
300
  - **Offline test budget.** The default `npm test` (no `PRISM_LIVE_PROVIDER_TESTS`) is pinned at **< 60s on Node 20** with a measured local baseline of ~45s (build ~18s + network-free tests/workspace tests/packaging smoke ~27s). Plan 057 retired the historical `phase11-freeze` … `phase34-freeze`/`phase30-release` gate files from the default suite (17 files, 247 tests) — they stay in the repo as immutable release evidence and remain audit-runnable standalone via `node --test scripts/<file>.test.mjs`, with their self-wiring assertions flipped to assert non-wiring so the retirement cannot silently regress. Release/security gates (`release-gate`, `tooling-gate`, `budget-gate`, `phase23-quality-gates`, `phase8–11` conformance) stay in the run. The full CI `sdk:ready` gate runs on Node 24 because docs tests execute `examples/*.ts` via native TypeScript stripping. `npm run sdk:ready` also runs typecheck, pack dry-run, and the coverage summary, so it is allowed to exceed the `npm test` budget while remaining network-free. `npm run test:coverage` additionally runs the combined coverage summary (`npm run coverage:summary`, ~25s local: core + each workspace suite once with `--experimental-test-coverage`; measured total ~70s on Node 24) — additive reporting only, the core gate stays the only hard threshold. The CI `sdk:ready` step has `timeout-minutes: 5` as a hang backstop; the separate Node 20 compatibility step has `timeout-minutes: 3`. The budget was raised from 30s after the default suite grew to include every first-party package, offline install smoke, packaging guards, docs examples, and workspace tests; optimize before raising it again.
1073
301
 
1074
- ### 0.0.12 release-candidate verification — 2026-07-22
1075
-
1076
- | Gate | Result |
1077
- | --- | --- |
1078
- | Package graph | Root + 34 workspaces = 35 publishable manifests at exact `0.0.12`; `@arnilo/prism-ag-ui` is public and reached only through `@arnilo/prism-all`. |
1079
- | Protocol and compaction | AG-UI root/`./acp`, core streamed durable resume, and coding compaction import from packed offline consumer; `benchmark-0.0.12` schema passed. |
1080
- | SDK readiness | `npm run sdk:ready` passed: typecheck, network-free tests, offline install/export checks, and 35 package dry-run packs. |
1081
- | Compatibility and supply chain | Node 20.20.2 imported every core export; audit found 0 high findings (2 moderate MCP-transitive advisories); SPDX/license check covered 192 packages/8 effective licenses. `@ag-ui/core@0.0.59` is an exact MIT override because its published metadata omits `license` while its shipped LICENSE is MIT; other `NOASSERTION` entries still fail. 963 present tracked files had 0 secret findings. |
1082
- | Registry/order | Public `release:check` found all 35 `@arnilo/*@0.0.12` versions available. Dependency-ordered `release:publish --dry-run --allow-dirty --allow-untagged` completed 35/35 with explicit public/latest/provenance; no commit, tag, or publication was created. |
1083
-
1084
- A deleted tracked feature-request markdown was intentionally not restored by release work; resolve it before a clean checkout runs the workflow's literal `git ls-files` secret-scan command. Protected live gates, signed tag, OIDC, and actual publication remain operator prerequisites.
1085
-
1086
- ### 0.0.11 dependency audit decision (2026-07-22)
1087
-
1088
- `npm audit --audit-level=high` reports 0 vulnerabilities and `npm ls --all --depth=0` resolves the exact 34-package `0.0.11` graph (including `@arnilo/prism-providers/anthropic`, `@arnilo/prism-providers/google`, and `@arnilo/prism-browser`). Locked-install SPDX and `scripts/verify-sbom.mjs` pass. Browser keeps `playwright-core@1.61.0` as an optional peer and ships no browser binary/image; no Office package/binary enters the graph. Host mode never claims disposable containment.
1089
-
1090
-
1091
- ### 0.0.11 release-candidate verification — 2026-07-22
302
+ ### GitHub Actions pipeline (0.0.27+)
1092
303
 
1093
- | Gate | Result |
1094
- | --- | --- |
1095
- | Package graph | Root + 33 workspaces = 34 publishable manifests at exact `0.0.11` with exact internal peer/dependency ranges; Anthropic/Google in `@arnilo/prism-providers` and transitively `@arnilo/prism-all`. |
1096
- | Coding harness P1 | SessionIndex/search, contextBudget, steer, ask_user_decision, runCodingGoalVerify; schema v4 FTS migration; `benchmark-0.0.11` search/budget schema green. |
1097
- | Providers | Native Anthropic + Google packages offline-conformant; live gates remain `PRISM_LIVE_PROVIDER_TESTS=1` + host keys. |
1098
- | SDK readiness | `npm run sdk:ready`: 2,047 tests (2,014 pass / 33 skip / 0 fail); pack 1,041,760 / 4,041,551 / 889 files; core 549,565 / 1,938,287 / 253. |
1099
- | 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. |
1100
304
 
305
+ `.github/workflows/release.yml` is the single pipeline: **push to `main`** runs CI (`verify` = `npm run sdk:ready`, `node20-compat`, `postgres-integration`, `supply-chain`), **`v0.3.0` or `@arnilo/*@*` package tags** additionally run `codeql-release` and the `publish` job (deterministic `release:publish` in dependency order with provenance attestation). `security.yml` adds CodeQL/dependency-review/SBOM on push and PR; `live-canaries.yml` and `sandbox-browser.yml` are scheduled. All actions are SHA-pinned (2026-08-06 fix: CodeQL pins were invalid 404 refs and `workflow_dispatch` was missing — re-verified every pin against its upstream repo). Prerequisites outside the repo: Actions enabled in repository settings, and the `NPM_TOKEN` secret (with `id-token: write` for provenance). To re-cut a tag after a fix commit, delete and recreate it (`git push origin :v0.0.28 && git push origin v0.0.28`) so the tag creation event fires.
1101
306
 
1102
307
  ## Formatting, linting, and coverage
1103
308
 
309
+
1104
310
  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.
1105
311
 
1106
312
  | Command | What it does |
@@ -1114,6 +320,7 @@ All four gates run inside `npm run sdk:ready` (after `typecheck`, before `pack:d
1114
320
 
1115
321
  ### Coverage denominators and per-package thresholds
1116
322
 
323
+
1117
324
  Workspace coverage rows used to include the symlinked root core `dist/` (workspace tests `import … from "@arnilo/prism"`, which resolves via `node_modules/@arnilo/prism -> ../..`), diluting every package denominator. Each workspace coverage run now passes `--test-coverage-include=dist/**`, so only `packages/<name>/dist/**` counts (the core run and its 60/70/75 gate are unchanged).
1118
325
 
1119
326
  | Fact | Value |
@@ -1129,6 +336,7 @@ A new workspace package must add an evidence-based threshold entry (or a `protec
1129
336
 
1130
337
  ### Release evidence and protected skips
1131
338
 
339
+
1132
340
  `npm run release:evidence` (run automatically at the start of `npm run release:gate`, and therefore at the end of `npm run sdk:ready`) aggregates every test surface into `scripts/release-evidence.json` — the machine-auditable release skip manifest. It records env var **names only, never values** (the manifest is retained and uploaded by CI).
1133
341
 
1134
342
  | State | Meaning | Gate effect |
@@ -1144,6 +352,7 @@ Override `PRISM_RELEASE_EVIDENCE` to redirect the manifest (used by the gate reg
1144
352
 
1145
353
  ### Quality-gate reports and the Biome baseline
1146
354
 
355
+
1147
356
  `npm run lint` runs Biome 2.x with the canonical config (`linter.rules.preset: "recommended"` — the deprecated `recommended: true` key is gone; `npx biome migrate --write` performs the rewrite) and writes a machine-readable SARIF report to `scripts/lint-report.sarif` in the same run (stable `--reporter=sarif`; the experimental `--reporter=json` schema is not used). The repo target is **zero** lint diagnostics; every remaining intentional diagnostic carries a justified `biome-ignore lint/<rule>: reason` comment (shell-interpolated strings, verbatim upstream fixtures, and literal grep targets in tests). Unused-code diagnostics are auto-fixed by `biome lint --write --unsafe .`; public-but-unused exports are never removed by Biome — they route to the unused-code sweep.
1148
357
 
1149
358
  `npm run sweep:unused` (also part of `npm test`) runs the tsc `--noUnusedLocals/--noUnusedParameters` sweep across the core and every workspace tsconfig and writes both `scripts/unused-sweep-report.txt` (human) and `scripts/unused-report.json` (`--json`, machine-readable: per-tsconfig counts + the dead-export scan). It stays non-blocking by design. Both reports are gitignored and CI-retained (`quality-gate-reports` artifact, 30 days).
@@ -1152,6 +361,7 @@ Timing assertions in tests follow a deterministic-barrier policy: racy wall-cloc
1152
361
 
1153
362
  ## Build serialization
1154
363
 
364
+
1155
365
  `dist/` is compiled by `tsc` in many small writes, so a concurrent build and test in the same working tree could race — a test importing `@arnilo/prism` mid-emit could observe a partially-written module (reproduced during the 0.2.3 review). Emit-producing leaves (`tsc` builds) and dist-consuming test leaves (`node --test dist/__tests__/*.test.js`) are therefore serialized through a dependency-free lock: `node scripts/with-build-lock.mjs <command>` acquires an `O_EXCL` lockfile at `node_modules/.prism-build.lock` (contents: holder `pid` + timestamp, no secrets), waits with a 100ms backoff, and fails closed — never proceeding without the lock. A stale lock whose holder PID is dead is reclaimed; a live lock is never stolen. Acquisition is leaf-only (never the `npm test`/`sdk:ready` orchestrators), so nested `npm run build` children cannot deadlock.
1156
366
 
1157
367
  | Fact | Value |
@@ -1167,6 +377,7 @@ Directly invoking `tsc` instead of `npm run build` bypasses the lock — use the
1167
377
 
1168
378
  ## Dependency major-upgrade isolation
1169
379
 
380
+
1170
381
  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.
1171
382
 
1172
383
  **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`):
@@ -1201,6 +412,7 @@ Major dependency upgrades are **isolated, compatibility-tested changes — never
1201
412
 
1202
413
  ## Release checklist
1203
414
 
415
+
1204
416
  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.
1205
417
 
1206
418
  | Gate | Enforcement |
@@ -1226,6 +438,7 @@ A change that adds a public persistence/runtime surface, a new package, or a new
1226
438
 
1227
439
  ## Independent package versioning (default after the 0.3.0 cut)
1228
440
 
441
+
1229
442
  `scripts/release.mjs` now defaults `check`, `publish`, and `gate` to **independent** (Decision B). Each package bumps only when it changes, internal pins stay in `^0.3.0`, and publication targets only changed packages at their own `name@version`. The final lockstep path is explicit: `--lockstep --version 0.3.0`.
1230
443
 
1231
444
  | Action | Command |
@@ -1251,6 +464,7 @@ No Changesets. No new runtime dependency. The 0.x caret window (`^0.3.0` = `>=0.
1251
464
 
1252
465
  ## Pre-publish compatibility gates (`release:gate`)
1253
466
 
467
+
1254
468
  `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; independent mode reads local git history for changed-package validation but never contacts the registry:
1255
469
 
1256
470
  - **ranges**: reuses `validateReleaseIndependent` by default, or `validateRelease` for explicit `--lockstep --version 0.3.0`; both verify internal ranges and lockfile entries.
@@ -1261,6 +475,7 @@ Gate behavior is unit-tested in `scripts/release-gate.test.mjs`. Signature diff
1261
475
 
1262
476
  ## Related APIs
1263
477
 
478
+
1264
479
  - [`docs/provider-packages.md`](provider-packages.md): first-party provider package layout and setup.
1265
480
  - [`docs/cli-rpc.md`](cli-rpc.md): the `prism` CLI bin and RPC protocol shipped as `dist/cli.js`.
1266
481
  - [`docs/configuration-and-manifests.md`](configuration-and-manifests.md): package manifest merging and validation.