@synapsor/runner 1.6.1 → 1.6.3

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 (53) hide show
  1. package/CHANGELOG.md +98 -3
  2. package/README.md +33 -19
  3. package/SECURITY.md +10 -2
  4. package/THREAT_MODEL.md +27 -4
  5. package/dist/authoring.mjs +53 -3
  6. package/dist/cli.d.ts +19 -2
  7. package/dist/cli.d.ts.map +1 -1
  8. package/dist/local-ui.d.ts +85 -1
  9. package/dist/local-ui.d.ts.map +1 -1
  10. package/dist/runner.mjs +33542 -20382
  11. package/dist/runtime.mjs +3581 -237
  12. package/dist/shadow.mjs +2423 -65
  13. package/docs/README.md +22 -2
  14. package/docs/agent-guided-setup.md +239 -0
  15. package/docs/approval-roles-and-operator-identity.md +353 -0
  16. package/docs/auto-boundary-and-scoped-explore.md +32 -6
  17. package/docs/capability-authoring.md +19 -0
  18. package/docs/current-scope.md +20 -1
  19. package/docs/cursor-plugin.md +2 -2
  20. package/docs/dsl-json-parity.md +75 -0
  21. package/docs/dsl-reference.md +10 -0
  22. package/docs/fresh-developer-usability.md +155 -80
  23. package/docs/getting-started-own-database.md +5 -4
  24. package/docs/guarded-crud-writeback.md +19 -0
  25. package/docs/guided-onboarding.md +331 -0
  26. package/docs/human-attention-notifications.md +367 -0
  27. package/docs/limitations.md +19 -3
  28. package/docs/local-mode.md +16 -2
  29. package/docs/migrating-to-synapsor-spec.md +38 -0
  30. package/docs/production.md +39 -0
  31. package/docs/release-notes.md +87 -4
  32. package/docs/runner-config-reference.md +132 -0
  33. package/docs/running-a-runner-fleet.md +16 -1
  34. package/docs/security-boundary.md +24 -0
  35. package/docs/store-lifecycle.md +20 -1
  36. package/docs/supervised-automatic-apply.md +267 -0
  37. package/docs/troubleshooting-first-run.md +35 -0
  38. package/examples/app-owned-writeback/command-handler.mjs +0 -0
  39. package/examples/fitflow-guided-onboarding/README.md +43 -0
  40. package/examples/fitflow-guided-onboarding/app/page.tsx +8 -0
  41. package/examples/fitflow-guided-onboarding/docker-compose.yml +16 -0
  42. package/examples/fitflow-guided-onboarding/package.json +18 -0
  43. package/examples/fitflow-guided-onboarding/prisma/schema.prisma +98 -0
  44. package/examples/fitflow-guided-onboarding/seed/postgres.sql +401 -0
  45. package/examples/mcp-postgres-billing-app-handler/scripts/run-demo.sh +0 -0
  46. package/examples/operator-oidc/issuer.mjs +188 -0
  47. package/examples/reference-support-billing-app/scripts/run-demo.sh +0 -0
  48. package/examples/support-billing-agent/scripts/run-demo.sh +0 -0
  49. package/examples/support-billing-agent/scripts/run-evaluation.sh +0 -0
  50. package/examples/support-plan-credit/README.md +6 -2
  51. package/package.json +11 -9
  52. package/schemas/schema-candidate-review.schema.json +42 -0
  53. package/schemas/synapsor.runner.schema.json +227 -4
@@ -1,6 +1,7 @@
1
1
  # Auto Boundary, Scoped Explore, And Protect
2
2
 
3
- Runner 1.6.0 adds a deterministic authoring path for a real application:
3
+ Runner 1.6.3 provides a deterministic, resumable authoring path for a real
4
+ application:
4
5
 
5
6
  ```text
6
7
  Connect staging
@@ -146,6 +147,22 @@ The immutable digest covers the reviewed resources, field permissions,
146
147
  relationships, scope, role posture, generation lock, compiler/spec version,
147
148
  profile, and every query/privacy budget. Model arguments cannot widen it.
148
149
 
150
+ ## Try Without An External MCP Host
151
+
152
+ Workbench can run the first safe read, bounded aggregate, and Protect flow
153
+ directly. The same authority is available through CLI Try:
154
+
155
+ ```bash
156
+ synapsor-runner try call --list --format json
157
+ synapsor-runner try explore --suggested --json
158
+ synapsor-runner try protect --name analytics.protected_analysis --json
159
+ ```
160
+
161
+ Cursor, Claude, Codex, and generic stdio are optional clients, not onboarding
162
+ dependencies. The packed FitFlow gate proves Workbench, CLI Try, and an
163
+ official-SDK generic stdio client produce the same bounded result and denial
164
+ behavior.
165
+
149
166
  ## Add The Authoring Tools To Cursor
150
167
 
151
168
  After activation, let Runner manage only its own project entry:
@@ -323,16 +340,25 @@ their previous startup, `doctor`, contract, and tool behavior.
323
340
 
324
341
  ## Verify The Reference Journey
325
342
 
326
- The packaged synthetic fixture is under `examples/auto-boundary-churn`.
343
+ The polished packed-artifact journey is under
344
+ `examples/fitflow-guided-onboarding`. The smaller
345
+ `examples/auto-boundary-churn` fixture remains a compatibility and focused
346
+ aggregate-security gate.
327
347
 
328
348
  From a source checkout:
329
349
 
330
350
  ```bash
