@synapsor/runner 1.6.3 → 1.6.5

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 (98) hide show
  1. package/AGENTS.md +2 -2
  2. package/CHANGELOG.md +94 -8
  3. package/CONTRIBUTING.md +10 -3
  4. package/README.md +90 -109
  5. package/SECURITY.md +7 -3
  6. package/THREAT_MODEL.md +37 -0
  7. package/dist/authoring.mjs +98 -13
  8. package/dist/cli.d.ts +12 -1
  9. package/dist/cli.d.ts.map +1 -1
  10. package/dist/local-ui.d.ts +60 -0
  11. package/dist/local-ui.d.ts.map +1 -1
  12. package/dist/runner.mjs +7688 -2227
  13. package/dist/runtime.mjs +528 -51
  14. package/docs/README.md +14 -0
  15. package/docs/agent-guided-setup.md +13 -11
  16. package/docs/aggregate-reads.md +14 -5
  17. package/docs/app-owned-executors.md +5 -6
  18. package/docs/auto-boundary-and-scoped-explore.md +70 -14
  19. package/docs/capability-authoring.md +2 -2
  20. package/docs/client-recipes.md +41 -12
  21. package/docs/cloud-mode.md +7 -7
  22. package/docs/conformance.md +6 -3
  23. package/docs/current-scope.md +13 -2
  24. package/docs/cursor-plugin.md +3 -3
  25. package/docs/database-enforced-scope.md +6 -0
  26. package/docs/dsl-reference.md +12 -1
  27. package/docs/fresh-developer-usability.md +6 -6
  28. package/docs/getting-started-own-database.md +52 -50
  29. package/docs/guided-onboarding.md +104 -34
  30. package/docs/host-compatibility.md +24 -11
  31. package/docs/limitations.md +34 -14
  32. package/docs/local-mode.md +20 -20
  33. package/docs/mcp-audit.md +14 -14
  34. package/docs/mcp-client-setup.md +26 -14
  35. package/docs/mcp-clients.md +47 -11
  36. package/docs/migrating-to-synapsor-spec.md +5 -1
  37. package/docs/openai-agents-sdk.md +2 -2
  38. package/docs/proposal-evidence-freshness.md +7 -7
  39. package/docs/recipes.md +6 -6
  40. package/docs/release-notes.md +100 -10
  41. package/docs/release-policy.md +20 -7
  42. package/docs/reversible-change-sets.md +1 -1
  43. package/docs/reviewed-database-views.md +132 -0
  44. package/docs/reviewed-relationships.md +245 -0
  45. package/docs/rfcs/006-reviewed-reversible-change-sets.md +1 -1
  46. package/docs/runner-bundles.md +7 -7
  47. package/docs/schema-api-candidates.md +1 -1
  48. package/docs/security-boundary.md +30 -0
  49. package/docs/troubleshooting-first-run.md +63 -19
  50. package/docs/use-your-own-database.md +6 -4
  51. package/docs/workbench-ask.md +279 -0
  52. package/docs/writeback-executors.md +7 -7
  53. package/examples/auto-boundary-churn/README.md +1 -1
  54. package/examples/community-solar-clean-room/README.md +7 -0
  55. package/examples/community-solar-clean-room/docker-compose.yml +16 -0
  56. package/examples/community-solar-clean-room/package.json +15 -0
  57. package/examples/community-solar-clean-room/prisma/schema.prisma +171 -0
  58. package/examples/community-solar-clean-room/seed/postgres.sql +571 -0
  59. package/examples/fitflow-guided-onboarding/README.md +2 -2
  60. package/examples/openai-agents-http/Makefile +1 -1
  61. package/examples/openai-agents-http/README.md +1 -1
  62. package/examples/openai-agents-stdio/Makefile +1 -1
  63. package/examples/openai-agents-stdio/README.md +2 -2
  64. package/examples/openai-agents-stdio/agent.py +1 -4
  65. package/examples/reference-support-billing-app/README.md +16 -16
  66. package/examples/retail-clean-room/README.md +7 -0
  67. package/examples/retail-clean-room/docker-compose.yml +16 -0
  68. package/examples/retail-clean-room/package.json +9 -0
  69. package/examples/retail-clean-room/prisma/schema.prisma +239 -0
  70. package/examples/retail-clean-room/seed/postgres.sql +781 -0
  71. package/examples/retail-clean-room/view-recipe/average-retained-revenue.synapsor.sql +21 -0
  72. package/examples/retail-clean-room/view-recipe/synapsor.runner.json +25 -0
  73. package/examples/support-plan-credit/mcp-client-examples/claude-code.sh +1 -4
  74. package/examples/support-plan-credit/mcp-client-examples/claude-desktop.json +1 -4
  75. package/examples/support-plan-credit/mcp-client-examples/codex.config.toml +1 -4
  76. package/examples/support-plan-credit/mcp-client-examples/cursor-global.mcp.json +1 -4
  77. package/examples/support-plan-credit/mcp-client-examples/cursor-project.mcp.json +1 -4
  78. package/examples/support-plan-credit/mcp-client-examples/generic-stdio.json +1 -4
  79. package/examples/support-plan-credit/mcp-client-examples/generic-stdio.mjs +1 -1
  80. package/examples/support-plan-credit/mcp-client-examples/google-adk.py +1 -1
  81. package/examples/support-plan-credit/mcp-client-examples/langchain.mjs +1 -1
  82. package/examples/support-plan-credit/mcp-client-examples/llamaindex.py +1 -1
  83. package/examples/support-plan-credit/mcp-client-examples/openai-agents-stdio.ts +1 -1
  84. package/examples/support-plan-credit/mcp-client-examples/vscode.mcp.json +1 -4
  85. package/fixtures/compatibility/published-1.6.3/manifest.json +76 -0
  86. package/fixtures/compatibility/published-1.6.3/sources/packages/dsl/examples/aggregate-read.synapsor.sql +21 -0
  87. package/fixtures/compatibility/published-1.6.3/sources/packages/dsl/examples/billing-late-fee.synapsor.sql +56 -0
  88. package/fixtures/compatibility/published-1.6.3/sources/packages/dsl/examples/bounded-set-multi-term.synapsor.sql +30 -0
  89. package/fixtures/compatibility/published-1.6.3/sources/packages/dsl/examples/principal-row-scope.synapsor.sql +23 -0
  90. package/fixtures/compatibility/published-1.6.3/sources/packages/spec/fixtures/conformance/aggregate-read/contract.json +119 -0
  91. package/fixtures/compatibility/published-1.6.3/sources/packages/spec/fixtures/conformance/approval-quorum/contract.json +44 -0
  92. package/fixtures/compatibility/published-1.6.3/sources/packages/spec/fixtures/conformance/bounded-set-threats/contract.json +115 -0
  93. package/fixtures/compatibility/published-1.6.3/sources/packages/spec/fixtures/conformance/principal-row-scope/contract.json +78 -0
  94. package/fixtures/compatibility/published-1.6.3/sources/packages/spec/fixtures/conformance/proposal-capability/contract.json +101 -0
  95. package/fixtures/compatibility/published-1.6.3/sources/packages/spec/fixtures/conformance/reversible-change-sets/contract.json +98 -0
  96. package/fixtures/compatibility/published-1.6.3/sources/packages/spec/fixtures/valid/basic-read.contract.json +60 -0
  97. package/llms.txt +10 -5
  98. package/package.json +9 -2
