@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/docs/README.md CHANGED
@@ -6,6 +6,16 @@ no-database demo, wire your database, then read deeper concepts.
6
6
 
7
7
  ## 01 Quickstart
8
8
 
9
+ - Audit a deliberately risky database MCP surface without cloning the repo or
10
+ connecting a database:
11
+
12
+ ```bash
13
+ npx -y @synapsor/runner audit --example dangerous-db-mcp
14
+ ```
15
+
16
+ Then use [MCP Audit](mcp-audit.md) to inspect your own tool manifest, remote
17
+ MCP endpoint, or stdio server. The audit is useful independently of whether
18
+ you adopt Runner.
9
19
  - [README](../README.md): audit-first proof, no-database demo, safety diagram,
10
20
  and the shortest own-database path.
11
21
  - [Troubleshooting First Run](troubleshooting-first-run.md): common first-run
@@ -98,9 +108,12 @@ no-database demo, wire your database, then read deeper concepts.
98
108
 
99
109
  - [Current Scope](current-scope.md): compact v0.1 scope summary.
100
110
  - [Current Limitations](limitations.md): intentional safety limits.
101
- - [Production-Candidate Guide](production.md): single-node OSS deployment
102
- scope, database roles, receipt grants, local ledger backup, restart behavior,
103
- Docker/systemd shapes, TLS, and release-gate expectations.
111
+ - [Production-Candidate Guide](production.md): single-node and bounded-fleet
112
+ OSS deployment scope, database roles, receipt grants, restart
113
+ behavior, Docker/systemd shapes, TLS, and release-gate expectations.
114
+ - [Running A Small Runner Fleet](running-a-runner-fleet.md): tested two-Runner
115
+ topology, claim-bound sessions, pools, fleet rate limits, quorum, metrics,
116
+ dead letters, backup/restore/retention, and kill/recovery evidence.
104
117
  - [Cloud Mode](cloud-mode.md): what stays local and what Cloud-linked mode adds.
105
118
  - [OSS Runner Vs Synapsor Cloud](oss-vs-cloud.md): detailed product and
106
119
  operational boundary.
@@ -136,6 +136,7 @@ reviewed runner JSON capabilities. Current parity:
136
136
  | proposal `transition_guards` | `TRANSITION status ALLOW pending -> approved\|rejected` or `TRANSITION status FROM current_status ALLOW open -> closed` | 0.1.8 | Values are state strings; use `|` for multiple target states. |
137
137
  | proposal `conflict_guard` | `CONFLICT GUARD updated_at` | 0.1 | If omitted, DSL emits an explicit weak-guard acknowledgement. Prefer a real row-version column. |
138
138
  | proposal `approval` | `APPROVAL ROLE billing_lead` | 0.1 | Local mode records the required role; enforcement is still outside the model-facing MCP tool. |
139
+ | proposal `approval.required_approvals` | `REQUIRE 2 APPROVALS` | 1.1 | Optional 1..10 distinct-reviewer quorum; defaults to 1. |
139
140
  | proposal `writeback` | `WRITEBACK DIRECT SQL`, `WRITEBACK APP HANDLER EXECUTOR name`, `WRITEBACK CLOUD WORKER`, `WRITEBACK NONE` | 0.1.7 | Handler URLs/tokens stay in `synapsor.runner.json`; contracts carry only the handler name. |
140
141
  | evidence options | `REQUIRE EVIDENCE` | 0.1 | Detailed evidence sources/handle prefixes are not expressible in DSL yet; use embedded JSON or generated contract JSON for those. |
141
142
 
@@ -285,7 +286,7 @@ surface.
285
286
  "late_fee_cents": { "minimum": 0, "maximum": 10000 }
286
287
  },
287
288
  "conflict_guard": { "column": "updated_at" },
288
- "approval": { "mode": "human", "required_role": "billing_lead" }
289
+ "approval": { "mode": "human", "required_role": "billing_lead", "required_approvals": 2 }
289
290
  }
