@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
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Untangled Finance Limited
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -4,8 +4,13 @@ Off-chain TypeScript synthesis core for the OpenZeppelin Accounts Policy Builder
4
4
 
5
5
  It records a Soroban transaction (from an on-chain hash or a raw envelope XDR),
6
6
  synthesises the **minimal** policy that permits exactly that flow, and compiles it
7
- through the OZ Accounts adapter into a proposed policy. On-chain verify, simulate,
8
- and the unsigned install transaction are later phases.
7
+ through the OZ Accounts adapter into a proposed policy. When the policy needs
8
+ constraint shapes OZ built-ins cannot express (exact ordered swap paths, oracle
9
+ price bounds, per-method scoping, recipient allowlists), the **interpreter
10
+ adapter** is opted in to emit a parallel predicate-shaped `PolicyDocument` that
11
+ installs alongside the OZ primitives. The synthesis is self-verified end-to-end
12
+ via `simulatePolicy` / `verifyPolicy` and the runner of the deny-case harness
13
+ before any bytes are emitted.
9
14
 
10
15
  The package is pure ESM, node-compatible, and has a single runtime dependency
11
16
  (`@stellar/stellar-sdk`). MIT-licensed.
@@ -73,11 +78,194 @@ events cross-check and lowers `parseConfidence`. It therefore **fails closed** a
73
78
  the default threshold; to accept a simulation-only recording, pass an explicit
74
79
  `confidenceOverride` that clears the gate.
75
80
 
