@synapsor/runner 1.5.3 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/CHANGELOG.md +82 -2
  2. package/README.md +131 -130
  3. package/dist/authoring.mjs +405 -9
  4. package/dist/cli.d.ts.map +1 -1
  5. package/dist/local-ui.d.ts +2 -0
  6. package/dist/local-ui.d.ts.map +1 -1
  7. package/dist/runner.mjs +19532 -14246
  8. package/dist/runtime.mjs +10856 -8495
  9. package/dist/shadow.mjs +101 -1
  10. package/docs/README.md +14 -6
  11. package/docs/aggregate-reads.md +22 -0
  12. package/docs/auto-boundary-and-scoped-explore.md +338 -0
  13. package/docs/capability-authoring.md +36 -1
  14. package/docs/cloud-mode.md +18 -0
  15. package/docs/conformance.md +16 -0
  16. package/docs/current-scope.md +55 -28
  17. package/docs/cursor-plugin.md +20 -3
  18. package/docs/database-enforced-scope.md +8 -0
  19. package/docs/dsl-reference.md +123 -4
  20. package/docs/getting-started-own-database.md +42 -35
  21. package/docs/guarded-crud-writeback.md +10 -1
  22. package/docs/http-mcp.md +222 -207
  23. package/docs/limitations.md +33 -9
  24. package/docs/local-mode.md +5 -2
  25. package/docs/mcp-client-setup.md +24 -11
  26. package/docs/mcp-clients.md +10 -4
  27. package/docs/openai-agents-sdk.md +16 -2
  28. package/docs/production.md +72 -7
  29. package/docs/release-notes.md +77 -3
  30. package/docs/runner-bundles.md +7 -2
  31. package/docs/runner-config-reference.md +96 -6
  32. package/docs/running-a-runner-fleet.md +42 -13
  33. package/docs/schema-api-candidates.md +28 -1
  34. package/docs/security-boundary.md +38 -3
  35. package/docs/store-lifecycle.md +93 -5
  36. package/docs/troubleshooting-first-run.md +98 -0
  37. package/examples/auto-boundary-churn/README.md +23 -0
  38. package/examples/auto-boundary-churn/app/page.tsx +8 -0
  39. package/examples/auto-boundary-churn/docker-compose.yml +16 -0
  40. package/examples/auto-boundary-churn/package.json +18 -0
  41. package/examples/auto-boundary-churn/prisma/schema.prisma +36 -0
  42. package/examples/auto-boundary-churn/seed/postgres.sql +126 -0
  43. package/examples/openai-agents-http/README.md +10 -4
  44. package/examples/openai-agents-http/agent.py +2 -2
  45. package/examples/runner-fleet/Dockerfile +7 -2
  46. package/examples/runner-fleet/README.md +11 -7
  47. package/examples/runner-fleet/docker-compose.yml +4 -4
  48. package/examples/runner-fleet/mint-dev-token.mjs +1 -1
  49. package/examples/runner-fleet/start-tls-runner.sh +21 -0
  50. package/examples/runner-fleet/synapsor.runner.json +27 -1
  51. package/examples/support-plan-credit/README.md +6 -1
  52. package/examples/support-plan-credit/mcp-client-examples/generic-streamable-http.json +4 -1
  53. package/examples/support-plan-credit/mcp-client-examples/openai-agents-streamable-http.ts +4 -0
  54. package/examples/support-plan-credit/synapsor.contract.json +0 -3
  55. package/fixtures/compatibility/published-1.5.4/manifest.json +76 -0
  56. package/fixtures/compatibility/published-1.5.4/sources/packages/dsl/examples/aggregate-read.synapsor.sql +21 -0
  57. package/fixtures/compatibility/published-1.5.4/sources/packages/dsl/examples/billing-late-fee.synapsor.sql +56 -0
  58. package/fixtures/compatibility/published-1.5.4/sources/packages/dsl/examples/bounded-set-multi-term.synapsor.sql +30 -0
  59. package/fixtures/compatibility/published-1.5.4/sources/packages/dsl/examples/principal-row-scope.synapsor.sql +23 -0
  60. package/fixtures/compatibility/published-1.5.4/sources/packages/spec/fixtures/conformance/aggregate-read/contract.json +119 -0
  61. package/fixtures/compatibility/published-1.5.4/sources/packages/spec/fixtures/conformance/approval-quorum/contract.json +44 -0
  62. package/fixtures/compatibility/published-1.5.4/sources/packages/spec/fixtures/conformance/bounded-set-threats/contract.json +115 -0
  63. package/fixtures/compatibility/published-1.5.4/sources/packages/spec/fixtures/conformance/principal-row-scope/contract.json +78 -0
  64. package/fixtures/compatibility/published-1.5.4/sources/packages/spec/fixtures/conformance/proposal-capability/contract.json +101 -0
  65. package/fixtures/compatibility/published-1.5.4/sources/packages/spec/fixtures/conformance/reversible-change-sets/contract.json +98 -0
  66. package/fixtures/compatibility/published-1.5.4/sources/packages/spec/fixtures/valid/basic-read.contract.json +60 -0
  67. package/llms.txt +37 -0
  68. package/package.json +7 -4
  69. package/schemas/synapsor.runner.schema.json +98 -1
