@arnilo/prism 0.5.4 → 0.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -0
- package/README.md +10 -10
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/run-limits.js +7 -2
- package/docs/credential-storage.md +1 -1
- package/docs/graft.md +1 -1
- package/docs/{0.1.0-readiness.md → history/0.1.0-readiness.md} +6 -6
- package/docs/history/README.md +11 -0
- package/docs/{migrate-to-0.4.md → history/migrate-to-0.4.md} +4 -4
- package/docs/history/migration-0.0.md +738 -0
- package/docs/history/migration-0.1.md +151 -0
- package/docs/history/migration-0.2.md +173 -0
- package/docs/history/migration-0.3.md +39 -0
- package/docs/history/migration-0.4.md +6 -0
- package/docs/{persistence-credentials-multimodality-primitives.md → history/persistence-credentials-multimodality-primitives.md} +13 -13
- package/docs/history/release-handoffs.md +848 -0
- package/docs/{workflow-orchestration-primitives.md → history/workflow-orchestration-primitives.md} +11 -11
- package/docs/host-security.md +1 -1
- package/docs/index.md +157 -143
- package/docs/migrate-to-0.5.md +1 -1
- package/docs/migration.md +15 -1042
- package/docs/multimodal-content.md +1 -1
- package/docs/performance.md +1 -1
- package/docs/postgres-persistence.md +1 -1
- package/docs/provider-packages.md +20 -20
- package/docs/release-and-install.md +57 -842
- package/docs/runs-and-usage.md +2 -2
- package/docs/session-stores-and-branching.md +1 -122
- package/docs/sqlite-persistence.md +1 -1
- package/docs/workflows.md +1 -1
- package/package.json +1 -1
- /package/docs/{workflow-tui-primitives.md → history/workflow-tui-primitives.md} +0 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# Migration archive — 0.1.x releases
|
|
2
|
+
|
|
3
|
+
## 0.1.7 → 0.2.0 fail-closed runtime and sandbox security (plan 020)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
Release **0.2.0** (plan 020) is the first cut of the 0.2.x review-remediation line: it closes the three security blockers found in the 2026-08-12 comprehensive review. The API surface is **additive-only** (plain compat gate at 0.2.0 shows zero removed/changed declarations; no `--allow-break`), but three behaviors are deliberately tightened for security, so untyped/legacy callers may now fail where 0.1.7 silently proceeded:
|
|
7
|
+
|
|
8
|
+
1. **Durable-resume decision validation (core).** `resumeAgentRun`/`resumeAgentRunStream` (and the lifecycle/resume-stream entrypoints behind them) now validate the resume payload **before any state claim, checkpoint write, or tool execution**. Unknown legacy decisions (anything other than `approve`/`deny`), malformed decision batches, oversized reasons/elicitation, and duplicate approval ids fail closed with a stable `AgentDecisionError` (`ERR_PRISM_DECISION_INVALID`/`ERR_PRISM_DECISION_LIMIT`/`ERR_PRISM_DECISION_DUPLICATE`), leave the checkpoint version untouched, and execute no tool. In 0.1.7 an unknown decision string (e.g. `"sideways"`) was accepted, the checkpoint was CAS-claimed to `running`, and the suspended tool executed. The HTTP server parser (`readAgentDecisions`) is unchanged — it remains defense in depth, not the security boundary.
|
|
9
|
+
|
|
10
|
+
```js
|
|
11
|
+
// 0.2.0: fails closed, no side effect, version untouched
|
|
12
|
+
try {
|
|
13
|
+
await resumeAgentRun(agent, ref, { expectedVersion: v, decision: "sideways" }, opts);
|
|
14
|
+
} catch (error) {
|
|
15
|
+
error.code; // "ERR_PRISM_DECISION_INVALID"
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
2. **Work-tool subprocess environments (`@arnilo/prism-work-tools`).** `createCliRunner` no longer inherits the full host `process.env`. The child environment is now: fixed base allow-list (`PATH`, `LANG`, `LC_ALL`, `TZ`; Windows adds `SYSTEMROOT`/`SystemRoot`/`TEMP`/`TMP`/`PATHEXT`/`COMSPEC`), then explicit validated `options.env`, then forced controls (`HOME` = `configDir`, `CLIMICROSOFT365_DISABLETELEMETRY=1`), then the late-bound per-identity token layer (`M365_ACCESSTOKEN`/`GOOGLE_ACCESS_TOKEN` style). Caps: 64 names / 64 KiB total (`ERR_PRISM_WORK_ENV`). `binary` and `configDir` must now be **absolute paths** (`path.isAbsolute`), and output capture is linear (single final `Buffer.concat`, capped at `maxStdoutBytes`/`maxStderrBytes`). In 0.1.7 the child inherited every ambient host variable.
|
|
20
|
+
|
|
21
|
+
3. **Explicit sandbox capabilities (`@arnilo/prism-coding-security`).** `SandboxAdapter` gains the optional `capabilities` field — `workspaceCoherent`/`filesystemIsolated`/`networkIsolated`/`processIsolated`/`privilegeIsolated`/`egressRestricted` (immutable booleans). Omission or malformed metadata resolves every isolation field `false` (fail-closed). `SandboxCodingComposition` now carries a resolved `capabilities` object; the old boolean `containmentClaim` is **deprecated** and is the conservative projection `workspaceCoherent && filesystemIsolated && networkIsolated && processIsolated`. Built-ins: Docker reports `filesystemIsolated: true`/`processIsolated: true`/`networkIsolated: true` only for `--network=none`/attested networks, `privilegeIsolated: false` by default; native sandbox reports `networkIsolated: true`/`egressRestricted: true` but **never** filesystem/process/privilege isolation. In 0.1.7 any `DisposableSandbox`-shaped adapter could make `containmentClaim` report `true` with no isolation-capability inspection; in 0.2.0 an un-attested adapter claims `workspaceCoherent` at most. Authorization should read the individual capabilities, never the deprecated boolean.
|
|
22
|
+
|
|
23
|
+
**Store compatibility:** 0.2.0 is store-compatible with 0.1.7 in both directions — no persisted-shape change, no migration step. Checkpoint, session-store, approval, and registry payloads are byte-identical; only the resume *input* validation is new.
|
|
24
|
+
|
|
25
|
+
**Rollout:** upgrade core first (resume validation applies immediately to all hosts), then `@arnilo/prism-work-tools` (pass absolute `binary`/`configDir` and any ambient keys your connector needs via `options.env` — the allow-list is deny-by-default by design), then `@arnilo/prism-coding-security` (capability-aware policy code; the deprecated `containmentClaim` keeps working with the stricter semantics).
|
|
26
|
+
|
|
27
|
+
**Rollback risk:** restoring 0.1.7 restores all three defects — rollback is **not** a mitigation. Hosts that must roll back should disable resume side effects and work-tool execution at their own boundary until they can return to 0.2.0.
|
|
28
|
+
|
|
29
|
+
## 0.1.4 → 0.1.5 deprecated-option removal (documented breaking cut)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
Release **0.1.5** (plan 017) removes the deprecated compatibility surface that 0.1.x kept after 0.0.19: the inert provider timeout/retry knobs, the `maxToolRounds` run-option alias, the pre-0.0.19 observational-memory flat keys and worker aliases, the read-tool `autoResizeImages` flag, and the `INIT_PROVIDERS` constant. This is the **documented breaking cut** announced in the 0.1.4 migration section; every other 0.1.x release keeps the compat baseline green. Three roadmap labels from the original 0.1.5 task were corrected during planning and are honored here:
|
|
33
|
+
|
|
34
|
+
1. **`RunOptions.maxToolRounds`** (not `AgentConfig.maxToolRounds`) is the removed alias → use `RunOptions.limits.maxToolRounds`. `AgentConfig.limits.maxToolRounds` and `RunLimits.maxToolRounds` stay supported.
|
|
35
|
+
2. **`ReadToolOptions.autoResizeImages`** is the removed flag; `transformImage` is the supported replacement (the roadmap text had the direction reversed).
|
|
36
|
+
3. **`INIT_PROVIDERS`** is the removed constant; `listInitProviders()` is the supported replacement that remains (the roadmap said to remove `listInitProviders`).
|
|
37
|
+
|
|
38
|
+
### Removed symbols and replacements
|
|
39
|
+
|
|
40
|
+
| Removed | Replaced by | Fail-closed behavior |
|
|
41
|
+
| --- | --- | --- |
|
|
42
|
+
| `ProviderRequestOptions.timeoutMs` | `ProviderRequest.signal` / `RunOptions.signal` (host-side abort) | removed from the type; untyped callers are refused with a `TypeError` naming the replacement before any provider call |
|
|
43
|
+
| `ProviderRequestOptions.maxRetries` | `AgentConfig.retry` / `RunOptions.retry` | same |
|
|
44
|
+
| `ProviderRequestOptions.maxRetryDelayMs` | `AgentConfig.retry` / `RunOptions.retry` | same |
|
|
45
|
+
| `RunOptions.maxToolRounds` | `RunOptions.limits.maxToolRounds` | removed from the type; untyped `{ maxToolRounds }` run input is refused before the agent starts |
|
|
46
|
+
| `ObservationalMemorySettingsInput.observeAfterTokens` | `observation.messageTokens` | flat key removed from the type; settings-provider JSON or untyped overrides carrying it throw a `TypeError` naming the nested replacement before any worker/provider call, compaction, or session append |
|
|
47
|
+
| `ObservationalMemorySettingsInput.reflectAfterTokens` | `reflection.observationTokens` | same |
|
|
48
|
+
| `ObservationalMemorySettingsInput.compactAfterTokens` | `context.compactAfterTokens` | same |
|
|
49
|
+
| `ObservationalMemorySettingsInput.keepRecentEntries` | `context.recentMessages` | same |
|
|
50
|
+
| `ObservationalMemorySettingsInput.recentMessageMaxTokens` | `context.recentMessageMaxTokens` | same |
|
|
51
|
+
| `ObservationalMemorySettingsInput.observationsPoolMaxTokens` | `context.observationsPoolMaxTokens` | same |
|
|
52
|
+
| `ObservationalMemorySettingsInput.observationsPoolTargetTokens` | `context.observationsPoolTargetTokens` | same |
|
|
53
|
+
| `ObservationalMemorySettingsInput.workerModel` | `observation.model` / `reflection.model` / `dropper.model` | same |
|
|
54
|
+
| `ObservationalMemorySettingsInput.thinkingLevel` | `observation.thinkingLevel` / `reflection.thinkingLevel` / `dropper.thinkingLevel` | same |
|
|
55
|
+
| `ObservationalMemorySettingsInput.requireExplicitModel` | `observation.requireExplicitModel` / `reflection.requireExplicitModel` / `dropper.requireExplicitModel` | same |
|
|
56
|
+
| `CreateObservationalMemoryOptions.workerProvider` / `workerModel` | `observation.provider` / `observation.model` (and the `reflection` / `dropper` equivalents) | removed from the type; the factories throw synchronously naming the replacement |
|
|
57
|
+
| `ObservationalMemoryRuntimeOptions.workerProvider` / `workerModel` | `observation` / `reflection` / `dropper` worker configs | same |
|
|
58
|
+
| `ReadToolOptions.autoResizeImages` | `transformImage` | removed from the type; `createReadTool` throws naming `transformImage` before any path resolution or filesystem access |
|
|
59
|
+
| `INIT_PROVIDERS` (root export) | `listInitProviders()` | removed; init parsing, usage text, validation, and tests all use the function |
|
|
60
|
+
|
|
61
|
+
### Before / after
|
|
62
|
+
|
|
63
|
+
Provider knobs were inert in first-party providers (hosts were always expected to abort/retry at their own layer):
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
// 0.1.4
|
|
67
|
+
const session = await agent.createSession();
|
|
68
|
+
await session.run("Hi", {
|
|
69
|
+
provider: { timeoutMs: 30_000, maxRetries: 3, maxRetryDelayMs: 250 },
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// 0.1.5
|
|
73
|
+
const session = await agent.createSession();
|
|
74
|
+
await session.run("Hi", {
|
|
75
|
+
retry: { maxAttempts: 3, baseDelayMs: 250 },
|
|
76
|
+
signal: AbortSignal.timeout(30_000),
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
`maxToolRounds` moves into the limits group (the CLI flag `--max-tool-rounds` is unchanged and maps to the nested limit):
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
// 0.1.4
|
|
84
|
+
await session.run("Hi", { maxToolRounds: 2 });
|
|
85
|
+
|
|
86
|
+
// 0.1.5
|
|
87
|
+
await session.run("Hi", { limits: { maxToolRounds: 2 } });
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Observational-memory settings and workers become nested-only (0.0.19 already introduced the nested groups; the flat keys were kept for pre-1.0 hosts):
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
// 0.1.4
|
|
94
|
+
createObservationalMemoryRuntime({
|
|
95
|
+
session,
|
|
96
|
+
appendEntry: (entry) => store.append(entry),
|
|
97
|
+
workerProvider,
|
|
98
|
+
sessionModel: agent.config.model,
|
|
99
|
+
overrides: { observeAfterTokens: 1, thinkingLevel: "low" },
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// 0.1.5
|
|
103
|
+
createObservationalMemoryRuntime({
|
|
104
|
+
session,
|
|
105
|
+
appendEntry: (entry) => store.append(entry),
|
|
106
|
+
observation: { provider: workerProvider, model: { provider: "neuralwatt", model: "glm-5.2-fast" } },
|
|
107
|
+
sessionModel: agent.config.model,
|
|
108
|
+
overrides: { observation: { messageTokens: 1, thinkingLevel: "low" } },
|
|
109
|
+
});
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
The read tool keeps only the host-owned resize callback:
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
// 0.1.4
|
|
116
|
+
createReadTool(cwd, { autoResizeImages: true });
|
|
117
|
+
|
|
118
|
+
// 0.1.5
|
|
119
|
+
createReadTool(cwd, {
|
|
120
|
+
transformImage: async ({ buffer, mimeType }) => resize(buffer, mimeType),
|
|
121
|
+
});
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Dynamic-config refusal behavior
|
|
125
|
+
|
|
126
|
+
Removed members are also removed from the runtime resolver paths, so **untyped** callers (plain JS, `as any`, settings-provider JSON, persisted run input) are caught before any side effect:
|
|
127
|
+
|
|
128
|
+
- Provider request knobs and `maxToolRounds`: refused at the top of the run entry point (`runInternal`) with a `TypeError` naming `RunOptions.limits.maxToolRounds` (or the abort/retry replacement) — before the agent starts, no tool/provider call happens.
|
|
129
|
+
- Observational-memory flat keys: `assertNoRemovedFlatKeys` runs before any worker/provider call, compaction, or session append; it names the first offending key and its nested replacement. The worker aliases are refused synchronously at both factory boundaries.
|
|
130
|
+
- `autoResizeImages`: refused at `createReadTool` construction, before path resolution or `access`/`statFile`/`readFile`.
|
|
131
|
+
- `INIT_PROVIDERS`: reads of the removed constant yield `undefined`; use `listInitProviders()`.
|
|
132
|
+
|
|
133
|
+
### Store compatibility
|
|
134
|
+
|
|
135
|
+
**Compatible — no persisted shape change.** None of the removals touch the session-store schema, run-state checkpoint shape, event schema, or default behavior: the removed options were inert aliases, and the nested replacements resolve to the same active values (e.g. `maxToolRounds` default 8 / hard cap 64 in `DEFAULT_RUN_LIMITS` / `HARD_RUN_LIMITS` are unchanged).
|
|
136
|
+
|
|
137
|
+
### Rollback
|
|
138
|
+
|
|
139
|
+
Restore the 0.1.4 manifests/tag (or revert this commit) — no data migration. Configs and code written against 0.1.5 nested forms also work on 0.1.4 (the nested members are not new in 0.1.5), but `@ts-expect-error`-free code must drop any removed-key usage first. Stores never change.
|
|
140
|
+
|
|
141
|
+
## 0.1.3 → 0.1.4 internal reorganization behind barrel re-exports (no migration)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
Release **0.1.4** (plan 016) is an **internal file reorganization behind barrel re-exports**: the root `src/agents.ts` and `src/contracts.ts` god-modules were split by concern into sibling modules (`contracts-core` / `contracts-run-state` / `contracts-protocol` behind the `contracts.ts` barrel; `agent-session` / `agent-run-lifecycle` / `agent-approval` / `agent-tool-dispatch` / `agent-run-state` / `agent-loops` / `compaction` behind the `agents.ts` barrel). **Public declaration surface unchanged** — the root entry surface is byte-identical to 0.1.3 (zero added/removed/changed on the public entry; the only union-surface additions are 14 internal cross-module helper exports that are not consumer-importable, see `scripts/compat-baseline/arnilo__prism.txt`). The optional `@arnilo/prism-browser` package extends additively with Chrome DevTools Protocol capabilities (0.1.4): `browser_evaluate`, `browser_observe`, and the `block_urls`/`unblock_urls`/`throttle`/`emulate` act actions on Chromium hosts, plus raw `{ css }`/`{ xpath }` targets — new exports and two optional structural interface members only, zero removals. **Store compatibility: compatible** — no persisted shape, event schema, or default behavior changed (no runtime path changed; the split is declaration-level). no migration step; rollback = restore the 0.1.3 manifests/tag (stores never change). The next line, **0.1.5**, is the documented **breaking cut** (deprecated-option removal); its migration section will list the removed symbols (the public-but-unused export candidates from `scripts/dead-exports.mjs`).
|
|
145
|
+
|
|
146
|
+
Release **0.1.3** (plan 015) is the dead-code and deprecation hygiene patch on the frozen 0.1.x line: benchmark-runner consolidation (one parameterized `scripts/benchmark.mjs --scenario <name>` replaces the per-version runners; 16 orphaned `benchmark-0.0.{8..16}` runner/test files removed, all `benchmark-*.json` evidence kept), the 12 `docs/review-coverage-2026-07-*.md` evidence files archived to the tarball-excluded `docs/_evidence/`, a non-blocking unused-code sweep (`npm run sweep:unused`, always exits 0, report to `scripts/unused-sweep-report.txt`), and opt-in checkpoint persistence (`persistSessionState: true` on durable run/resume options persists the loaded-skill name catalog ≤64 names in the run-state checkpoint and restores it on resume — bodies re-resolve from the live registry; `createReadPathSetPersistence` in `@arnilo/prism-coding-agent` persists the read-before-write path set through the host `CheckpointStore`, ≤1024 paths, ownership-scoped). **Store compatibility: compatible** — the persisted run-state schema stays at version 1 (the optional `sessionState` field is absent by default, so 0.1.2 checkpoints parse unchanged and opt-out checkpoints are byte-identical); no upgrade or rollback step exists (rollback = restore the 0.1.2 manifests/tag; stores never change). Declaration surface is additive-only vs the frozen 0.1.x contract (`scripts/compat-baseline` regenerated at 0.1.3 with zero breaking deltas, enforced by `node scripts/release.mjs gate`). No breaking defaults.
|
|
147
|
+
|
|
148
|
+
## 0.1.0 → 0.1.1 post-release hardening (additive, no migration)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
Release **0.1.1** (plan 013) is a hardening patch on the frozen 0.1.x line: five scoped fixes — build single-flight (`npm run clean` removed from `npm run build`, standalone), deterministic MCP SSE relay test (`relayStatelessBody` internal export in `@arnilo/prism-mcp`, not in the package entry surface), combined core + workspace coverage summary (`scripts/coverage-summary.mjs`), canonical manifest-count narrative (49 publishable manifests = root + 48 workspace packages), and ACP modes/config ownership-scoped persistence guidance (the agent never persists `modeId`/`configValues`; host stores MUST key by `sessions.ownership`). **Store compatibility: compatible** — no persisted shape, event schema, or default behavior changed; the 0.0.28 → 0.1.0 → 0.1.1 lines all stay on the same checksum-protected contract, so no upgrade or rollback step exists (rollback = restore the 0.1.0 manifests/tag; stores never change). Declaration surface is additive-only vs the frozen 0.1.x contract (`scripts/compat-baseline` regenerated at 0.1.1 with zero breaking deltas, enforced by `node scripts/release.mjs gate`). No breaking defaults.
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# Migration archive — 0.2.x releases
|
|
2
|
+
|
|
3
|
+
## 0.2.9 → 0.3.0 lockstep cut and independent package versions (additive)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
Release **0.3.0** is the final lockstep cut on the 0.3.x line: all 57 publishable manifests move from `0.2.9` to `0.3.0`, then internal first-party `dependencies`, `optionalDependencies`, and `peerDependencies` use `^0.3.0`. The package graph is now **Decision B**: changed packages may patch/minor independently inside `>=0.3.0 <0.4.0`; unchanged packages keep their version.
|
|
7
|
+
|
|
8
|
+
- **Release commands:** default `release.mjs check`, `publish`, and `gate` are independent. Use `--lockstep --version 0.3.0` only for the final cut or the one emergency lockstep train. Later publication tags are `@arnilo/<package>@<version>`; a generic `v*` tag does not publish the monorepo.
|
|
9
|
+
- **Consumer installs:** keep first-party peers inside `^0.3.0`. A package at `0.3.1` can be installed with other unchanged `0.3.0` packages; a `0.4.0` package requires the next coordinated peer-range cut.
|
|
10
|
+
- **New optional packages:**
|
|
11
|
+
- `@arnilo/prism-antigravity-agent` delegates autonomous coding sessions to the official `agy` CLI with per-run loopback MCP capability exposure, AG-UI timeline projection, and `--conversation` continuation; host owns binary and `agy login` authentication state; omitted from umbrellas.
|
|
12
|
+
- `@arnilo/prism-computer-use-linux` wraps a host-owned Linux `computer-use-linux` MCP binary. It is Linux-only, deny-by-default through `DeviceAdapter`, outside umbrella profiles, and never auto-connects on import.
|
|
13
|
+
- **Coding/ACP closeouts:** `read.findText`, visible fuzzy edit matches/miss context, ACP editor-buffer filesystem operations, spawnable per-session coding registries, and delete/move result locations are additive and require no store migration. Client filesystem mode remains text-only: image/document reads fail closed and never fall back to host disk.
|
|
14
|
+
|
|
15
|
+
No persisted store migration. Before publication, rollback by restoring the 0.2.9 manifests/tag. After publication, roll forward with an additive 0.3.x package patch; npm unpublish is not a rollback strategy.
|
|
16
|
+
|
|
17
|
+
## 0.2.8 → 0.2.9 provider adoption and behavior packages (additive)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
Release **0.2.9** (plan 029) adds three provider packages, SuperGrok device-code OAuth, `@arnilo/prism-impeccable`, Ponytail 4.9.0 empty-args status, and Caveman v2.1 extra skills. **Additive-only: no exported declaration removed, no persisted 0.2.8 shape repurposed.**
|
|
21
|
+
|
|
22
|
+
- Install `@arnilo/prism-provider-deepseek`, `@arnilo/prism-provider-xai`, or `@arnilo/prism-provider-clinepass` (or `@arnilo/prism-providers`) for the new adapters. SuperGrok login is host-invoked RFC 8628 at `auth.x.ai`; no `XAI_API_KEY` required when OAuth credentials are stored.
|
|
23
|
+
- Bare `/ponytail` now reports current+default mode and does not change mode. Use `/ponytail lite|full|ultra|off` to set mode.
|
|
24
|
+
- Caveman still requires the original seven skills; extra `skills/*/SKILL.md` register. Caveman 2 engine is not a Prism runtime.
|
|
25
|
+
- `@arnilo/prism-impeccable` needs `upstreamPath` to a compiled `SKILL.md`. Not in `prism-all`.
|
|
26
|
+
|
|
27
|
+
No store migration. Rollback = restore the 0.2.8 manifests/tag.
|
|
28
|
+
|
|
29
|
+
## 0.2.7 → 0.2.8 ACP adoption fixes (additive)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
Release **0.2.8** (plan 028) tightens ACP coding-host interop and adds the spawnable `@arnilo/prism-acp-agent` entrypoint. **Additive-only: no exported declaration removed or changed, no persisted 0.2.7 shape repurposed.**
|
|
33
|
+
|
|
34
|
+
Hosts that already speak ACP should re-check these wire behaviors (deny-by-default unchanged unless a new seam is wired):
|
|
35
|
+
|
|
36
|
+
- `usage_update` is omitted when the host cannot report a context window (never `size = used`).
|
|
37
|
+
- A terminal run `error` rejects `session/prompt` with `ERR_PRISM_ACP_RUN` instead of an `Agent error:` transcript chunk.
|
|
38
|
+
- Only boolean config options are advertised; `set_config_option` on a select option fails `ERR_PRISM_ACP_CAPABILITY`.
|
|
39
|
+
- Permission option kinds on the wire are `allow_once` / `allow_always` / `reject_once` / `reject_always`.
|
|
40
|
+
- New optional seams (`sessions.transcript`, `sessions.title`, `commands.list`, `capabilities.usage.contextWindow`, `createCodingToolProjection`, image `toolResult`) emit nothing when unwired.
|
|
41
|
+
|
|
42
|
+
No store migration. Rollback = restore the 0.2.7 manifests/tag. The added exports and `@arnilo/prism-acp-agent` simply disappear.
|
|
43
|
+
|
|
44
|
+
## 0.2.6 → 0.2.7 enterprise ERP production readiness (additive)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
Release **0.2.7** (plan 027) adds the enterprise ERP production-readiness primitives behind optional host-activated seams: the transactional outbox/inbox + bounded dispatcher, the durable saga compensation/reconciliation engine, multi-party separation-of-duties approvals, signed hash-chained audit export with WORM/SIEM sinks, field-level classification + fail-closed redaction, and the deterministic ERP invariant evals. **Additive-only: no exported declaration removed or changed, no persisted 0.2.6 shape repurposed.**
|
|
48
|
+
|
|
49
|
+
New ERP tables use **separate forward-only migrations** (no down migrations exist; production rollback is roll-forward repair only):
|
|
50
|
+
|
|
51
|
+
- `prism_erp_outbox` / `prism_erp_inbox` (migration `004_erp_messaging`, version 4) — transactional outbox/inbox with `FOR UPDATE SKIP LOCKED` claim, `ON CONFLICT DO NOTHING` idempotent append, claim-token CAS, and three partial indexes. Outbox append must run in the caller-owned `PoolClient` transaction with the business mutation (atomicity is the host's responsibility).
|
|
52
|
+
- `prism_erp_approvals` (migration `005_erp_approvals`, version 5) — multi-party approval requests with decisions stored as JSONB, `FOR UPDATE` row locking for atomic quorum recomputation, rejection as any-party veto, expiry checked at every protected transition, and atomic grant consumption in the host transaction.
|
|
53
|
+
|
|
54
|
+
Saga state persists as a surrogate `WorkflowCheckpointRecord` through the existing `WorkflowCheckpointAdapter` (private workflow id `__prism_saga__/<key>`) — no saga-specific SQL or 0.2.6 shape is repurposed. Audit export, field policy, and ERP invariant evals are stateless or in-memory and add no persisted shape. Secret-manager adapters (Vault/AWS/Azure/GCP) stay **deferred** behind the demand gate; no adapter ships and no ambient credential discovery is added.
|
|
55
|
+
|
|
56
|
+
**Rollback notes.** Rollback = restore the 0.2.6 manifests/tag. The two new ERP migrations are forward-only; before downgrading, stop all 0.2.7 workers (outbox dispatcher, saga engine, audit exporter) and drop or ignore the `prism_erp_outbox`/`prism_erp_inbox`/`prism_erp_approvals` tables (they hold no 0.2.6 data). No 0.2.6 persisted shape changed, so an ordinary downgrade is store-safe; the added exports and ERP tables simply disappear. **"ERP production ready" remains blocked until the 0.3.0 live-service matrix is recorded** — this release adds the primitives and the protected journey evidence, not the live-service matrix.
|
|
57
|
+
|
|
58
|
+
## 0.2.5 → 0.2.6 durable recovery, workspaces, and coding-agent readiness (additive)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
Release **0.2.6** (plan 026) adds the coding-agent readiness capabilities behind optional host-activated seams: host-selected PTY backends, the indexed/semantic repository-search seam, the ownership-scoped multi-repository/worktree lifecycle, durable process/ACP recovery, and the patch-review/diagnostics workflow. **Additive-only: no exported declaration removed or changed, no persisted 0.2.5 shape repurposed.**
|
|
62
|
+
|
|
63
|
+
New durable records use **separate versioned checkpoint namespaces**, never the 0.2.5 shapes:
|
|
64
|
+
|
|
65
|
+
- `prism.coding-agent.process.v1` (schemaVersion 1) — managed-process recovery records. Readers reject unknown schema versions and corrupt/foreign records fail closed (dropped, never recovered).
|
|
66
|
+
- `prism.coding-agent.workspace.v1` (schemaVersion 1) — coding workspace lifecycle records.
|
|
67
|
+
- `prism.coding-agent.cancel.v1` (schemaVersion 1) — durable ACP run-cancel markers.
|
|
68
|
+
|
|
69
|
+
`CodingCheckpointMetadata` (schemaVersion 1, `prism.coding-agent`) is **never silently repurposed**; 0.2.5 readers reject unknown schema versions as before.
|
|
70
|
+
|
|
71
|
+
**ACP active-run references (Task 5 decision: additive optional field).** `PersistedAcpSession` gains an optional bounded `activeRun` ref (frozen 512-byte cap) recorded while a durable run is live. The decision recorded here: an additive optional field, not a separate recovery namespace, because the ref is advisory metadata — the authoritative run status is always re-queried from `AgentRunLifecycle.status` at restore time, and 0.2.5 hosts safely ignore the field. `PersistedAcpSession.activeRun` stays optional; 0.2.5 records remain readable and a 0.2.5 host reading a 0.2.6 record does not lose required recovery state (the run state itself lives in the existing `prism.agent-run` records, which are untouched).
|
|
72
|
+
|
|
73
|
+
**Downgrade to 0.2.5** is safe only after stopping 0.2.6 workers/replicas and marking any live 0.2.6 process/workspace records `unknown` (their leases expire within TTL); durable state never serializes a PTY fd, browser context, process object, controller, pending promise, raw terminal output, env, token, or credential, and no exact-process-survival claim is made (attach-if-attested, otherwise unknown).
|
|
74
|
+
|
|
75
|
+
## 0.2.4 → 0.2.5 maintainability and bounded performance (no migration)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
Release **0.2.5** (plan 025) is the maintainability-and-bounded-performance cut: the six remaining implementation god-modules split into cohesive internal family files behind preserved barrels (compat-preserving, no `exports`-map subpath), 21 pure persistence helpers moved into the dependency-free `session-store-codecs` package (ownership scope/assertion, checkpoint stale/encode/decode, branch cursors, lifecycle quota/reason/page-limit, search metadata/clipping, deepFreeze/string-array/throwIfAborted, feedback row mapping), the quadratic per-push `Buffer.concat` loops in language framing and tar parsing became chunk-array readers (linear; caps and fail-closed overflow byte-identical), two internal dead type aliases removed (`PostgresPersistenceCloseOptions`, `SqlitePersistenceCloseOptions` — never re-exported from their adapter indexes), and 76 behavior-backed coverage regressions closed the low-coverage core areas (core 91.43/84.80/91.60 lines/branches/functions). **No runtime contract change and no migration**: no exported declaration was removed or changed (the plain reviewed compat gate at 0.2.5 shows the version literal plus 105 additive internal-helper exports), no persisted shape/schema/default/behavior changed, no new runtime dependency. Store compatibility with 0.2.4: **compatible in both directions** — no migration step; rollback = restore the 0.2.4 manifests/tag (stores never change; the added exports disappear on downgrade). The 20 dead-but-compat-tracked exports deferred from Task 4 are the 0.3.0 breaking-cut removal list (see `docs/_evidence/phase25-dead-exports-triage.md`).
|
|
79
|
+
|
|
80
|
+
## 0.2.3 → 0.2.4 package, documentation, and compatibility truth (plan 024)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
Release **0.2.4** (plan 024) is the package-documentation-and-compatibility-truth cut: umbrella wording now states the manifest closures (`@arnilo/prism-providers` = 11 of 14 first-party provider adapters, omitting Azure/Bedrock/Vertex; `@arnilo/prism-all` = 20 direct / 43 transitive first-party packages with the named omission set), and `scripts/package-truth.json` (generated by `scripts/package-truth.mjs`) is the manifest-derived single source for counts, provider membership, umbrella closures, and profile closures. **Peer-version policy (Decision A — exact pins):** every code package peers the bare exact `@arnilo/prism@0.2.4` version (no range, no `*`); all `@arnilo/prism-*` packages move at the same version (**atomic-upgrade rule** — a partial upgrade fails clearly at install time with npm `ERESOLVE` naming the conflicting peer); the range widens to `^1.0.0` at the 1.x stable release; third-party `@arnilo/prism-*` adapters peer on the documented exact current version (full policy in the release-and-install Extension notes). **No runtime code path, persisted shape, event schema, default, or exported declaration changed** (the plain reviewed compat gate at 0.2.4 shows the version literal only). Store compatibility with 0.2.3: **compatible in both directions** — no migration step; rollback = restore the 0.2.3 manifests/tag.
|
|
84
|
+
|
|
85
|
+
## 0.2.2 → 0.2.3 build, coverage, and release evidence integrity (no migration)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
Release **0.2.3** (plan 023) is a **tooling-and-evidence-only cut**: build serialization (`scripts/with-build-lock.mjs` — one `O_EXCL` lockfile serializing every emit/test leaf so concurrent compilers never expose a partial live `dist/`), corrected workspace coverage denominators (package-local `--test-coverage-include=dist/**`, evidence-based per-package thresholds with `protectedException` durable-leg rows), the machine-auditable release skip manifest (`scripts/release-skip-manifest.mjs` → `scripts/release-evidence.json` with `pass`/`skip`/`blocked`/`protected` states; required surfaces without evidence record `blocked` and fail the release gate), and stabilized quality gates (Biome 2.x `preset` config migration with zero lint diagnostics, deterministic timing-assertion barriers, machine-readable `lint-report.sarif` + `unused-report.json`). **No runtime code path, persisted shape, event schema, default, or exported declaration changed** (the plain compat gate at 0.2.3 shows the version literal only). Store compatibility with 0.2.2: **compatible in both directions** — no migration step; rollback = restore the 0.2.2 manifests/tag (stores never change; rollback reopens only the partial-`dist` race and the polluted coverage denominator, both CI/tooling defects, never data defects).
|
|
89
|
+
|
|
90
|
+
## 0.2.1 → 0.2.2 concurrent state and durability integrity (plan 022)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
Release **0.2.2** (plan 022) makes four concurrency/durability boundaries atomic or fail-loud. The API surface is **additive-only** (plain reviewed compat gate at 0.2.2: expected deltas are the version literal, `ModelRouterStateStore.reserveBudget`/`commitBudget`/`releaseBudget` plus `ModelRouterReservation`/`ModelRouterBudgets.reservationTtlMs`/`ModelRouterLimits.maxRateKeys`/`maxBudgetKeys` (memory + Postgres), `SessionRecord.version` with `appendSession` `expectedVersion`, `EventMultiplexerError` with code `ERR_PRISM_EVENT_MULTIPLEXER_SINGLE_CONSUMER`, and the `@arnilo/prism/testing/state-concurrency-conformance` subpath; no removal, no `--allow-break`). Three of the four changes tighten behavior where 0.2.1 silently accepted a race — concurrent hosts may now see an explicit conflict where 0.2.1 lost an update or oversubscribed a budget:
|
|
94
|
+
|
|
95
|
+
1. **Atomic model-budget reservation (`model-router`, `enterprise-postgres`).** Admission is now reserve/commit/release: `reserveBudget` runs at admission and fails the request when `used + reserved + requested` would exceed the window max, returning `{ reservationId, fencingToken, admitted, retryAfterMs? }`; `commitBudget` applies the actual usage delta at the outcome (an expired reservation still charges the reserved amount with `unknownUsage: true` so a late commit can never disappear from accounting); `releaseBudget` frees an uncommitted reservation. `readBudget`-based admission stays for requests with no per-request cap, and the 0.2.1 post-hoc `addUsage` remains as retrospective accounting only — it is no longer admission authority.
|
|
96
|
+
|
|
97
|
+
```js
|
|
98
|
+
// 0.2.1: readBudget then consumeRate then addUsage — concurrent admissions could collectively oversubscribe
|
|
99
|
+
// 0.2.2: admission reserves the full per-request cap, outcome commits/releases actuals
|
|
100
|
+
const reservation = await store.reserveBudget({
|
|
101
|
+
key: { tenantId, principalId, provider, model },
|
|
102
|
+
tokens: request.maxTokens, costUsd: request.maxCostUsd, // per-request caps, when set
|
|
103
|
+
windowMs: 24 * 60 * 60 * 1000, reservationTtlMs: 60_000,
|
|
104
|
+
});
|
|
105
|
+
if (!reservation.admitted) { /* denied; retry after reservation.retryAfterMs */ }
|
|
106
|
+
// ... run the request ...
|
|
107
|
+
await store.commitBudget({
|
|
108
|
+
key, reservationId: reservation.reservationId,
|
|
109
|
+
fencingToken: reservation.fencingToken, tokens: actualTokens, windowMs: 24 * 60 * 60 * 1000,
|
|
110
|
+
});
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Reservations expire after `reservationTtlMs` (default 60,000 ms, bounded to 31 days) even if a host never commits, so a crashed request cannot hold capacity forever. Rate/budget/circuit key maps are now capped (`maxRateKeys`/`maxBudgetKeys`, default 4,096, hard cap 65,536; circuits stay 1,024/16,384) with LRU eviction on insert; a budget row holding an active reservation is never evicted (the eviction candidates exclude held rows, and if nothing is evictable the insert fails with `ERR_PRISM_MODEL_ROUTER_STATE` `capacity-exhausted`). The durable Postgres store keeps reservations in a new `reservations` JSONB column on `prism_model_router_budgets` (migration 003, forward-only, applied automatically by `applyEnterpriseMigrations`; existing rows are untouched and read as no reservations).
|
|
114
|
+
|
|
115
|
+
2. **Atomic conversation metadata (`session-store-postgres`, `session-store-sqlite`, core `SessionRecord`).** `SessionRecord` gains `version` (fresh rows start at 1; migration 008 backfills legacy 0-version rows to 1) and `appendSession` accepts `expectedVersion`: `0` = create-only, `N > 0` = exact-version CAS update-only, omitted = the 0.2.1 last-write-wins behavior for untyped/legacy callers. A stale write throws `SessionMetadataConflictError` (`metadata_conflict`) carrying only `{ id, expectedVersion, currentVersion }` — never metadata content — and the HTTP server maps it to 409. Concurrent create/branch/archive are now single-statement: the branch `maxActiveBranches` cap is enforced inside the CAS write (a concurrent branch at cap-1 fails its version guard instead of silently dropping the oldest ref), archive wins over a stale concurrent write, and a retention-deleted session is never resurrected (the update arm requires the row to still exist).
|
|
116
|
+
|
|
117
|
+
```js
|
|
118
|
+
// 0.2.1: create could race to the last metadata write; concurrent branch calls could lose a ref
|
|
119
|
+
// 0.2.2: exactly one concurrent writer wins per version; losers get metadata_conflict
|
|
120
|
+
const { version } = await persistence.appendSession({
|
|
121
|
+
id: sessionId, ...ownership, createdAt, updatedAt, metadata: { state: "active" },
|
|
122
|
+
expectedVersion: 0, // create-only: conflict if the session already exists
|
|
123
|
+
});
|
|
124
|
+
try {
|
|
125
|
+
await persistence.appendSession({ ...record, metadata: { state: "archived" }, expectedVersion: version });
|
|
126
|
+
} catch (error) {
|
|
127
|
+
if (error.code === "metadata_conflict") { /* re-read the winning version and retry */ }
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
3. **Single-consumer `EventMultiplexer` (core).** `createEventMultiplexer().subscribe()` now rejects a second concurrent consumer with `EventMultiplexerError` `ERR_PRISM_EVENT_MULTIPLEXER_SINGLE_CONSUMER` instead of parking both consumers on one queue and silently losing events. The slot frees when the active consumer's iterator completes, is `return()`ed at a yield, or the multiplexer closes. Hosts that previously relied on multiple `subscribe()` calls sharing one multiplexer must either serialize consumption or use the event source's own broadcast `subscribe` (agent-events), which still supports multiple subscribers. `createWorkflowEventBus` and the supervisor (the only in-repo consumers) are unaffected — each already uses a single subscriber.
|
|
132
|
+
|
|
133
|
+
4. **Restart-stable NATS durable consumer identity (`session-store-nats`).** The durable consumer name is now exactly `prism_<hmac16 of tenantId|sessionId|runId>` — the 0.2.1 random suffix is gone, so a crashed durable subscribe is reused at its last-acked position by a restarting process (cursor resume, at-least-once). Clean stops still delete the durable consumer (resume then relies on the HMAC-signed cursor); only a crash leaves the consumer in place. Pre-0.2.2 consumers minted with the random suffix (`prism_<digest>_<random>`) are orphaned and reclaimed by the existing `deleteConsumer`/consumer-enumeration cleanup path on the next clean stop of a same-subject subscribe.
|
|
134
|
+
|
|
135
|
+
5. **Bounded, non-durable active-run registries (`workflows`).** The in-process workflow active-run registry is documented as non-durable (no timer, no background service): `registerActiveWorkflowRun` sweeps aborted/leaked entries before every insert and fails closed with `WorkflowRuntimeError` `ERR_PRISM_WORKFLOW_RUN_REGISTRY_OVERFLOW` at the 512 cap instead of evicting a live entry (a live eviction could silently allow a duplicate run). A run whose promise never settles is reclaimed only when it is aborted or the cap forces a sweep — there is no durable recovery of active runs in 0.2.2 (see Further Actions: 0.2.6).
|
|
136
|
+
|
|
137
|
+
**Store compatibility:** 0.2.2 is **not** rollback-compatible with 0.2.1 in the Postgres/SQLite persisted shape: `prism_sessions` gains a `version` column (migration 008) and `prism_model_router_budgets` gains a `reservations` column (enterprise migration 003). Both migrations are forward-only and additive — 0.2.2 code reads 0.2.1 databases correctly after migration (backfill included); a 0.2.1 binary pointed at a 0.2.2 database still works because the new columns are nullable/defaulted, but it will not maintain versions or reservations. The NATS durable-name change touches no persisted data (consumers are runtime state; orphaned 0.2.1 consumers are reclaimed on the next clean stop).
|
|
138
|
+
|
|
139
|
+
**Rollout:** upgrade core and the session stores together (migration 008 runs automatically via the existing checksummed `prism_migrations`; the version column must exist before any host writes CAS updates). Then `enterprise-postgres` (migration 003) and `model-router` (reservation admission can be enabled per-host; hosts that never call `recordUsage` rely on TTL expiry). Then `workflows`/`server` (conversation CAS is transparent to clients except new 409 responses), then `session-store-nats`. Branch/archive callers that intentionally lost races in 0.2.1 must now handle `metadata_conflict` (re-read + retry) where they previously accepted last-write-wins.
|
|
140
|
+
|
|
141
|
+
**Rollback risk:** restoring 0.2.1 against a 0.2.2 database is safe for reads and last-write-wins writes (the new columns are ignored) but silently reopens all four race windows: oversubscription, conversation lost updates, silent multi-subscriber event loss, and non-restart-stable NATS resume. Rollback is therefore only a stopgap, not a mitigation — prefer fixing the failing host on 0.2.2.
|
|
142
|
+
|
|
143
|
+
## 0.2.0 → 0.2.1 provider completion and outbound trust boundaries (plan 021)
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
Release **0.2.1** (plan 021) tightens the streaming-completion, outbound-fetch, and credential/signing/upload boundaries. The API surface is **additive-only** (plain reviewed compat gate at 0.2.1: the only deltas are the version literal and `@arnilo/prism-mcp` transport helpers `boundResponse`/`defaultResolver`/`isLoopbackAddress`/`isLoopbackHostname`/`normalizeHostname`/`raceAbort`/`requestPinned`/`resolvePinnedAddress` becoming re-exports of the lifted core primitives — same names, same signatures, no removal; no `--allow-break`), with five documented security-motivated behavior tightenings. Untyped/legacy callers may now fail where 0.2.0 silently proceeded:
|
|
147
|
+
|
|
148
|
+
1. **Strict stream completion is the shared default (all OpenAI-compatible adapters).** `createOpenAICompatibleProvider` now defaults `strictCompletion: true` — a stream that ends without a `[DONE]` marker AND a choice-level `finish_reason` (EOF, network cut, provider truncation) emits a `ProviderTransportError` (`incomplete_delta`) instead of a successful `providerDone`, and a successful done never fabricates usage. This applies to every inheriting adapter: Azure, Bedrock, Vertex, OpenRouter, ZAI, NeuralWatt (Alibaba/Kimi/Ollama/OpenCode-go had already opted in).
|
|
149
|
+
|
|
150
|
+
```js
|
|
151
|
+
// 0.2.1: truncated stream fails closed
|
|
152
|
+
for await (const event of provider.generate(request)) {
|
|
153
|
+
if (event.type === "error") {
|
|
154
|
+
event.error.code; // "incomplete_delta"
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// explicit opt-out stays available where hosts own truncation detection:
|
|
158
|
+
createOpenAICompatibleProvider({ ..., strictCompletion: false });
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
2. **Bounded success bodies on non-stream JSON endpoints.** `readBoundedResponseJson` (exported from `@arnilo/prism/providers/transport`) replaces unbounded `response.json()` on all model-discovery `/models` calls, NeuralWatt quota, Alibaba embeddings, OpenAI uploads, and the OAuth success paths. Defaults: 65,536-byte UTF-8 ceiling, max JSON depth 32, max properties 4096, caller-supplied shape gate, abort support, secret-redacted errors. Oversized or malformed bodies abort with `ProviderTransportError` `response_body_overflow`/`response_body_shape` instead of buffering unbounded input.
|
|
162
|
+
|
|
163
|
+
3. **DNS-pinned OIDC JWKS, OPA, and content fetches; redirects rejected.** The default fetch paths of `credentials-node` JWKS (`@arnilo/prism-credentials-node/oidc`), `policy` OPA decisions, and core content/media fetches now resolve the hostname once (1–32 addresses), validate every candidate against the SSRF policy, and connect only to a pinned address via a lookup-hook socket (no re-resolution). **3xx redirects are rejected outright** (`MediaContentError` code `redirect`) — a redirected fetch is never re-validated or followed. Private/metadata/loopback addresses fail closed (`MediaContentError` `ssrf_denied`). The MCP transport helpers were lifted to the shared core primitive (`pinnedFetch`, `resolvePinnedAddress`, `requestPinned` from `@arnilo/prism`) with byte-identical behavior and are re-exported from `@arnilo/prism-mcp`.
|
|
164
|
+
|
|
165
|
+
4. **Shared bounded OAuth device/token polling.** Core OpenAI OAuth (`@arnilo/prism-provider-openai`) and `@arnilo/prism-credentials-node` now share `pollDeviceCodeToken` (RFC 8628 poll loop with `authorization_pending` continue, `slow_down` +5 s backoff, expiry deadline, cancellation, bounded success/error reads, fail-closed token-shape gates, `[REDACTED]` secret redaction). No public change — the device/token flows keep their messages and cadence; provider-specific fields stay adapter options.
|
|
166
|
+
|
|
167
|
+
5. **Credential, signing, upload, and cache edge fixes.** (a) Azure and Vertex resolve a rotating/single-use credential **exactly once per request** — the inner provider signs with the same token the wrapper validated (a `CredentialValueSource` is never consumed twice). (b) Bedrock SigV4 canonicalization lowercases and merges duplicate-case request headers last-wins and sorts query parameters by encoded key then value — duplicate-case or reordered input can no longer produce a malformed signature. (c) OpenAI upload cleanup retains a file id until its `DELETE` succeeds — a failed/skipped cleanup leaves the id registered for a retried cleanup instead of leaking the remote file. (d) The cache-telemetry `__overflow__` bucket never carries cost — it reports requests and token totals only, so one model's cost metadata cannot mix into mixed-model overflow tokens.
|
|
168
|
+
|
|
169
|
+
**Store compatibility:** 0.2.1 is store-compatible with 0.2.0 in both directions — no persisted-shape change, no migration step. Checkpoint, session-store, approval, and registry payloads are byte-identical; only fetch/stream/credential behavior changed.
|
|
170
|
+
|
|
171
|
+
**Rollout:** upgrade core first (strict completion and bounded readers apply to all hosts immediately; truncated-stream callers must add `strictCompletion: false` only if they intentionally accept incomplete streams), then `@arnilo/prism-credentials-node` + `@arnilo/prism-policy` (DNS-pinned fetches; ensure JWKS/OPA hosts resolve to public addresses and never redirect), then the provider adapters (Azure/Vertex credential handling, Bedrock signing), then `@arnilo/prism-mcp` (re-export-only change).
|
|
172
|
+
|
|
173
|
+
**Rollback risk:** restoring 0.2.0 restores all five boundary gaps — rollback is **not** a mitigation. Hosts that must roll back should disable truncated-stream acceptance, unbounded-body endpoints, redirect-following fetches, rotating-credential reuse, and upload cleanup at their own boundary until they can return to 0.2.1.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Migration archive — 0.3.x releases
|
|
2
|
+
|
|
3
|
+
## 0.3.3 → 0.4.0 package reorganization (breaking)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
Prism 0.4 consolidates package names into explicit family subpaths. It is a dependency and import-specifier migration, not a persisted-data migration. See the complete [legacy 0.3 → 0.4 guide](migrate-to-0.4.md) for all 54 retired package mappings, profile replacements, optional peers/host binaries, security checks, rollback, and npm legacy-warning behavior.
|
|
7
|
+
|
|
8
|
+
## 0.3.1 → 0.3.2: bounded workflow loop durability (additive, no migration)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
`@arnilo/prism-workflows@0.3.2` adds the bounded `loopNode` durable extension. It adds optional `WorkflowNodeCheckpoint.iterations` records, each carrying `schemaVersion: 1`, a zero-based `iteration`, stable `iterationId`, and bounded/redacted output. Existing `WorkflowCheckpointValue.schemaVersion` remains `1`; older checkpoints without `iterations` remain readable through the legacy `iteration`/`lastOutput` cursor, and older hosts ignore the additive field. No SQL or generic checkpoint-store migration is required. Replay creates a new run and never mutates source iteration evidence. Hosts using saga compensation keep one saga step/aggregate and register per-iteration compensation by `iterationId` in reverse order.
|
|
12
|
+
|
|
13
|
+
This independent package patch freezes budget accounting: `maxNodes` counts declared DAG nodes once, while loop body executions consume only the required hard-capped `maxIterations` budget. Rollback is package-version rollback; no persisted migration is needed.
|
|
14
|
+
|
|
15
|
+
## 0.3.2 → 0.3.3: run-ledger prompt provenance (additive, schema version 9)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
Plan 042 adds an optional typed `promptVersion` ref (`{ name, version, hash }`) to `RunOptions` and `RunRecord`. Hosts resolve a prompt from `@arnilo/prism-prompts` and stamp the run: the ref is copied onto the start/finish ledger records and persisted by the first-party SQLite/PostgreSQL stores as a nullable `prompt_version` JSON column (shared schema migration `009_run_prompt_version`, schema version 8 → 9, forward-only and applied automatically by the adapters' checksummed `prism_migrations`). Strictly additive: unset `promptVersion` produces byte-identical rows and records, legacy rows read back without the field, and no exported declaration was removed. The ref carries identity only (`sha256:` body hash) — prompt bodies stay in the separate `@arnilo/prism-prompts` tables and out of run rows, metadata, and telemetry.
|
|
19
|
+
|
|
20
|
+
## 0.3.2 → 0.3.3: tool progressive disclosure (additive, no migration)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
Plan 041 adds opt-in progressive tool loading to `@arnilo/prism`: `toolsDisclosure` (default `"all"`, byte-identical to previous releases) and `toolsSearch.topK` on `AgentConfig` / `RunOptions`, plus the generated `search_tools` tool in search mode. Strictly additive — no exported declaration removed, no persisted shape repurposed. Durable run state gains an optional `sessionState.activatedToolNames` (names only, capped at 128); stores that ignore it resume exactly as before. Set nothing and behavior is unchanged; see [Tools](../tools.md#tool-disclosure-progressive-tool-loading).
|
|
24
|
+
|
|
25
|
+
## 0.3.1 → 0.3.2 memory package: composite recall scoring (additive, no migration)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
`@arnilo/prism-memory@0.3.2` adds opt-in `RecallOptions.scoring`: sum-normalized similarity/recency/importance blending, with a positive `halfLifeMs` required only when `recencyWeight > 0`. Default recall (no `scoring`) keeps its existing ordering and query count. `MemoryVectorRecord.importance?` persists through an additive nullable `importance REAL` column (`ADD COLUMN IF NOT EXISTS`); legacy NULL rows score neutral `1.0`, so no re-index or data migration is required. At write, hosts may pass a clamped `[0,1]` `entry.importance` or an `importanceFrom` hook over a redacted reflection; it runs once at write, never at recall. Rollback is package-version rollback only: old readers ignore the nullable column, and new readers treat absent values neutrally.
|
|
29
|
+
|
|
30
|
+
## 0.3.0 → 0.3.1 production RAG engine (independent patch)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
Only `@arnilo/prism-rag`, `@arnilo/prism-memory`, and `@arnilo/prism-observability-opentelemetry` move to `0.3.1`. Keep every other first-party package on `^0.3.0` — those ranges already satisfy `0.3.1`.
|
|
34
|
+
|
|
35
|
+
**Required for Embedder implementers.** `Embedder.id` is now a required `readonly id: string` (stable model/deploy identity, ≤256 chars). Hosts that construct their own embedder must set it; `createHashEmbedder` defaults to `"prism-hash-embedder"` and the Alibaba embedder uses `options.model`. `retrieveContext` fails closed with `ERR_PRISM_RAG_EMBEDDER_MISMATCH` when a stored `embedderId` is missing or differs (or dimensions differ). Re-index the source after an embedder/model change. Existing 0.3.0 rows without `embedderId` also fail closed until re-indexed.
|
|
36
|
+
|
|
37
|
+
Everything else is additive and opt-in: `createPostgresVectorStore`, hybrid `lexical` retrieve, `contentHash` skip, heading metadata, generation pointers, `createRagTelemetry`, `createTeiReranker`, multi-scope retrieve (`scopes` — pass `scope` for one corpus or `scopes` for one-or-many exact corpora; `scope` stays valid, both or neither throws). Default `retrieveContext` / `replaceSource` paths without those options stay 0.3.0-compatible (vector-only, single-scope, no skip, no telemetry).
|
|
38
|
+
|
|
39
|
+
Postgres DDL is additive (`IF NOT EXISTS` columns/indexes/tables). 0.3.0 rows remain readable. Rollback = restore the 0.3.0 package versions; no down migration.
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Migration archive — 0.4.x releases
|
|
2
|
+
|
|
3
|
+
## 0.4.x → 0.5.0 lockstep cut (breaking)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
Prism 0.5 (plans 055–065) ships four breaking surfaces: the 27 removed unused exports from the plan 058 sweep (symbol-surface only), the MCP TypeScript SDK v2 module move (plan 063 — hosts importing `@modelcontextprotocol/sdk` directly must move to the modular `client`/`server` 2.0.0 packages), the thinking-effort wire moves (plan 065 — Anthropic `effort` → `output_config.effort`, xAI `reasoning_effort` now sent, snap-on-declared semantics), and the plan 056 hardening behavior changes (tenant-scoped store factories, child env allow-list). Dependency majors (plan 062: pdf-parse 2.4 with Node ≥ 20.16, better-sqlite3 13, keyring 2 with typed locked-store errors) and the CLI real-provider contract (plan 064: explicit `--provider` required, exit 2 when omitted) are behavior changes without import impact. See the complete guide with per-symbol replacements and upgrade steps in [migrate-to-0.5.md](../migrate-to-0.5.md). All 10 publishable manifests bump to `0.5.0` lockstep; internal first-party ranges move `^0.4.0` → `^0.5.0`. Security keeper surface (ownership/checkpoint guards, `secureCompare`, `zeroBuffer`, sandbox path-escape guard, RAG scope guard, MCP content-bounds guard, secret-leak conformance assert) is unchanged.
|
|
@@ -8,7 +8,7 @@ Implementation is **shipped and phase-verified** (Tasks 0–7). Optional package
|
|
|
8
8
|
|
|
9
9
|
## When to use it
|
|
10
10
|
|
|
11
|
-
- **Adapter authors** implementing SQLite/PostgreSQL `SessionStore` + `RunLedger` should start here, then follow [Database persistence](database-persistence.md) and [Session store conformance](session-store-conformance.md).
|
|
11
|
+
- **Adapter authors** implementing SQLite/PostgreSQL `SessionStore` + `RunLedger` should start here, then follow [Database persistence](../database-persistence.md) and [Session store conformance](../session-store-conformance.md).
|
|
12
12
|
- **Host apps** wiring CLI/desktop credential persistence should use the credential seams and package matrix here before choosing `@arnilo/prism-core/credentials/node` backends.
|
|
13
13
|
- **Provider and core authors** extending multimodal input should use the content/resource/capability designs here instead of embedding provider upload IDs in core contracts.
|
|
14
14
|
- **Security reviewers** use the threat model and conformance matrix on this page as the acceptance baseline for Plan 056 Tasks 1–7.
|
|
@@ -289,15 +289,15 @@ See **Threat model summary** and **Performance notes** above. Cross-cutting rule
|
|
|
289
289
|
|
|
290
290
|
## Related APIs
|
|
291
291
|
|
|
292
|
-
- [Database persistence](database-persistence.md): reference schema, indexes, conditional append pattern
|
|
293
|
-
- [Session stores](session-stores.md): runtime `SessionStore` contract and branch handles
|
|
294
|
-
- [Session store conformance](session-store-conformance.md): `assertSessionStoreConforms`
|
|
295
|
-
- [Runs and usage ledger](runs-and-usage.md): `RunLedger` write seam
|
|
296
|
-
- [Node JSONL session store](node-jsonl-session-store.md): dev-only file adapter boundaries
|
|
297
|
-
- [Credentials and redaction](credentials-and-redaction.md): core resolver/OAuth helpers
|
|
298
|
-
- [Security/auth/trust](settings-auth-trust-security.md): trust, permissions, memory credentials
|
|
299
|
-
- [Input and prompt assembly](input-and-prompt-assembly.md): attachments and input layout
|
|
300
|
-
- [Resource loading](resource-loading.md): `ResourceLoader` decode helpers
|
|
301
|
-
- [Model registry](model-registry.md): `ModelCapabilities` metadata
|
|
302
|
-
- [Provider conformance](provider-conformance.md): content preservation and secret leak checks
|
|
303
|
-
- [Review coverage (2026-07-14)](_evidence/review-coverage-2026-07-14.md): traceability for C-005, C-010, C-011
|
|
292
|
+
- [Database persistence](../database-persistence.md): reference schema, indexes, conditional append pattern
|
|
293
|
+
- [Session stores](../session-stores.md): runtime `SessionStore` contract and branch handles
|
|
294
|
+
- [Session store conformance](../session-store-conformance.md): `assertSessionStoreConforms`
|
|
295
|
+
- [Runs and usage ledger](../runs-and-usage.md): `RunLedger` write seam
|
|
296
|
+
- [Node JSONL session store](../node-jsonl-session-store.md): dev-only file adapter boundaries
|
|
297
|
+
- [Credentials and redaction](../credentials-and-redaction.md): core resolver/OAuth helpers
|
|
298
|
+
- [Security/auth/trust](../settings-auth-trust-security.md): trust, permissions, memory credentials
|
|
299
|
+
- [Input and prompt assembly](../input-and-prompt-assembly.md): attachments and input layout
|
|
300
|
+
- [Resource loading](../resource-loading.md): `ResourceLoader` decode helpers
|
|
301
|
+
- [Model registry](../model-registry.md): `ModelCapabilities` metadata
|
|
302
|
+
- [Provider conformance](../provider-conformance.md): content preservation and secret leak checks
|
|
303
|
+
- [Review coverage (2026-07-14)](../_evidence/review-coverage-2026-07-14.md): traceability for C-005, C-010, C-011
|