331
351
  corepack pnpm test:auto-boundary-explore
332
352
  corepack pnpm test:auto-boundary-explore:packed
353
+ corepack pnpm test:guided-onboarding:packed
333
354
  ```
334
355
 
335
- The packed gate proves the PostgreSQL + Next.js + Prisma + Cursor-compatible
336
- MCP + Workbench flow, all aggregate denial/suppression/budget checks, Protect,
337
- production Explore absence, protected-capability survival, durable redacted
338
- audit, and an unchanged source database.
356
+ The packed gates prove the PostgreSQL + Next.js + Prisma + Workbench flow,
357
+ host-neutral CLI/generic-stdio parity, all aggregate
358
+ denial/suppression/budget checks, Protect, production Explore absence,
359
+ protected-capability survival, guided proposal/apply/compensation, verified
360
+ OIDC roles, durable redacted audit, and unchanged source data before every
361
+ authorized mutation.
362
+
363
+ For the timed first-read, Explore, Protect, proposal, and writeback walkthrough,
364
+ use [Database To First Safe Tool](guided-onboarding.md).
@@ -118,6 +118,24 @@ CREATE CAPABILITY billing.propose_late_fee_waiver
118
118
  END
119
119
  ```
120
120
 
121
+ `billing_lead` is a Synapsor contract role, not a database role or secret. For
122
+ shared or production operation, Runner must resolve that exact role from a
123
+ freshly verified operator identity and separately authorize apply. See
124
+ [Approval Roles And Verified Operator
125
+ Identity](approval-roles-and-operator-identity.md).
126
+
127
+ Manual apply remains the default. For an eligible direct single-row
128
+ INSERT/UPDATE, a reviewer may additionally place this clause before `END`:
129
+
130
+ ```sql
131
+ ALLOW SUPERVISED WORKER APPLY
132
+ ```
133
+
134
+ It grants only contract-side permission and becomes part of the exact contract
135
+ digest. Automatic execution still requires an independent deployment allowlist
136
+ for that capability and digest; see [Operator-Supervised Automatic
137
+ Apply](supervised-automatic-apply.md).
138
+
121
139
  Compile and validate:
122
140
 
