@agenticprimitives/treasury-service-agent 0.0.0-alpha.4

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 (107) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +70 -0
  3. package/dist/benchmarks/benchmark.d.ts +28 -0
  4. package/dist/benchmarks/benchmark.d.ts.map +1 -0
  5. package/dist/benchmarks/benchmark.js +26 -0
  6. package/dist/benchmarks/benchmark.js.map +1 -0
  7. package/dist/benchmarks/suite.d.ts +11 -0
  8. package/dist/benchmarks/suite.d.ts.map +1 -0
  9. package/dist/benchmarks/suite.js +166 -0
  10. package/dist/benchmarks/suite.js.map +1 -0
  11. package/dist/capabilities.d.ts +68 -0
  12. package/dist/capabilities.d.ts.map +1 -0
  13. package/dist/capabilities.js +68 -0
  14. package/dist/capabilities.js.map +1 -0
  15. package/dist/catalog-defi.d.ts +29 -0
  16. package/dist/catalog-defi.d.ts.map +1 -0
  17. package/dist/catalog-defi.js +79 -0
  18. package/dist/catalog-defi.js.map +1 -0
  19. package/dist/catalog.d.ts +86 -0
  20. package/dist/catalog.d.ts.map +1 -0
  21. package/dist/catalog.js +199 -0
  22. package/dist/catalog.js.map +1 -0
  23. package/dist/dispatch/delegation-authority.d.ts +58 -0
  24. package/dist/dispatch/delegation-authority.d.ts.map +1 -0
  25. package/dist/dispatch/delegation-authority.js +62 -0
  26. package/dist/dispatch/delegation-authority.js.map +1 -0
  27. package/dist/grant.d.ts +34 -0
  28. package/dist/grant.d.ts.map +1 -0
  29. package/dist/grant.js +40 -0
  30. package/dist/grant.js.map +1 -0
  31. package/dist/index.d.ts +45 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +37 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/intents/intent-types.d.ts +65 -0
  36. package/dist/intents/intent-types.d.ts.map +1 -0
  37. package/dist/intents/intent-types.js +44 -0
  38. package/dist/intents/intent-types.js.map +1 -0
  39. package/dist/intents/resolved-treasury-order.d.ts +38 -0
  40. package/dist/intents/resolved-treasury-order.d.ts.map +1 -0
  41. package/dist/intents/resolved-treasury-order.js +2 -0
  42. package/dist/intents/resolved-treasury-order.js.map +1 -0
  43. package/dist/intents/treasury-intent-resolver.d.ts +30 -0
  44. package/dist/intents/treasury-intent-resolver.d.ts.map +1 -0
  45. package/dist/intents/treasury-intent-resolver.js +113 -0
  46. package/dist/intents/treasury-intent-resolver.js.map +1 -0
  47. package/dist/payments/order-to-mandate.d.ts +31 -0
  48. package/dist/payments/order-to-mandate.d.ts.map +1 -0
  49. package/dist/payments/order-to-mandate.js +46 -0
  50. package/dist/payments/order-to-mandate.js.map +1 -0
  51. package/dist/plans.d.ts +27 -0
  52. package/dist/plans.d.ts.map +1 -0
  53. package/dist/plans.js +47 -0
  54. package/dist/plans.js.map +1 -0
  55. package/dist/plugins/defi-plugin.d.ts +54 -0
  56. package/dist/plugins/defi-plugin.d.ts.map +1 -0
  57. package/dist/plugins/defi-plugin.js +30 -0
  58. package/dist/plugins/defi-plugin.js.map +1 -0
  59. package/dist/profiles.d.ts +92 -0
  60. package/dist/profiles.d.ts.map +1 -0
  61. package/dist/profiles.js +60 -0
  62. package/dist/profiles.js.map +1 -0
  63. package/dist/receipt.d.ts +16 -0
  64. package/dist/receipt.d.ts.map +1 -0
  65. package/dist/receipt.js +16 -0
  66. package/dist/receipt.js.map +1 -0
  67. package/dist/risk/risk-policy.d.ts +44 -0
  68. package/dist/risk/risk-policy.d.ts.map +1 -0
  69. package/dist/risk/risk-policy.js +50 -0
  70. package/dist/risk/risk-policy.js.map +1 -0
  71. package/dist/schemas.d.ts +68 -0
  72. package/dist/schemas.d.ts.map +1 -0
  73. package/dist/schemas.js +24 -0
  74. package/dist/schemas.js.map +1 -0
  75. package/dist/solvers/broker.d.ts +24 -0
  76. package/dist/solvers/broker.d.ts.map +1 -0
  77. package/dist/solvers/broker.js +43 -0
  78. package/dist/solvers/broker.js.map +1 -0
  79. package/dist/solvers/digest.d.ts +5 -0
  80. package/dist/solvers/digest.d.ts.map +1 -0
  81. package/dist/solvers/digest.js +27 -0
  82. package/dist/solvers/digest.js.map +1 -0
  83. package/dist/solvers/plan-validation.d.ts +40 -0
  84. package/dist/solvers/plan-validation.d.ts.map +1 -0
  85. package/dist/solvers/plan-validation.js +66 -0
  86. package/dist/solvers/plan-validation.js.map +1 -0
  87. package/dist/solvers/quote-ranking.d.ts +47 -0
  88. package/dist/solvers/quote-ranking.d.ts.map +1 -0
  89. package/dist/solvers/quote-ranking.js +48 -0
  90. package/dist/solvers/quote-ranking.js.map +1 -0
  91. package/dist/solvers/solver-port.d.ts +104 -0
  92. package/dist/solvers/solver-port.d.ts.map +1 -0
  93. package/dist/solvers/solver-port.js +2 -0
  94. package/dist/solvers/solver-port.js.map +1 -0
  95. package/dist/strategy/strategy-controller.d.ts +36 -0
  96. package/dist/strategy/strategy-controller.d.ts.map +1 -0
  97. package/dist/strategy/strategy-controller.js +66 -0
  98. package/dist/strategy/strategy-controller.js.map +1 -0
  99. package/dist/strategy/strategy-definition.d.ts +55 -0
  100. package/dist/strategy/strategy-definition.d.ts.map +1 -0
  101. package/dist/strategy/strategy-definition.js +39 -0
  102. package/dist/strategy/strategy-definition.js.map +1 -0
  103. package/dist/strategy/triggers.d.ts +27 -0
  104. package/dist/strategy/triggers.d.ts.map +1 -0
  105. package/dist/strategy/triggers.js +22 -0
  106. package/dist/strategy/triggers.js.map +1 -0
  107. package/package.json +54 -0
