@arnilo/prism 0.2.3 → 0.2.5

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 +10 -0
  2. package/README.md +3 -3
  3. package/dist/agent-session/create-agent.d.ts +6 -0
  4. package/dist/agent-session/create-agent.js +13 -0
  5. package/dist/agent-session/event-subscriber.d.ts +17 -0
  6. package/dist/agent-session/event-subscriber.js +68 -0
  7. package/dist/agent-session/helpers.d.ts +44 -0
  8. package/dist/agent-session/helpers.js +194 -0
  9. package/dist/agent-session/session.d.ts +101 -0
  10. package/dist/agent-session/session.js +1568 -0
  11. package/dist/agent-session.d.ts +6 -105
  12. package/dist/agent-session.js +6 -1833
  13. package/dist/contracts-core/agent.d.ts +257 -0
  14. package/dist/contracts-core/agent.js +5 -0
  15. package/dist/contracts-core/compaction.d.ts +72 -0
  16. package/dist/contracts-core/compaction.js +2 -0
  17. package/dist/contracts-core/content.d.ts +116 -0
  18. package/dist/contracts-core/content.js +2 -0
  19. package/dist/contracts-core/extensions.d.ts +163 -0
  20. package/dist/contracts-core/extensions.js +2 -0
  21. package/dist/contracts-core/loop.d.ts +98 -0
  22. package/dist/contracts-core/loop.js +2 -0
  23. package/dist/contracts-core/persistence.d.ts +366 -0
  24. package/dist/contracts-core/persistence.js +9 -0
  25. package/dist/contracts-core/provider.d.ts +97 -0
  26. package/dist/contracts-core/provider.js +2 -0
  27. package/dist/contracts-core/resources.d.ts +44 -0
  28. package/dist/contracts-core/resources.js +7 -0
  29. package/dist/contracts-core/run-limits.d.ts +81 -0
  30. package/dist/contracts-core/run-limits.js +2 -0
  31. package/dist/contracts-core/session.d.ts +187 -0
  32. package/dist/contracts-core/session.js +131 -0
  33. package/dist/contracts-core.d.ts +13 -1425
  34. package/dist/contracts-core.js +10 -138
  35. package/dist/index.d.ts +1 -1
  36. package/dist/index.js +1 -1
  37. package/docs/0.1.0-readiness.md +15 -13
  38. package/docs/index.md +2 -2
  39. package/docs/migration.md +8 -0
  40. package/docs/release-and-install.md +59 -8
  41. package/package.json +2 -2
@@ -1,139 +1,11 @@
1
- export const SESSION_ENTRY_KINDS = [
2
- "message",
3
- "event",
4
- "summary",
5
- "metadata",
6
- "model_change",
7
- "label",
8
- "custom",
9
- "compaction",
10
- ];
11
- const SESSION_ENTRY_KIND_SET = new Set(SESSION_ENTRY_KINDS);
12
- export const SESSION_ENTRY_SCHEMA_VERSION = 1;
13
- export function isSessionEntryKind(value) {
14
- return typeof value === "string" && SESSION_ENTRY_KIND_SET.has(value);
15
- }
16
- /** Host-written `SessionRecord.metadata` / session metadata key for workspace filtering. */
17
- export const SESSION_SEARCH_WORKSPACE_METADATA_KEY = "workspaceRoot";
18
- export const DEFAULT_SESSION_SEARCH_LIMIT = 20;
19
- export const HARD_MAX_SESSION_SEARCH_LIMIT = 100;
20
- export const DEFAULT_MAX_SESSION_SEARCH_QUERY_BYTES = 4 * 1024;
21
- export const HARD_MAX_SESSION_SEARCH_QUERY_BYTES = 16 * 1024;
22
- export const DEFAULT_MAX_SESSION_SEARCH_SNIPPET_BYTES = 512;
23
- export const HARD_MAX_SESSION_SEARCH_SNIPPET_BYTES = 4 * 1024;
24
- export const DEFAULT_MAX_SESSION_SEARCH_CURSOR_BYTES = 1 * 1024;
25
- export const HARD_MAX_SESSION_SEARCH_CURSOR_BYTES = 4 * 1024;
26
- export const DEFAULT_MAX_SESSION_SEARCH_LINEAR_SESSIONS = 1_000;
27
- export const HARD_MAX_SESSION_SEARCH_LINEAR_SESSIONS = 5_000;
28
- export const DEFAULT_MAX_SESSION_SEARCH_LINEAR_ENTRIES = 10_000;
29
- export const HARD_MAX_SESSION_SEARCH_LINEAR_ENTRIES = 50_000;
30
- export const DEFAULT_MAX_SESSION_SEARCH_LINEAR_BYTES = 8 * 1024 * 1024;
31
- export const HARD_MAX_SESSION_SEARCH_LINEAR_BYTES = 64 * 1024 * 1024;
32
- export const DEFAULT_MAX_SESSION_SEARCH_FTS_CANDIDATES = 1_000;
33
- export const HARD_MAX_SESSION_SEARCH_FTS_CANDIDATES = 5_000;
34
- /**
35
- * O(1) validation before any scan/query. Applies default page limit; rejects NaN,
36
- * non-positive limits, oversize query/cursor/filter strings, and invalid order.
37
- */
38
- export function resolveSessionSearchQuery(query) {
39
- const limit = query.limit === undefined ? DEFAULT_SESSION_SEARCH_LIMIT : query.limit;
40
- if (!Number.isSafeInteger(limit) || limit < 1 || limit > HARD_MAX_SESSION_SEARCH_LIMIT) {
41
- throw new TypeError(`SessionSearchQuery.limit must be a safe integer from 1 to ${HARD_MAX_SESSION_SEARCH_LIMIT}`);
42
- }
43
- const order = query.order ?? "desc";
44
- if (order !== "asc" && order !== "desc") {
45
- throw new TypeError('SessionSearchQuery.order must be "asc" or "desc"');
46
- }
47
- assertSearchStringBytes(query.query, "query", HARD_MAX_SESSION_SEARCH_QUERY_BYTES);
48
- assertSearchStringBytes(query.cursor, "cursor", HARD_MAX_SESSION_SEARCH_CURSOR_BYTES);
49
- assertSearchStringBytes(query.workspaceRoot, "workspaceRoot", HARD_MAX_SESSION_SEARCH_QUERY_BYTES);
50
- assertSearchStringBytes(query.provider, "provider", HARD_MAX_SESSION_SEARCH_QUERY_BYTES);
51
- assertSearchStringBytes(query.model, "model", HARD_MAX_SESSION_SEARCH_QUERY_BYTES);
52
- assertSearchStringBytes(query.label, "label", HARD_MAX_SESSION_SEARCH_QUERY_BYTES);
53
- assertSearchStringBytes(query.summary, "summary", HARD_MAX_SESSION_SEARCH_QUERY_BYTES);
54
- assertSearchStringBytes(query.tenantId, "tenantId", HARD_MAX_SESSION_SEARCH_QUERY_BYTES);
55
- assertSearchStringBytes(query.accountId, "accountId", HARD_MAX_SESSION_SEARCH_QUERY_BYTES);
56
- assertSearchStringBytes(query.userId, "userId", HARD_MAX_SESSION_SEARCH_QUERY_BYTES);
57
- assertSearchStringBytes(query.fromUpdatedAt, "fromUpdatedAt", HARD_MAX_SESSION_SEARCH_QUERY_BYTES);
58
- assertSearchStringBytes(query.toUpdatedAt, "toUpdatedAt", HARD_MAX_SESSION_SEARCH_QUERY_BYTES);
59
- return { ...query, limit, order };
60
- }
61
- function assertSearchStringBytes(value, name, hardMax) {
62
- if (value === undefined)
63
- return;
64
- if (typeof value !== "string") {
65
- throw new TypeError(`SessionSearchQuery.${name} must be a string`);
66
- }
67
- // ponytail: UTF-8 byte length via TextEncoder; upgrade only if a non-Unicode host appears.
68
- const bytes = new TextEncoder().encode(value).byteLength;
69
- if (bytes > hardMax) {
70
- throw new TypeError(`SessionSearchQuery.${name} exceeds ${hardMax} bytes`);
71
- }
72
- }
73
- export const SESSION_SEARCH_UNSUPPORTED_CODE = "session_search_unsupported";
74
- /** Thrown when a store opts out of `searchSessions` (memory `unsupported`, JSONL). */
75
- export class SessionSearchUnsupportedError extends Error {
76
- code = SESSION_SEARCH_UNSUPPORTED_CODE;
77
- constructor(message = "session search is unsupported by this store") {
78
- super(message);
79
- this.name = "SessionSearchUnsupportedError";
80
- }
81
- }
82
- export function isSessionSearchUnsupported(error) {
83
- return error instanceof Error && error.code === SESSION_SEARCH_UNSUPPORTED_CODE;
84
- }
85
- /** Stable error code carried by `SessionAppendConflictError`. */
86
- export const SESSION_APPEND_CONFLICT_CODE = "session_append_conflict";
87
- /** CAS conflict code for `appendSession` metadata writes. Stable and message-independent. */
88
- export const SESSION_METADATA_CONFLICT_CODE = "metadata_conflict";
89
- /**
90
- * Thrown when `appendSession` is called with an `expectedVersion` CAS guard and the
91
- * stored session's version no longer matches (concurrent create/branch/archive, or a
92
- * delete raced the write). Recognize via the stable `code` or `isSessionMetadataConflict`.
93
- */
94
- export class SessionMetadataConflictError extends Error {
95
- conflict;
96
- code = SESSION_METADATA_CONFLICT_CODE;
97
- constructor(conflict) {
98
- super(`session metadata conflict: expected version ${conflict.expectedVersion}, current ${conflict.currentVersion}`);
99
- this.conflict = conflict;
100
- this.name = "SessionMetadataConflictError";
101
- }
102
- }
103
- /** Type guard keyed off the stable `code` (works across bundles; not message text). */
104
- export function isSessionMetadataConflict(error) {
105
- return error instanceof Error && error.code === SESSION_METADATA_CONFLICT_CODE;
106
- }
107
- /**
108
- * Thrown when `SessionStore.append` rejects an entry under `SessionAppendOptions`
109
- * (dangling/stale `expectedParentId`, stricter adapter CAS failure, or duplicate
110
- * idempotency key for the same parent). Recognize via the stable `code` and
111
- * `isSessionAppendConflict`, not message text.
112
- */
113
- export class SessionAppendConflictError extends Error {
114
- conflict;
115
- code = SESSION_APPEND_CONFLICT_CODE;
116
- constructor(conflict) {
117
- const detail = conflict.idempotencyDuplicate
118
- ? `idempotency key already used`
119
- : conflict.currentLeafId !== undefined
120
- ? `expected parent ${conflict.expectedParentId ?? "<none>"} does not match current leaf ${conflict.currentLeafId}`
121
- : `expected parent ${conflict.expectedParentId ?? "<none>"} is unavailable`;
122
- super(`session append conflict: ${detail}`);
123
- this.conflict = conflict;
124
- this.name = "SessionAppendConflictError";
125
- }
126
- }
127
- /** Type guard keyed off the stable `code` (works across bundles; not message text). */
128
- export function isSessionAppendConflict(error) {
129
- return error instanceof Error && error.code === SESSION_APPEND_CONFLICT_CODE;
130
- }
131
- const SESSION_METADATA_KEY_PATTERN = /^[A-Za-z0-9_][A-Za-z0-9_.-]{0,127}$/;
132
- /** Validate a top-level `SessionRecord.metadata` key used by `SessionQuery.metadataKey` filters. */
133
- export function assertSessionMetadataKey(key) {
134
- if (typeof key !== "string" || !SESSION_METADATA_KEY_PATTERN.test(key)) {
135
- throw new RangeError("metadataKey must match /^[A-Za-z0-9_][A-Za-z0-9_.-]{0,127}$/");
136
- }
137
- return key;
138
- }
1
+ export * from "./contracts-core/content.js";
2
+ export * from "./contracts-core/run-limits.js";
3
+ export * from "./contracts-core/provider.js";
4
+ export * from "./contracts-core/agent.js";
5
+ export * from "./contracts-core/extensions.js";
6
+ export * from "./contracts-core/session.js";
7
+ export * from "./contracts-core/persistence.js";
8
+ export * from "./contracts-core/compaction.js";
9
+ export * from "./contracts-core/resources.js";
10
+ export * from "./contracts-core/loop.js";
139
11
  //# sourceMappingURL=contracts-core.js.map
