@synapsor/runner 0.1.0-alpha.16 → 0.1.0-alpha.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/docs/README.md CHANGED
@@ -20,7 +20,7 @@ detail.
20
20
  capabilities, model-facing descriptions, result envelopes, trusted context,
21
21
  and writeback guards. JSON Schema:
22
22
  `../schemas/synapsor.runner.schema.json`.
23
- - [Result Envelope v2](result-envelope-v2.md): the opt-in
23
+ - [Result Envelope v2](result-envelope-v2.md): the generated-config default
24
24
  `ok`/`summary`/`data`/`proposal`/`error` response shape for MCP tools.
25
25
  - [Handler Helper](handler-helper.md): TypeScript helper for safe app-owned
26
26
  rich-write handlers.
@@ -60,8 +60,8 @@ detail.
60
60
  for approved proposals.
61
61
  - [App-Owned Executors](app-owned-executors.md): short entry point for rich
62
62
  business transactions handled by your app.
63
- - `synapsor-runner events tail`: local lifecycle events such as
64
- `proposal_created`, `proposal_approved`, `writeback_applied`, and
63
+ - `synapsor-runner events tail` and `events webhook`: local lifecycle events
64
+ such as `proposal_created`, `proposal_approved`, `writeback_applied`, and
65
65
  `writeback_conflict`.
66
66
 
67
67
  Useful examples:
@@ -13,6 +13,12 @@ Current alpha scope:
13
13
  business transactions;
14
14
  - stdio MCP, Streamable HTTP MCP, and a small JSON-RPC bridge.
15
15
 
16
+ Stable `0.1.x` compatibility, once `0.1.0` is promoted to `latest`, covers the
17
+ documented `synapsor-runner` binary, config schema version `1`, result envelope
18
+ v2 with v1 opt-out, stdio/Streamable HTTP MCP surfaces, documented MCP client
19
+ snippets, proposal/evidence/replay inspection commands, direct SQL writeback,
20
+ and app-owned executor contracts.
21
+
16
22
  Out of scope:
17
23
 
18
24
  - raw `execute_sql`;
@@ -179,7 +179,8 @@ The wizard:
179
179
  mode, semantic capability names, and proposal patch mappings;
180
180
  - asks review-mode users to choose direct guarded SQL writeback, an app-owned
181
181
  HTTP handler, or an app-owned command handler;
182
- - previews the MCP tools and what is not exposed;
182
+ - previews the MCP tools and what is not exposed, then lets you revise visible
183
+ fields or capability names before writing files;
183
184
  - attempts a first smoke call when you supplied a real object id and the
184
185
  required trusted env vars are present;
185
186
  - writes the generated config, `.env.example`, and MCP client snippets only
@@ -208,12 +209,17 @@ npx -y -p @synapsor/runner@alpha synapsor-runner init \
208
209
  --mode review \
209
210
  --visible-columns id,tenant_id,late_fee_cents,waiver_reason,updated_at \
210
211
  --allowed-columns late_fee_cents,waiver_reason \
211
- --patch-fixed late_fee_cents=0 \
212
- --patch-from-arg waiver_reason=reason \
213
- --numeric-bound late_fee_cents=0:5500 \
212
+ --tenant-column tenant_id \
213
+ --id-arg invoice_id \
214
+ --patch late_fee_cents=fixed:0,waiver_reason=arg:reason \
215
+ --patch-bounds late_fee_cents=0:5500 \
214
216
  --write-url-env SYNAPSOR_DATABASE_WRITE_URL
215
217
  ```
216
218
 
219
+ If you omit `--namespace`, Runner derives the namespace from the table name
220
+ instead of defaulting to `source.*`. Add `--read-tool` and `--proposal-tool`
221
+ when you want exact capability names in the generated contract.
222
+
217
223
  For app-owned writeback, replace the direct writer env with a handler executor:
218
224
 
219
225
  ```bash
@@ -225,13 +231,19 @@ npx -y -p @synapsor/runner@alpha synapsor-runner init \
225
231
  --namespace billing \
226
232
  --object-name invoice \