123
141
  ```bash
@@ -229,6 +247,7 @@ reviewed runner JSON capabilities. Current parity:
229
247
  | proposal weak `conflict_guard` | `CONFLICT GUARD WEAK ROW HASH ACKNOWLEDGED` | 1.4.4 | Explicit legacy escape hatch for an ordinary single-row source-DB UPDATE only. It hashes the captured projection and may miss concurrent changes outside that projection. It is rejected for DELETE, reversible writes, bounded sets, and Runner-ledger authority. |
230
248
  | proposal `approval` | `APPROVAL ROLE billing_lead` | 0.1 | Local mode records the required role; enforcement is still outside the model-facing MCP tool. |
231
249
  | proposal `approval.required_approvals` | `REQUIRE 2 APPROVALS` | 1.1 | Optional 1..10 distinct-reviewer quorum; defaults to 1. |
250
+ | proposal `execution.supervised_worker` | `ALLOW SUPERVISED WORKER APPLY` | 1.6 | Optional contract-side permission for eligible trusted-worker apply. It does nothing without a separate exact-digest deployment allowlist; old auto-approved proposals remain manual-apply. |
232
251
  | proposal `writeback` | `WRITEBACK DIRECT SQL`, `WRITEBACK APP HANDLER EXECUTOR name`, `WRITEBACK CLOUD WORKER`, `WRITEBACK NONE` | 0.1.7 | Handler URLs/tokens stay in `synapsor.runner.json`; contracts carry only the handler name. |
233
252
  | proposal `reversibility` | `REVERSIBLE` | 1.4 | Direct SQL only. Captures a bounded inverse after unambiguous apply; operator `revert` creates a new independently approved proposal. |
234
253
  | evidence options | `REQUIRE EVIDENCE` | 0.1 | Detailed evidence sources/handle prefixes are not expressible in DSL yet; use embedded JSON or generated contract JSON for those. |
@@ -2,9 +2,12 @@
2
2
 
3
3
  The canonical scope page is [Current Limitations](limitations.md).
4
4
 
5
- Current `1.6` scope:
5
+ Current `1.6.3` scope:
6
6
 
7
7
  - local semantic MCP tools over Postgres/MySQL without raw SQL tools;
8
+ - one-command, resumable, review-by-exception onboarding from
9
+ `DATABASE_URL` to a real safe read, bounded exploration, protected named
10
+ tools, guided write proposals, and host-neutral MCP client setup;
8
11
  - deterministic whole-schema Auto Boundary drafting from database metadata,
9
12
  statically parsed Prisma/Drizzle schemas, OpenAPI documents, and existing
10
13
  Synapsor definitions;
@@ -23,6 +26,10 @@ Current `1.6` scope:
23
26
  generated authority explicitly bound to a generation lock;
24
27
  - trusted context from environment, verified HTTP claims, Cloud sessions, or
25
28
  explicit development-only static values;
29
+ - verified operator decisions through signed local keys or external OIDC/JWKS
30
+ identity, with exact contract-role matching, token-time/issuer/audience
31
+ checks, immutable decision evidence, key rotation, and independent approval
32
+ and apply authority;
26
33
  - evidence handles, normalized query audit, proposals, receipts, local replay,
27
34
  and read-only lifecycle inspection without copying proposal ids;
28
35
  - optional proposal/evidence freshness: live target and declared same-source
@@ -34,6 +41,15 @@ Current `1.6` scope:
34
41
  and protocol-v3 exact receipts;
35
42
  - opt-in reviewed compensation for supported direct SQL changes, using a
36
43
  separate operator proposal and protocol-v4 receipt;
44
+ - default-off operator-supervised automatic apply for exact-digest,
45
+ contract-permitted single-row INSERT/UPDATE capabilities, with an independent
46
+ deployment allowlist, fenced worker leases, policy/limit/freshness/source
47
+ revalidation, hardened writer-posture checks, and explicit UNKNOWN
48
+ reconciliation;
49
+ - durable redacted proposal/worker/boundary/policy attention events, a
50
+ coalesced no-ID Workbench inbox, quiet per-sink routing and digests, JSONL
51
+ development output, signed generic HTTPS webhooks, and an optional
52
+ exact-capability supervision-sink health gate;
37
53
  - safety-wrapped app-owned `http_handler` and `command_handler` executors for
38
54
  richer approved business transactions;
39
55
  - stdio MCP, authenticated Streamable HTTP MCP, and a legacy JSON-RPC bridge;
@@ -63,6 +79,9 @@ Out of scope:
63
79
  - general join planning, many-to-many exploration, arbitrary formulas,
64
80
  functions, windows, `HAVING`, subqueries, or statistical privacy guarantees;
65
81
  - model-selected tenant/principal, activation, approval, or commit authority;
82
+ - automatic worker execution for DELETE, reversible changes, set writes,
83
+ app-owned/external effects, or capabilities without deterministic
84
+ single-row conflict/deduplication and receipt guarantees;
66
85
  - UPSERT, DDL, free-form predicates, unbounded writes, or cross-table direct
67
86
  transactions;
68
87
  - strict atomic freshness for app-owned handlers, APIs, or cross-source
@@ -19,7 +19,7 @@ claim that Cursor Marketplace review has completed.
19
19
 
20
20
  ## What the plugin installs
21
21
 
22
- - one production stdio MCP server pinned to `@synapsor/runner@1.6.1`;
22
+ - one production stdio MCP server pinned to `@synapsor/runner@1.6.2`;
23
23
  - one `/synapsor-protect` agent command;
24
24
  - one discoverable Safe Action skill;
25
25
  - one file-scoped rule for `synapsor/actions/**/*.ts`;
@@ -80,7 +80,7 @@ Required listing media:
80
80
 
81
81
  ## Submission checklist
82
82
 
83
- - [ ] Runner 1.6.1 package and plugin version agree.
83
+ - [ ] Runner 1.6.2 package and plugin version agree.
84
84
  - [ ] `corepack pnpm verify:cursor-plugin` passes from a clean checkout.
85
85
  - [ ] Plugin is manually loaded in current stable Cursor at workspace scope.
86
86
  - [ ] `/synapsor-protect` drafts and validates without activation.
@@ -0,0 +1,75 @@
1
+ # DSL / JSON Parity Matrix
2
+
3
+ Status: Synapsor contract `0.1`.
4
+
5
+ `@synapsor/spec` is the canonical contract. `@synapsor/dsl` is an authoring
6
+ layer that compiles into that JSON. `@synapsor/runner` and Synapsor Cloud should
7
+ consume the same contract shape instead of inventing separate semantics.
8
+
9
+ Author DSL files as `contract.synapsor.sql` when possible so editors provide
10
+ generic SQL highlighting. The legacy `contract.synapsor` suffix remains
11
+ supported, and both filenames compile to the same canonical JSON.
12
+
13
+ Legend:
14
+
15
+ - Supported: validated and preserved.
16
+ - Enforced: runtime checks the field before exposing or applying behavior.
17
+ - Preview: accepted as a contract declaration, but not a full local runtime
18
+ engine.
19
+ - Not supported: fails clearly or is documented as intentionally absent.
20
+
21
+ | Field / semantic | JSON spec | DSL syntax | Compile output | Runner load | Runner enforcement | C++/Cloud import/export | Cloud push | Tests / notes |
22
+ | --- | --- | --- | --- | --- | --- | --- | --- | --- |
23
+ | Context names | Supported | `CREATE AGENT CONTEXT` | Supported | Supported | Referenced by capabilities/workflows | Supported | Supported | Spec, DSL, runner, C++ fixtures |
24
+ | Capability names | Supported | `CREATE CAPABILITY` | Supported | Supported | Exposed as semantic MCP tools | Supported | Supported | Raw SQL/approval/commit tools remain absent |
25
+ | Workflow names | Supported | `CREATE AGENT WORKFLOW` | Supported | Loaded as declaration | Preview only; runner does not execute full DAGs | Supported as declaration | Supported | Do not claim workflow DAG execution |
26
+ | Policy names | Supported | Approval policy emitted by `AUTO APPROVE WHEN` | Preserved where represented | Loaded | Limited/local | Supported/preserved or rejected clearly | Supported | Rich policy packs are Cloud/paid surface |
27
+ | Contract description | Supported in `metadata.description` | Via metadata/examples | Preserved | Preserved | Not behavior-affecting | Supported | Supported | Useful for registry display |
28
+ | Context description | Supported | Preview/partial | Preserved when present | Preserved | Not behavior-affecting | Supported | Supported | Unknown fields fail unless extension-prefixed |
29
+ | Capability description | Supported | `DESCRIPTION '...'` | Supported | Tool metadata | Model-facing description | Supported | Supported | CLI tests inspect generated metadata |
30
+ | Argument description | Supported | `ARG ... DESCRIPTION '...'` | Supported | Input schema | Model-facing schema | Supported | Supported | Required args validated |
31
+ | Returns hint | Supported as `returns_hint` | `RETURNS HINT '...'` | Supported | Tool metadata | Model-facing output guidance | Supported | Supported | Strict DSL warns when missing on proposals |
32
+ | Arg name/type/required | Supported | `ARG name TYPE REQUIRED` | Supported | Input schema | Required/type validation | Supported | Supported | Model trust args rejected |
33
+ | Primary-key lookup | Supported as `lookup.id_from_arg` | `LOOKUP arg BY primary_key` | Supported; non-primary columns fail | Loaded | One fixed primary-key row | Supported | Supported | Compiler rejects `LOOKUP_COLUMN_UNSUPPORTED` rather than rewriting intent |
34
+ | Arg max length | Supported | `MAX LENGTH n` | Supported | Input schema | Enforced where runtime has input schema checks | Supported | Supported | String patterns are not yet supported |
35
+ | Arg numeric bounds | Supported | `ARG amount NUMBER MIN n MAX m` and `BOUND field n..m` | Supported | Input schema/proposal metadata | Enforced before proposal/apply where patch binding is known | Supported | Supported | Numeric-bounds fixture |
36
+ | Arg enum | Supported in JSON | Not expressible in DSL 0.1 | Preserved if in JSON | Loaded into schema | Enforced by schema validation where present | Supported/rejected clearly by validator | Supported | Use canonical JSON when an enum is required |
37
+ | Defaults / nullable | Not stable in 0.1 | Not supported | Fails as unknown core fields | Not supported | Not supported | Rejected unless extension-prefixed | Rejected | Avoid implying defaulted args |
38
+ | Visible fields | Supported | `ALLOW READ ...` | Supported | Read/proposal field map | Only visible fields can be returned | Supported | Supported | Kept-out overlap rejected |
39
+ | Kept-out fields | Supported | `KEEP OUT ...` | Supported | Hidden from tool schemas/results | Must not leak into evidence/replay/proposal surfaces | Supported | Supported | Kept-out conformance fixture |
40
+ | Hidden/model-forbidden fields | Represented by kept-out/trusted bindings | `KEEP OUT`, trusted context bindings | Supported | Supported | Raw table/column args rejected | Supported | Supported | No raw table/column model args |
41
+ | Session/tenant/principal bindings | Canonical `SESSION` plus `ENVIRONMENT`, `HTTP_CLAIM`, `CLOUD_SESSION`, and `STATIC_DEV` | `BIND ... FROM source`, `TENANT BINDING`, `PRINCIPAL BINDING` | Preserved; `--target runner` rejects `SESSION` | Runner rejects `SESSION`; implemented providers load normally | Model cannot supply tenant/principal authority; verified HTTP/Cloud claims remain distinct from process environment | C++/Cloud implements typed `SESSION` | Supported as canonical content | Runner commands fail `SESSION_BINDING_UNSUPPORTED`; no environment fallback |
42
+ | Evidence required | Supported | `REQUIRE EVIDENCE` | Supported | Loaded | Evidence/query audit recorded by runner flows | Supported | Supported | Read/proposal fixtures |
43
+ | Evidence options | Supported as `sources`, `query_audit`, `handle_prefix` | Partial | Preserved when present | Loaded | Query audit/evidence handles where supported | Supported/preserved | Supported | More DSL clauses may be added later |
44
+ | Proposal action | Supported | `PROPOSE ACTION ...` | Supported | Loaded | Proposal created instead of commit | Supported | Supported | Proposal conformance fixture |
45
+ | Allowed write fields | Supported | `ALLOW WRITE ...` | Supported | Loaded | Apply rejects widening beyond reviewed fields | Supported | Supported | Contract-authored apply regression |
46
+ | Patch bindings | Supported | `PATCH field = value/ARG arg` | Supported | Loaded | Direct SQL/app handler payload generation | Supported | Supported | Direct/app-handler tests |
47
+ | Numeric proposal bounds | Supported | `BOUND field min..max` | Supported | Loaded | Out-of-bounds proposals rejected | Supported | Supported | Numeric-bounds rejection test |
48
+ | Transition guards | Supported in JSON | `TRANSITION ...` preview | Preserved | Loaded | Enforced only where runner has enough current-row state | Supported/preserved | Supported | Metadata preservation test |
49
+ | Approval requirement | Supported | `APPROVAL ROLE ...` | Supported | Loaded | Approval remains outside MCP | Supported | Supported | No model-facing approve tool |
50
+ | Approval policy | Supported | `AUTO APPROVE WHEN field <= integer` after `APPROVAL ROLE` | Emits `approval.mode=policy`, `approval.policy`, and `policies[]` approval rules | Loaded | Runner may auto-approve; manual apply remains the default. A separate trusted worker may apply only under the exact-digest dual opt-in below. | Must preserve `approval.policy` and `policies[]` | Supported | Auto-approval conformance fixture |
51
+ | Supervised-worker permission | Optional, default-deny `proposal.execution.supervised_worker = "allowed"` | `ALLOW SUPERVISED WORKER APPLY` | Emits only the contract-side permission | Loaded | Applies nothing by itself. Eligible single-row INSERT/UPDATE may be consumed only when a separate deployment allowlist matches the exact active digest; all guarded checks run again. | Canonical field must be preserved; Cloud/C++ execution is not implied | Registry may preserve; execution support is local Runner-specific | Existing contracts without the field retain their normalization, digest, and manual-apply behavior |
52
+ | Writeback direct SQL | Supported | `WRITEBACK DIRECT SQL` | Supported | Loaded | Guarded single-row INSERT/UPDATE/DELETE | New operation fields require independent Cloud/C++ adoption | New operation fields require independent Cloud/C++ adoption | `test:guarded-crud` on Postgres/MySQL |
53
+ | Bounded set writeback | Supported as operation cardinality, typed selection/batch, row/value caps | `UPDATE|DELETE SET`, fixed `SELECT WHERE`, `INSERT SET`, typed `ITEM FIELD`, `MAX ROWS`, `MAX TOTAL` | Supported | Supported | Fixed/frozen/atomic Postgres/MySQL execution; human approval only; hard cap 100 | Not claimed until independently implemented and verified | Registry may preserve; execution support not claimed | R1-R7 conformance plus `test:bounded-set` |
54
+ | Reviewed reversibility | Supported as `proposal.reversibility.mode = reviewed_inverse` | `REVERSIBLE` | Supported | Supported | Direct SQL only; bounded inverse after unambiguous apply; operator revert creates a new proposal; no model-facing rollback | Canonical field must be preserved; Cloud/C++ execution not claimed until independently verified | Registry may preserve; execution support not claimed | Reversible-change-set conformance plus `test:reversible` |
55
+ | Writeback handler | Supported | `WRITEBACK APP HANDLER EXECUTOR name` | Supported | Loaded | Runner POSTs approved proposal to configured executor | Supported as contract intent | Supported | Handler URL/token stay in runner config, not contract |
56
+ | Idempotency metadata | Supported where represented | Limited | Preserved if present | Loaded | Receipts/idempotency guard local writes | Supported/preserved | Supported | Do not store credentials |
57
+ | x-cloud-* extensions | Supported in documented object locations | Not first-class syntax; JSON preserved | Preserved if present | Loaded/preserved | Not behavior unless known | Preserved or rejected clearly | Supported | Unknown unprefixed fields fail |
58
+ | x-runner-* extensions | Supported | Not first-class syntax; JSON preserved | Preserved if present | Loaded/preserved | Runner-specific where documented | Preserved | Supported | Keep separate from core semantics |
59
+ | x-experimental-* extensions | Supported | Not first-class syntax; JSON preserved | Preserved if present | Loaded/preserved | Experimental only | Preserved | Supported | Do not market as stable |
60
+ | Generated pseudo-syntax | Not supported | `ROOT EXTERNAL`, `JOIN EXTERNAL`, `RETURN ANSWER WITH CITATIONS`, `AUTO MERGE` fail | Fails clearly | Not loaded | Not applicable | Rejected unless promoted to spec | Rejected | These are not public 0.1 DSL |
61
+ | Cloud push dry-run | N/A | N/A | Normalized payload | N/A | No network call | N/A | Supported | `cloud push --dry-run --json` |
62
+ | Cloud push upload | N/A | N/A | Normalized payload POST | N/A | N/A | Cloud validates server-side | Supported | `/v1/control/projects/:project_id/agent-contracts` |
63
+ | Cloud registry versioning | N/A | N/A | N/A | N/A | N/A | Project-scoped registry | Supported | Identical digest is idempotent; changed digest creates new version |
64
+ | Runner bundle export | N/A | N/A | N/A | N/A | N/A | Backend bundle endpoint | Supported as backend foundation | Includes placeholders only, no secrets |
65
+
66
+ ## Current Intentional Limits
67
+
68
+ The runner can declare workflows in contracts, but it does not execute full
69
+ workflow DAGs, settlement policies, native Synapsor branches, or auto-merge
70
+ logic locally. Those remain Cloud/C++ platform features unless separately
71
+ implemented in the OSS runtime.
72
+
73
+ Contracts must not contain database URLs, API tokens, private keys, passwords,
74
+ or row data. Local runner config stores environment variable names. Cloud push
75
+ stores normalized contract JSON and audit metadata only.
@@ -389,6 +389,7 @@ patched column. Values may be identifiers or quoted strings.
389
389
  AUTO APPROVE WHEN amount_cents <= 2500
390
390
  LIMIT 20 PER DAY
391
391
  LIMIT TOTAL 100000 PER DAY
392
+ ALLOW SUPERVISED WORKER APPLY
392
393
  WRITEBACK DIRECT SQL
393
394
  ```