@@ -42,6 +42,36 @@ The model does not receive:
42
42
  - MCP endpoint tokens, JWTs, refresh tokens, client secrets, or TLS keys;
43
43
  - trusted tenant or principal authority as ordinary model arguments.
44
44
 
45
+ ## Optional Workbench model client
46
+
47
+ Workbench Ask is a local client of that same reviewed surface, not another
48
+ policy engine. It is available only from authenticated loopback Workbench in an
49
+ explicit development/staging profile. Its provider may request only the exact
50
+ active named capabilities plus valid local authoring tools. The request is
51
+ dispatched through the official MCP SDK and the existing typed-plan/runtime
52
+ validators; there is no parallel query or mutation executor.
53
+
54
+ The operator chooses provider, model, endpoint, and credential source and
55
+ acknowledges direct egress for the current authority digest. No model output can
56
+ change those values. Provider credentials and bounded conversation state stay
57
+ in local server memory and are not written to the project, ledger, browser
58
+ storage, logs, evidence, receipts, or replay. Reviewed tool results may be sent
59
+ directly to the provider after consent; Synapsor does not relay them.
60
+
61
+ Official remote providers use fixed HTTPS origins. Custom remote endpoints
62
+ require HTTPS; plaintext is restricted to loopback. Redirects are refused,
63
+ resolved destinations are checked and pinned on every connection, and
64
+ private/link-local/metadata/special remote addresses are blocked. Unknown
65
+ tools, malformed arguments/responses, authority drift, oversized data, time or
66
+ tool-loop exhaustion, and reported source mutation fail closed.
67
+
68
+ Provider prose remains untrusted. A write tool can create only the normal inert
69
+ proposal, and the Workbench directs the human to the separate operator path.
70
+ Ask never receives activation, Protect, approval, apply, worker, notification,
71
+ attention, or reconciliation tools. It is absent from production,
72
+ unknown-profile, shared, remote, and non-loopback surfaces. See [Workbench Ask
73
+ With Your Model](workbench-ask.md).
74
+
45
75
  ## Network transport and identity
46
76
 
47
77
  Local stdio is the preferred one-client path. The MCP client launches Runner and
@@ -3,26 +3,26 @@
3
3
  Run the friendly doctor first:
4
4
 