290
291
  ```
291
292
 
@@ -26,10 +26,15 @@ Current fixture groups:
26
26
  - `proposal-capability`
27
27
  - `kept-out-fields`
28
28
  - `manual-approval`
29
+ - `auto-approval`
30
+ - `aggregate-policy-limits`
31
+ - `numeric-bounds`
29
32
 
30
33
  The fixture set is intentionally small in 0.1. It covers the runner-supported
31
34
  semantic surface first: trusted context, scoped reads, evidence handles,
32
35
  proposal boundaries, kept-out fields, manual approval, and replay envelopes.
36
+ The aggregate-policy fixture additionally proves that reviewed daily ceilings
37
+ fall back to human review atomically and record the limit that tripped.
33
38
 
34
39
  Additional 0.1 parity coverage currently lives in tests and verification
35
40
  scripts rather than separate `cloud-push/` or `dsl-json-parity/` conformance
@@ -2,7 +2,7 @@
2
2
 
3
3
  The canonical scope page is [Current Limitations](limitations.md).
4
4
 
5
- Current `0.1.x` scope:
5
+ Current `1.1` scope:
6
6
 
7
7
  - local semantic MCP tools for Postgres/MySQL-backed business actions;
8
8
  - schema inspection and guided config generation;
@@ -12,8 +12,11 @@ Current `0.1.x` scope:
12
12
  - app-owned `http_handler` and `command_handler` executors for richer approved
13
13
  business transactions;
14
14
  - stdio MCP, Streamable HTTP MCP, and a small JSON-RPC bridge.
15
+ - a bounded small-fleet shape with asymmetric claim-bound sessions, shared
16
+ Postgres review state, source pools, fleet rate limits, readiness, protected
17
+ metrics, verified quorum review, dead letters, and backup/restore/retention;
15
18
 
16
- Stable `0.1.x` compatibility covers the documented `synapsor-runner` binary,
19
+ Stable `1.x` compatibility covers the documented `synapsor-runner` binary,
17
20
  config schema version `1`, result envelope v2 with v1 opt-out, stdio/Streamable
18
21
  HTTP MCP surfaces, documented MCP client snippets, proposal/evidence/replay
19
22
  inspection commands, direct SQL writeback, and app-owned executor contracts.
@@ -26,4 +29,5 @@ Out of scope:
26
29
  - generic multi-row SQL writeback;
27
30
  - physical branching of external Postgres/MySQL;
28
31
  - self-hosted Synapsor Cloud;
32
+ - unbounded or multi-region shared-ledger scale and a managed Runner fleet;
29
33
  - production SLA or compliance certification.
@@ -148,7 +148,10 @@ patched column. Values may be identifiers or quoted strings.
148
148
 
149
149
  ```sql
150
150
  APPROVAL ROLE billing_lead
151
+ REQUIRE 2 APPROVALS
151
152
  AUTO APPROVE WHEN amount_cents <= 2500
153
+ LIMIT 20 PER DAY
154
+ LIMIT TOTAL 100000 PER DAY
152
155
  WRITEBACK DIRECT SQL
153
156
  ```
154
157
 
@@ -156,10 +159,32 @@ patched column. Values may be identifiers or quoted strings.
156
159
  approval identity is operator-provided; enterprise identity/RBAC belongs to the
157
160
  Cloud boundary.
158
161
 
162
+ `REQUIRE n APPROVALS` is optional and accepts 1 through 10. It compiles to the
163
+ canonical `approval.required_approvals` field. The default is 1. Each slot
164
+ requires a distinct verified subject; duplicate subjects fail with
165
+ `APPROVER_ALREADY_COUNTED`. Apply/workers remain blocked until `n/N`, rejection
166
+ is terminal, and policy auto-approval is deferred when `n > 1`.
167
+
159
168
  `AUTO APPROVE WHEN field <= non_negative_integer` is supported only for a
160
169
  numeric patched field and must follow `APPROVAL ROLE`. Its maximum cannot exceed
161
170
  the field's `BOUND`. Policy approval still does not apply the write.
162
171
 
172
+ Aggregate limits follow the auto-approval clause:
173
+
174
+ ```sql
175
+ LIMIT 20 PER DAY
176
+ LIMIT TOTAL 100000 PER DAY
177
+ ```
178
+
179
+ `LIMIT n PER DAY` caps policy approvals for the trusted tenant and policy in
180
+ the UTC calendar day. `LIMIT TOTAL n PER DAY` sums the policy's numeric patch
181
+ field over the same scope. Use `PER OBJECT DAY` instead of `PER DAY` to scope a
182
+ limit to one trusted tenant, policy, and business object. The check and approval
183
+ are one atomic ledger transaction. When any ceiling would be exceeded, Runner
184
+ leaves the proposal in `pending_review` and records
185
+ `policy_auto_approval_deferred` with observed, proposed, and projected values.
186
+ It does not reject or auto-apply the proposal.
187
+
163
188
  Writeback forms:
164
189
 
165
190
  | Clause | Meaning |
package/docs/http-mcp.md CHANGED
@@ -70,7 +70,50 @@ cors: disabled
70
70
  sessions: in-memory
71
71
  ```