@@ -0,0 +1,43 @@
1
+ import { DEFAULT_RANK_WEIGHTS, buildSelectionReceipt, rankQuotes } from './quote-ranking.js';
2
+ import { validatePlanQuote } from './plan-validation.js';
3
+ export class SolverBroker {
4
+ solvers = [];
5
+ register(solver) {
6
+ this.solvers.push(solver);
7
+ return this;
8
+ }
9
+ async solve(order, ctx, opts = {}) {
10
+ const validate = opts.validate !== false;
11
+ const weights = opts.weights ?? DEFAULT_RANK_WEIGHTS;
12
+ // filter → quote
13
+ const quotes = [];
14
+ for (const solver of this.solvers) {
15
+ const support = await solver.supports(order, ctx);
16
+ if (!support.supported)
17
+ continue;
18
+ quotes.push(...(await solver.quote(order, ctx)));
19
+ }
20
+ // validate → partition
21
+ const rejected = [];
22
+ const valid = [];
23
+ for (const q of quotes) {
24
+ if (!validate) {
25
+ valid.push(q);
26
+ continue;
27
+ }
28
+ const v = validatePlanQuote(q, order, ctx);
29
+ if (v.valid)
30
+ valid.push(q);
31
+ else
32
+ rejected.push({ quoteId: q.quoteId, solverId: q.solverId, violations: v.violations });
33
+ }
34
+ // rank → select
35
+ const ranked = rankQuotes(valid, weights);
36
+ const selection = buildSelectionReceipt(ranked, ctx.nowSeconds, {
37
+ weights,
38
+ reason: ranked.length === 0 ? (quotes.length === 0 ? 'no supporting solver' : 'all quotes rejected in validation') : undefined,
39
+ });
40
+ return { quotes, rejected, ranked, selection };
41
+ }
42
+ }
43
+ //# sourceMappingURL=broker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broker.js","sourceRoot":"","sources":["../../src/solvers/broker.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,UAAU,EAA6D,MAAM,oBAAoB,CAAC;AACxJ,OAAO,EAAE,iBAAiB,EAAyB,MAAM,sBAAsB,CAAC;AAehF,MAAM,OAAO,YAAY;IACf,OAAO,GAAqB,EAAE,CAAC;IAEvC,QAAQ,CAAC,MAAsB;QAC7B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,KAA4B,EAAE,GAAkB,EAAE,OAAqB,EAAE;QACnF,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,KAAK,KAAK,CAAC;QACzC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,oBAAoB,CAAC;QAErD,iBAAiB;QACjB,MAAM,MAAM,GAAwB,EAAE,CAAC;QACvC,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAClC,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YAClD,IAAI,CAAC,OAAO,CAAC,SAAS;gBAAE,SAAS;YACjC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QACnD,CAAC;QAED,uBAAuB;QACvB,MAAM,QAAQ,GAA4B,EAAE,CAAC;QAC7C,MAAM,KAAK,GAAwB,EAAE,CAAC;QACtC,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;YACvB,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAAC,SAAS;YAAC,CAAC;YAC3C,MAAM,CAAC,GAAqB,iBAAiB,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;YAC7D,IAAI,CAAC,CAAC,KAAK;gBAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;;gBACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;QAC7F,CAAC;QAED,gBAAgB;QAChB,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC1C,MAAM,SAAS,GAAG,qBAAqB,CAAC,MAAM,EAAE,GAAG,CAAC,UAAU,EAAE;YAC9D,OAAO;YACP,MAAM,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,mCAAmC,CAAC,CAAC,CAAC,CAAC,SAAS;SAC/H,CAAC,CAAC;QAEH,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IACjD,CAAC;CACF"}
@@ -0,0 +1,5 @@
1
+ /** Stable JSON: object keys sorted recursively so equal values hash equal regardless of insertion order. */
2
+ export declare function stableStringify(value: unknown): string;
3
+ /** 32-bit FNV-1a → 8-hex-char string. */
4
+ export declare function structuralDigest(value: unknown): string;
5
+ //# sourceMappingURL=digest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"digest.d.ts","sourceRoot":"","sources":["../../src/solvers/digest.ts"],"names":[],"mappings":"AAMA,4GAA4G;AAC5G,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAOtD;AAED,yCAAyC;AACzC,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAQvD"}
@@ -0,0 +1,27 @@
1
+ // Deterministic STRUCTURAL digest (spec 284 PR-D). A dependency-free, order-independent hash used for
2
+ // anti-tamper/consistency checks INSIDE the broker flow (plan/quote/simulation digests). It is NOT a
3
+ // cryptographic primitive and carries no authority — the cryptographic binding is the payer mandate +
4
+ // delegation signature at the host (spec 285). FNV-1a over a stable (key-sorted) JSON serialization; no
5
+ // ambient Date/Math, no crypto dep.
6
+ /** Stable JSON: object keys sorted recursively so equal values hash equal regardless of insertion order. */
7
+ export function stableStringify(value) {
8
+ if (value === null || typeof value !== 'object')
9
+ return JSON.stringify(value) ?? 'null';
10
+ if (Array.isArray(value))
11
+ return `[${value.map(stableStringify).join(',')}]`;
12
+ const entries = Object.entries(value)
13
+ .filter(([, v]) => v !== undefined)
14
+ .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));
15
+ return `{${entries.map(([k, v]) => `${JSON.stringify(k)}:${stableStringify(v)}`).join(',')}}`;
16
+ }
17
+ /** 32-bit FNV-1a → 8-hex-char string. */
18
+ export function structuralDigest(value) {
19
+ const s = stableStringify(value);
20
+ let h = 0x811c9dc5;
21
+ for (let i = 0; i < s.length; i++) {
22
+ h ^= s.charCodeAt(i);
23
+ h = Math.imul(h, 0x01000193) >>> 0;
24
+ }
25
+ return `sd_${h.toString(16).padStart(8, '0')}`;
26
+ }
27
+ //# sourceMappingURL=digest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"digest.js","sourceRoot":"","sources":["../../src/solvers/digest.ts"],"names":[],"mappings":"AAAA,sGAAsG;AACtG,qGAAqG;AACrG,sGAAsG;AACtG,wGAAwG;AACxG,oCAAoC;AAEpC,4GAA4G;AAC5G,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC;IACxF,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;IAC7E,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC;SAC7D,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC;SAClC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpD,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;AAChG,CAAC;AAED,yCAAyC;AACzC,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,MAAM,CAAC,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACjC,IAAI,CAAC,GAAG,UAAU,CAAC;IACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QACrB,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,MAAM,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;AACjD,CAAC"}
@@ -0,0 +1,40 @@
1
+ import type { ResolvedTreasuryOrder } from '../intents/resolved-treasury-order.js';
2
+ import type { AssetEffect, PlanKind, TreasuryPlanQuote } from './solver-port.js';
3
+ export interface ValidationResult {
4
+ valid: boolean;
5
+ violations: string[];
6
+ }
7
+ export interface ValidatePlanQuoteContext {
8
+ nowSeconds: number;
9
+ allowedAssumptions?: string[];
10
+ allowedRepresentations?: PlanKind[];
11
+ }
12
+ export declare function validatePlanQuote(quote: TreasuryPlanQuote, order: ResolvedTreasuryOrder, ctx: ValidatePlanQuoteContext): ValidationResult;
13
+ export interface PreSignFields {
14
+ target: string;
15
+ sender: string;
16
+ network: string;
17
+ calldata?: string;
18
+ value?: string;
19
+ expectedOutput?: string;
20
+ }
21
+ export interface SimulationCommitment {
22
+ quoteId: string;
23
+ stepId: string;
24
+ simulatedAt: number;
25
+ fields: PreSignFields;
26
+ expectedEffects: AssetEffect[];
27
+ commitmentDigest: string;
28
+ }
29
+ /** Representations that REQUIRE a simulation + pre-sign validation before signing (spec 284). */
30
+ export declare function requiresSimulation(representation: PlanKind): boolean;
31
+ export declare function commitSimulation(args: {
32
+ quoteId: string;
33
+ stepId: string;
34
+ simulatedAt: number;
35
+ fields: PreSignFields;
36
+ expectedEffects: AssetEffect[];
37
+ }): SimulationCommitment;
38
+ /** Validate to-be-signed tx fields against the committed simulation — field by field, fail-closed. */
39
+ export declare function validatePreSign(commitment: SimulationCommitment, toSign: PreSignFields): ValidationResult;
40
+ //# sourceMappingURL=plan-validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-validation.d.ts","sourceRoot":"","sources":["../../src/solvers/plan-validation.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AACnF,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGjF,MAAM,WAAW,gBAAgB;IAAG,KAAK,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE;AAE1E,MAAM,WAAW,wBAAwB;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,sBAAsB,CAAC,EAAE,QAAQ,EAAE,CAAC;CACrC;AAQD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,qBAAqB,EAAE,GAAG,EAAE,wBAAwB,GAAG,gBAAgB,CAmCzI;AAGD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,aAAa,CAAC;IACtB,eAAe,EAAE,WAAW,EAAE,CAAC;IAC/B,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,iGAAiG;AACjG,wBAAgB,kBAAkB,CAAC,cAAc,EAAE,QAAQ,GAAG,OAAO,CAEpE;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,aAAa,CAAC;IAAC,eAAe,EAAE,WAAW,EAAE,CAAA;CAAE,GAAG,oBAAoB,CAG5K;AAID,sGAAsG;AACtG,wBAAgB,eAAe,CAAC,UAAU,EAAE,oBAAoB,EAAE,MAAM,EAAE,aAAa,GAAG,gBAAgB,CASzG"}
@@ -0,0 +1,66 @@
1
+ import { structuralDigest } from './digest.js';
2
+ /** Map a canonical constraint variable to the quote signal it bounds (extend as signals grow). */
3
+ const SIGNAL_FOR_VARIABLE = {
4
+ maximumSlippageBps: 'slippageBps',
5
+ maximumPriceImpactBps: 'priceImpactBps',
6
+ };
7
+ export function validatePlanQuote(quote, order, ctx) {
8
+ const violations = [];
9
+ // NEW-TSA-7 (2026-07-05 completeness audit): fail-closed on a non-finite expiry — `NaN <= now` is false,
10
+ // which would let a quote with no/NaN expiry pass the gate.
11
+ if (!Number.isFinite(quote.expiresAt) || quote.expiresAt <= ctx.nowSeconds)
12
+ violations.push('quote-expired');
13
+ if (ctx.allowedRepresentations && !ctx.allowedRepresentations.includes(quote.representation)) {
14
+ violations.push(`representation-not-allowed:${quote.representation}`);
15
+ }
16
+ if (quote.representation !== quote.plan.representation)
17
+ violations.push('representation-mismatch');
18
+ // Every named assumption must be recognized + allowed (spec 284: reject otherwise).
19
+ if (ctx.allowedAssumptions) {
20
+ const allowed = new Set(ctx.allowedAssumptions);
21
+ for (const a of quote.assumptions)
22
+ if (!allowed.has(a.name))
23
+ violations.push(`assumption-not-allowed:${a.name}`);
24
+ }
25
+ // Digest integrity (structural anti-tamper within the broker flow).
26
+ if (structuralDigest(quote.plan) !== quote.planDigest)
27
+ violations.push('plan-digest-mismatch');
28
+ const { quoteDigest, ...rest } = quote;
29
+ if (structuralDigest(rest) !== quoteDigest)
30
+ violations.push('quote-digest-mismatch');
31
+ // Signals vs the order's canonical hard constraint ceilings.
32
+ const signals = quote.signals ?? {};
33
+ for (const c of order.canonicalConstraints.hard) {
34
+ const sig = SIGNAL_FOR_VARIABLE[c.variable];
35
+ if (sig && c.domain.kind === 'range') {
36
+ const v = signals[sig] ?? 0;
37
+ const max = Number(c.domain.max);
38
+ // NEW-TSA-7: a non-finite signal or ceiling makes `v > max` always false (fall-open) — treat as a violation.
39
+ if (!Number.isFinite(v) || !Number.isFinite(max) || v > max)
40
+ violations.push(`exceeds-${c.variable}:${v}>${c.domain.max}`);
41
+ }
42
+ }
43
+ return { valid: violations.length === 0, violations };
44
+ }
45
+ /** Representations that REQUIRE a simulation + pre-sign validation before signing (spec 284). */
46
+ export function requiresSimulation(representation) {
47
+ return representation === 'opaque-calldata' || representation === 'offchain-order';
48
+ }
49
+ export function commitSimulation(args) {
50
+ const { quoteId, stepId, simulatedAt, fields, expectedEffects } = args;
51
+ return { quoteId, stepId, simulatedAt, fields, expectedEffects, commitmentDigest: structuralDigest({ quoteId, stepId, fields, expectedEffects }) };
52
+ }
53
+ const FIELDS = ['target', 'sender', 'network', 'calldata', 'value', 'expectedOutput'];
54
+ /** Validate to-be-signed tx fields against the committed simulation — field by field, fail-closed. */
55
+ export function validatePreSign(commitment, toSign) {
56
+ const violations = [];
57
+ if (structuralDigest({ quoteId: commitment.quoteId, stepId: commitment.stepId, fields: commitment.fields, expectedEffects: commitment.expectedEffects }) !== commitment.commitmentDigest) {
58
+ violations.push('commitment-digest-tampered');
59
+ }
60
+ for (const f of FIELDS) {
61
+ if (commitment.fields[f] !== toSign[f])
62
+ violations.push(`field-mismatch:${f}`);
63
+ }
64
+ return { valid: violations.length === 0, violations };
65
+ }
66
+ //# sourceMappingURL=plan-validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-validation.js","sourceRoot":"","sources":["../../src/solvers/plan-validation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import type { TreasuryPlanQuote } from './solver-port.js';
2
+ /** Weights for the cost model. Penalties are subtracted from net outcome. */
3
+ export interface RankWeights {
4
+ netOutcome: number;
5
+ fees: number;
6
+ gas: number;
7
+ slippageBps: number;
8
+ priceImpactBps: number;
9
+ executionFailureProb: number;
10
+ bridgeFinalitySeconds: number;
11
+ protocolRiskScore: number;
12
+ latencyMs: number;
13
+ }
14
+ export declare const DEFAULT_RANK_WEIGHTS: RankWeights;
15
+ export interface ScoreBreakdown {
16
+ components: Record<string, number>;
17
+ weights: RankWeights;
18
+ score: number;
19
+ }
20
+ export interface RankedQuote {
21
+ quote: TreasuryPlanQuote;
22
+ score: number;
23
+ breakdown: ScoreBreakdown;
24
+ }
25
+ /** Compute one quote's score = weighted net outcome minus weighted penalties. */
26
+ export declare function scoreQuote(quote: TreasuryPlanQuote, weights?: RankWeights): ScoreBreakdown;
27
+ /** Rank quotes descending by score; ties break on quoteId (lexicographic) for full determinism. */
28
+ export declare function rankQuotes(quotes: TreasuryPlanQuote[], weights?: RankWeights): RankedQuote[];
29
+ /** The auditable record of WHY a quote was selected — components + weights for every candidate. */
30
+ export interface SelectionReceipt {
31
+ selectedQuoteId: string | null;
32
+ candidates: {
33
+ quoteId: string;
34
+ solverId: string;
35
+ score: number;
36
+ components: Record<string, number>;
37
+ }[];
38
+ weights: RankWeights;
39
+ rankedAt: number;
40
+ reason?: string;
41
+ }
42
+ export declare function buildSelectionReceipt(ranked: RankedQuote[], rankedAt: number, opts?: {
43
+ selectedQuoteId?: string | null;
44
+ reason?: string;
45
+ weights?: RankWeights;
46
+ }): SelectionReceipt;
47
+ //# sourceMappingURL=quote-ranking.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quote-ranking.d.ts","sourceRoot":"","sources":["../../src/solvers/quote-ranking.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,6EAA6E;AAC7E,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,oBAAoB,EAAE,WAUlC,CAAC;AAEF,MAAM,WAAW,cAAc;IAAG,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,OAAO,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE;AAC3G,MAAM,WAAW,WAAW;IAAG,KAAK,EAAE,iBAAiB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,cAAc,CAAA;CAAE;AAInG,iFAAiF;AACjF,wBAAgB,UAAU,CAAC,KAAK,EAAE,iBAAiB,EAAE,OAAO,GAAE,WAAkC,GAAG,cAAc,CAkBhH;AAED,mGAAmG;AACnG,wBAAgB,UAAU,CAAC,MAAM,EAAE,iBAAiB,EAAE,EAAE,OAAO,GAAE,WAAkC,GAAG,WAAW,EAAE,CAIlH;AAED,mGAAmG;AACnG,MAAM,WAAW,gBAAgB;IAC/B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,UAAU,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,EAAE,CAAC;IACvG,OAAO,EAAE,WAAW,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE;IAAE,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,WAAW,CAAA;CAAO,GAAG,gBAAgB,CAQvL"}
@@ -0,0 +1,48 @@
1
+ export const DEFAULT_RANK_WEIGHTS = {
2
+ netOutcome: 1,
3
+ fees: 1,
4
+ gas: 1,
5
+ slippageBps: 0.5,
6
+ priceImpactBps: 0.5,
7
+ executionFailureProb: 5_000,
8
+ bridgeFinalitySeconds: 0.01,
9
+ protocolRiskScore: 10_000,
10
+ latencyMs: 0.001,
11
+ };
12
+ const sum = (xs) => xs.reduce((a, x) => a + (Number(x) || 0), 0);
13
+ /** Compute one quote's score = weighted net outcome minus weighted penalties. */
14
+ export function scoreQuote(quote, weights = DEFAULT_RANK_WEIGHTS) {
15
+ const s = quote.signals ?? {};
16
+ const net = Number(quote.expectedOutcome.minNetAmount ?? quote.expectedOutcome.amount) || 0;
17
+ const fees = sum(quote.fees.map((f) => f.amount));
18
+ const gas = sum(quote.gas.map((g) => g.amount));
19
+ const components = {
20
+ netOutcome: weights.netOutcome * net,
21
+ fees: -(weights.fees * fees),
22
+ gas: -(weights.gas * gas),
23
+ slippageBps: -(weights.slippageBps * (s.slippageBps ?? 0)),
24
+ priceImpactBps: -(weights.priceImpactBps * (s.priceImpactBps ?? 0)),
25
+ executionFailureProb: -(weights.executionFailureProb * (s.executionFailureProb ?? 0)),
26
+ bridgeFinalitySeconds: -(weights.bridgeFinalitySeconds * (s.bridgeFinalitySeconds ?? 0)),
27
+ protocolRiskScore: -(weights.protocolRiskScore * (s.protocolRiskScore ?? 0)),
28
+ latencyMs: -(weights.latencyMs * (s.latencyMs ?? 0)),
29
+ };
30
+ const score = Object.values(components).reduce((a, b) => a + b, 0);
31
+ return { components, weights, score };
32
+ }
33
+ /** Rank quotes descending by score; ties break on quoteId (lexicographic) for full determinism. */
34
+ export function rankQuotes(quotes, weights = DEFAULT_RANK_WEIGHTS) {
35
+ return quotes
36
+ .map((quote) => { const b = scoreQuote(quote, weights); return { quote, score: b.score, breakdown: b }; })
37
+ .sort((a, b) => (b.score - a.score) || (a.quote.quoteId < b.quote.quoteId ? -1 : a.quote.quoteId > b.quote.quoteId ? 1 : 0));
38
+ }
39
+ export function buildSelectionReceipt(ranked, rankedAt, opts = {}) {
40
+ return {
41
+ selectedQuoteId: opts.selectedQuoteId !== undefined ? opts.selectedQuoteId : (ranked[0]?.quote.quoteId ?? null),
42
+ candidates: ranked.map((r) => ({ quoteId: r.quote.quoteId, solverId: r.quote.solverId, score: r.score, components: r.breakdown.components })),
43
+ weights: opts.weights ?? ranked[0]?.breakdown.weights ?? DEFAULT_RANK_WEIGHTS,
44
+ rankedAt,
45
+ reason: opts.reason,
46
+ };
47
+ }
48
+ //# sourceMappingURL=quote-ranking.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quote-ranking.js","sourceRoot":"","sources":["../../src/solvers/quote-ranking.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,104 @@
1
+ import type { PlanKind, StepFailurePolicy } from '@agenticprimitives/service-agent';
2
+ import type { NamedAssumption } from '@agenticprimitives/intent-marketplace';
3
+ import type { ResolvedTreasuryOrder } from '../intents/resolved-treasury-order.js';
4
+ export type { PlanKind };
5
+ /** A balance change a step is expected to produce (reconciled against the receipt later). */
6
+ export interface AssetEffect {
7
+ account?: string;
8
+ asset: string;
9
+ deltaAmount: string;
10
+ direction: 'in' | 'out';
11
+ }
12
+ /** A concrete DAG step in a solver's execution plan. */
13
+ export interface TreasuryPlanStep {
14
+ stepId: string;
15
+ chain: string;
16
+ capability: string;
17
+ inputs: Record<string, unknown>;
18
+ dependsOn: string[];
19
+ failure: StepFailurePolicy;
20
+ expectedEffects: AssetEffect[];
21
+ }
22
+ export interface ExpectedOutcome {
23
+ asset: string;
24
+ amount: string;
25
+ minNetAmount?: string;
26
+ }
27
+ export interface FeeEstimate {
28
+ kind: string;
29
+ asset: string;
30
+ amount: string;
31
+ }
32
+ export interface GasEstimate {
33
+ chain: string;
34
+ amount: string;
35
+ }
36
+ export interface RiskDisclosure {
37
+ code: string;
38
+ severity: 'low' | 'medium' | 'high';
39
+ note?: string;
40
+ }
41
+ /** Numeric signals the broker ranks on (defaults to 0 — a solver that can't measure one doesn't get a free
42
+ * pass: 0 is neutral, and a missing signal a policy cares about should be a RiskDisclosure). */
43
+ export interface QuoteSignals {
44
+ slippageBps?: number;
45
+ priceImpactBps?: number;
46
+ executionFailureProb?: number;
47
+ bridgeFinalitySeconds?: number;
48
+ protocolRiskScore?: number;
49
+ latencyMs?: number;
50
+ }
51
+ /** A point-in-time chain observation the quote was computed against. block numbers are strings (digest-stable). */
52
+ export interface StateAnchor {
53
+ blockNumbers: Record<string, string>;
54
+ observedAt: number;
55
+ }
56
+ export interface TreasuryExecutionPlan {
57
+ planId: string;
58
+ intentId: string;
59
+ representation: PlanKind;
60
+ steps: TreasuryPlanStep[];
61
+ variables: {
62
+ name: string;
63
+ description?: string;
64
+ }[];
65
+ assumptions: NamedAssumption[];
66
+ feePolicy?: string;
67
+ settlementPolicy?: string;
68
+ failurePolicy?: string;
69
+ expectedOutcome: ExpectedOutcome;
70
+ }
71
+ export interface TreasuryPlanQuote {
72
+ quoteId: string;
73
+ solverId: string;
74
+ representation: PlanKind;
75
+ plan: TreasuryExecutionPlan;
76
+ assumptions: NamedAssumption[];
77
+ expectedOutcome: ExpectedOutcome;
78
+ fees: FeeEstimate[];
79
+ gas: GasEstimate[];
80
+ risks: RiskDisclosure[];
81
+ signals?: QuoteSignals;
82
+ stateAnchor: StateAnchor;
83
+ expiresAt: number;
84
+ planDigest: string;
85
+ quoteDigest: string;
86
+ }
87
+ /** Runtime context for a solve. `allowed*` are the treasury policy envelope the broker enforces. */
88
+ export interface SolverContext {
89
+ nowSeconds: number;
90
+ allowedAssumptions?: string[];
91
+ allowedRepresentations?: PlanKind[];
92
+ }
93
+ export interface SolverSupport {
94
+ supported: boolean;
95
+ reason?: string;
96
+ }
97
+ /** Solvers propose plans; they do not obtain authority merely by returning a quote (spec 284). */
98
+ export interface TreasurySolver {
99
+ readonly solverId: string;
100
+ supports(order: ResolvedTreasuryOrder, ctx: SolverContext): Promise<SolverSupport>;
101
+ quote(order: ResolvedTreasuryOrder, ctx: SolverContext): Promise<TreasuryPlanQuote[]>;
102
+ refreshQuote?(quote: TreasuryPlanQuote, ctx: SolverContext): Promise<TreasuryPlanQuote>;
103
+ }
104
+ //# sourceMappingURL=solver-port.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solver-port.d.ts","sourceRoot":"","sources":["../../src/solvers/solver-port.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=solver-port.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solver-port.js","sourceRoot":"","sources":["../../src/solvers/solver-port.ts"],"names":[],"mappings":""}
@@ -0,0 +1,36 @@
1
+ import { type ExposureState } from '../risk/risk-policy.js';
2
+ import type { StrategyDefinition } from './strategy-definition.js';
3
+ export interface ProposedRun {
4
+ strategyId: string;
5
+ skillId: string;
6
+ asset?: string;
7
+ network?: string;
8
+ /** Value at risk this run (decimal string, smallest unit). */
9
+ notionalValue: string;
10
+ quoteAgeSeconds?: number;
11
+ /** Projected exposure AFTER this run, for the risk policy. */
12
+ exposureAfter?: ExposureState;
13
+ /** Observed drawdown, bps. */
14
+ drawdownBps?: number;
15
+ leverage?: number;
16
+ }
17
+ export interface RunControlContext {
18
+ nowSeconds: number;
19
+ }
20
+ export interface RunDecision {
21
+ allowed: boolean;
22
+ violations: string[];
23
+ requiresApproval: boolean;
24
+ }
25
+ export declare class StrategyController {
26
+ /** Decide whether a proposed run is inside the strategy mandate. */
27
+ evaluateProposedRun(strategy: StrategyDefinition, run: ProposedRun, ctx: RunControlContext): RunDecision;
28
+ }
29
+ /** Require agreement among N independent worker verdicts before a high-value run executes (spec 284). A
30
+ * run is agreed only when at least `threshold` workers allow it AND none reports a hard violation. */
31
+ export declare function requireQuorum(verdicts: RunDecision[], threshold: number): {
32
+ agreed: boolean;
33
+ allowCount: number;
34
+ reason?: string;
35
+ };
36
+ //# sourceMappingURL=strategy-controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strategy-controller.d.ts","sourceRoot":"","sources":["../../src/strategy/strategy-controller.ts"],"names":[],"mappings":"AAIA,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC1E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEnE,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8DAA8D;IAC9D,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,8DAA8D;IAC9D,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,8BAA8B;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAAG,UAAU,EAAE,MAAM,CAAA;CAAE;AAEzD,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED,qBAAa,kBAAkB;IAC7B,oEAAoE;IACpE,mBAAmB,CAAC,QAAQ,EAAE,kBAAkB,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,iBAAiB,GAAG,WAAW;CAyCzG;AAED;uGACuG;AACvG,wBAAgB,aAAa,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAKlI"}
@@ -0,0 +1,66 @@
1
+ // Strategy controller (spec 284 PR-F). The deterministic mandate gate: the model PROPOSES a run; this
2
+ // controller decides whether it is inside the mandate. Fail-closed — any breach denies; high-notional runs
3
+ // flag requiresApproval; an expired delegation denies. For high-value runs, `requireQuorum` enforces
4
+ // agreement among independent resolver/simulation workers before execution (Open Autonomy pattern).
5
+ import { evaluateRisk } from '../risk/risk-policy.js';
6
+ export class StrategyController {
7
+ /** Decide whether a proposed run is inside the strategy mandate. */
8
+ evaluateProposedRun(strategy, run, ctx) {
9
+ const m = strategy.mandate;
10
+ const violations = [];
11
+ // NEW-TSA-4: a NaN / garbage notionalValue makes every `>` / `>=` comparison below false — silently
12
+ // escaping BOTH the capital ceiling and the approval gate. Parse once and fail-closed on a non-finite
13
+ // (or negative) amount — the controller's contract is "any breach denies".
14
+ const notional = Number(run.notionalValue);
15
+ // An empty / blank string coerces to 0 via Number() — treat it as garbage, not a zero amount.
16
+ const notionalOk = typeof run.notionalValue === 'string' && run.notionalValue.trim() !== '' && Number.isFinite(notional) && notional >= 0;
17
+ if (!notionalOk)
18
+ violations.push(`notional-not-a-finite-amount:${run.notionalValue}`);
19
+ if (!m.permittedSkillIds.includes(run.skillId))
20
+ violations.push(`skill-not-permitted:${run.skillId}`);
21
+ // NEW-TSA-4: when the mandate SCOPES an asset/network, an omitted run.asset/run.network must NOT skip the
22
+ // check (scope-omission fall-open) — a scoped mandate requires the run to declare what it touches.
23
+ if (m.assetScope) {
24
+ if (!run.asset)
25
+ violations.push('asset-required-by-mandate-scope');
26
+ else if (!m.assetScope.includes(run.asset))
27
+ violations.push(`asset-out-of-scope:${run.asset}`);
28
+ }
29
+ if (m.networkScope) {
30
+ if (!run.network)
31
+ violations.push('network-required-by-mandate-scope');
32
+ else if (!m.networkScope.includes(run.network))
33
+ violations.push(`network-out-of-scope:${run.network}`);
34
+ }
35
+ if (notionalOk && notional > Number(m.maxCapital))
36
+ violations.push(`notional-exceeds-max-capital:${run.notionalValue}>${m.maxCapital}`);
37
+ if (m.maxLossBps !== undefined && run.drawdownBps !== undefined && run.drawdownBps > m.maxLossBps)
38
+ violations.push(`drawdown-exceeded:${run.drawdownBps}>${m.maxLossBps}`);
39
+ if (m.maxLeverage !== undefined && run.leverage !== undefined && run.leverage > m.maxLeverage)
40
+ violations.push(`leverage-exceeded:${run.leverage}>${m.maxLeverage}`);
41
+ if (m.maxQuoteAgeSeconds !== undefined && run.quoteAgeSeconds !== undefined && run.quoteAgeSeconds > m.maxQuoteAgeSeconds)
42
+ violations.push(`quote-stale:${run.quoteAgeSeconds}>${m.maxQuoteAgeSeconds}`);
43
+ if (m.delegationExpiry !== undefined && ctx.nowSeconds >= m.delegationExpiry)
44
+ violations.push('delegation-expired');
45
+ if (m.riskPolicy && run.exposureAfter) {
46
+ const verdict = evaluateRisk(run.exposureAfter, m.riskPolicy);
47
+ for (const b of verdict.breaches)
48
+ violations.push(`risk:${b.code}`);
49
+ }
50
+ // NEW-TSA-4: a non-finite notional must NOT slip under the approval gate — force approval when the
51
+ // mandate has a threshold and we can't prove the amount is below it.
52
+ const requiresApproval = m.approvalThreshold !== undefined && (!notionalOk || notional >= Number(m.approvalThreshold));
53
+ return { allowed: violations.length === 0, violations, requiresApproval };
54
+ }
55
+ }
56
+ /** Require agreement among N independent worker verdicts before a high-value run executes (spec 284). A
57
+ * run is agreed only when at least `threshold` workers allow it AND none reports a hard violation. */
58
+ export function requireQuorum(verdicts, threshold) {
59
+ const allowCount = verdicts.filter((v) => v.allowed).length;
60
+ if (verdicts.some((v) => !v.allowed))
61
+ return { agreed: false, allowCount, reason: 'at least one worker reported a violation' };
62
+ if (allowCount < threshold)
63
+ return { agreed: false, allowCount, reason: `only ${allowCount}/${threshold} workers agreed` };
64
+ return { agreed: true, allowCount };
65
+ }
66
+ //# sourceMappingURL=strategy-controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strategy-controller.js","sourceRoot":"","sources":["../../src/strategy/strategy-controller.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ import type { RiskPolicy } from '../risk/risk-policy.js';
2
+ import type { TriggerCondition } from './triggers.js';
3
+ /** The deterministic bounds a strategy run must stay inside. */
4
+ export interface StrategyMandate {
5
+ /** Exactly the skills the strategy may invoke (allowlist). */
6
+ permittedSkillIds: string[];
7
+ assetScope?: string[];
8
+ networkScope?: string[];
9
+ /** Max value at risk across the strategy (decimal string, smallest unit). */
10
+ maxCapital: string;
11
+ /** Drawdown ceiling, bps — exceeding it forces the run out of mandate. */
12
+ maxLossBps?: number;
13
+ maxLeverage?: number;
14
+ minLiquidityReserve?: string;
15
+ /** Risk policy applied to a proposed run's projected exposure. */
16
+ riskPolicy?: RiskPolicy;
17
+ /** Quotes older than this (seconds) are stale. */
18
+ maxQuoteAgeSeconds?: number;
19
+ /** Runs whose notional ≥ this require explicit approval. */
20
+ approvalThreshold?: string;
21
+ /** Unix seconds; the host delegation backing the strategy expires here. */
22
+ delegationExpiry?: number;
23
+ /** Identifier permitted to trigger an emergency stop. */
24
+ emergencyStopAuthority?: string;
25
+ }
26
+ export interface StrategyDefinition {
27
+ strategyId: string;
28
+ objective: string;
29
+ triggers: TriggerCondition[];
30
+ mandate: StrategyMandate;
31
+ }
32
+ export type StrategyStatus = 'draft' | 'simulated' | 'awaiting-approval' | 'approved' | 'active' | 'paused' | 'expired' | 'closed' | 'cancelled';
33
+ export interface StrategyRunState {
34
+ strategyId: string;
35
+ runId: string;
36
+ status: StrategyStatus;
37
+ history: {
38
+ status: StrategyStatus;
39
+ at: number;
40
+ }[];
41
+ }
42
+ export declare class StrategyTransitionError extends Error {
43
+ }
44
+ export declare function createRun(strategyId: string, runId: string, at: number): StrategyRunState;
45
+ export declare function canTransition(from: StrategyStatus, to: StrategyStatus): boolean;
46
+ /** Guarded transition. Throws on an illegal transition (fail-closed). */
47
+ export declare function transitionRun(state: StrategyRunState, to: StrategyStatus, at: number): StrategyRunState;
48
+ /** Emergency stop: pause (or close) an active/paused run; only the declared authority may invoke it. */
49
+ export declare function emergencyStop(state: StrategyRunState, args: {
50
+ authority: string;
51
+ mandate: StrategyMandate;
52
+ at: number;
53
+ close?: boolean;
54
+ }): StrategyRunState;
55
+ //# sourceMappingURL=strategy-definition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strategy-definition.d.ts","sourceRoot":"","sources":["../../src/strategy/strategy-definition.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD,gEAAgE;AAChE,MAAM,WAAW,eAAe;IAC9B,8DAA8D;IAC9D,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,6EAA6E;IAC7E,UAAU,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,kEAAkE;IAClE,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,kDAAkD;IAClD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,4DAA4D;IAC5D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,2EAA2E;IAC3E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,yDAAyD;IACzD,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,OAAO,EAAE,eAAe,CAAC;CAC1B;AAED,MAAM,MAAM,cAAc,GACtB,OAAO,GAAG,WAAW,GAAG,mBAAmB,GAAG,UAAU,GACxD,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,WAAW,CAAC;AAE7D,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,cAAc,CAAC;IACvB,OAAO,EAAE;QAAE,MAAM,EAAE,cAAc,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACnD;AAcD,qBAAa,uBAAwB,SAAQ,KAAK;CAAG;AAErD,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,gBAAgB,CAEzF;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,cAAc,GAAG,OAAO,CAE/E;AAED,yEAAyE;AACzE,wBAAgB,aAAa,CAAC,KAAK,EAAE,gBAAgB,EAAE,EAAE,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,gBAAgB,CAKvG;AAED,wGAAwG;AACxG,wBAAgB,aAAa,CAAC,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,eAAe,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,gBAAgB,CAU3J"}