@synapsor/runner 1.4.1 → 1.4.121
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 +58 -0
- package/README.md +40 -43
- package/THREAT_MODEL.md +6 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/runner.mjs +28399 -3814
- package/docs/README.md +10 -0
- package/docs/aggregate-reads.md +49 -0
- package/docs/bounded-set-writeback.md +9 -4
- package/docs/compliance-reports.md +42 -0
- package/docs/conformance.md +9 -0
- package/docs/contract-review.md +57 -0
- package/docs/contract-testing.md +47 -0
- package/docs/dsl-reference.md +39 -6
- package/docs/getting-started-own-database.md +8 -1
- package/docs/graduated-trust.md +64 -0
- package/docs/limitations.md +10 -0
- package/docs/production.md +10 -0
- package/docs/release-notes.md +53 -0
- package/docs/runner-config-reference.md +16 -0
- package/docs/security-boundary.md +13 -0
- package/docs/troubleshooting-first-run.md +20 -0
- package/examples/runner-fleet/seed/postgres.sql +1 -0
- package/examples/support-plan-credit/synapsor.contract-tests.json +53 -0
- package/fixtures/dsl/aggregate-read.synapsor.sql +21 -0
- package/fixtures/dsl/bounded-set-multi-term.synapsor.sql +30 -0
- package/package.json +4 -1
- package/schemas/synapsor.contract-tests.schema.json +44 -0
- package/schemas/synapsor.runner.schema.json +92 -4
package/docs/README.md
CHANGED
|
@@ -70,6 +70,12 @@ no-database demo, wire your database, then read deeper concepts.
|
|
|
70
70
|
- [Recipes](recipes.md): starter business-capability templates.
|
|
71
71
|
- [JSON Schema](../schemas/synapsor.runner.schema.json): editor validation for
|
|
72
72
|
`synapsor.runner.json`.
|
|
73
|
+
- [Contract Review](contract-review.md): LSP setup, plain-language explanation,
|
|
74
|
+
and deterministic lint/SARIF output.
|
|
75
|
+
- [Contract Testing](contract-testing.md): adopter-owned static and disposable
|
|
76
|
+
PostgreSQL/MySQL allow/deny/redaction assertions.
|
|
77
|
+
- [Bounded Aggregate Reads](aggregate-reads.md): fixed scalar count/sum/avg,
|
|
78
|
+
tenant scope, suppression, and no-row evidence.
|
|
73
79
|
|
|
74
80
|
## 06 Serve MCP
|
|
75
81
|
|
|
@@ -113,6 +119,10 @@ no-database demo, wire your database, then read deeper concepts.
|
|
|
113
119
|
and lifecycle inspection.
|
|
114
120
|
- `examples/mysql-refund-agent/`: MySQL order/refund review example using the
|
|
115
121
|
same proposal, approval, guarded writeback, and replay loop.
|
|
122
|
+
- [Scoped Ledger Reports](compliance-reports.md): object/principal JSON,
|
|
123
|
+
Markdown, and PDF exports with digest/signature verification.
|
|
124
|
+
- [Graduated Trust](graduated-trust.md): off-by-default operator
|
|
125
|
+
recommendations that never auto-activate a policy.
|
|
116
126
|
|
|
117
127
|
## 09 App-Owned Handlers
|
|
118
128
|
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Bounded Aggregate Reads
|
|
2
|
+
|
|
3
|
+
An `aggregate_read` capability returns one reviewed scalar rather than source
|
|
4
|
+
rows. It is intended for questions such as a tenant-scoped overdue balance
|
|
5
|
+
total where exposing individual records would be unnecessary.
|
|
6
|
+
|
|
7
|
+
```sql
|
|
8
|
+
CREATE CAPABILITY billing.overdue_balance_total
|
|
9
|
+
DESCRIPTION 'Return the reviewed overdue balance total for the trusted tenant.'
|
|
10
|
+
USING CONTEXT local_operator
|
|
11
|
+
SOURCE billing_postgres
|
|
12
|
+
ON public.invoices
|
|
13
|
+
PRIMARY KEY id
|
|
14
|
+
TENANT KEY tenant_id
|
|
15
|
+
AGGREGATE READ SUM balance_cents
|
|
16
|
+
SELECT WHERE status = 'overdue'
|
|
17
|
+
MIN GROUP SIZE 5
|
|
18
|
+
REQUIRE EVIDENCE
|
|
19
|
+
END
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Compile the packaged example with:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
synapsor-runner dsl compile ./fixtures/dsl/aggregate-read.synapsor.sql \
|
|
26
|
+
--out ./synapsor.contract.json --strict
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
A permitted call returns one aggregate scalar; an undersized group returns a
|
|
30
|
+
stable suppressed result. Neither result contains source rows or member IDs.
|
|
31
|
+
|
|
32
|
+
Supported operations are `COUNT ROWS`, `COUNT NON NULL column`, `SUM column`,
|
|
33
|
+
and `AVG column`. The source, table/view, tenant key, function, column, optional
|
|
34
|
+
equality selection, and minimum group size are contract-authored. The first
|
|
35
|
+
release permits no model arguments, dynamic columns, joins, grouping, arbitrary
|
|
36
|
+
expressions, or model-controlled predicates.
|
|
37
|
+
|
|
38
|
+
When fewer records match than `MIN GROUP SIZE`, the stable result is suppressed
|
|
39
|
+
and contains no aggregate value or member identity. Allowed results contain one
|
|
40
|
+
scalar plus evidence/query-audit handles. Evidence records the contract digest,
|
|
41
|
+
trusted scope reference, reviewed operation, fixed predicate summary, and
|
|
42
|
+
suppression state; it never stores member rows or IDs.
|
|
43
|
+
|
|
44
|
+
PostgreSQL and MySQL execution is parameterized and uses the configured
|
|
45
|
+
statement timeout. A dependency outage or statement timeout returns a safe,
|
|
46
|
+
retryable unavailable result without exposing a driver error. Minimum-group
|
|
47
|
+
suppression reduces single-record inference; it does not solve every statistical
|
|
48
|
+
inference risk. Review the underlying view, database role, and aggregation
|
|
49
|
+
policy as well.
|
|
@@ -129,20 +129,25 @@ CREATE CAPABILITY tickets.close_overdue
|
|
|
129
129
|
CONFLICT GUARD version
|
|
130
130
|
LOOKUP reason BY id
|
|
131
131
|
ARG reason STRING REQUIRED MAX LENGTH 100
|
|
132
|
-
ALLOW READ id, tenant_id,
|
|
132
|
+
ALLOW READ id, tenant_id, risk_level, case_status, cost_cents, version
|
|
133
133
|
REQUIRE EVIDENCE
|
|
134
134
|
PROPOSE ACTION close_overdue UPDATE SET
|
|
135
|
-
SELECT WHERE
|
|
135
|
+
SELECT WHERE risk_level = 'high' AND case_status = 'active'
|
|
136
136
|
MAX ROWS 10
|
|
137
137
|
MAX TOTAL cost_cents BEFORE 50000
|
|
138
|
-
ALLOW WRITE
|
|
139
|
-
PATCH
|
|
138
|
+
ALLOW WRITE case_status
|
|
139
|
+
PATCH case_status = 'closed'
|
|
140
140
|
ADVANCE VERSION version USING INTEGER INCREMENT
|
|
141
141
|
APPROVAL ROLE ops_manager
|
|
142
142
|
WRITEBACK DIRECT SQL
|
|
143
143
|
END
|
|
144
144
|
```
|
|
145
145
|
|
|
146
|
+
Each `SELECT WHERE` term is a reviewer-fixed literal equality, and every term
|
|
147
|
+
must match. Up to eight terms may be joined by `AND`; quoted `AND` text remains
|
|
148
|
+
part of the value. `OR`, parentheses, inequalities, ranges, and free-form or
|
|
149
|
+
model-authored predicates are not supported.
|
|
150
|
+
|
|
146
151
|
Compile the contract and create `synapsor.runner.json`:
|
|
147
152
|
|
|
148
153
|
```bash
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Export Scoped Ledger Reports
|
|
2
|
+
|
|
3
|
+
Runner can export a deterministic chronology for one business object or one
|
|
4
|
+
principal inside an explicit tenant scope:
|
|
5
|
+
|
|
6
|
+
```bash
|
|
7
|
+
synapsor-runner report --object invoice:INV-3001 --tenant tenant_acme \
|
|
8
|
+
--store ./.synapsor/local.db --format markdown --out ./invoice-report.md
|
|
9
|
+
|
|
10
|
+
synapsor-runner report --principal support.operator --tenant tenant_acme \
|
|
11
|
+
--store ./.synapsor/local.db --format pdf --out ./operator-report.pdf
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Runner prints the output path and canonical `sha256:...` integrity digest. A
|
|
15
|
+
successful verification prints `PASS`, `REPORT_DIGEST_VERIFIED`, or
|
|
16
|
+
`REPORT_SIGNATURE_VERIFIED` when a public key is supplied.
|
|
17
|
+
|
|
18
|
+
For `storage.shared_postgres.mode = "runtime_store"`, include `--config
|
|
19
|
+
./synapsor.runner.json`; Runner reads through a bounded local bridge to the same
|
|
20
|
+
shared ledger.
|
|
21
|
+
|
|
22
|
+
Reports include scoped proposal, query-audit, approval/rejection, writeback,
|
|
23
|
+
receipt, replay, compensation, and graduated-trust decision metadata when those
|
|
24
|
+
records exist. Evidence rows are never exported. Kept-out values, credentials,
|
|
25
|
+
keys, raw driver errors, and database URLs are excluded.
|
|
26
|
+
|
|
27
|
+
JSON, Markdown, and PDF reports carry a canonical manifest digest. Optional
|
|
28
|
+
operator signing binds the export to the existing key model:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
synapsor-runner report --object invoice:INV-3001 --tenant tenant_acme \
|
|
32
|
+
--store ./.synapsor/local.db --format json --out ./invoice-report.json \
|
|
33
|
+
--signing-key ./operator-private.pem --key-id review-key-1
|
|
34
|
+
|
|
35
|
+
synapsor-runner report verify ./invoice-report.json \
|
|
36
|
+
--public-key ./operator-public.pem
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Verification detects content, ordering, digest, and signature tampering. A
|
|
40
|
+
verified export is tamper-evident; it does not make local SQLite immutable,
|
|
41
|
+
append-only compliance storage. Protect report files and signing keys with the
|
|
42
|
+
same care as the ledger.
|
package/docs/conformance.md
CHANGED
|
@@ -28,6 +28,7 @@ Current fixture groups:
|
|
|
28
28
|
- `manual-approval`
|
|
29
29
|
- `auto-approval`
|
|
30
30
|
- `aggregate-policy-limits`
|
|
31
|
+
- `aggregate-read`
|
|
31
32
|
- `numeric-bounds`
|
|
32
33
|
- `bounded-set-threats`
|
|
33
34
|
- `reversible-change-sets`
|
|
@@ -42,6 +43,12 @@ selection, count/value caps, frozen-version drift checks, atomic rollback,
|
|
|
42
43
|
exact receipts, hard-delete side-effect refusal, and human approval. Adapter
|
|
43
44
|
tests and `corepack pnpm test:bounded-set` complete the live PostgreSQL/MySQL
|
|
44
45
|
matrix.
|
|
46
|
+
The aggregate-read fixture proves a reviewer-fixed scalar operation, trusted
|
|
47
|
+
tenant scope, fixed equality selection, minimum-group suppression, and an
|
|
48
|
+
evidence/query-audit surface containing no member rows or identities. The live
|
|
49
|
+
`corepack pnpm test:aggregate-read` gate runs COUNT/SUM/AVG, suppression,
|
|
50
|
+
timeout, and dependency classification against disposable PostgreSQL and
|
|
51
|
+
MySQL.
|
|
45
52
|
The reversible-change-set fixture proves that undo is a new reviewed
|
|
46
53
|
compensation proposal, not rollback: apply-time receipts capture only
|
|
47
54
|
allowlisted inverse data, compensation uses fresh guards and exact members,
|
|
@@ -72,6 +79,8 @@ Run:
|
|
|
72
79
|
|
|
73
80
|
```bash
|
|
74
81
|
corepack pnpm --filter @synapsor-runner/mcp-server test
|
|
82
|
+
corepack pnpm test:contract-conformance
|
|
83
|
+
corepack pnpm test:aggregate-read
|
|
75
84
|
```
|
|
76
85
|
|
|
77
86
|
The spec package also validates every conformance contract:
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Review Contracts Before Serving Them
|
|
2
|
+
|
|
3
|
+
Runner uses the same DSL parser and canonical Spec validator for compilation,
|
|
4
|
+
editor diagnostics, explanation, and lint. These tools reduce authoring errors;
|
|
5
|
+
they do not replace a human review of database permissions, visible fields,
|
|
6
|
+
tenant binding, or business policy.
|
|
7
|
+
|
|
8
|
+
## Explain The Boundary
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
synapsor-runner contract explain ./contract.synapsor.sql --format markdown
|
|
12
|
+
synapsor-runner contract explain ./synapsor.contract.json --format json
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
The explanation lists trusted context bindings, model-facing arguments, fixed
|
|
16
|
+
targets and selections, visible and kept-out fields, evidence requirements,
|
|
17
|
+
proposal/writeback controls, approval, bounds, reversibility, and unresolved
|
|
18
|
+
runtime dependencies. It is derived from normalized canonical contract JSON.
|
|
19
|
+
It never reads environment values or prints database URLs, tokens, keys, or
|
|
20
|
+
evidence rows.
|
|
21
|
+
|
|
22
|
+
## Lint In CI
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
synapsor-runner contract lint ./contract.synapsor.sql --strict
|
|
26
|
+
synapsor-runner contract lint ./synapsor.contract.json \
|
|
27
|
+
--config ./synapsor.runner.json --format sarif --out ./contract-lint.sarif
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
`--strict` is equivalent to `--fail-on warning`; the default fails on errors.
|
|
31
|
+
Lint rule IDs, ordering, severity, and source ranges are deterministic. Rules
|
|
32
|
+
cover objective review gaps such as missing descriptions/evidence, unbounded
|
|
33
|
+
strings, unresolved wiring, irreversible operations, and policy/writeback
|
|
34
|
+
contradictions. Lint does not claim to discover every sensitive column.
|
|
35
|
+
|
|
36
|
+
Expected successful output ends with:
|
|
37
|
+
|
|
38
|
+
```text
|
|
39
|
+
Summary: 0 error / 0 warning / N info
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Language Server
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
synapsor-runner language-server --stdio
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The stdio LSP supports `.synapsor.sql` and legacy `.synapsor` documents. It
|
|
49
|
+
publishes parser/validator diagnostics and provides context-aware completion,
|
|
50
|
+
hover, and formatting. Configure a generic LSP client to launch the command
|
|
51
|
+
above with the workspace as its working directory. For VS Code, use any stdio
|
|
52
|
+
language-client extension that can associate both filename patterns with that
|
|
53
|
+
command. Generic SQL highlighting remains useful for `.synapsor.sql`; the LSP
|
|
54
|
+
adds Synapsor-specific semantics.
|
|
55
|
+
|
|
56
|
+
The server never suggests raw SQL, model-authored predicates, approval tools,
|
|
57
|
+
or clauses that are illegal for the current capability kind.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Test A Contract Boundary
|
|
2
|
+
|
|
3
|
+
Adopter-owned contract tests exercise reviewed allow/deny behavior without an
|
|
4
|
+
LLM. The public manifest schema is
|
|
5
|
+
[`schemas/synapsor.contract-tests.schema.json`](../schemas/synapsor.contract-tests.schema.json).
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
synapsor-runner contract test \
|
|
9
|
+
--contract ./synapsor.contract.json \
|
|
10
|
+
--tests ./synapsor.contract-tests.json \
|
|
11
|
+
--config ./synapsor.runner.json
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Static mode checks tool exposure, operator-only boundaries, argument limits,
|
|
15
|
+
transition guards, bounded-set caps, and other assertions that do not require a
|
|
16
|
+
database. Add `--live` to call the actual MCP runtime for scoped reads,
|
|
17
|
+
proposals, evidence/replay redaction, and source-unchanged checks.
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
synapsor-runner contract test \
|
|
21
|
+
--contract ./synapsor.contract.json \
|
|
22
|
+
--tests ./synapsor.contract-tests.json \
|
|
23
|
+
--config ./synapsor.runner.json \
|
|
24
|
+
--live --format junit --out ./contract-tests.xml
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Live mode accepts local/disposable PostgreSQL and MySQL targets. Runner refuses
|
|
28
|
+
remote hosts by default; `--allow-remote` is an explicit operator override and
|
|
29
|
+
does not grant implicit write permission. Use synthetic fixtures and a
|
|
30
|
+
disposable database. Unknown assertions and unresolved required tests fail
|
|
31
|
+
rather than being skipped.
|
|
32
|
+
|
|
33
|
+
A successful run ends with a stable count such as:
|
|
34
|
+
|
|
35
|
+
```text
|
|
36
|
+
Summary: 6 passed / 0 failed / 6 total
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Supported assertions cover valid scoped tools, cross-tenant denial, kept-out
|
|
40
|
+
fields, argument constraints, transition guards, set caps, unchanged source
|
|
41
|
+
state before approval, and the absence of model-facing approval/writeback.
|
|
42
|
+
Trusted tenant and principal values belong in test setup, not tool arguments.
|
|
43
|
+
|
|
44
|
+
The flagship example includes a working manifest at
|
|
45
|
+
[`examples/support-plan-credit/synapsor.contract-tests.json`](../examples/support-plan-credit/synapsor.contract-tests.json).
|
|
46
|
+
Contract tests prove the declared cases, not every possible threat or database
|
|
47
|
+
permission error.
|
package/docs/dsl-reference.md
CHANGED
|
@@ -71,6 +71,7 @@ END
|
|
|
71
71
|
ARG invoice_id STRING REQUIRED MAX LENGTH 128 DESCRIPTION 'Invoice id.'
|
|
72
72
|
ARG amount_cents NUMBER REQUIRED MIN 1 MAX 2500 DESCRIPTION 'Amount in cents.'
|
|
73
73
|
ARG confirmed BOOLEAN REQUIRED
|
|
74
|
+
ARG risk_level STRING ENUM('low', 'medium', 'high') REQUIRED
|
|
74
75
|
```
|
|
75
76
|
|
|
76
77
|
Argument types are `STRING`/`TEXT`, `NUMBER`, and `BOOLEAN`/`BOOL`.
|
|
@@ -80,12 +81,41 @@ Argument types are `STRING`/`TEXT`, `NUMBER`, and `BOOLEAN`/`BOOL`.
|
|
|
80
81
|
- `MIN n` and `MAX n` are numeric bounds for `NUMBER`.
|
|
81
82
|
- `MAX LENGTH n` bounds `STRING`/`TEXT`. Legacy text `MAX n` remains accepted.
|
|
82
83
|
- `LOOKUP arg BY column` binds one argument to the target row lookup.
|
|
84
|
+
- `ENUM(value, ...)` restricts an argument to reviewed string, numeric, or
|
|
85
|
+
boolean values of the declared type. Enums contain 1 through 64 unique,
|
|
86
|
+
non-null values and preserve declared order.
|
|
83
87
|
|
|
84
88
|
In spec 0.1, lookup is primary-key-only. The `BY` column must equal the declared
|
|
85
89
|
`PRIMARY KEY`. A different column fails with `LOOKUP_COLUMN_UNSUPPORTED`; Runner
|
|
86
90
|
never silently rewrites it. List/filter queries require a reviewed view or a
|
|
87
91
|
different capability design.
|
|
88
92
|
|
|
93
|
+
## Aggregate read
|
|
94
|
+
|
|
95
|
+
An aggregate capability returns one scalar and no source rows:
|
|
96
|
+
|
|
97
|
+
```sql
|
|
98
|
+
CREATE CAPABILITY billing.overdue_balance_total
|
|
99
|
+
DESCRIPTION 'Return overdue balance for the trusted tenant.'
|
|
100
|
+
USING CONTEXT local_operator
|
|
101
|
+
SOURCE billing_postgres
|
|
102
|
+
ON public.invoices
|
|
103
|
+
PRIMARY KEY id
|
|
104
|
+
TENANT KEY tenant_id
|
|
105
|
+
AGGREGATE READ SUM balance_cents
|
|
106
|
+
SELECT WHERE status = 'overdue'
|
|
107
|
+
MIN GROUP SIZE 5
|
|
108
|
+
REQUIRE EVIDENCE
|
|
109
|
+
END
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Use `COUNT ROWS`, `COUNT NON NULL column`, `SUM column`, or `AVG column`.
|
|
113
|
+
`SELECT WHERE` is the same contract-fixed equality AST used by reviewed set
|
|
114
|
+
operations. `MIN GROUP SIZE` is mandatory and must be 2 through 1,000,000.
|
|
115
|
+
Aggregate reads cannot declare model arguments, lookup, visible row fields,
|
|
116
|
+
proposal clauses, joins, grouping, or arbitrary expressions. See [Bounded
|
|
117
|
+
Aggregate Reads](aggregate-reads.md).
|
|
118
|
+
|
|
89
119
|
## Read surface and evidence
|
|
90
120
|
|
|
91
121
|
```sql
|
|
@@ -162,7 +192,7 @@ bounds, exact version guards, and human/operator approval:
|
|
|
162
192
|
|
|
163
193
|
```sql
|
|
164
194
|
PROPOSE ACTION close_overdue UPDATE SET
|
|
165
|
-
SELECT WHERE
|
|
195
|
+
SELECT WHERE risk_level = 'high' AND case_status = 'active'
|
|
166
196
|
MAX ROWS 10
|
|
167
197
|
MAX TOTAL balance_cents BEFORE 50000
|
|
168
198
|
ALLOW WRITE status
|
|
@@ -172,11 +202,14 @@ bounds, exact version guards, and human/operator approval:
|
|
|
172
202
|
WRITEBACK DIRECT SQL
|
|
173
203
|
```
|
|
174
204
|
|
|
175
|
-
`SELECT WHERE` accepts one
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
205
|
+
`SELECT WHERE` accepts one through eight literal equality terms joined by
|
|
206
|
+
`AND`. The separator is recognized only outside quoted literals, so
|
|
207
|
+
`description = 'salt AND pepper'` remains one term. `OR`, parentheses,
|
|
208
|
+
inequalities, ranges, trailing expressions, and free-form or model-authored
|
|
209
|
+
predicates are rejected during compilation. Runner reads `MAX ROWS + 1` and
|
|
210
|
+
rejects overflow rather than truncating. `MAX TOTAL column
|
|
211
|
+
BEFORE|AFTER|ABSOLUTE DELTA maximum` is a reviewer-visible aggregate value
|
|
212
|
+
bound.
|
|
180
213
|
|
|
181
214
|
Batch INSERT takes a complete typed item array:
|
|
182
215
|
|
|
@@ -368,7 +368,14 @@ npx -y -p @synapsor/runner synapsor-runner smoke call --config ./synapsor.runner
|
|
|
368
368
|
|
|
369
369
|
`smoke call` uses the same runtime as the MCP server. It records evidence and
|
|
370
370
|
query audit for read tools, or creates a proposal for proposal tools, then
|
|
371
|
-
prints the commands to inspect evidence/proposals/replay
|
|
371
|
+
prints the commands to inspect evidence/proposals/replay. With the default
|
|
372
|
+
storage topology those records are in local SQLite. With
|
|
373
|
+
`storage.shared_postgres.mode = "runtime_store"`, Runner `1.4.12` and later
|
|
374
|
+
write them to the authoritative shared Postgres ledger and include `--config`
|
|
375
|
+
in follow-up commands. The supplied `--store` path is compatibility plumbing
|
|
376
|
+
for those CLI commands; it does not receive an orphan proposal copy. If the
|
|
377
|
+
shared ledger is unavailable, `smoke call` fails safely and does not fall back
|
|
378
|
+
to SQLite.
|
|
372
379
|
|
|
373
380
|
The snippets contain the local command and args. They must not contain database
|
|
374
381
|
URLs, passwords, approval tools, commit tools, or write credentials.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Graduated Trust Recommendations
|
|
2
|
+
|
|
3
|
+
Graduated trust is an opt-in operator workflow that evaluates scoped ledger
|
|
4
|
+
history and recommends a bounded policy threshold change. It is disabled by
|
|
5
|
+
default. It never auto-approves itself, changes the active contract, pushes a
|
|
6
|
+
contract, or activates a registry version.
|
|
7
|
+
|
|
8
|
+
```json
|
|
9
|
+
{
|
|
10
|
+
"graduated_trust": {
|
|
11
|
+
"enabled": true,
|
|
12
|
+
"kill_switch": false,
|
|
13
|
+
"criteria": [{
|
|
14
|
+
"capability": "support.propose_plan_credit",
|
|
15
|
+
"policy": "small_credit",
|
|
16
|
+
"field": "plan_credit_cents",
|
|
17
|
+
"minimum_human_reviews": 20,
|
|
18
|
+
"window_days": 30,
|
|
19
|
+
"maximum_rejection_rate": 0.05,
|
|
20
|
+
"maximum_conflict_rate": 0.01,
|
|
21
|
+
"maximum_failure_rate": 0.01,
|
|
22
|
+
"maximum_revert_rate": 0.01,
|
|
23
|
+
"maximum_threshold_increase": 500,
|
|
24
|
+
"absolute_ceiling": 5000
|
|
25
|
+
}]
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Evaluate human-reviewed outcomes for one trusted tenant/capability/policy:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
synapsor-runner policy recommend --contract ./synapsor.contract.json \
|
|
34
|
+
--config ./synapsor.runner.json --tenant tenant_acme \
|
|
35
|
+
--capability support.propose_plan_credit --policy small_credit \
|
|
36
|
+
--store ./.synapsor/local.db
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Eligible history produces `RECOMMENDATION_CREATED` and a pending `ptr_...`
|
|
40
|
+
identifier. Disabled, insufficient, stale, or out-of-policy history returns a
|
|
41
|
+
stable non-success code and creates no recommendation.
|
|
42
|
+
|
|
43
|
+
Auto-approved outcomes do not count as independent human evidence. Missing or
|
|
44
|
+
legacy provenance, mismatched contract digest/version, tampered approvals,
|
|
45
|
+
cross-scope records, insufficient samples, or excessive rejection, conflict,
|
|
46
|
+
failure, or revert rates fail closed. `kill_switch: true` disables evaluation
|
|
47
|
+
even when `enabled` remains true.
|
|
48
|
+
|
|
49
|
+
A recommendation remains operator-only. List it with `policy recommendations
|
|
50
|
+
list`. Approval or rejection requires a cryptographically verified `signed_key`
|
|
51
|
+
or `jwt_oidc` operator identity. Rejection is terminal. Approval permits only
|
|
52
|
+
an explicit export of a separate reviewable contract artifact:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
synapsor-runner policy recommendations export ptr_... --tenant tenant_acme \
|
|
56
|
+
--contract ./synapsor.contract.json \
|
|
57
|
+
--out ./synapsor.contract.recommended.json --actor policy-reviewer --yes \
|
|
58
|
+
--store ./.synapsor/local.db
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Export rechecks the base contract digest, version, and current threshold. The
|
|
62
|
+
artifact is not activated. Activation remains an explicit operator or Cloud
|
|
63
|
+
registry action. Recommendation, decision, and export metadata remain in the
|
|
64
|
+
local or shared Postgres runtime ledger and can appear in scoped reports.
|
package/docs/limitations.md
CHANGED
|
@@ -49,6 +49,12 @@ enterprise SLA.
|
|
|
49
49
|
- Static MCP database risk review.
|
|
50
50
|
- Local indexed search for proposals, evidence bundles, query audit, writeback
|
|
51
51
|
receipts, and proposal replay.
|
|
52
|
+
- DSL enum arguments and fixed, tenant-scoped aggregate count/sum/avg tools
|
|
53
|
+
with mandatory minimum-group suppression and no source-row output.
|
|
54
|
+
- Contract LSP, explanation, deterministic lint, adopter-owned contract tests,
|
|
55
|
+
and scoped tamper-evident JSON/Markdown/PDF ledger reports.
|
|
56
|
+
- Off-by-default graduated-trust recommendations that require verified operator
|
|
57
|
+
review and explicit artifact export without activation.
|
|
52
58
|
|
|
53
59
|
## Runtime Contract
|
|
54
60
|
|
|
@@ -81,6 +87,10 @@ truth for the model-facing tools.
|
|
|
81
87
|
- Prompt-injection prevention.
|
|
82
88
|
- Unbounded/high-throughput or multi-region ledger scale.
|
|
83
89
|
- Managed fleet, SLA, compliance certification, or production support guarantee.
|
|
90
|
+
- Arbitrary aggregate expressions, joins, grouping, dynamic columns,
|
|
91
|
+
model-controlled aggregate predicates, or a statistical privacy guarantee.
|
|
92
|
+
- Automatic policy widening or activation from graduated-trust metrics.
|
|
93
|
+
- Immutable/WORM compliance storage from the local report exporter.
|
|
84
94
|
|
|
85
95
|
## Important External Database Semantics
|
|
86
96
|
|
package/docs/production.md
CHANGED
|
@@ -340,6 +340,16 @@ from `url_env`, auto-runs the shared-ledger migration, and serializes runtime
|
|
|
340
340
|
mutations with a transaction-scoped advisory lock. The MCP tools still expose no
|
|
341
341
|
database URLs or write credentials to the model.
|
|
342
342
|
|
|
343
|
+
`smoke call` uses the same runtime-store resolver as MCP serving. Its evidence,
|
|
344
|
+
query audit, proposal, events, and replay records therefore land directly in
|
|
345
|
+
the shared Postgres ledger and are immediately visible to another Runner using
|
|
346
|
+
the same config. `--store` remains accepted so the printed follow-up CLI
|
|
347
|
+
commands have a compatibility/bridge path, but that SQLite path is not an
|
|
348
|
+
authoritative copy and normally is not created by the smoke call. Shared-ledger
|
|
349
|
+
connection failure returns the safe availability error and a nonzero exit; it
|
|
350
|
+
never causes a local fallback. This consistency fix is present in Runner
|
|
351
|
+
`1.4.12` and later.
|
|
352
|
+
|
|
343
353
|
`runtime_store` covers MCP serving, CLI approval/apply, and supervised worker
|
|
344
354
|
runs. For CLI mutations, Runner restores the shared ledger into a temporary
|
|
345
355
|
local store while holding the Postgres advisory lock, runs the existing local
|
package/docs/release-notes.md
CHANGED
|
@@ -10,6 +10,59 @@ 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
|
+
## 1.4.121 (prepared, not published)
|
|
14
|
+
|
|
15
|
+
### Contract trust surface and bounded-set parser correctness
|
|
16
|
+
|
|
17
|
+
- Fixes BUG-018, where a documented fixed predicate containing multiple
|
|
18
|
+
equality terms joined by `AND` could compile as one string-valued term and
|
|
19
|
+
then fail closed with no matching source rows.
|
|
20
|
+
- The DSL compiler now consumes the complete clause, keeps `AND` inside quoted
|
|
21
|
+
strings, preserves ordered typed literals, and rejects malformed or
|
|
22
|
+
unsupported expressions before serving or proposal creation.
|
|
23
|
+
- This does not add free-form SQL predicates: only fixed literal equality terms
|
|
24
|
+
joined by `AND` are supported. `OR`, parentheses, inequalities, ranges, and
|
|
25
|
+
model-authored predicates remain unsupported.
|
|
26
|
+
- PostgreSQL and MySQL live verification proves all terms are applied together
|
|
27
|
+
within trusted tenant scope, source rows remain unchanged before approval,
|
|
28
|
+
and guarded apply, receipt/replay, retry, caps, and drift checks remain green.
|
|
29
|
+
- Contract authors gain one parser-backed review path: stdio LSP diagnostics,
|
|
30
|
+
completion, hover, and formatting; plain-language explanation; deterministic
|
|
31
|
+
lint; and adopter-owned static/disposable contract tests.
|
|
32
|
+
- Scoped object/principal reports export redacted JSON, Markdown, or PDF ledger
|
|
33
|
+
metadata with digest/signature verification. They are tamper-evident exports,
|
|
34
|
+
not a claim that local SQLite is immutable compliance storage.
|
|
35
|
+
- DSL enum arguments compile to the canonical enum shape and are enforced by
|
|
36
|
+
every Runner transport. Canonical aggregate reads return one fixed
|
|
37
|
+
tenant-scoped COUNT/SUM/AVG scalar, suppress small groups, and persist no
|
|
38
|
+
member rows or identities in evidence/query audit.
|
|
39
|
+
- Graduated trust remains disabled by default and operator-only. It can create
|
|
40
|
+
and export a verified, bounded policy recommendation artifact, but cannot
|
|
41
|
+
auto-approve, push, or activate it.
|
|
42
|
+
- C++/Cloud validators and exporters preserve the new additive enum/aggregate
|
|
43
|
+
fields for canonical round-trip compatibility.
|
|
44
|
+
|
|
45
|
+
Prepared package versions: `@synapsor/spec@1.4.1`,
|
|
46
|
+
`@synapsor/dsl@1.4.2`, and `@synapsor/runner@1.4.121`.
|
|
47
|
+
|
|
48
|
+
## 1.4.12 (prepared, not published)
|
|
49
|
+
|
|
50
|
+
### Runtime-store smoke-call consistency
|
|
51
|
+
|
|
52
|
+
- Fixes BUG-017, where `smoke call` could put proposal artifacts in the
|
|
53
|
+
requested local SQLite path even though the config selected authoritative
|
|
54
|
+
shared Postgres `runtime_store` mode.
|
|
55
|
+
- Smoke calls now use the same runtime storage resolver as MCP tool calls. A
|
|
56
|
+
second Runner can immediately inspect the proposal, evidence, query audit,
|
|
57
|
+
events, and replay from the shared ledger.
|
|
58
|
+
- Shared-ledger unavailability fails closed with a safe retryable error,
|
|
59
|
+
nonzero exit status, no credential leakage, and no local orphan proposal.
|
|
60
|
+
- Local SQLite and mirror modes retain their existing behavior; no source row
|
|
61
|
+
changes before the normal external approval/apply path.
|
|
62
|
+
|
|
63
|
+
Prepared package version: `@synapsor/runner@1.4.12`.
|
|
64
|
+
`@synapsor/dsl` remains `1.4.1`; `@synapsor/spec` remains `1.4.0`.
|
|
65
|
+
|
|
13
66
|
## 1.4.1 (prepared, not published)
|
|
14
67
|
|
|
15
68
|
### Bounded-set digest compatibility patch
|
|
@@ -38,6 +38,7 @@ Unknown keys fail when `strict` is true (the default).
|
|
|
38
38
|
| `session_auth` | HTTP claims | HS256 development or asymmetric RS256/ES256 session-token verification. |
|
|
39
39
|
| `rate_limits` | No | Operational fixed-window limits; fleet-wide only with shared `runtime_store`. |
|
|
40
40
|
| `metrics` | No | Separately authorized scrapeable HTTP metrics. Disabled by default. |
|
|
41
|
+
| `graduated_trust` | No | Off-by-default, operator-only policy recommendation criteria and kill switch. |
|
|
41
42
|
| `executors` | No | App-owned writeback wiring. |
|
|
42
43
|
| `cloud` | Cloud mode | Scoped Cloud adapter configuration. |
|
|
43
44
|
|
|
@@ -375,6 +376,21 @@ metrics token; the MCP bearer does not authorize metrics. Labels are bounded to
|
|
|
375
376
|
trusted tenant, capability, source, engine, and readiness component. Object
|
|
376
377
|
IDs, principals, URLs, tokens, and raw errors are never labels.
|
|
377
378
|
|
|
379
|
+
## Graduated trust
|
|
380
|
+
|
|
381
|
+
`graduated_trust` is runtime/operator policy, not model-facing authority. It is
|
|
382
|
+
disabled unless `enabled` is exactly `true`; `kill_switch: true` stops all
|
|
383
|
+
evaluation. Each criterion fixes one capability, approval policy, numeric
|
|
384
|
+
field, minimum human-reviewed sample (10..10000), window (1..365 days), maximum
|
|
385
|
+
rejection/conflict/failure/revert rates, maximum threshold increment, and
|
|
386
|
+
absolute ceiling. Optional `workspace_id` and `project_id` further scope stored
|
|
387
|
+
recommendations.
|
|
388
|
+
|
|
389
|
+
Auto-approved outcomes never count as human evidence. Recommendation decisions
|
|
390
|
+
require verified operator identity. Approval only permits exporting a new
|
|
391
|
+
contract artifact bound to the current digest/version; Runner never activates
|
|
392
|
+
it. See [Graduated Trust Recommendations](graduated-trust.md).
|
|
393
|
+
|
|
378
394
|
## Operator identity
|
|
379
395
|
|
|
380
396
|
Local development compatibility uses an explicitly unverified environment
|
|
@@ -40,6 +40,12 @@ The model does not receive:
|
|
|
40
40
|
- commit/writeback tools;
|
|
41
41
|
- trusted tenant or principal authority as ordinary model arguments.
|
|
42
42
|
|
|
43
|
+
Reviewed aggregate tools expose one scalar only. Their function, column,
|
|
44
|
+
tenant key, optional equality selection, and minimum-group threshold are fixed
|
|
45
|
+
in the contract; the model receives no predicate arguments or member rows.
|
|
46
|
+
Suppression reduces single-record inference but does not replace statistical
|
|
47
|
+
privacy review. See [Bounded Aggregate Reads](aggregate-reads.md).
|
|
48
|
+
|
|
43
49
|
Trusted context comes from local configuration, environment bindings, or Cloud
|
|
44
50
|
session context in Cloud mode. Tenant, principal, and authorization scope must
|
|
45
51
|
not be accepted from the model as authority.
|
|
@@ -121,6 +127,13 @@ approve/reject actions. It does not expose raw SQL, database URLs, write
|
|
|
121
127
|
credentials, approval tools, commit tools, or controls that widen reviewed
|
|
122
128
|
tables/columns.
|
|
123
129
|
|
|
130
|
+
Contract lint and tests are review aids rather than a proof of complete
|
|
131
|
+
security. Scoped report exports omit evidence rows and kept-out values and are
|
|
132
|
+
tamper-evident when their digest/signature verifies; local SQLite is not an
|
|
133
|
+
immutable compliance service. Graduated-trust evaluation is operator-only,
|
|
134
|
+
disabled by default, and can recommend/export a separate artifact but cannot
|
|
135
|
+
approve itself or activate policy.
|
|
136
|
+
|
|
124
137
|
Synapsor Runner supports reviewed single-row CRUD and the narrowly bounded set
|
|
125
138
|
path documented above. It does not support arbitrary SQL, DDL, UPSERT,
|
|
126
139
|
model-generated predicates, unbounded sets, or cross-table direct writeback.
|
|
@@ -12,6 +12,26 @@ Use JSON for automation:
|
|
|
12
12
|
npx -y -p @synapsor/runner synapsor-runner doctor --first-run --json
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
+
## Smoke Proposal Missing From Another Runner
|
|
16
|
+
|
|
17
|
+
What happened:
|
|
18
|
+
|
|
19
|
+
`smoke call` returned a proposal id, but `proposals list --config ...` on a
|
|
20
|
+
second Runner cannot find it.
|
|
21
|
+
|
|
22
|
+
Fix:
|
|
23
|
+
|
|
24
|
+
1. Verify `synapsor-runner --version` is `1.4.12` or later.
|
|
25
|
+
2. Confirm both commands use a config whose
|
|
26
|
+
`storage.shared_postgres.mode` is `runtime_store` and whose `url_env` and
|
|
27
|
+
`schema` identify the same ledger.
|
|
28
|
+
3. Run `store shared-postgres status --url-env <ENV> --schema <SCHEMA>`.
|
|
29
|
+
|
|
30
|
+
In `runtime_store` mode, `--store` is not the authoritative ledger. Runner does
|
|
31
|
+
not fall back to that SQLite path when shared Postgres is unavailable. Versions
|
|
32
|
+
before `1.4.12` could orphan smoke-call artifacts locally; recreate that test
|
|
33
|
+
proposal after upgrading.
|
|
34
|
+
|
|
15
35
|
## Docker Missing
|
|
16
36
|
|
|
17
37
|
What happened:
|
|
@@ -64,6 +64,7 @@ INSERT INTO public.invoices (id, tenant_id, status, late_fee_cents, waiver_reaso
|
|
|
64
64
|
('INV-ACME', 'acme', 'overdue', 2500, NULL, '2026-07-12T12:00:00Z'),
|
|
65
65
|
('INV-GLOBEX', 'globex', 'overdue', 3100, NULL, '2026-07-12T12:00:00Z'),
|
|
66
66
|
('INV-RATECO', 'rateco', 'overdue', 900, NULL, '2026-07-12T12:00:00Z'),
|
|
67
|
+
('INV-SMOKE-CALL', 'acme', 'overdue', 2100, NULL, '2026-07-12T12:00:00Z'),
|
|
67
68
|
('INV-BATCH-A', 'acme', 'overdue', 1100, NULL, '2026-07-12T12:00:00Z'),
|
|
68
69
|
('INV-BATCH-B', 'acme', 'overdue', 1300, NULL, '2026-07-12T12:00:00Z'),
|
|
69
70
|
('INV-QUORUM-RACE', 'acme', 'overdue', 1400, NULL, '2026-07-12T12:00:00Z'),
|