@@ -33,6 +33,9 @@ Current fixture groups:
33
33
  - `bounded-set-threats`
34
34
  - `reversible-change-sets`
35
35
  - `principal-row-scope`
36
+ - protected named row/aggregate parity is covered by the Spec/DSL tests, the
37
+ packaged Auto Boundary golden path, and the Cloud/C++ fixture described
38
+ below.
36
39
 
37
40
  The fixture set is intentionally small in 0.1. It covers the runner-supported
38
41
  semantic surface first: trusted context, scoped reads, evidence handles,
@@ -59,6 +62,12 @@ The principal-row-scope fixture proves that a reviewed owner/assignee column is
59
62
  bound to a required trusted principal and AND-composed with tenant scope. Run
60
63
  `corepack pnpm test:principal-scope` for the live Postgres/MySQL proof covering
61
64
  same-tenant denial and shared-ledger evidence-handle isolation.
65
+ The protected-read parity fixture proves digest- and generation-lock-bound
66
+ named reads, fixed predicates, reviewed measures/dimensions/time buckets,
67
+ one-hop many-to-one limits, suppression, response/query/extraction/
68
+ differencing budgets, and rejection of raw SQL or model-controlled trusted
69
+ scope. `corepack pnpm test:auto-boundary-explore:packed` proves the complete
70
+ authoring-to-production behavior through packed public artifacts.
62
71
 
63
72
  Additional 0.1 parity coverage currently lives in tests and verification
64
73
  scripts rather than separate `cloud-push/` or `dsl-json-parity/` conformance
@@ -73,6 +82,12 @@ fixture directories:
73
82
  - The main Synapsor repo script `scripts/verify_contract_cloud_push.sh`
74
83
  verifies real Cloud push, retrieval, idempotent versioning, unauthorized
75
84
  rejection, and runner-bundle download against a live local control-plane.
85
+ - The main Synapsor repo fixture
86
+ `tests/fixtures/synapsor_spec/protected-read-aggregate.contract.json`,
87
+ `SynapsorContractSpec.*`, control-plane tests, and
88
+ `scripts/verify_contract_roundtrip.sh` prove that Cloud/C++ validates,
89
+ normalizes, stores, and exports the same optional `protected_read` authority
90
+ without accepting SQL escape fields.
76
91
 
77
92
  ## Runner Usage
78
93
 
@@ -87,6 +102,7 @@ corepack pnpm --filter @synapsor-runner/mcp-server test
87
102
  corepack pnpm test:contract-conformance
88
103
  corepack pnpm test:aggregate-read
89
104
  corepack pnpm test:principal-scope
