@synapsor/runner 1.1.1 → 1.4.1

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 (72) hide show
  1. package/CHANGELOG.md +123 -1
  2. package/README.md +52 -31
  3. package/SECURITY.md +11 -0
  4. package/THREAT_MODEL.md +7 -4
  5. package/dist/cli.d.ts +5 -1
  6. package/dist/cli.d.ts.map +1 -1
  7. package/dist/local-ui.d.ts.map +1 -1
  8. package/dist/runner.mjs +8103 -2601
  9. package/docs/README.md +23 -3
  10. package/docs/benchmarks/bounded-set-local.md +27 -0
  11. package/docs/bounded-set-writeback.md +298 -0
  12. package/docs/capability-authoring.md +26 -8
  13. package/docs/conformance.md +12 -0
  14. package/docs/current-scope.md +12 -4
  15. package/docs/doctor.md +21 -7
  16. package/docs/dsl-reference.md +91 -5
  17. package/docs/getting-started-own-database.md +26 -3
  18. package/docs/guarded-crud-writeback.md +218 -0
  19. package/docs/limitations.md +30 -9
  20. package/docs/oss-vs-cloud.md +1 -1
  21. package/docs/production.md +52 -20
  22. package/docs/release-notes.md +105 -2
  23. package/docs/release-policy.md +1 -1
  24. package/docs/result-envelope-v2.md +20 -6
  25. package/docs/result-envelope-v3.md +43 -0
  26. package/docs/result-envelope-v4.md +47 -0
  27. package/docs/reversible-change-sets.md +151 -0
  28. package/docs/rfcs/004-guarded-crud-receipt-authority.md +165 -0
  29. package/docs/rfcs/005-bounded-set-writeback.md +164 -0
  30. package/docs/rfcs/006-reviewed-reversible-change-sets.md +152 -0
  31. package/docs/runner-config-reference.md +83 -9
  32. package/docs/running-a-runner-fleet.md +2 -1
  33. package/docs/security-boundary.md +36 -9
  34. package/docs/why-synapsor-vs-app-guardrails.md +169 -0
  35. package/docs/writeback-executors.md +12 -11
  36. package/examples/runner-fleet/seed/mysql.sql +47 -0
  37. package/examples/runner-fleet/seed/postgres.sql +48 -0
  38. package/examples/support-plan-credit/README.md +31 -0
  39. package/examples/support-plan-credit/contract.synapsor.sql +26 -0
  40. package/examples/support-plan-credit/expected-output/tools-preview.txt +1 -0
  41. package/examples/support-plan-credit/seed/001_seed.sql +14 -1
  42. package/examples/support-plan-credit/synapsor.contract.json +101 -1
  43. package/examples/support-plan-credit/synapsor.runner.json +7 -1
  44. package/fixtures/protocol/MANIFEST.json +131 -1
  45. package/fixtures/protocol/change-set.bounded-update.v3.json +57 -0
  46. package/fixtures/protocol/change-set.delete.v2.json +31 -0
  47. package/fixtures/protocol/change-set.insert.v2.json +36 -0
  48. package/fixtures/protocol/change-set.update.v2.json +32 -0
  49. package/fixtures/protocol/compensation-change-set.update.v1.json +40 -0
  50. package/fixtures/protocol/execution-receipt.bounded-update-applied.v3.json +39 -0
  51. package/fixtures/protocol/execution-receipt.compensation-update-applied.v4.json +37 -0
  52. package/fixtures/protocol/execution-receipt.delete-applied.v2.json +25 -0
  53. package/fixtures/protocol/execution-receipt.insert-applied.v2.json +24 -0
  54. package/fixtures/protocol/execution-receipt.reconciliation-required.v2.json +25 -0
  55. package/fixtures/protocol/execution-receipt.update-applied.v2.json +25 -0
  56. package/fixtures/protocol/writeback-job.bounded-update.v3.json +43 -0
  57. package/fixtures/protocol/writeback-job.compensation-update.v4.json +34 -0
  58. package/fixtures/protocol/writeback-job.delete.v2.json +22 -0
  59. package/fixtures/protocol/writeback-job.insert.v2.json +28 -0
  60. package/fixtures/protocol/writeback-job.update.v2.json +24 -0
  61. package/package.json +2 -1
  62. package/schemas/change-set.v2.schema.json +245 -0
  63. package/schemas/change-set.v3.schema.json +112 -0
  64. package/schemas/compensation-change-set.v1.schema.json +32 -0
  65. package/schemas/execution-receipt.v2.schema.json +106 -0
  66. package/schemas/execution-receipt.v3.schema.json +40 -0
  67. package/schemas/execution-receipt.v4.schema.json +22 -0
  68. package/schemas/inverse-descriptor.v1.schema.json +46 -0
  69. package/schemas/synapsor.runner.schema.json +132 -2
  70. package/schemas/writeback-job.v2.schema.json +238 -0
  71. package/schemas/writeback-job.v3.schema.json +53 -0
  72. package/schemas/writeback-job.v4.schema.json +17 -0