394
395
 
@@ -422,6 +423,15 @@ leaves the proposal in `pending_review` and records
422
423
  `policy_auto_approval_deferred` with observed, proposed, and projected values.
423
424
  It does not reject or auto-apply the proposal.
424
425
 
426
+ `ALLOW SUPERVISED WORKER APPLY` is an optional contract-side execution
427
+ permission. It compiles to
428
+ `execution: { "supervised_worker": "allowed" }` and changes the contract
429
+ digest. It does not start a worker or turn `AUTO APPROVE` into auto-apply.
430
+ Runner also requires a deployment allowlist for the exact capability/digest
431
+ and accepts only the narrower eligible single-row direct INSERT/UPDATE shapes.
432
+ See [Operator-Supervised Automatic
433
+ Apply](supervised-automatic-apply.md).
434
+
425
435
  Writeback forms:
426
436
 
427
437
  | Clause | Meaning |
@@ -1,110 +1,185 @@
1
1
  # Fresh-Developer Usability Protocol
2
2
 
3
- Use this protocol with five developers who have not previously used Synapsor.
4
- It is a launch gate, not an automated test. A maintainer may rehearse the
5
- protocol, but must not report a participant result unless that person actually
6
- completed the session.
3
+ This is the owner-observation script for Runner 1.6.3. Give it to a
4
+ database-familiar developer who has not used Synapsor. Automated tests prove
5
+ the mechanics; this protocol checks whether the product is understandable.
6
+
7
+ Do not report a participant result unless that person actually completed the
8
+ session.
7
9
 