72
72
 
73
- Use `/mcp` as the MCP endpoint. Health is available at `/healthz`.
73
+ Use `/mcp` as the MCP endpoint. Cheap process liveness is available at
74
+ `/healthz`; dependency readiness is available at `/readyz`. When separately
75
+ enabled and authorized, OpenMetrics is available at `/metrics`.
76
+
77
+ ## TLS And mTLS
78
+
79
+ For a non-local long-running service, terminate TLS at a trusted proxy or start
80
+ Runner with env-backed PEM material:
81
+
82
+ ```bash
83
+ export SYNAPSOR_TLS_CERT_PEM="$(cat ./server.crt)"
84
+ export SYNAPSOR_TLS_KEY_PEM="$(cat ./server.key)"
85
+
86
+ synapsor-runner mcp serve-streamable-http \
87
+ --host 0.0.0.0 \
88
+ --port 8766 \
89
+ --config ./synapsor.runner.json \
90
+ --store ./.synapsor/local.db \
91
+ --auth-token-env SYNAPSOR_RUNNER_HTTP_TOKEN \
92
+ --tls-cert-env SYNAPSOR_TLS_CERT_PEM \
93
+ --tls-key-env SYNAPSOR_TLS_KEY_PEM
94
+ ```
95
+
96
+ To require client certificates:
97
+
98
+ ```bash
99
+ export SYNAPSOR_TLS_CA_PEM="$(cat ./client-ca.crt)"
100
+
101
+ synapsor-runner mcp serve-streamable-http \
102
+ --host 0.0.0.0 \
103
+ --port 8766 \
104
+ --config ./synapsor.runner.json \
105
+ --store ./.synapsor/local.db \
106
+ --auth-token-env SYNAPSOR_RUNNER_HTTP_TOKEN \
107
+ --tls-cert-env SYNAPSOR_TLS_CERT_PEM \
108
+ --tls-key-env SYNAPSOR_TLS_KEY_PEM \
109
+ --tls-ca-env SYNAPSOR_TLS_CA_PEM \
110
+ --require-client-cert
111
+ ```
112
+
113
+ The CLI reads PEM contents from environment variables and never prints them.
114
+ Runner-owned mTLS currently protects the Streamable HTTP MCP boundary. For
115
+ app-owned `http_handler` executors, terminate mTLS in your service mesh/proxy
116
+ or handler process and keep bearer/signature checks enabled in the handler.
74
117
 
75
118
  ## Start The JSON-RPC Bridge
76
119
 
@@ -106,6 +149,7 @@ variable name. It does not print token values or database URLs.
106
149
  ```bash
107
150
  curl -i http://127.0.0.1:8766/healthz
108
151
  curl -i http://127.0.0.1:8765/healthz
152
+ curl -i http://127.0.0.1:8766/readyz
109
153
  ```
110
154
 
111
155
  The health endpoint is secret-free:
@@ -1,13 +1,21 @@
1
1
  # Limitations
2
2
 
3
- Synapsor Runner is intentionally narrow in the current alpha.
3
+ Synapsor Runner is intentionally narrow. Version 1.1 adds a bounded small-fleet
4
+ shape; it does not claim Synapsor Cloud scale or an enterprise SLA.
4
5
 
5
6
  ## Supported
6
7
 
7
8
  - Stdio MCP server for semantic database capabilities.
8
9
  - Local read and proposal tools.
9
- - Local SQLite evidence/proposal/query-audit/replay store.
10
- - Human approval through CLI commands.
10
+ - Local SQLite evidence/proposal/query-audit/replay store by default.
11
+ - Optional shared Postgres proposal/evidence/replay runtime store for MCP serving.
12
+ - Asymmetric claim-bound Streamable HTTP sessions and explicit readiness.
13
+ - Native Postgres/MySQL source pools and operational/fleet-wide rate limits.
14
+ - Verified operator approval through CLI, optional distinct-reviewer quorum,
15
+ and shared local review UI reads.
16
+ - Separately protected scrapeable metrics and dead-letter recovery commands.
17
+ - Shared-ledger backup/digest verification, clean restore, and
18
+ archive-before-retention.
11
19
  - Public protocol objects:
12
20
  - `synapsor.change-set.v1`
13
21
  - `synapsor.writeback-job.v1`
@@ -55,7 +63,8 @@ truth for the model-facing tools.
55
63
  - Model-callable approval or commit tools.
56
64
  - Generic MCP firewall behavior.
57
65
  - Prompt-injection prevention.
