@synapsor/runner 0.1.0-alpha.8 → 0.1.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 (67) hide show
  1. package/CHANGELOG.md +162 -0
  2. package/README.md +391 -25
  3. package/dist/cli.d.ts +2 -0
  4. package/dist/cli.d.ts.map +1 -1
  5. package/dist/runner.mjs +2945 -193
  6. package/docs/README.md +40 -0
  7. package/docs/app-owned-executors.md +38 -0
  8. package/docs/capability-authoring.md +265 -0
  9. package/docs/cloud-mode.md +24 -0
  10. package/docs/current-scope.md +29 -0
  11. package/docs/dependency-license-inventory.md +35 -0
  12. package/docs/doctor.md +98 -0
  13. package/docs/getting-started-own-database.md +131 -46
  14. package/docs/handler-helper.md +228 -0
  15. package/docs/http-mcp.md +85 -17
  16. package/docs/licensing.md +36 -0
  17. package/docs/local-mode.md +44 -25
  18. package/docs/mcp-audit.md +8 -8
  19. package/docs/mcp-client-setup.md +59 -21
  20. package/docs/openai-agents-sdk.md +57 -0
  21. package/docs/recipes.md +6 -6
  22. package/docs/release-notes.md +327 -0
  23. package/docs/release-policy.md +125 -0
  24. package/docs/result-envelope-v2.md +151 -0
  25. package/docs/rfcs/001-result-envelope-v2.md +143 -0
  26. package/docs/rfcs/002-app-owned-handler-helper.md +161 -0
  27. package/docs/rfcs/003-integrator-feedback-teardown.md +97 -0
  28. package/docs/store-lifecycle.md +83 -0
  29. package/docs/troubleshooting-first-run.md +6 -6
  30. package/docs/use-your-own-database.md +18 -0
  31. package/docs/writeback-executors.md +92 -1
  32. package/examples/app-owned-writeback/README.md +128 -0
  33. package/examples/app-owned-writeback/business-actions.md +221 -0
  34. package/examples/app-owned-writeback/command-handler.mjs +55 -0
  35. package/examples/app-owned-writeback/node-fastify-handler.mjs +64 -0
  36. package/examples/app-owned-writeback/python-fastapi-handler.py +66 -0
  37. package/examples/mcp-postgres-billing-app-handler/README.md +94 -0
  38. package/examples/mcp-postgres-billing-app-handler/app-handler.mjs +123 -0
  39. package/examples/mcp-postgres-billing-app-handler/docker-compose.yml +13 -0
  40. package/examples/mcp-postgres-billing-app-handler/schema.sql +59 -0
  41. package/examples/mcp-postgres-billing-app-handler/scripts/run-demo.sh +100 -0
  42. package/examples/mcp-postgres-billing-app-handler/seed.sql +39 -0
  43. package/examples/mcp-postgres-billing-app-handler/synapsor-handler.mjs +437 -0
  44. package/examples/mcp-postgres-billing-app-handler/synapsor.runner.json +158 -0
  45. package/examples/openai-agents-http/README.md +19 -12
  46. package/examples/openai-agents-http/agent.py +29 -65
  47. package/examples/openai-agents-stdio/README.md +10 -6
  48. package/examples/openai-agents-stdio/agent.py +4 -2
  49. package/examples/reference-support-billing-app/README.md +16 -16
  50. package/examples/reference-support-billing-app/mcp-client.generic.json +1 -1
  51. package/fixtures/benchmark/mcp-efficiency.json +53 -0
  52. package/fixtures/benchmark/mcp-efficiency.txt +25 -0
  53. package/fixtures/protocol/MANIFEST.json +54 -0
  54. package/fixtures/protocol/change-set.late-fee-waiver.v1.json +72 -0
  55. package/fixtures/protocol/execution-receipt.applied.v1.json +14 -0
  56. package/fixtures/protocol/execution-receipt.conflict.v1.json +15 -0
  57. package/fixtures/protocol/runner-registration.v1.json +22 -0
  58. package/fixtures/protocol/writeback-job.late-fee-waiver.v1.json +44 -0
  59. package/package.json +6 -1
  60. package/schemas/change-set.v1.schema.json +140 -0
  61. package/schemas/execution-receipt.v1.schema.json +34 -0
  62. package/schemas/onboarding-selection.v1.schema.json +132 -0
  63. package/schemas/runner-registration.v1.schema.json +48 -0
  64. package/schemas/synapsor.app-handler-receipt.v1.json +39 -0
  65. package/schemas/synapsor.app-handler-request.v1.json +119 -0
  66. package/schemas/synapsor.runner.schema.json +415 -0
  67. package/schemas/writeback-job.v1.schema.json +121 -0