105
+ corepack pnpm test:auto-boundary-explore:packed
90
106
  ```
91
107
 
92
108
  The spec package also validates every conformance contract:
@@ -2,40 +2,67 @@
2
2
 
3
3
  The canonical scope page is [Current Limitations](limitations.md).
4
4
 
5
- Current `1.4` scope:
5
+ Current `1.6` scope:
6
6
 
7
- - local semantic MCP tools for Postgres/MySQL-backed business actions;
8
- - schema inspection and guided config generation;
9
- - trusted context from environment/session values;
10
- - evidence handles, query audit, proposals, receipts, and local replay;
11
- - guarded single-row `INSERT`, `UPDATE`, and `DELETE` writeback with explicit
12
- receipt authority;
7
+ - local semantic MCP tools over Postgres/MySQL without raw SQL tools;
8
+ - deterministic whole-schema Auto Boundary drafting from database metadata,
9
+ statically parsed Prisma/Drizzle schemas, OpenAPI documents, and existing
10
+ Synapsor definitions;
11
+ - disabled generated `.synapsor.sql`, canonical JSON, tests, review evidence,
12
+ and generation locks; no generated authority activates itself;
13
+ - local development/staging Scoped Explore through exactly two temporary MCP
14
+ tools, using typed row plans or a reviewed PM-style analytical cube;
15
+ - aggregate `count`, reviewed `count_distinct`, `sum`, `avg`, reviewed
16
+ dimensions and day/week/month buckets, typed filters, bounded top-N, and at
17
+ most one proven many-to-one relationship;
18
+ - cohort suppression plus durable extraction, differencing, rate, query,
19
+ response, and complexity limits;
20
+ - Protect This Query from a successful local plan to public DSL, canonical
21
+ Spec, tests, and a disabled digest-bound named production capability;
22
+ - schema, grant, ownership, RLS, role, compiler, and Spec drift checks for
23
+ generated authority explicitly bound to a generation lock;
24
+ - trusted context from environment, verified HTTP claims, Cloud sessions, or
25
+ explicit development-only static values;
26
+ - evidence handles, normalized query audit, proposals, receipts, local replay,
27
+ and read-only lifecycle inspection without copying proposal ids;
28
+ - guarded single-row `INSERT`, `UPDATE`, and `DELETE`;
13
29
  - fixed-predicate set `UPDATE`/`DELETE` and exact-review batch `INSERT`, with
14
30
  mandatory row/value caps, frozen members, human approval, atomic execution,
15
31
  and protocol-v3 exact receipts;
16
- - opt-in reviewed compensation for direct SQL UPDATE, INSERT, soft-delete, and
17
- exact frozen sets, using a separate operator proposal and protocol-v4 receipt;
18
- - app-owned `http_handler` and `command_handler` executors for richer approved
19
- business transactions;
20
- - stdio MCP, Streamable HTTP MCP, and a small JSON-RPC bridge.
21
- - a bounded small-fleet shape with asymmetric claim-bound sessions, shared
22
- Postgres review state, source pools, fleet rate limits, readiness, protected
23
- metrics, verified quorum review, dead letters, and backup/restore/retention;
32
+ - opt-in reviewed compensation for supported direct SQL changes, using a
33
+ separate operator proposal and protocol-v4 receipt;
34
+ - safety-wrapped app-owned `http_handler` and `command_handler` executors for
35
+ richer approved business transactions;
36
+ - stdio MCP, authenticated Streamable HTTP MCP, and a legacy JSON-RPC bridge;
37
+ - bounded small-fleet operation with signed claim-bound sessions, shared
38
+ Postgres review state, pools, rate limits, readiness, quorum, dead letters,
39
+ and backup/restore/retention.
40
+
41
+ Scoped Explore is an authoring-plane feature, not a production runtime feature.
42
+ It is disabled by default, requires an explicit development/staging profile and
43
+ a demonstrably read-only non-owner role, and is never advertised by production,
44
+ unknown-profile, shared HTTP, remote, or non-loopback surfaces. Production uses
45
+ only activated named capabilities, including capabilities created through
46
+ Protect.
24
47
 
25
48
  Stable `1.x` compatibility covers the documented `synapsor-runner` binary,
26
- config schema version `1`, result envelope v2 with v1 opt-out, stdio/Streamable
27
- HTTP MCP surfaces, documented MCP client snippets, proposal/evidence/replay
28
- inspection commands, direct SQL writeback, and app-owned executor contracts.
49
+ config schema version `1`, canonical public contracts, result envelopes,
50
+ stdio/Streamable HTTP, established onboarding and CI routes, proposal/evidence/
51
+ replay inspection, guarded writeback, and app-owned executor contracts.
52
+ Existing hand-authored projects do not need Auto Boundary, Workbench,
53
+ generation locks, schema rescans, or new fields; their tool lists do not change
54
+ unless the feature is explicitly adopted.
29
55
 
30
56
  Out of scope:
31
57
 
32
- - raw `execute_sql`;
33
- - model-generated SQL;
34
- - UPSERT, DDL, model-generated predicates, or unguarded INSERT/DELETE;
35
- - model-generated, unbounded, or cross-table set writeback;
36
- - physical branching of external Postgres/MySQL;
37
- - automatic rollback/time travel and inferred compensation for app-owned or
38
- external effects;
39
- - self-hosted Synapsor Cloud;
40
- - unbounded or multi-region shared-ledger scale and a managed Runner fleet;
41
- - production SLA or compliance certification.
58
+ - raw `execute_sql`, SQL strings, model-generated SQL, or arbitrary identifiers;
59
+ - production Scoped Explore or a general-purpose analytics/query AST;
60
+ - general join planning, many-to-many exploration, arbitrary formulas,
61
+ functions, windows, `HAVING`, subqueries, or statistical privacy guarantees;
62
+ - model-selected tenant/principal, activation, approval, or commit authority;
63
+ - UPSERT, DDL, free-form predicates, unbounded writes, or cross-table direct
64
+ transactions;
65
+ - physical branching of external Postgres/MySQL or automatic rollback/time
66
+ travel;
67
+ - self-hosted Synapsor Cloud, an unbounded/multi-region shared ledger, a managed
68
+ Runner fleet, production SLA, or compliance certification.
@@ -14,12 +14,12 @@ plugin-reference, MCP, and deeplink documentation on 2026-07-20:
14
14
  - <https://cursor.com/docs/reference/deeplinks>
15
15
 
16
16
  The locally installed Cursor version used for validation is recorded in
17
- `development/runner-1.5.3-progress.md`. Protocol/static validation is not a
17
+ `development/runner-1.6.0-progress.md`. Protocol/static validation is not a
18
18
  claim that Cursor Marketplace review has completed.
19
19
 
20
20
  ## What the plugin installs
21
21
 
22
- - one stdio MCP server pinned to `@synapsor/runner@1.5.3`;
22
+ - one production stdio MCP server pinned to `@synapsor/runner@1.6.0`;
23
23
  - one `/synapsor-protect` agent command;
24
24
  - one discoverable Safe Action skill;
25
25
  - one file-scoped rule for `synapsor/actions/**/*.ts`;
@@ -29,6 +29,23 @@ The MCP entry uses Cursor's documented `${workspaceFolder}` interpolation for
29
29
  `synapsor.runner.json` and `.synapsor/local.db`. It exposes only `mcp serve`.
30
30
  Approval, apply, activation, commit, and revert remain outside MCP.
31
31
 
32
+ Auto Boundary authoring uses a separate CLI-managed project entry rather than
33
+ the production plugin entry:
34
+
35
+ ```bash
36
+ synapsor-runner mcp install cursor \
37
+ --project \
38
+ --authoring \
39
+ --project-root . \
40
+ --yes
41
+ ```
42
+
43
+ That temporary local stdio entry is accepted only after exact boundary
44
+ activation and advertises exactly `app.describe_data` and `app.explore_data`.
45
+ After Protect activation, reinstall the normal project config; production then
46
+ advertises only named reviewed capabilities. The plugin never makes Scoped
47
+ Explore available to production, shared HTTP, remote, or non-loopback serving.
48
+
32
49
  ## Build and verify
33
50
 
34
51
  ```bash
