@crediolabs/policy-synth 0.1.3 → 0.1.5

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 (194) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +193 -5
  3. package/dist/adapters/interpreter/adapter.d.ts +38 -0
  4. package/dist/adapters/interpreter/adapter.js +522 -0
  5. package/dist/adapters/interpreter/index.d.ts +1 -0
  6. package/dist/adapters/interpreter/index.js +2 -0
  7. package/dist/adapters/oz/adapter.js +2 -0
  8. package/dist/codegen/compile-gate.d.ts +33 -0
  9. package/dist/codegen/compile-gate.js +119 -0
  10. package/dist/codegen/index.d.ts +2 -0
  11. package/dist/codegen/index.js +8 -0
  12. package/dist/codegen/template.d.ts +18 -0
  13. package/dist/codegen/template.js +131 -0
  14. package/dist/errors.d.ts +1 -1
  15. package/dist/index.d.ts +2 -0
  16. package/dist/index.js +2 -0
  17. package/dist/ir/types.d.ts +13 -2
  18. package/dist/predicate/encode.d.ts +10 -0
  19. package/dist/predicate/encode.js +249 -0
  20. package/dist/predicate/index.d.ts +1 -0
  21. package/dist/predicate/index.js +2 -0
  22. package/dist/record/decode.d.ts +6 -3
  23. package/dist/record/decode.js +13 -3
  24. package/dist/review-card/builder.d.ts +14 -0
  25. package/dist/review-card/builder.js +261 -0
  26. package/dist/review-card/conflict.d.ts +40 -0
  27. package/dist/review-card/conflict.js +111 -0
  28. package/dist/review-card/cross-check.d.ts +11 -0
  29. package/dist/review-card/cross-check.js +148 -0
  30. package/dist/review-card/index.d.ts +3 -0
  31. package/dist/review-card/index.js +4 -0
  32. package/dist/run/index.d.ts +31 -0
  33. package/dist/run/index.js +164 -0
  34. package/dist/run/schemas.d.ts +2003 -0
  35. package/dist/run/schemas.js +215 -0
  36. package/dist/synth/compose-from-recording.d.ts +35 -7
  37. package/dist/synth/compose-from-recording.js +225 -34
  38. package/dist/synth/deny-cases.d.ts +12 -0
  39. package/dist/synth/deny-cases.js +377 -0
  40. package/dist/synth/evaluate.d.ts +39 -0
  41. package/dist/synth/evaluate.js +425 -0
  42. package/dist/synth/harness.d.ts +16 -0
  43. package/dist/synth/harness.js +26 -0
  44. package/dist/synth/index.d.ts +4 -0
  45. package/dist/synth/index.js +4 -0
  46. package/dist/synth/minimize.d.ts +4 -0
  47. package/dist/synth/minimize.js +38 -0
  48. package/dist/synth/predicate-literals.d.ts +5 -0
  49. package/dist/synth/predicate-literals.js +25 -0
  50. package/dist/synth/synthesize-from-recording.d.ts +37 -5
  51. package/dist/synth/synthesize-from-recording.js +550 -18
  52. package/dist/types.d.ts +40 -1
  53. package/dist/types.js +17 -0
  54. package/dist/verify/envelope.d.ts +15 -0
  55. package/dist/verify/envelope.js +22 -0
  56. package/dist/verify/index.d.ts +3 -0
  57. package/dist/verify/index.js +3 -0
  58. package/dist/verify/simulate.d.ts +31 -0
  59. package/dist/verify/simulate.js +258 -0
  60. package/dist/verify/verify.d.ts +21 -0
  61. package/dist/verify/verify.js +189 -0
  62. package/dist-cjs/adapters/interpreter/adapter.d.ts +38 -0
  63. package/dist-cjs/adapters/interpreter/adapter.js +527 -0
  64. package/dist-cjs/adapters/interpreter/index.d.ts +1 -0
  65. package/dist-cjs/adapters/interpreter/index.js +8 -0
  66. package/dist-cjs/adapters/oz/adapter.d.ts +20 -0
  67. package/dist-cjs/adapters/oz/adapter.js +289 -0
  68. package/dist-cjs/adapters/oz/index.d.ts +1 -0
  69. package/dist-cjs/adapters/oz/index.js +8 -0
  70. package/dist-cjs/codegen/compile-gate.d.ts +33 -0
  71. package/dist-cjs/codegen/compile-gate.js +123 -0
  72. package/dist-cjs/codegen/index.d.ts +2 -0
  73. package/dist-cjs/codegen/index.js +14 -0
  74. package/dist-cjs/codegen/template.d.ts +18 -0
  75. package/dist-cjs/codegen/template.js +134 -0
  76. package/dist-cjs/errors.d.ts +37 -0
  77. package/dist-cjs/errors.js +3 -0
  78. package/dist-cjs/index.d.ts +11 -0
  79. package/dist-cjs/index.js +27 -0
  80. package/dist-cjs/ir/index.d.ts +1 -0
  81. package/dist-cjs/ir/index.js +3 -0
  82. package/dist-cjs/ir/types.d.ts +108 -0
  83. package/dist-cjs/ir/types.js +12 -0
  84. package/dist-cjs/mandate/index.d.ts +2 -0
  85. package/dist-cjs/mandate/index.js +6 -0
  86. package/dist-cjs/mandate/to-ir.d.ts +3 -0
  87. package/dist-cjs/mandate/to-ir.js +63 -0
  88. package/dist-cjs/mandate/types.d.ts +20 -0
  89. package/dist-cjs/mandate/types.js +9 -0
  90. package/dist-cjs/package.json +3 -0
  91. package/dist-cjs/predicate/encode.d.ts +10 -0
  92. package/dist-cjs/predicate/encode.js +252 -0
  93. package/dist-cjs/predicate/index.d.ts +1 -0
  94. package/dist-cjs/predicate/index.js +6 -0
  95. package/dist-cjs/record/decode.d.ts +79 -0
  96. package/dist-cjs/record/decode.js +398 -0
  97. package/dist-cjs/record/freshness.d.ts +17 -0
  98. package/dist-cjs/record/freshness.js +55 -0
  99. package/dist-cjs/record/index.d.ts +21 -0
  100. package/dist-cjs/record/index.js +166 -0
  101. package/dist-cjs/record/movements.d.ts +20 -0
  102. package/dist-cjs/record/movements.js +192 -0
  103. package/dist-cjs/record/rpc.d.ts +22 -0
  104. package/dist-cjs/record/rpc.js +74 -0
  105. package/dist-cjs/record/validate.d.ts +22 -0
  106. package/dist-cjs/record/validate.js +63 -0
  107. package/dist-cjs/registry/identify.d.ts +11 -0
  108. package/dist-cjs/registry/identify.js +87 -0
  109. package/dist-cjs/registry/index.d.ts +3 -0
  110. package/dist-cjs/registry/index.js +15 -0
  111. package/dist-cjs/registry/known-addresses.d.ts +16 -0
  112. package/dist-cjs/registry/known-addresses.js +53 -0
  113. package/dist-cjs/registry/protocols.d.ts +38 -0
  114. package/dist-cjs/registry/protocols.js +153 -0
  115. package/dist-cjs/review-card/builder.d.ts +14 -0
  116. package/dist-cjs/review-card/builder.js +264 -0
  117. package/dist-cjs/review-card/conflict.d.ts +40 -0
  118. package/dist-cjs/review-card/conflict.js +114 -0
  119. package/dist-cjs/review-card/cross-check.d.ts +11 -0
  120. package/dist-cjs/review-card/cross-check.js +151 -0
  121. package/dist-cjs/review-card/index.d.ts +3 -0
  122. package/dist-cjs/review-card/index.js +10 -0
  123. package/dist-cjs/run/index.d.ts +31 -0
  124. package/dist-cjs/run/index.js +178 -0
  125. package/dist-cjs/run/schemas.d.ts +2003 -0
  126. package/dist-cjs/run/schemas.js +218 -0
  127. package/dist-cjs/seams/index.d.ts +1 -0
  128. package/dist-cjs/seams/index.js +3 -0
  129. package/dist-cjs/seams/types.d.ts +66 -0
  130. package/dist-cjs/seams/types.js +12 -0
  131. package/dist-cjs/synth/compose-from-recording.d.ts +64 -0
  132. package/dist-cjs/synth/compose-from-recording.js +356 -0
  133. package/dist-cjs/synth/deny-cases.d.ts +12 -0
  134. package/dist-cjs/synth/deny-cases.js +380 -0
  135. package/dist-cjs/synth/evaluate.d.ts +39 -0
  136. package/dist-cjs/synth/evaluate.js +428 -0
  137. package/dist-cjs/synth/harness.d.ts +16 -0
  138. package/dist-cjs/synth/harness.js +29 -0
  139. package/dist-cjs/synth/index.d.ts +9 -0
  140. package/dist-cjs/synth/index.js +23 -0
  141. package/dist-cjs/synth/lower.d.ts +23 -0
  142. package/dist-cjs/synth/lower.js +119 -0
  143. package/dist-cjs/synth/minimize.d.ts +4 -0
  144. package/dist-cjs/synth/minimize.js +41 -0
  145. package/dist-cjs/synth/predicate-literals.d.ts +5 -0
  146. package/dist-cjs/synth/predicate-literals.js +28 -0
  147. package/dist-cjs/synth/scope.d.ts +26 -0
  148. package/dist-cjs/synth/scope.js +81 -0
  149. package/dist-cjs/synth/synthesize-from-mandate.d.ts +5 -0
  150. package/dist-cjs/synth/synthesize-from-mandate.js +37 -0
  151. package/dist-cjs/synth/synthesize-from-recording.d.ts +49 -0
  152. package/dist-cjs/synth/synthesize-from-recording.js +711 -0
  153. package/dist-cjs/types.d.ts +288 -0
  154. package/dist-cjs/types.js +55 -0
  155. package/dist-cjs/verify/envelope.d.ts +15 -0
  156. package/dist-cjs/verify/envelope.js +23 -0
  157. package/dist-cjs/verify/index.d.ts +3 -0
  158. package/dist-cjs/verify/index.js +8 -0
  159. package/dist-cjs/verify/simulate.d.ts +31 -0
  160. package/dist-cjs/verify/simulate.js +261 -0
  161. package/dist-cjs/verify/verify.d.ts +21 -0
  162. package/dist-cjs/verify/verify.js +192 -0
  163. package/package.json +43 -3
  164. package/src/adapters/interpreter/adapter.ts +642 -0
  165. package/src/adapters/interpreter/index.ts +8 -0
  166. package/src/adapters/oz/adapter.ts +2 -0
  167. package/src/codegen/compile-gate.ts +162 -0
  168. package/src/codegen/index.ts +17 -0
  169. package/src/codegen/template.ts +148 -0
  170. package/src/errors.ts +2 -0
  171. package/src/index.ts +2 -0
  172. package/src/ir/types.ts +9 -2
  173. package/src/predicate/encode.ts +307 -0
  174. package/src/predicate/index.ts +3 -0
  175. package/src/record/decode.ts +21 -10
  176. package/src/review-card/builder.ts +303 -0
  177. package/src/review-card/conflict.ts +143 -0
  178. package/src/review-card/cross-check.ts +158 -0
  179. package/src/review-card/index.ts +12 -0
  180. package/src/run/index.ts +213 -0
  181. package/src/run/schemas.ts +242 -0
  182. package/src/synth/compose-from-recording.ts +277 -43
  183. package/src/synth/deny-cases.ts +466 -0
  184. package/src/synth/evaluate.ts +493 -0
  185. package/src/synth/harness.ts +40 -0
  186. package/src/synth/index.ts +12 -0
  187. package/src/synth/minimize.ts +44 -0
  188. package/src/synth/predicate-literals.ts +27 -0
  189. package/src/synth/synthesize-from-recording.ts +655 -19
  190. package/src/types.ts +38 -2
  191. package/src/verify/envelope.ts +28 -0
  192. package/src/verify/index.ts +5 -0
  193. package/src/verify/simulate.ts +311 -0
  194. package/src/verify/verify.ts +243 -0