package/README.md CHANGED
@@ -7,6 +7,68 @@ Runner lets an MCP agent inspect scoped data and request database-backed
7
7
  business actions without receiving raw SQL, write credentials, approval tools,
8
8
  or commit tools.
9
9
 
10
+ ## The Five-Line Model
11
+
12
+ Your agent talks to Synapsor Runner, not directly to your database.
13
+ It can look: scoped reads through reviewed tools.
14
+ It can suggest: saved proposals with evidence and exact diffs.
15
+ It cannot commit: approval and writeback happen outside the model-facing tool.
16
+ After writeback, Runner keeps receipts and replay so you can inspect what happened.
17
+
18
+ ## Four Terms
19
+
20
+ - Capability: a tool you define in config, such as `billing.inspect_invoice`
21
+ or `billing.propose_late_fee_waiver`. The agent only sees capabilities.
22
+ - Proposal: the agent's suggested database-backed change. It is saved, not
23
+ applied.
24
+ - Writeback: the moment an approved proposal actually changes the database.
25
+ - Executor: your app's writeback handler for anything richer than a guarded
26
+ one-row update.
27
+
28
+ You install only `@synapsor/runner`. There is no separate handler package to
29
+ install. A handler is your app's endpoint or script for rich approved writes;
30
+ Runner includes templates and examples to help you build one.
31
+
32
+ ## Who Does What
33
+
34
+ You write the config: sources, trusted context, capabilities, visible fields,
35
+ proposal fields, and guards. For rich writes, you also write a small handler.
36
+
37
+ Synapsor Runner serves the MCP tools, stores evidence/proposals/receipts,
38
+ enforces tenant, column, version, and idempotency guards, routes writeback, and
39
+ keeps the replay log. You do not rebuild the safety loop yourself.
40
+
41
+ ## The Writeback Rule
42
+
43
+ One-row update to an existing row: Runner can do guarded direct writeback.
44
+ Anything else, such as inserting a row, touching two tables, or emitting an
45
+ event: your app-owned executor does it after approval.
46
+
47
+ ## How An External Handler Works
48
+
49
+ Some changes are too rich for Runner's one-row writeback: insert a credit row,
50
+ touch two tables, or emit an event. For those, you run a small endpoint. The
51
+ flow is:
52
+
53
+ ```text
54
+ agent proposes
55
+ -> human approves outside MCP
56
+ -> Runner POSTs the approved change to your endpoint
57
+ -> your code writes it in its own transaction and returns a receipt
58
+ ```
59
+
60
+ The model never touches this code. You are the last line of defense: Runner
61
+ hands you the tenant, expected row version, and idempotency key, and your
62
+ handler must re-check all three. Skipping those checks reintroduces
63
+ cross-tenant writes, lost updates, or duplicate writes. Start from
64
+ `synapsor-runner handler template ...` instead of hand-rolling the safety checks.
65
+
66
+ ## Deliberate Limits
67
+
68
+ Runner does not expose raw SQL, write credentials, approval tools, or commit
69
+ tools to the model. Direct Runner writeback does not do generic `INSERT`,
70
+ `DELETE`, `UPSERT`, DDL, or multi-row SQL. Those are app-owned executor jobs.
71
+
10
72
  ```text
11
73
  AI agent or MCP client
12
74
  (Claude, Cursor, OpenAI Agents SDK, LangGraph)
@@ -51,7 +113,7 @@ Run the guided quick demo first. It does not require Docker, a database, a
51
113
  config file, an MCP client, or a Synapsor Cloud account.
52
114
 
53
115
  ```bash
54
- npx -y -p @synapsor/runner@alpha synapsor-runner demo --quick
116
+ npx -y -p @synapsor/runner synapsor-runner demo --quick
55
117
  ```
56
118
 
57
119
  In a terminal, it walks through the safety model step by step. In CI, piped
@@ -63,7 +125,7 @@ It does not prove database connectivity. It shows the proposal, evidence, and
63
125
  replay flow without giving the runner a database URL.
64
126
 
65
127
  ```bash
