@wowok/agent-mcp 3.3.9 → 3.4.0

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 (252) hide show
  1. package/dist/chain-semantics/field-capability.js +1 -1
  2. package/dist/chain-semantics/freeze-map.js +1 -1
  3. package/dist/chain-semantics/fund-flow.js +1 -1
  4. package/dist/chain-semantics/guard-verbs.js +1 -1
  5. package/dist/chain-semantics/object-graph.js +1 -1
  6. package/dist/composition/audit.js +1 -1
  7. package/dist/composition/compile.d.ts +3 -2
  8. package/dist/composition/compile.js +1 -1
  9. package/dist/composition/inflight.d.ts +6 -0
  10. package/dist/composition/inflight.js +1 -1
  11. package/dist/composition/materialize.d.ts +4 -0
  12. package/dist/composition/materialize.js +1 -1
  13. package/dist/composition/param-disclosure.d.ts +61 -0
  14. package/dist/composition/param-disclosure.js +1 -0
  15. package/dist/composition/plan.d.ts +11 -1
  16. package/dist/composition/plan.js +1 -1
  17. package/dist/customer/account-events.js +1 -1
  18. package/dist/data/api/api.spec.js +1 -1
  19. package/dist/data/api/cli.js +1 -1
  20. package/dist/data/api/server.d.ts +1 -0
  21. package/dist/data/api/server.js +1 -1
  22. package/dist/data/projection/store.d.ts +2 -1
  23. package/dist/data/projection/store.js +1 -1
  24. package/dist/data/projection/types.d.ts +10 -0
  25. package/dist/data/sync/cdc.js +1 -1
  26. package/dist/data/sync/cdc.spec.js +1 -1
  27. package/dist/data/sync/store.d.ts +5 -0
  28. package/dist/data/sync/store.js +1 -1
  29. package/dist/data/sync/types.d.ts +2 -0
  30. package/dist/evaluation/builtins/graph-service.spec.js +1 -1
  31. package/dist/evaluation/engine.js +1 -1
  32. package/dist/evaluation/guard-scan.js +1 -1
  33. package/dist/experience/realtime-feedback.js +1 -1
  34. package/dist/extensions/business-modules.js +1 -1
  35. package/dist/extensions/industry-pack.js +1 -1
  36. package/dist/extensions/modes.js +1 -1
  37. package/dist/graph/onchain/expand.js +1 -1
  38. package/dist/graph/onchain/exposure.js +1 -1
  39. package/dist/harness/recover.js +1 -1
  40. package/dist/index.js +1 -1
  41. package/dist/knowledge/allocation-risk.js +1 -1
  42. package/dist/knowledge/allocation-templates.js +1 -1
  43. package/dist/knowledge/allocator-rail-verifier.js +1 -1
  44. package/dist/knowledge/arb-fund-facts.d.ts +1 -0
  45. package/dist/knowledge/arb-fund-facts.js +1 -1
  46. package/dist/knowledge/arbitration-ledger.js +1 -1
  47. package/dist/knowledge/arbitration-risk.d.ts +1 -0
  48. package/dist/knowledge/arbitration-risk.js +1 -1
  49. package/dist/knowledge/audit-rules.js +1 -1
  50. package/dist/knowledge/baselines/rules/allocation.json +6 -6
  51. package/dist/knowledge/baselines/rules/arb.json +2 -2
  52. package/dist/knowledge/baselines/rules/guard.json +11 -11
  53. package/dist/knowledge/baselines/rules/order.json +1 -1
  54. package/dist/knowledge/baselines/rules/plan.json +1 -1
  55. package/dist/knowledge/baselines/semantic-facts.js +1 -1
  56. package/dist/knowledge/builtin-templates.d.ts +14 -1
  57. package/dist/knowledge/builtin-templates.js +1 -1
  58. package/dist/knowledge/catalog-facts.d.ts +4 -0
  59. package/dist/knowledge/catalog-facts.js +1 -0
  60. package/dist/knowledge/commission-landing.js +1 -1
  61. package/dist/knowledge/component-schema.d.ts +64 -0
  62. package/dist/knowledge/component-schema.js +1 -0
  63. package/dist/knowledge/entity-recipient-guard.js +1 -1
  64. package/dist/knowledge/event-semantics.js +1 -1
  65. package/dist/knowledge/fee-param-bindings.d.ts +26 -0
  66. package/dist/knowledge/fee-param-bindings.js +1 -0
  67. package/dist/knowledge/fund-layer.js +1 -1
  68. package/dist/knowledge/getting-started.d.ts +2 -2
  69. package/dist/knowledge/getting-started.js +1 -1
  70. package/dist/knowledge/guard-anchor-reach.js +1 -1
  71. package/dist/knowledge/guard-design-patterns.js +1 -1
  72. package/dist/knowledge/guard-ledger.js +1 -1
  73. package/dist/knowledge/guard-lint.d.ts +1 -0
  74. package/dist/knowledge/guard-lint.js +1 -1
  75. package/dist/knowledge/guard-puzzle.js +1 -1
  76. package/dist/knowledge/guard-risk.js +1 -1
  77. package/dist/knowledge/guard-templates.d.ts +1 -1
  78. package/dist/knowledge/guard-templates.js +1 -1
  79. package/dist/knowledge/guard-translation.js +1 -1
  80. package/dist/knowledge/index.js +1 -1
  81. package/dist/knowledge/industry-registry.js +1 -1
  82. package/dist/knowledge/industry-strategy.js +1 -1
  83. package/dist/knowledge/jsonrpc-enum.d.ts +14 -3
  84. package/dist/knowledge/jsonrpc-enum.js +1 -1
  85. package/dist/knowledge/knob-docs.d.ts +5 -0
  86. package/dist/knowledge/knob-docs.js +1 -0
  87. package/dist/knowledge/machine-templates.js +1 -1
  88. package/dist/knowledge/machine-topology.js +1 -1
  89. package/dist/knowledge/machine-translation.js +1 -1
  90. package/dist/knowledge/onchain-constants.d.ts +2 -0
  91. package/dist/knowledge/onchain-constants.js +1 -1
  92. package/dist/knowledge/order-ledger.js +1 -1
  93. package/dist/knowledge/param-schema.d.ts +70 -0
  94. package/dist/knowledge/param-schema.js +1 -0
  95. package/dist/knowledge/param-tiers.d.ts +25 -0
  96. package/dist/knowledge/param-tiers.js +1 -0
  97. package/dist/knowledge/passport-ledger.d.ts +1 -1
  98. package/dist/knowledge/passport-ledger.js +1 -1
  99. package/dist/knowledge/pattern-resolutions.d.ts +106 -0
  100. package/dist/knowledge/pattern-resolutions.js +1 -0
  101. package/dist/knowledge/projection.spec.js +1 -1
  102. package/dist/knowledge/safety-rules.js +1 -1
  103. package/dist/knowledge/scenario-modes.d.ts +1 -0
  104. package/dist/knowledge/scenario-modes.js +1 -1
  105. package/dist/knowledge/scenario-topology.js +1 -1
  106. package/dist/knowledge/service-allocation-semantics.js +1 -1
  107. package/dist/knowledge/service-ledger.js +1 -1
  108. package/dist/knowledge/service-templates.js +1 -1
  109. package/dist/knowledge/strategy-manuals.d.ts +1 -1
  110. package/dist/knowledge/strategy-manuals.js +1 -1
  111. package/dist/knowledge/template-loader.d.ts +101 -1
  112. package/dist/knowledge/template-loader.js +1 -1
  113. package/dist/knowledge/template-nav.d.ts +7 -0
  114. package/dist/knowledge/template-nav.js +1 -0
  115. package/dist/knowledge/template-registry.js +1 -1
  116. package/dist/knowledge/template-scanner.d.ts +33 -0
  117. package/dist/knowledge/template-scanner.js +1 -1
  118. package/dist/knowledge/template-test-profiles.d.ts +17 -0
  119. package/dist/knowledge/template-test-profiles.js +1 -0
  120. package/dist/knowledge/template-validation.d.ts +1 -0
  121. package/dist/knowledge/template-validation.js +1 -1
  122. package/dist/knowledge/tools-reference.js +1 -1
  123. package/dist/knowledge/treasury-templates.js +1 -1
  124. package/dist/knowledge/workflow-guidance.js +1 -1
  125. package/dist/monitor/MonitorLoop.js +1 -1
  126. package/dist/participation/time-window.d.ts +37 -0
  127. package/dist/participation/time-window.js +1 -0
  128. package/dist/playbooks/service-build/business-puzzle.js +1 -1
  129. package/dist/playbooks/service-build/machine-panorama.d.ts +1 -0
  130. package/dist/playbooks/service-build/machine-panorama.js +1 -1
  131. package/dist/playbooks/service-build/merchant-guide.d.ts +4 -1
  132. package/dist/playbooks/service-build/merchant-guide.js +1 -1
  133. package/dist/playbooks/service-build/migration-planner.js +1 -1
  134. package/dist/playbooks/service-build/object-panorama.js +1 -1
  135. package/dist/playbooks/service-build/participation-radar.d.ts +1 -0
  136. package/dist/playbooks/service-build/participation-radar.js +1 -1
  137. package/dist/playbooks/service-build/relationship-profile.js +1 -1
  138. package/dist/playbooks/service-build/service-panorama.d.ts +1 -0
  139. package/dist/playbooks/service-build/service-panorama.js +1 -1
  140. package/dist/playbooks/service-build/service-quote.js +1 -1
  141. package/dist/playbooks/service-build/service-quote.spec.js +1 -1
  142. package/dist/playbooks/service-build/workflow-design-assessment.js +1 -1
  143. package/dist/relationship/registry.js +1 -1
  144. package/dist/review/index.js +1 -1
  145. package/dist/runtime/instance-registry.d.ts +7 -1
  146. package/dist/runtime/instance-registry.js +1 -1
  147. package/dist/safety/confirm-gate.js +1 -1
  148. package/dist/schema/benchmark-migration/index.d.ts +2 -0
  149. package/dist/schema/benchmark-migration/index.js +1 -1
  150. package/dist/schema/call/allocation.js +1 -1
  151. package/dist/schema/call/arbitration.js +1 -1
  152. package/dist/schema/call/base.d.ts +8 -0
  153. package/dist/schema/call/base.js +1 -1
  154. package/dist/schema/call/bridge.d.ts +2 -0
  155. package/dist/schema/call/error-codes.d.ts +1 -1
  156. package/dist/schema/call/error-codes.js +1 -1
  157. package/dist/schema/call/guard.js +1 -1
  158. package/dist/schema/call/handler.js +1 -1
  159. package/dist/schema/call/machine.js +1 -1
  160. package/dist/schema/call/semantic.js +1 -1
  161. package/dist/schema/call/service.d.ts +3 -3
  162. package/dist/schema/call/service.js +1 -1
  163. package/dist/schema/common/index.js +1 -1
  164. package/dist/schema/evaluation/index.d.ts +8 -0
  165. package/dist/schema/evaluation/index.js +1 -1
  166. package/dist/schema/goal/planning.d.ts +1 -0
  167. package/dist/schema/goal/planning.js +1 -1
  168. package/dist/schema/industry-pack/index.d.ts +29 -0
  169. package/dist/schema/industry-pack/index.js +1 -1
  170. package/dist/schema/local/index.d.ts +20 -0
  171. package/dist/schema/local/index.js +1 -1
  172. package/dist/schema/messenger/index.d.ts +2 -0
  173. package/dist/schema/messenger/index.js +1 -1
  174. package/dist/schema/operations.d.ts +1 -1
  175. package/dist/schema/operations.js +1 -1
  176. package/dist/schema/query/bi.d.ts +106 -0
  177. package/dist/schema/query/bi.js +1 -1
  178. package/dist/schema/query/index.d.ts +5 -5
  179. package/dist/schema/query/index.js +1 -1
  180. package/dist/schema/schema-version.js +1 -1
  181. package/dist/schema/watch/index.js +1 -1
  182. package/dist/schema-query-impl/index.js +1 -1
  183. package/dist/schemas/account_operation.output.json +4 -2
  184. package/dist/schemas/benchmark_migration_operation.output.json +3 -3
  185. package/dist/schemas/benchmark_migration_operation.schema.json +16 -2
  186. package/dist/schemas/bridge_operation.output.json +4 -2
  187. package/dist/schemas/bridge_operation.schema.json +5 -5
  188. package/dist/schemas/evaluation_operation.output.json +16 -0
  189. package/dist/schemas/guard2file.schema.json +1 -1
  190. package/dist/schemas/index.json +1 -1
  191. package/dist/schemas/industry_pack_operation.output.json +150 -1
  192. package/dist/schemas/industry_pack_operation.schema.json +9 -3
  193. package/dist/schemas/keeper_operation.output.json +2 -2
  194. package/dist/schemas/local_cache_operation.output.json +4 -2
  195. package/dist/schemas/local_history_operation.output.json +4 -2
  196. package/dist/schemas/local_info_operation.output.json +4 -2
  197. package/dist/schemas/local_mark_operation.output.json +4 -2
  198. package/dist/schemas/machineNode2file.schema.json +1 -1
  199. package/dist/schemas/messenger_operation.output.json +13 -2
  200. package/dist/schemas/messenger_operation.schema.json +41 -34
  201. package/dist/schemas/monitor_events.output.json +2 -2
  202. package/dist/schemas/monitor_subscription.output.json +2 -2
  203. package/dist/schemas/onchain_events.output.json +14 -14
  204. package/dist/schemas/onchain_operations.output.json +13 -10
  205. package/dist/schemas/onchain_operations.schema.json +124 -99
  206. package/dist/schemas/onchain_operations_allocation.schema.json +7 -6
  207. package/dist/schemas/onchain_operations_arbitration.schema.json +7 -6
  208. package/dist/schemas/onchain_operations_contact.schema.json +4 -3
  209. package/dist/schemas/onchain_operations_demand.schema.json +4 -3
  210. package/dist/schemas/onchain_operations_gen_passport.schema.json +4 -3
  211. package/dist/schemas/onchain_operations_gen_proof.schema.json +1 -1
  212. package/dist/schemas/onchain_operations_guard.schema.json +7 -6
  213. package/dist/schemas/onchain_operations_machine.schema.json +9 -7
  214. package/dist/schemas/onchain_operations_order.schema.json +6 -4
  215. package/dist/schemas/onchain_operations_payment.schema.json +2 -2
  216. package/dist/schemas/onchain_operations_permission.schema.json +19 -15
  217. package/dist/schemas/onchain_operations_personal.schema.json +17 -14
  218. package/dist/schemas/onchain_operations_progress.schema.json +6 -4
  219. package/dist/schemas/onchain_operations_proof.schema.json +4 -3
  220. package/dist/schemas/onchain_operations_repository.schema.json +9 -7
  221. package/dist/schemas/onchain_operations_reward.schema.json +5 -4
  222. package/dist/schemas/onchain_operations_service.schema.json +15 -12
  223. package/dist/schemas/onchain_operations_treasury.schema.json +4 -3
  224. package/dist/schemas/onchain_table_data.output.json +18 -13
  225. package/dist/schemas/onchain_table_data.schema.json +13 -13
  226. package/dist/schemas/query_toolkit.output.json +301 -33
  227. package/dist/schemas/query_toolkit.schema.json +6 -6
  228. package/dist/schemas/watch_operation.output.json +3 -3
  229. package/dist/schemas/workflow_operation.schema.json +3 -2
  230. package/dist/schemas/wowok_buildin_info.schema.json +1 -1
  231. package/dist/task/playbook.js +1 -1
  232. package/dist/tools/handlers/benchmark-migration.d.ts +1 -0
  233. package/dist/tools/handlers/benchmark-migration.js +1 -1
  234. package/dist/tools/handlers/config.js +1 -1
  235. package/dist/tools/handlers/evaluation.js +1 -1
  236. package/dist/tools/handlers/evaluation.spec.js +1 -1
  237. package/dist/tools/handlers/industry-pack.js +1 -1
  238. package/dist/tools/handlers/messenger.js +1 -1
  239. package/dist/tools/handlers/onchain.d.ts +4 -0
  240. package/dist/tools/handlers/onchain.js +1 -1
  241. package/dist/tools/index.js +1 -1
  242. package/dist/tools/registry/business.js +1 -1
  243. package/dist/tools/registry/onchain.js +1 -1
  244. package/dist/tools/registry/query.js +1 -1
  245. package/dist/tools/sanitize-output.js +1 -1
  246. package/dist/tools/sanitize-output.spec.js +1 -1
  247. package/dist/tools/types.d.ts +1 -0
  248. package/dist/tools/upgrade-check.d.ts +22 -0
  249. package/dist/tools/upgrade-check.js +1 -1
  250. package/dist/tools/wrap.d.ts +1 -1
  251. package/dist/tools/wrap.js +1 -1
  252. package/package.json +7 -6
@@ -5,11 +5,14 @@ export interface InFlightRecord {
5
5
  allocation?: string;
6
6
  buyer?: string;
7
7
  items_count?: number;
8
+ total_pay?: string;
9
+ item_names?: string[];
8
10
  params_hash: string;
9
11
  started_at: number;
10
12
  digests: string[];
11
13
  status: "in_flight";
12
14
  }