@@ -63,7 +80,7 @@ Required listing media:
63
80
 
64
81
  ## Submission checklist
65
82
 
66
- - [ ] Runner 1.5.3 package and plugin version agree.
83
+ - [ ] Runner 1.6.0 package and plugin version agree.
67
84
  - [ ] `corepack pnpm verify:cursor-plugin` passes from a clean checkout.
68
85
  - [ ] Plugin is manually loaded in current stable Cursor at workspace scope.
69
86
  - [ ] `/synapsor-protect` drafts and validates without activation.
@@ -11,6 +11,10 @@ from model arguments. Choose the database enforcement mode deliberately:
11
11
 
12
12
  These modes are defense in depth, not substitutes for least-privilege roles,
13
13
  restricted views, application authorization, or staging-first validation.
14
+ HTTP endpoint authentication is another independent layer: it establishes who
15
+ may call Runner and, for signed shared sessions, which trusted tenant/principal
16
+ claims are bound. It does not turn `application_scope` into database-enforced
17
+ isolation. See [HTTP MCP](http-mcp.md).
14
18
 
15
19
  ## Default: Application-Level Scope
16
20
 
@@ -49,6 +53,10 @@ with environment-bound capabilities.
49
53
  For shared production HTTP, prefer asymmetric JWT verification so Runner holds
50
54
  only public verification material. HS256 remains useful for local development
51
55
  and controlled deployments but gives Runner access to the signing secret.
56
+ Also declare `http_security.deployment: shared`, an exact HTTPS
57
+ audience/protected resource, a direct-TLS or trusted-proxy channel, and exact
58
+ Host/Origin policy. A static endpoint token cannot supply shared tenant or
59
+ principal identity.
52
60
 
53
61
  Run `doctor --json` or `tools preview --json` to inspect the effective
54
62
  per-source assurance mode and trusted-context binding. Server startup prints
@@ -29,7 +29,7 @@ END
29
29
 
30
30
  | Clause | Meaning |
31
31
  | --- | --- |
32
- | `BIND name FROM source key [REQUIRED]` | Defines trusted context. Sources: `SESSION`, `ENV`/`ENVIRONMENT`, `CLOUD_SESSION`, `STATIC_DEV`, `HTTP_CLAIM`. Model tool arguments cannot set these bindings. |
32
+ | `BIND name FROM source key [REQUIRED]` | Defines trusted context. Canonical sources: `SESSION`, `ENV`/`ENVIRONMENT`, `CLOUD_SESSION`, `STATIC_DEV`, `HTTP_CLAIM`. Model tool arguments cannot set these bindings. Runner rejects `SESSION`; use one of its implemented verified providers described below. |
33
33
  | `TENANT BINDING name` | Selects the binding used for tenant scope. Defaults to a binding named `tenant_id`. |