66
- npx -y -p @synapsor/runner@alpha synapsor-runner demo inspect
128
+ npx -y -p @synapsor/runner synapsor-runner demo inspect
67
129
  ```
68
130
 
69
131
  Human output is concise by default. Use `--details` for reviewer metadata or
@@ -81,14 +143,69 @@ synapsor-runner demo inspect --npx
81
143
  Then choose one path:
82
144
 
83
145
  ```text
84
- Full disposable proof -> npx -y -p @synapsor/runner@alpha synapsor-runner demo
146
+ Full disposable proof -> npx -y -p @synapsor/runner synapsor-runner demo
85
147
  Your own staging DB -> export DATABASE_URL=... then run the inspect command below
86
- MCP risk review -> npx -y -p @synapsor/runner@alpha synapsor-runner audit --example dangerous-db-mcp
148
+ MCP risk review -> npx -y -p @synapsor/runner synapsor-runner audit --example dangerous-db-mcp
149
+ ```
150
+
151
+ For your own database, do this before wiring Claude, Cursor, OpenAI Agents SDK,
152
+ or another MCP client:
153
+
154
+ ```text
155
+ 1. Generate the config with start/init/onboard.
156
+ 2. Run tools preview to confirm no raw SQL or write credentials are exposed.
157
+ 3. Run smoke call against one generated inspect tool.
158
+ 4. Only then run up --serve or mcp serve.
87
159
  ```
88
160
 
89
161
  `synapsor-runner` is the public command for this OSS runner. `synapsor` is
90
162
  reserved for the Synapsor Cloud CLI.
91
163
 
164
+ Authoring reference:
165
+
166
+ - [Capability Authoring](docs/capability-authoring.md): read/proposal tools,
167
+ model-facing descriptions, result envelope v2, trusted context, and writeback
168
+ guards.
169
+ - [Result Envelope v2](docs/result-envelope-v2.md): stable
170
+ `ok`/`summary`/`data`/`proposal`/`error` MCP tool results.
171
+ - [JSON Schema](schemas/synapsor.runner.schema.json): editor validation for
172
+ `synapsor.runner.json`.
173
+
174
+ ## Current Alpha Details
175
+
176
+ These are current alpha requirements, not hidden behavior:
177
+
178
+ - Writeback with `--config ./synapsor.runner.json` reads the trusted writer
179
+ connection from the source `write_url_env`, for example
180
+ `SYNAPSOR_DATABASE_WRITE_URL`. `SYNAPSOR_DATABASE_URL` is only the legacy
181
+ fallback when you run direct worker/apply flows without a local config.
182
+ - `synapsor-runner mcp serve` is standard stdio MCP for local clients that can
183
+ launch Runner.
184
+ - `synapsor-runner mcp serve-streamable-http` is standard MCP Streamable HTTP
185
+ with `initialize` and in-memory session behavior for SDK/client HTTP MCP
186
+ integrations.
187
+ - OpenAI Agents SDK rejects dotted function/tool names. Use
188
+ `--alias-mode openai` or `--openai-tool-aliases` for OpenAI-facing MCP
189
+ transports. Runner exposes aliases such as `billing__inspect_invoice` and
190
+ keeps the canonical Synapsor capability name in tool metadata.
191
+ - `synapsor-runner mcp serve-http` is a small authenticated JSON-RPC bridge for
192
+ `tools/list`, `tools/call`, and `resources/read`. Use it only when you want a
193
+ simple app/server wrapper instead of full HTTP MCP.
194
+ - Direct SQL writeback creates or writes `synapsor_writeback_receipts` for
195
+ idempotency and replay. The trusted writer needs permission for that table,
196
+ or an administrator must pre-create it and grant access. Use an app-owned
197
+ `http_handler` or `command_handler` if Runner should not create receipt
198
+ tables in your application schema.
199
+ - Run `synapsor-runner doctor --config synapsor.runner.json --check-writeback`
200
+ after reviewing receipt-table DDL/grants to verify writer connectivity,
201
+ receipt-table permissions, and rollback-only target-table access. The probe
202
+ never mutates business rows, but it can create the receipt table if the
203
+ writer has permission.
204
+ - For app-owned `http_handler` executors, configure `signing_secret_env` to
205
+ have Runner sign writeback requests with `X-Synapsor-Signature`. Run
206
+ `synapsor-runner doctor --config synapsor.runner.json --check-handlers` to
207
+ check handler env vars and network reachability without applying a proposal.
208
+
92
209
  ## Connect Your Own Staging Database
93
210
 
94
211
  Put a read-only connection string in the environment:
@@ -101,17 +218,160 @@ For disposable dev RDS fixtures only, use `sslmode=no-verify` if your local
101
218
  Node/Postgres TLS stack cannot verify the test certificate chain. For real
102
219
  staging or production-like databases, keep certificate verification enabled.
103
220
 
104
- Inspect metadata:
221
+ Run the guided own-database path:
105
222
 
106
223
  ```bash
