@arnilo/prism 0.5.0 → 0.5.2

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 (48) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +10 -10
  3. package/dist/agent-session/session/provider-round.js +17 -1
  4. package/dist/agent-session/session.js +13 -3
  5. package/dist/contracts-core/agent.d.ts +2 -0
  6. package/dist/contracts-protocol.d.ts +2 -0
  7. package/dist/index.d.ts +3 -3
  8. package/dist/index.js +2 -2
  9. package/dist/input.js +3 -2
  10. package/dist/provider-request-policy.d.ts +15 -0
  11. package/dist/provider-request-policy.js +52 -0
  12. package/dist/providers/openai-primitives.js +1 -1
  13. package/docs/0.1.0-readiness.md +2 -2
  14. package/docs/agent-session-runtime.md +2 -1
  15. package/docs/compaction-llm.md +2 -0
  16. package/docs/compaction-observational-memory.md +3 -0
  17. package/docs/index.md +21 -19
  18. package/docs/input-and-prompt-assembly.md +1 -1
  19. package/docs/migrate-to-0.5.md +25 -3
  20. package/docs/migration.md +8 -0
  21. package/docs/provider-caching.md +4 -2
  22. package/docs/provider-packages.md +30 -34
  23. package/docs/provider-request-policies.md +18 -5
  24. package/docs/providers/ai-sdk.md +12 -0
  25. package/docs/providers/alibaba.md +12 -0
  26. package/docs/providers/anthropic.md +12 -0
  27. package/docs/providers/azure.md +12 -0
  28. package/docs/providers/bedrock.md +12 -0
  29. package/docs/providers/clinepass.md +12 -0
  30. package/docs/providers/commandcode.md +12 -0
  31. package/docs/providers/deepseek.md +12 -0
  32. package/docs/providers/google.md +12 -0
  33. package/docs/providers/hyper.md +12 -0
  34. package/docs/providers/kimi.md +12 -0
  35. package/docs/providers/neuralwatt.md +12 -0
  36. package/docs/providers/ollama.md +12 -0
  37. package/docs/providers/openai-compatible.md +12 -0
  38. package/docs/providers/openai.md +12 -0
  39. package/docs/providers/opencode-go.md +12 -0
  40. package/docs/providers/openrouter.md +12 -0
  41. package/docs/providers/vertex.md +12 -0
  42. package/docs/providers/xai.md +12 -0
  43. package/docs/providers/zai.md +12 -0
  44. package/docs/public-contracts.md +1 -1
  45. package/docs/release-and-install.md +37 -37
  46. package/docs/thinking-and-reasoning.md +13 -8
  47. package/docs/use-case-model-selection.md +1 -1
  48. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ ## [0.5.2] - 2026-09-08
2
+
3
+ ### Fixed
4
+ - **Stream tokens no longer persist as one content block per SSE delta.** Adjacent `text`/`thinking` deltas merge on persist (`text += delta`); `message_delta` events stay per-token. Replay serializers join those parts with `""` instead of `"\n"`, so multi-turn tool loops stop poisoning the next request into one token per line. Lockstep `0.5.1` → `0.5.2` with internal ranges `^0.5.1` → `^0.5.2`.
5
+
6
+ ## [0.5.1] - 2026-09-07 (plan 066)
7
+
8
+ ### Changed
9
+ - **Prism constructs valid provider requests on every owned generate site (plan 066, additive):** new `applyDefaultProviderRequestOptions(request, { sessionId, thinkingLevel? })` fills missing `options.sessionId` (from the kernel session id) and `options.cacheKey` (from that id) with host values always winning; new `AgentConfig.thinkingLevel` / `RunOptions.thinkingLevel` session intent (run overrides agent) reaches the wire through the existing `applyThinkingLevelForModel` snap/merge; cache-control and explicit-breakpoint models now get default `{ system_prompt, last_stable_message }` breakpoints with `cacheRetention: "short"` unless the host sets `cache.mode: "off"`, `cacheRetention: "none"`, or explicit breakpoints — implicit/host-owned providers (Azure, Bedrock, Vertex, AI SDK) emit nothing new. Host request policies (`createSessionCachePolicy` and friends) remain overlays and are never required for request success.
10
+ - **Observational memory derives its own correlation id** (`om:{session.id}`, shared across observer/reflector/dropper) fully separate from the agent session (workers may use a different model); **LLM compaction reuses the agent session id** so summaries hit the same prompt cache.
11
+ - **OpenCode Go fails closed before fetch:** a raw `provider.generate()` without resolvable `sessionId`/`cacheKey` throws the new typed `ProviderRequirementError` (`ERR_PRISM_PROVIDER_REQUIREMENT`, redacted message naming requirement + provider id) instead of an opaque upstream HTTP 400.
12
+ - **Lockstep 0.5.1 bump:** all 10 publishable manifests `0.5.0` → `0.5.1` with internal ranges `^0.5.0` → `^0.5.1`. New exports: `applyDefaultProviderRequestOptions`, `ProviderRequirementError`, `ApplyDefaultProviderRequestOptionsContext`. Contract rewrite in `docs/provider-packages.md` and `docs/provider-request-policies.md`; additive 0.5.1 section in `docs/migrate-to-0.5.md`; each provider page documents its P1 session wire, mandatory flag, and P2 default cache behavior.
13
+
1
14
  ## [0.5.0] - 2026-09-06 (plans 055-065)
2
15
 
3
16
  ### Changed
package/README.md CHANGED
@@ -162,16 +162,16 @@ printf '{"id":"1","command":"prompt","params":{"input":"Hi"}}\n' \
162
162
 
163
163
  | package | version | notes |
164
164
  | --- | --- | --- |
165
- | `@arnilo/prism` | 0.5.0 | core — runtime, CLI/RPC, templates, docs |
166
- | `@arnilo/prism-coding-tools` | 0.5.0 | family — /agent, /security, /document-reader, /openapi, /computer-use-linux, /dev, /caveman, /ponytail, /impeccable subpaths |
167
- | `@arnilo/prism-core` | 0.5.0 | family — /runtime, /sessions, /governance, /credentials, /enterprise, /work, /validation subpaths |
168
- | `@arnilo/prism-providers` | 0.5.0 | family — all provider adapters as `/<adapter>` subpaths |
169
- | `@arnilo/prism-acp-agent` | 0.5.0 | capability — ACP adapter |
170
- | `@arnilo/prism-ag-ui` | 0.5.0 | capability — AG-UI/A2A/A2UI adapter |
171
- | `@arnilo/prism-mcp` | 0.5.0 | capability — MCP client/server/OAuth interop |
172
- | `@arnilo/prism-memory` | 0.5.0 | capability — memory plus /rag, /compaction/*, /graft, /wiki subpaths |
173
- | `@arnilo/prism-office` | 0.5.0 | capability — /documents, /sheets, /diagrams subpaths |
174
- | `@arnilo/prism-web-tools` | 0.5.0 | capability — Brave/Exa/Firecrawl plus peer-gated /browser and /obscura subpaths |
165
+ | `@arnilo/prism` | 0.5.2 | core — runtime, CLI/RPC, templates, docs |
166
+ | `@arnilo/prism-coding-tools` | 0.5.2 | family — /agent, /security, /document-reader, /openapi, /computer-use-linux, /dev, /caveman, /ponytail, /impeccable subpaths |
167
+ | `@arnilo/prism-core` | 0.5.2 | family — /runtime, /sessions, /governance, /credentials, /enterprise, /work, /validation subpaths |
168
+ | `@arnilo/prism-providers` | 0.5.2 | family — all provider adapters as `/<adapter>` subpaths |
169
+ | `@arnilo/prism-acp-agent` | 0.5.2 | capability — ACP adapter |
170
+ | `@arnilo/prism-ag-ui` | 0.5.2 | capability — AG-UI/A2A/A2UI adapter |
171
+ | `@arnilo/prism-mcp` | 0.5.2 | capability — MCP client/server/OAuth interop |
172
+ | `@arnilo/prism-memory` | 0.5.2 | capability — memory plus /rag, /compaction/*, /graft, /wiki subpaths |
173
+ | `@arnilo/prism-office` | 0.5.2 | capability — /documents, /sheets, /diagrams subpaths |
174
+ | `@arnilo/prism-web-tools` | 0.5.2 | capability — Brave/Exa/Firecrawl plus peer-gated /browser and /obscura subpaths |
175
175
  <!-- generated:package-truth:inventory end -->
176
176
 
177
177
  ## Scripts
@@ -5,6 +5,22 @@ import { providerToolCallDeltaContent } from "../../provider-events.js";
5
5
  import { errorToErrorInfo, redactRunLedgerRecord, redactSecrets } from "../../redaction.js";
6
6
  import { createDefaultRetryPolicy, waitForRetry } from "../../retry.js";
7
7
  import { bridgeAbort, errorFromInfo, isSteerSoftInterrupt, jsonBytes, mergeRetry, ProviderTurnFailure, providerContent, randomId, reconstructMissingToolCalls, SteerSoftInterrupt, throwIfAborted, } from "../helpers.js";
8
+ function pushCoalescedContent(content, block) {
9
+ const last = content.at(-1);
10
+ if (last?.type === "text" && block.type === "text") {
11
+ content[content.length - 1] = { type: "text", text: last.text + block.text };
12
+ return;
13
+ }
14
+ if (last?.type === "thinking" && block.type === "thinking") {
15
+ content[content.length - 1] = {
16
+ type: "thinking",
17
+ text: last.text + block.text,
18
+ ...((block.signature ?? last.signature) ? { signature: block.signature ?? last.signature } : {}),
19
+ };
20
+ return;
21
+ }
22
+ content.push(block);
23
+ }
8
24
  /**
9
25
  * Plan 062: price usage through the host's {@link CostCatalog} when the provider
10
26
  * did not report a cost itself. Stale/unknown quotes, catalog failures, or
@@ -156,7 +172,7 @@ export async function generateProviderTurn(session, request, runId, signal, secr
156
172
  continue;
157
173
  }
158
174
  const block = providerContent(event);
159
- content.push(block);
175
+ pushCoalescedContent(content, block);
160
176
  if (block.type === "tool_call")
161
177
  calls.push(block);
162
178
  emitOutput({ type: "message_delta", sessionId: session.id, runId, content: block });
@@ -3,7 +3,7 @@ import { policyList } from "../agent-tool-dispatch.js";
3
3
  import { createDefaultCompactionStrategy, isCompactionEntryData } from "../compaction.js";
4
4
  import { DEFAULT_MAX_PENDING_STEER_BYTES, DEFAULT_MAX_PENDING_STEERS } from "../contracts.js";
5
5
  import { GuardrailError, runGuardrails } from "../guardrails.js";
6
- import { createProviderRequestPolicyChain, normalizeProviderRequestPolicyResult } from "../provider-request-policy.js";
6
+ import { applyDefaultProviderRequestOptions, createProviderRequestPolicyChain, normalizeProviderRequestPolicyResult, } from "../provider-request-policy.js";
7
7
  import { redactAgentEvent, redactProviderRequest, redactRunLedgerRecord, redactSecrets, redactSessionEntry } from "../redaction.js";
8
8
  import { createMemorySessionStore, createSessionEntry, getSessionBranchEntries, rebuildSessionContext } from "../session-stores.js";
9
9
  import { createLoadedSkillSet } from "../skill-disclosure.js";
@@ -370,10 +370,20 @@ export class RuntimeAgentSession {
370
370
  return true;
371
371
  }
372
372
  async applyProviderRequestPolicies(request, runId, options, metadata, signal) {
373
+ const stamped = applyDefaultProviderRequestOptions(request, {
374
+ sessionId: this.id,
375
+ thinkingLevel: options.thinkingLevel ?? this.agent.config.thinkingLevel,
376
+ });
373
377
  const policies = [...policyList(this.agent.config.providerRequestPolicies), ...policyList(options.providerRequestPolicies)];
374
378
  if (policies.length === 0)
375
- return { request, secrets: [] };
376
- const result = await createProviderRequestPolicyChain(policies).apply({ request, sessionId: this.id, runId, metadata, signal });
379
+ return { request: stamped, secrets: [] };
380
+ const result = await createProviderRequestPolicyChain(policies).apply({
381
+ request: stamped,
382
+ sessionId: this.id,
383
+ runId,
384
+ metadata,
385
+ signal,
386
+ });
377
387
  return normalizeProviderRequestPolicyResult(result);
378
388
  }
379
389
  async appendMessage(message, runId) {
@@ -73,6 +73,8 @@ export interface AgentConfig {
73
73
  /** Optional trust check for tool and resource targets. */