34
34
  | `PRINCIPAL BINDING name` | Selects the actor binding. Defaults to a binding named `principal`. |
35
35
 
@@ -65,16 +65,57 @@ END
65
65
  | `TENANT KEY column` | Required in DSL 0.1. Adds trusted tenant scope to every read/write. |
66
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. |
67
67
  | `CONFLICT GUARD column` | Captures the row-version value for exact guarded writeback. Prefer a monotonic version or native-precision timestamp. |
68
+ | `CONFLICT GUARD WEAK ROW HASH ACKNOWLEDGED` | Explicitly accepts a weaker hash over the captured projection for a legacy, ordinary single-row source-DB UPDATE. It may miss concurrent changes outside that projection and is never equivalent to a version column. |
69
+
70
+ An UPDATE proposal must choose one of those guard clauses. Omitting the clause
71
+ is a compile error; the compiler never silently selects the weak form. The weak
72
+ form is rejected for INSERT, DELETE, reversible writes, bounded sets, and
73
+ Runner-ledger authority. `contract lint`, `contract explain`, `doctor`, and
74
+ `tools preview` all identify it prominently.
75
+
76
+ To migrate a legacy DSL file that omitted the guard, inspect the target schema
77
+ and add an exact source column:
78
+
79
+ ```sql
80
+ CONFLICT GUARD version
81
+ ```
82
+
83
+ Use a monotonic integer/version column when available, or a native-precision
84
+ `updated_at` maintained by the database. If a legacy source has no usable
85
+ version column and the capability is an ordinary single-row UPDATE using
86
+ source-DB receipt authority, the explicit weak clause keeps the previous
87
+ projection-hash behavior while recording the reduced assurance in review
88
+ output. Do not use it as a production-equivalent substitute for a real version
89
+ column.
68
90
 
69
91
  `PRINCIPAL SCOPE KEY` means `tenant_key = trusted tenant AND
70
92
  principal_scope_key = trusted principal`. It cannot replace tenant scope,
71
93
  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
94
+ must be required and come from a trusted Runner provider: `ENVIRONMENT`,
95
+ verified `HTTP_CLAIM`, verified `CLOUD_SESSION`, or explicit
96
+ `STATIC_DEV` for development only. For networked multi-user serving, use
97
+ signed HTTP claims. Canonical `SESSION` is implemented by C++/Cloud but is
98
+ rejected by Runner; Runner never aliases it to environment variables. See the complete
75
99
  [`principal-row-scope.synapsor.sql`](../fixtures/dsl/principal-row-scope.synapsor.sql)
76
100
  example.
77
101
 
102
+ ### Migrating `FROM SESSION` for Runner
103
+
104
+ Choose the provider that owns the verified identity at the Runner boundary:
105
+
106
+ - local stdio or one trusted process: `FROM ENVIRONMENT`; export the named
107
+ values before starting Runner;
108
+ - Streamable HTTP: `FROM HTTP_CLAIM`; configure signed JWT verification and
109
+ bind only verified claims;
110
+ - Cloud embedding: `FROM CLOUD_SESSION`; use the verified Cloud session
111
+ supplied by the control plane; or
112
+ - disposable development only: `FROM STATIC_DEV`.
113
+
114
+ `synapsor-runner dsl validate` and `dsl compile` target Runner and fail with
115
+ `SESSION_BINDING_UNSUPPORTED` before serving. The standalone DSL accepts the
116
+ canonical syntax by default for other implementations; pass `--target runner`
117
+ to request the same fail-closed Runner validation.
118
+
78
119
  ## Arguments and lookup
79
120
 
