@synapsor/runner 1.4.1 → 1.4.121
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/CHANGELOG.md +58 -0
- package/README.md +40 -43
- package/THREAT_MODEL.md +6 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/runner.mjs +28399 -3814
- package/docs/README.md +10 -0
- package/docs/aggregate-reads.md +49 -0
- package/docs/bounded-set-writeback.md +9 -4
- package/docs/compliance-reports.md +42 -0
- package/docs/conformance.md +9 -0
- package/docs/contract-review.md +57 -0
- package/docs/contract-testing.md +47 -0
- package/docs/dsl-reference.md +39 -6
- package/docs/getting-started-own-database.md +8 -1
- package/docs/graduated-trust.md +64 -0
- package/docs/limitations.md +10 -0
- package/docs/production.md +10 -0
- package/docs/release-notes.md +53 -0
- package/docs/runner-config-reference.md +16 -0
- package/docs/security-boundary.md +13 -0
- package/docs/troubleshooting-first-run.md +20 -0
- package/examples/runner-fleet/seed/postgres.sql +1 -0
- package/examples/support-plan-credit/synapsor.contract-tests.json +53 -0
- package/fixtures/dsl/aggregate-read.synapsor.sql +21 -0
- package/fixtures/dsl/bounded-set-multi-term.synapsor.sql +30 -0
- package/package.json +4 -1
- package/schemas/synapsor.contract-tests.schema.json +44 -0
- package/schemas/synapsor.runner.schema.json +92 -4
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "../../schemas/synapsor.contract-tests.schema.json",
|
|
3
|
+
"version": 1,
|
|
4
|
+
"name": "support-plan-credit contract boundary",
|
|
5
|
+
"tests": [
|
|
6
|
+
{
|
|
7
|
+
"id": "operator-controls-stay-outside-mcp",
|
|
8
|
+
"kind": "operator_boundary",
|
|
9
|
+
"capability": "support.propose_plan_credit"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"id": "private-customer-fields-stay-hidden",
|
|
13
|
+
"kind": "hide_fields",
|
|
14
|
+
"capability": "support.inspect_customer",
|
|
15
|
+
"args": { "customer_id": "CUS-3001" },
|
|
16
|
+
"trusted_context": { "tenant_id": "acme", "principal": "contract_test" },
|
|
17
|
+
"fields": ["card_token", "raw_payment_method", "internal_risk_score", "private_notes"]
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"id": "credit-amount-is-bounded",
|
|
21
|
+
"kind": "argument_constraint",
|
|
22
|
+
"capability": "support.propose_plan_credit_record",
|
|
23
|
+
"argument": "credit_cents",
|
|
24
|
+
"expected": { "minimum": 1, "maximum": 50000 }
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"id": "trusted-tenant-can-read-own-customer",
|
|
28
|
+
"kind": "tool_allow",
|
|
29
|
+
"capability": "support.inspect_customer",
|
|
30
|
+
"args": { "customer_id": "CUS-3001" },
|
|
31
|
+
"trusted_context": { "tenant_id": "acme", "principal": "contract_test" }
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": "trusted-tenant-cannot-read-other-customer",
|
|
35
|
+
"kind": "tool_deny",
|
|
36
|
+
"capability": "support.inspect_customer",
|
|
37
|
+
"args": { "customer_id": "CUS-9001" },
|
|
38
|
+
"trusted_context": { "tenant_id": "acme", "principal": "contract_test" },
|
|
39
|
+
"expected_code": "NOT_FOUND_IN_TENANT"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"id": "proposal-does-not-write-before-approval",
|
|
43
|
+
"kind": "source_unchanged_before_approval",
|
|
44
|
+
"capability": "support.propose_plan_credit",
|
|
45
|
+
"args": {
|
|
46
|
+
"customer_id": "CUS-3001",
|
|
47
|
+
"credit_cents": 10000,
|
|
48
|
+
"reason": "synthetic conformance check"
|
|
49
|
+
},
|
|
50
|
+
"trusted_context": { "tenant_id": "acme", "principal": "contract_test" }
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
CREATE AGENT CONTEXT finance_operator
|
|
2
|
+
BIND tenant_id FROM ENVIRONMENT SYNAPSOR_TENANT_ID REQUIRED
|
|
3
|
+
BIND principal FROM ENVIRONMENT SYNAPSOR_PRINCIPAL REQUIRED
|
|
4
|
+
TENANT BINDING tenant_id
|
|
5
|
+
PRINCIPAL BINDING principal
|
|
6
|
+
END
|
|
7
|
+
|
|
8
|
+
CREATE CAPABILITY billing.overdue_balance_total
|
|
9
|
+
DESCRIPTION 'Return one suppressed overdue-balance aggregate for the trusted tenant.'
|
|
10
|
+
RETURNS HINT 'Returns one scalar or a suppression result; never member rows.'
|
|
11
|
+
USING CONTEXT finance_operator
|
|
12
|
+
SOURCE local_postgres
|
|
13
|
+
ON public.invoices
|
|
14
|
+
PRIMARY KEY id
|
|
15
|
+
TENANT KEY tenant_id
|
|
16
|
+
AGGREGATE READ SUM balance_cents
|
|
17
|
+
SELECT WHERE status = 'overdue'
|
|
18
|
+
MIN GROUP SIZE 5
|
|
19
|
+
KEEP OUT customer_email, private_notes
|
|
20
|
+
REQUIRE EVIDENCE
|
|
21
|
+
END
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
CREATE AGENT CONTEXT local_operator
|
|
2
|
+
BIND tenant_id FROM ENVIRONMENT SYNAPSOR_TENANT_ID REQUIRED
|
|
3
|
+
BIND principal FROM ENVIRONMENT SYNAPSOR_PRINCIPAL REQUIRED
|
|
4
|
+
TENANT BINDING tenant_id
|
|
5
|
+
PRINCIPAL BINDING principal
|
|
6
|
+
END
|
|
7
|
+
|
|
8
|
+
CREATE CAPABILITY cases.close_high_risk
|
|
9
|
+
DESCRIPTION 'Close active high-risk support cases within reviewed row and value caps.'
|
|
10
|
+
RETURNS HINT 'Returns a proposal for the exact reviewed set; source rows remain unchanged.'
|
|
11
|
+
USING CONTEXT local_operator
|
|
12
|
+
SOURCE support_db
|
|
13
|
+
ON public.support_cases
|
|
14
|
+
PRIMARY KEY id
|
|
15
|
+
TENANT KEY tenant_id
|
|
16
|
+
CONFLICT GUARD version
|
|
17
|
+
LOOKUP reason BY id
|
|
18
|
+
ARG reason STRING REQUIRED MAX LENGTH 100
|
|
19
|
+
ALLOW READ id, tenant_id, risk_level, case_status, exposure_cents, version
|
|
20
|
+
REQUIRE EVIDENCE
|
|
21
|
+
PROPOSE ACTION close_high_risk UPDATE SET
|
|
22
|
+
SELECT WHERE risk_level = 'high' AND case_status = 'active'
|
|
23
|
+
MAX ROWS 10
|
|
24
|
+
MAX TOTAL exposure_cents BEFORE 50000
|
|
25
|
+
ALLOW WRITE case_status
|
|
26
|
+
PATCH case_status = 'closed'
|
|
27
|
+
ADVANCE VERSION version USING INTEGER INCREMENT
|
|
28
|
+
APPROVAL ROLE support_manager
|
|
29
|
+
WRITEBACK DIRECT SQL
|
|
30
|
+
END
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@synapsor/runner",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.121",
|
|
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",
|
|
@@ -62,7 +62,10 @@
|
|
|
62
62
|
"@modelcontextprotocol/sdk": "1.29.0",
|
|
63
63
|
"jose": "6.2.3",
|
|
64
64
|
"mysql2": "^3.11.0",
|
|
65
|
+
"pdf-lib": "1.17.1",
|
|
65
66
|
"pg": "^8.13.0",
|
|
67
|
+
"vscode-languageserver": "9.0.1",
|
|
68
|
+
"vscode-languageserver-textdocument": "1.0.12",
|
|
66
69
|
"zod": "^3.25.0"
|
|
67
70
|
},
|
|
68
71
|
"devDependencies": {
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://schemas.synapsor.ai/synapsor.contract-tests.schema.json",
|
|
4
|
+
"title": "Synapsor adopter contract conformance manifest",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"required": ["version", "tests"],
|
|
8
|
+
"properties": {
|
|
9
|
+
"$schema": { "type": "string", "minLength": 1 },
|
|
10
|
+
"version": { "const": 1 },
|
|
11
|
+
"name": { "type": "string", "minLength": 1 },
|
|
12
|
+
"tests": {
|
|
13
|
+
"type": "array",
|
|
14
|
+
"minItems": 1,
|
|
15
|
+
"items": {
|
|
16
|
+
"type": "object",
|
|
17
|
+
"additionalProperties": false,
|
|
18
|
+
"required": ["id", "kind", "capability"],
|
|
19
|
+
"properties": {
|
|
20
|
+
"id": { "type": "string", "minLength": 1 },
|
|
21
|
+
"kind": {
|
|
22
|
+
"enum": ["tool_allow", "tool_deny", "hide_fields", "argument_constraint", "transition_guard", "set_cap", "source_unchanged_before_approval", "operator_boundary"]
|
|
23
|
+
},
|
|
24
|
+
"capability": { "type": "string", "minLength": 1 },
|
|
25
|
+
"args": { "type": "object" },
|
|
26
|
+
"trusted_context": {
|
|
27
|
+
"type": "object",
|
|
28
|
+
"additionalProperties": false,
|
|
29
|
+
"required": ["tenant_id", "principal"],
|
|
30
|
+
"properties": {
|
|
31
|
+
"tenant_id": { "type": "string", "minLength": 1 },
|
|
32
|
+
"principal": { "type": "string", "minLength": 1 },
|
|
33
|
+
"provenance": { "enum": ["environment", "static_dev", "http_claims", "cloud_session"] }
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"expected_code": { "type": "string", "minLength": 1 },
|
|
37
|
+
"fields": { "type": "array", "minItems": 1, "items": { "type": "string", "minLength": 1 }, "uniqueItems": true },
|
|
38
|
+
"argument": { "type": "string", "minLength": 1 },
|
|
39
|
+
"expected": { "type": "object" }
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -176,6 +176,23 @@
|
|
|
176
176
|
"token_env": { "$ref": "#/$defs/env_name" }
|
|
177
177
|
}
|
|
178
178
|
},
|
|
179
|
+
"graduated_trust": {
|
|
180
|
+
"description": "Disabled-by-default operator criteria for bounded policy recommendations. Recommendations never activate contracts.",
|
|
181
|
+
"type": "object",
|
|
182
|
+
"additionalProperties": false,
|
|
183
|
+
"properties": {
|
|
184
|
+
"enabled": { "type": "boolean", "default": false },
|
|
185
|
+
"kill_switch": { "type": "boolean", "default": false },
|
|
186
|
+
"workspace_id": { "type": "string", "minLength": 1 },
|
|
187
|
+
"project_id": { "type": "string", "minLength": 1 },
|
|
188
|
+
"criteria": {
|
|
189
|
+
"type": "array",
|
|
190
|
+
"minItems": 1,
|
|
191
|
+
"maxItems": 100,
|
|
192
|
+
"items": { "$ref": "#/$defs/graduated_trust_criterion" }
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
},
|
|
179
196
|
"operator_identity": {
|
|
180
197
|
"description": "Operator identity used by approve, reject, and apply. signed_key verifies a registered key; jwt_oidc verifies asymmetric JWT claims and Runner-attests the decision; dev_env is local-development compatibility only.",
|
|
181
198
|
"type": "object",
|
|
@@ -304,6 +321,28 @@
|
|
|
304
321
|
"window_seconds": { "type": "integer", "minimum": 1, "maximum": 86400 }
|
|
305
322
|
}
|
|
306
323
|
},
|
|
324
|
+
"graduated_trust_criterion": {
|
|
325
|
+
"type": "object",
|
|
326
|
+
"additionalProperties": false,
|
|
327
|
+
"required": [
|
|
328
|
+
"capability", "policy", "field", "minimum_human_reviews", "window_days",
|
|
329
|
+
"maximum_rejection_rate", "maximum_conflict_rate", "maximum_failure_rate",
|
|
330
|
+
"maximum_revert_rate", "maximum_threshold_increase", "absolute_ceiling"
|
|
331
|
+
],
|
|
332
|
+
"properties": {
|
|
333
|
+
"capability": { "$ref": "#/$defs/qualified_name" },
|
|
334
|
+
"policy": { "type": "string", "minLength": 1 },
|
|
335
|
+
"field": { "$ref": "#/$defs/identifier" },
|
|
336
|
+
"minimum_human_reviews": { "type": "integer", "minimum": 10, "maximum": 10000 },
|
|
337
|
+
"window_days": { "type": "integer", "minimum": 1, "maximum": 365 },
|
|
338
|
+
"maximum_rejection_rate": { "type": "number", "minimum": 0, "maximum": 1 },
|
|
339
|
+
"maximum_conflict_rate": { "type": "number", "minimum": 0, "maximum": 1 },
|
|
340
|
+
"maximum_failure_rate": { "type": "number", "minimum": 0, "maximum": 1 },
|
|
341
|
+
"maximum_revert_rate": { "type": "number", "minimum": 0, "maximum": 1 },
|
|
342
|
+
"maximum_threshold_increase": { "type": "number", "exclusiveMinimum": 0 },
|
|
343
|
+
"absolute_ceiling": { "type": "number", "exclusiveMinimum": 0 }
|
|
344
|
+
}
|
|
345
|
+
},
|
|
307
346
|
"env_name": {
|
|
308
347
|
"type": "string",
|
|
309
348
|
"pattern": "^[A-Z_][A-Z0-9_]*$"
|
|
@@ -444,14 +483,27 @@
|
|
|
444
483
|
"capability": {
|
|
445
484
|
"type": "object",
|
|
446
485
|
"additionalProperties": false,
|
|
447
|
-
"required": ["name", "kind", "source", "target", "args"
|
|
486
|
+
"required": ["name", "kind", "source", "target", "args"],
|
|
487
|
+
"allOf": [
|
|
488
|
+
{
|
|
489
|
+
"if": { "properties": { "kind": { "const": "aggregate_read" } }, "required": ["kind"] },
|
|
490
|
+
"then": { "required": ["aggregate", "evidence"] },
|
|
491
|
+
"else": {
|
|
492
|
+
"required": ["lookup", "visible_columns"],
|
|
493
|
+
"properties": {
|
|
494
|
+
"args": { "minProperties": 1 },
|
|
495
|
+
"visible_columns": { "minItems": 1 }
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
],
|
|
448
500
|
"properties": {
|
|
449
501
|
"name": {
|
|
450
502
|
"$ref": "#/$defs/qualified_name"
|
|
451
503
|
},
|
|
452
504
|
"kind": {
|
|
453
505
|
"type": "string",
|
|
454
|
-
"enum": ["read", "proposal"]
|
|
506
|
+
"enum": ["read", "aggregate_read", "proposal"]
|
|
455
507
|
},
|
|
456
508
|
"description": {
|
|
457
509
|
"description": "Model-facing text shown in MCP tools/list. Describe when to use the tool.",
|
|
@@ -480,7 +532,7 @@
|
|
|
480
532
|
},
|
|
481
533
|
"args": {
|
|
482
534
|
"type": "object",
|
|
483
|
-
"minProperties":
|
|
535
|
+
"minProperties": 0,
|
|
484
536
|
"additionalProperties": {
|
|
485
537
|
"$ref": "#/$defs/arg"
|
|
486
538
|
}
|
|
@@ -498,7 +550,7 @@
|
|
|
498
550
|
},
|
|
499
551
|
"visible_columns": {
|
|
500
552
|
"type": "array",
|
|
501
|
-
"minItems":
|
|
553
|
+
"minItems": 0,
|
|
502
554
|
"items": {
|
|
503
555
|
"$ref": "#/$defs/identifier"
|
|
504
556
|
}
|
|
@@ -510,6 +562,9 @@
|
|
|
510
562
|
"type": "integer",
|
|
511
563
|
"minimum": 1
|
|
512
564
|
},
|
|
565
|
+
"aggregate": {
|
|
566
|
+
"$ref": "#/$defs/aggregate_read"
|
|
567
|
+
},
|
|
513
568
|
"patch": {
|
|
514
569
|
"type": "object",
|
|
515
570
|
"additionalProperties": {
|
|
@@ -771,6 +826,39 @@
|
|
|
771
826
|
}
|
|
772
827
|
}
|
|
773
828
|
},
|
|
829
|
+
"aggregate_read": {
|
|
830
|
+
"type": "object",
|
|
831
|
+
"additionalProperties": false,
|
|
832
|
+
"required": ["function", "minimum_group_size"],
|
|
833
|
+
"properties": {
|
|
834
|
+
"function": { "enum": ["count", "sum", "avg"] },
|
|
835
|
+
"count_mode": { "enum": ["rows", "non_null"] },
|
|
836
|
+
"column": { "$ref": "#/$defs/identifier" },
|
|
837
|
+
"selection": {
|
|
838
|
+
"type": "object",
|
|
839
|
+
"additionalProperties": false,
|
|
840
|
+
"required": ["all"],
|
|
841
|
+
"properties": {
|
|
842
|
+
"all": {
|
|
843
|
+
"type": "array",
|
|
844
|
+
"minItems": 1,
|
|
845
|
+
"maxItems": 8,
|
|
846
|
+
"items": {
|
|
847
|
+
"type": "object",
|
|
848
|
+
"additionalProperties": false,
|
|
849
|
+
"required": ["column", "operator", "value"],
|
|
850
|
+
"properties": {
|
|
851
|
+
"column": { "$ref": "#/$defs/identifier" },
|
|
852
|
+
"operator": { "const": "eq" },
|
|
853
|
+
"value": { "$ref": "#/$defs/scalar" }
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
},
|
|
859
|
+
"minimum_group_size": { "type": "integer", "minimum": 2, "maximum": 1000000 }
|
|
860
|
+
}
|
|
861
|
+
},
|
|
774
862
|
"numeric_bound": {
|
|
775
863
|
"type": "object",
|
|
776
864
|
"additionalProperties": false,
|