8
10
  ## Goal
9
11
 
10
- Measure whether a developer can connect an existing supported staging project,
11
- draft one disabled Safe Action with a coding agent, receive an exact Data PR,
12
- approve outside the agent, and find the guarded receipt without learning the
13
- canonical JSON or SQL-like DSL first.
12
+ Starting from an empty directory and a synthetic or disposable staging
13
+ database, the participant should reach:
14
+
15
+ ```text
16
+ Connect -> Review -> Try -> Explore -> Protect -> Propose
17
+ ```
18
+
19
+ They must do so without raw SQL, hand-authored config/DSL/JSON/DDL, an account,
20
+ Cloud, Cursor, a model key, or maintainer instruction.
14
21
 
15
- Measure product time separately from the initial package download. Start the
16
- product timer only after `synapsor-runner --version` succeeds.
22
+ Measure product time separately from initial npm download. Start the timer
23
+ after this succeeds:
17
24
 
18
- ## Participant Setup
25
+ ```bash
26
+ npx -y @synapsor/runner@latest --version
27
+ ```
28
+
29
+ ## Setup
19
30
 
20
- Provide each participant with:
31
+ Provide:
21
32
 
22
- - a fresh clone of their application or the support-plan-credit reference app;
23
33
  - Node 22.13 or newer;