107
- npx -y -p @synapsor/runner@alpha synapsor-runner inspect \
108
- --engine auto \
224
+ npx -y -p @synapsor/runner synapsor-runner start \
109
225
  --from-env DATABASE_URL \
110
226
  --schema public
111
227
  ```
112
228
 
113
- Generate a reviewed read-only config first. The wizard creates this local
114
- flow:
229
+ `start --from-env` is the low-friction alias for `onboard db --from-env`. That
230
+ path inspects metadata, helps you choose one table/view, creates trusted
231
+ context bindings, generates semantic MCP tools, validates the tool boundary,
232
+ and prints the exact MCP/UI next commands. It does not require hand-authored
233
+ JSON. If you provide an optional real object id during the wizard, it also
234
+ writes `./.synapsor/smoke-input.json` so the first tool call can use an actual
235
+ row instead of guessed sample data. When the read URL env var and trusted
236
+ tenant/principal env vars are already set, onboarding also attempts that smoke
237
+ call immediately and stores the evidence/query audit in the local ledger. If
238
+ those env vars are missing, it prints the exact command to run after you set
239
+ them from `.env.example`.
240
+
241
+ The end-to-end shape is:
242
+
243
+ ```text
244
+ 1. Put your read-only DB URL in DATABASE_URL.
245
+ 2. Run start --from-env DATABASE_URL.
246
+ 3. Choose one table/view and the safe fields agents may see.
247
+ 4. Preview the generated capabilities.
248
+ 5. Serve them over MCP to Claude, Cursor, OpenAI Agents SDK, or your app.
249
+ 6. For writes, approve a proposal outside MCP before writeback.
250
+ ```
251
+
252
+ The generated config is just the safety contract. A small reviewed version
253
+ looks like this:
254
+
255
+ Bring the generated review-mode workspace up with one command:
256
+
257
+ ```bash
258
+ npx -y -p @synapsor/runner synapsor-runner up \
259
+ --serve \
260
+ --config ./synapsor.runner.json \
261
+ --store ./.synapsor/local.db
262
+ ```
263
+
264
+ `up` validates the config/store, summarizes model-facing tools, shows whether
265
+ proposal tools use direct SQL writeback or app-owned executors, checks active
266
+ store leases, and prints the next smoke, approve, apply, replay, UI, and doctor
267
+ commands. By default, `up` is guidance-only. Use `up --serve` to start the
268
+ standard Streamable HTTP MCP server after the checklist; use `--dry-run` to
269
+ rehearse without starting it. For app-owned executor configs, add
270
+ `--with-handler` to run the handler doctor before serving.
271
+
272
+ For CI, shell scripts, or an LLM driving the setup, use the prompt-free path:
273
+
274
+ ```bash
275
+ npx -y -p @synapsor/runner synapsor-runner onboard db \
276
+ --from-env DATABASE_URL \
277
+ --schema public \
278
+ --table invoices \
279
+ --mode review \
280
+ --tenant-column tenant_id \
281
+ --primary-key id \
282
+ --conflict-column updated_at \
283
+ --namespace billing \
284
+ --object-name invoice \
285
+ --id-arg invoice_id \
286
+ --visible-columns id,tenant_id,late_fee_cents,waiver_reason,updated_at \
287
+ --patch late_fee_cents=fixed:0,waiver_reason=arg:reason \
288
+ --patch-bounds late_fee_cents=0:5500 \
289
+ --write-url-env SYNAPSOR_DATABASE_WRITE_URL \
290
+ --yes
291
+ ```
292
+
293
+ If `--namespace` is omitted, Runner derives a namespace from the table name
294
+ instead of creating `source.*` tools. Use `--read-tool` and `--proposal-tool`
295
+ when you need exact model-facing names.
296
+
297
+ For app-owned writeback, replace `--write-url-env ...` with
298
+ `--writeback http_handler --handler-url-env APP_WRITEBACK_URL --emit-handler`.
299
+ Runner marks that source as read-only unless you explicitly pass a writer env,
300
+ so `config validate` does not warn that direct SQL writeback is disabled.
301
+ You can also pass `--answers ./answers.json --yes` for a fully declarative
302
+ setup file.
303
+
304
+ ```json
305
+ {
306
+ "version": 1,
307
+ "mode": "review",
308
+ "result_format": 2,
309
+ "sources": {
310
+ "app_postgres": {
311
+ "engine": "postgres",
312
+ "read_url_env": "DATABASE_URL",
313
+ "write_url_env": "SYNAPSOR_DATABASE_WRITE_URL"
314
+ }
315
+ },
316
+ "trusted_context": {
317
+ "provider": "environment",
318
+ "values": {
319
+ "tenant_id_env": "SYNAPSOR_TENANT_ID",
320
+ "principal_env": "SYNAPSOR_PRINCIPAL"
321
+ }
322
+ },
323
+ "capabilities": [
324
+ {
325
+ "name": "billing.inspect_invoice",
326
+ "kind": "read",
327
+ "source": "app_postgres",
328
+ "target": {
329
+ "schema": "public",
330
+ "table": "invoices",
331
+ "primary_key": "id",
332
+ "tenant_key": "tenant_id"
333
+ },
334
+ "args": {
335
+ "invoice_id": { "type": "string", "required": true }
336
+ },
337
+ "lookup": { "id_from_arg": "invoice_id" },
338
+ "visible_columns": ["id", "status", "late_fee_cents", "updated_at"],
339
+ "evidence": "required",
340
+ "max_rows": 1
341
+ },
342
+ {
343
+ "name": "billing.propose_late_fee_waiver",
344
+ "kind": "proposal",
345
+ "source": "app_postgres",
346
+ "target": {
347
+ "schema": "public",
348
+ "table": "invoices",
349
+ "primary_key": "id",
350
+ "tenant_key": "tenant_id"
351
+ },
352
+ "args": {
353
+ "invoice_id": { "type": "string", "required": true },
354
+ "reason": { "type": "string", "required": true }
355
+ },
356
+ "lookup": { "id_from_arg": "invoice_id" },
357
+ "visible_columns": ["id", "status", "late_fee_cents", "updated_at"],
358
+ "patch": {
359
+ "late_fee_cents": { "fixed": 0 },
360
+ "waiver_reason": { "from_arg": "reason" }
361
+ },
362
+ "allowed_columns": ["late_fee_cents", "waiver_reason"],
363
+ "conflict_guard": { "column": "updated_at" },
364
+ "approval": { "mode": "human", "required_role": "billing_lead" }
365
+ }
366
+ ]
367
+ }
368
+ ```
369
+
370
+ The agent sees `billing.inspect_invoice` and
371
+ `billing.propose_late_fee_waiver`. It does not see the database URL, writer
372
+ credential, raw SQL, approval command, or commit command.
373
+
374
+ The wizard creates this local flow:
115
375
 
116
376
  ```text
