@synapsor/runner 0.1.0-alpha.0 → 0.1.0-alpha.2
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/README.md +21 -19
- package/TRADEMARKS.md +23 -0
- package/dist/cli.js +15 -8723
- package/dist/runner.mjs +8767 -0
- package/docs/MCP_RUNNER_IMPLEMENTATION_PLAN.md +187 -0
- package/docs/README.md +56 -0
- package/docs/architecture.md +65 -0
- package/docs/capability-config.md +180 -0
- package/docs/cloud-mode.md +140 -0
- package/docs/config-migrations.md +67 -0
- package/docs/demo-transcript.md +73 -0
- package/docs/dependency-license-inventory.md +35 -0
- package/docs/first-10-minutes.md +147 -0
- package/docs/getting-started-own-database.md +367 -0
- package/docs/licensing.md +38 -0
- package/docs/limitations.md +75 -0
- package/docs/local-mode.md +246 -0
- package/docs/local-ui.md +163 -0
- package/docs/mcp-audit.md +135 -0
- package/docs/mcp-client-setup.md +155 -0
- package/docs/mcp-efficiency-benchmark.md +84 -0
- package/docs/operations.md +38 -0
- package/docs/own-db-20-minutes.md +185 -0
- package/docs/production-readiness.md +39 -0
- package/docs/protocol.md +90 -0
- package/docs/recipes.md +61 -0
- package/docs/roadmap.md +13 -0
- package/docs/schema-inspection.md +88 -0
- package/docs/security-boundary.md +70 -0
- package/docs/shadow-mode.md +67 -0
- package/docs/telemetry.md +28 -0
- package/docs/threat-model.md +25 -0
- package/docs/troubleshooting-first-run.md +248 -0
- package/docs/trusted-context.md +70 -0
- package/docs/writeback-executors.md +128 -0
- package/examples/dangerous-mcp-tools.json +88 -0
- package/examples/reference-support-billing-app/README.md +86 -0
- package/examples/reference-support-billing-app/docker-compose.yml +13 -0
- package/examples/reference-support-billing-app/mcp-client.generic.json +11 -0
- package/examples/reference-support-billing-app/schema.sql +55 -0
- package/examples/reference-support-billing-app/scripts/run-demo.sh +7 -0
- package/examples/reference-support-billing-app/seed.sql +26 -0
- package/examples/reference-support-billing-app/synapsor.runner.json +136 -0
- package/package.json +10 -4
- package/recipes/accounts.trial_extension.json +42 -0
- package/recipes/billing.late_fee_waiver.json +46 -0
- package/recipes/credits.account_credit.json +45 -0
- package/recipes/orders.refund_review.json +57 -0
- package/recipes/support.ticket_resolution.json +51 -0
- package/dist/bin.cjs +0 -13
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Schema Inspection
|
|
2
|
+
|
|
3
|
+
`synapsor inspect` reads database metadata so you can choose a
|
|
4
|
+
narrow reviewed capability without writing an entire runner config by hand.
|
|
5
|
+
|
|
6
|
+
Use the public `synapsor ...` runner CLI. From a source checkout, use
|
|
7
|
+
`./bin/synapsor ...` if the global binary is not linked yet.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx -y -p @synapsor/runner@alpha synapsor-runner inspect \
|
|
11
|
+
--engine auto \
|
|
12
|
+
--from-env SYNAPSOR_DATABASE_READ_URL \
|
|
13
|
+
--schema public
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
JSON output:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npx -y -p @synapsor/runner@alpha synapsor-runner inspect \
|
|
20
|
+
--engine mysql \
|
|
21
|
+
--from-env SYNAPSOR_DATABASE_READ_URL \
|
|
22
|
+
--schema app \
|
|
23
|
+
--json
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## What It Reads
|
|
27
|
+
|
|
28
|
+
The inspector collects metadata only:
|
|
29
|
+
|
|
30
|
+
- engine and server version;
|
|
31
|
+
- current database user;
|
|
32
|
+
- schemas/databases visible to the credential;
|
|
33
|
+
- tables and views;
|
|
34
|
+
- columns, types, nullability, defaults, and generated status;
|
|
35
|
+
- primary keys;
|
|
36
|
+
- unique constraints;
|
|
37
|
+
- foreign keys;
|
|
38
|
+
- index summaries;
|
|
39
|
+
- best-effort table writability from object type;
|
|
40
|
+
- suggested tenant columns;
|
|
41
|
+
- suggested conflict/version columns;
|
|
42
|
+
- suggested sensitive or large/binary fields.
|
|
43
|
+
|
|
44
|
+
It does not sample normal business rows by default.
|
|
45
|
+
|
|
46
|
+
## Suggestions Are Not Authority
|
|
47
|
+
|
|
48
|
+
Tenant, conflict, sensitive-field, and default-visible-column suggestions are
|
|
49
|
+
heuristics. You must review them before generating or serving a capability.
|
|
50
|
+
|
|
51
|
+
Suggested tenant column names include:
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
tenant_id, account_id, organization_id, org_id, workspace_id, customer_id
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Suggested conflict/version columns include:
|
|
58
|
+
|
|
59
|
+
```text
|
|
60
|
+
updated_at, modified_at, row_version, version, lock_version, etag
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Likely sensitive fields include names containing:
|
|
64
|
+
|
|
65
|
+
```text
|
|
66
|
+
password, secret, token, api_key, private_key, session, cookie, ssn,
|
|
67
|
+
credit_card, card_number, cvv, refresh_token, oauth
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Binary/blob/vector columns are excluded from generated default visible columns.
|
|
71
|
+
|
|
72
|
+
## Safety Behavior
|
|
73
|
+
|
|
74
|
+
- Use a read-only database credential.
|
|
75
|
+
- Pass the connection through an environment variable name, not a command-line
|
|
76
|
+
URL.
|
|
77
|
+
- Inspection opens read-only transactions where supported.
|
|
78
|
+
- Inspection applies statement timeouts.
|
|
79
|
+
- Inspection does not issue DDL or DML.
|
|
80
|
+
- Errors are sanitized to avoid printing connection strings.
|
|
81
|
+
|
|
82
|
+
## Next Step
|
|
83
|
+
|
|
84
|
+
Use the inspection result to create `onboarding-selection.json`, then run:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
npx -y -p @synapsor/runner@alpha synapsor-runner init --spec onboarding-selection.json --non-interactive
|
|
88
|
+
```
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Security Boundary
|
|
2
|
+
|
|
3
|
+
Synapsor Runner controls a narrow database path for MCP agents. It does not make
|
|
4
|
+
MCP generally secure and it does not solve prompt injection.
|
|
5
|
+
|
|
6
|
+
The model-facing MCP server exposes reviewed semantic tools such as
|
|
7
|
+
`billing.inspect_invoice` and `billing.propose_late_fee_waiver`.
|
|
8
|
+
|
|
9
|
+
The model does not receive:
|
|
10
|
+
|
|
11
|
+
- raw SQL;
|
|
12
|
+
- a generic `execute_sql` tool;
|
|
13
|
+
- arbitrary table, schema, or column names;
|
|
14
|
+
- database URLs or credentials;
|
|
15
|
+
- approval tools;
|
|
16
|
+
- commit/writeback tools;
|
|
17
|
+
- trusted tenant or principal authority as ordinary model arguments.
|
|
18
|
+
|
|
19
|
+
Trusted context comes from local configuration, environment bindings, or Cloud
|
|
20
|
+
session context in Cloud mode. Tenant, principal, and authorization scope must
|
|
21
|
+
not be accepted from the model as authority.
|
|
22
|
+
|
|
23
|
+
Proposal tools read the current row through the read credential, store evidence
|
|
24
|
+
and an exact before/after diff, and leave the source database unchanged.
|
|
25
|
+
|
|
26
|
+
The local proposal store rejects obvious credential material before persistence:
|
|
27
|
+
database URLs, bearer tokens, Synapsor runner tokens, private-key blocks, and
|
|
28
|
+
secret-like fields such as password, token, API key, private key, cookie,
|
|
29
|
+
credential, connection string, read URL, or write URL. If a selected table
|
|
30
|
+
contains one of those fields, remove it from the reviewed visible/evidence
|
|
31
|
+
projection before creating proposals.
|
|
32
|
+
|
|
33
|
+
Writeback is separate. A trusted local runner/apply path uses a write credential
|
|
34
|
+
outside the model-facing MCP server and verifies:
|
|
35
|
+
|
|
36
|
+
- local reviewed config;
|
|
37
|
+
- source and capability identity;
|
|
38
|
+
- fixed safe schema, table, and column identifiers;
|
|
39
|
+
- local approval state;
|
|
40
|
+
- proposal and job digests;
|
|
41
|
+
- target schema/table;
|
|
42
|
+
- primary-key and tenant guards;
|
|
43
|
+
- allowed mutable columns;
|
|
44
|
+
- conflict/version guard;
|
|
45
|
+
- idempotency key;
|
|
46
|
+
- job expiry;
|
|
47
|
+
- exactly one affected row.
|
|
48
|
+
|
|
49
|
+
If any authority check cannot be verified, the write fails closed.
|
|
50
|
+
|
|
51
|
+
When a capability uses an `http_handler` or `command_handler` executor, the
|
|
52
|
+
same approval boundary applies. The runner sends a structured proposal/job
|
|
53
|
+
payload to the configured handler after approval. Handler URLs, commands, bearer
|
|
54
|
+
tokens, database URLs, and write credentials come from environment variables and
|
|
55
|
+
are not exposed to MCP tools.
|
|
56
|
+
|
|
57
|
+
Writeback jobs and change sets also reject path-traversal or SQL-fragment-like
|
|
58
|
+
database identifiers such as `../private`, `id/../../tenant_id`, or
|
|
59
|
+
`status; DROP TABLE tickets` before adapter execution. Local CLI file paths
|
|
60
|
+
remain explicit user-provided paths; they are not model-facing authority.
|
|
61
|
+
|
|
62
|
+
Local review can happen through the CLI or `synapsor ui`. The UI is a localhost
|
|
63
|
+
review surface with a per-run session token and CSRF protection for
|
|
64
|
+
approve/reject actions. It does not expose raw SQL, database URLs, write
|
|
65
|
+
credentials, approval tools, commit tools, or controls that widen reviewed
|
|
66
|
+
tables/columns.
|
|
67
|
+
|
|
68
|
+
Synapsor Runner supports reviewed single-row business actions only in the
|
|
69
|
+
current alpha. It does not support arbitrary SQL, DDL, `INSERT`, `DELETE`,
|
|
70
|
+
`UPSERT`, or multi-row updates.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Shadow Mode
|
|
2
|
+
|
|
3
|
+
Shadow mode lets you evaluate autonomy before allowing writes.
|
|
4
|
+
|
|
5
|
+
The model can create proposals and evidence, but the source database is never
|
|
6
|
+
mutated. A human continues doing the real work in the application. You can then
|
|
7
|
+
record what the human actually did and compare it to the agent proposal.
|
|
8
|
+
|
|
9
|
+
Run a shadow config:
|
|
10
|
+
|
|
11
|
+
```json
|
|
12
|
+
{
|
|
13
|
+
"mode": "shadow"
|
|
14
|
+
}
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
List shadow proposals:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npx -y -p @synapsor/runner@alpha synapsor-runner shadow list --store ./.synapsor/local.db
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Record the human action:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
cat > human-action.json <<'JSON'
|
|
27
|
+
{
|
|
28
|
+
"late_fee_cents": 0,
|
|
29
|
+
"waiver_reason": "customer requested review"
|
|
30
|
+
}
|
|
31
|
+
JSON
|
|
32
|
+
|
|
33
|
+
npx -y -p @synapsor/runner@alpha synapsor-runner shadow record-human-action wrp_123 \
|
|
34
|
+
--store ./.synapsor/local.db \
|
|
35
|
+
--patch human-action.json \
|
|
36
|
+
--actor human_operator \
|
|
37
|
+
--notes "matched support lead decision"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Compare:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npx -y -p @synapsor/runner@alpha synapsor-runner shadow compare wrp_123 --store ./.synapsor/local.db
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Report:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npx -y -p @synapsor/runner@alpha synapsor-runner shadow report --store ./.synapsor/local.db
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The report counts:
|
|
53
|
+
|
|
54
|
+
- total shadow proposals;
|
|
55
|
+
- proposals with human actions;
|
|
56
|
+
- exact matches;
|
|
57
|
+
- partial matches;
|
|
58
|
+
- mismatches;
|
|
59
|
+
- proposals with no human action yet.
|
|
60
|
+
|
|
61
|
+
Use this path to move gradually:
|
|
62
|
+
|
|
63
|
+
```text
|
|
64
|
+
read-only -> shadow proposals -> human-reviewed commits -> policy-approved commits later
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
This goal does not add policy auto-approval.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Telemetry
|
|
2
|
+
|
|
3
|
+
Local mode does not send telemetry to Synapsor Cloud.
|
|
4
|
+
|
|
5
|
+
By default, Synapsor Runner local commands do not upload:
|
|
6
|
+
|
|
7
|
+
- schema metadata;
|
|
8
|
+
- table names;
|
|
9
|
+
- database rows;
|
|
10
|
+
- prompts;
|
|
11
|
+
- proposal contents;
|
|
12
|
+
- credentials or database URLs;
|
|
13
|
+
- usage data.
|
|
14
|
+
|
|
15
|
+
Cloud communication occurs only after an explicit Cloud action, such as
|
|
16
|
+
`synapsor cloud connect`, or when a config uses `mode: "cloud"`.
|
|
17
|
+
|
|
18
|
+
The local MCP server keeps database credentials in the local environment. MCP
|
|
19
|
+
client snippets reference the local command and store path; they must not
|
|
20
|
+
include database URLs or passwords.
|
|
21
|
+
|
|
22
|
+
Cloud mode may exchange documented control-plane metadata for runner
|
|
23
|
+
registration, heartbeats, tool catalogs, proposal/job leases, result reporting,
|
|
24
|
+
and replay/audit workflows. Cloud mode must remain testable and must not upload
|
|
25
|
+
database credentials.
|
|
26
|
+
|
|
27
|
+
If a future feature adds opt-in telemetry, it must be documented, disabled by
|
|
28
|
+
default for local mode, and must not include secrets or row payloads.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Threat Model
|
|
2
|
+
|
|
3
|
+
## Boundary
|
|
4
|
+
|
|
5
|
+
Synapsor Runner is the local trusted writeback boundary. The write credential stays in the customer environment. Synapsor Cloud sends approved structured jobs, not database URLs, passwords, raw SQL, prompts, or model confidence.
|
|
6
|
+
|
|
7
|
+
## Threats covered
|
|
8
|
+
|
|
9
|
+
- Compromised or prompt-injected model: runner ignores prompts and accepts only structured approved jobs.
|
|
10
|
+
- Malicious model arguments: target, tenant, allowed columns, conflict guard, and idempotency key come from Synapsor proposal state.
|
|
11
|
+
- Over-broad proposal target: runner requires primary key and tenant guard.
|
|
12
|
+
- Compromised runner token: token is scoped to one source and limited to configured runner permissions such as adapter read/invoke, runner heartbeat, job claim, and result reporting; it does not grant approval or arbitrary SQL authority.
|
|
13
|
+
- Replayed job: receipt table makes applied retries idempotent.
|
|
14
|
+
- Concurrent runners: receipt row and target row are locked inside a transaction.
|
|
15
|
+
- Stale row/version conflict: version-column mismatch returns `conflict`.
|
|
16
|
+
- Tenant mismatch: missing target row under tenant guard returns conflict and does not write.
|
|
17
|
+
- Multi-row impact: affected rows must equal one.
|
|
18
|
+
- Database outage mid-transaction: transaction rolls back and reports failed.
|
|
19
|
+
- Control-plane outage after commit: receipt table allows safe idempotent result retry.
|
|
20
|
+
- Log leakage: default logs redact tokens and database URLs.
|
|
21
|
+
- Dependency compromise: CI, lockfile review, and dependency audit are release gates.
|
|
22
|
+
|
|
23
|
+
## Limitations
|
|
24
|
+
|
|
25
|
+
The current alpha does not support arbitrary SQL, inserts, deletes, DDL, stored procedures, multi-row updates, cross-database transactions, automatic schema changes, or a self-hosted Synapsor control plane.
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
# Troubleshooting First Run
|
|
2
|
+
|
|
3
|
+
Run the friendly doctor first:
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npx -y -p @synapsor/runner@alpha synapsor-runner doctor --first-run
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Use JSON for automation:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npx -y -p @synapsor/runner@alpha synapsor-runner doctor --first-run --json
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Docker Missing
|
|
16
|
+
|
|
17
|
+
What happened:
|
|
18
|
+
|
|
19
|
+
```text
|
|
20
|
+
Docker CLI is missing.
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Why it matters:
|
|
24
|
+
|
|
25
|
+
The first-run demo starts disposable Postgres/MySQL containers.
|
|
26
|
+
|
|
27
|
+
Fix:
|
|
28
|
+
|
|
29
|
+
Install Docker Desktop or Docker Engine, then rerun:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
./scripts/try-synapsor.sh
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Docker Daemon Stopped
|
|
36
|
+
|
|
37
|
+
What happened:
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
Docker daemon is not reachable.
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Why it matters:
|
|
44
|
+
|
|
45
|
+
The demo cannot start disposable databases without the daemon.
|
|
46
|
+
|
|
47
|
+
Fix:
|
|
48
|
+
|
|
49
|
+
Start Docker Desktop or the Docker service, then rerun:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
./scripts/try-synapsor.sh
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
If the doctor reports Docker socket permission problems, add your user to the
|
|
56
|
+
Docker group or start Docker Desktop.
|
|
57
|
+
|
|
58
|
+
## Port Conflict
|
|
59
|
+
|
|
60
|
+
What happened:
|
|
61
|
+
|
|
62
|
+
```text
|
|
63
|
+
Port 55433 is already in use.
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Why it matters:
|
|
67
|
+
|
|
68
|
+
The fixtures bind predictable local ports.
|
|
69
|
+
|
|
70
|
+
Fix:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
./scripts/try-synapsor.sh --reset
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
If another application owns the port, stop that application and rerun.
|
|
77
|
+
|
|
78
|
+
## Stale Containers
|
|
79
|
+
|
|
80
|
+
What happened:
|
|
81
|
+
|
|
82
|
+
Doctor reports stale Synapsor demo containers.
|
|
83
|
+
|
|
84
|
+
Why it matters:
|
|
85
|
+
|
|
86
|
+
Old containers can hold ports or stale fixture state.
|
|
87
|
+
|
|
88
|
+
Fix:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
./scripts/try-synapsor.sh --reset
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Missing Source Dependencies
|
|
95
|
+
|
|
96
|
+
What happened:
|
|
97
|
+
|
|
98
|
+
```text
|
|
99
|
+
Dependencies are not installed yet.
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Why it matters:
|
|
103
|
+
|
|
104
|
+
Source checkout commands such as `synapsor ...` need workspace
|
|
105
|
+
dependencies.
|
|
106
|
+
|
|
107
|
+
Fix:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
corepack enable
|
|
111
|
+
corepack pnpm install
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
The Docker-only first-run demo does not require host Node dependencies.
|
|
115
|
+
|
|
116
|
+
## Config Missing
|
|
117
|
+
|
|
118
|
+
What happened:
|
|
119
|
+
|
|
120
|
+
```text
|
|
121
|
+
Runner config not found at synapsor.runner.json.
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Why it matters:
|
|
125
|
+
|
|
126
|
+
Own-database MCP setup needs a reviewed config before serving tools.
|
|
127
|
+
|
|
128
|
+
Fix:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
npx -y -p @synapsor/runner@alpha synapsor-runner init --from-env DATABASE_URL --mode review --wizard
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Or pass an example config:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
npx -y -p @synapsor/runner@alpha synapsor-runner tools preview --config ./examples/mcp-postgres-billing/synapsor.runner.json --store ./.synapsor/local.db
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## SQLite Store Missing
|
|
141
|
+
|
|
142
|
+
What happened:
|
|
143
|
+
|
|
144
|
+
```text
|
|
145
|
+
SQLite local store not found at ./.synapsor/local.db.
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Why it matters:
|
|
149
|
+
|
|
150
|
+
The local UI and replay read proposal/evidence state from the store.
|
|
151
|
+
|
|
152
|
+
Fix:
|
|
153
|
+
|
|
154
|
+
Run a demo or create a proposal first:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
./scripts/try-synapsor.sh
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
or:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
corepack pnpm demo:reference
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## DB URL Env Var Missing
|
|
167
|
+
|
|
168
|
+
What happened:
|
|
169
|
+
|
|
170
|
+
```text
|
|
171
|
+
SYNAPSOR_DATABASE_READ_URL is not set.
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Why it matters:
|
|
175
|
+
|
|
176
|
+
Configured capabilities need a read credential to inspect/propose against your
|
|
177
|
+
database.
|
|
178
|
+
|
|
179
|
+
Fix:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
export SYNAPSOR_DATABASE_READ_URL="<read-only-url>"
|
|
183
|
+
npx -y -p @synapsor/runner@alpha synapsor-runner doctor --config synapsor.runner.json
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Read/Write Credential Split Failed
|
|
187
|
+
|
|
188
|
+
What happened:
|
|
189
|
+
|
|
190
|
+
```text
|
|
191
|
+
Read and write env vars resolve to the same credential.
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Why it matters:
|
|
195
|
+
|
|
196
|
+
Read/proposal authority and writeback authority must be separated.
|
|
197
|
+
|
|
198
|
+
Fix:
|
|
199
|
+
|
|
200
|
+
Use a read-only credential for MCP reads and a separate writer credential only
|
|
201
|
+
for trusted apply.
|
|
202
|
+
|
|
203
|
+
## MCP Client Config Contains A Secret
|
|
204
|
+
|
|
205
|
+
What happened:
|
|
206
|
+
|
|
207
|
+
Doctor reports a generated MCP client config appears to contain a database URL,
|
|
208
|
+
password, or token.
|
|
209
|
+
|
|
210
|
+
Why it matters:
|
|
211
|
+
|
|
212
|
+
MCP clients must receive only the local runner command and args.
|
|
213
|
+
|
|
214
|
+
Fix:
|
|
215
|
+
|
|
216
|
+
Regenerate the snippet:
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
npx -y -p @synapsor/runner@alpha synapsor-runner mcp config claude-desktop \
|
|
220
|
+
--absolute-paths \
|
|
221
|
+
--config ./synapsor.runner.json \
|
|
222
|
+
--store ./.synapsor/local.db
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Keep database URLs in environment variables, not client JSON.
|
|
226
|
+
|
|
227
|
+
## Demo Did Not Prove The Boundary
|
|
228
|
+
|
|
229
|
+
What happened:
|
|
230
|
+
|
|
231
|
+
```text
|
|
232
|
+
Demo did not prove the Synapsor boundary.
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Why it matters:
|
|
236
|
+
|
|
237
|
+
The first-run demo must prove semantic tools, proposal creation, source row
|
|
238
|
+
unchanged, approval outside MCP, guarded writeback/conflict, replay, and no
|
|
239
|
+
secret leakage.
|
|
240
|
+
|
|
241
|
+
Fix:
|
|
242
|
+
|
|
243
|
+
Inspect the printed log path, then reset:
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
./scripts/try-synapsor.sh --reset
|
|
247
|
+
./scripts/try-synapsor.sh
|
|
248
|
+
```
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Trusted Context
|
|
2
|
+
|
|
3
|
+
Trusted context is the data Synapsor Runner uses as authority but does not allow
|
|
4
|
+
the model to choose freely.
|
|
5
|
+
|
|
6
|
+
Examples:
|
|
7
|
+
|
|
8
|
+
- tenant ID;
|
|
9
|
+
- principal/user ID;
|
|
10
|
+
- role;
|
|
11
|
+
- environment or workspace scope.
|
|
12
|
+
|
|
13
|
+
In local mode, the supported provider is environment binding:
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"trusted_context": {
|
|
18
|
+
"provider": "environment",
|
|
19
|
+
"values": {
|
|
20
|
+
"tenant_id_env": "SYNAPSOR_TENANT_ID",
|
|
21
|
+
"principal_env": "SYNAPSOR_PRINCIPAL"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
For larger configs, use named contexts so each capability says which trusted
|
|
28
|
+
binding it uses:
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"contexts": {
|
|
33
|
+
"local_support_operator": {
|
|
34
|
+
"provider": "environment",
|
|
35
|
+
"values": {
|
|
36
|
+
"tenant_id_env": "SYNAPSOR_TENANT_ID",
|
|
37
|
+
"principal_env": "SYNAPSOR_PRINCIPAL"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"capabilities": [
|
|
42
|
+
{
|
|
43
|
+
"name": "support.inspect_ticket",
|
|
44
|
+
"context": "local_support_operator"
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Backward compatibility: `trusted_context` still works as the global fallback.
|
|
51
|
+
If a capability names `context`, that named context is used for that capability.
|
|
52
|
+
If a capability does not name `context`, the global `trusted_context` is used.
|
|
53
|
+
Config validation fails when a capability references a missing named context.
|
|
54
|
+
|
|
55
|
+
At runtime:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
export SYNAPSOR_TENANT_ID="acme"
|
|
59
|
+
export SYNAPSOR_PRINCIPAL="local_operator"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
The model may pass business identifiers such as `invoice_id` or `ticket_id`.
|
|
63
|
+
Those identifiers are validated inside the trusted tenant scope.
|
|
64
|
+
|
|
65
|
+
The model must not pass `tenant_id`, principal, role, or authorization scope as
|
|
66
|
+
ordinary authority arguments. If a tool schema appears to require those fields
|
|
67
|
+
from the model, treat it as a bug.
|
|
68
|
+
|
|
69
|
+
Cloud mode may bind trusted context from Cloud runner/session context, but
|
|
70
|
+
database credentials still stay local.
|