5
5
  ```bash
6
- npx -y -p @synapsor/runner synapsor-runner doctor --first-run
6
+ npx -y @synapsor/runner doctor --first-run
7
7
  ```
8
8
 
9
9
  Use JSON for automation:
10
10
 
11
11
  ```bash
12
- npx -y -p @synapsor/runner synapsor-runner doctor --first-run --json
12
+ npx -y @synapsor/runner doctor --first-run --json
13
13
  ```
14
14
 
15
15
  ## Guided Recovery Contract
16
16
 
17
- Runner 1.6.3 failures should tell you what failed, why the boundary stopped,
17
+ Runner 1.6.4 failures should tell you what failed, why the boundary stopped,
18
18
  what state remains, and one next action. Do not delete the project or add
19
19
  `--force` merely to recover.
20
20
 
21
21
  | Failure | State preserved | One next action |
22
22
  | --- | --- | --- |
23
- | Database connection or metadata inspection failed | Existing project/review files and source rows | Fix the exported URL/network without printing the credential, then rerun `npx -y @synapsor/runner@latest start --from-env DATABASE_URL`. |
23
+ | Database connection or metadata inspection failed | Existing project/review files and source rows | Fix the URL/network without printing the credential, then rerun `npx -y @synapsor/runner start`. |
24
24
  | Read role is writable, owner, superuser, `BYPASSRLS`, or unverifiable | Disabled metadata draft; no source-row Explore | Supply a verifiably SELECT-only non-owner staging role, then rerun the same `start` command. |
25
- | Schema or project choice is ambiguous | Existing files; no authority activation | Rerun with the exact reviewed schema, for example `npx -y @synapsor/runner@latest start --from-env DATABASE_URL --schema public`. |
25
+ | Schema or project choice is ambiguous | Existing files; no authority activation | Rerun with the exact reviewed schema, for example `npx -y @synapsor/runner start --schema public`. |
26
26
  | Tenant or principal scope is unresolved | Conservative blocked resource decisions | Open the same Workbench URL and resolve the highlighted scope exception. |
27
27
  | Sensitive field remains unresolved | Field stays kept out; active tools unchanged | Open Workbench **Exceptions** and record one reviewed field decision. |
28
28
  | Row identifier is missing/composite/ambiguous | Resource remains blocked | Select a source-proven single-column primary/unique identity or keep the resource blocked. |
@@ -33,6 +33,9 @@ what state remains, and one next action. Do not delete the project or add
33
33
  | Config mode is missing/invalid | Config and source database are unchanged | Set `mode` to `read_only`, `shadow`, `review`, or `cloud`, then rerun `synapsor-runner config validate --json`. |
34
34
  | Config contains an unknown field | Config and source database are unchanged | Remove or correct the reported JSON path, then rerun `synapsor-runner config validate --json`. |
35
35
  | Workbench port is occupied | Review files, ledger, and source database | Rerun `synapsor-runner ui --open`; the default selects a free loopback port. |
36
+ | Workbench Ask is missing | Reviewed project remains usable through no-model Workbench/CLI/MCP | Use authenticated loopback Workbench with an explicit development/staging profile and at least one active reviewed tool. |
37
+ | Ask provider/key fails | Boundary, no-model composer, and external MCP remain usable | Check the exported key name, provider/model access, and local DNS/TLS; then retry without changing authority. |
38
+ | Ask says authority changed | Previous consent is invalid; active reviewed tools remain unchanged | Inspect the new tool/digest summary and acknowledge direct egress again. |
36
39
  | Writeback setup fails | Config and reviewed plan; transactional setup rolls back | Rerun `synapsor-runner writeback setup --profile staging --json` and review the reported prerequisite. |
37
40
  | Writer role/setup URL is missing | No DDL or grant was applied | Rerun the preview with `--writer-role <role> --setup-url-env <ADMIN_URL_ENV>`. |
38
41
  | No supported write candidate exists | Read boundary remains active; no write authority | Use **Add a safe action** on a writable base table with a proven identity/version field, or retain read-only mode. |
@@ -49,9 +52,10 @@ outcome; inspect the durable receipt/reconciliation state rather than guessing.
49
52
 
50
53
  ## Fresh Start Did Not Enter Auto Boundary
51
54
 
52
- Auto Boundary is the default only for a fresh interactive `start --from-env`
53
- with no existing config, selector, answers file, machine-output flag, or other
54
- automation input. This preserves every established 1.x route.
55
+ Auto Boundary is the default only for a fresh interactive `start` with no
56
+ existing config, selector, answers file, machine-output flag, or other
57
+ automation input. An exported `DATABASE_URL` is implied; explicit connection
58
+ and schema flags still win. This preserves every established 1.x route.
55
59
 
56
60
  Check the generated state:
57
61
 
@@ -80,9 +84,10 @@ Check:
80
84
  ```bash
81
85
  synapsor-runner boundary status --json
82
86
  synapsor-runner boundary diff --json
83
- synapsor-runner mcp status cursor --project
87
+ synapsor-runner mcp status claude-code --project
84
88
  ```