117
377
  trusted context -> capability -> MCP tool
@@ -119,10 +379,11 @@ trusted context -> capability -> MCP tool
119
379
 
120
380
  It asks which table/view backs the context, which tenant/scope column and
121
381
  backend session env vars are trusted, which fields are visible, and what
122
- semantic capability name to expose.
382
+ semantic capability name to expose. Before writing files, it shows a final
383
+ preview and lets you revise visible fields or capability names.
123
384
 
124
385
  ```bash
125
- npx -y -p @synapsor/runner@alpha synapsor-runner init \
386
+ npx -y -p @synapsor/runner synapsor-runner init \
126
387
  --wizard \
127
388
  --engine auto \
128
389
  --from-env DATABASE_URL \
@@ -133,15 +394,26 @@ npx -y -p @synapsor/runner@alpha synapsor-runner init \
133
394
  Preview and serve the semantic tools:
134
395
 
135
396
  ```bash
136
- npx -y -p @synapsor/runner@alpha synapsor-runner tools preview \
397
+ npx -y -p @synapsor/runner synapsor-runner tools preview \
137
398
  --config ./synapsor.runner.json \
138
399
  --store ./.synapsor/local.db
139
400
 
140
- npx -y -p @synapsor/runner@alpha synapsor-runner mcp serve \
401
+ npx -y -p @synapsor/runner synapsor-runner smoke call \
402
+ <generated.inspect_tool_name> \
403
+ --input ./.synapsor/smoke-input.json \
404
+ --config ./synapsor.runner.json \
405
+ --store ./.synapsor/local.db
406
+
407
+ npx -y -p @synapsor/runner synapsor-runner mcp serve \
141
408
  --config ./synapsor.runner.json \