58
- - High availability, SLA, compliance certification, or production support guarantee.
66
+ - Unbounded/high-throughput or multi-region ledger scale.
67
+ - Managed fleet, SLA, compliance certification, or production support guarantee.
59
68
 
60
69
  ## Important External Database Semantics
61
70
 
@@ -77,9 +86,15 @@ It does not mean external Postgres/MySQL time travel. Runner cannot reconstruct
77
86
  arbitrary historical rows that were never captured as evidence, and it does not
78
87
  provide `AS OF` queries over an external source.
79
88
 
80
- Local search is single-node SQLite search over the local runner store. It is
81
- useful for local/dev/staging usage. It is not a hosted central evidence ledger,
82
- not cross-runner aggregation, not RBAC/SSO, and not compliance retention.
89
+ Local search uses SQLite by default. In `runtime_store` mode, CLI/UI reads can
90
+ inspect one bounded shared Postgres ledger across a small fleet. This is still
91
+ not a hosted central evidence service, organization RBAC/SSO, compliance
92
+ retention system, or unbounded search engine. Each bridge operation serializes
93
+ through an advisory lock and fails above configured `max_entries`.
94
+
95
+ Only homogeneous 1.1 fleet operation is currently verified. Mixed 1.0/1.1
96
+ rolling operation is not claimed. See [Running A Small Runner
97
+ Fleet](running-a-runner-fleet.md).
83
98
 
84
99
  Use this wording:
85
100
 
@@ -127,6 +127,27 @@ Then keep only local wiring in `synapsor.runner.json`.
127
127
  }
128
128
  ```
129
129
 
130
+ ## 1.1 Approval Quorum
131
+
132
+ Existing contracts remain valid and require one approval. To require distinct
133
+ verified reviewers, add the optional canonical field:
134
+
135
+ ```json
136
+ {
137
+ "proposal": {
138
+ "approval": {
139
+ "mode": "human",
140
+ "required_role": "billing_lead",
141
+ "required_approvals": 2
142
+ }
143
+ }
144
+ }
145
+ ```
146
+
147
+ The equivalent DSL is `REQUIRE 2 APPROVALS` after `APPROVAL ROLE
148
+ billing_lead`. Runner 1.0 does not understand this new optional semantic field;
149
+ use Runner/spec/DSL 1.1 together. Omitted fields preserve 1.0 behavior.
150
+
130
151
  ## Validate
131
152
 
132
153
  ```bash
@@ -6,7 +6,8 @@ contract, but they solve different operational problems.
6
6
  Runner is the open-source runtime that stays next to your application and
7
7
  database. It serves reviewed MCP tools, binds trusted context, stores local
8
8
  evidence and proposals, keeps approval outside MCP, applies or routes approved
9
- writeback, and records receipts and replay in a local SQLite ledger.
9
+ writeback, and records receipts and replay in the default local SQLite ledger
10
+ or an opt-in shared Postgres runtime store.
10
11
 
11
12
  Cloud is the team control plane. It stores versioned contracts, produces
12
13
  downloadable Runner bundles, and provides shared activity, evidence, approval,
@@ -18,12 +19,12 @@ and investigation surfaces for enabled design-partner deployments.
18
19
  | Contract source | Local files reviewed in Git | Shared registry with immutable versions and digests |
19
20
  | Trusted context | Local environment/session bindings | Registered bindings plus deployment-specific Cloud session context |
20
21
  | Capabilities | Local semantic MCP tools | Registry, version history, and capability inspection |
21
- | Evidence and replay | Local SQLite ledger | Shared activity and evidence surfaces where enabled |
22
+ | Evidence and replay | Local SQLite ledger by default; optional shared Postgres runtime store | Shared activity and evidence surfaces where enabled |
22
23
  | Approval | Local CLI or localhost UI | Team approval surfaces where enabled |
23
24
  | Writeback | Guarded one-row update or app-owned executor | Cloud-linked jobs with local execution; managed production orchestration is future work |
24
25
  | MCP risk audit | Static local audit | Organization-wide continuous audit is future work |
25
26
  | Identity | Local operator boundary | Workspace RBAC where configured; SAML and SCIM are future work |
26
- | Operations | Customer-operated single node | Design-partner operation; no enterprise SLA in the current beta |
27
+ | Operations | Customer-operated single node or bounded small fleet | Managed fleet remains Cloud work; no enterprise SLA in the current beta |
27
28
 
28
29
  ## What Stays Local
29
30
 
@@ -14,10 +14,36 @@ MCP agent
14
14
  -> receipt/replay