package/dist/index.d.ts CHANGED
@@ -109,5 +109,5 @@ export { createToolParameterValidator, createToolRegistry, dispatchToolCall, fil
109
109
  export type { ResolvedUseCaseModel, ResolveUseCaseModelInput, UseCaseModelBinding, } from "./use-case-model.js";
110
110
  export { resolveUseCaseModel, resolveUseCaseModelBinding, useCaseCredentialProviderId, } from "./use-case-model.js";
111
111
  export declare const name = "prism";
112
- export declare const version = "0.2.3";
112
+ export declare const version = "0.2.5";
113
113
  export declare const description = "Agent harness for AI providers, agents, sessions, and tools.";
package/dist/index.js CHANGED
@@ -60,6 +60,6 @@ export { DEFAULT_TOOL_RESULT_FOLD_MAX_SUMMARY_BYTES, DEFAULT_TOOL_RESULT_FOLD_MI
60
60
  export { createToolParameterValidator, createToolRegistry, dispatchToolCall, filterTools } from "./tools.js";
61
61
  export { resolveUseCaseModel, resolveUseCaseModelBinding, useCaseCredentialProviderId, } from "./use-case-model.js";
62
62
  export const name = "prism";
63
- export const version = "0.2.3";
63
+ export const version = "0.2.5";
64
64
  export const description = "Agent harness for AI providers, agents, sessions, and tools.";
65
65
  //# sourceMappingURL=index.js.map
@@ -1,6 +1,6 @@
1
1
  # 0.1.0 / 1.0 Readiness Gates
2
2
 
3
- Status: **0.1.1** is the current release line (plan 013 hardening patch on the frozen 0.1.x line; plan 012 release-candidate hardening); **1.0** readiness remains operator-gated, not automatic.
3
+ Status: **0.2.5** is the current release line (the 0.2.x review-remediation line: fail-closed runtime/sandbox security, provider completion and outbound trust boundaries, concurrent-state/durability integrity, build/coverage/release-evidence integrity, package/documentation/compatibility truth, maintainability and bounded performance); **0.1.7** was the terminal 0.1.x baseline; **1.0** readiness remains operator-gated, not automatic.
4
4
 
5
5
  This page distills runnable readiness gates into one command-per-gate table.
6
6
  The **Last evidence** column records the 0.1.0-tree snapshot (plan 012 Tasks
@@ -17,22 +17,24 @@ Evidence trail: [`docs/_evidence/review-coverage-2026-07-26-phase-11.md`](./_evi
17
17
  The per-phase review-coverage evidence archive lives in [`docs/_evidence/`](./_evidence/)
18
18
  (plans 067–079, releases 0.0.4–0.0.16; tarball-excluded, kept in-repo for audit).
19
19
  Historical release lines (0.0.16 floor → 0.0.27 Phase 10 ACP interop → 0.1.0)
20
- keep their per-phase evidence in the pages above; this page records the 0.1.1
21
- snapshot (plan 013) with the 0.1.0 table below as the previous line.
20
+ keep their per-phase evidence in the pages above; this page records the 0.2.5
21
+ snapshot (plan 025) with the 0.1.x tables below as the historical record.
22
22
 
23
- ## Current line (0.1.1)
23
+ ## Current line (0.2.5)
24
24
 
25
25
  | Item | Status |
26
26
  |---|---|
27
- | Published graph | **49** publishable manifests at exact **0.1.1** (root + 48 workspace packages; `docs/release-and-install.md`) |
28
- | Plan 013 hardening patch | Five scoped fixes (plan 013 freeze `scripts/phase13-freeze-manifest.json`): build single-flight (`npm run clean` standalone), deterministic MCP SSE relay test (`relayStatelessBody` internal export, `sse-relay.test.ts`), combined coverage summary (`scripts/coverage-summary.mjs`, core gate the only hard threshold), canonical manifest-count narrative (49 = root + 48: 14 provider + 9 prism-* + 25 capability), ACP modes/config ownership-scoped persistence guidance (agent never persists them; host stores key by `sessions.ownership`, cross-tenant restore rejects `ERR_PRISM_ACP_INPUT`) |
29
- | Upgrade path | `docs/migration.md` `0.1.0 → 0.1.1` (additive, no migration); store-compatible both directions |
30
- | Compat promise | Additive-only vs the frozen 0.1.x contract; `scripts/compat-baseline` regenerated at 0.1.1 (single version-literal delta + one additive internal relay export), zero breaking deltas |
31
- | Security policy | `npm audit --audit-level=moderate` 0 at 0.1.1; threat-suites leg unchanged (plan 012) |
32
- | Docs freeze | tripwires green including the manifest-count tripwire and the plan 013 Task 6 handoff/migration tripwire |
33
- | Previous line | the **0.1.0** table below keeps the plan 012 snapshot; the **0.0.16** values remain the historical network-free floor |
34
-
35
- ## Current line (0.1.0)
27
+ | Published graph | **50** publishable manifests at exact **0.2.5** (root + 49 workspace packages: 14 provider adapters + 9 `prism-*` family/profile + 26 capability; generated by `node scripts/package-truth.mjs` → `scripts/package-truth.json`) |
28
+ | Current-line cut | The 0.2.x review-remediation line, additive-only vs the frozen 0.1.x contract: 0.2.0 fail-closed runtime/sandbox security (durable-resume decision validation, work-tool env isolation, explicit sandbox capabilities), 0.2.1 provider completion + outbound trust boundaries (strict stream completion, bounded success bodies, DNS-pinned OIDC/OPA fetches), 0.2.2 concurrent-state/durability integrity (model-budget reservation, conversation-metadata CAS, single-consumer EventMultiplexer, NATS durable identity), 0.2.3 build/coverage/release-evidence integrity (build single-flight, corrected coverage denominators, release skip manifest, stabilized quality gates), 0.2.4 package/documentation/compatibility truth (umbrella wording matches manifests, manifest-derived package truth, peer-version policy Decision A, current-line truth), 0.2.5 maintainability and bounded performance (god-module splits into cohesive family files behind preserved barrels, persistence-mechanics dedup into `session-store-codecs`, quadratic `Buffer.concat` removed from framing/tar, dead-code cleanup internal-only, 76 behavior-backed coverage regressions) |
29
+ | Upgrade path | `docs/migration.md` `0.2.4 → 0.2.5` (no runtime contract change, no migration); store-compatible throughout 0.2.x |
30
+ | Compat promise | Additive-only vs the frozen 0.1.x contract; `scripts/compat-baseline` regenerated at 0.2.5 (version literal + additive internal-helper exports), zero breaking deltas |
31
+ | Security policy | `npm audit --audit-level=moderate` 0 at 0.2.5; threat-suites legs (phase8–11 + phase20–25) green; protected Postgres/NATS/live-canary legs operator-gated |
32
+ | Docs freeze | tripwires green including the canonical manifest-count tripwire (50/49/14/9/26), the plan 024 package-truth tests (generator reproducibility + artifact equality + closure asserts + derived docs truth), and the plan 025 bounded-accumulation near-limit probe |
33
+ | 0.1.x line | **0.1.7** (plan 019) is the terminal 0.1.x baseline; the 0.1.1 table below keeps the plan 013 snapshot; the 0.1.0 table keeps the plan 012 snapshot; the **0.0.16** values remain the historical network-free floor |
34
+
35
+ ## Previous line (0.1.1)
36
+
37
+ ## Previous line (0.1.0)
36
38
 
37
39
  | Item | Status |
38
40
  |---|---|
package/docs/index.md CHANGED
@@ -129,7 +129,7 @@ Prism is a TypeScript/Node.js agent harness. Host apps and extension packages ow
129
129
  - [Ponytail behavior integration](ponytail.md): optional `@arnilo/prism-ponytail` — upstream Ponytail skills/commands, `ponytail-mode` injector, session `ponytail-mode` persistence; resolves peer `@dietrichgebert/ponytail` or `upstreamPath`; opt-in (not in code/sdk profiles).
130
130
 
131
131
  ## Release and install
132
- - [Release and install](release-and-install.md): current **0.2.3** 50-package graph (root + 49 workspace packages) — plan 023 the build-coverage-and-release-evidence-integrity cut: **build serialization** (dependency-free `scripts/with-build-lock.mjs` — one O_EXCL lockfile at `node_modules/.prism-build.lock` serializing every emit/test leaf so concurrent compilers can never expose a partial live `dist/`, stale-PID reclaim, env-overridable `PRISM_BUILD_LOCK_TIMEOUT_MS`, fail-closed; documented direct-`tsc` caveat), **corrected workspace coverage denominators** (package-local `--test-coverage-include=dist/**` so imported core `dist` no longer pollutes workspace rows — `mcp` 45.47→90.25, `rag` 19.70→94.82; evidence-based per-package thresholds in `scripts/coverage-thresholds.json` with `protectedException` for durable-leg packages shown separately, machine-readable `scripts/coverage-summary.json`), **machine-auditable release skip manifest** (`scripts/release-skip-manifest.mjs` → `scripts/release-evidence.json`: every surface recorded `pass`/`skip`/`blocked`/`protected` with reason and required env; the 33 protected/live skips named; a required surface without evidence records `blocked` and fails the release gate fail-closed — missing credentials/services can never convert into a green release), and **stabilized quality gates** (Biome 2.x `preset` config migration with zero lint diagnostics, the racy 150ms MCP bridge timing assert replaced by a deterministic barrier, load-sensitive guards carry documented `ponytail:` ceilings, machine-readable `lint-report.sarif` + `unused-report.json` retained by CI); no runtime contract delta (compat gate at 0.2.3: version literal only), no migration; then plan 022 the concurrent-state-and-durability-integrity cut: atomic model-budget reservation (`ModelRouterStateStore.reserveBudget`/`commitBudget`/`releaseBudget` with fencing tokens, `reservationTtlMs` expiry and unknown-usage reconciliation, rate/budget key-map caps with LRU eviction that never drops a held reservation), atomic conversation metadata (`SessionRecord.version` + `appendSession` `expectedVersion` CAS across Postgres/SQLite — create-only `0`, exact-version `N>0`, legacy last-write-wins when omitted; `SessionMetadataConflictError` `metadata_conflict` with versions only, HTTP 409; concurrent create/branch/archive single-statement with branch caps inside the CAS, archive wins, deleted rows never resurrect), single-consumer `EventMultiplexer` (`EventMultiplexerError` `ERR_PRISM_EVENT_MULTIPLEXER_SINGLE_CONSUMER` instead of silent queue sharing), restart-stable NATS durable consumer identity (`prism_<hmac16>` with no random suffix — crash-resumed subscribe continues from the last ack, orphaned 0.2.1 consumers reclaimed on clean stop), and bounded non-durable active-run registries (sweep + fail-closed 512 cap `ERR_PRISM_WORKFLOW_RUN_REGISTRY_OVERFLOW`); new regression surface `scripts/phase22-security.test.mjs` (4 blockers + gate accounting over built public entrypoints) + packed plain-JS `security22.mjs` consumer + the `@arnilo/prism/testing/state-concurrency-conformance` harness (7 probes across memory/Postgres/SQLite/NATS legs, no timing-only sleeps) + the `scripts/phase22-conformance.test.mjs` gate; additive-only compat (new exports only, no removals); forward-only migrations 008 (`prism_sessions.version`) and 003 (`prism_model_router_budgets.reservations`); migration `0.2.1 → 0.2.2`; then plan 021 the provider-completion-and-outbound-trust-boundaries cut: strict stream completion is the shared OpenAI-compatible default (truncated streams fail `incomplete_delta`, explicit `strictCompletion: false` opt-out), bounded success bodies via `readBoundedResponseJson` on all discovery/quota/embeddings/upload/OAuth JSON endpoints (65,536-byte ceiling, depth/property/shape caps), DNS-pinned OIDC JWKS/OPA/content fetches through the core `pinnedFetch` primitive with 3xx redirects rejected outright (private/metadata answers fail closed `ssrf_denied`), shared bounded OAuth device/token polling (`pollDeviceCodeToken`) across provider-openai and credentials-node, and the four edge fixes (Azure/Vertex credential-once, Bedrock duplicate-case/repeated-query SigV4 canonicalization, OpenAI upload failed-DELETE retention, cache `__overflow__` tokens-only); public-entrypoint threat-suite `scripts/phase21-security.test.mjs` + packed plain-JS consumer; additive-only compat (MCP transport helpers re-exported from core, no removals); migration `0.2.0 → 0.2.1`; then plan 020 the fail-closed runtime-and-sandbox-security cut on the 0.2.x review-remediation line: durable-resume decision validation in core (`assertValidAgentRunResume` — unknown decisions/malformed batches fail closed with `ERR_PRISM_DECISION_*` before any state claim, checkpoint write, or tool execution; server parser remains defense in depth), isolated work-tool subprocess environments (`@arnilo/prism-work-tools` — fixed base allow-list + explicit env + forced HOME/telemetry + late-bound per-identity tokens, 64-name/64-KiB caps, absolute binary/configDir, linear output capture), and explicit sandbox capabilities (`@arnilo/prism-coding-security` — `SandboxAdapter.capabilities` with omission-is-false fail-closed resolution, `SandboxCodingComposition.capabilities` from verified wiring, `containmentClaim` deprecated as the conservative projection; Docker reports only verified controls, native reports filesystem/process/privilege `false`); public-entrypoint security conformance (`scripts/phase20-security.test.mjs`, wired into `security:threat-suites`), packed plain-JS consumer regressions, and the sandbox-browser workflow's fail-loud Docker/native capability evidence gate — 0.2.0 never ships while a blocker is skipped; migration and rollback notes in `docs/migration.md` `0.1.7 → 0.2.0`, store-compatible with 0.1.7 in both directions; 0.1.7 was the performance-and-DX patch — dependency-free `createCacheTelemetry()` per-provider/model cache hit/miss aggregator (bounded cardinality with `__overflow__`, token counters/rates only, host-activated), host-configurable `ModelRouterSelectionPolicy` on `createModelRouter` with the reference `createCostLatencySelection` (ModelCost rank then in-memory latency EMA, default ordered behavior byte-identical), `prism providers add <name>` OpenAI-compatible provider scaffold (manifest/provider/models/cache/conformance test/docs stub, npm-name + traversal + symlink-escape validation, placeholders only), and the async `AgUiProjection` verification closeout (plan 009 Task 15 evidence recorded, no new code); plan 017 the documented breaking cut — deprecated-option removal with `docs/migration.md` `0.1.4 → 0.1.5` section and reviewed compat-baseline regeneration via `--allow-break` then `--update-baseline`: the inert provider request knobs, `RunOptions.maxToolRounds`, observational-memory flat settings keys + top-level worker aliases, `ReadToolOptions.autoResizeImages`, `INIT_PROVIDERS`; all removals fail closed naming their replacement; plan 016 internal god-module split — `agents.ts`/`contracts.ts` reorganized behind barrel re-exports with a byte-identical public entry surface, measured tree-shaking improvement in `scripts/phase16-baseline.json`, and additive `@arnilo/prism-browser` Chrome DevTools Protocol capabilities — `browser_evaluate`/`browser_observe` and `block_urls`/`unblock_urls`/`throttle`/`emulate` act actions; plan 015 dead-code and deprecation hygiene on the frozen 0.1.x line — parameterized benchmark runner `scripts/benchmark.mjs` absorbing the per-version runners, archived review-coverage evidence in `docs/_evidence/`, non-blocking unused-code sweep `npm run sweep:unused`, opt-in checkpoint persistence for loaded-skill names and read-path sets; plan 014 Alibaba provider enrichment — embeddings, video input, verified compatible-mode surface decision table; plan 013 post-release hardening — build single-flight, MCP SSE relay test, combined coverage summary, canonical manifest-count narrative, ACP modes/config persistence guidance; Phase 12 release-candidate hardening; plan 012 — freeze manifest, compatibility matrix, upgrade matrix, packed-install e2e journeys, restart-recovery evidence, capacity envelopes, security policy), exact-peer/install/tarball rules, deterministic resumable publication and publish dry-run, frozen 0.1.x compatibility and support matrix (Node/PostgreSQL/platform/provider/protocol pins and unsupported combinations, machine-checked against `scripts/phase12-freeze-manifest.json`), protected PostgreSQL gate, pinned supply-chain gates, offline tests, the 0.0.15 provider/AI-SDK/RAG/memory protected live-canary matrix, and sandbox-browser Docker/Playwright gates.
133
- - [0.1.0 / 1.0 readiness gates](0.1.0-readiness.md): command-per-gate 1.0 readiness table — frozen API surface + compat gate, migration/docs tripwires, budget table, live-suite matrix, security matrix, current-line status (**0.0.23** published target), signed-publication/live-canary prerequisites for 1.0, and Phase 12 demand-evidence entry criteria.
132
+ - [Release and install](release-and-install.md): current **0.2.5** 50-package graph (root + 49 workspace packages) — plan 025 the maintainability-and-bounded-performance cut: **god-module splits** (the six remaining implementation monoliths — `src/contracts-core.ts` 1,719 L, `src/agent-session.ts` 2,049 L, `workflows/src/run.ts` 1,227 L, `server/src/handler.ts` 1,005 L, `coding-agent/src/repository.ts` 974 L, `ag-ui/src/acp/agent.ts` 836 L — split into cohesive family files behind preserved barrels, compat-preserving with zero breaking deltas, no `exports`-map subpath, `RuntimeAgentSession` kept as one class with a recorded reason), **persistence-mechanics dedup** (21 pure ownership/cursor/checkpoint/lifecycle/search helpers moved into the dependency-free `session-store-codecs`; postgres/sqlite adapters shrank 273 lines; SQL dialect stays per-adapter; no schema/shape change; cross-store conformance green), **bounded accumulation removed** (per-push `Buffer.concat` in language framing + tar parsing → chunk-array readers; framing ~100–200× faster at 4,000 chunks, tar linear at 8 MiB, caps fail-closed byte-identical; CLI `collectOutput` audited already linear), **dead-code cleanup internal-only** (62 candidates triaged: 2 internal removals + 60 allow-listed in `docs/_evidence/phase25-dead-exports-triage.md`), and **coverage close** (76 behavior-backed regressions; core 90.53/84.20/90.54 → 91.43/84.80/91.60); additive-only compat (105 helper exports), no migration; then plan 024 the package-documentation-and-compatibility-truth cut: **umbrella wording matches manifests** (`@arnilo/prism-providers` installs 11 of 14 provider adapters — Azure/Bedrock/Vertex are added separately by `prism-all`; `prism-all` installs 20 direct / 43 transitive packages and omits document-reader, OpenAPI tools, NATS, Caveman, Ponytail; membership unchanged in 0.2.x), **manifest-derived package truth** (`scripts/package-truth.mjs` → `scripts/package-truth.json` is the single source for counts, provider membership, and closures; docs literals regenerate from it and drift fails the gates), **peer-version policy Decision A** (exact `@arnilo/prism: 0.2.4` pins, atomic-upgrade rule, ERESOLVE refusal for partial upgrades, `^1.0.0` widening at 1.x), and **current-line truth** (`docs/0.1.0-readiness.md` at the 0.2.x line with 0.1.7 as the terminal 0.1.x baseline); no runtime contract delta (compat gate at 0.2.4: version literal only), no migration; then plan 023 the build-coverage-and-release-evidence-integrity cut: **build serialization** (dependency-free `scripts/with-build-lock.mjs` — one O_EXCL lockfile at `node_modules/.prism-build.lock` serializing every emit/test leaf so concurrent compilers can never expose a partial live `dist/`, stale-PID reclaim, env-overridable `PRISM_BUILD_LOCK_TIMEOUT_MS`, fail-closed; documented direct-`tsc` caveat), **corrected workspace coverage denominators** (package-local `--test-coverage-include=dist/**` so imported core `dist` no longer pollutes workspace rows — `mcp` 45.47→90.25, `rag` 19.70→94.82; evidence-based per-package thresholds in `scripts/coverage-thresholds.json` with `protectedException` for durable-leg packages shown separately, machine-readable `scripts/coverage-summary.json`), **machine-auditable release skip manifest** (`scripts/release-skip-manifest.mjs` → `scripts/release-evidence.json`: every surface recorded `pass`/`skip`/`blocked`/`protected` with reason and required env; the 33 protected/live skips named; a required surface without evidence records `blocked` and fails the release gate fail-closed — missing credentials/services can never convert into a green release), and **stabilized quality gates** (Biome 2.x `preset` config migration with zero lint diagnostics, the racy 150ms MCP bridge timing assert replaced by a deterministic barrier, load-sensitive guards carry documented `ponytail:` ceilings, machine-readable `lint-report.sarif` + `unused-report.json` retained by CI); no runtime contract delta (compat gate at 0.2.3: version literal only), no migration; then plan 022 the concurrent-state-and-durability-integrity cut: atomic model-budget reservation (`ModelRouterStateStore.reserveBudget`/`commitBudget`/`releaseBudget` with fencing tokens, `reservationTtlMs` expiry and unknown-usage reconciliation, rate/budget key-map caps with LRU eviction that never drops a held reservation), atomic conversation metadata (`SessionRecord.version` + `appendSession` `expectedVersion` CAS across Postgres/SQLite — create-only `0`, exact-version `N>0`, legacy last-write-wins when omitted; `SessionMetadataConflictError` `metadata_conflict` with versions only, HTTP 409; concurrent create/branch/archive single-statement with branch caps inside the CAS, archive wins, deleted rows never resurrect), single-consumer `EventMultiplexer` (`EventMultiplexerError` `ERR_PRISM_EVENT_MULTIPLEXER_SINGLE_CONSUMER` instead of silent queue sharing), restart-stable NATS durable consumer identity (`prism_<hmac16>` with no random suffix — crash-resumed subscribe continues from the last ack, orphaned 0.2.1 consumers reclaimed on clean stop), and bounded non-durable active-run registries (sweep + fail-closed 512 cap `ERR_PRISM_WORKFLOW_RUN_REGISTRY_OVERFLOW`); new regression surface `scripts/phase22-security.test.mjs` (4 blockers + gate accounting over built public entrypoints) + packed plain-JS `security22.mjs` consumer + the `@arnilo/prism/testing/state-concurrency-conformance` harness (7 probes across memory/Postgres/SQLite/NATS legs, no timing-only sleeps) + the `scripts/phase22-conformance.test.mjs` gate; additive-only compat (new exports only, no removals); forward-only migrations 008 (`prism_sessions.version`) and 003 (`prism_model_router_budgets.reservations`); migration `0.2.1 → 0.2.2`; then plan 021 the provider-completion-and-outbound-trust-boundaries cut: strict stream completion is the shared OpenAI-compatible default (truncated streams fail `incomplete_delta`, explicit `strictCompletion: false` opt-out), bounded success bodies via `readBoundedResponseJson` on all discovery/quota/embeddings/upload/OAuth JSON endpoints (65,536-byte ceiling, depth/property/shape caps), DNS-pinned OIDC JWKS/OPA/content fetches through the core `pinnedFetch` primitive with 3xx redirects rejected outright (private/metadata answers fail closed `ssrf_denied`), shared bounded OAuth device/token polling (`pollDeviceCodeToken`) across provider-openai and credentials-node, and the four edge fixes (Azure/Vertex credential-once, Bedrock duplicate-case/repeated-query SigV4 canonicalization, OpenAI upload failed-DELETE retention, cache `__overflow__` tokens-only); public-entrypoint threat-suite `scripts/phase21-security.test.mjs` + packed plain-JS consumer; additive-only compat (MCP transport helpers re-exported from core, no removals); migration `0.2.0 → 0.2.1`; then plan 020 the fail-closed runtime-and-sandbox-security cut on the 0.2.x review-remediation line: durable-resume decision validation in core (`assertValidAgentRunResume` — unknown decisions/malformed batches fail closed with `ERR_PRISM_DECISION_*` before any state claim, checkpoint write, or tool execution; server parser remains defense in depth), isolated work-tool subprocess environments (`@arnilo/prism-work-tools` — fixed base allow-list + explicit env + forced HOME/telemetry + late-bound per-identity tokens, 64-name/64-KiB caps, absolute binary/configDir, linear output capture), and explicit sandbox capabilities (`@arnilo/prism-coding-security` — `SandboxAdapter.capabilities` with omission-is-false fail-closed resolution, `SandboxCodingComposition.capabilities` from verified wiring, `containmentClaim` deprecated as the conservative projection; Docker reports only verified controls, native reports filesystem/process/privilege `false`); public-entrypoint security conformance (`scripts/phase20-security.test.mjs`, wired into `security:threat-suites`), packed plain-JS consumer regressions, and the sandbox-browser workflow's fail-loud Docker/native capability evidence gate — 0.2.0 never ships while a blocker is skipped; migration and rollback notes in `docs/migration.md` `0.1.7 → 0.2.0`, store-compatible with 0.1.7 in both directions; 0.1.7 was the performance-and-DX patch — dependency-free `createCacheTelemetry()` per-provider/model cache hit/miss aggregator (bounded cardinality with `__overflow__`, token counters/rates only, host-activated), host-configurable `ModelRouterSelectionPolicy` on `createModelRouter` with the reference `createCostLatencySelection` (ModelCost rank then in-memory latency EMA, default ordered behavior byte-identical), `prism providers add <name>` OpenAI-compatible provider scaffold (manifest/provider/models/cache/conformance test/docs stub, npm-name + traversal + symlink-escape validation, placeholders only), and the async `AgUiProjection` verification closeout (plan 009 Task 15 evidence recorded, no new code); plan 017 the documented breaking cut — deprecated-option removal with `docs/migration.md` `0.1.4 → 0.1.5` section and reviewed compat-baseline regeneration via `--allow-break` then `--update-baseline`: the inert provider request knobs, `RunOptions.maxToolRounds`, observational-memory flat settings keys + top-level worker aliases, `ReadToolOptions.autoResizeImages`, `INIT_PROVIDERS`; all removals fail closed naming their replacement; plan 016 internal god-module split — `agents.ts`/`contracts.ts` reorganized behind barrel re-exports with a byte-identical public entry surface, measured tree-shaking improvement in `scripts/phase16-baseline.json`, and additive `@arnilo/prism-browser` Chrome DevTools Protocol capabilities — `browser_evaluate`/`browser_observe` and `block_urls`/`unblock_urls`/`throttle`/`emulate` act actions; plan 015 dead-code and deprecation hygiene on the frozen 0.1.x line — parameterized benchmark runner `scripts/benchmark.mjs` absorbing the per-version runners, archived review-coverage evidence in `docs/_evidence/`, non-blocking unused-code sweep `npm run sweep:unused`, opt-in checkpoint persistence for loaded-skill names and read-path sets; plan 014 Alibaba provider enrichment — embeddings, video input, verified compatible-mode surface decision table; plan 013 post-release hardening — build single-flight, MCP SSE relay test, combined coverage summary, canonical manifest-count narrative, ACP modes/config persistence guidance; Phase 12 release-candidate hardening; plan 012 — freeze manifest, compatibility matrix, upgrade matrix, packed-install e2e journeys, restart-recovery evidence, capacity envelopes, security policy), exact-peer/install/tarball rules, deterministic resumable publication and publish dry-run, frozen 0.1.x compatibility and support matrix (Node/PostgreSQL/platform/provider/protocol pins and unsupported combinations, machine-checked against `scripts/phase12-freeze-manifest.json`), protected PostgreSQL gate, pinned supply-chain gates, offline tests, the 0.0.15 provider/AI-SDK/RAG/memory protected live-canary matrix, and sandbox-browser Docker/Playwright gates.
133
+ - [0.1.0 / 1.0 readiness gates](0.1.0-readiness.md): command-per-gate 1.0 readiness table — frozen API surface + compat gate, migration/docs tripwires, budget table, live-suite matrix, security matrix, current-line status (**0.2.5** current line; 0.1.7 terminal 0.1.x baseline), signed-publication/live-canary prerequisites for 1.0, and Phase 12 demand-evidence entry criteria.
134
134
  - [Review coverage archive](_evidence/): per-phase evidence freezes (plans 067–079, releases 0.0.4–0.0.16) — traceability matrices, provider validation, capability/primitive/limit matrices, benchmark budgets, and artifact-diet findings; tarball-excluded, kept in-repo for audit.
135
135
 
package/docs/migration.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Migration guide
2
2
 
3
+ ## 0.2.4 → 0.2.5 maintainability and bounded performance (no migration)
4
+
5
+ Release **0.2.5** (plan 025) is the maintainability-and-bounded-performance cut: the six remaining implementation god-modules split into cohesive internal family files behind preserved barrels (compat-preserving, no `exports`-map subpath), 21 pure persistence helpers moved into the dependency-free `session-store-codecs` package (ownership scope/assertion, checkpoint stale/encode/decode, branch cursors, lifecycle quota/reason/page-limit, search metadata/clipping, deepFreeze/string-array/throwIfAborted, feedback row mapping), the quadratic per-push `Buffer.concat` loops in language framing and tar parsing became chunk-array readers (linear; caps and fail-closed overflow byte-identical), two internal dead type aliases removed (`PostgresPersistenceCloseOptions`, `SqlitePersistenceCloseOptions` — never re-exported from their adapter indexes), and 76 behavior-backed coverage regressions closed the low-coverage core areas (core 91.43/84.80/91.60 lines/branches/functions). **No runtime contract change and no migration**: no exported declaration was removed or changed (the plain reviewed compat gate at 0.2.5 shows the version literal plus 105 additive internal-helper exports), no persisted shape/schema/default/behavior changed, no new runtime dependency. Store compatibility with 0.2.4: **compatible in both directions** — no migration step; rollback = restore the 0.2.4 manifests/tag (stores never change; the added exports disappear on downgrade). The 20 dead-but-compat-tracked exports deferred from Task 4 are the 0.3.0 breaking-cut removal list (see `docs/_evidence/phase25-dead-exports-triage.md`).
6
+
7
+ ## 0.2.3 → 0.2.4 package, documentation, and compatibility truth (plan 024)
8
+
9
+ Release **0.2.4** (plan 024) is the package-documentation-and-compatibility-truth cut: umbrella wording now states the manifest closures (`@arnilo/prism-providers` = 11 of 14 first-party provider adapters, omitting Azure/Bedrock/Vertex; `@arnilo/prism-all` = 20 direct / 43 transitive first-party packages with the named omission set), and `scripts/package-truth.json` (generated by `scripts/package-truth.mjs`) is the manifest-derived single source for counts, provider membership, umbrella closures, and profile closures. **Peer-version policy (Decision A — exact pins):** every code package peers the bare exact `@arnilo/prism@0.2.4` version (no range, no `*`); all `@arnilo/prism-*` packages move at the same version (**atomic-upgrade rule** — a partial upgrade fails clearly at install time with npm `ERESOLVE` naming the conflicting peer); the range widens to `^1.0.0` at the 1.x stable release; third-party `@arnilo/prism-*` adapters peer on the documented exact current version (full policy in the release-and-install Extension notes). **No runtime code path, persisted shape, event schema, default, or exported declaration changed** (the plain reviewed compat gate at 0.2.4 shows the version literal only). Store compatibility with 0.2.3: **compatible in both directions** — no migration step; rollback = restore the 0.2.3 manifests/tag.
10
+
3
11
  ## 0.2.2 → 0.2.3 build, coverage, and release evidence integrity (no migration)
4
12
 
5
13
  Release **0.2.3** (plan 023) is a **tooling-and-evidence-only cut**: build serialization (`scripts/with-build-lock.mjs` — one `O_EXCL` lockfile serializing every emit/test leaf so concurrent compilers never expose a partial live `dist/`), corrected workspace coverage denominators (package-local `--test-coverage-include=dist/**`, evidence-based per-package thresholds with `protectedException` durable-leg rows), the machine-auditable release skip manifest (`scripts/release-skip-manifest.mjs` → `scripts/release-evidence.json` with `pass`/`skip`/`blocked`/`protected` states; required surfaces without evidence record `blocked` and fail the release gate), and stabilized quality gates (Biome 2.x `preset` config migration with zero lint diagnostics, deterministic timing-assertion barriers, machine-readable `lint-report.sarif` + `unused-report.json`). **No runtime code path, persisted shape, event schema, default, or exported declaration changed** (the plain compat gate at 0.2.3 shows the version literal only). Store compatibility with 0.2.2: **compatible in both directions** — no migration step; rollback = restore the 0.2.2 manifests/tag (stores never change; rollback reopens only the partial-`dist` race and the polluted coverage denominator, both CI/tooling defects, never data defects).
@@ -2,9 +2,9 @@
2
2
 
3
3
  ## What it does
4
4
 
5
- Prism is published as **50 publishable manifests**: the root `@arnilo/prism` core package plus **49 workspace packages** — 14 provider adapters, 9 `prism-*` family/profile packages, and 26 capability packages. (Regenerate the counts: `ls packages/*/package.json | wc -l` = 49 workspace; `ls -d packages/provider-*/ | wc -l` = 14; `ls -d packages/prism-*/ | wc -l` = 9; capability = 49 − 14 − 9 = 26; publishable = root + 49 = 50.) The 50th manifest is the 0.1.6 plan 018 optional `@arnilo/prism-document-reader` package (bounded PDF/Office literal-text extraction for the coding read tool; ships only because its `doc-reader` closeout is demanded — a deferred closeout keeps the graph at 49). This page describes how they are packed, what each tarball contains, how to install them, the required `@arnilo/prism` peer dependency, the release workflow, and the offline test budget. The measurable 1.0 readiness gates (command-per-gate) live in [`0.1.0-readiness.md`](./0.1.0-readiness.md).
5
+ Prism is published as **50 publishable manifests**: the root `@arnilo/prism` core package plus **49 workspace packages** — 14 provider adapters, 9 `prism-*` family/profile packages, and 26 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 50th manifest is the 0.1.6 plan 018 optional `@arnilo/prism-document-reader` package (bounded PDF/Office literal-text extraction for the coding read tool; ships only because its `doc-reader` closeout is demanded — a deferred closeout keeps the graph at 49). This page describes how they are packed, what each tarball contains, how to install them, the required `@arnilo/prism` peer dependency, the release workflow, and the offline test budget. The measurable 1.0 readiness gates (command-per-gate) live in [`0.1.0-readiness.md`](./0.1.0-readiness.md).
6
6
 
7
- Core `@arnilo/prism` ships runtime, CLI, templates, and docs. Every code package has a required `@arnilo/prism@0.1.0` peer; profiles are pure manifests. Installation activates no provider, listener, database, browser, credential, or tool capability.
7
+ Core `@arnilo/prism` ships runtime, CLI, templates, and docs. Every code package has a required `@arnilo/prism@0.2.5` peer; profiles are pure manifests. Installation activates no provider, listener, database, browser, credential, or tool capability.
8
8
 
9
9
  Current **50** publishable manifests (root + 49 workspace packages):
10
10
 
@@ -31,12 +31,12 @@ Consumers install the core package for the runtime and add first-party packages
31
31
  | --- | --- |
32
32
  | Install core only | `npm install @arnilo/prism` |
33
33
  | Scaffold a minimal project | `npx --package @arnilo/prism prism init my-agent [--provider openai] [--with-workflows] [--with-evals]` |
34
- | Install core + all providers | `npm install @arnilo/prism @arnilo/prism-providers` |
34
+ | Install core + provider family (11 of 14) | `npm install @arnilo/prism @arnilo/prism-providers` |
35
35
  | Install minimal safe profile | `npm install @arnilo/prism-base` |
36
36
  | Install compaction strategies only | `npm install @arnilo/prism @arnilo/prism-compaction` |
37
37
  | Install coding-agent profile | `npm install @arnilo/prism-code @arnilo/prism-provider-openai` |
38
38
  | Install application SDK profile | `npm install @arnilo/prism-sdk @arnilo/prism-provider-openai @arnilo/prism-session-store-sqlite` |
39
- | Install everything | `npm install @arnilo/prism-all` |
39
+ | Install the broad umbrella | `npm install @arnilo/prism-all` |
40
40
  | Install core + a single provider | `npm install @arnilo/prism @arnilo/prism-provider-openai` |
41
41
  | 0.0.12 AG-UI (after release) | `npm install @arnilo/prism@0.0.12 @arnilo/prism-ag-ui@0.0.12` |
42
42
  | Install bounded web research tools | `npm install @arnilo/prism @arnilo/prism-web-tools @arnilo/prism-tool-validator-json-schema` |
@@ -94,7 +94,7 @@ A packed tarball contains only public compiled output and release files:
94
94
  - Code packages ship `README.md`, `LICENSE`, and `CHANGELOG.md`; family/profile packages ship `README.md` and `CHANGELOG.md`.
95
95
  - The core tarball additionally ships the full `docs/` directory (the docs hub) and `templates/init/` used by `prism init`.
96
96
  - `dist/cli.js` and the `bin` link in core.
97
- - **Tarball filenames.** npm strips the `@scope/` prefix, so the core package `@arnilo/prism` produces a tarball named `arnilo-prism-0.1.0.tgz`; first-party packages produce `arnilo-prism-provider-<name>-0.1.0.tgz` / `arnilo-prism-compaction-<name>-0.1.0.tgz` / `arnilo-prism-coding-agent-0.1.0.tgz`; family/profile packages produce `arnilo-prism-{providers,compaction,base,code,sdk,all}-0.1.0.tgz`. The CLI bin name `prism` is unaffected by the package name (`npx prism` still works; npm allows the bin field to differ from the package name).
97
+ - **Tarball filenames.** npm strips the `@scope/` prefix, so the core package `@arnilo/prism` produces a tarball named `arnilo-prism-0.2.5.tgz`; first-party packages produce `arnilo-prism-provider-<name>-0.2.5.tgz` / `arnilo-prism-compaction-<name>-0.2.5.tgz` / `arnilo-prism-coding-agent-0.2.5.tgz`; family/profile packages produce `arnilo-prism-{providers,compaction,base,code,sdk,all}-0.2.5.tgz`. The CLI bin name `prism` is unaffected by the package name (`npx prism` still works; npm allows the bin field to differ from the package name).
98
98
 
99
99
  Excluded from every tarball by `files` negation:
100
100
 
@@ -275,6 +275,57 @@ git push origin v0.1.2 # tag push triggers release.yml publish job (prove
275
275
 
276
276
  **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.
277
277
 
278
+ ### 0.2.4 publish handoff (plan 024 Task 6)
279
+
280
+ **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):
281
+
282
+ ```js
283
+ import { readFileSync } from "node:fs";
284
+ const truth = JSON.parse(readFileSync("scripts/package-truth.json", "utf8"));
285
+ console.log(truth.counts.publishable, truth.umbrella["prism-all"].closure); // 50 43
286
+ ```
287
+
288
+ (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).
289
+
290
+ ```bash
291
+ # Operator prerequisites recorded: clean tree at the v0.2.4 tag candidate, GPG key, npm OIDC publisher.
292
+ node scripts/release.mjs bump --from 0.2.3 --to 0.2.4 # already applied by Task 6; idempotent
293
+ npm test # core + workspace suites + all script gates (incl. phase24-truth)
294
+ npm run security:threat-suites # phase8-11 + phase20 + phase21 + phase22 + phase23 public-entry conformance
295
+ PRISM_TEST_POSTGRES_URL=postgres://postgres:prism@127.0.0.1:54329/prism_test npm run sdk:ready
296
+ node scripts/release.mjs gate --version 0.2.4 # plain reviewed gate at 0.2.4: version literal only, 0 breaking deltas
297
+ npm run pack:dry-run # twice; diff reports — deterministic
298
+ npm audit --audit-level=moderate
299
+ npm run release:check -- --version 0.2.4 --report /tmp/prism-0.2.4-preflight.json
300
+ npm run release:publish -- --version 0.2.4 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.2.4-dry-run.json
301
+ # run the dry-run twice and diff the reports: deterministic, byte-identical
302
+ ```
303
+
304
+ 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.
305
+
306
+ ### 0.2.5 publish handoff (plan 025 Task 6)
307
+
308
+ **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.
309
+
310
+ **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).
311
+
312
+ ```bash
313
+ # Operator prerequisites recorded: clean tree at the v0.2.5 tag candidate, GPG key, npm OIDC publisher.
314
+ node scripts/release.mjs bump --from 0.2.4 --to 0.2.5 # already applied by Task 6; idempotent
315
+ npm test # core + workspace suites + all script gates (incl. phase24-truth + phase25-bounded-accumulation)
316
+ npm run security:threat-suites # phase8-11 + phase20-24 public-entry conformance
317
+ PRISM_TEST_POSTGRES_URL=postgres://postgres:prism@127.0.0.1:54329/prism_test npm run test:postgres # incl. the cross-store conformance legs
318
+ PRISM_TEST_POSTGRES_URL=postgres://postgres:prism@127.0.0.1:54329/prism_test npm run sdk:ready
319
+ node scripts/release.mjs gate --version 0.2.5 # plain reviewed gate at 0.2.5: version literal + additive exports only, 0 breaking deltas
320
+ npm run pack:dry-run # twice; diff reports — deterministic
321
+ npm audit --audit-level=moderate
322
+ npm run release:check -- --version 0.2.5 --report /tmp/prism-0.2.5-preflight.json
323
+ npm run release:publish -- --version 0.2.5 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.2.5-dry-run.json
324
+ # run the dry-run twice and diff the reports: deterministic, byte-identical
325
+ ```
326
+
327
+ 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.
328
+
278
329
  ### 0.2.3 publish handoff (plan 023 Task 6)
279
330
 
280
331
  **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.)
@@ -695,8 +746,8 @@ Audit fixes, dependency updates, and security patches land only for the supporte
695
746
 
696
747
  ## Extension and configuration notes
697
748
 
698
- - **Required `@arnilo/prism` peer.** Every first-party code package declares a non-optional `@arnilo/prism@0.0.28` peer (`peerDependenciesMeta` must not mark `@arnilo/prism` optional; other peers such as `playwright-core` may be optional). The range stays pinned to `0.0.28` for the current 0.x release and will widen to `^1.0.0` at the 1.x stable release. Inside the workspace each package also declares `"@arnilo/prism": "file:../.."` in `devDependencies` so `npm install` resolves the peer locally; that devDependency is stripped from consumer installs and is not a runtime dependency.
699
- - **Public access.** All 49 manifests (root + 48 workspace packages: 42 code packages + 6 pure-manifest family/profile packages) declare `"publishConfig": { "access": "public" }`; the publisher also passes `--access public` explicitly because scoped packages otherwise default to restricted on first publish.
749
+ - **Required `@arnilo/prism` peer.** Every first-party code package declares a non-optional **exact** `@arnilo/prism@0.2.5` peer (`peerDependenciesMeta` must not mark `@arnilo/prism` optional; other peers such as `playwright-core` may be optional). **Peer-version policy (plan 024, Decision A — exact pins):** the peer spec is the bare exact current version — no `~`/`^`/`>=` range, no `*` — for the whole 0.2.x line, and all `@arnilo/prism-*` packages move at the same version (the **atomic-upgrade rule**). A partial upgrade (e.g. `@arnilo/prism@0.2.5` installed with a package peering `@arnilo/prism@0.2.6`) is unsupported and 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 together. A third-party `@arnilo/prism-*` adapter declares the same exact peer on the documented current version; an unsupported mixture fails at install time, not at runtime. The range widens to `^1.0.0` at the 1.x stable release (the 1.0 readiness gates go operator-green on the 0.2.x line); rollback of a release moves the pins back atomically with the manifests/tag. 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.
750
+ - **Public access.** All 50 manifests (root + 49 workspace packages: 43 code packages + 6 pure-manifest family/profile packages — the 9 `prism-*` family/profile set is the 6 pure-manifest profiles plus the 3 code packages `prism-caveman`, `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.
700
751
  - **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).
701
752
  - **Release workflow.** `.github/workflows/release.yml` has six jobs. `verify` runs network-free SDK readiness on Node 24; `node20-compat` builds/imports every public root `exports` default target on Node 20 for declared `engines.node >=20` (docs examples need Node >=22.6 native TypeScript stripping); `postgres-integration` uses `pgvector/pgvector:pg16`; `supply-chain` runs high-severity audit, SPDX/license policy, and tracked-source secret scanning; and tag-only `codeql-release` runs SAST. Tag-only `publish` needs all five gates, preserves clean exact-tag/version/topological publication, and alone receives `NPM_TOKEN`, `id-token: write`, and `attestations: write`. Before npm publish it packs all current tarballs, generates checksums plus SPDX, scans unpacked public artifacts, creates GitHub attestations for tarballs and SBOM, then retains artifacts for 30 days. Registry state remains the resumable journal. Local `npm run release:dry-run` remains network-free SDK readiness; local PostgreSQL coverage is `PRISM_TEST_POSTGRES_URL=... npm run test:postgres`.
702
753
  - **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.
@@ -870,7 +921,7 @@ Every release gate maps to an exact enforcement test or command, so the checklis
870
921
  | 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`. |
871
922
  | 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. |
872
923
  | Examples run to completion with no secret leakage | `docs.test.ts` `examples_demos_run_to_completion_and_emit_no_secret` runs each demo (Node strips TypeScript types natively) with exit-0 and real-secret scans; `external_app_example_*` pins the DB-backed adapter reference exercising the `RunLedger`, branch-handle checkout, fork, and prior-run resume. |
873
- | Tarball excludes built tests, source maps, and source | `packaging.test.ts` rejects `dist/__tests__/`, `*.map`, `src/`, `plans/`, and internal files; confirms every package ships README/changelog (and code packages ship LICENSE), core ships docs + CLI, and every export target exists. `prism-all` reaches every current publishable package except the deliberate Caveman/Ponytail opt-outs. |
924
+ | Tarball excludes built tests, source maps, and source | `packaging.test.ts` rejects `dist/__tests__/`, `*.map`, `src/`, `plans/`, and internal files; confirms every package ships README/changelog (and code packages ship LICENSE), core ships docs + CLI, and every export target exists. `prism-all` reaches 43 of the 49 workspace packages (20 direct + 23 transitive); the deliberate Caveman/Ponytail opt-outs and the other non-closure packages (document-reader, OpenAPI tools, NATS) are not in its install set. |
874
925
  | NeuralWatt package/docs/examples release gate | `packaging.test.ts` pins `@arnilo/prism-provider-neuralwatt` package exports/type declarations and `@arnilo/prism-providers`/`@arnilo/prism-all` membership; `docs.test.ts` asserts `docs/index.md` links `providers/neuralwatt.md` and `provider-caching.md`, and that `examples/cache-aware-prompt-assembly.ts` plus `examples/neuralwatt-agent-run.ts` exist and are listed. |
875
926
  | Enterprise PostgreSQL package/docs/example gate | Packaging/install/public-contract tests include `@arnilo/prism-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. |
876
927
  | 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. |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arnilo/prism",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "description": "Agent harness for AI providers, agents, sessions, and tools.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -147,7 +147,7 @@
147
147
  "build": "npm run build:core && npm run build --workspaces --if-present",
148
148
  "typecheck": "npm run build && npm run typecheck --workspaces --if-present && tsc -p examples --noEmit",
149
149
  "sweep:unused": "node scripts/sweep-unused.mjs --json",
150
- "test": "npm run build && node scripts/with-build-lock.mjs node --test dist/__tests__/*.test.js && node scripts/with-build-lock.mjs node --test scripts/release-gate.test.mjs scripts/tooling-gate.test.mjs scripts/budget-gate.test.mjs scripts/phase8-conformance.test.mjs scripts/phase9-conformance.test.mjs scripts/phase10-conformance.test.mjs scripts/phase11-conformance.test.mjs scripts/phase11-freeze.test.mjs scripts/phase12-freeze.test.mjs scripts/phase13-freeze.test.mjs scripts/phase14-freeze.test.mjs scripts/phase15-freeze.test.mjs scripts/phase16-freeze.test.mjs scripts/phase17-freeze.test.mjs scripts/phase18-freeze.test.mjs scripts/phase19-freeze.test.mjs scripts/phase20-freeze.test.mjs scripts/phase21-freeze.test.mjs scripts/benchmark-0.1.0.test.mjs scripts/sweep-unused.test.mjs scripts/e2e-enterprise-journey.test.mjs scripts/e2e-coding-journey.test.mjs scripts/phase23-quality-gates.test.mjs && node --test scripts/phase23-build-race.test.mjs && npm run test --workspaces --if-present",
150
+ "test": "npm run build && node scripts/with-build-lock.mjs node --test dist/__tests__/*.test.js && node scripts/with-build-lock.mjs node --test scripts/release-gate.test.mjs scripts/tooling-gate.test.mjs scripts/budget-gate.test.mjs scripts/phase8-conformance.test.mjs scripts/phase9-conformance.test.mjs scripts/phase10-conformance.test.mjs scripts/phase11-conformance.test.mjs scripts/phase11-freeze.test.mjs scripts/phase12-freeze.test.mjs scripts/phase13-freeze.test.mjs scripts/phase14-freeze.test.mjs scripts/phase15-freeze.test.mjs scripts/phase16-freeze.test.mjs scripts/phase17-freeze.test.mjs scripts/phase18-freeze.test.mjs scripts/phase19-freeze.test.mjs scripts/phase20-freeze.test.mjs scripts/phase21-freeze.test.mjs scripts/benchmark-0.1.0.test.mjs scripts/sweep-unused.test.mjs scripts/e2e-enterprise-journey.test.mjs scripts/e2e-coding-journey.test.mjs scripts/phase23-quality-gates.test.mjs scripts/phase24-truth.test.mjs scripts/phase25-bounded-accumulation.test.mjs && node --test scripts/phase23-build-race.test.mjs && npm run test --workspaces --if-present",
151
151
  "test:coverage": "node scripts/with-build-lock.mjs node --test --experimental-test-coverage --test-coverage-lines=60 --test-coverage-functions=70 --test-coverage-branches=75 --test-coverage-exclude='**/__tests__/**' --test-coverage-exclude='**/node_modules/**' --test-coverage-exclude='**/scripts/**' --test-coverage-exclude='**/packages/**' --test-coverage-exclude='**/examples/**' dist/__tests__/*.test.js && node scripts/with-build-lock.mjs node scripts/coverage-summary.mjs && node --test scripts/phase23-coverage.test.mjs && node --test scripts/phase23-skip-manifest.test.mjs",
152
152
  "coverage:summary": "node scripts/with-build-lock.mjs node scripts/coverage-summary.mjs",
153
153
  "lint": "biome lint . --reporter=sarif --reporter-file=scripts/lint-report.sarif",