80
121
  ```sql
@@ -127,6 +168,84 @@ Aggregate reads cannot declare model arguments, lookup, visible row fields,
127
168
  proposal clauses, joins, grouping, or arbitrary expressions. See [Bounded
128
169
  Aggregate Reads](aggregate-reads.md).
129
170
 
171
+ ## Protected named reads
172
+
173
+ `PROTECTED READ` is the public DSL emitted by Protect This Query. It freezes a
174
+ successful local authoring plan into a named capability. It is not the
175
+ temporary `app.explore_data` plan grammar and it is not a generic query AST.
176
+
177
+ This aggregate example is representative:
178
+
179
+ ```sql
180
+ CREATE CAPABILITY analytics.churn_contributors_by_week
181
+ DESCRIPTION 'Describe reviewed weekly churn contributors.'
182
+ RETURNS HINT 'Returns privacy-suppressed reviewed groups.'
183
+ USING CONTEXT analytics_operator
184
+ SOURCE local_postgres
185
+ ON public.account_churn
186
+ PRIMARY KEY id
187
+ TENANT KEY tenant_id
188
+ ARG period_start STRING REQUIRED MAX LENGTH 32
189
+ ARG period_end STRING REQUIRED MAX LENGTH 32
190
+ PROTECTED READ AGGREGATE
191
+ BOUNDARY DIGEST sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
192
+ GENERATION LOCK sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
193
+ PROTECTED FILTER status EQ FIXED 'churned'
194
+ PROTECTED FILTER churned_at GTE ARG period_start
195
+ PROTECTED FILTER churned_at LT ARG period_end
196
+ MEASURE churned_accounts COUNT ROWS
197
+ MEASURE affected_customers COUNT DISTINCT customer_id
198
+ GROUP DIMENSION region BY region
199
+ GROUP DIMENSION reason BY churn_reason
200
+ TIME DIMENSION churn_week BY WEEK OF churned_at
201
+ AGGREGATE ORDER BY MEASURE churned_accounts DESC
202
+ TOP 20 GROUPS
203
+ MIN GROUP SIZE 5
204
+ KEEP OUT email, private_notes
205
+ REQUIRE EVIDENCE
206
+ PROTECTED LIMITS ROWS 50 GROUPS 50 CELLS 500 BYTES 65536 TIMEOUT MS 3000 QUERIES 40 EXTRACTED CELLS 4000 DIFFERENCING 6 RATE PER MINUTE 20
207
+ END
208
+ ```
209
+
210
+ In that example, uppercase phrases such as `PROTECTED READ AGGREGATE`,
211
+ `BOUNDARY DIGEST`, `MEASURE`, `GROUP DIMENSION`, and `TOP ... GROUPS` are DSL
212
+ keywords. Names such as `analytics.churn_contributors_by_week`,
213
+ `churned_accounts`, `affected_customers`, `region`, and `churn_week` are
214
+ user-reviewed identifiers. Table/column references such as
215
+ `public.account_churn`, `customer_id`, and `churned_at` come from inspected
216
+ schema evidence and are frozen into the capability.
217
+
218
+ The protected clauses mean:
219
+
220
+ | Clause | Reviewed meaning |
221
+ | --- | --- |
222
+ | `PROTECTED READ ROWS` / `AGGREGATE` | Selects a frozen row or aggregate protected-read shape. |
223
+ | `BOUNDARY DIGEST sha256:...` | Binds the capability to the exact human-activated exploration authority. |
224
+ | `GENERATION LOCK sha256:...` | Binds it to the reviewed schema, role/grant/RLS posture, compiler, and Spec fingerprint. |
225
+ | `PROTECTED RELATIONSHIP name ON local_key REFERENCES schema.table.target_key PRIMARY KEY pk TENANT KEY tenant [PRINCIPAL SCOPE KEY principal]` | Freezes at most one inspected, reviewed many-to-one path with fan-out one. |
226
+ | `PROTECTED FILTER field OP FIXED value` | Freezes a reviewed literal. `OP` is `EQ`, `NEQ`, `LT`, `LTE`, `GT`, `GTE`, or bounded fixed-list `IN`. |
227
+ | `PROTECTED FILTER field OP ARG name` | Allows only one declared typed/bounded argument at that reviewed literal position. |
228
+ | `ALLOW READ ...` / `ROW ORDER BY ...` | Freezes row projection and up to three fixed sort fields for row mode. |
229
+ | `MEASURE alias COUNT ROWS` | Counts the reviewed subject entity. |
230
+ | `MEASURE alias COUNT DISTINCT field` | Counts distinct values of a field approved for aggregate use; the raw values need not be visible. |
231
+ | `MEASURE alias SUM|AVG field` | Uses an explicitly approved aggregate-safe numeric measure. |
232
+ | `GROUP DIMENSION alias BY field` | Freezes a reviewed categorical grouping. |
233
+ | `TIME DIMENSION alias BY DAY|WEEK|MONTH OF field` | Freezes one reviewed timestamp and bucket. |
234
+ | `COMPARE RANGE field FROM value TO value` | Freezes at most two bounded reviewed time ranges. |
235
+ | `TOP n GROUPS` / `MIN GROUP SIZE n` | Fixes output breadth and cohort suppression. |
236
+ | `PROTECTED LIMITS ...` | Fixes row/group/response/time/query/extraction/differencing/rate budgets; MCP arguments cannot widen them. |
237
+
238
+ Protect normally generates this verbose authority block so that reviewers do
239
+ not have to transcribe digests or limits. The generated DSL compiles through
240
+ `@synapsor/dsl` into the optional default-deny `protected_read` field in the
241
+ canonical Spec. Existing contracts with no `protected_read` field normalize
242
+ and hash exactly as before.
243
+
244
+ Protected row and aggregate capabilities can be served after exact-digest
245
+ activation even when temporary Scoped Explore is disabled. Production never
246
+ needs or advertises `app.explore_data`. See [Auto Boundary, Scoped Explore, And
247
+ Protect](auto-boundary-and-scoped-explore.md).
248
+
130
249
  ## Read surface and evidence
131
250
 
132
251
  ```sql