@@ -0,0 +1,34 @@
1
+ {
2
+ "schema_version": "synapsor.writeback-job.v4",
3
+ "writeback_job_id": "wbj_revert_1",
4
+ "proposal_id": "wrp_revert_1",
5
+ "proposal_version": 1,
6
+ "proposal_hash": "sha256:revert-proposal",
7
+ "runner_scope": { "project_id": "local", "source_id": "src_1" },
8
+ "engine": "postgres",
9
+ "operation": "restore_update",
10
+ "target": { "schema": "public", "table": "customers", "primary_key": { "column": "id", "value": "CUS-1" } },
11
+ "tenant_guard": { "column": "tenant_id", "value": "acme" },
12
+ "allowed_columns": ["plan_credit_cents"],
13
+ "patch": {},
14
+ "compensation": {
15
+ "schema_version": "synapsor.inverse-descriptor.v1",
16
+ "availability": "available",
17
+ "reason_codes": [],
18
+ "operation": "restore_update",
19
+ "cardinality": "single",
20
+ "forward_proposal_id": "wrp_forward_1",
21
+ "forward_writeback_job_id": "wbj_forward_1",
22
+ "target": { "source_id": "src_1", "schema": "public", "table": "customers", "primary_key_column": "id" },
23
+ "tenant_guard": { "column": "tenant_id", "value": "acme" },
24
+ "allowed_columns": ["plan_credit_cents"],
25
+ "members": [{ "primary_key": { "column": "id", "value": "CUS-1" }, "expected_state": { "plan_credit_cents": 2500, "version": 8 }, "restore_values": { "plan_credit_cents": 0 } }],
26
+ "max_rows": 1,
27
+ "aggregate_bounds": [],
28
+ "version_advance": { "column": "version", "strategy": "integer_increment" },
29
+ "lineage": { "root_proposal_id": "wrp_forward_1", "parent_proposal_id": "wrp_forward_1", "reverts_proposal_id": "wrp_forward_1", "depth": 1 }
30
+ },
31
+ "forward_receipt_hash": "sha256:forward-receipt",
32
+ "idempotency_key": "revert:wrp_forward_1:wrp_revert_1",
33
+ "lease": { "lease_id": "lease_revert_1", "attempt": 1, "expires_at": "2026-07-13T23:59:59Z" }
34
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "schema_version": "synapsor.writeback-job.v2",
3
+ "writeback_job_id": "wbj_delete_2003",
4
+ "proposal_id": "wrp_delete_2003",
5
+ "proposal_version": 1,
6
+ "proposal_hash": "sha256:delete-proposal",
7
+ "runner_scope": { "project_id": "project_demo", "source_id": "src_support_demo" },
8
+ "engine": "mysql",
9
+ "target": {
10
+ "schema": "support",
11
+ "table": "pending_tasks",
12
+ "primary_key": { "column": "id", "value": "task_2003" }
13
+ },
14
+ "tenant_guard": { "column": "tenant_id", "value": "tenant_demo" },
15
+ "allowed_columns": [],
16
+ "mutation": {
17
+ "kind": "single_row_delete",
18
+ "conflict_guard": { "kind": "column", "column": "version", "expected_value": 4 }
19
+ },
20
+ "idempotency_key": "idem_delete_2003",
21
+ "lease": { "lease_id": "lease_delete_2003", "attempt": 1, "expires_at": "2026-07-13T19:02:00Z" }
22
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "schema_version": "synapsor.writeback-job.v2",
3
+ "writeback_job_id": "wbj_insert_2002",
4
+ "proposal_id": "wrp_insert_2002",
5
+ "proposal_version": 1,
6
+ "proposal_hash": "sha256:insert-proposal",
7
+ "runner_scope": { "project_id": "project_demo", "source_id": "src_billing_demo" },
8
+ "engine": "postgres",
9
+ "target": {
10
+ "schema": "public",
11
+ "table": "account_credits",
12
+ "primary_key": { "column": "id" }
13
+ },
14
+ "tenant_guard": { "column": "tenant_id", "value": "tenant_demo" },
15
+ "allowed_columns": ["amount_cents", "reason"],
16
+ "mutation": {
17
+ "kind": "single_row_insert",
18
+ "values": { "amount_cents": 2500, "reason": "service interruption" },
19
+ "deduplication": {
20
+ "components": [
21
+ { "column": "tenant_id", "value": "tenant_demo", "source": "trusted_tenant" },
22
+ { "column": "request_id", "value": "wrp_insert_2002", "source": "proposal_id" }
23
+ ]
24
+ }
25
+ },
26
+ "idempotency_key": "idem_insert_2002",
27
+ "lease": { "lease_id": "lease_insert_2002", "attempt": 1, "expires_at": "2026-07-13T19:01:00Z" }
28
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "schema_version": "synapsor.writeback-job.v2",
3
+ "writeback_job_id": "wbj_update_2001",
4
+ "proposal_id": "wrp_update_2001",
5
+ "proposal_version": 1,
6
+ "proposal_hash": "sha256:update-proposal",
7
+ "runner_scope": { "project_id": "project_demo", "source_id": "src_billing_demo" },
8
+ "engine": "postgres",
9
+ "target": {
10
+ "schema": "public",
11
+ "table": "account_credits",
12
+ "primary_key": { "column": "id", "value": "credit_2001" }
13
+ },
14
+ "tenant_guard": { "column": "tenant_id", "value": "tenant_demo" },
15
+ "allowed_columns": ["amount_cents"],
16
+ "mutation": {
17
+ "kind": "single_row_update",
18
+ "values": { "amount_cents": 2500 },
19
+ "conflict_guard": { "kind": "column", "column": "version", "expected_value": 7 },
20
+ "version_advance": { "column": "version", "strategy": "integer_increment" }
21
+ },
22
+ "idempotency_key": "idem_update_2001",
23
+ "lease": { "lease_id": "lease_update_2001", "attempt": 1, "expires_at": "2026-07-13T19:00:00Z" }
24
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synapsor/runner",
3
- "version": "1.1.1",
3
+ "version": "1.4.1",
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",
@@ -35,6 +35,7 @@
35
35
  "AGENTS.md",
36
36
  "CHANGELOG.md",
37
37
  "CONTRIBUTING.md",
38
+ "SECURITY.md",
38
39
  "LICENSE",
39
40
  "NOTICE",
40
41
  "THREAT_MODEL.md",
@@ -0,0 +1,245 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://schemas.synapsor.ai/synapsor.change-set.v2.schema.json",
4
+ "title": "Synapsor Change Set v2",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": [
8
+ "schema_version",
9
+ "proposal_id",
10
+ "proposal_version",
11
+ "action",
12
+ "operation",
13
+ "mode",
14
+ "principal",
15
+ "scope",
16
+ "source",
17
+ "before",
18
+ "patch",
19
+ "after",
20
+ "guards",
21
+ "evidence",
22
+ "approval",
23
+ "writeback",
24
+ "source_database_mutated",
25
+ "integrity",
26
+ "created_at"
27
+ ],
28
+ "properties": {
29
+ "schema_version": { "const": "synapsor.change-set.v2" },
30
+ "proposal_id": { "type": "string", "minLength": 1 },
31
+ "proposal_version": { "type": "integer", "minimum": 1 },
32
+ "action": { "type": "string", "minLength": 1 },
33
+ "operation": { "enum": ["single_row_update", "single_row_insert", "single_row_delete"] },
34
+ "mode": { "enum": ["read_only", "shadow", "review_required", "approved_for_writeback"] },
35
+ "principal": {
36
+ "type": "object",
37
+ "additionalProperties": false,
38
+ "required": ["id", "source"],
39
+ "properties": {
40
+ "id": { "type": "string", "minLength": 1 },
41
+ "source": { "enum": ["trusted_session", "cloud_session", "environment", "static_dev"] }
42
+ }
43
+ },
44
+ "scope": {
45
+ "type": "object",
46
+ "additionalProperties": false,
47
+ "required": ["tenant_id", "business_object", "object_id"],
48
+ "properties": {
49
+ "tenant_id": { "type": "string", "minLength": 1 },
50
+ "business_object": { "type": "string", "minLength": 1 },
51
+ "object_id": { "type": "string", "minLength": 1 }
52
+ }
53
+ },
54
+ "source": {
55
+ "type": "object",
56
+ "additionalProperties": false,
57
+ "required": ["kind", "source_id", "schema", "table", "primary_key"],
58
+ "properties": {
59
+ "kind": { "enum": ["external_postgres", "external_mysql", "synapsor_table"] },
60
+ "source_id": { "type": "string", "minLength": 1 },
61
+ "schema": { "$ref": "#/$defs/safeIdentifier" },
62
+ "table": { "$ref": "#/$defs/safeIdentifier" },
63
+ "primary_key": {
64
+ "type": "object",
65
+ "additionalProperties": false,
66
+ "required": ["column"],
67
+ "properties": {
68
+ "column": { "$ref": "#/$defs/safeIdentifier" },
69
+ "value": { "$ref": "#/$defs/scalar" }
70
+ }
71
+ }
72
+ }
73
+ },
74
+ "before": { "$ref": "#/$defs/scalarRecord" },
75
+ "patch": { "$ref": "#/$defs/scalarRecord" },
76
+ "after": { "$ref": "#/$defs/scalarRecord" },
77
+ "guards": {
78
+ "type": "object",
79
+ "additionalProperties": false,
80
+ "required": ["tenant", "allowed_columns"],
81
+ "properties": {
82
+ "tenant": { "$ref": "#/$defs/columnValue" },
83
+ "allowed_columns": {
84
+ "type": "array",
85
+ "items": { "$ref": "#/$defs/safeIdentifier" },
86
+ "maxItems": 256,
87
+ "uniqueItems": true
88
+ },
89
+ "expected_version": { "$ref": "#/$defs/columnValue" },
90
+ "version_advance": { "$ref": "#/$defs/versionAdvance" },
91
+ "deduplication": { "$ref": "#/$defs/deduplication" }
92
+ }
93
+ },
94
+ "evidence": {
95
+ "type": "object",
96
+ "additionalProperties": true,
97
+ "required": ["bundle_id", "query_fingerprint", "items"],
98
+ "properties": {
99
+ "bundle_id": { "type": "string", "minLength": 1 },
100
+ "query_fingerprint": { "$ref": "#/$defs/sha256" },
101
+ "items": { "type": "array", "maxItems": 1000 }
102
+ }
103
+ },
104
+ "approval": {
105
+ "type": "object",
106
+ "additionalProperties": true,
107
+ "required": ["status"],
108
+ "properties": {
109
+ "status": { "enum": ["pending", "approved", "rejected", "canceled"] },
110
+ "required_role": { "type": "string" },
111
+ "required_approvals": { "type": "integer", "minimum": 1, "maximum": 10 }
112
+ }
113
+ },
114
+ "writeback": {
115
+ "type": "object",
116
+ "additionalProperties": true,
117
+ "required": ["status", "mode"],
118
+ "properties": {
119
+ "status": { "enum": ["not_applied", "pending_worker", "applied", "conflict", "failed", "canceled", "reconciliation_required"] },
120
+ "mode": { "enum": ["trusted_worker_required", "synapsor_merge", "read_only"] }
121
+ }
122
+ },
123
+ "source_database_mutated": { "type": "boolean" },
124
+ "integrity": {
125
+ "type": "object",
126
+ "additionalProperties": false,
127
+ "required": ["proposal_hash"],
128
+ "properties": { "proposal_hash": { "$ref": "#/$defs/sha256" } }
129
+ },
130
+ "created_at": { "type": "string", "format": "date-time" }
131
+ },
132
+ "allOf": [
133
+ {
134
+ "if": { "properties": { "operation": { "const": "single_row_insert" } } },
135
+ "then": {
136
+ "properties": {
137
+ "before": { "maxProperties": 0 },
138
+ "patch": { "minProperties": 1 },
139
+ "after": { "minProperties": 1 },
140
+ "guards": {
141
+ "required": ["deduplication"],
142
+ "not": { "anyOf": [{ "required": ["expected_version"] }, { "required": ["version_advance"] }] },
143
+ "properties": {
144
+ "allowed_columns": { "minItems": 1 },
145
+ "deduplication": {
146
+ "properties": {
147
+ "components": {
148
+ "allOf": [
149
+ { "contains": { "properties": { "source": { "const": "proposal_id" } }, "required": ["source"] } },
150
+ { "contains": { "properties": { "source": { "const": "trusted_tenant" } }, "required": ["source"] } }
151
+ ]
152
+ }
153
+ }
154
+ }
155
+ }
156
+ }
157
+ }
158
+ }
159
+ },
160
+ {
161
+ "if": { "properties": { "operation": { "const": "single_row_update" } } },
162
+ "then": {
163
+ "properties": {
164
+ "source": { "properties": { "primary_key": { "required": ["value"] } } },
165
+ "before": { "minProperties": 1 },
166
+ "patch": { "minProperties": 1 },
167
+ "after": { "minProperties": 1 },
168
+ "guards": {
169
+ "required": ["expected_version"],
170
+ "not": { "required": ["deduplication"] },
171
+ "properties": { "allowed_columns": { "minItems": 1 } }
172
+ }
173
+ }
174
+ }
175
+ },
176
+ {
177
+ "if": { "properties": { "operation": { "const": "single_row_delete" } } },
178
+ "then": {
179
+ "properties": {
180
+ "source": { "properties": { "primary_key": { "required": ["value"] } } },
181
+ "before": { "minProperties": 1 },
182
+ "patch": { "maxProperties": 0 },
183
+ "after": { "maxProperties": 0 },
184
+ "guards": {
185
+ "required": ["expected_version"],
186
+ "not": { "anyOf": [{ "required": ["version_advance"] }, { "required": ["deduplication"] }] },
187
+ "properties": { "allowed_columns": { "maxItems": 0 } }
188
+ }
189
+ }
190
+ }
191
+ }
192
+ ],
193
+ "$defs": {
194
+ "safeIdentifier": { "type": "string", "pattern": "^[A-Za-z_][A-Za-z0-9_]*$" },
195
+ "sha256": { "type": "string", "pattern": "^sha256:.+" },
196
+ "scalar": { "type": ["string", "number", "boolean", "null"] },
197
+ "scalarRecord": {
198
+ "type": "object",
199
+ "propertyNames": { "$ref": "#/$defs/safeIdentifier" },
200
+ "additionalProperties": { "$ref": "#/$defs/scalar" },
201
+ "maxProperties": 256
202
+ },
203
+ "columnValue": {
204
+ "type": "object",
205
+ "additionalProperties": false,
206
+ "required": ["column", "value"],
207
+ "properties": {
208
+ "column": { "$ref": "#/$defs/safeIdentifier" },
209
+ "value": { "$ref": "#/$defs/scalar" }
210
+ }
211
+ },
212
+ "versionAdvance": {
213
+ "type": "object",
214
+ "additionalProperties": false,
215
+ "required": ["column", "strategy"],
216
+ "properties": {
217
+ "column": { "$ref": "#/$defs/safeIdentifier" },
218
+ "strategy": { "enum": ["integer_increment", "database_generated"] }
219
+ }
220
+ },
221
+ "deduplicationComponent": {
222
+ "type": "object",
223
+ "additionalProperties": false,
224
+ "required": ["column", "value", "source"],
225
+ "properties": {
226
+ "column": { "$ref": "#/$defs/safeIdentifier" },
227
+ "value": { "$ref": "#/$defs/scalar" },
228
+ "source": { "enum": ["proposal_id", "trusted_tenant", "fixed"] }
229
+ }
230
+ },
231
+ "deduplication": {
232
+ "type": "object",
233
+ "additionalProperties": false,
234
+ "required": ["components"],
235
+ "properties": {
236
+ "components": {
237
+ "type": "array",
238
+ "items": { "$ref": "#/$defs/deduplicationComponent" },
239
+ "minItems": 1,
240
+ "maxItems": 8
241
+ }
242
+ }
243
+ }
244
+ }
245
+ }
@@ -0,0 +1,112 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://schemas.synapsor.ai/synapsor.change-set.v3.schema.json",
4
+ "title": "Synapsor Bounded Change Set v3",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["schema_version", "proposal_id", "proposal_version", "action", "operation", "mode", "principal", "scope", "source", "before", "patch", "after", "guards", "frozen_set", "evidence", "approval", "writeback", "source_database_mutated", "integrity", "created_at"],
8
+ "properties": {
9
+ "schema_version": { "const": "synapsor.change-set.v3" },
10
+ "proposal_id": { "type": "string", "minLength": 1 },
11
+ "proposal_version": { "type": "integer", "minimum": 1 },
12
+ "action": { "type": "string", "minLength": 1 },
13
+ "operation": { "$ref": "#/$defs/setOperation" },
14
+ "mode": { "enum": ["read_only", "shadow", "review_required", "approved_for_writeback"] },
15
+ "principal": {
16
+ "type": "object", "additionalProperties": false, "required": ["id", "source"],
17
+ "properties": { "id": { "type": "string", "minLength": 1 }, "source": { "enum": ["trusted_session", "cloud_session", "environment", "static_dev"] } }
18
+ },
19
+ "scope": {
20
+ "type": "object", "additionalProperties": false, "required": ["tenant_id", "business_object", "object_id"],
21
+ "properties": { "tenant_id": { "type": "string", "minLength": 1 }, "business_object": { "type": "string", "minLength": 1 }, "object_id": { "type": "string", "minLength": 1 } }
22
+ },
23
+ "source": {
24
+ "type": "object", "additionalProperties": false, "required": ["kind", "source_id", "schema", "table", "primary_key"],
25
+ "properties": {
26
+ "kind": { "enum": ["external_postgres", "external_mysql", "synapsor_table"] },
27
+ "source_id": { "type": "string", "minLength": 1 },
28
+ "schema": { "$ref": "#/$defs/safeIdentifier" },
29
+ "table": { "$ref": "#/$defs/safeIdentifier" },
30
+ "primary_key": { "type": "object", "additionalProperties": false, "required": ["column"], "properties": { "column": { "$ref": "#/$defs/safeIdentifier" } } }
31
+ }
32
+ },
33
+ "before": { "$ref": "#/$defs/scalarRecord" },
34
+ "patch": { "$ref": "#/$defs/scalarRecord" },
35
+ "after": { "$ref": "#/$defs/scalarRecord" },
36
+ "guards": {
37
+ "type": "object", "additionalProperties": false, "required": ["tenant", "allowed_columns"],
38
+ "properties": {
39
+ "tenant": { "$ref": "#/$defs/columnValue" },
40
+ "allowed_columns": { "type": "array", "items": { "$ref": "#/$defs/safeIdentifier" }, "maxItems": 256, "uniqueItems": true },
41
+ "version_advance": { "$ref": "#/$defs/versionAdvance" }
42
+ }
43
+ },
44
+ "frozen_set": { "$ref": "#/$defs/frozenSet" },
45
+ "evidence": {
46
+ "type": "object", "additionalProperties": true, "required": ["bundle_id", "query_fingerprint", "items"],
47
+ "properties": { "bundle_id": { "type": "string", "minLength": 1 }, "query_fingerprint": { "$ref": "#/$defs/sha256" }, "items": { "type": "array", "maxItems": 100 } }
48
+ },
49
+ "approval": {
50
+ "type": "object", "additionalProperties": true, "required": ["status", "mode"],
51
+ "properties": { "status": { "enum": ["pending", "approved", "rejected", "canceled"] }, "mode": { "enum": ["human", "operator"] }, "required_role": { "type": "string", "minLength": 1 }, "required_approvals": { "type": "integer", "minimum": 1, "maximum": 10 } }
52
+ },
53
+ "writeback": {
54
+ "type": "object", "additionalProperties": true, "required": ["status", "mode", "executor"],
55
+ "properties": { "status": { "enum": ["not_applied", "pending_worker", "applied", "conflict", "failed", "canceled", "reconciliation_required"] }, "mode": { "const": "trusted_worker_required" }, "executor": { "const": "sql_update" } }
56
+ },
57
+ "source_database_mutated": { "type": "boolean" },
58
+ "integrity": { "type": "object", "additionalProperties": false, "required": ["proposal_hash"], "properties": { "proposal_hash": { "$ref": "#/$defs/sha256" } } },
59
+ "created_at": { "type": "string", "format": "date-time" }
60
+ },
61
+ "allOf": [
62
+ {
63
+ "if": { "properties": { "operation": { "const": "set_update" } }, "required": ["operation"] },
64
+ "then": {
65
+ "properties": {
66
+ "patch": { "minProperties": 1 },
67
+ "guards": { "required": ["version_advance"], "properties": { "allowed_columns": { "minItems": 1 }, "version_advance": { "properties": { "strategy": { "const": "integer_increment" } } } } },
68
+ "frozen_set": { "properties": { "members": { "items": { "required": ["expected_version", "before_digest", "after_digest"], "not": { "anyOf": [{ "required": ["tombstone_digest"] }, { "required": ["deduplication"] }] } } } } }
69
+ }
70
+ }
71
+ },
72
+ {
73
+ "if": { "properties": { "operation": { "const": "set_delete" } }, "required": ["operation"] },
74
+ "then": {
75
+ "properties": {
76
+ "patch": { "maxProperties": 0 },
77
+ "guards": { "not": { "required": ["version_advance"] }, "properties": { "allowed_columns": { "maxItems": 0 } } },
78
+ "frozen_set": { "properties": { "members": { "items": { "required": ["expected_version", "before_digest", "tombstone_digest"], "properties": { "after": { "maxProperties": 0 } }, "not": { "anyOf": [{ "required": ["after_digest"] }, { "required": ["deduplication"] }] } } } } }
79
+ }
80
+ }
81
+ },
82
+ {
83
+ "if": { "properties": { "operation": { "const": "batch_insert" } }, "required": ["operation"] },
84
+ "then": {
85
+ "properties": {
86
+ "guards": { "not": { "required": ["version_advance"] }, "properties": { "allowed_columns": { "minItems": 1 } } },
87
+ "frozen_set": { "properties": { "members": { "items": { "required": ["after_digest", "deduplication"], "properties": { "before": { "maxProperties": 0 }, "after": { "minProperties": 1 } }, "not": { "anyOf": [{ "required": ["expected_version"] }, { "required": ["before_digest"] }, { "required": ["tombstone_digest"] }] } } } } }
88
+ }
89
+ }
90
+ }
91
+ ],
92
+ "$defs": {
93
+ "safeIdentifier": { "type": "string", "pattern": "^[A-Za-z_][A-Za-z0-9_]*$" },
94
+ "sha256": { "type": "string", "pattern": "^sha256:.+" },
95
+ "scalar": { "type": ["string", "number", "boolean", "null"] },
96
+ "scalarRecord": { "type": "object", "propertyNames": { "$ref": "#/$defs/safeIdentifier" }, "additionalProperties": { "$ref": "#/$defs/scalar" }, "maxProperties": 256 },
97
+ "setOperation": { "enum": ["set_update", "set_delete", "batch_insert"] },
98
+ "columnValue": { "type": "object", "additionalProperties": false, "required": ["column", "value"], "properties": { "column": { "$ref": "#/$defs/safeIdentifier" }, "value": { "$ref": "#/$defs/scalar" } } },
99
+ "versionAdvance": { "type": "object", "additionalProperties": false, "required": ["column", "strategy"], "properties": { "column": { "$ref": "#/$defs/safeIdentifier" }, "strategy": { "enum": ["integer_increment", "database_generated"] } } },
100
+ "deduplicationComponent": { "type": "object", "additionalProperties": false, "required": ["column", "value", "source"], "properties": { "column": { "$ref": "#/$defs/safeIdentifier" }, "value": { "$ref": "#/$defs/scalar" }, "source": { "enum": ["proposal_id", "trusted_tenant", "fixed"] } } },
101
+ "deduplication": { "type": "object", "additionalProperties": false, "required": ["components"], "properties": { "components": { "type": "array", "items": { "$ref": "#/$defs/deduplicationComponent" }, "minItems": 1, "maxItems": 8 } } },
102
+ "aggregateBound": { "type": "object", "additionalProperties": false, "required": ["column", "measure", "maximum", "actual"], "properties": { "column": { "$ref": "#/$defs/safeIdentifier" }, "measure": { "enum": ["before", "after", "absolute_delta"] }, "maximum": { "type": "number", "minimum": 0 }, "actual": { "type": "number", "minimum": 0 } } },
103
+ "frozenMember": {
104
+ "type": "object", "additionalProperties": false, "required": ["primary_key", "before", "after"],
105
+ "properties": { "primary_key": { "$ref": "#/$defs/columnValue" }, "expected_version": { "$ref": "#/$defs/columnValue" }, "before": { "$ref": "#/$defs/scalarRecord" }, "after": { "$ref": "#/$defs/scalarRecord" }, "before_digest": { "$ref": "#/$defs/sha256" }, "after_digest": { "$ref": "#/$defs/sha256" }, "tombstone_digest": { "$ref": "#/$defs/sha256" }, "deduplication": { "$ref": "#/$defs/deduplication" } }
106
+ },
107
+ "frozenSet": {
108
+ "type": "object", "additionalProperties": false, "required": ["max_rows", "row_count", "aggregate_bounds", "members", "set_digest"],
109
+ "properties": { "max_rows": { "type": "integer", "minimum": 1, "maximum": 100 }, "row_count": { "type": "integer", "minimum": 1, "maximum": 100 }, "aggregate_bounds": { "type": "array", "items": { "$ref": "#/$defs/aggregateBound" }, "minItems": 1, "maxItems": 8 }, "members": { "type": "array", "items": { "$ref": "#/$defs/frozenMember" }, "minItems": 1, "maxItems": 100 }, "set_digest": { "$ref": "#/$defs/sha256" } }
110
+ }
111
+ }
112
+ }
@@ -0,0 +1,32 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://schemas.synapsor.ai/synapsor.compensation-change-set.v1.schema.json",
4
+ "title": "Synapsor Reviewed Compensation Change Set v1",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["schema_version", "proposal_id", "proposal_version", "action", "mode", "principal", "scope", "source", "before", "patch", "after", "compensation", "guards", "evidence", "approval", "writeback", "source_database_mutated", "integrity", "created_at"],
8
+ "properties": {
9
+ "schema_version": { "const": "synapsor.compensation-change-set.v1" },
10
+ "proposal_id": { "type": "string", "minLength": 1 },
11
+ "proposal_version": { "type": "integer", "minimum": 1 },
12
+ "action": { "type": "string", "minLength": 1 },
13
+ "mode": { "const": "review_required" },
14
+ "principal": { "type": "object", "additionalProperties": false, "required": ["id", "source"], "properties": { "id": { "type": "string", "minLength": 1 }, "source": { "enum": ["trusted_session", "cloud_session", "environment", "static_dev"] } } },
15
+ "scope": { "type": "object", "additionalProperties": false, "required": ["tenant_id", "business_object", "object_id"], "properties": { "tenant_id": { "type": "string", "minLength": 1 }, "business_object": { "type": "string", "minLength": 1 }, "object_id": { "type": "string", "minLength": 1 } } },
16
+ "source": { "type": "object", "additionalProperties": false, "required": ["kind", "source_id", "schema", "table", "primary_key"], "properties": { "kind": { "enum": ["external_postgres", "external_mysql"] }, "source_id": { "type": "string", "minLength": 1 }, "schema": { "$ref": "#/$defs/identifier" }, "table": { "$ref": "#/$defs/identifier" }, "primary_key": { "type": "object", "additionalProperties": false, "required": ["column"], "properties": { "column": { "$ref": "#/$defs/identifier" }, "value": { "$ref": "#/$defs/scalar" } } } } },
17
+ "before": { "$ref": "#/$defs/record" }, "patch": { "$ref": "#/$defs/record" }, "after": { "$ref": "#/$defs/record" },
18
+ "compensation": { "type": "object", "additionalProperties": false, "required": ["descriptor", "forward_receipt_hash"], "properties": { "descriptor": { "$ref": "inverse-descriptor.v1.schema.json" }, "forward_receipt_hash": { "$ref": "#/$defs/sha256" } } },
19
+ "guards": { "type": "object", "additionalProperties": false, "required": ["tenant", "allowed_columns"], "properties": { "tenant": { "$ref": "#/$defs/columnValue" }, "allowed_columns": { "type": "array", "items": { "$ref": "#/$defs/identifier" }, "maxItems": 256, "uniqueItems": true } } },
20
+ "evidence": { "type": "object", "required": ["bundle_id", "query_fingerprint", "items"], "properties": { "bundle_id": { "type": "string", "minLength": 1 }, "query_fingerprint": { "$ref": "#/$defs/sha256" }, "items": { "type": "array", "maxItems": 100 } } },
21
+ "approval": { "type": "object", "required": ["status", "mode"], "properties": { "status": { "enum": ["pending", "approved", "rejected", "canceled"] }, "mode": { "enum": ["human", "operator"] }, "required_role": { "type": "string", "minLength": 1 }, "required_approvals": { "type": "integer", "minimum": 1, "maximum": 10 } } },
22
+ "writeback": { "type": "object", "additionalProperties": false, "required": ["status", "mode", "executor"], "properties": { "status": { "const": "not_applied" }, "mode": { "const": "trusted_worker_required" }, "executor": { "const": "sql_update" } } },
23
+ "source_database_mutated": { "const": false },
24
+ "integrity": { "type": "object", "additionalProperties": false, "required": ["proposal_hash"], "properties": { "proposal_hash": { "$ref": "#/$defs/sha256" } } },
25
+ "created_at": { "type": "string", "format": "date-time" }
26
+ },
27
+ "$defs": {
28
+ "identifier": { "type": "string", "pattern": "^[A-Za-z_][A-Za-z0-9_]*$" }, "sha256": { "type": "string", "pattern": "^sha256:.+" }, "scalar": { "type": ["string", "number", "boolean", "null"] },
29
+ "record": { "type": "object", "propertyNames": { "$ref": "#/$defs/identifier" }, "additionalProperties": { "$ref": "#/$defs/scalar" }, "maxProperties": 256 },
30
+ "columnValue": { "type": "object", "additionalProperties": false, "required": ["column", "value"], "properties": { "column": { "$ref": "#/$defs/identifier" }, "value": { "$ref": "#/$defs/scalar" } } }
31
+ }
32
+ }
@@ -0,0 +1,106 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://schemas.synapsor.ai/synapsor.execution-receipt.v2.schema.json",
4
+ "title": "Synapsor Execution Receipt v2",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": [
8
+ "schema_version",
9
+ "writeback_job_id",
10
+ "proposal_id",
11
+ "proposal_hash",
12
+ "approval_id",
13
+ "runner_id",
14
+ "operation",
15
+ "receipt_authority",
16
+ "status",
17
+ "target",
18
+ "rows_affected",
19
+ "idempotency_key",
20
+ "source_database_mutated",
21
+ "safe_outcome_code",
22
+ "executed_at",
23
+ "receipt_hash"
24
+ ],
25
+ "properties": {
26
+ "schema_version": { "const": "synapsor.execution-receipt.v2" },
27
+ "writeback_job_id": { "type": "string", "minLength": 1 },
28
+ "proposal_id": { "type": "string", "minLength": 1 },
29
+ "proposal_hash": { "$ref": "#/$defs/sha256" },
30
+ "approval_id": { "type": "string", "minLength": 1 },
31
+ "runner_id": { "type": "string", "minLength": 1 },
32
+ "operation": { "enum": ["single_row_update", "single_row_insert", "single_row_delete"] },
33
+ "receipt_authority": { "enum": ["source_db", "runner_ledger"] },
34
+ "status": { "enum": ["applied", "conflict", "failed", "canceled", "already_applied", "reconciliation_required"] },
35
+ "target": {
36
+ "type": "object",
37
+ "additionalProperties": false,
38
+ "required": ["source_id", "schema", "table", "identity"],
39
+ "properties": {
40
+ "source_id": { "type": "string", "minLength": 1 },
41
+ "schema": { "$ref": "#/$defs/safeIdentifier" },
42
+ "table": { "$ref": "#/$defs/safeIdentifier" },
43
+ "identity": {
44
+ "type": "array",
45
+ "items": { "$ref": "#/$defs/columnValue" },
46
+ "minItems": 1,
47
+ "maxItems": 8
48
+ }
49
+ }
50
+ },
51
+ "rows_affected": { "type": "integer", "minimum": 0, "maximum": 1 },
52
+ "idempotency_key": { "type": "string", "minLength": 1 },
53
+ "before_digest": { "$ref": "#/$defs/sha256" },
54
+ "after_digest": { "$ref": "#/$defs/sha256" },
55
+ "tombstone_digest": { "$ref": "#/$defs/sha256" },
56
+ "source_database_mutated": { "type": "boolean" },
57
+ "safe_outcome_code": { "$ref": "#/$defs/code" },
58
+ "safe_error_code": { "$ref": "#/$defs/code" },
59
+ "executed_at": { "type": "string", "format": "date-time" },
60
+ "receipt_hash": { "$ref": "#/$defs/sha256" },
61
+ "reconciliation": {
62
+ "type": "object",
63
+ "additionalProperties": false,
64
+ "required": ["intent_id", "reason"],
65
+ "properties": {
66
+ "intent_id": { "type": "string", "minLength": 1 },
67
+ "reason": { "type": "string", "minLength": 1 }
68
+ }
69
+ }
70
+ },
71
+ "allOf": [
72
+ {
73
+ "if": { "properties": { "status": { "const": "reconciliation_required" } } },
74
+ "then": { "required": ["reconciliation"] }
75
+ },
76
+ {
77
+ "if": {
78
+ "properties": {
79
+ "operation": { "const": "single_row_delete" },
80
+ "status": { "enum": ["applied", "already_applied"] }
81
+ },
82
+ "required": ["operation", "status"]
83
+ },
84
+ "then": { "required": ["tombstone_digest"] }
85
+ },
86
+ {
87
+ "if": { "properties": { "rows_affected": { "minimum": 1 } } },
88
+ "then": { "properties": { "source_database_mutated": { "const": true } } }
89
+ }
90
+ ],
91
+ "$defs": {
92
+ "safeIdentifier": { "type": "string", "pattern": "^[A-Za-z_][A-Za-z0-9_]*$" },
93
+ "sha256": { "type": "string", "pattern": "^sha256:.+" },
94
+ "code": { "type": "string", "pattern": "^[A-Z][A-Z0-9_]*$" },
95
+ "scalar": { "type": ["string", "number", "boolean", "null"] },
96
+ "columnValue": {
97
+ "type": "object",
98
+ "additionalProperties": false,
99
+ "required": ["column", "value"],
100
+ "properties": {
101
+ "column": { "$ref": "#/$defs/safeIdentifier" },
102
+ "value": { "$ref": "#/$defs/scalar" }
103
+ }
104
+ }
105
+ }
106
+ }