85
89
 
90
+ Use `cursor` or `vscode` instead when that is the selected client.
86
91
  The exact boundary digest must be active, the profile must explicitly be
87
92
  `development` or `staging`, the generation lock and compiler/Spec versions
88
93
  must be current, and the inspected database role must still be SELECT-only,
@@ -93,12 +98,48 @@ A write-capable, owner, superuser, `BYPASSRLS`, or unverifiable credential may
93
98
  still inspect metadata with a warning. It cannot enable source-row Explore.
94
99
  Use a dedicated staging reader instead of weakening this check.
95
100
 
96
- ## Cursor Has Production Tools Instead Of Authoring Tools
101
+ ## Workbench Ask Is Missing Or Refused
102
+
103
+ Ask is optional and follows a stricter local profile boundary. It appears only
104
+ in authenticated loopback Workbench for explicit `development` or `staging`
105
+ projects with at least one reviewed tool. Production, unknown, shared, remote,
106
+ and non-loopback surfaces intentionally omit it.
107
+
108
+ Normal Runner and MCP execution do not automatically source `.env`. Fresh
109
+ interactive `start` may read a regular project `.env` only after explicit
110
+ consent and keeps the selected database URL in that process. For the optional
111
+ model provider, export the key in the same shell that launches Workbench, then
112
+ select **Read an environment variable** and enter only the variable name. A
113
+ session-only masked paste is also supported.
114
+
115
+ Provider errors are redacted and do not disable the no-model composer:
116
+
117
+ - `ASK_KEY_REQUIRED`: export the selected key or use the masked session paste;
118
+ - `ASK_AUTHORITY_CHANGED`: review the current tools/digest and acknowledge
119
+ direct egress again;
120
+ - `ASK_PROVIDER_UNAVAILABLE`: verify provider availability, key/model access,
121
+ and local DNS/TLS, then retry;
122
+ - `ASK_PROVIDER_REDIRECT_REFUSED`: use the final fixed endpoint; Runner never
123
+ forwards credentials across redirects;
124
+ - `ASK_PROVIDER_DESTINATION_REFUSED`: the host resolved to a private, special,
125
+ metadata, or otherwise disallowed remote address;
126
+ - `ASK_REMOTE_HTTPS_REQUIRED`: remote custom endpoints require HTTPS; HTTP is
127
+ accepted only on loopback;
128
+ - `ASK_TOOL_REQUIRED`: the provider answered from prose without using a
129
+ reviewed Synapsor tool;
130
+ - `ASK_UNKNOWN_TOOL` or `ASK_OPERATOR_TOOL_REFUSED`: the provider requested
131
+ authority outside the displayed tool surface.
132
+
133
+ Select **Clear** after a session to cancel active work and discard in-memory
134
+ provider configuration/history. See [Workbench Ask With Your
135
+ Model](workbench-ask.md).
136
+
137
+ ## A Project Client Has Production Tools Instead Of Authoring Tools
97
138
 
98
139
  Install the managed local authoring entry only after boundary activation:
99
140
 
100
141
  ```bash
101
- synapsor-runner mcp install cursor \
142
+ synapsor-runner mcp install claude-code \
102
143
  --project \
103
144
  --authoring \
104
145
  --project-root . \
@@ -111,13 +152,15 @@ production config. The protected named capability remains available while
111
152
  Explore disappears:
112
153
 
113
154
  ```bash
114
- synapsor-runner mcp install cursor \
155
+ synapsor-runner mcp install claude-code \
115
156
  --project \
116
157
  --config ./synapsor.runner.json \
117
158
  --store ./.synapsor/local.db \
118
159
  --yes
119
160
  ```
120
161
 
162
+ Use `cursor` or `vscode` instead of `claude-code` for those clients.
163
+
121
164
  ## Boundary Became Stale After A Schema Or Grant Change
122
165
 
123
166
  Generated authority is bound to the schema, role, grants, ownership, RLS
@@ -164,19 +207,20 @@ Open the secured Workbench, run the real source-unchanged staging Data PR
164
207
  preview, review the complete digest, and activate it there. There is
165
208
  intentionally no activation CLI command to hand to a coding agent.
166
209
 
167
- ## Activated Tool Does Not Appear In Cursor
210
+ ## Activated Tool Does Not Appear In The MCP Client
168
211
 
169
212
  Some MCP hosts do not refresh `tools/list` for a running stdio session. First
170
213
  confirm that Runner's active tool surface changed:
171
214
 
172
215
  ```bash
173
216
  synapsor-runner action status --json
