@synapsor/runner 0.1.15 → 1.0.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.
@@ -14,6 +14,16 @@ CREATE TABLE IF NOT EXISTS public.customers (
14
14
  private_notes text
15
15
  );
16
16
 
17
+ CREATE TABLE IF NOT EXISTS public.synapsor_writeback_receipts (
18
+ idempotency_key text PRIMARY KEY,
19
+ job_id text UNIQUE NOT NULL,
20
+ proposal_id text NOT NULL,
21
+ status text NOT NULL,
22
+ result_hash text,
23
+ created_at timestamptz NOT NULL DEFAULT now(),
24
+ completed_at timestamptz
25
+ );
26
+
17
27
  INSERT INTO public.customers (
18
28
  id,
19
29
  tenant_id,
@@ -87,6 +97,6 @@ $$;
87
97
 
88
98
  GRANT CONNECT ON DATABASE synapsor_runner_plan_credit TO synapsor_reader, synapsor_writer;
89
99
  GRANT USAGE ON SCHEMA public TO synapsor_reader, synapsor_writer;
90
- GRANT CREATE ON SCHEMA public TO synapsor_writer;
91
100
  GRANT SELECT ON public.customers TO synapsor_reader, synapsor_writer;
92
101
  GRANT UPDATE (plan_credit_cents, credit_reason, updated_at) ON public.customers TO synapsor_writer;
102
+ GRANT SELECT, INSERT, UPDATE ON public.synapsor_writeback_receipts TO synapsor_writer;
@@ -166,6 +166,21 @@
166
166
  "policies": [
167
167
  {
168
168
  "kind": "approval",
169
+ "limits": [
170
+ {
171
+ "kind": "count",
172
+ "max": 20,
173
+ "period": "day",
174
+ "scope": "tenant_policy"
175
+ },
176
+ {
177
+ "field": "plan_credit_cents",
178
+ "kind": "total",
179
+ "max": 100000,
180
+ "period": "day",
181
+ "scope": "tenant_policy"
182
+ }
183
+ ],
169
184
  "mode": "green",
170
185
  "name": "support_propose_plan_credit_auto_approval",
171
186
  "rules": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synapsor/runner",
3
- "version": "0.1.15",
3
+ "version": "1.0.0",
4
4
  "description": "Stop giving AI agents execute_sql; expose reviewed Postgres/MySQL MCP actions with proposals, approval, writeback, and replay.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -5,12 +5,36 @@
5
5
  "description": "Configuration for local Synapsor Runner MCP capabilities over Postgres/MySQL.",
6
6
  "type": "object",
7
7
  "additionalProperties": false,
8
- "required": ["version", "mode", "sources", "trusted_context", "capabilities"],
8
+ "required": ["version", "mode"],
9
+ "allOf": [
10
+ {
11
+ "if": { "properties": { "mode": { "const": "cloud" } }, "required": ["mode"] },
12
+ "then": { "required": ["cloud"] },
13
+ "else": { "required": ["sources"] }
14
+ },
15
+ {
16
+ "if": { "required": ["contracts"] },
17
+ "then": {},
18
+ "else": {
19
+ "if": { "properties": { "mode": { "not": { "const": "cloud" } } }, "required": ["mode"] },
20
+ "then": {
21
+ "required": ["capabilities"],
22
+ "properties": { "capabilities": { "minItems": 1 } },
23
+ "anyOf": [
24
+ { "required": ["trusted_context"] },
25
+ { "required": ["contexts"] }
26
+ ]
27
+ }
28
+ }
29
+ }
30
+ ],
9
31
  "properties": {
10
32
  "version": {
33
+ "description": "Runner configuration contract version. Version 1 is the current public format.",
11
34
  "const": 1
12
35
  },
13
36
  "mode": {
37
+ "description": "Local execution mode. review permits proposals and trusted writeback; cloud delegates reviewed tools to Synapsor Cloud.",
14
38
  "type": "string",
15
39
  "enum": ["read_only", "shadow", "review", "cloud"]
16
40
  },
@@ -21,20 +45,53 @@
21
45
  "default": 1
22
46
  },
23
47
  "strict": {
48
+ "description": "Reject unknown configuration keys when true.",
24
49
  "type": "boolean",
25
50
  "default": true
26
51
  },
27
52
  "storage": {
53
+ "description": "Local proposal, evidence, receipt, and replay ledger. Relative sqlite_path values resolve from the Runner process working directory.",
28
54
  "type": "object",
29
55
  "additionalProperties": false,
30
56
  "properties": {
31
57
  "sqlite_path": {
58
+ "description": "SQLite ledger path. The file can contain visible business-data evidence and is created with owner-only permissions on POSIX.",
32
59
  "type": "string",
33
60
  "minLength": 1
61
+ },
62
+ "shared_postgres": {
63
+ "description": "Optional shared Postgres ledger. mode=mirror coordinates bounded CLI mutations with a schema-scoped advisory lock while the live runtime store remains local SQLite. mode=runtime_store makes MCP serving use Postgres as the primary proposal/evidence/replay store.",
64
+ "type": "object",
65
+ "additionalProperties": false,
66
+ "required": ["mode", "url_env"],
67
+ "properties": {
68
+ "mode": {
69
+ "type": "string",
70
+ "enum": ["mirror", "runtime_store", "disabled"]
71
+ },
72
+ "url_env": {
73
+ "description": "Environment variable containing the shared ledger Postgres URL. The URL itself must not be stored in config.",
74
+ "type": "string",
75
+ "pattern": "^[A-Z_][A-Z0-9_]*$"
76
+ },
77
+ "schema": {
78
+ "description": "Postgres schema for shared ledger tables.",
79
+ "type": "string",
80
+ "pattern": "^[A-Za-z_][A-Za-z0-9_]*$",
81
+ "default": "synapsor_runner"
82
+ },
83
+ "lock_timeout_ms": {
84
+ "description": "How long mirror-mode CLI commands wait for the schema-scoped advisory lock.",
85
+ "type": "integer",
86
+ "minimum": 0,
87
+ "default": 10000
88
+ }
89
+ }
34
90
  }
35
91
  }
36
92
  },
37
93
  "sources": {
94
+ "description": "Named Postgres/MySQL sources. Contract SOURCE names must match these keys.",
38
95
  "type": "object",
39
96
  "minProperties": 1,
40
97
  "additionalProperties": {
@@ -42,30 +99,116 @@
42
99
  }
43
100
  },
44
101
  "trusted_context": {
102
+ "description": "Default operator-controlled tenant/principal binding. These values are never model arguments.",
45
103
  "$ref": "#/$defs/trusted_context"
46
104
  },
47
105
  "contexts": {
106
+ "description": "Named trusted contexts referenced by capabilities or portable contracts.",
48
107
  "type": "object",
49
108
  "additionalProperties": {
50
109
  "$ref": "#/$defs/trusted_context"
51
110
  }
52
111
  },
53
112
  "executors": {
113
+ "description": "Trusted app-owned writeback executors. URLs, tokens, and commands are referenced through environment-variable names.",
54
114
  "type": "object",
55
115
  "additionalProperties": {
56
116
  "$ref": "#/$defs/executor"
57
117
  }
58
118
  },
59
- "capabilities": {
119
+ "contracts": {
120
+ "description": "Portable @synapsor/spec contract files. Relative paths resolve from this config file's directory.",
60
121
  "type": "array",
61
122
  "minItems": 1,
123
+ "items": {
124
+ "type": "string",
125
+ "minLength": 1
126
+ }
127
+ },
128
+ "capabilities": {
129
+ "description": "Embedded compatibility capabilities. May be empty when contracts supplies the capability catalog.",
130
+ "type": "array",
131
+ "minItems": 0,
62
132
  "items": {
63
133
  "$ref": "#/$defs/capability"
64
134
  }
65
135
  },
136
+ "policies": {
137
+ "description": "Embedded reviewed policies. Contract-authored policies are merged into the same runtime catalog.",
138
+ "type": "array",
139
+ "items": { "$ref": "#/$defs/policy" }
140
+ },
141
+ "approvals": {
142
+ "description": "Local approval behavior overrides.",
143
+ "type": "object",
144
+ "additionalProperties": false,
145
+ "properties": {
146
+ "disable_auto_approval": { "type": "boolean" }
147
+ }
148
+ },
149
+ "operator_identity": {
150
+ "description": "Operator identity used by approve, reject, and apply. signed_key verifies possession of a registered private key; dev_env is local-development compatibility only.",
151
+ "type": "object",
152
+ "additionalProperties": false,
153
+ "required": ["provider"],
154
+ "allOf": [
155
+ {
156
+ "if": { "properties": { "provider": { "const": "signed_key" } }, "required": ["provider"] },
157
+ "then": { "required": ["operators"] }
158
+ }
159
+ ],
160
+ "properties": {
161
+ "provider": { "enum": ["dev_env", "signed_key"] },
162
+ "actor_env": { "$ref": "#/$defs/env_name" },
163
+ "roles_env": { "$ref": "#/$defs/env_name" },
164
+ "apply_roles": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/identifier" } },
165
+ "operators": {
166
+ "type": "object",
167
+ "minProperties": 1,
168
+ "additionalProperties": {
169
+ "type": "object",
170
+ "additionalProperties": false,
171
+ "required": ["public_key_path", "roles"],
172
+ "properties": {
173
+ "public_key_path": { "type": "string", "minLength": 1 },
174
+ "roles": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/identifier" } }
175
+ }
176
+ }
177
+ }
178
+ }
179
+ },
180
+ "session_auth": {
181
+ "description": "Signed per-session identity for Streamable HTTP http_claims contexts. The HMAC secret stays in an environment variable.",
182
+ "type": "object",
183
+ "additionalProperties": false,
184
+ "required": ["provider", "secret_env"],
185
+ "properties": {
186
+ "provider": { "const": "jwt_hs256" },
187
+ "secret_env": { "$ref": "#/$defs/env_name" },
188
+ "previous_secret_env": { "$ref": "#/$defs/env_name" },
189
+ "issuer": { "type": "string", "minLength": 1 },
190
+ "audience": { "type": "string", "minLength": 1 },
191
+ "tenant_claim": { "$ref": "#/$defs/identifier" },
192
+ "principal_claim": { "$ref": "#/$defs/identifier" },
193
+ "clock_skew_seconds": { "type": "integer", "minimum": 0, "maximum": 300 }
194
+ }
195
+ },
66
196
  "cloud": {
67
197
  "type": "object",
68
- "additionalProperties": true
198
+ "additionalProperties": false,
199
+ "required": ["base_url_env", "runner_token_env", "adapter_id"],
200
+ "properties": {
201
+ "base_url_env": { "$ref": "#/$defs/env_name" },
202
+ "runner_token_env": { "$ref": "#/$defs/env_name" },
203
+ "runner_id": { "type": "string", "minLength": 1 },
204
+ "runner_version": { "type": "string", "minLength": 1 },
205
+ "project_id": { "type": "string", "minLength": 1 },
206
+ "adapter_id": { "type": "string", "minLength": 1 },
207
+ "source_id": { "type": "string", "minLength": 1 },
208
+ "engines": { "type": "array", "minItems": 1, "items": { "enum": ["postgres", "mysql"] } },
209
+ "capabilities": { "type": "array", "minItems": 1, "items": { "type": "string", "minLength": 1 } },
210
+ "session": { "type": "object" }
211
+ }
69
212
  }
70
213
  },
71
214
  "$defs": {
@@ -94,15 +237,18 @@
94
237
  "enum": ["postgres", "mysql"]
95
238
  },
96
239
  "read_url_env": {
240
+ "description": "Environment variable containing the least-privilege read connection URL.",
97
241
  "$ref": "#/$defs/env_name"
98
242
  },
99
243
  "write_url_env": {
244
+ "description": "Environment variable containing the separate trusted writer URL. It is never exposed over MCP.",
100
245
  "$ref": "#/$defs/env_name"
101
246
  },
102
247
  "read_only": {
103
248
  "type": "boolean"
104
249
  },
105
250
  "statement_timeout_ms": {
251
+ "description": "Per-read database statement timeout in milliseconds.",
106
252
  "type": "integer",
107
253
  "minimum": 1
108
254
  },
@@ -295,9 +441,16 @@
295
441
  },
296
442
  "required_role": {
297
443
  "type": "string"
444
+ },
445
+ "policy": {
446
+ "type": "string",
447
+ "minLength": 1
298
448
  }
299
449
  }
300
450
  },