15
15
  ```
16
16
 
17
- Use this only for bounded database workflows where you can accept a single-node
18
- local ledger and local/operator approval. Use Synapsor Cloud when you need HA,
19
- central audit, RBAC/SSO, multi-reviewer approvals, hosted retention, managed
20
- runners, policy packs, or production support/SLA.
17
+ Use this only for bounded database workflows using either the default
18
+ single-node SQLite ledger or the tested, serialized small-fleet Postgres
19
+ runtime store. Use Synapsor Cloud when you need a managed fleet, hosted central
20
+ audit, organization administration, SSO/SCIM, compliance retention, or a
21
+ production support/SLA. See [Running A Small Runner
22
+ Fleet](running-a-runner-fleet.md) for the exact OSS fleet guarantees and limits.
23
+
24
+ ## Audit The Agent-Facing Surface First
25
+
26
+ Before configuring writeback or connecting a production-like database, audit
27
+ the MCP tools the agent can see. Start with Runner's built-in risky database MCP
28
+ example:
29
+
30
+ ```bash
31
+ npx -y @synapsor/runner audit --example dangerous-db-mcp
32
+ ```
33
+
34
+ Then audit the actual manifest, remote MCP endpoint, or stdio server you intend
35
+ to expose:
36
+
37
+ ```bash
38
+ synapsor-runner audit ./tools-list.json
39
+ synapsor-runner audit https://mcp.example.com --bearer-env MCP_AUDIT_TOKEN
40
+ synapsor-runner audit 'stdio:node ./server.mjs'
41
+ ```
42
+
43
+ Audit is a static risk review, not proof that an MCP server is secure. Treat
44
+ generic SQL/query tools, model-controlled tenant or principal fields, and
45
+ model-facing approval/apply tools as deployment blockers. See [MCP
46
+ Audit](mcp-audit.md) for supported inputs, findings, and machine-readable output.
21
47
 
22
48
  ## Supported Scope
23
49
 
@@ -27,6 +53,11 @@ Production-candidate OSS scope:
27
53
  - trusted context from environment/session values, not model arguments;
28
54
  - local SQLite ledger for evidence, query audit, proposals, receipts, replay,
29
55
  and lifecycle events;
56
+ - bounded shared Postgres runtime ledger for several claim-bound HTTP Runner
57
+ instances and verified reviewers;
58
+ - asymmetric RS256/ES256 session authentication, readiness probes, separately
59
+ protected metrics, source pools, and fleet-wide rate limits;
60
+ - distinct-reviewer approval quorum from the canonical contract;
30
61
  - direct guarded single-row `UPDATE` for simple approved edits;
31
62
  - app-owned `http_handler` or `command_handler` executors for richer approved
32
63
  business transactions;
@@ -37,8 +68,8 @@ Out of scope:
37
68
  - raw `execute_sql` or model-generated SQL;
38
69
  - generic direct `INSERT`, `DELETE`, `UPSERT`, DDL, or multi-row SQL writeback;
39
70
  - physical branching of external Postgres/MySQL;
40
- - workflow DAGs, auto-merge/settlement, RBAC/SSO, HA ledger, or compliance
41
- retention;
71
+ - workflow DAGs, auto-merge/settlement, hosted team administration, SSO/SCIM,
72
+ multi-region ledger replication, or compliance retention;
42
73
  - making prompt injection impossible.
43
74
 
44
75
  ## Database Roles
@@ -150,12 +181,172 @@ Useful commands:
150
181
  ```bash
151
182
  synapsor-runner store stats --store ./.synapsor/local.db
152
183
  synapsor-runner events tail --store ./.synapsor/local.db --follow
184
+ synapsor-runner metrics show --store ./.synapsor/local.db
153
185
  synapsor-runner store prune --store ./.synapsor/local.db --older-than 30d --dry-run
154
186
  synapsor-runner store vacuum --store ./.synapsor/local.db