142
409
  --store ./.synapsor/local.db
143
410
  ```
144
411
 
412
+ `smoke call` uses the same runtime as MCP, records evidence/query audit or a
413
+ proposal in the local store, and prints the evidence/proposal/replay commands
414
+ to inspect what happened. If you skipped the optional smoke input in the
415
+ wizard, pass `--json '{"<lookup_arg>":"<real_id>"}'` instead.
416
+
145
417
  ## Two Ways To Run MCP
146
418
 
147
419
  Use stdio when the MCP client runs locally and can launch Synapsor Runner. Use
@@ -156,26 +428,70 @@ synapsor-runner mcp serve \
156
428
  --store ./.synapsor/local.db
157
429
  ```
158
430
 
431
+ For OpenAI Agents SDK over stdio, add OpenAI-safe aliases:
432
+
433
+ ```bash
434
+ synapsor-runner mcp serve \
435
+ --config ./synapsor.runner.json \
436
+ --store ./.synapsor/local.db \
437
+ --alias-mode openai
438
+ ```
439
+
159
440
  App/server deployments:
160
441
 
161
442
  ```bash
162
443
  export SYNAPSOR_RUNNER_HTTP_TOKEN="dev-local-token"
163
444
 
445
+ synapsor-runner mcp serve-streamable-http \
446
+ --config ./synapsor.runner.json \
447
+ --store ./.synapsor/local.db \
448
+ --auth-token-env SYNAPSOR_RUNNER_HTTP_TOKEN \
449
+ --alias-mode openai
450
+ ```
451
+
452
+ You can also start the same review-mode server through the safer startup
453
+ checklist:
454
+
455
+ ```bash
456
+ synapsor-runner up --serve \
457
+ --config ./synapsor.runner.json \
458
+ --store ./.synapsor/local.db \
459
+ --auth-token-env SYNAPSOR_RUNNER_HTTP_TOKEN \
460
+ --alias-mode openai
461
+ ```
462
+
463
+ Equivalent unified command:
464
+
465
+ ```bash
466
+ synapsor-runner mcp serve \
467
+ --transport streamable-http \
468
+ --config ./synapsor.runner.json \
469
+ --store ./.synapsor/local.db \
470
+ --auth-token-env SYNAPSOR_RUNNER_HTTP_TOKEN \
471
+ --alias-mode openai
472
+ ```
473
+
474
+ Streamable HTTP defaults to `127.0.0.1:8766`, requires bearer auth by default,
475
+ and should use private networking, TLS, and rate limits before being exposed
476
+ beyond a local machine. With `--alias-mode openai`, tools are exposed to
477
+ the model as OpenAI-safe aliases such as `billing__inspect_invoice`; `_meta`
478
+ still includes `synapsor.canonical_tool_name = billing.inspect_invoice`, and
479
+ Runner routes calls back to the canonical Synapsor capability. Use
480
+ `--alias-mode both` during migrations if one client still expects canonical
481
+ dotted names while another needs OpenAI-safe aliases.
482
+
483
+ Bridge mode:
484
+
485
+ ```bash
164
486
  synapsor-runner mcp serve-http \
165
487
  --config ./synapsor.runner.json \
166
488
  --store ./.synapsor/local.db \
167
489
  --auth-token-env SYNAPSOR_RUNNER_HTTP_TOKEN
168
490
  ```
169
491
 