174
- synapsor-runner mcp status cursor --project --check-launch
217
+ synapsor-runner mcp status claude-code --project --check-launch
175
218
  ```
176
219
 
220
+ Use `cursor` or `vscode` instead of `claude-code` for those clients.
177
221
  Then reconnect or restart the project MCP server as directed by the Workbench.
178
222
  Do not work around a stale host session by adding approval, apply, activation,
179
- credentials, tenant values, or raw SQL to the Cursor configuration.
223
+ credentials, tenant values, or raw SQL to the client configuration.
180
224
 
181
225
  ## Safe Action Validation Reports Review Placeholders
182
226
 
@@ -327,13 +371,13 @@ Own-database MCP setup needs a reviewed config before serving tools.
327
371
  Fix:
328
372
 
329
373
  ```bash
330
- npx -y -p @synapsor/runner synapsor-runner init --from-env DATABASE_URL --mode review --wizard
374
+ npx -y @synapsor/runner init --from-env DATABASE_URL --mode review --wizard
331
375
  ```
332
376
 
333
377
  Or pass an example config:
334
378
 
335
379
  ```bash
336
- npx -y -p @synapsor/runner synapsor-runner tools preview --config ./examples/mcp-postgres-billing/synapsor.runner.json --store ./.synapsor/local.db
380
+ npx -y @synapsor/runner tools preview --config ./examples/mcp-postgres-billing/synapsor.runner.json --store ./.synapsor/local.db
337
381
  ```
338
382
 
339
383
  ## SQLite Store Missing
@@ -379,7 +423,7 @@ Fix:
379
423
 
380
424
  ```bash
381
425
  export SYNAPSOR_DATABASE_READ_URL="<read-only-url>"
382
- npx -y -p @synapsor/runner synapsor-runner doctor --config synapsor.runner.json
426
+ npx -y @synapsor/runner doctor --config synapsor.runner.json
383
427
  ```
384
428
 
385
429
  ## Read/Write Credential Split Failed
@@ -491,7 +535,7 @@ Fix:
491
535
  Regenerate the snippet:
492
536
 
493
537
  ```bash
494
- npx -y -p @synapsor/runner synapsor-runner mcp config claude-desktop \
538
+ synapsor-runner mcp config claude-desktop \
495
539
  --absolute-paths \
496
540
  --config ./synapsor.runner.json \
497
541
  --store ./.synapsor/local.db
@@ -10,9 +10,11 @@ model.
10
10
  Short path:
11
11
 
12
12
  ```bash
13
- export DATABASE_URL="postgresql://readonly_user:password@host:5432/app?sslmode=require"
14
- npx -y -p @synapsor/runner synapsor-runner start --from-env DATABASE_URL --schema public
13
+ npx -y @synapsor/runner start
15
14
  ```
16
15
 