451
+ "writeback": {
452
+ "$ref": "#/$defs/writeback"
453
+ },
301
454
  "single_tenant_dev_ack": {
302
455
  "type": "boolean"
303
456
  }
@@ -410,6 +563,66 @@
410
563
  }
411
564
  }
412
565
  }
566
+ },
567
+ "writeback": {
568
+ "type": "object",
569
+ "additionalProperties": false,
570
+ "required": ["mode"],
571
+ "properties": {
572
+ "mode": {
573
+ "enum": ["direct_sql", "app_handler", "cloud_worker", "none"]
574
+ },
575
+ "executor": {
576
+ "type": "string",
577
+ "minLength": 1
578
+ }
579
+ }
580
+ },
581
+ "policy": {
582
+ "type": "object",
583
+ "additionalProperties": false,
584
+ "required": ["name", "kind"],
585
+ "properties": {
586
+ "name": { "type": "string", "minLength": 1 },
587
+ "kind": { "enum": ["approval", "settlement", "scope", "custom"] },
588
+ "mode": { "type": "string" },
589
+ "rules": {
590
+ "type": "array",
591
+ "items": {
592
+ "type": "object",
593
+ "additionalProperties": false,
594
+ "required": ["field", "max"],
595
+ "properties": {
596
+ "field": { "$ref": "#/$defs/identifier" },
597
+ "max": { "type": "integer", "minimum": 0 }
598
+ }
599
+ }
600
+ },
601
+ "limits": {
602
+ "description": "Reviewed aggregate ceilings for policy auto-approval. Exceeding one falls back to human review.",
603
+ "type": "array",
604
+ "minItems": 1,
605
+ "items": {
606
+ "type": "object",
607
+ "additionalProperties": false,
608
+ "required": ["kind", "max", "period"],
609
+ "allOf": [
610
+ {
611
+ "if": { "properties": { "kind": { "const": "total" } }, "required": ["kind"] },
612
+ "then": { "required": ["field"] },
613
+ "else": { "not": { "required": ["field"] } }
614
+ }
615
+ ],
616
+ "properties": {
617
+ "kind": { "enum": ["count", "total"] },
618
+ "max": { "type": "integer", "minimum": 0 },
619
+ "period": { "const": "day" },
620
+ "field": { "$ref": "#/$defs/identifier" },
621
+ "scope": { "enum": ["tenant_policy", "tenant_policy_object"] }
622
+ }
623
+ }
624
+ }
625
+ }
413
626
  }
414
627
  }
415
628
  }