155
187
  ```
156
188
 
157
189
  Details: [Store Lifecycle](store-lifecycle.md).
158
190
 
191
+ ## Shared Postgres Ledger Setup
192
+
193
+ The default runtime ledger is SQLite. For shared deployments, Runner now ships a
194
+ Postgres ledger setup surface that creates the schema used for shared audit
195
+ entries, proposal locks, and worker leases:
196
+
197
+ ```bash
198
+ export SYNAPSOR_LEDGER_DATABASE_URL="postgresql://ledger_writer:..."
199
+
200
+ synapsor-runner store shared-postgres migration --schema synapsor_runner
201
+ synapsor-runner store shared-postgres apply-migration \
202
+ --url-env SYNAPSOR_LEDGER_DATABASE_URL \
203
+ --schema synapsor_runner \
204
+ --yes
205
+ synapsor-runner store shared-postgres status \
206
+ --url-env SYNAPSOR_LEDGER_DATABASE_URL \
207
+ --schema synapsor_runner
208
+ synapsor-runner store shared-postgres sync \
209
+ --store ./.synapsor/local.db \
210
+ --url-env SYNAPSOR_LEDGER_DATABASE_URL \
211
+ --schema synapsor_runner \
212
+ --yes
213
+ synapsor-runner store shared-postgres restore \
214
+ --store ./.synapsor/restored.db \
215
+ --url-env SYNAPSOR_LEDGER_DATABASE_URL \
216
+ --schema synapsor_runner \
217
+ --yes
218
+ ```
219
+
220
+ These commands do not print the database URL. `sync` upserts a stable snapshot
221
+ of the local proposal/evidence/replay ledger into Postgres for shared audit,
222
+ backup, and retention. `restore` rebuilds a local SQLite store from those
223
+ shared ledger entries for recovery or offline investigation.
224
+
225
+ Runner supports two shared Postgres modes:
226
+
227
+ - `mirror`: bounded CLI mutations restore from Postgres into local SQLite,
228
+ mutate locally, then sync back under a schema-scoped advisory lock.
229
+ - `runtime_store`: MCP serving uses Postgres as the primary
230
+ proposal/evidence/replay store instead of opening a local SQLite store.
231
+
232
+ Local SQLite remains the default. Use `runtime_store` when several MCP sessions
233
+ or runner processes need to share proposal/evidence/replay state through one
234
+ ledger database. Use `mirror` when you want bounded operator handoff while still
235
+ running CLI mutations against a local SQLite file.
236
+
237
+ Mirror mode config:
238
+
239
+ ```json
240
+ {
241
+ "storage": {
242
+ "sqlite_path": "./.synapsor/local.db",
243
+ "shared_postgres": {
244
+ "mode": "mirror",
245
+ "url_env": "SYNAPSOR_LEDGER_DATABASE_URL",
246
+ "schema": "synapsor_runner",
247
+ "lock_timeout_ms": 10000,
248
+ "max_entries": 10000
249
+ }
250
+ }
251
+ }
252
+ ```
253
+
254
+ ```bash
255
+ export SYNAPSOR_LEDGER_DATABASE_URL="postgresql://ledger_writer:..."
256
+
257
+ synapsor-runner doctor \
258
+ --config ./synapsor.runner.json \
259
+ --store ./.synapsor/local.db
260
+
261
+ synapsor-runner propose support.propose_plan_credit --sample \
262
+ --config ./synapsor.runner.json \
263
+ --store ./.synapsor/local.db
264
+
265
+ synapsor-runner proposals approve latest --yes \
266
+ --config ./synapsor.runner.json \
267
+ --store ./.synapsor/local.db
268
+
269
+ synapsor-runner apply --all-approved --yes \
270
+ --config ./synapsor.runner.json \
271
+ --store ./.synapsor/local.db
272
+ ```
273
+
274
+ When `storage.shared_postgres.mode` is `mirror`, `doctor` checks that the
275
+ ledger URL environment variable is present and that `ledger_entries`,
276
+ `proposal_locks`, `worker_leases`, and `rate_limit_buckets` exist in the
277
+ configured schema. It reports
278
+ environment variable names and table readiness only; it does not print database
279
+ URLs or initialize the schema.
280
+
281
+ Mirror mode restores the Postgres ledger into the local store before a mutation
282
+ and syncs the local store back after the command, including failure events when
283
+ they were recorded locally. While it runs, Runner holds a schema-scoped
284
+ Postgres advisory lock so concurrent mirror-mode operators do not restore,
285
+ mutate, and sync over one another. The default lock wait is 10 seconds; tune it
286
+ with `--shared-ledger-lock-timeout-ms` or
287
+ `SYNAPSOR_SHARED_LEDGER_LOCK_TIMEOUT_MS`.
288
+
289
+ Mirror mode is explicit because the local SQLite store still executes the CLI
290
+ mutation. It is useful for bounded operator workflows and finite workers
291
+ (`worker run --once` or `--drain`); use `runtime_store` for long-lived MCP
292
+ serving and shared worker loops that need one proposal/evidence/replay ledger.
293
+
294
+ Runtime-store mode config:
295
+
296
+ ```json
297
+ {
298
+ "storage": {
299
+ "shared_postgres": {
300
+ "mode": "runtime_store",
301
+ "url_env": "SYNAPSOR_LEDGER_DATABASE_URL",
302
+ "schema": "synapsor_runner",
303
+ "lock_timeout_ms": 10000
304
+ }
305
+ }
306
+ }
307
+ ```
308
+
309
+ When MCP serving starts in `runtime_store` mode, Runner opens the Postgres URL
310
+ from `url_env`, auto-runs the shared-ledger migration, and serializes runtime
311
+ mutations with a transaction-scoped advisory lock. The MCP tools still expose no
312
+ database URLs or write credentials to the model.
313
+
314
+ `runtime_store` covers MCP serving, CLI approval/apply, and supervised worker
315
+ runs. For CLI mutations, Runner restores the shared ledger into a temporary
316
+ local store while holding the Postgres advisory lock, runs the existing local
317
+ mutation, then syncs the resulting ledger entries back to Postgres. A
318
+ long-running `worker run --yes` repeats bounded drain cycles under that lock
319
+ and sleeps between idle polls, so multiple workers can share one Postgres ledger
320
+ without holding the lock while idle.
321
+
322
+ The current bridge loads a bounded snapshot and serializes each mutation. It
323
+ fails closed above `max_entries`; it is not an unbounded scalable database
324
+ engine. `proposals`, `evidence`, `query-audit`, `receipts`, `replay`,
325
+ `activity`, `metrics`, worker status, and the local UI can read the same shared
326
+ queue with `--config`. Back up, verify, restore, and archive-before-retention
327
+ with the commands in [Running A Small Runner Fleet](running-a-runner-fleet.md).
328
+
329
+ For unattended policy-approved queues, declare reviewed aggregate `LIMIT`
330
+ clauses first, then use the explicit batch command:
331
+
332
+ ```bash
333
+ synapsor-runner apply --all-approved --yes \
334
+ --config ./synapsor.runner.json --store ./.synapsor/local.db \
335
+ --capability support.propose_plan_credit --tenant acme --max 20
336
+ ```
337
+
338
+ Each proposal is independent: a stale-row conflict does not abort later jobs.
339
+ The final summary reports applied, conflict, and skipped IDs. Re-running is
340
+ idempotent through durable receipts. Do not schedule batch apply for a policy
341
+ that has no reviewed aggregate limits.
342
+
343
+ Runner writes newline-delimited JSON events to stderr for model-facing tool
344
+ rejections, operator decisions, and terminal writeback outcomes. These events
345
+ contain safe codes and identifiers, never tool arguments, row values, database
346
+ URLs, tokens, private keys, or free-form driver errors. Prometheus/OpenMetrics
347
+ counters are available with `metrics show` and are grouped by trusted tenant
348
+ and reviewed capability.
349
+
159
350
  ## Restart And Recovery
160
351
 
161
352
  Runner stores proposal/evidence/replay state before writeback.
@@ -183,7 +374,26 @@ synapsor-runner activity search --proposal wrp_... --store ./.synapsor/local.db
183
374
  ### Docker Compose Shape
184
375
 
185
376
  Use Compose to run the MCP server next to your app and database network. Keep
186
- secrets in environment variables or your platform secret manager.
377
+ secrets in environment variables or your platform secret manager. To hydrate
378
+ Runner env vars from AWS Secrets Manager at startup, pass a JSON map through
379
+ `SYNAPSOR_SECRET_MAP`:
380
+
381
+ ```bash
382
+ export SYNAPSOR_SECRET_MAP='{
383
+ "SYNAPSOR_DATABASE_READ_URL": "prod/synapsor/runner#read_url",
384
+ "SYNAPSOR_DATABASE_WRITE_URL": "prod/synapsor/runner#write_url",
385
+ "SYNAPSOR_RUNNER_HTTP_TOKEN": "prod/synapsor/runner#http_token"
386
+ }'
387
+
388
+ synapsor-runner mcp serve-streamable-http \
389
+ --config ./synapsor.runner.json \
390
+ --store ./.synapsor/local.db \
391
+ --secrets-provider aws-secretsmanager-cli \
392
+ --secret-map-env SYNAPSOR_SECRET_MAP
393
+ ```
394
+
395
+ The AWS provider shells out to `aws secretsmanager get-secret-value`; the runner
396
+ logs only how many target env vars were loaded or skipped.
187
397
 
188
398
  ```yaml