24
- - a disposable Postgres staging database and least-privilege read/write roles;
25
- - exported database URLs and trusted tenant/principal values;
26
- - current stable Cursor, with no existing Synapsor configuration;
27
- - the README only. Do not give verbal product-architecture instruction.
28
-
29
- Never use production credentials or data. Record the OS, Node version, Cursor
30
- version, package-install method, database engine, and whether the package was
31
- already cached.
32
-
33
- ## Tasks
34
-
35
- Ask the participant to complete these tasks without a maintainer taking control:
36
-
37
- 1. Run the four-second synthetic proof and identify whether the model can call
38
- `approve`, `apply`, `commit`, or raw SQL.
39
- 2. Connect the staging project and confirm the trusted organization scope.
40
- 3. Tell Cursor one business action to make safe and use the generated
41
- `/synapsor-protect` path or exact fallback prompt.
42
- 4. Find the disabled action file and explain why editing it does not activate a
43
- tool.
44
- 5. Open the Workbench effect preview and confirm the source row is unchanged.
45
- 6. Explicitly activate the reviewed digest through the operator-controlled UI.
46
- 7. Reconnect Cursor if instructed and create one proposal through the semantic
47
- tool.
48
- 8. Review the exact before/after Data PR, approve outside Cursor, and apply it.
49
- 9. Locate the receipt/replay record and explain what happens on retry.
50
- 10. Draft a second disabled action without changing the active tool surface.
51
-
52
- Do not rescue a participant until they have been blocked for two minutes. Record
53
- the exact screen, command, wording, or missing prerequisite that blocked them.
34
+ - the packaged synthetic FitFlow fixture or equivalent disposable staging
35
+ Postgres;
36
+ - an exported `DATABASE_URL` using a SELECT-only, non-owner role;
37
+ - exported synthetic `SYNAPSOR_TENANT_ID` and `SYNAPSOR_PRINCIPAL`;
38
+ - the README only;
39
+ - no existing Synapsor project files.
54
40
 
55
- ## Measurements
41
+ Never use production credentials or data. Record OS, Node version, package
42
+ cache state, database engine, and whether an external document was opened.
56
43
 
57
- For each participant, record:
44
+ ## Participant Prompt
58
45
 
