@synapsor/runner 0.1.16 → 1.1.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.
Files changed (35) hide show
  1. package/CHANGELOG.md +47 -1
  2. package/README.md +59 -3
  3. package/THREAT_MODEL.md +29 -2
  4. package/dist/cli.d.ts.map +1 -1
  5. package/dist/local-ui.d.ts +3 -0
  6. package/dist/local-ui.d.ts.map +1 -1
  7. package/dist/runner.mjs +6587 -918
  8. package/docs/README.md +16 -3
  9. package/docs/capability-authoring.md +2 -1
  10. package/docs/conformance.md +5 -0
  11. package/docs/current-scope.md +6 -2
  12. package/docs/dsl-reference.md +25 -0
  13. package/docs/http-mcp.md +45 -1
  14. package/docs/limitations.md +22 -7
  15. package/docs/migrating-to-synapsor-spec.md +21 -0
  16. package/docs/oss-vs-cloud.md +4 -3
  17. package/docs/production.md +219 -7
  18. package/docs/release-notes.md +47 -7
  19. package/docs/release-policy.md +58 -6
  20. package/docs/runner-config-reference.md +208 -5
  21. package/docs/running-a-runner-fleet.md +349 -0
  22. package/examples/runner-fleet/Dockerfile +11 -0
  23. package/examples/runner-fleet/README.md +52 -0
  24. package/examples/runner-fleet/docker-compose.yml +76 -0
  25. package/examples/runner-fleet/mint-dev-token.mjs +19 -0
  26. package/examples/runner-fleet/seed/mysql.sql +20 -0
  27. package/examples/runner-fleet/seed/postgres.sql +73 -0
  28. package/examples/runner-fleet/synapsor.runner.json +105 -0
  29. package/examples/support-plan-credit/README.md +16 -1
  30. package/examples/support-plan-credit/contract.synapsor.sql +2 -0
  31. package/examples/support-plan-credit/synapsor.contract.json +15 -0
  32. package/fixtures/protocol/MANIFEST.json +1 -1
  33. package/package.json +3 -1
  34. package/schemas/change-set.v1.schema.json +2 -1
  35. package/schemas/synapsor.runner.schema.json +208 -0
package/CHANGELOG.md CHANGED
@@ -1,6 +1,52 @@
1
1
  # Changelog
2
2
 
3
- ## Unreleased
3
+ ## 1.1.0 (prepared, not published)
4
+
5
+ ### Fleet Safety And Operations
6
+
7
+ - Fails closed when claim-authenticated HTTP serving resolves an
8
+ environment/static contract context, and fixes object-filtered activity so
9
+ unrelated receipts cannot enter results.
10
+ - Adds RS256/ES256 session and operator JWT verification with bounded JWKS or
11
+ public-PEM loading, plus verified operator attestations without bearer-token
12
+ persistence.
13
+ - Adds dependency-aware `/readyz`, separately protected `/metrics`, reusable
14
+ bounded Postgres/MySQL pools, and trusted tenant/capability fixed-window rate
15
+ limits that are atomic in shared runtime-store mode.
16
+ - Adds optional canonical `required_approvals` and DSL `REQUIRE n APPROVALS`,
17
+ distinct-reviewer enforcement, `n/N` progress, terminal rejection, and
18
+ policy-auto-approval deferral for multi-human quorum.
19
+ - Hardens shared Postgres migration startup, bounds the transient bridge with
20
+ `max_entries`, makes CLI/UI reviewers read the shared queue, and fixes nested
21
+ worker/apply bridge locking.
22
+ - Adds verified dead-letter list/show/requeue/discard, shared-ledger
23
+ backup/digest/restore, archive-before-retention, and a repeatable two-Runner
24
+ kill/recovery test over synthetic Postgres/MySQL.
25
+ - Stages `@synapsor/spec@1.1.0`, `@synapsor/dsl@1.1.0`, and
26
+ `@synapsor/runner@1.1.0`. Nothing is published by this change.
27
+
28
+ ## 1.0.0
29
+
30
+ ### Production Approval Loop
31
+
32
+ - Adds `apply --all-approved --yes` with per-proposal results, conflict
33
+ isolation, idempotent reruns, and `--capability`, `--tenant`, and `--max`
34
+ filters.
35
+ - Adds canonical aggregate auto-approval limits in `@synapsor/spec`, DSL
36
+ `LIMIT` clauses, reviewer-visible limit trip events, and doctor/tool preview
37
+ surfacing.
38
+ - Adds signed operator identity checks for approve/reject/apply while keeping
39
+ dev env identity available for local experiments.
40
+ - Adds structured operational logs, per-tenant/capability counters, supervised
41
+ writeback worker retries/dead letters, and continued owner-only local store
42
+ permission tests.
43
+ - Adds Postgres shared ledger support, runtime-store mode, per-session
44
+ HTTP-claims trusted context, managed secret hydration, token rotation hooks,
45
+ and Streamable HTTP mTLS.
46
+ - Declares the first semver contract for the documented CLI, schema, contract,
47
+ MCP result, writeback, approval, metrics, and replay surfaces.
48
+ - Stages `@synapsor/spec@1.0.0`, `@synapsor/dsl@1.0.0`, and
49
+ `@synapsor/runner@1.0.0`.
4
50
 