189
399
  services:
@@ -256,6 +466,8 @@ synapsor-runner config validate --config synapsor.runner.json
256
466
  synapsor-runner doctor --config synapsor.runner.json --report --redact --output synapsor-doctor.md
257
467
  synapsor-runner doctor --config synapsor.runner.json --check-writeback
258
468
  synapsor-runner tools preview --config synapsor.runner.json --store ./.synapsor/local.db
469
+ curl --fail http://127.0.0.1:8766/healthz
470
+ curl --fail http://127.0.0.1:8766/readyz
259
471
  ```
260
472
 
261
473
  Doctor reports should be redacted by default before sharing. They must not
@@ -1,7 +1,7 @@
1
1
  # Release Notes
2
2
 
3
- These notes track public Synapsor Runner behavior. Starting with `0.1.0`, the
4
- normal install path uses the untagged stable package:
3
+ These notes track public Synapsor Runner behavior. Starting with `1.0.0`, the
4
+ documented production-loop compatibility line uses the untagged stable package:
5
5
 
6
6
  ```bash
7
7
  npx -y -p @synapsor/runner synapsor-runner demo --quick
@@ -10,7 +10,48 @@ npx -y -p @synapsor/runner synapsor-runner demo --quick
10
10
  The OSS runner command is `synapsor-runner`. The `synapsor` command is reserved