@@ -1,62 +1,66 @@
1
1
  # Connect Your Own Database
2
2
 
3
- Use this path after the Docker demo passes and you want to try Synapsor Runner
4
- against a staging or disposable Postgres/MySQL database.
3
+ Use this path after the synthetic proof passes and you want to try Synapsor
4
+ Runner against a staging or disposable Postgres/MySQL database.
5
5
 
6
6
  Do not start with your most sensitive production database. Runner is a
7
- commit-safety runtime for reviewed single-row business actions, not a
8
- production certification.
7
+ reviewed data boundary, not a production certification.
9
8
 
10
9
  If you only ran `synapsor-runner demo --quick`, you have tested the fixture-only
11
10
  teaching path and local ledger commands. This page is the real own-database
12
- path: it inspects your Postgres/MySQL metadata and generates reviewed semantic
13
- tools from your selections.
11
+ path. Auto Boundary inspects the whole selected schema, combines deterministic
12
+ database/Prisma/Drizzle/OpenAPI/Synapsor evidence, and generates disabled
13
+ review artifacts without sampling source rows or using an LLM.
14
14
 
15
15
  ## Fast path
16
16
 
17
- Set one read-only database URL and run the public guided path:
17
+ Set a dedicated SELECT-only, non-owner database URL plus trusted development
18
+ scope and run the public guided path:
18
19
 
19
20
  ```bash
20
21
  export DATABASE_URL="<postgres-or-mysql-read-url>"
22
+ export SYNAPSOR_TENANT_ID="<staging-tenant>"
23
+ export SYNAPSOR_PRINCIPAL="<developer-id>"
21
24
  npx -y -p @synapsor/runner synapsor-runner start --from-env DATABASE_URL
22
25
  ```
23
26
 
24
- That command does the useful local mini-Synapsor path:
27
+ A fresh interactive project with no existing config, selector, or automation
28
+ input follows:
25
29
 
26
30
  ```text
27
- inspect your schema
28
- -> choose one table/view
29
- -> choose trusted scope and visible fields
30
- -> optionally choose proposal/writeback rules
31
- -> generate synapsor.runner.json + canonical synapsor.contract.json
32
- -> preview MCP tools exposed to the model
33
- -> run a local smoke check of the tool boundary
34
- -> optionally write .synapsor/smoke-input.json for one real row
35
- -> open the secured localhost first-action workbench in an interactive terminal
31
+ inspect the whole selected schema and structured application artifacts
32
+ -> draft disabled public DSL, canonical JSON, tests, and generation lock
33
+ -> review scope, fields, analytics permissions, relationships, and budgets
34
+ -> activate the exact exploration-boundary digest in local Workbench
35
+ -> install exactly app.describe_data and app.explore_data in Cursor
36
+ -> ask a bounded row or PM-style aggregate question against staging
37
+ -> Protect This Query into a disabled named capability
38
+ -> activate that exact digest and remove broad Explore
39
+ -> serve only the named protected capability in production
36
40
  ```
37
41
 
38
42
  It does not print your database URL, put the URL in MCP client config, expose
39
43
  `execute_sql`, expose approval/commit tools, or give the model write
40
- credentials.
44
+ credentials. Before boundary activation it does not read source rows.
41
45
 
42
46
  `start --from-env` is the shortest public command for first-run onboarding.
43
- `onboard db --from-env DATABASE_URL` is the same explicit path if you prefer the
44
- older command name in scripts.
47
+ Read [Auto Boundary, Scoped Explore, And
48
+ Protect](auto-boundary-and-scoped-explore.md) for the complete command and
49
+ security reference.
45
50
 
46
- Interactive `start` opens the focused local workbench after config validation
47
- and an MCP boundary handshake. Use `--no-open` for CI or scripts. That handshake
48
- proves the reviewed tool surface; the workbench's **Test** step remains pending
49
- until a real scoped read is recorded in the local ledger.
51
+ Established routes remain unchanged. `--table`, `--answers`, `onboard db`,
52
+ explicit `init` flags, existing configs, headless startup, JSON output, and CI
53
+ do not enter Auto Boundary, prompt unexpectedly, open a browser, rescan an
54
+ existing project, or require a generation lock. For example:
50
55
 
