@arnilo/prism 0.0.25 → 0.0.27

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.
@@ -0,0 +1,147 @@
1
+ # Process sessions
2
+
3
+ ## What it does
4
+
5
+ `createProcessSessions` is an optional host-activated registry in `@arnilo/prism-coding-agent` for **long-running** child processes: start, cursor-paged output, input, wait, signal/kill, and release (detach). Sessions have bounded lifetime (sweep on registry access — no import-time timers), ownership/identity attribution, durable metadata (command fingerprint without env/secrets), and typed `CodingProcessEvent`s via a host callback. Reuses `ExecutionPolicy`, `killProcessTree`, and `OutputAccumulator` (including spill + `readRaw` cursor paging). Optional duck-typed `sandbox` backend uses `startProcess` when present; one-shot adapters fail closed. Nothing spawns on import or construction.
6
+
7
+ | Export | Purpose |
8
+ | --- | --- |
9
+ | `createProcessSessions(options)` | Build a `ProcessSessions` registry bound to one workspace `cwd`. |
10
+ | `ProcessSessions` | `start`, `get`, `cancelOwned`, `markUnknown`, `reconcile`, `dispose`. |
11
+ | `ProcessSession` | Handle: `output` / `input` / `wait` / `signal` / `kill` / `release` / `metadata`. |
12
+ | `ProcessSessionState` | `starting` \| `running` \| `exited` \| `killed` \| `released` \| `expired` \| `unknown`. |
13
+ | `ProcessSandboxBackend` | Duck-typed optional sandbox (`startProcess?`, `status?`); mirrors coding-security `SandboxProcessHandle`. |
14
+ | `CodingProcessEvent` | Host-sink events (`process_started` / `_exited` / `_killed` / `_released` / `_expired` / `_unknown`). |
15
+ | `ProcessSessionError` | Typed fail-closed errors (`ERR_PRISM_PROCESS_*`). |
16
+ | `resolveProcessSessionLimits` / `DEFAULT_MAX_PROCESS_*` / `HARD_MAX_PROCESS_*` | Session count, input bytes, lifetime, chunk/total output caps. |
17
+
18
+ ## When to use it
19
+
20
+ Use when a host needs attachable long-running processes (watch modes, language servers, interactive CLIs) that one-shot `shell` cannot model. Do not use as a job-control language or PTY emulator — `pty: true` fails closed with `ERR_PRISM_PROCESS_PTY_UNSUPPORTED` until a platform capability is wired. Pass a sandbox with `startProcess` for contained long-running work; omit `sandbox` for native spawn.
21
+
22
+ ```ts
23
+ import { createProcessSessions } from "@arnilo/prism-coding-agent";
24
+
25
+ const sessions = createProcessSessions({ cwd: workspaceRoot, policy, sandbox, onEvent });
26
+ const p = await sessions.start({ command: "npm", args: ["test", "--", "--watch"] });
27
+ const out = await p.output({ cursor: 0, maxBytes: 8192 });
28
+ await p.input("q\n");
29
+ await p.wait({ timeoutMs: 5000 });
30
+ await sessions.dispose();
31
+ ```
32
+
33
+ ## Inputs / request
34
+
35
+ `createProcessSessions` options:
36
+
37
+ | Field | Type | Purpose |
38
+ | --- | --- | --- |
39
+ | `cwd` | `string` | Workspace root; session `cwd` must stay inside. |
40
+ | `policy?` | `ExecutionPolicy` | Gated before spawn and rechecked on input/signal/kill. |
41
+ | `limits?` | `ProcessSessionLimits` | Optional overrides; invalid values fail instead of clamping. |
42
+ | `onEvent?` | `(CodingProcessEvent) => void` | Host-owned sink (core `AgentEvent` unchanged); audit owner + terminal/unknown. |
43
+ | `ownership?` | `OwnershipScope` | Default owner key for sessions. |
44
+ | `identity?` | `AgentIdentity` | When ownership omitted, owner key projects from identity. |
45
+ | `sandbox?` | `ProcessSandboxBackend` | When set: require `startProcess` or fail closed; `status` loss → all running → `unknown`. |
46
+
47
+ `ProcessStartRequest`:
48
+
49
+ | Field | Purpose |
50
+ | --- | --- |
51
+ | `command` / `args?` | Executable + argv (not a shell string). |
52
+ | `cwd?` | Relative/absolute path contained under registry `cwd`. |
53
+ | `env?` | Extra env merged onto `process.env` (never in fingerprint). |
54
+ | `pty?` | Default false; unsupported → `ERR_PRISM_PROCESS_PTY_UNSUPPORTED`. |
55
+ | `lifetimeMs?` | Bounded by `maxLifetimeMs`. |
56
+ | `owner?` | Override owner string. |
57
+ | `releaseOnCancel?` | If true, `cancelOwned` releases instead of killing. |
58
+
59
+ ## Outputs / response / events
60
+
61
+ | Method | Result |
62
+ | --- | --- |
63
+ | `start` | `ProcessSession` in `running`; emits `process_started`. |
64
+ | `output({ cursor, maxBytes })` | `{ data, cursor, eof }` UTF-8 page from byte cursor. |
65
+ | `input` | Writes stdin; capped by `maxInputBytes`; fails if not running / stdin closed. |
66
+ | `wait` | `{ exitCode, state }` — `exitCode` is `null` for killed/released/expired/unknown. |
67
+ | `signal` / `kill` / `release` | Soft signal, hard kill, or detach (no re-attach). |
68
+ | `cancelOwned(owner)` | Kill (default) or release owned running sessions. |
69
+ | `markUnknown` | Backend-loss terminal state; never fabricates `exitCode`. |
70
+ | `reconcile()` | Host resume: mark every running/starting session `unknown` (O(sessions)). |
71
+
72
+ Events: `process_started`, `process_exited`, `process_killed`, `process_released`, `process_expired`, `process_unknown`.
73
+
74
+ Errors: `ERR_PRISM_PROCESS_POLICY`, `ERR_PRISM_PROCESS_OWNERSHIP`, `ERR_PRISM_PROCESS_STATE`, `ERR_PRISM_PROCESS_LIMIT`, `ERR_PRISM_PROCESS_PTY_UNSUPPORTED`, `ERR_PRISM_PROCESS_UNSUPPORTED`.
75
+
76
+ ## Request/response example
77
+
78
+ ```json
79
+ {
80
+ "command": "npm",
81
+ "args": ["test", "--", "--watch"],
82
+ "lifetimeMs": 14400000,
83
+ "releaseOnCancel": false
84
+ }
85
+ ```
86
+
87
+ ## Implementation example
88
+
89
+ ```ts
90
+ const sessions = createProcessSessions({
91
+ cwd: workspaceRoot,
92
+ ownership: { tenantId: "t1", userId: "u1" },
93
+ sandbox, // DisposableSandbox with startProcess, or omit for native
94
+ limits: { maxSessions: 8 },
95
+ onEvent: (e) => audit.write(e),
96
+ policy: hostExecutionPolicy,
97
+ });
98
+
99
+ const p = await sessions.start({
100
+ command: process.execPath,
101
+ args: ["server.js"],
102
+ lifetimeMs: 3_600_000,
103
+ });
104
+
105
+ let cursor = 0;
106
+ for (;;) {
107
+ const chunk = await p.output({ cursor, maxBytes: 50_000 });
108
+ cursor = chunk.cursor;
109
+ if (chunk.eof) break;
110
+ }
111
+
112
+ await sessions.cancelOwned(p.owner); // run cancellation
113
+ await sessions.dispose();
114
+ ```
115
+
116
+ ## Extension and configuration notes
117
+
118
+ - Native when `sandbox` omitted; with `sandbox`, capability is `typeof startProcess === "function"` (never assumed).
119
+ - One-shot sandbox (no `startProcess`) → `ERR_PRISM_PROCESS_UNSUPPORTED` (no native fallback).
120
+ - Sandbox `status` not `running` (or throws) → all live sessions → `unknown`; further `start` fails closed.
121
+ - Host restart: call `reconcile()` on a new registry for in-memory orphans, or listen for `process_unknown` and wire Phase 7 `ToolEffectStore.markUnknown` in the host.
122
+ - Expiry sweep runs on registry/handle access — no timers at import.
123
+ - Command fingerprint is SHA-256 of `[command, ...args]` only (no env).
124
+ - Docker reference adapter does not implement `startProcess` yet — fail closed until a capable runtime is wired.
125
+
126
+ ## Security and performance notes
127
+
128
+ | Cap | Default | Hard |
129
+ | --- | ---: | ---: |
130
+ | Sessions per registry | 8 | 32 |
131
+ | Input write bytes | 64 KiB | 1 MiB |
132
+ | Session lifetime | 4 h | 24 h |
133
+ | Output chunk | 50 KiB | 1 MiB |
134
+ | Total output / session | 64 MiB | 1 GiB |
135
+
136
+ - Wrong-owner `get(id, owner)` → `ERR_PRISM_PROCESS_OWNERSHIP`.
137
+ - Released sessions reject all further handle ops.
138
+ - `cwd` outside workspace → `ERR_PRISM_PROCESS_POLICY`.
139
+ - Policy denial before spawn / on mutate → `ERR_PRISM_PROCESS_POLICY`.
140
+ - Unknown outcome never invents an exit code.
141
+
142
+ ## Related APIs
143
+
144
+ - [Coding agent tools](coding-agent-tools.md): one-shot `shell` vs long-running sessions.
145
+ - [Language intelligence](language-intelligence.md): LSP servers may later register as managed sessions.
146
+ - [Coding security](coding-security.md): `SandboxProcessHandle` / optional `DisposableSandbox.startProcess`.
147
+ - [Tool effects](tool-effects.md): unknown-outcome vocabulary mirrored by `markUnknown` / `process_unknown` / `reconcile`.
@@ -2,11 +2,11 @@
2
2
 
