@synapsor/runner 1.4.12 → 1.4.122
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 +65 -0
- package/README.md +63 -60
- package/THREAT_MODEL.md +6 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/runner.mjs +29227 -2475
- package/docs/README.md +11 -0
- package/docs/aggregate-reads.md +49 -0
- package/docs/bounded-set-writeback.md +9 -4
- package/docs/capability-authoring.md +43 -1
- package/docs/cloud-cli.md +248 -0
- package/docs/cloud-mode.md +88 -6
- package/docs/cloud-push.md +22 -5
- package/docs/compliance-reports.md +42 -0
- package/docs/conformance.md +15 -0
- package/docs/contract-review.md +57 -0
- package/docs/contract-testing.md +76 -0
- package/docs/dsl-reference.md +50 -6
- package/docs/graduated-trust.md +64 -0
- package/docs/hosted-cloud-linked-verification.md +97 -0
- package/docs/limitations.md +10 -0
- package/docs/oss-vs-cloud.md +13 -6
- package/docs/release-notes.md +65 -0
- package/docs/rfcs/007-trusted-principal-row-scope.md +75 -0
- package/docs/runner-bundles.md +24 -0
- package/docs/runner-config-reference.md +16 -0
- package/docs/running-a-runner-fleet.md +8 -0
- package/docs/security-boundary.md +28 -1
- package/examples/runner-fleet/seed/mysql.sql +5 -1
- package/examples/runner-fleet/seed/postgres.sql +5 -1
- package/examples/support-plan-credit/README.md +8 -6
- 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/fixtures/dsl/principal-row-scope.synapsor.sql +23 -0
- package/fixtures/protocol/MANIFEST.json +10 -10
- package/package.json +4 -1
- package/schemas/change-set.v1.schema.json +14 -0
- package/schemas/change-set.v2.schema.json +14 -0
- package/schemas/change-set.v3.schema.json +2 -0
- package/schemas/compensation-change-set.v1.schema.json +3 -2
- package/schemas/inverse-descriptor.v1.schema.json +2 -0
- package/schemas/synapsor.contract-tests.schema.json +54 -0
- package/schemas/synapsor.runner.schema.json +92 -4
- package/schemas/writeback-job.v1.schema.json +14 -0
- package/schemas/writeback-job.v2.schema.json +14 -0
- package/schemas/writeback-job.v3.schema.json +2 -0
- package/schemas/writeback-job.v4.schema.json +2 -2
|
@@ -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,76 @@
|
|
|
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,
|
|
40
|
+
same-tenant cross-principal denial, kept-out
|
|
41
|
+
fields, argument constraints, transition guards, set caps, unchanged source
|
|
42
|
+
state before approval, and the absence of model-facing approval/writeback.
|
|
43
|
+
Trusted tenant and principal values belong in test setup, not tool arguments.
|
|
44
|
+
|
|
45
|
+
Use `cross_principal_deny` to prove both the allowed and denied sides of one
|
|
46
|
+
row lock. The two contexts must use the same tenant and different principals:
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"id": "case-manager-b-cannot-read-a",
|
|
51
|
+
"kind": "cross_principal_deny",
|
|
52
|
+
"capability": "care.inspect_assigned_patient",
|
|
53
|
+
"args": { "patient_id": "PAT-1001" },
|
|
54
|
+
"trusted_context": {
|
|
55
|
+
"tenant_id": "hospital_a",
|
|
56
|
+
"principal": "case_manager_a",
|
|
57
|
+
"provenance": "http_claims"
|
|
58
|
+
},
|
|
59
|
+
"other_trusted_context": {
|
|
60
|
+
"tenant_id": "hospital_a",
|
|
61
|
+
"principal": "case_manager_b",
|
|
62
|
+
"provenance": "http_claims"
|
|
63
|
+
},
|
|
64
|
+
"expected_code": "NOT_FOUND_IN_TENANT"
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Live execution first proves the owner can read the row, then requires the other
|
|
69
|
+
principal to receive the generic denial and `RESOURCE_NOT_FOUND` for the
|
|
70
|
+
owner's evidence handle. Run the repository's Postgres/MySQL proof with
|
|
71
|
+
`corepack pnpm test:principal-scope`.
|
|
72
|
+
|
|
73
|
+
The flagship example includes a working manifest at
|
|
74
|
+
[`examples/support-plan-credit/synapsor.contract-tests.json`](../examples/support-plan-credit/synapsor.contract-tests.json).
|
|
75
|
+
Contract tests prove the declared cases, not every possible threat or database
|
|
76
|
+
permission error.
|
package/docs/dsl-reference.md
CHANGED
|
@@ -47,6 +47,7 @@ CREATE CAPABILITY billing.inspect_invoice
|
|
|
47
47
|
ON public.invoices
|
|
48
48
|
PRIMARY KEY id
|
|
49
49
|
TENANT KEY tenant_id
|
|
50
|
+
PRINCIPAL SCOPE KEY assigned_to
|
|
50
51
|
CONFLICT GUARD updated_at
|
|
51
52
|
...
|
|
52
53
|
END
|
|
@@ -62,8 +63,18 @@ END
|
|
|
62
63
|
| `ON schema.table` | Required fixed target. Table/schema are never model inputs. |
|
|
63
64
|
| `PRIMARY KEY column` | Fixed single-row target key. Defaults to `id` in DSL 0.1. Declare it explicitly. |
|
|
64
65
|
| `TENANT KEY column` | Required in DSL 0.1. Adds trusted tenant scope to every read/write. |
|
|
66
|
+
| `PRINCIPAL SCOPE KEY column` | Optional tenant-additive row lock. Runner binds this fixed column to the context's required trusted `PRINCIPAL BINDING`; it is never a model argument. |
|
|
65
67
|
| `CONFLICT GUARD column` | Captures the row-version value for exact guarded writeback. Prefer a monotonic version or native-precision timestamp. |
|
|
66
68
|
|
|
69
|
+
`PRINCIPAL SCOPE KEY` means `tenant_key = trusted tenant AND
|
|
70
|
+
principal_scope_key = trusted principal`. It cannot replace tenant scope,
|
|
71
|
+
default to all rows, or be overridden by an argument. The principal binding
|
|
72
|
+
must be required and come from a trusted provider such as `ENVIRONMENT`,
|
|
73
|
+
`HTTP_CLAIM`, `SESSION`, or `CLOUD_SESSION`. For networked multi-user serving,
|
|
74
|
+
use signed HTTP claims. See the complete
|
|
75
|
+
[`principal-row-scope.synapsor.sql`](../fixtures/dsl/principal-row-scope.synapsor.sql)
|
|
76
|
+
example.
|
|
77
|
+
|
|
67
78
|
## Arguments and lookup
|
|
68
79
|
|
|
69
80
|
```sql
|
|
@@ -71,6 +82,7 @@ END
|
|
|
71
82
|
ARG invoice_id STRING REQUIRED MAX LENGTH 128 DESCRIPTION 'Invoice id.'
|
|
72
83
|
ARG amount_cents NUMBER REQUIRED MIN 1 MAX 2500 DESCRIPTION 'Amount in cents.'
|
|
73
84
|
ARG confirmed BOOLEAN REQUIRED
|
|
85
|
+
ARG risk_level STRING ENUM('low', 'medium', 'high') REQUIRED
|
|
74
86
|
```
|
|
75
87
|
|
|
76
88
|
Argument types are `STRING`/`TEXT`, `NUMBER`, and `BOOLEAN`/`BOOL`.
|
|
@@ -80,12 +92,41 @@ Argument types are `STRING`/`TEXT`, `NUMBER`, and `BOOLEAN`/`BOOL`.
|
|
|
80
92
|
- `MIN n` and `MAX n` are numeric bounds for `NUMBER`.
|
|
81
93
|
- `MAX LENGTH n` bounds `STRING`/`TEXT`. Legacy text `MAX n` remains accepted.
|
|
82
94
|
- `LOOKUP arg BY column` binds one argument to the target row lookup.
|
|
95
|
+
- `ENUM(value, ...)` restricts an argument to reviewed string, numeric, or
|
|
96
|
+
boolean values of the declared type. Enums contain 1 through 64 unique,
|
|
97
|
+
non-null values and preserve declared order.
|
|
83
98
|
|
|
84
99
|
In spec 0.1, lookup is primary-key-only. The `BY` column must equal the declared
|
|
85
100
|
`PRIMARY KEY`. A different column fails with `LOOKUP_COLUMN_UNSUPPORTED`; Runner
|
|
86
101
|
never silently rewrites it. List/filter queries require a reviewed view or a
|
|
87
102
|
different capability design.
|
|
88
103
|
|
|
104
|
+
## Aggregate read
|
|
105
|
+
|
|
106
|
+
An aggregate capability returns one scalar and no source rows:
|
|
107
|
+
|
|
108
|
+
```sql
|
|
109
|
+
CREATE CAPABILITY billing.overdue_balance_total
|
|
110
|
+
DESCRIPTION 'Return overdue balance for the trusted tenant.'
|
|
111
|
+
USING CONTEXT local_operator
|
|
112
|
+
SOURCE billing_postgres
|
|
113
|
+
ON public.invoices
|
|
114
|
+
PRIMARY KEY id
|
|
115
|
+
TENANT KEY tenant_id
|
|
116
|
+
AGGREGATE READ SUM balance_cents
|
|
117
|
+
SELECT WHERE status = 'overdue'
|
|
118
|
+
MIN GROUP SIZE 5
|
|
119
|
+
REQUIRE EVIDENCE
|
|
120
|
+
END
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Use `COUNT ROWS`, `COUNT NON NULL column`, `SUM column`, or `AVG column`.
|
|
124
|
+
`SELECT WHERE` is the same contract-fixed equality AST used by reviewed set
|
|
125
|
+
operations. `MIN GROUP SIZE` is mandatory and must be 2 through 1,000,000.
|
|
126
|
+
Aggregate reads cannot declare model arguments, lookup, visible row fields,
|
|
127
|
+
proposal clauses, joins, grouping, or arbitrary expressions. See [Bounded
|
|
128
|
+
Aggregate Reads](aggregate-reads.md).
|
|
129
|
+
|
|
89
130
|
## Read surface and evidence
|
|
90
131
|
|
|
91
132
|
```sql
|
|
@@ -162,7 +203,7 @@ bounds, exact version guards, and human/operator approval:
|
|
|
162
203
|
|
|
163
204
|
```sql
|
|
164
205
|
PROPOSE ACTION close_overdue UPDATE SET
|
|
165
|
-
SELECT WHERE
|
|
206
|
+
SELECT WHERE risk_level = 'high' AND case_status = 'active'
|
|
166
207
|
MAX ROWS 10
|
|
167
208
|
MAX TOTAL balance_cents BEFORE 50000
|
|
168
209
|
ALLOW WRITE status
|
|
@@ -172,11 +213,14 @@ bounds, exact version guards, and human/operator approval:
|
|
|
172
213
|
WRITEBACK DIRECT SQL
|
|
173
214
|
```
|
|
174
215
|
|
|
175
|
-
`SELECT WHERE` accepts one
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
216
|
+
`SELECT WHERE` accepts one through eight literal equality terms joined by
|
|
217
|
+
`AND`. The separator is recognized only outside quoted literals, so
|
|
218
|
+
`description = 'salt AND pepper'` remains one term. `OR`, parentheses,
|
|
219
|
+
inequalities, ranges, trailing expressions, and free-form or model-authored
|
|
220
|
+
predicates are rejected during compilation. Runner reads `MAX ROWS + 1` and
|
|
221
|
+
rejects overflow rather than truncating. `MAX TOTAL column
|
|
222
|
+
BEFORE|AFTER|ABSOLUTE DELTA maximum` is a reviewer-visible aggregate value
|
|
223
|
+
bound.
|
|
180
224
|
|
|
181
225
|
Batch INSERT takes a complete typed item array:
|
|
182
226
|
|
|
@@ -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.
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Hosted Cloud-Linked Verification
|
|
2
|
+
|
|
3
|
+
This is the manual release gate for the complete OSS Runner and single-node
|
|
4
|
+
Synapsor Cloud boundary. It is intentionally opt-in because it creates Cloud
|
|
5
|
+
records and mutates a synthetic source row.
|
|
6
|
+
|
|
7
|
+
The verifier installs packed or published Cloud CLI and Runner packages in a
|
|
8
|
+
clean temporary directory and proves:
|
|
9
|
+
|
|
10
|
+
- public protocol discovery;
|
|
11
|
+
- packed CLI human `whoami`, secure one-time service-key output, and immediate
|
|
12
|
+
service-key revocation;
|
|
13
|
+
- canonical contract push parity between `synapsor contracts push` and
|
|
14
|
+
`synapsor-runner cloud push` with one immutable version identity;
|
|
15
|
+
- source-scoped Runner token creation, rotation, registration idempotency, and
|
|
16
|
+
heartbeat;
|
|
17
|
+
- credential-free Runner bundle download;
|
|
18
|
+
- scoped MCP read and cross-tenant denial;
|
|
19
|
+
- proposal creation without a source write and automatic durable-outbox
|
|
20
|
+
delivery without a manual `cloud sync` command;
|
|
21
|
+
- authenticated Cloud approval and guarded local writeback through the packed
|
|
22
|
+
Runner's public worker CLI;
|
|
23
|
+
- two registered Runner processes competing for one exclusive job lease;
|
|
24
|
+
- duplicate-claim idempotency, rejection, and stale-version conflict;
|
|
25
|
+
- linked Cloud activity integrity and canonical export;
|
|
26
|
+
- reviewed activation and rollback of a risk-increasing contract version; and
|
|
27
|
+
- immediate Runner-token revocation across doctor, registration, claim, and
|
|
28
|
+
result submission.
|
|
29
|
+
|
|
30
|
+
It never accepts production data. Use a disposable project and a synthetic
|
|
31
|
+
Postgres or MySQL database that can be reset after the run.
|
|
32
|
+
|
|
33
|
+
## Prerequisites
|
|
34
|
+
|
|
35
|
+
Build the workspace and pack both packages before a pre-publish check:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
corepack pnpm install
|
|
39
|
+
corepack pnpm build
|
|
40
|
+
corepack pnpm --filter @synapsor/runner pack --pack-destination /tmp
|
|
41
|
+
corepack pnpm --filter @synapsor/cli pack --pack-destination /tmp
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Prepare:
|
|
45
|
+
|
|
46
|
+
- a disposable Cloud project and imported synthetic source;
|
|
47
|
+
- an authenticated human session token obtained through the normal browser/
|
|
48
|
+
device login flow;
|
|
49
|
+
- separate least-privilege read and write source URLs;
|
|
50
|
+
- a canonical contract with one scoped read and one proposal capability; and
|
|
51
|
+
- three independent proposal fixture rows: apply, reject, and stale-conflict.
|
|
52
|
+
|
|
53
|
+
Read tokens and database URLs from a secret prompt or secret manager. Do not
|
|
54
|
+
put them in Git, shell history, command-line arguments, or the Runner bundle.
|
|
55
|
+
|
|
56
|
+
## Run
|
|
57
|
+
|
|
58
|
+
Set the non-secret fixture identifiers and JSON assertions for your synthetic
|
|
59
|
+
database. The exact required variables and their meanings are always available
|
|
60
|
+
without credentials:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
corepack pnpm verify:hosted-cloud-linked -- --help
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Then opt in explicitly and run:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
export SYNAPSOR_HOSTED_E2E=1
|
|
70
|
+
export SYNAPSOR_E2E_DISPOSABLE_PROJECT=1
|
|
71
|
+
export SYNAPSOR_CLOUD_BASE_URL="https://dev-api.synapsor.ai"
|
|
72
|
+
export SYNAPSOR_RUNNER_PACKAGE_SPEC="/tmp/synapsor-runner-<version>.tgz"
|
|
73
|
+
export SYNAPSOR_CLI_PACKAGE_SPEC="/tmp/synapsor-cli-<version>.tgz"
|
|
74
|
+
|
|
75
|
+
corepack pnpm verify:hosted-cloud-linked
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
The command refuses to run unless both opt-in flags are present. HTTPS is
|
|
79
|
+
required unless `SYNAPSOR_E2E_ALLOW_HTTP=1` is explicitly set for a local
|
|
80
|
+
control-plane test. The generated Runner token is revoked in a `finally` block,
|
|
81
|
+
and the temporary directory is removed unless
|
|
82
|
+
`SYNAPSOR_E2E_KEEP_TEMP=1` is set for debugging.
|
|
83
|
+
|
|
84
|
+
## Passing Result
|
|
85
|
+
|
|
86
|
+
A pass prints only a boolean summary with all checks set to `true`. The
|
|
87
|
+
`token_rotated`, `registration_idempotent`, `two_runner_exclusive_claim`,
|
|
88
|
+
`registration_heartbeat`, `proposal_reviewed_metadata`,
|
|
89
|
+
`two_runner_exclusive_claim`, `receipt_replay_linked`, `activity_exported`,
|
|
90
|
+
`contract_governance`, and `revoked_operations_blocked` fields prove those
|
|
91
|
+
additional boundaries explicitly. It does not print bearer tokens, database
|
|
92
|
+
URLs, source rows, or kept-out values. Confirm the synthetic fixture is reset
|
|
93
|
+
after the run before reusing the project.
|
|
94
|
+
|
|
95
|
+
This gate is evidence for the existing single-node design-partner boundary. It
|
|
96
|
+
does not establish multi-region availability, managed Runner hosting, SSO/SCIM,
|
|
97
|
+
legal hold, formal compliance certification, or an enterprise SLA.
|
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/oss-vs-cloud.md
CHANGED
|
@@ -9,9 +9,12 @@ evidence and proposals, keeps approval outside MCP, applies or routes approved
|
|
|
9
9
|
writeback, and records receipts and replay in the default local SQLite ledger
|
|
10
10
|
or an opt-in shared Postgres runtime store.
|
|
11
11
|
|
|
12
|
-
Cloud is the team control plane.
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
Cloud is the team control plane. In the design-partner deployment it stores
|
|
13
|
+
versioned contracts, issues source-scoped Runner identities, produces
|
|
14
|
+
credential-free bundles, receives reviewed local proposals, records human
|
|
15
|
+
decisions, leases approved jobs to compatible local Runners, and links safe
|
|
16
|
+
activity/receipt/replay metadata. The database connection and enforcement
|
|
17
|
+
runtime stay local.
|
|
15
18
|
|
|
16
19
|
| Need | OSS Runner | Synapsor Cloud |
|
|
17
20
|
| --- | --- | --- |
|
|
@@ -19,9 +22,9 @@ and investigation surfaces for enabled design-partner deployments.
|
|
|
19
22
|
| Contract source | Local files reviewed in Git | Shared registry with immutable versions and digests |
|
|
20
23
|
| Trusted context | Local environment/session bindings | Registered bindings plus deployment-specific Cloud session context |
|
|
21
24
|
| Capabilities | Local semantic MCP tools | Registry, version history, and capability inspection |
|
|
22
|
-
| Evidence and replay | Local SQLite ledger by default; optional shared Postgres runtime store |
|
|
23
|
-
| Approval | Local CLI or localhost UI |
|
|
24
|
-
| Writeback | Guarded one-row CRUD, fixed/frozen bounded sets, or app-owned executor |
|
|
25
|
+
| Evidence and replay | Local SQLite ledger by default; optional shared Postgres runtime store | Redacted shared chronology and references; full evidence payload stays local by default |
|
|
26
|
+
| Approval | Local CLI or localhost UI | Human-authenticated shared approval inbox; unavailable to MCP/Runner tokens |
|
|
27
|
+
| Writeback | Guarded one-row CRUD, fixed/frozen bounded sets, or app-owned executor | Durable approval/job/lease coordination; the local Runner rechecks and executes |
|
|
25
28
|
| MCP risk audit | Static local audit | Organization-wide continuous audit is future work |
|
|
26
29
|
| Identity | Local operator boundary | Workspace RBAC where configured; SAML and SCIM are future work |
|
|
27
30
|
| Operations | Customer-operated single node or bounded small fleet | Managed fleet remains Cloud work; no enterprise SLA in the current beta |
|
|
@@ -45,6 +48,10 @@ environment-variable wiring, and MCP client templates.
|
|
|
45
48
|
3. Keep contracts in Git and exercise proposal, approval, writeback, and replay.
|
|
46
49
|
4. Push the validated contract when the team needs a shared registry and review
|
|
47
50
|
surface.
|
|
51
|
+
5. Create a source-scoped Runner token, download a bundle, and verify the
|
|
52
|
+
registration heartbeat.
|
|
53
|
+
6. Sync one staging proposal, approve it in Cloud, and verify the local guarded
|
|
54
|
+
write plus linked receipt/replay chronology.
|
|
48
55
|
|
|
49
56
|
See [Cloud Push](cloud-push.md), [Runner Bundles](runner-bundles.md), and
|
|
50
57
|
[Cloud Mode](cloud-mode.md) for commands and deployment details. See
|
package/docs/release-notes.md
CHANGED
|
@@ -10,6 +10,71 @@ 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.122 (prepared, not published)
|
|
14
|
+
|
|
15
|
+
### Trusted principal scope and Cloud-linked authority
|
|
16
|
+
|
|
17
|
+
- Contracts may bind a reviewed target column to a required trusted principal
|
|
18
|
+
in addition to the existing tenant lock. Runner applies both predicates in
|
|
19
|
+
SQL and never accepts the principal value from model arguments.
|
|
20
|
+
- Same-tenant rows owned by another principal and cross-principal evidence,
|
|
21
|
+
proposal, receipt, and replay handles return the same generic miss as absent
|
|
22
|
+
or cross-tenant resources.
|
|
23
|
+
- PostgreSQL/MySQL live tests cover scoped read/propose/insert/update/delete,
|
|
24
|
+
aggregate and bounded-set operations, conflict/idempotency, compensation,
|
|
25
|
+
signed HTTP sessions, and generic denial behavior.
|
|
26
|
+
- In explicit `cloud_linked` mode, Cloud is authoritative for governance while
|
|
27
|
+
the local/shared Runner store remains the durable operational spool. An
|
|
28
|
+
idempotent outbox synchronizes bounded proposal/activity/result metadata;
|
|
29
|
+
full evidence, source rows, SQL details, replay payloads, and credentials
|
|
30
|
+
remain local.
|
|
31
|
+
- Cloud-linked approval and apply cannot fall back to local operator commands.
|
|
32
|
+
The trusted Runner still verifies the exact local contract, proposal hash,
|
|
33
|
+
tenant/principal guards, bounds, conflict checks, and receipt rules before
|
|
34
|
+
source mutation.
|
|
35
|
+
- A separate `@synapsor/cli@0.1.0-beta.1` package manages Cloud contracts,
|
|
36
|
+
projects, scoped credentials, Runner connections, proposal decisions, and
|
|
37
|
+
audit records. Runner keeps the `synapsor-runner` binary and local boundary.
|
|
38
|
+
|
|
39
|
+
Prepared package versions: `@synapsor/spec@1.4.2`,
|
|
40
|
+
`@synapsor/dsl@1.4.3`, `@synapsor/runner@1.4.122`, and
|
|
41
|
+
`@synapsor/cli@0.1.0-beta.1`.
|
|
42
|
+
|
|
43
|
+
## 1.4.121 (prepared, not published)
|
|
44
|
+
|
|
45
|
+
### Contract trust surface and bounded-set parser correctness
|
|
46
|
+
|
|
47
|
+
- Fixes BUG-018, where a documented fixed predicate containing multiple
|
|
48
|
+
equality terms joined by `AND` could compile as one string-valued term and
|
|
49
|
+
then fail closed with no matching source rows.
|
|
50
|
+
- The DSL compiler now consumes the complete clause, keeps `AND` inside quoted
|
|
51
|
+
strings, preserves ordered typed literals, and rejects malformed or
|
|
52
|
+
unsupported expressions before serving or proposal creation.
|
|
53
|
+
- This does not add free-form SQL predicates: only fixed literal equality terms
|
|
54
|
+
joined by `AND` are supported. `OR`, parentheses, inequalities, ranges, and
|
|
55
|
+
model-authored predicates remain unsupported.
|
|
56
|
+
- PostgreSQL and MySQL live verification proves all terms are applied together
|
|
57
|
+
within trusted tenant scope, source rows remain unchanged before approval,
|
|
58
|
+
and guarded apply, receipt/replay, retry, caps, and drift checks remain green.
|
|
59
|
+
- Contract authors gain one parser-backed review path: stdio LSP diagnostics,
|
|
60
|
+
completion, hover, and formatting; plain-language explanation; deterministic
|
|
61
|
+
lint; and adopter-owned static/disposable contract tests.
|
|
62
|
+
- Scoped object/principal reports export redacted JSON, Markdown, or PDF ledger
|
|
63
|
+
metadata with digest/signature verification. They are tamper-evident exports,
|
|
64
|
+
not a claim that local SQLite is immutable compliance storage.
|
|
65
|
+
- DSL enum arguments compile to the canonical enum shape and are enforced by
|
|
66
|
+
every Runner transport. Canonical aggregate reads return one fixed
|
|
67
|
+
tenant-scoped COUNT/SUM/AVG scalar, suppress small groups, and persist no
|
|
68
|
+
member rows or identities in evidence/query audit.
|
|
69
|
+
- Graduated trust remains disabled by default and operator-only. It can create
|
|
70
|
+
and export a verified, bounded policy recommendation artifact, but cannot
|
|
71
|
+
auto-approve, push, or activate it.
|
|
72
|
+
- C++/Cloud validators and exporters preserve the new additive enum/aggregate
|
|
73
|
+
fields for canonical round-trip compatibility.
|
|
74
|
+
|
|
75
|
+
Prepared package versions: `@synapsor/spec@1.4.1`,
|
|
76
|
+
`@synapsor/dsl@1.4.2`, and `@synapsor/runner@1.4.121`.
|
|
77
|
+
|
|
13
78
|
## 1.4.12 (prepared, not published)
|
|
14
79
|
|
|
15
80
|
### Runtime-store smoke-call consistency
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# RFC 007: Trusted Principal Row Scope
|
|
2
|
+
|
|
3
|
+
Status: accepted for implementation
|
|
4
|
+
|
|
5
|
+
## Problem
|
|
6
|
+
|
|
7
|
+
Runner already binds a trusted tenant and principal to a context, but the
|
|
8
|
+
principal is currently identity/audit metadata rather than a database row
|
|
9
|
+
predicate. Two users in one tenant can therefore share a tenant-scoped
|
|
10
|
+
capability even when each should see only rows assigned to that user.
|
|
11
|
+
|
|
12
|
+
## Canonical Shape
|
|
13
|
+
|
|
14
|
+
Add one optional subject field:
|
|
15
|
+
|
|
16
|
+
```json
|
|
17
|
+
{
|
|
18
|
+
"tenant_key": "hospital_id",
|
|
19
|
+
"principal_scope_key": "assigned_to"
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The value for `principal_scope_key` always comes from the capability context's
|
|
24
|
+
required `principal_binding`. The contract does not store a principal value and
|
|
25
|
+
the model does not supply one.
|
|
26
|
+
|
|
27
|
+
The DSL form is:
|
|
28
|
+
|
|
29
|
+
```sql
|
|
30
|
+
TENANT KEY hospital_id
|
|
31
|
+
PRINCIPAL SCOPE KEY assigned_to
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
No second representation is introduced. Existing contracts without the field
|
|
35
|
+
retain their current tenant-scoped semantics.
|
|
36
|
+
|
|
37
|
+
## Invariant
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
effective row authority = tenant predicate
|
|
41
|
+
AND principal predicate
|
|
42
|
+
AND reviewed fixed guards
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Principal scope is invalid without tenant scope or without a required trusted
|
|
46
|
+
principal binding. It cannot replace tenant scope, use a model argument, OR
|
|
47
|
+
with another predicate, default to match-all, or be bypassed dynamically. A
|
|
48
|
+
tenant-wide supervisor uses a separately reviewed capability without principal
|
|
49
|
+
scope.
|
|
50
|
+
|
|
51
|
+
## Enforcement
|
|
52
|
+
|
|
53
|
+
The principal predicate is a bound SQL parameter in every applicable read,
|
|
54
|
+
proposal, aggregate, bounded-set, CRUD, compensation, and apply-time query.
|
|
55
|
+
INSERT forces the reviewed column from trusted context. Executor envelopes carry
|
|
56
|
+
an immutable reviewed scope guard. The principal scope is included in proposal
|
|
57
|
+
integrity and writeback authority.
|
|
58
|
+
|
|
59
|
+
Cloud receives only the reviewed column/binding metadata and a stable safe
|
|
60
|
+
fingerprint. The local proposal retains the trusted value needed for SQL. A
|
|
61
|
+
Cloud job cannot substitute it; Runner verifies the job fingerprint, proposal
|
|
62
|
+
hash, and contract digest before mutation.
|
|
63
|
+
|
|
64
|
+
Evidence, proposal, receipt, activity, and replay lookups recheck tenant and
|
|
65
|
+
principal authority. Opaque handles are not bearer credentials. A same-tenant
|
|
66
|
+
cross-principal miss has the same public result as a cross-tenant or absent row,
|
|
67
|
+
and the query performs no separate existence probe.
|
|
68
|
+
|
|
69
|
+
## Compatibility And Release
|
|
70
|
+
|
|
71
|
+
The field changes `@synapsor/spec`, `@synapsor/dsl`, and Runner behavior. It is
|
|
72
|
+
covered by canonical normalization/digest tests, TypeScript/C++ round-trip
|
|
73
|
+
fixtures, PostgreSQL/MySQL live tests, and packed-package tests. The next Runner
|
|
74
|
+
release remains on the `1.4.x` line and targets `1.4.122` if unused; this RFC
|
|
75
|
+
does not justify a `1.5.0` jump.
|
package/docs/runner-bundles.md
CHANGED
|
@@ -11,6 +11,7 @@ Every bundle contains:
|
|
|
11
11
|
```text
|
|
12
12
|
synapsor.contract.json
|
|
13
13
|
synapsor.runner.json
|
|
14
|
+
synapsor.cloud.json
|
|
14
15
|
.env.example
|
|
15
16
|
README.md
|
|
16
17
|
mcp-client-examples/
|
|
@@ -43,9 +44,27 @@ set -a && . ./.env && set +a
|
|
|
43
44
|
npx -y -p @synapsor/runner synapsor-runner contract validate ./synapsor.contract.json
|
|
44
45
|
npx -y -p @synapsor/runner synapsor-runner config validate --config ./synapsor.runner.json
|
|
45
46
|
npx -y -p @synapsor/runner synapsor-runner tools preview --config ./synapsor.runner.json --store ./.synapsor/local.db
|
|
47
|
+
npx -y -p @synapsor/runner synapsor-runner cloud connect --config ./synapsor.cloud.json
|
|
46
48
|
npx -y -p @synapsor/runner synapsor-runner mcp serve --config ./synapsor.runner.json --store ./.synapsor/local.db
|
|
47
49
|
```
|
|
48
50
|
|
|
51
|
+
For proposal contracts, run the trusted worker in a separate
|
|
52
|
+
operator-controlled terminal:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
set -a && . ./.env && set +a
|
|
56
|
+
npx -y -p @synapsor/runner synapsor-runner start --config ./synapsor.runner.json --store ./.synapsor/local.db
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
After an MCP tool creates a local proposal, sync its reviewed diff and safe
|
|
60
|
+
references to Cloud:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
npx -y -p @synapsor/runner synapsor-runner cloud sync latest \
|
|
64
|
+
--config ./synapsor.cloud.json \
|
|
65
|
+
--store ./.synapsor/local.db
|
|
66
|
+
```
|
|
67
|
+
|
|
49
68
|
For the OpenAI Agents SDK, use the included TypeScript examples. Their stdio
|
|
50
69
|
command enables `--alias-mode openai`; the Streamable HTTP example includes the
|
|
51
70
|
matching server command. Claude, Cursor, and generic templates use canonical
|
|
@@ -57,3 +76,8 @@ Approval and writeback remain outside the model-facing MCP tool surface. Use
|
|
|
57
76
|
The bundle's `.env.example` contains names and placeholders only. Fill it for a
|
|
58
77
|
local or staging source, source it into the shell or process that launches your
|
|
59
78
|
MCP client, and keep the resulting `.env` out of source control.
|
|
79
|
+
|
|
80
|
+
The Cloud `source_id` scopes the Runner token and job queue. The contract's
|
|
81
|
+
source alias selects the local database adapter. They are intentionally
|
|
82
|
+
different identifiers. Cloud jobs never contain a database URL or handler
|
|
83
|
+
secret.
|