81
+ ## Interpreter predicate emission (the `interpreter` opt-in)
82
+
83
+ OZ built-ins express spending limits, simple thresholds, and weighted
84
+ thresholds. They **cannot** express an exact ordered swap path, an oracle
85
+ price bound, per-method scoping, a recipient allowlist, or an
86
+ invocation-count window. The recording path surfaces those gaps as warnings
87
+ by default ("Not covered by OZ built-in primitives: ..."). When the caller
88
+ opts in to the **interpreter adapter**, the same constraint set is routed to
89
+ the parallel interpreter IR; the adapter compiles it into a canonical
90
+ predicate `PolicyDocument` and merges it with the OZ refs. The byte blob on
91
+ the wire is the canonical XDR the on-chain interpreter will consume.
92
+
93
+ The opt-in is purely additive — every `ToolResponse` shape is unchanged; the
94
+ two new fields are `policyDocuments` (the predicate-shaped interpreter doc)
95
+ and one `policyRef` of `kind: 'interpreter'`.
96
+
97
+ ```ts
98
+ import { Address } from '@stellar/stellar-sdk'
99
+ import {
100
+ synthesizeFromRecording,
101
+ placeholderOzConfig,
102
+ } from '@crediolabs/policy-synth'
103
+
104
+ const oz = placeholderOzConfig('mainnet')
105
+ const smartAccount = Address.contract(Buffer.alloc(32, 0xee)).toString()
106
+
107
+ const result = synthesizeFromRecording(
108
+ recordedTx,
109
+ {
110
+ network: 'mainnet',
111
+ userResponses: {
112
+ windowSeconds: 2592000, // 30 days
113
+ limitAmount: '1000000000', // supplied cap
114
+ validUntilLedger: 200000000, // future ledger
115
+ oraclePriceBound: [ // optional oracle bound
116
+ { asset: 'CEURC', operator: 'lt', value: '1000000000' },
117
+ ],
118
+ swapRecipientAllowlist: ['GOWNER'], // optional allowlist
119
+ },
120
+ interpreter: {
121
+ smartAccountAddress: smartAccount, // MUST be a C... contract address
122
+ installNonce: 1, // first install -> 1
123
+ // oracleParams: { maxStalenessSeconds: 60, maxDeviationBps: 100 }
124
+ // (tighten-only vs the wasm defaults; widening is rejected)
125
+ },
126
+ },
127
+ oz
128
+ )
129
+
130
+ if (result.ok) {
131
+ console.log(result.data.policyDocuments.length) // >= 1 when constraints are routable
132
+ const interpreterRef = result.data.policyRefs.find((r) => r.kind === 'interpreter')
133
+ console.log(interpreterRef?.predicateBlobBase64) // canonical XDR, base64
134
+ console.log(result.data.contextRule.validUntilLedger)
135
+ }
136
+ ```
137
+
138
+ The interpreter compile path is **fail-closed**:
139
+
140
+ - `SCOPE_SELF_CALL` — the call's recipient equals the smart account.
141
+ - `ORACLE_LEAF_INVALID_POSITION` — an oracle leaf is wrongly nested.
142
+ - `ORACLE_PARAMS_OUT_OF_RANGE` — `oracleParams` widening vs the wasm defaults.
143
+ - `SYNTHESIS_ERROR` — the interpreter IR is not fully covered.
144
+ - `DENY_CASE_FAILURE` — the emitted predicate fails the deny-case battery;
145
+ `details.failures` lists the flipped dimension(s).
146
+
147
+ A recorded swap that compiles to a permissive policy under OZ alone therefore
148
+ stays permissive unless the interpreter opt-in is supplied AND the predicate
149
+ self-verifies end-to-end.
150
+
151
+ ### Self-verify + minimise (always-on with the opt-in)
152
+
153
+ Opting in to the interpreter also turns on the **self-verify pipeline**:
154
+
155
+ 1. The adapter emits the candidate predicate.
156
+ 2. The synth builds a permit `EvalContext` from the recorded transaction (the
157
+ only call the user actually performed).
158
+ 3. The candidate is **minimised** — load-bearing-free top-level conjuncts are
159
+ dropped (`and` predicates only; other shapes are returned unchanged).
160
+ 4. The minimised predicate is run through the deny-case battery — a structural
161
+ fingerprint across `contract`, `function`, `args`, `amount`, `window`,
162
+ `oracle`, `recipient`, `frequency`. Each case must deny.
163
+ 5. The intended recorded call is evaluated against the predicate; it must
164
+ permit.
165
+ 6. The (possibly minimised) predicate is re-encoded; the canonical bytes + the
166
+ SHA-256 hash are stamped back onto the `PolicyDocument` and the
167
+ `interpreter` `policyRef`.
168
+
169
+ A successful `ok: true` is the proof that the emitted document is minimal AND
170
+ self-verified. A failure surfaces the matching gate code (see above).
171
+
172
+ ## Simulate and verify (the `verify/` surface)
173
+
174
+ The same self-verify pipeline is exposed as a public API for callers that want
175
+ to re-run a check on a proposed predicate without re-synthesising:
176
+
177
+ ```ts
178
+ import { simulatePolicy, verifyPolicy } from '@crediolabs/policy-synth'
179
+
180
+ // Runtime check: re-evaluate the predicate against the recorded call.
181
+ const runtime = simulatePolicy(predicate, recordedTx, {
182
+ validUntilLedger: 200000000,
183
+ oraclePricesByAsset: { CEURC: { price: '999999999', timestampSeconds: now } },
184
+ })
185
+
186
+ // Static minimality check: prove no top-level conjunct is load-bearing-free.
187
+ const staticCheck = verifyPolicy(predicate, recordedTx)
188
+ ```
189
+
190
+ The boundary is pinned:
191
+
192
+ - `SIMULATION_ERROR` — runtime evaluation failed (malformed fixture, missing
193
+ oracle price, uncontrolled throw). The policy may still be minimal.
194
+ - `VERIFICATION_FAILED` — the static minimality check failed. The policy is
195
+ structurally over-broad regardless of how any concrete call evaluates.
196
+
197
+ Both are deterministic: same `(predicate, recordedTx, opts)` → byte-identical
198
+ envelope.
199
+
200
+ ## Review-card (the human-audit surface)
201
+
202
+ The package emits a deterministic review-card summary so a human auditor can
203
+ sanity-check the inferred policy without re-running the synthesis:
204
+
205
+ ```ts
206
+ import {
207
+ buildReviewCardSummary,
208
+ classifyConflict,
209
+ summaryCrossCheck,
210
+ } from '@crediolabs/policy-synth'
211
+
212
+ const summary = buildReviewCardSummary(proposedPolicy, recordedTx)
213
+ const conflict = classifyConflict(proposedPolicy, recordedTx)
214
+ const crossCheck = summaryCrossCheck(proposedPolicy, recordedTx)
215
+ ```
216
+
217
+ The summary is the canonical human-readable digest of the proposed policy;
218
+ `classifyConflict` flags refs that contradict the recording; `summaryCrossCheck`
219
+ re-derives the summary from the raw refs and the recording, and reports
220
+ discrepancies. All three are pure and deterministic.
221
+
222
+ ## Codegen escape hatch (the Rust interpreter)
223
+
224
+ When the canonical verifier is unavailable, the recorder can emit a Rust
225
+ source file that performs the same predicate evaluation off-chain via a
226
+ `cargo` build. The escape hatch is OUT of the audited happy path: the
227
+ synthesiser never calls `generateRust` itself; the CLI subcommand is the only
228
+ entry point.
229
+
230
+ ```ts
231
+ import { generateRust, compileCheck, hasRustToolchain } from '@crediolabs/policy-synth'
232
+
233
+ if (await hasRustToolchain()) {
234
+ const { source, path } = generateRust(predicate, { out: 'policy.rs' })
235
+ const gate = await compileCheck({ crateDir: '.', predicate })
236
+ if (!gate.ok) console.error('compile gate failed:', gate.error)
237
+ }
238
+ ```
239
+
240
+ The escape hatch is toolchain-gated: `hasRustToolchain()` returns `false`
241
+ when `cargo` is not installed, and `compileCheck()` refuses to run on a
242
+ machine without one. The generated source is **not** the on-chain interpreter
243
+ — it is a deterministic off-chain reference that re-evaluates the same
244
+ predicate for parity testing.
245
+
246
+ ## Composition rules
247
+
248
+ The merged `policyRefs` on a `ProposedPolicy` are ordered
249
+ `[interpreterRef?, ...oz_builtinRefs]` and bounded by
250
+ `OZ_LIMITS.maxPoliciesPerRule` (5). The orchestrator refuses to install a
251
+ policy that exceeds this cap (`POLICY_CAP_EXCEEDED`). The OZ-side `uncovered`
252
+ warnings that the interpreter actually lowered (per-method scoping, recipient
253
+ allowlists, exact ordered sequences, oracle price bounds, invocation-count
254
+ windows, token-mismatch spending limits) are dropped from the user-facing
255
+ warnings when the interpreter succeeds — the warning list reflects what is
256
+ still UN-enforced, not what OZ alone could not do.
257
+
76
258
  ## Status