3
3
  ## What it does
4
4
 
5
- Prism is published as one core package, forty first-party capability packages, and six pure-manifest family/profile packages (**47** publishable manifests total). This page describes how they are packed, what each tarball contains, how to install them, the required `@arnilo/prism` peer dependency, the release workflow, and the offline test budget. The measurable 1.0 readiness gates (command-per-gate) live in [`0.1.0-readiness.md`](./0.1.0-readiness.md).
5
+ Prism is published as one core package, forty-one first-party capability packages, and six pure-manifest family/profile packages (**48** publishable manifests total). This page describes how they are packed, what each tarball contains, how to install them, the required `@arnilo/prism` peer dependency, the release workflow, and the offline test budget. The measurable 1.0 readiness gates (command-per-gate) live in [`0.1.0-readiness.md`](./0.1.0-readiness.md).
6
6
 
7
- Core `@arnilo/prism` ships runtime, CLI, templates, and docs. Every code package has a required `@arnilo/prism@0.0.25` 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.0.27` peer; profiles are pure manifests. Installation activates no provider, listener, database, browser, credential, or tool capability.
8
8
 
9
- Current **47** publishable manifests:
9
+ Current **48** publishable manifests:
10
10
 
11
11
  `@arnilo/prism`, `@arnilo/prism-ag-ui`, `@arnilo/prism-browser`, `@arnilo/prism-coding-agent`, `@arnilo/prism-coding-security`, `@arnilo/prism-compaction-llm`
12
12
  `@arnilo/prism-compaction-observational-memory`, `@arnilo/prism-credentials-node`, `@arnilo/prism-enterprise-postgres`, `@arnilo/prism-evals`, `@arnilo/prism-mcp`, `@arnilo/prism-memory`
@@ -14,7 +14,7 @@ Current **47** publishable manifests:
14
14
  `@arnilo/prism-code`, `@arnilo/prism-compaction`, `@arnilo/prism-ponytail`, `@arnilo/prism-providers`, `@arnilo/prism-sdk`, `@arnilo/prism-provider-ai-sdk`
15
15
  `@arnilo/prism-provider-alibaba`, `@arnilo/prism-provider-anthropic`, `@arnilo/prism-provider-azure`, `@arnilo/prism-provider-bedrock`, `@arnilo/prism-provider-google`, `@arnilo/prism-provider-kimi`
16
16
  `@arnilo/prism-provider-neuralwatt`, `@arnilo/prism-provider-ollama`, `@arnilo/prism-provider-openai`, `@arnilo/prism-provider-opencode-go`, `@arnilo/prism-provider-openrouter`, `@arnilo/prism-provider-vertex`
17
- `@arnilo/prism-provider-zai`, `@arnilo/prism-rag`, `@arnilo/prism-server`, `@arnilo/prism-session-store-codecs`, `@arnilo/prism-session-store-postgres`, `@arnilo/prism-session-store-sqlite`
17
+ `@arnilo/prism-provider-zai`, `@arnilo/prism-rag`, `@arnilo/prism-server`, `@arnilo/prism-session-store-codecs`, `@arnilo/prism-session-store-nats`, `@arnilo/prism-session-store-postgres`, `@arnilo/prism-session-store-sqlite`
18
18
  `@arnilo/prism-supervisor`, `@arnilo/prism-tool-validator-json-schema`, `@arnilo/prism-web-tools`, `@arnilo/prism-work-tools`, `@arnilo/prism-workflows`
19
19
 
20
20
  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` includes all eleven `@arnilo/prism-provider-*` packages.
