@arnilo/prism 0.0.13 → 0.0.15

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 (52) hide show
  1. package/CHANGELOG.md +23 -2
  2. package/README.md +9 -2
  3. package/dist/agent-loops.d.ts +4 -0
  4. package/dist/agent-loops.js +16 -3
  5. package/dist/artifacts.d.ts +78 -0
  6. package/dist/artifacts.js +24 -0
  7. package/dist/contracts.d.ts +86 -0
  8. package/dist/contracts.js +8 -0
  9. package/dist/conversations.d.ts +50 -0
  10. package/dist/conversations.js +97 -0
  11. package/dist/credentials.d.ts +14 -0
  12. package/dist/credentials.js +9 -0
  13. package/dist/devices.d.ts +94 -0
  14. package/dist/devices.js +138 -0
  15. package/dist/index.d.ts +12 -6
  16. package/dist/index.js +7 -4
  17. package/dist/provider-events.d.ts +1 -0
  18. package/dist/provider-events.js +3 -0
  19. package/dist/providers/openai-primitives.js +5 -2
  20. package/docs/ag-ui.md +5 -0
  21. package/docs/browser-automation.md +3 -0
  22. package/docs/conversations.md +135 -0
  23. package/docs/credential-storage.md +28 -1
  24. package/docs/credentials-and-redaction.md +2 -0
  25. package/docs/database-persistence.md +5 -1
  26. package/docs/device-adapters.md +97 -0
  27. package/docs/host-security.md +7 -2
  28. package/docs/index.md +24 -19
  29. package/docs/migration.md +50 -1
  30. package/docs/multimodal-content.md +8 -5
  31. package/docs/performance.md +36 -0
  32. package/docs/policy-and-audit.md +1 -0
  33. package/docs/provider-caching.md +12 -0
  34. package/docs/provider-conformance.md +29 -5
  35. package/docs/provider-packages.md +26 -2
  36. package/docs/providers/ai-sdk.md +23 -7
  37. package/docs/providers/alibaba.md +179 -0
  38. package/docs/providers/ollama.md +166 -0
  39. package/docs/providers/openai.md +22 -3
  40. package/docs/rag.md +41 -12
  41. package/docs/release-and-install.md +135 -17
  42. package/docs/resource-loading.md +3 -0
  43. package/docs/review-coverage-2026-07-25-phase-9.md +256 -0
  44. package/docs/review-coverage-2026-07-26-phase-10.md +132 -0
  45. package/docs/server.md +4 -0
  46. package/docs/work-artifacts-and-review.md +100 -0
  47. package/docs/work-connectors.md +5 -1
  48. package/docs/work-tools.md +3 -0
  49. package/docs/workflows.md +4 -0
  50. package/docs/working-and-semantic-memory.md +40 -7
  51. package/package.json +1 -1
  52. package/templates/init/providers.json +22 -0
package/docs/rag.md CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  ## What it does
4
4
 
5
- `@arnilo/prism-rag` is an optional package for deterministic plain-text/Markdown chunking, bounded embedding/vector indexing, filtered semantic retrieval, stable citations, and explicit `ContextProvider` injection. It reuses `Embedder` and `VectorStore` from `@arnilo/prism-memory`; Prism core input assembly is unchanged.
5
+ `@arnilo/prism-rag` is an optional package for deterministic text/Markdown chunking, bounded embedding/vector indexing, atomic scoped source replacement/deletion, focused text/Markdown/HTML/PDF parsing, bounded reranking, ingestion status, attributable citations, content-trust metadata, and explicit `ContextProvider` injection. It reuses `Embedder` and `VectorStore` from `@arnilo/prism-memory`; Prism core input assembly is unchanged.
6
6
 
7
7
  ## When to use it
8
8
 
9
- Use it when a host already owns trusted document text and needs small retrieval primitives without a document framework. Do not use it for PDF/HTML/LaTeX parsing, semantic chunking, metadata extraction agents, reranker pipelines, GraphRAG, crawling, URL fetching, or filesystem discovery.
9
+ Use it when a host needs bounded replacement of one owned source, focused parsing after a host-authorized resource or host-selected web fetch, or a host-selected reranker over a finite candidate set. Do not use it for LaTeX parsing, semantic chunking, metadata extraction agents, a hosted reranker implementation, GraphRAG, crawling, URL fetching outside `@arnilo/prism-web-tools`, or filesystem discovery.
10
10
 
11
11
  ## Inputs / request
12
12
 
@@ -20,6 +20,16 @@ Chunking:
20
20
  | `size` / `overlap` | Character ceiling and repeated context |
21
21
  | `metadata` | JSON metadata copied to every chunk |
22
22
 
23
+ Document lifecycle:
24
+
25
+ | API/field | Meaning |
26
+ | --- | --- |
27
+ | `replaceSource({ sourceId, chunks, store, scope, ... })` | Atomically replaces one source after all bounded embedding succeeds; the store must implement scoped `getBySource()` and `transaction()`. |
28
+ | `deleteSource({ sourceId, store, scope })` | Deletes only matching IDs under exact tenant/resource/corpus scope. |
29
+ | `replaceDocument({ uri, loader, parser, store, scope, ... })` | Loads through a host seam, parses, chunks, and atomically replaces. `sourceId` is required unless loader supplies one. |
30
+ | `DocumentLoader` / `Parser` | Small host-replaceable seams. Root and `@arnilo/prism-rag/loaders` / `@arnilo/prism-rag/parsers` export reference adapters. |
31
+ | `textParser` / `markdownParser` / `htmlParser` / `pdfParser` | UTF-8 text, Markdown, script/style-stripping HTML, and uncompressed-text PDF parsers. |
32
+
23
33
  Index/retrieve:
24
34
 
25
35
  | Field | Required | Meaning |
@@ -29,18 +39,24 @@ Index/retrieve:
29
39
  | `chunks` | indexing | `RagChunk[]` from package chunkers or compatible host parser |
30
40
  | `topK` / `queryCandidates` | retrieval | Returned result count and bounded pre-filter candidates |
31
41
  | `filter` | no | Shallow JSON metadata equality filter |
32
- | `redactor` / `secrets` | no | Redact before embedding, persistence, and injection |
33
- | `signal` | no | Abort embedding, vector operations, and batch progression |
42
+ | `reranker` | no | Host-owned `Reranker` receives redacted bounded `RagHit[]` and must return the same IDs once each, in preferred order. |
43
+ | `maxRerankBytes` / `maxRerankMs` / `rerankConcurrency` | no | Reranker caps; defaults/hard limits are 64/256 KiB, 2/10 s, and 2/8 active calls per reranker object. |
44
+ | `statusStore` | no | `IngestionStatusStore` records per-source pending/indexed/failed/partial byte/chunk progress; use `listIngestionStatus()` for capped exact-scope pages. |
45
+ | `redactor` / `secrets` | no | Redact before embedding, persistence, reranking, and injection |
46
+ | `signal` | no | Abort embedding, vector operations, reranking, and batch progression |
34
47
 
35
48
  ## Outputs / response / events
36
49
 
37
50
  - `chunkText()` / `chunkMarkdown()` return frozen `RagChunk[]` with `sourceId`, zero-based index, offsets, and stable IDs such as `guide#0001`.
38
51
  - `indexChunks()` returns `{ indexed, sourceIds }` after bounded batch upserts.
39
- - `retrieveContext()` returns `{ query, text, hits, citations, truncated }`. Rendered text uses `[citation-id] text` blocks.
52
+ - `replaceSource()` / `deleteSource()` return `{ sourceId, deleted, indexed }`.
53
+ - `replaceDocument()` carries loader parser metadata into chunk metadata; the web loader preserves web-tools citation ID and `untrusted: true`.
54
+ - `retrieveContext()` returns `{ query, trust, text, hits, citations, truncated }`. Every hit/citation carries `{ provenance: { sourceId, chunkId, citationId, provider, retrieval: "vector", retrievedAt }, trust: { untrusted: true, inert: true, injectionCapable: true } }`; `retrievalRank` preserves pre-rerank order. Rendered text uses `[citation-id] text` blocks.
55
+ - `createMemoryIngestionStatusStore()` is a bounded in-memory reference adapter. `listIngestionStatus({ store, scope, limit, cursor })` returns capped status pages; hosts supply durable stores when status must survive process restart.
40
56
  - `createRagContextProvider()` returns one ordinary context provider. Empty queries/results contribute no block.
41
57
  - No events, tools, permissions, provider calls, loaders, or network requests are added.
42
58
 
43
- Default hard ceilings include 1,000/16,384 chunk characters, 100/4,096 overlap, 1,048,576/8,388,608 document characters, 2,048/8,192 chunks, 32/128 embed batch, top-K 5/32, candidates 20/128, result 64/512 KiB, and context 2,000/8,000 estimated tokens.
59
+ Default/hard ceilings include 1,000/16,384 chunk characters, 100/4,096 overlap, 1,048,576/8,388,608 document bytes/chars, 30 s parsing, 256 PDF pages, 2,048/8,192 chunks, 32/128 embed batch, top-K 5/32, candidates 20/128, result 64/512 KiB, context 2,000/8,000 estimated tokens, reranker input 64/256 KiB, reranker wall time 2/10 s, reranker active calls 2/8, and status pages 50/200.
44
60
 
45
61
  ## Request/response example
46
62
 
@@ -51,7 +67,8 @@ Default hard ceilings include 1,000/16,384 chunk characters, 100/4,096 overlap,
51
67
  "topK": 1,
52
68
  "result": {
53
69
  "text": "[security-guide#0001] Recheck policy before side effects.",
54
- "citations": [{ "id": "security-guide#0001", "sourceId": "security-guide" }]
70
+ "trust": { "untrusted": true, "inert": true, "injectionCapable": true },
71
+ "citations": [{ "id": "security-guide#0001", "sourceId": "security-guide", "provenance": { "provider": "host", "retrieval": "vector" } }]
55
72
  }
56
73
  }
57
74
  ```
@@ -61,7 +78,7 @@ Default hard ceilings include 1,000/16,384 chunk characters, 100/4,096 overlap,
61
78
  ```ts
62
79
  import { createAgent, createMockProvider, providerDone, providerTextDelta } from "@arnilo/prism";
63
80
  import { createHashEmbedder, createMemoryVectorStore } from "@arnilo/prism-memory";
64
- import { chunkMarkdown, createRagContextProvider, indexChunks, retrieveContext } from "@arnilo/prism-rag";
81
+ import { chunkMarkdown, createMemoryIngestionStatusStore, createRagContextProvider, indexChunks, listIngestionStatus, retrieveContext } from "@arnilo/prism-rag";
65
82
 
66
83
  const embedder = createHashEmbedder(); // deterministic demo/test helper, not production semantic quality
67
84
  const store = createMemoryVectorStore();
@@ -70,7 +87,9 @@ const chunks = chunkMarkdown("# Approval\n\nRecheck current policy before side e
70
87
  sourceId: "security-guide",
71
88
  metadata: { category: "security" },
72
89
  });
73
- await indexChunks({ chunks, embedder, store, scope });
90
+ const statusStore = createMemoryIngestionStatusStore();
91
+ await indexChunks({ chunks, embedder, store, scope, statusStore });
92
+ // For a replaceable source use `replaceSource`; it keeps previous chunks until embedding succeeds.
74
93
 
75
94
  const found = await retrieveContext("approval policy", {
76
95
  embedder,
@@ -78,7 +97,9 @@ const found = await retrieveContext("approval policy", {
78
97
  scope,
79
98
  topK: 4,
80
99
  filter: { category: "security" },
100
+ reranker: { rerank: async ({ hits }) => [...hits].sort((a, b) => b.score - a.score) },
81
101
  });
102
+ console.log(await listIngestionStatus({ store: statusStore, scope }));
82
103
 
83
104
  const agent = createAgent({
84
105
  model: { provider: "mock", model: "demo" },
@@ -92,9 +113,13 @@ console.log(found.text, await agent.createSession().run("How do approvals work?"
92
113
 
93
114
  - Supply any Phase 7-conforming embedder/vector store, including the in-memory reference or PostgreSQL/pgvector adapter.
94
115
  - Metadata filtering is package-local after a bounded candidate query so existing vector contracts/adapters remain unchanged. Increase `queryCandidates` only when selective filters measurably need it.
116
+ - `Reranker` is a host seam, not a provider integration. Return each redacted candidate ID exactly once; Prism retains canonical hit/provenance/trust fields and exposes `retrievalRank` for diagnostics. Add a hosted reranker only when a host owns its credentials, quota, and retry policy.
117
+ - `IngestionStatusStore` is optional observability storage. It is keyed by exact scope and source ID; use `listIngestionStatus()` rather than an unbounded corpus scan. The reference memory store is process-local; implement the same capped scope behavior for durable status.
95
118
  - `createRagContextProvider()` derives its query from latest user text by default; pass a fixed string or callback for host-controlled query generation.
96
- - Load source text separately with a host-owned `ResourceLoader`. The RAG package intentionally accepts text, not URLs or filesystem paths.
97
- - Package is available directly or through `@arnilo/prism-all`; installation does not create an embedder, vector store, or context provider.
119
+ - `createResourceDocumentLoader({ loader })` calls one host-owned `ResourceLoader`; it scans nothing and performs no filesystem or network I/O itself. Pass the host's permission/trust context to that loader.
120
+ - `createWebFetchDocumentLoader({ fetcher })` accepts an already-configured `@arnilo/prism-web-tools` fetch adapter. It never opens a socket, rejects file/local/private/IP-literal URLs, and carries normalized citation/trust metadata forward. The fetch adapter still owns DNS/SSRF policy.
121
+ - `pdfParser` is deliberately limited to bounded, uncompressed PDF text. Provide a host parser through `Parser` for compressed, scanned, or complex PDFs; do not silently index partial text.
122
+ - Package is available directly or through `@arnilo/prism-all`; installation does not create an embedder, vector store, loader, parser, or context provider.
98
123
 
99
124
  ## Security and performance notes
100
125
 
@@ -102,7 +127,11 @@ console.log(found.text, await agent.createSession().run("How do approvals work?"
102
127
  - Source IDs become citation/storage IDs and must be stable non-secret identifiers. Text and user metadata can be redacted before external embedding and persistence.
103
128
  - Retrieved documents are untrusted inert context. Prompt-injection text cannot activate tools, skills, credentials, permissions, or extensions.
104
129
  - Remote sources must pass existing resource/media trust, SSRF, MIME, and byte policies before their decoded text reaches this package.
105
- - Indexing is bounded per batch and checks abort between embed/upsert operations. A failure can leave completed batches persisted; retry is idempotent for the same stable source/chunk IDs.
130
+ - `replaceSource()` stages every bounded embedding before opening the store transaction. It requires a source-aware transactional store and fails closed rather than pretending generic upserts are atomic. `createMemoryVectorStore()` supplies the reference `getBySource()` / transaction capability; durable stores must implement equivalent exact-scope behavior.
131
+ - `deleteSource()` rechecks every returned record's tenant/resource/corpus and source metadata before delete. Same source IDs in another corpus remain untouched.
132
+ - Parsers enforce byte/page/time caps, abort before and after parsing, decode UTF-8 strictly, and strip HTML script/style content. Parsed and retrieved text remains untrusted inert context; it never gains tool authority.
133
+ - Rerankers receive redacted input under byte/time/concurrency caps. Timeout, abort, unknown/duplicate/missing IDs, oversized input, and reranker failures fail closed; returned objects cannot overwrite Prism provenance/trust fields.
134
+ - Ingestion failure errors are redacted before status storage. Status reads reject foreign scope entries and page-limit violations; status itself creates no permission or tool authority.
106
135
  - Filtering scans at most `queryCandidates` hits; rendering stops at top-K, UTF-8 result bytes, or estimated context-token ceiling.
107
136
 
108
137
  ## Related APIs
@@ -2,13 +2,13 @@
2
2
 
3
3
  ## What it does
4
4
 
5
- Prism is published as one core package, thirty-four first-party capability packages, and six pure-manifest family/profile packages (**41** publishable manifests total). This page describes how they are packed, what each tarball contains, how to install them, the required `@arnilo/prism` peer dependency, the release workflow, and the offline test budget.
5
+ Prism is published as one core package, thirty-six first-party capability packages, and six pure-manifest family/profile packages (**43** publishable manifests total). This page describes how they are packed, what each tarball contains, how to install them, the required `@arnilo/prism` peer dependency, the release workflow, and the offline test budget.
6
6
 
7
7
  Core package:
8
8
 
9
9
  - `@arnilo/prism` — the runtime, contracts, registries, streaming events, CLI (including `prism init`), and the `/docs` hub. `files`: `dist` (with `!dist/__tests__` and `!dist/**/*.map` negations), `docs`, `templates`, `CHANGELOG.md`. `bin`: `prism` -> `dist/cli.js`. `sideEffects`: `["dist/cli.js"]`.
10
10
 
11
- First-party workspace packages (each has non-optional `@arnilo/prism@0.0.13` peer and `sideEffects: false`; RAG also peers on memory, and server also peers on workflows):
11
+ First-party workspace packages (each has non-optional `@arnilo/prism@0.0.15` peer and `sideEffects: false`; RAG also peers on memory, and server also peers on workflows):
12
12
 
13
13
  - `@arnilo/prism-provider-anthropic`, `@arnilo/prism-provider-google`, `@arnilo/prism-provider-openai`, `@arnilo/prism-provider-openrouter`, `@arnilo/prism-provider-kimi`, `@arnilo/prism-provider-zai`, `@arnilo/prism-provider-opencode-go`, `@arnilo/prism-provider-neuralwatt` — provider adapters.
14
14
  - `@arnilo/prism-provider-azure`, `@arnilo/prism-provider-bedrock`, `@arnilo/prism-provider-vertex` — optional enterprise-cloud adapters (Entra/IAM/ADC; separate from consumer Anthropic/Google).
@@ -36,11 +36,11 @@ First-party workspace packages (each has non-optional `@arnilo/prism@0.0.13` pee
36
36
 
37
37
  ### 0.0.12 AG-UI package boundary
38
38
 
39
- `@arnilo/prism-ag-ui` is a publishable optional code package with root AG-UI exports and stable `./acp` sibling, peer `@arnilo/prism@0.0.12`, pinned `@ag-ui/core@0.0.57` / `@agentclientprotocol/sdk@1.3.0`, and no import-time network/listener/run. It is included by `@arnilo/prism-all` only—not `@arnilo/prism-code` or `@arnilo/prism-sdk`—so coding and SDK profiles stay free of UI protocol dependencies.
39
+ `@arnilo/prism-ag-ui` is a publishable optional code package with root AG-UI exports and stable `./acp` sibling, peer `@arnilo/prism@0.0.15`, pinned `@ag-ui/core@0.0.57` / `@agentclientprotocol/sdk@1.3.0`, and no import-time network/listener/run. It is included by `@arnilo/prism-all` only—not `@arnilo/prism-code` or `@arnilo/prism-sdk`—so coding and SDK profiles stay free of UI protocol dependencies.
40
40
 
41
41
  Family/profile packages (pure manifests, no code or `dist`; ship `README.md` and `CHANGELOG.md`; use exact hard `dependencies`):
42
42
 
43
- - `@arnilo/prism-providers` — all nine `@arnilo/prism-provider-*` packages: eight HTTP adapters plus AI SDK interoperability.
43
+ - `@arnilo/prism-providers` — all eleven `@arnilo/prism-provider-*` packages: ten HTTP adapters plus AI SDK interoperability.
44
44
  - `@arnilo/prism-compaction` — both `@arnilo/prism-compaction-*` packages.
45
45
  - `@arnilo/prism-base` — core + compaction family + JSON Schema validator; excludes providers, MCP, native credentials/storage, and coding tools.
46
46
  - `@arnilo/prism-code` — base + coding-agent + coding-security + MCP; providers and persistence remain explicit choices.
@@ -77,9 +77,9 @@ Consumers install the core package for the runtime and add first-party packages
77
77
  | Run the default (network-free) test suite | `npm test` |
78
78
  | Dry-run pack core + every package | `npm run pack:dry-run` |
79
79
  | Local mirror of the release verify gate | `npm run release:dry-run` |
80
- | Validate clean tag/version/ranges and reject registry collisions | `npm run release:check -- --version 0.0.12` |
81
- | Preview deterministic publish order | `npm run release:publish -- --version 0.0.12 --dry-run --allow-dirty --allow-untagged` |
82
- | Resume interrupted tagged publication | `npm run release:publish -- --version 0.0.12 --resume --report release-artifacts/publish-report.json` |
80
+ | Validate clean tag/version/ranges and reject registry collisions | `npm run release:check -- --version 0.0.15` |
81
+ | Preview deterministic publish order | `npm run release:publish -- --version 0.0.15 --dry-run --allow-dirty --allow-untagged` |
82
+ | Resume interrupted tagged publication | `npm run release:publish -- --version 0.0.15 --resume --report release-artifacts/publish-report.json` |
83
83
  | Full SDK readiness gate (typecheck + offline tests + pack) | `npm run sdk:ready` |
84
84
 
85
85
  Public core import specifiers (from the root `exports` map):
@@ -116,7 +116,7 @@ A packed tarball contains only public compiled output and release files:
116
116
  - Code packages ship `README.md`, `LICENSE`, and `CHANGELOG.md`; family/profile packages ship `README.md` and `CHANGELOG.md`.
117
117
  - The core tarball additionally ships the full `docs/` directory (the docs hub) and `templates/init/` used by `prism init`.
118
118
  - `dist/cli.js` and the `bin` link in core.
119
- - **Tarball filenames.** npm strips the `@scope/` prefix, so the core package `@arnilo/prism` produces a tarball named `arnilo-prism-0.0.12.tgz`; first-party packages produce `arnilo-prism-provider-<name>-0.0.12.tgz` / `arnilo-prism-compaction-<name>-0.0.12.tgz` / `arnilo-prism-coding-agent-0.0.12.tgz`; family/profile packages produce `arnilo-prism-{providers,compaction,base,code,sdk,all}-0.0.12.tgz`. The CLI bin name `prism` is unaffected by the package name (`npx prism` still works; npm allows the bin field to differ from the package name).
119
+ - **Tarball filenames.** npm strips the `@scope/` prefix, so the core package `@arnilo/prism` produces a tarball named `arnilo-prism-0.0.15.tgz`; first-party packages produce `arnilo-prism-provider-<name>-0.0.15.tgz` / `arnilo-prism-compaction-<name>-0.0.15.tgz` / `arnilo-prism-coding-agent-0.0.15.tgz`; family/profile packages produce `arnilo-prism-{providers,compaction,base,code,sdk,all}-0.0.15.tgz`. The CLI bin name `prism` is unaffected by the package name (`npx prism` still works; npm allows the bin field to differ from the package name).
120
120
 
121
121
  Excluded from every tarball by `files` negation:
122
122
 
@@ -135,9 +135,9 @@ Excluded from every tarball by `files` negation:
135
135
  "name": "host-app",
136
136
  "type": "module",
137
137
  "dependencies": {
138
- "@arnilo/prism": "0.0.12",
139
- "@arnilo/prism-provider-openai": "0.0.12",
140
- "@arnilo/prism-compaction-observational-memory": "0.0.12"
138
+ "@arnilo/prism": "0.0.15",
139
+ "@arnilo/prism-provider-openai": "0.0.15",
140
+ "@arnilo/prism-compaction-observational-memory": "0.0.15"
141
141
  }
142
142
  }
143
143
  ```
@@ -147,7 +147,7 @@ Installing the provider/compaction packages without `@arnilo/prism` present prod
147
147
  ```text
148
148
  npm error code ERESOLVE
149
149
  npm error Could not resolve dependency:
150
- npm error peer @arnilo/prism@"0.0.12" from @arnilo/prism-provider-openai@0.0.12
150
+ npm error peer @arnilo/prism@"0.0.15" from @arnilo/prism-provider-openai@0.0.15
151
151
  ```
152
152
 
153
153
  ## Implementation example
@@ -180,11 +180,11 @@ For SDK readiness, run the same one-command gate directly. It composes existing
180
180
  npm run sdk:ready
181
181
  ```
182
182
 
183
- Release publication derives all 34 packages from the workspace once, validates exact `0.0.12` manifest/lockfile/internal ranges, then uses deterministic dependency order. `release:check` requires a clean commit tagged `v0.0.12` and rejects any existing registry version. `release:publish --resume` skips only registry versions whose internal dependency fingerprint matches the local manifest; conflicting versions fail closed. Each attempted package is written immediately to the JSON report, so a failed job can rerun safely. `--dry-run` still performs registry availability checks and invokes `npm publish --dry-run` with explicit public access, provenance, and `latest` tag.
183
+ Release publication derives all **43** manifests from the workspace once, validates exact `0.0.15` manifest/lockfile/internal ranges, then uses deterministic dependency order. `release:check` requires a clean commit tagged `v0.0.15` and rejects any existing registry version. `release:publish --resume` skips only registry versions whose internal dependency fingerprint matches the local manifest; conflicting versions fail closed. Each attempted package is written immediately to the JSON report, so a failed job can rerun safely. `--dry-run` performs registry availability checks and invokes `npm publish --dry-run` with explicit public access, provenance, and `latest` tag, but does not publish.
184
184
 
185
185
  ```bash
186
- npm run release:check -- --version 0.0.12
187
- npm run release:publish -- --version 0.0.12 --dry-run --allow-dirty --allow-untagged
186
+ npm run release:check -- --version 0.0.15
187
+ npm run release:publish -- --version 0.0.15 --dry-run --allow-dirty --allow-untagged
188
188
  ```
189
189
 
190
190
  `--allow-dirty` and `--allow-untagged` exist only for local preview; real publication and CI never pass them. npm registry calls occur only in these release preflight/publication commands, never build/test/package discovery.
@@ -195,6 +195,124 @@ Optional live smoke tests stay separate from SDK readiness because they require
195
195
  PRISM_LIVE_PROVIDER_TESTS=1 npm run test --workspaces --if-present
196
196
  ```
197
197
 
198
+ ### 0.0.15 protected live-canary matrix
199
+
200
+ Default `npm test`, `npm run sdk:ready`, and `benchmark-0.0.15` are network-free. Run live rows only from a protected scheduled/release environment (or an explicitly authorized operator workstation); never place credentials in fixtures, benchmark JSON, pull-request jobs, or package scripts. Use least-privilege keys, one bounded request, and retain only redacted aggregate status. A blank **checked-in gate** means Prism deliberately has no generic credential fixture: host owns that provider/account compatibility probe.
201
+
202
+ | Surface | Gate and credential | Checked-in/protected command | Canary scope |
203
+ | --- | --- | --- | --- |
204
+ | OpenAI Responses baseline | `PRISM_LIVE_PROVIDER_TESTS=1` + `OPENAI_API_KEY` | `npm test -w @arnilo/prism-provider-openai` | Bounded text/tool/abort smoke; key never enters events. |
205
+ | OpenAI hosted tools + Realtime | `OPENAI_API_KEY`; protected release harness additionally supplies host-owned safety identifier and hosted-tool entitlement | No generic fixture; record result with the release evidence | Provider-hosted `web_search`/similar execution and Realtime audio/interruption need account-specific availability, so fake transport coverage remains default gate. |
206
+ | AI SDK adapter | Host-selected AI SDK v4 model factory plus its provider credential | No generic fixture; run host integration in protected release environment | Exact `@ai-sdk/provider@4.0.3` mapping/version check; Prism does not own upstream model credentials. |
207
+ | Kimi / Moonshot | `PRISM_LIVE_PROVIDER_TESTS=1` + `KIMI_API_KEY` | `npm test -w @arnilo/prism-provider-kimi` | Coding route; Moonshot entitlement is account-specific. |
208
+ | Z.AI | `PRISM_LIVE_PROVIDER_TESTS=1` + `ZAI_API_KEY` | `npm test -w @arnilo/prism-provider-zai` | GLM stream/tool/reasoning smoke. |
209
+ | OpenRouter | `PRISM_LIVE_PROVIDER_TESTS=1` + `OPENROUTER_API_KEY` | `npm test -w @arnilo/prism-provider-openrouter` | Routed stream/model metadata smoke; host chooses permitted route. |
210
+ | OpenCode Go | `PRISM_LIVE_PROVIDER_TESTS=1` + `OPENCODE_API_KEY` | `npm test -w @arnilo/prism-provider-opencode-go` | OpenAI/Anthropic route selection smoke. |
211
+ | Alibaba DashScope | Alibaba least-privilege API key | No generic fixture; host compatibility probe in protected release environment | Region/preset/catalog entitlement varies; offline serializer and catalog tests remain default gate. |
212
+ | Ollama Cloud/local | Cloud API key or host-local authenticated endpoint | No generic fixture; host compatibility probe in protected release environment | Cloud account and local daemon/model availability are host-owned; no daemon starts during Prism tests. |
213
+ | NeuralWatt | `PRISM_LIVE_PROVIDER_TESTS=1` + `NEURALWATT_API_KEY` | `npm test -w @arnilo/prism-provider-neuralwatt` | Stream/retry/quota telemetry smoke. |
214
+ | Anthropic | `PRISM_LIVE_PROVIDER_TESTS=1` + `ANTHROPIC_API_KEY` | `npm test -w @arnilo/prism-provider-anthropic` | Restricted one-turn provider smoke. |
215
+ | Google | `PRISM_LIVE_PROVIDER_TESTS=1` + `GOOGLE_API_KEY` or `GEMINI_API_KEY` | `npm test -w @arnilo/prism-provider-google` | Restricted one-turn provider smoke. |
216
+ | Memory PostgreSQL/pgvector | `PRISM_TEST_POSTGRES_URL` with `vector` extension | `npm run test:postgres -w @arnilo/prism-memory` | Shared memory conformance, export/rebuild pagination, and finite-vector boundary. |
217
+
218
+ The scheduled/manual `live-canaries` workflow uses protected environment `live-canaries`; release validation uses its protected release environment. Neither workflow receives a broad workspace key. A successful offline benchmark is never evidence that a live row ran; each protected invocation must record its enabled matrix rows and skipped/missing prerequisites.
219
+
220
+ ### 0.0.15 publish handoff
221
+
222
+ **Decision: GO after protected operator prerequisites below.** Phase 10 closes provider, memory, and RAG ecosystem parity without changing the Task 0 package freeze: the exact graph remains **43 publishable manifests**. It adds OpenAI hosted-tool attribution, bounded Responses continuation and Realtime; exact AI SDK V4 mapping; bounded RAG source lifecycle/document adapters/reranking/provenance/trust/status; and memory export/rebuild production conformance. No Studio, Office, remote-browser vendor, additional vector-store, Slack/Teams, voice/desktop-control, internal-auth, or queue package ships. Protected CI, signed tag, npm authentication, OIDC attestation, and protected live-canary evidence remain operator/workflow prerequisites; no package is published by this handoff.
223
+
224
+ ```bash
225
+ git diff --check
226
+ npm ci
227
+ npm run sdk:ready
228
+ node scripts/benchmark-0.0.15.mjs
229
+ node --test scripts/benchmark-0.0.15.test.mjs
230
+ npm audit --audit-level=high
231
+ npm run release:check -- --version 0.0.15 --allow-dirty --allow-untagged --report /tmp/prism-0.0.15-preflight.json
232
+ npm run release:publish -- --version 0.0.15 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.0.15-dry-run.json
233
+ git tag -s v0.0.15 -m "Prism 0.0.15"
234
+ git verify-tag v0.0.15
235
+ git push origin v0.0.15
236
+ ```
237
+
238
+ The dry-run checks every registry collision and executes npm's non-publishing tarball validation for each dependency-ordered manifest. The protected tag workflow alone publishes through `npm run release:publish -- --version "${GITHUB_REF_NAME#v}" --resume --report release-artifacts/publish-report.json`; re-run a failed job for the same tag. `npm audit signatures --json --include-attestations` and artifact checksums remain post-publish checks.
239
+
240
+ #### Rollback limitations
241
+
242
+ npm publication is immutable: partial publication is a resume case, and a confirmed defect requires deprecation plus a fixed version rather than rollback.
243
+
244
+ The 0.0.15 package set is unchanged from the canonical **43-package** list below; `release:check` derives it from the workspace and rejects missing, private, version-skewed, or internally mismatched manifests.
245
+
246
+ ### 0.0.14 publish handoff
247
+
248
+ **Decision: GO after operator prerequisites below.** Phase 9 personal/work-agent conversations, memory consent/lifecycle, durable artifact review + authorized delivery, AG-UI co-work events, scoped M365/GWS OAuth connectors, browser verified-state checkpoints, a deny-by-default device adapter contract, and two new optional provider packages (`@arnilo/prism-provider-alibaba`, `@arnilo/prism-provider-ollama`). The exact 0.0.14 graph has **43 manifests** (41 → 43; only the two provider packages are new, enrolled via `@arnilo/prism-providers`). `@arnilo/prism-code` and `@arnilo/prism-sdk` stay lean; browser/ag-ui/work-tools remain optional. no Office package, Slack/Teams channel package, voice/desktop-control vendor package, internal auth DB, or Redis/SQS queue adapter ships. Clean protected-branch CI, signed commit/tag, npm authentication, OIDC attestation, protected live canaries, and actual publication remain operator/workflow prerequisites.
249
+
250
+ ```bash
251
+ git diff --check
252
+ npm ci
253
+ npm run sdk:ready
254
+ node scripts/benchmark-0.0.14.mjs
255
+ node --test scripts/benchmark-0.0.14.test.mjs
256
+ npm run release:check -- --version 0.0.14 --allow-untagged --report /tmp/prism-0.0.14-preflight.json
257
+ git tag -s v0.0.14 -m "Prism 0.0.14"
258
+ git verify-tag v0.0.14
259
+ git push origin v0.0.14
260
+ ```
261
+
262
+ The tag workflow publishes only through `npm run release:publish -- --version "${GITHUB_REF_NAME#v}" --resume --report release-artifacts/publish-report.json`. Re-run failed jobs for the same tag; registry state is the resumable journal. `npm audit signatures --json --include-attestations` and artifact checksums remain post-publish operator checks.
263
+
264
+ #### Rollback limitations
265
+
266
+ npm publication is immutable: partial publication is a resume case, and confirmed defects require deprecation plus a fixed version rather than rollback.
267
+
268
+ Package set (43):
269
+
270
+ ```text
271
+ @arnilo/prism
272
+ @arnilo/prism-ag-ui
273
+ @arnilo/prism-browser
274
+ @arnilo/prism-coding-agent
275
+ @arnilo/prism-coding-security
276
+ @arnilo/prism-compaction-llm
277
+ @arnilo/prism-compaction-observational-memory
278
+ @arnilo/prism-credentials-node
279
+ @arnilo/prism-evals
280
+ @arnilo/prism-mcp
281
+ @arnilo/prism-memory
282
+ @arnilo/prism-model-router
283
+ @arnilo/prism-observability-opentelemetry
284
+ @arnilo/prism-policy
285
+ @arnilo/prism-all
286
+ @arnilo/prism-base
287
+ @arnilo/prism-code
288
+ @arnilo/prism-compaction
289
+ @arnilo/prism-providers
290
+ @arnilo/prism-sdk
291
+ @arnilo/prism-provider-ai-sdk
292
+ @arnilo/prism-provider-alibaba
293
+ @arnilo/prism-provider-anthropic
294
+ @arnilo/prism-provider-azure
295
+ @arnilo/prism-provider-bedrock
296
+ @arnilo/prism-provider-google
297
+ @arnilo/prism-provider-kimi
298
+ @arnilo/prism-provider-neuralwatt
299
+ @arnilo/prism-provider-ollama
300
+ @arnilo/prism-provider-openai
301
+ @arnilo/prism-provider-opencode-go
302
+ @arnilo/prism-provider-openrouter
303
+ @arnilo/prism-provider-vertex
304
+ @arnilo/prism-provider-zai
305
+ @arnilo/prism-rag
306
+ @arnilo/prism-server
307
+ @arnilo/prism-session-store-postgres
308
+ @arnilo/prism-session-store-sqlite
309
+ @arnilo/prism-supervisor
310
+ @arnilo/prism-tool-validator-json-schema
311
+ @arnilo/prism-web-tools
312
+ @arnilo/prism-work-tools
313
+ @arnilo/prism-workflows
314
+ ```
315
+
198
316
  ### 0.0.13 publish handoff
199
317
 
200
318
  **Decision: GO after operator prerequisites below.** Phase 8 enterprise identity, policy/audit, model governance, Azure/Bedrock/Vertex providers, server deployment seams, persistence schema v5 lifecycle hooks, and M365/GWS work connectors. The exact 0.0.13 graph has **41 manifests**. Phase 8 optional packages (`@arnilo/prism-policy`, `@arnilo/prism-model-router`, enterprise providers, `@arnilo/prism-work-tools`) enroll in `@arnilo/prism-all` only; `@arnilo/prism-code` and `@arnilo/prism-sdk` stay lean. no Office package, 0.0.14 conversation/artifact services, internal auth DB, or Redis/SQS queue adapter ships. Clean protected-branch CI, signed commit/tag, npm authentication, OIDC attestation, protected live canaries, and actual publication remain operator/workflow prerequisites.
@@ -603,8 +721,8 @@ npm publication is not transactional and published versions are immutable. Parti
603
721
 
604
722
  ## Extension and configuration notes
605
723
 
606
- - **Required `@arnilo/prism` peer.** Every first-party code package declares a non-optional `@arnilo/prism@0.0.13` peer (`peerDependenciesMeta` must not mark `@arnilo/prism` optional; other peers such as `playwright-core` may be optional). The range stays pinned to `0.0.13` for the current 0.x release and will widen to `^1.0.0` at the 1.x stable release. Inside the workspace each package also declares `"@arnilo/prism": "file:../.."` in `devDependencies` so `npm install` resolves the peer locally; that devDependency is stripped from consumer installs and is not a runtime dependency.
607
- - **Public access.** All 41 manifests (35 code packages + 6 family/profile packages) declare `"publishConfig": { "access": "public" }`; the publisher also passes `--access public` explicitly because scoped packages otherwise default to restricted on first publish.
724
+ - **Required `@arnilo/prism` peer.** Every first-party code package declares a non-optional `@arnilo/prism@0.0.15` peer (`peerDependenciesMeta` must not mark `@arnilo/prism` optional; other peers such as `playwright-core` may be optional). The range stays pinned to `0.0.15` for the current 0.x release and will widen to `^1.0.0` at the 1.x stable release. Inside the workspace each package also declares `"@arnilo/prism": "file:../.."` in `devDependencies` so `npm install` resolves the peer locally; that devDependency is stripped from consumer installs and is not a runtime dependency.
725
+ - **Public access.** All 43 manifests (37 code packages + 6 family/profile packages) declare `"publishConfig": { "access": "public" }`; the publisher also passes `--access public` explicitly because scoped packages otherwise default to restricted on first publish.
608
726
  - **Map retention knob.** Source maps are emitted locally but stripped from tarballs by `!dist/**/*.map`. Removing that `files` negation ships maps in releases (larger tarballs, better consumer stack traces).
609
727
  - **Release workflow.** `.github/workflows/release.yml` has six jobs. `verify` runs network-free SDK readiness on Node 24; `node20-compat` builds/imports every public root `exports` default target on Node 20 for declared `engines.node >=20` (docs examples need Node >=22.6 native TypeScript stripping); `postgres-integration` uses `pgvector/pgvector:pg16`; `supply-chain` runs high-severity audit, SPDX/license policy, and tracked-source secret scanning; and tag-only `codeql-release` runs SAST. Tag-only `publish` needs all five gates, preserves clean exact-tag/version/topological publication, and alone receives `NPM_TOKEN`, `id-token: write`, and `attestations: write`. Before npm publish it packs all current tarballs, generates checksums plus SPDX, scans unpacked public artifacts, creates GitHub attestations for tarballs and SBOM, then retains artifacts for 30 days. Registry state remains the resumable journal. Local `npm run release:dry-run` remains network-free SDK readiness; local PostgreSQL coverage is `PRISM_TEST_POSTGRES_URL=... npm run test:postgres`.
610
728
  - **Adding a package.** New workspace packages are picked up automatically by `npm run build --workspaces`, `npm test --workspaces`, `npm run pack:dry-run`, the packaging guard (`src/__tests__/packaging.test.ts`), and the install-smoke test (`src/__tests__/install-smoke.test.ts`) via the workspace glob; add the package to both tests' config arrays for explicit per-package assertions.
@@ -87,6 +87,8 @@ console.log(bytes.byteLength, manifest.name, prompt);
87
87
  - Helpers do not choose a loader by URI scheme. Hosts can use contribution registries or their own routing when they need that.
88
88
  - Helpers do not execute loaded text or imported modules. Package activation remains a host decision.
89
89
  - `loadManifestResource()` only validates manifest data; it does not register manifest contributions.
90
+ - `@arnilo/prism-rag` `createResourceDocumentLoader({ loader, context? })` is the RAG bridge for an already-authorized artifact. It calls the supplied `ResourceLoader` once for a caller-selected URI, preserves text/binary media type, and adds no URI routing, local-file discovery, or network fallback. Pair it with a bounded RAG `Parser`; `replaceDocument()` then chunks and atomically replaces one exact RAG source.
91
+ - For public web documents, use `createWebFetchDocumentLoader({ fetcher })` with a host-configured `@arnilo/prism-web-tools` fetch adapter instead of adding web I/O to a `ResourceLoader`. It reuses normalized citation/trust data; the web adapter retains DNS/SSRF policy ownership.
90
92
 
91
93
  ## Security and performance notes
92
94
 
@@ -96,6 +98,7 @@ console.log(bytes.byteLength, manifest.name, prompt);
96
98
  - Helpers call `loader.load()` once per helper call and do not cache, scan, list, watch, poll, or discover packages.
97
99
  - JSON parsing fails closed for invalid JSON or non-object JSON.
98
100
  - Do not put resolved credential values, tokens, headers, or executable code in loaded config, manifests, prompts, skills, or metadata.
101
+ - A RAG resource loader is not permission escalation: pass the same host-owned trust/permission context used for any resource load. HTML/PDF parser output and web content are untrusted inert text; compressed/scanned PDFs require a host parser rather than partial fallback.
99
102
 
100
103
  ## MCP resources
101
104