5
51
  ## 0.1.16
6
52
 
package/README.md CHANGED
@@ -25,6 +25,19 @@ even if you never adopt Runner:
25
25
  npx -y @synapsor/runner audit --example dangerous-db-mcp
26
26
  ```
27
27
 
28
+ Then point the same static review at your own exported tool manifest, remote
29
+ `tools/list` endpoint, or stdio MCP server:
30
+
31
+ ```bash
32
+ npx -y @synapsor/runner audit ./tools-list.json
33
+ ```
34
+
35
+ The audit flags raw SQL, arbitrary table/column inputs, model-controlled tenant
36
+ or principal authority, model-facing approval/writeback tools, and missing
37
+ conflict or idempotency signals. It does not call business tools, and it is a
38
+ risk review rather than proof that a server is secure. See [MCP Database Risk
39
+ Review](docs/mcp-audit.md) for remote, stdio, JSON, and Markdown workflows.
40
+
28
41
  Then see the proposal, approval boundary, evidence, and replay loop. It needs no
29
42
  database, Docker, config file, MCP client, or Synapsor account:
30
43
 
@@ -65,6 +78,21 @@ approval or apply tools. A human or trusted operator approves outside MCP, then
65
78
  Runner either performs one guarded row update or routes the approved proposal
66
79
  to an app-owned executor.
67
80
 
81
+ The distinction is the complete boundary, not a read-only toggle or a generic
82
+ approve/reject prompt:
83
+
84
+ - reviewed contracts constrain tools, tenant context, visible and writable
85
+ columns, numeric bounds, transitions, and approval requirements;
86
+ - proposals separate model intent from commit authority, including aggregate
87
+ auto-approval ceilings where configured;
88
+ - evidence, query audit, idempotency receipts, and replay preserve what was
89
+ inspected, requested, approved, and applied.
90
+
91
+ Runner supports bounded production deployments when its documented database,
92
+ identity, ledger, backup, and operational controls are satisfied. It does not
93
+ make arbitrary agent code, raw SQL tools, host infrastructure, or
94
+ prompt-injection-prone clients safe by itself.
95
+
68
96
  ## Connect A Staging Database
69
97
 
70
98
  Start with a staging or disposable database and a read-only credential. Keep
@@ -146,6 +174,32 @@ least-privilege database access, host security, or application authorization.
146
174
  See [Security Boundary](docs/security-boundary.md) and
147
175
  [Current Limitations](docs/limitations.md).
148
176
 
177
+ ## Operate The Approval Loop
178
+
179
+ Reviewed policies can combine a per-proposal threshold with daily count and
180
+ total ceilings. Exceeding a ceiling routes that proposal to human review; it
181
+ never auto-applies. Operators can apply the bounded approved queue independently
182
+ with `apply --all-approved --yes`, inspect Prometheus counters with `metrics
183
+ show`, and consume safe newline-delimited JSON outcome logs from stderr. Signed
184
+ operator keys can enforce contract reviewer roles and separate apply roles.
185
+ Shared Postgres ledger mirror mode is available for bounded operator handoffs,
186
+ and `storage.shared_postgres.mode = "runtime_store"` lets MCP serving use
187
+ Postgres as the primary proposal/evidence/replay store with bounded CLI
188
+ approval/apply/worker commands bridged through the same ledger. Local SQLite
189
+ remains the default. See
190
+ [Production](docs/production.md) and the
191
+ [Runner Config Reference](docs/runner-config-reference.md).
192
+
193
+ For a small multi-tenant fleet, bind every capability context to verified HTTP
194
+ claims, use `jwt_asymmetric` session auth, and share a bounded Postgres
195
+ `runtime_store`. Never assume a global `http_claims` setting overrides an
196
+ environment-bound contract context; Runner rejects that contradiction before
197
+ serving tools. Load balancers should use dependency-free `/healthz` for
198
+ liveness and `/readyz` for source/ledger/writeback readiness. The tested
199
+ two-Runner topology, pool/rate-limit budgets, metrics, backup/restore,
200
+ dead-letter, and rolling-upgrade rules are in
201
+ [Running A Small Runner Fleet](docs/running-a-runner-fleet.md).
202
+
149
203
  ## Packages
150
204
 
151
205
  | Package | Purpose |
@@ -168,9 +222,11 @@ owner-only permissions, inspection commands, and retention.
168
222
 
169
223
  ## OSS And Cloud
170
224
 
171
- Synapsor Runner works by itself for local and single-node deployments: your
172
- database remains the source of truth and the local SQLite ledger stores review
173
- artifacts. Synapsor Cloud adds a shared contract registry, immutable versions,
225
+ Synapsor Runner works by itself for local, single-node, and bounded small-fleet
226
+ deployments: your database remains the source of truth and Runner stores review
227
+ artifacts in the default local SQLite ledger or an opt-in shared Postgres
228
+ runtime store.
229
+ Synapsor Cloud adds a shared contract registry, immutable versions,
174
230
  downloadable Runner bundles, and team activity, evidence, and approval
175
231
  surfaces. See [OSS Runner vs Synapsor Cloud](docs/oss-vs-cloud.md) for the
176
232
  detailed boundary.
package/THREAT_MODEL.md CHANGED
@@ -10,7 +10,8 @@ It is not a general MCP security gateway, not a prompt-injection cure, not a rep
10
10
  - Business rows targeted by model-facing workflows.
11
11
  - Trusted tenant, principal, source, object, allowed-column, and version bindings.
12
12
  - Proposal diffs, evidence bundles, query audit, approvals, writeback jobs, receipts, and replay records.
13
- - Runner token and local SQLite proposal store.
13
+ - Runner/session/operator tokens, local SQLite state, and optional shared
14
+ Postgres proposal/evidence/replay ledger.
14
15
 
15
16
  ## Trust Boundaries
16
17
 
@@ -38,6 +39,12 @@ MCP client/model
38
39
 
39
40
  The model-facing MCP tool call has request/proposal authority. The trusted runner has execution authority only for already-approved, scoped writeback jobs.
40
41
 
42
+ In small-fleet mode, a TLS load balancer sends signed sessions to stateless
43
+ Runner instances. Every effective capability context must bind tenant and
44
+ principal from verified claims. Shared-ledger mutations serialize under a
45
+ bounded Postgres advisory lock; source-side receipts remain the durable
46
+ idempotency boundary for effects.
47
+
41
48
  ## Covered Threats
42
49
 
43
50
  - Model asks for arbitrary SQL: no generic SQL tool is exposed in the Synapsor path.
@@ -50,6 +57,16 @@ The model-facing MCP tool call has request/proposal authority. The trusted runne
50
57
  - Over-broad update: only single-row `UPDATE` is supported and success requires exactly one affected row.
51
58
  - Cloud credential leakage: database URLs and write credentials stay local and are not sent to Cloud.
52
59
  - Model-callable approval: approval/commit tools are not exposed to MCP clients by default.
60
+ - Claims/environment confusion: an `http_claims` server fails before serving
61
+ if a capability resolves an environment/static contract context.
62
+ - JWT algorithm/key confusion: networked sessions use an explicit RS256/ES256
63
+ allowlist, issuer/audience/time checks, `kid`, and bounded public-key/JWKS
64
+ loading.
65
+ - Fleet races: shared proposal creation, distinct reviewer decisions, worker
66
+ claims, and fixed-window rate buckets are serialized/atomic in one ledger
67
+ schema.
68
+ - Worker death around an effect: source receipts make retry before write safe
69
+ and recovery after commit return `already_applied` rather than duplicate.
53
70
 
54
71
  ## Not Covered
55
72
 
@@ -60,7 +77,12 @@ The model-facing MCP tool call has request/proposal authority. The trusted runne
60
77
  - Sensitive data already returned to a model.
61
78
  - Prompt injection itself.
62
79
  - Business invariants not represented in the capability config, proposal, application handler, or database constraints.
63
- - Multi-row business transactions, DDL, DELETE, INSERT, UPSERT, or cross-database atomicity in v0.1.
80
+ - Generic multi-row business transactions, DDL, DELETE, INSERT, UPSERT, or
81
+ cross-database atomicity in the Runner direct-write path.
82
+ - A compromised IdP/JWKS host, ledger database, source database, TLS
83
+ terminator, or administrator-approved contract.
84
+ - Unbounded/high-throughput or multi-region ledger scale, compliance
85
+ certification, or production SLA.
64
86
 
65
87
  ## Required Operator Controls
66
88
 
@@ -71,6 +93,11 @@ The model-facing MCP tool call has request/proposal authority. The trusted runne
71
93
  - Prefer version/timestamp conflict guards over weak row-hash fallback.
72
94
  - Review proposal diffs and evidence before approval.
73
95
  - Monitor conflict/failed receipt rates.
96
+ - Allowlist JWKS egress, keep `/metrics` separately authorized, budget source
97
+ pools across replicas, back up/verify the shared ledger, and retain the
98
+ configured `max_entries` safety bound.
99
+ - Use verified `signed_key` or `jwt_oidc` reviewers for production-like shared
100
+ queues; `dev_env` is unverified.
74
101
 
75
102
  ## Release Blockers
76
103
 
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAYA,OAAO,EAAoP,KAAK,WAAW,EAA2F,MAAM,6BAA6B,CAAC;AAoB1Y,OAAO,EAA6G,KAAK,YAAY,EAAwB,MAAM,2BAA2B,CAAC;AAE/L,OAAO,EAOL,KAAK,gBAAgB,EAEtB,MAAM,mCAAmC,CAAC;AAgV3C,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAyD1D;AAqED,KAAK,SAAS,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAE9E,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,GAAE;IACP,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;CACvC,GACL,OAAO,CAAC,MAAM,CAAC,CA2TjB;AAiwED,wBAAsB,0BAA0B,CAAC,GAAG,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAS/H"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAYA,OAAO,EAAoP,KAAK,WAAW,EAA0H,MAAM,6BAA6B,CAAC;AAwBza,OAAO,EAA6G,KAAK,YAAY,EAAwB,MAAM,2BAA2B,CAAC;AAE/L,OAAO,EAOL,KAAK,gBAAgB,EAEtB,MAAM,mCAAmC,CAAC;AAmV3C,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA4D1D;AA0FD,KAAK,SAAS,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAE9E,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,GAAE;IACP,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;CACvC,GACL,OAAO,CAAC,MAAM,CAAC,CA2TjB;AA+gFD,wBAAsB,0BAA0B,CAAC,GAAG,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAS/H"}
@@ -1,4 +1,5 @@
1
1
  import { type Server } from "node:http";
2
+ import { ProposalStore } from "@synapsor-runner/proposal-store";
2
3
  export type LocalUiOptions = {
3
4
  configPath?: string;
4
5
  storePath?: string;
@@ -8,7 +9,9 @@ export type LocalUiOptions = {
8
9
  csrfToken?: string;
9
10
  allowRemoteBind?: boolean;
10
11
  tour?: boolean;
12
+ storeAccess?: LocalUiStoreAccess;
11
13
  };
14
+ export type LocalUiStoreAccess = <T>(mode: "read" | "write", operation: string, callback: (store: ProposalStore) => T) => Promise<T>;
12
15
  export type LocalUiServer = {
13
16
  server: Server;
14
17
  url: string;
@@ -1 +1 @@
1
- {"version":3,"file":"local-ui.d.ts","sourceRoot":"","sources":["../src/local-ui.ts"],"names":[],"mappings":"AAEA,OAAO,EAAsC,KAAK,MAAM,EAAuB,MAAM,WAAW,CAAC;AAQjG,MAAM,MAAM,cAAc,GAAG;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B,CAAC;AAEF,wBAAsB,kBAAkB,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,aAAa,CAAC,CA8C7F"}
1
+ {"version":3,"file":"local-ui.d.ts","sourceRoot":"","sources":["../src/local-ui.ts"],"names":[],"mappings":"AAEA,OAAO,EAAsC,KAAK,MAAM,EAAuB,MAAM,WAAW,CAAC;AAIjG,OAAO,EAAE,aAAa,EAAgD,MAAM,iCAAiC,CAAC;AAI9G,MAAM,MAAM,cAAc,GAAG;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,EACjC,IAAI,EAAE,MAAM,GAAG,OAAO,EACtB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,CAAC,KAClC,OAAO,CAAC,CAAC,CAAC,CAAC;AAEhB,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B,CAAC;AAEF,wBAAsB,kBAAkB,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,aAAa,CAAC,CA+C7F"}