227
233
  --mode review \
228
- --patch-fixed late_fee_cents=0 \
229
- --patch-from-arg waiver_reason=reason \
234
+ --tenant-column tenant_id \
235
+ --id-arg invoice_id \
236
+ --patch late_fee_cents=fixed:0,waiver_reason=arg:reason \
230
237
  --writeback http_handler \
231
238
  --handler-url-env APP_WRITEBACK_URL \
232
- --handler-token-env APP_WRITEBACK_TOKEN
239
+ --handler-token-env APP_WRITEBACK_TOKEN \
240
+ --emit-handler
233
241
  ```
234
242
 
243
+ Handler-owned configs mark the Runner source as read-only unless you explicitly
244
+ pass `--write-url-env`, so `config validate` does not warn that direct SQL
245
+ writeback is disabled.
246
+
235
247
  Use `--writeback command_handler --handler-command-env APP_WRITEBACK_COMMAND`
236
248
  when your app-owned writer is a local command/script instead of HTTP.
237
249
 
@@ -244,8 +256,7 @@ npx -y -p @synapsor/runner@alpha synapsor-runner init \
244
256
  --namespace billing \
245
257
  --object-name invoice \
246
258
  --mode review \
247
- --patch-fixed late_fee_cents=0 \
248
- --patch-from-arg waiver_reason=reason
259
+ --patch late_fee_cents=fixed:0,waiver_reason=arg:reason
249
260
  ```
250
261
 
251
262
  The command uses inspected metadata for primary-key, tenant-key, conflict-column,
@@ -253,15 +264,15 @@ and default-visible-column suggestions. If a suggestion is ambiguous or missing,
253
264
  pass explicit flags such as `--primary-key`, `--tenant-key`, and
254
265
  `--conflict-column`.
255
266
 
256
- Review mode requires at least one explicit `--patch-fixed` or
257
- `--patch-from-arg` mapping. Use `--mode read_only` if you only want an inspect
258
- tool.
267
+ Review mode requires at least one explicit `--patch` mapping, or the older
268
+ `--patch-fixed` / `--patch-from-arg` flags. Use `--mode read_only` if you only
269
+ want an inspect tool.
259
270
 
260
271
  For bounded business actions, add reviewed value guards:
261
272
 
262
273
  ```bash
263
- --numeric-bound credit_cents=0:10000
264
- --transition-guard status=open:pending_review
274
+ --patch-bounds credit_cents=0:10000
275
+ --status-guards status=open:pending_review
265
276
  ```
266
277
 
267
278
  `--numeric-bound` keeps a proposed numeric column inside a fixed range before a
@@ -279,6 +290,7 @@ Create `onboarding-selection.json` from one table and one safe business action.
279
290
  "version": 1,
280
291
  "engine": "postgres",
281
292
  "mode": "review",
293
+ "result_format": 2,
282
294
  "read_url_env": "SYNAPSOR_DATABASE_READ_URL",
283
295
  "write_url_env": "SYNAPSOR_DATABASE_WRITE_URL",
284
296
  "schema": "public",
@@ -288,6 +300,8 @@ Create `onboarding-selection.json` from one table and one safe business action.
288
300
  "conflict_column": "updated_at",
289
301
  "namespace": "billing",
290
302
  "object_name": "invoice",
303
+ "read_tool": "billing.inspect_invoice",
304
+ "proposal_tool": "billing.propose_late_fee_waiver",
291
305
  "visible_columns": ["id", "tenant_id", "late_fee_cents", "waiver_reason", "updated_at"],
292
306
  "allowed_columns": ["late_fee_cents", "waiver_reason"],