59
- | Measure | Target |
60
- | --- | --- |
61
- | Installed CLI to first own-data Data PR | under 5 minutes |
62
- | Installed CLI to first guarded receipt | under 8 minutes |
63
- | Second disabled action draft after setup | under 2 minutes |
64
- | Second action ready for explicit activation | under 5 minutes |
65
- | Handwritten canonical JSON or DSL | none on the happy path |
66
- | Extra CLI command after Cursor proposal call | none |
67
- | Unsafe authority exposed to Cursor | none |
46
+ Say only:
47
+
48
+ ```text
49
+ Set up Synapsor for this staging application. Reach one safe read, ask one
50
+ bounded aggregate question you have not seen before, protect that analysis as
51
+ a reusable tool, and create one safe write proposal. Explain what the model can
52
+ and cannot do as you go.
53
+ ```
68
54
 
69
- Also record every wrong turn, maintainer intervention, misunderstood trust
70
- boundary, and request for a model-provider key or Synapsor account.
55
+ Do not explain Synapsor’s architecture first.
71
56
 
72
- ## Pass Criteria
57
+ ## Starting Command
73
58
 
74
- The launch gate passes only when all five participants:
59
+ The participant should find and run:
75
60
 
76
- - complete the first Data PR without handwritten JSON or DSL;
77
- - correctly identify that activation, approval, and apply are outside the
78
- model-facing MCP surface;
79
- - observe unchanged source data before approval;
80
- - produce one guarded receipt; and
81
- - expose only the intended semantic read/proposal tools in Cursor.
61
+ ```bash
62
+ npx -y @synapsor/runner@latest start --from-env DATABASE_URL
63
+ ```
82
64
 
83
- At least four of five must meet every timing target. Any cross-tenant result,
84
- hidden-field exposure, pre-approval mutation, automatic activation, raw SQL
85
- tool, or model-visible commit authority is a release blocker regardless of
86
- timing.
65
+ No other shell command should be required through the first proposal. The
66
+ participant may use Workbench for all human review and Try steps.
67
+
68
+ ## Observation Tasks
69
+
70
+ Record whether the participant can:
71
+
72
+ 1. identify the database, inspected resources, and current authority state;
73
+ 2. explain why no source row was read before activation;
74
+ 3. find fields Runner kept out and unresolved high-risk exceptions;
75
+ 4. confirm row identity, tenant scope, and principal scope;
76
+ 5. activate only the displayed reviewed digest;
77
+ 6. drive one real safe read and state which fields were visible;
78
+ 7. explain that the result came from a named capability or temporary
79
+ authoring-only Explore authority;
80
+ 8. ask one unfamiliar PM-style aggregate without SQL or plan JSON;
81
+ 9. understand a cohort-suppression or reviewed-boundary refusal;
82
+ 10. recover from one intentionally blocked request using the displayed single
83
+ next action;
84
+ 11. Protect the useful result without copying an opaque handle;
85
+ 12. explain why the protected capability is still disabled;
86
+ 13. activate that exact digest and confirm Explore can be disabled while the
87
+ named capability remains;
88
+ 14. choose **Add a safe action** and define one bounded single-row business
89
+ proposal;
90
+ 15. explain why schema structure did not grant business write authority;
91
+ 16. call the action and confirm the source database is unchanged;
92
+ 17. find the proposal, exact effect, required approval, receipt mode, and
93
+ conflict guard;
94
+ 18. explain who may activate, approve, and apply.
95
+
96
+ Do not rescue the participant until they have been blocked for two minutes.
97
+ Record the exact screen, wording, or prerequisite that blocked them.
98
+
99
+ ## Required Comprehension Check
100
+
101
+ Ask the participant to explain these four facts in their own words:
102
+
103
+ 1. The model does not receive raw SQL.
104
+ 2. Reads use reviewed fields and trusted tenant/principal scope.
105
+ 3. Model-facing writes create proposals instead of committing.
106
+ 4. The model cannot activate, approve, or apply.
107
+
108
+ Any incorrect answer is a usability failure even when the commands worked.
87
109
 
88
- ## Reporting Template
110
+ ## Measurements
89
111
 
90
- Record one row per real participant:
112
+ | Measure | Release target |
113
+ | --- | --- |
114
+ | First schema summary | at most 60 seconds |
115
+ | First safe read | at most 3 minutes |
116
+ | First PM-style aggregate | at most 5 minutes |
117
+ | First protected named capability | at most 8 minutes |
118
+ | First guided proposal | at most 10 minutes |
119
+ | Shell commands through first proposal | at most 3; golden target is 1 |
120
+ | Manual project-file edits | 0 |
121
+ | External documentation searches | 0 |
122
+ | Raw SQL or plan JSON composed | 0 |
123
+ | Opaque handles copied | 0 |
124
+ | Screens with multiple primary next actions | 0 |
125
+ | Unsafe authority exposed to a model | 0 |
126
+
127
+ Also record clicks, deliberate human security decisions, wrong turns,
128
+ maintainer interventions, and whether resuming the first command changed any
129
+ file or digest.
130
+
131
+ For a realistic 30–50-table schema, the first useful result must still complete
132
+ within five minutes through review by exception. A blind bulk-approval control
133
+ is an automatic failure.
134
+
135
+ ## Safety Blockers
136
+
137
+ Stop and fail the release for any:
138
+
139
+ - cross-tenant or cross-principal result;
140
+ - kept-out-field exposure;
141
+ - source-row read before activation;
142
+ - source mutation before approval;
143
+ - automatic activation;
144
+ - raw SQL/SQL-string/model-generated identifier;
145
+ - model-visible activation, approval, apply, commit, setup, or revert;
146
+ - production or remote Scoped Explore tool;
147
+ - write-capable/owner/superuser/`BYPASSRLS` Explore credential;
148
+ - discarded review state after a recoverable failure.
149
+
150
+ ## Recording Template
91
151
 
