@arnilo/prism 0.0.13 → 0.0.14
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 +12 -0
- package/README.md +8 -2
- package/dist/artifacts.d.ts +78 -0
- package/dist/artifacts.js +24 -0
- package/dist/contracts.d.ts +10 -0
- package/dist/contracts.js +8 -0
- package/dist/conversations.d.ts +50 -0
- package/dist/conversations.js +97 -0
- package/dist/credentials.d.ts +14 -0
- package/dist/credentials.js +9 -0
- package/dist/devices.d.ts +94 -0
- package/dist/devices.js +138 -0
- package/dist/index.d.ts +10 -4
- package/dist/index.js +6 -3
- package/dist/providers/openai-primitives.js +5 -2
- package/docs/ag-ui.md +5 -0
- package/docs/browser-automation.md +3 -0
- package/docs/conversations.md +135 -0
- package/docs/credential-storage.md +28 -1
- package/docs/credentials-and-redaction.md +2 -0
- package/docs/database-persistence.md +5 -1
- package/docs/device-adapters.md +97 -0
- package/docs/host-security.md +4 -2
- package/docs/index.md +16 -12
- package/docs/migration.md +21 -0
- package/docs/performance.md +2 -0
- package/docs/policy-and-audit.md +1 -0
- package/docs/provider-caching.md +4 -0
- package/docs/provider-packages.md +4 -1
- package/docs/providers/alibaba.md +179 -0
- package/docs/providers/ollama.md +166 -0
- package/docs/release-and-install.md +75 -5
- package/docs/review-coverage-2026-07-25-phase-9.md +256 -0
- package/docs/server.md +4 -0
- package/docs/work-artifacts-and-review.md +100 -0
- package/docs/work-connectors.md +5 -1
- package/docs/work-tools.md +3 -0
- package/docs/workflows.md +4 -0
- package/docs/working-and-semantic-memory.md +20 -5
- package/package.json +1 -1
- package/templates/init/providers.json +22 -0
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
## What it does
|
|
4
4
|
|
|
5
|
-
Prism is published as one core package, thirty-
|
|
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.
|
|
11
|
+
First-party workspace packages (each has non-optional `@arnilo/prism@0.0.14` 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).
|
|
@@ -40,7 +40,7 @@ First-party workspace packages (each has non-optional `@arnilo/prism@0.0.13` pee
|
|
|
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
|
|
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.
|
|
@@ -195,6 +195,76 @@ 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.14 publish handoff
|
|
199
|
+
|
|
200
|
+
**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.
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
git diff --check
|
|
204
|
+
npm ci
|
|
205
|
+
npm run sdk:ready
|
|
206
|
+
node scripts/benchmark-0.0.14.mjs
|
|
207
|
+
node --test scripts/benchmark-0.0.14.test.mjs
|
|
208
|
+
npm run release:check -- --version 0.0.14 --allow-untagged --report /tmp/prism-0.0.14-preflight.json
|
|
209
|
+
git tag -s v0.0.14 -m "Prism 0.0.14"
|
|
210
|
+
git verify-tag v0.0.14
|
|
211
|
+
git push origin v0.0.14
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
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.
|
|
215
|
+
|
|
216
|
+
#### Rollback limitations
|
|
217
|
+
|
|
218
|
+
npm publication is immutable: partial publication is a resume case, and confirmed defects require deprecation plus a fixed version rather than rollback.
|
|
219
|
+
|
|
220
|
+
Package set (43):
|
|
221
|
+
|
|
222
|
+
```text
|
|
223
|
+
@arnilo/prism
|
|
224
|
+
@arnilo/prism-ag-ui
|
|
225
|
+
@arnilo/prism-browser
|
|
226
|
+
@arnilo/prism-coding-agent
|
|
227
|
+
@arnilo/prism-coding-security
|
|
228
|
+
@arnilo/prism-compaction-llm
|
|
229
|
+
@arnilo/prism-compaction-observational-memory
|
|
230
|
+
@arnilo/prism-credentials-node
|
|
231
|
+
@arnilo/prism-evals
|
|
232
|
+
@arnilo/prism-mcp
|
|
233
|
+
@arnilo/prism-memory
|
|
234
|
+
@arnilo/prism-model-router
|
|
235
|
+
@arnilo/prism-observability-opentelemetry
|
|
236
|
+
@arnilo/prism-policy
|
|
237
|
+
@arnilo/prism-all
|
|
238
|
+
@arnilo/prism-base
|
|
239
|
+
@arnilo/prism-code
|
|
240
|
+
@arnilo/prism-compaction
|
|
241
|
+
@arnilo/prism-providers
|
|
242
|
+
@arnilo/prism-sdk
|
|
243
|
+
@arnilo/prism-provider-ai-sdk
|
|
244
|
+
@arnilo/prism-provider-alibaba
|
|
245
|
+
@arnilo/prism-provider-anthropic
|
|
246
|
+
@arnilo/prism-provider-azure
|
|
247
|
+
@arnilo/prism-provider-bedrock
|
|
248
|
+
@arnilo/prism-provider-google
|
|
249
|
+
@arnilo/prism-provider-kimi
|
|
250
|
+
@arnilo/prism-provider-neuralwatt
|
|
251
|
+
@arnilo/prism-provider-ollama
|
|
252
|
+
@arnilo/prism-provider-openai
|
|
253
|
+
@arnilo/prism-provider-opencode-go
|
|
254
|
+
@arnilo/prism-provider-openrouter
|
|
255
|
+
@arnilo/prism-provider-vertex
|
|
256
|
+
@arnilo/prism-provider-zai
|
|
257
|
+
@arnilo/prism-rag
|
|
258
|
+
@arnilo/prism-server
|
|
259
|
+
@arnilo/prism-session-store-postgres
|
|
260
|
+
@arnilo/prism-session-store-sqlite
|
|
261
|
+
@arnilo/prism-supervisor
|
|
262
|
+
@arnilo/prism-tool-validator-json-schema
|
|
263
|
+
@arnilo/prism-web-tools
|
|
264
|
+
@arnilo/prism-work-tools
|
|
265
|
+
@arnilo/prism-workflows
|
|
266
|
+
```
|
|
267
|
+
|
|
198
268
|
### 0.0.13 publish handoff
|
|
199
269
|
|
|
200
270
|
**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 +673,8 @@ npm publication is not transactional and published versions are immutable. Parti
|
|
|
603
673
|
|
|
604
674
|
## Extension and configuration notes
|
|
605
675
|
|
|
606
|
-
- **Required `@arnilo/prism` peer.** Every first-party code package declares a non-optional `@arnilo/prism@0.0.
|
|
607
|
-
- **Public access.** All
|
|
676
|
+
- **Required `@arnilo/prism` peer.** Every first-party code package declares a non-optional `@arnilo/prism@0.0.14` peer (`peerDependenciesMeta` must not mark `@arnilo/prism` optional; other peers such as `playwright-core` may be optional). The range stays pinned to `0.0.14` 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.
|
|
677
|
+
- **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
678
|
- **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
679
|
- **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
680
|
- **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.
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
# Review coverage — 2026-07-25 Phase 9
|
|
2
|
+
|
|
3
|
+
Working evidence for Plan 077 Task 0. Freezes Phase 9 / Release **0.0.14** scope, package ownership, primitive inventory, finite limits, capability/consent token shapes, replay semantics, threats, tests, docs, and release gates before implementation.
|
|
4
|
+
|
|
5
|
+
**Evidence frozen:** 2026-07-25. **Prism source:** `56692ad8ab8d05dce2d5a08f29ad768a8b43e0af`. **Release target:** 0.0.14. **Publishable graph:** 41 → 43 manifests (exactly two new provider packages authorized — `@arnilo/prism-provider-alibaba`, `@arnilo/prism-provider-ollama` — added before version completion per user request; no other new packages). **Default test rule:** network-free fakes and protocol fixtures; M365/GWS OAuth, Playwright, PostgreSQL/keychain live canaries remain explicit host/operator gates.
|
|
6
|
+
|
|
7
|
+
## Status legend
|
|
8
|
+
|
|
9
|
+
| Status | Meaning |
|
|
10
|
+
| --- | --- |
|
|
11
|
+
| `existing` | Current public contract covers the requirement. |
|
|
12
|
+
| `extend` | Owning task adds a generic reusable contract to an existing seam. |
|
|
13
|
+
| `compose` | Existing public primitives suffice; package-local wiring only. |
|
|
14
|
+
| `out-of-scope` | Later phase or deliberately unsupported; must not land in 0.0.14. |
|
|
15
|
+
|
|
16
|
+
## Frozen product decision
|
|
17
|
+
|
|
18
|
+
0.0.14 adds **durable personal/work-agent conversations, memory consent/lifecycle, artifact co-work review, AG-UI co-work events, scoped OAuth connector establishment, and browser/device composition gates** — all as extensions of shipped packages. Roadmap gate 8 is binding: channel/device/co-work features remain optional and cannot broaden user consent, memory, network, file, browser, connector, or tool permissions; they reuse the AG-UI adapter shipped in 0.0.12.
|
|
19
|
+
|
|
20
|
+
**Not in 0.0.14** (do not implement here):
|
|
21
|
+
|
|
22
|
+
| Deferred or rejected item | Owner / reason |
|
|
23
|
+
| --- | --- |
|
|
24
|
+
| Studio, hosted cloud, managed observability, chat product UI | Demand-gated 0.1.x; hosts own UI chrome. |
|
|
25
|
+
| Slack/Teams or broader chat channel catalog | Deferred until web/AG-UI demand is measured (roadmap Phase 9). |
|
|
26
|
+
| Realtime voice vendor packages and desktop OS control vendor packages | Contracts + deny-by-default conformance only in 0.0.14; vendor implementations demand-gated 0.1.x. |
|
|
27
|
+
| Local Office executable/SDK/wrapper/runtime for artifact previews | Outside Prism product scope; previews/edits stay host-owned. |
|
|
28
|
+
| `WorkAgent` or second work-agent runtime, second memory runtime, second event system | Compose ordinary agents over sessions/workflows/tools; extend AG-UI, memory, server in place. |
|
|
29
|
+
| Artifact file-body blob store | Prism persists bounded metadata/hashes/refs; hosts own blob storage and rendering. |
|
|
30
|
+
| Serialized browser internals (cookies/localStorage/context) in checkpoints | Checkpoints persist verified URLs/domain state + host data refs only. |
|
|
31
|
+
| Permission broadening of any kind (consent/memory/network/file/browser/connector/tool) | Forbidden by roadmap gate 8; regression-guarded in Task 8. |
|
|
32
|
+
| Always-on proactive agent or push daemon | Schedules require explicit user enablement + revocable capability tokens; host transports consume replay streams. |
|
|
33
|
+
| Cross-identity token fallback, model-selected OAuth scopes, credentials in argv/model context | Unsupported; per-identity isolation and host-pinned least-privilege scope maps only. |
|
|
34
|
+
|
|
35
|
+
## Frozen external revisions
|
|
36
|
+
|
|
37
|
+
| Surface | Frozen reference | Compatibility decision |
|
|
38
|
+
| --- | --- | --- |
|
|
39
|
+
| Prism | [`56692ad8ab8d05dce2d5a08f29ad768a8b43e0af`](../plans/077-release-0-0-14-personal-work-agent-conversations-co-work-review-channels.md) | 0.0.13 graph (41 manifests → 43 at 0.0.14 with provider packages alibaba/ollama); conversation/artifact/memory/AG-UI/connector/device seams inventoried below. |
|
|
40
|
+
| Node.js | Release support remains Node 20+ | Delivery-link/token signing uses node `crypto` HMAC via host key material; no new runtime dependency enters core. |
|
|
41
|
+
| AG-UI | `@ag-ui/core` **0.0.57** (pinned in `packages/ag-ui/package.json`); [Events](https://docs.ag-ui.com/concepts/events), [State](https://docs.ag-ui.com/concepts/state), [Interrupts](https://docs.ag-ui.com/concepts/interrupts) | Co-work events ride official `CUSTOM`/state extension points; produced events still validate with `EventSchemas`; no fork of the 0.0.12 mapper. |
|
|
42
|
+
| ACP | `@agentclientprotocol/sdk` **1.3.0** stable root | `./acp` sibling gains co-work parity only where stable `session/update` contracts overlap; no experimental v2. |
|
|
43
|
+
| Microsoft Graph OAuth | Current Microsoft identity platform / Graph permission docs at implementation time (delegated `Mail.Read`, `Mail.Send`, `Calendars.ReadWrite`, `Files.ReadWrite`, `Tasks.ReadWrite` family) | PKCE auth-code flow via existing `OAuthProvider` seam; delegated least-privilege scopes only; no application-permission defaults. |
|
|
44
|
+
| Google Workspace OAuth | Current Google OAuth 2.0 / Gmail-Calendar-Drive scope docs at implementation time (`gmail.readonly`/`gmail.send`, calendar, drive scopes) | Same seam; incremental consent per bundle; no broad `*` scopes. |
|
|
45
|
+
| Playwright | Version pinned by `@arnilo/prism-browser` at 0.0.13 | Checkpoint/resume-verify seam composes existing manager/policy; no new browser engine. |
|
|
46
|
+
|
|
47
|
+
## Frozen package and API contract
|
|
48
|
+
|
|
49
|
+
| Decision | Frozen choice |
|
|
50
|
+
| --- | --- |
|
|
51
|
+
| Release graph | **41 → 43 manifests.** Exactly two new provider packages (`@arnilo/prism-provider-alibaba`, `@arnilo/prism-provider-ollama`) authorized per user request before version completion; no other new packages. All Phase 9 surface extends `@arnilo/prism` (types only), `@arnilo/prism-server`, `@arnilo/prism-memory`, `@arnilo/prism-ag-ui` (+`/acp`), `@arnilo/prism-credentials-node`, `@arnilo/prism-work-tools`, `@arnilo/prism-browser`, `@arnilo/prism-workflows`, and the sqlite/postgres session stores. A split (e.g. `@arnilo/prism-conversations`) is authorized only if Task 1/3 records measured size/cohesion evidence, never speculatively. |
|
|
52
|
+
| Conversation service | Core exports conversation **types only** (`ConversationThread`, thread state `active \| archived`, replay cursor, request-id idempotency). `@arnilo/prism-server` adds `createConversationService({ sessions, authorize, limits })` with create/list/continue/branch/archive/export/delete. A thread is an ownership-scoped session branch + metadata; `continue` resumes via `resumeAgentRunStream()` + checkpoint CAS so completed tool calls never rerun. |
|
|
53
|
+
| Replay semantics | Cursor = opaque ownership-scoped `{ threadId, lastEventSeq }`; pages durable redacted rows via `queryEvents`, then attaches to the live bounded subscriber (0.0.12 pattern); at-least-once across the page/live boundary with stable event/message/tool IDs for client dedup; terminal replay never invokes a provider or tool; gaps detected and recoverable. |
|
|
54
|
+
| Memory consent/lifecycle | `@arnilo/prism-memory` extends records with `consent: { source, scope, visible, grantedAt?, revokedAt? }` over the existing `MemoryScope` (`source` user/agent/system; `scope` thread/profile/user maps to user/profile/thread controls; no new scope axis). The single `recall()` gate enforces consent+visibility at assembly time (O(1) per record), covering direct recall and `createContextProvider()` injection; `requireConsent` strict mode also drops consent-less entries. `setConsent`/`correct`/`forget`/`applyRetention` lifecycle APIs (real deletes, bounded batches); conformance covers vector + working stores (in-memory + PostgreSQL/pgvector adapters). |
|
|
55
|
+
| Proactive capability | `packages/workflows` gains `createProactiveScheduleCapabilities`: frozen token `{ tokenId, scheduleId, workflowId, scope, actor, createdAt, expiresAt, revoked, revokedAt?, version }` (TTL 24h/31d, record ≤ 16 KiB). Revocation marks the token revoked and pauses the underlying schedule so `pollOnce` never fires it; `assertActive` fails closed on missing/revoked/expired for manual trigger paths. `onCapability` events (redacted actor refs) bridge to `@arnilo/prism-policy`. No schedule runs without an explicit grant. |
|
|
56
|
+
| Artifact service | Core exports artifact **types only** (`ArtifactRecord`, `ArtifactRevision`, `ArtifactApproval`, approval state `pending \| approved \| rejected`, `ArtifactDeliveryToken`). `@arnilo/prism-server` adds `createArtifactService(store: CheckpointStore, { redactor, linkSecret, limits, onDecision })` + `createArtifactHandler`: attach/revise/compare/approve/reject/lastValidated/deliveryLink. Records persist as versioned checkpoint values (namespace `prism.artifact`, key `threadId:artifactId`); the checkpoint version is the CAS counter for concurrent reviewers (no lost approvals), revision numbers/approvals/`lastValidatedVersion` live in the JSON value — no separate artifact schema/migration. Compare is hash+metadata-bounded (exactly 2 revisions per call; hosts render content). Delivery links are `base64url(payload).base64url(HMAC-SHA256)` over `{ artifactId, threadId, version, ownership, issuedAt, expiresAt }`, reauthorized per download. Local filesystem paths rejected; records redacted before persist/response. Persistence stores records/revisions only — never file bodies. |
|
|
57
|
+
| AG-UI co-work | `packages/ag-ui` extends (not reimplements) `ag-ui-mapper.ts`, `projection.ts`, `handler.ts`, `replay.ts`, `types.ts` with co-work events: `artifact.progress`, `artifact.approval.requested`, `draft.connector.pending`, `browser.snapshot` (redacted), `artifact.download.link` (expiring token). `AgUiEventMapper.mapCoWork()` (+ ACP `mapCoWork()` parity) validate/host-project/redact/byte-cap each event into a named `CUSTOM` event (malformed/oversized fail closed to nothing); shared `projectCoWorkEvent()` keeps one projection path. `createAgUiHandler` accepts `coWorkContext` (`{ threadId, artifactId, identity }`) + a durable `coWork` source (`createCoWorkReplay()`) and appends one bounded redacted page after the run. Default-deny projection from 0.0.12 stands: no local paths, raw tool args/results, or secrets. |
|
|
58
|
+
| OAuth connectors | `packages/credentials-node` adds a shared `createOAuth2Provider()` (PKCE auth-code + device-code + refresh + revoke, redacted errors) behind `createMicrosoft365OAuthProvider()` / `createGoogleWorkspaceOAuthProvider()` over the existing `OAuthProvider` seam (Codex pattern); least-privilege scope bundles per capability via `resolveMicrosoft365Scopes` / `resolveGoogleWorkspaceScopes` (read vs mutation; unknown capability fails closed). Core gains optional `OAuthProvider.revoke?` + `revokeOAuthCredential()` (best-effort upstream + mandatory local store delete; GWS RFC 7009, M365 no public endpoint so local delete is the fail-closed boundary). `createOAuthWorkTokenProvider()` bridges stored credentials to a per-identity connector env var: late-bound single-flight refresh, and missing/expired/revoked/cross-identity/wrong-tenant tokens fail closed. `packages/work-tools` adapters accept an optional `tokenProvider` and inject the token via per-exec env — never argv/model context; login UX host-owned. |
|
|
59
|
+
| Browser composition | `packages/browser` adds `createBrowserCheckpointLedger()` persisting `{ url, domainStateHash, hostDataRef }` only — never cookies/localStorage/serialized context (frozen caps: URL 8 KiB/16 KiB, hash 256 B/1 KiB, ref 2 KiB/8 KiB, 16/64 checkpoints per run, oldest evicted). `markResumed(runId)` marks state stale after resume/interruption; `assertVerifiedBeforeSideEffect(runId)` fails closed until the host reloads + `verify()`s, so side effects never replay on stale state. Checkpoints are run-scoped: a conversation thread composes through the run it owns, consuming shared `RunLimits` and existing sandbox/egress/secret-injection/approval policy. |
|
|
60
|
+
| Device adapters | Core (`src/devices.ts`) adds a minimal `DeviceAdapter` contract + deny-by-default `resolveDevicePolicy()` / `assertDeviceAdmit()` (types + policy only; compose over `PermissionPolicy`, `RunLimits`, redactor). Admission fails closed without explicit `enabled`, an explicit sandbox, approval (when required), an under-budget session count (1/4), and shared `RunLimits`; `acceptDeviceChunk()` drops oversize stream chunks (1 MiB/8 MiB) with a marker; `redactDeviceTelemetry()` redacts before emit/persist; `runDevicePolicyConformance()` is the conformance pair (denial/approval/session-budget/run-accounting/stream-bounds/redaction) for future vendor adapters. No vendor voice or desktop OS control package ships in 0.0.14 (demand-gated 0.1.x). |
|
|
61
|
+
| Profile inclusion | No profile changes needed: server/memory/ag-ui/work-tools/browser/credentials-node already enroll per 0.0.12–0.0.13 rules; `prism-code`/`prism-sdk` stay protocol/connector-free. |
|
|
62
|
+
|
|
63
|
+
## Capability traceability matrix
|
|
64
|
+
|
|
65
|
+
| Phase 9 roadmap criterion | Existing surface | Minimum gap | Status / owner | Required proof | Docs | Release gate |
|
|
66
|
+
| --- | --- | --- | --- | --- | --- | --- |
|
|
67
|
+
| Durable conversation service: create/list/continue/branch/archive/export/delete user-scoped threads | Session branches + `checkout`, `idempotencyKey` append dedup, `queryEvents` paging, server `authorize`→ownership, `AgentIdentity` | Thread metadata seam on stores + conversation service on server | `extend` / Task 1 | create/continue/branch/archive/export/delete; wrong-user denial; duplicate request-id idempotency; export redaction | `conversations.md` (new), server, session-stores | offline store + server tests |
|
|
68
|
+
| Reconnect/replay bounded ordered events without rerunning completed work | `resumeAgentRunStream()`, `AgentRunLifecycle.resumeStream`, 0.0.12 durable-resume page→live pattern, checkpoints/CAS | Ownership-scoped thread replay cursor + gap recovery | `compose` / Task 1 | cursor resume; event-gap recovery; tool-call count invariant across reconnect; backpressure | conversations, ag-ui | offline integration |
|
|
69
|
+
| Memory consent/source/visibility/correction/retention/deletion, per-user/profile/thread controls | `MemoryScope` (tenant/account/user/thread), vector + working stores, `runMemoryConformance`, `assertFiniteVector` | Consent fields + injection filter + lifecycle APIs | `extend` / Task 2 | grant/revoke/correct/delete/retention per scope; revoked/invisible absent from assembled requests/events/exports; cross-user denial | working-and-semantic-memory, host-security | offline conformance |
|
|
70
|
+
| Proactive schedules/events require explicit enablement + revocable capabilities | `createWorkflowSchedules`, workflow suspend/approve, `assertIdentityActive`, policy ledger | Capability token verified at fire time + revocation fail-closed | `extend` / Task 2 | enable/revoke; revoked token fails closed at fire; audit record; no default-on schedule | workflows, policy-and-audit | offline fixtures |
|
|
71
|
+
| Durable artifact service: MIME/hash/version, producer run, citations, preview metadata, approval state, delivery; compare/request-changes/approve/reject; last-validated recovery | Workflow `tool_approval` interruption, persistence lifecycle (0.0.13 v5), `ResourceLoader`, Plan 076 `IdempotencyStore` + draft-then-approve pattern | Artifact record/revision/approval/delivery seam on persistence + server | `extend` / Task 3 | attach/revise/compare/approve/reject; CAS reviewer conflict; failed-update rollback; last-validated recovery; local-path redaction | `work-artifacts-and-review.md` (new), server, persistence pages | offline store + server tests |
|
|
72
|
+
| AG-UI maps browser snapshots, connector drafts, approvals, progress, authorized artifact download links into reconnectable co-work events; no local paths | `createAgUiEventMapper`/`createAgUiHandler`/`createPersistenceAgUiReplay`, default-deny projection, `@ag-ui/core` 0.0.57 `EventSchemas` | Co-work event types + thread/artifact-scoped handler input | `extend` / Task 4 | mapping round-trips; disconnect/resume; overflow/backpressure; malformed client event; redaction | ag-ui, work-artifacts-and-review | offline package test |
|
|
73
|
+
| OAuth connector flows establish scoped M365/GWS credentials for Outlook/Gmail workloads; Slack/Teams deferred | `OAuthProvider`, `refreshOAuthCredential`, `createOAuthCredentialStoreAdapter`, Codex PKCE pattern, work-tools identity wiring | M365/GWS OAuth adapters + least-privilege scope maps + revocation | `extend` / Task 5 | establish/refresh/revoke; token redaction; cross-identity isolation; least-scope per bundle; no Slack/Teams artifact | credential-storage, work-connectors | offline + gated OAuth canaries |
|
|
74
|
+
| Voice/desktop adapters optional, isolated, approval-aware, observable, disabled by default; browser tools compose via existing policy | `PermissionPolicy`, `RunLimits`, `tool_approval`, redactor, browser sandbox/egress policy | `DeviceAdapter` contract + deny-by-default policy + conformance; browser checkpoint/resume-verify | `extend` / Task 6 | denial-by-default; approval gate; stream bounds; side-effect non-replay; checkpoint reload/verify; redacted telemetry | browser-automation, host-security, migration | offline conformance |
|
|
75
|
+
| Finite byte/time/rate/version limits + reconnect backpressure everywhere; review/browser loops consume shared budgets | Server/SSE/subscriber/persistence limits, `RunLimits`, package limit resolvers | Frozen caps below + `scripts/benchmark-0.0.14.mjs` | `compose` / Tasks 1–6, 8 | hostile overflow fixtures; network-free benchmark schema/budgets | performance, review page | `sdk:ready` + benchmark |
|
|
76
|
+
| Conversation/artifact APIs reuse sessions/branches/checkpoints/events/server/resources; AG-UI extended not reimplemented; no second runtime | All seams above | Package/profile guards | `compose` / Tasks 0, 7–8 | 41 → 43 pack graph (alibaba/ollama providers only); no `WorkAgent`/second-memory/second-event export; prism-code/sdk stay protocol-free | release-and-install, migration | pack/install + diff review |
|
|
77
|
+
| Authenticated identity owns every thread/memory/artifact/connector/browser/device action; consent/permission rechecked; links authorized+expiring; tokens/paths/secrets/document-private data never leak | `AgentIdentity`/`IdentityVerifier`, `ownershipFromIdentity`, redactor, policy ledger | Threat matrix enforcement in owning tasks | `compose` / all tasks | negative test per threat row; permission-non-broadening regression | host-security + task docs | security review before publish |
|
|
78
|
+
|
|
79
|
+
## Primitive and caller inventory
|
|
80
|
+
|
|
81
|
+
| Primitive / symbol | Existing contract and callers | Phase 9 disposition |
|
|
82
|
+
| --- | --- | --- |
|
|
83
|
+
| Session branches: `checkout(leafId)`, leaf entries, branch ancestor paging (`src/contracts.ts`) | Session stores (jsonl/sqlite/postgres), `SessionIndex` search hits return `leafId` | **Extend** with thread metadata (title/state/owner) keyed to a branch; thread = branch, not a second tree. |
|
|
84
|
+
| `SessionIndex` (`src/contracts.ts:1109`) | sqlite/postgres FTS search, memory fallback | Reuse for thread listing/filtering where stores implement it; memory store may return explicit unsupported. |
|
|
85
|
+
| `subscribe(options)` event multiplexer + `queryEvents(AgentEventQuery)` durable pages (`src/contracts.ts`) | Server SSE, 0.0.12 `createPersistenceAgUiReplay`, `createPrismEventReplay` | Reuse for conversation reconnect/replay (page→live, at-least-once, stable IDs). No second event system. |
|
|
86
|
+
| `resumeAgentRunStream()` / `AgentRunLifecycle.resumeStream` (`src/agents.ts`, `src/agent-run-lifecycle.ts`) | AG-UI handler resume, durable approvals | Reuse for `continue` so completed tool calls never rerun; checkpoint CAS + `expectedVersion` required. |
|
|
87
|
+
| `RunLimits` (`src/contracts.ts:137`) | Agent loops, workflows, browser, connectors | Reuse as shared turn/tool/token/cost budget for review and browser loops. |
|
|
88
|
+
| `AgentRunInterruptionKind` / `tool_approval` (`src/agents.ts:576`) | Secure agent, workflow suspension, connector draft-then-approve | Reuse for artifact review approvals and device side effects; no second approval runtime. |
|
|
89
|
+
| `idempotencyKey` session append dedup (`src/contracts.ts`) | Session append, Plan 076 connector `IdempotencyStore` | Reuse pattern for conversation `continue` request IDs and artifact mutation dedup. |
|
|
90
|
+
| `AgentIdentity` / `IdentityVerifier` / `ownershipFromIdentity` / `assertIdentityActive` / `narrowIdentity` (`src/identity.ts`) | Server authorize, tools, workflows, MCP/A2A, telemetry, connectors | Reuse; every conversation/memory/artifact/connector/browser/device action starts from verified identity; recheck on resume and at schedule fire time. |
|
|
91
|
+
| `OAuthProvider` / `OAuthCredentialStore` / `refreshOAuthCredential` (`src/credentials.ts`, `src/index.ts:76`) | OpenAI Codex PKCE adapter, credentials-node stored resolver | **Extend** with M365 + GWS adapters and per-bundle scope maps; single-flight refresh; revocation. |
|
|
92
|
+
| `createStoredCredentialResolver` / `createOAuthCredentialStoreAdapter` / encrypted + keychain stores / KMS envelope (`packages/credentials-node`) | Provider credentials, work-tools identity | Reuse for per-identity connector token storage; secrets never in argv/model context/events. |
|
|
93
|
+
| `MemoryScope` / vector store / working store / `runMemoryConformance` / `assertFiniteVector` (`packages/memory`) | Memory injection, postgres/memory adapters | **Extend** with consent/source/visibility fields, injection filter, correction/delete/retention, conformance cases. |
|
|
94
|
+
| `createWorkflowSchedules` / `WorkflowScheduleRecord` / coordinator / checkpoints (`packages/workflows`) | Durable schedules, suspend/resume, replay | **Extend** with capability-token verification at fire time + revocation; audit via policy ledger. |
|
|
95
|
+
| `createPolicyEvaluator` / `evaluateAndAppend` / policy stores / `exportPolicyDecisions` (`packages/policy`) | Enterprise policy decisions, audit export | Reuse for consent-revocation, schedule-revocation, artifact-approval, delivery-link audit records. |
|
|
96
|
+
| `RetentionPolicy` / `queryRetentionPolicies` / persistence lifecycle hooks (`src/contracts.ts:1559`, `src/persistence-lifecycle.ts`) | sqlite/postgres lifecycle (0.0.13) | Reuse for thread/memory/artifact retention/deletion/legal-hold; no new retention engine. |
|
|
97
|
+
| `ResourceLoader` / `registerResourceLoader` (`src/contracts.ts:1812`) | Media/resource loading, SSRF bounds | Reuse for authorized artifact source/output references; hosts resolve blob bodies. |
|
|
98
|
+
| `createSecretRedactor` / `redactAgentEvent` / `redactSessionEntry` (`src/redaction.ts`) | Events, persistence, exports, telemetry | Reuse for conversation export, artifact records, co-work events, device streams. |
|
|
99
|
+
| `createPrismHandler` / `createPrismEventReplay` / `createPrismHealthHandler` / drain / rate-limit / deployment lease (`packages/server`) | All server routes, 0.0.13 deployment seams | **Extend** with conversation + artifact services and delivery-link signer/verifier; ownership still only from authorize. |
|
|
100
|
+
| `createAgUiEventMapper` / `createAgUiHandler` / `createPersistenceAgUiReplay` / projection / limits (`packages/ag-ui`, `/acp`) | Host TUI/desktop coding apps (0.0.12) | **Extend** with co-work event types + thread/artifact handler scope; default-deny projection stands. |
|
|
101
|
+
| `createBrowserManager` / `createBrowserTools` / `policy.ts` / `network.ts` / snapshot / uploads / downloads / shared-sandbox (`packages/browser`) | Sandboxed Playwright tools (0.0.9–0.0.10) | **Extend** with checkpoint (`url`/`domainStateHash`/`hostDataRef`) + resume-verify-before-side-effect; no serialized browser internals. |
|
|
102
|
+
| `createWorkTools` / `createMemoryIdempotencyStore` / `identityKey` / `assertSafeArgv` / CLI runners (`packages/work-tools`) | M365/GWS connectors (0.0.13) | Reuse; consume per-identity OAuth tokens from Task 5; idempotent draft-then-approve mutations unchanged. |
|
|
103
|
+
|
|
104
|
+
### Primitive decision
|
|
105
|
+
|
|
106
|
+
**Authorized generic extensions (each needs ≥2 consumers or a conformance pair):**
|
|
107
|
+
|
|
108
|
+
1. Conversation thread metadata seam on session stores (consumers: sqlite + postgres; memory store explicit unsupported/linear fallback) + conversation service on server (consumers: host transports, AG-UI handler scope).
|
|
109
|
+
2. Memory consent/source/visibility fields + injection filter + lifecycle APIs (consumers: vector store + working store + prompt assembly filter + conformance suite).
|
|
110
|
+
3. Artifact record/revision/approval/delivery seam on persistence + server (consumers: sqlite + postgres + server handler + AG-UI co-work projection).
|
|
111
|
+
4. Schedule capability-token verification + revocation (consumers: workflow schedules + policy-ledger audit).
|
|
112
|
+
5. `DeviceAdapter` contract + deny-by-default `resolveDevicePolicy()` (conformance pair: future voice + desktop-control adapters; tested now via fixtures only).
|
|
113
|
+
6. M365/GWS `OAuthProvider` adapters + scope maps (consumers: work-tools M365 + GWS subpaths).
|
|
114
|
+
7. Browser checkpoint/resume-verify seam (consumers: conversation-scoped browser runs + workflow browser checkpoints).
|
|
115
|
+
|
|
116
|
+
**Authorized package changes — extensions plus exactly two new provider packages (`@arnilo/prism-provider-alibaba`, `@arnilo/prism-provider-ollama`):** server (conversation/artifact/delivery), memory (consent/lifecycle), ag-ui + acp (co-work events), credentials-node (OAuth adapters), work-tools (token wiring), browser (checkpoint), workflows (schedule capability), core (types + device contract), sqlite/postgres stores (session write seam + query filters; artifacts reuse the existing checkpoint store — no new schema).
|
|
117
|
+
|
|
118
|
+
**Rejected:** new conversation/artifact/device packages without measured evidence; Studio/chat UI; Slack/Teams channel packages; voice/desktop vendor packages; `WorkAgent` or second memory/event runtime; artifact blob store; serialized browser internals in checkpoints; cross-identity token fallback; model-selected scopes; any permission broadening (gate 8).
|
|
119
|
+
|
|
120
|
+
## Frozen finite limits and charging points
|
|
121
|
+
|
|
122
|
+
**Rule:** validate every untrusted field before persistence, provider call, connector spawn, event emission, link signing, or export enqueue. Owning tasks may tighten defaults but must not raise hard caps without updating this page, tests, and docs. All loops consume shared `RunLimits` (turn/tool/token/cost/wall).
|
|
123
|
+
|
|
124
|
+
### Conversations (Task 1)
|
|
125
|
+
|
|
126
|
+
| Resource | Default / hard cap | Charge/check point | Failure/cleanup owner |
|
|
127
|
+
| --- | ---: | --- | --- |
|
|
128
|
+
| Thread list page | 50 / 200 | Before store list query | Task 1 pages; ownership-scoped index required. |
|
|
129
|
+
| Event replay page rows | 100 / 500 | Before `queryEvents` | Task 1 pages; matches server replay. |
|
|
130
|
+
| Replay cursor | 4 KiB / 16 KiB | Before cursor parse | Task 1 rejects malformed cursors. |
|
|
131
|
+
| Thread title | 256 B / 2 KiB | Before create/rename persist | Task 1 truncates with marker or rejects. |
|
|
132
|
+
| Client request ID (idempotency) | 256 B / 2 KiB | Before continue/create dedup | Task 1 rejects oversized IDs. |
|
|
133
|
+
| Active branches per thread | 16 / 64 | Before branch create | Task 1 rejects with attributable error. |
|
|
134
|
+
| Export payload per request | 8 MiB / 32 MiB | Before export serialize | Task 1 stops with cursor; redactor applied. |
|
|
135
|
+
| Export pages per request | 100 / 500 | Before next export page | Task 1 stops; client re-requests with cursor. |
|
|
136
|
+
|
|
137
|
+
### Memory consent / proactive capability (Task 2)
|
|
138
|
+
|
|
139
|
+
| Resource | Default / hard cap | Charge/check point | Failure/cleanup owner |
|
|
140
|
+
| --- | ---: | --- | --- |
|
|
141
|
+
| Consent source string | 256 B / 2 KiB | Before remember/update persist | Task 2 rejects. |
|
|
142
|
+
| Consent metadata per record | 1 KiB / 8 KiB | Before persist | Task 2 rejects; never stores secrets. |
|
|
143
|
+
| Injection consent check | O(1) per record field check | During assembly filter | Task 2 excludes non-consented/invisible; no full-corpus scan. |
|
|
144
|
+
| Retention sweep batch | 500 / 5,000 | Per sweep tick | Task 2 pages; bounded time per batch. |
|
|
145
|
+
| Capability token record | 4 KiB / 16 KiB | Before enable/persist | Task 2 rejects. |
|
|
146
|
+
| Capability TTL | 24 h / 31 d | Before enable; recheck at fire | Task 2 expires fail-closed. |
|
|
147
|
+
| Revocation state | 1 boolean per token (no growing list) | On revoke | Task 2 marks token revoked + pauses schedule; nothing to compact. |
|
|
148
|
+
|
|
149
|
+
### Artifacts / review / delivery (Task 3)
|
|
150
|
+
|
|
151
|
+
| Resource | Default / hard cap | Charge/check point | Failure/cleanup owner |
|
|
152
|
+
| --- | ---: | --- | --- |
|
|
153
|
+
| Artifacts per thread | 64 / 256 | Before attach | Task 3 rejects. |
|
|
154
|
+
| Revisions per artifact | 32 / 128 | Before revise | Task 3 rejects; last-validated remains recoverable. |
|
|
155
|
+
| Artifact metadata record | 8 KiB / 64 KiB | Before persist | Task 3 rejects unrestricted payloads; no file bodies. |
|
|
156
|
+
| Preview metadata | 16 KiB / 64 KiB | Before persist | Task 3 rejects; metadata only, host renders content. |
|
|
157
|
+
| Citation / data-source refs | 32 / 128 entries | Before persist | Task 3 truncates with marker or rejects. |
|
|
158
|
+
| One citation ref | 2 KiB / 8 KiB | Before persist | Task 3 rejects. |
|
|
159
|
+
| MIME string | 128 B / 512 B | Before attach/revise | Task 3 rejects. |
|
|
160
|
+
| Hash string | 256 B / 1 KiB | Before attach/revise | Task 3 rejects. |
|
|
161
|
+
| Revisions per compare call | exactly 2 | Before compare | Task 3 rejects other arities; hash+metadata only. |
|
|
162
|
+
| Delivery link TTL | 5 min / 24 h | Before link sign | Task 3 rejects longer TTLs. |
|
|
163
|
+
| Delivery link token | 4 KiB / 16 KiB | Before verify | Task 3 rejects; reauthorize per download. |
|
|
164
|
+
|
|
165
|
+
### AG-UI co-work (Task 4)
|
|
166
|
+
|
|
167
|
+
| Resource | Default / hard cap | Charge/check point | Failure/cleanup owner |
|
|
168
|
+
| --- | ---: | --- | --- |
|
|
169
|
+
| Redacted browser snapshot payload | 256 KiB / 2 MiB | Before event emit | Task 4 truncates with marker or drops event. |
|
|
170
|
+
| Connector draft payload | 64 KiB / 512 KiB | Before event emit | Task 4 rejects oversized; draft stays in connector store. |
|
|
171
|
+
| Progress / approval record | 4 KiB / 16 KiB | Before event emit | Task 4 rejects. |
|
|
172
|
+
| Download-link event payload | 4 KiB / 16 KiB | Before event emit | Task 4 rejects; token only, never body. |
|
|
173
|
+
| Existing mapper/handler limits | unchanged from 0.0.12 | Existing resolve/emit paths | Task 4 does not raise them; overflow uses existing subscriber policy. |
|
|
174
|
+
|
|
175
|
+
### OAuth connectors (Task 5)
|
|
176
|
+
|
|
177
|
+
| Resource | Default / hard cap | Charge/check point | Failure/cleanup owner |
|
|
178
|
+
| --- | ---: | --- | --- |
|
|
179
|
+
| Scopes per grant | 16 / 64 | Before authorize URL / token exchange | Task 5 rejects non-map scopes; host-pinned map only. |
|
|
180
|
+
| One scope string | 128 B / 512 B | Before grant | Task 5 rejects. |
|
|
181
|
+
| Refresh attempts per resolve | 2 / 4 | Before refresh | Task 5 fails closed with attributable error. |
|
|
182
|
+
| Concurrent refreshes per identity+provider | 1 / 1 (single-flight) | Before refresh | Task 5 coalesces; no token storm on reconnect. |
|
|
183
|
+
| Revocation request timeout | 10 s / 60 s | Before revoke call | Task 5 marks locally revoked regardless; remote best-effort. |
|
|
184
|
+
| Token storage envelope | reuse credentials-node 4 MiB / 16 MiB | Before store write | Task 5 rejects; encrypted at rest. |
|
|
185
|
+
|
|
186
|
+
### Browser composition / device contracts (Task 6)
|
|
187
|
+
|
|
188
|
+
| Resource | Default / hard cap | Charge/check point | Failure/cleanup owner |
|
|
189
|
+
| --- | ---: | --- | --- |
|
|
190
|
+
| Checkpoint URL | 8 KiB / 16 KiB | Before checkpoint persist | Task 6 rejects. |
|
|
191
|
+
| Domain state hash | 256 B / 1 KiB | Before checkpoint persist | Task 6 rejects. |
|
|
192
|
+
| Host data ref | 2 KiB / 8 KiB | Before checkpoint persist | Task 6 rejects; refs only, never bodies. |
|
|
193
|
+
| Checkpoints per run | 16 / 64 | Before checkpoint persist | Task 6 evicts oldest or rejects. |
|
|
194
|
+
| Verify before side effect | mandatory after any resume/interruption | Before first mutating browser action | Task 6 reloads + verifies or fails closed. |
|
|
195
|
+
| Device enabled default | `false` (disabled by default) | Before any device admit | Task 6 denies without explicit consent+sandbox+approval. |
|
|
196
|
+
| Audio / screenshot / stream chunk | 1 MiB / 8 MiB | Before chunk accept/emit | Task 6 drops with marker; redactor applied. |
|
|
197
|
+
| Concurrent device sessions per identity | 1 / 4 | Before session admit | Task 6 rejects. |
|
|
198
|
+
| Device wall time / turns / tool calls | consume shared `RunLimits` | Existing run accounting | Task 6 denies on breach. |
|
|
199
|
+
|
|
200
|
+
**Forbidden:** unbounded replay/export scans, file-body persistence in artifact records, serialized browser internals in checkpoints, cross-identity token fallback, model-selected OAuth scopes, credentials in argv/model context/events, default-enabled devices, schedule execution without capability verification, raising hard caps silently, any permission broadening per gate 8.
|
|
201
|
+
|
|
202
|
+
## Channel and device capability freeze
|
|
203
|
+
|
|
204
|
+
| Channel / device | 0.0.14 status | Notes |
|
|
205
|
+
| --- | --- | --- |
|
|
206
|
+
| Web / AG-UI host TUI/desktop | supported (0.0.12 + co-work extensions) | Primary surface; co-work events ride official AG-UI schemas. |
|
|
207
|
+
| ACP sibling | supported where stable contracts overlap | `./acp` parity for co-work where `session/update` covers it. |
|
|
208
|
+
| Slack / Teams chat channels | deferred — demand-gated | Added only after web/AG-UI demand is measured (roadmap); no package/export/docs entry in 0.0.14. |
|
|
209
|
+
| Realtime voice | contract + conformance only | `DeviceAdapter` + deny-by-default policy; vendor packages demand-gated 0.1.x. |
|
|
210
|
+
| Desktop OS / computer control | contract + conformance only | Same; approval-aware, isolated, observable, disabled by default. |
|
|
211
|
+
| Playwright browser | supported via `@arnilo/prism-browser` | Conversation composition through existing sandbox/egress/secret/approval/limit policy; checkpoint = verified state. |
|
|
212
|
+
| Push notification daemon / always-on proactive agent | unsupported | Host transports consume replay streams; schedules need explicit enablement + revocable capability. |
|
|
213
|
+
|
|
214
|
+
## Threat and authority matrix
|
|
215
|
+
|
|
216
|
+
| Boundary | Trusted authority | Untrusted input | Mandatory control | Default / unsupported |
|
|
217
|
+
| --- | --- | --- | --- | --- |
|
|
218
|
+
| Thread ownership | Verified `AgentIdentity` → ownership | Caller thread IDs/cursors | Authorize + ownership on every op; wrong-user → not-found/forbidden | Cross-user list/continue/export unsupported. |
|
|
219
|
+
| Replay / continue | Durable cursor + checkpoint CAS | Cursor tampering, reconnect storms | Page→live at-least-once with stable IDs; CAS resume; request-id idempotency | Rerunning completed tool calls unsupported. |
|
|
220
|
+
| Memory consent | User consent record + injection filter | Model-requested recall, export flags | Consent+visibility enforced at assembly; revocation immediate | Non-consented/invisible memory in prompts/events/exports unsupported. |
|
|
221
|
+
| Proactive schedules | Explicit enablement + capability token | Schedule fire without recheck | Fire-time identity + consent re-verification; revocation fail-closed; policy audit | Default-on proactivity unsupported. |
|
|
222
|
+
| Artifact records | Identity + thread ownership + CAS | Revision storms, stale approvals | Version CAS; approval state machine; metadata-only persistence | File-body store / blind approve unsupported. |
|
|
223
|
+
| Delivery links | Signed expiring token | Link replay/share | TTL ≤ hard cap; reauthorize per download; ownership check | Permanent/public links unsupported. |
|
|
224
|
+
| Exports | Identity + redactor | Export page requests | Bounded pages; redacted payloads; legal-hold honored | Unredacted / unbounded export unsupported. |
|
|
225
|
+
| OAuth tokens | Host-pinned scope map + encrypted store | Model scope requests, cross-identity reuse | Least-privilege per bundle; single-flight refresh; per-identity isolation; redaction everywhere | Model-selected scopes / token fallback / credentials in argv unsupported. |
|
|
226
|
+
| Browser checkpoints | Verified URL/domain state + host data refs | Resumed context claims | Reload + verify before side effect; no serialized internals | Side-effect replay after interruption unsupported. |
|
|
227
|
+
| Device streams | Explicit consent + sandbox + approval | Stream chunks | Disabled by default; chunk caps; `tool_approval` for side effects; redacted telemetry | Default-enabled voice/desktop unsupported. |
|
|
228
|
+
| Co-work events | Default-deny projection | Client event payloads | No local paths/raw args/secrets; malformed events fail closed; `EventSchemas` validation | Raw tool payload / filesystem path events unsupported. |
|
|
229
|
+
| Permission surface | Roadmap gate 8 | Feature pressure | Non-broadening regression in Task 8 | Any new default consent/memory/network/file/browser/connector/tool permission unsupported. |
|
|
230
|
+
|
|
231
|
+
## Validation matrix for Task 0
|
|
232
|
+
|
|
233
|
+
| Check | Frozen assertion |
|
|
234
|
+
| --- | --- |
|
|
235
|
+
| Traceability | Every Phase 9 roadmap Functional/Performance/Code Quality/Security criterion has one primary Task 1–8 owner; Studio/Slack/Teams/voice-vendor/desktop-vendor/Office have none. |
|
|
236
|
+
| Package names | Exactly two new provider packages (`@arnilo/prism-provider-alibaba`, `@arnilo/prism-provider-ollama`); 41 → 43 manifests at release; otherwise extensions only in server, memory, ag-ui(+acp), credentials-node, work-tools, browser, workflows, core types, sqlite/postgres stores. |
|
|
237
|
+
| Primitive reuse | Only the seven authorized generic extensions above; each has ≥2 consumers or a conformance pair; no `WorkAgent`, second memory runtime, or second event system. |
|
|
238
|
+
| Gate 8 | No permission broadening; device adapters disabled by default; schedules require explicit enablement + revocable capability; Task 8 ships a non-broadening regression. |
|
|
239
|
+
| Replay semantics | Ownership-scoped cursor; page→live at-least-once; stable IDs for dedup; CAS resume; terminal replay never invokes provider/tools. |
|
|
240
|
+
| Token shapes | MemoryConsent, ScheduleCapability, DeliveryLink shapes frozen above; all expiring and ownership-bound. |
|
|
241
|
+
| Finite resources | All conversation/memory/artifact/co-work/connector/browser/device caps above enforced by owning tasks; shared `RunLimits` for review/browser loops. |
|
|
242
|
+
| Security | Verified identity owns every action; consent/permission rechecked on resume and fire; links authorized+expiring; tokens/paths/secrets/document-private data never enter model context, events, telemetry, or unauthorized exports. |
|
|
243
|
+
|
|
244
|
+
## Documentation and release ownership
|
|
245
|
+
|
|
246
|
+
- Task 0: this evidence page, `docs/index.md` link, and `docs.test.ts` Phase 9 regression guard.
|
|
247
|
+
- Task 1: `docs/conversations.md` (new) + server/session-store updates.
|
|
248
|
+
- Task 2: `docs/working-and-semantic-memory.md` + workflow/policy consent/capability notes.
|
|
249
|
+
- Task 3: `docs/work-artifacts-and-review.md` (new) + server/persistence updates.
|
|
250
|
+
- Task 4: `docs/ag-ui.md` co-work event tables + ACP parity notes.
|
|
251
|
+
- Task 5: `docs/credential-storage.md` + `docs/work-connectors.md` OAuth scope maps.
|
|
252
|
+
- Task 6: `docs/browser-automation.md` checkpoint/resume + device-contract deferral note in `docs/migration.md`.
|
|
253
|
+
- Task 7: canonical docs, examples, migration, index navigation.
|
|
254
|
+
- Task 8: 0.0.14 graph, `scripts/benchmark-0.0.14.mjs`, pack/install, supply-chain, dry-run publish, roadmap completion evidence.
|
|
255
|
+
|
|
256
|
+
No public implementation API changes land in Task 0. This page, `roadmap.md` Phase 9, and Plan 077 are authoritative until implementation; later tasks may tighten defaults but cannot widen scope, raise hard caps, add packages, ship channel/voice/desktop vendor implementations, store artifact file bodies, serialize browser internals, or broaden permissions without updating this evidence, tests, docs, and plan.
|
package/docs/server.md
CHANGED
|
@@ -137,6 +137,8 @@ Compose beside `createPrismHandler` — Prism starts no listener, container orch
|
|
|
137
137
|
| `rateLimit` on handler | Host adapter after authorize, before session create. Return denial `{ retryAfterMs, code, message }` → `429` + optional `Retry-After`. `createMemoryRateLimiter` is single-process only. |
|
|
138
138
|
| `createPrismEventReplay` / `createPrismReplayHandler` | Ownership-scoped `queryEvents` pages (`redacted: true`). Does not re-run work. Unauthorized replay denies. |
|
|
139
139
|
| `createPrismDeploymentLease` | Lease election under `prism.server.deployment`. Coordinator replica holds `key: "coordinator"` before schedule ticks; workers run `@arnilo/prism-workflows` `createWorkflowCoordinator` for queued runs (fencing tokens). |
|
|
140
|
+
| `createConversationService` / `createConversationHandler` | Durable user-scoped conversation threads (create/list/continue/branch/archive/export/delete) over session + event-ledger seams, with thread-bound reconnectable replay. Mounts beside the handler; see [Conversations](conversations.md). |
|
|
141
|
+
| `createArtifactService` / `createArtifactHandler` | Durable artifact co-work review (attach/revise/compare/approve/reject/last-validated/delivery-link + authorized download) over the versioned checkpoint store; records persist metadata/revisions/approvals only, never file bodies. Mounts beside the handler; see [Work artifacts and review](work-artifacts-and-review.md). |
|
|
140
142
|
|
|
141
143
|
**Queues:** Redis/SQS/other adapters are absent. Postgres checkpoint polling via `createWorkflowCoordinator` remains the default background path until a measured polling/load justification is recorded.
|
|
142
144
|
|
|
@@ -168,5 +170,7 @@ A2A routes are not added to `createPrismHandler()`. Install `@arnilo/prism-super
|
|
|
168
170
|
- [MCP client and server exposure](mcp-tools.md): selected MCP capabilities and web-standard MCP transport.
|
|
169
171
|
- [Host security guide](host-security.md): remote-boundary checklist.
|
|
170
172
|
- [A2A interoperability](a2a.md): separately mounted A2A 1.0 handler/client.
|
|
173
|
+
- [Conversations](conversations.md): durable user-scoped conversation service, replay, branches, export, deletion.
|
|
174
|
+
- [Work artifacts and review](work-artifacts-and-review.md): durable artifact review service, revisions, approvals, authorized expiring delivery links.
|
|
171
175
|
- [Frontend interoperability (AG-UI and ACP)](ag-ui.md): separately installed authorized AG-UI Web handler; it is not a `@arnilo/prism-server` route.
|
|
172
176
|
- [Release and install](release-and-install.md): optional package installation and profiles.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Work artifacts and review
|
|
2
|
+
|
|
3
|
+
## What it does
|
|
4
|
+
|
|
5
|
+
`@arnilo/prism-server` ships a durable artifact co-work review service (Phase 9 / 0.0.14): authorized attach of source/output references with MIME/hash/version, producer-run attribution, citations/data sources, and preview metadata; revision comparison; reviewer approve/reject (request-changes) with last-validated recovery; and authorized, expiring delivery links. Core (`@arnilo/prism`) exports artifact **types only** (`ArtifactRecord`, `ArtifactRevision`, `ArtifactApproval`, `ArtifactDeliveryToken`, approval state `pending | approved | rejected`). Prism persists bounded metadata, revisions, approvals, and delivery references over the existing versioned checkpoint store — **never file bodies**; hosts own blob storage and rendering.
|
|
6
|
+
|
|
7
|
+
## When to use it
|
|
8
|
+
|
|
9
|
+
- Durable human-in-the-loop review of agent-produced outputs (drafts, exports, generated files) where users compare revisions, request changes, and approve/reject.
|
|
10
|
+
- Authorized, time-boxed delivery of a validated artifact revision to a downstream consumer.
|
|
11
|
+
- Recovering the last approved ("validated") revision after a later revision is rejected.
|
|
12
|
+
|
|
13
|
+
Not for: storing file content (use host blob storage), local Office preview/rendering (host-owned), or SaaS connector delivery (see work-connectors).
|
|
14
|
+
|
|
15
|
+
## Inputs / request
|
|
16
|
+
|
|
17
|
+
`createArtifactService(store: CheckpointStore, options)`:
|
|
18
|
+
|
|
19
|
+
| Field | Required | Meaning |
|
|
20
|
+
| --- | --- | --- |
|
|
21
|
+
| `store` | yes | Any `CheckpointStore` (sqlite/postgres `persistence.checkpoints`, or `createMemoryCheckpointStore()` for tests) |
|
|
22
|
+
| `options.redactor` | yes | `SecretRedactor`; records are redacted before persist and on every response |
|
|
23
|
+
| `options.linkSecret` | yes | Host HMAC key material for signing/verifying delivery links |
|
|
24
|
+
| `options.limits` | no | Frozen caps (below); each clamped to a hard maximum |
|
|
25
|
+
| `options.onDecision` | no | Audit seam (redacted refs) for attach/revise/approve/reject; bridge to `@arnilo/prism-policy` |
|
|
26
|
+
|
|
27
|
+
Every operation input carries `ownership` (from host `authorize`, never request JSON) plus optional verified `identity`. `attach` requires `threadId`, `uri`, `mime`, `hash`; `revise` requires `uri`, `hash` (mime defaults to the previous revision); `compare` requires two distinct revision numbers; `approve`/`reject` require a `version`; `deliveryLink` accepts optional `version` (defaults to last validated, else latest) and `ttlSeconds`.
|
|
28
|
+
|
|
29
|
+
## Outputs / response / events
|
|
30
|
+
|
|
31
|
+
| API | Result |
|
|
32
|
+
| --- | --- |
|
|
33
|
+
| `attach` | `ArtifactRecord` with revision 1, pending state (idempotent get-or-create with explicit `id`) |
|
|
34
|
+
| `list` | Ownership/thread-scoped `PersistencePage<ArtifactRecord>` |
|
|
35
|
+
| `get` | `ArtifactRecord` |
|
|
36
|
+
| `revise` | `ArtifactRecord` with an appended revision (new revision resets state to pending) |
|
|
37
|
+
| `compare` | `{ artifactId, from, to, changed: { hash, mime, uri, citations } }` — hash+metadata only |
|
|
38
|
+
| `approve` / `reject` | `ArtifactRecord`; approve advances `lastValidatedVersion`, reject never clears it |
|
|
39
|
+
| `lastValidated` | The last approved `ArtifactRevision` (fails closed before any approval) |
|
|
40
|
+
| `deliveryLink` | `{ link, token }` — signed expiring `ArtifactDeliveryToken` |
|
|
41
|
+
|
|
42
|
+
No package-owned agent events are emitted; `onDecision` is the audit seam (redacted actor refs only).
|
|
43
|
+
|
|
44
|
+
## Request/response example
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"attach": { "threadId": "thread-1", "uri": "https://blob.example/doc-v1", "mime": "text/markdown", "hash": "sha256:aaa" },
|
|
49
|
+
"compare": { "from": 1, "to": 2, "changed": { "hash": true, "mime": false, "uri": true, "citations": false } },
|
|
50
|
+
"approve": { "version": 2, "lastValidatedVersion": 2, "approvals": [{ "version": 2, "state": "approved", "reviewer": "user:user-1" }] },
|
|
51
|
+
"deliveryLink": { "link": "<base64url payload>.<base64url hmac>", "token": { "artifactId": "art_1", "version": 2, "expiresAt": "2026-07-25T04:10:00.000Z" } }
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Implementation example
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
import { createSecretRedactor } from "@arnilo/prism";
|
|
59
|
+
import { createSqlitePersistence } from "@arnilo/prism-session-store-sqlite";
|
|
60
|
+
import { createArtifactService, createArtifactHandler } from "@arnilo/prism-server";
|
|
61
|
+
|
|
62
|
+
const persistence = createSqlitePersistence({ filename: "prism.db" });
|
|
63
|
+
const artifacts = createArtifactService(persistence.checkpoints, {
|
|
64
|
+
redactor: createSecretRedactor([/* host secrets */]),
|
|
65
|
+
linkSecret: process.env.PRISM_ARTIFACT_LINK_SECRET!,
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const record = await artifacts.attach({ ownership, identity, threadId: "thread-1", uri: "https://blob.example/doc", mime: "text/markdown", hash: "sha256:aaa" });
|
|
69
|
+
await artifacts.revise({ ownership, threadId: "thread-1", artifactId: record.id, uri: "https://blob.example/doc-v2", hash: "sha256:bbb" });
|
|
70
|
+
await artifacts.approve({ ownership, identity, threadId: "thread-1", artifactId: record.id, version: 2 });
|
|
71
|
+
const { link } = await artifacts.deliveryLink({ ownership, threadId: "thread-1", artifactId: record.id });
|
|
72
|
+
|
|
73
|
+
// Framework-free HTTP adapter (default base /prism/artifacts); ownership only from authorize.
|
|
74
|
+
export const handler = createArtifactHandler({ service: artifacts, authorize: hostAuthorize, linkSecret: process.env.PRISM_ARTIFACT_LINK_SECRET! });
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Extension and configuration notes
|
|
78
|
+
|
|
79
|
+
- Artifact records are versioned checkpoint values (namespace `prism.artifact`, key `threadId:artifactId`). The checkpoint `version` is the CAS counter for concurrent reviewers, distinct from revision numbers. Any `CheckpointStore` works; sqlite/postgres persistence already expose `.checkpoints`, so there is no separate artifact schema or migration.
|
|
80
|
+
- `createArtifactHandler` mounts attach/list/get/revise/compare/approve/reject/last-validated/delivery-link plus `GET /prism/artifacts/download?link=…`. Download verifies the link signature + expiry, then **reauthorizes** against the token's ownership (mismatch fails closed), and returns the authorized revision reference only — the host fetches the body.
|
|
81
|
+
- Delivery links are `base64url(payload).base64url(HMAC-SHA256)` over `{ artifactId, threadId, version, ownership, issuedAt, expiresAt }`; they are reauthorized per download and are not bearer secrets.
|
|
82
|
+
- Review loops driven by an agent consume the shared `RunLimits` at the host's agent layer; the artifact service itself is a passive, bounded record store.
|
|
83
|
+
|
|
84
|
+
## Security and performance notes
|
|
85
|
+
|
|
86
|
+
- Every operation requires authenticated identity + thread ownership derived from host `authorize`; cross-ownership access fails closed as `not_found` (never leaks existence).
|
|
87
|
+
- Concurrent reviewer conflicts resolve via checkpoint CAS (`expectedVersion`); the loser gets a retryable `conflict` and no approval is lost or duplicated. A throw before commit persists nothing, so failed updates roll back.
|
|
88
|
+
- Local filesystem paths are rejected in `uri`/citations (`file:`, absolute, or drive paths); records are redacted before persist and on response, so paths/secrets/document-private data never enter records, events, or exports.
|
|
89
|
+
- Frozen caps (default / hard): artifacts per thread 64/256; revisions per artifact 32/128; record 8/64 KiB; preview 16/64 KiB; citations 32/128 and 2/8 KiB each; MIME 128/512 B; hash 256/1 KiB; compare exactly 2 revisions; delivery TTL 5 min/24 h; delivery token 4/16 KiB. Raising the revision cap may require raising `recordBytes` (aggregate backstop).
|
|
90
|
+
- Compare is hash+metadata-bounded (hosts render content); no file bodies are persisted or transferred.
|
|
91
|
+
|
|
92
|
+
## Related APIs
|
|
93
|
+
|
|
94
|
+
- [Server](server.md): `createArtifactService` / `createArtifactHandler` mount alongside the Prism handler; ownership only from `authorize`.
|
|
95
|
+
- [Conversations](conversations.md): artifact threads reuse conversation thread ownership scoping.
|
|
96
|
+
- [Database persistence](database-persistence.md): artifact records persist as versioned checkpoint values (sqlite/postgres `.checkpoints`).
|
|
97
|
+
- [Workflows](workflows.md): durable suspend/approve seam; hosts may gate revisions behind `tool_approval`.
|
|
98
|
+
- [Policy and audit](policy-and-audit.md): `onDecision` events bridge here for an auditable review ledger.
|
|
99
|
+
- [Host security](host-security.md): identity/ownership, redaction, and expiring-link boundaries.
|
|
100
|
+
- [Frontend interoperability (AG-UI and ACP)](ag-ui.md): projects artifact progress/approval/download-link as redacted co-work events over the durable-resume stream.
|
package/docs/work-connectors.md
CHANGED
|
@@ -23,6 +23,10 @@ See [Work tools](work-tools.md). Adapter: `createGoogleWorkspaceCliAdapter` / su
|
|
|
23
23
|
|
|
24
24
|
Uses [`@googleworkspace/cli` (`gws`)](https://github.com/googleworkspace/cli): `gmail users messages list|get`, `gmail +send`, `calendar events list|insert`, `drive files list|create`, `drive permissions create`, `tasks tasks *`. Docs/Sheets/Slides create remain capability-gated. Discovery `schema` and `auth`/`login`/`setup` are forbidden from Prism argv.
|
|
25
25
|
|
|
26
|
+
## Scoped OAuth establishment (0.0.14)
|
|
27
|
+
|
|
28
|
+
Hosts establish, refresh, and revoke scoped OAuth credentials for these workloads through the existing `OAuthProvider` / credential-store seams (`@arnilo/prism-credentials-node`): `createMicrosoft365OAuthProvider` / `createGoogleWorkspaceOAuthProvider` (PKCE + device code), least-privilege scope bundles per capability (`resolveMicrosoft365Scopes` / `resolveGoogleWorkspaceScopes`, read vs mutation). Connectors consume a per-identity token via a late-bound `tokenProvider` injected as an env var — never argv, never model context; revocation fails closed. See [Credential storage](credential-storage.md) and [Work tools](work-tools.md).
|
|
29
|
+
|
|
26
30
|
## Out of scope
|
|
27
31
|
|
|
28
|
-
Local Office binaries, model-controlled CLI, generic Graph/Discovery free-form calls, tenant-admin/login/debug from Prism.
|
|
32
|
+
Local Office binaries, model-controlled CLI, generic Graph/Discovery free-form calls, tenant-admin/login/debug from Prism. **Slack/Teams chat-channel adapters are not shipped** (demand-gated until web/AG-UI usage is measured); the M365 `teams` capability op is a separate gated workload op, not a channel adapter.
|
package/docs/work-tools.md
CHANGED
|
@@ -30,6 +30,8 @@ const microsoft365 = createMicrosoft365CliAdapter({
|
|
|
30
30
|
binary: process.env.M365_BIN!,
|
|
31
31
|
configDir: `/var/prism/m365/${tenant}/${user}`,
|
|
32
32
|
identity,
|
|
33
|
+
// Optional late-bound per-identity token (0.0.14): env var only, never argv/model context.
|
|
34
|
+
// tokenProvider: createOAuthWorkTokenProvider({ provider: m365OAuth, store, envVar: "M365_ACCESSTOKEN" }),
|
|
33
35
|
});
|
|
34
36
|
|
|
35
37
|
const googleWorkspace = createGoogleWorkspaceCliAdapter({
|
|
@@ -102,6 +104,7 @@ Mutation tools (`*_mail_draft_send`, `*_draft_*`) create an in-adapter draft and
|
|
|
102
104
|
## Security
|
|
103
105
|
|
|
104
106
|
- Require host-verified `AgentIdentity`; no cross-identity configDir reuse.
|
|
107
|
+
- Connector tokens (0.0.14): an optional `tokenProvider` resolves a per-identity access token into an env var per call — never argv, never model context. A missing/expired/revoked/cross-identity/wrong-tenant token fails the call closed before any exec. Refresh is late-bound and single-flighted per account (no refresh storm under reconnect). Build one with `createOAuthWorkTokenProvider()` from `@arnilo/prism-credentials-node`.
|
|
105
108
|
- External mail recipients fail closed unless `externalRecipients.allow` returns true.
|
|
106
109
|
- Anonymous / `anyone` sharing denied.
|
|
107
110
|
- CLI stdout/stderr capped; NDJSON page streams strictly parsed and page-capped; process killed on timeout/abort/overflow.
|
package/docs/workflows.md
CHANGED
|
@@ -18,6 +18,7 @@ Primary exports:
|
|
|
18
18
|
| `createWorkflowCommands` | Optional `CommandDefinition[]` for direct/background/replay/status/list/cancel/resume and, when selected, schedule control |
|
|
19
19
|
| `enqueueWorkflow` / `startWorkflowBackground` / `createWorkflowCoordinator` | Persist queued work and atomically claim/renew/execute it across processes using `LeaseStore` |
|
|
20
20
|
| `createWorkflowSchedules` | Explicit ownership-scoped one-time/interval/host-calculated schedules over existing checkpoint/lease stores |
|
|
21
|
+
| `createProactiveScheduleCapabilities` | Scoped, expiring, revocable capability tokens that enable proactive schedules; revocation stops firing fail-closed |
|
|
21
22
|
|
|
22
23
|
Included through `@arnilo/prism-sdk` and `@arnilo/prism-all`; installing either profile does not start workflows. Interactive TUI is out of scope (C-012 deferred).
|
|
23
24
|
|
|
@@ -82,6 +83,8 @@ Every node receives bounded `ctx.state`, `ctx.stateVersion`, and async `ctx.upda
|
|
|
82
83
|
|
|
83
84
|
`createWorkflowSchedules({ store, leases, checkpoints, workflows, ownership, ownerId, calculators? })` is inert until its host calls `pollOnce()` or `run({ signal })`. Ownership requires `tenantId` plus `accountId` or `userId`. Methods are `create`, `get`, `list`, `pause`, `resume`, `trigger`, `delete`, `pollOnce`, and `run`. A record has one required `nextRunAt`, optional fixed `intervalMs` or registered `calculatorId` (never both), bounded input/metadata, status, version, and last-fire attribution. Manual trigger requires an idempotency key. Scheduled run IDs derive from schedule ID plus fire timestamp, so retry after enqueue-before-advance finds the same queued checkpoint instead of duplicating it. Defaults: page 100/hard 500, due claims 16/hard 256, input 256 KiB/hard 1 MiB, poll 1s, fire lease 30s.
|
|
84
85
|
|
|
86
|
+
`createProactiveScheduleCapabilities({ schedules, store, ownership, ownerId, defaultTtlMs?, maxTtlMs?, onCapability? })` wraps a `WorkflowSchedules` facade in explicit user enablement. `enable({ workflowId, scope, actor, nextRunAt, intervalMs?|calculatorId?, input?, ttlMs? })` creates the schedule plus a scoped, expiring `ScheduleCapabilityToken` (default TTL 24h / hard 31d, record ≤ 16 KiB) stamped with redacted actor refs. `revoke(tokenId, actor)` marks the token revoked and pauses the underlying schedule so `pollOnce()` never fires it (fail-closed). `assertActive(tokenId)` is a fail-closed guard for manual trigger paths — it throws on missing/revoked/expired tokens. `onCapability` emits `capability_enabled` / `capability_revoked` / `capability_denied` events (redacted refs only) that hosts bridge to `@arnilo/prism-policy` for an auditable ledger. Tokens are ownership-scoped checkpoint records; no cron expression or secret is persisted.
|
|
87
|
+
|
|
85
88
|
## Outputs / response / events
|
|
86
89
|
|
|
87
90
|
`runWorkflow` / `resumeWorkflow` resolve to `WorkflowRunResult`:
|
|
@@ -280,6 +283,7 @@ runRpcServer({
|
|
|
280
283
|
- Nested workflows inherit host registries/policies and cannot inject broader tools, agents, ownership, or credentials. Nested depth is inherited; child suspension bubbles to the parent review cursor.
|
|
281
284
|
- Replay source ownership/hash/status/node eligibility are checked before a new checkpoint is created. Source records are immutable, lineage is bounded, and copied approval-bearing paths are rejected.
|
|
282
285
|
- Schedule services are ownership-scoped and explicitly started. Per-fire leases plus deterministic run IDs/CAS prevent duplicate enqueue across coordinators and crash retry. Host calculator IDs resolve only from the supplied map; no callback or cron expression is persisted.
|
|
286
|
+
- Proactive schedules require an explicit capability grant. Revocation pauses the schedule (never fired by `pollOnce`) and `assertActive` fails closed on missing/revoked/expired tokens; enable/revoke/deny events carry redacted actor refs for the host policy ledger. Capability TTL is capped (default 24h / hard 31d) and the token record is byte-bounded (≤ 16 KiB); tokens are ownership-scoped, so foreign access fails closed rather than leaking existence.
|
|
283
287
|
- Scheduler stores O(nodes + active outputs + bounded state history); ready-node work uses indegree maps, not repeated full scans.
|
|
284
288
|
- Lease acquisition is atomic; opaque tokens protect renew/release; monotonically increasing fencing tokens plus checkpoint compare-and-swap prevent expired workers from committing after takeover. Node functions must honor `ctx.signal` for prompt cooperative cancellation.
|
|
285
289
|
|