51
- During the wizard, provide the optional sample object id if you know one safe
52
- row in the selected table. Runner writes `./.synapsor/smoke-input.json` with
53
- that id and prints the exact `smoke call` command. If you skip it, use
54
- `--json '{"<lookup_arg>":"<real_id>"}'` when you are ready to test one real
55
- row.
56
+ ```bash
57
+ synapsor-runner start --from-env DATABASE_URL --table invoices --no-open
58
+ synapsor-runner onboard db --from-env DATABASE_URL --answers ./answers.json
59
+ ```
56
60
 
57
- The rest of this page shows the same flow step by step using the public
58
- `synapsor-runner ...` CLI. From a source checkout, use `./bin/synapsor-runner ...` if the
59
- global binary is not linked yet.
61
+ The rest of this page documents those established one-object/manual routes.
62
+ They remain supported for existing projects and automation. From a source
63
+ checkout, use `./bin/synapsor-runner ...` if the global binary is not linked.
60
64
 
61
65
  From a source checkout, `./scripts/use-your-db.sh` runs the same kind of
62
66
  guided flow plus local repository checks.
@@ -520,7 +524,7 @@ MCP client:
520
524
  ```bash
521
525
  export SYNAPSOR_TENANT_ID="acme"
522
526
  export SYNAPSOR_PRINCIPAL="local_operator"
523
- export SYNAPSOR_RUNNER_HTTP_TOKEN="dev-local-token"
527
+ export SYNAPSOR_RUNNER_HTTP_TOKEN="$(node -e 'process.stdout.write(require("node:crypto").randomBytes(32).toString("base64url"))')"
524
528
 
525
529
  npx -y -p @synapsor/runner synapsor-runner up --serve \
526
530
  --config ./synapsor.runner.json \
@@ -543,9 +547,12 @@ npx -y -p @synapsor/runner synapsor-runner mcp serve-streamable-http \
543
547
  ```
544
548
 
545
549
  Streamable HTTP defaults to `127.0.0.1:8766` and requires bearer auth by
546
- default. Use private networking/TLS before exposing it beyond localhost. See
550
+ default. A non-loopback listener refuses to start until direct TLS, an explicitly
551
+ trusted TLS proxy, or authenticated emergency break glass is selected. Shared
552
+ services use signed per-session identity rather than one endpoint token. See
547
553
  [HTTP MCP](http-mcp.md). If you want the smaller JSON-RPC bridge instead, use
548
- `synapsor-runner mcp serve-http`.
554
+ `synapsor-runner mcp serve-http`; it is not suitable for claim-bound shared MCP
555
+ sessions.
549
556
 
550
557
  The model-facing MCP server exposes semantic tools such as:
551
558
 
@@ -27,13 +27,22 @@ does not fit either direct boundary.
27
27
 
28
28
  | Operation | Required source guard | Direct-write behavior |
29
29
  | --- | --- | --- |
30
- | `UPDATE` | Primary key, trusted tenant, exact version/conflict column | Patches only allowlisted columns and affects exactly one row. In Runner-ledger mode, the version must advance in the same source transaction. |
30
+ | `UPDATE` | Primary key, trusted tenant, and normally an exact version/conflict column | Patches only allowlisted columns and affects exactly one row. In Runner-ledger mode, the exact version must advance in the same source transaction. |
31
31
  | `INSERT` | Source `PRIMARY KEY` or `UNIQUE` constraint over the reviewed dedup identity | Runner injects tenant and proposal-derived identity values, inserts only allowlisted fields, and requires exactly one row. |
32
32
  | `DELETE` | Primary key, trusted tenant, exact version column | Deletes exactly one reviewed row. Hard delete requires human/operator approval and is refused when Runner detects write triggers or widening cascades. Prefer soft delete as guarded `UPDATE`. |
33
33
 
34
34
  Existing proposal capabilities with no `operation` field continue to mean
35
35
  single-row `UPDATE`.
36
36
 
37
+ DSL authoring requires `CONFLICT GUARD <column>` for UPDATE and never silently
38
+ chooses weak semantics. A narrow legacy single-row, non-reversible UPDATE using
39
+ source-DB receipt authority may explicitly declare
40
+ `CONFLICT GUARD WEAK ROW HASH ACKNOWLEDGED`. That mode hashes only the captured
41
+ projection and may miss concurrent changes outside it. It is prominently
42
+ reported by lint/explain/doctor/preview and is unavailable for Runner-ledger,
43
+ DELETE, reversibility, or bounded sets. Treat it as a compatibility escape
44
+ hatch, not equivalent protection.
45
+
37
46
  ## Receipt authority
38
47
 
39
48
  Receipt authority and source-table provisioning are separate decisions: