@wowok/agent-mcp 3.0.3 → 3.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (300) hide show
  1. package/dist/evaluation/path-reasoning.d.ts +4 -2
  2. package/dist/evaluation/path-reasoning.js +1 -1
  3. package/dist/extensions/constraint-registry.d.ts +2 -2
  4. package/dist/extensions/constraint-registry.js +1 -1
  5. package/dist/extensions/custom-registry-file.d.ts +22 -0
  6. package/dist/extensions/custom-registry-file.js +1 -0
  7. package/dist/extensions/index.d.ts +2 -1
  8. package/dist/extensions/index.js +1 -1
  9. package/dist/extensions/industry-pack.d.ts +7 -0
  10. package/dist/extensions/industry-pack.js +1 -1
  11. package/dist/extensions/metric-registry.d.ts +2 -2
  12. package/dist/extensions/metric-registry.js +1 -1
  13. package/dist/extensions/modes.js +1 -1
  14. package/dist/extensions/registry.d.ts +2 -2
  15. package/dist/extensions/registry.js +1 -1
  16. package/dist/extensions/types.d.ts +4 -0
  17. package/dist/goal/GoalEngine.d.ts +13 -1
  18. package/dist/goal/GoalEngine.js +1 -1
  19. package/dist/goal/next-steps.d.ts +12 -0
  20. package/dist/goal/next-steps.js +1 -0
  21. package/dist/goal/pursue.d.ts +18 -0
  22. package/dist/goal/pursue.js +1 -0
  23. package/dist/goal/types.d.ts +72 -0
  24. package/dist/goal/types.js +1 -1
  25. package/dist/graph/onchain/analyze.d.ts +44 -0
  26. package/dist/graph/onchain/analyze.js +1 -0
  27. package/dist/graph/onchain/analyze.spec.d.ts +1 -0
  28. package/dist/graph/onchain/analyze.spec.js +1 -0
  29. package/dist/graph/onchain/anti-cheat.d.ts +39 -0
  30. package/dist/graph/onchain/anti-cheat.js +1 -0
  31. package/dist/graph/onchain/anti-cheat.spec.d.ts +1 -0
  32. package/dist/graph/onchain/anti-cheat.spec.js +1 -0
  33. package/dist/graph/onchain/dataplane.d.ts +44 -0
  34. package/dist/graph/onchain/dataplane.js +1 -0
  35. package/dist/graph/onchain/edge-schema.d.ts +60 -0
  36. package/dist/graph/onchain/edge-schema.js +1 -0
  37. package/dist/graph/onchain/expand.d.ts +4 -0
  38. package/dist/graph/onchain/expand.js +1 -0
  39. package/dist/graph/onchain/extract.d.ts +21 -0
  40. package/dist/graph/onchain/extract.js +1 -0
  41. package/dist/graph/onchain/index.d.ts +17 -0
  42. package/dist/graph/onchain/index.js +1 -0
  43. package/dist/graph/onchain/interest.d.ts +10 -0
  44. package/dist/graph/onchain/interest.js +1 -0
  45. package/dist/graph/onchain/interest.spec.d.ts +1 -0
  46. package/dist/graph/onchain/interest.spec.js +1 -0
  47. package/dist/graph/onchain/onchain.spec.d.ts +1 -0
  48. package/dist/graph/onchain/onchain.spec.js +1 -0
  49. package/dist/graph/onchain/order-status.d.ts +53 -0
  50. package/dist/graph/onchain/order-status.js +1 -0
  51. package/dist/graph/onchain/project-relationship.d.ts +3 -0
  52. package/dist/graph/onchain/project-relationship.js +1 -0
  53. package/dist/graph/onchain/sdk-batch.d.ts +117 -0
  54. package/dist/graph/onchain/sdk-batch.js +1 -0
  55. package/dist/graph/onchain/sdk-dataplane.d.ts +40 -0
  56. package/dist/graph/onchain/sdk-dataplane.js +1 -0
  57. package/dist/graph/onchain/strategy.d.ts +54 -0
  58. package/dist/graph/onchain/strategy.js +1 -0
  59. package/dist/graph/onchain/strategy.spec.d.ts +1 -0
  60. package/dist/graph/onchain/strategy.spec.js +1 -0
  61. package/dist/graph/onchain/types.d.ts +238 -0
  62. package/dist/graph/onchain/types.js +1 -0
  63. package/dist/graph/onchain/viewport.d.ts +5 -0
  64. package/dist/graph/onchain/viewport.js +1 -0
  65. package/dist/harness/recover.js +1 -1
  66. package/dist/index.js +1 -1
  67. package/dist/intent/enrich.js +1 -1
  68. package/dist/keeper/detectors.d.ts +1 -1
  69. package/dist/keeper/detectors.js +1 -1
  70. package/dist/knowledge/account-marks.js +1 -1
  71. package/dist/knowledge/anti-cheat.d.ts +2 -37
  72. package/dist/knowledge/anti-cheat.js +1 -1
  73. package/dist/knowledge/contract-invariants.js +1 -1
  74. package/dist/knowledge/event-semantics.js +1 -1
  75. package/dist/knowledge/getting-started.d.ts +37 -0
  76. package/dist/knowledge/getting-started.js +1 -0
  77. package/dist/knowledge/goal-completion.js +1 -1
  78. package/dist/knowledge/guard-puzzle.js +1 -1
  79. package/dist/knowledge/guard-render.d.ts +1 -0
  80. package/dist/knowledge/guard-render.js +1 -1
  81. package/dist/knowledge/guard-submission-brief.d.ts +83 -0
  82. package/dist/knowledge/guard-submission-brief.js +1 -0
  83. package/dist/knowledge/guard-submission-prompt.d.ts +13 -0
  84. package/dist/knowledge/guard-submission-prompt.js +1 -1
  85. package/dist/knowledge/index.d.ts +6 -4
  86. package/dist/knowledge/index.js +1 -1
  87. package/dist/knowledge/industry-registry.js +1 -1
  88. package/dist/knowledge/industry-strategy.d.ts +91 -0
  89. package/dist/knowledge/industry-strategy.js +1 -0
  90. package/dist/knowledge/jsonrpc-enum.js +1 -1
  91. package/dist/knowledge/market-metrics.d.ts +14 -3
  92. package/dist/knowledge/market-metrics.js +1 -1
  93. package/dist/knowledge/migration-preflight.js +1 -1
  94. package/dist/knowledge/operation-dictionary.d.ts +1 -1
  95. package/dist/knowledge/safety-rules.js +1 -1
  96. package/dist/knowledge/scenario-topology.d.ts +6 -1
  97. package/dist/knowledge/scenario-topology.js +1 -1
  98. package/dist/knowledge/service-ledger.js +1 -1
  99. package/dist/knowledge/service-risk-node.d.ts +3 -0
  100. package/dist/knowledge/service-risk-node.js +1 -0
  101. package/dist/knowledge/service-risk.d.ts +2 -0
  102. package/dist/knowledge/service-risk.js +1 -1
  103. package/dist/knowledge/service-templates.d.ts +2 -0
  104. package/dist/knowledge/service-templates.js +1 -1
  105. package/dist/knowledge/strategy-manuals.d.ts +17 -0
  106. package/dist/knowledge/strategy-manuals.js +1 -0
  107. package/dist/knowledge/supply-chain.d.ts +3 -1
  108. package/dist/knowledge/supply-chain.js +1 -1
  109. package/dist/knowledge/template-registry.js +1 -1
  110. package/dist/knowledge/tools-reference.js +1 -1
  111. package/dist/knowledge/workflow-guidance.d.ts +3 -118
  112. package/dist/knowledge/workflow-guidance.js +1 -1
  113. package/dist/knowledge/workspace-lists.js +1 -1
  114. package/dist/monitor/MonitorLoop.js +1 -1
  115. package/dist/monitor/ScopeResolver.js +1 -1
  116. package/dist/participation/radar-core.d.ts +15 -15
  117. package/dist/participation/radar-core.js +1 -1
  118. package/dist/persona/analyzer.d.ts +2 -1
  119. package/dist/persona/bridge.d.ts +5 -1
  120. package/dist/persona/bridge.js +1 -1
  121. package/dist/persona/defaults.js +1 -1
  122. package/dist/persona/distill-goal.d.ts +7 -1
  123. package/dist/persona/distill-goal.js +1 -1
  124. package/dist/persona/index.d.ts +13 -3
  125. package/dist/persona/index.js +1 -1
  126. package/dist/persona/model.d.ts +12 -2
  127. package/dist/persona/model.js +1 -1
  128. package/dist/persona/overrides.d.ts +1 -0
  129. package/dist/persona/overrides.js +1 -1
  130. package/dist/persona/topology-focus.d.ts +29 -0
  131. package/dist/persona/topology-focus.js +1 -0
  132. package/dist/persona/types.d.ts +81 -0
  133. package/dist/playbooks/service-build/business-puzzle.js +1 -1
  134. package/dist/playbooks/service-build/context-assembly.js +1 -1
  135. package/dist/playbooks/service-build/machine-nodes.js +1 -1
  136. package/dist/playbooks/service-build/machine-panorama.js +1 -1
  137. package/dist/playbooks/service-build/object-panorama.js +1 -1
  138. package/dist/playbooks/service-build/participation-radar.js +1 -1
  139. package/dist/playbooks/service-build/relationship-profile.d.ts +1 -0
  140. package/dist/playbooks/service-build/relationship-profile.js +1 -1
  141. package/dist/playbooks/service-build/service-panorama.d.ts +4 -0
  142. package/dist/playbooks/service-build/service-panorama.js +1 -1
  143. package/dist/playbooks/service-build/topology-query.d.ts +14 -0
  144. package/dist/playbooks/service-build/topology-query.js +1 -0
  145. package/dist/role/index.d.ts +1 -0
  146. package/dist/role/index.js +1 -1
  147. package/dist/role/profiles.d.ts +26 -0
  148. package/dist/role/profiles.js +1 -0
  149. package/dist/safety/confirm-gate.d.ts +4 -1
  150. package/dist/safety/confirm-gate.js +1 -1
  151. package/dist/schema/call/allocation.d.ts +11 -6
  152. package/dist/schema/call/arbitration.d.ts +5 -0
  153. package/dist/schema/call/base.d.ts +5 -0
  154. package/dist/schema/call/base.js +1 -1
  155. package/dist/schema/call/bridge.d.ts +26 -1
  156. package/dist/schema/call/contact.d.ts +5 -0
  157. package/dist/schema/call/demand.d.ts +5 -0
  158. package/dist/schema/call/guard.d.ts +35 -20
  159. package/dist/schema/call/machine.d.ts +10 -0
  160. package/dist/schema/call/order.d.ts +5 -0
  161. package/dist/schema/call/payment.d.ts +5 -0
  162. package/dist/schema/call/permission.d.ts +5 -0
  163. package/dist/schema/call/personal.d.ts +5 -0
  164. package/dist/schema/call/progress.d.ts +5 -0
  165. package/dist/schema/call/proof.d.ts +10 -0
  166. package/dist/schema/call/repository.d.ts +5 -0
  167. package/dist/schema/call/repository.js +1 -1
  168. package/dist/schema/call/reward.d.ts +5 -0
  169. package/dist/schema/call/semantic.js +1 -1
  170. package/dist/schema/call/service.d.ts +9 -4
  171. package/dist/schema/call/treasury.d.ts +5 -0
  172. package/dist/schema/common/index.js +1 -1
  173. package/dist/schema/employee/index.d.ts +7 -7
  174. package/dist/schema/evaluation/index.d.ts +22 -9
  175. package/dist/schema/evaluation/index.js +1 -1
  176. package/dist/schema/goal/index.d.ts +37 -1
  177. package/dist/schema/goal/index.js +1 -1
  178. package/dist/schema/goal/planning.d.ts +1 -1
  179. package/dist/schema/index.d.ts +2 -0
  180. package/dist/schema/index.js +1 -1
  181. package/dist/schema/industry-pack/index.d.ts +7 -0
  182. package/dist/schema/industry-pack/index.js +1 -1
  183. package/dist/schema/interaction/index.d.ts +34 -0
  184. package/dist/schema/interaction/index.js +1 -0
  185. package/dist/schema/local/index.d.ts +8 -4
  186. package/dist/schema/local/index.js +1 -1
  187. package/dist/schema/messenger/index.d.ts +324 -64
  188. package/dist/schema/messenger/index.js +1 -1
  189. package/dist/schema/operations.d.ts +236 -11
  190. package/dist/schema/operations.js +1 -1
  191. package/dist/schema/persona/index.d.ts +15743 -0
  192. package/dist/schema/persona/index.js +1 -1
  193. package/dist/schema/query/bi.d.ts +869 -2
  194. package/dist/schema/query/bi.js +1 -1
  195. package/dist/schema/query/index.d.ts +163 -41
  196. package/dist/schema/query/index.js +1 -1
  197. package/dist/schema/schema-query/index.d.ts +16 -0
  198. package/dist/schema/schema-query/index.js +1 -1
  199. package/dist/schema/schema-version.js +1 -1
  200. package/dist/schema/strategy-review/index.d.ts +137 -0
  201. package/dist/schema/strategy-review/index.js +1 -0
  202. package/dist/schema/trust/index.d.ts +6 -6
  203. package/dist/schema/workflow/index.d.ts +2 -2
  204. package/dist/schema-query-impl/index.js +1 -1
  205. package/dist/schemas/account_operation.output.json +8 -4
  206. package/dist/schemas/account_operation.schema.json +6 -2
  207. package/dist/schemas/ask_user.output.json +54 -0
  208. package/dist/schemas/ask_user.schema.json +78 -0
  209. package/dist/schemas/bridge_operation.schema.json +50 -5
  210. package/dist/schemas/evaluation_operation.output.json +24 -0
  211. package/dist/schemas/goal_operation.schema.json +124 -0
  212. package/dist/schemas/guard2file.schema.json +10 -1
  213. package/dist/schemas/index.json +13 -1
  214. package/dist/schemas/industry_pack_operation.output.json +39 -0
  215. package/dist/schemas/local_mark_operation.schema.json +2 -2
  216. package/dist/schemas/machineNode2file.schema.json +10 -1
  217. package/dist/schemas/messenger_operation.output.json +678 -200
  218. package/dist/schemas/messenger_operation.schema.json +74 -239
  219. package/dist/schemas/onchain_events.output.json +2 -2
  220. package/dist/schemas/onchain_operations.schema.json +183 -21
  221. package/dist/schemas/onchain_operations_allocation.schema.json +10 -1
  222. package/dist/schemas/onchain_operations_arbitration.schema.json +10 -1
  223. package/dist/schemas/onchain_operations_contact.schema.json +10 -1
  224. package/dist/schemas/onchain_operations_demand.schema.json +10 -1
  225. package/dist/schemas/onchain_operations_gen_passport.schema.json +10 -1
  226. package/dist/schemas/onchain_operations_gen_proof.schema.json +10 -1
  227. package/dist/schemas/onchain_operations_guard.schema.json +10 -1
  228. package/dist/schemas/onchain_operations_machine.schema.json +10 -1
  229. package/dist/schemas/onchain_operations_order.schema.json +10 -1
  230. package/dist/schemas/onchain_operations_payment.schema.json +10 -1
  231. package/dist/schemas/onchain_operations_permission.schema.json +10 -1
  232. package/dist/schemas/onchain_operations_personal.schema.json +10 -1
  233. package/dist/schemas/onchain_operations_progress.schema.json +10 -1
  234. package/dist/schemas/onchain_operations_proof.schema.json +10 -1
  235. package/dist/schemas/onchain_operations_repository.schema.json +13 -4
  236. package/dist/schemas/onchain_operations_reward.schema.json +10 -1
  237. package/dist/schemas/onchain_operations_service.schema.json +10 -1
  238. package/dist/schemas/onchain_operations_treasury.schema.json +10 -1
  239. package/dist/schemas/onchain_table_data.output.json +184 -0
  240. package/dist/schemas/onchain_table_data.schema.json +43 -43
  241. package/dist/schemas/persona_operation.output.json +37778 -262
  242. package/dist/schemas/persona_operation.schema.json +5960 -1
  243. package/dist/schemas/query_toolkit.output.json +1580 -2
  244. package/dist/schemas/query_toolkit.schema.json +194 -32
  245. package/dist/schemas/schema_query.schema.json +25 -1
  246. package/dist/schemas/strategy_review_operation.output.json +532 -0
  247. package/dist/schemas/strategy_review_operation.schema.json +66 -0
  248. package/dist/schemas/wowok_buildin_info.output.json +188 -6
  249. package/dist/schemas/wowok_buildin_info.schema.json +14 -0
  250. package/dist/strategy/collectors.d.ts +66 -0
  251. package/dist/strategy/collectors.js +1 -0
  252. package/dist/strategy/collectors.spec.d.ts +1 -0
  253. package/dist/strategy/collectors.spec.js +1 -0
  254. package/dist/strategy/index.d.ts +5 -0
  255. package/dist/strategy/index.js +1 -0
  256. package/dist/strategy/metrics.d.ts +20 -0
  257. package/dist/strategy/metrics.js +1 -0
  258. package/dist/strategy/review.d.ts +48 -0
  259. package/dist/strategy/review.js +1 -0
  260. package/dist/strategy/scorecard.d.ts +32 -0
  261. package/dist/strategy/scorecard.js +1 -0
  262. package/dist/strategy/store.d.ts +26 -0
  263. package/dist/strategy/store.js +1 -0
  264. package/dist/tools/handlers/ask-user.d.ts +3 -0
  265. package/dist/tools/handlers/ask-user.js +1 -0
  266. package/dist/tools/handlers/config.js +1 -1
  267. package/dist/tools/handlers/evaluation.js +1 -1
  268. package/dist/tools/handlers/goal.js +1 -1
  269. package/dist/tools/handlers/industry-pack.js +1 -1
  270. package/dist/tools/handlers/local.js +1 -1
  271. package/dist/tools/handlers/messenger.js +1 -1
  272. package/dist/tools/handlers/onchain.js +1 -1
  273. package/dist/tools/handlers/permission.js +1 -1
  274. package/dist/tools/handlers/persona.js +1 -1
  275. package/dist/tools/handlers/query.d.ts +6 -0
  276. package/dist/tools/handlers/query.js +1 -1
  277. package/dist/tools/handlers/schema-query.js +1 -1
  278. package/dist/tools/handlers/strategy-review.d.ts +2 -0
  279. package/dist/tools/handlers/strategy-review.js +1 -0
  280. package/dist/tools/handlers/watch.js +1 -1
  281. package/dist/tools/handlers/workflow.js +1 -1
  282. package/dist/tools/index.d.ts +5 -2
  283. package/dist/tools/index.js +1 -1
  284. package/dist/tools/registry/agent.js +1 -1
  285. package/dist/tools/registry/bridge.js +1 -1
  286. package/dist/tools/registry/business.js +1 -1
  287. package/dist/tools/registry/interaction.d.ts +2 -0
  288. package/dist/tools/registry/interaction.js +1 -0
  289. package/dist/tools/registry/local.js +1 -1
  290. package/dist/tools/registry/messenger.js +1 -1
  291. package/dist/tools/registry/monitor.js +1 -1
  292. package/dist/tools/registry/onchain.js +1 -1
  293. package/dist/tools/registry/query.js +1 -1
  294. package/dist/tools/rules-hook.js +1 -1
  295. package/dist/tools/shared.d.ts +2 -1
  296. package/dist/tools/shared.js +1 -1
  297. package/dist/tools/types.d.ts +7 -1
  298. package/dist/tools/wrap.d.ts +3 -3
  299. package/dist/tools/wrap.js +1 -1
  300. package/package.json +2 -2