@@ -45,9 +45,9 @@ Consumers install the core package for the runtime and add first-party packages
45
45
  | Run the default (network-free) test suite | `npm test` |
46
46
  | Dry-run pack core + every package | `npm run pack:dry-run` |
47
47
  | Local mirror of the release verify gate | `npm run release:dry-run` |
48
- | Validate clean tag/version/ranges and reject registry collisions | `npm run release:check -- --version 0.0.25` |
49
- | Preview deterministic publish order | `npm run release:publish -- --version 0.0.25 --dry-run --allow-dirty --allow-untagged` |
50
- | Resume interrupted tagged publication | `npm run release:publish -- --version 0.0.25 --resume --report release-artifacts/publish-report.json` |
48
+ | Validate clean tag/version/ranges and reject registry collisions | `npm run release:check -- --version 0.0.27` |
49
+ | Preview deterministic publish order | `npm run release:publish -- --version 0.0.27 --dry-run --allow-dirty --allow-untagged` |
50
+ | Resume interrupted tagged publication | `npm run release:publish -- --version 0.0.27 --resume --report release-artifacts/publish-report.json` |
51
51
  | Protected PostgreSQL enterprise suite | `PRISM_TEST_POSTGRES_URL="$DATABASE_URL" npm run test:postgres` |
