@arnilo/prism 0.11.0 → 0.12.0
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 +32 -0
- package/README.md +28 -27
- package/dist/cli-dev.js +1 -1
- package/dist/cli-init.js +4 -4
- package/dist/cli-provider-add.js +2 -2
- package/dist/field-evidence.d.ts +53 -0
- package/dist/field-evidence.js +143 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2 -1
- package/dist/run-bundle.js +2 -2
- package/docs/acp-agent.md +2 -2
- package/docs/ag-ui.md +1 -1
- package/docs/attention-compiler.md +1 -1
- package/docs/cli-rpc.md +2 -2
- package/docs/coding-tools.md +3 -3
- package/docs/compaction-observational-memory.md +13 -3
- package/docs/computer-use-linux.md +2 -2
- package/docs/core.md +9 -10
- package/docs/dev-inspector.md +1 -1
- package/docs/disaster-recovery.md +1 -1
- package/docs/document-extraction.md +140 -0
- package/docs/evaluations.md +1 -1
- package/docs/execution-timeline.md +30 -0
- package/docs/guardrails.md +53 -0
- package/docs/history/130-cyclic-workflows-primitive-review.md +293 -0
- package/docs/history/132-document-ingestion-primitive-review.md +124 -0
- package/docs/history/README.md +2 -0
- package/docs/history/migrate-to-0.12.0.md +57 -0
- package/docs/history/retire-node-runtime.md +59 -0
- package/docs/hooks.md +1 -1
- package/docs/host-compositions.md +2 -2
- package/docs/host-security.md +1 -1
- package/docs/index.md +30 -25
- package/docs/live-testing.md +1 -1
- package/docs/mcp-tools.md +2 -2
- package/docs/messaging-channels.md +1 -1
- package/docs/migrate-to-0.7.md +1 -1
- package/docs/migrate-to-0.8.md +2 -2
- package/docs/migrate-to-0.9.md +1 -1
- package/docs/migration.md +2 -2
- package/docs/model-registry.md +1 -1
- package/docs/model-routing.md +21 -0
- package/docs/multi-agent-patterns.md +77 -4
- package/docs/obscura.md +1 -1
- package/docs/openapi-tools.md +1 -1
- package/docs/operations.md +2 -2
- package/docs/peer-dependencies.md +18 -17
- package/docs/performance.md +32 -32
- package/docs/prompt-registry.md +1 -1
- package/docs/provider-packages.md +23 -21
- package/docs/providers/decisions.md +134 -0
- package/docs/providers/laya.md +116 -0
- package/docs/providers/typesafe.md +148 -0
- package/docs/rag.md +17 -5
- package/docs/release-and-install.md +119 -113
- package/docs/run-bundle.md +4 -0
- package/docs/runs-and-usage.md +1 -1
- package/docs/signal-channel.md +1 -1
- package/docs/sqlite-persistence.md +5 -5
- package/docs/synapta-integration-review.md +238 -0
- package/docs/telegram-channel.md +1 -1
- package/docs/testing.md +33 -14
- package/docs/wiki.md +12 -11
- package/docs/work-sandbox.md +2 -0
- package/docs/work-tools.md +3 -3
- package/docs/workflows.md +213 -11
- package/package.json +22 -21
- package/templates/business-worker/README.md.tmpl +3 -3
- package/templates/business-worker/package.json.tmpl +4 -5
- package/templates/business-worker/src/tests/agent.test.ts.tmpl +1 -1
- package/templates/business-worker/tsconfig.json.tmpl +2 -1
- package/templates/deep-research/README.md.tmpl +4 -4
- package/templates/deep-research/package.json.tmpl +4 -5
- package/templates/deep-research/src/tests/research.test.ts.tmpl +1 -1
- package/templates/deep-research/tsconfig.json.tmpl +2 -1
- package/templates/init/README.md.tmpl +3 -3
- package/templates/init/optional/evals-example.ts.tmpl +1 -1
- package/templates/init/optional/workflows-example.ts.tmpl +1 -1
- package/templates/init/package.json.tmpl +4 -5
- package/templates/init/src/tests/agent.test.ts.tmpl +1 -1
- package/templates/init/tsconfig.json.tmpl +2 -1
- package/templates/personal-assistant/README.md.tmpl +3 -3
- package/templates/personal-assistant/package.json.tmpl +4 -5
- package/templates/personal-assistant/src/tests/agent.test.ts.tmpl +1 -1
- package/templates/personal-assistant/tsconfig.json.tmpl +2 -1
- package/templates/provider/README.md.tmpl +2 -2
- package/templates/provider/package.json.tmpl +3 -4
- package/templates/provider/src/tests/provider.test.ts.tmpl +1 -1
- package/templates/provider/tsconfig.json.tmpl +1 -1
package/docs/run-bundle.md
CHANGED
|
@@ -63,6 +63,10 @@ exactly as it would during the run. `storage.*.kind` comes from the store's decl
|
|
|
63
63
|
and is reduced to a plain token (`[a-z0-9_.-]`, ≤64 chars); anything URL-shaped is reported as `custom`, so a
|
|
64
64
|
connection string can never reach a pinned artifact.
|
|
65
65
|
|
|
66
|
+
`requestPolicies` lists agent-level policies followed by run-level policies, in execution order.
|
|
67
|
+
Run policies extend the agent chain; even an empty run-level list does not remove agent policies.
|
|
68
|
+
Policy names, not policy implementations or credentials, enter the snapshot.
|
|
69
|
+
|
|
66
70
|
## Example
|
|
67
71
|
|
|
68
72
|
```ts
|
package/docs/runs-and-usage.md
CHANGED
|
@@ -80,7 +80,7 @@ const estimate = estimateMessageTokens(messages, "claude-sonnet-4.5"); // model
|
|
|
80
80
|
|
|
81
81
|
`MODEL_FAMILY_TOKENS` holds the chars/token ratio, per-message overhead, and confidence label per family (`anthropic`, `openai`, `google`, `deepseek`, `openrouter-generic`, `mistral`, `unknown`). `resolveModelFamily(modelId)` maps a model id or provider id to a table key; unmatched input resolves to `unknown`, whose row is the most conservative (highest estimated token count) and carries `confidence: "low"` / `lowConfidence: true`. Estimates are heuristics, not tokenizers: prose, fenced code, and CJK content are weighted separately, and every calibrated family is `confidence: "medium"` because Prism ships no real tokenizer. The estimator is pure — no network, no I/O, and no content retention. `MODEL_FAMILY_TOKENS` is frozen at runtime (every row and the table), so ratios cannot be overridden in place — recalibration stays a source change plus the live leg below, never a runtime override.
|
|
82
82
|
|
|
83
|
-
Row provenance and recalibration: reference counts per family are frozen in `src/__tests__/fixtures/usage-calibration.json` — `openai` measured against `o200k_base` (dev-time oracle; no tokenizer ships), `anthropic`/`google`/`mistral` as their published chars/token guidance, and `deepseek`/`openrouter-generic` as row-basis values (no public count endpoint). `src/__tests__/usage-calibration.test.ts` fails when a shipped row drifts outside the recorded bands (prose ±12%, CJK ±20%, per-message overhead ±1 token). To re-measure, run `PRISM_LIVE_PROVIDER_TESTS=1` with `ANTHROPIC_API_KEY` and/or `GEMINI_API_KEY`/`GOOGLE_API_KEY` and `
|
|
83
|
+
Row provenance and recalibration: reference counts per family are frozen in `src/__tests__/fixtures/usage-calibration.json` — `openai` measured against `o200k_base` (dev-time oracle; no tokenizer ships), `anthropic`/`google`/`mistral` as their published chars/token guidance, and `deepseek`/`openrouter-generic` as row-basis values (no public count endpoint). `src/__tests__/usage-calibration.test.ts` fails when a shipped row drifts outside the recorded bands (prose ±12%, CJK ±20%, per-message overhead ±1 token). To re-measure, run `PRISM_LIVE_PROVIDER_TESTS=1` with `ANTHROPIC_API_KEY` and/or `GEMINI_API_KEY`/`GOOGLE_API_KEY` and `bun test scripts/usage-calibration-live.test.mjs` (matrix suite `calibration/vendor-count-tokens`): it posts the fixed corpus to `POST /v1/messages/count_tokens` and `POST /v1beta/models/{model}:countTokens`, asserts each shipped row against the measured count, and refreshes `docs/_evidence/phase103-family-token-calibration.md`. A measurement outside its band means updating the row in `src/usage-estimation.ts` and the fixture counts in one change.
|
|
84
84
|
|
|
85
85
|
### Automatic fallback (`AgentConfig.usageEstimation`)
|
|
86
86
|
|
package/docs/signal-channel.md
CHANGED
|
@@ -11,7 +11,7 @@ Importing or constructing the adapter does nothing: it never downloads, spawns,
|
|
|
11
11
|
Use only after an operator records acceptable-use and GPL distribution decisions for an already-operated Signal account. Not an official bot API; not for groups, topics, attachments, identity linking, bulk messaging (including `MessagingRuntime.notify`, which is unicast to one existing DM binding only), automated account creation, or streaming previews (Signal has no Bot API draft equivalent, so this adapter ignores `MessagingRuntimeOptions.onAssistantDelta`).
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
|
|
14
|
+
bun add @arnilo/prism @arnilo/prism-channels
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
## Inputs / request
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# SQLite persistence
|
|
2
2
|
|
|
3
|
-
> **
|
|
3
|
+
> **Runtime:** Bun's built-in `bun:sqlite`. No optional peer. See [Optional peer dependencies](peer-dependencies.md) for the drivers that still are peers (`pg`).
|
|
4
4
|
|
|
5
5
|
## What it does
|
|
6
6
|
|
|
@@ -16,11 +16,11 @@ Factory:
|
|
|
16
16
|
- `SqlitePersistenceOptions`
|
|
17
17
|
- `SqlitePersistence.close()`
|
|
18
18
|
|
|
19
|
-
The adapter uses `
|
|
19
|
+
The adapter uses the Bun runtime's `bun:sqlite`, enables WAL and foreign keys, applies versioned migrations from the shared Plan 056 schema model, and passes the full session-store and run-ledger conformance suites including process reopen.
|
|
20
20
|
|
|
21
21
|
## When to use it
|
|
22
22
|
|
|
23
|
-
Use this package when you want a small, file-backed persistence layer on
|
|
23
|
+
Use this package when you want a small, file-backed persistence layer on the Bun runtime without operating a database server:
|
|
24
24
|
|
|
25
25
|
- local CLI tools and desktop hosts
|
|
26
26
|
- single-writer or low-concurrency deployments
|
|
@@ -41,7 +41,7 @@ import { createSqlitePersistence } from "@arnilo/prism-core/sessions/sqlite";
|
|
|
41
41
|
| `busyTimeoutMs` | `number` | SQLite `busy_timeout` in milliseconds. Defaults to `5000`. |
|
|
42
42
|
| `feedbackRedactor` | `SecretRedactor` | Optional redaction for feedback comment/tags/metadata before insert. |
|
|
43
43
|
| `fileMode` | `number` | Unix file mode for newly created database files. Defaults to `0o600`. |
|
|
44
|
-
| `database` | `Database` | Advanced: supply an existing `
|
|
44
|
+
| `database` | `Database` | Advanced: supply an existing `bun:sqlite` handle (caller owns lifecycle). |
|
|
45
45
|
|
|
46
46
|
## Outputs / response / events
|
|
47
47
|
|
|
@@ -102,7 +102,7 @@ For resume/timeline flows, use `queryRuns`, `queryEvents`, `queryToolCalls`, and
|
|
|
102
102
|
- Hosts choose the database path and own backup, retention enforcement, and filesystem permissions.
|
|
103
103
|
- `SessionAppendOptions` idempotency rows are durable in `prism_session_append_idempotency` and survive reopen.
|
|
104
104
|
- Schema version **6** applies `001_init`, `002_usage_scope`, `003_run_feedback`, `004_session_search`, `005_lifecycle_hold_quota`, and `006_agent_event_source`. Migration 006 backfills `prism_agent_event_streams` and uses it to allocate unique per-run event sequences inside the SQLite append transaction. It is sequence-compatible with PostgreSQL but remains local/file-backed; it does not expose distributed subscriptions. 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.
|
|
105
|
-
- Pass an existing `
|
|
105
|
+
- Pass an existing `bun:sqlite` `Database` via `database` when your host already manages connections.
|
|
106
106
|
|
|
107
107
|
## Durable events
|
|
108
108
|
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
# Synapta → Prism integration review
|
|
2
|
+
|
|
3
|
+
## Scope and conclusion
|
|
4
|
+
|
|
5
|
+
Reviewed local working trees: Synapta `6078398` plus existing uncommitted changes; Prism `949323af` (`0.11.1`) before this review's fixes. Synapta's execution-worker still pins the Prism family to **0.9.0**. These are source observations, not claims about deployed or published artifacts. Synapta was not edited. Existing unrelated Prism files were left untouched.
|
|
6
|
+
|
|
7
|
+
**Recommendation: improve Prism's host integration contracts, not its orchestration breadth.** Synapta needs a bounded, inspectable in-turn engine under its own authority. Most foundations already exist; several needs are adoption/composition gaps rather than missing SDK features.
|
|
8
|
+
|
|
9
|
+
This is a targeted review and set of recommendations, not an approved implementation roadmap or exhaustive security audit. No live provider, Synapta cluster, database, or browser journey was exercised.
|
|
10
|
+
|
|
11
|
+
Paths prefixed `synapta-core/` below are relative to `~/Projects`; other paths are relative to Prism.
|
|
12
|
+
|
|
13
|
+
## 1. Synapta's agentic system
|
|
14
|
+
|
|
15
|
+
| Surface | Mechanism | Authority / durability |
|
|
16
|
+
| --- | --- | --- |
|
|
17
|
+
| Ask | Fresh Prism session, browser-supplied user/assistant text history, host-owned Decision OS reads, evidence/output checks; model-less desk answers available | Effect-free; cannot propose or commit |
|
|
18
|
+
| Do | Temporal investigation Activity runs a host step loop; one Prism run per business step; host tools explore, clarify, paint a StepPlan, and propose | Kernel freezes typed commands into an immutable digest; human decision and current-state authorization precede commit |
|
|
19
|
+
| Run | Compile committed commands into recipe IR, then replay with Temporal | Not prompt replay or generated Temporal workflow code |
|
|
20
|
+
| Operating | Compiled event/schedule/queue/metric watches; deterministic matcher starts bounded work | Kernel fire identity, same-transaction outbox, JetStream delivery, Temporal waits; no model in matcher |
|
|
21
|
+
| Authoring | Separate Prism/AG-UI loop with PostgreSQL sessions, progressive disclosure, compaction and evals | Produces workflow IR, not a business commit; not Agent home's default path |
|
|
22
|
+
|
|
23
|
+
Decision OS supplies typed objects/links, governed metrics, authorized extracts and bounded computation, inert knowledge, and proposal verbs. A host classifier narrows tools by plane; it is distinct from provider/model selection. Guidance and playbooks grant no authority. Reads and effects remain constrained by **user ∩ agent ∩ task**, with current commit-time rechecks.
|
|
24
|
+
|
|
25
|
+
Do currently narrows turns, tool calls, and wall time across step runs, but keeps token ceilings per run. Its transcript store is process-local, action-scoped and LRU-bounded; Temporal/kernel durability does not make that transcript durable. Observational-memory attachment runs at step boundaries without observer workers or a recall tool.
|
|
26
|
+
|
|
27
|
+
**Evidence:** `synapta-core/docs/architecture/synapta-agent-mechanism.md:19–58, 113–150, 232–299, 366–421`; `synapta-core/services/execution-worker/src/do-host.ts:435–455, 1337–1669`; `synapta-core/docs/architecture/target-execution-architecture.md:80–176`.
|
|
28
|
+
|
|
29
|
+
### Roadmap implications
|
|
30
|
+
|
|
31
|
+
Synapta's intended product is an accountable operating layer over existing systems, with a native business suite as an optional consolidation path:
|
|
32
|
+
|
|
33
|
+
- **P02:** observability and Harness Studio before wider dependence on agents: effective run bundles, traces, evaluation, reviewed configuration changes and rollback.
|
|
34
|
+
- **P03–P06:** semantic onboarding → secure Data/Knowledge → accounting/CRM/email adapters → a verified overdue-receivables journey. Sending a reminder is explicitly not collecting payment.
|
|
35
|
+
- **P07–P09:** reports/documents, complete Integration Exchange, then bounded standing authority. Aggregate limits, revocation, uncertainty and outcome verification become mandatory.
|
|
36
|
+
- **P10–P18:** native service-company operations and finance, lakehouse/Gold semantics, broader functions and regulated domains, with profile-specific production evidence.
|
|
37
|
+
|
|
38
|
+
Near-term plans also name proposal-payload provenance (156), ledger-only Do telemetry and transcript durability decisions (157), behavioral evals (159), knowledge revocation (161), and a shadow-tested System One decision layer (163). These are not all implemented simply because underlying Prism primitives exist.
|
|
39
|
+
|
|
40
|
+
**Evidence:** `synapta-core/roadmap.md:34–88, 146–168, 301–466, 468–637`; respective plan introductions.
|
|
41
|
+
|
|
42
|
+
## 2. Confirmed Prism defects fixed
|
|
43
|
+
|
|
44
|
+
All changes are local, dependency-free, and include regression checks.
|
|
45
|
+
|
|
46
|
+
### F1 — Run-bundle audit omitted policies that actually executed
|
|
47
|
+
|
|
48
|
+
**Impact:** P02 could record an incomplete effective configuration. With agent policies plus run policies, execution applied both, while `snapshotRunBundle()` reported only the run list. An empty run list also hid agent policies.
|
|
49
|
+
|
|
50
|
+
**Fix:** snapshot concatenates agent then run policies, matching execution order. This repairs reporting, not authorization enforcement; runtime enforcement was already correct.
|
|
51
|
+
|
|
52
|
+
- Implementation: `src/run-bundle.ts:99,142`.
|
|
53
|
+
- Runtime contract: `src/agent-session/session.ts:742–763`.
|
|
54
|
+
- Regression: `src/__tests__/run-bundle.test.ts`, `records_agent_and_run_request_policies_in_actual_execution_order` executes a real mock-backed run and compares its applied policies with the snapshot.
|
|
55
|
+
- Documentation: `docs/run-bundle.md`.
|
|
56
|
+
|
|
57
|
+
### F2 — System One resolved credentials twice, under different provider names
|
|
58
|
+
|
|
59
|
+
**Impact:** provider-scoped resolvers could succeed for `laya`/`typesafe`, then fail to resolve under display labels `Laya`/`TypeSafe Jev`. Rotating credentials could also differ between transport and outer error redaction.
|
|
60
|
+
|
|
61
|
+
**Fix:** resolve once using the configured provider id; pass that resolved value to the shared transport. Authentication and outer error redaction now use the same credential.
|
|
62
|
+
|
|
63
|
+
- Implementation: `packages/prism-providers/src/shared/systemone-provider.ts:40–51`.
|
|
64
|
+
- Regression: `packages/prism-providers/src/laya/__tests__/laya.test.ts`, `laya_resolves_credentials_once_with_provider_id_and_redacts_transport_failures`.
|
|
65
|
+
- Both Laya and TypeSafe use this shared implementation.
|
|
66
|
+
|
|
67
|
+
### F3 — Malformed System One responses became successful decisions
|
|
68
|
+
|
|
69
|
+
**Impact:** the old transport checked only `model` and an `answers` object. Missing or string-valued noul probabilities could be coerced to booleans; non-finite scores could render invalid semantic values; malformed confidence/probability metadata and negative/string token counts passed the success gate. This is especially unsuitable for Plan 163's confidence gates.
|
|
70
|
+
|
|
71
|
+
**Fix:** validate answer discriminants and values, finite scores, probability ranges, optional confidence/distributions/legends, and reported token counts before emitting output. Renderer also validates answers and requires own answer properties. Finite rubric scores retain the documented rounding/clamping behavior. Invalid responses fail; they do not become synthetic neutral decisions.
|
|
72
|
+
|
|
73
|
+
- Implementation: `packages/prism-providers/src/shared/systemone.ts:158–195`; `systemone-schema.ts:102–111`.
|
|
74
|
+
- Regressions: shared transport/schema suites plus Laya's malformed-success check.
|
|
75
|
+
- Documentation: `docs/providers/typesafe.md`.
|
|
76
|
+
|
|
77
|
+
This is shape/range validation, not a claim that returned probabilities are empirically calibrated or normalized distributions.
|
|
78
|
+
|
|
79
|
+
### F4 — A valid choice label disappeared during request construction
|
|
80
|
+
|
|
81
|
+
**Impact:** assigning the string enum label `__proto__` into a plain criteria object did not create an own property. The advertised choice set could differ from the schema.
|
|
82
|
+
|
|
83
|
+
**Fix:** construct criteria with `Object.fromEntries`, preserving labels as own data properties. Existing forbidden schema-key validation remains intact; no prototype-pollution bypass was found or enabled.
|
|
84
|
+
|
|
85
|
+
- Implementation: `packages/prism-providers/src/shared/systemone-schema.ts:195–202`.
|
|
86
|
+
- Regression: `preserves_prototype_named_choice_labels_as_own_wire_options`.
|
|
87
|
+
|
|
88
|
+
## 3. Recommended additions and enhancements
|
|
89
|
+
|
|
90
|
+
Priorities below express this review's recommendation, not authorization to change Synapta's approved sequence.
|
|
91
|
+
|
|
92
|
+
### Highest priority — coverage-safe memory compaction
|
|
93
|
+
|
|
94
|
+
**Observed integration hazard:** Synapta attaches observational-memory compaction without observation workers (`do-host.ts:1480–1507`). Prism's strategy renders existing observations; it does not summarize raw messages. The attach loop ignores a skipped flush and may still compact. With no observations, old messages can leave the next model context behind a summary containing “none”. The original entries remain stored: this is loss of usable context, not physical deletion.
|
|
95
|
+
|
|
96
|
+
A local two-message probe against Prism reproduced this: after render-only OM compaction retaining one recent entry, an early evidence sentinel was absent from `rebuildSessionContext(...).messages` and `.summaries`. Synapta's current compaction test asserts that a compaction entry exists and a scripted proposal freezes, not that early evidence survives (`do-host.test.ts:842–886`). That does not establish semantic memory retention.
|
|
97
|
+
|
|
98
|
+
**Prism enhancement:** coverage-aware admission for automatic OM compaction: do not discard an unobserved prefix after a skipped/failed observer pass. Preserve uncovered messages or explicitly refuse/defer compaction. Keep a successful empty observation pass distinct from no observation pass. Make recall guidance conditional on a host-provided recall capability; current renderer advertises `recall` even when Synapta deliberately exposes none.
|
|
99
|
+
|
|
100
|
+
**Why now:** multi-step evidence reuse underpins P06. A smaller prompt is not proof of preserved evidence. This needs an explicit compatibility decision and semantic retention tests, not a silent change to every caller's compaction policy; it was not patched in this review.
|
|
101
|
+
|
|
102
|
+
**Reuse:** existing coverage markers, `unscannedEntries`, step-boundary compaction and work scopes. No new memory database, automatic worker, or recall tool.
|
|
103
|
+
|
|
104
|
+
**Acceptance evidence:** early authorized facts survive the next run or compaction explicitly refuses; missing worker, worker failure, and successful empty observation passes have distinct outcomes; revoked facts stay excluded.
|
|
105
|
+
|
|
106
|
+
**Prism sources:** `packages/memory/src/compaction/observational-memory/strategy.ts:27–91`, `compose.ts:207–226`, `runtime.ts:159–195`, `render.ts:20–45`; `src/session-stores.ts:149–179`.
|
|
107
|
+
|
|
108
|
+
### Highest priority — confidence-preserving host decision calls
|
|
109
|
+
|
|
110
|
+
**Already present:** TypeSafe/Jev and Laya providers, shared System One wire client, retries, bounded response parsing and schema-to-question compilation. Do not implement another HTTP client.
|
|
111
|
+
|
|
112
|
+
**Real gap:** public adapters return schema-shaped text and deliberately discard confidence/distributions and actual responding model. Shared raw client is not a public provider subpath export. Consequently the existing adapters do not fulfill Synapta's Plan 163 shadow classification, confidence gating and calibration needs, despite sharing the wire.
|
|
113
|
+
|
|
114
|
+
**Smallest addition:** a host-only typed decision call over the existing client, preserving question ids, raw probabilities, actual model version, usage and timing. Keep the existing `AIProvider` adapter for callers wanting only schema values. Add explicit state/question bounds and cancellation/deadline composition. Calibration version and threshold decisions belong in host configuration; forward engine-specific calibration controls only when the supported wire contract is verified.
|
|
115
|
+
|
|
116
|
+
Do **not** add automatic routing/sufficiency/retrieval hooks to every agent yet. Synapta can invoke one decision call from its own classifier and retain its deterministic fallback. Do not turn timeouts into plausible `0.5` answers: error/unavailable must remain distinguishable from measured uncertainty. Decisions never grant effect authority.
|
|
117
|
+
|
|
118
|
+
**Why:** immediately removes the need for the interim Synapta client while preserving its core reason to exist. Benchmark savings and provider pricing claims in the feature request were not independently validated here; neither justifies a default rollout or a new billing unit without evidence.
|
|
119
|
+
|
|
120
|
+
**Evidence:** `synapta-core/plans/163-SystemOneDecisionLayer.md:169–295`; `synapta-core/plans/evidence/163-prism-feature-request.md`; `docs/providers/typesafe.md` “Outputs”; `packages/prism-providers/src/shared/systemone-provider.ts:42–63`.
|
|
121
|
+
|
|
122
|
+
### High priority — fixed-model aggregate budget composition
|
|
123
|
+
|
|
124
|
+
**Already present:** `createGovernedProvider`, atomic task reservations, durable router state, unknown-usage settlement, and task attribution. No new scheduler or budget database is needed.
|
|
125
|
+
|
|
126
|
+
**Observed gap:** Synapta's step loop subtracts turns/tools/time but intentionally resets token ceilings per run (`do-host.ts:1533–1605`). A 500,000-input-token run ceiling is therefore not a 500,000-token action ceiling. Separate attempts, authoring, compaction and embeddings are additional accounting paths.
|
|
127
|
+
|
|
128
|
+
**Prism enhancement:** a maintained fixed-model composition demonstrating shared task accounting across multiple `session.run()` calls and auxiliary work, with fallback disabled. Expose remaining aggregate liability separately from context-window pressure; do not change attention thresholds just to represent another run's spend. Add a smaller budget-only facade only if this composition proves the existing API is genuinely unsuitable.
|
|
129
|
+
|
|
130
|
+
**Why:** P09 requires cumulative limits under concurrency; P02/P06 need truthful cost per outcome. A policy-preserving model pin is compatible with accounting, not equivalent to automatic model routing.
|
|
131
|
+
|
|
132
|
+
**Host gate:** Synapta explicitly withheld governed-router adoption in `plans/executed/122-Prism070ModelRouterBudgets.md:1–17`. Obtain that decision before wiring or migrations. This review does not lift it.
|
|
133
|
+
|
|
134
|
+
**Acceptance evidence:** concurrent steps/attempts cannot reset a task ceiling; missing usage remains unknown liability; auxiliary calls share the task; changing models or restarting workers cannot reset spend.
|
|
135
|
+
|
|
136
|
+
**Prism sources:** `docs/model-routing.md`, `packages/prism-core/src/governance/model-router/invocation.ts`, `router.ts:429,543,635`.
|
|
137
|
+
|
|
138
|
+
### High priority — structured telemetry/evals for host-owned step loops
|
|
139
|
+
|
|
140
|
+
**Already present:** `ExecutionTimeline`, incremental folders, session summaries, turn budgets/stop reasons, exhaustion details, `snapshotRunBundle`, trajectory and environment scorers, release-eval manifests.
|
|
141
|
+
|
|
142
|
+
**Prism enhancement:** a reference composition that correlates action/attempt/step → Prism session/run and persists metadata-only timelines into a host ledger. Use existing identities/events first; add correlation fields only where a demonstrated projection loses them. Show a host's external commit/verification evidence alongside Prism runs without pretending those effects occurred inside Prism.
|
|
143
|
+
|
|
144
|
+
**Why:** Synapta currently compresses Do telemetry to a 480-character trace and competes with business steps for an eight-step snapshot. Plan 157 already proposes a ledger-only channel. Parsing trace prose would duplicate information Prism already exposes structurally. P02 and Plan 159 should share the same projection and hard-invariant scorers.
|
|
145
|
+
|
|
146
|
+
**Acceptance evidence:** a full eight-step plan loses no trace; live/replayed projections agree; required evidence cannot silently truncate into a passing eval; approval-before-effect and independently verified outcome fail separately from answer quality. No chain-of-thought capture by default.
|
|
147
|
+
|
|
148
|
+
**Evidence:** `synapta-core/services/execution-worker/src/do-host.ts:112–311, 914–950, 1508–1530`; `synapta-core/plans/157-DoTransparencyClosure.md:1–24`; `docs/execution-timeline.md`; `docs/evaluations.md`; F1 above.
|
|
149
|
+
|
|
150
|
+
### High priority — typed proposal provenance, not only answer grounding
|
|
151
|
+
|
|
152
|
+
**Already present:** tool-input guardrails, artifact citation/review types, claim-grounding output checks and invariant evals.
|
|
153
|
+
|
|
154
|
+
**Gap named by Synapta:** answer figures are evidence-checked, but schema-valid invented figures or identifiers can reach proposal review. Plan 156 names this asymmetry explicitly.
|
|
155
|
+
|
|
156
|
+
**Prism enhancement:** a small optional field-evidence verifier/example built on tool-input guardrails: host-selected field paths, typed source references, exact normalized values, source revisions and freshness. Prefer reusable validation over a domain proposal engine. The host must supply authoritative evidence and decide which fields require it.
|
|
157
|
+
|
|
158
|
+
**Why:** schema validity and an approval digest do not establish factual provenance. Conversely, matching a number in any tool result is not sufficient: currency, units, object identity and revision matter.
|
|
159
|
+
|
|
160
|
+
**Acceptance evidence:** invented amount/id rejected; correct value attached to wrong object/revision rejected; properly typed authorized evidence accepted. Rust/Synapta still owns money, grant checks, digest freeze and commit-time validation.
|
|
161
|
+
|
|
162
|
+
**Evidence:** `synapta-core/plans/156-ProposePayloadProvenance.md:1–20`; `synapta-core/services/execution-worker/src/do-host.ts:961–1061`; `docs/guardrails.md`; `docs/work-artifacts-and-review.md`.
|
|
163
|
+
|
|
164
|
+
### High priority — cross-layer revocation composition
|
|
165
|
+
|
|
166
|
+
**Already present:** ACL-filtered RAG query legs, access rechecks, lineage tombstones, deletion/repoint handlers and OM invalidation primitives. Do not propose generic “add secure RAG”.
|
|
167
|
+
|
|
168
|
+
**Prism enhancement:** an executable host composition proving source revoke/delete → retrieval exclusion → derived wiki/OM exclusion → subsequent context assembly. Clearly separate global deletion from a principal losing access. Any new seam should carry host-resolved invalidated ids/access decisions into existing projection paths, not invent another authorization authority.
|
|
169
|
+
|
|
170
|
+
**Why:** P04/P07 cover reused conversations, wiki pages, extracts and generated artifacts—not only the next vector query. The reviewed automatic OM strategy/attach paths do not themselves consult Synapta's current source grants. Source access rechecks during retrieval cannot authorize an old transcript or report download.
|
|
171
|
+
|
|
172
|
+
**Host work remains:** current kernel/source checks, source-to-entry/artifact lineage, multi-source page permission intersections, and authorization at render/download/delivery. Synapta Plan 161 owns these application obligations.
|
|
173
|
+
|
|
174
|
+
**Acceptance evidence:** revoke during rerank, between step runs, and after report generation blocks subsequent exposure; legal-hold retention does not restore retrieval; authorized prior external disclosure is not claimed erased.
|
|
175
|
+
|
|
176
|
+
**Evidence:** `synapta-core/plans/161-KnowledgeRetrievalAndRevocationClosure.md:249–480`; `docs/rag.md:92–175,224–225`; `packages/memory/src/compaction/observational-memory/strategy.ts:42`.
|
|
177
|
+
|
|
178
|
+
### Later — connector/outcome and packed compatibility proofs
|
|
179
|
+
|
|
180
|
+
For P05–P08, extend existing connector/artifact examples with provider rejection, timeout-after-acceptance, receipt reconciliation, stale source revisions, and export revocation. Prism already models unknown effects; do not introduce a second approval ledger around Synapta's authoritative command ledger. Dispatch success and verified business outcome must remain separate.
|
|
181
|
+
|
|
182
|
+
Maintain a small packed-install consumer contract suite for the Synapta-shaped composition: host tools only, policy-chain snapshot, per-step stop, memory retention, usage/attention trace, revocation, and optional typed decisions. Verify the exact family release under Synapta's selected runtime before upgrading. Its 0.9.0 pin will not receive these local 0.11.1-tree fixes automatically.
|
|
183
|
+
|
|
184
|
+
**Evidence:** `synapta-core/roadmap.md:363–444`; `docs/work-tools.md:116–135`; `synapta-core/services/execution-worker/package.json`.
|
|
185
|
+
|
|
186
|
+
## 4. What not to move into Prism
|
|
187
|
+
|
|
188
|
+
- Temporal ownership, mandate matching, business outcome state machines or the StepPlan authority model.
|
|
189
|
+
- OpenFGA task-grant compilation, product allocation/licensing, exact-money invariants or commit authorization.
|
|
190
|
+
- Native ERP entities, metrics, lakehouse SQL, domain playbooks or a Synapta-specific supervisor.
|
|
191
|
+
- Automatic swarms, model-visible memory/inspection tools, or MCP as an internal bus.
|
|
192
|
+
- Implicit source/model fallback that turns unavailable evidence or uncertain effects into success.
|
|
193
|
+
|
|
194
|
+
These would duplicate authorities Synapta deliberately owns. Generic Prism primitives remain useful without importing every Prism subsystem.
|
|
195
|
+
|
|
196
|
+
## 5. Verification and remaining limits
|
|
197
|
+
|
|
198
|
+
Executed:
|
|
199
|
+
|
|
200
|
+
```sh
|
|
201
|
+
npm run build:core
|
|
202
|
+
npm run build --workspace @arnilo/prism-providers
|
|
203
|
+
npm test --workspace @arnilo/prism-providers
|
|
204
|
+
node --test --test-concurrency=1 \
|
|
205
|
+
dist/__tests__/run-bundle.test.js \
|
|
206
|
+
dist/__tests__/guardrail-packs.test.js \
|
|
207
|
+
dist/__tests__/guardrail-pack-durability.test.js \
|
|
208
|
+
dist/__tests__/provider-request-policy.test.js
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
- Provider suite: **628 passed, 95 skipped, 0 failed**. Skipped live/environment-dependent tests are not compatibility evidence.
|
|
212
|
+
- Runtime/policy suites: **36 passed, 0 failed** with serial file execution.
|
|
213
|
+
- Initial parallel runtime check failed the existing 5 ms snapshot benchmark at **7.61 ms**; serial rerun passed. No threshold or assertion was weakened.
|
|
214
|
+
- Regression tests first demonstrated the policy-chain omission, double credential resolution, and malformed-answer acceptance; targeted and full provider checks pass after fixes.
|
|
215
|
+
- Biome checks and `git diff --check` pass for changed code.
|
|
216
|
+
- The render-only OM probe establishes a local composition hazard; no Synapta live incident or production data loss is claimed.
|
|
217
|
+
|
|
218
|
+
Not run: full Prism release gate, packed-install matrix, live System One servers, Synapta e2e, or cross-replica database fault tests. No package versions, lockfiles, dependencies, approved roadmap statuses, or Synapta files changed.
|
|
219
|
+
|
|
220
|
+
## 6. Remediation status
|
|
221
|
+
|
|
222
|
+
These recommendations were executed as plan `plans/122-Synapta-Integration-Review-Remediations.md` (Tasks 1–9, 2026-09-24/25, local `0.11.1` tree); the `CHANGELOG.md` entries drafted there ship in the first release containing that plan. The defects in §2 are fixed in-tree with regression tests, and §4's authority list is unchanged — no Temporal, OpenFGA, commit-authorization, ERP, or implicit-fallback logic moved into Prism. To re-run the compatibility contract against a host-selected family release before upgrading, use the replay recipe in [Test layout and isolation](testing.md#replaying-the-packed-contract-against-a-host-selected-runtime) and append the observed delta block to this section.
|
|
223
|
+
|
|
224
|
+
| Recommendation | Status | Delivered |
|
|
225
|
+
| --- | --- | --- |
|
|
226
|
+
| §2 F1 run-bundle policy order | fixed in this tree | Snapshot concatenates agent then run policies in execution order; the packed-install `policy-chain-snapshot` check pins it. |
|
|
227
|
+
| §2 F2 single credential resolution | fixed in this tree | One resolve under the configured provider id, reused by transport and outer redaction. |
|
|
228
|
+
| §2 F3 malformed-response rejection | fixed in this tree | Answer discriminants, finite scores, probability ranges, optional confidence/distributions/legends, and token counts validated before success. |
|
|
229
|
+
| §2 F4 `__proto__` choice labels | fixed in this tree | Criteria built with `Object.fromEntries`; the regression is pinned. |
|
|
230
|
+
| §3 coverage-safe memory compaction | implemented (Task 2) | Eligible messages after the coverage cursor are retained past the recent window, the fold boundary stays behind an unscanned prefix, and automatic compaction defers when the observer skipped without a coverage cursor; `advertiseRecall` gates the recall hint. |
|
|
231
|
+
| §3 confidence-preserving decision calls | implemented (Task 3) | `@arnilo/prism-providers/decisions` typed call preserves raw probabilities/confidence, responding model, usage, and timing, with explicit bounds, deadline/abort composition, and typed errors; calibration stays host config and timeouts never become plausible answers. |
|
|
232
|
+
| §3 fixed-model aggregate budget composition | demonstrated (Task 4) | `examples/model-router-aggregate-budgets.ts` draws three sequential runs plus an auxiliary call on one task ceiling, with renewal fencing, unknown-usage liability, and aggregate-versus-context-window reporting; existing router APIs only. |
|
|
233
|
+
| §3 step-loop telemetry/evals | demonstrated (Task 5) | `examples/host-step-loop-timeline.ts` correlates host action/attempt/step ids with Prism session/run ids in a metadata-only NDJSON ledger and keeps external host commit evidence outside Prism effects. |
|
|
234
|
+
| §3 typed proposal provenance | implemented (Task 6) | `createFieldEvidenceGuardrail` (`tool_input`, fail-closed) verifies host-selected field paths against host-supplied evidence values, sources, and revisions. |
|
|
235
|
+
| §3 cross-layer revocation composition | demonstrated (Task 7) | `examples/revocation-propagation.ts` chains grant loss, lineage-closed deletion, observational-memory withholding on read and write paths, a mid-rerank revoke, and a redacted fail-closed denial. |
|
|
236
|
+
| §5 packed compatibility proofs | implemented (Task 8) | `examples/host-composition-compat.ts` runs from packed tarballs against the Synapta-shaped composition; the `0.9.0` pin reports named deltas instead of failing, offline by default. |
|
|
237
|
+
|
|
238
|
+
**Verification limits, updated.** The full release gate, the PostgreSQL durable conformance run (583 tests, 0 failures), and the packed-install matrix now run locally; the pinned-old-family leg is env-gated and skipped without an explicit opt-in. Still not exercised: live System One servers, Synapta end-to-end, and cross-replica database fault drills. Skipped live legs remain non-evidence, as §5 states.
|
package/docs/telegram-channel.md
CHANGED
|
@@ -11,7 +11,7 @@ Use for official Telegram Bot API text and bounded media. Private DMs are the de
|
|
|
11
11
|
Install peer and channel package:
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
|
|
14
|
+
bun add @arnilo/prism @arnilo/prism-channels
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
## Inputs / request
|
package/docs/testing.md
CHANGED
|
@@ -11,32 +11,51 @@ Documents how the hermetic suite runs, which stage a new suite belongs to, and t
|
|
|
11
11
|
|
|
12
12
|
## Running the suite
|
|
13
13
|
|
|
14
|
-
`
|
|
14
|
+
`bun run test` delegates to `scripts/run-all-tests.mjs`, which runs every stage in `STAGES` and reports each one even when an earlier stage fails:
|
|
15
15
|
|
|
16
16
|
| stage | runner | contents |
|
|
17
17
|
| :--- | :--- | :--- |
|
|
18
|
-
| build | `
|
|
19
|
-
| performance budget | `
|
|
20
|
-
| root suites | `
|
|
21
|
-
| sqlite suites | `bun test --timeout=0` | `packages/prism-core/dist/sessions/sqlite/__tests__/*.test.js` —
|
|
22
|
-
| gate suites | `
|
|
23
|
-
| build race | `
|
|
24
|
-
| workspace suites | `
|
|
25
|
-
| examples execution | `
|
|
26
|
-
| branch coverage | `
|
|
27
|
-
|
|
28
|
-
|
|
18
|
+
| build | `bun run build` | TypeScript emit for the root and every workspace |
|
|
19
|
+
| performance budget | `bun test --timeout=0` | `scripts/budget-gate.test.mjs`, alone and single-process because its ceiling measures host contention |
|
|
20
|
+
| root suites | `bun test --parallel=4 --timeout=0` | `dist/__tests__/*.test.js` — bounded at 4 workers (plan 124 Task 2, measured 2026-09-25) so the run-bundle 5 ms snapshot budget stops flaking under host load without changing the threshold; `--path-ignore-patterns=packages/**` keeps the two suffix twins (`content.test.js`, `schema.test.js`) in the workspace stage only |
|
|
21
|
+
| sqlite suites | `bun test --timeout=0` | `packages/prism-core/dist/sessions/sqlite/__tests__/*.test.js` — prism-core's own run excludes this glob, so each SQLite file runs exactly once |
|
|
22
|
+
| gate suites | `bun test --parallel=4 --timeout=0` | `scripts/*.test.mjs` — the protection, truth, benchmark, journey, and conformance gates listed in `GATE_FILES` (`scripts/run-all-tests.mjs`), including the three split `scripts/phase54-legacy-registry-{dry-run,apply,fail-closed}.test.mjs` scenario files; bounded like the root suites because the tool-search and redaction benchmarks assert frozen absolute-time caps |
|
|
23
|
+
| build race | `bun test --timeout=0` | `scripts/phase23-build-race.test.mjs` (unwrapped: its children take the real build lock) |
|
|
24
|
+
| workspace suites | `bun run --cwd <dir> test` × 11 | each package's `bun test --parallel=4 --timeout=0` file set, two packages in flight at a time; every leaf takes `scripts/with-build-lock.mjs --shared` |
|
|
25
|
+
| examples execution | `bun test --timeout=0` | `scripts/examples-execution.test.mjs` — spawns `examples/*.ts` not already run by docs demos or a dedicated spawn; manifest skips use a fixed vocabulary. `examples/host-composition-compat.ts` is the packed-install contract consumer: its companion root suite (`host-composition-compat.test.ts`) packs the family tarballs into a fresh consumer, installs them on Bun (`bun install --offline`, plan 125 Task 2) and runs the contract plus the Task 5/7 fixtures there; the contract's sixth check `legacy-adapter-safety` probes the legacy System One adapter (one credential resolution under the configured provider id, malformed answers rejected instead of rendered, `__proto__` choice labels kept as own wire options); the pinned-old-family delta leg is env-gated (`PRISM_TEST_COMPAT_PIN_DIR` for pre-packed tarballs, `PRISM_TEST_COMPAT_PIN_FETCH=1` to pack from the registry, `PRISM_TEST_COMPAT_PIN` to change 0.9.0) and offline by default |
|
|
26
|
+
| branch coverage | `bun scripts/branch-coverage-audit.mjs` | the audit keeps its internal **Node** branch instrument (Bun 1.4.2 emits no branch data); core `dist/**` only; floor 83.49; Bun's own coverage gate still records `branches: null` |
|
|
27
|
+
|
|
28
|
+
| total (offline test budget) | `bun run test` | the whole chain, pinned `< 240s` with a measured local baseline of ~200 s (plan 124 Task 6; the pin, its method, and every load row are in `docs/_evidence/phase115-suite-budget.md` §20). The number is wall clock on a quiet host: the same chain measured 156-200 s in the quiet band and 266-588 s while an unrelated 5-VM cluster saturated this 16-CPU host, so a red pin on a loaded machine is a host reading, not a suite regression. |
|
|
29
|
+
|
|
30
|
+
Every stage runs the Bun binary (plan 124 Task 2). Bun's test runner is at parity or faster than the retired Node runner at equal file counts (root 27.1 s vs 29.7 s; gate 48.0 s vs 50.0 s, same-load A/B in `docs/_evidence/phase124-bun-only-inventory.md` §9.3) and the examples stage is ~2.8× faster because its spawned `.ts` children run natively. `bun run test:coverage` measures with `bun test --coverage` (Bun-measured floors, per-package `bunfig.toml` scoping) and runs the core suite once: the stage captures that run's output and exit code and `coverage-summary.mjs` parses the capture for the core row instead of spawning a second run (no seam set — a standalone summary, or a captured non-zero exit — still measures). The PostgreSQL leg runs `bun test` and `scripts/postgres-evidence.mjs` reads its reporter: one `(pass)`/`(fail)` line per executed test plus the trailing `Ran N tests across M files.` summary, with the exit code as the first gate. A missing or unparseable summary, a zero-test capture, or any `(fail)` line fails closed — no evidence file is written, so a broken leg can never read as a green one.
|
|
29
31
|
|
|
30
32
|
The build lock has two modes: `tsc`/emit leaves keep the exclusive default, and dist-consuming test leaves pass `--shared`. Readers overlap each other (the workspace stage depends on it), while a writer still excludes every reader and a reader excludes writers — `scripts/phase23-build-race.test.mjs` proves both directions with concurrent children, plus stale-reader reclaim. The workspace stage's pool is bounded at two in-flight packages because some package suites carry soft real-time ceilings that a busier host starves; the bound and its upgrade path are documented at the stage in `scripts/run-all-tests.mjs`.
|
|
31
33
|
|
|
32
|
-
Protected-environment legs (Postgres, PTY, NATS, live credentials) are not part of `
|
|
34
|
+
Protected-environment legs (Postgres, PTY, NATS, live credentials) are not part of `bun run test`; they fail closed with one canonical `BLOCKED GATE <id> requires=<names> evidence=<surface> hint=<how to unblock>` record and a non-zero exit when their infrastructure is absent (registry and audit: `bun scripts/blocked-gate.mjs`). A successful `PRISM_TEST_POSTGRES_URL=… bun run test:postgres` first removes stale evidence, then writes gitignored `scripts/postgres-evidence.json` with only current `gitHead`, capture time, and reporter counts; release evidence accepts it only at the same `HEAD`. Retired phase freeze/release gates live in `scripts/` for audit but are deliberately kept out of the chain. 0.7.0 host-completeness packed proof is `scripts/fixtures/e2e-070-host-completeness-journey.mjs` (same packed consumer as the full-surface journey) plus `scripts/host-completeness-evidence.test.mjs`; live legs stay skip-not-fail. R16/R17 stay blocked until plans 077/074 ship.
|
|
35
|
+
|
|
36
|
+
### Replaying the packed contract against a host-selected runtime
|
|
37
|
+
|
|
38
|
+
The packed-install contract can be replayed against any Prism family release with the existing pin triple — no new script or variable, offline by default:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# Registry route: explicit network opt-in, packs @arnilo/prism*@<pin> from npm.
|
|
42
|
+
PRISM_TEST_COMPAT_PIN=0.11.1 PRISM_TEST_COMPAT_PIN_FETCH=1 \
|
|
43
|
+
bun test --timeout=0 dist/__tests__/host-composition-compat.test.js
|
|
44
|
+
|
|
45
|
+
# Offline route: tarballs the host already packed, installed with `bun install --offline`
|
|
46
|
+
# (a cold cache retries with `--prefer-offline`: registry metadata for externals only).
|
|
47
|
+
PRISM_TEST_COMPAT_PIN_DIR=/path/to/family/tarballs \
|
|
48
|
+
bun test --timeout=0 dist/__tests__/host-composition-compat.test.js
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Without either variable the leg skips with its reason; a missing pin or an install that cannot resolve offline also skips with a reason instead of failing. Every failing check prints a named delta (`<check>: <assertion>`, plus any Task 5/7 fixture delta); **append that delta block to the remediation table in the [Synapta integration review](synapta-integration-review.md#6-remediation-status)** — deltas observed by a host-selected runtime belong in that section, not in this file. The 0.11.1 rehearsal on 2026-09-25 measured ≈9 s for the pinned leg on the registry route (≈19 s for the whole file, current leg included) and ≈11 s for the whole file on the offline route; the offline route does no first-party network work: the tarballs the host packed are the installed packages, recorded by path in the consumer lockfile.
|
|
33
52
|
|
|
34
53
|
## Isolation rules
|
|
35
54
|
|
|
36
55
|
- **Scratch roots come from the OS.** A suite that writes anything creates its root with `mkdtempSync(join(tmpdir(), "prism-…"))` and removes it in `after()`. Never rely on `process.cwd()` for write targets: the same suite runs with different working directories (workspace stage vs. root stage), so a cwd-relative root silently writes into the repository.
|
|
37
56
|
- **Pass explicit roots.** Wiki, memory, and store helpers default `workspaceRoot` to `process.cwd()`; suites pass their scratch root (and a `wikiRoot` relative to it) instead of accepting the default.
|
|
38
57
|
- **Tracked fixtures stay byte-identical.** `packages/memory/.wiki/` is a tracked wiki fixture and `docs/` is a tracked corpus. `scripts/wiki-scratch-isolation.test.mjs` runs the wiki suites from the package and from the repository root and fails if the tracked fixture hashes change, if a new file appears inside the fixture, if `<repo>/.wiki/` is scaffolded, or if the old cwd-relative scratch directories reappear.
|
|
39
|
-
- **Gates never write inside the repository.** A gate asserts against tracked content and spawns suites in temporary directories only. A gate that spawns
|
|
58
|
+
- **Gates never write inside the repository.** A gate asserts against tracked content and spawns suites in temporary directories only. A gate that spawns a **Node** nested runner must strip `NODE_TEST_CONTEXT`/`NODE_TEST_WORKER_ID` from the child environment (an inherited value makes the nested runner skip every file and still exit 0) and assert the child reported a non-zero pass count; `bun test` sets neither `BUN_*` nor `NODE_TEST_*` (measured on 1.4.2), so a Bun child needs no strip. The wiki gate spawns a plain sequential `bun test`: every nested file runs in its one runner process — the guarantee `--test-isolation=none` gave — avoiding process-worker IPC deserialization without retrying failures. No repository spawn names `node` (a Bun-only host may not have the binary) and no Node-only test flag rides `process.execPath` (Bun under the only parent, where `bun --test` is a script run, not a test runner); `scripts/tooling-gate.test.mjs` scans the repository for the violation, with one documented exception: `scripts/branch-coverage-audit.mjs` keeps the Node branch instrument. Runner-agnostic spawns (`-e` snippets, CLI invocations) keep `process.execPath` on purpose — Bun's `-e` exists.
|
|
40
59
|
- **Wait by polling, not by sleeping.** Async browser state (download quarantine, idle reaping) is not awaitable from the outside — `manager.ts` settles it on a fire-and-forget listener promise — so a fixed sleep is a race that loses under CPU load and fails the assertion for a reason unrelated to the behavior under test. Suites poll observable state through `waitFor(read, ok, label, { timeoutMs, intervalMs })` in `packages/web-tools/src/browser/__tests__/wait-for.ts`, which returns as soon as the state appears and otherwise throws naming the label and the last observed value. Fixed sleeps remain only where real elapsed time is the subject of the test (idle TTLs).
|
|
41
60
|
|
|
42
61
|
## Related APIs
|
package/docs/wiki.md
CHANGED
|
@@ -52,23 +52,23 @@ The Karpathy LLM Wiki pattern is structured into 3 distinct tiers:
|
|
|
52
52
|
|
|
53
53
|
```bash
|
|
54
54
|
# Initialize wiki in project
|
|
55
|
-
|
|
55
|
+
bunx prism-wiki init --profile codebase
|
|
56
56
|
|
|
57
57
|
# Refresh wiki after code edits
|
|
58
|
-
|
|
58
|
+
bunx prism-wiki refresh
|
|
59
59
|
|
|
60
60
|
# Check wiki health: dead anchors, broken links, orphans, pruned sources
|
|
61
|
-
|
|
61
|
+
bunx prism-wiki lint
|
|
62
62
|
|
|
63
63
|
# Search wiki from terminal
|
|
64
|
-
|
|
64
|
+
bunx prism-wiki search "How does authentication work?" --mode query
|
|
65
65
|
|
|
66
66
|
# Stage an external source for the wiki
|
|
67
|
-
|
|
67
|
+
bunx prism-wiki ingest --path notes/paper.pdf --title "Paper"
|
|
68
68
|
|
|
69
69
|
# `--url` is a usage error in the standalone CLI:
|
|
70
70
|
# the wiki package never fetches — URL ingest needs a host fetchUrl hook
|
|
71
|
-
|
|
71
|
+
bunx prism-wiki ingest --url https://example.com/rfc.pdf # → exit 1
|
|
72
72
|
```
|
|
73
73
|
|
|
74
74
|
Lint output is one summary line plus per-issue detail, and the report shape is `{ deadAnchors, brokenLinks, orphans, gaps, prunedSources, ok }`. **Pruned sources are not a failure**: a page whose raw sources were retired (`retireWikiSources`), re-pointed to a path that does not exist, or deleted out-of-band is maintainer work, so it is reported as `prunedSources` entries (`{ page, missing }`, both workspace-relative, capped to the first few paths in command/CLI text) while the health check stays `ok` and the CLI exits 0. The `wiki-maintainer` skill covers the response: re-read the surviving sources and re-file the page, or delete it when none remain.
|
|
@@ -85,14 +85,15 @@ The staging primitive behind `/wiki-ingest`, `wiki_ingest`, and the CLI. Accepts
|
|
|
85
85
|
|
|
86
86
|
| Input | Parse behavior |
|
|
87
87
|
| :--- | :--- |
|
|
88
|
-
| Text-like files and `text` | Decoded as UTF-8
|
|
89
|
-
|
|
|
90
|
-
|
|
|
88
|
+
| Text-like files and `text` | Decoded as UTF-8, except `.csv` when `extractDocument` is set |
|
|
89
|
+
| PDF | Built-in RAG parser when no hook is set. With `extractDocument`, the hook runs first and a null or throw writes nothing — no built-in fallback |
|
|
90
|
+
| CSV | UTF-8 when no hook is set. With `extractDocument`, the hook runs first and a null or throw writes nothing |
|
|
91
|
+
| DOCX / other binaries | Throws unless `extractDocument` returns text |
|
|
91
92
|
| `url` | `assertSsrfAllowedUrl` runs first (private/link-local hosts rejected before any fetch); then the host `fetchUrl` hook supplies the bytes/text — missing or empty hook output fails closed. Staged filename comes from the hook, the URL extension (`doc.pdf`), or `source.md` |
|
|
92
|
-
| Images |
|
|
93
|
+
| Images | Stub extract, no OCR. `ocrImages: true` with `extractDocument` replaces the stub only on success; null or throw writes nothing |
|
|
93
94
|
| Unknown binary | Fails closed unless `extractDocument` claims it |
|
|
94
95
|
|
|
95
|
-
Caps: 32 MiB per staged input, 2 MiB per extract. `path` must resolve inside the workspace root (realpath containment). `log.md` gains an `**Ingested**` entry only when the wiki root exists.
|
|
96
|
+
Caps: 32 MiB per staged input, 2 MiB per extract. `path` must resolve inside the workspace root (realpath containment). `log.md` gains an `**Ingested**` entry only when the wiki root exists. The wiki does not fetch links inside an extract. Standalone `prism-wiki ingest` has no extractor flag; hosts pass `extractDocument` to `createWikiExtension`.
|
|
96
97
|
|
|
97
98
|
Wiring a `fetchUrl` hook (the wiki package ships no HTTP client — hosts bring their own, e.g. Obscura):
|
|
98
99
|
|
package/docs/work-sandbox.md
CHANGED
|
@@ -105,6 +105,7 @@ Do not enable macros. Encrypted OOXML stays dropped. No in-process OLE parser.
|
|
|
105
105
|
- LibreOffice wrapper: private `/tmp/lo-profile`, `--headless`, no macro enable, `--accept` refused. No listening socket. Legacy convert uses the same wrapper.
|
|
106
106
|
- Zip bombs: existing office parse caps; sandbox export uses existing export caps.
|
|
107
107
|
- Image build is CI/protected, not default unit tests. Composition construct is in-process with a fake sandbox.
|
|
108
|
+
- Document OCR does not use `execFile`. That request has no stdin. The host runner for [document extraction](document-extraction.md) spawns `docling/ocr.py` with scrubbed env, stdin bytes, and a kill on abort. Pin Docling and the model dir in the image; do not give the worker network or token env.
|
|
108
109
|
|
|
109
110
|
## Related APIs
|
|
110
111
|
|
|
@@ -112,4 +113,5 @@ Do not enable macros. Encrypted OOXML stays dropped. No in-process OLE parser.
|
|
|
112
113
|
- [Work tools](work-tools.md) — host-side connectors
|
|
113
114
|
- [Documents](documents.md) — `createOfficeTools`
|
|
114
115
|
- [Document reader](document-reader.md) — optional `reader` injection
|
|
116
|
+
- [Document extraction](document-extraction.md) — optional Docling OCR runner, not `work_exec`
|
|
115
117
|
- [Context and skills](context-and-skills.md) — `loadWorkSkills()` (`docx`, `xlsx`, `powerpoint`, `pdf`)
|
package/docs/work-tools.md
CHANGED
|
@@ -9,10 +9,10 @@ Use when agents must read or mutate tenant mail/calendar/files/tasks through a h
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
|
|
12
|
+
bun add @arnilo/prism @arnilo/prism-work
|
|
13
13
|
# host separately:
|
|
14
|
-
#
|
|
15
|
-
#
|
|
14
|
+
# bun add -g @pnp/cli-microsoft365
|
|
15
|
+
# bun add -g @googleworkspace/cli
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
## API
|