92
152
  ```text
93
153
  Participant:
94
154
  Date:
95
155
  Environment:
96
- Cold package download:
156
+ Package cached: yes | no
97
157
  Product timer start:
98
- First Data PR:
99
- First receipt:
100
- Second draft:
101
- Second activation-ready action:
158
+ Schema summary:
159
+ First safe read:
160
+ First aggregate:
161
+ Protected capability:
162
+ First proposal:
163
+ Shell commands:
164
+ Workbench primary actions:
165
+ Human authority decisions:
166
+ Manual file edits:
167
+ External docs opened:
168
+ Blocked-request recovery:
102
169
  Interventions:
103
- Tool surface observed:
104
- Safety-boundary explanation:
170
+ Four-part explanation:
105
171
  Outcome: pass | fail
106
172
  ```
107
173
 
108
- Until five real sessions are recorded, report this gate as **owner verification
109
- pending**. Do not infer usability from unit tests, protocol tests, or a
110
- maintainer-run demo.
174
+ ## Maintainer Evidence
175
+
176
+ The automated packed FitFlow run records deterministic timing and interaction
177
+ evidence in:
178
+
179
+ ```text
180
+ development/runner-1.6.3-fitflow-results.json
181
+ ```
182
+
183
+ That evidence does not substitute for a first-time participant. Until a real
184
+ session is recorded, report **owner observation pending**, not “developer
185
+ usability proven.”
@@ -21,7 +21,7 @@ scope and run the public guided path:
21
21
  export DATABASE_URL="<postgres-or-mysql-read-url>"
22
22
  export SYNAPSOR_TENANT_ID="<staging-tenant>"
23
23
  export SYNAPSOR_PRINCIPAL="<developer-id>"
24
- npx -y -p @synapsor/runner synapsor-runner start --from-env DATABASE_URL
24
+ npx -y @synapsor/runner@latest start --from-env DATABASE_URL
25
25
  ```
26
26
 
27
27
  A fresh interactive project with no existing config, selector, or automation
@@ -44,9 +44,10 @@ It does not print your database URL, put the URL in MCP client config, expose
44
44
  credentials. Before boundary activation it does not read source rows.
45
45
 
46
46
  `start --from-env` is the shortest public command for first-run onboarding.
47
- Read [Auto Boundary, Scoped Explore, And
48
- Protect](auto-boundary-and-scoped-explore.md) for the complete command and
49
- security reference.
47
+ Read [Database To First Safe Tool](guided-onboarding.md) for the timed guided
48
+ journey and [Auto Boundary, Scoped Explore, And
49
+ Protect](auto-boundary-and-scoped-explore.md) for the complete security
50
+ reference.
50
51
 
51
52
  Established routes remain unchanged. `--table`, `--answers`, `onboard db`,
52
53
  explicit `init` flags, existing configs, headless startup, JSON output, and CI
@@ -119,6 +119,12 @@ APPROVAL ROLE billing_reviewer
119
119
  WRITEBACK DIRECT SQL
120
120
  ```
121
121
 
122
+ The role requirement is enforced against verified operator identity outside
123
+ MCP; it is not a PostgreSQL role or model argument. Apply has its own role
124
+ gate. See [Approval Roles And Verified Operator
125
+ Identity](approval-roles-and-operator-identity.md) for the complete tested
126
+ OIDC/JWKS and signed-key paths.
127
+
122
128
  Guarded `INSERT` needs a source-unique, Runner-supplied dedup identity:
123
129
 
124
130
  ```sql
@@ -212,6 +218,19 @@ Resolution appends immutable events and a reconciliation receipt. It does not
212
218
  rewrite history or retry the source mutation. Configured production operator
213
219
  identity is required when enabled.
214
220
 
221
+ ## Optional supervised execution
222
+
223
+ Manual apply remains the default, including for `AUTO APPROVE`. Runner can
224
+ optionally let a separately trusted worker consume approved single-row
225
+ `INSERT`/`UPDATE` proposals, but only after contract permission and an
226
+ independent deployment allowlist bind the exact active digest. The worker
227
+ reuses this same guarded path and repeats current source/evidence, policy,
228
+ limit, writer-posture, receipt, and lease checks immediately before apply.
229
+
230
+ Hard `DELETE`, reversible actions, app-owned executors, and multi-row writes
231
+ are not eligible for the first automatic path. See
232
+ [Operator-Supervised Automatic Apply](supervised-automatic-apply.md).
233
+
215
234
  ## Verification
216
235
 
217
236
  The repository includes a disposable Postgres/MySQL test that proves every