@arnilo/prism 0.0.3 → 0.0.4
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 +22 -0
- package/README.md +32 -20
- package/dist/agent-loops.d.ts +8 -1
- package/dist/agent-loops.js +57 -11
- package/dist/agents.js +70 -17
- package/dist/checkpoints.d.ts +11 -0
- package/dist/checkpoints.js +144 -0
- package/dist/compaction.js +9 -1
- package/dist/content.d.ts +102 -0
- package/dist/content.js +410 -0
- package/dist/contracts.d.ts +142 -2
- package/dist/event-multiplexer.d.ts +23 -0
- package/dist/event-multiplexer.js +136 -0
- package/dist/execution-policy.d.ts +28 -0
- package/dist/execution-policy.js +24 -0
- package/dist/index.d.ts +17 -5
- package/dist/index.js +11 -4
- package/dist/input.js +11 -1
- package/dist/leases.d.ts +8 -0
- package/dist/leases.js +111 -0
- package/dist/node/agent-definitions.js +3 -5
- package/dist/node/config.d.ts +1 -0
- package/dist/node/config.js +5 -3
- package/dist/node/contribution-discovery.js +5 -8
- package/dist/node/session-store-jsonl.js +8 -5
- package/dist/node/settings.js +2 -2
- package/dist/node/trust.js +2 -4
- package/dist/observability.d.ts +3 -0
- package/dist/observability.js +18 -0
- package/dist/providers/media.d.ts +42 -0
- package/dist/providers/media.js +116 -0
- package/dist/providers/openai-compatible.js +18 -119
- package/dist/providers/openai-primitives.d.ts +9 -0
- package/dist/providers/openai-primitives.js +129 -0
- package/dist/providers/transport.d.ts +40 -0
- package/dist/providers/transport.js +221 -0
- package/dist/redaction.js +40 -13
- package/dist/resources.d.ts +5 -0
- package/dist/resources.js +4 -0
- package/dist/structured-output.d.ts +11 -0
- package/dist/structured-output.js +59 -0
- package/dist/testing/persistence-schema.d.ts +102 -0
- package/dist/testing/persistence-schema.js +457 -0
- package/dist/testing/provider-conformance.js +10 -1
- package/dist/testing/run-ledger-conformance.d.ts +33 -0
- package/dist/testing/run-ledger-conformance.js +172 -0
- package/dist/testing/session-store-conformance.d.ts +16 -0
- package/dist/testing/session-store-conformance.js +73 -0
- package/dist/tools.d.ts +17 -0
- package/dist/tools.js +29 -2
- package/docs/agent-events.md +13 -4
- package/docs/agent-loops.md +10 -4
- package/docs/agent-session-runtime.md +1 -0
- package/docs/cli-rpc.md +3 -0
- package/docs/coding-agent-tools.md +41 -7
- package/docs/coding-security.md +84 -0
- package/docs/credential-storage.md +177 -0
- package/docs/credentials-and-redaction.md +2 -1
- package/docs/database-persistence.md +44 -2
- package/docs/host-security.md +15 -1
- package/docs/index.md +28 -12
- package/docs/input-and-prompt-assembly.md +6 -5
- package/docs/mcp-tools.md +139 -0
- package/docs/middleware-hooks.md +2 -0
- package/docs/migration.md +21 -28
- package/docs/model-registry.md +5 -3
- package/docs/multimodal-content.md +148 -0
- package/docs/observability.md +163 -0
- package/docs/performance.md +40 -1
- package/docs/persistence-credentials-multimodality-primitives.md +303 -0
- package/docs/postgres-persistence.md +141 -0
- package/docs/provider-conformance.md +17 -0
- package/docs/provider-layer.md +1 -1
- package/docs/provider-primitives.md +281 -0
- package/docs/providers/kimi.md +1 -0
- package/docs/providers/neuralwatt.md +1 -0
- package/docs/providers/openai-compatible.md +2 -1
- package/docs/providers/openai.md +8 -1
- package/docs/providers/opencode-go.md +1 -0
- package/docs/providers/openrouter.md +1 -0
- package/docs/providers/zai.md +1 -0
- package/docs/public-contracts.md +9 -2
- package/docs/release-and-install.md +209 -25
- package/docs/resource-loading.md +14 -4
- package/docs/review-coverage-2026-07-14.md +260 -0
- package/docs/run-ledger-conformance.md +96 -0
- package/docs/runs-and-usage.md +2 -0
- package/docs/session-store-conformance.md +16 -0
- package/docs/session-stores-and-branching.md +1 -0
- package/docs/settings-auth-trust-security.md +2 -1
- package/docs/sqlite-persistence.md +122 -0
- package/docs/structured-output.md +9 -0
- package/docs/tool-conformance.md +1 -0
- package/docs/tool-execution-primitives.md +374 -0
- package/docs/tools.md +39 -1
- package/docs/workflow-orchestration-primitives.md +565 -0
- package/docs/workflow-tui-primitives.md +5 -0
- package/docs/workflows.md +219 -0
- package/package.json +33 -5
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Coding execution approval and sandboxing
|
|
2
|
+
|
|
3
|
+
## What it does
|
|
4
|
+
|
|
5
|
+
`@arnilo/prism-coding-security` is an optional package that supplies structured execution policy for `@arnilo/prism-coding-agent` tools. It complements name-based `PermissionPolicy` at dispatch time with path/command context checked **inside** each tool before side effects.
|
|
6
|
+
|
|
7
|
+
| Export | Purpose |
|
|
8
|
+
| --- | --- |
|
|
9
|
+
| `createCodingApprovalPolicy(options)` | Returns an `ExecutionPolicy` with trusted roots, read-only mode, command allow/deny rules, approval caching, and timeout/abort-aware approval waits. |
|
|
10
|
+
| `createSandboxBashOperations(adapter)` | Maps a host-owned `SandboxAdapter` to coding-agent `BashOperations` for delegated shell execution. |
|
|
11
|
+
| `assertPathInsideRoots`, `isPathInsideReal` | Symlink-aware path containment helpers. |
|
|
12
|
+
| `evaluateCommandRules`, `hasShellMetacharacters` | Command classification helpers. |
|
|
13
|
+
|
|
14
|
+
Core contracts live in `@arnilo/prism`:
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
import type { ExecutionAction, ExecutionPolicy, ExecutionDecision } from "@arnilo/prism";
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## When to use it
|
|
21
|
+
|
|
22
|
+
Use this package when coding tools need path scoping, human approval, command rules, or a pluggable sandbox backend. Wire the returned policy through `createCodingTools(cwd, { executionPolicy })` or per-tool `executionPolicy` options.
|
|
23
|
+
|
|
24
|
+
Prism does **not** claim OS-level isolation unless the host provides a sandbox adapter. Default policy denies shell/write/edit without an `approve` callback and rejects paths outside configured roots. Coding shell definitions are marked `exclusive: true`, matching the approval policy's shell decision, so a single-shot turn containing shell work runs sequentially even when `toolConcurrency > 1`. Non-shell turns retain configured parallelism.
|
|
25
|
+
|
|
26
|
+
## Inputs / request
|
|
27
|
+
|
|
28
|
+
| Option | Default | Purpose |
|
|
29
|
+
| --- | --- | --- |
|
|
30
|
+
| `roots` | required | Realpath-contained filesystem roots. |
|
|
31
|
+
| `readOnly` | `false` | Deny shell/write/edit actions. |
|
|
32
|
+
| `commandRules` | `[]` | Ordered allow/deny/approval command classification. |
|
|
33
|
+
| `approve` | none | Host callback for actions not statically allowed; omission fails closed. |
|
|
34
|
+
| `approvalCacheScope` | `"none"` | Optional `run` or `session` decision cache scope. |
|
|
35
|
+
| `approvalTimeoutMs` | `30000` | Bound approval wait; caller abort also cancels it. |
|
|
36
|
+
|
|
37
|
+
## Outputs / response / events
|
|
38
|
+
|
|
39
|
+
`createCodingApprovalPolicy()` returns an `ExecutionPolicy`. Allowed checks return `ExecutionDecision { allowed: true }`; denied checks include a stable reason; shell decisions set `exclusive: true`. Sandbox adapters return coding-agent-compatible `BashOperations` and never grant policy approval themselves.
|
|
40
|
+
|
|
41
|
+
## Request/response example
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
{
|
|
45
|
+
"action": { "kind": "shell", "operation": "execute", "command": "npm test", "paths": [] },
|
|
46
|
+
"decision": { "allowed": true, "exclusive": true }
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Implementation example
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
import { createCodingTools } from "@arnilo/prism-coding-agent";
|
|
54
|
+
import { createCodingApprovalPolicy, createSandboxBashOperations } from "@arnilo/prism-coding-security";
|
|
55
|
+
|
|
56
|
+
const policy = createCodingApprovalPolicy({
|
|
57
|
+
roots: [workspaceRoot],
|
|
58
|
+
approve: async ({ action, signal }) => ui.confirm(action, { signal }),
|
|
59
|
+
approvalCacheScope: "run",
|
|
60
|
+
approvalTimeoutMs: 60_000,
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
const tools = createCodingTools(workspaceRoot, {
|
|
64
|
+
executionPolicy: policy,
|
|
65
|
+
shell: {
|
|
66
|
+
operations: createSandboxBashOperations(mySandboxAdapter),
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Extension and configuration notes
|
|
72
|
+
|
|
73
|
+
Policies are ordinary host values: attach one globally through `createCodingTools()` or per tool. `SandboxAdapter` is replaceable and host-owned; approval policy and sandboxing are separate layers. Use run-scoped approval caching unless a wider host identity/lifecycle is explicit.
|
|
74
|
+
|
|
75
|
+
## Security and performance notes
|
|
76
|
+
|
|
77
|
+
Containment resolves symlinks and rejects paths outside roots. Command rules are not a shell parser; shell metacharacters require approval. Approval waits and subprocess execution honor abort/timeouts. Path checks and cache lookup are local; sandbox latency belongs to the supplied adapter.
|
|
78
|
+
|
|
79
|
+
## Related APIs
|
|
80
|
+
|
|
81
|
+
- [Coding agent tools](coding-agent-tools.md)
|
|
82
|
+
- [Host security guide](host-security.md)
|
|
83
|
+
- [Tool execution primitives](tool-execution-primitives.md)
|
|
84
|
+
- [Security/auth/trust](settings-auth-trust-security.md)
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# Credential storage
|
|
2
|
+
|
|
3
|
+
## What it does
|
|
4
|
+
|
|
5
|
+
The optional `@arnilo/prism-credentials-node` package ships host-owned credential persistence for Node.js CLI and desktop apps:
|
|
6
|
+
|
|
7
|
+
- **Encrypted file store** — AES-256-GCM envelope with scrypt KDF, atomic rename writes, versioned on-disk format
|
|
8
|
+
- **System keychain store** — cross-platform secret service via `@napi-rs/keyring@^1.3.0`
|
|
9
|
+
- **Stored credential resolver** — `createStoredCredentialResolver(store)` for explicit resolver chains
|
|
10
|
+
- **OAuth adapter** — extends the core `OAuthCredentialStore` seam with `get`/`delete` for refresh flows
|
|
11
|
+
|
|
12
|
+
Factories:
|
|
13
|
+
|
|
14
|
+
- `openEncryptedCredentialStore(options)` / `createEncryptedCredentialStore(options)`
|
|
15
|
+
- `createKeychainCredentialStore(options)`
|
|
16
|
+
- `createStoredCredentialResolver(store)`
|
|
17
|
+
- `createOAuthCredentialStoreAdapter(store)`
|
|
18
|
+
- `rotateEncryptedCredentialStorePassphrase(options)`
|
|
19
|
+
|
|
20
|
+
Core `@arnilo/prism` remains storage-free. Hosts choose a backend explicitly at startup; there is no global credential singleton and no silent fallback from keychain to plaintext file storage.
|
|
21
|
+
|
|
22
|
+
## When to use it
|
|
23
|
+
|
|
24
|
+
Use this package when a host needs durable credentials beyond `createMemoryCredentialStore()`:
|
|
25
|
+
|
|
26
|
+
- local CLI tools storing API keys or OAuth tokens between runs
|
|
27
|
+
- desktop hosts integrating with macOS Keychain, Windows Credential Manager, or Linux Secret Service
|
|
28
|
+
- integration tests that need encrypted reopen semantics without a live keychain
|
|
29
|
+
|
|
30
|
+
Do **not** use it when credentials should live in a remote vault, HSM, or cloud secret manager — implement `CredentialResolver` against that service instead.
|
|
31
|
+
|
|
32
|
+
## Inputs / request
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import {
|
|
36
|
+
openEncryptedCredentialStore,
|
|
37
|
+
createKeychainCredentialStore,
|
|
38
|
+
} from "@arnilo/prism-credentials-node";
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Encrypted file
|
|
42
|
+
|
|
43
|
+
| Field | Type | Purpose |
|
|
44
|
+
| --- | --- | --- |
|
|
45
|
+
| `path` | `string` | Vault file path. Parent directories are created as needed. |
|
|
46
|
+
| `getPassphrase` | `() => string \| Promise<string>` | Host-owned passphrase retrieval. Never logged by the adapter. |
|
|
47
|
+
| `scrypt` | `{ N?, r?, p?, keyLength? }` | Optional KDF tuning. Defaults: `N=32768`, `r=8`, `p=1`, `keyLength=32`. Minimum `N=16384`. |
|
|
48
|
+
| `fileMode` | `number` | Unix mode for newly written files. Defaults to `0o600`. |
|
|
49
|
+
|
|
50
|
+
### System keychain
|
|
51
|
+
|
|
52
|
+
| Field | Type | Purpose |
|
|
53
|
+
| --- | --- | --- |
|
|
54
|
+
| `service` | `string` | Keychain service name (application identifier). |
|
|
55
|
+
| `namespace` | `string` | Optional prefix separating environments or tenants within one service. |
|
|
56
|
+
| `timeoutMs` | `number` | Operation timeout. Defaults to `5000`. |
|
|
57
|
+
|
|
58
|
+
## Outputs / response / events
|
|
59
|
+
|
|
60
|
+
Both backends implement `StoredCredentialStore`:
|
|
61
|
+
|
|
62
|
+
| Method | Behavior |
|
|
63
|
+
| --- | --- |
|
|
64
|
+
| `set(record)` / `get(request)` / `delete(request)` | Namespaced by `(provider, name)` for API keys and bearer tokens. |
|
|
65
|
+
| `setOAuth(provider, credentials, accountId?)` | Stores OAuth tokens per provider/account. |
|
|
66
|
+
| `getOAuth(provider, accountId?)` / `deleteOAuth(...)` | Reads or removes OAuth rows. |
|
|
67
|
+
| `resolve(request)` | `CredentialResolver` compatibility via `createStoredCredentialResolver`. |
|
|
68
|
+
|
|
69
|
+
Encrypted file stores also expose:
|
|
70
|
+
|
|
71
|
+
- `reload()` — re-read and decrypt from disk
|
|
72
|
+
- `flush()` — force rewrite of the encrypted envelope
|
|
73
|
+
|
|
74
|
+
Errors are explicit and fail closed:
|
|
75
|
+
|
|
76
|
+
| Error | Code | When |
|
|
77
|
+
| --- | --- | --- |
|
|
78
|
+
| `CredentialDecryptError` | `credential_decrypt_failed` | Wrong passphrase or tampered ciphertext |
|
|
79
|
+
| `CredentialStoreLockedError` | `credential_store_locked` | Keychain denied or locked |
|
|
80
|
+
| `CredentialStoreUnavailableError` | `credential_store_unavailable` | No OS secret service |
|
|
81
|
+
| `CredentialStoreTimeoutError` | `credential_store_timeout` | Keychain call exceeded `timeoutMs` |
|
|
82
|
+
| `WeakKdfParametersError` | `weak_kdf_parameters` | scrypt work factor below minimum |
|
|
83
|
+
|
|
84
|
+
## Request/response example
|
|
85
|
+
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"path": "./credentials.vault",
|
|
89
|
+
"fileMode": 384,
|
|
90
|
+
"keychain": {
|
|
91
|
+
"service": "my-app",
|
|
92
|
+
"namespace": "production",
|
|
93
|
+
"timeoutMs": 5000
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
On-disk envelope (illustrative — ciphertext is base64, secrets are not plaintext):
|
|
99
|
+
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"version": 1,
|
|
103
|
+
"kdf": { "algorithm": "scrypt", "N": 32768, "r": 8, "p": 1, "salt": "...", "keyLength": 32 },
|
|
104
|
+
"cipher": { "algorithm": "aes-256-gcm", "iv": "..." },
|
|
105
|
+
"ciphertext": "..."
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Implementation example
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
import {
|
|
113
|
+
createExplicitCredentialResolver,
|
|
114
|
+
refreshOAuthCredential,
|
|
115
|
+
resolveCredentialValue,
|
|
116
|
+
} from "@arnilo/prism";
|
|
117
|
+
import {
|
|
118
|
+
createOAuthCredentialStoreAdapter,
|
|
119
|
+
createStoredCredentialResolver,
|
|
120
|
+
openEncryptedCredentialStore,
|
|
121
|
+
} from "@arnilo/prism-credentials-node";
|
|
122
|
+
|
|
123
|
+
const store = await openEncryptedCredentialStore({
|
|
124
|
+
path: "./credentials.vault",
|
|
125
|
+
getPassphrase: () => process.env.MY_APP_CREDENTIAL_PASSPHRASE!,
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
const resolver = createExplicitCredentialResolver([
|
|
129
|
+
{ name: "stored", resolver: createStoredCredentialResolver(store) },
|
|
130
|
+
]);
|
|
131
|
+
|
|
132
|
+
const apiKey = await resolveCredentialValue(resolver, { name: "apiKey", provider: "demo" });
|
|
133
|
+
|
|
134
|
+
const oauthStore = createOAuthCredentialStoreAdapter(store);
|
|
135
|
+
await refreshOAuthCredential({
|
|
136
|
+
provider: myOAuthProvider,
|
|
137
|
+
credentials: existing,
|
|
138
|
+
store: oauthStore,
|
|
139
|
+
});
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Passphrase rotation:
|
|
143
|
+
|
|
144
|
+
```ts
|
|
145
|
+
import { rotateEncryptedCredentialStorePassphrase } from "@arnilo/prism-credentials-node";
|
|
146
|
+
|
|
147
|
+
await rotateEncryptedCredentialStorePassphrase({
|
|
148
|
+
path: "./credentials.vault",
|
|
149
|
+
getCurrentPassphrase: () => oldPassphrase,
|
|
150
|
+
getNewPassphrase: () => newPassphrase,
|
|
151
|
+
});
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Extension and configuration notes
|
|
155
|
+
|
|
156
|
+
- Passphrase retrieval, TLS, and OS permission prompts remain host-owned.
|
|
157
|
+
- Use distinct `namespace` or vault paths per tenant/environment.
|
|
158
|
+
- Keychain `list()` / `listOAuth()` are intentionally unsupported — enumerate credentials through host configuration instead of scanning the OS store.
|
|
159
|
+
- Combine with `createExplicitCredentialResolver()` so runtime overrides still win over stored values.
|
|
160
|
+
- Wire `createOAuthCredentialStoreAdapter(store)` into `refreshOAuthCredential()` so refreshed tokens persist durably.
|
|
161
|
+
|
|
162
|
+
## Security and performance notes
|
|
163
|
+
|
|
164
|
+
- Authenticated encryption uses Node built-in `aes-256-gcm` and `scrypt`; no extra crypto dependencies for the file backend.
|
|
165
|
+
- Atomic writes use temp file + rename; partial writes cannot replace a valid vault.
|
|
166
|
+
- Derived keys are zeroed after encrypt/decrypt operations where practical.
|
|
167
|
+
- Default scrypt `N=32768` targets interactive CLI unlock; raise `N` for higher security at the cost of unlock latency.
|
|
168
|
+
- Keychain operations honor `timeoutMs` and surface `CredentialStoreTimeoutError` instead of blocking indefinitely.
|
|
169
|
+
- Never log passphrases, derived keys, or decrypted credential payloads. Error messages do not echo secret values.
|
|
170
|
+
- Live keychain tests are opt-in (`PRISM_TEST_KEYCHAIN=1`); default `npm test` stays offline.
|
|
171
|
+
|
|
172
|
+
## Related APIs
|
|
173
|
+
|
|
174
|
+
- [Credentials and redaction](credentials-and-redaction.md): core resolver helpers and `refreshOAuthCredential()`
|
|
175
|
+
- [Security/auth/trust](settings-auth-trust-security.md): host-owned settings/credentials boundaries
|
|
176
|
+
- [Persistence, credentials, and multimodality primitives](persistence-credentials-multimodality-primitives.md): Plan 056 threat model and conformance matrix rows 7–10
|
|
177
|
+
- `@arnilo/prism`: `CredentialResolver`, `OAuthCredentialStore`, `createMemoryCredentialStore()`
|
|
@@ -113,6 +113,7 @@ console.log(error.message);
|
|
|
113
113
|
- `AgentConfig.credentials` is not eagerly resolved, serialized into provider requests/events/stores, or passed to loops/compaction by the core runtime.
|
|
114
114
|
- `resolveCredentialValue()` and `createExplicitCredentialResolver()` do not cache values. Add host-side caching only if a real credential source needs it.
|
|
115
115
|
- `refreshOAuthCredential()` only calls the supplied OAuth provider and optional store; it has no built-in persistence or retry loop.
|
|
116
|
+
- OpenAI Codex device-code OAuth polls inside `createOpenAICodexOAuthProvider().login()` with bounded delays and abort support via `OAuthLoginCallbacks.signal`. Token-endpoint failures redact authorization codes, PKCE verifiers, device/user codes, and access/refresh tokens when those values are known.
|
|
116
117
|
|
|
117
118
|
## Related APIs
|
|
118
119
|
|
|
@@ -121,4 +122,4 @@ console.log(error.message);
|
|
|
121
122
|
- [LLM compaction package](compaction-llm.md): resolves optional summary-provider credentials per compaction call and redacts exact known values.
|
|
122
123
|
- [OpenAI-compatible provider](providers/openai-compatible.md): resolves API keys per request and redacts known values from adapter errors.
|
|
123
124
|
|
|
124
|
-
Phase 10 added `createMemoryCredentialStore()`, `createChainedCredentialResolver()`, and `createSecretRedactor()` for opt-in in-memory auth and runtime redaction. Phase 11 adds OAuth/API-key contracts plus explicit resolver order helpers. Core still has no persistent secret store and does not read environment variables or files for credentials. See [Security/auth/trust](settings-auth-trust-security.md).
|
|
125
|
+
Phase 10 added `createMemoryCredentialStore()`, `createChainedCredentialResolver()`, and `createSecretRedactor()` for opt-in in-memory auth and runtime redaction. Phase 11 adds OAuth/API-key contracts plus explicit resolver order helpers. Core still has no persistent secret store and does not read environment variables or files for credentials. For durable storage, use [`@arnilo/prism-credentials-node`](credential-storage.md) encrypted-file or keychain backends. See [Security/auth/trust](settings-auth-trust-security.md).
|
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
The production persistence contracts describe database-neutral types for durable, multi-tenant storage of Prism sessions, branch handles, session entries, runs, agent-event ledger rows, tool-call rows, usage rows, agent-definition versions, retention policies, and migration records. They also define cursor-paginated query shapes so hosts can implement SQL, NoSQL, or object-store adapters without changing Prism runtime internals.
|
|
6
6
|
|
|
7
|
-
Prism itself does not ship a production database adapter. The built-in `SessionStore` contract (`append` / `list` / optional `get`) remains the runtime seam; `ProductionPersistenceStore` is the optional adapter-facing contract for hosts that need paginated reads, tenant isolation, audit tables, and
|
|
7
|
+
Prism itself does not ship a production database adapter. The built-in `SessionStore` contract (`append` / `list` / optional `get`) remains the runtime seam; `ProductionPersistenceStore` is the optional adapter-facing contract for hosts that need paginated reads, tenant isolation, audit tables, retention, and optional generic `CheckpointStore` / `LeaseStore` capabilities.
|
|
8
|
+
|
|
9
|
+
Plan 056 Task 1 adds dialect-neutral shared primitives under `@arnilo/prism/testing/persistence-schema`, `@arnilo/prism/testing/session-store-conformance`, and `@arnilo/prism/testing/run-ledger-conformance`. Task 2 ships `@arnilo/prism-session-store-sqlite` (see [SQLite persistence](sqlite-persistence.md)); Task 3 ships `@arnilo/prism-session-store-postgres` (see [PostgreSQL persistence](postgres-persistence.md)). Both implement dialect-local SQL against the shared model; Prism core still ships no ORM, driver, or migration runner.
|
|
8
10
|
|
|
9
11
|
## When to use it
|
|
10
12
|
|
|
@@ -184,6 +186,42 @@ The `usage` JSONB stores the `Usage` shape: input/output/total/cache tokens, cos
|
|
|
184
186
|
|
|
185
187
|
Prism does not run migrations; hosts own migration tooling and use this table to record applied changes.
|
|
186
188
|
|
|
189
|
+
## Shared schema model and migration contract
|
|
190
|
+
|
|
191
|
+
Adapter packages import the shared model instead of copying table names piecemeal:
|
|
192
|
+
|
|
193
|
+
```ts
|
|
194
|
+
import {
|
|
195
|
+
createPersistenceSchemaModel,
|
|
196
|
+
createPersistenceMigrationContract,
|
|
197
|
+
assertPersistenceSchemaModel,
|
|
198
|
+
assertAdapterSchemaMatchesModel,
|
|
199
|
+
assertPersistenceQueryPaginationConforms,
|
|
200
|
+
assertTenantScopedQueryIsolation,
|
|
201
|
+
getPersistencePaginationCursors,
|
|
202
|
+
PARAMETERIZED_QUERY_GUIDANCE,
|
|
203
|
+
} from "@arnilo/prism/testing/persistence-schema";
|
|
204
|
+
import { assertSessionStoreConforms, runSessionStoreConformance } from "@arnilo/prism/testing/session-store-conformance";
|
|
205
|
+
import { assertRunLedgerConforms, runRunLedgerConformance } from "@arnilo/prism/testing/run-ledger-conformance";
|
|
206
|
+
|
|
207
|
+
const model = createPersistenceSchemaModel();
|
|
208
|
+
assertPersistenceSchemaModel(model);
|
|
209
|
+
|
|
210
|
+
await runSessionStoreConformance(() => createStore(testDatabase), { exerciseReopen: true });
|
|
211
|
+
await runRunLedgerConformance(() => createLedger(testDatabase), { exerciseReopen: true });
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
| Primitive | Purpose |
|
|
215
|
+
| --- | --- |
|
|
216
|
+
| `PersistenceSchemaModel` | Versioned table/column/index model covering sessions, entries, parent chain, idempotency side table, runs, events, tool calls, usage, tenant columns, and `prism_migrations` |
|
|
217
|
+
| `createPersistenceMigrationContract()` | Strictly increasing migration steps, `prism_migrations` recording, advisory-lock guidance, and least-privilege migration/runtime role guidance |
|
|
218
|
+
| `getPersistencePaginationCursors()` | Indexed `(session_id, timestamp, id)`, `(run_id, sequence)`, `(run_id, recorded_at, id)` cursor shapes that avoid offset scans |
|
|
219
|
+
| `assertPersistenceQueryPaginationConforms()` | Generic cursor pagination fixture for `queryEntries` |
|
|
220
|
+
| `assertTenantScopedQueryIsolation()` | Tenant-filtered reads must not leak rows or primary-id collisions across tenants |
|
|
221
|
+
| `PARAMETERIZED_QUERY_GUIDANCE` | Values are always bound parameters; only validated identifiers may be quoted |
|
|
222
|
+
|
|
223
|
+
Dialect-local SQL remains in optional adapter packages. The shared model is the contract both adapters must satisfy before release.
|
|
224
|
+
|
|
187
225
|
## Adapter readiness checklist
|
|
188
226
|
|
|
189
227
|
Before using a host database adapter in production:
|
|
@@ -382,9 +420,12 @@ const dbStore: ProductionPersistenceStore = {
|
|
|
382
420
|
## Extension and configuration notes
|
|
383
421
|
|
|
384
422
|
- `ProductionPersistenceStore` is an optional extension point. The runtime does not require it.
|
|
385
|
-
-
|
|
423
|
+
- `ProductionPersistenceStore.checkpoints?: CheckpointStore` exposes generic versioned save/load/bounded-list/delete with compare-and-swap and fencing tokens, without workflow vocabulary.
|
|
424
|
+
- `ProductionPersistenceStore.leases?: LeaseStore` exposes atomic acquire/renew/release/get with opaque claim tokens, expiries, ownership scope, and monotonic fencing tokens.
|
|
425
|
+
- Hosts choose the database, schema, transaction, and indexing strategy. The contracts specify query and checkpoint capability shapes.
|
|
386
426
|
- `SessionStore` (`append`/`list`/`get`/optional `readBranchPath`) can be implemented on top of `ProductionPersistenceStore` or kept separate.
|
|
387
427
|
- Cursor values and idempotency keys are host-defined and opaque to Prism.
|
|
428
|
+
- First-party SQLite/PostgreSQL adapters expose `persistence.checkpoints` and `persistence.leases`, backed by package-owned `prism_checkpoints` / `prism_leases` tables. `@arnilo/prism-workflows` consumes them for durable resume and multi-process coordination; workflow code owns no SQL table.
|
|
388
429
|
|
|
389
430
|
## Security and performance notes
|
|
390
431
|
|
|
@@ -405,3 +446,4 @@ const dbStore: ProductionPersistenceStore = {
|
|
|
405
446
|
- [Agent events](agent-events.md): `AgentEvent` variants and redaction.
|
|
406
447
|
- [Tools](tools.md): `ToolResult`, `ToolCallContent`, and tool execution events.
|
|
407
448
|
- [Public contracts](public-contracts.md): full public contract inventory.
|
|
449
|
+
- [Workflows](workflows.md): package-local durable checkpoint adapters on shared SQLite/Postgres handles.
|
package/docs/host-security.md
CHANGED
|
@@ -25,6 +25,7 @@ Start from explicit host inputs. Do not let runtime code discover security state
|
|
|
25
25
|
| Permission decisions | allow/deny rules or approval UI result | `createStaticPermissionPolicy`, `assertPermission()` |
|
|
26
26
|
| Tool allow-list | active tools for this agent/session/run | `createToolRegistry`, `filterTools()`, `dispatchToolCall()` |
|
|
27
27
|
| Tool argument rules | host validator | `AgentConfig.validator`, `RunOptions.validate`, `ToolValidator` |
|
|
28
|
+
| Coding execution policy | path/command approval adapter | `ExecutionPolicy`, `@arnilo/prism-coding-security` |
|
|
28
29
|
| Durable history | host database adapter | `SessionStore`, `assertSessionStoreConforms()` |
|
|
29
30
|
| Durable audit | host ledger adapter | `RunLedger`, `redactRunLedgerRecord()` |
|
|
30
31
|
| Extensions | explicit package imports only | `createExtensionKernel`, `ExtensionAPI` |
|
|
@@ -120,12 +121,25 @@ Wire those values where they matter: provider adapters receive the resolved cred
|
|
|
120
121
|
- Prism does not sandbox host tools, extensions, provider adapters, credential resolvers, or custom middleware. Use OS/container/process isolation when code is untrusted.
|
|
121
122
|
- Redaction is exact known-secret replacement only. It is not arbitrary secret detection, entropy scanning, or DLP.
|
|
122
123
|
- Known secrets must be passed into redactors before data is emitted or persisted. Redact again in host adapters if they transform records after Prism redaction.
|
|
123
|
-
- Tool `parameters` metadata is not
|
|
124
|
+
- Tool `parameters` metadata is not validated by default. Add a `ToolValidator`, use `createToolParameterValidator()` with a schema adapter, or install `@arnilo/prism-tool-validator-json-schema` before side effects.
|
|
125
|
+
- MCP tools from `@arnilo/prism-mcp` are untrusted remote servers. Configure stdio commands and HTTP URLs explicitly; bound output with `maxResultBytes`; register prefixed tools only after trust review. See [MCP client bridge](mcp-tools.md).
|
|
126
|
+
- Coding tools from `@arnilo/prism-coding-agent` accept an optional `ExecutionPolicy` checked inside each tool before side effects. Use `@arnilo/prism-coding-security` for path roots, command rules, and approval caching. Prism does not provide OS sandboxing unless the host supplies a sandbox adapter.
|
|
124
127
|
- Permission checks happen before tool validation and before `tool.execute()`. Middleware cannot grant permission by renaming a tool.
|
|
125
128
|
- Session stores and ledgers receive redacted values when a redactor is active, but durable storage remains host-owned. Enforce tenant/account/user ownership and retention in the database layer.
|
|
126
129
|
- Provider-owned auth/content/session/cache/security headers win over caller headers in adapters that merge headers.
|
|
127
130
|
- Security checks are bounded explicit calls on the active path. Prism adds no hidden global middleware, background workers, watchers, network calls, or filesystem scans.
|
|
128
131
|
|
|
132
|
+
### 0.0.4 release security audit (2026-07-14)
|
|
133
|
+
|
|
134
|
+
- `npm audit --audit-level=high`: 0 vulnerabilities at every severity.
|
|
135
|
+
- Lockfile: 162 registry dependency records, all with `resolved` provenance URL and integrity hash; `npm ls --all` reports a clean graph.
|
|
136
|
+
- License inventory: 160 locked third-party packages; all declare permissive MIT, ISC, BSD, Apache-2.0, or compatible dual licenses. No GPL, AGPL, SSPL, or missing lockfile license metadata.
|
|
137
|
+
- Install scripts: only `better-sqlite3@12.11.1` runs an install script (`prebuild-install || node-gyp rebuild --release`), required by the explicitly installed SQLite adapter. Core and other optional packages add no install hook.
|
|
138
|
+
- Secret scan: source, tests, docs, workflow files, package metadata, built tests, packed-install canary, and tarball deny-list checks found no private-key block or common live-token prefix. Runtime redaction fixtures cover requests, events, ledgers, stores, checkpoints, provider/OAuth errors, and credential ciphertext.
|
|
139
|
+
- Threat suites pass for parameterized SQL/tenant isolation, HTTP URL/SSRF rejection, realpath/symlink containment, shell-metacharacter approval, schema prototype-pollution/remote-reference bounds, OAuth polling/abort/redaction, credential tamper/wrong-key/KDF floors, MCP result bounds/timeouts, and coding approval/path policy.
|
|
140
|
+
|
|
141
|
+
PostgreSQL TLS/network policy, MCP endpoint allow-listing, provider base URLs, OS keychain availability, process sandboxing, workflow tenant identity, and ANSI/control-sequence sanitization in any host terminal renderer remain host boundaries. Prism 0.0.4 ships JSON-line RPC, not an interactive TUI; hosts must render untrusted model/tool text safely. Credential-gated PostgreSQL/provider/keychain tests are separate operator/CI gates, not silently replaced by mocks.
|
|
142
|
+
|
|
129
143
|
## Related APIs
|
|
130
144
|
|
|
131
145
|
- [Settings, auth, trust, and security controls](settings-auth-trust-security.md): low-level helpers and boundary hardening table.
|
package/docs/index.md
CHANGED
|
@@ -3,16 +3,17 @@
|
|
|
3
3
|
Prism is a TypeScript/Node.js agent harness. Host apps and extension packages own providers, tools, resources, credentials, storage, UI, and business behavior. Prism supplies contracts, registries, streaming events, and replaceable runtime primitives.
|
|
4
4
|
|
|
5
5
|
## Public contracts
|
|
6
|
-
- [Public contracts](public-contracts.md): type shapes for messages,
|
|
6
|
+
- [Public contracts](public-contracts.md): type shapes for messages, agents, tools, stores, generic `CheckpointStore`, atomic `LeaseStore`, bounded `EventMultiplexer`, resources, credentials, and events.
|
|
7
7
|
|
|
8
8
|
## Agent/session runtime
|
|
9
9
|
- [Agent/session runtime](agent-session-runtime.md): create agents and sessions, run prompts, subscribe to normalized events, and see which `AgentConfig` fields are runtime-consumed vs host-owned metadata. Covers tool-call loop transcript shape and prior-reasoning preservation across turns.
|
|
10
10
|
- [Agent definitions](agent-definitions.md): resolve declarative `AgentDefinition` values via `resolveAgentDefinition`, and turn app-config `<configRoot>/agents/<name>/AGENT.md` bundles into runnable agents via `discoverAgentBundles` / `resolveAgentBundle` (explicit tool/skill activation by name, fail-closed omitted capabilities, migration-only `activateAllCapabilities`, strict duplicate scope checks, configurable prompt layers, no auto-discovery).
|
|
11
11
|
- [Agent loops](agent-loops.md): replaceable per-run control loops — `singleShotLoop` default and `generate-validate-revise` with host-supplied `validator`/`parser`/`repairer` callbacks.
|
|
12
|
-
- [Agent events](agent-events.md): the `AgentEvent` stream — agent/turn/message (including live `tool_call_delta` fragments), tool execution, queue/subscriber overflow, compaction/retry, artifact validation/refinement, and error variants, redacted via `redactAgentEvent`.
|
|
12
|
+
- [Agent events](agent-events.md): the `AgentEvent` stream — agent/turn/message (including live `tool_call_delta` fragments), provider turn timing, tool execution, queue/subscriber overflow, compaction/retry, artifact validation/refinement, and error variants, redacted via `redactAgentEvent`.
|
|
13
|
+
- [Observability](observability.md): metadata-only `provider_turn_*` events, `ToolExecutionMetadata`, core helpers, and optional `@arnilo/prism-observability-opentelemetry` adapter.
|
|
13
14
|
- [Runs and usage ledger](runs-and-usage.md): `RunLedger` adapter for durable run, event, tool-call, usage persistence, cache diagnostics, ownership/idempotency, and redaction guidance.
|
|
14
15
|
- [Performance limits](performance.md): bounded live subscriber queues, branch-read pagination expectations, JSONL/dev-store limits, and production sizing assumptions.
|
|
15
|
-
- [Structured output](structured-output.md): the `Artifact*` seam
|
|
16
|
+
- [Structured output](structured-output.md): the `Artifact*` seam plus provider-native `StructuredOutputOptions` / `structuredOutputMode` for capable models.
|
|
16
17
|
|
|
17
18
|
## Compaction/session memory
|
|
18
19
|
- [Compaction and retry policies](compaction-and-retry.md): summarize branch history and retry transient provider failures with host-replaceable policies.
|
|
@@ -20,11 +21,15 @@ Prism is a TypeScript/Node.js agent harness. Host apps and extension packages ow
|
|
|
20
21
|
- [Observational memory compaction package](compaction-observational-memory.md): optional source-backed memory, owned runtime append callback, provider-valid worker transcripts, fast compaction, recall tool, and status/view command package.
|
|
21
22
|
- [Session stores](session-stores.md): `SessionStore` contract, `SessionAppendOptions`, `SessionAppendConflictError`, branch handles, `readBranchPath`, and dev-vs-production branch reads — start here for session persistence.
|
|
22
23
|
- [Session stores and branching](session-stores-and-branching.md): detailed branch semantics and helper reference (kept for compatibility; links back to the canonical atomic append / branch-handle sections).
|
|
23
|
-
- [Database persistence](database-persistence.md): production persistence contracts, conditional append transaction pattern, idempotency indexes, `readBranchPath`, reference relational schema, retention, migrations, and NoSQL mapping.
|
|
24
|
-
- [
|
|
24
|
+
- [Database persistence](database-persistence.md): production persistence contracts, shared schema/migration primitives (`@arnilo/prism/testing/persistence-schema`), conditional append transaction pattern, idempotency indexes, `readBranchPath`, reference relational schema, retention, migrations, and NoSQL mapping.
|
|
25
|
+
- [SQLite persistence](sqlite-persistence.md): optional `@arnilo/prism-session-store-sqlite` adapter — `SessionStore`, `RunLedger`, `ProductionPersistenceStore`, and generic durable checkpoints and atomic leases over `better-sqlite3`.
|
|
26
|
+
- [PostgreSQL persistence](postgres-persistence.md): optional pooled adapter — session/run/query persistence plus generic durable checkpoints and atomic leases over `pg`, with advisory-lock migrations and opt-in live conformance.
|
|
27
|
+
- [Migration guide](migration.md): 0.0.3 compatibility and optional 0.0.4 adoption — first-party/custom database persistence plus explicit fail-closed tool/skill activation.
|
|
25
28
|
- [Node JSONL session store](node-jsonl-session-store.md): development-only JSONL file adapter for single-process Node hosts; no cross-process safety.
|
|
29
|
+
- [Persistence, credentials, and multimodality primitives](persistence-credentials-multimodality-primitives.md): Plan 056 inventory — session/run-ledger/persistence contracts, credential/OAuth seams, content/resource/model capabilities, package dependency matrix, conformance matrix, and threat model for production adapters.
|
|
26
30
|
|
|
27
31
|
## Provider and model connection
|
|
32
|
+
- [Provider primitives](provider-primitives.md): shared bounded transport and OpenAI serialization helpers — migrated across first-party providers; native structured-output and observability contracts.
|
|
28
33
|
- [Provider layer](provider-layer.md): register and resolve host-owned providers/models, choose replace-or-error duplicate policy, create provider events, stream/reconstruct tool-call deltas, use generic provider request options, and test with the mock provider; deprecated provider-level timeout/retry hints point to runtime abort/retry.
|
|
29
34
|
- [Model registry](model-registry.md): register and resolve `ModelConfig` records with capabilities, limits, cost, cache support metadata, compat data, and duplicate policy.
|
|
30
35
|
- [Provider caching](provider-caching.md): use `PromptCacheHints`, `PromptCacheBreakpoint`, `ModelCacheCapabilities`, cache-aware stable-prefix guidance, and shared cache diagnostics helpers; includes a per-provider explicit/implicit cache matrix for OpenAI, OpenRouter, OpenCode Go, Z.AI, Kimi, and NeuralWatt; cache hints are best-effort and cache keys are never secrets.
|
|
@@ -35,17 +40,22 @@ Prism is a TypeScript/Node.js agent harness. Host apps and extension packages ow
|
|
|
35
40
|
|
|
36
41
|
## Input, prompt, and context assembly
|
|
37
42
|
- [SDK customization guide](customization.md): map provider resolution, middleware, context, builders, injectors, loops, compaction, retry, stores, and skills to explicit host-wired APIs.
|
|
38
|
-
- [Input and prompt assembly](input-and-prompt-assembly.md): render tiny prompt templates and turn common host input, history, attachments, explicit resources, summaries, and tool results into messages with replaceable builders, provider-input assembly, legacy default order, and opt-in cache-aware ordering.
|
|
43
|
+
- [Input and prompt assembly](input-and-prompt-assembly.md): render tiny prompt templates and turn common host input, history, attachments, explicit resources, summaries, and tool results into messages with replaceable builders, provider-input assembly, legacy default order, and opt-in cache-aware ordering. Audio/file/document `ContentBlock` types and capability checks are documented there.
|
|
44
|
+
- [Multimodal content](multimodal-content.md): bounded `audio`, `file`, and `document` content blocks, media resolution helpers, SSRF/MIME policy, and `ModelCapabilities.input` tags.
|
|
39
45
|
- [System prompts](system-prompts.md): compose explicit user/package/app/run system prompt layers, auto-load the standard `AGENTS.md` (workspace) / `SYSTEM.md` prompt files via the Node `loadSystemPromptFiles` loader (trust-gated for `AGENTS.md`), and append `SYSTEM.md` → per-agent `AGENT.md` body → repo `AGENTS.md` layers from a discovered agent bundle via `resolveAgentBundle`.
|
|
40
46
|
- [Instruction injection](instruction-injection.md): register package injectors that layer redacted instructions/context blocks without granting tools, permissions, or resource escapes.
|
|
41
47
|
- [Context and skills](context-and-skills.md): resolve ordered context providers and keep context/skill selection host-owned; omitted declarative skills stay inactive by default, `toolNames` fail closed before provider turns, and strict skill registries prevent silent shadowing.
|
|
42
48
|
|
|
43
49
|
## Tools
|
|
44
50
|
- [Tools](tools.md): register host-owned active tools with replace-or-error duplicate policy, apply exact allow/deny filtering, and dispatch tool calls.
|
|
45
|
-
- [
|
|
51
|
+
- [Tool execution primitives](tool-execution-primitives.md): JSON Schema validation, exclusive-aware bounded parallel dispatch, MCP bridge mapping, coding execution policy, and image-read bounds.
|
|
52
|
+
- [Tool validator JSON Schema package](../packages/tool-validator-json-schema/README.md): optional `@arnilo/prism-tool-validator-json-schema` adapter for `tool.parameters`.
|
|
53
|
+
- [MCP client bridge](mcp-tools.md): optional `@arnilo/prism-mcp` package mapping remote MCP tools to `ToolDefinition`s.
|
|
54
|
+
- [Coding agent tools](coding-agent-tools.md): optional first-party package `@arnilo/prism-coding-agent` providing `shell`, `read`, `write`, and `edit` tools (ported from pi) as `ToolDefinition`s a host registers; pluggable operation backends, per-path mutation serialization, optional `ExecutionPolicy`, bounded image reads (`maxImageBytes`, `transformImage`), and read-only/coding aggregators. Host shell/filesystem access — gate with permission/trust policies and `@arnilo/prism-coding-security` approval.
|
|
55
|
+
- [Coding execution approval and sandboxing](coding-security.md): optional `@arnilo/prism-coding-security` package for path roots, command rules, approval caching, shell-turn exclusivity, and pluggable sandbox adapters for coding tools.
|
|
46
56
|
|
|
47
57
|
## Extensions/plugins
|
|
48
|
-
- [Contribution discovery (workspace)](contribution-discovery.md): opt-in, realpath-contained directory scanner turning `SKILL.md`/`manifest.json` into inert `DiscoveredContribution` envelopes the host registers — no `import()`, no auto-activate, no provider scanning.
|
|
58
|
+
- [Contribution discovery (workspace)](contribution-discovery.md): opt-in, realpath-contained directory scanner turning `SKILL.md`/`manifest.json` into inert `DiscoveredContribution` envelopes the host registers — no `import()`, no auto-activate, no provider scanning. Per-agent bundles remain app-controlled and are documented under Agent/session runtime.
|
|
49
59
|
- [Contribution registries](contribution-registries.md): explicit host-owned registries for extension/package contributions without hidden globals, with `duplicate: "error"` strict mode for provider/model/tool/skill shadowing prevention.
|
|
50
60
|
- [Extension kernel and event bus](extensions.md): load host-provided extensions in order, register contributions, emit lifecycle events, and isolate extension errors.
|
|
51
61
|
- [Extension authoring guide](extension-authoring.md): publish third-party extension packages that register inert contributions and show host-owned activation, trust, permissions, redaction, and no-sandbox boundaries.
|
|
@@ -54,25 +64,31 @@ Prism is a TypeScript/Node.js agent harness. Host apps and extension packages ow
|
|
|
54
64
|
## Configuration/manifests
|
|
55
65
|
- [Configuration and manifests](configuration-and-manifests.md): merge in-memory JSON config layers and validate data-only package manifests with prototype-pollution key rejection.
|
|
56
66
|
- [Node filesystem config loader](node-filesystem-config.md): explicitly read caller-named JSON config files in Node hosts.
|
|
57
|
-
- [Resource loading](resource-loading.md): decode text, JSON, and manifest resources through caller-provided loaders.
|
|
67
|
+
- [Resource loading](resource-loading.md): decode text, JSON, binary, and manifest resources through caller-provided loaders with bounded byte limits.
|
|
58
68
|
|
|
59
69
|
## CLI/RPC
|
|
60
70
|
- [CLI/RPC](cli-rpc.md): Run print/json modes and LF-delimited RPC over the public AgentSession runtime, including branch-handle results, fixed `forkSession`, and `checkout`.
|
|
71
|
+
- [Workflows](workflows.md): optional `@arnilo/prism-workflows` typed bounded DAG orchestration — local execution plus SQLite/PostgreSQL multi-process coordination with enqueue, leases, heartbeats, fencing, durable cancel/resume, events, and optional RPC bindings. Interactive TUI (C-012) deferred.
|
|
72
|
+
- [Workflow orchestration primitives](workflow-orchestration-primitives.md): architecture inventory — workflow adapters consume core `CheckpointStore`, `LeaseStore`, and bounded `EventMultiplexer`; run control and optional RPC commands stay package-local.
|
|
73
|
+
- [Workflow/TUI scope](workflow-tui-primitives.md): records why 0.0.4 ships workflow APIs/RPC control but no interactive terminal UI.
|
|
61
74
|
|
|
62
75
|
## Security and credentials
|
|
63
76
|
- [Host security guide](host-security.md): fail-closed checklist for credentials, settings, redaction, trust roots, permission policies, persistence, extension loading, and tool validation.
|
|
64
77
|
- [Security/auth/trust](settings-auth-trust-security.md): settings providers, credential helpers, trust/permission policies, redaction controls, host-owned `AgentConfig.settings`/`credentials`, and security-boundary hardening summary.
|
|
65
78
|
- [Credentials and redaction](credentials-and-redaction.md): compose explicit credential resolver order, use caller-supplied env objects/OAuth refresh helpers, avoid eager `AgentConfig.credentials` resolution, and redact known secret values.
|
|
79
|
+
- [Credential storage](credential-storage.md): optional `@arnilo/prism-credentials-node` encrypted-file and system-keychain adapters for durable host-owned credentials.
|
|
66
80
|
|
|
67
81
|
## Testing and examples
|
|
68
|
-
-
|
|
82
|
+
- Provider test doubles: `createMockProvider()` and provider event helpers are documented on the canonical Provider layer page above.
|
|
69
83
|
- [Provider conformance](provider-conformance.md): run network-free provider adapter assertions (stream order, abort, tool-call reconstruction, cache usage, content coverage, protected header ownership, secret leak) from `@arnilo/prism/testing/provider-conformance`.
|
|
70
84
|
- [Session store conformance](session-store-conformance.md): assert any `SessionStore` adapter satisfies append/idempotency/conflict/branch invariants from `@arnilo/prism/testing/session-store-conformance`.
|
|
85
|
+
- [Run ledger conformance](run-ledger-conformance.md): assert any `RunLedger` adapter satisfies durable run/event/tool/usage writes and reopen survival from `@arnilo/prism/testing/run-ledger-conformance`.
|
|
71
86
|
- [Compaction conformance](compaction-conformance.md): assert any `CompactionStrategy` returns a non-empty redacted summary and observes abort from `@arnilo/prism/testing/compaction-conformance`.
|
|
72
87
|
- [Tool conformance](tool-conformance.md): assert the tool-dispatch blocked-reason matrix (unknown/denied/invalid/permission/validator) and success path from `@arnilo/prism/testing/tool-conformance`.
|
|
73
88
|
- [Extension conformance](extension-conformance.md): assert an `Extension` setup runs, contributions stay inert, and setup errors are redacted or rethrown from `@arnilo/prism/testing/extension-conformance`.
|
|
74
|
-
- `examples/`: compile-checked typed examples and runnable mock demos (SDK basics, provider registration, auth, tools, cache-aware prompt assembly, NeuralWatt agent run, stores/branching, compaction, observational-memory recall, structured-output/artifact-loop, CLI, RPC).
|
|
89
|
+
- `examples/`: compile-checked typed examples and runnable mock demos (SDK basics, provider registration, auth, tools, cache-aware prompt assembly, NeuralWatt agent run, stores/branching, compaction, observational-memory recall, structured-output/artifact-loop, CLI, RPC, workflow orchestration).
|
|
75
90
|
|
|
76
91
|
## Release and install
|
|
77
|
-
- [Release and install](release-and-install.md): package
|
|
92
|
+
- [Release and install](release-and-install.md): 24-package graph and profiles, install/tarball rules, deterministic resumable provenance publication, and offline test budget.
|
|
93
|
+
- [Review coverage (2026-07-14)](review-coverage-2026-07-14.md): traceability matrix linking review findings and bug-report fixes to plan tasks, tests, and documentation for release 0.0.4.
|
|
78
94
|
|
|
@@ -60,7 +60,7 @@ Useful exported types:
|
|
|
60
60
|
- `DefaultInputBuilder`: the default `InputBuilder` with typed default context.
|
|
61
61
|
- `InputAssemblyLayout`: `"legacy" | "cache_aware"`; legacy is default.
|
|
62
62
|
- `DefaultInputBuildContext`: optional input layout, instructions, history, summaries, attachments, resource loader/URIs, tool results, middleware, ids, metadata, and abort signal.
|
|
63
|
-
- `InputAttachment`: already-loaded text/content or an explicit URI loaded through a caller-provided `ResourceLoader`.
|
|
63
|
+
- `InputAttachment`: already-loaded text/content blocks (including `audio`, `file`, and `document`) or an explicit URI loaded through a caller-provided `ResourceLoader`.
|
|
64
64
|
- `PromptInstruction`: labeled system instruction text.
|
|
65
65
|
- `DefaultPromptBuilder`: the default `PromptBuilder`.
|
|
66
66
|
- `AssembleProviderInputOptions`: model, input, optional builders, context providers, selected skills, active tools, generic provider options, metadata, and signal.
|
|
@@ -82,10 +82,10 @@ The builder returns `readonly Message[]`.
|
|
|
82
82
|
The default prompt builder still prepends context, selected skills, and tool declarations before those input messages. Cache-aware ordering gives cache-capable providers a stable prefix only while those stable inputs stay byte-stable; changing tools, context, resources, summaries, history, or attachments changes the prefix too.
|
|
83
83
|
- History is prepended before current input.
|
|
84
84
|
- Instructions and summaries are system messages; compacted branch summaries from `rebuildSessionContext()` use the same path.
|
|
85
|
-
- Text attachments and explicit text resources are user messages
|
|
85
|
+
- Text attachments and explicit text resources are user messages; inline `audio`/`file`/`document` blocks pass through unchanged on attachments with `content`.
|
|
86
86
|
- Tool results are tool messages containing `tool_result` content; the agent/session runtime uses this to feed dispatched tool results into the next provider turn, placing the assistant `tool_call` and the matching role `tool` `tool_result` before any final assistant content. Cache-aware layout keeps tool results before the current user suffix so it does not split tool transcripts.
|
|
87
87
|
- Middleware runs only when `middleware` is supplied in the context.
|
|
88
|
-
- `assembleProviderInput()` returns a `ProviderRequest` with the caller's model/tools/provider options/metadata/signal and composed messages/context.
|
|
88
|
+
- `assembleProviderInput()` returns a `ProviderRequest` with the caller's model/tools/provider options/metadata/signal and composed messages/context. It also calls `assertMessagesSupportModelCapabilities()` so unsupported `audio`/`file`/`document`/`image` blocks fail with `UnsupportedModalityError` when the model declares `capabilities.input`.
|
|
89
89
|
- `renderPromptTemplate()` replaces top-level `{{name}}` variables with caller-supplied JSON-compatible values. Strings are inserted directly; numbers, booleans, `null`, arrays, and objects are stringified deterministically with sorted object keys. Missing variables throw by default or stay unchanged with `{ missing: "preserve" }`.
|
|
90
90
|
|
|
91
91
|
## Request/response example
|
|
@@ -165,7 +165,7 @@ const request = await assembleProviderInput({
|
|
|
165
165
|
- The builder is linear in supplied messages, attachments, resources, and tool results. Layout selection is one flattening branch over already-built groups.
|
|
166
166
|
- Template expansion is dependency-free string replacement over `{{name}}` variables. It does not evaluate expressions, filters, loops, partials, JavaScript, globals, or prototype properties.
|
|
167
167
|
- It performs no provider calls, tool execution, credential resolution, package discovery, filesystem scan, network access, timers, or watchers.
|
|
168
|
-
- URI attachments/resources load only through the caller-provided `ResourceLoader`.
|
|
168
|
+
- URI attachments/resources load only through the caller-provided `ResourceLoader`. Binary media uses `resolveMediaContentBlock()` / `loadBinaryResource()` with bounded bytes, SSRF checks for URLs, and MIME magic validation — see [Multimodal content](multimodal-content.md).
|
|
169
169
|
- Do not place secrets in templates, variables, instructions, messages, attachments, tool results, metadata, middleware payloads, or docs examples.
|
|
170
170
|
- Active tools are passed through from the host; prompt middleware cannot grant additional provider tools.
|
|
171
171
|
- Skill selection is handled by the host/skill registry path; this builder only includes selected skills passed by the caller.
|
|
@@ -175,7 +175,8 @@ const request = await assembleProviderInput({
|
|
|
175
175
|
- [SDK customization guide](customization.md): high-level map of replaceable provider resolution, middleware, context, builder, injector, loop, compaction, retry, store, and skill seams.
|
|
176
176
|
- [Public contracts](public-contracts.md): `Message`, `ContentBlock`, `InputBuilder`, `InputBuildContext`, `ToolResult`, and `ResourceLoader` shapes.
|
|
177
177
|
- [Context and skills](context-and-skills.md): ordered context resolution feeding prompt composition.
|
|
178
|
-
- [
|
|
178
|
+
- [Multimodal content](multimodal-content.md): `audio`/`file`/`document` blocks, bounded media resolution, and capability checks.
|
|
179
|
+
- [Resource loading](resource-loading.md): `loadTextResource()` and `loadBinaryResource()` behavior used for explicit URI resources.
|
|
179
180
|
- [Middleware hooks](middleware-hooks.md): ordered middleware registry and `input_assembly`, `context`, and `prompt_build` hooks.
|
|
180
181
|
- [System prompts](system-prompts.md): compose layered package/app/user/run prompts before input assembly.
|
|
181
182
|
- [Contribution registries](contribution-registries.md): inert input, prompt, context, and skill contributions.
|