52
52
  | Full SDK readiness gate (typecheck + offline tests + pack) | `npm run sdk:ready` |
53
53
 
@@ -87,7 +87,7 @@ A packed tarball contains only public compiled output and release files:
87
87
  - Code packages ship `README.md`, `LICENSE`, and `CHANGELOG.md`; family/profile packages ship `README.md` and `CHANGELOG.md`.
88
88
  - The core tarball additionally ships the full `docs/` directory (the docs hub) and `templates/init/` used by `prism init`.
89
89
  - `dist/cli.js` and the `bin` link in core.
90
- - **Tarball filenames.** npm strips the `@scope/` prefix, so the core package `@arnilo/prism` produces a tarball named `arnilo-prism-0.0.25.tgz`; first-party packages produce `arnilo-prism-provider-<name>-0.0.25.tgz` / `arnilo-prism-compaction-<name>-0.0.25.tgz` / `arnilo-prism-coding-agent-0.0.25.tgz`; family/profile packages produce `arnilo-prism-{providers,compaction,base,code,sdk,all}-0.0.25.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).
90
+ - **Tarball filenames.** npm strips the `@scope/` prefix, so the core package `@arnilo/prism` produces a tarball named `arnilo-prism-0.0.27.tgz`; first-party packages produce `arnilo-prism-provider-<name>-0.0.27.tgz` / `arnilo-prism-compaction-<name>-0.0.27.tgz` / `arnilo-prism-coding-agent-0.0.27.tgz`; family/profile packages produce `arnilo-prism-{providers,compaction,base,code,sdk,all}-0.0.27.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).
91
91
 
92
92
  Excluded from every tarball by `files` negation:
93
93
 
@@ -106,9 +106,9 @@ Excluded from every tarball by `files` negation:
106
106
  "name": "host-app",
107
107
  "type": "module",
108
108
  "dependencies": {
109
- "@arnilo/prism": "0.0.25",
110
- "@arnilo/prism-enterprise-postgres": "0.0.25",
111
- "@arnilo/prism-provider-openai": "0.0.25"
109
+ "@arnilo/prism": "0.0.27",
110
+ "@arnilo/prism-enterprise-postgres": "0.0.27",
111
+ "@arnilo/prism-provider-openai": "0.0.27"
112
112
  }
113
113
  }
114
114
  ```
@@ -151,11 +151,11 @@ For SDK readiness, run the same one-command gate directly. It composes existing
151
151
  npm run sdk:ready
152
152
  ```