@@ -0,0 +1,164 @@
1
+ // packages/policy-synth/src/run/index.ts
2
+ //
3
+ // Tool-body adapters for the two core front-ends. Reachable as
4
+ // `@crediolabs/policy-synth/run` from both the MCP server (which re-exports
5
+ // for tool-registration glue) and the CLI (which calls them directly). Each
6
+ // body is a THIN adapter over the pure core:
7
+ //
8
+ // 1. Re-validate the parsed input via Zod. This is a defence-in-depth check -
9
+ // the SDK has already parsed it through the registered schema, but we never
10
+ // want a tool body to throw on garbage (the SDK treats uncaught throws as
11
+ // transport errors and the agent loses the machine-readable ToolError).
12
+ // 2. Dispatch to the matching core entry point with the minimum required
13
+ // inputs.
14
+ // 3. Return the core's ToolResponse<T> unchanged. The server layer maps it
15
+ // to the MCP envelope; nothing here knows about MCP.
16
+ //
17
+ // No business logic. No retries. No session state. The same call shape can
18
+ // drive the CLI (which calls into the same core directly without MCP).
19
+ import { placeholderOzConfig, recordTransaction, synthesizeFromMandate, synthesizeFromRecording, } from "../index.js";
20
+ import { RecordTransactionInputSchema, SynthesizePolicyInputSchema, } from "./schemas.js";
21
+ // Re-export the underlying Zod schemas so the MCP package (and any other
22
+ // downstream consumer) can import the canonical input shapes from the same
23
+ // module that owns the tool-body glue. The strict schemas are the source of
24
+ // truth - MCP tool shapes are derived from them.
25
+ export { ComposeUserResponsesSchema, InterpreterOptionsSchema, MandateSpecSchema, NetworkSchema, OzAdapterConfigSchema, RecordedTransactionSchema, RecordTransactionInputSchema, SynthesizePolicyInputSchema, ToolErrorSchema, } from "./schemas.js";
26
+ /** `record_transaction` body - wraps `recordTransaction`. The tool input
27
+ * matches the core RecordInput minus the injected `fetcher` (the transport
28
+ * layer does not own the RPC). Returns the core ToolResponse unchanged.
29
+ *
30
+ * Item 6: a try/catch envelope wraps the core call. The core's own
31
+ * `recordTransaction` already returns `{ok:false, error}` for Zod + decoder
32
+ * failures, but a throw from the SDK (e.g. a malformed hash handed to
33
+ * `@stellar/stellar-sdk`'s StrKey decoder) would otherwise surface as
34
+ * "[object Object]" in the MCP transport. The envelope converts any
35
+ * non-ToolResponse throw into a structured `RECORDING_FAILED` ToolError so
36
+ * the agent always sees a machine-readable error code. */
37
+ export async function runRecordTransaction(raw) {
38
+ const parsed = RecordTransactionInputSchema.safeParse(raw);
39
+ if (!parsed.success) {
40
+ return {
41
+ ok: false,
42
+ error: validationError('record_transaction', parsed.error.issues),
43
+ };
44
+ }
45
+ const input = parsed.data;
46
+ // Strip the wire-only `confidenceOverride` and pass the rest straight through.
47
+ const coreInput = {
48
+ network: input.network,
49
+ ...(input.hash !== undefined ? { hash: input.hash } : {}),
50
+ ...(input.xdr !== undefined ? { xdr: input.xdr } : {}),
51
+ ...(input.confidenceOverride !== undefined
52
+ ? { confidenceOverride: input.confidenceOverride }
53
+ : {}),
54
+ };
55
+ try {
56
+ return await recordTransaction(coreInput);
57
+ }
58
+ catch (e) {
59
+ return {
60
+ ok: false,
61
+ error: caughtError('record_transaction', 'RECORDING_FAILED', e),
62
+ };
63
+ }
64
+ }
65
+ /** `synthesize_policy` body - discriminated union on `source`:
66
+ * - `mandate` -> synthesizeFromMandate
67
+ * - `recording` -> synthesizeFromRecording
68
+ * Exposing BOTH front-ends through ONE tool keeps the MCP surface tiny while
69
+ * letting the agent pick the deterministic or the inferred path. The CLI
70
+ * routes the same way.
71
+ *
72
+ * Item 6: same try/catch envelope as `runRecordTransaction`. The core
73
+ * `synthesizeFromRecording` already converts ToolError-shaped throws to
74
+ * `{ok:false, error}`, but a raw throw from the SDK (e.g. an unexpected
75
+ * XDR decode error in the adapter) would otherwise surface as
76
+ * "[object Object]" in the MCP transport. */
77
+ export async function runSynthesizePolicy(raw) {
78
+ const parsed = SynthesizePolicyInputSchema.safeParse(raw);
79
+ if (!parsed.success) {
80
+ return {
81
+ ok: false,
82
+ error: validationError('synthesize_policy', parsed.error.issues),
83
+ };
84
+ }
85
+ const input = parsed.data;
86
+ const ozConfig = resolveOzConfig(input);
87
+ try {
88
+ if (input.source === 'mandate') {
89
+ // Zod's optional fields widen to `T | undefined`, which the core's
90
+ // exact-optional MandateSpec rejects; the schema already validated the
91
+ // shape, so assert it (same pattern as the recordedTx cast below).
92
+ return await synthesizeFromMandate(input.mandate, ozConfig);
93
+ }
94
+ // recording source
95
+ const recorded = input.recordedTx;
96
+ return await synthesizeFromRecording(recorded, {
97
+ network: input.network,
98
+ ...(input.userResponses !== undefined ? { userResponses: input.userResponses } : {}),
99
+ ...(input.confidenceOverride !== undefined
100
+ ? { confidenceOverride: input.confidenceOverride }
101
+ : {}),
102
+ ...(input.interpreter !== undefined ? { interpreter: input.interpreter } : {}),
103
+ }, ozConfig);
104
+ }
105
+ catch (e) {
106
+ return {
107
+ ok: false,
108
+ error: caughtError('synthesize_policy', 'SYNTHESIS_ERROR', e),
109
+ };
110
+ }
111
+ }
112
+ function resolveOzConfig(input) {
113
+ if (input.ozConfig)
114
+ return input.ozConfig;
115
+ // The mandate path is network-agnostic; fall back to mainnet so the
116
+ // placeholder OZ instance addresses are deterministic.
117
+ return placeholderOzConfig('mainnet');
118
+ }
119
+ /** Build a canonical ToolError for a Zod validation failure. The remediation
120
+ * hint points the agent back at the right tool with an empty arg bag - the
121
+ * tool name IS the machine-readable hint. */
122
+ function validationError(toolName, issues) {
123
+ const code = toolName === 'record_transaction' ? 'RECORDING_FAILED' : 'SYNTHESIS_ERROR';
124
+ return {
125
+ code,
126
+ message: `${toolName}: invalid input: ${issues
127
+ .map((i) => `${i.path.join('.') || '<root>'}: ${i.message}`)
128
+ .join('; ')}`,
129
+ severity: 'error',
130
+ retryable: false,
131
+ remediation: {
132
+ toolCall: { name: toolName, args: {} },
133
+ },
134
+ };
135
+ }
136
+ /** Build a canonical ToolError for a thrown exception caught by the tool
137
+ * envelope. We refuse to surface the raw exception's text (the MCP SDK
138
+ * stringifies thrown objects as "[object Object]"), so we extract a
139
+ * string-friendly message and tag the original error in `details` for the
140
+ * agent to inspect. The `code` is the tool's domain code (RECORDING_FAILED
141
+ * for `record_transaction`, SYNTHESIS_ERROR for `synthesize_policy`) so the
142
+ * agent dispatches on the same code the structured ToolError would carry. */
143
+ function caughtError(toolName, code, e) {
144
+ let message;
145
+ if (e instanceof Error) {
146
+ message = e.message || `${toolName}: unknown error`;
147
+ }
148
+ else if (typeof e === 'string') {
149
+ message = e;
150
+ }
151
+ else {
152
+ message = `${toolName}: caught non-Error throw of type ${typeof e}`;
153
+ }
154
+ return {
155
+ code,
156
+ message: `${toolName}: unhandled throw escaped core envelope: ${message}`,
157
+ severity: 'error',
158
+ retryable: false,
159
+ remediation: {
160
+ toolCall: { name: toolName, args: {} },
161
+ },
162
+ details: { thrown: String(e) },
163
+ };
164
+ }