170
- HTTP defaults to `127.0.0.1:8765`, requires bearer auth by default, and should
171
- use private networking, TLS, and rate limits before being exposed beyond a
172
- local machine.
173
-
174
- HTTP alpha scope: `serve-http` is a JSON-RPC endpoint for `tools/list`,
175
- `tools/call`, and `resources/read`. It is not full MCP Streamable HTTP and does
176
- not implement `initialize`/SSE. If an SDK HTTP MCP client expects that
177
- handshake, use stdio mode or wrap the HTTP endpoint like the OpenAI HTTP
178
- example.
492
+ Bridge HTTP defaults to `127.0.0.1:8765` and supports only JSON-RPC
493
+ `tools/list`, `tools/call`, and `resources/read`. It does not implement MCP
494
+ Streamable HTTP `initialize`/session behavior.
179
495
 
180
496
  OpenAI Agents SDK examples:
181
497
 
@@ -195,6 +511,15 @@ Before asking an agent to solve a real task, confirm it can call a Runner tool:
195
511
  synapsor-runner tools preview --config ./synapsor.runner.json --store ./.synapsor/local.db
196
512
  ```
197
513
 
514
+ For OpenAI-facing clients:
515
+
516
+ ```bash
517
+ synapsor-runner tools preview \
518
+ --config ./synapsor.runner.json \
519
+ --store ./.synapsor/local.db \
520
+ --alias-mode openai
521
+ ```
522
+
198
523
  Then ask the agent:
199
524
 
200
525
  ```text
@@ -217,12 +542,25 @@ The disposable reference app includes proposal-first write examples for:
217
542
  Each tool creates evidence, a before/after diff, and a proposal. The source
218
543
  database remains unchanged until approval outside MCP and guarded writeback.
219
544
 
220
- For a longer local session, you can install the alpha package explicitly:
545
+ For a longer local session, you can install the package globally:
221
546
 
222
547
  ```bash
223
- npm install -g @synapsor/runner@alpha
548
+ npm install -g @synapsor/runner
224
549
  ```
225
550
 
551
+ ## Stable Compatibility Promise
552
+
553
+ Starting with `0.1.0`, Synapsor Runner keeps the documented `synapsor-runner`
554
+ binary, `synapsor.runner.json` schema version `1`, result envelope v2, stdio
555
+ MCP, Streamable HTTP MCP, MCP client snippets, proposal/approval/writeback
556
+ inspection commands, direct SQL writeback contract, and app-owned executor
557
+ contract compatible through the `0.1.x` line unless a release note marks a
558
+ deprecation first.
559
+
560
+ Stable does not mean production SLA, hosted Cloud features, compliance
561
+ certification, physical Postgres/MySQL branching, generic SQL writeback, or
562
+ support for undocumented local SQLite internals.
563
+
226
564
  ## Runtime Flow
227
565
 
228
566
  The local runner keeps the model-facing tool call separate from approval and
@@ -307,6 +645,8 @@ relying on `latest`:
307
645
 
308
646
  ```bash
309
647
  synapsor-runner activity search --tenant acme --object invoice:INV-3001
648
+ synapsor-runner events tail --store ./.synapsor/local.db
649
+ synapsor-runner events webhook --url http://127.0.0.1:8788/synapsor/events --kind proposal_created --store ./.synapsor/local.db
310
650
  synapsor-runner proposals list --tenant acme --object invoice:INV-3001 --status approved
311
651
  synapsor-runner evidence show ev_...
312
652
  synapsor-runner query-audit list --evidence ev_...
@@ -332,16 +672,24 @@ Create a redacted local diagnostic report:
332
672
 
333
673
  ```bash
334
674
  synapsor-runner doctor --config synapsor.runner.json --report --redact --output synapsor-doctor.md
675
+ synapsor-runner doctor --config synapsor.runner.json --check-writeback
335
676
  ```
336
677
 
337
678
  Inspect or compact the local ledger:
338
679
 
339
680
  ```bash
340
681
  synapsor-runner store stats --store ./.synapsor/local.db
682
+ synapsor-runner events tail --store ./.synapsor/local.db --follow
683
+ synapsor-runner events webhook --url-env SYNAPSOR_EVENT_WEBHOOK_URL --auth-token-env SYNAPSOR_EVENT_WEBHOOK_TOKEN --follow --store ./.synapsor/local.db
341
684
  synapsor-runner store vacuum --store ./.synapsor/local.db
342
685
  synapsor-runner store prune --store ./.synapsor/local.db --older-than 30d --dry-run
