@arnilo/prism 0.5.6 → 0.6.0
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.
- package/CHANGELOG.md +37 -0
- package/README.md +10 -10
- package/dist/agent-approval.js +7 -6
- package/dist/agent-loops.js +51 -12
- package/dist/agent-session/session.d.ts +1 -0
- package/dist/agent-session/session.js +20 -2
- package/dist/agent-tool-dispatch.js +5 -4
- package/dist/content.d.ts +3 -16
- package/dist/content.js +9 -99
- package/dist/context-budget.d.ts +12 -1
- package/dist/context-budget.js +42 -19
- package/dist/contracts-core/agent.d.ts +11 -0
- package/dist/contracts-core/agent.js +4 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +3 -3
- package/dist/input.d.ts +6 -0
- package/dist/input.js +12 -1
- package/dist/media-types.d.ts +34 -0
- package/dist/media-types.js +158 -0
- package/dist/pinned-fetch.d.ts +2 -2
- package/dist/pinned-fetch.js +11 -12
- package/dist/redaction.js +74 -1
- package/dist/session-stores.d.ts +11 -0
- package/dist/session-stores.js +23 -8
- package/docs/acp.md +1 -1
- package/docs/ag-ui.md +4 -2
- package/docs/agent-events.md +2 -0
- package/docs/agent-loops.md +1 -1
- package/docs/agent-session-runtime.md +3 -1
- package/docs/browser-automation.md +5 -2
- package/docs/contributing.md +37 -0
- package/docs/core.md +2 -0
- package/docs/document-reader.md +2 -0
- package/docs/documents.md +1 -1
- package/docs/graft.md +3 -1
- package/docs/history/release-handoffs.md +33 -0
- package/docs/host-security.md +2 -2
- package/docs/index.md +27 -14
- package/docs/input-and-prompt-assembly.md +4 -4
- package/docs/language-intelligence.md +1 -1
- package/docs/migrate-to-0.5.md +7 -2
- package/docs/migrate-to-0.6.md +89 -0
- package/docs/migration.md +30 -0
- package/docs/model-registry.md +1 -1
- package/docs/multimodal-content.md +1 -1
- package/docs/obscura.md +3 -1
- package/docs/options-index.md +286 -0
- package/docs/peer-dependencies.md +94 -0
- package/docs/performance.md +34 -2
- package/docs/ponytail.md +2 -0
- package/docs/postgres-persistence.md +3 -1
- package/docs/provider-conformance.md +1 -1
- package/docs/provider-packages.md +21 -21
- package/docs/provider-primitives.md +2 -1
- package/docs/providers/ai-sdk.md +5 -2
- package/docs/public-contracts.md +2 -2
- package/docs/release-and-install.md +75 -55
- package/docs/server.md +1 -1
- package/docs/session-stores.md +3 -1
- package/docs/sqlite-persistence.md +2 -0
- package/docs/testing.md +38 -0
- package/docs/tools.md +1 -1
- package/docs/wiki.md +1 -1
- package/package.json +5 -5
package/docs/performance.md
CHANGED
|
@@ -85,6 +85,16 @@ Recorded 2026-08-31 on Node v24.19.0 / Linux x64: 5 warmups + 20 measured runs,
|
|
|
85
85
|
node scripts/benchmark.mjs --scenario workflow-loop --out /tmp/prism-workflow-loop.json
|
|
86
86
|
```
|
|
87
87
|
|
|
88
|
+
## Secret redaction (plan 070)
|
|
89
|
+
|
|
90
|
+
`node scripts/benchmark.mjs --scenario redaction` is network-free (in-memory, no credentials). It builds one transcript-scale string (≥ 1 MiB) and one small entry-shaped object, both carrying 16 realistic secret-shaped needles, and measures `redactSecrets` against a local copy of the ordered `needles.reduce(split/join)` loop it replaced for large strings: the two must stay byte-identical and no needle may survive either path. Caps live in `scripts/budgets.json#redaction` (same-process speedup floor 5, transcript p95 ceiling 250 ms, small-entry p95 ceiling 25 ms — sanity bounds, machine-dependent). Schema/caps/network-free gating in `npm test`: `scripts/benchmark-redaction.test.mjs`.
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
node scripts/benchmark.mjs --scenario redaction --out /tmp/prism-redaction.json
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Recorded 2026-09-11, Node v24.19.0 / Linux x64: 1 MiB transcript × 16 needles **9.39 ms → 0.69 ms p50 (13.7×, floor 5×)**, small entry 0.15 ms p50 / 0.22 ms p95. Strings below 16 KB keep the ordered loop (`src/redaction.ts`): the equivalence check that guards the single scan costs more than the passes it saves below ~4 KB.
|
|
97
|
+
|
|
88
98
|
## Current-line root artifact diet
|
|
89
99
|
|
|
90
100
|
`npm pack --dry-run --json` on `@arnilo/prism` is gated by `scripts/budget-gate.test.mjs` against `scripts/budgets.json#root` (±5%). Repository-only history stays out of the tarball: `docs/_evidence/**`, `docs/release-*-evidence.md`, `docs/api-page-template.md`, `dist/__tests__`, and `*.map`. Every page linked from shipped `docs/index.md` must be in the pack. Recorded 2026-08-27: **923,045 packed / 3,149,665 unpacked / 375 files** (226 `dist` js+d.ts, 124 index-linked docs, 25 other). 0.1.0 freeze 713,454 / 293 stays historical.
|
|
@@ -102,10 +112,32 @@ demand gate.
|
|
|
102
112
|
**Pass/fail thresholds.** Network-free rows fail above the frozen ceiling in
|
|
103
113
|
the table below; protected PostgreSQL rows fail above their per-phase
|
|
104
114
|
budgets.json ceilings (50/100 ms per the approved budget contract); startup
|
|
105
|
-
import fails above `startupImportMsCeiling` (250 ms)
|
|
115
|
+
import fails above `startupImportMsCeiling` (250 ms) on a quiet machine — see the
|
|
116
|
+
startup-gate note below for how the in-chain check stays load-tolerant; root
|
|
117
|
+
packed bytes and
|
|
106
118
|
file count fail above baseline × 1.05. Labels: **network-free** = runs in
|
|
107
119
|
`npm test` evidence, no network; **protected** = requires live PostgreSQL.
|
|
108
120
|
|
|
121
|
+
**Startup gate (plan 071 Task 3).** The in-`npm test` check in
|
|
122
|
+
`scripts/budget-gate.test.mjs` asserts a *machine-relative ratio* rather than a raw
|
|
123
|
+
millisecond bound: cold-process `import('./dist/index.js')` wall time (trimmed mean
|
|
124
|
+
of five spawns, min/max dropped) over the median empty `node -e ''` process start
|
|
125
|
+
measured in the same run. External CPU load inflates both numbers, so the ratio held
|
|
126
|
+
at 3.3 idle, 3.5–4.1 with a full `npm test` running concurrently, and up to 7.2 with
|
|
127
|
+
40 competing processes, while the absolute import alone moved 60 ms → 258 ms — the
|
|
128
|
+
same contention that failed the old fixed 250 ms check (273 ms at plan 070 Task 11,
|
|
129
|
+
1104.8 ms at Task 13, both at load average ~25). Off load
|
|
130
|
+
(loadavg-per-CPU < 1.5) the tight ratio ceiling (`importRatioCeiling` 8) and the
|
|
131
|
+
absolute ceiling (250 ms) are both asserted; under load the ratio ceiling widens to
|
|
132
|
+
`importRatioCeilingUnderLoad` (20) and the absolute bound becomes
|
|
133
|
+
evidence-of-record, still measured by `scripts/benchmark-0.1.0.mjs` (39.79 ms in
|
|
134
|
+
`scripts/benchmark-0.1.0.json`) and re-gated by `scripts/benchmark-0.1.0.test.mjs`;
|
|
135
|
+
the current-line scenario runner `scripts/benchmark.mjs` carries the six scenario
|
|
136
|
+
medians and no startup row. Both ceilings live in
|
|
137
|
+
`scripts/budgets.json#startup` with the calibration recorded in their `$comment`;
|
|
138
|
+
freeze deviation `dev-007` records the enforcement change (the frozen 250 ms number
|
|
139
|
+
itself is unchanged).
|
|
140
|
+
|
|
109
141
|
| Envelope | Recorded p95 ms | Ceiling ms | Source leg | Label |
|
|
110
142
|
| --- | ---: | ---: | --- | --- |
|
|
111
143
|
| oidcVerifyCacheHitMs | 0.151 | 5 | enterprise adapters (0.0.28) | network-free |
|
|
@@ -543,7 +575,7 @@ The ledger percentage overhead is intentionally not a threshold: its no-ledger b
|
|
|
543
575
|
|
|
544
576
|
### 0.0.5 Phase 0 baseline (2026-07-15)
|
|
545
577
|
|
|
546
|
-
Scope froze at commit `f5128a816ae204c52f3e2f089de71c99bd5de6d4`. Measurement host: Node v24.18.0, npm 11.16.0, Linux 7.1.3 x86_64, AMD Ryzen 9 PRO 7940HS (16 logical CPUs). Supported package runtime
|
|
578
|
+
Scope froze at commit `f5128a816ae204c52f3e2f089de71c99bd5de6d4`. Measurement host: Node v24.18.0, npm 11.16.0, Linux 7.1.3 x86_64, AMD Ryzen 9 PRO 7940HS (16 logical CPUs). Supported package runtime is Node >=22 (>=20 at the time of this baseline; raised in 0.6.0) and the host measured above is Node 24. These are dated local comparison points, not portable CI wall-clock assertions.
|
|
547
579
|
|
|
548
580
|
| Surface | Workload | Result |
|
|
549
581
|
| --- | --- | --- |
|
package/docs/ponytail.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Ponytail behavior integration
|
|
2
2
|
|
|
3
|
+
> **Optional peer install:** `@dietrichgebert/ponytail` — see [Optional peer dependencies](peer-dependencies.md).
|
|
4
|
+
|
|
3
5
|
## What it does
|
|
4
6
|
|
|
5
7
|
`@arnilo/prism-coding-tools/ponytail` is an optional package that wires [DietrichGebert/ponytail](https://github.com/DietrichGebert/ponytail) into Prism contribution contracts.
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# PostgreSQL persistence
|
|
2
2
|
|
|
3
|
+
> **Optional peer install:** `pg` — see [Optional peer dependencies](peer-dependencies.md).
|
|
4
|
+
|
|
3
5
|
## What it does
|
|
4
6
|
|
|
5
7
|
The optional `@arnilo/prism-core/sessions/postgres` package ships a production-oriented PostgreSQL adapter that implements:
|
|
@@ -14,7 +16,7 @@ Factory:
|
|
|
14
16
|
- `PostgresPersistenceOptions`
|
|
15
17
|
- `PostgresPersistence.close()` (async; ends adapter-owned pools only)
|
|
16
18
|
|
|
17
|
-
The adapter uses `pg@^8.
|
|
19
|
+
The adapter uses `pg@^8.23.0`, applies versioned migrations from the shared Plan 056 schema model inside a transaction guarded by `pg_advisory_xact_lock`, validates/quotes schema identifiers, and passes the full session-store and run-ledger conformance suites when `PRISM_TEST_POSTGRES_URL` is set.
|
|
18
20
|
|
|
19
21
|
## When to use it
|
|
20
22
|
|
|
@@ -31,7 +31,7 @@ Offline conformance is mandatory for every package; credentialed probes are not
|
|
|
31
31
|
| Package | Required offline evidence | Restricted live evidence |
|
|
32
32
|
| --- | --- | --- |
|
|
33
33
|
| OpenAI | Responses serialization/stream ordering, provider-hosted authority, continuation cap/cursor, Realtime fake WebSocket caps | Standard API-key smoke; separate protected hosted-tool/Realtime entitlement probe |
|
|
34
|
-
| AI SDK | Exact 4.0.
|
|
34
|
+
| AI SDK | Exact 4.0.13/V4 gate (`4.0.3`, `4.0.4`, `4.0.10` also listed); every mapped stream part; authority, cache usage, redaction, unsupported mapping | Host-created V4 model only; no Prism credential fixture |
|
|
35
35
|
| Anthropic | Messages serialization, cache/thinking/tools, header/redaction/abort assertions | Protected `ANTHROPIC_API_KEY` smoke |
|
|
36
36
|
| Google | `generateContent` serialization, complete tool calls, media/abort/redaction assertions | Protected `GOOGLE_API_KEY` or `GEMINI_API_KEY` smoke |
|
|
37
37
|
| Kimi | Coding/Moonshot route fixtures, thinking/tool reconstruction, headers/redaction | Protected `KIMI_API_KEY` smoke |
|
|
@@ -25,26 +25,26 @@ Do not use provider packages as a package manager, credential store, env loader,
|
|
|
25
25
|
|
|
26
26
|
| adapter package | version |
|
|
27
27
|
| --- | --- |
|
|
28
|
-
| `@arnilo/prism-providers/ai-sdk` | 0.
|
|
29
|
-
| `@arnilo/prism-providers/alibaba` | 0.
|
|
30
|
-
| `@arnilo/prism-providers/anthropic` | 0.
|
|
31
|
-
| `@arnilo/prism-providers/azure` | 0.
|
|
32
|
-
| `@arnilo/prism-providers/bedrock` | 0.
|
|
33
|
-
| `@arnilo/prism-providers/clinepass` | 0.
|
|
34
|
-
| `@arnilo/prism-providers/commandcode` | 0.
|
|
35
|
-
| `@arnilo/prism-providers/deepseek` | 0.
|
|
36
|
-
| `@arnilo/prism-providers/google` | 0.
|
|
37
|
-
| `@arnilo/prism-providers/hyper` | 0.
|
|
38
|
-
| `@arnilo/prism-providers/kimi` | 0.
|
|
39
|
-
| `@arnilo/prism-providers/model-discovery` | 0.
|
|
40
|
-
| `@arnilo/prism-providers/neuralwatt` | 0.
|
|
41
|
-
| `@arnilo/prism-providers/ollama` | 0.
|
|
42
|
-
| `@arnilo/prism-providers/openai` | 0.
|
|
43
|
-
| `@arnilo/prism-providers/opencode-go` | 0.
|
|
44
|
-
| `@arnilo/prism-providers/openrouter` | 0.
|
|
45
|
-
| `@arnilo/prism-providers/vertex` | 0.
|
|
46
|
-
| `@arnilo/prism-providers/xai` | 0.
|
|
47
|
-
| `@arnilo/prism-providers/zai` | 0.
|
|
28
|
+
| `@arnilo/prism-providers/ai-sdk` | 0.6.0 |
|
|
29
|
+
| `@arnilo/prism-providers/alibaba` | 0.6.0 |
|
|
30
|
+
| `@arnilo/prism-providers/anthropic` | 0.6.0 |
|
|
31
|
+
| `@arnilo/prism-providers/azure` | 0.6.0 |
|
|
32
|
+
| `@arnilo/prism-providers/bedrock` | 0.6.0 |
|
|
33
|
+
| `@arnilo/prism-providers/clinepass` | 0.6.0 |
|
|
34
|
+
| `@arnilo/prism-providers/commandcode` | 0.6.0 |
|
|
35
|
+
| `@arnilo/prism-providers/deepseek` | 0.6.0 |
|
|
36
|
+
| `@arnilo/prism-providers/google` | 0.6.0 |
|
|
37
|
+
| `@arnilo/prism-providers/hyper` | 0.6.0 |
|
|
38
|
+
| `@arnilo/prism-providers/kimi` | 0.6.0 |
|
|
39
|
+
| `@arnilo/prism-providers/model-discovery` | 0.6.0 |
|
|
40
|
+
| `@arnilo/prism-providers/neuralwatt` | 0.6.0 |
|
|
41
|
+
| `@arnilo/prism-providers/ollama` | 0.6.0 |
|
|
42
|
+
| `@arnilo/prism-providers/openai` | 0.6.0 |
|
|
43
|
+
| `@arnilo/prism-providers/opencode-go` | 0.6.0 |
|
|
44
|
+
| `@arnilo/prism-providers/openrouter` | 0.6.0 |
|
|
45
|
+
| `@arnilo/prism-providers/vertex` | 0.6.0 |
|
|
46
|
+
| `@arnilo/prism-providers/xai` | 0.6.0 |
|
|
47
|
+
| `@arnilo/prism-providers/zai` | 0.6.0 |
|
|
48
48
|
<!-- generated:package-truth:providers end -->
|
|
49
49
|
|
|
50
50
|
|
|
@@ -123,7 +123,7 @@ Every package remains explicit, setup-zero-fetch, and late-credential-bound. `Mo
|
|
|
123
123
|
| Package | Protocol / model source | Content mapping | Stream, tools, and reasoning | Cache / canary |
|
|
124
124
|
| --- | --- | --- | --- | --- |
|
|
125
125
|
| OpenAI | Responses; featured or caller-gated `listOpenAIModels` | text, image, audio, file, document | Host and provider-hosted tools; 8-hop continuation; Realtime seam; Responses reasoning | `openai_key`; checked-in standard smoke + protected hosted/Realtime probe |
|
|
126
|
-
| AI SDK | Host `LanguageModelV4`; no Prism catalog | declared text/image/audio/file/document prompt parts (role-limited) | v4 mapping; provider-executed tool authority; host-owned reasoning | host-owned; exact 4.0.
|
|
126
|
+
| AI SDK | Host `LanguageModelV4`; no Prism catalog | declared text/image/audio/file/document prompt parts (role-limited) | v4 mapping; provider-executed tool authority; host-owned reasoning | host-owned; exact 4.0.13 matrix (`4.0.3`, `4.0.4`, `4.0.10` also listed); protected host integration |
|
|
127
127
|
| Anthropic | Messages; caller-gated list | text, image, PDF document/file | tool deltas, thinking | `cache_control`; protected API-key smoke |
|
|
128
128
|
| Google | Gemini `generateContent`; caller-gated list | text, image, audio, document/file | complete tool calls, thinking | no Prism cache marker; protected API-key smoke |
|
|
129
129
|
| Kimi | Coding Messages or opt-in Moonshot; caller-gated list | text, image, PDF document/file by route/model | tool deltas, route-native thinking replay | implicit / optional Anthropic markers; protected API-key smoke |
|
|
@@ -35,9 +35,10 @@ Static scan of root `src/providers/` and `packages/prism-providers/src/*/` befor
|
|
|
35
35
|
| Runtime retry | `@arnilo/prism` `AgentConfig.retry` / `RunOptions.retry` | Classifies `ErrorInfo.code`; provider packages set numeric HTTP `code` on errors |
|
|
36
36
|
| `ProviderRequestOptions.maxRetries` / `timeoutMs` | Contracts | **Removed in 0.1.5**; use `RunOptions.signal` / `AgentConfig.retry` / `RunOptions.retry` |
|
|
37
37
|
| NeuralWatt `classifyNeuralWattError` | `packages/prism-providers/src/neuralwatt` | Parses `Retry-After`, `error.retry_after`, `retry_strategy`; no extra network calls |
|
|
38
|
+
| Shared retry HTTP plane | `packages/prism-providers/src/shared/retry-http.ts` | **Migrated (plan 070 Task 11)** — `readRetryAfterMs` (header, plus a caller-supplied body field), `parseErrorBody`, the secret-redacting `providerHttpError` builder, and `RETRYABLE_STATUSES`; hyper, NeuralWatt, and Command Code classifiers keep their own status/field decisions |
|
|
38
39
|
| Quota endpoint throttling | `packages/prism-providers/src/neuralwatt/quota.ts` | Documents 1 rps limit; caller-owned cache |
|
|
39
40
|
|
|
40
|
-
|
|
41
|
+
The `Retry-After` HTTP plane is shared inside `@arnilo/prism-providers` (`src/shared/retry-http.ts`, plan 070 Task 11), so the three classifiers cannot drift on header reading or on the redaction of provider error text. `x-request-id` extraction and a *core*-level helper for every provider do not exist yet.
|
|
41
42
|
|
|
42
43
|
### Structured output
|
|
43
44
|
|
package/docs/providers/ai-sdk.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# AI SDK provider adapter
|
|
2
2
|
|
|
3
|
+
> **Optional peer install:** `@ai-sdk/provider@4.0.13` (exact pin) — see [Optional peer dependencies](../peer-dependencies.md).
|
|
4
|
+
|
|
3
5
|
## What it does
|
|
4
6
|
|
|
5
7
|
`@arnilo/prism-providers/ai-sdk` adapts a host-supplied AI SDK `LanguageModelV4` into a Prism `AIProvider`. It maps Prism messages, tools, and structured-output options into `doStream` call options, then translates stream parts into Prism provider events incrementally.
|
|
@@ -12,7 +14,8 @@ Core `@arnilo/prism` does not depend on the AI SDK.
|
|
|
12
14
|
| --- | --- | --- |
|
|
13
15
|
| `4.0.3` | `LanguageModelV4`, `specificationVersion: "v4"` | Supported and offline-tested |
|
|
14
16
|
| `4.0.4` | `LanguageModelV4`, `specificationVersion: "v4"` | Supported and offline-tested |
|
|
15
|
-
| `4.0.10` | `LanguageModelV4`, `specificationVersion: "v4"` |
|
|
17
|
+
| `4.0.10` | `LanguageModelV4`, `specificationVersion: "v4"` | Supported and offline-tested |
|
|
18
|
+
| `4.0.13` | `LanguageModelV4`, `specificationVersion: "v4"` | Current peer; supported and offline-tested |
|
|
16
19
|
|
|
17
20
|
The peer dependency is intentionally exact. `createAiSdkProvider()` reads its resolved `@ai-sdk/provider/package.json` version during setup and throws typed `AiSdkProviderError { code: "unsupported_version" }` for an unlisted version; it does not infer compatibility from a matching `"v4"` string.
|
|
18
21
|
|
|
@@ -145,7 +148,7 @@ Official evidence: [Custom providers / LanguageModelV4](https://ai-sdk.dev/provi
|
|
|
145
148
|
|
|
146
149
|
## Extension and configuration notes
|
|
147
150
|
|
|
148
|
-
- Peer dependency: `@ai-sdk/provider@4.0.
|
|
151
|
+
- Peer dependency: `@ai-sdk/provider@4.0.13` (matrix also lists `4.0.3`, `4.0.4`, and `4.0.10`). Upgrade policy adds a matrix row and offline conformance fixture before accepting any new version.
|
|
149
152
|
- First-party HTTP providers remain independent; this adapter is available directly or through `@arnilo/prism-providers`. Installation does not select a model or invoke AI SDK.
|
|
150
153
|
- `options.compat` / `options.extra` pass through as AI SDK `providerOptions.prism`.
|
|
151
154
|
- Export helpers `toAiSdkCallOptions`, `toAiSdkPrompt`, and `mapAiSdkStream` for tests and custom hosts.
|
package/docs/public-contracts.md
CHANGED
|
@@ -131,7 +131,7 @@ Important request shapes:
|
|
|
131
131
|
| `SkillRegistry` | Host active skill registry shape: `register()`, `get()`, `resolve()`, and `list()`. |
|
|
132
132
|
| `CredentialRequest` | Credential lookup request: credential `name`, optional provider id, and metadata. |
|
|
133
133
|
| `OAuthProvider` | Host/package OAuth callbacks for login, optional refresh, and conversion to a `Credential`. |
|
|
134
|
-
| `AgentSessionConfig` | Session creation input: optional id, agent, store, leaf id, and
|
|
134
|
+
| `AgentSessionConfig` | Session creation input: optional id, agent, store, leaf id, metadata, and `snapshotCacheTtlMs` (branch-cache TTL; `0` disables). |
|
|
135
135
|
| `RunOptions` | Per-run overrides: optional abort signal, model, input layout, run limits (incl. `limits.maxToolRounds`), provider options/request policies, system prompt layers, compaction, retry, metadata, skill selection, validate, redactor, and loop. |
|
|
136
136
|
| `SubscribeOptions` / `SubscriberOverflowPolicy` | Live `AgentEvent` subscriber queue limit and overflow policy: `maxQueuedEvents`, `overflow: "close" \| "drop_oldest" \| "drop_newest"`. |
|
|
137
137
|
| `resumeAgentRunStream` / `AgentRunResumeStreamOptions` | One durable-run event stream: existing checkpoint/resume options plus `signal` and bounded subscriber options. `AgentRunLifecycle.resumeStream()` adds host capability resolution; no protocol types enter core. Runtime resume validation (0.2.0): every resume entrypoint validates the full input in core before any checkpoint write, tool call, or event — unknown legacy decisions and malformed batches fail closed with `AgentDecisionError` and no side effect; see [Agent/session runtime § Durable interruption](agent-session-runtime.md#durable-interruption). |
|
|
@@ -157,7 +157,7 @@ Important request shapes:
|
|
|
157
157
|
| `SessionIndex` / `SessionSearchQuery` / `SessionSearchHit` | Bounded optional session search seam (`search` / `SessionStore.searchSessions?`). Filters: workspace (`metadata.workspaceRoot`), time, provider/model, label/summary, optional FTS `query`, ownership. Hits return `sessionId` + optional `leafId` for resume; never credentials. Caps via `resolveSessionSearchQuery` / `DEFAULT_*` / `HARD_MAX_*` session-search constants. |
|
|
158
158
|
| `contextBudget` / `getContextBudgetReport` / `ContextBudgetError` | Opt-in assembler budget on `AssembleProviderInputOptions`; deterministic eviction; omission report in `ProviderRequest.metadata` (kinds/ids/sizes only). |
|
|
159
159
|
| `AgentSession.steer` / `SteerOptions` / pending-steer caps | Mid-run enqueue into active run; optional `softInterrupt`; default 8 msgs / 64 KiB UTF-8. |
|
|
160
|
-
| `SessionSearchUnsupportedError` / `sessionSearchMode` | Memory opt-out + JSONL; typed throw (not empty success). |
|
|
160
|
+
| `SessionSearchUnsupportedError` / `sessionSearchMode` | Memory opt-out + JSONL; typed throw (not empty success). Memory linear caps are host-overridable via `CreateMemorySessionStoreOptions.search`. |
|
|
161
161
|
| `BranchRecord` / `BranchQuery` | Branch handle/leaf pointer and query filters (session, name, parent branch, leaf presence). |
|
|
162
162
|
| `SessionEntryQuery` | Paginated entry filters: `sessionId`, `runId`, `parentId`, `leafId`, `kind`, timestamp range, ownership. |
|
|
163
163
|
| `RunRecord` / `RunQuery` | Stored run and filters: session, branch, status, timestamps, ownership. |
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
## What it does
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
Prism's current **0.
|
|
8
|
+
Prism's current **0.6.0** 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.6.0` 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).
|
|
9
9
|
|
|
10
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.
|
|
11
11
|
|
|
@@ -14,16 +14,16 @@ Core `@arnilo/prism` ships runtime, CLI, templates, and docs. Every code package
|
|
|
14
14
|
|
|
15
15
|
| package | version | notes |
|
|
16
16
|
| --- | --- | --- |
|
|
17
|
-
| `@arnilo/prism` | 0.
|
|
18
|
-
| `@arnilo/prism-coding-tools` | 0.
|
|
19
|
-
| `@arnilo/prism-core` | 0.
|
|
20
|
-
| `@arnilo/prism-providers` | 0.
|
|
21
|
-
| `@arnilo/prism-acp-agent` | 0.
|
|
22
|
-
| `@arnilo/prism-ag-ui` | 0.
|
|
23
|
-
| `@arnilo/prism-mcp` | 0.
|
|
24
|
-
| `@arnilo/prism-memory` | 0.
|
|
25
|
-
| `@arnilo/prism-office` | 0.
|
|
26
|
-
| `@arnilo/prism-web-tools` | 0.
|
|
17
|
+
| `@arnilo/prism` | 0.6.0 | core — runtime, CLI/RPC, templates, docs |
|
|
18
|
+
| `@arnilo/prism-coding-tools` | 0.6.0 | family — /agent, /security, /document-reader, /openapi, /computer-use-linux, /dev, /caveman, /ponytail, /impeccable subpaths |
|
|
19
|
+
| `@arnilo/prism-core` | 0.6.0 | family — /runtime, /sessions, /governance, /credentials, /enterprise, /work, /validation subpaths |
|
|
20
|
+
| `@arnilo/prism-providers` | 0.6.0 | family — all provider adapters as `/<adapter>` subpaths |
|
|
21
|
+
| `@arnilo/prism-acp-agent` | 0.6.0 | capability — ACP adapter |
|
|
22
|
+
| `@arnilo/prism-ag-ui` | 0.6.0 | capability — AG-UI/A2A/A2UI adapter |
|
|
23
|
+
| `@arnilo/prism-mcp` | 0.6.0 | capability — MCP client/server/OAuth interop |
|
|
24
|
+
| `@arnilo/prism-memory` | 0.6.0 | capability — memory plus /rag, /compaction/*, /graft, /wiki subpaths |
|
|
25
|
+
| `@arnilo/prism-office` | 0.6.0 | capability — /documents, /sheets, /diagrams subpaths |
|
|
26
|
+
| `@arnilo/prism-web-tools` | 0.6.0 | capability — Brave/Exa/Firecrawl plus peer-gated /browser and /obscura subpaths |
|
|
27
27
|
<!-- generated:package-truth:inventory end -->
|
|
28
28
|
|
|
29
29
|
|
|
@@ -32,30 +32,30 @@ Core `@arnilo/prism` ships runtime, CLI, templates, and docs. Every code package
|
|
|
32
32
|
|
|
33
33
|
| adapter package | version |
|
|
34
34
|
| --- | --- |
|
|
35
|
-
| `@arnilo/prism-providers/ai-sdk` | 0.
|
|
36
|
-
| `@arnilo/prism-providers/alibaba` | 0.
|
|
37
|
-
| `@arnilo/prism-providers/anthropic` | 0.
|
|
38
|
-
| `@arnilo/prism-providers/azure` | 0.
|
|
39
|
-
| `@arnilo/prism-providers/bedrock` | 0.
|
|
40
|
-
| `@arnilo/prism-providers/clinepass` | 0.
|
|
41
|
-
| `@arnilo/prism-providers/commandcode` | 0.
|
|
42
|
-
| `@arnilo/prism-providers/deepseek` | 0.
|
|
43
|
-
| `@arnilo/prism-providers/google` | 0.
|
|
44
|
-
| `@arnilo/prism-providers/hyper` | 0.
|
|
45
|
-
| `@arnilo/prism-providers/kimi` | 0.
|
|
46
|
-
| `@arnilo/prism-providers/model-discovery` | 0.
|
|
47
|
-
| `@arnilo/prism-providers/neuralwatt` | 0.
|
|
48
|
-
| `@arnilo/prism-providers/ollama` | 0.
|
|
49
|
-
| `@arnilo/prism-providers/openai` | 0.
|
|
50
|
-
| `@arnilo/prism-providers/opencode-go` | 0.
|
|
51
|
-
| `@arnilo/prism-providers/openrouter` | 0.
|
|
52
|
-
| `@arnilo/prism-providers/vertex` | 0.
|
|
53
|
-
| `@arnilo/prism-providers/xai` | 0.
|
|
54
|
-
| `@arnilo/prism-providers/zai` | 0.
|
|
35
|
+
| `@arnilo/prism-providers/ai-sdk` | 0.6.0 |
|
|
36
|
+
| `@arnilo/prism-providers/alibaba` | 0.6.0 |
|
|
37
|
+
| `@arnilo/prism-providers/anthropic` | 0.6.0 |
|
|
38
|
+
| `@arnilo/prism-providers/azure` | 0.6.0 |
|
|
39
|
+
| `@arnilo/prism-providers/bedrock` | 0.6.0 |
|
|
40
|
+
| `@arnilo/prism-providers/clinepass` | 0.6.0 |
|
|
41
|
+
| `@arnilo/prism-providers/commandcode` | 0.6.0 |
|
|
42
|
+
| `@arnilo/prism-providers/deepseek` | 0.6.0 |
|
|
43
|
+
| `@arnilo/prism-providers/google` | 0.6.0 |
|
|
44
|
+
| `@arnilo/prism-providers/hyper` | 0.6.0 |
|
|
45
|
+
| `@arnilo/prism-providers/kimi` | 0.6.0 |
|
|
46
|
+
| `@arnilo/prism-providers/model-discovery` | 0.6.0 |
|
|
47
|
+
| `@arnilo/prism-providers/neuralwatt` | 0.6.0 |
|
|
48
|
+
| `@arnilo/prism-providers/ollama` | 0.6.0 |
|
|
49
|
+
| `@arnilo/prism-providers/openai` | 0.6.0 |
|
|
50
|
+
| `@arnilo/prism-providers/opencode-go` | 0.6.0 |
|
|
51
|
+
| `@arnilo/prism-providers/openrouter` | 0.6.0 |
|
|
52
|
+
| `@arnilo/prism-providers/vertex` | 0.6.0 |
|
|
53
|
+
| `@arnilo/prism-providers/xai` | 0.6.0 |
|
|
54
|
+
| `@arnilo/prism-providers/zai` | 0.6.0 |
|
|
55
55
|
<!-- generated:package-truth:providers end -->
|
|
56
56
|
|
|
57
57
|
|
|
58
|
-
Core ships `dist`, docs, templates, and `CHANGELOG.md`; code packages ship compiled output, README, license, and changelog. Family/profile packages ship manifest, README, and changelog. `@arnilo/prism-providers` is the unified provider family: all provider adapters ship as `dist/<adapter>` subpaths in one tarball (Azure/Bedrock/Vertex included), with the required `@arnilo/prism` peer as the only dependency and `@ai-sdk/provider` an optional peer of `/ai-sdk`. `@arnilo/prism-core` provides the unified runtime, sessions, governance, credentials, enterprise persistence, and work integration family package. `@arnilo/prism-web-tools` provides the unified web tools family: root Brave/Exa/Firecrawl research tools plus `/browser` (Playwright-peer gated) and `/obscura` (host-binary + MCP gated) subpaths. `@arnilo/prism-memory` provides the unified memory and context family: root working/vector memory plus `/rag` (with `/rag/loaders` and `/rag/parsers`), `/compaction/llm`, `/compaction/observational-memory`, `/graft` (`@nanonets/graft` optional-peer gated), and `/wiki` subpaths, including the `prism-wiki` bin and bundled skills. `@arnilo/prism-coding-tools/dev` ships the loopback dev inspector — the `prism-dev` bin, the `prism dev` CLI composition, and the `/dev/cli` export the core CLI delegates to for `prism dev` (plan 040 Tasks 4–5); dev tooling is developer-time only and must never be the production API boundary. `@arnilo/prism-core/governance/prompts` (plan 042) is the versioned prompt registry: an explicit host opt-in with no first-party package depending on it — unlike `@arnilo/prism-memory` (a family member) and `@arnilo/prism-core/governance/evals` (used by the promotion helper as an optional peer). `@arnilo/prism-office` (plan 054 Task 8, absorbing plans 051–053) is the unified office family: `/documents`, `/sheets`, and `/diagrams` subpaths in one tarball with exact-pinned `@office-open/{docx,xlsx,pptx,xml}` regular dependencies and
|
|
58
|
+
Core ships `dist`, docs, templates, and `CHANGELOG.md`; code packages ship compiled output, README, license, and changelog. Family/profile packages ship manifest, README, and changelog. `@arnilo/prism-providers` is the unified provider family: all provider adapters ship as `dist/<adapter>` subpaths in one tarball (Azure/Bedrock/Vertex included), with the required `@arnilo/prism` peer as the only dependency and `@ai-sdk/provider` an optional peer of `/ai-sdk`. `@arnilo/prism-core` provides the unified runtime, sessions, governance, credentials, enterprise persistence, and work integration family package. `@arnilo/prism-web-tools` provides the unified web tools family: root Brave/Exa/Firecrawl research tools plus `/browser` (Playwright-peer gated) and `/obscura` (host-binary + MCP gated) subpaths. `@arnilo/prism-memory` provides the unified memory and context family: root working/vector memory plus `/rag` (with `/rag/loaders` and `/rag/parsers`), `/compaction/llm`, `/compaction/observational-memory`, `/graft` (`@nanonets/graft` optional-peer gated), and `/wiki` subpaths, including the `prism-wiki` bin and bundled skills. `@arnilo/prism-coding-tools/dev` ships the loopback dev inspector — the `prism-dev` bin, the `prism dev` CLI composition, and the `/dev/cli` export the core CLI delegates to for `prism dev` (plan 040 Tasks 4–5); dev tooling is developer-time only and must never be the production API boundary. `@arnilo/prism-core/governance/prompts` (plan 042) is the versioned prompt registry: an explicit host opt-in with no first-party package depending on it — unlike `@arnilo/prism-memory` (a family member) and `@arnilo/prism-core/governance/evals` (used by the promotion helper as an optional peer). `@arnilo/prism-office` (plan 054 Task 8, absorbing plans 051–053) is the unified office family: `/documents`, `/sheets`, and `/diagrams` subpaths in one tarball with exact-pinned `@office-open/{docx,xlsx,pptx,xml}` regular dependencies and no optional peer (the diagrams embed is browser-agnostic; `playwright-core` stays a devDependency for the gated live draw.io test). Importing one subpath never evaluates another. The three draft names `@arnilo/prism-documents`/`sheets`/`diagrams` were never published.
|
|
59
59
|
|
|
60
60
|
## When to use it
|
|
61
61
|
|
|
@@ -82,7 +82,7 @@ Consumers install the core package for the runtime and add first-party packages
|
|
|
82
82
|
| Install core + a single provider adapter | `npm install @arnilo/prism @arnilo/prism-providers` (import `@arnilo/prism-providers/openai`) |
|
|
83
83
|
| 0.0.12 AG-UI (after release) | `npm install @arnilo/prism@0.0.12 @arnilo/prism-ag-ui@0.0.12` |
|
|
84
84
|
| Install bounded web research tools | `npm install @arnilo/prism @arnilo/prism-web-tools @arnilo/prism-core` |
|
|
85
|
-
| Install browser automation tools (Playwright-peer gated `/browser`) | `npm install @arnilo/prism @arnilo/prism-web-tools playwright-core@1.
|
|
85
|
+
| Install browser automation tools (Playwright-peer gated `/browser`) | `npm install @arnilo/prism @arnilo/prism-web-tools playwright-core@1.63.0` |
|
|
86
86
|
| Install Obscura browser-engine tools (host supplies the binary; `/obscura`) | `npm install @arnilo/prism @arnilo/prism-web-tools @arnilo/prism-mcp` |
|
|
87
87
|
| Install RAG retrieval (memory family `/rag`) | `npm install @arnilo/prism @arnilo/prism-memory` |
|
|
88
88
|
| Install the Wiki CLI and skills (memory family `/wiki`) | `npm install @arnilo/prism @arnilo/prism-memory` (`npx prism-wiki --help`) |
|
|
@@ -143,7 +143,7 @@ A packed tarball contains only public compiled output and release files:
|
|
|
143
143
|
- Code packages ship `README.md`, `LICENSE`, and `CHANGELOG.md`; family/profile packages ship `README.md` and `CHANGELOG.md`.
|
|
144
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`.
|
|
145
145
|
- `dist/cli.js` and the `bin` link in core.
|
|
146
|
-
- **Tarball filenames.** npm strips the `@scope/` prefix, so the core package `@arnilo/prism` produces a tarball named `arnilo-prism-0.
|
|
146
|
+
- **Tarball filenames.** npm strips the `@scope/` prefix, so the core package `@arnilo/prism` produces a tarball named `arnilo-prism-0.6.0.tgz`; family packages produce `arnilo-prism-core-0.6.0.tgz`, `arnilo-prism-coding-tools-0.6.0.tgz`, `arnilo-prism-providers-0.6.0.tgz` (all 19 adapters inside), `arnilo-prism-memory-0.6.0.tgz`, `arnilo-prism-web-tools-0.6.0.tgz`, and `arnilo-prism-office-0.6.0.tgz`; capability packages like `arnilo-prism-mcp-0.6.0.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).
|
|
147
147
|
|
|
148
148
|
Excluded from every tarball by `files` negation:
|
|
149
149
|
|
|
@@ -242,6 +242,11 @@ Every side effect carries the run suffix and is cleaned up idempotently (PR clos
|
|
|
242
242
|
|
|
243
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.
|
|
244
244
|
|
|
245
|
+
| Runtime | Supported | Measured in CI |
|
|
246
|
+
| --- | --- | --- |
|
|
247
|
+
| Node | 22, 24 (`engines.node >=22`) | `verify` runs the full `sdk:ready` gate on Node 24; `node22-compat` builds and imports every public root `exports` target on Node 22. Node 20 support was dropped in 0.6.0 (`dev-006`; Node 20 reached upstream end-of-life 2026-04-30). |
|
|
248
|
+
| PostgreSQL | 16 (`pgvector/pgvector:pg16`) | `postgres-integration` service container |
|
|
249
|
+
|
|
245
250
|
## Extension and configuration notes
|
|
246
251
|
|
|
247
252
|
|
|
@@ -249,7 +254,7 @@ Frozen by Phase 12 Task 0 in `scripts/phase12-freeze-manifest.json` (schema gate
|
|
|
249
254
|
- **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.
|
|
250
255
|
- **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.
|
|
251
256
|
- **Map retention knob.** Source maps are emitted locally but stripped from tarballs by `!dist/**/*.map`. Removing that `files` negation ships maps in releases (larger tarballs, better consumer stack traces).
|
|
252
|
-
- **Release workflow.** `.github/workflows/release.yml` has six jobs. `verify` runs network-free SDK readiness on Node 24; `
|
|
257
|
+
- **Release workflow.** `.github/workflows/release.yml` has six jobs. `verify` runs network-free SDK readiness on Node 24; `node22-compat` builds/imports every public root `exports` default target on Node 22 for declared `engines.node >=22` (docs examples need Node >=22.6 native TypeScript stripping, inside the ≥22 floor); `postgres-integration` uses `pgvector/pgvector:pg16`; `supply-chain` runs high-severity audit, SPDX/license policy, and tracked-source secret scanning; and tag-only `codeql-release` runs SAST. `publish` runs on `v0.3.0` for the one lockstep cut and on `@arnilo/*@*` package tags afterward; it needs all five gates, preserves clean tagged/version/topological publication, and alone receives `NPM_TOKEN`, `id-token: write`, and `attestations: write`. Before npm publish it packs all current tarballs, generates checksums plus SPDX, scans unpacked public artifacts, creates GitHub attestations for tarballs and SBOM, then retains artifacts for 30 days. Registry state remains the resumable journal. Local `npm run release:dry-run` remains network-free SDK readiness; local PostgreSQL coverage is `PRISM_TEST_POSTGRES_URL=... npm run test:postgres`.
|
|
253
258
|
- **Protected integration matrix (plan 060).** Required on protected branches; pull requests do not run these jobs (no PR secrets). Connection strings are masked in logs.
|
|
254
259
|
|
|
255
260
|
| Job | Workflow | Cadence | Evidence |
|
|
@@ -292,17 +297,17 @@ Frozen by Phase 12 Task 0 in `scripts/phase12-freeze-manifest.json` (schema gate
|
|
|
292
297
|
- Provider live tests read the API key from the env only when both gates are set; the key is used as a bearer token and never logged. `assertNoSecretLeak` verifies the key value does not appear in any streamed event. The compaction placeholders still carry no real credentials.
|
|
293
298
|
- Enforced by `network-free-guard.test.ts` (default suite stays network-free) and by source-scanning meta-tests that assert each `live.test.ts` keeps its `skip:` guard.
|
|
294
299
|
- **Supply-chain workflows.** `.github/workflows/security.yml` runs CodeQL JavaScript/TypeScript SAST, PR-only dependency review, `npm audit`, SPDX 2.3 generation, exact license allow/deny policy, tracked-source plus unpacked-tarball credential-pattern scans, and seven-day SBOM retention. Dependabot opens bounded weekly npm and GitHub Actions updates. Every third-party action uses a full immutable revision; workflows never use `pull_request_target`. GitHub repository secret scanning/push protection and required-check branch rules remain repository settings because GitHub provides no equivalent checked-in workflow toggle; enable `security / codeql`, `security / supply-chain`, PR dependency review, and release checks on protected branches.
|
|
295
|
-
- **Sandbox/browser protected workflow.** `.github/workflows/sandbox-browser.yml` is scheduled/manual only in protected `sandbox-browser` environment. It runs network-free adversarial eval fixtures by default, optionally enables digest-pinned Docker and Playwright gates via repository variables (`PRISM_TEST_DOCKER_IMAGE`, `PRISM_ENABLE_PLAYWRIGHT_GATE`), receives no provider/npm/OIDC secrets, and uploads only a redacted aggregate status artifact (7-day retention).
|
|
300
|
+
- **Sandbox/browser protected workflow.** `.github/workflows/sandbox-browser.yml` is scheduled/manual only in protected `sandbox-browser` environment. It runs network-free adversarial eval fixtures by default, optionally enables digest-pinned Docker and Playwright gates via repository variables (`PRISM_TEST_DOCKER_IMAGE`, `PRISM_ENABLE_PLAYWRIGHT_GATE`), plus Obscura (`PRISM_ENABLE_OBSCURA_GATE`, `PRISM_OBSCURA_BIN`) and draw.io (`PRISM_ENABLE_DRAWIO_GATE`, `PRISM_TEST_DRAWIO_URL`) legs whose suites live in `@arnilo/prism-web-tools` and `@arnilo/prism-office` — the draw.io leg runs through `scripts/live-matrix.mjs` with `PRISM_LIVE_FILTER=office/drawio-live`; it receives no provider/npm/OIDC secrets, and uploads only a redacted aggregate status artifact (7-day retention).
|
|
296
301
|
- **Release attestations.** Tag publication uses GitHub OIDC with only `contents: read`, `id-token: write`, and `attestations: write` at the publish job. `actions/attest-build-provenance` attests every `.tgz` and `sbom.spdx.json` before npm publication; npm still receives `--provenance`. Verify downloaded attestations with GitHub CLI and npm signatures on the release host.
|
|
297
302
|
- **Install smoke is offline.** The install-smoke test packs core + every package into a temp dir and installs tarballs with `--offline --no-audit --no-fund` into a fresh project. External dependencies are satisfied from the lockfile-backed npm cache prepared by `npm ci`; any attempted uncached registry fetch fails the gate.
|
|
298
|
-
- **Packed-install e2e journeys (plan 012 Task 3).** `scripts/e2e-enterprise-journey.test.mjs` and `scripts/e2e-coding-journey.test.mjs` pack the first-party packages for their journey, install the exact tarballs into a fresh consumer project, and run the journey script inside that consumer — public exports only, no workspace-relative resolution (asserted per run). The **enterprise journey** composes OIDC identity → OPA policy decision (durable ledger) → agent run with durable events (memory, or real PostgreSQL when `PRISM_TEST_POSTGRES_URL` is set) → batched approval → OpenAPI side effect with idempotency → artifact upload + signed delivery, with policy-deny and hash-mismatch fail-closed injections. The **coding journey** composes an ACP editor session (init capability negotiation, session new + load/resume) → bounded coding tools (git-aware list/search, glob, read-before-write write, delete, move) → sandboxed process session → forge handoff with idempotent PR creation, with execution-policy and read-before-write denial paths. Each fixture asserts the installed version matches the packed manifest graph and stays within the frozen `e2eJourneyFixtureMsCeiling` (120 s in `scripts/phase12-freeze-manifest.json`).
|
|
303
|
+
- **Packed-install e2e journeys (plan 012 Task 3).** `scripts/e2e-enterprise-journey.test.mjs` and `scripts/e2e-coding-journey.test.mjs` pack the first-party packages for their journey, install the exact tarballs into a fresh consumer project, and run the journey script inside that consumer — public exports only, no workspace-relative resolution (asserted per run). The **enterprise journey** composes OIDC identity → OPA policy decision (durable ledger) → agent run with durable events (memory, or real PostgreSQL when `PRISM_TEST_POSTGRES_URL` is set **and the `pg` peer is installed in that consumer**) → batched approval → OpenAPI side effect with idempotency → artifact upload + signed delivery, with policy-deny and hash-mismatch fail-closed injections. The durable leg is peer-gated and never assumed from the env alone: with `PRISM_TEST_POSTGRES_URL` ambient but `pg` unresolvable (the default, since `pg` is a peer of `@arnilo/prism-core` and the consumer installs only Prism tarballs), the fixture prints `SKIP durable postgres leg: …` and runs the memory event source instead of dying with `ERR_MODULE_NOT_FOUND`; the test reports that line as a TAP diagnostic and asserts it, so the skip can never be silent. Scope the env to the phase that needs it (`PRISM_TEST_POSTGRES_URL=… npm run test:postgres`, or `phase release:gate` in `.github/workflows/release.yml`) rather than exporting it globally. The **coding journey** composes an ACP editor session (init capability negotiation, session new + load/resume) → bounded coding tools (git-aware list/search, glob, read-before-write write, delete, move) → sandboxed process session → forge handoff with idempotent PR creation, with execution-policy and read-before-write denial paths. Each fixture asserts the installed version matches the packed manifest graph and stays within the frozen `e2eJourneyFixtureMsCeiling` (120 s in `scripts/phase12-freeze-manifest.json`).
|
|
299
304
|
- **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`.
|
|
300
|
-
- **Offline test budget.** The default `npm test` (no `PRISM_LIVE_PROVIDER_TESTS`) is pinned at **< 60s
|
|
305
|
+
- **Offline test budget.** The default `npm test` (no `PRISM_LIVE_PROVIDER_TESTS`) is pinned at **< 60s** with a measured local baseline of ~45s (build ~18s + network-free tests/workspace tests/packaging smoke ~27s; the 0.5.x baselines were measured on Node 20, the current ones on Node 24). 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. Their criteria are content-verified, not filesystem-verified (plan 071 Tasks 5 and 10): capture ordering compares the baselines' recorded `captured` dates instead of file mtimes, phase markers resolve against the live file plus the frozen lineage (the phase plan of record and `docs/history/`) so a living doc that is rewritten between releases cannot fail an audit gate (a marker set that is checked this way is declared in the gate's own manifest — `phase26-freeze-manifest.json` `lineageCheckedFiles` — so the fallback stays bounded to the files that need it), a path retired since the freeze resolves to its recorded archive instead of being hash-compared (`status: "retired"` + `retiredTo` in the baseline, with the Task 0 `sha256` kept as history), and a version literal is asserted as a *transition* (`!`-prefixed marker: the pre-cut literal must be gone) rather than an equality that the next release sweep would invalidate. 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: 30` as a hang backstop; the separate Node 22 compatibility job has `timeout-minutes: 10`. 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.
|
|
301
306
|
|
|
302
307
|
### GitHub Actions pipeline (0.0.27+)
|
|
303
308
|
|
|
304
309
|
|
|
305
|
-
`.github/workflows/release.yml` is the single pipeline: **push to `main`** runs CI (`verify` = `npm run sdk:ready`, `
|
|
310
|
+
`.github/workflows/release.yml` is the single pipeline: **push to `main`** runs CI (`verify` = `npm run sdk:ready`, `node22-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.
|
|
306
311
|
|
|
307
312
|
## Formatting, linting, and coverage
|
|
308
313
|
|
|
@@ -314,7 +319,7 @@ Prism uses one tool for formatting and linting — [Biome](https://biomejs.dev)
|
|
|
314
319
|
| `npm run lint` | `biome lint .` — fails on any lint error (warnings are non-fatal). |
|
|
315
320
|
| `npm run format:check` | `biome format .` — fails if any file is unformatted. |
|
|
316
321
|
| `npm run format` | `biome format --write .` — normalizes formatting in place. |
|
|
317
|
-
| `npm run test:coverage` | `node --test --experimental-test-coverage` over the core suite with enforced minimums: **lines 60%**, **functions 70%**, **branches 75%** (current baseline ≈
|
|
322
|
+
| `npm run test:coverage` | `node --test --experimental-test-coverage` over the core suite with enforced minimums: **lines 60%**, **functions 70%**, **branches 75%** (current baseline ≈ 92.0 / 85.0 / 92.6), then `scripts/coverage-summary.mjs` + the `phase23-coverage` gate. Excludes `__tests__/`, `node_modules/`, `scripts/`, and `packages/` from the core report. |
|
|
318
323
|
|
|
319
324
|
All four gates run inside `npm run sdk:ready` (after `typecheck`, before `pack:dry-run`). A few rules are disabled in `biome.json` because they are false positives for this codebase: `noControlCharactersInRegex` and `noAssignInExpressions` (security/redaction code intentionally matches control characters and uses `while ((m = re.exec(…)))` loops), `noShadowRestrictedNames`, `noThenProperty` (the workflow DSL has a legitimate `then` branch field), `noExplicitAny`, `noVoidTypeReturn`, and `useYield`. Raise the coverage thresholds in `package.json` `test:coverage` as the baseline climbs.
|
|
320
325
|
|
|
@@ -326,13 +331,14 @@ Workspace coverage rows used to include the symlinked root core `dist/` (workspa
|
|
|
326
331
|
| Fact | Value |
|
|
327
332
|
| --- | --- |
|
|
328
333
|
| Workspace include filter | `--test-coverage-include=dist/**` per package (package-local denominator) |
|
|
329
|
-
|
|
|
330
|
-
|
|
|
331
|
-
|
|
|
334
|
+
| Workspace discovery | any `*.test.js` under `packages/<name>/dist/**`, nested layouts included (`@arnilo/prism-acp-agent` builds to `dist/src/__tests__`, `@arnilo/prism-office` to `dist/<area>/__tests__`) — all 9 workspace packages are measured |
|
|
335
|
+
| Per-package gate | `lines >= threshold` from `scripts/coverage-thresholds.json` (recaptured 2026-09-11 = min of two back-to-back runs − 3pp; the two runs differed by ≤ 0.02pp); branches/functions recorded, not gated. `phase23-coverage` also fails when a row names a package that is not in the live workspace graph — retired rows must be pruned |
|
|
336
|
+
| Protected exceptions | `@arnilo/prism-core` only (durable postgres/NATS legs need `PRISM_TEST_POSTGRES_URL` / `PRISM_TEST_NATS_URL`); exempt from the gate and reported separately with the reason. Env- or capability-gated legs elsewhere (memory postgres, coding-tools native sandbox, provider live legs) skip as protected skips but their packages stay gated on the measured run |
|
|
337
|
+
| Artifact | `scripts/coverage-summary.json` (gitignored, CI-retained): per-package `lines`/`branches`/`functions`/`denominatorFiles`/`threshold`/`pass`/`protectedException` + `belowThreshold`; a row whose child failed additionally carries `status`/`exitCode`/`tail` (a redacted tail of the child's output) |
|
|
332
338
|
| Fail-closed | a non-protected package below its threshold, a suite failure, or a run producing no coverage data exits non-zero; a missing threshold entry is a config error |
|
|
333
339
|
| Overrides | `PRISM_COVERAGE_THRESHOLDS`, `PRISM_COVERAGE_ARTIFACT` (used by the gate regression) |
|
|
334
340
|
|
|
335
|
-
A new workspace package must add an evidence-based threshold entry (or a `protectedException` reason) to `scripts/coverage-thresholds.json` before `test:coverage` passes.
|
|
341
|
+
A new workspace package must add an evidence-based threshold entry (or a `protectedException` reason) to `scripts/coverage-thresholds.json` before `test:coverage` passes, and a removed package's row must be pruned in the same change (the retired-row assertion in `scripts/phase23-coverage.test.mjs` fails otherwise). Recapture the rows from a `scripts/coverage-summary.json` written by two back-to-back runs; never hand-edit a percentage. A failing package is self-describing: the summary prints the child's redacted output tail under the row (repo root and home become `<repo>`/`<home>`, credential-shaped env values are redacted through `createSecretRedactor` — names only, never values), and the same `tail` lands in the artifact, so a bare `(suite failed)` is never the whole story (`scripts/coverage-failure.mjs`, unit-tested by the gate).
|
|
336
342
|
|
|
337
343
|
### Release evidence and protected skips
|
|
338
344
|
|
|
@@ -350,6 +356,14 @@ Surfaces: core `npm test` (counts and the skip total come from the latest `phase
|
|
|
350
356
|
|
|
351
357
|
Override `PRISM_RELEASE_EVIDENCE` to redirect the manifest (used by the gate regression). The manifest is gitignored and CI-retained (`release-evidence` artifact). A release cannot ship with a required env absent and unexplained — the operator sees every blocked surface in the retained manifest.
|
|
352
358
|
|
|
359
|
+
Protected legs fail closed through one convention (`scripts/blocked-gate.mjs`): a leg that cannot run prints exactly one canonical record and exits non-zero (test-style legs fail as a test failure), never a passing skip:
|
|
360
|
+
|
|
361
|
+
```text
|
|
362
|
+
BLOCKED GATE <id> requires=<names> evidence=<surface> hint=<how to unblock>
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
`node scripts/blocked-gate.mjs` audits the same registry — which protected legs cannot run with the current environment, which of them a release profile owns (their evidence surface decides the gate), and which are documented gaps that never block. `scripts/blocked-gate.test.mjs` (in-chain) asserts the registry, the record shape, and the fail-closed exits; `scripts/phase27-freeze-manifest.json` freezes the record template.
|
|
366
|
+
|
|
353
367
|
### Quality-gate reports and the Biome baseline
|
|
354
368
|
|
|
355
369
|
|
|
@@ -382,43 +396,46 @@ Major dependency upgrades are **isolated, compatibility-tested changes — never
|
|
|
382
396
|
|
|
383
397
|
**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`):
|
|
384
398
|
|
|
399
|
+
Development type packages track the **declared** engines floor, not the machine that builds them: `@types/node` stays on the oldest supported Node line (`^22.20.0` while `engines.node` is `>=22`), so an API that the floor cannot provide fails the build instead of compiling clean against a newer type surface. Raising the floor is a support-matrix change (freeze manifest + CI legs + `docs/migration.md`), never a side effect of bumping the types package.
|
|
400
|
+
|
|
385
401
|
| Dependency | Range | Resolved (lockfile) | Used by |
|
|
386
402
|
| --- | --- | --- | --- |
|
|
387
403
|
| `typescript` (dev) | `^7.0.2` | 7.0.2 | root build |
|
|
388
|
-
| `@types/node` (dev) | `^
|
|
389
|
-
| `@biomejs/biome` (dev) | `^2.5.
|
|
404
|
+
| `@types/node` (dev) | `^22.20.0` | 22.20.2 | root build (pinned to the `engines.node` floor) |
|
|
405
|
+
| `@biomejs/biome` (dev) | `^2.5.13` | 2.5.13 | lint/format |
|
|
390
406
|
| `diff` | `^9.0.0` | 9.0.0 | `@arnilo/prism-coding-tools/agent` |
|
|
391
|
-
| `pg` | `^8.
|
|
392
|
-
| `better-sqlite3` | `^
|
|
407
|
+
| `pg` | `^8.23.0` | 8.23.0 | `@arnilo/prism-memory`, `@arnilo/prism-core/sessions/postgres` |
|
|
408
|
+
| `better-sqlite3` | `^13.0.3` | 13.0.3 | `@arnilo/prism-core/sessions/sqlite` |
|
|
393
409
|
| `ajv` | `^8.17.1` | 8.20.0 | `@arnilo/prism-core/validation/json-schema` |
|
|
394
|
-
| `zod` | `^4.
|
|
410
|
+
| `zod` | `^4.6.2` | 4.6.2 | `@arnilo/prism-mcp` |
|
|
395
411
|
| `@napi-rs/keyring` | `^1.3.0` | 1.3.0 | `@arnilo/prism-core/credentials/node` |
|
|
396
|
-
| `@modelcontextprotocol/
|
|
412
|
+
| `@modelcontextprotocol/client` | `2.0.0` | 2.0.0 | `@arnilo/prism-mcp` |
|
|
413
|
+
| `@modelcontextprotocol/server` | `2.0.0` | 2.0.0 | `@arnilo/prism-mcp` |
|
|
397
414
|
| `@ag-ui/core` | `0.0.59` | 0.0.59 | `@arnilo/prism-ag-ui` |
|
|
398
|
-
| `@agentclientprotocol/sdk` | `1.
|
|
415
|
+
| `@agentclientprotocol/sdk` | `1.4.0` | 1.4.0 | `@arnilo/prism-ag-ui`, `@arnilo/prism-acp-agent` |
|
|
399
416
|
|
|
400
417
|
**Recorded compatibility matrix (2026-07-26, release 0.0.16):**
|
|
401
418
|
|
|
402
419
|
| Leg | Node | Result |
|
|
403
420
|
| --- | --- | --- |
|
|
404
421
|
| Full SDK readiness (`npm run sdk:ready`: typecheck, lint, format, test, coverage, pack, release:gate) | 24.18.0 (current) | ✅ green — 1312/1312 tests, lint 0 errors, format clean, coverage 64/72/79 vs 60/70/75 thresholds. |
|
|
405
|
-
| Build toolchain (`tsc` 7.0.2, `biome` 2.5.
|
|
422
|
+
| Build toolchain (`tsc` 7.0.2, `biome` 2.5.13) | 20.20.2 (LTS iron) | ✅ both run under Node 20. |
|
|
406
423
|
| Public surface import smoke (all 21 root `exports` default targets) | 20.20.2 | ✅ all import cleanly. |
|
|
407
424
|
| Full core test suite | 20.20.2 | 1311/1312 — the single failure is `examples_demos_run_to_completion_and_emit_no_secret`, which executes `examples/*.ts` via Node's native TypeScript stripping (Node 22.6+). This is a test-harness capability, not an SDK runtime incompatibility, and is exactly why CI scopes Node 20 to build + import smoke. |
|
|
408
425
|
|
|
409
|
-
**CI enforcement** (`.github/workflows/release.yml`): the `verify` job runs `npm run sdk:ready` on Node 24; `
|
|
426
|
+
**CI enforcement** (`.github/workflows/release.yml`): the `verify` job runs `npm run sdk:ready` on Node 24; `node22-compat` runs `npm ci`, `npm run build`, and the public-import smoke on Node 22; `supply-chain` runs audit, SPDX/license checks, SBOM, and source-secret scans; `publish` `needs:` all of `verify`, `node22-compat`, `postgres-integration`, `codeql-release`, and `supply-chain`, so nothing publishes unless every leg — including the audit/SBOM gates — passes.
|
|
410
427
|
|
|
411
428
|
**Process for a major-upgrade PR:** (1) bump exactly one dependency major in its own branch; (2) `npm run sdk:ready` green; (3) packed-install evidence (`npm run pack:dry-run`, or a scratch `npm install <tarball>` import smoke for native deps like `better-sqlite3`); (4) review lockfile churn line-by-line; (5) the `supply-chain` job supplies audit/SBOM; (6) confirm no build-time regression beyond measured noise on the matrix above; (7) merge separately from any feature work.
|
|
412
429
|
|
|
413
430
|
## Release checklist
|
|
414
431
|
|
|
415
432
|
|
|
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; `
|
|
433
|
+
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; `node22-compat` runs `npm ci`, `npm run build`, and public export imports on Node 22; `postgres-integration` runs the opt-in PostgreSQL adapter suite against a CI Postgres service.
|
|
417
434
|
|
|
418
435
|
| Gate | Enforcement |
|
|
419
436
|
| --- | --- |
|
|
420
437
|
| Docs coverage for persistence/runtime/migration surfaces | `docs.test.ts` enrolls every API page in `apiPages` (heading + index-link + bare-specifier + secret-scan checks); dedicated section assertions pin `database-persistence.md`, `runs-and-usage.md`, `session-stores-and-branching.md`, `migration.md`, `agent-definitions.md`, `performance.md`, and the Phase 41 `external_app_example_*` / `phase41_external_app_surfaces_*` gates. |
|
|
421
|
-
| Package exports/subpaths resolve to built output | `public-export-contract.test.ts` asserts every `exports`/`main`/`types`/`bin` target resolves to a built file under `dist/` with a sibling `.d.ts` (`dist/index.js` + `dist/index.d.ts` for a root package), and no target escapes `dist/` (no `src/` or `examples/` leak). CI `
|
|
438
|
+
| Package exports/subpaths resolve to built output | `public-export-contract.test.ts` asserts every `exports`/`main`/`types`/`bin` target resolves to a built file under `dist/` with a sibling `.d.ts` (`dist/index.js` + `dist/index.d.ts` for a root package), and no target escapes `dist/` (no `src/` or `examples/` leak). CI `node22-compat` also imports every public root `exports` default target on Node 22. |
|
|
422
439
|
| Public-API drift | `public-export-contract.test.ts` `phase39_public_protocol_exports_and_types_do_not_drift` pins the runtime protocol (`providerToolCallDelta`, `ToolCallDeltaContent`), the `/testing/provider-conformance` subpath shape, and the observational-memory runtime `.d.ts` surface. |
|
|
423
440
|
| Root SDK export surface freeze | `public-export-contract.test.ts` `root export surface is frozen` snapshots every value and type export of `src/index.ts` (107 value + 69 type) so any add/remove is a deliberate test update; `every frozen value export resolves at runtime` rebuilds `dist/index.js` and asserts each value export is present (catches build drift), and `every frozen type export appears in the built type declarations` asserts each type export is in `dist/index.d.ts`. |
|
|
424
441
|
| Examples compile and are listed; runnable demos execute | `npm run typecheck` runs `tsc -p examples --noEmit`; `docs.test.ts` checks every `examples/*.ts` file is listed in `examples/README.md`, then runs demos offline and scans output for secrets. |
|
|
@@ -427,10 +444,13 @@ Every release gate maps to an exact enforcement test or command, so the checklis
|
|
|
427
444
|
| NeuralWatt package/docs/examples release gate | `packaging.test.ts` pins `@arnilo/prism-providers/neuralwatt` package exports/type declarations and `@arnilo/prism-providers` family membership; `docs.test.ts` asserts `docs/index.md` links `providers/neuralwatt.md` and `provider-caching.md`, and that `examples/cache-aware-prompt-assembly.ts` plus `examples/neuralwatt-agent-run.ts` exist and are listed. |
|
|
428
445
|
| Enterprise PostgreSQL package/docs/example gate | Packaging/install/public-contract tests include `@arnilo/prism-core/enterprise/postgres`; `docs.test.ts` pins its API page, four-store migration/ownership/unknown-outcome/async-router guidance, and `examples/enterprise-postgres-state.ts`; `npm run test:postgres` exercises migration, restart, contention, and cleanup with an explicit database URL. |
|
|
429
446
|
| Version graph and resumable publication | `release.test.ts` covers exact package/lock/range validation, topological order, registry collisions, dry-run, interrupted reports/resume, clean tagged git state, provenance/public/tag arguments, and token-safe errors. `release:check` and `release:publish` derive the workspace graph without a manual package list. |
|
|
447
|
+
| Release version claims have one source | `currentVersion()` (`scripts/package-truth.mjs`) reads the root manifest, and `scripts/version-literal-gate.test.mjs` fails when any surface that claims the release version disagrees with it: all 10 manifests, every internal `@arnilo/*` caret range, `package-lock.json`, the `src/index.ts` version constant, the `docs/index.md` current-line banner, the `release.yml` tag list, and the generated `scripts/package-truth.json`. Each stale surface is named in one pre-flight (with a positive control for a half-finished cut), and the release-line suites (`packaging.test.ts`, `docs.test.ts`, `release.test.ts`, `phase24-truth`, `phase34-freeze`) derive their expectations from the manifest instead of pinning the cut. |
|
|
430
448
|
| Pre-publish compatibility gates | `release:gate` (in `sdk:ready`) fails on removed/changed `.d.ts` exports vs `scripts/compat-baseline/` (unless `--allow-break` + migration note), version-range/lockfile drift, and tarball deny-list violations (`plans/`, `code-reviews/`, `docs/review-coverage-*`, `*.map`, `__tests__/`); unit-tested in `scripts/release-gate.test.mjs`. |
|
|
431
449
|
| Legacy registry markers (plan 054 Task 7) | `scripts/phase54-legacy-registry.mjs --dry-run` verifies every retired name's final published version exists and `latest` is unchanged, and that each deprecation URL anchor exists in `docs/migrate-to-0.4.md`, without mutating the registry; `--apply --confirm` pre-flights all 54 entries and fails closed (zero mutations) on any mismatch, then idempotently adds the `legacy` dist-tag and `<0.4.0` deprecation warning (already-correct entries skipped; per-entry status in `release-artifacts/legacy-registry-plan.json` for safe resume). `packaging.test.ts` asserts the generated plan covers all 54 retired names with uniform messages and valid guide anchors; the offline fixture suite `scripts/phase54-legacy-registry.test.mjs` proves the dry-run/apply/resume behavior without network or tokens. |
|
|
432
450
|
| Formatting, linting, and coverage thresholds | `npm run lint` and `npm run format:check` run Biome (single root `biome.json`, workspaces inherit) and fail on any lint error or unformatted file; `npm run test:coverage` uses Node's built-in `--experimental-test-coverage` with enforced minimums (lines 60 / functions 70 / branches 75) and no third-party service. All three run inside `sdk:ready`. |
|
|
433
451
|
| Supply-chain and live-canary policy | `supply-chain-security.test.ts` verifies SPDX allow/deny behavior, bounded source/artifact secret detection, credential-free canary reports, timeout/redacted failures, immutable action revisions, no `pull_request_target`, protected live environment, attestation paths, and publish dependency on `supply-chain`; CI adds CodeQL and PR dependency review. |
|
|
452
|
+
| Release secret scan covers the tracked release set | `scripts/phase27-release.test.mjs` enumerates `git ls-files` (plus built `packages/prism-core/dist` when present) and passes that explicit list to the unchanged `scanSecrets` — the same tracked set CI scans (`git ls-files -z \| xargs -0 node scripts/scan-secrets.mjs` in `release.yml`/`security.yml`), so no untracked or gitignored working-tree file can fail the gate or mask a tracked finding; a bare `node scripts/scan-secrets.mjs <path>` still walks everything for pre-commit use, and the gate reports the mode, file count, and untracked-but-unignored findings as a note without failing on them. |
|
|
453
|
+
| Workflow and script references resolve | `scripts/workflow-liveness.test.mjs` resolves every `-w <pkg>` / `--workspace <pkg>` target in `.github/workflows/*.yml` against the live workspace inventory and every named npm script against that package's manifest (root scripts included for a bare `npm run x`), resolves every `@arnilo/*` specifier in `scripts/**/*.mjs` against the live package and its `exports` subpaths, and rejects any `uses:` reference that is not a full 40-hex commit SHA — the drift class that left `sandbox-browser.yml` building four retired packages, `scripts/fixtures/phase26-coding-journey.mjs` packing `packages/coding-agent`/`-security` and `scripts/benchmark-scenarios/phase11-auth.mjs` importing `@arnilo/prism-openapi-tools`/`-server` after plan 054 folded them, with a positive control for each. |
|
|
434
454
|
| Network-free + offline test budget | `network-free-guard.test.ts` keeps the default suite network-free; budget pinned `< 60s` (measured baseline above). Install-smoke is offline (`--offline --no-audit --no-fund`, zero registry fetches). |
|
|
435
455
|
| Core security invariants reaffirmed | Runtime/docs tests hold the trust boundary: **no built-in app tools** (hosts register tools; the core ships only the mock provider and contract helpers), **no hidden provider/credential globals** (providers/credentials are host-owned `AgentConfig` fields, resolved via explicit `providerSource`/`CredentialResolver`), **no auto package discovery** (provider/tool/skill packages are opt-in and individually installed; contribution discovery is realpath-contained and emits inert envelopes the host registers), and **no secret persistence in core** (redaction applies before any `RunLedger`/`SessionStore` append; the ledger gate asserts each message event is written exactly once and redacted). |
|
|
436
456
|
|
package/docs/server.md
CHANGED
|
@@ -8,7 +8,7 @@ No listener starts on import. Empty `agents`/`workflows` maps expose nothing. Au
|
|
|
8
8
|
|
|
9
9
|
## When to use it
|
|
10
10
|
|
|
11
|
-
Use it when a Node
|
|
11
|
+
Use it when a Node 22, serverless, worker, or framework host already speaks Web `Request`/`Response` and needs a small Prism API boundary. Wrap it in the platform's native adapter rather than adding Express, Fastify, Hono, Koa, Nest, or Next to Prism.
|
|
12
12
|
|
|
13
13
|
Use `AgentSession` or workflow APIs directly for in-process applications. Do not treat this package as an auth provider, user database, firewall, durable agent-result store, or public listener.
|
|
14
14
|
|