17
- Runner stores environment-variable names in `synapsor.runner.json`, not database
18
- URLs. Keep credentials in your shell, process manager, or secret manager.
16
+ Paste a read-only URL into the hidden prompt, explicitly approve a regular
17
+ project `.env` file for this process, or export `DATABASE_URL`. PostgreSQL
18
+ defaults to `public`; explicit `--from-env`, `--schema`, and `--project-root`
19
+ flags remain available and always win. Runner stores environment-variable names
20
+ in `synapsor.runner.json`, not database URLs.
@@ -0,0 +1,279 @@
1
+ # Workbench Ask With Your Model
2
+
3
+ Workbench Ask is an optional local client for the reviewed Synapsor tools that
4
+ already exist. It lets a developer ask a plain-language question through
5
+ OpenAI, Anthropic, or an explicitly configured OpenAI-compatible endpoint
6
+ without installing an external MCP host first.
7
+
8
+ Ask does not generate or activate authority. It does not replace the no-model
9
+ Workbench composer, which remains the default onboarding path and requires no
10
+ model API key.
11
+
12
+ ```text
13
+ human activates a reviewed boundary or named capability
14
+ -> Workbench lists that exact model-facing tool surface
15
+ -> human selects a provider and acknowledges direct data egress
16
+ -> provider may request one of those reviewed tools
17
+ -> Runner executes the request through the normal MCP/runtime path
18
+ -> provider receives the bounded reviewed result
19
+ -> Workbench renders provider prose as untrusted output
20
+ ```
21
+
22
+ The model cannot activate a boundary, Protect a query, approve or apply a
23
+ proposal, control a worker, acknowledge attention, reconcile an outcome, or
24
+ change provider configuration.
25
+
26
+ ## Availability
27
+
28
+ Ask appears only when all of these conditions hold:
29
+
30
+ - Workbench is authenticated and bound to loopback;
31
+ - the deployment profile is explicitly `development` or `staging`;
32
+ - at least one reviewed model-facing tool is available;
33
+ - generated authority and its generation lock are current when applicable.
34
+
35
+ It is absent from production, missing/unknown profiles, non-loopback
36
+ Workbench, shared remote HTTP, and model-facing MCP configuration. An MCP
37
+ request cannot enable Ask or select its provider.
38
+
39
+ While Scoped Explore is active, Ask may use:
40
+
41
+ ```text
42
+ app.describe_data
43
+ app.explore_data
44
+ ```
45
+
46
+ After Explore is disabled, Ask may use only the activated named capabilities
47
+ in `synapsor.runner.json`, such as:
48
+
49
+ ```text
50
+ analytics.weekly_revenue_by_store
51
+ retail.propose_order_fulfillment
52
+ ```
53
+
54
+ The panel displays the exact tool names and an Ask authority digest. That digest
55
+ binds the tool surface, runtime config, deployment profile, and active
56
+ exploration digest when one exists. A material authority change invalidates
57
+ egress consent before another provider call.
58
+
59
+ ## Start Without A Model
60
+
61
+ Begin with the normal one-command staging path:
62
+
63
+ ```bash
64
+ export SYNAPSOR_TENANT_ID='<reviewed tenant>'
65
+ export SYNAPSOR_PRINCIPAL='<reviewed principal>'
66
+ npx -y @synapsor/runner start
67
+ ```
68
+
69
+ Paste the SELECT-only database URL into Runner's hidden terminal prompt, or
70
+ explicitly consent to loading only `DATABASE_URL` from a recognized project
71
+ environment file. For an intentionally exported automation path, use
72
+ `start --from-env DATABASE_URL`.
73
+
74
+ Review and activate the boundary, then run the first safe read or aggregate in
75
+ Workbench. At this point the complete no-model path is already working.
76
+
77
+ Open **Analyze**, then **Ask with your model**. Workbench shows:
78
+
79
+ - the reviewed tools the provider may request;
80
+ - the current boundary/authority digest;
81
+ - provider, model, origin, and credential source;
82
+ - that approved visible results may go directly to the provider;
83
+ - that Synapsor does not relay the request;
84
+ - that the source database is unchanged by a read or proposal call.
85
+
86
+ ## Provider Credentials
87
+
88
+ Workbench Ask does not load provider keys from `.env` files. Instant database
89
+ onboarding may separately read only a selected `DATABASE_URL` after explicit
90
+ human consent. Export a provider key in the same shell that starts Runner:
91
+
92
+ ```bash
93
+ export OPENAI_API_KEY='<provider key>'
94
+ npx -y @synapsor/runner start
95
+ ```
96
+
97
+ Provide the database URL through the same hidden/consented path above. If
98
+ Runner is already running, use the masked Workbench key field instead of
99
+ restarting only to add a provider key.
100
+
101
+ In Workbench select:
102
+
103
+ ```text
104
+ Provider: OpenAI
105
+ Credential: Read an environment variable
106
+ Environment variable name: OPENAI_API_KEY
107
+ ```
108
+
109
+ The browser sends only the environment variable name. The value stays in the
110
+ local Runner process and is not returned to the browser.
111
+
112
+ Alternatively, paste a key into the masked Workbench field. Runner holds that
113
+ value only in server memory for the current local session and clears the field
114
+ after configuration. Do not paste credentials into an agent chat.
115
+
116
+ Keys and authorization headers are not written to:
117
+
118
+ - generated DSL, JSON, locks, or config;
119
+ - the SQLite/shared ledger, evidence, receipts, or replay;
120
+ - browser local/session storage;
121
+ - logs, screenshots, telemetry, or command-line arguments.
122
+
123
+ Select **Clear** to cancel an active request, remove in-memory provider
124
+ configuration, and discard bounded conversation history. Stopping Workbench
125
+ also clears it.
126
+
127
+ ## Direct Egress
128
+
129
+ Before the first call, Workbench requires this provider-specific decision:
130
+
131
+ ```text
132
+ Your reviewed visible data may be sent directly to this provider using your
133
+ credential. Synapsor does not receive it. Fields kept out by the active
134
+ boundary are unavailable to this model.
135
+ ```
136
+
137
+ Consent is bound to the provider, model, endpoint origin, and current Ask
138
+ authority digest. Changing any of those requires a new acknowledgement.
139
+ Consent does not activate or widen database authority.
140
+
141
+ The question, reviewed tool definitions, and bounded tool results go directly
142
+ from local Runner to the selected provider. A tool result can contain reviewed
143
+ source values, so use a provider and data-handling policy appropriate for that
144
+ data. Kept-out fields are unavailable to selection, filtering, grouping,
145
+ sorting, joins, or returned results.
146
+
147
+ Runner does not persist the conversation, provider response, or returned tool
148
+ rows by default. Existing normalized query audit still records the boundary
149
+ digest, keyed plan/literal fingerprints, suppression decision, timing, and
150
+ result size without storing result values or trusted tenant/principal values.
151
+ An operator-created screenshot or external provider may retain data under its
152
+ own policy; Runner cannot erase those external copies.
153
+
154
+ ## Authority And Proposal Behavior
155
+
156
+ Provider tool calls use the official MCP SDK and the same canonical runtime as
157
+ an external client:
158
+
159
+ - typed argument validation;
160
+ - trusted tenant/principal injection outside model arguments;
161
+ - read-only transaction enforcement for Scoped Explore;
162
+ - field, relationship, suppression, extraction, and differencing limits;
163
+ - proposal construction and exact active contract digest;
164
+ - the same error envelope and source-change state.
165
+
166
+ Provider prose, tool names, arguments, and response metadata remain untrusted.
167
+ An unknown or operator-plane tool is refused. A malformed or oversized
168
+ request, repeated tool loop, changed authority, timeout, or provider failure
169
+ stops safely.
170
+
171
+ A reviewed write tool may create an inert proposal:
172
+
173
+ ```text
174
+ Proposal only
175
+ The source database did not change.
176
+ The model cannot approve or apply this proposal.
177
+ ```
178
+
179
+ The human continues through the separate Workbench/CLI operator workflow.
180
+ Ask never receives approval or commit tools.
181
+
182
+ ## Endpoint Security
183
+
184
+ Official providers use fixed endpoints:
185
+
186
+ ```text
187
+ OpenAI: https://api.openai.com/v1/chat/completions
188
+ Anthropic: https://api.anthropic.com/v1/messages
189
+ ```
190
+
191
+ Use **Custom OpenAI-compatible** for another endpoint. Remote custom endpoints
192
+ must use HTTPS. Plain HTTP is accepted only for an explicit loopback endpoint,
193
+ for example:
194
+
195
+ ```text
196
+ http://127.0.0.1:11434/v1
197
+ ```
198
+
199
+ Runner:
200
+
201
+ - rejects URL credentials, fragments, and query parameters;
202
+ - disables redirects and never forwards a key across one;
203
+ - resolves and validates DNS for every connection;
204
+ - pins the connection to the validated address while retaining TLS hostname
205
+ verification;
206
+ - blocks private, link-local, multicast, unspecified, metadata, and other
207
+ special destinations for remote mode;
208
+ - permits custom local mode only on loopback;
209
+ - bounds request/response bytes, tool schemas/results, tool calls, iterations,
210
+ history, time, and reported tokens.
211
+
212
+ No URL, model, header, or destination comes from model output.
213
+
214
+ ## Fixed Session Bounds
215
+
216
+ The current release enforces:
217
+
218
+ | Item | Bound |
219
+ | --- | ---: |
220
+ | Question | 4,000 characters |
221
+ | Model identifier | 128 characters |
222
+ | Provider request | 256 KiB |
223
+ | Provider response | 1 MiB |
224
+ | Tool schema surface | 128 KiB and 64 tools |
225
+ | One tool result | 128 KiB |
226
+ | Tool calls | 4 per provider response, 8 per turn |
227
+ | Tool-loop iterations | 6 |
228
+ | Conversation history | 4 completed turns, 16 KiB |
229
+ | Final answer | 16 KiB |
230
+ | Provider request timeout | 30 seconds |
231
+ | Reported session token usage | 50,000 tokens |
232
+
233
+ One Workbench Ask session runs one request at a time. Runner does not
234
+ automatically retry provider calls in this release. A developer may retry a
235
+ known safe failure from the UI; every retry begins with current authority
236
+ validation. Token accounting depends on usage reported by the provider and is
237
+ not a monetary spend guarantee.
238
+
239
+ ## Tested Provider Matrix
240
+
241
+ Status as of the prepared 1.6.4 source:
242
+
243
+ | Provider surface | Verification | Claim |
244
+ | --- | --- | --- |
245
+ | OpenAI `gpt-5-mini` | Live packed-Workbench run against real local PostgreSQL on 2026-07-25 | Live tested |
246
+ | Anthropic Messages/tool-use protocol | Deterministic mock server, normal/refusal/error paths | Protocol tested; no live Anthropic account run |
247
+ | Custom OpenAI-compatible loopback | Real local HTTP server plus deterministic tool/refusal/proposal paths | Tested against the documented Chat Completions subset |
248
+ | Ollama or another named compatible server | Not installed in the release environment | Unknown until tested; compatibility is not implied by the label |
249
+
250
+ The live OpenAI run used `app.describe_data` and `app.explore_data`, matched the
251
+ official MCP aggregate result, changed no source rows, and passed exact-key
252
+ artifact scans. See
253
+ `development/runner-1.6.4-community-solar-results.json`.
254
+
255
+ ## Troubleshooting
256
+
257
+ **Ask is missing:** confirm loopback Workbench, an explicit development/staging
258
+ profile, and at least one active reviewed tool. Production intentionally omits
259
+ Ask.
260
+
261
+ **Key required:** export the named variable in the process that launches
262
+ Runner, or use the session-only masked paste. Runner does not load `.env`.
263
+
264
+ **Authority changed:** inspect the new tool/digest summary and acknowledge
265
+ egress again. Do not bypass the check.
266
+
267
+ **Provider unavailable:** the reviewed boundary and no-model composer remain
268
+ usable. Check provider status, local DNS/TLS, key validity, and model access.
269
+ Runner returns a redacted failure and does not retry automatically.
270
+
271
+ **Custom endpoint refused:** use HTTPS remotely or an exact loopback HTTP URL.
272
+ Private network and metadata endpoints are intentionally blocked.
273
+
274
+ **Provider answers without a tool:** Runner refuses to present prose as a
275
+ database answer until at least one reviewed Synapsor tool succeeds or returns a
276
+ reviewed refusal.
277
+
278
+ **Proposal did not commit:** that is correct. Open the separate operator
279
+ workflow to review, approve, and guardedly apply it.
@@ -59,9 +59,9 @@ It does not claim distributed exactly-once. See
59
59
  Use the helper commands before enabling direct SQL writeback:
60
60
 
61
61
  ```bash
62
- npx -y -p @synapsor/runner synapsor-runner writeback doctor --config ./synapsor.runner.json
63
- npx -y -p @synapsor/runner synapsor-runner writeback migration --engine postgres
64
- npx -y -p @synapsor/runner synapsor-runner writeback grants --engine postgres --writer-role app_writer
62
+ npx -y @synapsor/runner writeback doctor --config ./synapsor.runner.json
63
+ npx -y @synapsor/runner writeback migration --engine postgres
64
+ npx -y @synapsor/runner writeback grants --engine postgres --writer-role app_writer
65
65
  ```
66
66
 
67
67
  `writeback doctor --check-db` connects with the configured writer credential and
@@ -106,7 +106,7 @@ literal values.
106
106
  Run after approval:
107
107
 
108
108
  ```bash
109
- npx -y -p @synapsor/runner synapsor-runner apply \
109
+ npx -y @synapsor/runner apply \
110
110
  --proposal wrp_123 \
111
111
  --config ./synapsor.runner.json \
112
112
  --store ./.synapsor/local.db
@@ -199,13 +199,13 @@ handler receipt.
199
199
  Or generate one into your app:
200
200
 
201
201
  ```bash
202
- npx -y -p @synapsor/runner synapsor-runner handler template node-fastify \
202
+ npx -y @synapsor/runner handler template node-fastify \
203
203
  --output ./synapsor-writeback-handler.mjs