74
74
  readonly trust?: TrustPolicy;
75
75
  readonly providerOptions?: ProviderRequestOptions;
76
+ /** Portable thinking intent. Snapped per model; run value overrides. */
77
+ readonly thinkingLevel?: string;
76
78
  readonly providerRequestPolicies?: ProviderRequestPolicy | readonly ProviderRequestPolicy[];
77
79
  readonly systemPrompt?: SystemPromptConfig;
78
80
  readonly redactor?: SecretRedactor;
@@ -75,6 +75,8 @@ export interface RunOptions {
75
75
  /** Run-scoped ceilings. When an agent config also sets limits, these can only narrow it. */
76
76
  readonly limits?: RunLimits;
77
77
  readonly providerOptions?: ProviderRequestOptions;
78
+ /** Portable thinking intent for this run. Overrides `AgentConfig.thinkingLevel`. */
79
+ readonly thinkingLevel?: string;
78
80
  readonly providerRequestPolicies?: ProviderRequestPolicy | readonly ProviderRequestPolicy[];
79
81
  readonly systemPrompt?: SystemPromptConfig;
80
82
  readonly compaction?: false | CompactionOptions;
package/dist/index.d.ts CHANGED
@@ -73,8 +73,8 @@ export { createMemoryPersistenceLifecycle, DEFAULT_LIFECYCLE_PAGE_SIZE, DEFAULT_
73
73
  export { boundResponse, defaultResolver, isLoopbackAddress, isLoopbackHostname, normalizeHostname, type PinnedFetchOptions, pinnedFetch, raceAbort, requestPinned, resolvePinnedAddress, } from "./pinned-fetch.js";
74
74
  export { providerContentDelta, providerContinuationRequired, providerDone, providerError, providerTextDelta, providerThinkingDelta, providerToolCall, providerToolCallDelta, providerUsage, toolCallContent, toolCallFromArgumentsText, } from "./provider-events.js";
75
75
  export { authMethodKey, defineProviderPackage, systemPromptContributionKey } from "./provider-packages.js";
76
- export type { SessionCachePolicyOptions } from "./provider-request-policy.js";
77
- export { createProviderRequestPolicyChain, createSessionCachePolicy, mergeProviderRequestOptions } from "./provider-request-policy.js";
76
+ export type { ApplyDefaultProviderRequestOptionsContext, SessionCachePolicyOptions } from "./provider-request-policy.js";
77
+ export { applyDefaultProviderRequestOptions, createProviderRequestPolicyChain, createSessionCachePolicy, mergeProviderRequestOptions, ProviderRequirementError, } from "./provider-request-policy.js";
78
78
  export { canonicalizeJsonSchema } from "./providers/schema.js";
79
79
  export type { ProviderRegistry, ProviderRegistryOptions } from "./providers.js";
80
80
  export { createProviderRegistry, createProviderResolver } from "./providers.js";
@@ -119,5 +119,5 @@ export { trimTrailingSlashes } from "./trim-trailing-slashes.js";
119
119
  export type { ResolvedUseCaseModel, ResolveUseCaseModelInput, UseCaseModelBinding, } from "./use-case-model.js";
120
120
  export { resolveUseCaseModel, resolveUseCaseModelBinding, useCaseCredentialProviderId, } from "./use-case-model.js";
121
121
  export declare const name = "prism";
122
- export declare const version = "0.5.0";
122
+ export declare const version = "0.5.2";
123
123
  export declare const description = "Agent harness for AI providers, agents, sessions, and tools.";
package/dist/index.js CHANGED
@@ -40,7 +40,7 @@ export { createMemoryPersistenceLifecycle, DEFAULT_LIFECYCLE_PAGE_SIZE, DEFAULT_
40
40
  export { boundResponse, defaultResolver, isLoopbackAddress, isLoopbackHostname, normalizeHostname, pinnedFetch, raceAbort, requestPinned, resolvePinnedAddress, } from "./pinned-fetch.js";
41
41
  export { providerContentDelta, providerContinuationRequired, providerDone, providerError, providerTextDelta, providerThinkingDelta, providerToolCall, providerToolCallDelta, providerUsage, toolCallContent, toolCallFromArgumentsText, } from "./provider-events.js";
42
42
  export { authMethodKey, defineProviderPackage, systemPromptContributionKey } from "./provider-packages.js";
43
- export { createProviderRequestPolicyChain, createSessionCachePolicy, mergeProviderRequestOptions } from "./provider-request-policy.js";
43
+ export { applyDefaultProviderRequestOptions, createProviderRequestPolicyChain, createSessionCachePolicy, mergeProviderRequestOptions, ProviderRequirementError, } from "./provider-request-policy.js";
44
44
  export { canonicalizeJsonSchema } from "./providers/schema.js";
45
45
  export { createProviderRegistry, createProviderResolver } from "./providers.js";
46
46
  export { createSecretRedactor, errorToErrorInfo, redactAgentEvent, redactMessage, redactProviderRequest, redactRunLedgerRecord, redactSecrets, redactSessionEntry, resolveRedactor, } from "./redaction.js";
@@ -66,6 +66,6 @@ export { createToolParameterValidator, createToolRegistry, dispatchToolCall, fil
66
66
  export { trimTrailingSlashes } from "./trim-trailing-slashes.js";
67
67
  export { resolveUseCaseModel, resolveUseCaseModelBinding, useCaseCredentialProviderId, } from "./use-case-model.js";
68
68
  export const name = "prism";
69
- export const version = "0.5.0";
69
+ export const version = "0.5.2";
70
70
  export const description = "Agent harness for AI providers, agents, sessions, and tools.";
71
71
  //# sourceMappingURL=index.js.map
package/dist/input.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { assertMessagesSupportModelCapabilities } from "./content.js";
2
2
  import { applyContextBudget, CONTEXT_BUDGET_REPORT_METADATA_KEY } from "./context-budget.js";
3
3
  import { runInstructionInjectors } from "./instruction-injection.js";
4
+ import { applyDefaultProviderRequestOptions } from "./provider-request-policy.js";
4
5
  import { redactMessage } from "./redaction.js";
5
6
  import { loadTextResource } from "./resources.js";
6
7
  import { skillMessages as buildSkillMessages } from "./skill-disclosure.js";
@@ -200,7 +201,7 @@ export async function assembleProviderInput(options) {
200
201
  const providerMessages = await promptBuilder.build({ ...promptRequest, inputLayout: layout, tools, model: options.model });
201
202
  assertMessagesSupportModelCapabilities(options.model, providerMessages);
202
203
  const metadata = budgetReport ? { ...options.metadata, [CONTEXT_BUDGET_REPORT_METADATA_KEY]: budgetReport } : options.metadata;
203
- return {
204
+ return applyDefaultProviderRequestOptions({
204
205
  model: options.model,
205
206
  messages: providerMessages,
206
207
  tools,
@@ -208,7 +209,7 @@ export async function assembleProviderInput(options) {
208
209
  options: options.providerOptions,
209
210
  metadata,
210
211
  signal: options.signal,
211
- };
212
+ }, { sessionId: options.sessionId });
212
213
  }
213
214
  async function buildDefaultInputMessageGroups(input, context) {
214
215
  return {
@@ -3,6 +3,21 @@ export interface SessionCachePolicyOptions {
3
3
  readonly retention?: CacheRetention;
4
4
  readonly cacheKey?: string;
5
5
  }
6
+ export interface ApplyDefaultProviderRequestOptionsContext {
7
+ readonly sessionId?: string;
8
+ readonly thinkingLevel?: string;
9
+ }
10
+ export declare class ProviderRequirementError extends Error {
11
+ readonly code: "ERR_PRISM_PROVIDER_REQUIREMENT";
12
+ readonly requirement: string;
13
+ readonly providerId?: string;
14
+ constructor(message: string, options: {
15
+ readonly requirement: string;
16
+ readonly providerId?: string;
17
+ });
18
+ }
19
+ /** Fill-if-missing `sessionId` / `cacheKey` / cache defaults from `model.cache`. Host values win. Thinking intent patches after. */
20
+ export declare function applyDefaultProviderRequestOptions(request: ProviderRequest, ctx?: ApplyDefaultProviderRequestOptionsContext): ProviderRequest;
6
21
  export declare function createProviderRequestPolicyChain(policies: readonly ProviderRequestPolicy[]): ProviderRequestPolicy;
7
22
  export declare function createSessionCachePolicy(options?: SessionCachePolicyOptions): ProviderRequestPolicy;
8
23
  export declare function mergeProviderRequestOptions(base: ProviderRequestOptions | undefined, patch: ProviderRequestOptions | undefined): ProviderRequestOptions | undefined;
@@ -1,3 +1,55 @@
1
+ import { applyThinkingLevelForModel } from "./thinking.js";
2
+ export class ProviderRequirementError extends Error {
3
+ code = "ERR_PRISM_PROVIDER_REQUIREMENT";
4
+ requirement;
5
+ providerId;
6
+ constructor(message, options) {
7
+ super(message);
8
+ this.name = "ProviderRequirementError";
9
+ this.requirement = options.requirement;
10
+ this.providerId = options.providerId;
11
+ }
12
+ }
13
+ function present(value) {
14
+ return value ? value : undefined;
15
+ }
16
+ const DEFAULT_CACHE_BREAKPOINTS = [
17
+ { location: "system_prompt" },
18
+ { location: "last_stable_message" },
19
+ ];
20
+ function defaultCacheOptions(request) {
21
+ const cache = request.model.cache;
22
+ if (!cache || (cache.kind !== "cache_control" && cache.explicitBreakpoints !== true))
23
+ return undefined;
24
+ const options = request.options;
25
+ if (options?.cache?.mode === "off" || options?.cacheRetention === "none" || options?.cache?.breakpoints?.length) {
26
+ return undefined;
27
+ }
28
+ return {
29
+ ...(options?.cacheRetention ? {} : { cacheRetention: "short" }),
30
+ cache: { breakpoints: DEFAULT_CACHE_BREAKPOINTS },
31
+ };
32
+ }
33
+ /** Fill-if-missing `sessionId` / `cacheKey` / cache defaults from `model.cache`. Host values win. Thinking intent patches after. */
34
+ export function applyDefaultProviderRequestOptions(request, ctx = {}) {
35
+ const sessionId = present(request.options?.sessionId) ?? present(ctx.sessionId);
36
+ const cacheKey = present(request.options?.cacheKey) ?? sessionId;
37
+ const cachePatch = defaultCacheOptions(request);
38
+ const thinkingLevel = present(ctx.thinkingLevel);
39
+ if (sessionId === present(request.options?.sessionId) &&
40
+ cacheKey === present(request.options?.cacheKey) &&
41
+ !cachePatch &&
42
+ !thinkingLevel) {
43
+ return request;
44
+ }
45
+ const merged = mergeProviderRequestOptions(request.options, {
46
+ ...(sessionId !== undefined ? { sessionId } : {}),
47
+ ...(cacheKey !== undefined ? { cacheKey } : {}),
48
+ ...cachePatch,
49
+ });
50
+ const options = thinkingLevel ? applyThinkingLevelForModel(merged, thinkingLevel, request.model) : merged;
51
+ return { ...request, options };
52
+ }
1
53
  export function createProviderRequestPolicyChain(policies) {
2
54
  return {
3
55
  name: "provider-request-policy-chain",
@@ -66,7 +66,7 @@ export function serializeOpenAIChatMessage(message, capabilities = {}) {
66
66
  if (toolCalls.length > 0) {
67
67
  return {
68
68
  role: "assistant",
69
- content: textParts.map((part) => part.text).join("\n") || null,
69
+ content: textParts.map((part) => part.text).join("") || null,
70
70
  tool_calls: toolCalls.map((call) => ({
71
71
  id: call.id,
72
72
  type: "function",
@@ -1,6 +1,6 @@
1
1
  # 0.1.0 / 1.0 Readiness Gates
2
2
 
3
- Status: **0.5.0** is the current release line (dead-export removal cut: 10 active packages, family subpaths, `^0.5.0` peers); **0.3.3** was the terminal 0.3.x cut; **0.1.7** was the terminal 0.1.x baseline; **1.0** readiness remains operator-gated, not automatic.
3
+ Status: **0.5.2** is the current release line (10 active packages, family subpaths, `^0.5.2` peers); **0.3.3** was the terminal 0.3.x cut; **0.1.7** was the terminal 0.1.x baseline; **1.0** readiness remains operator-gated, not automatic.
4
4
 
5
5
  This page distills runnable readiness gates into one command-per-gate table.
6
6
  The **Last evidence** column records the 0.1.0-tree snapshot (plan 012 Tasks
@@ -20,7 +20,7 @@ Historical release lines (0.0.16 floor → 0.0.27 Phase 10 ACP interop → 0.1.0
20
20
  keep their per-phase evidence in the pages above; this page records the 0.2.6
21
21
  snapshot (plan 026) with the 0.1.x tables below as the historical record.
22
22
 
23
- ## Current line (0.5.0)
23
+ ## Current line (0.5.2)
24
24
 
25
25
  | Item | Status |
26
26
  |---|---|
@@ -49,7 +49,7 @@ string | Message | readonly Message[]
49
49
 
50
50
  `AgentConfig.limits` sets run ceilings; `RunOptions.limits` may only narrow configured agent values. Limits cover turns, provider attempts, tool rounds/calls, wall time, request/response bytes, tokens, and optional single-currency cost. A breach emits one `run_limit_exceeded` event and throws `AgentRunError` with `result.limit`; see [Runs and usage ledger](runs-and-usage.md#run-limits).
51
51
 
52
- `RunOptions.model` can override the request model for a run. Model overrides append a `model_change` entry. `AgentConfig.inputLayout` selects the default input assembly layout (`"cache_aware"` by default, or opt-in `"legacy"`); `RunOptions.inputLayout` wins for one run. `AgentConfig.providerOptions`/`RunOptions.providerOptions` supply generic provider request options (session/cache/header/compat/extra hints only — provider-level timeout/retry hints were removed in 0.1.5). Use `RunOptions.signal`/host abort controllers for timeouts and `AgentConfig.retry`/`RunOptions.retry` for retry. `AgentConfig.providerRequestPolicies`/`RunOptions.providerRequestPolicies` run before `AIProvider.generate()` and before `provider_request` middleware. `AgentConfig.systemPrompt` and `RunOptions.systemPrompt` add explicit layered system prompt contributions; `RunOptions.systemPrompt: false` disables configured prompt layers for that run while keeping `AgentConfig.instructions` as the base path. `RunOptions.compaction` can enable auto-compaction for that run or use `false` to disable configured auto-compaction. `RunOptions.retry` can enable provider-turn retry for that run or use `false` to disable configured retry. `RunOptions.metadata` is merged with agent/session metadata for assembly, provider requests, and tool contexts. Run tool-round limits via `RunOptions.limits.maxToolRounds`. `RunOptions.signal` is bridged into the per-run abort signal passed to assembly, providers, tools, auto-compaction, and retry backoff.
52
+ `RunOptions.model` can override the request model for a run. Model overrides append a `model_change` entry. `AgentConfig.inputLayout` selects the default input assembly layout (`"cache_aware"` by default, or opt-in `"legacy"`); `RunOptions.inputLayout` wins for one run. `AgentConfig.thinkingLevel` / `RunOptions.thinkingLevel` (run wins) is the session thinking intent — Prism snaps it onto the request after host `providerOptions`. `AgentConfig.providerOptions`/`RunOptions.providerOptions` supply generic provider request options (session/cache/header/compat/extra hints only — provider-level timeout/retry hints were removed in 0.1.5). Kernel construction always stamps `options.sessionId`/`cacheKey` from `session.id` when missing; `createSessionCachePolicy` is an overlay, not required. Use `RunOptions.signal`/host abort controllers for timeouts and `AgentConfig.retry`/`RunOptions.retry` for retry. `AgentConfig.providerRequestPolicies`/`RunOptions.providerRequestPolicies` run before `AIProvider.generate()` and before `provider_request` middleware. `AgentConfig.systemPrompt` and `RunOptions.systemPrompt` add explicit layered system prompt contributions; `RunOptions.systemPrompt: false` disables configured prompt layers for that run while keeping `AgentConfig.instructions` as the base path. `RunOptions.compaction` can enable auto-compaction for that run or use `false` to disable configured auto-compaction. `RunOptions.retry` can enable provider-turn retry for that run or use `false` to disable configured retry. `RunOptions.metadata` is merged with agent/session metadata for assembly, provider requests, and tool contexts. Run tool-round limits via `RunOptions.limits.maxToolRounds`. `RunOptions.signal` is bridged into the per-run abort signal passed to assembly, providers, tools, auto-compaction, and retry backoff.
53
53
 
54
54
  `RunOptions.activeSkills` selects named skills from a configured `SkillRegistry`; `RunOptions.skills` replaces a plain `Skill[]` config for one run. When `AgentConfig.skills` is a registry and neither is set, **no skills activate** unless `activateAllSkills: true` (run or agent). `skillsDisclosure` (`"progressive"` default, `"eager"` opt-in; run wins) controls catalog vs full instruction bodies; the session-owned `LoadedSkillSet` is populated by `load_skill` when the host registers `createLoadSkillTool`. `toolResultFold` (off unless the host supplies `summarize`) optionally folds aged large tool results in provider input only. See [Context and skills](context-and-skills.md).
55
55
 
@@ -117,6 +117,7 @@ const agent = createAgent({
117
117
  provider: createMockProvider([providerTextDelta("Hello"), providerDone()]),
118
118
  tools: [echo],
119
119
  store,
120
+ thinkingLevel: "low",
120
121
  });
121
122
 
122
123
  const session = agent.createSession({ id: "s1" });
@@ -32,6 +32,7 @@ Key exports:
32
32
  | `providerRequestPolicies` | Optional Prism provider request policies applied before the summary call. |
33
33
  | `customInstructions` | Additional summary focus appended to prompts. |
34
34
  | `thinkingLevel` | Mapped into `ProviderRequest.options.compat` via `applyThinkingLevel` / `thinkingFamilyForModel` (not inert `extra.thinkingLevel`). See [Thinking and reasoning](thinking-and-reasoning.md). |
35
+ | session correlation | Summary `provider.generate` uses the **agent** `context.sessionId` (same cache key as the chat session). Kernel stamps `sessionId`/`cacheKey` even with no `providerRequestPolicies`. |
35
36
  | `reserveTokens` | Output budget basis; defaults to `16384`, hard cap `131072`. |
36
37
  | `keepRecentTokens` | Approximate recent-token budget; defaults to `20000`. |
37
38
  | `maxSummaryTokens` / `maxOutputTokens` | Summary retention/request ceiling; default `16384`, hard cap `131072`. `maxSummaryTokens` wins over the compatibility alias. The finite value is written to `model.parameters.maxTokens`; first-party providers map it to their wire field. |
@@ -132,6 +133,7 @@ The strategy makes only the needed provider call(s): one history summary plus on
132
133
 
133
134
  - [Use-case model selection](use-case-model-selection.md): `summaryModel` vs session `model` fallback.
134
135
  - [Thinking and reasoning](thinking-and-reasoning.md): `thinkingLevel` → `compat`.
136
+ - [Provider request policies](provider-request-policies.md): kernel stamps agent `sessionId` on summary requests.
135
137
  - [Compaction and retry policies](compaction-and-retry.md): replaceable compaction strategy boundary and core compaction strategy surface.
136
138
  - [Observational memory compaction package](compaction-observational-memory.md): source-backed memory workers with the same use-case binding pattern.
137
139
  - [Agent/session runtime](agent-session-runtime.md): `AgentSession.compact()` and opt-in auto-compaction.
@@ -156,6 +156,8 @@ Observer/reflector/dropper may use separate providers, models, instructions, thi
156
156
 
157
157
  Token counting uses `estimateEntryTokens()` / `estimateMessageTokens()`.
158
158
 
159
+ Worker `provider.generate` calls use a **derived** correlation id `om:{session.id}` (shared by observer/reflector/dropper of that attach; adapters sanitize via `sanitizeCacheKey`). This is fully separate from the agent session id so OM cache does not collide with chat. Host `providerOptions.sessionId` still wins. Workers may use a different model than the session.
160
+
159
161
  The runtime requires host-supplied `session`, an `appendEntry` callback bound to that session's owning store/branch, and at least one worker provider (`observation.provider` / `reflection.provider` / `dropper.provider`). Model selection uses [use-case model selection](use-case-model-selection.md): pass per-worker `model` (or settings `observation.model` / `reflection.model` / `dropper.model`) to override, and `sessionModel: agent.config.model` so workers fall back to the session model when no worker model is configured. `requireExplicitModel: true` restores the historical `missing_model` skip when no explicit worker model is set. It no longer accepts a separate `store` option because mismatched session/store pairs can append memory entries outside the active branch. After each memory append, the runtime checks the appended entry is visible at the session leaf and fails closed/restores the previous checkout if the callback points elsewhere. Optional credential resolution is explicit; missing requested credentials skip worker execution. Default credential requests use the **resolved** model's provider id.
160
162
 
161
163
  `createObservationalMemoryCompactionStrategy()` keeps recent message entries like the default compaction strategy, renders existing observations/reflections as the summary, and returns a standard Prism compaction entry. Its `data` includes `throughEntryId`, `keepEntryIds`, `strategy`, `trigger`, and `memory: { type: "om.folded", version: 1, fullFold, observations, reflections, droppedObservationIds }`. When active observations exceed `context.observationsPoolMaxTokens`, it performs a full fold and synchronously trims lowest-relevance observations until the folded payload fits hard byte/token caps (or throws a typed error).
@@ -230,6 +232,7 @@ Ownership: funnel only within the `OwnershipScope` already on the parent agent/s
230
232
 
231
233
  - [Use-case model selection](use-case-model-selection.md): session vs worker model binding and `resolveUseCaseModel`.
232
234
  - [Thinking and reasoning](thinking-and-reasoning.md): `thinkingLevel` → provider `compat`.
235
+ - [Provider request policies](provider-request-policies.md): derived `om:{session.id}` on worker generate.
233
236
  - [Compaction and retry policies](compaction-and-retry.md): replaceable compaction strategy boundary.
234
237
  - [LLM compaction package](compaction-llm.md): existing optional compaction-package pattern.
235
238
  - [Session stores and branching](session-stores-and-branching.md): branch entries that observational memory reads and appends to.
package/docs/index.md CHANGED
@@ -2,9 +2,11 @@
2
2
 
3
3
  Prism is a TypeScript/Node.js agent harness. Host apps and extension packages own providers, tools, resources, credentials, storage, UI, and business behavior. Prism supplies contracts, registries, streaming events, and replaceable runtime primitives.
4
4
 
5
- ## Current line (0.4)
5
+ ## Current line (0.5.2)
6
6
 
7
- - **10 publishable packages**: consolidated family packages use explicit subpaths and changed packages publish independently under Decision B.
7
+ - **Stream token coalesce**: adjacent `text`/`thinking` deltas merge on persist; replay serializers join with `""` so multi-turn tool loops do not grow interstitial newlines.
8
+ - **Provider request construction**: Prism stamps `sessionId`/`cacheKey` on every owned generate site, default cache breakpoints on `cache_control` / explicit-breakpoint models, and `thinkingLevel` on `AgentConfig` / `RunOptions`. Host policies are overlays. OpenCode Go missing session fails closed with `ProviderRequirementError` before fetch.
9
+ - **10 publishable packages**: lockstep `0.5.2` (plans 055–066); family packages use explicit subpaths.
8
10
  - **Linux desktop control**: optional `@arnilo/prism-coding-tools/computer-use-linux` wraps a host-owned `computer-use-linux` MCP binary; DeviceAdapter admission is deny-by-default and the package is omitted from umbrellas.
9
11
  - **Coding/ACP closeouts**: `read.findText`, visible fuzzy edit outcomes and miss context, ACP editor-buffer operations, per-session spawnable coding registries, and delete/move projections.
10
12
 
@@ -36,8 +38,8 @@ Prism is a TypeScript/Node.js agent harness. Host apps and extension packages ow
36
38
 
37
39
  ## Compaction/session memory
38
40
  - [Compaction and retry policies](compaction-and-retry.md): summarize branch history and retry transient provider failures with host-replaceable policies. Task-boundary `session.compact()` fails closed during an active run (`Error("Agent session already has an active run")`).
39
- - [LLM compaction subpath](compaction-llm.md): optional provider-backed strategy with finite summary/reserve/error caps, bounded redacted streaming retention, mandatory finite post-policy `model.parameters.maxTokens`, and `createCodingCompactionStrategy()` for coding handoff focus.
40
- - [Observational memory compaction subpath](compaction-observational-memory.md): optional source-backed memory with explicit `attach()` lifecycle — **Recent exact messages**, **Observation log**, **Reflections**, **Raw-source retrieval** (exact-id recall + cursor paging); dual coverage, **nested-only settings** (pre-0.0.19 flat keys and top-level `workerProvider`/`workerModel` aliases removed in 0.1.5; removed keys fail closed naming the nested replacement), branch-isolated `appendEntry`, secrets redaction, inert import/extension, and an opt-in cross-session recall pattern (host-composed store funnel; default remains per-session).
41
+ - [LLM compaction subpath](compaction-llm.md): optional provider-backed strategy with finite summary/reserve/error caps, bounded redacted streaming retention, mandatory finite post-policy `model.parameters.maxTokens`, and `createCodingCompactionStrategy()` for coding handoff focus. Summary generate uses the **agent session id** so it can hit the same prompt cache.
42
+ - [Observational memory compaction subpath](compaction-observational-memory.md): optional source-backed memory with explicit `attach()` lifecycle — **Recent exact messages**, **Observation log**, **Reflections**, **Raw-source retrieval** (exact-id recall + cursor paging); dual coverage, **nested-only settings** (pre-0.0.19 flat keys and top-level `workerProvider`/`workerModel` aliases removed in 0.1.5; removed keys fail closed naming the nested replacement), branch-isolated `appendEntry`, secrets redaction, inert import/extension, and an opt-in cross-session recall pattern (host-composed store funnel; default remains per-session). Worker generate uses derived `om:{session.id}`, separate from the agent session.
41
43
  - [Working and semantic memory](working-and-semantic-memory.md): optional `@arnilo/prism-memory` working-memory store, semantic recall with opt-in composite recency/importance scoring (sum-normalized weights, component-exposing hits), finite Embedder/VectorStore contracts (incl. embedder identity + generation pointers), PostgreSQL/pgvector path (`createPostgresVectorStore` standalone, HNSW/fts DDL on the host knowledge database), consent lifecycle, identity-bound redacted export, and resumable bounded rebuild.
42
44
  - [Session stores](session-stores.md): `SessionStore` contract, `SessionAppendOptions`, `SessionAppendConflictError`, branch handles, `readBranchPath`, optional bounded `searchSessions` / `SessionIndex` (memory linear|unsupported), and dev-vs-production branch reads — start here for session persistence.
43
45
  - [Conversations](conversations.md): durable user-scoped conversation threads (create/list/continue/branch/archive/export/delete) on session + event-ledger seams, thread-bound reconnectable replay, frozen caps, atomic metadata via version/CAS (`metadata_conflict` on stale writes), and legal-hold-aware deletion.
@@ -61,10 +63,10 @@ Prism is a TypeScript/Node.js agent harness. Host apps and extension packages ow
61
63
  - [Provider layer](provider-layer.md): register and resolve host-owned providers/models, choose replace-or-error duplicate policy, create provider events, stream/reconstruct tool-call deltas, use generic provider request options, and test with the mock provider; deprecated provider-level timeout/retry hints point to runtime abort/retry.
62
64
  - [Model registry](model-registry.md): register and resolve `ModelConfig` records with capabilities, limits, cost, cache support metadata, compat data, and duplicate policy.
63
65
  - [Provider caching](provider-caching.md): use `PromptCacheHints`, `PromptCacheBreakpoint`, `ModelCacheCapabilities`, cache-aware stable-prefix guidance, and shared cache diagnostics helpers; includes the complete per-provider explicit/implicit cache matrix plus no-Prism-cache entries (including Anthropic, Google, Alibaba, Ollama, cloud adapters, and host-owned AI SDK); cache hints are best-effort and cache keys are never secrets; `createCacheTelemetry()` aggregates per-provider/model hit rate and cache-token totals from the `usage` event stream for tuning the `cache_aware` layout — the `__overflow__` bucket reports requests/token totals only, never mixed-model cost.
64
- - [Thinking and reasoning](thinking-and-reasoning.md): model-aware effort adapter (`applyThinkingLevelForModel`) resolves the compat family, snaps the level to the model's declared `capabilities.thinkingLevels`, and merges the patch — with new `google` and `output_config_effort` families, per-provider legality in the coverage evidence matrix (`docs/_evidence/thinking-coverage-2026-09-05.md`), and per-provider declared-level tables.
66
+ - [Thinking and reasoning](thinking-and-reasoning.md): session entry point is `AgentConfig.thinkingLevel` / `RunOptions.thinkingLevel`; `applyThinkingLevelForModel` snaps the level to the model's declared `capabilities.thinkingLevels` and merges the patch — with `google` and `output_config_effort` families, per-provider legality in the coverage evidence matrix (`docs/_evidence/thinking-coverage-2026-09-05.md`), and per-provider declared-level tables.
65
67
  - [Use-case model selection](use-case-model-selection.md): bind `{ model?, provider?, thinkingLevel? }` for observational memory, LLM compaction, and other non-session LLM jobs with explicit session-model fallback via `resolveUseCaseModel`.
66
- - [Provider request policies](provider-request-policies.md): chain `ProviderRequestPolicy` hooks, use `createSessionCachePolicy`, and merge legacy/structured cache options safely.
67
- - [Provider packages](provider-packages.md): all provider adapters ship as `@arnilo/prism-providers/<adapter>` subpaths (importing one adapter never evaluates another); define explicit provider packages, model metadata, auth descriptors, request/cache policies, provider-owned header precedence, the provider-authorized OAuth matrix, and the Phase 10 first-party compatibility matrix without package discovery or provider-specific core behavior; includes a cache behavior summary and **caller-gated on-demand model discovery** (`list*Models`, setup zero-fetch).
68
+ - [Provider request policies](provider-request-policies.md): kernel `applyDefaultProviderRequestOptions` constructs session/cache/thinking; `createSessionCachePolicy` and other `ProviderRequestPolicy` hooks are overlays; merge legacy/structured cache options safely.
69
+ - [Provider packages](provider-packages.md): all provider adapters ship as `@arnilo/prism-providers/<adapter>` subpaths (importing one adapter never evaluates another); define explicit provider packages, model metadata, auth descriptors, request/cache overlays, provider-owned header precedence, the provider-authorized OAuth matrix, and the Phase 10 first-party compatibility matrix without package discovery or provider-specific core behavior. Prism constructs valid requests (session correlation, cache defaults, thinking intent); hosts own credentials/OAuth/env/overlays. Includes a cache behavior summary and **caller-gated on-demand model discovery** (`list*Models`, setup zero-fetch).
68
70
  - Phase 12 package workspaces: [`@arnilo/prism-providers/openai`](providers/openai.md) (Responses hosted-tool attribution, bounded continuation, Realtime session seam), [`@arnilo/prism-providers/anthropic`](providers/anthropic.md) (native Messages, `cache_control`, thinking, caller-gated `listAnthropicModels`), [`@arnilo/prism-providers/google`](providers/google.md) (native Gemini `generateContent` SSE, caller-gated `listGoogleModels`), [`@arnilo/prism-providers/opencode-go`](providers/opencode-go.md) (official Go open models, dual-route Anthropic/OpenAI, caller-gated `listOpenCodeGoModels`, `reasoning_content`/thinking preserve), [`@arnilo/prism-providers/openrouter`](providers/openrouter.md) (app-controlled catalog, caller-gated `listOpenRouterModels`, `reasoning` merge/preserve, `cache_control` + sticky `session_id`), [`@arnilo/prism-providers/zai`](providers/zai.md) (official `thinking`/`reasoning_effort`/`tool_stream`, implicit cache, caller-gated `listZaiModels`), [`@arnilo/prism-providers/deepseek`](providers/deepseek.md) (official `thinking` + `reasoning_effort`, implicit prefix cache, caller-gated `listDeepSeekModels`), [`@arnilo/prism-providers/xai`](providers/xai.md) (Grok Completions, `x-grok-conv-id`, SuperGrok device-code OAuth, caller-gated `listXaiModels`), [`@arnilo/prism-providers/clinepass`](providers/clinepass.md) (stream-only `cline-pass/*` catalog, implicit cache, no WorkOS), [`@arnilo/prism-providers/hyper`](providers/hyper.md) (Charm Hyper, dual-route Anthropic/OpenAI plus explicit `/v1/responses` pass-through, `reasoning_effort`, caller-gated `listHyperModels`, Hypercredit cost telemetry, `402` billing semantics), [`@arnilo/prism-providers/commandcode`](providers/commandcode.md) (Command Code Provider API, server-enforced dual-route Anthropic/OpenAI, optional ZDR, caller-gated `listCommandCodeModels`, off-peak/deal pricing caveats), [`@arnilo/prism-providers/kimi`](providers/kimi.md), [`@arnilo/prism-providers/alibaba`](providers/alibaba.md) (Alibaba Cloud Model Studio / DashScope + Coding Plan, OpenAI-compatible, caller-gated `listAlibabaModels`, implicit + explicit `cache_control` caching, Qwen `enable_thinking`), [`@arnilo/prism-providers/ollama`](providers/ollama.md) (Ollama Cloud + local, OpenAI-compatible, caller-gated `listOllamaModels`, implicit-only caching, `reasoning_effort`), and [`@arnilo/prism-providers/neuralwatt`](providers/neuralwatt.md) with implicit vLLM prefix caching, reasoning controls (`reasoning_effort`/`thinking_token_budget`/`enable_thinking`/`preserve_thinking`/`clear_thinking`), reasoning preservation, OpenAI-style tool-call loop, quota, telemetry, and retry classification helpers, plus the cross-vendor `@arnilo/prism-providers/model-discovery` model-list/capability discovery adapters (OpenAI-compatible + Google, provenance + TTL cache, see model-registry.md).
69
71
  - Phase 8 enterprise cloud (workload identity; separate from consumer Anthropic/Google): [`@arnilo/prism-providers/azure`](providers/azure.md) (Entra / Foundry, credential once per request), [`@arnilo/prism-providers/bedrock`](providers/bedrock.md) (IAM/IRSA + region/PrivateLink, duplicate-case-safe SigV4 signing), [`@arnilo/prism-providers/vertex`](providers/vertex.md) (ADC / Vertex OpenAPI, credential once per request).
70
72
  - Optional AI SDK adapter: [`@arnilo/prism-providers/ai-sdk`](providers/ai-sdk.md) maps host-owned pinned `LanguageModelV4` models onto Prism `AIProvider` streams (offline-tested `@ai-sdk/provider` version matrix; no Prism catalog; maps metadata/tool authority/`finish.usage` cache tokens; reasoning is host-model-owned).
@@ -161,8 +163,8 @@ Prism is a TypeScript/Node.js agent harness. Host apps and extension packages ow
161
163
  - [Impeccable behavior integration](impeccable.md): optional `@arnilo/prism-coding-tools/impeccable` — host `upstreamPath` to compiled Impeccable `SKILL.md`, skill + `/impeccable` → `load_skill`; no detector CLI, no live browser, not in code/sdk/all.
162
164
 
163
165
  ## Release and install
164
- - [Release and install](release-and-install.md): current **0.5.0** package graph — generated inventory in the [package-inventory section](#package-inventory) and the release page — plan 041-044 changed-package cut (progressive tool loading with `search_tools` disclosure, `@arnilo/prism-prompts` initial cut with run-ledger `promptVersion` provenance (persistence schema 9), trace-to-dataset curation in `@arnilo/prism-evals`, and composite memory-recall scoring in `@arnilo/prism-memory@0.3.2`) and independent `^0.3.0` publication; plan 050 changed-package cut (clay-integration-findings fixes + OKF v0.2 wiki bundles) and independent `^0.3.0` publication; plan 030 last-lockstep cut and independent `^0.3.0` publication; plan 029 **0.2.9** provider adoption (DeepSeek, xAI SuperGrok OAuth, ClinePass), `@arnilo/prism-impeccable`, Ponytail 4.9.0, Caveman v2.1 extras; then plan 028 **0.2.8** ACP adoption fixes; then plan 026 the fully-featured coding-agent-readiness cut: **host-selected PTY** (`pty: true` delegates only to the host `ptyBackend`, fails closed as unsupported when absent, bounded resize/TERM/attach caps), **indexed code search** (host-owned incremental index seam with explicit `indexed_literal`/`semantic` modes, literal remains the default, stale/failed/untrusted indexes fail closed `ERR_PRISM_INDEX_*`, results labeled `untrusted_index`), **coding workspaces** (`createCodingWorkspaceLifecycle`: durable CheckpointStore CAS records + LeaseStore fencing, locked worktrees, credential-free fingerprints, cleanup refusal matrix), **durable recovery** (process intent/ACP `activeRun` refs over Postgres/SQLite stores with attach-if-attested `recover()` and durable fence-checked cancellation, never fabricated exits), **patch review and diagnostics** (`createCodingPatchReviewManifest` + `assertCodingPatchAccepted` with pending/accepted/rejected/superseded bound to digest + revision + identity, opt-in LSP `syncDocument`/`diagnosticDelta`), and the **protected real coding journey** (packed consumer through real provider/Docker/Postgres/GitHub/Playwright/PTY services with retained evidence report; forge breadth GitLab/Bitbucket stays demand-gated); then plan 025 the maintainability-and-bounded-performance cut: **god-module splits** (the six remaining implementation monoliths — `src/contracts-core.ts` 1,719 L, `src/agent-session.ts` 2,049 L, `workflows/src/run.ts` 1,227 L, `server/src/handler.ts` 1,005 L, `coding-agent/src/repository.ts` 974 L, `ag-ui/src/acp/agent.ts` 836 L — split into cohesive family files behind preserved barrels, compat-preserving with zero breaking deltas, no `exports`-map subpath, `RuntimeAgentSession` kept as one class with a recorded reason), **persistence-mechanics dedup** (21 pure ownership/cursor/checkpoint/lifecycle/search helpers moved into the dependency-free `session-store-codecs`; postgres/sqlite adapters shrank 273 lines; SQL dialect stays per-adapter; no schema/shape change; cross-store conformance green), **bounded accumulation removed** (per-push `Buffer.concat` in language framing + tar parsing → chunk-array readers; framing ~100–200× faster at 4,000 chunks, tar linear at 8 MiB, caps fail-closed byte-identical; CLI `collectOutput` audited already linear), **dead-code cleanup internal-only** (62 candidates triaged: 2 internal removals + 60 allow-listed in `docs/_evidence/phase25-dead-exports-triage.md`), and **coverage close** (76 behavior-backed regressions; core 90.53/84.20/90.54 → 91.43/84.80/91.60); additive-only compat (105 helper exports), no migration; then plan 024 the package-documentation-and-compatibility-truth cut: **umbrella wording matches manifests** (`@arnilo/prism-providers` installs 11 of 14 provider adapters — Azure/Bedrock/Vertex are added separately by `prism-all`; `prism-all` installs 20 direct / 43 transitive packages and omits document-reader, OpenAPI tools, NATS, Caveman, Ponytail; membership unchanged in 0.2.x), **manifest-derived package truth** (`scripts/package-truth.mjs` → `scripts/package-truth.json` is the single source for counts, provider membership, and closures; docs literals regenerate from it and drift fails the gates), **peer-version policy Decision A** (exact `@arnilo/prism: 0.2.4` pins, atomic-upgrade rule, ERESOLVE refusal for partial upgrades, `^1.0.0` widening at 1.x), and **current-line truth** (`docs/0.1.0-readiness.md` at the 0.2.x line with 0.1.7 as the terminal 0.1.x baseline); no runtime contract delta (compat gate at 0.2.4: version literal only), no migration; then plan 023 the build-coverage-and-release-evidence-integrity cut: **build serialization** (dependency-free `scripts/with-build-lock.mjs` — one O_EXCL lockfile at `node_modules/.prism-build.lock` serializing every emit/test leaf so concurrent compilers can never expose a partial live `dist/`, stale-PID reclaim, env-overridable `PRISM_BUILD_LOCK_TIMEOUT_MS`, fail-closed; documented direct-`tsc` caveat), **corrected workspace coverage denominators** (package-local `--test-coverage-include=dist/**` so imported core `dist` no longer pollutes workspace rows — `mcp` 45.47→90.25, `rag` 19.70→94.82; evidence-based per-package thresholds in `scripts/coverage-thresholds.json` with `protectedException` for durable-leg packages shown separately, machine-readable `scripts/coverage-summary.json`), **machine-auditable release skip manifest** (`scripts/release-skip-manifest.mjs` → `scripts/release-evidence.json`: every surface recorded `pass`/`skip`/`blocked`/`protected` with reason and required env; the 33 protected/live skips named; a required surface without evidence records `blocked` and fails the release gate fail-closed — missing credentials/services can never convert into a green release), and **stabilized quality gates** (Biome 2.x `preset` config migration with zero lint diagnostics, the racy 150ms MCP bridge timing assert replaced by a deterministic barrier, load-sensitive guards carry documented `ponytail:` ceilings, machine-readable `lint-report.sarif` + `unused-report.json` retained by CI); no runtime contract delta (compat gate at 0.2.3: version literal only), no migration; then plan 022 the concurrent-state-and-durability-integrity cut: atomic model-budget reservation (`ModelRouterStateStore.reserveBudget`/`commitBudget`/`releaseBudget` with fencing tokens, `reservationTtlMs` expiry and unknown-usage reconciliation, rate/budget key-map caps with LRU eviction that never drops a held reservation), atomic conversation metadata (`SessionRecord.version` + `appendSession` `expectedVersion` CAS across Postgres/SQLite — create-only `0`, exact-version `N>0`, legacy last-write-wins when omitted; `SessionMetadataConflictError` `metadata_conflict` with versions only, HTTP 409; concurrent create/branch/archive single-statement with branch caps inside the CAS, archive wins, deleted rows never resurrect), single-consumer `EventMultiplexer` (`EventMultiplexerError` `ERR_PRISM_EVENT_MULTIPLEXER_SINGLE_CONSUMER` instead of silent queue sharing), restart-stable NATS durable consumer identity (`prism_<hmac16>` with no random suffix — crash-resumed subscribe continues from the last ack, orphaned 0.2.1 consumers reclaimed on clean stop), and bounded non-durable active-run registries (sweep + fail-closed 512 cap `ERR_PRISM_WORKFLOW_RUN_REGISTRY_OVERFLOW`); new regression surface `scripts/phase22-security.test.mjs` (4 blockers + gate accounting over built public entrypoints) + packed plain-JS `security22.mjs` consumer + the `@arnilo/prism/testing/state-concurrency-conformance` harness (7 probes across memory/Postgres/SQLite/NATS legs, no timing-only sleeps) + the `scripts/phase22-conformance.test.mjs` gate; additive-only compat (new exports only, no removals); forward-only migrations 008 (`prism_sessions.version`) and 003 (`prism_model_router_budgets.reservations`); migration `0.2.1 → 0.2.2`; then plan 021 the provider-completion-and-outbound-trust-boundaries cut: strict stream completion is the shared OpenAI-compatible default (truncated streams fail `incomplete_delta`, explicit `strictCompletion: false` opt-out), bounded success bodies via `readBoundedResponseJson` on all discovery/quota/embeddings/upload/OAuth JSON endpoints (65,536-byte ceiling, depth/property/shape caps), DNS-pinned OIDC JWKS/OPA/content fetches through the core `pinnedFetch` primitive with 3xx redirects rejected outright (private/metadata answers fail closed `ssrf_denied`), shared bounded OAuth device/token polling (`pollDeviceCodeToken`) across provider-openai and credentials-node, and the four edge fixes (Azure/Vertex credential-once, Bedrock duplicate-case/repeated-query SigV4 canonicalization, OpenAI upload failed-DELETE retention, cache `__overflow__` tokens-only); public-entrypoint threat-suite `scripts/phase21-security.test.mjs` + packed plain-JS consumer; additive-only compat (MCP transport helpers re-exported from core, no removals); migration `0.2.0 → 0.2.1`; then plan 020 the fail-closed runtime-and-sandbox-security cut on the 0.2.x review-remediation line: durable-resume decision validation in core (`assertValidAgentRunResume` — unknown decisions/malformed batches fail closed with `ERR_PRISM_DECISION_*` before any state claim, checkpoint write, or tool execution; server parser remains defense in depth), isolated work-tool subprocess environments (`@arnilo/prism-work-tools` — fixed base allow-list + explicit env + forced HOME/telemetry + late-bound per-identity tokens, 64-name/64-KiB caps, absolute binary/configDir, linear output capture), and explicit sandbox capabilities (`@arnilo/prism-coding-security` — `SandboxAdapter.capabilities` with omission-is-false fail-closed resolution, `SandboxCodingComposition.capabilities` from verified wiring, `containmentClaim` deprecated as the conservative projection; Docker reports only verified controls, native reports filesystem/process/privilege `false`); public-entrypoint security conformance (`scripts/phase20-security.test.mjs`, wired into `security:threat-suites`), packed plain-JS consumer regressions, and the sandbox-browser workflow's fail-loud Docker/native capability evidence gate — 0.2.0 never ships while a blocker is skipped; migration and rollback notes in `docs/migration.md` `0.1.7 → 0.2.0`, store-compatible with 0.1.7 in both directions; 0.1.7 was the performance-and-DX patch — dependency-free `createCacheTelemetry()` per-provider/model cache hit/miss aggregator (bounded cardinality with `__overflow__`, token counters/rates only, host-activated), host-configurable `ModelRouterSelectionPolicy` on `createModelRouter` with the reference `createCostLatencySelection` (ModelCost rank then in-memory latency EMA, default ordered behavior byte-identical), `prism providers add <name>` OpenAI-compatible provider scaffold (manifest/provider/models/cache/conformance test/docs stub, npm-name + traversal + symlink-escape validation, placeholders only), and the async `AgUiProjection` verification closeout (plan 009 Task 15 evidence recorded, no new code); plan 017 the documented breaking cut — deprecated-option removal with `docs/migration.md` `0.1.4 → 0.1.5` section and reviewed compat-baseline regeneration via `--allow-break` then `--update-baseline`: the inert provider request knobs, `RunOptions.maxToolRounds`, observational-memory flat settings keys + top-level worker aliases, `ReadToolOptions.autoResizeImages`, `INIT_PROVIDERS`; all removals fail closed naming their replacement; plan 016 internal god-module split — `agents.ts`/`contracts.ts` reorganized behind barrel re-exports with a byte-identical public entry surface, measured tree-shaking improvement in `scripts/phase16-baseline.json`, and additive `@arnilo/prism-browser` Chrome DevTools Protocol capabilities — `browser_evaluate`/`browser_observe` and `block_urls`/`unblock_urls`/`throttle`/`emulate` act actions; plan 015 dead-code and deprecation hygiene on the frozen 0.1.x line — parameterized benchmark runner `scripts/benchmark.mjs` absorbing the per-version runners, archived review-coverage evidence in `docs/_evidence/`, non-blocking unused-code sweep `npm run sweep:unused`, opt-in checkpoint persistence for loaded-skill names and read-path sets; plan 014 Alibaba provider enrichment — embeddings, video input, verified compatible-mode surface decision table; plan 013 post-release hardening — build single-flight, MCP SSE relay test, combined coverage summary, canonical manifest-count narrative, ACP modes/config persistence guidance; Phase 12 release-candidate hardening; plan 012 — freeze manifest, compatibility matrix, upgrade matrix, packed-install e2e journeys, restart-recovery evidence, capacity envelopes, security policy), exact-peer/install/tarball rules, deterministic resumable publication and publish dry-run, frozen 0.1.x compatibility and support matrix (Node/PostgreSQL/platform/provider/protocol pins and unsupported combinations, machine-checked against `scripts/phase12-freeze-manifest.json`), protected PostgreSQL gate, pinned supply-chain gates, offline tests, the 0.0.15 provider/AI-SDK/RAG/memory protected live-canary matrix, and sandbox-browser Docker/Playwright gates. 0.2.6 (plan 026 Task 7) adds the protected coding journey: `scripts/phase26-coding-journey.test.mjs` runs a packed consumer through real provider calls, a digest-pinned Docker sandbox, the durable Postgres worktree lifecycle, provider-driven ACP edits with policy approval, named checks with `diagnosticDelta`, patch review over the server ArtifactService, cross-replica process recovery, durable cancellation, real GitHub PR push/reconcile/cleanup, host Playwright inspection, and the host PTY adapter (frozen profile) — the retained `scripts/phase26-coding-journey-report.json` gates release evidence (pass/blocked/protected, never a passing skip).
165
- - [Migrate 0.4 to 0.5](migrate-to-0.5.md): the complete 0.5.0 migration guide (plans 055–065) — new Hyper/CommandCode adapters, tenant-scoped store factories + child env allow-list, the 27 removed unused exports with replacements, dependency majors (pdf-parse 2.4, better-sqlite3 13, keyring 2), the MCP SDK v2 module move, the CLI real-provider contract, and model-aware thinking effort (Anthropic `output_config.effort`, xAI `reasoning_effort`, snapping, Azure/Vertex/Bedrock compat forwarding) — plus rollback.
166
+ - [Release and install](release-and-install.md): current **0.5.2** package graph — generated inventory in the [package-inventory section](#package-inventory) and the release page — plan 041-044 changed-package cut (progressive tool loading with `search_tools` disclosure, `@arnilo/prism-prompts` initial cut with run-ledger `promptVersion` provenance (persistence schema 9), trace-to-dataset curation in `@arnilo/prism-evals`, and composite memory-recall scoring in `@arnilo/prism-memory@0.3.2`) and independent `^0.3.0` publication; plan 050 changed-package cut (clay-integration-findings fixes + OKF v0.2 wiki bundles) and independent `^0.3.0` publication; plan 030 last-lockstep cut and independent `^0.3.0` publication; plan 029 **0.2.9** provider adoption (DeepSeek, xAI SuperGrok OAuth, ClinePass), `@arnilo/prism-impeccable`, Ponytail 4.9.0, Caveman v2.1 extras; then plan 028 **0.2.8** ACP adoption fixes; then plan 026 the fully-featured coding-agent-readiness cut: **host-selected PTY** (`pty: true` delegates only to the host `ptyBackend`, fails closed as unsupported when absent, bounded resize/TERM/attach caps), **indexed code search** (host-owned incremental index seam with explicit `indexed_literal`/`semantic` modes, literal remains the default, stale/failed/untrusted indexes fail closed `ERR_PRISM_INDEX_*`, results labeled `untrusted_index`), **coding workspaces** (`createCodingWorkspaceLifecycle`: durable CheckpointStore CAS records + LeaseStore fencing, locked worktrees, credential-free fingerprints, cleanup refusal matrix), **durable recovery** (process intent/ACP `activeRun` refs over Postgres/SQLite stores with attach-if-attested `recover()` and durable fence-checked cancellation, never fabricated exits), **patch review and diagnostics** (`createCodingPatchReviewManifest` + `assertCodingPatchAccepted` with pending/accepted/rejected/superseded bound to digest + revision + identity, opt-in LSP `syncDocument`/`diagnosticDelta`), and the **protected real coding journey** (packed consumer through real provider/Docker/Postgres/GitHub/Playwright/PTY services with retained evidence report; forge breadth GitLab/Bitbucket stays demand-gated); then plan 025 the maintainability-and-bounded-performance cut: **god-module splits** (the six remaining implementation monoliths — `src/contracts-core.ts` 1,719 L, `src/agent-session.ts` 2,049 L, `workflows/src/run.ts` 1,227 L, `server/src/handler.ts` 1,005 L, `coding-agent/src/repository.ts` 974 L, `ag-ui/src/acp/agent.ts` 836 L — split into cohesive family files behind preserved barrels, compat-preserving with zero breaking deltas, no `exports`-map subpath, `RuntimeAgentSession` kept as one class with a recorded reason), **persistence-mechanics dedup** (21 pure ownership/cursor/checkpoint/lifecycle/search helpers moved into the dependency-free `session-store-codecs`; postgres/sqlite adapters shrank 273 lines; SQL dialect stays per-adapter; no schema/shape change; cross-store conformance green), **bounded accumulation removed** (per-push `Buffer.concat` in language framing + tar parsing → chunk-array readers; framing ~100–200× faster at 4,000 chunks, tar linear at 8 MiB, caps fail-closed byte-identical; CLI `collectOutput` audited already linear), **dead-code cleanup internal-only** (62 candidates triaged: 2 internal removals + 60 allow-listed in `docs/_evidence/phase25-dead-exports-triage.md`), and **coverage close** (76 behavior-backed regressions; core 90.53/84.20/90.54 → 91.43/84.80/91.60); additive-only compat (105 helper exports), no migration; then plan 024 the package-documentation-and-compatibility-truth cut: **umbrella wording matches manifests** (`@arnilo/prism-providers` installs 11 of 14 provider adapters — Azure/Bedrock/Vertex are added separately by `prism-all`; `prism-all` installs 20 direct / 43 transitive packages and omits document-reader, OpenAPI tools, NATS, Caveman, Ponytail; membership unchanged in 0.2.x), **manifest-derived package truth** (`scripts/package-truth.mjs` → `scripts/package-truth.json` is the single source for counts, provider membership, and closures; docs literals regenerate from it and drift fails the gates), **peer-version policy Decision A** (exact `@arnilo/prism: 0.2.4` pins, atomic-upgrade rule, ERESOLVE refusal for partial upgrades, `^1.0.0` widening at 1.x), and **current-line truth** (`docs/0.1.0-readiness.md` at the 0.2.x line with 0.1.7 as the terminal 0.1.x baseline); no runtime contract delta (compat gate at 0.2.4: version literal only), no migration; then plan 023 the build-coverage-and-release-evidence-integrity cut: **build serialization** (dependency-free `scripts/with-build-lock.mjs` — one O_EXCL lockfile at `node_modules/.prism-build.lock` serializing every emit/test leaf so concurrent compilers can never expose a partial live `dist/`, stale-PID reclaim, env-overridable `PRISM_BUILD_LOCK_TIMEOUT_MS`, fail-closed; documented direct-`tsc` caveat), **corrected workspace coverage denominators** (package-local `--test-coverage-include=dist/**` so imported core `dist` no longer pollutes workspace rows — `mcp` 45.47→90.25, `rag` 19.70→94.82; evidence-based per-package thresholds in `scripts/coverage-thresholds.json` with `protectedException` for durable-leg packages shown separately, machine-readable `scripts/coverage-summary.json`), **machine-auditable release skip manifest** (`scripts/release-skip-manifest.mjs` → `scripts/release-evidence.json`: every surface recorded `pass`/`skip`/`blocked`/`protected` with reason and required env; the 33 protected/live skips named; a required surface without evidence records `blocked` and fails the release gate fail-closed — missing credentials/services can never convert into a green release), and **stabilized quality gates** (Biome 2.x `preset` config migration with zero lint diagnostics, the racy 150ms MCP bridge timing assert replaced by a deterministic barrier, load-sensitive guards carry documented `ponytail:` ceilings, machine-readable `lint-report.sarif` + `unused-report.json` retained by CI); no runtime contract delta (compat gate at 0.2.3: version literal only), no migration; then plan 022 the concurrent-state-and-durability-integrity cut: atomic model-budget reservation (`ModelRouterStateStore.reserveBudget`/`commitBudget`/`releaseBudget` with fencing tokens, `reservationTtlMs` expiry and unknown-usage reconciliation, rate/budget key-map caps with LRU eviction that never drops a held reservation), atomic conversation metadata (`SessionRecord.version` + `appendSession` `expectedVersion` CAS across Postgres/SQLite — create-only `0`, exact-version `N>0`, legacy last-write-wins when omitted; `SessionMetadataConflictError` `metadata_conflict` with versions only, HTTP 409; concurrent create/branch/archive single-statement with branch caps inside the CAS, archive wins, deleted rows never resurrect), single-consumer `EventMultiplexer` (`EventMultiplexerError` `ERR_PRISM_EVENT_MULTIPLEXER_SINGLE_CONSUMER` instead of silent queue sharing), restart-stable NATS durable consumer identity (`prism_<hmac16>` with no random suffix — crash-resumed subscribe continues from the last ack, orphaned 0.2.1 consumers reclaimed on clean stop), and bounded non-durable active-run registries (sweep + fail-closed 512 cap `ERR_PRISM_WORKFLOW_RUN_REGISTRY_OVERFLOW`); new regression surface `scripts/phase22-security.test.mjs` (4 blockers + gate accounting over built public entrypoints) + packed plain-JS `security22.mjs` consumer + the `@arnilo/prism/testing/state-concurrency-conformance` harness (7 probes across memory/Postgres/SQLite/NATS legs, no timing-only sleeps) + the `scripts/phase22-conformance.test.mjs` gate; additive-only compat (new exports only, no removals); forward-only migrations 008 (`prism_sessions.version`) and 003 (`prism_model_router_budgets.reservations`); migration `0.2.1 → 0.2.2`; then plan 021 the provider-completion-and-outbound-trust-boundaries cut: strict stream completion is the shared OpenAI-compatible default (truncated streams fail `incomplete_delta`, explicit `strictCompletion: false` opt-out), bounded success bodies via `readBoundedResponseJson` on all discovery/quota/embeddings/upload/OAuth JSON endpoints (65,536-byte ceiling, depth/property/shape caps), DNS-pinned OIDC JWKS/OPA/content fetches through the core `pinnedFetch` primitive with 3xx redirects rejected outright (private/metadata answers fail closed `ssrf_denied`), shared bounded OAuth device/token polling (`pollDeviceCodeToken`) across provider-openai and credentials-node, and the four edge fixes (Azure/Vertex credential-once, Bedrock duplicate-case/repeated-query SigV4 canonicalization, OpenAI upload failed-DELETE retention, cache `__overflow__` tokens-only); public-entrypoint threat-suite `scripts/phase21-security.test.mjs` + packed plain-JS consumer; additive-only compat (MCP transport helpers re-exported from core, no removals); migration `0.2.0 → 0.2.1`; then plan 020 the fail-closed runtime-and-sandbox-security cut on the 0.2.x review-remediation line: durable-resume decision validation in core (`assertValidAgentRunResume` — unknown decisions/malformed batches fail closed with `ERR_PRISM_DECISION_*` before any state claim, checkpoint write, or tool execution; server parser remains defense in depth), isolated work-tool subprocess environments (`@arnilo/prism-work-tools` — fixed base allow-list + explicit env + forced HOME/telemetry + late-bound per-identity tokens, 64-name/64-KiB caps, absolute binary/configDir, linear output capture), and explicit sandbox capabilities (`@arnilo/prism-coding-security` — `SandboxAdapter.capabilities` with omission-is-false fail-closed resolution, `SandboxCodingComposition.capabilities` from verified wiring, `containmentClaim` deprecated as the conservative projection; Docker reports only verified controls, native reports filesystem/process/privilege `false`); public-entrypoint security conformance (`scripts/phase20-security.test.mjs`, wired into `security:threat-suites`), packed plain-JS consumer regressions, and the sandbox-browser workflow's fail-loud Docker/native capability evidence gate — 0.2.0 never ships while a blocker is skipped; migration and rollback notes in `docs/migration.md` `0.1.7 → 0.2.0`, store-compatible with 0.1.7 in both directions; 0.1.7 was the performance-and-DX patch — dependency-free `createCacheTelemetry()` per-provider/model cache hit/miss aggregator (bounded cardinality with `__overflow__`, token counters/rates only, host-activated), host-configurable `ModelRouterSelectionPolicy` on `createModelRouter` with the reference `createCostLatencySelection` (ModelCost rank then in-memory latency EMA, default ordered behavior byte-identical), `prism providers add <name>` OpenAI-compatible provider scaffold (manifest/provider/models/cache/conformance test/docs stub, npm-name + traversal + symlink-escape validation, placeholders only), and the async `AgUiProjection` verification closeout (plan 009 Task 15 evidence recorded, no new code); plan 017 the documented breaking cut — deprecated-option removal with `docs/migration.md` `0.1.4 → 0.1.5` section and reviewed compat-baseline regeneration via `--allow-break` then `--update-baseline`: the inert provider request knobs, `RunOptions.maxToolRounds`, observational-memory flat settings keys + top-level worker aliases, `ReadToolOptions.autoResizeImages`, `INIT_PROVIDERS`; all removals fail closed naming their replacement; plan 016 internal god-module split — `agents.ts`/`contracts.ts` reorganized behind barrel re-exports with a byte-identical public entry surface, measured tree-shaking improvement in `scripts/phase16-baseline.json`, and additive `@arnilo/prism-browser` Chrome DevTools Protocol capabilities — `browser_evaluate`/`browser_observe` and `block_urls`/`unblock_urls`/`throttle`/`emulate` act actions; plan 015 dead-code and deprecation hygiene on the frozen 0.1.x line — parameterized benchmark runner `scripts/benchmark.mjs` absorbing the per-version runners, archived review-coverage evidence in `docs/_evidence/`, non-blocking unused-code sweep `npm run sweep:unused`, opt-in checkpoint persistence for loaded-skill names and read-path sets; plan 014 Alibaba provider enrichment — embeddings, video input, verified compatible-mode surface decision table; plan 013 post-release hardening — build single-flight, MCP SSE relay test, combined coverage summary, canonical manifest-count narrative, ACP modes/config persistence guidance; Phase 12 release-candidate hardening; plan 012 — freeze manifest, compatibility matrix, upgrade matrix, packed-install e2e journeys, restart-recovery evidence, capacity envelopes, security policy), exact-peer/install/tarball rules, deterministic resumable publication and publish dry-run, frozen 0.1.x compatibility and support matrix (Node/PostgreSQL/platform/provider/protocol pins and unsupported combinations, machine-checked against `scripts/phase12-freeze-manifest.json`), protected PostgreSQL gate, pinned supply-chain gates, offline tests, the 0.0.15 provider/AI-SDK/RAG/memory protected live-canary matrix, and sandbox-browser Docker/Playwright gates. 0.2.6 (plan 026 Task 7) adds the protected coding journey: `scripts/phase26-coding-journey.test.mjs` runs a packed consumer through real provider calls, a digest-pinned Docker sandbox, the durable Postgres worktree lifecycle, provider-driven ACP edits with policy approval, named checks with `diagnosticDelta`, patch review over the server ArtifactService, cross-replica process recovery, durable cancellation, real GitHub PR push/reconcile/cleanup, host Playwright inspection, and the host PTY adapter (frozen profile) — the retained `scripts/phase26-coding-journey-report.json` gates release evidence (pass/blocked/protected, never a passing skip).
167
+ - [Migrate 0.4 to 0.5](migrate-to-0.5.md): the complete 0.5.x migration guide (plans 055–066) — 0.5.0 lockstep plus **0.5.1** additive request construction (`thinkingLevel` field, kernel session/cache defaults, OpenCode Go `ProviderRequirementError`) — plus rollback.
166
168
  - [Migrate legacy 0.3 packages to 0.4](migrate-to-0.4.md): complete breaking package-reorganization guide — all retired package/import mappings, profile replacements, optional peers and host binaries, security boundaries, rollback, and npm `legacy`/deprecation lifecycle.
167
169
  - [0.1.0 / 1.0 readiness gates](0.1.0-readiness.md): command-per-gate 1.0 readiness table — frozen API surface + compat gate, migration/docs tripwires, budget table, live-suite matrix, security matrix, current-line status (**0.2.5** current line; 0.1.7 terminal 0.1.x baseline), signed-publication/live-canary prerequisites for 1.0, and Phase 12 demand-evidence entry criteria.
168
170
  - [Review coverage archive](_evidence/): per-phase evidence freezes (plans 067–079, releases 0.0.4–0.0.16, 0.2.7 ERP evidence) — traceability matrices, provider validation, capability/primitive/limit matrices, benchmark budgets, and artifact-diet findings; tarball-excluded, kept in-repo for audit.
@@ -177,15 +179,15 @@ The generated inventory below derives from [`scripts/package-truth.json`](../scr
177
179
 
178
180
  | package | version | notes |
179
181
  | --- | --- | --- |
180
- | `@arnilo/prism` | 0.5.0 | core — runtime, CLI/RPC, templates, docs |
181
- | `@arnilo/prism-coding-tools` | 0.5.0 | family — /agent, /security, /document-reader, /openapi, /computer-use-linux, /dev, /caveman, /ponytail, /impeccable subpaths |
182
- | `@arnilo/prism-core` | 0.5.0 | family — /runtime, /sessions, /governance, /credentials, /enterprise, /work, /validation subpaths |
183
- | `@arnilo/prism-providers` | 0.5.0 | family — all provider adapters as `/<adapter>` subpaths |
184
- | `@arnilo/prism-acp-agent` | 0.5.0 | capability — ACP adapter |
185
- | `@arnilo/prism-ag-ui` | 0.5.0 | capability — AG-UI/A2A/A2UI adapter |
186
- | `@arnilo/prism-mcp` | 0.5.0 | capability — MCP client/server/OAuth interop |
187
- | `@arnilo/prism-memory` | 0.5.0 | capability — memory plus /rag, /compaction/*, /graft, /wiki subpaths |
188
- | `@arnilo/prism-office` | 0.5.0 | capability — /documents, /sheets, /diagrams subpaths |
189
- | `@arnilo/prism-web-tools` | 0.5.0 | capability — Brave/Exa/Firecrawl plus peer-gated /browser and /obscura subpaths |
182
+ | `@arnilo/prism` | 0.5.2 | core — runtime, CLI/RPC, templates, docs |
183
+ | `@arnilo/prism-coding-tools` | 0.5.2 | family — /agent, /security, /document-reader, /openapi, /computer-use-linux, /dev, /caveman, /ponytail, /impeccable subpaths |
184
+ | `@arnilo/prism-core` | 0.5.2 | family — /runtime, /sessions, /governance, /credentials, /enterprise, /work, /validation subpaths |
185
+ | `@arnilo/prism-providers` | 0.5.2 | family — all provider adapters as `/<adapter>` subpaths |
186
+ | `@arnilo/prism-acp-agent` | 0.5.2 | capability — ACP adapter |
187
+ | `@arnilo/prism-ag-ui` | 0.5.2 | capability — AG-UI/A2A/A2UI adapter |
188
+ | `@arnilo/prism-mcp` | 0.5.2 | capability — MCP client/server/OAuth interop |
189
+ | `@arnilo/prism-memory` | 0.5.2 | capability — memory plus /rag, /compaction/*, /graft, /wiki subpaths |
190
+ | `@arnilo/prism-office` | 0.5.2 | capability — /documents, /sheets, /diagrams subpaths |
191
+ | `@arnilo/prism-web-tools` | 0.5.2 | capability — Brave/Exa/Firecrawl plus peer-gated /browser and /obscura subpaths |
190
192
  <!-- generated:package-truth:inventory end -->
191
193
 
@@ -90,7 +90,7 @@ In cache-aware mode, leading system instructions form the stable boundary before
90
90
  - Text attachments and explicit text resources are user messages; inline `audio`/`file`/`document` blocks pass through unchanged on attachments with `content`.
91
91
  - Tool results are tool messages containing `tool_result` content; the agent/session runtime uses this to feed dispatched tool results into the next provider turn, placing the assistant `tool_call` and the matching role `tool` `tool_result` before any final assistant content. Cache-aware layout keeps tool results before the current user suffix so it does not split tool transcripts.
92
92
  - Middleware runs only when `middleware` is supplied in the context.
93
- - `assembleProviderInput()` returns a `ProviderRequest` with the caller's model/tools/provider options/metadata/signal and composed messages/context. It also calls `assertMessagesSupportModelCapabilities()` so unsupported `audio`/`file`/`document`/`image` blocks fail with `UnsupportedModalityError` when the model declares `capabilities.input`.
93
+ - `assembleProviderInput()` returns a `ProviderRequest` with the caller's model/tools/provider options/metadata/signal and composed messages/context. It stamps missing `sessionId`/`cacheKey` via `applyDefaultProviderRequestOptions` when `sessionId` is passed (agent sessions always pass `session.id`). It also calls `assertMessagesSupportModelCapabilities()` so unsupported `audio`/`file`/`document`/`image` blocks fail with `UnsupportedModalityError` when the model declares `capabilities.input`.
94
94
  - Optional `contextBudget` (at least one of `maxInputTokens` / `maxInputBytes`) runs after default message groups are built and before final flatten. Eviction drops droppable sections first (toolResults → history → summaries → context → skills → attachments; layout-aware). Within `history`, oldest messages drop first. Protected instructions + current user `input` (+ tools catalog) fail closed with `ContextBudgetError` if they alone exceed the budget. When `reportOmissions: true`, attach `ProviderRequest.metadata[CONTEXT_BUDGET_REPORT_METADATA_KEY]` and read via `getContextBudgetReport(request)` (kinds/ids/sizes only — no secrets). Raw session store entries are never deleted.
95
95
  - `renderPromptTemplate()` replaces top-level `{{name}}` variables with caller-supplied JSON-compatible values. Strings are inserted directly; numbers, booleans, `null`, arrays, and objects are stringified deterministically with sorted object keys. Missing variables throw by default or stay unchanged with `{ missing: "preserve" }`.
96
96
 
@@ -1,6 +1,6 @@
1
1
  # Migrate Prism 0.4 to 0.5
2
2
 
3
- > **Status: released 2026-09-06** (`v0.5.0` tag). Covers every host-visible change from plan 055 onward: new provider adapters (055), security hardening (056), the dead-export cut (058), dependency majors (062), the MCP 2026-07-28 adoption (063), the CLI real-provider contract (064), and model-aware thinking effort (065).
3
+ > **Status: 0.5.2** (stream-token coalesce, additive on the 2026-09-07 `v0.5.1` tag). 0.5.0 covers plans 055–065. 0.5.1 adds kernel provider-request construction.
4
4
 
5
5
  ## What changes
6
6
 
@@ -105,15 +105,37 @@ What to do:
105
105
 
106
106
  Contract reference: [`docs/thinking-and-reasoning.md`](thinking-and-reasoning.md); per-provider declared levels + wire fields on each `docs/providers/*.md` page.
107
107
 
108
+ ## 8. Provider request construction — additive (plan 066 / 0.5.1)
109
+
110
+ Prism now constructs a valid wire request for every generate site it owns. Hosts pick provider + model + intent. Host request policies are overlays and are never required for success.
111
+
112
+ Additive surface:
113
+
114
+ | Change | Behavior |
115
+ | --- | --- |
116
+ | `applyDefaultProviderRequestOptions` | Fill-if-missing `sessionId`/`cacheKey`; default `{ system_prompt, last_stable_message }` + `cacheRetention: "short"` on `cache_control` / `explicitBreakpoints` models |
117
+ | `AgentConfig.thinkingLevel` / `RunOptions.thinkingLevel` | Session thinking intent (run overrides agent); snapped via `applyThinkingLevelForModel` |
118
+ | `ProviderRequirementError` (`ERR_PRISM_PROVIDER_REQUIREMENT`) | OpenCode Go throws **before fetch** when `sessionId`/`cacheKey` is missing — not an opaque upstream 400. Message has no request body. |
119
+ | OM vs compaction ids | Observational-memory workers use derived `om:{session.id}`; LLM compaction uses the agent session id |
120
+
121
+ What to do:
122
+
123
+ 1. You can drop `createSessionCachePolicy()` from Clay / host agent config if it existed only to inject session correlation.
124
+ 2. Prefer `createAgent({ thinkingLevel: "low" })` over hand-merging `providerOptions.compat`.
125
+ 3. Raw `provider.generate()` to OpenCode Go without `options.sessionId` now fails closed with `ProviderRequirementError` instead of HTTP 400.
126
+ 4. Custom generate sites should call `applyDefaultProviderRequestOptions(request, { sessionId, thinkingLevel })`.
127
+ 5. Nothing persisted changes. Session/cache keys are correlation ids, never secrets.
128
+
108
129
  ## Upgrade steps
109
130
 
110
- 1. Bump every `@arnilo/*` dependency/peer to `^0.5.0`.
131
+ 1. Bump every `@arnilo/*` dependency/peer to `^0.5.1` (0.5.0 hosts: `^0.5.0` still works until you want construction).
111
132
  2. Build; if the compiler flags a removed symbol above, apply the replacement from the table.
112
133
  3. If you host MCP: move SDK imports to the v2 modular packages (section 5).
113
134
  4. If you spawn child processes with ambient env: pass env explicitly (section 2).
114
135
  5. If you construct durable stores: pass the tenant scope (section 2).
115
- 6. If you set thinking levels: move to `applyThinkingLevelForModel` (section 7).
136
+ 6. If you set thinking levels: prefer `AgentConfig.thinkingLevel` / `RunOptions.thinkingLevel` (section 8); `applyThinkingLevelForModel` remains for custom generate sites (section 7).
116
137
  7. Run your suite. No persisted-data migration exists or is needed.
138
+ 8. After 0.5.1: drop host-only `createSessionCachePolicy` if it existed only for OpenCode Go / session headers (section 8).
117
139
 
118
140
  ## Rollback
119
141