77
259
 
78
- The recorder, both synthesizer front-ends, and the OZ Accounts adapter are
79
- implemented and unit-test covered. Install, on-chain verify, simulate, and the
80
- Rust interpreter are later phases.
260
+ Implemented and unit-test covered: the recorder, both synthesizer
261
+ front-ends, the OZ Accounts adapter, the interpreter adapter, the
262
+ predicate encoder, the evaluator, the deny-case battery, the minimiser, the
263
+ self-verify pipeline, the simulate / verify surface, the review-card
264
+ builder, the cross-check, and the Rust codegen escape hatch.
265
+
266
+ The on-chain Rust interpreter, install-transaction assembly, and live RPC
267
+ integration are wired in the @crediolabs/policy-builder-cli layer (separate
268
+ package).
81
269
 
82
270
  ## License
83
271
 
@@ -0,0 +1,38 @@
1
+ import type { IRPolicyRule } from '../../ir/types.ts';
2
+ import type { CustodyAdapter } from '../../seams/types.ts';
3
+ import type { Network, PredicateNode } from '../../types.ts';
4
+ /** [VERIFY] NOT a real deployed address. The interpreter is a per-network
5
+ * deploy artifact we do not have yet; install is a later phase. */
6
+ export declare const PLACEHOLDER_INTERPRETER_ADDRESS = "VERIFY-interpreter-address";
7
+ /** Wasm-level oracle defaults (mirrors INTERPRETER_INSTALL_PARAMS.md OracleParams).
8
+ * Per-policy overrides may TIGHTEN only - they may never exceed these. */
9
+ export declare const ORACLE_DEFAULTS: {
10
+ readonly maxStalenessSeconds: 600;
11
+ readonly maxDeviationBps: 200;
12
+ };
13
+ export interface InterpreterAdapterConfig {
14
+ network: Network;
15
+ /** Per-rule install nonce (first install = 1; replay-protected). */
16
+ installNonce: number;
17
+ /** The smart account this interpreter policy will be installed against. Used
18
+ * by the self-call gate: any `in`-allowlist containing this address is
19
+ * rejected as `SCOPE_SELF_CALL`. */
20
+ smartAccountAddress: string;
21
+ /** Optional per-policy oracle overrides. Must TIGHTEN vs ORACLE_DEFAULTS
22
+ * (i.e. <= each default). A widening value throws ORACLE_PARAMS_OUT_OF_RANGE
23
+ * at compile time. */
24
+ oracleParams?: {
25
+ maxStalenessSeconds?: number;
26
+ maxDeviationBps?: number;
27
+ };
28
+ }
29
+ export declare function createInterpreterAdapter(config: InterpreterAdapterConfig): CustodyAdapter;
30
+ /** Lower a single IR rule to the canonical pre-encoding `PredicateNode`. The
31
+ * orchestrator uses this to wire the self-verify + minimise pipeline: after
32
+ * `compile(ir)` succeeds (`covered === true`, `proposed` set), the
33
+ * orchestrator re-derives the PredicateNode via this helper to drive
34
+ * `minimize` and `runHarness` on the SAME shape the encoder saw. Pure and
35
+ * deterministic: same `rule + config` -> byte-identical PredicateNode. The
36
+ * `uncovered` list the adapter surfaces during compile is NOT re-derived
37
+ * here; callers that need it should use the result of `compile(ir)`. */
38
+ export declare function lowerRuleToPredicate(rule: IRPolicyRule, config: InterpreterAdapterConfig): PredicateNode;