@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.
Files changed (48) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/README.md +63 -60
  3. package/THREAT_MODEL.md +6 -0
  4. package/dist/cli.d.ts +3 -0
  5. package/dist/cli.d.ts.map +1 -1
  6. package/dist/runner.mjs +29227 -2475
  7. package/docs/README.md +11 -0
  8. package/docs/aggregate-reads.md +49 -0
  9. package/docs/bounded-set-writeback.md +9 -4
  10. package/docs/capability-authoring.md +43 -1
  11. package/docs/cloud-cli.md +248 -0
  12. package/docs/cloud-mode.md +88 -6
  13. package/docs/cloud-push.md +22 -5
  14. package/docs/compliance-reports.md +42 -0
  15. package/docs/conformance.md +15 -0
  16. package/docs/contract-review.md +57 -0
  17. package/docs/contract-testing.md +76 -0
  18. package/docs/dsl-reference.md +50 -6
  19. package/docs/graduated-trust.md +64 -0
  20. package/docs/hosted-cloud-linked-verification.md +97 -0
  21. package/docs/limitations.md +10 -0
  22. package/docs/oss-vs-cloud.md +13 -6
  23. package/docs/release-notes.md +65 -0
  24. package/docs/rfcs/007-trusted-principal-row-scope.md +75 -0
  25. package/docs/runner-bundles.md +24 -0
  26. package/docs/runner-config-reference.md +16 -0
  27. package/docs/running-a-runner-fleet.md +8 -0
  28. package/docs/security-boundary.md +28 -1
  29. package/examples/runner-fleet/seed/mysql.sql +5 -1
  30. package/examples/runner-fleet/seed/postgres.sql +5 -1
  31. package/examples/support-plan-credit/README.md +8 -6
  32. package/examples/support-plan-credit/synapsor.contract-tests.json +53 -0
  33. package/fixtures/dsl/aggregate-read.synapsor.sql +21 -0
  34. package/fixtures/dsl/bounded-set-multi-term.synapsor.sql +30 -0
  35. package/fixtures/dsl/principal-row-scope.synapsor.sql +23 -0
  36. package/fixtures/protocol/MANIFEST.json +10 -10
  37. package/package.json +4 -1
  38. package/schemas/change-set.v1.schema.json +14 -0
  39. package/schemas/change-set.v2.schema.json +14 -0
  40. package/schemas/change-set.v3.schema.json +2 -0
  41. package/schemas/compensation-change-set.v1.schema.json +3 -2
  42. package/schemas/inverse-descriptor.v1.schema.json +2 -0
  43. package/schemas/synapsor.contract-tests.schema.json +54 -0
  44. package/schemas/synapsor.runner.schema.json +92 -4
  45. package/schemas/writeback-job.v1.schema.json +14 -0
  46. package/schemas/writeback-job.v2.schema.json +14 -0
  47. package/schemas/writeback-job.v3.schema.json +2 -0
  48. 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.
@@ -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 status = 'overdue'
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 or more literal equality terms joined by `AND`.
176
- Columns, operators, values, ordering, ranges, and raw SQL cannot come from a
177
- model argument. Runner reads `MAX ROWS + 1` and rejects overflow rather than
178
- truncating. `MAX TOTAL column BEFORE|AFTER|ABSOLUTE DELTA maximum` is a
179
- reviewer-visible aggregate value bound.
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.
@@ -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
 
@@ -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. It stores versioned contracts, produces
13
- downloadable Runner bundles, and provides shared activity, evidence, approval,
14
- and investigation surfaces for enabled design-partner deployments.
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 | Shared activity and evidence surfaces where enabled |
23
- | Approval | Local CLI or localhost UI | Team approval surfaces where enabled |
24
- | Writeback | Guarded one-row CRUD, fixed/frozen bounded sets, or app-owned executor | Cloud-linked jobs with local execution; managed production orchestration is future work |
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
@@ -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.
@@ -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.