@arnilo/prism 0.2.7 → 0.2.9

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 (58) hide show
  1. package/CHANGELOG.md +11 -1
  2. package/README.md +6 -3
  3. package/dist/agent-loops.js +4 -0
  4. package/dist/agent-run-lifecycle.js +2 -2
  5. package/dist/agent-session/helpers.d.ts +1 -1
  6. package/dist/agent-session/helpers.js +2 -1
  7. package/dist/agent-session/session.d.ts +1 -1
  8. package/dist/agent-session/session.js +28 -20
  9. package/dist/agent-session.d.ts +1 -1
  10. package/dist/agent-session.js +1 -1
  11. package/dist/agents.d.ts +1 -1
  12. package/dist/agents.js +1 -1
  13. package/dist/contracts-core/agent.d.ts +5 -5
  14. package/dist/contracts-core/agent.js +2 -0
  15. package/dist/contracts-core/extensions.d.ts +3 -3
  16. package/dist/contracts-core/extensions.js +2 -0
  17. package/dist/contracts-core/loop.d.ts +6 -1
  18. package/dist/contracts-core/session.d.ts +1 -1
  19. package/dist/contracts-core.d.ts +6 -6
  20. package/dist/contracts-core.js +6 -6
  21. package/dist/contracts-protocol.d.ts +8 -2
  22. package/dist/contracts.d.ts +1 -1
  23. package/dist/contracts.js +1 -1
  24. package/dist/index.d.ts +6 -6
  25. package/dist/index.js +5 -5
  26. package/dist/input.js +1 -1
  27. package/dist/oauth-device-code.d.ts +5 -0
  28. package/dist/oauth-device-code.js +38 -14
  29. package/dist/tools.d.ts +1 -1
  30. package/dist/tools.js +1 -1
  31. package/docs/0.1.0-readiness.md +7 -7
  32. package/docs/acp-agent.md +78 -0
  33. package/docs/acp.md +21 -10
  34. package/docs/ag-ui.md +1 -1
  35. package/docs/agent-definitions.md +1 -1
  36. package/docs/agent-events.md +2 -2
  37. package/docs/agent-loops.md +2 -2
  38. package/docs/caveman.md +3 -2
  39. package/docs/coding-agent-tools.md +3 -1
  40. package/docs/coding-security.md +6 -0
  41. package/docs/context-and-skills.md +2 -2
  42. package/docs/credential-storage.md +1 -1
  43. package/docs/credentials-and-redaction.md +2 -2
  44. package/docs/extensions.md +1 -0
  45. package/docs/impeccable.md +102 -0
  46. package/docs/index.md +6 -4
  47. package/docs/migration.md +25 -0
  48. package/docs/ponytail.md +2 -2
  49. package/docs/provider-caching.md +6 -0
  50. package/docs/provider-packages.md +19 -6
  51. package/docs/providers/clinepass.md +120 -0
  52. package/docs/providers/deepseek.md +147 -0
  53. package/docs/providers/openai.md +1 -1
  54. package/docs/providers/xai.md +138 -0
  55. package/docs/release-and-install.md +54 -12
  56. package/docs/structured-output.md +10 -10
  57. package/docs/thinking-and-reasoning.md +6 -3
  58. package/package.json +4 -3
