@arnilo/prism 0.0.12 → 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 +23 -0
- package/README.md +8 -2
- package/dist/agents.js +21 -2
- package/dist/artifacts.d.ts +78 -0
- package/dist/artifacts.js +24 -0
- package/dist/contracts.d.ts +35 -1
- 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/extensions.d.ts +11 -0
- package/dist/extensions.js +15 -0
- package/dist/identity.d.ts +92 -0
- package/dist/identity.js +257 -0
- package/dist/index.d.ts +15 -5
- package/dist/index.js +8 -3
- package/dist/persistence-lifecycle.d.ts +103 -0
- package/dist/persistence-lifecycle.js +204 -0
- package/dist/providers/openai-compatible.d.ts +5 -1
- package/dist/providers/openai-compatible.js +15 -6
- package/dist/providers/openai-primitives.js +5 -2
- package/dist/secure-agent.js +7 -1
- package/dist/testing/persistence-schema.d.ts +2 -2
- package/dist/testing/persistence-schema.js +35 -2
- package/dist/tools.d.ts +2 -0
- package/dist/tools.js +6 -0
- package/docs/a2a.md +2 -0
- package/docs/ag-ui.md +5 -0
- package/docs/agent-identity.md +111 -0
- package/docs/browser-automation.md +3 -0
- package/docs/conversations.md +135 -0
- package/docs/credential-storage.md +31 -1
- package/docs/credentials-and-redaction.md +2 -0
- package/docs/database-persistence.md +22 -7
- package/docs/device-adapters.md +97 -0
- package/docs/extensions.md +1 -0
- package/docs/guardrails.md +3 -0
- package/docs/host-security.md +9 -3
- package/docs/index.md +26 -13
- package/docs/mcp-tools.md +2 -0
- package/docs/migration.md +48 -0
- package/docs/model-routing.md +102 -0
- package/docs/observability.md +2 -0
- package/docs/performance.md +21 -0
- package/docs/policy-and-audit.md +128 -0
- package/docs/postgres-persistence.md +1 -1
- package/docs/provider-caching.md +4 -0
- package/docs/provider-packages.md +12 -2
- package/docs/provider-request-policies.md +2 -0
- package/docs/providers/alibaba.md +179 -0
- package/docs/providers/azure.md +74 -0
- package/docs/providers/bedrock.md +72 -0
- package/docs/providers/google.md +1 -0
- package/docs/providers/ollama.md +166 -0
- package/docs/providers/openai-compatible.md +3 -1
- package/docs/providers/openrouter.md +2 -0
- package/docs/providers/vertex.md +71 -0
- package/docs/public-contracts.md +3 -1
- package/docs/release-and-install.md +149 -7
- package/docs/review-coverage-2026-07-23-phase-8.md +245 -0
- package/docs/review-coverage-2026-07-25-phase-9.md +256 -0
- package/docs/runs-and-usage.md +2 -0
- package/docs/server.md +37 -4
- package/docs/sqlite-persistence.md +1 -1
- package/docs/supervisors.md +2 -0
- package/docs/work-artifacts-and-review.md +100 -0
- package/docs/work-connectors.md +32 -0
- package/docs/work-tools.md +117 -0
- package/docs/workflows.md +4 -0
- package/docs/working-and-semantic-memory.md +20 -5
- package/package.json +4 -1
- package/templates/init/providers.json +22 -0
|
@@ -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/runs-and-usage.md
CHANGED
|
@@ -286,6 +286,7 @@ console.log(cacheUsageReport(aggregate?.usage));
|
|
|
286
286
|
- **Idempotency is host-owned.** The runtime writes the key into `RunRecord.idempotencyKey`; enforcing unique keys and deduplicating retries is the host adapter's responsibility.
|
|
287
287
|
- **Tenant isolation.** `OwnershipScope` fields are copied from the active ownership scope, but the runtime does not enforce tenant isolation for ledger rows. Feedback is stricter: append/query/delete require tenant plus account/user, and first-party stores compare the exact scope to the linked run.
|
|
288
288
|
- **Feedback privacy.** Comments/tags/metadata can contain PII. Configure a feedback redactor, apply retention, and call owned `delete()` for erasure. Never copy comments or tag values into metric labels.
|
|
289
|
+
- **Policy audit is separate.** Enterprise allow/deny/modify/approval rows with evidence refs live in optional `@arnilo/prism-policy`, not `RunLedger`. See [Policy and audit](policy-and-audit.md).
|
|
289
290
|
|
|
290
291
|
## Optional batching and durability
|
|
291
292
|
|
|
@@ -304,6 +305,7 @@ Runtime session snapshots cache one leaf/generation for at most one second. Succ
|
|
|
304
305
|
|
|
305
306
|
## Related APIs
|
|
306
307
|
|
|
308
|
+
- [Policy and audit](policy-and-audit.md): optional enterprise decision ledger (separate from run usage rows).
|
|
307
309
|
- [Performance limits](performance.md): batching, cursor keys, and production sizing assumptions.
|
|
308
310
|
- [Agent/session runtime](agent-session-runtime.md): `session.run()` and runtime event emission.
|
|
309
311
|
- [Agent events](agent-events.md): `AgentEvent` union and `session.subscribe()`.
|
package/docs/server.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
## What it does
|
|
4
4
|
|
|
5
|
-
`@arnilo/prism-server` exposes explicitly selected agents and workflows through one framework-free `(Request) => Promise<Response>` handler. It supports direct agent results, bounded agent/workflow SSE, opt-in durable agent status/resume, durable workflow start/enqueue/status/cancel/resume/replay, ownership-scoped schedules, host authorization, ownership propagation, redaction, and
|
|
5
|
+
`@arnilo/prism-server` exposes explicitly selected agents and workflows through one framework-free `(Request) => Promise<Response>` handler. It supports direct agent results, bounded agent/workflow SSE, opt-in durable agent status/resume, durable workflow start/enqueue/status/cancel/resume/replay, ownership-scoped schedules, host authorization, ownership propagation, redaction, resource ceilings, and optional deployment seams (health/readiness, drain, host rate-limit adapter, ownership-scoped event replay, worker/coordinator lease election).
|
|
6
6
|
|
|
7
|
-
No listener starts on import. Empty `agents`/`workflows` maps expose nothing. Authentication, authorization, route selection, durable stores, TLS, rate limiting, and framework/serverless adaptation remain host-owned.
|
|
7
|
+
No listener starts on import. Empty `agents`/`workflows` maps expose nothing. Authentication, authorization, route selection, durable stores, TLS, distributed rate limiting, queues, and framework/serverless adaptation remain host-owned.
|
|
8
8
|
|
|
9
9
|
## When to use it
|
|
10
10
|
|
|
@@ -15,6 +15,7 @@ Use `AgentSession` or workflow APIs directly for in-process applications. Do not
|
|
|
15
15
|
## Inputs / request
|
|
16
16
|
|
|
17
17
|
```ts
|
|
18
|
+
const drain = createPrismDrainController({ deadlineMs: 30_000 });
|
|
18
19
|
const handler = createPrismHandler({
|
|
19
20
|
agents?: Record<string, Agent | PrismAgentExposure>,
|
|
20
21
|
agentRuns?: Record<string, PrismAgentRunExposure>, // explicit durable status/resume only
|
|
@@ -22,8 +23,11 @@ const handler = createPrismHandler({
|
|
|
22
23
|
schedules?: WorkflowSchedules | ((authorization, signal) => WorkflowSchedules),
|
|
23
24
|
authorize: async ({ request, operation, capabilityId }) => false | {
|
|
24
25
|
ownership: { tenantId?: string; accountId?: string; userId?: string },
|
|
26
|
+
identity?: AgentIdentity, // optional host-verified; must match ownership
|
|
25
27
|
metadata?: Record<string, unknown>,
|
|
26
28
|
},
|
|
29
|
+
drain?, // blocks admit ops with 503 while draining
|
|
30
|
+
rateLimit?, // host adapter after authorize, before session/run create
|
|
27
31
|
basePath?: "/prism",
|
|
28
32
|
allowedHosts?: string[],
|
|
29
33
|
allowedOrigins?: string[],
|
|
@@ -31,6 +35,7 @@ const handler = createPrismHandler({
|
|
|
31
35
|
limits?: PrismServerLimits,
|
|
32
36
|
disconnectAborts?: boolean,
|
|
33
37
|
});
|
|
38
|
+
const health = createPrismHealthHandler({ ready: () => store.ping(), drain });
|
|
34
39
|
```
|
|
35
40
|
|
|
36
41
|
At least one non-empty ownership field must come from `authorize()`. Request JSON never chooses ownership.
|
|
@@ -117,14 +122,38 @@ Default/hard ceilings:
|
|
|
117
122
|
| concurrent runs | 16 | 256 |
|
|
118
123
|
| subscriber queue | 128 | 4,096 |
|
|
119
124
|
| request/run timeout | 120 s | 30 min |
|
|
125
|
+
| health response | 4 KiB | 64 KiB |
|
|
126
|
+
| drain admit cutoff | 30 s | 5 min |
|
|
127
|
+
| replay page / cursor | 100 / 4 KiB | 500 / 16 KiB |
|
|
128
|
+
|
|
129
|
+
## Deployment seams (optional)
|
|
130
|
+
|
|
131
|
+
Compose beside `createPrismHandler` — Prism starts no listener, container orchestrator, or queue worker.
|
|
132
|
+
|
|
133
|
+
| Helper | Role |
|
|
134
|
+
| --- | --- |
|
|
135
|
+
| `createPrismHealthHandler` | `GET /health`, `/livez`, `/readyz`. Minimal JSON; `?detail=1` requires `authorizeDetail`. No secrets/tenant payloads by default. Ready fails while draining. |
|
|
136
|
+
| `createPrismDrainController` | `beginDrain()` rejects admit ops (`agent.run`/`stream`/`resume`, workflow run/stream/enqueue/resume/replay, schedule create/trigger) with `503 ERR_PRISM_SERVER_DRAINING`. Status/cancel/list stay open. |
|
|
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
|
+
| `createPrismEventReplay` / `createPrismReplayHandler` | Ownership-scoped `queryEvents` pages (`redacted: true`). Does not re-run work. Unauthorized replay denies. |
|
|
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). |
|
|
142
|
+
|
|
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.
|
|
144
|
+
|
|
145
|
+
Network-free demo: [`examples/server-deployment-seams.ts`](../examples/server-deployment-seams.ts).
|
|
120
146
|
|
|
121
147
|
## Security and performance notes
|
|
122
148
|
|
|
123
149
|
- `authorize()` is required and runs for every matched operation before capability lookup or body execution. Return `false` on missing/invalid credentials. Do not trust caller ownership fields.
|
|
150
|
+
- Optional `authorization.identity` must be host-verified (`AgentIdentity.verified`); the handler asserts activity and ownership match, then forwards identity into agent runs. Caller-asserted identity without a host verifier is rejected.
|
|
124
151
|
- Use authorization metadata only for non-secret audit context. Never put credentials in metadata, input, route IDs, run IDs, checkpoints, events, or responses.
|
|
125
152
|
- Configure `SecretRedactor` before runs. Redaction matches known secrets; it is not DLP.
|
|
126
153
|
- Agent tools and workflow tool nodes still need their own `PermissionPolicy`, `ToolValidator`, and `ExecutionPolicy`. HTTP authorization does not replace side-effect policy.
|
|
127
|
-
- Host and origin allow-lists are exact string matches. Configure reverse-proxy normalization, TLS,
|
|
154
|
+
- Host and origin allow-lists are exact string matches. Configure reverse-proxy normalization, TLS, IP policy, CSRF/cookie policy, and authentication outside Prism. Optional `rateLimit` is an attributable short-circuit only — not a WAF.
|
|
155
|
+
- Health endpoints reveal process/liveness only by default; detail flags require host authorize and must omit secrets/tenant dumps.
|
|
156
|
+
- Drain and event replay require the same ownership/authorize boundary as other routes; replay never invokes providers or tools.
|
|
128
157
|
- SSE uses bounded upstream subscriber queues. Consumer cancellation aborts owned work by default and releases concurrency; set `disconnectAborts: false` only when the host deliberately owns background completion.
|
|
129
158
|
- Source inputs/resource URLs remain host responsibilities and use existing resource/media SSRF policies. Server package does not fetch URLs.
|
|
130
159
|
- Schedule routes never accept ownership from JSON. Services carry mandatory ownership and explicit workflow/calculator registries; route authorization cannot broaden either. Replay applies workflow ownership/hash/approval checks.
|
|
@@ -134,10 +163,14 @@ A2A routes are not added to `createPrismHandler()`. Install `@arnilo/prism-super
|
|
|
134
163
|
|
|
135
164
|
## Related APIs
|
|
136
165
|
|
|
166
|
+
- [Agent identity](agent-identity.md): optional verified identity on authorize results.
|
|
167
|
+
- [Performance](performance.md): capacity notes for concurrent runs and deployment probes.
|
|
137
168
|
- [Agent/session runtime](agent-session-runtime.md): direct result and event stream semantics.
|
|
138
|
-
- [Workflows](workflows.md): durable checkpoints, status, cancellation,
|
|
169
|
+
- [Workflows](workflows.md): durable checkpoints, status, cancellation, exact-once resume, and `createWorkflowCoordinator` workers.
|
|
139
170
|
- [MCP client and server exposure](mcp-tools.md): selected MCP capabilities and web-standard MCP transport.
|
|
140
171
|
- [Host security guide](host-security.md): remote-boundary checklist.
|
|
141
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.
|
|
142
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.
|
|
143
176
|
- [Release and install](release-and-install.md): optional package installation and profiles.
|
|
@@ -99,7 +99,7 @@ For resume/timeline flows, use `queryRuns`, `queryEvents`, `queryToolCalls`, and
|
|
|
99
99
|
- The package is optional and workspace-local; `@arnilo/prism` core has no SQLite dependency.
|
|
100
100
|
- Hosts choose the database path and own backup, retention enforcement, and filesystem permissions.
|
|
101
101
|
- `SessionAppendOptions` idempotency rows are durable in `prism_session_append_idempotency` and survive reopen.
|
|
102
|
-
- Schema version **
|
|
102
|
+
- Schema version **5** applies `001_init`, `002_usage_scope`, `003_run_feedback`, `004_session_search`, and `005_lifecycle_hold_quota`. Migration 003 adds immutable `prism_run_feedback` rows with run FK/cascade deletion and owner/run/trace cursor indexes. Migration 004 adds session search FTS (FTS5 virtual table `prism_session_search_fts` dual-written on append) plus `prism_sessions(updated_at, id)` cursor index; existing entries are backfilled once. `persistence.feedback` validates exact run ownership, bounds/redacts through optional `feedbackRedactor`, queries bounded pages, and deletes only exact-owned IDs. Search hits never include credentials; ownership filters apply when present. PostgreSQL shares the same model with dialect-local DDL.
|
|
103
103
|
- Pass an existing `better-sqlite3` `Database` via `database` when your host already manages connections.
|
|
104
104
|
|
|
105
105
|
## Security and performance notes
|
package/docs/supervisors.md
CHANGED
|
@@ -61,10 +61,12 @@ Child factories resolve their own providers/credentials and construct context/me
|
|
|
61
61
|
- Tool budget is checked before side effects. Token usage is enforced on terminal aggregate usage and can exceed by at most one provider turn because providers report tokens after generation.
|
|
62
62
|
- Abort and timeout cover hooks, child creation, nested delegation, and the run. Host child code must cooperate with `AbortSignal`.
|
|
63
63
|
- Redaction applies before hook input, run metadata/results, completion hooks, and events. Child credentials are never supplied in delegation context.
|
|
64
|
+
- When forwarding verified identity into children or A2A, use `narrowIdentity` / `assertIdentityPropagation` so scopes and tenant cannot widen across the boundary.
|
|
64
65
|
- Static workflows remain smaller and more reproducible for known graphs.
|
|
65
66
|
|
|
66
67
|
## Related APIs
|
|
67
68
|
|
|
69
|
+
- [Agent identity](agent-identity.md): host-verified identity and narrow delegation.
|
|
68
70
|
- [A2A interoperability](a2a.md): separate remote protocol boundary. `A2ATaskLifecycle` adapts host durable agent/workflow state directly; it does not route A2A execution through local supervisor child planning.
|
|
69
71
|
- [Workflows](workflows.md): preferred deterministic orchestration.
|
|
70
72
|
- [Working and semantic memory](working-and-semantic-memory.md): child scope construction.
|
|
@@ -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.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Work connectors
|
|
2
|
+
|
|
3
|
+
Least-privilege Microsoft 365 and Google Workspace connectors live in `@arnilo/prism-work-tools`.
|
|
4
|
+
|
|
5
|
+
## Principles
|
|
6
|
+
|
|
7
|
+
1. **Host-pinned binary** — Prism never downloads or shells an untrusted CLI path.
|
|
8
|
+
2. **Hard-coded argv templates** — models choose typed tool args; they never supply command strings.
|
|
9
|
+
3. **Draft-then-approve** — mutations create a draft; side effects run only after host approval.
|
|
10
|
+
4. **Idempotent retries** — `IdempotencyStore` keyed by identity + operation key.
|
|
11
|
+
5. **Isolated config** — per-identity `configDir` (CLI `HOME`); no credential argv.
|
|
12
|
+
6. **Shared result shapes** — mail/calendar/file/task list/get tools normalize onto `WorkMailMessage` / `WorkCalendarEvent` / `WorkFileItem` / `WorkTaskItem` without hiding provider-specific ops.
|
|
13
|
+
|
|
14
|
+
## Microsoft 365
|
|
15
|
+
|
|
16
|
+
See [Work tools](work-tools.md). Adapter: `createMicrosoft365CliAdapter` / subpath `@arnilo/prism-work-tools/microsoft365`.
|
|
17
|
+
|
|
18
|
+
Uses [@pnp/cli-microsoft365](https://pnp.github.io/cli-microsoft365/) commands such as `outlook message list|get`, `outlook mail send`, `outlook event list|add`, `file list|add`, `spo file sharinglink add`. To Do / Planner / Teams remain capability-gated.
|
|
19
|
+
|
|
20
|
+
## Google Workspace
|
|
21
|
+
|
|
22
|
+
See [Work tools](work-tools.md). Adapter: `createGoogleWorkspaceCliAdapter` / subpath `@arnilo/prism-work-tools/google-workspace`.
|
|
23
|
+
|
|
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
|
+
|
|
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
|
+
|
|
30
|
+
## Out of scope
|
|
31
|
+
|
|
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.
|