204
204
 
205
- npx -y -p @synapsor/runner synapsor-runner handler template python-fastapi \
205
+ npx -y @synapsor/runner handler template python-fastapi \
206
206
  --output ./synapsor_writeback_handler.py
207
207
 
208
- npx -y -p @synapsor/runner synapsor-runner handler template command \
208
+ npx -y @synapsor/runner handler template command \
209
209
  --output ./synapsor-command-handler.mjs
210
210
  ```
211
211
 
@@ -1,6 +1,6 @@
1
1
  # Auto Boundary Churn Fixture
2
2
 
3
- This synthetic staging fixture is the measured Runner 1.6.0 golden path:
3
+ This synthetic staging fixture is the original Runner 1.6.0 focused path:
4
4
  PostgreSQL, Next.js, Prisma, Cursor-compatible local MCP, and the local
5
5
  Workbench.
6
6
 
@@ -0,0 +1,7 @@
1
+ # Community Solar Clean-Room Fixture
2
+
3
+ This synthetic PostgreSQL and Prisma application exists only for the Runner
4
+ 1.6.4 clean-room adoption gate. It contains no production data or credentials.
5
+
6
+ The measured journey starts from a copied packed artifact and this fixture in a
7
+ new temporary directory. Synapsor artifacts are not pre-generated.
@@ -0,0 +1,16 @@
1
+ services:
2
+ postgres:
3
+ image: postgres:16
4
+ environment:
5
+ POSTGRES_DB: community_solar
6
+ POSTGRES_USER: solar_admin
7
+ POSTGRES_PASSWORD: solar_admin_password
8
+ ports:
9
+ - "127.0.0.1:55464:5432"
10
+ healthcheck:
11
+ test: ["CMD-SHELL", "test \"$(psql -U solar_admin -d community_solar -tAc \"SELECT pg_postmaster_start_time() > initialized_at FROM public.synapsor_fixture_ready LIMIT 1\" 2>/dev/null | xargs)\" = t"]
12
+ interval: 1s
13
+ timeout: 3s
14
+ retries: 60
15
+ volumes:
16
+ - ./seed/postgres.sql:/docker-entrypoint-initdb.d/001-schema.sql:ro
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "synapsor-community-solar-clean-room",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "dependencies": {
6
+ "@prisma/client": "^6.0.0",
7
+ "next": "^15.0.0",
8
+ "react": "^19.0.0",
9
+ "react-dom": "^19.0.0"
10
+ },
11
+ "devDependencies": {
12
+ "prisma": "^6.0.0",
13
+ "typescript": "^5.8.0"
14
+ }
15
+ }