153
153
 
154
- Release publication derives all **47** manifests from the workspace once, validates exact `0.0.25` manifest/lockfile/internal ranges, then uses deterministic dependency order. `release:check` requires a clean commit tagged `v0.0.25` and rejects any existing registry version. `release:publish --resume` skips only registry versions whose internal dependency fingerprint matches the local manifest; conflicting versions fail closed. Each attempted package is written immediately to the JSON report, so a failed job can rerun safely. `--dry-run` performs registry availability checks and invokes `npm publish --dry-run` with explicit public access, provenance, and `latest` tag, but does not publish.
154
+ Release publication derives all **48** manifests from the workspace once, validates exact `0.0.27` manifest/lockfile/internal ranges, then uses deterministic dependency order. `release:check` requires a clean commit tagged `v0.0.27` and rejects any existing registry version. `release:publish --resume` skips only registry versions whose internal dependency fingerprint matches the local manifest; conflicting versions fail closed. Each attempted package is written immediately to the JSON report, so a failed job can rerun safely. `--dry-run` performs registry availability checks and invokes `npm publish --dry-run` with explicit public access, provenance, and `latest` tag, but does not publish.
155
155
 
156
156
  ```bash
157
- npm run release:check -- --version 0.0.25
158
- npm run release:publish -- --version 0.0.25 --dry-run --allow-dirty --allow-untagged
157
+ npm run release:check -- --version 0.0.27
158
+ npm run release:publish -- --version 0.0.27 --dry-run --allow-dirty --allow-untagged
159
159
  ```
160
160
 
161
161
  `--allow-dirty` and `--allow-untagged` exist only for local preview; real publication and CI never pass them. npm registry calls occur only in these release preflight/publication commands, never build/test/package discovery.
@@ -166,25 +166,29 @@ Optional live smoke tests stay separate from SDK readiness because they require
166
166
  PRISM_LIVE_PROVIDER_TESTS=1 npm run test --workspaces --if-present
167
167
  ```
168
168
 
169
- ### 0.0.25 publish handoff
169
+ ### GitHub Actions pipeline (0.0.27+)
170
170
 
171
- **Decision: GO after protected operator prerequisites below.** Release **0.0.25** (Phase 8, plan 008) ships durable custom-loop snapshot/restore, shared pending-decision / sticky HITL, nested supervisor attributions, protocol batch resume, opt-in A2UI painting, and standard AG-UI projectors. Publishable graph stays **47** manifests. See [migration](migration.md) `0.0.24 → 0.0.25`, [agent loops](agent-loops.md), and [AG-UI](ag-ui.md).
171
+ `.github/workflows/release.yml` is the single pipeline: **push to `main`** runs CI (`verify` = `npm run sdk:ready`, `node20-compat`, `postgres-integration`, `supply-chain`), **push of a `v*` tag** additionally runs `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.27 && git push origin v0.0.27`) so the tag creation event fires.
172
+
173
+ ### 0.0.27 publish handoff
174
+
175
+ **Decision: GO after protected operator prerequisites below.** Release **0.0.27** (Phase 10, plan 010) ships complete ACP coding-host interop in `@arnilo/prism-ag-ui/acp`: seam-based capability advertisement, session persistence, modes/config overlays, client fs/terminal adapters, MCP select gate, `CodingLifecycleEvent` → ACP update mapping, four-outcome approvals with elicitation, and frozen caps. Publishable graph stays **48** manifests. See [migration](migration.md) `0.0.26 → 0.0.27` and [ACP coding-host interop](acp.md).
172
176
 
173
177
  ```bash
174
178
  git diff --check
175
179
  npm ci
176
180
  npm run sdk:ready
177
- node --test scripts/phase8-conformance.test.mjs
178
- node scripts/benchmark-0.0.25.mjs > scripts/benchmark-0.0.25.json
181
+ node --test scripts/phase10-conformance.test.mjs
182
+ node scripts/benchmark-0.0.27.mjs > scripts/benchmark-0.0.27.json
179
183
  node --test scripts/budget-gate.test.mjs scripts/tooling-gate.test.mjs
180
184
  node scripts/scan-secrets.mjs && node scripts/verify-sbom.mjs
181
185
  npm audit --audit-level=moderate