293
307
  "patch": {
@@ -386,6 +400,20 @@ export SYNAPSOR_TENANT_ID="acme"
386
400
  export SYNAPSOR_PRINCIPAL="local_operator"
387
401
  export SYNAPSOR_RUNNER_HTTP_TOKEN="dev-local-token"
388
402
 
403
+ npx -y -p @synapsor/runner@alpha synapsor-runner up --serve \
404
+ --config ./synapsor.runner.json \
405
+ --store ./.synapsor/local.db \
406
+ --auth-token-env SYNAPSOR_RUNNER_HTTP_TOKEN
407
+ ```
408
+
409
+ `up --serve` runs the review-mode checklist first, then starts Streamable HTTP.
410
+ Use `--dry-run` for the checklist only, or `--with-handler` when the config uses
411
+ an app-owned executor and you want Runner to check the handler endpoint before
412
+ serving.
413
+
414
+ The lower-level MCP command starts the same transport directly:
415
+
416
+ ```bash
389
417
  npx -y -p @synapsor/runner@alpha synapsor-runner mcp serve-streamable-http \
390
418
  --config ./synapsor.runner.json \
391
419
  --store ./.synapsor/local.db \
@@ -48,7 +48,7 @@ request/receipt schema and the FastAPI template in `examples/app-owned-writeback
48
48
 
49
49
  The helper implementation exists in this source repo under `packages/handler`
50
50
  and is used by the app-owned executor example and tests. It is not published as
51
- a standalone `@synapsor/handler` npm package yet.
51
+ a standalone npm package yet.
52
52
 
53
53
  If you installed `@synapsor/runner` from npm, use one of these alpha paths:
54
54
 
@@ -57,10 +57,6 @@ If you installed `@synapsor/runner` from npm, use one of these alpha paths:
57
57
  - run `examples/mcp-postgres-billing-app-handler/`, which includes a bundled
58
58
  `synapsor-handler.mjs` shim inside the runner package.
59
59
 
60
- The `@synapsor/handler` import below is the source-checkout API and the planned
61
- standalone package API. Do not `npm install @synapsor/handler` until that
62
- package is published.
63
-
64
60
  ## Schemas
65
61
 
66
62
  Published schemas:
@@ -74,8 +70,12 @@ the alpha migration.
74
70
 
75
71
  ## TypeScript Usage From A Source Checkout
76
72
 
73
+ The source checkout has an internal helper under `packages/handler`. It is not
74
+ an npm install path. Import it by workspace-relative path while developing this
75
+ repository, or use the bundled example shim in the packaged runner.
76
+
77
77
  ```ts
78
- import { createWritebackHandler } from "@synapsor/handler";
78
+ import { createWritebackHandler } from "../packages/handler/src/index.js";
79
79
 
80
80
  export const handler = createWritebackHandler({
81
81
  tokenEnv: "SYNAPSOR_APP_HANDLER_TOKEN",
@@ -274,6 +274,7 @@ or prune it without touching your source Postgres/MySQL database:
274
274
  ```bash
275
275
  synapsor-runner store stats --store ./.synapsor/local.db
276
276
  synapsor-runner events tail --store ./.synapsor/local.db
277
+ synapsor-runner events webhook --url http://127.0.0.1:8788/synapsor/events --kind proposal_created --store ./.synapsor/local.db
277
278
  synapsor-runner store vacuum --store ./.synapsor/local.db
278
279
  synapsor-runner store prune --store ./.synapsor/local.db --older-than 30d --dry-run
279
280
  synapsor-runner store prune --store ./.synapsor/local.db --older-than 30d --yes
@@ -286,6 +287,11 @@ ledger, including proposal creation, approval/rejection, writeback jobs, and
286
287
  writeback applied/conflict/failed receipts. Add `--follow` to keep polling a
287
288
  running local store.
288
289
 
290
+ `events webhook` pushes the same local lifecycle events to a local/dev/staging
291
+ HTTP endpoint, one event envelope per POST. Use it for a review UI, Slack bridge,
292
+ or app-local notification path when polling is awkward. It is not a hosted
293
+ central ledger and does not expose database credentials.
294
+
289
295
  `store prune` defaults to dry-run. `store reset` requires `--yes` and removes
290
296
  only the local SQLite ledger files. MCP server modes write a small active-store
291
297
  lease next to the SQLite file; destructive store operations refuse while that
@@ -11,6 +11,46 @@ npx -y -p @synapsor/runner@alpha synapsor-runner demo --quick
11
11
  The OSS runner command is `synapsor-runner`. The `synapsor` command is reserved
12
12
  for the Synapsor Cloud CLI.
13
13
 
14
+ ## 0.1.0-alpha.17
15
+
16
+ ### Scripted Onboarding
17
+
18
+ - `onboard db` and `init` now have a prompt-free path for scripts, CI, and LLM
19
+ agents. Use `--yes`, `--non-interactive`, or `--answers <file.json>`.
20
+ - Added friendly flags that match the first-run mental model:
21
+ `--tenant-column`, `--id-arg`, `--patch column=fixed:value|arg:name`,
22
+ `--patch-bounds`, `--status-guards`, `--read-description`,
23
+ `--read-returns-hint`, `--read-tool`, `--proposal-tool`,
24
+ `--handler-output`, and `--emit-handler`.
25
+ - Answers-file onboarding writes the reviewed config, `.env.example`, MCP
26
+ snippets, and optional handler template without opening a TTY prompt.
27
+ - When `--namespace` is omitted, generated capability names now derive a
28
+ namespace from the selected table instead of falling back to `source.*`.
29
+ - The guided wizard now has a final "what I am about to write" preview where
30
+ users can revise visible fields or capability names before files are written.
31
+ - README Start Here now tells users to run `tools preview` and `smoke call`
32
+ before wiring an MCP client.
33
+ - `events webhook` / `events push` can POST local proposal/writeback lifecycle
34
+ events to a local/dev/staging HTTP endpoint for review UIs or notifications.
35
+
36
+ ### Writeback Readiness
37
+
38
+ - App-owned executor configs generated by Runner now mark the Runner source as
39
+ `read_only: true` when no writer env is supplied. `config validate` no longer
40
+ reports `WRITEBACK_DISABLED` for handler-owned writeback paths.
41
+ - Direct SQL review-mode proposals still surface `WRITEBACK_DISABLED` if the
42
+ source has no `write_url_env`, because Runner cannot apply those proposals
43
+ without a trusted writer connection.
44
+
45
+ ### Handler Docs
46
+
47
+ - README and runner README now include a short "How An External Handler Works"
48
+ section: agent proposes, human approves outside MCP, Runner POSTs to your
49
+ endpoint, and your code writes in its own transaction.
50
+ - Published docs/examples no longer include install-looking imports for a
51
+ separate handler package. Use `synapsor-runner handler template ...` or the
52
+ bundled `synapsor-handler.mjs` shim in the app-owned example.
53
+
14
54
  ## 0.1.0-alpha.16
15
55
 
16
56
  ### Review-Mode Bring-Up
@@ -20,17 +60,18 @@ for the Synapsor Cloud CLI.
20
60
  model-facing tools, identifies direct SQL versus app-owned executor writeback
21
61
  paths, and prints the next smoke, approval, apply, replay, UI, and doctor
22
62
  commands.
63
+ - `up` is guidance-only by default. `up --serve` starts the standard MCP
64
+ Streamable HTTP server after the same validation and guidance.
23
65
  - `up --dry-run` gives the full checklist without starting a server.
24
- - `up --transport streamable-http` starts the standard MCP Streamable HTTP
25
- server after the same validation and guidance.
26
- - `up --handler-check` runs the redacted handler env/reachability doctor path
27
- before serving.
66
+ - `up --handler-check` or `up --with-handler` runs the redacted handler
67
+ env/reachability doctor path before serving.
28
68
  - The guided wizard now writes model-facing capability descriptions,
29
- per-argument descriptions, returns hints, and can opt into
69
+ per-argument descriptions, returns hints, and defaults generated configs to
30
70
  `result_format: 2`.
31
71
  - `result_format: 2` gives MCP clients a stable envelope with `ok`, `summary`,
32
72
  `data`, `proposal`, `error`, `evidence`, `source_database_changed`, and
33
- `_meta.canonical_capability`.
73
+ `_meta.canonical_capability`. Pass `--result-format v1` or
74
+ `"result_format": 1` only when an older client needs the legacy shape.
34
75
  - `tools list`, `tools list --aliases`, and
35
76
  `mcp client-config --include-instructions` help users inspect exposed tools
36
77
  and generate client snippets without source reading.
@@ -57,10 +98,10 @@ for the Synapsor Cloud CLI.
57
98
 
58
99
  ### Handler Helper And Changelog Clarity
59
100
 
60
- - Public docs now state that `@synapsor/handler` is not published as a
61
- standalone npm package yet. The helper currently ships as source under
62
- `packages/handler` and as the bundled `synapsor-handler.mjs` shim in the
63
- app-owned executor example included with `@synapsor/runner`.
101
+ - Public docs now state that the handler helper is not a standalone npm package
102
+ yet. The helper currently ships as source under `packages/handler` and as the
103
+ bundled `synapsor-handler.mjs` shim in the app-owned executor example
104
+ included with `@synapsor/runner`.
64
105
  - `CHANGELOG.md` is included in the `@synapsor/runner` npm tarball.
65
106
 
66
107
  ## 0.1.0-alpha.13
@@ -194,6 +235,9 @@ for the Synapsor Cloud CLI.
194
235
  writeback jobs, execution receipts, and events.
195
236
  - `synapsor-runner events tail` prints local lifecycle events from the SQLite
196
237
  ledger and can follow new proposal/writeback events while a local flow runs.
238
+ - `synapsor-runner events webhook` pushes those local lifecycle events to a
239
+ local/dev/staging HTTP endpoint for review UIs or notifications without
240
+ polling. It is not a hosted central ledger.
197
241
  - MCP server modes write an active-store lease next to the local SQLite file.
198
242
  Destructive `store prune --yes` refuses while that lease points at a live
199
243
  process unless `--force` is provided.
@@ -243,13 +287,18 @@ changing. A stable `0.1.0` release should only be tagged after:
243
287
  For the local tarball before publish, run:
244
288
 
245
289
  ```bash
246
- ./scripts/verify-packed-runner.sh
247
- ./scripts/verify-packed-own-db.sh
290
+ ./scripts/verify-release-gate.sh
248
291
  ```
249
292
 
250
293
  After publishing an alpha, verify the public package from a clean temporary
251
294
  directory:
252
295
 
253
296
  ```bash
254
- ./scripts/verify-published-alpha.sh 0.1.0-alpha.16
297
+ VERIFY_PUBLISHED_ALPHA=1 ./scripts/verify-release-gate.sh 0.1.0-alpha.17
298
+ ```
299
+
300
+ After publishing/promoting stable `latest`, verify the stable channel:
301
+
302
+ ```bash
303
+ ./scripts/verify-published-stable.sh 0.1.0
255
304
  ```
@@ -5,7 +5,7 @@ or an exact version:
5
5
 
6
6
  ```bash
7
7
  npx -y -p @synapsor/runner@alpha synapsor-runner demo --quick
8
- npm install -g @synapsor/runner@0.1.0-alpha.16
8
+ npm install -g @synapsor/runner@0.1.0-alpha.17
9
9
  ```
10
10
 
11
11
  Do not rely on the untagged `latest` dist-tag until a stable release is
@@ -55,13 +55,35 @@ A stable `0.1.0` release should only be tagged after:
55
55
  - there are no known docs/code mismatches around transport, credentials,
56
56
  receipt tables, or handler expectations.
57
57
 
58
+ ## Stable Compatibility Promise
59
+
60
+ After `0.1.0` is promoted to the untagged `latest` dist-tag, Synapsor Runner
61
+ keeps these public surfaces compatible through the `0.1.x` line unless a
62
+ release note marks a deprecation first:
63
+
64
+ - the `synapsor-runner` binary name and README quickstart commands;
65
+ - `synapsor.runner.json` schema version `1` for documented fields;
66
+ - result envelope v2 for new configs, with the documented v1 opt-out;
67
+ - stdio MCP and Streamable HTTP MCP command surfaces;
68
+ - generated MCP client snippets for documented clients;
69
+ - proposal, approval, guarded writeback, receipt, evidence, query-audit, and
70
+ replay inspection commands;
71
+ - direct SQL writeback and app-owned executor contracts documented in README
72
+ and `docs/writeback-executors.md`.
73
+
74
+ Stable does not promise production SLA, hosted Cloud features, compliance
75
+ certification, physical Postgres/MySQL branching, generic SQL writeback,
76
+ generic multi-row writes, or compatibility for undocumented local SQLite
77
+ internals. Local store migrations may happen inside `0.1.x`, but documented CLI
78
+ inspection commands should remain the supported way to read the store.
79
+
58
80
  Serious alpha users should pin an exact alpha version in package.json, CI, and
59
81
  MCP client snippets. Use `@alpha` only when intentionally testing the moving
60
82
  preview channel.
61
83
 
62
84
  ## Result Envelope Migration
63
85
 
64
- `result_format: 2` is opt-in during alpha migration:
86
+ New `init` and `onboard db` configs default to:
65
87
 
66
88
  ```json
67
89
  {
@@ -69,32 +91,36 @@ preview channel.
69
91
  }
70
92
  ```
71
93
 
72
- or:
94
+ Existing hand-written configs without `result_format` keep the legacy runtime
95
+ default for compatibility. To force v2 or opt an older client back to v1, use:
73
96
 
74
97
  ```bash
75
98
  synapsor-runner mcp serve --result-format v2
76
99
  synapsor-runner mcp serve-streamable-http --result-format v2
100
+ synapsor-runner mcp serve --result-format v1
77
101
  ```
78
102
 
79
- v1 remains the default until the migration is explicitly called out in a future
80
- release note. v2 makes `ok` the only required branch point for MCP client code.
103
+ v2 makes `ok` the only required branch point for MCP client code. Do not remove
104
+ the v1 escape hatch until the stable compatibility policy says legacy result
105
+ shapes are no longer supported.
81
106
 
82
107
  ## Publish Checklist
83
108
 
84
109
  Before publishing a new alpha:
85
110
 
86
111
  ```bash
87
- corepack pnpm typecheck
88
- corepack pnpm exec vitest run packages/mcp-server/src/index.test.ts apps/runner/src/cli.test.ts
89
- ./scripts/verify-packed-runner.sh
90
- npm pack --dry-run
91
- git diff --check
112
+ ./scripts/verify-release-gate.sh
92
113
  ```
93
114
 
94
115
  After publishing:
95
116
 
96
117
  ```bash
97
- npm view @synapsor/runner@alpha version bin license
98
- npx -y -p @synapsor/runner@alpha synapsor-runner demo --quick --no-interactive
99
- npx -y -p @synapsor/runner@alpha synapsor-runner audit --example dangerous-db-mcp --format markdown
118
+ VERIFY_PUBLISHED_ALPHA=1 ./scripts/verify-release-gate.sh 0.1.0-alpha.17
119
+ ```
120
+
121
+ Before promoting `latest` to stable, bump and publish a non-prerelease version,
122
+ then verify the stable channel from a clean temporary directory:
123
+
124
+ ```bash
125
+ ./scripts/verify-published-stable.sh 0.1.0
100
126
  ```
@@ -144,5 +144,8 @@ INTERNAL
144
144
  ```
145
145
 
146
146
  Current alpha implementation redacts raw connection and driver messages from v2
147
- MCP results. Legacy result format v1 remains the default for compatibility in
148
- this alpha.
147
+ MCP results. New `init` and `onboard db` configs write `result_format: 2` by
148
+ default. Existing hand-written configs without `result_format` keep the legacy
149
+ runtime default for compatibility; pass `--result-format v2` when serving an
150
+ older config to force the v2 envelope, or `--result-format v1` for an older
151
+ client that still depends on the legacy shape.
@@ -56,7 +56,7 @@ Receipt the handler must return (today's status vocabulary, kept):
56
56
  ## Helper API (TypeScript — first-party, since the runner is TS/Node)
57
57
 
58
58
  ```ts
59
- import { createWritebackHandler } from "@synapsor/handler";
59
+ import { createWritebackHandler } from "../packages/handler/src/index.js";
60
60
 
61
61
  export const handler = createWritebackHandler({
62
62
  // 1. Authenticity: helper verifies bearer AND the HMAC signature for you.
@@ -15,7 +15,7 @@ The SQLite store is shared state, and the running server holds it open. Deleting
15
15
  Direct writeback does CREATE TABLE IF NOT EXISTS synapsor_writeback_receipts, which a least-privilege writer can't do (PG15+ no CREATE on public). Now documented, but doctor could detect it and print the exact GRANT/DDL (or a flag to pre-create). I had to invent the dedicated-schema trick myself.
16
16
 
17
17
  5. App-owned handlers re-implement security by hand.
18
- The executor contract is "match the example": you must re-check tenant, parse change_set, enforce the expected_version stale-row guard, and do idempotency yourself. It's easy to write an insecure handler (skip the version check, forget tenant scope). There's no handler SDK/helper and no request signing — the only auth is a bearer token, so the handler trusts the POST body's tenant/version. A @synapsor/handler helper (verify + parse + enforce guards, optional HMAC signature) would remove a whole class of mistakes.
18
+ The executor contract is "match the example": you must re-check tenant, parse change_set, enforce the expected_version stale-row guard, and do idempotency yourself. It's easy to write an insecure handler (skip the version check, forget tenant scope). There's no published handler SDK/helper and no request signing — the only auth is a bearer token, so the handler trusts the POST body's tenant/version. A first-party handler helper (verify + parse + enforce guards, optional HMAC signature) would remove a whole class of mistakes.
19
19
 
20
20
  6. Versioning discipline.
21
21
  @alpha is a moving tag and behavior changed meaningfully across alpha.6→11 (transport, arg types string→number, credential resolution). I had to pin and bump six times. A stable channel + changelog + semver promise is table stakes before serious devs build on it.
@@ -119,13 +119,5 @@ function writeJson(response, statusCode, body) {
119
119
  }
120
120
 
121
121
  async function loadHandlerHelper() {
122
- try {
123
- return await import("@synapsor/handler");
124
- } catch (workspaceError) {
125
- try {
126
- return await import(new URL("./synapsor-handler.mjs", import.meta.url));
127
- } catch {
128
- throw workspaceError;
129
- }
130
- }
122
+ return await import(new URL("./synapsor-handler.mjs", import.meta.url));
131
123
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synapsor/runner",
3
- "version": "0.1.0-alpha.16",
3
+ "version": "0.1.0-alpha.17",
4
4
  "description": "Commit-safe MCP runner for Postgres and MySQL agents",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -22,6 +22,8 @@
22
22
  "conflict_column": { "type": "string", "pattern": "^[A-Za-z_][A-Za-z0-9_]*$" },
23
23
  "namespace": { "type": "string", "pattern": "^[A-Za-z_][A-Za-z0-9_]*$" },
24
24
  "object_name": { "type": "string", "pattern": "^[A-Za-z_][A-Za-z0-9_]*$" },
25
+ "read_tool": { "type": "string", "pattern": "^[A-Za-z_][A-Za-z0-9_]*(\\.[A-Za-z_][A-Za-z0-9_]*)+$" },
26
+ "proposal_tool": { "type": "string", "pattern": "^[A-Za-z_][A-Za-z0-9_]*(\\.[A-Za-z_][A-Za-z0-9_]*)+$" },
25
27
  "inspect_tool_name": { "type": "string", "pattern": "^[A-Za-z_][A-Za-z0-9_]*(\\.[A-Za-z_][A-Za-z0-9_]*)+$" },
26
28
  "proposal_tool_name": { "type": "string", "pattern": "^[A-Za-z_][A-Za-z0-9_]*(\\.[A-Za-z_][A-Za-z0-9_]*)+$" },
27
29
  "inspect_description": { "type": "string", "minLength": 1 },
@@ -99,6 +99,9 @@
99
99
  "write_url_env": {
100
100
  "$ref": "#/$defs/env_name"
101
101
  },
102
+ "read_only": {
103
+ "type": "boolean"
104
+ },
102
105
  "statement_timeout_ms": {
103
106
  "type": "integer",
104
107
  "minimum": 1