@synapsor/runner 1.0.0 → 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.
- package/CHANGELOG.md +24 -1
- package/README.md +42 -3
- package/THREAT_MODEL.md +29 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/local-ui.d.ts +3 -0
- package/dist/local-ui.d.ts.map +1 -1
- package/dist/runner.mjs +3901 -858
- package/docs/README.md +16 -3
- package/docs/capability-authoring.md +2 -1
- package/docs/current-scope.md +5 -1
- package/docs/dsl-reference.md +7 -0
- package/docs/http-mcp.md +4 -1
- package/docs/limitations.md +20 -6
- package/docs/migrating-to-synapsor-spec.md +21 -0
- package/docs/oss-vs-cloud.md +1 -1
- package/docs/production.md +50 -8
- package/docs/release-notes.md +19 -1
- package/docs/release-policy.md +21 -0
- package/docs/runner-config-reference.md +101 -3
- package/docs/running-a-runner-fleet.md +349 -0
- package/examples/runner-fleet/Dockerfile +11 -0
- package/examples/runner-fleet/README.md +52 -0
- package/examples/runner-fleet/docker-compose.yml +76 -0
- package/examples/runner-fleet/mint-dev-token.mjs +19 -0
- package/examples/runner-fleet/seed/mysql.sql +20 -0
- package/examples/runner-fleet/seed/postgres.sql +73 -0
- package/examples/runner-fleet/synapsor.runner.json +105 -0
- package/fixtures/protocol/MANIFEST.json +1 -1
- package/package.json +3 -1
- package/schemas/change-set.v1.schema.json +2 -1
- package/schemas/synapsor.runner.schema.json +115 -7
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
|
|
102
|
-
scope, database roles, receipt grants,
|
|
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
|
|
package/docs/current-scope.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
The canonical scope page is [Current Limitations](limitations.md).
|
|
4
4
|
|
|
5
|
-
Current `1.
|
|
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,6 +12,9 @@ Current `1.0` 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
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
|
|
@@ -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.
|
package/docs/dsl-reference.md
CHANGED
|
@@ -148,6 +148,7 @@ 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
|
|
152
153
|
LIMIT 20 PER DAY
|
|
153
154
|
LIMIT TOTAL 100000 PER DAY
|
|
@@ -158,6 +159,12 @@ patched column. Values may be identifiers or quoted strings.
|
|
|
158
159
|
approval identity is operator-provided; enterprise identity/RBAC belongs to the
|
|
159
160
|
Cloud boundary.
|
|
160
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
|
+
|
|
161
168
|
`AUTO APPROVE WHEN field <= non_negative_integer` is supported only for a
|
|
162
169
|
numeric patched field and must follow `APPROVAL ROLE`. Its maximum cannot exceed
|
|
163
170
|
the field's `BOUND`. Policy approval still does not apply the write.
|
package/docs/http-mcp.md
CHANGED
|
@@ -70,7 +70,9 @@ cors: disabled
|
|
|
70
70
|
sessions: in-memory
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
-
Use `/mcp` as the MCP endpoint.
|
|
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`.
|
|
74
76
|
|
|
75
77
|
## TLS And mTLS
|
|
76
78
|
|
|
@@ -147,6 +149,7 @@ variable name. It does not print token values or database URLs.
|
|
|
147
149
|
```bash
|
|
148
150
|
curl -i http://127.0.0.1:8766/healthz
|
|
149
151
|
curl -i http://127.0.0.1:8765/healthz
|
|
152
|
+
curl -i http://127.0.0.1:8766/readyz
|
|
150
153
|
```
|
|
151
154
|
|
|
152
155
|
The health endpoint is secret-free:
|
package/docs/limitations.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# Limitations
|
|
2
2
|
|
|
3
|
-
Synapsor Runner is intentionally narrow
|
|
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
|
|
|
@@ -8,7 +9,13 @@ Synapsor Runner is intentionally narrow in the current alpha.
|
|
|
8
9
|
- Local read and proposal tools.
|
|
9
10
|
- Local SQLite evidence/proposal/query-audit/replay store by default.
|
|
10
11
|
- Optional shared Postgres proposal/evidence/replay runtime store for MCP serving.
|
|
11
|
-
-
|
|
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.
|
|
12
19
|
- Public protocol objects:
|
|
13
20
|
- `synapsor.change-set.v1`
|
|
14
21
|
- `synapsor.writeback-job.v1`
|
|
@@ -56,7 +63,8 @@ truth for the model-facing tools.
|
|
|
56
63
|
- Model-callable approval or commit tools.
|
|
57
64
|
- Generic MCP firewall behavior.
|
|
58
65
|
- Prompt-injection prevention.
|
|
59
|
-
-
|
|
66
|
+
- Unbounded/high-throughput or multi-region ledger scale.
|
|
67
|
+
- Managed fleet, SLA, compliance certification, or production support guarantee.
|
|
60
68
|
|
|
61
69
|
## Important External Database Semantics
|
|
62
70
|
|
|
@@ -78,9 +86,15 @@ It does not mean external Postgres/MySQL time travel. Runner cannot reconstruct
|
|
|
78
86
|
arbitrary historical rows that were never captured as evidence, and it does not
|
|
79
87
|
provide `AS OF` queries over an external source.
|
|
80
88
|
|
|
81
|
-
Local search
|
|
82
|
-
|
|
83
|
-
not
|
|
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).
|
|
84
98
|
|
|
85
99
|
Use this wording:
|
|
86
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
|
package/docs/oss-vs-cloud.md
CHANGED
|
@@ -24,7 +24,7 @@ and investigation surfaces for enabled design-partner deployments.
|
|
|
24
24
|
| Writeback | Guarded one-row update or app-owned executor | Cloud-linked jobs with local execution; managed production orchestration is future work |
|
|
25
25
|
| MCP risk audit | Static local audit | Organization-wide continuous audit is future work |
|
|
26
26
|
| Identity | Local operator boundary | Workspace RBAC where configured; SAML and SCIM are future work |
|
|
27
|
-
| Operations | Customer-operated single node |
|
|
27
|
+
| Operations | Customer-operated single node or bounded small fleet | Managed fleet remains Cloud work; no enterprise SLA in the current beta |
|
|
28
28
|
|
|
29
29
|
## What Stays Local
|
|
30
30
|
|
package/docs/production.md
CHANGED
|
@@ -14,10 +14,36 @@ MCP agent
|
|
|
14
14
|
-> receipt/replay
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
Use this only for bounded database workflows
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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,
|
|
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
|
|
@@ -213,7 +244,8 @@ Mirror mode config:
|
|
|
213
244
|
"mode": "mirror",
|
|
214
245
|
"url_env": "SYNAPSOR_LEDGER_DATABASE_URL",
|
|
215
246
|
"schema": "synapsor_runner",
|
|
216
|
-
"lock_timeout_ms": 10000
|
|
247
|
+
"lock_timeout_ms": 10000,
|
|
248
|
+
"max_entries": 10000
|
|
217
249
|
}
|
|
218
250
|
}
|
|
219
251
|
}
|
|
@@ -241,7 +273,8 @@ synapsor-runner apply --all-approved --yes \
|
|
|
241
273
|
|
|
242
274
|
When `storage.shared_postgres.mode` is `mirror`, `doctor` checks that the
|
|
243
275
|
ledger URL environment variable is present and that `ledger_entries`,
|
|
244
|
-
`proposal_locks`, and `
|
|
276
|
+
`proposal_locks`, `worker_leases`, and `rate_limit_buckets` exist in the
|
|
277
|
+
configured schema. It reports
|
|
245
278
|
environment variable names and table readiness only; it does not print database
|
|
246
279
|
URLs or initialize the schema.
|
|
247
280
|
|
|
@@ -286,6 +319,13 @@ long-running `worker run --yes` repeats bounded drain cycles under that lock
|
|
|
286
319
|
and sleeps between idle polls, so multiple workers can share one Postgres ledger
|
|
287
320
|
without holding the lock while idle.
|
|
288
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
|
+
|
|
289
329
|
For unattended policy-approved queues, declare reviewed aggregate `LIMIT`
|
|
290
330
|
clauses first, then use the explicit batch command:
|
|
291
331
|
|
|
@@ -426,6 +466,8 @@ synapsor-runner config validate --config synapsor.runner.json
|
|
|
426
466
|
synapsor-runner doctor --config synapsor.runner.json --report --redact --output synapsor-doctor.md
|
|
427
467
|
synapsor-runner doctor --config synapsor.runner.json --check-writeback
|
|
428
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
|
|
429
471
|
```
|
|
430
472
|
|
|
431
473
|
Doctor reports should be redacted by default before sharing. They must not
|
package/docs/release-notes.md
CHANGED
|
@@ -10,7 +10,25 @@ 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
|
-
##
|
|
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`.
|
|
14
32
|
|
|
15
33
|
## 1.0.0
|
|
16
34
|
|
package/docs/release-policy.md
CHANGED
|
@@ -85,6 +85,27 @@ versioning. Breaking changes require a new major version, except for security
|
|
|
85
85
|
fixes that close a vulnerability while preserving the safest possible
|
|
86
86
|
compatibility path.
|
|
87
87
|
|
|
88
|
+
## 1.1 Fleet Gate
|
|
89
|
+
|
|
90
|
+
Do not publish `1.1.0` until all 1.0 gates remain green and the local synthetic
|
|
91
|
+
fleet verifier proves:
|
|
92
|
+
|
|
93
|
+
- claim/context contradictions fail before serving;
|
|
94
|
+
- two claim-bound Runners preserve tenant isolation and one active proposal;
|
|
95
|
+
- shared fixed-window rate limits reject with `retry_after_ms`;
|
|
96
|
+
- distinct verified reviewers satisfy canonical quorum and apply remains
|
|
97
|
+
blocked before `N/N`;
|
|
98
|
+
- Postgres/MySQL pool acquisition and queue limits fail fast;
|
|
99
|
+
- worker termination before write and after commit recovers without a duplicate
|
|
100
|
+
effect;
|
|
101
|
+
- backup digest, clean restore, and archive-before-retention preserve active
|
|
102
|
+
records;
|
|
103
|
+
- `/healthz`, `/readyz`, and separately authorized `/metrics` expose no secrets
|
|
104
|
+
or business object/principal labels.
|
|
105
|
+
|
|
106
|
+
Run `corepack pnpm test:fleet`. Only homogeneous 1.1 fleet operation is part of
|
|
107
|
+
this gate; mixed-minor operation must be tested before it is claimed.
|
|
108
|
+
|
|
88
109
|
## Stable Compatibility Promise
|
|
89
110
|
|
|
90
111
|
Starting with `1.0.0`, Synapsor Runner keeps these public surfaces compatible
|
|
@@ -35,6 +35,9 @@ Unknown keys fail when `strict` is true (the default).
|
|
|
35
35
|
| `policies` | No | Embedded reviewed policies; contract policies merge into the same catalog. |
|
|
36
36
|
| `approvals` | No | Local approval overrides. |
|
|
37
37
|
| `operator_identity` | No | Verified operator identity and apply-role wiring for approve/reject/apply. |
|
|
38
|
+
| `session_auth` | HTTP claims | HS256 development or asymmetric RS256/ES256 session-token verification. |
|
|
39
|
+
| `rate_limits` | No | Operational fixed-window limits; fleet-wide only with shared `runtime_store`. |
|
|
40
|
+
| `metrics` | No | Separately authorized scrapeable HTTP metrics. Disabled by default. |
|
|
38
41
|
| `executors` | No | App-owned writeback wiring. |
|
|
39
42
|
| `cloud` | Cloud mode | Scoped Cloud adapter configuration. |
|
|
40
43
|
|
|
@@ -58,7 +61,8 @@ Unknown keys fail when `strict` is true (the default).
|
|
|
58
61
|
"mode": "mirror",
|
|
59
62
|
"url_env": "SYNAPSOR_LEDGER_DATABASE_URL",
|
|
60
63
|
"schema": "synapsor_runner",
|
|
61
|
-
"lock_timeout_ms": 10000
|
|
64
|
+
"lock_timeout_ms": 10000,
|
|
65
|
+
"max_entries": 10000
|
|
62
66
|
}
|
|
63
67
|
}
|
|
64
68
|
}
|
|
@@ -85,10 +89,17 @@ ledger by restoring into a temporary local store under the Postgres advisory
|
|
|
85
89
|
lock, running the existing mutation, and syncing back. Long-running worker
|
|
86
90
|
processes repeat bounded drain cycles and release the advisory lock while idle.
|
|
87
91
|
|
|
92
|
+
The bridge loads at most `max_entries` ledger records per operation. The default
|
|
93
|
+
is 10,000; valid values are 100 through 100,000. It fails closed with
|
|
94
|
+
`POSTGRES_RUNTIME_STORE_CAPACITY_EXCEEDED` above the bound. Reviewer CLI reads
|
|
95
|
+
and the local UI use the same shared queue. This is a serialized small-fleet
|
|
96
|
+
design, not an unbounded high-throughput primary store.
|
|
97
|
+
|
|
88
98
|
`synapsor-runner doctor --config ./synapsor.runner.json` checks shared Postgres
|
|
89
99
|
wiring when this block is present: the URL env var must be set, and the
|
|
90
|
-
configured schema must already contain `ledger_entries`, `proposal_locks`,
|
|
91
|
-
`worker_leases`. Doctor reports env var names and
|
|
100
|
+
configured schema must already contain `ledger_entries`, `proposal_locks`,
|
|
101
|
+
`worker_leases`, and `rate_limit_buckets`. Doctor reports env var names and
|
|
102
|
+
table readiness only; it does
|
|
92
103
|
not print database URLs or create the schema.
|
|
93
104
|
|
|
94
105
|
## Sources
|
|
@@ -115,6 +126,13 @@ timeout. `ssl` carries adapter-specific reviewed SSL options when used.
|
|
|
115
126
|
|
|
116
127
|
A contract's `SOURCE billing_postgres` must exactly match a `sources` key.
|
|
117
128
|
|
|
129
|
+
Long-running servers reuse native driver pools. Optional `pool` keys are
|
|
130
|
+
`max_connections` (default 10), `connection_timeout_ms` (3000),
|
|
131
|
+
`idle_timeout_ms` (30000), `queue_timeout_ms` (5000), and `queue_limit`
|
|
132
|
+
(default `max(10, max_connections * 4)`). Queue overflow returns
|
|
133
|
+
`SOURCE_POOL_QUEUE_FULL`; acquisition timeout returns `SOURCE_POOL_TIMEOUT`.
|
|
134
|
+
One-shot CLI commands close their pools.
|
|
135
|
+
|
|
118
136
|
## Trusted context
|
|
119
137
|
|
|
120
138
|
```json
|
|
@@ -161,6 +179,35 @@ the active secret first, then the previous secret. Existing MCP sessions remain
|
|
|
161
179
|
bound to the exact token fingerprint, so clients cannot swap tenant/principal
|
|
162
180
|
identity inside an initialized session.
|
|
163
181
|
|
|
182
|
+
For networked deployments prefer asymmetric public-key verification:
|
|
183
|
+
|
|
184
|
+
```json
|
|
185
|
+
{
|
|
186
|
+
"session_auth": {
|
|
187
|
+
"provider": "jwt_asymmetric",
|
|
188
|
+
"algorithms": ["RS256"],
|
|
189
|
+
"jwks_url_env": "SYNAPSOR_SESSION_JWKS_URL",
|
|
190
|
+
"issuer": "https://identity.example",
|
|
191
|
+
"audience": "synapsor-runner",
|
|
192
|
+
"tenant_claim": "tenant_id",
|
|
193
|
+
"principal_claim": "sub",
|
|
194
|
+
"clock_skew_seconds": 30,
|
|
195
|
+
"jwks_cache_seconds": 600,
|
|
196
|
+
"jwks_cooldown_seconds": 30,
|
|
197
|
+
"fetch_timeout_ms": 3000,
|
|
198
|
+
"max_response_bytes": 1048576
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
`jwt_asymmetric` requires an explicit `RS256`/`ES256` allowlist and exactly one
|
|
204
|
+
public-key source: `jwks_url_env`, `public_key_env`, or `public_key_path`.
|
|
205
|
+
JWKS selection uses `kid`; unknown keys get one controlled refresh. Fetches are
|
|
206
|
+
timeout/size bounded and do not follow redirects. Private JWK fields are
|
|
207
|
+
rejected. Every effective named context in an `http_claims` server must bind
|
|
208
|
+
tenant and principal from claims; environment/static contradictions fail with
|
|
209
|
+
`TRUSTED_CONTEXT_PROVIDER_CONFLICT` before serving.
|
|
210
|
+
|
|
164
211
|
## Contracts and embedded capabilities
|
|
165
212
|
|
|
166
213
|
```json
|
|
@@ -215,6 +262,48 @@ from reviewed DSL `LIMIT` clauses, not an unreviewed local override. A tripped
|
|
|
215
262
|
limit falls back to human review and is recorded in the ledger.
|
|
216
263
|
`approvals.disable_auto_approval: true` disables local policy auto-approval
|
|
217
264
|
without changing the reviewed contract. Approval never becomes an MCP tool.
|
|
265
|
+
Portable `approval.required_approvals` defaults to `1` and accepts `1..10`.
|
|
266
|
+
Distinct verified subjects fill quorum slots; one subject cannot count twice.
|
|
267
|
+
A rejection is terminal. Policy auto-approval is deferred when quorum is
|
|
268
|
+
greater than one.
|
|
269
|
+
|
|
270
|
+
## Rate limits
|
|
271
|
+
|
|
272
|
+
```json
|
|
273
|
+
{
|
|
274
|
+
"rate_limits": {
|
|
275
|
+
"enabled": true,
|
|
276
|
+
"default": { "requests": 60, "window_seconds": 60 },
|
|
277
|
+
"capabilities": {
|
|
278
|
+
"billing.propose_refund": { "requests": 10, "window_seconds": 60 }
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
Rules are fixed-window deployment controls keyed by trusted tenant plus
|
|
285
|
+
reviewed capability. There is no separate burst allowance: all configured
|
|
286
|
+
requests may arrive immediately, but the next request is rejected until the
|
|
287
|
+
aligned window resets. They are process-local with SQLite and fleet-wide/atomic
|
|
288
|
+
with shared `runtime_store`. `RATE_LIMITED` includes `retry_after_ms` to that
|
|
289
|
+
reset boundary, records a counter, and creates no proposal. Rate limits are
|
|
290
|
+
runtime wiring and never portable contract fields.
|
|
291
|
+
|
|
292
|
+
## HTTP metrics
|
|
293
|
+
|
|
294
|
+
```json
|
|
295
|
+
{
|
|
296
|
+
"metrics": {
|
|
297
|
+
"enabled": true,
|
|
298
|
+
"token_env": "SYNAPSOR_METRICS_TOKEN"
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
`/metrics` is disabled by default. Non-loopback exposure requires a separate
|
|
304
|
+
metrics token; the MCP bearer does not authorize metrics. Labels are bounded to
|
|
305
|
+
trusted tenant, capability, source, engine, and readiness component. Object
|
|
306
|
+
IDs, principals, URLs, tokens, and raw errors are never labels.
|
|
218
307
|
|
|
219
308
|
## Operator identity
|
|
220
309
|
|
|
@@ -257,6 +346,15 @@ subject, timestamp, roles, signature, and integrity hash into the approval
|
|
|
257
346
|
ledger. `apply_roles` independently gates writeback. The local browser UI
|
|
258
347
|
refuses approval/rejection in signed-key mode so it cannot bypass this check.
|
|
259
348
|
|
|
349
|
+
For OIDC-style operator identity, use `provider: "jwt_oidc"` with the same
|
|
350
|
+
asymmetric public-key options as session auth, plus one token source:
|
|
351
|
+
`token_env`, `token_file_env`, or `token_stdin: true`. With stdin, pipe or paste
|
|
352
|
+
one token and close stdin; combine it with `--yes` so confirmation does not
|
|
353
|
+
compete for the stream. Also configure `roles_claim`, `subject_claim`, and an
|
|
354
|
+
`attestation_secret_env` containing at least 32 bytes. Runner persists verified
|
|
355
|
+
subject/roles/issuer/key ID and an attested decision proof, never the bearer
|
|
356
|
+
token. Tokens must not be passed as command-line arguments.
|
|
357
|
+
|
|
260
358
|
## Cloud mode
|
|
261
359
|
|
|
262
360
|
Cloud mode omits local sources/capabilities and requires:
|