686
+ synapsor-runner store reset --store ./.synapsor/local.db --yes
343
687
  ```
344
688
 
689
+ `events webhook` is a local/dev/staging convenience for review UIs, Slack
690
+ bridges, or app-local notifications. It POSTs one redacted local event envelope
691
+ per lifecycle event; it is not a hosted central ledger.
692
+
345
693
  This is local indexed search for local/dev/staging usage. It is not external
346
694
  database time travel, not cross-runner search, and not hosted compliance
347
695
  retention.
@@ -353,6 +701,24 @@ your application service already owns business writes, configure an
353
701
  `http_handler` or `command_handler` executor. Approval still happens outside
354
702
  MCP, and the handler returns an applied/conflict/failed receipt for replay.
355
703
 
704
+ > **Important:** your app handler owns the final business write. Runner creates
705
+ > the proposal and calls your handler only after approval, but your handler must
706
+ > still enforce tenant/scope checks, expected-version or conflict guards,
707
+ > idempotency keys, allowed business actions, transaction/rollback, and safe
708
+ > error receipts. If you skip those checks, you can reintroduce cross-tenant
709
+ > writes, lost updates, or duplicate writes. Keep handler credentials out of MCP.
710
+
711
+ Starter handlers are included under `examples/app-owned-writeback`.
712
+ The packaged app-owned billing example also includes a bundled
713
+ `synapsor-handler.mjs` helper shim. There is no separate handler package to
714
+ install.
715
+ You can also generate a starter handler directly:
716
+
717
+ ```bash
718
+ npx -y -p @synapsor/runner synapsor-runner handler template node-fastify \
719
+ --output ./synapsor-writeback-handler.mjs
720
+ ```
721
+
356
722
  For direct SQL writeback, set the writer env var named by the source
357
723
  `write_url_env`, for example `SYNAPSOR_DATABASE_WRITE_URL`. Runner also creates
358
724
  or writes `synapsor_writeback_receipts` for idempotency/replay, so the writer
@@ -372,4 +738,4 @@ Synapsor DBMS, not a physical branch engine for Postgres/MySQL, and not a
372
738
  general MCP security platform.
373
739
 
374
740
  See the full repository README and docs for Docker demos, MCP client setup,
375
- configuration recipes, and security boundaries.
741
+ configuration recipes, security boundaries, and release notes.
package/dist/cli.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ import { type DbRowReader } from "@synapsor-runner/mcp-server";
2
3
  import { type WritebackJob } from "@synapsor-runner/protocol";
3
4
  import { type SchemaInspection } from "@synapsor-runner/schema-inspector";
4
5
  export declare function main(argv: string[]): Promise<number>;
@@ -7,6 +8,7 @@ export declare function runInitWizard(args: string[], options?: {
7
8
  ask?: WizardAsk;
8
9
  env?: NodeJS.ProcessEnv;
9
10
  inspection?: SchemaInspection;
11
+ readRow?: DbRowReader;
10
12
  stdout?: Pick<NodeJS.WriteStream, "write">;
11
13
  }): Promise<number>;
12
14
  export declare function resolveSqlWriteDatabaseUrl(job: WritebackJob, configPath: string, env: NodeJS.ProcessEnv): Promise<string>;
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AA8BA,OAAO,EAA6G,KAAK,YAAY,EAAwB,MAAM,2BAA2B,CAAC;AAC/L,OAAO,EAOL,KAAK,gBAAgB,EAEtB,MAAM,mCAAmC,CAAC;AA4H3C,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA8C1D;AA0DD,KAAK,SAAS,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAE9E,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,GAAE;IACP,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;CACvC,GACL,OAAO,CAAC,MAAM,CAAC,CAiLjB;AAsyCD,wBAAsB,0BAA0B,CAAC,GAAG,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAM/H"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAYA,OAAO,EAAqG,KAAK,WAAW,EAA2F,MAAM,6BAA6B,CAAC;AAmB3P,OAAO,EAA6G,KAAK,YAAY,EAAwB,MAAM,2BAA2B,CAAC;AAC/L,OAAO,EAOL,KAAK,gBAAgB,EAEtB,MAAM,mCAAmC,CAAC;AA4U3C,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAmD1D;AA+DD,KAAK,SAAS,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAE9E,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,GAAE;IACP,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;CACvC,GACL,OAAO,CAAC,MAAM,CAAC,CA2TjB;AAo7DD,wBAAsB,0BAA0B,CAAC,GAAG,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAM/H"}