15
+ export declare function isDeterministicOutcomeMessage(msg: string): boolean;
13
16
  export declare function beginInFlight(op: string, data: unknown, env?: {
14
17
  account?: string;
15
18
  network?: string;
@@ -51,12 +54,15 @@ export interface OrderLandedEvent {
51
54
  sender?: string;
52
55
  time?: string | number;
53
56
  digest?: string;
57
+ amount?: string | number | null;
54
58
  }
55
59
  export declare function matchOrderLandedEvent(marker: InFlightRecord, ev: OrderLandedEvent): string | undefined;
56
60
  export interface RecentOrderCandidate {
57
61
  order: string;
58
62
  owner?: string | null;
59
63
  time?: string | number;
64
+ amount?: string | number | null;
65
+ items?: unknown;
60
66
  }
61
67
  export declare function matchRecentOrder(marker: InFlightRecord, cand: RecentOrderCandidate): string | undefined;
62
68
  export {};
@@ -1 +1 @@
1
- const MAX_RECORDS=0x32,MAX_AGE_MS=0x2*0x3c*0x3c*0x3e8,records=new Map();let seq=0x0;function hash(a){let b=0x1505;for(let c=0x0;c<a['length'];c++)b=(b<<0x5)+b+a['charCodeAt'](c)>>>0x0;return b['toString'](0x10);}function prune(){const a=Date['now']();for(const [b,c]of records){if(a-c['started_at']>MAX_AGE_MS)records['delete'](b);}while(records['size']>MAX_RECORDS){const d=records['keys']()['next']()['value'];if(d===undefined)break;records['delete'](d);}}function addr(a){return typeof a==='string'&&a['startsWith']('0x')?a:undefined;}export function beginInFlight(a,b,c,d,e){if(c?.['dry_run']===!![])return'';const f=b,g=f?.['order_new']?.['buy'],h=f?.['alloc_by_guard']!=null,i={'marker_id':'ifl_'+Date['now']()['toString'](0x10)+'_'+(seq++)['toString'](0x10),'op':a,'service':h?undefined:addr(f?.['object'])??addr(g?.['service']),'allocation':h?addr(f?.['object']):undefined,'buyer':addr(c?.['account']),'items_count':Array['isArray'](g?.['items'])?g['items']['length']:undefined,'params_hash':inFlightParamsHash(b,d,c?.['account']),'started_at':e??Date['now'](),'digests':[],'status':'in_flight'};return records['set'](i['marker_id'],i),prune(),i['marker_id'];}const UNKNOWN_OUTCOME_BACKDATE_MS=0x3c*0x3e8;export function parkUnknownOutcomeMarker(a,b,c,d){if(c?.['dry_run']===!![])return;if(lastInFlightMarker(a,inFlightParamsHash(b,d,c?.['account'])))return;beginInFlight(a,b,c,d,Date['now']()-UNKNOWN_OUTCOME_BACKDATE_MS);}export function markerOpFor(a,b){const c=b;if(c?.['order_new']!=null)return'order_new';if(c?.['alloc_by_guard']!=null)return'alloc_by_guard';return a;}export function recordInFlightOutcome(a,b){const c=records['get'](a);if(!c)return;const d=b?.['digest'];typeof d==='string'&&d&&(recordLandedTombstone(c['op'],d),records['delete'](a));}const MAX_TOMBSTONES=0xa,TOMBSTONE_MAX_AGE_MS=0xa*0x3c*0x3e8,tombstones=[];function recordLandedTombstone(a,b){tombstones['push']({'op':a,'digest':b,'at':Date['now']()});while(tombstones['length']>MAX_TOMBSTONES)tombstones['shift']();}export function recentLandedTombstone(){const a=Date['now']();while(tombstones['length']>0x0&&a-tombstones[0x0]['at']>TOMBSTONE_MAX_AGE_MS)tombstones['shift']();return tombstones['length']>0x0?tombstones[tombstones['length']-0x1]:undefined;}export function clearInFlightMarkers(){const a=records['size']+tombstones['length'];return records['clear'](),tombstones['length']=0x0,a;}const MAX_RETURNED_DIGESTS=0x200,returnedDigests=[];export function noteReturnedDigest(a,b){if(!a||a['startsWith']('dry_run:'))return;if(returnedDigests['some'](c=>c['digest']===a))return;returnedDigests['push']({'digest':a,'op':b,'at':Date['now']()});while(returnedDigests['length']>MAX_RETURNED_DIGESTS)returnedDigests['shift']();}export function priorReturnOfDigest(a){if(!a)return undefined;for(let b=returnedDigests['length']-0x1;b>=0x0;b--){if(returnedDigests[b]['digest']===a)return returnedDigests[b];}return undefined;}export function attachInFlightDigest(a,b,c){const d=lastInFlightMarker(a,b);if(!d)return;if(!d['digests']['includes'](c))d['digests']['push'](c);}export function inFlightParamsHash(a,b,c){const d=typeof c==='string'?c['trim']()['toLowerCase']():'';return hash(JSON['stringify'](a??{})+'\x00'+JSON['stringify'](b??null)+'\x00'+d);}export function describeLastInFlight(a,b){let c;for(const f of records['values']()){if(f['op']!==a)continue;if(b!==undefined&&f['params_hash']!==b)continue;c=f;}if(!c)return undefined;const d=[c['service']?'service='+c['service']:undefined,c['allocation']?'allocation='+c['allocation']:undefined,c['buyer']?'buyer='+c['buyer']:undefined,c['items_count']!==undefined?'items='+c['items_count']:undefined]['filter'](Boolean)['join']('\x20'),e=c['digests']['length']>0x0?'\x0aReported\x20submission\x20digest(s):\x20'+c['digests']['join'](',\x20')+'\x20—\x20verify\x20THE\x20DIGEST\x20FIRST\x20'+'(onchain_transaction\x20by\x20digest):\x20an\x20executed\x20status\x20means\x20the\x20operation\x20LANDED\x20—\x20adopt\x20the\x20'+'created\x20object(s)\x20and\x20stop;\x20a\x20failure\x20status\x20is\x20FINAL\x20(its\x20bytes\x20are\x20consumed\x20—\x20fix\x20the\x20cause\x20'+'and\x20build\x20a\x20fresh\x20transaction);\x20a\x20digest\x20that\x20does\x20not\x20resolve\x20means\x20nothing\x20landed\x20and\x20a\x20'+'resubmit\x20is\x20safe.':'';return'IN-FLIGHT\x20MARKER\x20'+c['marker_id']+':\x20op='+c['op']+'\x20'+d+'\x20started\x20'+new Date(c['started_at'])['toISOString']()+'\x20'+'—\x20this\x20operation\x20is\x20observability-non-atomic:\x20a\x20transport\x20drop\x20after\x20submit\x20leaves\x20the\x20commit\x20state\x20'+'open.\x20Before\x20resubmitting,\x20first\x20verify\x20whether\x20an\x20order\x20with\x20this\x20exact\x20signature\x20already\x20landed\x20'+'(query\x20the\x20sender\x27s\x20recent\x20on-chain\x20objects\x20or\x20onchain_events\x20for\x20this\x20service);\x20adopt\x20it\x20if\x20present,\x20'+'resubmit\x20only\x20if\x20confirmed\x20absent.'+e;}export function lastInFlightMarker(a,b){let c;for(const d of records['values']()){if(d['op']!==a)continue;if(b!==undefined&&d['params_hash']!==b)continue;c=d;}return c;}export function consumeInFlightMarker(a,b){let c=0x0;for(const [d,e]of records){e['op']===a&&e['params_hash']===b&&(records['delete'](d),c++);}return c;}const RESEND_INTERCEPT_WINDOW_MS=0x78*0x3e8;export function pendingInFlightResend(a,b,c,d){if(d?.['dry_run']===!![])return undefined;const e=lastInFlightMarker(a,inFlightParamsHash(b,c,d?.['account']));if(!e)return undefined;if(Date['now']()-e['started_at']>=RESEND_INTERCEPT_WINDOW_MS)return undefined;const f=e['allocation']??e['service']??'the\x20object\x20referenced\x20by\x20this\x20call',g=new Date(e['started_at']+RESEND_INTERCEPT_WINDOW_MS)['toISOString'](),h=e['allocation']?'query\x20the\x20Allocation\x20object\x20and\x20the\x20Payment\x20object(s)\x20it\x20produced\x20'+'(onchain_objects\x20/\x20onchain_events\x20for\x20this\x20allocation)':'query\x20the\x20object(s)\x20this\x20exact\x20call\x20creates\x20or\x20mutates,\x20and\x20the\x20signing\x20'+'account\x27s\x20recent\x20events\x20(query_toolkit\x20onchain_objects\x20/\x20onchain_events\x20for\x20the\x20sender)';return'THIS\x20EXACT\x20CALL\x20WAS\x20SUBMITTED\x20MOMENTS\x20AGO\x20AND\x20ITS\x20OUTCOME\x20WAS\x20NEVER\x20OBSERVED\x20'+('(in-flight\x20marker\x20'+e['marker_id']+',\x20started\x20'+new Date(e['started_at'])['toISOString']()+',\x20')+('op='+e['op']+',\x20'+f+').\x20The\x20call\x20is\x20observability-non-atomic:\x20a\x20transport\x20drop\x20after\x20submit\x20')+'leaves\x20the\x20commit\x20state\x20open,\x20and\x20resubmitting\x20the\x20same\x20payload\x20without\x20checking\x20may\x20move\x20the\x20funds\x20'+'a\x20second\x20time.\x20Before\x20doing\x20anything\x20else,\x20verify\x20whether\x20the\x20previous\x20submission\x20already\x20landed:\x20'+(h+'\x20—\x20if\x20a\x20result\x20already\x20landed,\x20adopt\x20it\x20and\x20stop;\x20')+'only\x20resubmit\x20once\x20you\x20have\x20confirmed\x20on-chain\x20that\x20nothing\x20landed.\x20'+'Scope\x20of\x20this\x20check:\x20it\x20holds\x20ONLY\x20this\x20exact\x20payload\x20(data\x20+\x20submission\x20envelope\x20together),\x20and\x20'+('only\x20until\x20'+g+'\x20('+Math['round'](RESEND_INTERCEPT_WINDOW_MS/0x3e8)+'s\x20from\x20the\x20marker\x20start)\x20—\x20')+'past\x20that\x20moment\x20the\x20identical\x20call\x20goes\x20through\x20unchanged.\x20A\x20changed\x20payload\x20(different\x20amounts,\x20'+'recipients,\x20targets,\x20or\x20a\x20corrected\x20submission\x20envelope)\x20is\x20never\x20affected:\x20fixing\x20the\x20envelope\x20and\x20'+'retrying\x20right\x20away\x20is\x20always\x20allowed.';}export function matchOrderLandedEvent(a,b){const c=a['started_at']-0xf*0x3e8,d=Number(b?.['time']);if(Number['isFinite'](d)&&d<c)return undefined;if(priorReturnOfDigest(b?.['digest']))return undefined;const e=!!(a['service']&&b?.['service']&&b['service']===a['service']),f=!!(a['buyer']&&b?.['sender']&&b['sender']['toLowerCase']()===a['buyer']['toLowerCase']());if(!e&&!f)return undefined;if(a['buyer']&&b?.['sender']&&!f)return undefined;const g=b?.['digest']??'unknown';return'AUTO-VERIFIED\x20ON-CHAIN:\x20this\x20order\x20DID\x20land\x20despite\x20the\x20error\x20above\x20—\x20order='+(b?.['order']??'?')+((b?.['progress']?'\x20progress='+b['progress']:'')+'\x20digest='+g+'.\x20ADOPT\x20this\x20order\x20object;\x20')+'resubmitting\x20the\x20same\x20call\x20would\x20escrow\x20a\x20SECOND\x20time.';}export function matchRecentOrder(a,b){const c=a['started_at']-0xf*0x3e8,d=Number(b?.['time']);if(!Number['isFinite'](d)||d<c)return undefined;if(a['buyer']&&b?.['owner']&&b['owner']['toLowerCase']()!==a['buyer']['toLowerCase']())return undefined;const e=a['buyer']&&b?.['owner']?',\x20owner-verified':'';return'AUTO-VERIFIED\x20ON-CHAIN:\x20this\x20order\x20DID\x20land\x20despite\x20the\x20error\x20above\x20—\x20order='+(b?.['order']??'?')+'\x20'+('(service\x20recent_orders\x20reverse\x20lookup'+e+').\x20ADOPT\x20this\x20order\x20object;\x20')+'resubmitting\x20the\x20same\x20call\x20would\x20escrow\x20a\x20SECOND\x20time.';}
1
+ const MAX_RECORDS=0x32,MAX_AGE_MS=0x2*0x3c*0x3c*0x3e8,records=new Map();let seq=0x0;function hash(a){let b=0x1505;for(let c=0x0;c<a['length'];c++)b=(b<<0x5)+b+a['charCodeAt'](c)>>>0x0;return b['toString'](0x10);}function prune(){const a=Date['now']();for(const [b,c]of records){if(a-c['started_at']>MAX_AGE_MS)records['delete'](b);}while(records['size']>MAX_RECORDS){const d=records['keys']()['next']()['value'];if(d===undefined)break;records['delete'](d);}}function addr(a){return typeof a==='string'&&a['startsWith']('0x')?a:undefined;}export function isDeterministicOutcomeMessage(a){return/MoveAbort|abort code|has been deleted|new guard check failed|guard verification would fail on-chain/i['test'](a)||/cannot derive total_pay|buy\.total_pay is (omitted|REQUIRED)/i['test'](a);}export function beginInFlight(a,b,c,d,e){if(c?.['dry_run']===!![])return'';const f=b,g=f?.['order_new']?.['buy'],h=f?.['alloc_by_guard']!=null,i=g?.['total_pay']!=null&&typeof g['total_pay']==='object'?g['total_pay']['balance']:undefined,j=Array['isArray'](g?.['items'])?g['items']['map'](l=>typeof l?.['name']==='string'?l['name']:'')['filter'](Boolean):undefined,k={'marker_id':'ifl_'+Date['now']()['toString'](0x10)+'_'+(seq++)['toString'](0x10),'op':a,'service':h?undefined:addr(f?.['object'])??addr(g?.['service']),'allocation':h?addr(f?.['object']):undefined,'buyer':addr(c?.['account']),'items_count':Array['isArray'](g?.['items'])?g['items']['length']:undefined,...typeof i==='string'&&i!==''?{'total_pay':i}:{},...j&&j['length']>0x0?{'item_names':j}:{},'params_hash':inFlightParamsHash(b,d,c?.['account']),'started_at':e??Date['now'](),'digests':[],'status':'in_flight'};return records['set'](k['marker_id'],k),prune(),k['marker_id'];}const UNKNOWN_OUTCOME_BACKDATE_MS=0x3c*0x3e8;export function parkUnknownOutcomeMarker(a,b,c,d){if(c?.['dry_run']===!![])return;if(lastInFlightMarker(a,inFlightParamsHash(b,d,c?.['account'])))return;beginInFlight(a,b,c,d,Date['now']()-UNKNOWN_OUTCOME_BACKDATE_MS);}export function markerOpFor(a,b){const c=b;if(c?.['order_new']!=null)return'order_new';if(c?.['alloc_by_guard']!=null)return'alloc_by_guard';return a;}export function recordInFlightOutcome(a,b){const c=records['get'](a);if(!c)return;const d=b?.['digest'];typeof d==='string'&&d&&(recordLandedTombstone(c['op'],d),records['delete'](a));}const MAX_TOMBSTONES=0xa,TOMBSTONE_MAX_AGE_MS=0xa*0x3c*0x3e8,tombstones=[];function recordLandedTombstone(a,b){tombstones['push']({'op':a,'digest':b,'at':Date['now']()});while(tombstones['length']>MAX_TOMBSTONES)tombstones['shift']();}export function recentLandedTombstone(){const a=Date['now']();while(tombstones['length']>0x0&&a-tombstones[0x0]['at']>TOMBSTONE_MAX_AGE_MS)tombstones['shift']();return tombstones['length']>0x0?tombstones[tombstones['length']-0x1]:undefined;}export function clearInFlightMarkers(){const a=records['size']+tombstones['length'];return records['clear'](),tombstones['length']=0x0,a;}const MAX_RETURNED_DIGESTS=0x200,returnedDigests=[];export function noteReturnedDigest(a,b){if(!a||a['startsWith']('dry_run:'))return;if(returnedDigests['some'](c=>c['digest']===a))return;returnedDigests['push']({'digest':a,'op':b,'at':Date['now']()});while(returnedDigests['length']>MAX_RETURNED_DIGESTS)returnedDigests['shift']();}export function priorReturnOfDigest(a){if(!a)return undefined;for(let b=returnedDigests['length']-0x1;b>=0x0;b--){if(returnedDigests[b]['digest']===a)return returnedDigests[b];}return undefined;}export function attachInFlightDigest(a,b,c){const d=lastInFlightMarker(a,b);if(!d)return;if(!d['digests']['includes'](c))d['digests']['push'](c);}export function inFlightParamsHash(a,b,c){const d=typeof c==='string'?c['trim']()['toLowerCase']():'';return hash(JSON['stringify'](a??{})+'\x00'+JSON['stringify'](b??null)+'\x00'+d);}export function describeLastInFlight(a,b){let c;for(const f of records['values']()){if(f['op']!==a)continue;if(b!==undefined&&f['params_hash']!==b)continue;c=f;}if(!c)return undefined;const d=[c['service']?'service='+c['service']:undefined,c['allocation']?'allocation='+c['allocation']:undefined,c['buyer']?'buyer='+c['buyer']:undefined,c['items_count']!==undefined?'items='+c['items_count']:undefined]['filter'](Boolean)['join']('\x20'),e=c['digests']['length']>0x0?'\x0aReported\x20submission\x20digest(s):\x20'+c['digests']['join'](',\x20')+'\x20—\x20verify\x20THE\x20DIGEST\x20FIRST\x20'+'(onchain_transaction\x20by\x20digest):\x20an\x20executed\x20status\x20means\x20the\x20operation\x20LANDED\x20—\x20adopt\x20the\x20'+'created\x20object(s)\x20and\x20stop;\x20a\x20failure\x20status\x20is\x20FINAL\x20(its\x20bytes\x20are\x20consumed\x20—\x20fix\x20the\x20cause\x20'+'and\x20build\x20a\x20fresh\x20transaction);\x20a\x20digest\x20that\x20does\x20not\x20resolve\x20means\x20nothing\x20landed\x20and\x20a\x20'+'resubmit\x20is\x20safe.':'';return'IN-FLIGHT\x20MARKER\x20'+c['marker_id']+':\x20op='+c['op']+'\x20'+d+'\x20started\x20'+new Date(c['started_at'])['toISOString']()+'\x20'+'—\x20this\x20operation\x20is\x20observability-non-atomic:\x20a\x20transport\x20drop\x20after\x20submit\x20leaves\x20the\x20commit\x20state\x20'+'open.\x20Before\x20resubmitting,\x20first\x20verify\x20whether\x20an\x20order\x20with\x20this\x20exact\x20signature\x20already\x20landed\x20'+'(query\x20the\x20sender\x27s\x20recent\x20on-chain\x20objects\x20or\x20onchain_events\x20for\x20this\x20service);\x20adopt\x20it\x20if\x20present,\x20'+'resubmit\x20only\x20if\x20confirmed\x20absent.'+e;}export function lastInFlightMarker(a,b){let c;for(const d of records['values']()){if(d['op']!==a)continue;if(b!==undefined&&d['params_hash']!==b)continue;c=d;}return c;}export function consumeInFlightMarker(a,b){let c=0x0;for(const [d,e]of records){e['op']===a&&e['params_hash']===b&&(records['delete'](d),c++);}return c;}const RESEND_INTERCEPT_WINDOW_MS=0x78*0x3e8;export function pendingInFlightResend(a,b,c,d){if(d?.['dry_run']===!![])return undefined;const e=lastInFlightMarker(a,inFlightParamsHash(b,c,d?.['account']));if(!e)return undefined;if(Date['now']()-e['started_at']>=RESEND_INTERCEPT_WINDOW_MS)return undefined;const f=e['allocation']??e['service']??'the\x20object\x20referenced\x20by\x20this\x20call',g=new Date(e['started_at']+RESEND_INTERCEPT_WINDOW_MS)['toISOString'](),h=e['allocation']?'query\x20the\x20Allocation\x20object\x20and\x20the\x20Payment\x20object(s)\x20it\x20produced\x20'+'(onchain_objects\x20/\x20onchain_events\x20for\x20this\x20allocation)':'query\x20the\x20object(s)\x20this\x20exact\x20call\x20creates\x20or\x20mutates,\x20and\x20the\x20signing\x20'+'account\x27s\x20recent\x20events\x20(query_toolkit\x20onchain_objects\x20/\x20onchain_events\x20for\x20the\x20sender)';return'THIS\x20EXACT\x20CALL\x20WAS\x20SUBMITTED\x20MOMENTS\x20AGO\x20AND\x20ITS\x20OUTCOME\x20WAS\x20NEVER\x20OBSERVED\x20'+('(in-flight\x20marker\x20'+e['marker_id']+',\x20started\x20'+new Date(e['started_at'])['toISOString']()+',\x20')+('op='+e['op']+',\x20'+f+').\x20The\x20call\x20is\x20observability-non-atomic:\x20a\x20transport\x20drop\x20after\x20submit\x20')+'leaves\x20the\x20commit\x20state\x20open,\x20and\x20resubmitting\x20the\x20same\x20payload\x20without\x20checking\x20may\x20move\x20the\x20funds\x20'+'a\x20second\x20time.\x20Before\x20doing\x20anything\x20else,\x20verify\x20whether\x20the\x20previous\x20submission\x20already\x20landed:\x20'+(h+'\x20—\x20if\x20a\x20result\x20already\x20landed,\x20adopt\x20it\x20and\x20stop;\x20')+'only\x20resubmit\x20once\x20you\x20have\x20confirmed\x20on-chain\x20that\x20nothing\x20landed.\x20'+'Scope\x20of\x20this\x20check:\x20it\x20holds\x20ONLY\x20this\x20exact\x20payload\x20(data\x20+\x20submission\x20envelope\x20together),\x20and\x20'+('only\x20until\x20'+g+'\x20('+Math['round'](RESEND_INTERCEPT_WINDOW_MS/0x3e8)+'s\x20from\x20the\x20marker\x20start)\x20—\x20')+'past\x20that\x20moment\x20the\x20identical\x20call\x20goes\x20through\x20unchanged.\x20A\x20changed\x20payload\x20(different\x20amounts,\x20'+'recipients,\x20targets,\x20or\x20a\x20corrected\x20submission\x20envelope)\x20is\x20never\x20affected:\x20fixing\x20the\x20envelope\x20and\x20'+'retrying\x20right\x20away\x20is\x20always\x20allowed.';}export function matchOrderLandedEvent(a,b){const c=a['started_at']-0xf*0x3e8,d=Number(b?.['time']);if(Number['isFinite'](d)&&d<c)return undefined;if(priorReturnOfDigest(b?.['digest']))return undefined;if(a['total_pay']!=null&&b?.['amount']!=null&&amountMatches(a['total_pay'],b['amount'])===![])return undefined;const e=!!(a['service']&&b?.['service']&&b['service']===a['service']),f=!!(a['buyer']&&b?.['sender']&&b['sender']['toLowerCase']()===a['buyer']['toLowerCase']());if(!e&&!f)return undefined;if(a['buyer']&&b?.['sender']&&!f)return undefined;const g=b?.['digest']??'unknown';return'AUTO-VERIFIED\x20ON-CHAIN:\x20this\x20order\x20DID\x20land\x20despite\x20the\x20error\x20above\x20—\x20order='+(b?.['order']??'?')+((b?.['progress']?'\x20progress='+b['progress']:'')+'\x20digest='+g+'.\x20ADOPT\x20this\x20order\x20object;\x20')+'resubmitting\x20the\x20same\x20call\x20would\x20escrow\x20a\x20SECOND\x20time.';}function amountMatches(c,d){try{const e=BigInt(String(c)),f=BigInt(String(d));return e===f;}catch{return undefined;}}export function matchRecentOrder(a,b){const c=a['started_at']-0xf*0x3e8,d=Number(b?.['time']);if(!Number['isFinite'](d)||d<c)return undefined;if(a['buyer']&&b?.['owner']&&b['owner']['toLowerCase']()!==a['buyer']['toLowerCase']())return undefined;const e=amountMatches(a['total_pay'],b?.['amount']);if(e===![])return undefined;const f=Array['isArray'](b?.['items'])?b['items']['map'](k=>typeof k?.['name']==='string'?k['name']['toLowerCase']():'')['filter'](Boolean)['sort']():undefined,g=(a['item_names']??[])['map'](k=>k['toLowerCase']())['sort'](),h=g['length']>0x0&&f!==undefined;if(h&&JSON['stringify'](g)!==JSON['stringify'](f))return undefined;const i=[a['buyer']&&b?.['owner']?'owner-verified':undefined,e===!![]?'amount-verified':undefined,h?'items-verified':undefined]['filter'](Boolean),j=i['length']>0x0?',\x20'+i['join'](',\x20'):'';return'AUTO-VERIFIED\x20ON-CHAIN:\x20this\x20order\x20DID\x20land\x20despite\x20the\x20error\x20above\x20—\x20order='+(b?.['order']??'?')+'\x20'+('(service\x20recent_orders\x20reverse\x20lookup'+j+').\x20ADOPT\x20this\x20order\x20object;\x20')+'resubmitting\x20the\x20same\x20call\x20would\x20escrow\x20a\x20SECOND\x20time.';}
@@ -17,8 +17,11 @@ export interface MaterializeIO {
17
17
  resolveLate?: LateResolver;
18
18
  read?: ObjectReader;
19
19
  env?: unknown;
20
+ envByAccount?: Record<string, unknown>;
21
+ timeoutMs?: number;
20
22
  }
21
23
  export declare function handlerExecutor(env?: unknown): Executor;
24
+ export declare function adaptConfigureParams(method: string, params: unknown): unknown;
22
25
  export declare function adaptCreateData(step: CreateStep, resolved: Record<string, unknown>): Record<string, unknown>;
23
26
  export declare function preflightPlan(plan: Plan): {
24
27
  plan: Plan;
@@ -36,6 +39,7 @@ export interface MaterializeResult {
36
39
  steps: StepResult[];
37
40
  outputs: Record<string, string>;
38
41
  completed: boolean;
42
+ budgetExhausted: boolean;
39
43
  preflight: PlanAuditResult;
40
44
  readback: ReadbackReport;
41
45
  }
@@ -1 +1 @@
1
- import{CREATABLE_OBJECTS,createsOf,isRef,resolveValue}from'./plan.js';import{auditPlan}from'./audit.js';export function handlerExecutor(a){return async(b,c)=>{const {handleOnchainOperations:d}=await import('../tools/handlers/onchain.js'),e=await d({'operation_type':b,'data':c,'env':a}),f=e['structuredContent'],g=f?.['result'];return{'outcome':f?.['outcome']==='executed'?'executed':f?.['outcome']==='pending_input'?'pending_input':'failed','digest':g?.['digest'],'created':Array['isArray'](g?.['created'])?g['created']:[],'error':g?.['error']};};}export function adaptCreateData(a,b){const {name:c,permission:d,type_parameter:e,nodes:f,...g}=b;switch(a['object']){case'service':case'arbitration':return{'object':{'name':c,'type_parameter':e,'permission':d},...g};case'machine':return{'object':{'name':c,...d!==undefined?{'permission':d}:{}},...g['description']!==undefined?{'description':g['description']}:{},'node':{'op':'add','nodes':f,'bReplace':!![]}};case'guard':return b;case'permission':case'contact':case'repository':default:return{'object':{'name':c,...d!==undefined?{'permission':d}:{}},...g};}}export function preflightPlan(a){const b=auditPlan(a),c=new Set(b['findings']['map'](g=>g['rule_id'])),d=c['has']('ARB-KEY-PLANE-01'),e=b['issues']['length']===0x0&&!b['findings']['some'](g=>g['level']==='critical')&&!d,f=a['steps']['map'](g=>{if(g['op']!=='publish')return g;const h=g['preflight']['map'](i=>{const j=i['check']['endsWith']('_publish')?e:!c['has'](i['check']);return{...i,'status':j?'pass':'fail'};});return{...g,'preflight':h};});return{'plan':{...a,'steps':f},'audit':b};}function stripGenerics(a){return a['replace'](/<.*>$/,'');}function matchCreated(a,b){const c=stripGenerics(b);return a['created']['find'](d=>{if(typeof d['type_raw']!=='string'||typeof d['object']!=='string')return![];return stripGenerics(d['type_raw'])['endsWith']('::'+c);})?.['object'];}const DEFAULT_LATE=a=>{if(a['by']==='address')return a['address'];throw new Error('unresolved\x20late\x20binding\x20(no\x20resolver\x20injected):\x20local_name\x20\x27'+a['mark']+'\x27');};export async function materializePlan(a,b,c){const {plan:d,audit:f}=preflightPlan(a),g=new Map(Object['entries'](c?.['outputs']??{})),h=new Set(c?.['completedSteps']??[]),i=[],j=b['resolveLate']??DEFAULT_LATE,k=new Map(d['steps']['filter'](o=>o['op']==='create')['map'](o=>[o['id'],o['object']])),l=o=>resolveValue(o,g,j);let m=![];for(const o of d['steps']){if(m){i['push']({'stepId':o['id'],'status':'blocked','error':'halted\x20by\x20earlier\x20failure/blocked\x20publish'});continue;}if(h['has'](o['id'])){const p=g['get'](o['id']);if(p===undefined){i['push']({'stepId':o['id'],'status':'failed','error':'resumed\x20step\x20has\x20no\x20recorded\x20output\x20—\x20pass\x20it\x20in\x20previous_outputs'}),m=!![];continue;}i['push']({'stepId':o['id'],'status':'executed','address':p,'error':'resumed\x20from\x20a\x20prior\x20run\x20(adopted,\x20not\x20re-executed)'});continue;}try{if(o['op']==='publish'){const t=o['preflight']['filter'](w=>w['status']==='fail');if(t['length']>0x0){i['push']({'stepId':o['id'],'status':'blocked','error':'preflight\x20failed:\x20'+t['map'](w=>w['check'])['join'](',\x20')+'\x20(refusing\x20to\x20publish\x20—\x20A-2)'});continue;}const u=l(o['target']),v=await b['execute'](k['get'](o['target']['$ref'])??'',{'object':u,'publish':!![]},b['env']);if(v['outcome']!=='executed'){i['push']({'stepId':o['id'],'status':'failed','error':v['error']??v['outcome']}),m=!![];continue;}i['push']({'stepId':o['id'],'status':'executed','digest':v['digest'],'address':u});continue;}const q=Object['fromEntries'](Object['entries'](o['params'])['map'](([w,x])=>[w,l(x)]));if(o['op']==='create'){const w=adaptCreateData(o,q),x=await b['execute'](o['object'],w,b['env']);if(x['outcome']!=='executed'){i['push']({'stepId':o['id'],'status':'failed','error':x['error']??x['outcome']}),m=!![];continue;}const y=matchCreated(x,CREATABLE_OBJECTS[o['object']]);if(y===undefined){i['push']({'stepId':o['id'],'status':'failed','error':'created\x20'+o['object']+'\x20not\x20found\x20in\x20transaction\x20result'}),m=!![];continue;}g['set'](o['id'],y),i['push']({'stepId':o['id'],'status':'executed','digest':x['digest'],'address':y});continue;}const r=l(o['target']),s=await b['execute'](k['get'](isRef(o['target'])?o['target']['$ref']:'')??'',{'object':r,[o['method']]:q},b['env']);if(s['outcome']!=='executed'){i['push']({'stepId':o['id'],'status':'failed','error':s['error']??s['outcome']}),m=!![];continue;}i['push']({'stepId':o['id'],'status':'executed','digest':s['digest'],'address':r});}catch(z){i['push']({'stepId':o['id'],'status':'failed','error':z instanceof Error?z['message']:String(z)}),m=!![];}}const n=await verifyMaterialization(d,g,b);return{'steps':i,'outputs':Object['fromEntries'](g),'completed':i['every'](A=>A['status']==='executed'),'preflight':f,'readback':n};}export function planAllocatorRows(a){const b=[],c=d=>{if(typeof d==='object'&&d!==null&&!Array['isArray'](d)){const e=d;if(Array['isArray'](e['allocators']))d=e['allocators'];}if(!Array['isArray'](d))return;for(const f of d){if(typeof f==='object'&&f!==null)b['push'](f);}};for(const d of a['steps']){if(d['op']==='create'&&d['object']==='service')c(d['params']['order_allocators']);if(d['op']==='configure'&&d['method']==='order_allocators')c(d['params']['allocators']);}return b;}export function conservationCheck(a){const b=planAllocatorRows(a);if(b['length']===0x0)return[{'name':'allocator_conservation','ok':![],'detail':'no\x20allocator\x20rows\x20(PLAN-ALLOC-01)'}];const c=new Map();for(const e of b){const f=e['track']??'settlement';c['set'](f,[...c['get'](f)??[],e]);}const d=[];for(const [g,h]of c){const i=h['flatMap'](l=>(l['sharing']??[])['map'](m=>m['mode']));if(i['some'](l=>l==='Amount')){d['push']({'name':'conservation:'+g,'ok':!![],'detail':'contains\x20Amount-mode\x20row(s)\x20—\x20fixed\x20payouts\x20are\x20not\x20statically\x20verifiable\x20against\x20the\x20escrow\x20total'});continue;}let j=0x0;for(const l of h){for(const m of l['sharing']??[]){if(m['mode']==='Rate'||m['mode']==='RateGross')j+=Number(m['sharing']??0x0);}}const k=i['some'](n=>n==='Surplus');if(j>0x2710)d['push']({'name':'conservation:'+g,'ok':![],'detail':'rate\x20sum\x20'+j+'\x20>\x2010000\x20—\x20track\x20pays\x20out\x20MORE\x20than\x20it\x20holds'});else j<0x2710&&!k?d['push']({'name':'conservation:'+g,'ok':![],'detail':'rate\x20sum\x20'+j+'\x20<\x2010000\x20and\x20no\x20Surplus\x20row\x20—\x20the\x20remainder\x20has\x20no\x20fund\x20exit'}):d['push']({'name':'conservation:'+g,'ok':!![],'detail':k?'rate\x20sum\x20'+j+'\x20+\x20Surplus\x20row\x20absorbs\x20the\x20remainder':'rate\x20sum\x20'+j+'\x20==\x2010000'});}return d;}export async function verifyMaterialization(a,b,c){const d=[...conservationCheck(a)];if(c['read']!==undefined)for(const f of createsOf(a,'service')){const g=b['get'](f['id']);if(g===undefined)continue;try{const h=await c['read'](g,'service',c['env']);if(h===undefined||h===null){d['push']({'name':'readback:'+f['id'],'ok':![],'detail':'service\x20'+g+'\x20not\x20readable\x20after\x20creation'});continue;}const i=planAllocatorRows(a)['length'],j=h['order_allocators']?.['allocators']?.['length']??(Array['isArray'](h['order_allocators'])?h['order_allocators']['length']:undefined);j!==undefined&&d['push']({'name':'readback:'+f['id']+':allocators','ok':j>=i,'detail':'on-chain\x20allocator\x20rows\x20'+j+'\x20vs\x20plan\x20'+i});}catch(k){d['push']({'name':'readback:'+f['id'],'ok':![],'detail':k instanceof Error?k['message']:String(k)});}}return{'ok':d['every'](l=>l['ok']),'checks':d};}
1
+ import{CREATABLE_OBJECTS,createsOf,isRef,resolveValue}from'./plan.js';import{auditPlan}from'./audit.js';function deriveCreated(a){if(Array['isArray'](a['created']))return a['created'];const b=Array['isArray'](a['objectChanges'])?a['objectChanges']:[];return b['filter'](d=>d?.['type']==='created'&&typeof d?.['objectId']==='string')['map'](d=>({'object':d['objectId'],'type_raw':d['objectType']}));}export function handlerExecutor(a){return async(b,c)=>{const {handleOnchainOperations:d}=await import('../tools/handlers/onchain.js'),e=await d({'operation_type':b,'data':c,'env':a}),f=e['structuredContent']??{},g=f['result']!==undefined&&f['result']['data']!==undefined?f['result']:f,h=g['data']?.['result']??g['result']??g,i=g['outcome']??g['data']?.['outcome']??f['outcome']??f['status'];return{'outcome':i==='executed'||i==='success'?'executed':i==='pending_input'?'pending_input':'failed','digest':h['digest']??g['digest'],'created':deriveCreated(h),'error':h['error']??g['error']};};}function normalizeGuardTableNames(a){if(!Array['isArray'](a))return a;return a['map'](b=>{if(!b||typeof b!=='object')return b;const c=b,d=c['name'];if(typeof d!=='string')return b;let e=d['startsWith']('0x')?'n_'+d:d;if(Buffer['byteLength'](e,'utf8')>0x3f){while(Buffer['byteLength'](e+'...','utf8')>0x3f)e=e['slice'](0x0,-0x1);e=e+'...';}return e===d?b:{...c,'name':e};});}const MAX_DESCRIPTION_CONTENT=0xf9e;function truncateToBytes(a,b){if(Buffer['byteLength'](a,'utf8')<=b)return a;let c=a;while(c['length']>0x0&&Buffer['byteLength'](c,'utf8')>b)c=c['slice'](0x0,-0x1);return c;}function truncateDescription(a){if(typeof a!=='string')return a;if(Buffer['byteLength'](a,'utf8')>MAX_DESCRIPTION_CONTENT)return truncateToBytes(a,MAX_DESCRIPTION_CONTENT-0x3)+'...';return a;}export function adaptConfigureParams(a,b){if(a==='guard_add'&&b!==null&&typeof b==='object'&&!Array['isArray'](b))return[b];if(a==='coin_add'&&b!==null&&typeof b==='object'&&!Array['isArray'](b)){const c=b,d=c['coin'];if(c['balance']===undefined&&(typeof d==='number'||typeof d==='string'&&/^[0-9]+$/['test'](d)))return{'balance':d};}if(a==='order_allocators'&&b!==null&&typeof b==='object'){const e=b,f=e['allocators'];if(Array['isArray'](f)){const g=f['map'](h=>{const i=h,j=i['sharing'];if(!Array['isArray'](j))return h;return{...i,'sharing':j['map'](k=>{const m=k,n=m['who'];if(n&&typeof n['Entity']==='string')return{...m,'who':{'Entity':{'name_or_address':n['Entity']}}};return k;})};});return{...e,'allocators':g};}}if(a==='sales'&&b!==null&&typeof b==='object'){const h=b,i=h['sales'];if(Array['isArray'](i)){const j=i['map'](k=>{if(!k||typeof k!=='object')return k;const l=k,m=l['stock']??l['quantity']??0x0;return{'suspension':![],'wip':'','wip_hash':'',...l,'stock':m};});return{...h,'sales':j};}}return b;}export function adaptCreateData(a,b){const {name:c,permission:d,type_parameter:e,nodes:f,...g}=b;if(g['description']!==undefined)g['description']=truncateDescription(g['description']);switch(a['object']){case'service':case'arbitration':return{'object':{'name':c,'type_parameter':e,'permission':d},...g};case'machine':return{'object':{'name':c,...d!==undefined?{'permission':d}:{}},...g['description']!==undefined?{'description':g['description']}:{},'node':{'op':'add','nodes':f,'bReplace':!![]}};case'guard':return{...b,'description':truncateDescription(b['description']),'table':normalizeGuardTableNames(b['table'])};case'permission':case'contact':case'repository':default:{const h=g['policies'];return{'object':{'name':c,...d!==undefined?{'permission':d}:{}},...g,...a['object']==='repository'&&Array['isArray'](h)?{'policies':{'op':'set','policy':h['map'](i=>{if(!i||typeof i!=='object')return i;const j=i;return typeof j['description']==='string'?{...j,'description':truncateToBytes(j['description'],0x1f4)}:j;})}}:{}};}}}export function preflightPlan(a){const b=auditPlan(a),c=new Set(b['findings']['map'](g=>g['rule_id'])),d=c['has']('ARB-KEY-PLANE-01'),e=b['issues']['length']===0x0&&!b['findings']['some'](g=>g['level']==='critical')&&!d,f=a['steps']['map'](g=>{if(g['op']!=='publish')return g;const h=g['preflight']['map'](i=>{const j=i['check']['endsWith']('_publish')?e:!c['has'](i['check']);return{...i,'status':j?'pass':'fail'};});return{...g,'preflight':h};});return{'plan':{...a,'steps':f},'audit':b};}function stripGenerics(a){return a['replace'](/<.*>$/,'');}function matchCreated(a,b){const c=stripGenerics(b);return a['created']['find'](d=>{if(typeof d['type_raw']!=='string'||typeof d['object']!=='string')return![];return stripGenerics(d['type_raw'])['endsWith']('::'+c);})?.['object'];}const DEFAULT_LATE=a=>{if(a['by']==='address')return a['address'];throw new Error('unresolved\x20late\x20binding\x20(no\x20resolver\x20injected):\x20local_name\x20\x27'+a['mark']+'\x27');};export async function materializePlan(a,b,c){const {plan:d,audit:f}=preflightPlan(a),g=new Map(Object['entries'](c?.['outputs']??{})),h=new Set(c?.['completedSteps']??[]),i=[],j=b['resolveLate']??DEFAULT_LATE,k=new Map(d['steps']['filter'](t=>t['op']==='create')['map'](t=>[t['id'],t['object']])),l=s=>resolveValue(s,g,j),m=s=>{if(s['account']===undefined)return b['env'];const t=b['envByAccount']?.[s['account']];if(t===undefined)throw new Error('step\x20\x27'+s['id']+'\x27\x20declares\x20account\x20\x27'+s['account']+'\x27\x20but\x20no\x20env\x20was\x20provided\x20for\x20it\x20—\x20'+('re-run\x20plan_execute\x20with\x20accounts[\x22'+s['account']+'\x22]\x20(a\x20declared\x20account\x20never\x20falls\x20back\x20')+'to\x20the\x20default\x20signer:\x20the\x20controller\x20identity\x20is\x20the\x20point)');return t;};let n=![],o='halted\x20by\x20earlier\x20failure/blocked\x20publish';const p=b['timeoutMs']!==undefined&&b['timeoutMs']>0x0?Date['now']()+b['timeoutMs']:undefined;let q=![];for(const s of d['steps']){if(n){i['push']({'stepId':s['id'],'status':'blocked','error':o});continue;}if(h['has'](s['id'])){const t=g['get'](s['id']);if(t===undefined){i['push']({'stepId':s['id'],'status':'failed','error':'resumed\x20step\x20has\x20no\x20recorded\x20output\x20—\x20pass\x20it\x20in\x20previous_outputs'}),n=!![];continue;}i['push']({'stepId':s['id'],'status':'executed','address':t,'error':'resumed\x20from\x20a\x20prior\x20run\x20(adopted,\x20not\x20re-executed)'});continue;}if(p!==undefined&&Date['now']()>=p){q=!![],n=!![],o='time\x20budget\x20('+b['timeoutMs']+'ms)\x20exhausted\x20before\x20this\x20step\x20—\x20RESUME,\x20not\x20re-run:\x20send\x20plan_execute\x20again\x20with\x20completed_steps\x20=\x20every\x20stepId\x20whose\x20status\x20is\x20\x27executed\x27,\x20previous_outputs\x20=\x20outputs',i['push']({'stepId':s['id'],'status':'blocked','error':o});continue;}try{if(s['op']==='publish'){const x=s['preflight']['filter'](A=>A['status']==='fail');if(x['length']>0x0){i['push']({'stepId':s['id'],'status':'blocked','error':'preflight\x20failed:\x20'+x['map'](A=>A['check'])['join'](',\x20')+'\x20(refusing\x20to\x20publish\x20—\x20A-2)'});continue;}const y=l(s['target']),z=await b['execute'](k['get'](s['target']['$ref'])??'',{'object':y,'publish':!![]},m(s));if(z['outcome']!=='executed'){i['push']({'stepId':s['id'],'status':'failed',...z['digest']!==undefined?{'digest':z['digest']}:{},'error':z['error']??z['outcome']}),n=!![];continue;}i['push']({'stepId':s['id'],'status':'executed','digest':z['digest'],'address':y});continue;}const u=Object['fromEntries'](Object['entries'](s['params'])['map'](([A,B])=>[A,l(B)]));if(s['op']==='create'){const A=adaptCreateData(s,u),B=await b['execute'](s['object'],A,m(s));if(B['outcome']!=='executed'){i['push']({'stepId':s['id'],'status':'failed',...B['digest']!==undefined?{'digest':B['digest']}:{},'error':B['error']??B['outcome']}),n=!![];continue;}const C=matchCreated(B,CREATABLE_OBJECTS[s['object']]);if(C===undefined){i['push']({'stepId':s['id'],'status':'failed',...B['digest']!==undefined?{'digest':B['digest']}:{},'error':'created\x20'+s['object']+'\x20not\x20found\x20in\x20transaction\x20result'}),n=!![];continue;}g['set'](s['id'],C),i['push']({'stepId':s['id'],'status':'executed','digest':B['digest'],'address':C});continue;}const v=l(s['target']),w=await b['execute'](k['get'](isRef(s['target'])?s['target']['$ref']:'')??'',{'object':v,[s['method']]:adaptConfigureParams(s['method'],u)},m(s));if(w['outcome']!=='executed'){i['push']({'stepId':s['id'],'status':'failed',...w['digest']!==undefined?{'digest':w['digest']}:{},'error':w['error']??w['outcome']}),n=!![];continue;}i['push']({'stepId':s['id'],'status':'executed','digest':w['digest'],'address':v});}catch(D){const E=D?.['digest'];i['push']({'stepId':s['id'],'status':'failed',...typeof E==='string'&&E?{'digest':E}:{},'error':D instanceof Error?D['message']:String(D)}),n=!![];}}const r=await verifyMaterialization(d,g,b);return{'steps':i,'outputs':Object['fromEntries'](g),'completed':i['every'](F=>F['status']==='executed'),'budgetExhausted':q,'preflight':f,'readback':r};}export function planAllocatorRows(a){const b=[],c=d=>{if(typeof d==='object'&&d!==null&&!Array['isArray'](d)){const e=d;if(Array['isArray'](e['allocators']))d=e['allocators'];}if(!Array['isArray'](d))return;for(const f of d){if(typeof f==='object'&&f!==null)b['push'](f);}};for(const d of a['steps']){if(d['op']==='create'&&d['object']==='service')c(d['params']['order_allocators']);if(d['op']==='configure'&&d['method']==='order_allocators')c(d['params']['allocators']);}return b;}export function conservationCheck(a){const b=planAllocatorRows(a);if(b['length']===0x0)return[{'name':'allocator_conservation','ok':![],'detail':'no\x20allocator\x20rows\x20(PLAN-ALLOC-01)'}];const c=[];return b['forEach']((d,e)=>{const f=d['track']??'settlement',g=typeof d['guard']==='object'&&d['guard']!==null?String(d['guard']['$ref']??JSON['stringify'](d['guard'])['slice'](0x0,0x28)):String(d['guard']??'?'),h='conservation:'+f+'['+e+']'+(g!=='?'?'('+g+')':''),i=(d['sharing']??[])['map'](l=>l['mode']);if(i['some'](l=>l==='Amount')){c['push']({'name':h,'ok':!![],'detail':'contains\x20Amount-mode\x20row(s)\x20—\x20fixed\x20payouts\x20are\x20not\x20statically\x20verifiable\x20against\x20the\x20escrow\x20total'});return;}let j=0x0;for(const l of d['sharing']??[]){if(l['mode']==='Rate'||l['mode']==='RateGross')j+=Number(l['sharing']??0x0);}const k=i['some'](n=>n==='Surplus');if(j>0x2710)c['push']({'name':h,'ok':![],'detail':'rate\x20sum\x20'+j+'\x20>\x2010000\x20—\x20row\x20pays\x20out\x20MORE\x20than\x20it\x20holds'});else j<0x2710&&!k?c['push']({'name':h,'ok':![],'detail':'rate\x20sum\x20'+j+'\x20<\x2010000\x20and\x20no\x20Surplus\x20row\x20—\x20the\x20remainder\x20has\x20no\x20fund\x20exit'}):c['push']({'name':h,'ok':!![],'detail':k?'rate\x20sum\x20'+j+'\x20+\x20Surplus\x20row\x20absorbs\x20the\x20remainder':'rate\x20sum\x20'+j+'\x20==\x2010000'});}),c;}export async function verifyMaterialization(a,b,c){const d=[...conservationCheck(a)];if(c['read']!==undefined)for(const f of createsOf(a,'service')){const g=b['get'](f['id']);if(g===undefined)continue;try{const h=await c['read'](g,'service',c['env']);if(h===undefined||h===null){d['push']({'name':'readback:'+f['id'],'ok':![],'detail':'service\x20'+g+'\x20not\x20readable\x20after\x20creation'});continue;}const i=planAllocatorRows(a)['length'],j=h['order_allocators']?.['allocators']?.['length']??(Array['isArray'](h['order_allocators'])?h['order_allocators']['length']:undefined);j!==undefined&&d['push']({'name':'readback:'+f['id']+':allocators','ok':j>=i,'detail':'on-chain\x20allocator\x20rows\x20'+j+'\x20vs\x20plan\x20'+i});}catch(k){d['push']({'name':'readback:'+f['id'],'ok':![],'detail':k instanceof Error?k['message']:String(k)});}}return{'ok':d['every'](l=>l['ok']),'checks':d};}
@@ -0,0 +1,61 @@
1
+ import { type ParamRow } from "../knowledge/param-tiers.js";
2
+ import { type ParamSchemaRow } from "../knowledge/param-schema.js";
3
+ import { type IndustryTemplate } from "../knowledge/template-loader.js";
4
+ export type ParamStatus = "live" | "inert" | "not-flippable";
5
+ export interface DisclosedParam extends ParamRow {
6
+ status: ParamStatus;
7
+ effect: string[];
8
+ landing: {
9
+ surface: string;
10
+ site: string;
11
+ }[];
12
+ editable: boolean;
13
+ paired_with?: string;
14
+ blocked_by?: string;
15
+ }
16
+ export declare function discloseParams(t: IndustryTemplate): DisclosedParam[];
17
+ export interface DisclosureSummary {
18
+ total: number;
19
+ knobs: number;
20
+ editable: number;
21
+ inertKnobs: string[];
22
+ benchmark: number;
23
+ hidden: number;
24
+ liveKnobs: string[];
25
+ }
26
+ export declare function disclosureSummary(t: IndustryTemplate): DisclosureSummary;
27
+ export type ParamPlaneRow = ParamSchemaRow & {
28
+ status: ParamStatus;
29
+ effect: string[];
30
+ landing: {
31
+ surface: string;
32
+ site: string;
33
+ }[];
34
+ landing_line: string;
35
+ editable: boolean;
36
+ inert_reason?: {
37
+ code: InertCode;
38
+ detail: string;
39
+ };
40
+ blocked_by?: string;
41
+ pair_note?: string;
42
+ };
43
+ export type InertCode = "external_object" | "no_consumer" | "prose_only" | "seat_not_built" | "not_settable" | "hidden";
44
+ export declare function inertReason(r: {
45
+ key: string;
46
+ status: ParamStatus;
47
+ disclosure: string;
48
+ landing: readonly {
49
+ surface: string;
50
+ site: string;
51
+ }[];
52
+ blocked_by?: string;
53
+ }): {
54
+ code: InertCode;
55
+ detail: string;
56
+ } | undefined;
57
+ export declare function landingLine(landing: readonly {
58
+ surface: string;
59
+ site: string;
60
+ }[]): string;
61
+ export declare function paramPlane(t: IndustryTemplate): ParamPlaneRow[];
@@ -0,0 +1 @@
1
+ import{landPlatformCommission}from'../knowledge/commission-landing.js';import{collectFeeParamLandings}from'../knowledge/template-scanner.js';import{describeFeeParams}from'../knowledge/param-tiers.js';import{paramSchema}from'../knowledge/param-schema.js';import{PLATFORM_TAKE_KEY}from'../knowledge/template-loader.js';import{compileTemplate}from'./compile.js';const DISCLOSURE_BUILD_MS=Date['UTC'](0x7ea,0x0,0x1);function probeValue(a){const b=typeof a==='number'?a:Number(a);if(!Number['isFinite'](b))return undefined;if(b===0x0)return 0x1;if(b===0x1)return 0x2;return Math['max'](0x1,Math['floor'](b/0x2));}function landedEffect(a,b,c){if(!PLATFORM_TAKE_KEY['test'](b))return{'effect':[]};const d=a['fee_params'],e=landPlatformCommission(a,d),f=landPlatformCommission(a,{...d,[b]:c});if(f['error']!==undefined)return{'effect':[],'blocked':f['error']['split']('.\x20')[0x0]};if(f['rows']===undefined||f['landing']?.['fee_key']!==b)return{'effect':[]};const g=e['rows']??(a['allocator']['rows']??[]);if(JSON['stringify'](g)===JSON['stringify'](f['rows']))return{'effect':[]};return{'effect':['allocator_rows:'+b]};}function changedSteps(c,d){if(d['blockers']['length']>c['blockers']['length'])return[];const e=movedSteps(c,d);if(e['length']===0x0&&d['blockers']['length']<c['blockers']['length']){const f=new Set(d['blockers']['map'](g=>g['code']));for(const g of new Set(c['blockers']['filter'](h=>!f['has'](h['code']))['map'](h=>h['code']))){e['push']('unblocks:'+g);}}return e;}function movedSteps(c,d){const e=[],f=Math['max'](c['plan']['steps']['length'],d['plan']['steps']['length']);for(let g=0x0;g<f;g++){const h=JSON['stringify'](c['plan']['steps'][g]??null),j=JSON['stringify'](d['plan']['steps'][g]??null);if(h!==j)e['push'](c['plan']['steps'][g]?.['id']??d['plan']['steps'][g]?.['id']??'#'+g);}return e;}function pairedKeys(a){const b=new Map();for(const d of a['allocator']['rows']??[]){const e=d['value_from'];if(e===undefined)continue;const f=d['guard_key']??'\x00unkeyed',h=b['get'](f)??new Set();h['add'](e),b['set'](f,h);}const c=new Map();for(const i of b['values']()){if(i['size']<0x2)continue;const j=[...i];for(const k of j)c['set'](k,j['find'](l=>l!==k));}return c;}export function discloseParams(a){const b=collectFeeParamLandings(a),c=compileTemplate(a,{},{'buildTimeMs':DISCLOSURE_BUILD_MS}),d=pairedKeys(a);return describeFeeParams(a)['map'](e=>{const f=(b['get'](e['key'])??[])['map'](n=>({'surface':n['surface'],'site':n['site']})),g=e['selector']&&typeof e['value']==='string'?(a['conditional_guards']??[])['filter'](n=>n['param']===e['key'])['flatMap'](n=>n['values']??[])['find'](n=>n!==e['value']):undefined,h=g??probeValue(e['value']);if(h===undefined)return{...e,'status':'not-flippable','effect':[],'landing':f,'editable':![]};const i=compileTemplate(a,{[e['key']]:h},{'buildTimeMs':DISCLOSURE_BUILD_MS}),j=typeof h==='number'?landedEffect(a,e['key'],h):{'effect':[]};j['effect']['length']>0x0&&!f['some'](n=>n['surface']==='allocator_row')&&f['push']({'surface':'allocator_row','site':e['key']});const k=[...changedSteps(c,i),...j['effect']],l=d['get'](e['key']);let m=k['length']>0x0?'live':'inert';return m==='inert'&&l!==undefined&&movedSteps(c,i)['length']>0x0&&(m='live'),{...e,'status':m,'effect':k['length']>0x0?k:m==='live'?['allocator_rows:'+e['key']]:k,'landing':f,'editable':m==='live'&&e['disclosure']!=='hidden',...l!==undefined&&m==='live'?{'paired_with':l}:{},...j['blocked']!==undefined?{'blocked_by':j['blocked']}:{}};});}export function disclosureSummary(a){const b=discloseParams(a);return{'total':b['length'],'knobs':b['filter'](c=>c['disclosure']==='knob')['length'],'editable':b['filter'](c=>c['editable'])['length'],'inertKnobs':b['filter'](c=>c['disclosure']==='knob'&&c['status']==='inert')['map'](c=>c['key']),'benchmark':b['filter'](c=>c['disclosure']==='card')['length'],'hidden':b['filter'](c=>c['disclosure']==='hidden')['length'],'liveKnobs':b['filter'](c=>c['disclosure']==='knob'&&c['status']==='live')['map'](c=>c['key'])};}const EXTERNAL_CARRIER={'arbitration_fee_usd':'the\x20Service\x27s\x20bound\x20Arbitration\x20object\x20(a\x20case-level\x20fee\x20configured\x20there,\x20never\x20a\x20template\x20parameter)','courier_tip_bps':'the\x20rider\x20payroll\x20settled\x20outside\x20the\x20order\x20escrow\x20(tips\x20are\x20not\x20a\x20claim\x20on\x20this\x20pool)','max_discount_bps':'the\x20Service-side\x20Discount\x20(coupon)\x20object;\x20this\x20value\x20only\x20bounds\x20what\x20that\x20object\x20may\x20charge\x20(build-time\x20scale\x20check)','merchant_service_fee_bps':'the\x20INCUMBENT\x20platform\x27s\x20merchant-side\x20fee\x20(benchmark\x20only);\x20this\x20store\x20is\x20WoWok\x20direct\x20sales\x20and\x20takes\x20no\x20platform\x20commission,\x20so\x20no\x20money\x20rail\x20reads\x20this\x20value'};export function inertReason(a){if(a['disclosure']==='hidden')return{'code':'hidden','detail':'Plumbing/directive\x20row:\x20not\x20offered\x20and\x20not\x20meant\x20to\x20be\x20set.'};if(a['status']==='live')return undefined;const b=EXTERNAL_CARRIER[a['key']];if(b!==undefined)return{'code':'external_object','detail':'Carried\x20by\x20'+b+'.\x20Setting\x20it\x20on\x20this\x20template\x20changes\x20nothing\x20on\x20chain\x20—\x20configure\x20it\x20on\x20that\x20object\x20instead.'};if(a['blocked_by']!==undefined)return{'code':'external_object','detail':a['blocked_by']+'.\x20This\x20value\x20is\x20carried\x20by\x20a\x20different\x20object\x20or\x20money\x20shape,\x20not\x20by\x20this\x20template\x27s\x20guards.'};if(a['status']==='not-flippable')return{'code':'not_settable','detail':'The\x20value\x20is\x20not\x20a\x20number\x20a\x20control\x20can\x20offer\x20(no\x20sibling\x20value\x20to\x20probe).'};if(a['landing']['length']===0x0)return{'code':'no_consumer','detail':'No\x20guard,\x20allocator\x20row\x20or\x20time\x20anchor\x20names\x20this\x20key\x20—\x20setting\x20it\x20changes\x20nothing\x20on\x20chain.'};if(a['landing']['every'](e=>e['surface']==='directive'))return{'code':'prose_only','detail':'Named\x20only\x20in\x20the\x20template\x27s\x20prose\x20(build\x20notes\x20/\x20user\x20inputs);\x20no\x20machine\x20object\x20reads\x20it.'};const c=[...new Set(a['landing']['map'](e=>e['surface']+'\x20\x27'+e['site']+'\x27'))]['join'](',\x20'),d=a['landing']['some'](e=>e['surface']==='allocator_row')?'\x20—\x20the\x20allocator\x20rows\x20compile\x20with\x20a\x20literal\x20value,\x20not\x20this\x20key':a['landing']['some'](e=>e['surface']==='guard')?'\x20—\x20the\x20guard\x27s\x20constant\x20is\x20frozen\x20into\x20the\x20Guard\x20at\x20publish':a['landing']['some'](e=>e['surface']==='time_anchor')?'\x20—\x20the\x20time\x20anchor\x20compiles\x20its\x20duration\x20as\x20a\x20constant':'';return{'code':'seat_not_built','detail':'A\x20seat\x20is\x20declared\x20('+c+')\x20but\x20overriding\x20the\x20value\x20does\x20not\x20change\x20the\x20compiled\x20plan'+d+'.\x20It\x20is\x20a\x20published\x20price/capacity\x20figure,\x20not\x20an\x20enforced\x20constant:\x20a\x20Machine\x20rebuild\x20is\x20what\x20changes\x20it.'};}const SURFACE_WORDING={'guard':'enforced\x20by\x20guard','allocator_row':'allocator\x20row','time_anchor':'time\x20anchor','kernel':'compile\x20kernel','directive':'prose\x20only\x20(no\x20chain\x20effect)'};export function landingLine(a){if(a['length']===0x0)return'no\x20declared\x20landing';const b=new Set(),c=[];for(const d of a){const e=SURFACE_WORDING[d['surface']]??d['surface'],f=d['surface']==='directive'?e:e+'\x20\x27'+d['site']+'\x27';if(b['has'](f))continue;b['add'](f),c['push'](f);}return c['join'](';\x20');}export function paramPlane(a){const b=new Map(paramSchema(a)['map'](c=>[c['key'],c]));return discloseParams(a)['map'](c=>{const d=b['get'](c['key']);if(d===undefined)throw new Error('paramPlane:\x20\x27'+c['key']+'\x27\x20has\x20no\x20schema\x20row\x20(classification\x20is\x20not\x20total)');const e=inertReason(c);return{...d,'status':c['status'],'effect':c['effect'],'landing':c['landing'],'landing_line':c['status']!=='live'&&EXTERNAL_CARRIER[c['key']]!==undefined?'carried\x20by\x20'+EXTERNAL_CARRIER[c['key']]:landingLine(c['landing']),'editable':c['editable'],...e!==undefined?{'inert_reason':e}:{},...c['blocked_by']!==undefined?{'blocked_by':c['blocked_by']}:{},...c['paired_with']!==undefined?{'pair_note':'Shares\x20ONE\x2010000\x20basis-point\x20split\x20with\x20\x27'+c['paired_with']+'\x27\x20—\x20set\x20both\x20together;\x20moving\x20either\x20alone\x20exceeds\x2010000\x20and\x20the\x20build\x20refuses.'}:{}};});}
@@ -40,6 +40,7 @@ export type PublishableKind = (typeof PUBLISHABLE_KINDS)[number];
40
40
  interface StepBase {
41
41
  id: StepId;
42
42
  notes?: string;
43
+ account?: string;
43
44
  }
44
45
  export interface CreateStep extends StepBase {
45
46
  op: "create";
@@ -78,13 +79,22 @@ export interface Plan {
78
79
  inputs: Record<string, JsonValue>;
79
80
  steps: PlanStep[];
80
81
  pending_guards?: PendingGuard[];
82
+ derived_params?: DerivedParam[];
83
+ }
84
+ export interface DerivedParam {
85
+ param: string;
86
+ from: string;
87
+ input: number;
88
+ value: number;
89
+ at_ms: number;
90
+ note: string;
81
91
  }
82
92
  export declare function refsOf(value: unknown, out?: Set<StepId>): Set<StepId>;
83
93
  export declare function stepById(plan: Plan, id: StepId): PlanStep | undefined;
84
94
  export declare function createsOf(plan: Plan, kind: CreatableKind): CreateStep[];
85
95
  export declare function resolveValue(value: ResolvedValue, outputs: ReadonlyMap<StepId, string>, resolveLate: (q: LateQuery) => string): JsonValue | string;
86
96
  export interface PlanIssue {
87
- code: "PLAN_DUP_STEP" | "PLAN_UNKNOWN_KIND" | "PLAN_REF_UNKNOWN" | "PLAN_REF_FORWARD" | "PLAN_PUBLISH_TARGET" | "PLAN_PROSE_GUARD" | "PLAN_MACHINE_NODES" | "PLAN_REQUIRES_UNKNOWN";
97
+ code: "PLAN_DUP_STEP" | "PLAN_UNKNOWN_KIND" | "PLAN_REF_UNKNOWN" | "PLAN_REF_FORWARD" | "PLAN_PUBLISH_TARGET" | "PLAN_PROSE_GUARD" | "PLAN_MACHINE_NODES" | "PLAN_REQUIRES_UNKNOWN" | "PLAN_GUARD_PLACEHOLDER" | "PLAN_GUARD_EMPTY_VEC" | "PLAN_LOGIC_ARITY";
88
98
  step?: StepId;
89
99
  detail: string;
90
100
  }
@@ -1 +1 @@
1
- import{OBJECT_GRAPH}from'../chain-semantics/index.js';export function isRef(a){return typeof a==='object'&&a!==null&&!Array['isArray'](a)&&typeof a['$ref']==='string'&&Object['keys'](a)['every'](b=>b==='$ref'||b==='path');}export function isLate(a){return typeof a==='object'&&a!==null&&!Array['isArray'](a)&&typeof a['$late']==='object'&&a['$late']!==null&&Object['keys'](a)['every'](b=>b==='$late');}export const CREATABLE_OBJECTS={'permission':'Permission','guard':'Guard','repository':'Repository','machine':'Machine','service':'Service<T>','arbitration':'Arbitration<T>','treasury':'Treasury<T>','reward':'Reward<T>','demand':'Demand','contact':'Contact','proof':'Proof','resource':'Resource'};export const PUBLISHABLE_KINDS=['service','machine'];export function refsOf(a,b=new Set()){if(isRef(a))b['add'](a['$ref']);else{if(Array['isArray'](a)){for(const c of a)refsOf(c,b);}else{if(typeof a==='object'&&a!==null&&!isLate(a)){for(const d of Object['values'](a))refsOf(d,b);}}}return b;}export function stepById(a,b){return a['steps']['find'](c=>c['id']===b);}export function createsOf(a,b){return a['steps']['filter'](c=>c['op']==='create'&&c['object']===b);}export function resolveValue(a,b,c){if(isRef(a)){const d=b['get'](a['$ref']);if(d===undefined)throw new Error('unresolved\x20ref:\x20'+a['$ref']);return a['path']?''+d+a['path']:d;}if(isLate(a))return c(a['$late']);if(Array['isArray'](a))return a['map'](e=>resolveValue(e,b,c));if(typeof a==='object'&&a!==null)return Object['fromEntries'](Object['entries'](a)['map'](([e,f])=>[e,resolveValue(f,b,c)]));return a;}export function validatePlan(a){const b=[],c=new Set(a['steps']['map'](e=>e['id'])),d=new Map();return a['steps']['forEach']((e,f)=>{d['has'](e['id'])&&b['push']({'code':'PLAN_DUP_STEP','step':e['id'],'detail':'duplicate\x20step\x20id\x20at\x20index\x20'+f});d['set'](e['id'],f);if(e['op']==='create'){if(!(e['object']in CREATABLE_OBJECTS))b['push']({'code':'PLAN_UNKNOWN_KIND','step':e['id'],'detail':'unknown\x20object\x20kind:\x20'+e['object']});else!(CREATABLE_OBJECTS[e['object']]in OBJECT_GRAPH)&&b['push']({'code':'PLAN_UNKNOWN_KIND','step':e['id'],'detail':'kind\x20'+e['object']+'\x20not\x20in\x20chain\x20OBJECT_GRAPH'});if(e['object']==='guard'){const h=e['params']['table'];(!Array['isArray'](h)||h['length']===0x0)&&b['push']({'code':'PLAN_PROSE_GUARD','step':e['id'],'detail':'guard\x20requires\x20a\x20non-empty\x20structured\x20`table`\x20param\x20(no\x20prose\x20logic\x20slots)'});}if(e['object']==='machine'){const j=e['params']['nodes'];(!Array['isArray'](j)||j['length']===0x0)&&b['push']({'code':'PLAN_MACHINE_NODES','step':e['id'],'detail':'machine\x20requires\x20a\x20non-empty\x20`nodes`\x20param'});}}if(e['op']==='configure')for(const k of e['requires']??[]){(!d['has'](k)||d['get'](k)===f)&&b['push']({'code':'PLAN_REQUIRES_UNKNOWN','step':e['id'],'detail':'requires\x20unknown/prior-less\x20step:\x20'+k});}if(e['op']==='publish'){const l=d['get'](e['target']['$ref']),m=l===undefined?undefined:a['steps'][l];if(!c['has'](e['target']['$ref']))b['push']({'code':'PLAN_REF_UNKNOWN','step':e['id'],'detail':'publish\x20target\x20unknown:\x20'+e['target']['$ref']});else(m===undefined||m['op']!=='create'||!PUBLISHABLE_KINDS['includes'](m['object']))&&b['push']({'code':'PLAN_PUBLISH_TARGET','step':e['id'],'detail':'publish\x20target\x20must\x20be\x20a\x20created\x20service|machine,\x20got:\x20'+(m?.['op']==='create'?m['object']:m?.['op'])});}const g=e['op']==='create'||e['op']==='configure'?refsOf(e['params']):new Set();if(e['op']==='configure'&&isRef(e['target']))g['add'](e['target']['$ref']);if(e['op']==='publish')g['add'](e['target']['$ref']);for(const n of g){const o=d['get'](n);if(!c['has'](n))b['push']({'code':'PLAN_REF_UNKNOWN','step':e['id'],'detail':'ref\x20to\x20unknown\x20step:\x20'+n});else(o===undefined||o>=f)&&b['push']({'code':'PLAN_REF_FORWARD','step':e['id'],'detail':'ref\x20to\x20non-prior\x20step:\x20'+n});}}),b;}
1
+ import{OBJECT_GRAPH}from'../chain-semantics/index.js';export function isRef(a){return typeof a==='object'&&a!==null&&!Array['isArray'](a)&&typeof a['$ref']==='string'&&Object['keys'](a)['every'](b=>b==='$ref'||b==='path');}export function isLate(a){return typeof a==='object'&&a!==null&&!Array['isArray'](a)&&typeof a['$late']==='object'&&a['$late']!==null&&Object['keys'](a)['every'](b=>b==='$late');}export const CREATABLE_OBJECTS={'permission':'Permission','guard':'Guard','repository':'Repository','machine':'Machine','service':'Service<T>','arbitration':'Arbitration<T>','treasury':'Treasury<T>','reward':'Reward<T>','demand':'Demand','contact':'Contact','proof':'Proof','resource':'Resource'};export const PUBLISHABLE_KINDS=['service','machine'];export function refsOf(a,b=new Set()){if(isRef(a))b['add'](a['$ref']);else{if(Array['isArray'](a)){for(const c of a)refsOf(c,b);}else{if(typeof a==='object'&&a!==null&&!isLate(a)){for(const d of Object['values'](a))refsOf(d,b);}}}return b;}export function stepById(a,b){return a['steps']['find'](c=>c['id']===b);}export function createsOf(a,b){return a['steps']['filter'](c=>c['op']==='create'&&c['object']===b);}export function resolveValue(a,b,c){if(isRef(a)){const d=b['get'](a['$ref']);if(d===undefined)throw new Error('unresolved\x20ref:\x20'+a['$ref']);return a['path']?''+d+a['path']:d;}if(isLate(a))return c(a['$late']);if(Array['isArray'](a))return a['map'](e=>resolveValue(e,b,c));if(typeof a==='object'&&a!==null)return Object['fromEntries'](Object['entries'](a)['map'](([e,f])=>[e,resolveValue(f,b,c)]));return a;}function guardStructuralIssues(a,b){const c=[],d=g=>{typeof g==='string'&&g['includes']('${')&&c['push']({'code':'PLAN_GUARD_PLACEHOLDER','step':a,'detail':'unfilled\x20template\x20placeholder\x20\x27'+g['slice'](0x0,0x30)+'\x27\x20—\x20resolve\x20every\x20guard\x20param\x20before\x20execution'});},e=b['table'];if(Array['isArray'](e))for(const g of e){if(g===null||typeof g!=='object')continue;const h=g,i=h['value'];i===''&&c['push']({'code':'PLAN_GUARD_EMPTY_VEC','step':a,'detail':'table\x20row\x20'+String(h['identifier'])+'\x20carries\x20an\x20EMPTY\x20value\x20—\x20the\x20serialized\x20bytes\x20are\x20empty\x20and\x20the\x20chain\x20aborts\x20the\x20create\x20(E_TABLE_ITEM_VALUE_EMPTY=14)'}),d(i);}const f=j=>{if(Array['isArray'](j)){for(const m of j)f(m);return;}if(j===null||typeof j!=='object')return;const l=j;(l['type']==='logic_and'||l['type']==='logic_or')&&Array['isArray'](l['nodes'])&&l['nodes']['length']===0x1&&c['push']({'code':'PLAN_LOGIC_ARITY','step':a,'detail':String(l['type'])+'\x20with\x20a\x20single\x20child\x20—\x20the\x20kernel\x20rejects\x20the\x20shape;\x20unwrap\x20the\x20operand\x20(the\x20compile\x20kernel\x20normalizes\x20this\x20automatically)'});for(const [o,p]of Object['entries'](l)){if(o==='type')continue;d(p),f(p);}};return f(b['root']),c;}export function validatePlan(a){const b=[],c=new Set(a['steps']['map'](e=>e['id'])),d=new Map();return a['steps']['forEach']((e,f)=>{d['has'](e['id'])&&b['push']({'code':'PLAN_DUP_STEP','step':e['id'],'detail':'duplicate\x20step\x20id\x20at\x20index\x20'+f});d['set'](e['id'],f);if(e['op']==='create'){if(!(e['object']in CREATABLE_OBJECTS))b['push']({'code':'PLAN_UNKNOWN_KIND','step':e['id'],'detail':'unknown\x20object\x20kind:\x20'+e['object']});else!(CREATABLE_OBJECTS[e['object']]in OBJECT_GRAPH)&&b['push']({'code':'PLAN_UNKNOWN_KIND','step':e['id'],'detail':'kind\x20'+e['object']+'\x20not\x20in\x20chain\x20OBJECT_GRAPH'});if(e['object']==='guard'){const h=e['params']['table'];(!Array['isArray'](h)||h['length']===0x0)&&b['push']({'code':'PLAN_PROSE_GUARD','step':e['id'],'detail':'guard\x20requires\x20a\x20non-empty\x20structured\x20`table`\x20param\x20(no\x20prose\x20logic\x20slots)'}),b['push'](...guardStructuralIssues(e['id'],e['params']));}if(e['object']==='machine'){const j=e['params']['nodes'];(!Array['isArray'](j)||j['length']===0x0)&&b['push']({'code':'PLAN_MACHINE_NODES','step':e['id'],'detail':'machine\x20requires\x20a\x20non-empty\x20`nodes`\x20param'});}}if(e['op']==='configure')for(const k of e['requires']??[]){(!d['has'](k)||d['get'](k)===f)&&b['push']({'code':'PLAN_REQUIRES_UNKNOWN','step':e['id'],'detail':'requires\x20unknown/prior-less\x20step:\x20'+k});}if(e['op']==='publish'){const l=d['get'](e['target']['$ref']),m=l===undefined?undefined:a['steps'][l];if(!c['has'](e['target']['$ref']))b['push']({'code':'PLAN_REF_UNKNOWN','step':e['id'],'detail':'publish\x20target\x20unknown:\x20'+e['target']['$ref']});else(m===undefined||m['op']!=='create'||!PUBLISHABLE_KINDS['includes'](m['object']))&&b['push']({'code':'PLAN_PUBLISH_TARGET','step':e['id'],'detail':'publish\x20target\x20must\x20be\x20a\x20created\x20service|machine,\x20got:\x20'+(m?.['op']==='create'?m['object']:m?.['op'])});}const g=e['op']==='create'||e['op']==='configure'?refsOf(e['params']):new Set();if(e['op']==='configure'&&isRef(e['target']))g['add'](e['target']['$ref']);if(e['op']==='publish')g['add'](e['target']['$ref']);for(const n of g){const o=d['get'](n);if(!c['has'](n))b['push']({'code':'PLAN_REF_UNKNOWN','step':e['id'],'detail':'ref\x20to\x20unknown\x20step:\x20'+n});else(o===undefined||o>=f)&&b['push']({'code':'PLAN_REF_FORWARD','step':e['id'],'detail':'ref\x20to\x20non-prior\x20step:\x20'+n});}}),b;}
@@ -1 +1 @@
1
- import{watch_conversations,query_events,query_objects}from'@wowok/wowok';import{computeReviewStats,detectReviewManipulation,filterVerifiedReviews}from'../knowledge/reputation-rules.js';import{pendingWrappersAt,trackAccountPayments}from'../knowledge/payment-tracker.js';const watchers=new Map();export function registerAccountEventWatcher(a){if(!a['id']||watchers['has'](a['id']))return![];return watchers['set'](a['id'],a),!![];}export function unregisterAccountEventWatcher(a){return watchers['delete'](a);}export function listAccountEventWatchers(){return Array['from'](watchers['values']());}const PRIORITY_RANK={'required':0x4,'recommended':0x3,'info':0x2,'reminder':0x1};export async function runAccountEventWatchers(a,b){const c=[],d=b&&b['length']>0x0?new Set(b):undefined;for(const g of watchers['values']()){if(d&&!d['has'](g['id']))continue;if(g['applies']&&!await g['applies'](a))continue;try{c['push'](...await g['watch'](a));}catch{}}const f=new Map();for(const h of c)f['set'](h['id'],h);return Array['from'](f['values']())['sort']((i,j)=>PRIORITY_RANK[j['priority']]-PRIORITY_RANK[i['priority']]||j['timestamp']-i['timestamp']);}registerAccountEventWatcher({'id':'messenger_unread','description':'Unread\x20encrypted\x20messages\x20needing\x20attention','watch':async({account:a})=>{const b=await watch_conversations({'account':a,'unreadOnly':!![],'previewMessageCount':0x1,'skipAutoMarkViewed':!![]});return b['map'](d=>({'id':'messenger_unread:'+d['peerAddress'],'category':'messenger_unread','priority':'reminder','title':'Unread\x20messages\x20from\x20'+d['peerAddress'],'message':d['unreadCount']+'\x20unread\x20message(s)'+(d['lastMessagePreview']?'\x20—\x20\x22'+d['lastMessagePreview']+'\x22':''),'action':'View\x20and\x20reply\x20via\x20messenger_operation','object_ref':d['peerAddress'],'timestamp':Date['now']()}));}});function toCollectionEvent(a){const b=a['plan']['holder_kind']==='business_object';return{'id':'order_collection:'+a['wrapper_id'],'category':'order_collection','priority':'recommended','title':b?'Payment\x20awaiting\x20extraction\x20at\x20object\x20'+a['holder']:'Payment\x20awaiting\x20unwrap\x20in\x20your\x20account','message':'CoinWrapper\x20'+a['wrapper_id']+'\x20(payment\x20'+a['payment']+',\x20amount\x20'+a['amount']+')\x20is\x20held\x20by\x20'+a['holder']+'.\x20'+('Drive\x20'+a['plan']['operation']+(a['plan']['anyone_can_submit']?'\x20—\x20anyone\x20may\x20submit\x20the\x20transaction':'')+';\x20')+('the\x20bare\x20Coin\x20settles\x20to\x20'+a['plan']['settles_to']+'.\x20'+a['plan']['steps']['join']('\x20')),'action':'Extract\x20via\x20'+a['plan']['operation'],'object_ref':a['wrapper_id'],'timestamp':Date['now']()};}registerAccountEventWatcher({'id':'order_collection','description':'CoinWrappers\x20awaiting\x20extraction\x20at\x20the\x20account\x20or\x20at\x20objects\x20the\x20account\x20beneficially\x20owns','watch':async({account:a,network:b})=>{if(!a)return[];const c=new Map();try{for(const d of await pendingWrappersAt(a,{'network':b})){c['set'](d['wrapper_id'],toCollectionEvent(d));}}catch{}try{const e=await trackAccountPayments({'account':a,'network':b,'max_events':0x64});for(const f of e){for(const g of f['pending']){if(!c['has'](g['wrapper_id']))c['set'](g['wrapper_id'],toCollectionEvent(g));}}}catch{}return Array['from'](c['values']());}}),registerAccountEventWatcher({'id':'demand_presented','description':'A\x20service\x20presented\x20against\x20one\x20of\x20my\x20demands','watch':async({account:a,network:b})=>{if(!a)return[];const c=await query_events({'type':'DemandPresentEvent','order':'descending','limit':0x14,'network':b,'no_cache':!![]}),d=[];for(const e of c?.['data']??[]){const f=e['demand'];if(!f)continue;try{const g=await query_objects({'objects':[f],'network':b,'no_cache':!![]}),h=g['objects']?.[0x0],i=typeof h?.['owner']==='string'?h['owner']:h?.['owner']?.['AddressOwner'];i&&i['toLowerCase']()===a['toLowerCase']()&&d['push']({'id':'demand_presented:'+f+':'+(e['service']??'?'),'category':'demand_presented','priority':'info','title':'New\x20service\x20presented\x20on\x20your\x20demand','message':'A\x20service\x20('+(e['service']??'unknown')+')\x20presented\x20against\x20demand\x20'+f+(e['recommend']?'\x20—\x20\x22'+e['recommend']+'\x22':''),'action':'Review\x20the\x20presenter\x20via\x20onchain_table_data\x20(demand\x20presenter\x20item)','object_ref':f,'timestamp':Number(e['time']??Date['now']())});}catch{}}return d;}}),registerAccountEventWatcher({'id':'reputation_integrity','description':'Review-reputation\x20analysis\x20for\x20supplied\x20review\x20rows:\x20verification,\x20stats,\x20and\x20manipulation\x20detection\x20(knowledge/reputation-rules)','applies':({reviews:a})=>Array['isArray'](a)&&a['length']>0x0,'watch':async({reviews:a,order_history:b})=>{const c=a??[],d=b&&b['length']>0x0?filterVerifiedReviews(c,b):c,e=computeReviewStats(d),f=detectReviewManipulation(d),g=[];return f['suspicious']&&g['push']({'id':'reputation_integrity:manipulation','category':'reputation_integrity','priority':'required','title':'Suspicious\x20review\x20activity\x20detected','message':'Manipulation\x20signals:\x20'+f['reasons']['join'](';\x20')+'.\x20Stats:\x20'+e['likes']+'\x20likes\x20/\x20'+e['dislikes']+'\x20dislikes\x20across\x20'+e['total']+'\x20reviews\x20('+e['verifiedCount']+'\x20verified).','action':'Cross-check\x20reviewer\x20addresses\x20against\x20completed\x20orders\x20before\x20trusting\x20the\x20review\x20aggregate','timestamp':Date['now']()}),e['total']>=0x5&&e['verifiedCount']/e['total']<0.3&&g['push']({'id':'reputation_integrity:unverified','category':'reputation_integrity','priority':'recommended','title':'Reviews\x20are\x20dominated\x20by\x20unverified\x20submissions','message':'Only\x20'+e['verifiedCount']+'/'+e['total']+'\x20reviews\x20carry\x20a\x20completed-order\x20credential\x20—\x20the\x20aggregate\x20may\x20reflect\x20spam\x20rather\x20than\x20real\x20buyers.','action':'Declare\x20the\x20review\x20rail\x20in\x20the\x20service\x20build\x20(review_mode\x20\x27review\x27\x20or\x20\x27review_reward\x27)\x20so\x20the\x20build\x20plan\x20emits\x20the\x20review\x20Repository\x20with\x20the\x20verified-buyer\x20write\x20credential\x20(AR-1)\x20—\x20manual\x20Guard/Repository\x20assembly\x20is\x20deprecated','timestamp':Date['now']()}),e['recentTrend']==='declining'&&g['push']({'id':'reputation_integrity:declining','category':'reputation_integrity','priority':'info','title':'Review\x20trend\x20is\x20declining','message':'Recent\x20like-rate\x20is\x20materially\x20below\x20the\x20earlier\x20period\x20('+Math['round'](e['likeRate']*0x64)+'%\x20overall,\x20top\x20tags:\x20'+(e['topTags']['map'](h=>h['tag'])['join'](',\x20')||'none')+').','action':'Inspect\x20recent\x20dislike\x20tags\x20for\x20recurring\x20complaint\x20themes','timestamp':Date['now']()}),g;}});
1
+ import{watch_conversations,query_events,query_objects}from'@wowok/wowok';import{computeReviewStats,detectReviewManipulation,filterVerifiedReviews}from'../knowledge/reputation-rules.js';import{pendingWrappersAt,trackAccountPayments}from'../knowledge/payment-tracker.js';const watchers=new Map();export function registerAccountEventWatcher(a){if(!a['id']||watchers['has'](a['id']))return![];return watchers['set'](a['id'],a),!![];}export function unregisterAccountEventWatcher(a){return watchers['delete'](a);}export function listAccountEventWatchers(){return Array['from'](watchers['values']());}const PRIORITY_RANK={'required':0x4,'recommended':0x3,'info':0x2,'reminder':0x1};export async function runAccountEventWatchers(a,b){const c=[],d=b&&b['length']>0x0?new Set(b):undefined;for(const g of watchers['values']()){if(d&&!d['has'](g['id']))continue;if(g['applies']&&!await g['applies'](a))continue;try{c['push'](...await g['watch'](a));}catch{}}const f=new Map();for(const h of c)f['set'](h['id'],h);return Array['from'](f['values']())['sort']((i,j)=>PRIORITY_RANK[j['priority']]-PRIORITY_RANK[i['priority']]||j['timestamp']-i['timestamp']);}registerAccountEventWatcher({'id':'messenger_unread','description':'Unread\x20encrypted\x20messages\x20needing\x20attention','watch':async({account:a})=>{const b=await watch_conversations({'account':a,'unreadOnly':!![],'previewMessageCount':0x1,'skipAutoMarkViewed':!![]});return b['map'](d=>({'id':'messenger_unread:'+d['peerAddress'],'category':'messenger_unread','priority':'reminder','title':'Unread\x20messages\x20from\x20'+d['peerAddress'],'message':d['unreadCount']+'\x20unread\x20message(s)'+(d['lastMessagePreview']?'\x20—\x20\x22'+d['lastMessagePreview']+'\x22':''),'action':'View\x20and\x20reply\x20via\x20messenger_operation','object_ref':d['peerAddress'],'timestamp':Date['now']()}));}});function toCollectionEvent(a){const b=a['plan']['holder_kind']==='business_object';return{'id':'order_collection:'+a['wrapper_id'],'category':'order_collection','priority':'recommended','title':b?'Payment\x20awaiting\x20extraction\x20at\x20object\x20'+a['holder']:'Payment\x20awaiting\x20unwrap\x20in\x20your\x20account','message':'CoinWrapper\x20'+a['wrapper_id']+'\x20(payment\x20'+a['payment']+',\x20amount\x20'+a['amount']+')\x20is\x20held\x20by\x20'+a['holder']+'.\x20'+('Drive\x20'+a['plan']['operation']+(a['plan']['anyone_can_submit']?'\x20—\x20anyone\x20may\x20submit\x20the\x20transaction':'')+';\x20')+('the\x20bare\x20Coin\x20settles\x20to\x20'+a['plan']['settles_to']+'.\x20'+a['plan']['steps']['join']('\x20')),'action':'Extract\x20via\x20'+a['plan']['operation'],'object_ref':a['wrapper_id'],'timestamp':Date['now']()};}registerAccountEventWatcher({'id':'order_collection','description':'CoinWrappers\x20awaiting\x20extraction\x20at\x20the\x20account\x20or\x20at\x20objects\x20the\x20account\x20beneficially\x20owns','watch':async({account:a,network:b})=>{if(!a)return[];const c=new Map();try{for(const d of await pendingWrappersAt(a,{'network':b})){c['set'](d['wrapper_id'],toCollectionEvent(d));}}catch{}try{const e=await trackAccountPayments({'account':a,'network':b,'max_events':0x64});for(const f of e){for(const g of f['pending']){if(!c['has'](g['wrapper_id']))c['set'](g['wrapper_id'],toCollectionEvent(g));}}}catch{}return Array['from'](c['values']());}}),registerAccountEventWatcher({'id':'demand_presented','description':'A\x20service\x20presented\x20against\x20one\x20of\x20my\x20demands','watch':async({account:a,network:b})=>{if(!a)return[];const c=await query_events({'type':'DemandPresentEvent','order':'descending','limit':0x14,'network':b,'no_cache':!![]}),d=[];for(const e of c?.['data']??[]){const f=e['demand'];if(!f)continue;try{const g=await query_objects({'objects':[f],'network':b,'no_cache':!![]}),h=g['objects']?.[0x0],i=typeof h?.['owner']==='string'?h['owner']:h?.['owner']?.['AddressOwner'];i&&i['toLowerCase']()===a['toLowerCase']()&&d['push']({'id':'demand_presented:'+f+':'+(e['service']??'?'),'category':'demand_presented','priority':'info','title':'New\x20service\x20presented\x20on\x20your\x20demand','message':'A\x20service\x20('+(e['service']??'unknown')+')\x20presented\x20against\x20demand\x20'+f+(e['recommend']?'\x20—\x20\x22'+e['recommend']+'\x22':''),'action':'Review\x20the\x20presenter\x20via\x20onchain_table_data\x20(demand\x20presenter\x20item)','object_ref':f,'timestamp':Number(e['time']??Date['now']())});}catch{}}return d;}}),registerAccountEventWatcher({'id':'reputation_integrity','description':'Review-reputation\x20analysis\x20for\x20supplied\x20review\x20rows:\x20verification,\x20stats,\x20and\x20manipulation\x20detection\x20(the\x20review-reputation\x20rules)','applies':({reviews:a})=>Array['isArray'](a)&&a['length']>0x0,'watch':async({reviews:a,order_history:b})=>{const c=a??[],d=b&&b['length']>0x0?filterVerifiedReviews(c,b):c,e=computeReviewStats(d),f=detectReviewManipulation(d),g=[];return f['suspicious']&&g['push']({'id':'reputation_integrity:manipulation','category':'reputation_integrity','priority':'required','title':'Suspicious\x20review\x20activity\x20detected','message':'Manipulation\x20signals:\x20'+f['reasons']['join'](';\x20')+'.\x20Stats:\x20'+e['likes']+'\x20likes\x20/\x20'+e['dislikes']+'\x20dislikes\x20across\x20'+e['total']+'\x20reviews\x20('+e['verifiedCount']+'\x20verified).','action':'Cross-check\x20reviewer\x20addresses\x20against\x20completed\x20orders\x20before\x20trusting\x20the\x20review\x20aggregate','timestamp':Date['now']()}),e['total']>=0x5&&e['verifiedCount']/e['total']<0.3&&g['push']({'id':'reputation_integrity:unverified','category':'reputation_integrity','priority':'recommended','title':'Reviews\x20are\x20dominated\x20by\x20unverified\x20submissions','message':'Only\x20'+e['verifiedCount']+'/'+e['total']+'\x20reviews\x20carry\x20a\x20completed-order\x20credential\x20—\x20the\x20aggregate\x20may\x20reflect\x20spam\x20rather\x20than\x20real\x20buyers.','action':'Declare\x20the\x20review\x20rail\x20in\x20the\x20service\x20build\x20(review_mode\x20\x27review\x27\x20or\x20\x27review_reward\x27)\x20so\x20the\x20build\x20plan\x20emits\x20the\x20review\x20Repository\x20with\x20the\x20verified-buyer\x20write\x20credential\x20(AR-1)\x20—\x20manual\x20Guard/Repository\x20assembly\x20is\x20deprecated','timestamp':Date['now']()}),e['recentTrend']==='declining'&&g['push']({'id':'reputation_integrity:declining','category':'reputation_integrity','priority':'info','title':'Review\x20trend\x20is\x20declining','message':'Recent\x20like-rate\x20is\x20materially\x20below\x20the\x20earlier\x20period\x20('+Math['round'](e['likeRate']*0x64)+'%\x20overall,\x20top\x20tags:\x20'+(e['topTags']['map'](h=>h['tag'])['join'](',\x20')||'none')+').','action':'Inspect\x20recent\x20dislike\x20tags\x20for\x20recurring\x20complaint\x20themes','timestamp':Date['now']()}),g;}});
@@ -1 +1 @@
1
- import{toBase58}from'@wowok/wowok';import{DataType,newDb}from'pg-mem';import{afterEach,beforeEach,describe,expect,it}from'vitest';import{PostgresProjectionStore}from'../projection/store.js';import{PostgresSyncStore}from'../sync/store.js';import{createProjectionApi}from'./server.js';const digest=toBase58(new Uint8Array(0x20)['fill'](0x7)),objectId='0x14'+'01'['repeat'](0x1f);describe('projection\x20read-only\x20API',()=>{let a,b,c,d;beforeEach(async()=>{const e=newDb();e['public']['registerFunction']({'name':'pg_advisory_xact_lock','args':[DataType['integer'],DataType['integer']],'returns':DataType['integer'],'implementation':()=>0x0});const {Pool:f}=e['adapters']['createPg']();a=new PostgresProjectionStore(new f(),0x10),b=new PostgresSyncStore(new f()),await a['migrate'](),await b['migrate'](),await a['apply']({'chain_id':'chain_a','object_id':objectId,'object_version':'1','move_type':'0x2::service::Service<0x2::wow::WOW>','owner_kind':'Shared','payload_uri':'test://raw/service-1','payload_hash':'0x'+'41'['repeat'](0x20),'payload_format':'json+bcs-v1','payload_json':{'name':'Indexed\x20service','stock':0x3},'checkpoint':'100','tx_digest':digest,'state':'active','observed_at':'2026-10-24T00:00:00.000Z'});const g=await b['start']({'chainId':'chain_a','stream':'graphql-shared:Service','scope':{'kind':'Service'},'checkpoint':'100'});await b['savePage']({'chainId':g['chainId'],'stream':g['stream'],'runId':g['runId'],'cursor':null,'checkpoint':'100','objects':[{'objectId':objectId,'objectVersion':0x1n}]}),await b['complete']({'chainId':g['chainId'],'stream':g['stream'],'runId':g['runId']}),c=createProjectionApi({'chainId':'chain_a','projection':a,'sync':b}),await new Promise(i=>c['listen'](0x0,'127.0.0.1',i));const h=c['address']();d='http://127.0.0.1:'+h['port'];}),afterEach(async()=>{await new Promise((e,f)=>{c['close'](g=>g?f(g):e());}),await a['close'](),await b['close']();}),it('returns\x20projection\x20and\x20persisted\x20sync\x20status',async()=>{const e=await fetch(d+'/v1/status'),f=await e['json']();expect(e['status'])['toBe'](0xc8),expect(f)['toMatchObject']({'chain_id':'chain_a','read_only':!![],'projection':{'active_objects':0x1,'coverage':{'complete':![]}},'sync':[{'state':'complete','pages':0x1,'objects':0x1}],'head':null,'freshness':null}),expect(f['watermarks'])['toEqual']([{'verified_kind':'Service','max_checkpoint':'100','active_objects':0x1}]);}),it('reports\x20chain-head\x20lag\x20and\x20staleness\x20when\x20a\x20probe\x20is\x20configured',async()=>{const e=createProjectionApi({'chainId':'chain_a','projection':a,'sync':b,'staleLag':0x3,'head':{'read':async()=>({'checkpoint':'105','observed_at':'2026-10-24T12:00:00.000Z','source':'probe'})}});await new Promise(g=>e['listen'](0x0,'127.0.0.1',g));const f=e['address']();try{const g=await fetch('http://127.0.0.1:'+f['port']+'/v1/status'),h=await g['json']();expect(h['head'])['toMatchObject']({'checkpoint':'105','source':'probe'}),expect(h['freshness'])['toEqual']({'head_checkpoint':'105','projection_checkpoint':'100','head_lag':'5','stale':!![]});}finally{await new Promise((i,j)=>{e['close'](k=>k?j(k):i());});}}),it('lists\x20current\x20objects\x20with\x20coverage\x20and\x20version\x20metadata',async()=>{const e=await fetch(d+'/v1/objects?kind=Service&limit=1'),f=await e['json']();expect(e['status'])['toBe'](0xc8),expect(f['objects'])['toHaveLength'](0x1),expect(f['objects'][0x0])['toMatchObject']({'objectId':objectId,'objectVersion':'1','verifiedKind':'Service','payloadJson':{'name':'Indexed\x20service','stock':0x3}}),expect(f['coverage'])['toMatchObject']({'mode':'known_objects','complete':![]}),expect(e['headers']['get']('cache-control'))['toBe']('no-store');}),it('rejects\x20invalid\x20selectors\x20without\x20exposing\x20internal\x20errors',async()=>{const e=await fetch(d+'/v1/objects?kind=Unknown'),f=await fetch(d+'/v1/objects?cursor=invalid'),g=await fetch(d+'/v1/objects?shard_count=16');expect(e['status'])['toBe'](0x190),expect(f['status'])['toBe'](0x190),expect(g['status'])['toBe'](0x190),expect(await e['json']())['toEqual']({'error':{'code':'BAD_REQUEST','message':'Unknown\x20object\x20kind:\x20Unknown'}});}),it('exposes\x20graph\x20edges\x20with\x20orphan\x20annotation',async()=>{const e='0x15'+'02'['repeat'](0x1f);await a['apply']({'chain_id':'chain_a','object_id':objectId,'object_version':'2','move_type':'0x2::service::Service<0x2::wow::WOW>','owner_kind':'Shared','payload_uri':'test://raw/service-2','payload_hash':'0x'+'43'['repeat'](0x20),'payload_format':'rpc-content-v1','payload_json':{'machine':e,'name':'Indexed\x20service'},'checkpoint':'101','tx_digest':digest,'state':'active','observed_at':'2026-10-24T01:00:00.000Z'});const f=await fetch(d+'/v1/edges?src='+objectId),g=await f['json']();expect(f['status'])['toBe'](0xc8),expect(g)['toMatchObject']({'direction':'out','object_id':objectId,'orphan_count':0x1}),expect(g['edges'])['toEqual']([{'src':objectId,'srcKind':'Service','edge':'machine','dst':e,'dstKind':'Machine','objectVersion':'2','dstProjected':![]}]);const h=await fetch(d+'/v1/edges?dst='+e),i=await h['json']();expect(h['status'])['toBe'](0xc8),expect(i['direction'])['toBe']('in'),expect(i['edges'][0x0])['toMatchObject']({'src':objectId,'edge':'machine'});const j=await fetch(d+'/v1/edges'),k=await fetch(d+'/v1/edges?src=invalid');expect(j['status'])['toBe'](0x190),expect(k['status'])['toBe'](0x190);}),it('has\x20no\x20write\x20or\x20catch-all\x20endpoints',async()=>{const e=await fetch(d+'/v1/objects',{'method':'POST','body':'{}'}),f=await fetch(d+'/v1/unknown');expect(e['status'])['toBe'](0x195),expect(e['headers']['get']('allow'))['toBe']('GET'),expect(f['status'])['toBe'](0x194);});}),describe('match\x20API',()=>{let a,b,c,d;const e=j=>'0x14'+j['repeat'](0x1f),f=e('01'),g=e('02'),h=e('03');function i(j,k,l){return{'chain_id':'chain_a','object_id':j,'object_version':k,'move_type':'0x2::service::Service<0x2::wow::WOW>','owner_kind':'Shared','payload_uri':'test://raw/'+j+'-'+k,'payload_hash':'0x'+'41'['repeat'](0x20),'payload_format':'rpc-content-v1','payload_json':l,'checkpoint':'100','tx_digest':toBase58(new Uint8Array(0x20)['fill'](0x7)),'state':'active','observed_at':'2026-10-24T00:00:00.000Z'};}beforeEach(async()=>{const j=newDb();j['public']['registerFunction']({'name':'pg_advisory_xact_lock','args':[DataType['integer'],DataType['integer']],'returns':DataType['integer'],'implementation':()=>0x0});const {Pool:k}=j['adapters']['createPg']();a=new PostgresProjectionStore(new k(),0x10),b=new PostgresSyncStore(new k()),await a['migrate'](),await b['migrate'](),await a['apply'](i(f,'1',{'description':'Exclusive\x20beat\x20license\x20for\x20hip\x20hop\x20producers','location':'remote','sales':[{'fields':{'name':'Beat\x20License','price':'6000000000','wip_hash':'0xabc'}}],'arbitrations':['0x12'+'04'['repeat'](0x1f)],'compensation_fund':'1000000000','machine':'0x15'+'05'['repeat'](0x1f),'um':'0x24'+'06'['repeat'](0x1f),'bPublished':!![],'bPaused':![]})),await a['apply'](i(g,'1',{'description':'Coffee\x20shop\x20interior\x20mural\x20painting','location':'Shanghai','sales':[{'fields':{'name':'Mural','price':'15000000000'}}],'arbitrations':[],'compensation_fund':'0','bPublished':!![],'bPaused':![]})),await a['apply'](i(h,'1',{'description':'Beat\x20store\x20on\x20holiday','sales':[{'fields':{'name':'Beat\x20Pack','price':'1000000000'}}],'bPublished':!![],'bPaused':!![]})),c=createProjectionApi({'chainId':'chain_a','projection':a,'sync':b}),await new Promise(l=>c['listen'](0x0,'127.0.0.1',l)),d='http://127.0.0.1:'+c['address']()['port'];}),afterEach(async()=>{await new Promise((j,k)=>{c['close'](l=>l?k(l):j());}),await a['close'](),await b['close']();}),it('matches\x20materialized\x20facets\x20end-to-end\x20with\x20honest\x20coverage',async()=>{const j=new URLSearchParams({'kind':'Service','q':'beat\x20license','capabilities':'has_arbitration','budget':'10','limit':'10'}),k=await fetch(d+'/v1/match?'+j),l=await k['json']();expect(k['status'])['toBe'](0xc8),expect(l['chain_id'])['toBe']('chain_a'),expect(l['policy_version'])['toBe']('public-baseline-1'),expect(l['coverage'])['toMatchObject']({'mode':'known_objects','complete':![]}),expect(l['recall'])['toMatchObject']({'live_set':0x3,'gated':0x2,'merged':0x2,'channels_active':['structured','bm25']}),expect(l['candidates']['map'](o=>o['object_id']))['toEqual']([f,g]);const m=l['candidates'][0x0];expect(m['server_evaluation']['policy_version'])['toBe']('public-baseline-1'),expect(m['server_evaluation']['total'])['toBe'](0x64),expect(m['server_evaluation']['unknown_rules']['some'](o=>o['startsWith']('trust:')))['toBe'](!![]),expect(m['public_features']['capabilities'])['toContain']('has_refund_path');const n=l['candidates'][0x1];expect(n['server_evaluation']['red_flags'])['toEqual'](['price_over_budget','missing_capability:has_arbitration']);}),it('rejects\x20invalid\x20match\x20parameters',async()=>{const j=['/v1/match','/v1/match?kind=Arb','/v1/match?kind=Service&capabilities=has_wings','/v1/match?kind=Service&budget=abc','/v1/match?kind=Service&budget=1.2345678901','/v1/match?kind=Service&budget=-5','/v1/match?kind=Service&limit=0','/v1/match?kind=Service&limit=101','/v1/match?kind=Service&recall_limit=1001'];for(const k of j){const l=await fetch(''+d+k);expect(l['status'],k)['toBe'](0x190),expect((await l['json']())['error']['code'])['toBe']('BAD_REQUEST');}});});
1
+ import{toBase58}from'@wowok/wowok';import{DataType,newDb}from'pg-mem';import{afterEach,beforeEach,describe,expect,it}from'vitest';import{PostgresProjectionStore}from'../projection/store.js';import{PostgresSyncStore}from'../sync/store.js';import{createProjectionApi}from'./server.js';const digest=toBase58(new Uint8Array(0x20)['fill'](0x7)),objectId='0x14'+'01'['repeat'](0x1f);describe('projection\x20read-only\x20API',()=>{let a,b,c,d;beforeEach(async()=>{const e=newDb();e['public']['registerFunction']({'name':'pg_advisory_xact_lock','args':[DataType['integer'],DataType['integer']],'returns':DataType['integer'],'implementation':()=>0x0});const {Pool:f}=e['adapters']['createPg']();a=new PostgresProjectionStore(new f(),0x10),b=new PostgresSyncStore(new f()),await a['migrate'](),await b['migrate'](),await a['apply']({'chain_id':'chain_a','object_id':objectId,'object_version':'1','move_type':'0x2::service::Service<0x2::wow::WOW>','owner_kind':'Shared','payload_uri':'test://raw/service-1','payload_hash':'0x'+'41'['repeat'](0x20),'payload_format':'json+bcs-v1','payload_json':{'name':'Indexed\x20service','stock':0x3},'checkpoint':'100','tx_digest':digest,'state':'active','observed_at':'2026-10-24T00:00:00.000Z'});const g=await b['start']({'chainId':'chain_a','stream':'graphql-shared:Service','scope':{'kind':'Service'},'checkpoint':'100'});await b['savePage']({'chainId':g['chainId'],'stream':g['stream'],'runId':g['runId'],'cursor':null,'checkpoint':'100','objects':[{'objectId':objectId,'objectVersion':0x1n}]}),await b['complete']({'chainId':g['chainId'],'stream':g['stream'],'runId':g['runId']}),c=createProjectionApi({'chainId':'chain_a','projection':a,'sync':b}),await new Promise(i=>c['listen'](0x0,'127.0.0.1',i));const h=c['address']();d='http://127.0.0.1:'+h['port'];}),afterEach(async()=>{await new Promise((e,f)=>{c['close'](g=>g?f(g):e());}),await a['close'](),await b['close']();}),it('returns\x20projection\x20and\x20persisted\x20sync\x20status',async()=>{const e=await fetch(d+'/v1/status'),f=await e['json']();expect(e['status'])['toBe'](0xc8),expect(f)['toMatchObject']({'chain_id':'chain_a','read_only':!![],'projection':{'active_objects':0x1,'coverage':{'complete':![]}},'sync':[{'state':'complete','pages':0x1,'objects':0x1}],'head':null,'freshness':null,'cdc':[]}),expect(f['watermarks'])['toEqual']([{'verified_kind':'Service','max_checkpoint':'100','active_objects':0x1}]);}),it('publishes\x20every\x20CDC\x20cursor\x20with\x20its\x20distance\x20from\x20head',async()=>{await b['setCdcCheckpoint']('chain_a','Service','100'),await b['setCdcCheckpoint']('chain_a','Demand','90');const e=createProjectionApi({'chainId':'chain_a','projection':a,'sync':b,'head':{'read':async()=>({'checkpoint':'200','observed_at':'2026-10-24T12:00:00.000Z','source':'probe'})}});await new Promise(g=>e['listen'](0x0,'127.0.0.1',g));const f=e['address']();try{const g=await(await fetch('http://127.0.0.1:'+f['port']+'/v1/status'))['json']();expect(g['cdc'])['toEqual']([{'kind':'Demand','checkpoint':'90','updated_at':expect['any'](String),'behind_head':'110'},{'kind':'Service','checkpoint':'100','updated_at':expect['any'](String),'behind_head':'100'}]);}finally{await new Promise((h,i)=>{e['close'](j=>j?i(j):h());});}}),it('reports\x20chain-head\x20lag\x20and\x20staleness\x20when\x20a\x20probe\x20is\x20configured',async()=>{const e=createProjectionApi({'chainId':'chain_a','projection':a,'sync':b,'staleLag':0x3,'head':{'read':async()=>({'checkpoint':'105','observed_at':'2026-10-24T12:00:00.000Z','source':'probe'})}});await new Promise(g=>e['listen'](0x0,'127.0.0.1',g));const f=e['address']();try{const g=await fetch('http://127.0.0.1:'+f['port']+'/v1/status'),h=await g['json']();expect(h['head'])['toMatchObject']({'checkpoint':'105','source':'probe'}),expect(h['freshness'])['toMatchObject']({'head_checkpoint':'105','projection_checkpoint':'100','head_lag':'5','stale':!![]}),expect(h['freshness']['projection_age_seconds'])['toBe'](0x0),expect(h['freshness']['version_observed_at'])['toBe']('2026-10-24T00:00:00.000Z');}finally{await new Promise((i,j)=>{e['close'](k=>k?j(k):i());});}}),it('scores\x20freshness\x20off\x20the\x20last\x20confirmed\x20round,\x20not\x20off\x20the\x20last\x20version\x20change',async()=>{const e=await b['start']({'chainId':'chain_a','stream':'graphql-shared:Service','scope':{'kind':'Service'},'checkpoint':'200'});await b['savePage']({'chainId':e['chainId'],'stream':e['stream'],'runId':e['runId'],'cursor':null,'checkpoint':'200','objects':[{'objectId':objectId,'objectVersion':0x1n}]}),await b['complete']({'chainId':e['chainId'],'stream':e['stream'],'runId':e['runId']});const f=createProjectionApi({'chainId':'chain_a','projection':a,'sync':b,'staleAgeSec':0x1,'head':{'read':async()=>({'checkpoint':'210','observed_at':new Date()['toISOString'](),'source':'probe'})}});await new Promise(h=>f['listen'](0x0,'127.0.0.1',h));const g=f['address']();try{const h=await(await fetch('http://127.0.0.1:'+g['port']+'/v1/status'))['json']();expect(h['freshness'])['toMatchObject']({'projection_checkpoint':'200','head_lag':'10','version_checkpoint':'100','version_observed_at':'2026-10-24T00:00:00.000Z','stale':![]}),expect(h['freshness']['projection_age_seconds'])['toBeLessThan'](0x3c);}finally{await new Promise((i,j)=>{f['close'](k=>k?j(k):i());});}}),it('splits\x20quarantined\x20facts\x20into\x20blocking\x20and\x20superseded',async()=>{const e=await a['apply']({'chain_id':'chain_a','object_id':objectId,'object_version':'1','move_type':'0x2::service::Service<0x2::wow::WOW>','owner_kind':'Shared','payload_uri':'test://raw/service-other','payload_hash':'0x'+'42'['repeat'](0x20),'payload_format':'json+bcs-v1','checkpoint':'150','tx_digest':digest,'state':'active','observed_at':'2026-10-24T01:00:00.000Z'});expect(e['status'])['toBe']('conflict');const f=await a['apply']({'chain_id':'chain_a','object_id':'0x14'+'02'['repeat'](0x1f),'object_version':'7','move_type':'0x9::unknown::Unknown','owner_kind':'Shared','payload_uri':'test://raw/unknown-1','payload_hash':'0x'+'43'['repeat'](0x20),'payload_format':'json+bcs-v1','checkpoint':'160','tx_digest':digest,'state':'active','observed_at':'2026-10-24T02:00:00.000Z'});expect(f['status'])['toBe']('quarantined');const g=await(await fetch(d+'/v1/status'))['json']();expect(g['quarantine']['blocking'])['toBe'](0x1),expect(g['quarantine']['entries']['map'](h=>[h['reason_code'],h['blocking']]))['toEqual']([['UNSUPPORTED_OR_INVALID_MOVE_TYPE',!![]],['CONFLICTING_OBJECT_VERSION',![]]]),expect(g['quarantine']['entries'][0x1]['object_id'])['toBe'](objectId);}),it('calls\x20a\x20projection\x20stale\x20by\x20age\x20even\x20when\x20it\x20sits\x20on\x20the\x20chain\x20head',async()=>{for(const g of await b['status']('chain_a')){await b['fail'](g['chainId'],g['stream'],g['runId'],'simulated\x20timer\x20outage');}const e=createProjectionApi({'chainId':'chain_a','projection':a,'sync':b,'staleAgeSec':0x1,'head':{'read':async()=>({'checkpoint':'100','observed_at':'2026-10-24T12:00:00.000Z','source':'probe'})}});await new Promise(h=>e['listen'](0x0,'127.0.0.1',h));const f=e['address']();try{const h=await(await fetch('http://127.0.0.1:'+f['port']+'/v1/status'))['json']();expect(h['freshness'])['toMatchObject']({'head_lag':'0','stale':!![]}),expect(h['projection']['observed_at'])['toBe']('2026-10-24T00:00:00.000Z');}finally{await new Promise((i,j)=>{e['close'](k=>k?j(k):i());});}}),it('lists\x20current\x20objects\x20with\x20coverage\x20and\x20version\x20metadata',async()=>{const e=await fetch(d+'/v1/objects?kind=Service&limit=1'),f=await e['json']();expect(e['status'])['toBe'](0xc8),expect(f['objects'])['toHaveLength'](0x1),expect(f['objects'][0x0])['toMatchObject']({'objectId':objectId,'objectVersion':'1','verifiedKind':'Service','payloadJson':{'name':'Indexed\x20service','stock':0x3}}),expect(f['coverage'])['toMatchObject']({'mode':'known_objects','complete':![]}),expect(e['headers']['get']('cache-control'))['toBe']('no-store');}),it('rejects\x20invalid\x20selectors\x20without\x20exposing\x20internal\x20errors',async()=>{const e=await fetch(d+'/v1/objects?kind=Unknown'),f=await fetch(d+'/v1/objects?cursor=invalid'),g=await fetch(d+'/v1/objects?shard_count=16');expect(e['status'])['toBe'](0x190),expect(f['status'])['toBe'](0x190),expect(g['status'])['toBe'](0x190),expect(await e['json']())['toEqual']({'error':{'code':'BAD_REQUEST','message':'Unknown\x20object\x20kind:\x20Unknown'}});}),it('exposes\x20graph\x20edges\x20with\x20orphan\x20annotation',async()=>{const e='0x15'+'02'['repeat'](0x1f);await a['apply']({'chain_id':'chain_a','object_id':objectId,'object_version':'2','move_type':'0x2::service::Service<0x2::wow::WOW>','owner_kind':'Shared','payload_uri':'test://raw/service-2','payload_hash':'0x'+'43'['repeat'](0x20),'payload_format':'rpc-content-v1','payload_json':{'machine':e,'name':'Indexed\x20service'},'checkpoint':'101','tx_digest':digest,'state':'active','observed_at':'2026-10-24T01:00:00.000Z'});const f=await fetch(d+'/v1/edges?src='+objectId),g=await f['json']();expect(f['status'])['toBe'](0xc8),expect(g)['toMatchObject']({'direction':'out','object_id':objectId,'orphan_count':0x1}),expect(g['edges'])['toEqual']([{'src':objectId,'srcKind':'Service','edge':'machine','dst':e,'dstKind':'Machine','objectVersion':'2','dstProjected':![]}]);const h=await fetch(d+'/v1/edges?dst='+e),i=await h['json']();expect(h['status'])['toBe'](0xc8),expect(i['direction'])['toBe']('in'),expect(i['edges'][0x0])['toMatchObject']({'src':objectId,'edge':'machine'});const j=await fetch(d+'/v1/edges'),k=await fetch(d+'/v1/edges?src=invalid');expect(j['status'])['toBe'](0x190),expect(k['status'])['toBe'](0x190);}),it('has\x20no\x20write\x20or\x20catch-all\x20endpoints',async()=>{const e=await fetch(d+'/v1/objects',{'method':'POST','body':'{}'}),f=await fetch(d+'/v1/unknown');expect(e['status'])['toBe'](0x195),expect(e['headers']['get']('allow'))['toBe']('GET'),expect(f['status'])['toBe'](0x194);});}),describe('match\x20API',()=>{let a,b,c,d;const e=j=>'0x14'+j['repeat'](0x1f),f=e('01'),g=e('02'),h=e('03');function i(j,k,l){return{'chain_id':'chain_a','object_id':j,'object_version':k,'move_type':'0x2::service::Service<0x2::wow::WOW>','owner_kind':'Shared','payload_uri':'test://raw/'+j+'-'+k,'payload_hash':'0x'+'41'['repeat'](0x20),'payload_format':'rpc-content-v1','payload_json':l,'checkpoint':'100','tx_digest':toBase58(new Uint8Array(0x20)['fill'](0x7)),'state':'active','observed_at':'2026-10-24T00:00:00.000Z'};}beforeEach(async()=>{const j=newDb();j['public']['registerFunction']({'name':'pg_advisory_xact_lock','args':[DataType['integer'],DataType['integer']],'returns':DataType['integer'],'implementation':()=>0x0});const {Pool:k}=j['adapters']['createPg']();a=new PostgresProjectionStore(new k(),0x10),b=new PostgresSyncStore(new k()),await a['migrate'](),await b['migrate'](),await a['apply'](i(f,'1',{'description':'Exclusive\x20beat\x20license\x20for\x20hip\x20hop\x20producers','location':'remote','sales':[{'fields':{'name':'Beat\x20License','price':'6000000000','wip_hash':'0xabc'}}],'arbitrations':['0x12'+'04'['repeat'](0x1f)],'compensation_fund':'1000000000','machine':'0x15'+'05'['repeat'](0x1f),'um':'0x24'+'06'['repeat'](0x1f),'bPublished':!![],'bPaused':![]})),await a['apply'](i(g,'1',{'description':'Coffee\x20shop\x20interior\x20mural\x20painting','location':'Shanghai','sales':[{'fields':{'name':'Mural','price':'15000000000'}}],'arbitrations':[],'compensation_fund':'0','bPublished':!![],'bPaused':![]})),await a['apply'](i(h,'1',{'description':'Beat\x20store\x20on\x20holiday','sales':[{'fields':{'name':'Beat\x20Pack','price':'1000000000'}}],'bPublished':!![],'bPaused':!![]})),c=createProjectionApi({'chainId':'chain_a','projection':a,'sync':b}),await new Promise(l=>c['listen'](0x0,'127.0.0.1',l)),d='http://127.0.0.1:'+c['address']()['port'];}),afterEach(async()=>{await new Promise((j,k)=>{c['close'](l=>l?k(l):j());}),await a['close'](),await b['close']();}),it('matches\x20materialized\x20facets\x20end-to-end\x20with\x20honest\x20coverage',async()=>{const j=new URLSearchParams({'kind':'Service','q':'beat\x20license','capabilities':'has_arbitration','budget':'10','limit':'10'}),k=await fetch(d+'/v1/match?'+j),l=await k['json']();expect(k['status'])['toBe'](0xc8),expect(l['chain_id'])['toBe']('chain_a'),expect(l['policy_version'])['toBe']('public-baseline-1'),expect(l['coverage'])['toMatchObject']({'mode':'known_objects','complete':![]}),expect(l['recall'])['toMatchObject']({'live_set':0x3,'gated':0x2,'merged':0x2,'channels_active':['structured','bm25']}),expect(l['candidates']['map'](o=>o['object_id']))['toEqual']([f,g]);const m=l['candidates'][0x0];expect(m['server_evaluation']['policy_version'])['toBe']('public-baseline-1'),expect(m['server_evaluation']['total'])['toBe'](0x64),expect(m['server_evaluation']['unknown_rules']['some'](o=>o['startsWith']('trust:')))['toBe'](!![]),expect(m['public_features']['capabilities'])['toContain']('has_refund_path');const n=l['candidates'][0x1];expect(n['server_evaluation']['red_flags'])['toEqual'](['price_over_budget','missing_capability:has_arbitration']);}),it('rejects\x20invalid\x20match\x20parameters',async()=>{const j=['/v1/match','/v1/match?kind=Arb','/v1/match?kind=Service&capabilities=has_wings','/v1/match?kind=Service&budget=abc','/v1/match?kind=Service&budget=1.2345678901','/v1/match?kind=Service&budget=-5','/v1/match?kind=Service&limit=0','/v1/match?kind=Service&limit=101','/v1/match?kind=Service&recall_limit=1001'];for(const k of j){const l=await fetch(''+d+k);expect(l['status'],k)['toBe'](0x190),expect((await l['json']())['error']['code'])['toBe']('BAD_REQUEST');}});});
@@ -1 +1 @@
1
- import{PostgresProjectionStore}from'../projection/store.js';import{PostgresSyncStore}from'../sync/store.js';import{createChainHeadProbe}from'./head.js';import{createProjectionApi}from'./server.js';async function main(){const a=process['argv']['slice'](0x2);if(a[0x0]==='--help'||a[0x0]==='help'){console['log']('Usage:\x20index-api\x20<chain-id>\x0aEnvironment:\x20DATABASE_URL,\x20WOWOK_INDEX_HOST=127.0.0.1,\x20WOWOK_INDEX_PORT=8787,\x20WOWOK_HEAD_RPC_URL\x20(optional),\x20WOWOK_INDEX_STALE_LAG=0\x20(optional)');return;}if(a['length']!==0x1||!a[0x0]){console['error']('Usage:\x20index-api\x20<chain-id>'),process['exitCode']=0x2;return;}const b=process['env']['DATABASE_URL'];if(!b)throw new Error('DATABASE_URL\x20is\x20required');const c=process['env']['WOWOK_INDEX_HOST']??'127.0.0.1',d=Number(process['env']['WOWOK_INDEX_PORT']??0x2253);if(!Number['isInteger'](d)||d<0x0||d>0xffff)throw new Error('Invalid\x20API\x20port');const e=Number(process['env']['WOWOK_INDEX_SHARD_COUNT']??0x100),f=Number(process['env']['WOWOK_INDEX_STALE_LAG']??0x0),g=process['env']['WOWOK_HEAD_RPC_URL'],h=PostgresProjectionStore['fromDatabaseUrl'](b,e),i=PostgresSyncStore['fromDatabaseUrl'](b),j=createProjectionApi({'chainId':a[0x0],'projection':h,'sync':i,'staleLag':f,'head':g?createChainHeadProbe(g):undefined});try{await new Promise((k,l)=>{j['once']('error',l),j['listen'](d,c,()=>{const n=j['address']();console['log'](JSON['stringify']({'status':'listening','host':n['address'],'port':n['port'],'read_only':!![]}));});const m=()=>{j['close'](n=>n?l(n):k());};process['once']('SIGINT',m),process['once']('SIGTERM',m);});}finally{await h['close'](),await i['close']();}}await main();
1
+ import{PostgresProjectionStore}from'../projection/store.js';import{PostgresSyncStore}from'../sync/store.js';import{createChainHeadProbe}from'./head.js';import{createProjectionApi}from'./server.js';async function main(){const a=process['argv']['slice'](0x2);if(a[0x0]==='--help'||a[0x0]==='help'){console['log']('Usage:\x20index-api\x20<chain-id>\x0aEnvironment:\x20DATABASE_URL,\x20WOWOK_INDEX_HOST=127.0.0.1,\x20WOWOK_INDEX_PORT=8787,\x20WOWOK_HEAD_RPC_URL\x20(optional),\x20WOWOK_INDEX_STALE_LAG=0\x20(optional),\x20WOWOK_INDEX_STALE_AGE_SEC=0\x20(optional)');return;}if(a['length']!==0x1||!a[0x0]){console['error']('Usage:\x20index-api\x20<chain-id>'),process['exitCode']=0x2;return;}const b=process['env']['DATABASE_URL'];if(!b)throw new Error('DATABASE_URL\x20is\x20required');const c=process['env']['WOWOK_INDEX_HOST']??'127.0.0.1',d=Number(process['env']['WOWOK_INDEX_PORT']??0x2253);if(!Number['isInteger'](d)||d<0x0||d>0xffff)throw new Error('Invalid\x20API\x20port');const e=Number(process['env']['WOWOK_INDEX_SHARD_COUNT']??0x100),f=Number(process['env']['WOWOK_INDEX_STALE_LAG']??0x0),g=Number(process['env']['WOWOK_INDEX_STALE_AGE_SEC']??0x0),h=process['env']['WOWOK_HEAD_RPC_URL'],i=PostgresProjectionStore['fromDatabaseUrl'](b,e),j=PostgresSyncStore['fromDatabaseUrl'](b),k=createProjectionApi({'chainId':a[0x0],'projection':i,'sync':j,'staleLag':f,'staleAgeSec':g,'head':h?createChainHeadProbe(h):undefined});try{await new Promise((l,m)=>{k['once']('error',m),k['listen'](d,c,()=>{const o=k['address']();console['log'](JSON['stringify']({'status':'listening','host':o['address'],'port':o['port'],'read_only':!![]}));});const n=()=>{k['close'](o=>o?m(o):l());};process['once']('SIGINT',n),process['once']('SIGTERM',n);});}finally{await i['close'](),await j['close']();}}await main();
@@ -8,5 +8,6 @@ export interface ProjectionApiOptions {
8
8
  sync: PostgresSyncStore;
9
9
  head?: ChainHeadProbe;
10
10
  staleLag?: number;
11
+ staleAgeSec?: number;
11
12
  }
12
13
  export declare function createProjectionApi(options: ProjectionApiOptions): Server;
@@ -1 +1 @@
1
- import{createServer}from'node:http';import{WOW_OBJECT_TYPE_TAGS,wowAddressToBytes}from'@wowok/wowok';import{KNOWN_CAPABILITIES,runMatch}from'./match.js';function json(a,b,c){a['writeHead'](b,{'Content-Type':'application/json;\x20charset=utf-8','Cache-Control':'no-store','X-Content-Type-Options':'nosniff'}),a['end'](JSON['stringify'](c));}function badRequest(a,b){json(a,0x190,{'error':{'code':'BAD_REQUEST','message':b}});}const WOW_DECIMALS=0x9;function parseWowToWei(a){const b=/^(\d+)(?:\.(\d{1,9}))?$/['exec'](a['trim']());if(!b)return null;const c=(b[0x2]??'')['padEnd'](WOW_DECIMALS,'0');return(BigInt(b[0x1])*BigInt(0xa**WOW_DECIMALS)+BigInt(c))['toString']();}function parsePositiveInt(a){return/^\d+$/['test'](a['trim']())?Number(a['trim']()):null;}export function createProjectionApi(a){if(!a['chainId'])throw new Error('chainId\x20is\x20required');const b=a['staleLag']??0x0;if(!Number['isInteger'](b)||b<0x0)throw new Error('Invalid\x20staleLag');return createServer(async(c,d)=>{try{if(c['method']!=='GET'){d['setHeader']('Allow','GET'),json(d,0x195,{'error':{'code':'METHOD_NOT_ALLOWED','message':'GET\x20required'}});return;}const e=new URL(c['url']??'/','http://localhost');if(e['pathname']==='/v1/status'){const [f,g,h,i]=await Promise['all']([a['projection']['status'](a['chainId']),a['sync']['status'](a['chainId']),a['projection']['watermarks'](a['chainId']),a['head']?a['head']['read']():Promise['resolve'](null)]);let j=null;if(i?.['checkpoint']!==null&&i?.['checkpoint']!==undefined&&f['max_checkpoint']!==null){const k=BigInt(i['checkpoint'])-BigInt(f['max_checkpoint']);j={'head_checkpoint':i['checkpoint'],'projection_checkpoint':f['max_checkpoint'],'head_lag':(k>0x0n?k:0x0n)['toString'](),'stale':b>0x0&&k>BigInt(b)};}json(d,0xc8,{'chain_id':a['chainId'],'read_only':!![],'generated_at':new Date()['toISOString'](),'projection':f,'sync':g,'watermarks':h,'head':i,'freshness':j});return;}if(e['pathname']==='/v1/objects'){const l=e['searchParams']['get']('kind')??undefined;if(l&&!(l in WOW_OBJECT_TYPE_TAGS)){badRequest(d,'Unknown\x20object\x20kind:\x20'+l);return;}const m=e['searchParams']['get']('cursor')??undefined;if(m)try{wowAddressToBytes(m);}catch{badRequest(d,'Invalid\x20object\x20cursor');return;}const n=e['searchParams']['get']('limit'),o=n===null?undefined:Number(n);if(o!==undefined&&(!Number['isInteger'](o)||o<0x1||o>0x3e8)){badRequest(d,'limit\x20must\x20be\x20an\x20integer\x20between\x201\x20and\x201000');return;}const p=e['searchParams']['get']('shard_count'),r=e['searchParams']['get']('shard_index');if(p===null!==(r===null)){badRequest(d,'shard_count\x20and\x20shard_index\x20must\x20be\x20provided\x20together');return;}const s=p===null||r===null?undefined:{'count':Number(p),'index':Number(r)};if(s&&(!Number['isInteger'](s['count'])||s['count']<0x1||!Number['isInteger'](s['index'])||s['index']<0x0||s['index']>=s['count'])){badRequest(d,'Invalid\x20shard\x20selector');return;}const t=await a['projection']['listCurrent']({'chainId':a['chainId'],'kind':l,'cursor':m,'limit':o,'shard':s});json(d,0xc8,{'chain_id':a['chainId'],'generated_at':new Date()['toISOString'](),...t});return;}if(e['pathname']==='/v1/edges'){const u=e['searchParams']['get']('src'),v=e['searchParams']['get']('dst');if(u===null===(v===null)){badRequest(d,'Provide\x20exactly\x20one\x20of\x20src\x20or\x20dst');return;}const w=u??v;try{wowAddressToBytes(w);}catch{badRequest(d,'Invalid\x20object\x20address');return;}const x=u!==null?await a['projection']['edgesFrom'](a['chainId'],w):await a['projection']['edgesTo'](a['chainId'],w);json(d,0xc8,{'chain_id':a['chainId'],'generated_at':new Date()['toISOString'](),'direction':u!==null?'out':'in','object_id':w['toLowerCase'](),'edges':x,'orphan_count':x['filter'](y=>!y['dstProjected'])['length']});return;}if(e['pathname']==='/v1/match'){const y=e['searchParams']['get']('kind');if(y!=='Service'&&y!=='Demand'){badRequest(d,'kind\x20must\x20be\x20\x27Service\x27\x20or\x20\x27Demand\x27');return;}const z=e['searchParams']['get']('q')??undefined,A=e['searchParams']['get']('location')??undefined,B=e['searchParams']['get']('industry')??undefined;let C;const D=e['searchParams']['get']('budget');if(D!==null){C=parseWowToWei(D)??undefined;if(C===undefined){badRequest(d,'budget\x20must\x20be\x20a\x20non-negative\x20decimal\x20WOW\x20amount\x20(max\x209\x20fractional\x20digits)');return;}}let E;const F=e['searchParams']['get']('capabilities');if(F!==null){E=F['split'](',')['map'](S=>S['trim']())['filter'](S=>S['length']>0x0);const R=E['filter'](S=>!KNOWN_CAPABILITIES['includes'](S));if(R['length']>0x0){badRequest(d,'Unknown\x20capability:\x20'+R['join'](',\x20')+'\x20(known:\x20'+KNOWN_CAPABILITIES['join'](',\x20')+')');return;}}let G=0x14;const H=e['searchParams']['get']('limit');if(H!==null){G=parsePositiveInt(H)??-0x1;if(!Number['isInteger'](G)||G<0x1||G>0x64){badRequest(d,'limit\x20must\x20be\x20an\x20integer\x20between\x201\x20and\x20100');return;}}let I=0xc8;const J=e['searchParams']['get']('recall_limit');if(J!==null){I=parsePositiveInt(J)??-0x1;if(!Number['isInteger'](I)||I<0x1||I>0x3e8){badRequest(d,'recall_limit\x20must\x20be\x20an\x20integer\x20between\x201\x20and\x201000');return;}}const K=e['searchParams']['get']('include_payload');let L=![];if(K!==null){if(K==='1'||K==='true')L=!![];else{if(K!=='0'&&K!=='false'){badRequest(d,'include_payload\x20must\x20be\x20one\x20of\x201,\x20true,\x200,\x20false');return;}}}const M={'kind':y,'q':z,'location':A,'industry':B,'budgetWei':C,'capabilities':E,'limit':G,'recallLimit':I},[N,O]=await Promise['all']([a['projection']['activeFacets'](a['chainId'],y),a['projection']['status'](a['chainId'])]),P=runMatch(N,M);let Q=P['candidates'];if(L&&Q['length']>0x0){const S=await a['projection']['currentPayloads'](a['chainId'],Q['map'](T=>T['object_id']));Q=Q['map'](T=>({...T,'payload_json':S['get'](T['object_id'])??null}));}json(d,0xc8,{'chain_id':a['chainId'],'generated_at':new Date()['toISOString'](),'coverage':O['coverage'],...P,'candidates':Q});return;}json(d,0x194,{'error':{'code':'NOT_FOUND','message':'Unknown\x20endpoint'}});}catch{json(d,0x1f4,{'error':{'code':'INTERNAL_ERROR','message':'Index\x20query\x20failed'}});}});}
1
+ import{createServer}from'node:http';import{WOW_OBJECT_TYPE_TAGS,wowAddressToBytes}from'@wowok/wowok';import{KNOWN_CAPABILITIES,runMatch}from'./match.js';function json(a,b,c){a['writeHead'](b,{'Content-Type':'application/json;\x20charset=utf-8','Cache-Control':'no-store','X-Content-Type-Options':'nosniff'}),a['end'](JSON['stringify'](c));}function badRequest(a,b){json(a,0x190,{'error':{'code':'BAD_REQUEST','message':b}});}const WOW_DECIMALS=0x9;function parseWowToWei(a){const b=/^(\d+)(?:\.(\d{1,9}))?$/['exec'](a['trim']());if(!b)return null;const c=(b[0x2]??'')['padEnd'](WOW_DECIMALS,'0');return(BigInt(b[0x1])*BigInt(0xa**WOW_DECIMALS)+BigInt(c))['toString']();}function parsePositiveInt(a){return/^\d+$/['test'](a['trim']())?Number(a['trim']()):null;}export function createProjectionApi(a){if(!a['chainId'])throw new Error('chainId\x20is\x20required');const b=a['staleLag']??0x0;if(!Number['isInteger'](b)||b<0x0)throw new Error('Invalid\x20staleLag');const c=a['staleAgeSec']??0x0;if(!Number['isInteger'](c)||c<0x0)throw new Error('Invalid\x20staleAgeSec');return createServer(async(d,e)=>{try{if(d['method']!=='GET'){e['setHeader']('Allow','GET'),json(e,0x195,{'error':{'code':'METHOD_NOT_ALLOWED','message':'GET\x20required'}});return;}const f=new URL(d['url']??'/','http://localhost');if(f['pathname']==='/v1/status'){const [g,h,i,j,k,l]=await Promise['all']([a['projection']['status'](a['chainId']),a['sync']['status'](a['chainId']),a['projection']['watermarks'](a['chainId']),a['head']?a['head']['read']():Promise['resolve'](null),a['sync']['cdcCursors'](a['chainId']),a['projection']['quarantineQueue'](a['chainId'])]);let m=g['max_checkpoint'],n=g['observed_at'];for(const p of h){if(p['state']!=='complete'||!p['checkpoint'])continue;(m===null||BigInt(p['checkpoint'])>BigInt(m))&&(m=p['checkpoint']);const r=p['updatedAt'];r&&(n===null||Date['parse'](r)>Date['parse'](n))&&(n=r);}let o=null;if(j?.['checkpoint']!==null&&j?.['checkpoint']!==undefined&&m!==null){const s=BigInt(j['checkpoint'])-BigInt(m),t=n===null?null:Math['max'](0x0,Math['floor']((Date['now']()-Date['parse'](n))/0x3e8));o={'head_checkpoint':j['checkpoint'],'projection_checkpoint':m,'head_lag':(s>0x0n?s:0x0n)['toString'](),'projection_age_seconds':t,'version_checkpoint':g['max_checkpoint'],'version_observed_at':g['observed_at'],'stale':b>0x0&&s>BigInt(b)||c>0x0&&t!==null&&t>c};}json(e,0xc8,{'chain_id':a['chainId'],'read_only':!![],'generated_at':new Date()['toISOString'](),'projection':g,'sync':h,'watermarks':i,'head':j,'freshness':o,'cdc':k['map'](u=>({...u,'behind_head':j?.['checkpoint']===null||j?.['checkpoint']===undefined?null:((()=>{const v=BigInt(j['checkpoint'])-BigInt(u['checkpoint']);return(v>0x0n?v:0x0n)['toString']();})())})),'quarantine':{'blocking':l['filter'](u=>u['blocking'])['length'],'entries':l}});return;}if(f['pathname']==='/v1/objects'){const u=f['searchParams']['get']('kind')??undefined;if(u&&!(u in WOW_OBJECT_TYPE_TAGS)){badRequest(e,'Unknown\x20object\x20kind:\x20'+u);return;}const v=f['searchParams']['get']('cursor')??undefined;if(v)try{wowAddressToBytes(v);}catch{badRequest(e,'Invalid\x20object\x20cursor');return;}const w=f['searchParams']['get']('limit'),x=w===null?undefined:Number(w);if(x!==undefined&&(!Number['isInteger'](x)||x<0x1||x>0x3e8)){badRequest(e,'limit\x20must\x20be\x20an\x20integer\x20between\x201\x20and\x201000');return;}const y=f['searchParams']['get']('shard_count'),z=f['searchParams']['get']('shard_index');if(y===null!==(z===null)){badRequest(e,'shard_count\x20and\x20shard_index\x20must\x20be\x20provided\x20together');return;}const A=y===null||z===null?undefined:{'count':Number(y),'index':Number(z)};if(A&&(!Number['isInteger'](A['count'])||A['count']<0x1||!Number['isInteger'](A['index'])||A['index']<0x0||A['index']>=A['count'])){badRequest(e,'Invalid\x20shard\x20selector');return;}const B=await a['projection']['listCurrent']({'chainId':a['chainId'],'kind':u,'cursor':v,'limit':x,'shard':A});json(e,0xc8,{'chain_id':a['chainId'],'generated_at':new Date()['toISOString'](),...B});return;}if(f['pathname']==='/v1/edges'){const C=f['searchParams']['get']('src'),D=f['searchParams']['get']('dst');if(C===null===(D===null)){badRequest(e,'Provide\x20exactly\x20one\x20of\x20src\x20or\x20dst');return;}const E=C??D;try{wowAddressToBytes(E);}catch{badRequest(e,'Invalid\x20object\x20address');return;}const F=C!==null?await a['projection']['edgesFrom'](a['chainId'],E):await a['projection']['edgesTo'](a['chainId'],E);json(e,0xc8,{'chain_id':a['chainId'],'generated_at':new Date()['toISOString'](),'direction':C!==null?'out':'in','object_id':E['toLowerCase'](),'edges':F,'orphan_count':F['filter'](G=>!G['dstProjected'])['length']});return;}if(f['pathname']==='/v1/match'){const G=f['searchParams']['get']('kind');if(G!=='Service'&&G!=='Demand'){badRequest(e,'kind\x20must\x20be\x20\x27Service\x27\x20or\x20\x27Demand\x27');return;}const H=f['searchParams']['get']('q')??undefined,I=f['searchParams']['get']('location')??undefined,J=f['searchParams']['get']('industry')??undefined;let K;const L=f['searchParams']['get']('budget');if(L!==null){K=parseWowToWei(L)??undefined;if(K===undefined){badRequest(e,'budget\x20must\x20be\x20a\x20non-negative\x20decimal\x20WOW\x20amount\x20(max\x209\x20fractional\x20digits)');return;}}let M;const N=f['searchParams']['get']('capabilities');if(N!==null){M=N['split'](',')['map'](a0=>a0['trim']())['filter'](a0=>a0['length']>0x0);const Z=M['filter'](a0=>!KNOWN_CAPABILITIES['includes'](a0));if(Z['length']>0x0){badRequest(e,'Unknown\x20capability:\x20'+Z['join'](',\x20')+'\x20(known:\x20'+KNOWN_CAPABILITIES['join'](',\x20')+')');return;}}let O=0x14;const P=f['searchParams']['get']('limit');if(P!==null){O=parsePositiveInt(P)??-0x1;if(!Number['isInteger'](O)||O<0x1||O>0x64){badRequest(e,'limit\x20must\x20be\x20an\x20integer\x20between\x201\x20and\x20100');return;}}let Q=0xc8;const R=f['searchParams']['get']('recall_limit');if(R!==null){Q=parsePositiveInt(R)??-0x1;if(!Number['isInteger'](Q)||Q<0x1||Q>0x3e8){badRequest(e,'recall_limit\x20must\x20be\x20an\x20integer\x20between\x201\x20and\x201000');return;}}const S=f['searchParams']['get']('include_payload');let T=![];if(S!==null){if(S==='1'||S==='true')T=!![];else{if(S!=='0'&&S!=='false'){badRequest(e,'include_payload\x20must\x20be\x20one\x20of\x201,\x20true,\x200,\x20false');return;}}}const U={'kind':G,'q':H,'location':I,'industry':J,'budgetWei':K,'capabilities':M,'limit':O,'recallLimit':Q},[V,W]=await Promise['all']([a['projection']['activeFacets'](a['chainId'],G),a['projection']['status'](a['chainId'])]),X=runMatch(V,U);let Y=X['candidates'];if(T&&Y['length']>0x0){const a0=await a['projection']['currentPayloads'](a['chainId'],Y['map'](a1=>a1['object_id']));Y=Y['map'](a1=>({...a1,'payload_json':a0['get'](a1['object_id'])??null}));}json(e,0xc8,{'chain_id':a['chainId'],'generated_at':new Date()['toISOString'](),'coverage':W['coverage'],...X,'candidates':Y});return;}json(e,0x194,{'error':{'code':'NOT_FOUND','message':'Unknown\x20endpoint'}});}catch{json(e,0x1f4,{'error':{'code':'INTERNAL_ERROR','message':'Index\x20query\x20failed'}});}});}
@@ -1,6 +1,6 @@
1
1
  import { type WowTypedObjectKind } from "@wowok/wowok";
2
2
  import { Pool } from "pg";
3
- import type { ApplyProjectionResult, CurrentObjectPage, GraphEdgeView, ObjectFacetRow, ObjectVersionFact, ProjectionStatus, ProjectionWatermark, RecordReconciliationOptions, RecordReconciliationResult, ReconciliationGeneration } from "./types.js";
3
+ import type { ApplyProjectionResult, CurrentObjectPage, GraphEdgeView, ObjectFacetRow, ObjectVersionFact, ProjectionStatus, ProjectionWatermark, QuarantineEntry, RecordReconciliationOptions, RecordReconciliationResult, ReconciliationGeneration } from "./types.js";
4
4
  export interface ListCurrentObjectsOptions {
5
5
  chainId: string;
6
6
  kind?: WowTypedObjectKind;
@@ -45,5 +45,6 @@ export declare class PostgresProjectionStore {
45
45
  private reconciledThrough;
46
46
  status(chainId: string): Promise<ProjectionStatus>;
47
47
  watermarks(chainId: string): Promise<ProjectionWatermark[]>;
48
+ quarantineQueue(chainId: string, limit?: number): Promise<QuarantineEntry[]>;
48
49
  listCurrent(options: ListCurrentObjectsOptions): Promise<CurrentObjectPage>;
49
50
  }