@@ -0,0 +1,147 @@
1
+ # DeepSeek provider package
2
+
3
+ ## What it does
4
+
5
+ `@arnilo/prism-provider-deepseek` provides explicit, side-effect-free setup for the
6
+ DeepSeek Chat Completions API (`POST /chat/completions`) with official thinking
7
+ mode, reasoning-effort mapping, tool-turn `reasoning_content` replay, and
8
+ implicit prefix caching.
9
+
10
+ The package registers a provider, featured V4 model metadata, and an `api_key`
11
+ auth method through `createExtensionKernel().load([...])`.
12
+
13
+ ## When to use it
14
+
15
+ Use it when a host app wants DeepSeek V4 Flash / Pro through Prism's
16
+ `AgentSession` runtime with official `thinking` / `reasoning_effort` mapping
17
+ and automatic KV prefix cache.
18
+
19
+ Do not use it for the Anthropic-compatible route, automatic credential
20
+ discovery, setup-time catalog fetches, or real-network tests.
21
+
22
+ ## Inputs / request
23
+
24
+ ```ts
25
+ import {
26
+ createDeepSeekProviderPackage,
27
+ defineDeepSeekModel,
28
+ listDeepSeekModels,
29
+ } from "@arnilo/prism-provider-deepseek";
30
+
31
+ createDeepSeekProviderPackage(options: DeepSeekProviderPackageOptions): ProviderPackage
32
+ defineDeepSeekModel(config: DeepSeekModelConfig): ModelConfig
33
+ listDeepSeekModels(options?: ListDeepSeekModelsOptions): Promise<ModelConfig[]>
34
+ ```
35
+
36
+ | Field | Type | Purpose |
37
+ | --- | --- | --- |
38
+ | `apiKey` | `CredentialValueSource` | Direct/callback/resolver API-key source. |
39
+ | `fetch` | `typeof fetch` | Optional fetch implementation for tests/hosts. |
40
+ | `baseUrl` | `string` | Overrides the DeepSeek base URL (default `https://api.deepseek.com`). |
41
+ | `id` | `string` | Overrides the provider id (default `deepseek`). |
42
+ | `models` | `readonly ModelConfig[]` | Overrides featured `deepseekModels` defaults. |
43
+
44
+ ### Thinking / reasoning compat
45
+
46
+ Official body fields (request `options.compat` wins over `model.compat`):
47
+
48
+ | Compat / body field | Wire shape | Notes |
49
+ | --- | --- | --- |
50
+ | `thinking` | `boolean` or `{ type: "enabled" \| "disabled" }` | Default **enabled**. Boolean `true`/`false` maps to those types. |
51
+ | `reasoning_effort` | `low` \| `high` \| `max` | Default `high`. Portable `medium` and `xhigh` map to `high`. Omitted when thinking is disabled. |
52
+
53
+ `applyThinkingLevel(..., "thinking_type")` toggles `thinking.type`. Set
54
+ `reasoning_effort` in `compat` for effort. `ProviderRequestOptions.cacheRetention: "none"`
55
+ forces `thinking: { type: "disabled" }`.
56
+
57
+ Thinking mode ignores `temperature`, `top_p`, `presence_penalty`, and
58
+ `frequency_penalty`; this adapter strips them so they cannot break the cache prefix.
59
+
60
+ ## Outputs / response / events
61
+
62
+ | Surface | Behavior |
63
+ | --- | --- |
64
+ | Provider stream | Prism text, thinking (`delta.reasoning_content`), tool-call delta/final, `usage`, `done`, redacted `error`. |
65
+ | Block preservation | Text; thinking → `reasoning_content` on tool-turn assistants (otherwise dropped, never flattened into text); assistant `tool_call` → `tool_calls`; `tool_result` → role `tool`. |
66
+ | Auth method | `api_key` for the configured provider id, credential name `apiKey`. |
67
+ | Usage | `prompt_cache_hit_tokens` → `Usage.cacheReadTokens` via `mapOpenAIChatUsage`. |
68
+
69
+ Unsupported media blocks fail before fetch. Text-only input.
70
+
71
+ ## Request/response example
72
+
73
+ ```json
74
+ {
75
+ "model": "deepseek-v4-flash",
76
+ "messages": [{ "role": "user", "content": "Hello" }],
77
+ "stream": true,
78
+ "thinking": { "type": "enabled" },
79
+ "reasoning_effort": "high"
80
+ }
81
+ ```
82
+
83
+ ## Implementation example
84
+
85
+ ```ts
86
+ import { createExtensionKernel } from "@arnilo/prism";
87
+ import { createDeepSeekProviderPackage, listDeepSeekModels } from "@arnilo/prism-provider-deepseek";
88
+
89
+ const kernel = createExtensionKernel();
90
+ await kernel.load([createDeepSeekProviderPackage({ apiKey: "fake-deepseek-key" })]);
91
+
92
+ const live = await listDeepSeekModels({ apiKey: "fake-deepseek-key" });
93
+ await kernel.load([createDeepSeekProviderPackage({ apiKey: "fake-deepseek-key", models: live })]);
94
+ ```
95
+
96
+ Per-turn thinking override:
97
+
98
+ ```ts
99
+ await session.prompt("Plan the refactor", {
100
+ providerOptions: {
101
+ compat: {
102
+ thinking: { type: "enabled" },
103
+ reasoning_effort: "low",
104
+ },
105
+ },
106
+ });
107
+ ```
108
+
109
+ ## Extension and configuration notes
110
+
111
+ - Default base URL is `https://api.deepseek.com`. The Anthropic-compatible
112
+ route is not implemented.
113
+ - Featured `deepseekModels` are offline bootstrap aliases (`deepseek-v4-flash`,
114
+ `deepseek-v4-pro`) with 1M context / 384k max output, `cache.kind: "implicit"`,
115
+ and documented USD-per-million cost including cache-read.
116
+ - `listDeepSeekModels()` is caller-gated `GET {base}/models`. Setup never fetches.
117
+ - Tool JSON Schema keys (`properties` / `required`) are sorted before send so the
118
+ implicit prefix stays stable.
119
+ - Tool-turn assistants must replay `reasoning_content` or the API returns 400.
120
+ Non-tool multi-turn may omit it (the API ignores it).
121
+
122
+ ## Security and performance notes
123
+
124
+ - SSE streams and HTTP error bodies use bounded transport helpers.
125
+ - No network calls during import, setup, build, or default tests.
126
+ - No automatic environment, file, keychain, or shell credential lookup.
127
+ - API keys are resolved per request and redacted from errors (including discovery).
128
+ - Provider-owned headers (`content-type`, `authorization`) win over caller headers.
129
+ - One POST per generate. No provider retry loop.
130
+ - Live tests stay opt-in behind `PRISM_LIVE_PROVIDER_TESTS=1` plus `DEEPSEEK_API_KEY`.
131
+
132
+ ## Related APIs
133
+
134
+ - [Provider packages](../provider-packages.md): `defineProviderPackage`,
135
+ caller-gated discovery, per-turn thinking.
136
+ - [Thinking and reasoning](../thinking-and-reasoning.md): portable
137
+ `applyThinkingLevel` → DeepSeek `thinking.type` / `reasoning_effort`.
138
+ - [Credentials and redaction](../credentials-and-redaction.md):
139
+ `resolveCredentialValue`, `redactSecrets`.
140
+ - [Provider caching](../provider-caching.md): implicit DeepSeek prefix cache.
141
+ - [Provider conformance](../provider-conformance.md): network-free adapter tests.
142
+
143
+ ## Official evidence
144
+
145
+ - [Thinking Mode](https://api-docs.deepseek.com/guides/thinking_mode)
146
+ - [KV Cache](https://api-docs.deepseek.com/guides/kv_cache)
147
+ - [Create Chat Completion](https://api-docs.deepseek.com/api/create-chat-completion)
@@ -54,7 +54,7 @@ uses official Responses `reasoning: { effort, summary? }` via
54
54
  | Continuation | An incomplete Responses stream self-resumes at most eight HTTP hops using opaque `previous_response_id`; a cursor is at most 4 KiB, is never replayed, and is observable as `continuation_required`. |
55
55
  | Realtime | `createOpenAIRealtimeSession()` exposes server-session creation, audio in/out, transcript deltas, provider-hosted calls, interrupt, and idempotent close through the neutral `RealtimeSession` seam. |
56
56
  | Block preservation | User/system text → `input_text`; assistant text → `output_text`; assistant host `tool_call` → top-level `function_call` with `call_id`; provider-hosted calls are not replayed; `tool_result` → top-level `function_call_output`; images/files/audio when declared on the model. Bare thinking without an encrypted Responses reasoning item is omitted on replay. |
57
- | Auth methods | `api_key` for `openai`; host-invoked subscription `oauth` for `openai-codex`. This is Prism's only first-party subscription OAuth flow in 0.0.12. |
57
+ | Auth methods | `api_key` for `openai`; host-invoked subscription `oauth` for `openai-codex`. xAI SuperGrok is the other first-party subscription OAuth flow ([xAI](xai.md)). |
58
58
 
59
59
  Unsupported block placements or unclaimed images fail before `fetch`. Provider-hosted calls are telemetry only: Prism never dispatches them as host tools or sends a `tool_result`.
60
60
 
@@ -0,0 +1,138 @@
1
+ # xAI provider package
2
+
3
+ ## What it does
4
+
5
+ `@arnilo/prism-provider-xai` provides explicit, side-effect-free setup for the
6
+ xAI Grok Chat Completions API (`POST https://api.x.ai/v1/chat/completions`)
7
+ with implicit prefix caching via a sanitized `x-grok-conv-id` header, reasoning
8
+ replay, and host-invoked SuperGrok / X Premium OAuth.
9
+
10
+ The package registers a provider, featured Completions models, an `api_key`
11
+ auth method, and an `oauth` auth method (`createXaiOAuthProvider`, id `xai`).
12
+
13
+ ## When to use it
14
+
15
+ Use it when a host wants Grok 4.6 / 4.3 / Build through Prism with either an
16
+ xAI API key or a SuperGrok / X Premium subscription login.
17
+
18
+ Do not use it for Responses-only `grok-4.5`, PKCE loopback, `cli-chat-proxy.grok.com`,
19
+ `~/.grok` credential import, or setup-time catalog fetches.
20
+
21
+ ## Inputs / request
22
+
23
+ ```ts
24
+ import {
25
+ createXaiOAuthProvider,
26
+ createXaiProviderPackage,
27
+ listXaiModels,
28
+ } from "@arnilo/prism-provider-xai";
29
+
30
+ createXaiProviderPackage(options: XaiProviderPackageOptions): ProviderPackage
31
+ createXaiOAuthProvider(options?: XaiOAuthOptions): OAuthProvider
32
+ listXaiModels(options?: ListXaiModelsOptions): Promise<ModelConfig[]>
33
+ ```
34
+
35
+ | Field | Type | Purpose |
36
+ | --- | --- | --- |
37
+ | `apiKey` | `CredentialValueSource` | API key **or** SuperGrok access token (host wires after `login` / `refreshOAuthCredential`). |
38
+ | `fetch` | `typeof fetch` | Optional fetch for tests/hosts. |
39
+ | `baseUrl` | `string` | Default `https://api.x.ai/v1`. |
40
+ | `id` | `string` | Provider id (default `xai`). |
41
+ | `models` | `readonly ModelConfig[]` | Overrides featured `xaiModels`. |
42
+ | `oauth` | `XaiOAuthOptions` | Optional client id / endpoints / referrer overrides. |
43
+
44
+ ### Cache header
45
+
46
+ `x-grok-conv-id` is `sanitizeCacheKey(cache.key ?? cacheKey ?? sessionId, 128)`.
47
+ Omitted when `cache.mode` is `off`, `cacheRetention` is `none`, or the key sanitizes empty.
48
+
49
+ ### SuperGrok OAuth
50
+
51
+ RFC 8628 device-code. Default public client id
52
+ `b1a00492-073a-47ea-816f-4c329264a828` is **not a secret**. Scope
53
+ `openid profile email offline_access grok-cli:access api:access`. Referrer
54
+ default `prism`. Endpoints: `https://auth.x.ai/oauth2/device/code`,
55
+ `/token`, `/revoke`. Form-urlencoded bodies. `verification_uri` /
56
+ `verification_uri_complete` must be `https:`. Refresh keeps the previous
57
+ `refresh_token` when omitted and applies a 5-minute expiry skew. Revoke is
58
+ best-effort; `revokeOAuthCredential` still deletes the local store.
59
+
60
+ No PKCE loopback. Login requires `onDeviceCode`. Setup never logs in.
61
+
62
+ ## Outputs / response / events
63
+
64
+ | Surface | Behavior |
65
+ | --- | --- |
66
+ | Provider stream | Prism text, thinking (`delta.reasoning_content` / `delta.reasoning`), tool-call, `usage`, `done`, redacted `error`. |
67
+ | Cache usage | `prompt_tokens_details.cached_tokens` → `cacheReadTokens`. If `cached_tokens > prompt_tokens` (exclusive report), values are kept as-is; unused input is not invented. |
68
+ | Auth | `api_key` and `oauth` (`getCredential` → `{ type: "bearer", value: access }`). |
69
+ | Images | Allowed when `capabilities.input` includes `image`. Rejected otherwise. |
70
+
71
+ ## Request/response example
72
+
73
+ ```json
74
+ {
75
+ "model": "grok-4.6",
76
+ "messages": [{ "role": "user", "content": "Hello" }],
77
+ "stream": true
78
+ }
79
+ ```
80
+
81
+ Header: `x-grok-conv-id: sess-1`.
82
+
83
+ ## Implementation example
84
+
85
+ ```ts
86
+ import { createExtensionKernel, refreshOAuthCredential } from "@arnilo/prism";
87
+ import { createXaiOAuthProvider, createXaiProviderPackage } from "@arnilo/prism-provider-xai";
88
+
89
+ const kernel = createExtensionKernel();
90
+ await kernel.load([createXaiProviderPackage({ apiKey: "fake-xai-key" })]);
91
+
92
+ const oauth = createXaiOAuthProvider();
93
+ const creds = await oauth.login({
94
+ onDeviceCode: ({ userCode, verificationUri }) => {
95
+ console.log(`Open ${verificationUri} and enter ${userCode}`);
96
+ },
97
+ });
98
+ await store.set("xai", creds);
99
+
100
+ await kernel.load([
101
+ createXaiProviderPackage({
102
+ apiKey: async () => {
103
+ const current = await store.get("xai");
104
+ return (await refreshOAuthCredential({ provider: oauth, credentials: current, store })).access;
105
+ },
106
+ }),
107
+ ]);
108
+ ```
109
+
110
+ ## Extension and configuration notes
111
+
112
+ - Featured Completions: `grok-4.6` (500k), `grok-4.3` (1M), `grok-build-0.1` (256k). All image + reasoning, `cache.kind: "implicit"`.
113
+ - `grok-4.5` / Responses API is not implemented.
114
+ - `listXaiModels()` is caller-gated `GET {base}/models`. Setup never fetches.
115
+ - Reasoning models replay `reasoning_content` and do not flatten thinking into text.
116
+ - Generate always hits `https://api.x.ai/v1/chat/completions` (same backend for API key and SuperGrok access).
117
+
118
+ ## Security and performance notes
119
+
120
+ - Public client id is documented as not a secret. Device/user/access/refresh codes are redacted.
121
+ - HTTPS verification URI only. No PKCE loopback. No `~/.grok/**` or env scan.
122
+ - Provider-owned headers (`authorization`, `content-type`) win. Conv-id is never a credential.
123
+ - Bounded OAuth and API error bodies. No retry loop. No refresh timer.
124
+ - Live API-key smoke: `PRISM_LIVE_PROVIDER_TESTS=1` + `XAI_API_KEY`. SuperGrok login is operator-only (`PRISM_LIVE_XAI_OAUTH=1`).
125
+
126
+ ## Related APIs
127
+
128
+ - [Provider packages](../provider-packages.md): OAuth support matrix.
129
+ - [Credentials and redaction](../credentials-and-redaction.md): SuperGrok is authorized; Claude/Gemini are not.
130
+ - [Credential storage](../credential-storage.md): host-owned store after explicit `login`.
131
+ - [Provider caching](../provider-caching.md): implicit xAI prefix cache + conv-id.
132
+ - [Thinking and reasoning](../thinking-and-reasoning.md): xAI reasoning replay.
133
+ - [OpenAI Codex](openai.md): the other first-party subscription OAuth flow.
134
+
135
+ ## Official evidence
136
+
137
+ - [Prompt caching](https://docs.x.ai/developers/advanced-api-usage/prompt-caching)
138
+ - [OIDC discovery](https://auth.x.ai/.well-known/openid-configuration)
@@ -2,22 +2,22 @@
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. (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).
5
+ Prism is published as **55 publishable manifests**: the root `@arnilo/prism` core package plus **54 workspace packages** — 17 provider adapters, 10 `prism-*` family/profile packages, and 27 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 0.2.9 plan 029 cut adds DeepSeek, xAI, ClinePass, and `@arnilo/prism-impeccable` on the 0.2.8 51-package graph. 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.2.7` 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.9` peer; profiles are pure manifests. Installation activates no provider, listener, database, browser, credential, or tool capability.
8
8
 
9
- Current **50** publishable manifests (root + 49 workspace packages):
9
+ Current **55** publishable manifests (root + 54 workspace packages):
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`
13
13
  `@arnilo/prism-model-router`, `@arnilo/prism-observability-opentelemetry`, `@arnilo/prism-policy`, `@arnilo/prism-all`, `@arnilo/prism-base`, `@arnilo/prism-caveman`
14
- `@arnilo/prism-code`, `@arnilo/prism-compaction`, `@arnilo/prism-ponytail`, `@arnilo/prism-providers`, `@arnilo/prism-sdk`, `@arnilo/prism-provider-ai-sdk`
14
+ `@arnilo/prism-code`, `@arnilo/prism-compaction`, `@arnilo/prism-impeccable`, `@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-nats`, `@arnilo/prism-session-store-postgres`, `@arnilo/prism-session-store-sqlite`
17
+ `@arnilo/prism-provider-clinepass`, `@arnilo/prism-provider-deepseek`, `@arnilo/prism-provider-xai`, `@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-openapi-tools`, `@arnilo/prism-supervisor`, `@arnilo/prism-tool-validator-json-schema`, `@arnilo/prism-web-tools`, `@arnilo/prism-work-tools`, `@arnilo/prism-workflows`, `@arnilo/prism-document-reader`
19
19
 
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.
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 fourteen `@arnilo/prism-provider-*` packages in its family (Azure/Bedrock/Vertex stay on `@arnilo/prism-all`).
21
21
 
22
22
  ## When to use it
23
23
 
@@ -31,7 +31,7 @@ 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 + provider family (11 of 14) | `npm install @arnilo/prism @arnilo/prism-providers` |
34
+ | Install core + provider family (14 of 17) | `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` |
@@ -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.2.7.tgz`; first-party packages produce `arnilo-prism-provider-<name>-0.2.7.tgz` / `arnilo-prism-compaction-<name>-0.2.7.tgz` / `arnilo-prism-coding-agent-0.2.7.tgz`; family/profile packages produce `arnilo-prism-{providers,compaction,base,code,sdk,all}-0.2.7.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.9.tgz`; first-party packages produce `arnilo-prism-provider-<name>-0.2.9.tgz` / `arnilo-prism-compaction-<name>-0.2.9.tgz` / `arnilo-prism-coding-agent-0.2.9.tgz`; family/profile packages produce `arnilo-prism-{providers,compaction,base,code,sdk,all}-0.2.9.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
 
@@ -348,6 +348,48 @@ npm run release:publish -- --version 0.2.6 --dry-run --allow-dirty --allow-untag
348
348
 
349
349
  Protected evidence (never a passing skip): the durable recovery/workspace conformance legs (real Postgres two-replica split-brain fence, cross-replica cancellation, terminal-before-recovery), the protected PTY leg (real PTY host adapter), the protected real coding journey (`scripts/phase26-coding-journey-report.json` — pass/blocked/protected, never a passing skip; runs in `.github/workflows/coding-journey.yml` with real provider/Docker/Playwright/GitHub/Postgres/PTY services), and the live canaries (provider OIDC/OPA, MCP, A2A, Brave — always `protected` rows in the manifest, never `pass`). The release skip manifest names every skip class with its required env; missing protected evidence records 0.2.6 as **blocked**, never a passing skip.
350
350
 
351
+ ### 0.2.9 publish handoff (plan 029 Task 10)
352
+
353
+ **Decision: GO when the operator prerequisites below are recorded.** Release **0.2.9** (plan 029) is the provider-adoption and behavior-packages cut on the 0.2.x review-remediation line. API surface **additive-only** (plain reviewed compat gate at 0.2.9: expected deltas are the version literal plus the new provider/OAuth/impeccable exports and the form-urlencoded `pollDeviceCodeToken` options; zero removals; baselines regenerated with `--update-baseline`, no `--allow-break`). Ships `@arnilo/prism-provider-deepseek`, `@arnilo/prism-provider-xai` (API key + SuperGrok RFC 8628), `@arnilo/prism-provider-clinepass`, and `@arnilo/prism-impeccable`. Ponytail peer `^4.9.0` (bare `/ponytail` reports status). Caveman registers extra `SKILL.md`. SuperGrok is host-invoked; Cline WorkOS, DeepSeek `/anthropic`, grok-cli file scan, harness/Cordis/Muse, Caveman 2 engine, and Impeccable live detector stay out. Release graph is **55** publishable manifests at exact **0.2.9** (root + 54 workspace). Store compatibility with 0.2.8: **compatible, no migration**.
354
+
355
+ **Rollback notes.** Rollback = restore the 0.2.8 manifests/tag. No persisted 0.2.8 shape changed; the added packages simply disappear.
356
+
357
+ ```bash
358
+ node scripts/release.mjs bump --from 0.2.8 --to 0.2.9 # already applied by Task 10; idempotent
359
+ npm test
360
+ PRISM_CLIENT_NAMES=<names> node scripts/check-client-neutrality.mjs
361
+ npm run sdk:ready
362
+ node scripts/release.mjs gate --version 0.2.9
363
+ npm run pack:dry-run
364
+ npm audit --audit-level=moderate
365
+ node scripts/scan-secrets.mjs && npm sbom --sbom-format spdx > security-artifacts/sbom.spdx.json && node scripts/verify-sbom.mjs
366
+ npm run release:check -- --version 0.2.9 --report /tmp/prism-0.2.9-preflight.json
367
+ npm run release:publish -- --version 0.2.9 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.2.9-dry-run.json
368
+ ```
369
+
370
+ Protected evidence stays the same classes as 0.2.8 plus SuperGrok live login (`PRISM_LIVE_XAI_OAUTH`) — always `protected`, never a silent pass. Publication remains the operator handoff (signed `v0.2.9` tag + npm OIDC).
371
+
372
+ ### 0.2.8 publish handoff (plan 028 Task 18)
373
+
374
+ **Decision: GO when the operator prerequisites below are recorded.** Release **0.2.8** (plan 028) is the ACP adoption-fixes cut on the 0.2.x review-remediation line. API surface **additive-only** (plain reviewed compat gate at 0.2.8: expected deltas are the version literal plus the plan 028 additive exports — `ToolKind`/`kind` on `ToolDefinition`, `AgentFinishReason`, `createCodingToolProjection`/`AgUiProjectedImage`/`AgUiProjectedToolResult`, `AcpCommand`/`AcpCommandsSeam`, `ERR_PRISM_ACP_RUN`, `acpImageBytes`/`acpCommandsPerUpdate`, and the new `@arnilo/prism-acp-agent` package; zero removals; baselines regenerated with `--update-baseline`, no `--allow-break`). Client names are scrubbed; `scripts/check-client-neutrality.mjs` is part of `release:gate`. ACP B1–B5 and F1–F10 as recorded in `plans/028-Release-0-2-8-ACP-Adoption-Fixes.md`. Release graph is **51** publishable manifests at exact **0.2.8** (root + 50 workspace). Store compatibility with 0.2.7: **compatible, no migration**.
375
+
376
+ **Rollback notes.** Rollback = restore the 0.2.7 manifests/tag. No persisted 0.2.7 shape changed; the added exports and `@arnilo/prism-acp-agent` simply disappear.
377
+
378
+ ```bash
379
+ node scripts/release.mjs bump --from 0.2.7 --to 0.2.8 # already applied by Task 18; idempotent
380
+ npm test
381
+ PRISM_CLIENT_NAMES=<names> node scripts/check-client-neutrality.mjs
382
+ npm run sdk:ready
383
+ node scripts/release.mjs gate --version 0.2.8
384
+ npm run pack:dry-run
385
+ npm audit --audit-level=moderate
386
+ node scripts/scan-secrets.mjs && npm sbom --sbom-format spdx > security-artifacts/sbom.spdx.json && node scripts/verify-sbom.mjs
387
+ npm run release:check -- --version 0.2.8 --report /tmp/prism-0.2.8-preflight.json
388
+ npm run release:publish -- --version 0.2.8 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.2.8-dry-run.json
389
+ ```
390
+
391
+ Protected evidence stays the same classes as 0.2.7 (Postgres durable legs, live canaries). Missing protected evidence records **blocked**, never a passing skip. Publication remains the operator handoff (signed `v0.2.8` tag + npm OIDC).
392
+
351
393
  ### 0.2.7 publish handoff (plan 027 Task 10)
352
394
 
353
395
  **Decision: GO when the operator prerequisites below are recorded.** Release **0.2.7** (plan 027) is the enterprise ERP production-readiness cut on the 0.2.x review-remediation line. API surface **additive-only** (plain reviewed compat gate at 0.2.7: expected deltas are the version literal plus the plan 027 additive exports — ERP outbox/inbox + dispatcher, saga engine, SoD approvals, audit export, field policy, ERP invariant evals; zero removals; baselines regenerated with `--update-baseline`, no `--allow-break`; freeze manifest `scripts/phase27-freeze-manifest.json` records per-task evidence tokens, state machines, caps, the demand registry, measured HA/DR/classification/journey numbers, and the explicit 0.3.0 blocker). Nine roadmap items, **no exactly-once claim, additive forward-only migrations**: (1) **transactional outbox/inbox** (`erp-messaging`, Task 1) — `ErpOutboxStore`/`ErpInboxStore` + bounded `ErpOutboxDispatcher` with claim-token CAS, `FOR UPDATE SKIP LOCKED`, `ON CONFLICT DO NOTHING` idempotent append, at-least-once delivery with explicit unknown-outcome, dead-letter/replay requiring verified tenant `AgentIdentity`; migration `004_erp_messaging` (`prism_erp_outbox`/`prism_erp_inbox`, 14+4 columns, 3 partial indexes). (2) **saga compensation and reconciliation** (`saga`, Task 2) — `defineSaga`/`runSaga`/`resumeSaga` over existing CheckpointStore + LeaseStore (`prism.workflow.saga`), reverse-order compensation, unknown-outcome detection, manual resolution requiring verified identity + bounded reason + audit ref, stable tenant-scoped operation keys, redacted snapshots, `MAX_SAGA_STEPS=100`. (3) **multi-party and separation-of-duties approvals** (`approvals`, Task 3) — `ApprovalStore` with role/quorum rules, requester/approver separation, any-party-veto rejection, delegated authority (max depth 8), expiry checked at every protected transition, atomic grant consumption in the host transaction, `policyRevision` pin denying on mismatch; migration `005_erp_approvals` (`prism_erp_approvals`, JSONB decisions, `FOR UPDATE` row lock). (4) **tamper-evident audit export** (`audit-export`, Task 4) — `createAuditExporter` with WORM-then-SIEM ordering, hash-chained record envelopes (genesis 0x64 zeros), `verifyAuditBatch` independent verification, `AuditCursorStore` CAS, SIEM best-effort pending replay (8-entry cap), legal-hold flag preservation, RFC 8785 canonical JSON for digests; Prism does not certify NIST/SIEM/WORM compliance programs. (5) **secret-manager adapters demand-gated** (Task 5) — Vault/AWS/Azure/GCP stay **deferred** behind the demand gate (no named consumer; no adapter ships; `scripts/phase27-demand-gate.mjs` enforces zero ambient discovery). (6) **HA registries and recovery** (`ha-dr`, Task 6) — two-replica drill on real Postgres proves failover within lease TTL+5s (measured 4100 ms vs 9000 ms ceiling), idempotent outbox re-append on uncertain-commit replay, stale fence/revision write rejection, exactly-one lease owner, tenant isolation fail-closed. (7) **backup, restore, and migration rollback evidence** (Task 7) — `pg_dump`/`pg_restore` custom-format backup (108,291 B / 122 ms / 382 ms restore), 0.2.6→0.2.7 migration forward+rollback rehearsed (5 migrations), PITR RPO 0 s / RTO 1 s (recovery 1163 ms); production rollback is roll-forward repair only (no down migrations). (8) **field-level data classification and redaction** (`field-policy`, Task 8) — `applyFieldPolicy`/`FieldPolicy`/`createProtectedFieldPolicy` at the redaction, audit-export, and OpenTelemetry seams; unknown-label deny-on-outbound fail-closed default, sparse-copy walker, measured overhead peak 99.8% of the redactor-walk baseline (cap 110%). (9) **ERP release journey** (`erp-evals`, Task 9) — `erpInvariantDataset` + `createErpInvariantScorers` (8 hard 0/1 gates consuming structured facts only) + `scripts/phase27-erp-journey.test.mjs` exercising identity/policy/budget/SoD-approval/outbox/saga-compensation/audit-export/legal-hold/classification/failover/restore end-to-end (4815 ms, all 8 invariants pass). Release graph stays **50** publishable manifests at exact **0.2.7**; zero new runtime dependency names (core remains dependency-free); 43 code packages + 6 pure-manifest family/profile.
@@ -500,7 +542,7 @@ git push origin v0.1.7 # tag push triggers release.yml publish job (prove
500
542
 
501
543
  ### 0.1.6 publish handoff (plan 018 Task 7)
502
544
 
503
- **Decision: GO when the operator prerequisites below are recorded.** Release **0.1.6** (plan 018) is the coding-agent capability-closeouts patch on the frozen 0.1.x line — **additive-only** vs 0.1.5 (plain compat gate at 0.1.6 passed with 0 breaking declaration deltas; the baseline text was regenerated with `--update-baseline` for the version literal only, no `--allow-break` anywhere). Five demand-gated closeouts shipped, each flipped to `demanded` by named demand evidence (operator `arn` for native-sandbox/doc-reader/delete-glob/checkpoint-bodies, user `Clay` for acp-session-store) before its task landed; the demand-gate registry (`scripts/phase18-freeze-manifest.json`) machine-checks demanded ⇒ implemented, deferred ⇒ untouched. Shipped: (1) **durable ACP session store** — `@arnilo/prism-ag-ui` `AcpSessionStore` host seam (`save`/`loadAll`/`evict`), persisted `{sessionId, ownership, modeId, configValues, cwd, additionalDirectories, updatedAt}`, lazy ownership-scoped restore, fail-closed drops, absent seam = 0.1.5 behavior; (2) **network-free native sandbox** — `createNativeSandbox` in `@arnilo/prism-coding-security` (fresh netns per command via the OS `unshare` binary, chained ulimits with `|| exit 126`, argv-only exec, cwd containment, process-group kill, env allow-list, Linux-only fail-closed); (3) **bounded PDF/Office document reader** — new optional package `@arnilo/prism-document-reader` (the 50th manifest, graph 49 → 50) with optional `pdf-parse`/`mammoth` peers fail-closed at creation, magic-byte gating, null fall-through, caps + redaction at the adapter boundary; (4) **recursive delete + brace-expanding glob** — per-call `recursive: true` with fan-out cap and symlink-unlink-not-follow, host-selected/per-call `braceExpansion` bounded to 128 alternatives / 4096 expanded bytes, fail-closed on overflow/malformed braces; (5) **checkpoint persistence for loaded-skill bodies** — opt-in `includeSkillBodies` on run + resume options (names-only stays default, 0.1.3 shapes byte-identical), ≤64 bodies / ≤256-char names / ≤262144-byte bodies / ≤1 MiB total, `maxStateBytes` refusal, redacted at rest, registry-independent resume render. Store compatibility with 0.1.5: **compatible, no migration** (additive-only; no persisted-shape change; `docs/migration.md` gains no entries). Exit gate green: npm test core 1,433/1,433 + 190 script gates (incl. phase18-freeze done-phase), `sdk:ready` exit 0, audit 0 moderate, pack dry-run 50/50 twice byte-identical, budget/benchmark gates green; evidence in `scripts/phase18-baseline.json` `exitGate`. Rollback = restore the 0.1.5 manifests/tag.
545
+ **Decision: GO when the operator prerequisites below are recorded.** Release **0.1.6** (plan 018) is the coding-agent capability-closeouts patch on the frozen 0.1.x line — **additive-only** vs 0.1.5 (plain compat gate at 0.1.6 passed with 0 breaking declaration deltas; the baseline text was regenerated with `--update-baseline` for the version literal only, no `--allow-break` anywhere). Five demand-gated closeouts shipped, each flipped to `demanded` by named demand evidence (operator `arn` for native-sandbox/doc-reader/delete-glob/checkpoint-bodies, a consuming-app user for acp-session-store) before its task landed; the demand-gate registry (`scripts/phase18-freeze-manifest.json`) machine-checks demanded ⇒ implemented, deferred ⇒ untouched. Shipped: (1) **durable ACP session store** — `@arnilo/prism-ag-ui` `AcpSessionStore` host seam (`save`/`loadAll`/`evict`), persisted `{sessionId, ownership, modeId, configValues, cwd, additionalDirectories, updatedAt}`, lazy ownership-scoped restore, fail-closed drops, absent seam = 0.1.5 behavior; (2) **network-free native sandbox** — `createNativeSandbox` in `@arnilo/prism-coding-security` (fresh netns per command via the OS `unshare` binary, chained ulimits with `|| exit 126`, argv-only exec, cwd containment, process-group kill, env allow-list, Linux-only fail-closed); (3) **bounded PDF/Office document reader** — new optional package `@arnilo/prism-document-reader` (the 50th manifest, graph 49 → 50) with optional `pdf-parse`/`mammoth` peers fail-closed at creation, magic-byte gating, null fall-through, caps + redaction at the adapter boundary; (4) **recursive delete + brace-expanding glob** — per-call `recursive: true` with fan-out cap and symlink-unlink-not-follow, host-selected/per-call `braceExpansion` bounded to 128 alternatives / 4096 expanded bytes, fail-closed on overflow/malformed braces; (5) **checkpoint persistence for loaded-skill bodies** — opt-in `includeSkillBodies` on run + resume options (names-only stays default, 0.1.3 shapes byte-identical), ≤64 bodies / ≤256-char names / ≤262144-byte bodies / ≤1 MiB total, `maxStateBytes` refusal, redacted at rest, registry-independent resume render. Store compatibility with 0.1.5: **compatible, no migration** (additive-only; no persisted-shape change; `docs/migration.md` gains no entries). Exit gate green: npm test core 1,433/1,433 + 190 script gates (incl. phase18-freeze done-phase), `sdk:ready` exit 0, audit 0 moderate, pack dry-run 50/50 twice byte-identical, budget/benchmark gates green; evidence in `scripts/phase18-baseline.json` `exitGate`. Rollback = restore the 0.1.5 manifests/tag.
504
546
 
505
547
  ```bash
506
548
  # Operator prerequisites recorded: clean tree at the v0.1.6 tag candidate, GPG key, npm OIDC publisher.
@@ -817,8 +859,8 @@ Audit fixes, dependency updates, and security patches land only for the supporte
817
859
 
818
860
  ## Extension and configuration notes
819
861
 
820
- - **Required `@arnilo/prism` peer.** Every first-party code package declares a non-optional **exact** `@arnilo/prism@0.2.7` 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.7` installed with a package peering `@arnilo/prism@0.2.8`) 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.
821
- - **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.
862
+ - **Required `@arnilo/prism` peer.** Every first-party code package declares a non-optional **exact** `@arnilo/prism@0.2.9` 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.8` installed with a package peering `@arnilo/prism@0.2.9`) 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.
863
+ - **Public access.** All 55 manifests (root + 54 workspace packages: 48 code packages + 6 pure-manifest family/profile packages — the 10 `prism-*` family/profile set is the 6 pure-manifest profiles plus the 4 code packages `prism-caveman`, `prism-impeccable`, `prism-openapi-tools`, `prism-ponytail`) declare `"publishConfig": { "access": "public" }`; the publisher also passes `--access public` explicitly because scoped packages otherwise default to restricted on first publish.
822
864
  - **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).
823
865
  - **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`.
824
866
  - **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.
@@ -992,7 +1034,7 @@ Every release gate maps to an exact enforcement test or command, so the checklis
992
1034
  | 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`. |
993
1035
  | 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. |
994
1036
  | 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. |
995
- | 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. |
1037
+ | 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 47 of the 54 workspace packages (21 direct + 26 transitive); the deliberate Caveman/Ponytail/Impeccable opt-outs and the other non-closure packages (document-reader, OpenAPI tools, NATS) are not in its install set. |
996
1038
  | 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. |
997
1039
  | 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. |
998
1040
  | 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. |
@@ -2,17 +2,17 @@
2
2
 
3
3
  ## What it does
4
4
 
5
- Structured output in Prism is the `Artifact*` contract seam: a host-defined type `T` threaded through host-supplied `parser` → `validator` → `repairer` callbacks inside the `generateValidateReviseLoop` agent loop. Prism never instantiates `T`. The only way to get typed output from a loop is `ArtifactParser<T>`; Prism has no `WorkflowStep`/`NodeSchema`/`synapta*` types and no domain control-flow vocabulary — the seam is generic over an opaque host `T`.
5
+ Structured output in Prism is the `Artifact*` contract seam: a host-defined type `T` threaded through host-supplied `parser` → `validator` → `repairer` callbacks inside the `generateValidateReviseLoop` agent loop. Prism never instantiates `T`. The only way to get typed output from a loop is `ArtifactParser<T>`; Prism has no `WorkflowStep`/`NodeSchema`/host-domain types and no domain control-flow vocabulary — the seam is generic over an opaque host `T`.
6
6
 
7
7
  An artifact loop generates provider text, parses it to `T`, validates `T` against a host schema, and on validation failure runs a repairer to build a follow-up input that asks the model to fix the artifact — repeating up to `maxRevisions` times. The result of every validation and the terminal `artifact_finished`/`artifact_failed` outcomes are observable through `AgentEvent` artifact variants.
8
8
 
9
9
  ## When to use it
10
10
 
11
- Use `generateValidateReviseLoop` (with host `parser`/`validator`/`repairer`) when a run should produce an artifact that must satisfy a host-owned schema before it is considered complete: structured JSON output, a generated file passing lint, a typed response conforming to a Synapta-defined model. Wrap your existing schema/validation library behind the `Artifact*` callbacks.
11
+ Use `generateValidateReviseLoop` (with host `parser`/`validator`/`repairer`) when a run should produce an artifact that must satisfy a host-owned schema before it is considered complete: structured JSON output, a generated file passing lint, a typed response conforming to a host-defined model. Wrap your existing schema/validation library behind the `Artifact*` callbacks.
12
12
 
13
13
  When the model declares `capabilities.structuredOutput` and the host opts into native mode, pass `structuredOutput` on `RunOptions.providerOptions` or on the `generate-validate-revise` loop options so capable providers map the schema to their wire format (`response_format` / Responses `text.format`) and valid output can finish in one turn without repair revisions.
14
14
 
15
- Do not use it to re-implement provider calls, retry, abort, store, or event emission — those stay runtime-owned and are exposed to the loop only through `LoopContext`. Do not use it for runs that need tool calls during revision turns — use `singleShotLoop` or a custom `AgentLoopStrategy` instead. Do not put Synapta domain types into Prism; map them to `ArtifactValidation` in your callbacks.
15
+ Do not use it to re-implement provider calls, retry, abort, store, or event emission — those stay runtime-owned and are exposed to the loop only through `LoopContext`. Do not use it for runs that need tool calls during revision turns — use `singleShotLoop` or a custom `AgentLoopStrategy` instead. Do not put host domain types into Prism; map them to `ArtifactValidation` in your callbacks.
16
16
 
17
17
  ## Inputs / request
18
18
 
@@ -90,7 +90,7 @@ See [Agent events § Artifact event ordering](agent-events.md#artifact-event-ord
90
90
 
91
91
  ## Implementation example
92
92
 
93
- A Synapta-style host maps its own schema to `ArtifactValidation` via the callbacks — no Synapta type is imported by Prism:
93
+ A host maps its own schema to `ArtifactValidation` via the callbacks — no host type is imported by Prism:
94
94
 
95
95
  ```ts
96
96
  import {
@@ -104,7 +104,7 @@ import {
104
104
  type ArtifactRepairer,
105
105
  } from "@arnilo/prism";
106
106
 
107
- // Host owns this schema (Synapta's own type). Prism never imports it.
107
+ // Host owns this schema (the host's own type). Prism never imports it.
108
108
  interface ReleaseNote { readonly title: string; readonly body: string }
109
109
 
110
110
  const parser: ArtifactParser<ReleaseNote> = (text) => {
@@ -143,7 +143,7 @@ await agent.createSession().run("Produce the JSON release note.", {
143
143
 
144
144
  ## End-to-end third-party integration
145
145
 
146
- A third-party host (for example, Synapta) can mix first-party and own providers, register tools, select skills, load `AGENTS.md`/`SYSTEM.md`, and opt a run into the artifact loop — all without importing any `synapta*` types into Prism and without any `workflow`/`node`/`step` vocabulary in the core contracts.
146
+ A third-party host can mix first-party and own providers, register tools, select skills, load `AGENTS.md`/`SYSTEM.md`, and opt a run into the artifact loop — all without importing any host-domain types into Prism and without any `workflow`/`node`/`step` vocabulary in the core contracts.
147
147
 
148
148
  ```ts
149
149
  import {
@@ -160,7 +160,7 @@ import {
160
160
  } from "@arnilo/prism";
161
161
  import { loadSystemPromptFiles } from "@arnilo/prism/node/system-prompts";
162
162
 
163
- // Host-owned schema (Synapta's own type). Prism never imports it.
163
+ // Host-owned schema (the host's own type). Prism never imports it.
164
164
  interface ReleaseNote { readonly title: string; readonly body: string }
165
165
 
166
166
  // Map the host schema to ArtifactValidation. The callbacks are generic at the
@@ -229,7 +229,7 @@ Key cross-seam points:
229
229
  - `systemPrompt` is loaded from `AGENTS.md`/`SYSTEM.md` via the Node loader; the runtime itself is file-name agnostic. See [System prompts](system-prompts.md).
230
230
  - The `validator`/`parser`/`repairer` callbacks are typed as `Artifact*<unknown>` at the loop boundary; the host's `ReleaseNote` type is cast inside the callback body. Prism threads an opaque value and never instantiates it.
231
231
  - Every `artifact_*` event payload is redacted through the active `SecretRedactor`, so secrets echoed in `errors[].message` or `metadata` are scrubbed before subscribers see them. See [Credentials and redaction](credentials-and-redaction.md).
232
- - For a runnable, network-free version that also demonstrates tool dispatch and redaction, see [`examples/synapta-style-artifact-loop.ts`](../examples/synapta-style-artifact-loop.ts).
232
+ - For a runnable, network-free version that also demonstrates tool dispatch and redaction, see [`examples/host-artifact-loop.ts`](../examples/host-artifact-loop.ts).
233
233
 
234
234
  ## Extension and configuration notes
235
235
 
@@ -244,8 +244,8 @@ Key cross-seam points:
244
244
 
245
245
  ## Security and performance notes
246
246
 
247
- - Prism never instantiates `T`; it only threads the host-supplied value through parser→validator→repairer. No Synapta type is imported by `src/`.
248
- - Boundary lock: `src/` imports no `synapta*` package, and the `Artifact*` / `AgentLoop*` / `LoopContext` contract field names contain no `workflow`/`node`/`step` domain vocabulary. Hosts map their own schema names to `ArtifactValidation.errors[].path`.
247
+ - Prism never instantiates `T`; it only threads the host-supplied value through parser→validator→repairer. No host type is imported by `src/`.
248
+ - Boundary lock: `src/` imports no host-domain package, and the `Artifact*` / `AgentLoop*` / `LoopContext` contract field names contain no `workflow`/`node`/`step` domain vocabulary. Hosts map their own schema names to `ArtifactValidation.errors[].path`.
249
249
  - `ArtifactValidation.errors[].message` and `metadata` may echo model text; every `artifact_*` event payload is redacted through `redactAgentEvent` / the active `SecretRedactor`. The generic walker handles nested objects/arrays and replaces cyclic references with `"[Circular]"` without throwing.
250
250
  - A run makes at most `maxRevisions + 1` provider turns; it cannot loop forever on an always-failing validator. Each revision costs one provider turn plus one store append.
251
251
  - No new dependency is required to use structured output — host callbacks wrap whatever schema/validation library the host already uses.
@@ -49,8 +49,8 @@ Core maps only shapes shared by ≥2 packages (or an explicit no-op). Unique kno
49
49
  | Family | Compat patch | Used by (official fields) |
50
50
  | --- | --- | --- |
51
51
  | `openai_reasoning` | `{ reasoning: { effort } }` | OpenAI Responses `reasoning.effort`; OpenRouter `reasoning.effort` |
52
- | `reasoning_effort` | `{ reasoning_effort }` | Z.AI `reasoning_effort`; NeuralWatt `reasoning_effort`; Kimi K3 `reasoning_effort` |
53
- | `thinking_type` | `{ thinking: { type: "enabled" \| "disabled" } }` | Z.AI `thinking.type`; Kimi K2.x `thinking.type` (`none` → `disabled`) |
52
+ | `reasoning_effort` | `{ reasoning_effort }` | Z.AI `reasoning_effort`; NeuralWatt `reasoning_effort`; Kimi K3 `reasoning_effort`; DeepSeek `reasoning_effort`; ClinePass `reasoning_effort` |
53
+ | `thinking_type` | `{ thinking: { type: "enabled" \| "disabled" } }` | Z.AI `thinking.type`; Kimi K2.x `thinking.type` (`none` → `disabled`); DeepSeek `thinking.type` |
54
54
  | `noop` | `{}` | AI SDK / host-owned adapters — effort is host-model settings |
55
55
 
56
56
  `applyThinkingLevel` defaults `family` to `reasoning_effort` when omitted. For `openai_reasoning`, an existing `compat.reasoning.summary` (or other reasoning keys) is preserved when merging `effort`.
@@ -66,6 +66,9 @@ Core maps only shapes shared by ≥2 packages (or an explicit no-op). Unique kno
66
66
  | `@arnilo/prism-provider-kimi` | K3: `reasoning_effort`; K2.x: `thinking_type` | K2.7-code thinking is always on; do not send conflicting `thinking` + `reasoning_effort` |
67
67
  | `@arnilo/prism-provider-opencode-go` | Anthropic route: thinking blocks (`thinking_type` family); OpenAI route: `reasoning_content` preserve + optional `thinking`/`reasoning_effort`/`reasoning` passthrough | Official dual endpoints; MiniMax/Qwen → Anthropic, others → OpenAI |
68
68
  | `@arnilo/prism-provider-ai-sdk` | `noop` | Host `LanguageModelV4` owns reasoning settings |
69
+ | `@arnilo/prism-provider-deepseek` | `thinking_type` + `reasoning_effort` | Thinking on by default (`high`). `cacheRetention: "none"` or `thinking: false` disables. Tool turns must replay `reasoning_content` or the API returns 400. |
70
+ | `@arnilo/prism-provider-xai` | replay only | Featured Completions do not send `reasoning_effort`. Reasoning models must replay `reasoning_content` or the prefix cache breaks. Do not flatten thinking into text. |
71
+ | `@arnilo/prism-provider-clinepass` | `reasoning_effort` | Per-model `compat.thinkingLevelMap`. GLM `xhigh` passthrough (never send `max`). K3 `high` → `max`. Unsupported slots omit the field. |
69
72
 
70
73
  `thinkingFamilyForModel` infers family from existing `compat` shape, then safe provider heuristics (`openai*` → `openai_reasoning`, `neuralwatt` → `reasoning_effort`), then `capabilities.reasoning` → `reasoning_effort`, else `noop`. Docs and packages may map other provider ids explicitly; core avoids provider-specific literals beyond those heuristics.
71
74
 
@@ -91,7 +94,7 @@ LLM compaction and observational memory accept `thinkingLevel?: string`. They ca
91
94
 
92
95
  - [Use-case model selection](use-case-model-selection.md) — session vs worker/summary model binding
93
96
  - [Provider packages](provider-packages.md) — package boundaries and discovery
94
- - [Provider caching](provider-caching.md) — cache retention can disable thinking on some providers (e.g. Z.AI when `cacheRetention: "none"`)
97
+ - [Provider caching](provider-caching.md) — cache retention can disable thinking on some providers (e.g. Z.AI / DeepSeek when `cacheRetention: "none"`)
95
98
  - [Provider request policies](provider-request-policies.md) — `mergeProviderRequestOptions`
96
99
  - [Agent/session runtime](agent-session-runtime.md) — prior-reasoning preservation across turns
97
100
  - Per-provider pages under [docs/providers](providers/)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arnilo/prism",
3
- "version": "0.2.7",
3
+ "version": "0.2.9",
4
4
  "description": "Agent harness for AI providers, agents, sessions, and tools.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -138,6 +138,7 @@
138
138
  "packages/enterprise-postgres",
139
139
  "packages/browser",
140
140
  "packages/ag-ui",
141
+ "packages/acp-agent",
141
142
  "packages/document-reader",
142
143
  "packages/prism-*"
143
144
  ],
@@ -147,7 +148,7 @@
147
148
  "build": "npm run build:core && npm run build --workspaces --if-present",
148
149
  "typecheck": "npm run build && npm run typecheck --workspaces --if-present && tsc -p examples --noEmit",
149
150
  "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 scripts/phase24-truth.test.mjs scripts/phase25-bounded-accumulation.test.mjs scripts/phase26-freeze.test.mjs scripts/phase27-freeze.test.mjs scripts/phase27-ha.test.mjs scripts/phase27-erp-journey.test.mjs scripts/phase27-release.test.mjs scripts/phase26-index-benchmark.test.mjs && node --test scripts/phase23-build-race.test.mjs && npm run test --workspaces --if-present",
151
+ "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 scripts/phase26-freeze.test.mjs scripts/phase27-freeze.test.mjs scripts/phase27-ha.test.mjs scripts/phase27-erp-journey.test.mjs scripts/phase27-release.test.mjs scripts/phase29-freeze.test.mjs scripts/phase26-index-benchmark.test.mjs && node --test scripts/phase23-build-race.test.mjs && npm run test --workspaces --if-present",
151
152
  "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
153
  "coverage:summary": "node scripts/with-build-lock.mjs node scripts/coverage-summary.mjs",
153
154
  "lint": "biome lint . --reporter=sarif --reporter-file=scripts/lint-report.sarif",
@@ -160,7 +161,7 @@
160
161
  "release:publish": "node scripts/release.mjs publish",
161
162
  "release:evidence": "node scripts/release-skip-manifest.mjs",
162
163
  "sdk:ready": "npm run typecheck && npm run lint && npm run format:check && npm test && npm run test:coverage && npm run pack:dry-run && npm run release:gate",
163
- "release:gate": "node scripts/release-skip-manifest.mjs && node scripts/release.mjs gate",
164
+ "release:gate": "node scripts/release-skip-manifest.mjs && node scripts/check-client-neutrality.mjs && node scripts/release.mjs gate",
164
165
  "security:threat-suites": "node --test scripts/phase8-conformance.test.mjs scripts/phase9-conformance.test.mjs scripts/phase10-conformance.test.mjs scripts/phase11-conformance.test.mjs scripts/phase20-security.test.mjs scripts/phase21-security.test.mjs scripts/phase22-security.test.mjs scripts/phase23-security.test.mjs"
165
166
  },
166
167
  "devDependencies": {