11
11
  for the Synapsor Cloud CLI.
12
12
 
13
- ## Unreleased
13
+ ## 1.1.0 (prepared, not published)
14
+
15
+ ### Bounded Small-Fleet Runtime
16
+
17
+ - Fixes claim/context authority conflicts before serving and keeps
18
+ object-filtered receipts/activity scoped to the requested object.
19
+ - Adds asymmetric session/operator identity, readiness, protected HTTP
20
+ metrics, bounded native source pools, and shared fleet rate limits.
21
+ - Adds portable distinct-reviewer quorum in the OSS canonical spec and DSL.
22
+ Existing 1.0 contracts still default to one approval. Cloud/C++ enforcement
23
+ of this optional field is not claimed until independently verified there.
24
+ - Adds bounded shared-ledger CLI/UI review, startup-safe schema migration,
25
+ dead-letter recovery, backup/restore/retention, and tested worker recovery
26
+ before write and after durable commit.
27
+ - Adds [Running A Small Runner Fleet](running-a-runner-fleet.md) and the
28
+ `corepack pnpm test:fleet` synthetic two-Runner verification.
29
+
30
+ Prepared package versions: `@synapsor/spec@1.1.0`,
31
+ `@synapsor/dsl@1.1.0`, and `@synapsor/runner@1.1.0`.
32
+
33
+ ## 1.0.0
34
+
35
+ ### Production Approval Loop
36
+
37
+ - Adds batch apply for approved proposals with independent per-proposal
38
+ outcomes, rerun-safe idempotency, and `--capability`, `--tenant`, and
39
+ `--max` filters.
40
+ - Adds aggregate policy ceilings to canonical contracts and DSL authoring so
41
+ small proposals fall back to human review once daily count or total limits are
42
+ reached.
43
+ - Adds signed operator-key approval/apply enforcement, tamper-evident approval
44
+ records, operational counters/logs, and a supervised local writeback worker.
45
+ - Adds shared Postgres ledger support, runtime-store mode, per-session trusted
46
+ context, managed secret hydration, token rotation hooks, and Streamable HTTP
47
+ mTLS for scale-out deployments.
48
+ - Keeps local SQLite as the default while allowing runtime-store workers to run
49
+ long-lived shared ledger drain loops under a Postgres advisory lock.
50
+ - Declares the first semver contract for the documented CLI, schema, contract,
51
+ MCP result, writeback, approval, metrics, and replay surfaces.
52
+
53
+ Prepared package versions: `@synapsor/spec@1.0.0`,
54
+ `@synapsor/dsl@1.0.0`, and `@synapsor/runner@1.0.0`.
14
55
 
15
56
  ## 0.1.16
16
57
 
@@ -478,10 +519,9 @@ not change and must not be republished for this release.
478
519
 
479
520
  ## Stable Release Policy
480
521
 
481
- Use untagged `@synapsor/runner` for stable installs. Use `@alpha` or an exact
482
- prerelease only when intentionally testing preview behavior. Stable `0.1.x`
483
- releases should keep the compatibility promise documented in
484
- `docs/release-policy.md`.
522
+ Use untagged `@synapsor/runner` for stable installs. Use an exact prerelease
523
+ only when intentionally testing preview behavior. Stable `1.x` releases should
524
+ keep the compatibility promise documented in `docs/release-policy.md`.
485
525
 
486
526
  The first stable `0.1.0` release was gated on:
487
527