182
- npm run release:gate -- --version 0.0.25 --allow-break --allow-dirty --allow-untagged
183
- npm run release:check -- --version 0.0.25 --allow-dirty --allow-untagged --report /tmp/prism-0.0.25-preflight.json
184
- npm run release:publish -- --version 0.0.25 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.0.25-dry-run.json
185
- git tag -s v0.0.25 -m "Prism 0.0.25"
186
- git verify-tag v0.0.25
187
- git push origin v0.0.25
186
+ npm run release:gate -- --version 0.0.27 --allow-break --allow-dirty --allow-untagged
187
+ npm run release:check -- --version 0.0.27 --allow-dirty --allow-untagged --report /tmp/prism-0.0.27-preflight.json
188
+ npm run release:publish -- --version 0.0.27 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.0.27-dry-run.json
189
+ git tag -s v0.0.27 -m "Prism 0.0.27"
190
+ git verify-tag v0.0.27
191
+ git push origin v0.0.27
188
192
  ```
189
193
 
190
194
  ### 0.0.24 publish handoff
@@ -284,8 +288,8 @@ Older 0.0.10–0.0.15 handoffs are summarized in [migration](migration.md); hist
284
288
 
285
289
  ## Extension and configuration notes
286
290
 
287
- - **Required `@arnilo/prism` peer.** Every first-party code package declares a non-optional `@arnilo/prism@0.0.25` peer (`peerDependenciesMeta` must not mark `@arnilo/prism` optional; other peers such as `playwright-core` may be optional). The range stays pinned to `0.0.25` 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.
288
- - **Public access.** All 47 manifests (41 code packages + 6 family/profile packages) declare `"publishConfig": { "access": "public" }`; the publisher also passes `--access public` explicitly because scoped packages otherwise default to restricted on first publish.
291
+ - **Required `@arnilo/prism` peer.** Every first-party code package declares a non-optional `@arnilo/prism@0.0.27` peer (`peerDependenciesMeta` must not mark `@arnilo/prism` optional; other peers such as `playwright-core` may be optional). The range stays pinned to `0.0.27` 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.
292
+ - **Public access.** All 48 manifests (42 code packages + 6 family/profile packages) declare `"publishConfig": { "access": "public" }`; the publisher also passes `--access public` explicitly because scoped packages otherwise default to restricted on first publish.
289
293
  - **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).
290
294
  - **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`.
291
295
  - **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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arnilo/prism",
3
- "version": "0.0.25",
3
+ "version": "0.0.27",
4
4
  "description": "Agent harness for AI providers, agents, sessions, and tools.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -141,8 +141,8 @@
141
141
  "clean": "rm -rf dist packages/*/dist",
142
142
  "build": "npm run clean && npm run build:core && npm run build --workspaces --if-present",
143
143
  "typecheck": "npm run build && npm run typecheck --workspaces --if-present && tsc -p examples --noEmit",
144
- "test": "npm run build && node --test dist/__tests__/*.test.js && node --test scripts/release-gate.test.mjs scripts/tooling-gate.test.mjs scripts/budget-gate.test.mjs scripts/phase8-conformance.test.mjs && npm run test --workspaces --if-present",
145
- "test:coverage": "node --test --experimental-test-coverage --test-coverage-lines=60 --test-coverage-functions=70 --test-coverage-branches=75 --test-coverage-exclude='**/__tests__/**' --test-coverage-exclude='**/node_modules/**' --test-coverage-exclude='**/scripts/**' dist/__tests__/*.test.js",
144
+ "test": "npm run build && node --test dist/__tests__/*.test.js && node --test scripts/release-gate.test.mjs scripts/tooling-gate.test.mjs scripts/budget-gate.test.mjs scripts/phase8-conformance.test.mjs scripts/phase9-conformance.test.mjs scripts/phase10-conformance.test.mjs && npm run test --workspaces --if-present",
145
+ "test:coverage": "node --test --experimental-test-coverage --test-coverage-lines=60 --test-coverage-functions=70 --test-coverage-branches=75 --test-coverage-exclude='**/__tests__/**' --test-coverage-exclude='**/node_modules/**' --test-coverage-exclude='**/scripts/**' --test-coverage-exclude='**/packages/**' --test-coverage-exclude='**/examples/**' dist/__tests__/*.test.js",
146
146
  "lint": "biome lint .",
147
147
  "format": "biome format --write .",
148
148
  "format:check": "biome format .",