@@ -0,0 +1,44 @@
1
+ import type { Analyzer, Confidence, Finding, FindingKind, FindingSeverity, NodeAnalyzer, Retention, TopoNode, ViewerRole, Viewport } from "./types.js";
2
+ export declare function pathConfidence(v: Viewport, pathEdges: Array<{
3
+ schema: string;
4
+ from: string;
5
+ truncated?: boolean;
6
+ retention: Retention;
7
+ }>): {
8
+ confidence: Confidence;
9
+ window?: {
10
+ observed: number;
11
+ limit: number;
12
+ };
13
+ };
14
+ interface ControlIndex {
15
+ controllers: Map<string, Set<string>>;
16
+ objectsByEoa: Map<string, Set<string>>;
17
+ permsOfObject: Map<string, Set<string>>;
18
+ }
19
+ export declare function buildControlIndex(v: Viewport): ControlIndex;
20
+ export declare const DEFAULT_ANALYZERS: Analyzer[];
21
+ export declare function registerAnalyzer(analyzer: Analyzer): void;
22
+ export declare function getAnalyzer(id: string): Analyzer | undefined;
23
+ export declare function listAnalyzers(): string[];
24
+ export declare function runAnalyzers(v: Viewport, opts?: {
25
+ only?: string[];
26
+ kinds?: FindingKind[];
27
+ }): Finding[];
28
+ export interface NodeRuleOutcome {
29
+ severity?: FindingSeverity;
30
+ titleZh: string;
31
+ detailZh: string;
32
+ suggestionZh: string;
33
+ roles?: ViewerRole[];
34
+ confidence?: Confidence;
35
+ }
36
+ export interface NodeRuleBinding {
37
+ id: string;
38
+ kind: FindingKind;
39
+ objectType: string;
40
+ inspect(node: TopoNode, v: Viewport): NodeRuleOutcome[];
41
+ }
42
+ export declare function adaptNodeAnalyzer(binding: NodeRuleBinding): NodeAnalyzer;
43
+ export declare function runNodeAnalyzers(v: Viewport, analyzers: NodeAnalyzer[]): Finding[];
44
+ export {};
@@ -0,0 +1 @@
1
+ import{detectFakeOrders,detectShellMerchant}from'./anti-cheat.js';import{orderCompletionInGraph}from'./expand.js';function root(a){const b=a?.['raw'],c=b?.['data']??b;return c&&typeof c==='object'?c:undefined;}function str(a){return typeof a==='string'&&a!=='0x0'?a:undefined;}function big(a){if(a==null)return 0x0n;try{return BigInt(typeof a==='number'?Math['trunc'](a):String(a));}catch{return 0x0n;}}function bool(a){return a===!![]||a===0x1||a==='1';}function asList(a){return Array['isArray'](a)?a:[];}function wfNodeName(a){const b=a['indexOf']('::node::');return b>=0x0?a['slice'](b+'::node::'['length']):a;}function wfMachineOf(a){const b=a['indexOf']('::node::');return b>=0x0?a['slice'](0x0,b):'';}function typedNodes(a,b){const c=[];for(const d of a['visibleNodes']){const e=a['graph']['nodes']['get'](d);if(e?.['kind']==='object'&&e['objectType']===b&&e['raw'])c['push'](e);}return c;}function edgeList(a,b){return a['visibleEdges']['filter'](c=>c['schema']===b);}function out(a,b,c){return a['visibleEdges']['filter'](d=>d['from']===b['toLowerCase']()&&d['schema']===c);}function inc(a,b,c){return a['visibleEdges']['filter'](d=>d['to']===b['toLowerCase']()&&d['schema']===c);}const RETENTION_RANK={'complete':0x0,'bounded_exact':0x1,'membership':0x1,'derived':0x2,'bounded_window':0x3},WINDOW_LIMIT=0x1450;export function pathConfidence(a,b){let c=0x0,d=![];for(const g of b){c=Math['max'](c,RETENTION_RANK[g['retention']]??0x0);if(g['retention']==='bounded_window'||g['truncated'])d=!![];}if(d){let h=0x0;for(const i of b){if(i['retention']!=='bounded_window'&&!i['truncated'])continue;const j=a['visibleEdges']['filter'](l=>l['schema']===i['schema']&&l['from']===i['from'])['length'];h=Math['max'](h,j);const k=a['graph']['truncations']['find'](l=>l['nodeId']===i['from']&&l['schema']===i['schema']);if(k)h=Math['max'](h,k['observed']);}return{'confidence':'windowed','window':{'observed':h||b['length'],'limit':WINDOW_LIMIT}};}const f=c===0x0?'exact':c===0x2?'derived':'bounded';return{'confidence':f};}function makeFinding(a,b,c,d,e){const {confidence:f,window:g}=pathConfidence(a,e['pathEdges']??[]);return{'id':b,'kind':c,'severity':e['severity']??'info','titleZh':d,'path':e['path'],'confidence':f,...g?{'window':g}:{},'roles':e['roles']??['neutral'],'detailZh':e['detailZh'],'suggestionZh':e['suggestionZh']};}const MAX_FINDINGS_PER_RULE=0x14,ROLE_OWNER_OR_ADMIN=0x1|0x2;export function buildControlIndex(a){const b=new Map(),c=new Map(),d=new Map(),f=(h,i,j)=>{const l=h['get'](i)??new Set();l['add'](j),h['set'](i,l);},g=new Map();for(const h of edgeList(a,'eoa.permission')){const i=typeof h['payload']?.['roleBits']==='number'?h['payload']['roleBits']:ROLE_OWNER_OR_ADMIN;if((i&ROLE_OWNER_OR_ADMIN)===0x0)continue;f(g,h['from'],h['to']);}for(const j of edgeList(a,'permission.core_binding')){const k=a['graph']['nodes']['get'](j['to']);if(!k||k['kind']!=='object')continue;f(d,j['to'],j['from']);for(const [l,m]of g){if(!m['has'](j['from']))continue;f(b,j['to'],l),f(c,l,j['to']);}}return{'controllers':b,'objectsByEoa':c,'permsOfObject':d};}function machineViews(a){const b=new Map();for(const d of edgeList(a,'wf.transition')){const f=wfMachineOf(d['from']);if(!f)continue;const g=b['get'](f)??[];g['push'](d),b['set'](f,g);}const c=[];for(const [h,i]of b){const j=a['graph']['nodes']['get'](h);if(!j||!a['visibleNodes']['has'](h))continue;const k=new Set([...(function*(){const l=new Set(i['map'](p=>String(p['payload']?.['node']??''))['filter'](Boolean)),o=new Set(i['map'](p=>String(p['payload']?.['prevNode']??''))['filter'](Boolean));for(const p of l)if(!o['has'](p))yield p;}())]);c['push']({'machine':j,'transitions':i,'terminals':k});}return c;}const ROLES_RISK_NEUTRAL_MERCHANT=['neutral','system','merchant'],R1={'id':'R1','kind':'risk','run'(b){const c=buildControlIndex(b),d=[],e=typedNodes(b,'Service'),f=typedNodes(b,'Arbitration');o:for(const g of e){const h=c['controllers']['get'](g['id']);if(!h)continue;for(const i of f){const j=c['controllers']['get'](i['id']);if(!j)continue;const k=c['permsOfObject']['get'](g['id']),l=c['permsOfObject']['get'](i['id']),m=[...k??[]]['some'](n=>l?.['has'](n));if(m)continue;for(const n of h){if(!j['has'](n))continue;d['push'](makeFinding(b,'R1:'+g['id']+':'+i['id']+':'+n,'risk','同裁风险:店铺与仲裁服务受同一实控\x20EOA\x20支配',{'severity':'high','path':[n,'eoa.permission','permission.core_binding',g['id'],i['id']],'pathEdges':edgeList(b,'permission.core_binding'),'roles':['neutral','system','merchant','arbitrator'],'detailZh':'EOA\x20'+n+'\x20同时以\x20owner/admin\x20身份控制\x20Service\x20'+g['id']+'\x20与\x20Arbitration\x20'+i['id']+','+'且二者挂接在不同\x20Permission\x20下(E33\x20只禁止同一\x20Permission,未禁跨组同裁)。'+'该\x20EOA\x20在结构上可以同时影响被裁店铺与裁决结果。','suggestionZh':'核查该\x20EOA\x20的实控关系;要求店铺与仲裁服务的\x20owner/admin\x20集合互不相交,或将该仲裁服务移出可选列表。'}));if(d['length']>=MAX_FINDINGS_PER_RULE)break o;}}}return d;}},R2={'id':'R2','kind':'risk','run'(a){const b=[];for(const c of typedNodes(a,'Service')){const f=root(c),g=out(a,c['id'],'service.order');if(g['length']===0x0)continue;let h=0x0n,i=0x0;for(const l of g){const m=root(a['graph']['nodes']['get'](l['to']));if(!m)continue;h+=big(m['amount']),i++;}if(i===0x0)continue;const j=big(f['compensation_fund']),k=h*0x3n;if(j>=k)continue;b['push'](makeFinding(a,'R2:'+c['id'],'risk','赔付敞口:补偿基金低于窗口订单额的\x203\x20倍上限',{'severity':j<h?'high':'medium','path':[c['id'],'service.order','Order.amount','Service.compensation_fund'],'pathEdges':g,'roles':['neutral','system','merchant','buyer'],'detailZh':'补偿基金\x20'+j+'\x20基准单位,窗口内\x20'+i+'\x20笔订单金额合计\x20'+h+','+('法定赔付封顶为单笔\x203×amount\x20的结构总敞口\x20'+k+'(arb.move:302-321)。'),'suggestionZh':'补足\x20compensation_fund\x20至窗口金额\x203\x20倍以上,或在窗口内降低未结订单规模。'}));if(b['length']>=MAX_FINDINGS_PER_RULE)break;}return b;}},CONTROL_TYPES=new Set(['Service','Machine','Treasury']),CONTROL_FANOUT_ALERT=0x3,R3={'id':'R3','kind':'risk','run'(a){const b=buildControlIndex(a),c=[];for(const [d,e]of b['objectsByEoa']){const f=[...e]['filter'](i=>CONTROL_TYPES['has'](a['graph']['nodes']['get'](i)?.['objectType']??''));if(f['length']<CONTROL_FANOUT_ALERT)continue;const g=f['filter'](i=>a['graph']['nodes']['get'](i)?.['objectType']==='Service'),h=g['reduce']((i,j)=>i+out(a,j,'service.order')['length'],0x0);c['push'](makeFinding(a,'R3:'+d,'risk','权限集中:单个\x20EOA\x20控制多个经营核心对象',{'severity':f['length']>=0x5?'medium':'low','path':[d,'eoa.permission','permission.core_binding'],'pathEdges':edgeList(a,'eoa.permission')['concat'](edgeList(a,'permission.core_binding')),'roles':ROLES_RISK_NEUTRAL_MERCHANT,'detailZh':'EOA\x20'+d+'\x20通过\x20owner/admin\x20权限控制\x20'+f['length']+'\x20个\x20Service/Machine/Treasury\x20对象'+('(其中\x20Service\x20'+g['length']+'\x20个,窗口内可见订单\x20'+h+'\x20笔),经营规模与权限分散度不匹配。'),'suggestionZh':'将日常运营权限下放给独立\x20admin/entity\x20角色,owner\x20仅保留紧急处置;核心对象避免同组挂接。'}));if(c['length']>=MAX_FINDINGS_PER_RULE)break;}return c;}},R4={'id':'R4','kind':'risk','run'(a){const b=[];p:for(const c of machineViews(a)){const d=new Map();for(const g of c['transitions']){if(!c['terminals']['has'](String(g['payload']?.['node']??'')))continue;const h=g['from']+'→'+g['to'],i=d['get'](h)??[];i['push'](g),d['set'](h,i);}for(const [j,k]of d){const l=new Set();let m=![];for(const n of k){if(str(n['payload']?.['namedOperator']))l['add']('name:'+n['payload']['namedOperator']);if(typeof n['payload']?.['permissionIndex']==='number')l['add']('perm:'+n['payload']['permissionIndex']);if(str(n['payload']?.['guard']))m=!![];}if(l['size']===0x1&&!m){const o=[...l][0x0];b['push'](makeFinding(a,'R4:'+c['machine']['id']+':'+j,'risk','流程单点:终态前\x20Forward\x20仅唯一操作方且无替补\x20Guard',{'severity':'medium','path':[c['machine']['id'],'machine.node','wf.transition',j],'pathEdges':k,'roles':['neutral','system','merchant','collaborator'],'detailZh':'Machine\x20'+c['machine']['id']+'\x20进入终态\x20'+wfNodeName(k[0x0]['to'])+'\x20的路径\x20'+j+'\x20上,'+('唯一可执行操作方为\x20'+o+',且所有\x20Forward\x20均无\x20guard\x20兜底;该操作方离线即流程卡死。'),'suggestionZh':'为该\x20Forward\x20增加\x20permissionIndex\x20备选或挂接\x20guard\x20自动推进条件,避免单人阻断终态。'}));if(b['length']>=MAX_FINDINGS_PER_RULE)break p;}}}return b;}},R5={'id':'R5','kind':'risk','run'(a){const b=[],c=new Set();for(const d of a['graph']['truncations']){if(!a['visibleNodes']['has'](d['nodeId']))continue;const e=d['nodeId']+'|'+d['schema'];if(c['has'](e))continue;c['add'](e),b['push']({'id':'R5:'+e,'kind':'risk','severity':'info','titleZh':'窗口截断:相关结论仅为\x20≤5200\x20FIFO/环形窗口内下界','path':[d['nodeId'],d['schema']],'confidence':'windowed','window':{'observed':d['observed'],'limit':d['limit']??WINDOW_LIMIT},'roles':['neutral','system','merchant','buyer','supplier','arbitrator','collaborator'],'detailZh':'节点\x20'+d['nodeId']+'\x20的\x20'+d['schema']+'\x20扇出被截断(已观测\x20'+d['observed']+',窗口上限\x20'+(d['limit']??WINDOW_LIMIT)+');'+'依赖该路径的任何结论都必须表述为\x22窗口内/至少\x22,不得当作全量真值。','suggestionZh':'需要全量结论时改走事件通道(channel\x20D)或在预算内放大\x20perKindCaps。'});if(b['length']>=MAX_FINDINGS_PER_RULE)break;}return b;}},R6={'id':'R6','kind':'risk','run'(a){const b=[];for(const c of typedNodes(a,'Service')){const e=root(c);if(!bool(e['bPublished']))continue;if(big(e['setting_lock_duration'])!==0x0n)continue;b['push'](makeFinding(a,'R6:'+c['id'],'risk','设置锁缺失:已发布\x20Service\x20的\x20setting_lock_duration=0',{'severity':'medium','path':[c['id'],'Service.setting_lock_duration'],'roles':ROLES_RISK_NEUTRAL_MERCHANT['concat']('buyer'),'detailZh':'Service\x20'+c['id']+'\x20已发布但\x20setting_lock_duration=0:order_allocators\x20/\x20rewards\x20/\x20arbitrations\x20/\x20machine\x20'+'与\x20compensation_fund\x20提现可被即时修改(默认锁为\x2030\x20天,service.move:38),买家面对的是可瞬变条款。','suggestionZh':'发布后设置\x20setting_lock_duration(30\x20天=2592000000\x20毫秒起),条款变更必须经过等待期。'}));if(b['length']>=MAX_FINDINGS_PER_RULE)break;}return b;}},RATE_BASIS=0x2710n;function allocationStructuralIssues(a){const b=[];let c=0x0,d=![];for(const e of asList(a)){const f=e??{};let g=0x0n,h=![];for(const i of asList(f['sharing'])){const j=i??{},k=Number(j['mode']);if(k===0x2||j['mode']==='Surplus'){c++,d=!![];continue;}k===0x1||j['mode']==='Rate'?g+=big(j['sharing']):h=!![];}g!==0x0n&&g!==RATE_BASIS&&!d&&b['push']('存在\x20Rate\x20分账合计\x20'+g+'\x20≠\x2010000\x20基点且无\x20Surplus\x20兜底,支付时将中止'),h&&(f['max']==null||big(f['max'])===0x0n)&&b['push']('定额(Amount)分账\x20Allocator\x20缺少\x20max\x20上限,guard\x20触发时存在超额划出空间');}if(c>0x1)b['push']('Surplus\x20条目\x20'+c+'\x20个(合法至多\x201\x20个),多余收益归属不确定');return[...new Set(b)];}const A1={'id':'A1','kind':'arbitrage','run'(a){const b=[],c=(e,f,g,h)=>{const i=allocationStructuralIssues(f);if(i['length']===0x0||h['has'](e))return;h['add'](e),b['push'](makeFinding(a,'A1:'+e,'arbitrage','分账结构错配:Rate/Surplus/max\x20配置存在可被触发的结构性问题',{'severity':'medium','path':[e,'allocators[].sharing'],'pathEdges':g,'roles':['neutral','system','merchant','buyer'],'detailZh':e+':'+i['join'](';')+'(allocation.move:173-200)。','suggestionZh':'Rate\x20组补齐至\x2010000\x20或配置唯一\x20Surplus;定额\x20Allocator\x20必须设置\x20max;上线前用分账预检工具回归。'}));},d=new Set();for(const e of typedNodes(a,'Allocation')){c(e['id'],root(e)['allocators'],inc(a,e['id'],'order.allocation'),d);}for(const f of typedNodes(a,'Service')){const g=root(f)['order_allocators'];if(g?.['allocators'])c(f['id'],g['allocators'],edgeList(a,'service.order_allocator_guard'),d);}return b['slice'](0x0,MAX_FINDINGS_PER_RULE);}},DISCOUNT_FIXED=0x1,THIRTY_DAYS_MS=0x1en*0x18n*0x3cn*0x3cn*0x3e8n,A2={'id':'A2','kind':'arbitrage','run'(a){const b=[];for(const c of typedNodes(a,'Discount')){const e=root(c),f=big(e['time_end'])-big(e['time_start'])>=THIRTY_DAYS_MS;if(!bool(e['transferable'])||!f)continue;if(Number(e['discount_type'])!==DISCOUNT_FIXED)continue;if(e['benchmark']!=null&&e['benchmark']!=='0')continue;b['push'](makeFinding(a,'A2:'+c['id'],'arbitrage','折扣组合:可转让\x20+\x20宽时间窗\x20+\x20无\x20benchmark\x20固定额折扣',{'severity':'low','path':[c['id'],'Discount.transferable/time_window/benchmark'],'roles':['neutral','system','merchant'],'detailZh':'Discount\x20'+c['id']+'\x20可转让、有效期\x20≥30\x20天、为固定额折扣且无\x20benchmark\x20价格校验(service.move:109-121),'+'存在囤券与转手套利空间。','suggestionZh':'缩短有效期、改为\x20RATES\x20比例折扣或增加\x20benchmark\x20\x20Guards;必要时关闭\x20transferable。'}));if(b['length']>=MAX_FINDINGS_PER_RULE)break;}return b;}},A3={'id':'A3','kind':'arbitrage','run'(a){const b=[];for(const e of typedNodes(a,'Arbitration')){const f=root(e),g=big(f['fee'])===0x0n&&!str(f['usage_guard']);g&&b['push'](makeFinding(a,'A3:'+e['id'],'arbitrage','救济成本结构:零费用\x20+\x20无使用门槛,恶意纠纷具备正期望结构条件',{'severity':'medium','path':[e['id'],'Arbitration.fee','Arbitration.usage_guard'],'roles':['neutral','system','arbitrator','merchant','buyer'],'detailZh':'Arbitration\x20'+e['id']+'\x20的\x20fee=0\x20且\x20usage_guard\x20为空;叠加赔付封顶\x203×amount、单次\x20claim、'+'30\x20天提现锁等规则(arb.move:302-358,\x20order.move:86-96),恶意发起纠纷在结构上无需前置成本。','suggestionZh':'设置非零\x20fee\x20覆盖裁决成本,或用\x20usage_guard\x20要求纠纷方持有链上参与凭证。'}));if(b['length']>=MAX_FINDINGS_PER_RULE)break;}const c=new Map();for(const h of a['visibleNodes']){const i=a['graph']['nodes']['get'](h),j=i?.['raw']?.['type_raw'];if(typeof j!=='string'||!j['includes']('::payment::CoinWrapper<'))continue;const k=j['slice'](j['indexOf']('<')+0x1,j['lastIndexOf']('>'))['trim'](),l=c['get'](k)??[];l['push'](h),c['set'](k,l);}if(c['size']>0x0){const m=[...c['keys']()]['sort']();b['push']({'id':'A3:coinwrapper','kind':'arbitrage','severity':'info','titleZh':'跨币托管审查点:图中存在\x20CoinWrapper<K>\x20托管对象','path':['payment::CoinWrapper'],'confidence':'exact','roles':['neutral','system','arbitrator','merchant'],'detailZh':'可见\x20CoinWrapper\x20托管覆盖币种:'+m['join'](',\x20')+'(对象数\x20'+[...c['values']()]['reduce']((o,p)=>o+p['length'],0x0)+')。'+'v1\x20不做行情估值;涉及救济/分账时须人工审查币种错配与脱锚风险。','suggestionZh':'核对托管币种与服务币种\x20T\x20是否一致;跨币场景补充独立汇率/预言机证据后再下结论。'});}return b['slice'](0x0,MAX_FINDINGS_PER_RULE);}},SCARCE_PRESENTERS=0x2;function demandGuardIds(a,b){const c=new Set();for(const d of out(a,b,'demand.guard'))c['add'](d['to']);return c;}function serviceGuardIds(a,b){const c=new Set();for(const f of out(a,b['id'],'service.buy_guard'))c['add'](f['to']);const d=out(a,b['id'],'service.machine')[0x0]?.['to'];if(d)for(const g of a['visibleEdges']){if(g['schema']==='wf.forward_guard'&&g['from']['startsWith'](d+'::node::'))c['add'](g['to']);}return c;}const O1={'id':'O1','kind':'opportunity','run'(a){const b=[],c=typedNodes(a,'Service');for(const d of typedNodes(a,'Demand')){const e=out(a,d['id'],'demand.presenter');if(e['length']>=SCARCE_PRESENTERS)continue;const f=demandGuardIds(a,d['id']),g=[];for(const i of c){const j=serviceGuardIds(a,i);if(f['size']===0x0||[...f]['every'](k=>j['has'](k)))g['push'](i['id']);}const h=e;b['push'](makeFinding(a,'O1:'+d['id'],'opportunity','开放需求:提案稀缺,存在结构能力匹配的供应方',{'severity':'info','path':[d['id'],'demand.presenter','demand.guard','Service'],'pathEdges':h['concat'](out(a,d['id'],'demand.guard')),'roles':['neutral','system','supplier'],'detailZh':'Demand\x20'+d['id']+'\x20当前仅\x20'+e['length']+'\x20个提案;按\x20Guard\x20结构(不解析\x20Guard\x20字节码)匹配到\x20'+(g['length']+'\x20个候选\x20Service:'+(g['slice'](0x0,0x5)['join'](',\x20')||'(图内无匹配)')+'。'),'suggestionZh':'候选供方可准备\x20present\x20证据(需求\x20Guards\x20的可通过性证明);机会结论为结构性,不构成履约能力背书。'}));if(b['length']>=MAX_FINDINGS_PER_RULE)break;}return b;}},O2={'id':'O2','kind':'opportunity','run'(a){const b=typedNodes(a,'Service'),c=typedNodes(a,'Demand');if(b['length']===0x0&&c['length']===0x0)return[];const d=b['filter'](f=>bool(root(f)['bPublished'])&&!bool(root(f)['bPaused']))['length'],e=c['filter'](f=>out(a,f['id'],'demand.presenter')['length']===0x0)['length'];return[makeFinding(a,'O2:graph','opportunity','供需密度:图内供应/开放需求统计',{'path':['Service','Demand','demand.presenter'],'pathEdges':edgeList(a,'demand.presenter'),'roles':['neutral','system','supplier','merchant'],'detailZh':'当前视角内\x20Service\x20'+b['length']+'\x20个(已发布未暂停\x20'+d+'),Demand\x20'+c['length']+'\x20个'+('(无提案的开放需求\x20'+e+')。开放需求/活跃供应比\x20=\x20')+((d>0x0?(e/d)['toFixed'](0x3):'n/a')+'。'),'suggestionZh':'比值偏高说明供给稀缺;结合类目精确匹配数(collectors\x20category_enumerated_count)判断切入品类。'})];}},O3={'id':'O3','kind':'opportunity','run'(a){const b=[];for(const c of machineViews(a)){const d=new Map();for(const g of c['transitions']){if(str(g['payload']?.['namedOperator'])||g['payload']?.['permissionIndex']!=null)continue;const h=String(g['payload']?.['forward']??g['payload']?.['prevNode']+'→'+g['payload']?.['node']);d['set'](wfNodeName(g['from'])+':'+h,g);}if(d['size']===0x0)continue;const f=[...d['values']()];b['push'](makeFinding(a,'O3:'+c['machine']['id'],'opportunity','流程空位:关键\x20Forward\x20无操作方绑定(仅\x20guard/付款方直通)',{'path':[c['machine']['id'],'machine.node','wf.transition'],'pathEdges':f,'roles':['neutral','system','supplier','collaborator','merchant'],'detailZh':'Machine\x20'+c['machine']['id']+'\x20有\x20'+d['size']+'\x20个\x20Forward\x20无\x20namedOperator/permissionIndex\x20绑定:'+([...d['keys']()]['slice'](0x0,0x8)['join'](',\x20')+'。这些位点只能由\x20guard\x20自动满足或付款交易直接推进。'),'suggestionZh':'供应方/协作者可承接这些位点的操作职责,或推动商家把隐式直通改为显式角色绑定。'}));if(b['length']>=MAX_FINDINGS_PER_RULE)break;}return b;}};function arbitrationCases(a,b){return inc(a,b,'arb.arbitration_service')['map'](c=>a['graph']['nodes']['get'](c['from']))['filter'](c=>!!c&&c['objectType']==='Arb'&&!!c['raw']);}const G1={'id':'G1','kind':'game','run'(a){const b=[];for(const e of typedNodes(a,'Arbitration')){const f=root(e),g=asList(f['voting_guard']),h=new Set(g['map'](l=>l['vote_weight']&&typeof l['vote_weight']==='object'?Object['keys'](l['vote_weight'])[0x0]:'unknown')),i=arbitrationCases(a,e['id']),j=new Map();let k=0x0;for(const l of i){for(const m of asList(root(l)['voted'])){const n=Number(m['weight']??0x0);j['set'](n,(j['get'](n)??0x0)+0x1),k++;}}b['push'](makeFinding(a,'G1:'+e['id'],'game','投票权结构:仲裁投票\x20Guard\x20配置与实际投票权重分布',{'severity':'info','path':[e['id'],'arbitration.voting_guard','arb.arbitration_service','arb.voter'],'pathEdges':out(a,e['id'],'arbitration.voting_guard')['concat'](edgeList(a,'arb.voter')),'roles':['neutral','system','arbitrator','merchant','buyer'],'detailZh':'Arbitration\x20'+e['id']+':voting_guard\x20'+(g['length']===0x0?'为空=全员可投(arbitration.move:48-59)':'权重制('+[...h]['join']('/')+')')+';'+('窗口内案件\x20'+i['length']+'\x20个、实际投票\x20'+k+'\x20人次')+(j['size']?',权重分布\x20'+[...j['entries']()]['map'](([o,p])=>'w'+o+'×'+p)['join'](',\x20'):'')+'。','suggestionZh':'全员可投适合低标的高频场景;高标的应使用权重\x20Guard;该结论只描述客观局面,打分由博弈模块完成。'}));if(b['length']>=MAX_FINDINGS_PER_RULE)break;}return b;}},G2={'id':'G2','kind':'game','run'(a){const b=[];n:for(const c of machineViews(a)){const d=out(a,c['machine']['id'],'machine.permission')[0x0]?.['to'],f=d?inc(a,d,'permission.entity')['map'](h=>({'eoa':h['to'],'bits':h['payload']?.['permIndices']??[]})):[],g=new Set();for(const h of c['transitions']){const i=String(h['payload']?.['forward']??h['payload']?.['prevNode']+'→'+h['payload']?.['node']),j=wfNodeName(h['from'])+':'+i;if(g['has'](j))continue;let k,l='';if(str(h['payload']?.['namedOperator']))k=0x1,l='namedOperator='+h['payload']['namedOperator'];else{if(h['payload']?.['permissionIndex']!=null){if(!d)continue;const m=Number(h['payload']['permissionIndex']);k=f['filter'](n=>n['bits']['includes'](m))['length'],l='permissionIndex='+m;if(k===0x0)continue;}else continue;}if(k!==0x1)continue;g['add'](j),b['push'](makeFinding(a,'G2:'+c['machine']['id']+':'+j,'game','操作权可替代池=1:敲竹杠位点',{'severity':'low','path':[c['machine']['id'],'machine.node','wf.transition',j],'pathEdges':[h],'roles':['neutral','system','collaborator','merchant','supplier'],'detailZh':'Machine\x20'+c['machine']['id']+'\x20的\x20Forward\x20'+j+'('+l+')可执行方池大小为\x201:'+'该方在流程节点上拥有不可替代的议价地位(machine.move\x20操作预检)。','suggestionZh':'增加同\x20permissionIndex\x20的备选实体或设置\x20namedOperator\x20候补;签订覆盖该位点的\x20SLA/惩罚条款。'}));if(b['length']>=MAX_FINDINGS_PER_RULE)break n;}}return b;}},G3={'id':'G3','kind':'game','run'(a){const b=[];for(const c of typedNodes(a,'Arbitration')){const e=root(c),f=asList(e['voting_guard']);b['push'](makeFinding(a,'G3:'+c['id'],'game','救济策略参数:收益/等待矩阵的结构化输入',{'severity':'info','path':[c['id'],'Arbitration.fee/usage_guard/voting_guard'],'roles':['neutral','system','arbitrator','merchant','buyer'],'detailZh':'Arbitration\x20'+c['id']+':fee='+big(e['fee'])+',usage_guard='+(str(e['usage_guard'])??'无')+',voting_guard='+f['length']+'\x20个。'+'全局结构常量:赔付封顶\x203×amount、补偿提现\x2030\x20天锁、赔付单次\x20claim、撤回/异议窗\x2030\x20天'+'(arb.move:302-358,\x20order.move:86-96)。','suggestionZh':'将上述参数作为\x20node-game/arbitration-game\x20的收益与等待矩阵输入;本分析器不打分、不排序。'}));if(b['length']>=MAX_FINDINGS_PER_RULE)break;}return b;}},ANTI_CHEAT_ROLES=['neutral','system','merchant','buyer'];function projectOrderEvidence(a,b){const c=[];for(const d of typedNodes(a,'Service')){const f=[...b['controllers']['get'](d['id'])??[]];if(f['length']===0x0)continue;for(const g of out(a,d['id'],'service.order')){const h=a['graph']['nodes']['get'](g['to']);if(!h||h['kind']!=='object'||h['objectType']!=='Order'||!h['raw'])continue;const i=out(a,h['id'],'order.builder')[0x0]?.['to'];if(!i)continue;const j=orderCompletionInGraph(a['graph'],h['id'])['status'],k=String(root(h)?.['amount']??0x0),l=out(a,h['id'],'order.allocation')[0x0]?.['to']??null;for(const m of f){c['push']({'service':d['id'],'id':h['id'],'buyer':i,'seller':m,'amount':k,'status':j,'allocation':l});}}}return c;}function orderCheatEdges(a){return edgeList(a,'service.order')['concat'](edgeList(a,'eoa.permission'))['concat'](edgeList(a,'permission.core_binding'));}function shortRefs(a){const b=a['slice'](0x0,0x5)['join']('、');return a['length']>0x5?b+'\x20等\x20'+a['length']+'\x20个对象':b;}const AC1={'id':'AC1','kind':'risk','run'(a){const b=projectOrderEvidence(a,buildControlIndex(a)),c=detectFakeOrders(b)['find'](e=>e['code']==='self_buy');if(!c)return[];const d=c['refs']??[];return[makeFinding(a,'AC1:'+d['join'](','),'risk','刷单嫌疑:窗口内订单买家即店铺实控\x20EOA(自买自卖)',{'severity':'high','path':['EOA','eoa.permission','permission.core_binding','Service','service.order','Order','order.builder'],'pathEdges':orderCheatEdges(a),'roles':ANTI_CHEAT_ROLES,'detailZh':'窗口内可见\x20'+d['length']+'\x20笔订单的买家\x20EOA\x20同时以\x20owner/admin\x20身份控制售出该订单的\x20Service'+('('+shortRefs(d)+'):买卖双方处于同一实控集合,资金体内循环,不构成真实竞争成交。'),'suggestionZh':'将该批订单剔除出销量/声誉统计,结合支付分账腿与时间窗复核;对该\x20Service\x20降低市场曝光与推荐权重。'})];}},AC2={'id':'AC2','kind':'risk','run'(a){const b=projectOrderEvidence(a,buildControlIndex(a)),c=detectFakeOrders(b)['find'](e=>e['code']==='reciprocal_loop');if(!c)return[];const d=c['refs']??[];return[makeFinding(a,'AC2:'+d['join'](','),'risk','对倒嫌疑:窗口内存在买卖角色互换的资金循环',{'severity':c['severity'],'path':['EOA-A','order.builder','Order@Service-B','service.order','EOA-B','order.builder','Order@Service-A'],'pathEdges':orderCheatEdges(a),'roles':ANTI_CHEAT_ROLES,'detailZh':'窗口内\x20'+d['length']+'\x20笔订单构成买卖互换:A\x20实控集合购买\x20B\x20的\x20Service,同时\x20B\x20实控集合购买\x20A\x20的\x20Service'+('('+shortRefs(d)+')。双向成交可能是互为捧场的资金对倒。'),'suggestionZh':'核查两个实控集合的关联关系(设备/权限/资金往来);对互购订单不计入有效竞争成交。'})];}},AC3={'id':'AC3','kind':'risk','run'(a){const b=projectOrderEvidence(a,buildControlIndex(a)),c=detectFakeOrders(b)['find'](e=>e['code']==='no_allocation');if(!c)return[];const d=c['refs']??[];return[makeFinding(a,'AC3:'+d['join'](','),'risk','无资金闭环:已完成的正额订单缺少\x20Allocation\x20分账对象',{'severity':c['severity'],'path':['Service','service.order','Order','order.allocation'],'pathEdges':orderCheatEdges(a),'roles':ANTI_CHEAT_ROLES,'detailZh':'窗口内\x20'+d['length']+'\x20笔已完成(完成态由\x20order-status\x20结构终结点集权威判定)且\x20amount>0\x20的订单没有\x20Allocation'+('('+shortRefs(d)+')。order.move\x20L130\x20规定正额订单必有分账路径,缺失意味着该“成交”无资金闭环证据。')+'零额订单不在此列(无资金流)。','suggestionZh':'复核订单原始支付记录;无支付凭证的完成订单不得计入声誉;排查无\x20Allocation\x20完成路径的合约入口。'})];}},SHELL_COPY={'shell_no_arbitration':{'titleZh':'空壳商家:已发布\x20Service\x20无仲裁绑定,争议无救济路径','detailZh':'Service\x20处于已发布状态但\x20arbitrations\x20为空:买家下单后没有可选仲裁服务,争议无法进入裁决流程。','suggestionZh':'发布前至少绑定一个与店铺\x20Permission\x20不同组的\x20Arbitration;无救济路径的店铺不应进入推荐。'},'shell_funded_no_arbitration':{'titleZh':'赔付资金悬空:补偿基金已充值但无\x20Arbitration,赔付无法裁决/发放','detailZh':'compensation_fund>0\x20却没有任何\x20Arbitration:触发赔付时无人可裁、无路径可发,充值只构成宣传假象。','suggestionZh':'先绑定仲裁服务再对外宣传赔付保障;市场侧应将“有基金无仲裁”标记为高危并限制曝光。'},'shell_no_machine':{'titleZh':'空壳商家:已发布\x20Service\x20未绑定\x20Machine,无结构化履约流程','detailZh':'Service\x20已发布但\x20machine\x20为空:没有冻结的工作流模板,交付与完成节点均无链上结构约束。','suggestionZh':'绑定并发布\x20Machine\x20后再开张;无工作流的已发布店铺仅适合现货即时交割类目。'}},AC4={'id':'AC4','kind':'risk','run'(a){const b=[];for(const c of typedNodes(a,'Service')){const e=root(c);if(!bool(e['bPublished']))continue;const f=e['arbitrations']!=null?asList(e['arbitrations'])['length']:out(a,c['id'],'service.arbitration')['length'],g=str(e['machine'])??out(a,c['id'],'service.machine')[0x0]?.['to']??null,h=detectShellMerchant({'object':c['id'],'arbitrations':Array(f)['fill']('x'),'compensation_fund':String(big(e['compensation_fund'])),'machine':g,'bPublished':!![]}),i=out(a,c['id'],'service.arbitration')['concat'](out(a,c['id'],'service.machine'));for(const j of h){const k=SHELL_COPY[j['code']];if(!k)continue;b['push'](makeFinding(a,'AC4:'+c['id']+':'+j['code'],'risk',k['titleZh'],{'severity':j['severity'],'path':[c['id'],'Service.bPublished','Service.arbitrations','Service.machine','Service.compensation_fund'],'pathEdges':i,'roles':ANTI_CHEAT_ROLES,'detailZh':k['detailZh']+'(对象:'+c['id']+')','suggestionZh':k['suggestionZh']}));if(b['length']>=MAX_FINDINGS_PER_RULE)return b;}}return b;}};export const DEFAULT_ANALYZERS=[R1,R2,R3,R4,R5,R6,A1,A2,A3,O1,O2,O3,G1,G2,G3,AC1,AC2,AC3,AC4];const registry=new Map(DEFAULT_ANALYZERS['map'](b=>[b['id'],b]));export function registerAnalyzer(a){registry['set'](a['id'],a);}export function getAnalyzer(a){return registry['get'](a);}export function listAnalyzers(){return[...registry['keys']()];}export function runAnalyzers(a,b){const c=b?.['only']?new Set(b['only']):undefined,d=[];for(const e of registry['values']()){if(c&&!c['has'](e['id']))continue;if(b?.['kinds']&&!b['kinds']['includes'](e['kind']))continue;try{d['push'](...e['run'](a));}catch{}}return d;}export function adaptNodeAnalyzer(a){return{'id':a['id'],'kind':a['kind'],'objectType':a['objectType'],'run'(b,c){const d=a['inspect'](b,c);return d['map']((e,f)=>({'id':a['id']+':'+b['id']+'#'+f,'kind':a['kind'],'severity':e['severity']??'info','titleZh':e['titleZh'],'path':[b['id']],'confidence':e['confidence']??'exact','roles':e['roles']??['neutral'],'detailZh':e['detailZh'],'suggestionZh':e['suggestionZh']}));}};}export function runNodeAnalyzers(a,b){const c=[];for(const d of b){for(const e of typedNodes(a,d['objectType'])){try{c['push'](...d['run'](e,a));}catch{}}}return c;}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ import{describe,it,expect}from'vitest';import{ENTRYPOINT}from'@wowok/wowok';import{buildViewport,runAnalyzers,runNodeAnalyzers,adaptNodeAnalyzer,listAnalyzers,registerAnalyzer}from'./index.js';const FAMILY={'eoa.permission':'R','permission.core_binding':'R','permission.entity':'W','service.order':'R','service.machine':'F','service.buy_guard':'F','machine.permission':'F','machine.node':'W','wf.transition':'W','wf.forward_guard':'W','order.allocation':'F','demand.guard':'R','demand.presenter':'R','arbitration.voting_guard':'F','arb.arbitration_service':'F','arb.voter':'S'};class GB{['nodes']=new Map();['edges']=[];['out']=new Map();['inc']=new Map();['truncations']=[];['eoa'](a){return this['nodes']['set'](a,{'id':a,'kind':'eoa','state':'fetched','origins':[],'depth':0x0}),this;}['obj'](a,b,c,d){return this['nodes']['set'](a,{'id':a,'kind':'object','objectType':b,'state':'fetched','origins':[],'depth':0x1,'raw':{'object':a,'type':b,...d?{'type_raw':d}:{},'data':c}}),this;}['edge'](a,b,c,d,f,g=![]){const h={'id':a+'|'+b+'→'+c+(d?.['forward']?'|'+d['forward']:''),'schema':a,'family':FAMILY[a]??'F','from':b,'to':c,'retention':f??(FAMILY[a]==='R'?'bounded_exact':'complete'),'evidence':'test','observedAt':0x1,...d?{'payload':d}:{},...g?{'truncated':!![]}:{}};return this['edges']['push'](h),(this['out']['get'](b)??this['out']['set'](b,[])['get'](b))['push'](h),(this['inc']['get'](c)??this['inc']['set'](c,[])['get'](c))['push'](h),h;}['trunc'](a,b,c){return this['truncations']['push']({'nodeId':a,'schema':b,'observed':c,'limit':0x1450}),this;}['build'](a='0xseed'){return{'network':ENTRYPOINT['Mainnet'],'seed':a,'builtAt':0x1,'nodes':this['nodes'],'edges':this['edges'],'out':this['out'],'inc':this['inc'],'gaps':[],'truncations':this['truncations'],'rpcReport':{'batches':0x0,'byChannel':{'objects':0x0,'keyedFields':0x0,'tables':0x0,'events':0x0},'dedupHits':0x0},'budgetExhausted':{}};}['vp'](a='0xseed',b='neutral'){return buildViewport(this['build'](a),a,b);}}const ids=a=>a['map'](b=>b['id']);describe('analyze\x20—\x20registry',()=>{it('ships\x20the\x2019\x20rules\x20(R1-6/A1-3/O1-3/G1-3\x20+\x20anti-cheat\x20AC1-4)',()=>{expect(listAnalyzers()['sort']())['toEqual'](['R1','R2','R3','R4','R5','R6','A1','A2','A3','O1','O2','O3','G1','G2','G3','AC1','AC2','AC3','AC4']['sort']());}),it('is\x20fail-soft:\x20a\x20throwing\x20analyzer\x20never\x20aborts\x20the\x20suite',()=>{registerAnalyzer({'id':'__boom','kind':'risk','run':()=>{throw new Error('boom');}});const a=new GB()['obj']('0xs1','Service',{'bPublished':!![],'setting_lock_duration':'0'})['vp'](),b=runAnalyzers(a,{'only':['__boom','R6']});expect(ids(b))['toContain']('R6:0xs1'),expect(b['find'](c=>c['id']['startsWith']('__boom')))['toBeUndefined']();}),it('adapts\x20single-object\x20legacy\x20rules\x20through\x20the\x20NodeAnalyzer\x20bridge',()=>{const a=adaptNodeAnalyzer({'id':'legacy-lock','kind':'risk','objectType':'Service','inspect':e=>{const f=e['raw']['data']??{};return f['setting_lock_duration']==='0'?[{'titleZh':'锁','detailZh':'d','suggestionZh':'s','roles':['merchant']}]:[];}}),b=new GB()['obj']('0xs1','Service',{'bPublished':!![],'setting_lock_duration':'0'})['vp'](),c=runNodeAnalyzers(b,[a]);expect(c)['toHaveLength'](0x1),expect(c[0x0]['id'])['toBe']('legacy-lock:0xs1#0'),expect(c[0x0]['kind'])['toBe']('risk');});}),describe('analyze\x20—\x20risk\x20rules',()=>{it('R6\x20flags\x20published\x20services\x20without\x20a\x20setting\x20lock',()=>{const a=new GB()['obj']('0xs1','Service',{'bPublished':!![],'setting_lock_duration':'0'})['obj']('0xs2','Service',{'bPublished':!![],'setting_lock_duration':'2592000000'})['obj']('0xs3','Service',{'bPublished':![],'setting_lock_duration':'0'})['vp'](),b=runAnalyzers(a,{'only':['R6']});expect(ids(b))['toEqual'](['R6:0xs1']);}),it('R2\x20measures\x20the\x20compensation\x20fund\x20against\x203x\x20windowed\x20order\x20volume',()=>{const a=new GB();a['obj']('0xs1','Service',{'bPublished':!![],'compensation_fund':'100'}),a['obj']('0xo1','Order',{'amount':'100'}),a['obj']('0xo2','Order',{'amount':'100'}),a['edge']('service.order','0xs1','0xo1',undefined,'bounded_window'),a['edge']('service.order','0xs1','0xo2',undefined,'bounded_window',!![]);const b=runAnalyzers(a['vp'](),{'only':['R2']});expect(b)['toHaveLength'](0x1),expect(b[0x0]['severity'])['toBe']('high'),expect(b[0x0]['confidence'])['toBe']('windowed'),expect(b[0x0]['window']?.['limit'])['toBe'](0x1450);}),it('R1\x20flags\x20one\x20EOA\x20controlling\x20a\x20shop\x20and\x20an\x20arbitration\x20service\x20across\x20distinct\x20permissions',()=>{const a=new GB();a['eoa']('0xe1'),a['obj']('0xp1','Permission',{'owner':'0xe1'}),a['obj']('0xp2','Permission',{'owner':'0xe1'}),a['obj']('0xs1','Service',{}),a['obj']('0xa1','Arbitration',{'fee':'0'}),a['edge']('eoa.permission','0xe1','0xp1',{'roleBits':0x3}),a['edge']('eoa.permission','0xe1','0xp2',{'roleBits':0x3}),a['edge']('permission.core_binding','0xp1','0xs1'),a['edge']('permission.core_binding','0xp2','0xa1');const b=runAnalyzers(a['vp'](),{'only':['R1']});expect(b)['toHaveLength'](0x1),expect(b[0x0]['severity'])['toBe']('high');const c=new GB();c['eoa']('0xe1')['obj']('0xp1','Permission',{})['obj']('0xs1','Service',{})['obj']('0xa1','Arbitration',{'fee':'0'}),c['edge']('eoa.permission','0xe1','0xp1',{'roleBits':0x3}),c['edge']('permission.core_binding','0xp1','0xs1'),c['edge']('permission.core_binding','0xp1','0xa1'),expect(runAnalyzers(c['vp'](),{'only':['R1']}))['toHaveLength'](0x0);}),it('R3\x20flags\x20concentrated\x20control\x20of\x20core\x20objects',()=>{const a=new GB();a['eoa']('0xe1')['obj']('0xp1','Permission',{}),a['obj']('0xs1','Service',{})['obj']('0xs2','Service',{})['obj']('0xm1','Machine',{}),a['edge']('eoa.permission','0xe1','0xp1',{'roleBits':0x1});for(const c of['0xs1','0xs2','0xm1'])a['edge']('permission.core_binding','0xp1',c);const b=runAnalyzers(a['vp'](),{'only':['R3']});expect(ids(b))['toEqual'](['R3:0xe1']);}),it('R4\x20flags\x20a\x20unique\x20operator\x20with\x20no\x20backup\x20guard\x20on\x20a\x20terminal-entering\x20forward',()=>{const a=new GB();a['obj']('0xm1','Machine',{'bPublished':!![]}),a['edge']('wf.transition','0xm1::node::paid','0xm1::node::delivered',{'node':'delivered','prevNode':'paid','forward':'go','namedOperator':'alice'});const b=runAnalyzers(a['vp'](),{'only':['R4']});expect(b)['toHaveLength'](0x1);const c=new GB();c['obj']('0xm1','Machine',{'bPublished':!![]}),c['edge']('wf.transition','0xm1::node::paid','0xm1::node::delivered',{'node':'delivered','prevNode':'paid','forward':'go','namedOperator':'alice','guard':'0xg1'}),expect(runAnalyzers(c['vp'](),{'only':['R4']}))['toHaveLength'](0x0);}),it('R5\x20reports\x20window\x20truncations\x20as\x20downgraded\x20meta\x20findings',()=>{const a=new GB()['obj']('0xs1','Service',{})['trunc']('0xs1','service.order',0x1450),b=runAnalyzers(a['vp'](),{'only':['R5']});expect(b)['toHaveLength'](0x1),expect(b[0x0]['confidence'])['toBe']('windowed'),expect(b[0x0]['window'])['toEqual']({'observed':0x1450,'limit':0x1450});});}),describe('analyze\x20—\x20arbitrage\x20rules',()=>{it('A1\x20detects\x20rate-basis\x20mismatch,\x20surplus\x20duplication\x20and\x20missing\x20max',()=>{const a=new GB();a['obj']('0xal1','Allocation',{'allocators':[{'guard':'0xg1','max':null,'sharing':[{'who':'0xa','mode':0x0,'sharing':'100'}]},{'guard':'0xg2','sharing':[{'who':'0xb','mode':0x1,'sharing':'9000'}]},{'guard':'0xg3','sharing':[{'who':'0xc','mode':0x2}]},{'guard':'0xg4','sharing':[{'who':'0xd','mode':0x2}]}]});const b=runAnalyzers(a['vp'](),{'only':['A1']});expect(b)['toHaveLength'](0x1),expect(b[0x0]['detailZh'])['toContain']('9000'),expect(b[0x0]['detailZh'])['toContain']('max'),expect(b[0x0]['detailZh'])['toContain']('Surplus');}),it('A2\x20flags\x20transferable\x20fixed\x20long-window\x20discounts\x20without\x20a\x20benchmark',()=>{const a=new GB();a['obj']('0xd1','Discount',{'discount_type':0x1,'benchmark':null,'transferable':!![],'time_start':'0','time_end':String(0x1fn*0x18n*0x3cn*0x3cn*0x3e8n)});const b=runAnalyzers(a['vp'](),{'only':['A2']});expect(b)['toHaveLength'](0x1);const c=new GB();c['obj']('0xd2','Discount',{'discount_type':0x1,'benchmark':null,'transferable':![],'time_start':'0','time_end':String(0x1fn*0x18n*0x3cn*0x3cn*0x3e8n)}),expect(runAnalyzers(c['vp'](),{'only':['A2']}))['toHaveLength'](0x0);}),it('A3\x20flags\x20zero-fee/no-usage-guard\x20arbitration\x20and\x20reports\x20CoinWrapper\x20custody',()=>{const a=new GB();a['obj']('0xa1','Arbitration',{'fee':'0','usage_guard':null,'voting_guard':[]}),a['obj']('0xcw1','Payment',{},'0x2::payment::CoinWrapper<0x2::wow::WOW>');const b=runAnalyzers(a['vp'](),{'only':['A3']});expect(ids(b)['sort']())['toEqual'](['A3:0xa1','A3:coinwrapper']),expect(b['find'](c=>c['id']==='A3:coinwrapper')['detailZh'])['toContain']('0x2::wow::WOW');});}),describe('analyze\x20—\x20opportunity\x20rules',()=>{it('O1\x20surfaces\x20scarce-presenter\x20demands\x20with\x20structurally\x20matching\x20services',()=>{const a=new GB();a['obj']('0xdm1','Demand',{'guards':[{'guard':'0xg1'}]}),a['edge']('demand.guard','0xdm1','0xg1'),a['obj']('0xs1','Service',{'bPublished':!![]}),a['obj']('0xm1','Machine',{}),a['edge']('service.machine','0xs1','0xm1'),a['edge']('wf.forward_guard','0xm1::node::paid','0xg1');const b=runAnalyzers(a['vp'](),{'only':['O1']});expect(b)['toHaveLength'](0x1),expect(b[0x0]['detailZh'])['toContain']('0xs1'),a['eoa']('0u1')['eoa']('0u2'),a['edge']('demand.presenter','0xdm1','0u1',{'service':'0xs1'}),a['edge']('demand.presenter','0xdm1','0u2',{'service':'0xs1'}),expect(runAnalyzers(a['vp'](),{'only':['O1']}))['toHaveLength'](0x0);}),it('O2\x20reports\x20graph\x20supply/demand\x20density',()=>{const a=new GB();a['obj']('0xs1','Service',{'bPublished':!![],'bPaused':![]}),a['obj']('0xs2','Service',{'bPublished':![]}),a['obj']('0xd1','Demand',{});const b=runAnalyzers(a['vp'](),{'only':['O2']});expect(b)['toHaveLength'](0x1),expect(b[0x0]['detailZh'])['toContain']('Service\x202'),expect(b[0x0]['detailZh'])['toContain']('开放需求\x201');}),it('O3\x20lists\x20operator-less\x20forwards\x20as\x20workflow\x20slots',()=>{const a=new GB();a['obj']('0xm1','Machine',{}),a['edge']('wf.transition','0xm1::node::paid','0xm1::node::done',{'node':'done','prevNode':'paid','forward':'auto','namedOperator':null,'permissionIndex':null,'guard':'0xg1'});const b=runAnalyzers(a['vp'](),{'only':['O3']});expect(b)['toHaveLength'](0x1),expect(b[0x0]['detailZh'])['toContain']('paid:auto');});}),describe('analyze\x20—\x20game\x20rules',()=>{it('G1\x20reports\x20all-vote\x20vs\x20weighted\x20structures\x20plus\x20observed\x20case\x20weights',()=>{const a=new GB();a['obj']('0xa1','Arbitration',{'fee':'0','voting_guard':[]}),a['obj']('0xcase1','Arb',{'voted':[{'voter':'0u1','weight':0x1},{'voter':'0u2','weight':0x2}]}),a['edge']('arb.arbitration_service','0xcase1','0xa1');const b=runAnalyzers(a['vp'](),{'only':['G1']});expect(b)['toHaveLength'](0x1),expect(b[0x0]['detailZh'])['toContain']('全员可投'),expect(b[0x0]['detailZh'])['toContain']('w1×1'),expect(b[0x0]['detailZh'])['toContain']('w2×1');}),it('G2\x20marks\x20a\x20named-operator\x20forward\x20as\x20a\x20pool-of-one\x20hold-up\x20point',()=>{const a=new GB();a['obj']('0xm1','Machine',{}),a['edge']('wf.transition','0xm1::node::paid','0xm1::node::done',{'node':'done','prevNode':'paid','forward':'sign','namedOperator':'bob'});const b=runAnalyzers(a['vp'](),{'only':['G2']});expect(b)['toHaveLength'](0x1),expect(b[0x0]['id'])['toContain']('paid:sign');}),it('G3\x20emits\x20the\x20relief\x20parameter\x20matrix\x20for\x20every\x20arbitration\x20service',()=>{const a=new GB();a['obj']('0xa1','Arbitration',{'fee':'5','usage_guard':'0xg1','voting_guard':[{'guard':'0xg2'}]});const b=runAnalyzers(a['vp'](),{'only':['G3']});expect(b)['toHaveLength'](0x1),expect(b[0x0]['detailZh'])['toContain']('fee=5'),expect(b[0x0]['detailZh'])['toContain']('30\x20天');});}),describe('analyze\x20—\x20anti-cheat\x20rules\x20(AC1-AC4)',()=>{function a(c,d,e,f){c['eoa'](d),c['edge']('eoa.permission',d,e,{'roleBits':0x1|0x2}),c['edge']('permission.core_binding',e,f);}function b(c,d,e,f){c['obj'](e,'Order',f),c['edge']('service.order',d,e,undefined,'bounded_window'),c['edge']('order.builder',e,String(f['builder']));}it('AC1\x20flags\x20window\x20orders\x20whose\x20buyer\x20controls\x20the\x20selling\x20Service',()=>{const c=new GB();c['obj']('0xs1','Service',{'bPublished':!![],'machine':'0xm1'}),a(c,'0u1','0p1','0xs1'),b(c,'0xs1','0o1',{'builder':'0u1','service':'0xs1','amount':'100'});const d=runAnalyzers(c['vp'](),{'only':['AC1']});expect(d)['toHaveLength'](0x1),expect(d[0x0]['severity'])['toBe']('high'),expect(d[0x0]['confidence'])['toBe']('windowed'),expect(d[0x0]['id'])['toContain']('0o1');const e=new GB();e['obj']('0xs1','Service',{'bPublished':!![],'machine':'0xm1'}),a(e,'0u1','0p1','0xs1'),b(e,'0xs1','0o1',{'builder':'0u2','service':'0xs1','amount':'100'}),expect(runAnalyzers(e['vp'](),{'only':['AC1']}))['toEqual']([]);}),it('AC2\x20flags\x20reciprocal\x20buying\x20between\x20two\x20controlled\x20Services',()=>{const c=new GB();c['obj']('0xs1','Service',{'bPublished':!![],'machine':'0xm1'}),c['obj']('0xs2','Service',{'bPublished':!![],'machine':'0xm2'}),a(c,'0u1','0p1','0xs1'),a(c,'0u2','0p2','0xs2'),b(c,'0xs1','0o1',{'builder':'0u2','service':'0xs1','amount':'100'}),b(c,'0xs2','0o2',{'builder':'0u1','service':'0xs2','amount':'100'});const d=runAnalyzers(c['vp'](),{'only':['AC2']});expect(d)['toHaveLength'](0x1),expect(d[0x0]['severity'])['toBe']('medium'),expect(d[0x0]['id'])['toContain']('0o1'),expect(d[0x0]['id'])['toContain']('0o2');}),it('AC3\x20flags\x20completed\x20positive-amount\x20orders\x20without\x20Allocation,\x20but\x20not\x20zero-amount\x20orders',()=>{const c=new GB();c['obj']('0xs1','Service',{'bPublished':!![],'machine':'0xm1'}),a(c,'0u1','0p1','0xs1'),b(c,'0xs1','0opaid',{'builder':'0u9','service':'0xs1','amount':'100'}),b(c,'0xs1','0ofree',{'builder':'0u8','service':'0xs1','amount':'0'});const d=runAnalyzers(c['vp'](),{'only':['AC3']});expect(d)['toHaveLength'](0x1),expect(d[0x0]['id'])['toContain']('0opaid'),expect(d[0x0]['id'])['not']['toContain']('0ofree'),c['edge']('order.allocation','0opaid','0al1'),expect(runAnalyzers(c['vp'](),{'only':['AC3']}))['toEqual']([]);}),it('AC4\x20surfaces\x20shell-merchant\x20shapes\x20only\x20for\x20published\x20Services',()=>{const c=new GB();c['obj']('0xs1','Service',{'bPublished':!![],'arbitrations':[],'compensation_fund':'0'});const d=runAnalyzers(c['vp'](),{'only':['AC4']});expect(ids(d)['sort']())['toEqual'](['AC4:0xs1:shell_no_arbitration','AC4:0xs1:shell_no_machine']['sort']());const e=new GB();e['obj']('0xs2','Service',{'bPublished':!![],'arbitrations':[],'compensation_fund':'500'});const f=runAnalyzers(e['vp'](),{'only':['AC4']});expect(f['map'](h=>h['severity'])['sort']())['toEqual'](['high','low','medium']['sort']());const g=new GB();g['obj']('0xs3','Service',{'bPublished':![],'arbitrations':[],'compensation_fund':'500'}),expect(runAnalyzers(g['vp'](),{'only':['AC4']}))['toEqual']([]);});});
@@ -0,0 +1,39 @@
1
+ export type AntiCheatSeverity = "high" | "medium" | "low";
2
+ export interface AntiCheatSignal {
3
+ kind: "fake_order" | "fake_review" | "shell_merchant" | "reputation_trade";
4
+ code: "self_buy" | "reciprocal_loop" | "no_allocation" | "reviews_unverified" | "reviewer_duplicate" | "review_time_burst" | "shell_no_arbitration" | "shell_funded_no_arbitration" | "shell_no_machine" | "reputation_bound";
5
+ severity: AntiCheatSeverity;
6
+ description: string;
7
+ refs?: string[];
8
+ }
9
+ export interface OrderEvidence {
10
+ id: string;
11
+ buyer: string;
12
+ seller: string;
13
+ amount: number | bigint | string;
14
+ status: string;
15
+ allocation?: string | null;
16
+ }
17
+ export interface ReviewEvidence {
18
+ reviewer: string;
19
+ rating: "like" | "dislike";
20
+ orderRef?: string;
21
+ verified?: boolean;
22
+ timestamp?: number;
23
+ }
24
+ export interface MerchantEvidence {
25
+ service: {
26
+ object: string;
27
+ arbitrations: string[];
28
+ compensation_fund: number | bigint | string;
29
+ machine: string | null;
30
+ bPublished: boolean;
31
+ };
32
+ orders: OrderEvidence[];
33
+ reviews: ReviewEvidence[];
34
+ }
35
+ export declare function detectFakeOrders(orders: OrderEvidence[]): AntiCheatSignal[];
36
+ export declare function detectFakeReviews(reviews: ReviewEvidence[]): AntiCheatSignal[];
37
+ export declare function detectShellMerchant(service: MerchantEvidence["service"]): AntiCheatSignal[];
38
+ export declare function reputationTradeNote(): AntiCheatSignal;
39
+ export declare function assessAntiCheat(evidence: MerchantEvidence): AntiCheatSignal[];
@@ -0,0 +1 @@
1
+ function toBigInt(a){if(a===undefined||a===null)return undefined;try{return BigInt(a);}catch{return undefined;}}export function detectFakeOrders(a){const b=[];if(a['length']===0x0)return b;const c=a['filter'](h=>h['buyer']===h['seller']);c['length']>0x0&&b['push']({'kind':'fake_order','code':'self_buy','severity':'high','description':c['length']+'\x20order(s)\x20with\x20buyer\x20==\x20seller\x20(self-buy-sell)','refs':[...new Set(c['map'](h=>h['id']))]});const d=new Set(a['map'](h=>h['buyer'])),e=new Set(a['map'](h=>h['seller'])),f=a['filter'](h=>d['has'](h['seller'])&&e['has'](h['buyer']));f['length']>=0x2&&b['push']({'kind':'fake_order','code':'reciprocal_loop','severity':'medium','description':f['length']+'\x20order(s)\x20in\x20a\x20reciprocal\x20buyer/seller\x20loop\x20(possible\x20fund\x20circulation)','refs':[...new Set(f['map'](h=>h['id']))]});const g=a['filter'](h=>!h['allocation']&&h['status']==='completed'&&(toBigInt(h['amount'])??0x0n)>0x0n);return g['length']>0x0&&b['push']({'kind':'fake_order','code':'no_allocation','severity':'medium','description':g['length']+'\x20completed\x20positive-amount\x20order(s)\x20without\x20an\x20Allocation\x20(no\x20fund-closure\x20evidence)','refs':[...new Set(g['map'](h=>h['id']))]}),b;}export function detectFakeReviews(a){const b=[];if(a['length']===0x0)return b;const c=a['filter'](g=>!g['verified']);c['length']>0x0&&c['length']===a['length']&&b['push']({'kind':'fake_review','code':'reviews_unverified','severity':'high','description':'all\x20'+a['length']+'\x20review(s)\x20are\x20unverified\x20(no\x20completed-order\x20credential)'});const d=new Map();for(const g of a){d['set'](g['reviewer'],(d['get'](g['reviewer'])??0x0)+0x1);}const e=[...d['values']()]['filter'](h=>h>0x1)['length'];e>0x0&&b['push']({'kind':'fake_review','code':'reviewer_duplicate','severity':'medium','description':e+'\x20address(es)\x20submitted\x20multiple\x20reviews'});const f=a['filter'](h=>h['timestamp']!=null);if(f['length']>0xa){const h=[...f]['sort']((j,k)=>(j['timestamp']??0x0)-(k['timestamp']??0x0)),i=(h[h['length']-0x1]['timestamp']??0x0)-(h[0x0]['timestamp']??0x0);i>0x0&&i<0x36ee80&&b['push']({'kind':'fake_review','code':'review_time_burst','severity':'medium','description':f['length']+'\x20review(s)\x20within\x201\x20hour\x20(concentrated\x20timing)'});}return b;}export function detectShellMerchant(a){const b=[];if(!a['bPublished'])return b;a['arbitrations']['length']===0x0&&b['push']({'kind':'shell_merchant','code':'shell_no_arbitration','severity':a['machine']?'low':'medium','description':'published\x20Service\x20has\x20no\x20Arbitration\x20binding\x20(no\x20dispute\x20path)','refs':[a['object']]});const c=toBigInt(a['compensation_fund'])??0x0n;return c>0x0n&&a['arbitrations']['length']===0x0&&b['push']({'kind':'shell_merchant','code':'shell_funded_no_arbitration','severity':'high','description':'funded\x20compensation_fund\x20but\x20no\x20Arbitration\x20(compensation\x20cannot\x20be\x20ruled/disbursed)','refs':[a['object']]}),!a['machine']&&b['push']({'kind':'shell_merchant','code':'shell_no_machine','severity':'low','description':'published\x20Service\x20has\x20no\x20Machine\x20(no\x20workflow)','refs':[a['object']]}),b;}export function reputationTradeNote(){return{'kind':'reputation_trade','code':'reputation_bound','severity':'low','description':'reputation\x20aggregates\x20by\x20historical\x20fulfillment\x20and\x20is\x20not\x20transferable\x20with\x20the\x20object\x20—\x20reputation\x20trading\x20is\x20structurally\x20prevented'};}export function assessAntiCheat(a){return[...detectFakeOrders(a['orders']),...detectFakeReviews(a['reviews']),...detectShellMerchant(a['service']),reputationTradeNote()];}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ import{describe,expect,it}from'vitest';import{assessAntiCheat,detectFakeOrders,detectShellMerchant}from'./index.js';function order(a){return{'amount':'0','status':'completed','allocation':null,...a};}describe('anti-cheat\x20pure\x20engine\x20—\x20detectFakeOrders',()=>{it('flags\x20self-buy-sell\x20with\x20order\x20refs\x20and\x20code',()=>{const a=detectFakeOrders([order({'id':'o1','buyer':'a','seller':'a'})]);expect(a)['toHaveLength'](0x1),expect(a[0x0]['code'])['toBe']('self_buy'),expect(a[0x0]['severity'])['toBe']('high'),expect(a[0x0]['refs'])['toEqual'](['o1']);}),it('flags\x20reciprocal\x20buyer/seller\x20loops\x20only\x20with\x20two\x20or\x20more\x20matching\x20orders',()=>{const a=detectFakeOrders([order({'id':'o1','buyer':'a','seller':'b'})]);expect(a['find'](d=>d['code']==='reciprocal_loop'))['toBeUndefined']();const b=detectFakeOrders([order({'id':'o1','buyer':'a','seller':'b','amount':'100','allocation':'al1'}),order({'id':'o2','buyer':'b','seller':'a','amount':'100','allocation':'al2'})]),c=b['find'](d=>d['code']==='reciprocal_loop');expect(c?.['refs'])['toEqual'](['o1','o2']);}),it('treats\x20completed\x20positive-amount\x20orders\x20without\x20Allocation\x20as\x20unclosed,\x20but\x20exempts\x20zero-amount\x20orders',()=>{const a=detectFakeOrders([order({'id':'paid-noalloc','buyer':'a','seller':'b','amount':'100','status':'completed'}),order({'id':'free-noalloc','buyer':'a','seller':'b','amount':'0','status':'completed'}),order({'id':'open-noalloc','buyer':'a','seller':'b','amount':'100','status':'in_progress'})]),b=a['find'](c=>c['code']==='no_allocation');expect(b?.['refs'])['toEqual'](['paid-noalloc']);});}),describe('anti-cheat\x20pure\x20engine\x20—\x20detectShellMerchant',()=>{const a={'object':'s1','arbitrations':[],'compensation_fund':'0','machine':null,'bPublished':!![]};it('stays\x20silent\x20for\x20unpublished\x20services',()=>{expect(detectShellMerchant({...a,'bPublished':![]}))['toEqual']([]);}),it('emits\x20the\x20three\x20shell\x20codes\x20with\x20contract-aligned\x20severities',()=>{const b=detectShellMerchant({...a,'compensation_fund':'9'});expect(b['map'](d=>d['code'])['sort']())['toEqual'](['shell_no_arbitration','shell_funded_no_arbitration','shell_no_machine']['sort']()),expect(b['find'](d=>d['code']==='shell_funded_no_arbitration')?.['severity'])['toBe']('high');const c=detectShellMerchant({...a,'machine':'m1','compensation_fund':'0'});expect(c['find'](d=>d['code']==='shell_no_arbitration')?.['severity'])['toBe']('low');});}),describe('anti-cheat\x20pure\x20engine\x20—\x20assessAntiCheat',()=>{it('composes\x20order/review/service\x20signals\x20plus\x20the\x20static\x20reputation\x20note',()=>{const a=assessAntiCheat({'service':{'object':'s1','arbitrations':[],'compensation_fund':'0','machine':null,'bPublished':!![]},'orders':[order({'id':'o1','buyer':'a','seller':'a'})],'reviews':[]});expect(a['map'](b=>b['code']))['toContain']('self_buy'),expect(a['map'](b=>b['code']))['toContain']('reputation_bound');});});
@@ -0,0 +1,44 @@
1
+ import type { DataPlane, EventCursor, EventPage, ExpandBudget, RawObject, SingletonId, TableItem } from "./types.js";
2
+ export declare const MAX_OBJECTS_PER_QUERY = 50;
3
+ export declare const DEFAULT_BUDGET: ExpandBudget;
4
+ export declare function mergeBudget(b?: Partial<ExpandBudget>): ExpandBudget;
5
+ export declare function mapPool<T, R>(items: T[], concurrency: number, fn: (item: T, index: number) => Promise<R>): Promise<R[]>;
6
+ export declare function chunk50<T>(items: T[]): T[][];
7
+ export interface FakePlaneState {
8
+ objects: Map<string, RawObject>;
9
+ keyedFields: Map<string, Map<string, unknown>>;
10
+ tables: Map<string, TableItem[]>;
11
+ events: Map<string, {
12
+ events: unknown[];
13
+ cursor?: EventCursor | null;
14
+ }[]>;
15
+ }
16
+ export declare class FakeDataPlane implements DataPlane {
17
+ readonly state: FakePlaneState;
18
+ batches: {
19
+ objects: number;
20
+ keyedFields: number;
21
+ tables: number;
22
+ events: number;
23
+ };
24
+ dedupHits: number;
25
+ private seenObjects;
26
+ private seenKeyed;
27
+ constructor(state?: Partial<FakePlaneState>);
28
+ getObjects(ids: string[]): Promise<Map<string, RawObject>>;
29
+ getKeyedFields(parent: SingletonId, keys: string[], opts?: {
30
+ keyType?: "address" | "u64";
31
+ }): Promise<Map<string, RawObject>>;
32
+ getTable(parent: string, opts?: {
33
+ maxItems?: number;
34
+ pageLimit?: number;
35
+ fetchValues?: boolean;
36
+ }): Promise<{
37
+ items: TableItem[];
38
+ truncated: boolean;
39
+ }>;
40
+ getEvents(type: string, opts?: {
41
+ cursor?: EventCursor | null;
42
+ maxPages?: number;
43
+ }): Promise<EventPage>;
44
+ }
@@ -0,0 +1 @@
1
+ export const MAX_OBJECTS_PER_QUERY=0x32;export const DEFAULT_BUDGET={'maxDepth':0x4,'maxNodes':0x1f4,'maxFanoutPerNode':0x3c,'maxRpcs':0x78,'maxEventPages':0x64,'perKindCaps':{'service.order':0xc8,'eoa.order':0x64,'target.vote':0x64,'machine.node':0x64,'permission.core_binding':0x3c,'permission.entity':0x3c,'service.arbitration':0x14,'service.reward':0x14,'service.repository':0x64,'arb.voter':0xc8,'payment.recipient':0xc8},'concurrency':0x4};export function mergeBudget(a){return{...DEFAULT_BUDGET,...a,'perKindCaps':{...DEFAULT_BUDGET['perKindCaps'],...a?.['perKindCaps']}};}export async function mapPool(a,b,c){const d=new Array(a['length']);let e=0x0;const f=Array['from']({'length':Math['max'](0x1,Math['min'](b,a['length']||0x1))},async()=>{for(;;){const g=e++;if(g>=a['length'])return;d[g]=await c(a[g],g);}});return await Promise['all'](f),d;}export function chunk50(a){const b=[];for(let c=0x0;c<a['length'];c+=MAX_OBJECTS_PER_QUERY)b['push'](a['slice'](c,c+MAX_OBJECTS_PER_QUERY));return b;}export class FakeDataPlane{['state'];['batches']={'objects':0x0,'keyedFields':0x0,'tables':0x0,'events':0x0};['dedupHits']=0x0;['seenObjects']=new Set();['seenKeyed']=new Set();constructor(a){this['state']={'objects':new Map(a?.['objects']??[]),'keyedFields':a?.['keyedFields']??new Map(),'tables':a?.['tables']??new Map(),'events':a?.['events']??new Map()};}async['getObjects'](a){const b=[...new Set(a['map'](e=>e['toLowerCase']()))],c=[],d=new Map();for(const e of b){if(this['seenObjects']['has'](e)){this['dedupHits']++;const f=lookupLower(this['state']['objects'],e);if(f)d['set'](e,f);}else this['seenObjects']['add'](e),c['push'](e);}for(const g of chunk50(c)){this['batches']['objects']++;for(const h of g){const i=lookupLower(this['state']['objects'],h);if(i)d['set'](h,i);}}return d;}async['getKeyedFields'](a,b,c){const d=this['state']['keyedFields']['get'](a)??new Map(),e=[...new Set(b['map'](g=>String(g)['toLowerCase']()))],f=new Map();for(const g of chunk50(e)){this['batches']['keyedFields']++;for(const h of g){const i=a+'|'+(c?.['keyType']??'address')+'|'+h;if(this['seenKeyed']['has'](i))this['dedupHits']++;this['seenKeyed']['add'](i);const j=lookupLower(d,h);if(j!=null)f['set'](h,typeof j==='object'&&j&&'data'in j?j:{'data':j});}}return f;}async['getTable'](a,b){this['batches']['tables']++;const c=this['state']['tables']['get'](a['toLowerCase']())??[],d=b?.['maxItems'],e=d!=null&&c['length']>d?c['slice'](0x0,d):c,f=b?.['fetchValues']===![]?e['map'](({key:g,objectId:h})=>({'key':g,'objectId':h})):e;return{'items':f,'truncated':d!=null&&c['length']>d};}async['getEvents'](a,b){this['batches']['events']++;const c=this['state']['events']['get'](a)??[],d=c[c['length']-0x1];return{'events':d?.['events']??[],'cursor':d?.['cursor']??null,'truncated':![]};}}function lookupLower(a,b){const c=a['get'](b);if(c!==undefined)return c;for(const [d,e]of a)if(d['toLowerCase']()===b)return e;return undefined;}
@@ -0,0 +1,60 @@
1
+ import type { EdgeFamily, Retention, SingletonId } from "./types.js";
2
+ export interface FieldRead {
3
+ kind: "field";
4
+ path: string;
5
+ }
6
+ export interface FieldsRead {
7
+ kind: "fields";
8
+ path: string;
9
+ }
10
+ export interface StructFieldsRead {
11
+ kind: "structFields";
12
+ path: string;
13
+ field: string;
14
+ }
15
+ export interface DeepRead {
16
+ kind: "deep";
17
+ segments: string[];
18
+ field: string;
19
+ }
20
+ export interface ReverseRead {
21
+ kind: "reverse";
22
+ parent: SingletonId;
23
+ filterType?: string;
24
+ }
25
+ export interface TableRead {
26
+ kind: "table";
27
+ rowType: "MachineNode" | "PermissionPerm" | "DemandPresenter";
28
+ }
29
+ export interface DerivedRead {
30
+ kind: "derived";
31
+ producer: string;
32
+ }
33
+ export type EdgeRead = FieldRead | FieldsRead | StructFieldsRead | DeepRead | ReverseRead | TableRead | DerivedRead;
34
+ export type Cardinality = 1 | "0..1" | "N";
35
+ export type FieldMutabilityAction = "add" | "remove" | "clear" | "set" | "update";
36
+ export interface EdgeContractMeta {
37
+ field: string;
38
+ frozenWhen: string | null;
39
+ forbiddenActions: FieldMutabilityAction[];
40
+ allowedActions: FieldMutabilityAction[];
41
+ unfreeze: string | null;
42
+ moveAnchor: string;
43
+ }
44
+ export interface EdgeSchema {
45
+ id: string;
46
+ family: EdgeFamily;
47
+ source: string;
48
+ target: string;
49
+ cardinality: Cardinality;
50
+ read: EdgeRead;
51
+ retention: Retention;
52
+ evidence: string;
53
+ contract?: EdgeContractMeta;
54
+ bridgeIds?: string[];
55
+ zh: string;
56
+ }
57
+ export declare const EDGE_SCHEMAS: EdgeSchema[];
58
+ export declare const EDGE_SCHEMA_BY_ID: Map<string, EdgeSchema>;
59
+ export declare function outgoingSchemaIds(sourceType: string): string[];
60
+ export declare const COVERED_OBJECT_TYPES: string[];
@@ -0,0 +1 @@
1
+ const EOA='EOA',ANY='ANY',F_EDGES=[{'id':'service.permission','family':'F','source':'Service','target':'Permission','cardinality':0x1,'read':{'kind':'field','path':'permission'},'retention':'complete','evidence':'service.move\x20L175-194','bridgeIds':['b06','b09'],'zh':'店铺挂接的权限组(裁决回避\x20E33\x20的对照边)'},{'id':'service.machine','family':'F','source':'Service','target':'Machine','cardinality':'0..1','read':{'kind':'field','path':'machine'},'retention':'complete','evidence':'service.move\x20L175-194','bridgeIds':['b04'],'contract':{'field':'machine','frozenWhen':'after\x20publish','forbiddenActions':['set','remove'],'allowedActions':[],'unfreeze':null,'moveAnchor':'service.move\x20machine_set_imp\x20/\x20machine_none_imp\x20(assert!(!bPublished))'},'zh':'店铺绑定的工作流模板'},{'id':'service.buy_guard','family':'F','source':'Service','target':'Guard','cardinality':'0..1','read':{'kind':'field','path':'buy_guard'},'retention':'complete','evidence':'service.move\x20L175-194','bridgeIds':['b01','b10'],'contract':{'field':'buy_guard','frozenWhen':null,'forbiddenActions':[],'allowedActions':['set','remove'],'unfreeze':null,'moveAnchor':'service.move\x20buy_guard_set_imp\x20/\x20buy_guard_none_imp\x20(no\x20assert!(!bPublished))'},'zh':'下单前置校验\x20Guard'},{'id':'service.arbitration','family':'F','source':'Service','target':'Arbitration','cardinality':'N','read':{'kind':'fields','path':'arbitrations'},'retention':'complete','evidence':'service.move\x20L175-194\x20(≤20)','bridgeIds':['b06'],'contract':{'field':'arbitrations','frozenWhen':'after\x20publish','forbiddenActions':['remove','clear'],'allowedActions':['add'],'unfreeze':'pause\x20+\x20setting_lock_duration\x20elapsed','moveAnchor':'service.move\x20arbitration_remove_imp\x20/\x20arbitration_clear_imp\x20(assert_not_published)'},'zh':'店铺可选仲裁服务(≤20)'},{'id':'service.reward','family':'F','source':'Service','target':'Reward','cardinality':'N','read':{'kind':'fields','path':'rewards'},'retention':'complete','evidence':'service.move\x20L175-194\x20(≤20)','bridgeIds':['b07'],'contract':{'field':'rewards','frozenWhen':'after\x20publish','forbiddenActions':['remove','clear'],'allowedActions':['add'],'unfreeze':'pause\x20+\x20setting_lock_duration\x20elapsed','moveAnchor':'service.move\x20reward_remove_imp\x20/\x20reward_clear_imp\x20(assert_not_published)'},'zh':'店铺挂接的激励池(≤20)'},{'id':'service.repository','family':'F','source':'Service','target':'Repository','cardinality':'N','read':{'kind':'fields','path':'repositories'},'retention':'complete','evidence':'service.move\x20L175-194\x20(≤100)','bridgeIds':['b02'],'contract':{'field':'repositories','frozenWhen':null,'forbiddenActions':[],'allowedActions':['add','remove','clear'],'unfreeze':null,'moveAnchor':'service.move\x20repository_remove_imp\x20/\x20repository_clear_imp\x20(no\x20assert_not_published)'},'zh':'店铺证据资料库(≤100)'},{'id':'service.um','family':'F','source':'Service','target':'Contact','cardinality':'0..1','read':{'kind':'field','path':'um'},'retention':'complete','evidence':'service.move\x20L175-194','bridgeIds':['b11'],'zh':'店铺会员关系簿'},{'id':'service.order_allocator_guard','family':'F','source':'Service','target':'Guard','cardinality':'N','read':{'kind':'deep','segments':['order_allocators','allocators'],'field':'guard'},'retention':'complete','evidence':'service.move\x20L175-194;\x20allocation.move\x20L194-200','bridgeIds':['b05'],'zh':'店铺下单分账模板的触发\x20Guard'},{'id':'order.builder','family':'F','source':'Order','target':EOA,'cardinality':0x1,'read':{'kind':'field','path':'builder'},'retention':'complete','evidence':'order.move\x20L60-75\x20(owner;\x20SDK\x20builder)','bridgeIds':['b01'],'zh':'订单买家(owner/builder)'},{'id':'order.agent','family':'F','source':'Order','target':EOA,'cardinality':'N','read':{'kind':'fields','path':'agent'},'retention':'complete','evidence':'order.move\x20L60-75,L179\x20(≤10)','zh':'买家授权的商家代理人(≤10,买家调用\x20agent_set)'},{'id':'order.service','family':'F','source':'Order','target':'Service','cardinality':0x1,'read':{'kind':'field','path':'service'},'retention':'complete','evidence':'order.move\x20L60-75','bridgeIds':['b01'],'zh':'订单购买的店铺(购买快照)'},{'id':'order.machine','family':'F','source':'Order','target':'Machine','cardinality':'0..1','read':{'kind':'field','path':'machine'},'retention':'complete','evidence':'order.move\x20L130\x20(machine⇒progress)','bridgeIds':['b01','b04'],'zh':'订单绑定的工作流(购买快照)'},{'id':'order.progress','family':'F','source':'Order','target':'Progress','cardinality':'0..1','read':{'kind':'field','path':'progress'},'retention':'complete','evidence':'order.move\x20L130','bridgeIds':['b04'],'zh':'订单履约进度'},{'id':'order.allocation','family':'F','source':'Order','target':'Allocation','cardinality':'0..1','read':{'kind':'field','path':'allocation'},'retention':'complete','evidence':'order.move\x20L130\x20(amount>0⇒allocation)','bridgeIds':['b05'],'zh':'订单分账模板'},{'id':'order.discount','family':'F','source':'Order','target':'Discount','cardinality':'0..1','read':{'kind':'field','path':'discount'},'retention':'complete','evidence':'order.move\x20L60-75','bridgeIds':['b01'],'zh':'订单使用的折扣'},{'id':'order.dispute','family':'F','source':'Order','target':'Arb','cardinality':'N','read':{'kind':'fields','path':'dispute'},'retention':'complete','evidence':'order.move\x20L60-75','bridgeIds':['b06'],'zh':'订单关联的仲裁案件'},{'id':'order.claimed_by','family':'F','source':'Order','target':EOA,'cardinality':'0..1','read':{'kind':'field','path':'claimed_by'},'retention':'complete','evidence':'order.move\x20L86-96\x20(single-use)','bridgeIds':['b06'],'zh':'赔付领取人(单次)'},{'id':'progress.machine','family':'F','source':'Progress','target':'Machine','cardinality':0x1,'read':{'kind':'field','path':'machine'},'retention':'complete','evidence':'progress.move\x20L76-86','bridgeIds':['b04'],'contract':{'field':'machine','frozenWhen':'bound\x20at\x20creation','forbiddenActions':['set','remove'],'allowedActions':[],'unfreeze':null,'moveAnchor':'progress.move\x20new_imp\x20(machine\x20bound\x20at\x20creation;\x20no\x20mutation\x20entry)'},'zh':'进度对应的工作流模板'},{'id':'progress.task','family':'F','source':'Progress','target':'Order','cardinality':'0..1','read':{'kind':'field','path':'task'},'retention':'complete','evidence':'progress.move\x20L76-86','bridgeIds':['b04'],'contract':{'field':'task','frozenWhen':'after\x20task_set','forbiddenActions':['set'],'allowedActions':[],'unfreeze':null,'moveAnchor':'progress.move\x20task_set_imp\x20(assert!\x20option::is_none\x20→\x20E_TASK_ALREADY_SET)'},'zh':'进度关联的订单'},{'id':'progress.named_operator','family':'F','source':'Progress','target':EOA,'cardinality':'N','read':{'kind':'deep','segments':['namedOperator','operators'],'field':''},'retention':'complete','evidence':'progress.move\x20L76-86\x20(≤80)','bridgeIds':['b04'],'zh':'具名操作员运行时绑定(≤80\x20地址)'},{'id':'machine.permission','family':'F','source':'Machine','target':'Permission','cardinality':0x1,'read':{'kind':'field','path':'permission'},'retention':'complete','evidence':'machine.move\x20L299-308','bridgeIds':['b09'],'zh':'工作流的权限组'},{'id':'machine.consensus_repository','family':'F','source':'Machine','target':'Repository','cardinality':'N','read':{'kind':'fields','path':'consensus_repositories'},'retention':'complete','evidence':'machine.move\x20L299-308','contract':{'field':'consensus_repositories','frozenWhen':null,'forbiddenActions':[],'allowedActions':['add','remove','clear'],'unfreeze':null,'moveAnchor':'machine.move\x20consensus_repositories_remove_imp\x20(no\x20assert_not_published)'},'zh':'工作流共识资料库'},{'id':'machine.um','family':'F','source':'Machine','target':'Contact','cardinality':'0..1','read':{'kind':'field','path':'um'},'retention':'complete','evidence':'machine.move\x20L299-308','bridgeIds':['b11'],'zh':'工作流会员关系簿'},{'id':'allocation.guard','family':'F','source':'Allocation','target':'Guard','cardinality':'N','read':{'kind':'deep','segments':['allocators','allocators'],'field':'guard'},'retention':'complete','evidence':'allocation.move\x20L194-200','bridgeIds':['b05'],'contract':{'field':'allocators','frozenWhen':'after\x20create\x20(share)','forbiddenActions':['add','remove','clear','set'],'allowedActions':[],'unfreeze':null,'moveAnchor':'allocation.move\x20create\x20(bound\x20via\x20new_with_balance;\x20no\x20mutation\x20entry)'},'zh':'分账段触发\x20Guard'},{'id':'arbitration.permission','family':'F','source':'Arbitration','target':'Permission','cardinality':0x1,'read':{'kind':'field','path':'permission'},'retention':'complete','evidence':'arbitration.move\x20L48-59','bridgeIds':['b06','b09'],'zh':'仲裁服务的权限组(须与店铺\x20permission\x20不同,E33)'},{'id':'arbitration.voting_guard','family':'F','source':'Arbitration','target':'Guard','cardinality':'N','read':{'kind':'structFields','path':'voting_guard','field':'guard'},'retention':'complete','evidence':'arbitration.move\x20L48-59','bridgeIds':['b06','b10'],'zh':'仲裁投票权\x20Guard(空=人人可投)'},{'id':'arbitration.usage_guard','family':'F','source':'Arbitration','target':'Guard','cardinality':'0..1','read':{'kind':'field','path':'usage_guard'},'retention':'complete','evidence':'arbitration.move\x20L48-59','bridgeIds':['b06','b10'],'zh':'仲裁服务使用门槛\x20Guard'},{'id':'arbitration.um','family':'F','source':'Arbitration','target':'Contact','cardinality':'0..1','read':{'kind':'field','path':'um'},'retention':'complete','evidence':'arbitration.move\x20L48-59','bridgeIds':['b11'],'zh':'仲裁会员关系簿'},{'id':'arb.order','family':'F','source':'Arb','target':'Order','cardinality':0x1,'read':{'kind':'field','path':'order'},'retention':'complete','evidence':'arb.move\x20L96-111','bridgeIds':['b06'],'zh':'仲裁案件对应的订单'},{'id':'arb.arbitration_service','family':'F','source':'Arb','target':'Arbitration','cardinality':'0..1','read':{'kind':'field','path':'arbitration'},'retention':'complete','evidence':'arb.move\x20L96-111','bridgeIds':['b06'],'zh':'案件适用的仲裁服务'},{'id':'arb.voter','family':'S','source':'Arb','target':EOA,'cardinality':'N','read':{'kind':'structFields','path':'voted','field':'voter'},'retention':'complete','evidence':'arb.move\x20L96-111\x20(voted≤520)','bridgeIds':['b06'],'zh':'案件实际投票人及权重(≤520)'},{'id':'demand.permission','family':'F','source':'Demand','target':'Permission','cardinality':0x1,'read':{'kind':'field','path':'permission'},'retention':'complete','evidence':'demand.move\x20L68-77','bridgeIds':['b09'],'zh':'需求的权限组(需求方)'},{'id':'demand.guard','family':'F','source':'Demand','target':'Guard','cardinality':'N','read':{'kind':'structFields','path':'guards','field':'guard'},'retention':'complete','evidence':'demand.move\x20L68-77','bridgeIds':['b03','b10'],'zh':'需求接单\x20Guard(裸\x20present\x20时须为空)'},{'id':'demand.reward','family':'F','source':'Demand','target':'Reward','cardinality':'N','read':{'kind':'fields','path':'rewards'},'retention':'complete','evidence':'demand.move\x20L68-77','bridgeIds':['b07'],'zh':'需求托管激励池'},{'id':'demand.um','family':'F','source':'Demand','target':'Contact','cardinality':'0..1','read':{'kind':'field','path':'um'},'retention':'complete','evidence':'demand.move\x20L68-77','bridgeIds':['b11'],'zh':'需求会员关系簿'},{'id':'reward.permission','family':'F','source':'Reward','target':'Permission','cardinality':0x1,'read':{'kind':'field','path':'permission'},'retention':'complete','evidence':'reward.move\x20L129','bridgeIds':['b09'],'zh':'激励池权限组'},{'id':'reward.guard','family':'F','source':'Reward','target':'Guard','cardinality':'N','read':{'kind':'structFields','path':'guards','field':'guard'},'retention':'complete','evidence':'reward.move\x20L129','bridgeIds':['b07'],'zh':'激励领取\x20Guard'},{'id':'reward.um','family':'F','source':'Reward','target':'Contact','cardinality':'0..1','read':{'kind':'field','path':'um'},'retention':'complete','evidence':'reward.move\x20L129','bridgeIds':['b11'],'zh':'激励池会员关系簿'},{'id':'repository.permission','family':'F','source':'Repository','target':'Permission','cardinality':0x1,'read':{'kind':'field','path':'permission'},'retention':'complete','evidence':'repository.move\x20(struct)','bridgeIds':['b02','b09'],'zh':'资料库权限组'},{'id':'repository.reward','family':'F','source':'Repository','target':'Reward','cardinality':'N','read':{'kind':'fields','path':'rewards'},'retention':'complete','evidence':'repository.move\x20(struct)','bridgeIds':['b07'],'zh':'资料库挂接的激励池'},{'id':'repository.policy_guard','family':'F','source':'Repository','target':'Guard','cardinality':'N','read':{'kind':'structFields','path':'policies','field':'guard'},'retention':'complete','evidence':'repository.move\x20(read/write\x20policies)','bridgeIds':['b02','b10'],'zh':'资料库读写策略\x20Guard(值门控)'},{'id':'contact.permission','family':'F','source':'Contact','target':'Permission','cardinality':0x1,'read':{'kind':'field','path':'permission'},'retention':'complete','evidence':'contact.move\x20L25-31','bridgeIds':['b09','b11'],'zh':'客服会员簿的权限组'},{'id':'permission.admin','family':'F','source':'Permission','target':EOA,'cardinality':'N','read':{'kind':'fields','path':'admin'},'retention':'complete','evidence':'permission.move\x20L34-42\x20(admin\x20vector)','bridgeIds':['b09'],'zh':'权限组管理员\x20EOA\x20列表'},{'id':'guard.relies','family':'F','source':'Guard','target':'Guard','cardinality':'N','read':{'kind':'fields','path':'relies'},'retention':'complete','evidence':'guard.move\x20L85-95\x20(≤4,\x20one\x20level)','bridgeIds':['b10'],'zh':'Guard\x20依赖的子\x20Guard(≤4,仅一层)'},{'id':'passport.signer','family':'F','source':'Passport','target':EOA,'cardinality':0x1,'read':{'kind':'field','path':'signer'},'retention':'complete','evidence':'passport.move\x20L41-49,L94-98','bridgeIds':['b12'],'zh':'通行证签署人(单笔\x20tx\x20一次性)'},{'id':'passport.guard','family':'F','source':'Passport','target':'Guard','cardinality':'N','read':{'kind':'structFields','path':'guard','field':'guard'},'retention':'complete','evidence':'passport.move\x20L41-49','bridgeIds':['b10','b12'],'zh':'通行证持有的\x20Guard\x20校验票据'},{'id':'proof.signer','family':'F','source':'Proof','target':EOA,'cardinality':0x1,'read':{'kind':'field','path':'signer'},'retention':'complete','evidence':'proof.move\x20L14-25','bridgeIds':['b12'],'zh':'WTS\x20证据签名人'},{'id':'proof.about','family':'F','source':'Proof','target':ANY,'cardinality':'0..1','read':{'kind':'field','path':'about'},'retention':'complete','evidence':'proof.move\x20L14-25','bridgeIds':['b12'],'zh':'证据关联对象'},{'id':'treasury.permission','family':'F','source':'Treasury','target':'Permission','cardinality':0x1,'read':{'kind':'field','path':'permission'},'retention':'complete','evidence':'treasury.move\x20L72-83','bridgeIds':['b09'],'zh':'金库权限组'},{'id':'treasury.external_guard','family':'F','source':'Treasury','target':'Guard','cardinality':'N','read':{'kind':'fields','path':'external_guards'},'retention':'complete','evidence':'treasury.move\x20L72-83','bridgeIds':['b10'],'zh':'金库外部存取\x20Guard'}],R_EDGES=[{'id':'eoa.permission','family':'R','source':EOA,'target':'Permission','cardinality':'N','read':{'kind':'reverse','parent':'0xaaad'},'retention':'membership','evidence':'entity_permission.move\x20L32\x20(bits\x201/2/4)','bridgeIds':['b09'],'zh':'账号当前参与的权限组(成员关系,移除即消失)'},{'id':'eoa.order','family':'R','source':EOA,'target':'Order','cardinality':'N','read':{'kind':'reverse','parent':'0xaa8'},'retention':'bounded_window','evidence':'entity_order.move\x20L31\x20(FIFO\x205200)','bridgeIds':['b01'],'zh':'账号作为买家/代理人参与的订单(买家视角,FIFO\x205200)'},{'id':'eoa.contact','family':'R','source':EOA,'target':'Contact','cardinality':'N','read':{'kind':'reverse','parent':'0xaa9'},'retention':'membership','evidence':'entity_contact.move\x20L24','bridgeIds':['b11'],'zh':'账号当前加入的客服会员簿'},{'id':'permission.core_binding','family':'R','source':'Permission','target':ANY,'cardinality':'N','read':{'kind':'reverse','parent':'0xaae'},'retention':'bounded_exact','evidence':'object_linker.move\x20L37,L88\x20(≤5200\x20aborts)','bridgeIds':['b09'],'zh':'权限组无损挂接的核心对象(Service/Demand/Machine/…)'},{'id':'permission.tx_binding','family':'R','source':'Permission','target':ANY,'cardinality':'N','read':{'kind':'reverse','parent':'0xaaf'},'retention':'bounded_window','evidence':'object_linker.move\x20L43\x20(FIFO\x205200\x20operational)','bridgeIds':['b09'],'zh':'权限组运行期触碰对象(FIFO\x205200\x20下界)'},{'id':'service.order','family':'R','source':'Service','target':'Order','cardinality':'N','read':{'kind':'reverse','parent':'0xaaf','filterType':'Order'},'retention':'bounded_window','evidence':'object_linker.move\x20L43,L136-140\x20(FIFO\x205200)','bridgeIds':['b01'],'zh':'店铺订单(商家视角权威路径,FIFO\x205200\x20下界;全量走事件通道)'},{'id':'target.vote','family':'S','source':ANY,'target':EOA,'cardinality':'N','read':{'kind':'reverse','parent':'0xaaa'},'retention':'bounded_window','evidence':'registrar.move\x20L154-171\x20(ring\x205200,\x20bits\x200x02/0x04/0x08)','zh':'目标地址收到的\x20like/dislike/favor\x20投票(环形\x205200)'}],TABLE_EDGES=[{'id':'permission.entity','family':'R','source':'Permission','target':ANY,'cardinality':'N','read':{'kind':'table','rowType':'PermissionPerm'},'retention':'membership','evidence':'permission.move\x20L34-42\x20(entity\x20may\x20be\x20EOA\x20or\x20Guard\x20address)','bridgeIds':['b04','b09'],'zh':'权限组实体表成员(EOA\x20或\x20Guard,携带\x20perm\x20索引位)'},{'id':'demand.presenter','family':'R','source':'Demand','target':EOA,'cardinality':'N','read':{'kind':'table','rowType':'DemandPresenter'},'retention':'membership','evidence':'demand.move\x20L68-77\x20(presenters\x20table)','bridgeIds':['b03'],'zh':'向需求提案的供应方及\x20acceptance_score'},{'id':'machine.node','family':'W','source':'Machine','target':'MachineNode','cardinality':'N','read':{'kind':'table','rowType':'MachineNode'},'retention':'complete','evidence':'machine.move\x20L299-308\x20(immutable\x20after\x20publish)','bridgeIds':['b04'],'contract':{'field':'nodes','frozenWhen':'after\x20publish','forbiddenActions':['add','remove','update'],'allowedActions':[],'unfreeze':null,'moveAnchor':'machine.move\x20node_add_imp\x20/\x20node_remove_imp\x20/\x20node_rename_imp\x20(assert_not_published)'},'zh':'工作流节点表(发布后不可变)'}],W_EDGES=[{'id':'wf.transition','family':'W','source':'MachineNode','target':'MachineNode','cardinality':'N','read':{'kind':'derived','producer':'machineRows'},'retention':'derived','evidence':'machine.move\x20L101\x20NodePair,L269','bridgeIds':['b04'],'zh':'节点对有向边(prev_node→node,携带\x20threshold)'},{'id':'wf.forward_guard','family':'W','source':'MachineNode','target':'Guard','cardinality':'N','read':{'kind':'derived','producer':'machineRows'},'retention':'derived','evidence':'machine.move\x20L63\x20Forward','bridgeIds':['b04','b05','b10','b12'],'zh':'节点前进操作的后置\x20Guard(供应链/赔付分账挂点)'}],M_EDGES=[{'id':'payment.recipient','family':'M','source':'Payment','target':EOA,'cardinality':'N','read':{'kind':'structFields','path':'record','field':'recipient'},'retention':'complete','evidence':'payment.move\x20L93-101\x20(Revenue≤200)','bridgeIds':['b05','b08'],'zh':'支付分账收款人(携带金额,逐腿)'},{'id':'payment.from_object','family':'M','source':'Payment','target':ANY,'cardinality':'0..1','read':{'kind':'field','path':'from_object'},'retention':'complete','evidence':'payment.move\x20L149-161\x20(framework-only)','bridgeIds':['b05','b08'],'zh':'资金来源池(Treasury/Allocation/Service,仅框架可设)'},{'id':'payment.for_object','family':'M','source':'Payment','target':ANY,'cardinality':'0..1','read':{'kind':'field','path':'info.for_object'},'retention':'complete','evidence':'payment.move\x20L93-101\x20(info\x20routing\x20hint)','bridgeIds':['b05','b08'],'zh':'业务路由对象(用户可设)'},{'id':'payment.for_guard','family':'M','source':'Payment','target':'Guard','cardinality':'0..1','read':{'kind':'field','path':'info.for_guard'},'retention':'complete','evidence':'payment.move\x20L93-101','bridgeIds':['b05'],'zh':'业务路由\x20Guard'}];export const EDGE_SCHEMAS=[...F_EDGES,...R_EDGES,...TABLE_EDGES,...W_EDGES,...M_EDGES];export const EDGE_SCHEMA_BY_ID=new Map(EDGE_SCHEMAS['map'](a=>[a['id'],a]));export function outgoingSchemaIds(a){return EDGE_SCHEMAS['filter'](b=>b['source']===a||b['source']===ANY)['map'](b=>b['id']);}export const COVERED_OBJECT_TYPES=[...new Set(EDGE_SCHEMAS['flatMap'](a=>[a['source'],a['target']])['filter'](a=>a!==EOA&&a!==ANY&&a!=='MachineNode'))];
@@ -0,0 +1,4 @@
1
+ import type { DataPlane, ExpandOptions, TopologyGraph } from "./types.js";
2
+ import { type CompletionResult } from "./order-status.js";
3
+ export declare function expandTopology(plane: DataPlane, opts: ExpandOptions): Promise<TopologyGraph>;
4
+ export declare function orderCompletionInGraph(graph: TopologyGraph, orderId: string): CompletionResult;
@@ -0,0 +1 @@
1
+ import{EDGE_SCHEMAS,EDGE_SCHEMA_BY_ID}from'./edge-schema.js';import{extractCoinType,extractObjectEdges,extractReverseRefs,extractTableRefs,inferObjectType}from'./extract.js';import{mergeBudget}from'./dataplane.js';import{deriveOrderCompletion,terminalNamesOfEdges}from'./order-status.js';const WINDOW_RING_LIMIT=0x1450;function readStats(a){const b=a;if(b['stats'])return{'batches':b['stats']['batches'],'byChannel':{...b['stats']['byChannel']},'dedupHits':b['stats']['dedupHits']};if(b['batches'])return{'batches':Object['values'](b['batches'])['reduce']((c,d)=>c+d,0x0),'byChannel':{...b['batches']},'dedupHits':b['dedupHits']??0x0};return{'batches':0x0,'byChannel':{'objects':0x0,'keyedFields':0x0,'tables':0x0,'events':0x0},'dedupHits':0x0};}function firstByte(a){return parseInt(a['slice'](0x2,0x4),0x10);}function isEoa(a){return firstByte(a)===0x0;}function isWfNodeId(a){return a['includes']('::node::');}class Gate{['wl'];constructor(a){this['wl']=a;}['allows'](a,b){if(this['wl']['deny']?.['includes'](a['id']))return![];const c=this['wl']['familyDepths']?.[a['family']];if(c!==undefined&&b>=c)return![];if(this['wl']['schemas'])return this['wl']['schemas']['includes'](a['id']);if(this['wl']['families']&&!this['wl']['families']['includes'](a['family']))return![];return!![];}['allowsTable'](a,b){return a['read']['kind']==='table'&&this['allows'](a,b)&&!!this['wl']['tableEdges']?.['includes'](a['id']);}}class GraphBuilder{['graph'];['edgeIds']=new Set();['budget'];['exhausted']={};constructor(a,b,c){this['budget']=c,this['graph']={'network':a,'seed':b,'builtAt':Date['now'](),'nodes':new Map(),'edges':[],'out':new Map(),'inc':new Map(),'gaps':[],'truncations':[],'rpcReport':{'batches':0x0,'byChannel':{'objects':0x0,'keyedFields':0x0,'tables':0x0,'events':0x0},'dedupHits':0x0},'budgetExhausted':{}};}['addSeed'](a){const b=inferObjectType(a),c={'id':a,'kind':isWfNodeId(a)?'wfnode':isEoa(a)?'eoa':'object','objectType':b??undefined,'state':'seed','origins':[],'depth':0x0};return this['graph']['nodes']['set'](a,c),c;}['addNode'](a,b,c){const d=this['graph']['nodes']['get'](a);if(d){if(c)d['origins']['push']({'via':c['schema'],'from':c['from'],'depth':b});return d;}if(this['graph']['nodes']['size']>=this['budget']['maxNodes'])return this['exhausted']['nodes']=!![],undefined;const e=isWfNodeId(a),f=e?undefined:inferObjectType(a),g={'id':a,'kind':e?'wfnode':isEoa(a)?'eoa':'object','objectType':f??undefined,'state':e?'stub':'seed','origins':c?[{'via':c['schema'],'from':c['from'],'depth':b}]:[],'depth':b};return this['graph']['nodes']['set'](a,g),g;}['addEdge'](a,b,c,d,e){const f=c['to'],g=c['key']?'|'+c['key']:'',h=a['id']+'|'+b+'→'+f+g;if(this['edgeIds']['has'](h))return;this['edgeIds']['add'](h);const i={'id':h,'schema':a['id'],'family':a['family'],'from':b,'to':f,'retention':a['retention'],'evidence':a['evidence'],'observedAt':d,'payload':c['payload'],'truncated':e||a['retention']==='bounded_window','key':c['key']};this['graph']['edges']['push'](i),pushMap(this['graph']['out'],b,i),pushMap(this['graph']['inc'],f,i);}['markTruncation'](a){this['graph']['truncations']['push'](a);}['finalize'](a){return this['graph']['rpcReport']=readStats(a),this['graph']['budgetExhausted']=this['exhausted'],this['graph'];}}function pushMap(a,b,c){const d=a['get'](b);if(d)d['push'](c);else a['set'](b,[c]);}export async function expandTopology(a,c){const d=c['seed']['toLowerCase'](),e=mergeBudget(c['budget']),f=new Gate(c['edges']??{}),h=new GraphBuilder(c['network'],d,e);h['addSeed'](d);const i=new Set(),j=new Set(),l=new Set();let m=new Set([d]);for(let n=0x0;n<=e['maxDepth'];n++){if(m['size']===0x0)break;if(h['exhausted']['nodes'])break;const o=Date['now'](),p=[...m]['filter'](y=>{const z=h['graph']['nodes']['get'](y);return z['kind']==='object'&&(z['state']==='seed'||z['state']==='stub')&&!i['has'](y);}),q=new Set();if(p['length']>0x0){const y=await a['getObjects'](p);if(readStats(a)['batches']>=e['maxRpcs'])h['exhausted']['rpcs']=!![];for(const z of p){const A=h['graph']['nodes']['get'](z),B=lookupMapLower(y,z);i['add'](z);if(!B){A['state']='error',A['error']='not_found_or_failed',h['graph']['gaps']['push'](z);continue;}A['state']='fetched',A['raw']=B,A['objectType']=String(B['type']??A['objectType']??inferObjectType(z)??''),A['coinType']=extractCoinType(B['type_raw']),q['add'](z);}}const r=[];for(const C of q){const D=h['graph']['nodes']['get'](C);if(!D['objectType']||!D['raw'])continue;for(const E of extractObjectEdges(D['objectType'],D['raw'])){const F=EDGE_SCHEMA_BY_ID['get'](E['schemaId']);if(!F||!f['allows'](F,n))continue;r['push']({'schema':F,'sourceId':C,'refs':E['refs'],'observed':E['refs']['length']});}}const s=[...q]['filter'](G=>{const H=h['graph']['nodes']['get'](G);return EDGE_SCHEMAS['some'](I=>I['source']===H['objectType']&&I['read']['kind']==='table');});for(const G of s){const H=h['graph']['nodes']['get'](G);for(const I of EDGE_SCHEMAS){if(I['source']!==H['objectType']||!f['allowsTable'](I,n))continue;const J=G+'|'+I['id'];if(l['has'](J))continue;l['add'](J);const K=e['perKindCaps'][I['id']]??e['maxFanoutPerNode'];try{const {items:L,truncated:M}=await a['getTable'](G,{'maxItems':K});if(readStats(a)['batches']>=e['maxRpcs'])h['exhausted']['rpcs']=!![];const N=extractTableRefs(I['id'],G,L);for(const O of N){const P=EDGE_SCHEMA_BY_ID['get'](O['schemaId']);r['push']({'schema':P,'sourceId':G,'refs':O['refs'],'observed':O['refs']['length']});}if(M)h['markTruncation']({'nodeId':G,'schema':I['id'],'observed':L['length'],'limit':K});}catch{h['graph']['gaps']['push'](G+'#'+I['id']);}}}const t=[...m]['filter'](Q=>{const R=h['graph']['nodes']['get'](Q);return R['kind']!=='wfnode'&&(R['kind']==='eoa'||R['state']==='fetched');}),u=new Map(),v=new Map();for(const Q of t){const R=h['graph']['nodes']['get'](Q);for(const S of EDGE_SCHEMAS){if(S['read']['kind']!=='reverse'||!f['allows'](S,n))continue;if(!sourceMatches(S['source'],R))continue;const T=S['read']['parent'],U=Q+'|'+T;if(j['has'](U))continue;if(!u['has'](T))u['set'](T,[]);u['get'](T)['push'](Q);const V=Q+'|'+T+'|schema',W=v['get'](V)??[];W['push'](S),v['set'](V,W);}}for(const [X,Y]of u){for(const a0 of Y)j['add'](a0+'|'+X);let Z=new Map();try{Z=await a['getKeyedFields'](X,Y);if(readStats(a)['batches']>=e['maxRpcs'])h['exhausted']['rpcs']=!![];}catch{h['graph']['gaps']['push']('reverse:'+X);continue;}for(const a1 of Y){const a2=v['get'](a1+'|'+X+'|schema')??[],a3=lookupMapLower(Z,a1);if(!a3)continue;const a4=extractReverseRefs(X,a3['data']??a3);for(const a5 of a2){const a6=a5['read'];let a7=a4;a6['kind']==='reverse'&&a6['filterType']&&(a7=a4['filter'](a8=>inferObjectType(a8['to'])===a6['filterType']));if(a7['length']===0x0)continue;r['push']({'schema':a5,'sourceId':a1,'refs':a7,'observed':a7['length']});}}}const w=new Set(),x=new Map();for(const a8 of r){const a9=e['perKindCaps'][a8['schema']['id']]??e['maxFanoutPerNode'],aa=x['get'](a8['sourceId'])??0x0,ab=Math['max'](0x0,e['maxFanoutPerNode']-aa),ac=Math['min'](a9,ab),ad=a8['refs']['slice'](0x0,ac);a8['refs']['length']>ac&&h['markTruncation']({'nodeId':a8['sourceId'],'schema':a8['schema']['id'],'observed':a8['refs']['length'],'limit':WINDOW_RING_LIMIT});for(const ae of ad){const af=ae['from']??a8['sourceId'],ag=isWfNodeId(ae['to'])?n:n+0x1,ah=h['graph']['nodes']['has'](ae['to']);if(ag>e['maxDepth']&&!ah){h['exhausted']['depth']=!![];continue;}const ai=h['addNode'](ae['to'],Math['min'](ag,e['maxDepth']),{'schema':a8['schema']['id'],'from':af});if(!ai)break;h['addEdge'](a8['schema'],af,ae,o,a8['refs']['length']>ac),x['set'](a8['sourceId'],aa+0x1);if(!isWfNodeId(ae['to'])&&ag<=e['maxDepth'])w['add'](ae['to']);}}if(h['exhausted']['rpcs']){h['graph']['gaps']['push']('budget:maxRpcs');break;}m=w;}return h['finalize'](a);}function sourceMatches(a,b){if(a==='ANY')return!![];if(a==='EOA')return b['kind']==='eoa';return b['objectType']===a;}function lookupMapLower(a,b){const c=a['get'](b);if(c!==undefined)return c;for(const [d,e]of a)if(d['toLowerCase']()===b)return e;return undefined;}export function orderCompletionInGraph(a,b){const c=a['nodes']['get'](b['toLowerCase']()),d=c?.['raw']?.['data']??c?.['raw']??{},e=String(d['machine']??''),f=String(d['progress']??''),g=a['nodes']['get'](f['toLowerCase']()),h=String((g?.['raw']?.['data']??g?.['raw']??{})['current']??'');let i=null;if(e){const j=e['toLowerCase']()+'::node::',k=a['edges']['filter'](l=>l['schema']==='wf.transition'&&l['from']['startsWith'](j))['map'](l=>({'node':l['payload']?.['node'],'prev_node':l['payload']?.['prevNode']}));if(k['length']>0x0)i=terminalNamesOfEdges(k);}return deriveOrderCompletion({'machine':e||null,'progress':f||null,'currentNode':h||null,'terminalNames':i});}
@@ -0,0 +1,21 @@
1
+ import { type EdgeSchema } from "./edge-schema.js";
2
+ import type { RawObject, TableItem, TopoEdgePayload } from "./types.js";
3
+ export declare function normAddr(v: unknown): string | undefined;
4
+ export declare function rootOf(raw: RawObject | undefined): Record<string, unknown>;
5
+ export interface RawRef {
6
+ to: string;
7
+ from?: string;
8
+ payload?: TopoEdgePayload;
9
+ key?: string;
10
+ }
11
+ export interface ExtractedEdges {
12
+ schemaId: string;
13
+ refs: RawRef[];
14
+ }
15
+ export declare function wfNodeId(machine: string, name: string): string;
16
+ export declare function extractReverseRefs(parent: string, field: unknown): RawRef[];
17
+ export declare function extractTableRefs(schemaId: string, sourceId: string, items: TableItem[]): ExtractedEdges[];
18
+ export declare function inferObjectType(addr: string): string | undefined;
19
+ export declare function extractCoinType(typeRaw: unknown): string | undefined;
20
+ export declare function extractObjectEdges(objectType: string, raw: RawObject): ExtractedEdges[];
21
+ export declare function schemaById(id: string): EdgeSchema | undefined;
@@ -0,0 +1 @@
1
+ import{objectTypeFromAddress}from'@wowok/wowok';import{EDGE_SCHEMAS}from'./edge-schema.js';const ADDR_RE=/^0x[0-9a-f]{64}$/;export function normAddr(a){if(typeof a!=='string')return undefined;const b=a['trim']()['toLowerCase']();return ADDR_RE['test'](b)?b:undefined;}export function rootOf(a){const b=a;return b?.['data']??b??{};}function dig(a,b){return b['split']('.')['reduce']((c,d)=>{if(c==null)return undefined;return c[d];},a);}function asArray(a){if(Array['isArray'](a))return a;if(a==null)return[];return[a];}function addrOf(a,b){if(typeof a==='string')return normAddr(a);if(a&&typeof a==='object'){const c=a;return normAddr(c[b]??c['guard']??c['address']??c['who']);}return undefined;}function deepAddrs(b,c,d){let e=b;for(const g of c){if(Array['isArray'](e))e=e['flatMap'](h=>asArray(h?.[g]));else e&&typeof e==='object'?e=e[g]:e=undefined;}const f=[];for(const h of asArray(e)){if(typeof h==='string'){const i=normAddr(h);if(i)f['push']({'addr':i,'item':{}});}else{if(h&&typeof h==='object'){const j=h,k=addrOf(j,d||'guard');if(k)f['push']({'addr':k,'item':j});}}}return f;}export function wfNodeId(a,b){return(normAddr(a)??a['toLowerCase']())+'::node::'+b;}function strAmt(a){if(a==null)return undefined;if(typeof a==='bigint')return a['toString']();const b=String(a);return b===''?undefined:b;}function extractFieldEdges(b,c,d){const e=rootOf(c),f=[];for(const g of EDGE_SCHEMAS){if(g['source']!==b)continue;const i=g['read'];if(i['kind']==='reverse'||i['kind']==='table'||i['kind']==='derived')continue;let j=[];switch(i['kind']){case'field':{const k=addrOf(dig(e,i['path']),'guard');if(k)j=[{'to':k}];break;}case'fields':{j=asArray(dig(e,i['path']))['map'](l=>addrOf(l,'guard'))['filter'](l=>!!l)['map'](l=>({'to':l}));break;}case'structFields':{j=asArray(dig(e,i['path']))['map'](l=>{const m=addrOf(l,i['field']);if(!m)return undefined;const n=typeof l==='object'&&l?l:{};return{'to':m,'payload':payloadFor(g['id'],n,d)};})['filter'](l=>!!l);break;}case'deep':{if(g['id']==='progress.named_operator'){const l=asArray(e['namedOperator']);for(const m of l){const n=m??{};for(const p of asArray(n['operators'])){const q=normAddr(p);if(q)j['push']({'to':q,'key':String(n['name']??''),'payload':{'namedOperator':n['name']!=null?String(n['name']):null}});}}}else j=deepAddrs(e,i['segments'],i['field'])['map'](({addr:r,item:s})=>({'to':r,'payload':payloadFor(g['id'],s,d)}));break;}}g['family']==='M'&&d&&(j=j['map'](s=>({...s,'payload':{'coinType':d,...s['payload']}})));if(j['length']>0x0)f['push']({'schemaId':g['id'],'refs':j});}return f;}function payloadFor(a,b,c){switch(a){case'payment.recipient':{const d=strAmt(b['amount']);return d!=null?{'amount':d,'coinType':c}:undefined;}case'arb.voter':return{'weight':Number(b['weight']??0x0)||undefined};case'allocation.guard':case'service.order_allocator_guard':return b['mode']!=null?{'mode':clampMode(Number(b['mode']))}:undefined;default:return undefined;}}function clampMode(a){return a===0x1||a===0x2?a:0x0;}export function extractReverseRefs(a,b){const c=b??{},e=[];if(a==='0xaaa'){for(const f of asArray(c['votes'])){const g=f??{},h=normAddr(g['who']);if(!h)continue;e['push']({'to':h,'payload':{'voteBits':(g['like']?0x2:0x0)|(g['dislike']?0x4:0x0)|(g['favor']?0x8:0x0),'voteLike':!!g['like'],'voteDislike':!!g['dislike'],'voteFavor':!!g['favor']}});}return e;}for(const i of asArray(c['items'])){const j=i??{},k=normAddr(j['permission']??j['contact']??j['order']??j['who']);if(!k)continue;const l=j['role']!=null?Number(j['role']):undefined;e['push']({'to':k,'payload':l!=null?{'roleBits':l}:undefined});}return e;}export function extractTableRefs(a,b,c){switch(a){case'permission.entity':{const e=[];for(const f of c){const g=rootOf(f['object']),h=normAddr(g['address']),i=Array['isArray'](g['perm'])?g['perm']['map'](Number):[];if(h)e['push']({'to':h,'payload':{'permIndices':i}});}return e['length']?[{'schemaId':a,'refs':e}]:[];}case'demand.presenter':{const j=[];for(const k of c){const l=rootOf(k['object']),m=normAddr(l['address']);if(!m)continue;j['push']({'to':m,'payload':{'service':normAddr(l['service'])??undefined,'score':l['acceptance_score']!=null?Number(l['acceptance_score']):undefined,'recommend':l['recommend']!=null?String(l['recommend']):undefined}});}return j['length']?[{'schemaId':a,'refs':j}]:[];}case'machine.node':return extractMachineTable(b,c);default:return[];}}function extractMachineTable(a,b){const c=[],e=[],g=[],h=new Set(),i=k=>{const l=String(k??'')['trim']();if(!l)return undefined;const m=wfNodeId(a,l);return!h['has'](m)&&(h['add'](m),c['push']({'to':m,'key':l,'payload':{'node':l}})),m;};for(const k of b){const l=rootOf(k['object']),m=String(l['name']??''),n=i(m);if(!n)continue;for(const o of asArray(l['value'])){const q=o??{},r=String(q['prev_node']??'')['trim']();if(r)i(r);const s=r?wfNodeId(a,r):undefined,t=Number(q['threshold']??0x0);for(const u of asArray(q['forwards'])){const v=u??{},w=String(v['name']??''),x=addrOf(v['guard'],'guard');s&&e['push']({'from':s,'to':n,'key':w||undefined,'payload':{'forward':w||undefined,'prevNode':r||undefined,'node':m,'threshold':t||undefined,'guard':x??undefined,'weight':Number(v['weight']??0x0)||undefined,'namedOperator':v['namedOperator']!=null?String(v['namedOperator']):null,'permissionIndex':v['permissionIndex']!=null?Number(v['permissionIndex']):null}}),x&&g['push']({'to':x,'key':w||undefined,'payload':{'forward':w||undefined,'weight':Number(v['weight']??0x0)||undefined,'namedOperator':v['namedOperator']!=null?String(v['namedOperator']):null,'permissionIndex':v['permissionIndex']!=null?Number(v['permissionIndex']):null}});}}}const j=[];if(c['length'])j['push']({'schemaId':'machine.node','refs':c});if(e['length'])j['push']({'schemaId':'wf.transition','refs':e});if(g['length'])j['push']({'schemaId':'wf.forward_guard','refs':g});return j;}export function inferObjectType(a){return objectTypeFromAddress(a)??undefined;}export function extractCoinType(a){if(typeof a!=='string'||!a['includes']('<'))return undefined;const b=a['slice'](a['indexOf']('<')+0x1,a['lastIndexOf']('>'));return b['trim']()||undefined;}export function extractObjectEdges(a,b){return extractFieldEdges(a,b,extractCoinType(b['type_raw']));}export function schemaById(a){return EDGE_SCHEMAS['find'](b=>b['id']===a);}
@@ -0,0 +1,17 @@
1
+ export * from "./types.js";
2
+ export * from "./edge-schema.js";
3
+ export * from "./extract.js";
4
+ export * from "./order-status.js";
5
+ export { MAX_OBJECTS_PER_QUERY, DEFAULT_BUDGET, mergeBudget, chunk50, mapPool, FakeDataPlane } from "./dataplane.js";
6
+ export type { FakePlaneState } from "./dataplane.js";
7
+ export { SdkDataPlane } from "./sdk-dataplane.js";
8
+ export * from "./sdk-batch.js";
9
+ export { expandTopology, orderCompletionInGraph } from "./expand.js";
10
+ export { TOPOLOGY_INTENTS, INTENT_PRESETS, resolveExpansionStrategy, isTopologyIntent, normalizeTopologyFocusPref, type TopologyIntent, type IntentPreset, type StrategyFragment, type ExpansionStrategy, type StrategyResolutionInput, type ExplicitExpansionParams, type TopologyFocusPref, } from "./strategy.js";
11
+ export { detectFakeOrders, detectFakeReviews, detectShellMerchant, reputationTradeNote, assessAntiCheat, } from "./anti-cheat.js";
12
+ export type { AntiCheatSeverity, AntiCheatSignal, OrderEvidence, ReviewEvidence, MerchantEvidence, } from "./anti-cheat.js";
13
+ export { buildViewport, edgesOut, edgesInc, nodeOf } from "./viewport.js";
14
+ export { buildRoleInterest, toCommercialRole, viewerRoleOf, type RoleInterestResult, } from "./interest.js";
15
+ export { buildControlIndex } from "./analyze.js";
16
+ export { projectRelationshipFacts } from "./project-relationship.js";
17
+ export { DEFAULT_ANALYZERS, registerAnalyzer, getAnalyzer, listAnalyzers, runAnalyzers, adaptNodeAnalyzer, runNodeAnalyzers, pathConfidence, type NodeRuleBinding, type NodeRuleOutcome, } from "./analyze.js";
@@ -0,0 +1 @@
1
+ export*from'./types.js';export*from'./edge-schema.js';export*from'./extract.js';export*from'./order-status.js';export{MAX_OBJECTS_PER_QUERY,DEFAULT_BUDGET,mergeBudget,chunk50,mapPool,FakeDataPlane}from'./dataplane.js';export{SdkDataPlane}from'./sdk-dataplane.js';export*from'./sdk-batch.js';export{expandTopology,orderCompletionInGraph}from'./expand.js';export{TOPOLOGY_INTENTS,INTENT_PRESETS,resolveExpansionStrategy,isTopologyIntent,normalizeTopologyFocusPref}from'./strategy.js';export{detectFakeOrders,detectFakeReviews,detectShellMerchant,reputationTradeNote,assessAntiCheat}from'./anti-cheat.js';export{buildViewport,edgesOut,edgesInc,nodeOf}from'./viewport.js';export{buildRoleInterest,toCommercialRole,viewerRoleOf}from'./interest.js';export{buildControlIndex}from'./analyze.js';export{projectRelationshipFacts}from'./project-relationship.js';export{DEFAULT_ANALYZERS,registerAnalyzer,getAnalyzer,listAnalyzers,runAnalyzers,adaptNodeAnalyzer,runNodeAnalyzers,pathConfidence}from'./analyze.js';
@@ -0,0 +1,10 @@
1
+ import { type CommercialRole } from "../../role/types.js";
2
+ import { type PersonaDrive } from "../../evaluation/game-strategy.js";
3
+ import type { Finding, InterestPayload, TopologyGraph, ViewerRole } from "./types.js";
4
+ export declare function toCommercialRole(role: string): CommercialRole;
5
+ export declare function viewerRoleOf(role: CommercialRole): ViewerRole;
6
+ export interface RoleInterestResult {
7
+ finding: Finding;
8
+ view: InterestPayload;
9
+ }
10
+ export declare function buildRoleInterest(graph: TopologyGraph, observerInput: string, role: CommercialRole, drive?: PersonaDrive): RoleInterestResult;