@wowok/agent-mcp 3.2.2 → 3.2.3
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.
- package/dist/chain-semantics/field-capability.d.ts +11 -0
- package/dist/chain-semantics/field-capability.js +1 -0
- package/dist/chain-semantics/freeze-map.d.ts +11 -0
- package/dist/chain-semantics/freeze-map.js +1 -0
- package/dist/chain-semantics/fund-flow.d.ts +10 -0
- package/dist/chain-semantics/fund-flow.js +1 -0
- package/dist/chain-semantics/guard-verbs.d.ts +22 -0
- package/dist/chain-semantics/guard-verbs.js +1 -0
- package/dist/chain-semantics/index.d.ts +10 -0
- package/dist/chain-semantics/index.js +1 -0
- package/dist/chain-semantics/object-graph.d.ts +18 -0
- package/dist/chain-semantics/object-graph.js +1 -0
- package/dist/composition/audit.d.ts +10 -0
- package/dist/composition/audit.js +1 -0
- package/dist/composition/compile.d.ts +38 -0
- package/dist/composition/compile.js +1 -0
- package/dist/composition/materialize.d.ts +64 -0
- package/dist/composition/materialize.js +1 -0
- package/dist/composition/plan.d.ts +92 -0
- package/dist/composition/plan.js +1 -0
- package/dist/composition/reflux.d.ts +28 -0
- package/dist/composition/reflux.js +1 -0
- package/dist/evaluation/builtins/graph-service.spec.js +1 -1
- package/dist/evaluation/engine.js +1 -1
- package/dist/experience/realtime-feedback.js +1 -1
- package/dist/extensions/business-modules.js +1 -1
- package/dist/extensions/industry-pack.js +1 -1
- package/dist/extensions/modes.js +1 -1
- package/dist/graph/onchain/expand.js +1 -1
- package/dist/graph/onchain/exposure.js +1 -1
- package/dist/graph/onchain/facts.js +1 -1
- package/dist/keeper/detectors.d.ts +7 -0
- package/dist/keeper/detectors.js +1 -1
- package/dist/keeper/types.d.ts +1 -1
- package/dist/keeper/types.js +1 -1
- package/dist/knowledge/allocation-ledger.js +1 -1
- package/dist/knowledge/allocation-puzzle.js +1 -1
- package/dist/knowledge/allocation-risk.js +1 -1
- package/dist/knowledge/allocation-templates.js +1 -1
- package/dist/knowledge/arb-fund-facts.d.ts +31 -0
- package/dist/knowledge/arb-fund-facts.js +1 -0
- package/dist/knowledge/baselines/rules/allocation.json +44 -15
- package/dist/knowledge/baselines/rules/guard.json +27 -8
- package/dist/knowledge/baselines/rules/plan.json +161 -0
- package/dist/knowledge/baselines/semantic-facts.d.ts +12 -0
- package/dist/knowledge/baselines/semantic-facts.js +1 -0
- package/dist/knowledge/builtin-templates.d.ts +1 -1
- package/dist/knowledge/builtin-templates.js +1 -1
- package/dist/knowledge/getting-started.js +1 -1
- package/dist/knowledge/guard-design-patterns.js +1 -1
- package/dist/knowledge/guard-ledger.js +1 -1
- package/dist/knowledge/guard-risk.js +1 -1
- package/dist/knowledge/guard-templates.js +1 -1
- package/dist/knowledge/index.js +1 -1
- package/dist/knowledge/industry-registry.js +1 -1
- package/dist/knowledge/jsonrpc-enum.js +1 -1
- package/dist/knowledge/onchain-constants.d.ts +2 -2
- package/dist/knowledge/onchain-constants.js +1 -1
- package/dist/knowledge/scenario-modes.d.ts +12 -0
- package/dist/knowledge/service-allocation-semantics.js +1 -1
- package/dist/knowledge/service-ledger.js +1 -1
- package/dist/knowledge/service-templates.js +1 -1
- package/dist/knowledge/strategy-manuals.js +1 -1
- package/dist/knowledge/template-loader.d.ts +16 -1
- package/dist/knowledge/template-loader.js +1 -1
- package/dist/knowledge/template-registry.js +1 -1
- package/dist/knowledge/template-scanner.js +1 -1
- package/dist/knowledge/tools-reference.js +1 -1
- package/dist/knowledge/workflow-guidance.js +1 -1
- package/dist/monitor/MonitorLoop.js +1 -1
- package/dist/participation/radar-core.d.ts +6 -0
- package/dist/participation/radar-core.js +1 -1
- package/dist/playbooks/service-build/business-puzzle.js +1 -1
- package/dist/playbooks/service-build/machine-panorama.js +1 -1
- package/dist/playbooks/service-build/merchant-guide.js +1 -1
- package/dist/playbooks/service-build/migration-planner.js +1 -1
- package/dist/playbooks/service-build/object-panorama.js +1 -1
- package/dist/playbooks/service-build/participation-radar.js +1 -1
- package/dist/playbooks/service-build/relationship-profile.js +1 -1
- package/dist/playbooks/service-build/service-panorama.js +1 -1
- package/dist/playbooks/service-build/service-quote.js +1 -1
- package/dist/review/index.js +1 -1
- package/dist/safety/confirm-gate.js +1 -1
- package/dist/schema/call/order.d.ts +60 -0
- package/dist/schema/call/order.js +1 -1
- package/dist/schema/call/semantic.js +1 -1
- package/dist/schema/call/service.d.ts +56 -0
- package/dist/schema/call/service.js +1 -1
- package/dist/schema/common/index.js +1 -1
- package/dist/schema/index.d.ts +1 -0
- package/dist/schema/index.js +1 -1
- package/dist/schema/industry-pack/index.d.ts +2 -0
- package/dist/schema/industry-pack/index.js +1 -1
- package/dist/schema/local/index.js +1 -1
- package/dist/schema/operations.d.ts +48 -0
- package/dist/schema/query/index.js +1 -1
- package/dist/schema/schema-version.js +1 -1
- package/dist/schema/service-clone/index.d.ts +46 -0
- package/dist/schema/service-clone/index.js +1 -0
- package/dist/schema-query-impl/index.js +1 -1
- package/dist/schemas/index.json +7 -1
- package/dist/schemas/industry_pack_operation.output.json +4 -0
- package/dist/schemas/industry_pack_operation.schema.json +4 -0
- package/dist/schemas/onchain_operations.output.json +1 -1
- package/dist/schemas/onchain_operations.schema.json +405 -94
- package/dist/schemas/onchain_operations_allocation.schema.json +5 -5
- package/dist/schemas/onchain_operations_arbitration.schema.json +2 -2
- package/dist/schemas/onchain_operations_contact.schema.json +1 -1
- package/dist/schemas/onchain_operations_demand.schema.json +3 -3
- package/dist/schemas/onchain_operations_gen_passport.schema.json +1 -1
- package/dist/schemas/onchain_operations_guard.schema.json +59 -59
- package/dist/schemas/onchain_operations_machine.schema.json +1 -1
- package/dist/schemas/onchain_operations_order.schema.json +133 -1
- package/dist/schemas/onchain_operations_progress.schema.json +1 -1
- package/dist/schemas/onchain_operations_proof.schema.json +1 -1
- package/dist/schemas/onchain_operations_repository.schema.json +1 -1
- package/dist/schemas/onchain_operations_reward.schema.json +4 -4
- package/dist/schemas/onchain_operations_service.schema.json +186 -7
- package/dist/schemas/onchain_operations_treasury.schema.json +7 -7
- package/dist/schemas/query_toolkit.output.json +45 -45
- package/dist/schemas/service_clone_operation.output.json +168 -0
- package/dist/schemas/service_clone_operation.schema.json +49 -0
- package/dist/schemas/workflow_operation.schema.json +1 -1
- package/dist/tools/handlers/config.js +1 -1
- package/dist/tools/handlers/industry-pack.js +1 -1
- package/dist/tools/handlers/onchain.js +1 -1
- package/dist/tools/handlers/query.js +1 -1
- package/dist/tools/handlers/service-clone.d.ts +2 -0
- package/dist/tools/handlers/service-clone.js +1 -0
- package/dist/tools/index.js +1 -1
- package/dist/tools/registry/business.js +1 -1
- package/dist/tools/wrap.d.ts +6 -1
- package/dist/tools/wrap.js +1 -1
- package/package.json +2 -2
package/dist/extensions/modes.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getScenarioMode}from'../knowledge/scenario-modes.js';import{getIndustryTraits}from'../knowledge/industry-registry.js';import{getIndustryRiskChecks,getIndustryNeeds}from'../customer/index.js';import{SUPPORTED_INDUSTRIES}from'../customer/user-preferences.js';import{getFlywheelForIndustry}from'../knowledge/acquisition-flywheel.js';const GENERAL_TRAITS={'has_logistics':![],'communication_heavy':![],'pure_digital':![],'long_cycle':![],'deposit_required':![],'multi_tier_allocation':![],'regulatory_intensity':'low','trust_sensitivity':'medium','consumption_frequency':'occasional','avg_ticket_size':'medium'},GENERAL_FLYWHEEL={'industry':'general','trustSellingPoints':[],'keyActions':[],'rewardStrategy':'User-defined','discountStrategy':'User-defined','trustDescription':'User-defined\x20trust\x20mechanism'},GENERAL_MACHINE_SHAPE=[{'name':'paid','role':'Entry:\x20order\x20created\x20and\x20paid'},{'name':'delivering','role':'Service\x20delivery\x20in\x20progress'},{'name':'delivered','role':'Deliverable\x20available\x20for\x20review'},{'name':'completed','role':'Service\x20completed,\x20funds\x20released'},{'name':'cancelled','role':'Pre-delivery\x20cancellation\x20—\x20triggers\x20refund\x20Allocator','operator':'order_payer'}],GENERAL_ALLOCATOR={'recipient':'signer','count':0x1,'mode':'surplus','description':'Default:\x20surplus\x20to\x20service\x20owner\x20(general\x20fallback)'},RETAIL_D2C_MACHINE_SHAPE=[{'name':'ordered','role':'Entry:\x20order\x20created\x20(funds\x20escrowed\x20in\x20Allocation)'},{'name':'shipped','role':'Merchant\x20ships\x20goods'},{'name':'delivered','role':'Goods\x20delivered\x20to\x20buyer'},{'name':'completed','role':'Buyer\x20confirms\x20receipt\x20—\x20withdraw_guard\x20releases\x20funds','operator':'order_payer'},{'name':'cancelled','role':'Pre-ship\x20cancellation\x20—\x20refund_guard\x20refunds\x20buyer','operator':'order_payer'}],RETAIL_D2C_GUARDS=[{'template_id':'withdraw_guard_delivery','host':'service','purpose':'Release\x20funds\x20to\x20merchant\x20+\x20processor\x20on\x20order\x20completion\x20(delivery\x20confirmation)'},{'template_id':'refund_guard_cancellation','host':'service','purpose':'Refund\x20100%\x20to\x20buyer\x20on\x20order\x20cancellation'}],RETAIL_D2C_ALLOCATOR={'recipient':'entity','count':0x2,'mode':'rate','description':'Merchant\x2097%\x20+\x20Processor\x203%\x20(rate-based\x20split,\x20no\x20platform\x20commission)'},RETAIL_D2C_KEY_RISK='No\x20platform\x20arbitration\x20—\x20disputes\x20rely\x20on\x20optional\x20Arbitration\x20or\x20off-chain\x20chargeback',RETAIL_D2C_BUILD_NOTES=['Allocation\x20escrow\x20replaces\x20platform\x20custody\x20—\x20funds\x20locked\x20in\x20contract\x20until\x20Guard\x20releases','withdraw_guard\x20enforces\x20delivery\x20gate\x20—\x20merchant\x20must\x20reach\x20\x27completed\x27\x20state\x20to\x20receive\x20payment','refund_guard\x20ensures\x20100%\x20refund\x20on\x20cancellation\x20—\x20no\x20merchant\x20approval\x20needed','No\x20buy_guard\x20needed\x20—\x20D2C\x20doesn\x27t\x20gate\x20purchases\x20(open\x20storefront)','Arbitration\x20is\x20optional\x20—\x20add\x20when\x20dispute\x20volume\x20justifies\x20the\x20cost','Service\x20↔\x20Guard\x20circular\x20dependency:\x20create\x20Service\x20(unpublished)\x20→\x20create\x20Guards\x20→\x20update\x20Service\x20(publish)'],SUPPORTED_INDUSTRY_SET=new Set([...SUPPORTED_INDUSTRIES,'retail_d2c']);function fetchTemplate(a){const b=a==='retail_d2c'?'retail':a,c=getIndustryTraits(b)??GENERAL_TRAITS,d=SUPPORTED_INDUSTRY_SET['has'](a),e=a==='retail_d2c'?'retail':a,f=d?getIndustryRiskChecks(e):[],g=d?getIndustryNeeds(e):[],h=getFlywheelForIndustry(b)??GENERAL_FLYWHEEL;let i,j,k,l,m;if(a==='retail_d2c')i=RETAIL_D2C_MACHINE_SHAPE,j=RETAIL_D2C_GUARDS,k=RETAIL_D2C_ALLOCATOR,l=RETAIL_D2C_KEY_RISK,m=RETAIL_D2C_BUILD_NOTES;else{if(a==='general'){const n=getScenarioMode('general');i=GENERAL_MACHINE_SHAPE,j=[],k=GENERAL_ALLOCATOR,l=n?.['key_risk']??'No\x20safety\x20net\x20—\x20user\x20must\x20design\x20all\x20trust\x20mechanisms\x20manually',m=n?.['build_notes'];}else{const o=getScenarioMode(a);if(!o)throw new Error('[modes.ts]\x20No\x20scenario\x20mode\x20found\x20for\x20industry:\x20'+a);i=o['machine_shape'],j=o['guards'],k=o['allocator'],l=o['key_risk'],m=o['build_notes'];}}return{'traits':c,'risk_checks':f,'needs':g,'flywheel':h,'machine_shape':i,'guards':j,'allocator':k,'key_risk':l,'build_notes':m};}export const BUILTIN_MODES=[{'name':'freelance','display_name':'Freelance','version':'v1','source':'builtin',...fetchTemplate('freelance'),'analyze':{'key_questions':['Are\x20WIP\x20hashes\x20bound\x20to\x20each\x20milestone,\x20so\x20delivery\x20evidence\x20cannot\x20be\x20substituted\x20after\x20acceptance?','Does\x20the\x20acceptance\x20gate\x20have\x20a\x20time-bounded\x20escape\x20(keeper-driven\x20auto-accept),\x20or\x20can\x20a\x20silent\x20buyer\x20hold\x20the\x20provider\x27s\x20funds\x20hostage\x20indefinitely?']},'capabilities_used':['permission.index_create','permission.role_assign','guard.validate_buy','guard.validate_wip_hash','machine.node_topology','treasury.owner_receive','allocation.distribute','allocation.distribute_milestone','service.publish','progress.advance','arb.vote_weighted','contact.im_create'],'config_overrides':{'service':{'setting_locked_time':'30d','engagement_type':'milestone'},'machine':{'wip_required':!![],'wip_hash_algorithm':'sha256','acceptance_gate':!![]}},'expected_benefits':[{'metric':'Dispute\x20rate\x20reduction','expected_value':'40%','evidence':'WIP\x20hash\x20+\x20milestone\x20allocation\x20enforces\x20delivery\x20evidence'},{'metric':'Delivery\x20confirmation\x20efficiency','expected_value':'+50%','evidence':'acceptance\x20gate\x20automates\x20acceptance\x20workflow'},{'metric':'Provider\x20payment\x20assurance','expected_value':'100%','evidence':'Funds\x20auto-release\x20to\x20provider\x20after\x20accepted\x20node'}],'risk_appetite':'balanced','risk_constraints':{'require_arbitration':!![],'require_compensation_fund':![],'require_wip_evidence':!![],'other_constraints':['setting_locked_time\x20>=\x207d\x20to\x20lock\x20engagement-period\x20rules','ISSUE-P1-4:\x2048h\x20auto-accept\x20requires\x20off-chain\x20keeper\x20(WoWok\x20Guard\x20does\x20not\x20support\x20time-based\x20triggers).\x20Deploy\x20a\x20keeper\x20service\x20that\x20polls\x20Progress\x20objects\x20in\x20\x27delivered\x27\x20state\x20and\x20calls\x20adminUnhold\x20(permission\x20224)\x20after\x2048h\x20timeout.\x20See\x20keeper\x20template\x20in\x20docs.']},'applicable_conditions':{'business_scale':'small','min_daily_orders':0x1,'other_conditions':['Suitable\x20for\x20mid-to-long-term\x20project\x20delivery','Requires\x20milestone-based\x20phased\x20acceptance']},'similar_industries':['rental','education'],'novel_capabilities':['allocation.distribute_milestone'],'disabled_builtin_constraints':['require_compensation_fund']},{'name':'rental','display_name':'Rental','version':'v1','source':'builtin',...fetchTemplate('rental'),'analyze':{'key_questions':['Is\x20the\x20deposit\x20escrowed\x20on-chain\x20and\x20sized\x20against\x20the\x20item\x27s\x20full\x20replacement\x20value,\x20not\x20just\x20the\x20rental\x20fee?','Are\x20pre-handover\x20and\x20post-return\x20WIP\x20states\x20hash-recorded,\x20so\x20damage\x20attribution\x20is\x20provable\x20rather\x20than\x20asserted?']},'capabilities_used':['permission.index_create','permission.role_assign','guard.validate_buy','guard.validate_wip_hash','machine.node_topology','treasury.owner_receive','allocation.distribute','service.publish','progress.advance','arb.vote_weighted','contact.im_create'],'config_overrides':{'treasury':{'deposit_escrow':!![],'deposit_deductible':!![]},'machine':{'wip_required':!![],'wip_stages':['handover_out','returned'],'inspection_gate':!![]}},'expected_benefits':[{'metric':'Deposit\x20dispute\x20rate','expected_value':'-60%','evidence':'pre-rental\x20WIP\x20mandatorily\x20records\x20item\x27s\x20original\x20state'},{'metric':'Damage\x20liability\x20accuracy','expected_value':'+70%','evidence':'pre/post\x20WIP\x20hash\x20comparison\x20eliminates\x20unfounded\x20deductions'},{'metric':'Trust\x20score','expected_value':'+25%','evidence':'compensation_fund\x20covers\x20damage\x20risk'}],'risk_appetite':'conservative','risk_constraints':{'require_arbitration':!![],'require_compensation_fund':!![],'require_wip_evidence':!![],'max_single_transaction':0x2710,'compensation_fund_coverage_ratio':0xa,'other_constraints':['Deposit\x20must\x20be\x20escrowed\x20(no\x20direct\x20transfer)','lock_duration\x20>=\x207d\x20to\x20prevent\x20arbitrary\x20merchant\x20withdrawal']},'applicable_conditions':{'business_scale':'small','min_daily_orders':0x1,'other_conditions':['Requires\x20physical\x20item\x20handover','Has\x20logistics\x20or\x20offline\x20delivery\x20leg']},'similar_industries':['retail','travel'],'novel_capabilities':[]},{'name':'education','display_name':'Education','version':'v1','source':'builtin',...fetchTemplate('education'),'analyze':{'key_questions':['Does\x20tuition\x20release\x20per\x20attended\x20session\x20(Progress\x20node),\x20so\x20undelivered\x20sessions\x20stay\x20refundable\x20if\x20the\x20institution\x20disappears?','Does\x20setting_locked_time\x20span\x20the\x20full\x20term,\x20so\x20the\x20institution\x20cannot\x20tighten\x20refund\x20rules\x20mid-course?']},'capabilities_used':['permission.index_create','permission.role_assign','guard.validate_buy','guard.validate_wip_hash','machine.node_topology','treasury.owner_receive','allocation.distribute','allocation.distribute_milestone','service.publish','progress.advance','arb.vote_weighted','contact.im_create'],'config_overrides':{'allocation':{'strategy':{'recipient':'entity','count':0x1,'mode':'amount','description':'1/N\x20of\x20tuition\x20released\x20per\x20session\x20attendance'},'session_threshold':!![]},'service':{'setting_locked_time':'120d','anti_runaway':!![]}},'expected_benefits':[{'metric':'Refund\x20dispute\x20rate','expected_value':'-50%','evidence':'per-session\x20release\x20distributes\x20tuition\x20by\x20class'},{'metric':'Institution\x20runaway\x20risk','expected_value':'eliminated','evidence':'Funds\x20release\x20per\x20session;\x20undelivered\x20portion\x20is\x20refundable'},{'metric':'Attendance\x20traceability','expected_value':'100%','evidence':'attendance_guard\x20signs\x20each\x20session'}],'risk_appetite':'conservative','risk_constraints':{'require_arbitration':!![],'require_compensation_fund':!![],'require_wip_evidence':![],'other_constraints':['setting_locked_time\x20covers\x20the\x20entire\x20term\x20(>=90d)','Long-cycle\x20projects\x20must\x20monitor\x20>90d\x20progress']},'applicable_conditions':{'business_scale':'medium','min_daily_orders':0x1,'other_conditions':['Long-cycle\x20delivery','Requires\x20per-session\x20acceptance','Regulatory\x20intensity:\x20medium']},'similar_industries':['freelance','subscription'],'novel_capabilities':['allocation.distribute_milestone'],'disabled_builtin_constraints':['require_wip_evidence']},{'name':'travel','display_name':'Travel','version':'v1','source':'builtin',...fetchTemplate('travel'),'analyze':{'key_questions':['Does\x20each\x20itinerary\x20segment\x20have\x20its\x20own\x20guard\x20and\x20WIP\x20acceptance,\x20so\x20one\x20failed\x20leg\x20is\x20refundable\x20without\x20unwinding\x20the\x20whole\x20trip?','Is\x20the\x20multi-tier\x20allocation\x20waterfall\x20(agency\x20→\x20hotel/guide/driver)\x20visible\x20on-chain,\x20so\x20the\x20agency\x20cannot\x20silently\x20re-split\x20funds?']},'capabilities_used':['permission.index_create','permission.role_assign','guard.validate_buy','guard.validate_wip_hash','machine.node_topology','treasury.owner_receive','allocation.distribute','service.publish','progress.advance','arb.vote_weighted','contact.im_create'],'config_overrides':{'allocation':{'strategy':{'recipient':'entity','count':0x3,'mode':'amount','description':'Deposit\x2020%\x20to\x20agency,\x20final\x2080%\x20to\x20agency,\x20then\x20agency-side\x20Allocation\x20splits\x20to\x20hotel/guide/driver\x20per\x20segment'},'multi_tier_waterfall':!![],'guard_chaining':!![]},'service':{'supply_chain_suborders':!![],'segment_guard_required':!![]}},'expected_benefits':[{'metric':'Fund\x20transparency','expected_value':'100%','evidence':'multi-tier\x20allocation\x20splits\x20per\x20segment\x20to\x20hotel/guide/driver'},{'metric':'Itinerary\x20change\x20disputes','expected_value':'-45%','evidence':'segment\x20WIP\x20accepts\x20each\x20leg'},{'metric':'Breach\x20compensation\x20assurance','expected_value':'+60%','evidence':'compensation_fund\x20covers\x20itinerary\x20breach'}],'risk_appetite':'balanced','risk_constraints':{'require_arbitration':!![],'require_compensation_fund':!![],'require_wip_evidence':!![],'other_constraints':['Multi-tier\x20allocation\x20requires\x20guard\x20chaining\x20validation','deposit\x2020%\x20+\x20final\x2080%\x20two-stage\x20payment']},'applicable_conditions':{'business_scale':'medium','min_daily_orders':0x1,'other_conditions':['Multi-segment\x20itinerary\x20combination','Requires\x20hotel/guide/driver\x20multi-party\x20allocation']},'similar_industries':['rental','education'],'novel_capabilities':[]},{'name':'subscription','display_name':'Subscription','version':'v1','source':'builtin',...fetchTemplate('subscription'),'analyze':{'key_questions':['Is\x20every\x20periodic\x20charge\x20gated\x20by\x20an\x20explicit\x20user\x20confirmation,\x20with\x20no\x20auto-renew\x20default?','Can\x20the\x20subscriber\x20cancel\x20anytime\x20effective\x20next\x20period,\x20without\x20a\x20dead-end\x20node\x20in\x20the\x20machine?']},'capabilities_used':['permission.index_create','permission.role_assign','guard.validate_buy','machine.node_topology','treasury.owner_receive','allocation.distribute','service.publish','progress.advance','arb.vote_weighted','reward.claim_guard','contact.im_create'],'config_overrides':{'machine':{'no_auto_renew_trap':!![],'user_confirmed_charge':!![],'cancel_anytime':!![],'next_period_effective':!![]},'service':{'creator_data_subscription':!![],'periodic_billing':!![]}},'expected_benefits':[{'metric':'Renewal\x20rate','expected_value':'+25%','evidence':'loyalty\x20reward\x20+\x20transparent\x20subscription\x20mechanism'},{'metric':'Cancellation\x20disputes','expected_value':'eliminated','evidence':'cancel\x20anytime\x20+\x20no\x20auto-renew\x20trap'},{'metric':'Creator\x20retention','expected_value':'+30%','evidence':'deliver_guard_wip\x20prevents\x20content\x20dropout'}],'risk_appetite':'aggressive','risk_constraints':{'require_arbitration':![],'require_compensation_fund':![],'require_wip_evidence':![],'compensation_fund_coverage_ratio':0x3,'other_constraints':['Forbid\x20dead-end\x20nodes\x20(prevent\x20lock-in)','charge_guard\x20requires\x20user\x20confirmation\x20each\x20period']},'applicable_conditions':{'business_scale':'small','min_daily_orders':0x5,'other_conditions':['Pure-digital\x20delivery','Periodic\x20content\x20or\x20SaaS\x20service']},'similar_industries':['freelance','education'],'novel_capabilities':[],'disabled_builtin_constraints':['require_arbitration','require_compensation_fund','require_wip_evidence']},{'name':'retail','display_name':'Retail','version':'v1','source':'builtin',...fetchTemplate('retail'),'analyze':{'key_questions':['Is\x20the\x20logistics\x20tracking\x20number\x20recorded\x20as\x20WIP\x20before\x20the\x20confirm\x20gate,\x20so\x20receipt\x20disputes\x20have\x20carrier\x20evidence?','Is\x20the\x20refund\x20window\x20at\x20least\x207\x20days\x20with\x20an\x20on-chain\x20refund\x20path\x20that\x20does\x20not\x20rely\x20on\x20merchant\x20goodwill?']},'capabilities_used':['permission.index_create','permission.role_assign','guard.validate_buy','guard.validate_wip_hash','machine.node_topology','treasury.owner_receive','allocation.distribute','service.publish','progress.advance','arb.vote_weighted','reward.claim_guard','contact.im_create'],'config_overrides':{'machine':{'wip_required':!![],'wip_field':'tracking_number','confirm_gate':!![],'refund_requires_approval':!![]},'service':{'logistics_mode':'standard','first_order_discount':!![]}},'expected_benefits':[{'metric':'Return\x20dispute\x20rate','expected_value':'-35%','evidence':'logistics\x20WIP\x20+\x20refund\x20path\x20assurance'},{'metric':'Repurchase\x20rate','expected_value':'+20%','evidence':'spend\x20cashback\x20reward'},{'metric':'Product\x20authenticity\x20traceability','expected_value':'100%','evidence':'WIP\x20verifies\x20product/logistics\x20info'}],'risk_appetite':'conservative','risk_constraints':{'require_arbitration':!![],'require_compensation_fund':!![],'require_wip_evidence':![],'compensation_fund_coverage_ratio':0x5,'other_constraints':['refund_window\x20>=\x207d','confirm_gate:\x20only\x20buyer\x20can\x20confirm\x20receipt']},'applicable_conditions':{'business_scale':'medium','min_daily_orders':0xa,'other_conditions':['Has\x20logistics\x20shipping\x20leg','High-frequency\x20small-ticket\x20transactions']},'similar_industries':['rental','subscription'],'novel_capabilities':[],'disabled_builtin_constraints':['require_wip_evidence']},{'name':'retail_d2c','display_name':'Retail\x20D2C\x20(Direct-to-Consumer)','version':'v1','source':'builtin',...fetchTemplate('retail_d2c'),'analyze':{'key_questions':['Do\x20withdraw_guard\x20and\x20refund_guard\x20fully\x20enclose\x20the\x20Allocation\x20escrow,\x20so\x20neither\x20side\x20can\x20move\x20funds\x20outside\x20the\x20contract\x20path?','With\x20no\x20platform\x20arbitration,\x20what\x20off-chain\x20recourse\x20(if\x20any)\x20backs\x20a\x20delivery\x20failure\x20—\x20and\x20is\x20that\x20acceptable\x20for\x20the\x20ticket\x20size?']},'capabilities_used':['permission.index_create','permission.role_assign','guard.validate_withdraw','guard.validate_refund','machine.node_topology','allocation.distribute','service.publish','progress.advance','contact.im_create'],'config_overrides':{'machine':{'wip_required':![],'confirm_gate':!![],'refund_requires_approval':![]},'service':{'logistics_mode':'merchant_managed','multi_recipient_allocation':!![]}},'expected_benefits':[{'metric':'Merchant\x20revenue\x20share','expected_value':'97%','evidence':'No\x20platform\x20commission\x20—\x20only\x203%\x20processing\x20fee'},{'metric':'Fund\x20safety','expected_value':'contract-grade','evidence':'Allocation\x20escrow\x20+\x20Guard\x20verification\x20replaces\x20platform\x20custody'},{'metric':'Delivery\x20reliability','expected_value':'high','evidence':'withdraw_guard\x20enforces\x20delivery\x20confirmation\x20before\x20payment'}],'risk_appetite':'balanced','risk_constraints':{'require_arbitration':![],'require_compensation_fund':![],'require_wip_evidence':![],'other_constraints':['Allocation\x20escrow\x20required\x20(withdraw_guard\x20+\x20refund_guard)','Service\x20↔\x20Guard\x20circular\x20dependency\x20requires\x203-step\x20creation\x20pattern']},'applicable_conditions':{'business_scale':'small','min_daily_orders':0x1,'other_conditions':['Independent\x20storefront\x20(no\x20marketplace)','Merchant-managed\x20logistics','Allocation\x20escrow\x20model']},'similar_industries':['retail','subscription'],'novel_capabilities':['Allocation\x20escrow\x20as\x20platform-custody\x20alternative','Multi-recipient\x20allocation\x20(merchant\x20+\x20processor)'],'disabled_builtin_constraints':['require_arbitration','require_compensation_fund','require_wip_evidence']},{'name':'general','display_name':'General','version':'v1','source':'builtin',...fetchTemplate('general'),'analyze':{'key_questions':['Which\x20trust\x20mechanisms\x20(arbitration,\x20compensation\x20fund,\x20WIP\x20evidence)\x20are\x20missing\x20here,\x20and\x20what\x20does\x20each\x20absence\x20cost\x20in\x20the\x20worst\x20case?','What\x20is\x20the\x20single\x20point\x20of\x20failure\x20—\x20who\x20can\x20unilaterally\x20take\x20funds\x20or\x20stall\x20the\x20workflow?']},'capabilities_used':['permission.index_create','machine.node_topology','treasury.owner_receive','allocation.distribute','service.publish','progress.advance'],'expected_benefits':[{'metric':'Flexibility','expected_value':'100%','evidence':'User\x20customizes\x20all\x20trust\x20mechanism\x20parameters'},{'metric':'Degraded\x20safety','expected_value':'usable','evidence':'Can\x20fall\x20back\x20to\x20general\x20at\x20any\x20time'}],'risk_appetite':'balanced','risk_constraints':{'require_arbitration':![],'require_compensation_fund':![],'require_wip_evidence':![]},'applicable_conditions':{'business_scale':'small','other_conditions':['Fallback\x20degraded\x20mode','Hybrid\x20scenarios\x20not\x20covered\x20by\x20other\x20industries']},'similar_industries':[],'novel_capabilities':[],'disabled_builtin_constraints':['require_arbitration','require_compensation_fund','require_wip_evidence']}];
|
|
1
|
+
import{getScenarioMode}from'../knowledge/scenario-modes.js';import{getIndustryTraits}from'../knowledge/industry-registry.js';import{getIndustryRiskChecks,getIndustryNeeds}from'../customer/index.js';import{SUPPORTED_INDUSTRIES}from'../customer/user-preferences.js';import{getFlywheelForIndustry}from'../knowledge/acquisition-flywheel.js';const GENERAL_TRAITS={'has_logistics':![],'communication_heavy':![],'pure_digital':![],'long_cycle':![],'deposit_required':![],'multi_tier_allocation':![],'regulatory_intensity':'low','trust_sensitivity':'medium','consumption_frequency':'occasional','avg_ticket_size':'medium'},GENERAL_FLYWHEEL={'industry':'general','trustSellingPoints':[],'keyActions':[],'rewardStrategy':'User-defined','discountStrategy':'User-defined','trustDescription':'User-defined\x20trust\x20mechanism'},GENERAL_MACHINE_SHAPE=[{'name':'paid','role':'Entry:\x20order\x20created\x20and\x20paid'},{'name':'delivering','role':'Service\x20delivery\x20in\x20progress'},{'name':'delivered','role':'Deliverable\x20available\x20for\x20review'},{'name':'completed','role':'Service\x20completed,\x20funds\x20released'},{'name':'cancelled','role':'Pre-delivery\x20cancellation\x20—\x20triggers\x20refund\x20Allocator','operator':'order_payer'}],GENERAL_ALLOCATOR={'recipient':'signer','count':0x1,'mode':'surplus','description':'Default:\x20surplus\x20to\x20service\x20owner\x20(general\x20fallback)'},RETAIL_D2C_MACHINE_SHAPE=[{'name':'ordered','role':'Entry:\x20order\x20created\x20(funds\x20escrowed\x20in\x20Allocation)'},{'name':'shipped','role':'Merchant\x20ships\x20goods'},{'name':'delivered','role':'Goods\x20delivered\x20to\x20buyer'},{'name':'completed','role':'Buyer\x20confirms\x20receipt\x20—\x20withdraw_guard\x20releases\x20funds','operator':'order_payer'},{'name':'cancelled','role':'Pre-ship\x20cancellation\x20—\x20refund_guard\x20refunds\x20buyer','operator':'order_payer'}],RETAIL_D2C_GUARDS=[{'template_id':'withdraw_guard_delivery','host':'service','purpose':'Release\x20funds\x20to\x20merchant\x20+\x20processor\x20on\x20order\x20completion\x20(delivery\x20confirmation)'},{'template_id':'refund_guard_cancellation','host':'service','purpose':'Refund\x20100%\x20to\x20buyer\x20on\x20order\x20cancellation'}],RETAIL_D2C_ALLOCATOR={'recipient':'entity','count':0x2,'mode':'rate','description':'Merchant\x2097%\x20+\x20Processor\x203%\x20(rate-based\x20split,\x20no\x20platform\x20commission)'},RETAIL_D2C_KEY_RISK='No\x20platform\x20arbitration\x20—\x20disputes\x20rely\x20on\x20optional\x20Arbitration\x20or\x20off-chain\x20chargeback',RETAIL_D2C_BUILD_NOTES=['Allocation\x20escrow\x20replaces\x20platform\x20custody\x20—\x20funds\x20locked\x20in\x20contract\x20until\x20Guard\x20releases','withdraw_guard\x20enforces\x20delivery\x20gate\x20—\x20merchant\x20must\x20reach\x20\x27completed\x27\x20state\x20to\x20receive\x20payment','refund_guard\x20ensures\x20100%\x20refund\x20on\x20cancellation\x20—\x20no\x20merchant\x20approval\x20needed','No\x20buy_guard\x20needed\x20—\x20D2C\x20doesn\x27t\x20gate\x20purchases\x20(open\x20storefront)','Arbitration\x20is\x20optional\x20—\x20add\x20when\x20dispute\x20volume\x20justifies\x20the\x20cost','Service\x20↔\x20Guard\x20circular\x20dependency:\x20create\x20Service\x20(unpublished)\x20→\x20create\x20Guards\x20→\x20update\x20Service\x20(publish)'],SUPPORTED_INDUSTRY_SET=new Set([...SUPPORTED_INDUSTRIES,'retail_d2c']);function fetchTemplate(a){const b=a==='retail_d2c'?'retail':a,c=getIndustryTraits(b)??GENERAL_TRAITS,d=SUPPORTED_INDUSTRY_SET['has'](a),e=a==='retail_d2c'?'retail':a,f=d?getIndustryRiskChecks(e):[],g=d?getIndustryNeeds(e):[],h=getFlywheelForIndustry(b)??GENERAL_FLYWHEEL;let i,j,k,l,m;if(a==='retail_d2c')i=RETAIL_D2C_MACHINE_SHAPE,j=RETAIL_D2C_GUARDS,k=RETAIL_D2C_ALLOCATOR,l=RETAIL_D2C_KEY_RISK,m=RETAIL_D2C_BUILD_NOTES;else{if(a==='general'){const n=getScenarioMode('general');i=GENERAL_MACHINE_SHAPE,j=[],k=GENERAL_ALLOCATOR,l=n?.['key_risk']??'No\x20safety\x20net\x20—\x20user\x20must\x20design\x20all\x20trust\x20mechanisms\x20manually',m=n?.['build_notes'];}else{const o=getScenarioMode(a);if(!o)throw new Error('[modes.ts]\x20No\x20scenario\x20mode\x20found\x20for\x20industry:\x20'+a);i=o['machine_shape'],j=o['guards'],k=o['allocator'],l=o['key_risk'],m=o['build_notes'];}}return{'traits':c,'risk_checks':f,'needs':g,'flywheel':h,'machine_shape':i,'guards':j,'allocator':k,'key_risk':l,'build_notes':m};}export const BUILTIN_MODES=[{'name':'freelance','display_name':'Freelance','version':'v1','source':'builtin',...fetchTemplate('freelance'),'analyze':{'key_questions':['Are\x20WIP\x20hashes\x20bound\x20to\x20each\x20milestone,\x20so\x20delivery\x20evidence\x20cannot\x20be\x20substituted\x20after\x20acceptance?','Does\x20the\x20acceptance\x20gate\x20have\x20a\x20time-bounded\x20escape\x20(keeper-driven\x20auto-accept),\x20or\x20can\x20a\x20silent\x20buyer\x20hold\x20the\x20provider\x27s\x20funds\x20hostage\x20indefinitely?']},'capabilities_used':['permission.index_create','permission.role_assign','guard.validate_buy','guard.validate_wip_hash','machine.node_topology','treasury.owner_receive','allocation.distribute','allocation.distribute_milestone','service.publish','progress.advance','arb.vote_weighted','contact.im_create'],'config_overrides':{'service':{'setting_locked_time':'30d','engagement_type':'milestone'},'machine':{'wip_required':!![],'wip_hash_algorithm':'sha256','acceptance_gate':!![]}},'expected_benefits':[{'metric':'Dispute\x20rate\x20reduction','expected_value':'40%','evidence':'WIP\x20hash\x20+\x20milestone\x20allocation\x20enforces\x20delivery\x20evidence'},{'metric':'Delivery\x20confirmation\x20efficiency','expected_value':'+50%','evidence':'acceptance\x20gate\x20automates\x20acceptance\x20workflow'},{'metric':'Provider\x20payment\x20assurance','expected_value':'100%','evidence':'Funds\x20auto-release\x20to\x20provider\x20after\x20accepted\x20node'}],'risk_appetite':'balanced','risk_constraints':{'require_arbitration':!![],'require_compensation_fund':![],'require_wip_evidence':!![],'other_constraints':['setting_locked_time\x20>=\x207d\x20to\x20lock\x20engagement-period\x20rules','Acceptance\x20timeout\x20=\x20the\x20template\x27s\x20escrow_release_days\x20(single\x20source:\x20fee_params,\x20override\x20via\x20fee_overrides).\x20Mechanism:\x20dual-branch\x20time-gated\x20forward\x20(pattern.time_lock_progress\x20anchored\x20on\x20the\x20delivered\x20entry);\x20a\x20keeper\x20advances\x20the\x20timeout\x20path.\x20adminUnhold\x20(224)\x20is\x20ONLY\x20the\x20hold-release\x20escape\x20hatch,\x20never\x20the\x20timeout\x20mechanism.']},'applicable_conditions':{'business_scale':'small','min_daily_orders':0x1,'other_conditions':['Suitable\x20for\x20mid-to-long-term\x20project\x20delivery','Requires\x20milestone-based\x20phased\x20acceptance']},'similar_industries':['rental','education'],'novel_capabilities':['allocation.distribute_milestone'],'disabled_builtin_constraints':['require_compensation_fund']},{'name':'rental','display_name':'Rental','version':'v1','source':'builtin',...fetchTemplate('rental'),'analyze':{'key_questions':['Is\x20the\x20deposit\x20escrowed\x20on-chain\x20and\x20sized\x20against\x20the\x20item\x27s\x20full\x20replacement\x20value,\x20not\x20just\x20the\x20rental\x20fee?','Are\x20pre-handover\x20and\x20post-return\x20WIP\x20states\x20hash-recorded,\x20so\x20damage\x20attribution\x20is\x20provable\x20rather\x20than\x20asserted?']},'capabilities_used':['permission.index_create','permission.role_assign','guard.validate_buy','guard.validate_wip_hash','machine.node_topology','treasury.owner_receive','allocation.distribute','service.publish','progress.advance','arb.vote_weighted','contact.im_create'],'config_overrides':{'treasury':{'deposit_escrow':!![],'deposit_deductible':!![]},'machine':{'wip_required':!![],'wip_stages':['handover_out','returned'],'inspection_gate':!![]}},'expected_benefits':[{'metric':'Deposit\x20dispute\x20rate','expected_value':'-60%','evidence':'pre-rental\x20WIP\x20mandatorily\x20records\x20item\x27s\x20original\x20state'},{'metric':'Damage\x20liability\x20accuracy','expected_value':'+70%','evidence':'pre/post\x20WIP\x20hash\x20comparison\x20eliminates\x20unfounded\x20deductions'},{'metric':'Trust\x20score','expected_value':'+25%','evidence':'compensation_fund\x20covers\x20damage\x20risk'}],'risk_appetite':'conservative','risk_constraints':{'require_arbitration':!![],'require_compensation_fund':!![],'require_wip_evidence':!![],'max_single_transaction':0x2710,'compensation_fund_coverage_ratio':0xa,'other_constraints':['Deposit\x20must\x20be\x20escrowed\x20(no\x20direct\x20transfer)','lock_duration\x20>=\x207d\x20to\x20prevent\x20arbitrary\x20merchant\x20withdrawal']},'applicable_conditions':{'business_scale':'small','min_daily_orders':0x1,'other_conditions':['Requires\x20physical\x20item\x20handover','Has\x20logistics\x20or\x20offline\x20delivery\x20leg']},'similar_industries':['retail','travel'],'novel_capabilities':[]},{'name':'education','display_name':'Education','version':'v1','source':'builtin',...fetchTemplate('education'),'analyze':{'key_questions':['Does\x20tuition\x20release\x20per\x20attended\x20session\x20(Progress\x20node),\x20so\x20undelivered\x20sessions\x20stay\x20refundable\x20if\x20the\x20institution\x20disappears?','Does\x20setting_locked_time\x20span\x20the\x20full\x20term,\x20so\x20the\x20institution\x20cannot\x20tighten\x20refund\x20rules\x20mid-course?']},'capabilities_used':['permission.index_create','permission.role_assign','guard.validate_buy','guard.validate_wip_hash','machine.node_topology','treasury.owner_receive','allocation.distribute','allocation.distribute_milestone','service.publish','progress.advance','arb.vote_weighted','contact.im_create'],'config_overrides':{'allocation':{'strategy':{'recipient':'entity','count':0x1,'mode':'amount','description':'1/N\x20of\x20tuition\x20released\x20per\x20session\x20attendance'},'session_threshold':!![]},'service':{'setting_locked_time':'120d','anti_runaway':!![]}},'expected_benefits':[{'metric':'Refund\x20dispute\x20rate','expected_value':'-50%','evidence':'per-session\x20release\x20distributes\x20tuition\x20by\x20class'},{'metric':'Institution\x20runaway\x20risk','expected_value':'eliminated','evidence':'Funds\x20release\x20per\x20session;\x20undelivered\x20portion\x20is\x20refundable'},{'metric':'Attendance\x20traceability','expected_value':'100%','evidence':'attendance_guard\x20signs\x20each\x20session'}],'risk_appetite':'conservative','risk_constraints':{'require_arbitration':!![],'require_compensation_fund':!![],'require_wip_evidence':![],'other_constraints':['setting_locked_time\x20covers\x20the\x20entire\x20term\x20(>=90d)','Long-cycle\x20projects\x20must\x20monitor\x20>90d\x20progress']},'applicable_conditions':{'business_scale':'medium','min_daily_orders':0x1,'other_conditions':['Long-cycle\x20delivery','Requires\x20per-session\x20acceptance','Regulatory\x20intensity:\x20medium']},'similar_industries':['freelance','subscription'],'novel_capabilities':['allocation.distribute_milestone'],'disabled_builtin_constraints':['require_wip_evidence']},{'name':'travel','display_name':'Travel','version':'v1','source':'builtin',...fetchTemplate('travel'),'analyze':{'key_questions':['Does\x20each\x20itinerary\x20segment\x20have\x20its\x20own\x20guard\x20and\x20WIP\x20acceptance,\x20so\x20one\x20failed\x20leg\x20is\x20refundable\x20without\x20unwinding\x20the\x20whole\x20trip?','Is\x20the\x20multi-tier\x20allocation\x20waterfall\x20(agency\x20→\x20hotel/guide/driver)\x20visible\x20on-chain,\x20so\x20the\x20agency\x20cannot\x20silently\x20re-split\x20funds?']},'capabilities_used':['permission.index_create','permission.role_assign','guard.validate_buy','guard.validate_wip_hash','machine.node_topology','treasury.owner_receive','allocation.distribute','service.publish','progress.advance','arb.vote_weighted','contact.im_create'],'config_overrides':{'allocation':{'strategy':{'recipient':'entity','count':0x3,'mode':'amount','description':'Deposit\x2020%\x20to\x20agency,\x20final\x2080%\x20to\x20agency,\x20then\x20agency-side\x20Allocation\x20splits\x20to\x20hotel/guide/driver\x20per\x20segment'},'multi_tier_waterfall':!![],'guard_chaining':!![]},'service':{'supply_chain_suborders':!![],'segment_guard_required':!![]}},'expected_benefits':[{'metric':'Fund\x20transparency','expected_value':'100%','evidence':'multi-tier\x20allocation\x20splits\x20per\x20segment\x20to\x20hotel/guide/driver'},{'metric':'Itinerary\x20change\x20disputes','expected_value':'-45%','evidence':'segment\x20WIP\x20accepts\x20each\x20leg'},{'metric':'Breach\x20compensation\x20assurance','expected_value':'+60%','evidence':'compensation_fund\x20covers\x20itinerary\x20breach'}],'risk_appetite':'balanced','risk_constraints':{'require_arbitration':!![],'require_compensation_fund':!![],'require_wip_evidence':!![],'other_constraints':['Multi-tier\x20allocation\x20requires\x20guard\x20chaining\x20validation','deposit\x2020%\x20+\x20final\x2080%\x20two-stage\x20payment']},'applicable_conditions':{'business_scale':'medium','min_daily_orders':0x1,'other_conditions':['Multi-segment\x20itinerary\x20combination','Requires\x20hotel/guide/driver\x20multi-party\x20allocation']},'similar_industries':['rental','education'],'novel_capabilities':[]},{'name':'subscription','display_name':'Subscription','version':'v1','source':'builtin',...fetchTemplate('subscription'),'analyze':{'key_questions':['Is\x20every\x20periodic\x20charge\x20gated\x20by\x20an\x20explicit\x20user\x20confirmation,\x20with\x20no\x20auto-renew\x20default?','Can\x20the\x20subscriber\x20cancel\x20anytime\x20effective\x20next\x20period,\x20without\x20a\x20dead-end\x20node\x20in\x20the\x20machine?']},'capabilities_used':['permission.index_create','permission.role_assign','guard.validate_buy','machine.node_topology','treasury.owner_receive','allocation.distribute','service.publish','progress.advance','arb.vote_weighted','reward.claim_guard','contact.im_create'],'config_overrides':{'machine':{'no_auto_renew_trap':!![],'user_confirmed_charge':!![],'cancel_anytime':!![],'next_period_effective':!![]},'service':{'creator_data_subscription':!![],'periodic_billing':!![]}},'expected_benefits':[{'metric':'Renewal\x20rate','expected_value':'+25%','evidence':'loyalty\x20reward\x20+\x20transparent\x20subscription\x20mechanism'},{'metric':'Cancellation\x20disputes','expected_value':'eliminated','evidence':'cancel\x20anytime\x20+\x20no\x20auto-renew\x20trap'},{'metric':'Creator\x20retention','expected_value':'+30%','evidence':'deliver_guard_wip\x20prevents\x20content\x20dropout'}],'risk_appetite':'aggressive','risk_constraints':{'require_arbitration':![],'require_compensation_fund':![],'require_wip_evidence':![],'compensation_fund_coverage_ratio':0x3,'other_constraints':['Forbid\x20dead-end\x20nodes\x20(prevent\x20lock-in)','charge_guard\x20requires\x20user\x20confirmation\x20each\x20period']},'applicable_conditions':{'business_scale':'small','min_daily_orders':0x5,'other_conditions':['Pure-digital\x20delivery','Periodic\x20content\x20or\x20SaaS\x20service']},'similar_industries':['freelance','education'],'novel_capabilities':[],'disabled_builtin_constraints':['require_arbitration','require_compensation_fund','require_wip_evidence']},{'name':'retail','display_name':'Retail','version':'v1','source':'builtin',...fetchTemplate('retail'),'analyze':{'key_questions':['Is\x20the\x20logistics\x20tracking\x20number\x20recorded\x20as\x20WIP\x20before\x20the\x20confirm\x20gate,\x20so\x20receipt\x20disputes\x20have\x20carrier\x20evidence?','Is\x20the\x20refund\x20window\x20at\x20least\x207\x20days\x20with\x20an\x20on-chain\x20refund\x20path\x20that\x20does\x20not\x20rely\x20on\x20merchant\x20goodwill?']},'capabilities_used':['permission.index_create','permission.role_assign','guard.validate_buy','guard.validate_wip_hash','machine.node_topology','treasury.owner_receive','allocation.distribute','service.publish','progress.advance','arb.vote_weighted','reward.claim_guard','contact.im_create'],'config_overrides':{'machine':{'wip_required':!![],'wip_field':'tracking_number','confirm_gate':!![],'refund_requires_approval':!![]},'service':{'logistics_mode':'standard','first_order_discount':!![]}},'expected_benefits':[{'metric':'Return\x20dispute\x20rate','expected_value':'-35%','evidence':'logistics\x20WIP\x20+\x20refund\x20path\x20assurance'},{'metric':'Repurchase\x20rate','expected_value':'+20%','evidence':'spend\x20cashback\x20reward'},{'metric':'Product\x20authenticity\x20traceability','expected_value':'100%','evidence':'WIP\x20verifies\x20product/logistics\x20info'}],'risk_appetite':'conservative','risk_constraints':{'require_arbitration':!![],'require_compensation_fund':!![],'require_wip_evidence':![],'compensation_fund_coverage_ratio':0x5,'other_constraints':['refund_window\x20>=\x207d','confirm_gate:\x20only\x20buyer\x20can\x20confirm\x20receipt']},'applicable_conditions':{'business_scale':'medium','min_daily_orders':0xa,'other_conditions':['Has\x20logistics\x20shipping\x20leg','High-frequency\x20small-ticket\x20transactions']},'similar_industries':['rental','subscription'],'novel_capabilities':[],'disabled_builtin_constraints':['require_wip_evidence']},{'name':'retail_d2c','display_name':'Retail\x20D2C\x20(Direct-to-Consumer)','version':'v1','source':'builtin',...fetchTemplate('retail_d2c'),'analyze':{'key_questions':['Do\x20withdraw_guard\x20and\x20refund_guard\x20fully\x20enclose\x20the\x20Allocation\x20escrow,\x20so\x20neither\x20side\x20can\x20move\x20funds\x20outside\x20the\x20contract\x20path?','With\x20no\x20platform\x20arbitration,\x20what\x20off-chain\x20recourse\x20(if\x20any)\x20backs\x20a\x20delivery\x20failure\x20—\x20and\x20is\x20that\x20acceptable\x20for\x20the\x20ticket\x20size?']},'capabilities_used':['permission.index_create','permission.role_assign','guard.validate_withdraw','guard.validate_refund','machine.node_topology','allocation.distribute','service.publish','progress.advance','contact.im_create'],'config_overrides':{'machine':{'wip_required':![],'confirm_gate':!![],'refund_requires_approval':![]},'service':{'logistics_mode':'merchant_managed','multi_recipient_allocation':!![]}},'expected_benefits':[{'metric':'Merchant\x20revenue\x20share','expected_value':'97%','evidence':'No\x20platform\x20commission\x20—\x20only\x203%\x20processing\x20fee'},{'metric':'Fund\x20safety','expected_value':'contract-grade','evidence':'Allocation\x20escrow\x20+\x20Guard\x20verification\x20replaces\x20platform\x20custody'},{'metric':'Delivery\x20reliability','expected_value':'high','evidence':'withdraw_guard\x20enforces\x20delivery\x20confirmation\x20before\x20payment'}],'risk_appetite':'balanced','risk_constraints':{'require_arbitration':![],'require_compensation_fund':![],'require_wip_evidence':![],'other_constraints':['Allocation\x20escrow\x20required\x20(withdraw_guard\x20+\x20refund_guard)','Service\x20↔\x20Guard\x20circular\x20dependency\x20requires\x203-step\x20creation\x20pattern']},'applicable_conditions':{'business_scale':'small','min_daily_orders':0x1,'other_conditions':['Independent\x20storefront\x20(no\x20marketplace)','Merchant-managed\x20logistics','Allocation\x20escrow\x20model']},'similar_industries':['retail','subscription'],'novel_capabilities':['Allocation\x20escrow\x20as\x20platform-custody\x20alternative','Multi-recipient\x20allocation\x20(merchant\x20+\x20processor)'],'disabled_builtin_constraints':['require_arbitration','require_compensation_fund','require_wip_evidence']},{'name':'general','display_name':'General','version':'v1','source':'builtin',...fetchTemplate('general'),'analyze':{'key_questions':['Which\x20trust\x20mechanisms\x20(arbitration,\x20compensation\x20fund,\x20WIP\x20evidence)\x20are\x20missing\x20here,\x20and\x20what\x20does\x20each\x20absence\x20cost\x20in\x20the\x20worst\x20case?','What\x20is\x20the\x20single\x20point\x20of\x20failure\x20—\x20who\x20can\x20unilaterally\x20take\x20funds\x20or\x20stall\x20the\x20workflow?']},'capabilities_used':['permission.index_create','machine.node_topology','treasury.owner_receive','allocation.distribute','service.publish','progress.advance'],'expected_benefits':[{'metric':'Flexibility','expected_value':'100%','evidence':'User\x20customizes\x20all\x20trust\x20mechanism\x20parameters'},{'metric':'Degraded\x20safety','expected_value':'usable','evidence':'Can\x20fall\x20back\x20to\x20general\x20at\x20any\x20time'}],'risk_appetite':'balanced','risk_constraints':{'require_arbitration':![],'require_compensation_fund':![],'require_wip_evidence':![]},'applicable_conditions':{'business_scale':'small','other_conditions':['Fallback\x20degraded\x20mode','Hybrid\x20scenarios\x20not\x20covered\x20by\x20other\x20industries']},'similar_industries':[],'novel_capabilities':[],'disabled_builtin_constraints':['require_arbitration','require_compensation_fund','require_wip_evidence']}];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{EDGE_SCHEMAS,EDGE_SCHEMA_BY_ID}from'./edge-schema.js';import{extractCoinType,extractEventRefs,extractObjectEdges,extractReverseRefs,extractTableRefs,inferObjectType,REVERSE_GROUP_WILDCARD}from'./extract.js';import{mergeBudget}from'./dataplane.js';import{deriveOrderCompletion,terminalNamesOfEdges}from'./order-status.js';import{LINKER_RING_LIMIT as a84a}from'./sdk-batch.js';import{wowAddressKind}from'@wowok/wowok';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 isEoa(a){return wowAddressKind(a)==='user';}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){if(a['read']['kind']!=='table')return![];if(this['wl']['deny']?.['includes'](a['id']))return![];const c=this['wl']['familyDepths']?.[a['family']];if(c!==undefined&&b>=c)return![];if(this['wl']['families']&&!this['wl']['families']['includes'](a['family']))return![];return!!this['wl']['tableEdges']?.['includes'](a['id']);}['allowsEvent'](a,b){if(a['read']['kind']!=='event')return![];if(this['wl']['deny']?.['includes'](a['id']))return![];const c=this['wl']['familyDepths']?.[a['family']];if(c!==undefined&&b>=c)return![];if(this['wl']['families']&&!this['wl']['families']['includes'](a['family']))return![];return!!this['wl']['eventEdges']?.['includes'](a['id']);}['effectiveMaxHops'](a){const b=a['maxHops'],c=this['wl']['schemaHops']?.[a['id']];if(b===undefined)return c;if(c===undefined)return b;return Math['min'](b,c);}}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'],'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(),m=new Map(),n=new Set();let o=new Set([d]);for(let p=0x0;p<=e['maxDepth'];p++){if(o['size']===0x0)break;if(h['exhausted']['nodes'])break;const q=Date['now'](),r=new Map(),t=(D,E)=>{const F=r['get'](D);if(F)return F;const G=new Map();r['set'](D,G);const H=h['graph']['nodes']['get'](D);if(H&&H['origins']['length']>0x0&&!E['has'](D)){E['add'](D);for(const I of H['origins']){if(!I['via']||!I['from']||E['has'](I['from']))continue;const J=t(I['from'],E);for(const [L,M]of J){if(M<(G['get'](L)??Infinity))G['set'](L,M);}const K=(J['get'](I['via'])??0x0)+0x1;if(K<(G['get'](I['via'])??Infinity))G['set'](I['via'],K);}E['delete'](D);}return G;},u=[...o]['filter'](D=>{const E=h['graph']['nodes']['get'](D);return E['kind']==='object'&&(E['state']==='seed'||E['state']==='stub')&&!i['has'](D);}),v=new Set();if(u['length']>0x0){const D=await a['getObjects'](u);if(readStats(a)['batches']>=e['maxRpcs'])h['exhausted']['rpcs']=!![];for(const E of u){const F=h['graph']['nodes']['get'](E),G=lookupMapLower(D,E);i['add'](E);if(!G){F['state']='error',F['error']='not_found_or_failed',h['graph']['gaps']['push'](E);continue;}F['state']='fetched',F['raw']=G,F['objectType']=String(G['type']??F['objectType']??inferObjectType(E)??''),F['coinType']=extractCoinType(G['type_raw']),v['add'](E);}}const w=[];for(const H of v){const I=h['graph']['nodes']['get'](H);if(!I['objectType']||!I['raw'])continue;for(const J of extractObjectEdges(I['objectType'],I['raw'])){const K=EDGE_SCHEMA_BY_ID['get'](J['schemaId']);if(!K||!f['allows'](K,p))continue;w['push']({'schema':K,'sourceId':H,'refs':J['refs'],'observed':J['refs']['length']});}}const x=[...v]['filter'](L=>{const M=h['graph']['nodes']['get'](L);return EDGE_SCHEMAS['some'](N=>N['source']===M['objectType']&&N['read']['kind']==='table');});for(const L of x){const M=h['graph']['nodes']['get'](L),N=EDGE_SCHEMAS['filter'](P=>P['source']===M['objectType']&&P['read']['kind']==='table'&&f['allowsTable'](P,p)),O=new Map();for(const P of N){const Q=P['read']['rowType'],R=O['get'](Q)??[];R['push'](P),O['set'](Q,R);}for(const [S,T]of O){const U=L+'|'+S;if(l['has'](U))continue;l['add'](U);const V=Math['max'](...T['map'](a0=>e['perKindCaps'][a0['id']]??e['maxFanoutPerNode']));let W,X=![];try{const a0=await a['getTable'](L,{'maxItems':V});if(readStats(a)['batches']>=e['maxRpcs'])h['exhausted']['rpcs']=!![];W=a0['items'],X=a0['truncated'];}catch{h['graph']['gaps']['push'](L+'#'+S);continue;}const Y=new Set(T['map'](a1=>a1['id'])),Z=extractTableRefs(S,L,W)['filter'](a1=>{const a2=EDGE_SCHEMA_BY_ID['get'](a1['schemaId']);return a2['read']['kind']==='derived'||Y['has'](a1['schemaId']);});for(const a1 of Z){const a2=EDGE_SCHEMA_BY_ID['get'](a1['schemaId']);let a3=a1['refs'];a2['family']==='M'&&M['coinType']&&(a3=a3['map'](a4=>({...a4,'payload':{'coinType':M['coinType'],...a4['payload']}}))),w['push']({'schema':a2,'sourceId':L,'refs':a3,'observed':a3['length']});}X&&h['markTruncation']({'nodeId':L,'schema':T[0x0]['id'],'observed':W['length'],'limit':V,'reason':'table_page'});}}const y=[...o]['filter'](a4=>{const a5=h['graph']['nodes']['get'](a4);return a5['kind']!=='wfnode'&&(a5['kind']==='eoa'||a5['state']==='fetched');}),z=new Map(),A=new Map();for(const a4 of y){const a5=h['graph']['nodes']['get'](a4);for(const a6 of EDGE_SCHEMAS){if(a6['read']['kind']!=='reverse'||!f['allows'](a6,p))continue;if(!sourceMatches(a6['source'],a5))continue;const a7=a6['read']['parent'],a8=a4+'|'+a7;if(j['has'](a8))continue;if(!z['has'](a7))z['set'](a7,[]);z['get'](a7)['push'](a4);const a9=a4+'|'+a7+'|schema',aa=A['get'](a9)??[];aa['push'](a6),A['set'](a9,aa);}}for(const [ab,ac]of z){for(const ae of ac)j['add'](ae+'|'+ab);let ad=new Map();try{ad=await a['getKeyedFields'](ab,ac);if(readStats(a)['batches']>=e['maxRpcs'])h['exhausted']['rpcs']=!![];}catch{h['graph']['gaps']['push']('reverse:'+ab);continue;}for(const af of ac){const ag=A['get'](af+'|'+ab+'|schema')??[],ah=lookupMapLower(ad,af);if(!ah)continue;const ai=extractReverseRefs(ab,ah['data']??ah);for(const aj of ag){const ak=aj['read'];for(const al of ai){if(al['schemaId']!==REVERSE_GROUP_WILDCARD&&al['schemaId']!==aj['id'])continue;let am=al['refs']['map'](an=>an['to']?an:{...an,'to':af});ak['kind']==='reverse'&&ak['filterType']&&(am=am['filter'](an=>inferObjectType(an['to'])===ak['filterType']));if(am['length']===0x0)continue;w['push']({'schema':aj,'sourceId':af,'refs':am,'observed':am['length']});}}}}for(const an of EDGE_SCHEMAS){const ao=an['read'];if(ao['kind']!=='event'||!f['allowsEvent'](an,p))continue;const ap=[...o]['filter'](ar=>{if(n['has'](ar+'|'+an['id']))return![];return sourceMatches(an['source'],h['graph']['nodes']['get'](ar));});if(ap['length']===0x0)continue;let aq=m['get'](ao['eventType']);if(!aq){aq={'events':[],'truncated':![],'failed':![]};try{const ar=await a['getEvents'](ao['eventType'],{'maxPages':e['maxEventPages']});if(readStats(a)['batches']>=e['maxRpcs'])h['exhausted']['rpcs']=!![];aq['events']=ar['events'],aq['truncated']=ar['truncated'],ar['truncated']&&ar['events']['length']===0x0&&(aq['failed']=!![],h['graph']['gaps']['push']('events:'+ao['eventType']));}catch{aq['failed']=!![],h['graph']['gaps']['push']('events:'+ao['eventType']);}m['set'](ao['eventType'],aq);}if(aq['failed']){for(const as of ap)n['add'](as+'|'+an['id']);continue;}if(aq['truncated']){h['exhausted']['eventPages']=!![];for(const at of ap){h['markTruncation']({'nodeId':at,'schema':an['id'],'observed':aq['events']['length'],'limit':e['maxEventPages'],'reason':'event_pages'});}}for(const au of ap){n['add'](au+'|'+an['id']);const av=extractEventRefs(ao,au,aq['events']);if(av['length']===0x0)continue;w['push']({'schema':an,'sourceId':au,'refs':av,'observed':av['length'],'truncated':aq['truncated']});}}const B=new Set(),C=new Map();for(const aw of w){const ax=e['perKindCaps'][aw['schema']['id']]??e['maxFanoutPerNode'],ay=C['get'](aw['sourceId'])??0x0,az=Math['max'](0x0,e['maxFanoutPerNode']-ay),aA=Math['min'](ax,az),aB=aw['refs']['slice'](0x0,aA);aw['refs']['length']>aA&&h['markTruncation']({'nodeId':aw['sourceId'],'schema':aw['schema']['id'],'observed':aw['refs']['length'],'limit':a84a,'reason':'fanout'});const aC=new Map();for(const aD of aB){const aE=aD['from']??aw['sourceId'],aF=isWfNodeId(aD['to'])?p:p+0x1,aG=h['graph']['nodes']['has'](aD['to']),aH=f['effectiveMaxHops'](aw['schema']);if(aH!==undefined){const aJ=(t(aE,new Set())['get'](aw['schema']['id'])??0x0)+0x1;if(aJ>aH&&!aG){aC['set'](aE,(aC['get'](aE)??0x0)+0x1);continue;}}if(aF>e['maxDepth']&&!aG){h['exhausted']['depth']=!![];continue;}const aI=h['addNode'](aD['to'],Math['min'](aF,e['maxDepth']),{'schema':aw['schema']['id'],'from':aE});if(!aI)break;h['addEdge'](aw['schema'],aE,aD,q,aw['truncated']===!![]||aw['refs']['length']>aA),C['set'](aw['sourceId'],ay+0x1);if(!isWfNodeId(aD['to'])&&aF<=e['maxDepth'])B['add'](aD['to']);}for(const [aK,aL]of aC){h['markTruncation']({'nodeId':aK,'schema':aw['schema']['id'],'observed':aL,'limit':f['effectiveMaxHops'](aw['schema'])??0x0,'reason':'schema_hops'});}}if(h['exhausted']['rpcs']){h['graph']['gaps']['push']('budget:maxRpcs');break;}o=B;}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});}
|
|
1
|
+
import{EDGE_SCHEMAS,EDGE_SCHEMA_BY_ID}from'./edge-schema.js';import{extractCoinType,extractEventRefs,extractObjectEdges,extractReverseRefs,extractTableRefs,inferObjectType,REVERSE_GROUP_WILDCARD}from'./extract.js';import{mergeBudget}from'./dataplane.js';import{deriveOrderCompletion,terminalNamesOfEdges}from'./order-status.js';import{LINKER_RING_LIMIT as a95a}from'./sdk-batch.js';import{wowAddressKind}from'@wowok/wowok';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 isEoa(a){return wowAddressKind(a)==='user';}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){if(a['read']['kind']!=='table')return![];if(this['wl']['deny']?.['includes'](a['id']))return![];const c=this['wl']['familyDepths']?.[a['family']];if(c!==undefined&&b>=c)return![];if(this['wl']['families']&&!this['wl']['families']['includes'](a['family']))return![];return!!this['wl']['tableEdges']?.['includes'](a['id']);}['allowsEvent'](a,b){if(a['read']['kind']!=='event')return![];if(this['wl']['deny']?.['includes'](a['id']))return![];const c=this['wl']['familyDepths']?.[a['family']];if(c!==undefined&&b>=c)return![];if(this['wl']['families']&&!this['wl']['families']['includes'](a['family']))return![];return!!this['wl']['eventEdges']?.['includes'](a['id']);}['effectiveMaxHops'](a){const b=a['maxHops'],c=this['wl']['schemaHops']?.[a['id']];if(b===undefined)return c;if(c===undefined)return b;return Math['min'](b,c);}}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'],'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(),m=new Map(),n=new Set();let o=new Set([d]);for(let p=0x0;p<=e['maxDepth'];p++){if(o['size']===0x0)break;if(h['exhausted']['nodes'])break;const q=Date['now'](),r=new Map(),t=(D,E)=>{const F=r['get'](D);if(F)return F;const G=new Map();r['set'](D,G);const H=h['graph']['nodes']['get'](D);if(H&&H['origins']['length']>0x0&&!E['has'](D)){E['add'](D);for(const I of H['origins']){if(!I['via']||!I['from']||E['has'](I['from']))continue;const J=t(I['from'],E);for(const [L,M]of J){if(M<(G['get'](L)??Infinity))G['set'](L,M);}const K=(J['get'](I['via'])??0x0)+0x1;if(K<(G['get'](I['via'])??Infinity))G['set'](I['via'],K);}E['delete'](D);}return G;},u=[...o]['filter'](D=>{const E=h['graph']['nodes']['get'](D);return E['kind']==='object'&&(E['state']==='seed'||E['state']==='stub')&&!i['has'](D);}),v=new Set();if(u['length']>0x0){const D=await a['getObjects'](u);if(readStats(a)['batches']>=e['maxRpcs'])h['exhausted']['rpcs']=!![];for(const E of u){const F=h['graph']['nodes']['get'](E),G=lookupMapLower(D,E);i['add'](E);if(!G){F['state']='error',F['error']='not_found_or_failed',h['graph']['gaps']['push'](E);continue;}F['state']='fetched',F['raw']=G,F['objectType']=String(G['type']??F['objectType']??inferObjectType(E)??''),F['coinType']=extractCoinType(G['type_raw']),v['add'](E);}}const w=[];for(const H of v){const I=h['graph']['nodes']['get'](H);if(!I['objectType']||!I['raw'])continue;for(const J of extractObjectEdges(I['objectType'],I['raw'])){const K=EDGE_SCHEMA_BY_ID['get'](J['schemaId']);if(!K||!f['allows'](K,p))continue;w['push']({'schema':K,'sourceId':H,'refs':J['refs'],'observed':J['refs']['length']});}}const x=[...v]['filter'](L=>{const M=h['graph']['nodes']['get'](L);return EDGE_SCHEMAS['some'](N=>N['source']===M['objectType']&&N['read']['kind']==='table');});for(const L of x){const M=h['graph']['nodes']['get'](L),N=EDGE_SCHEMAS['filter'](P=>P['source']===M['objectType']&&P['read']['kind']==='table'&&f['allowsTable'](P,p)),O=new Map();for(const P of N){const Q=P['read']['rowType'],R=O['get'](Q)??[];R['push'](P),O['set'](Q,R);}for(const [S,T]of O){const U=L+'|'+S;if(l['has'](U))continue;l['add'](U);const V=Math['max'](...T['map'](a0=>e['perKindCaps'][a0['id']]??e['maxFanoutPerNode']));let W,X=![];try{const a0=await a['getTable'](L,{'maxItems':V});if(readStats(a)['batches']>=e['maxRpcs'])h['exhausted']['rpcs']=!![];W=a0['items'],X=a0['truncated'];}catch{h['graph']['gaps']['push'](L+'#'+S);continue;}const Y=new Set(T['map'](a1=>a1['id'])),Z=extractTableRefs(S,L,W)['filter'](a1=>{const a2=EDGE_SCHEMA_BY_ID['get'](a1['schemaId']);return a2['read']['kind']==='derived'||Y['has'](a1['schemaId']);});for(const a1 of Z){const a2=EDGE_SCHEMA_BY_ID['get'](a1['schemaId']);let a3=a1['refs'];a2['family']==='M'&&M['coinType']&&(a3=a3['map'](a4=>({...a4,'payload':{'coinType':M['coinType'],...a4['payload']}}))),w['push']({'schema':a2,'sourceId':L,'refs':a3,'observed':a3['length']});}X&&h['markTruncation']({'nodeId':L,'schema':T[0x0]['id'],'observed':W['length'],'limit':V,'reason':'table_page'});}}const y=[...o]['filter'](a4=>{const a5=h['graph']['nodes']['get'](a4);return a5['kind']!=='wfnode'&&(a5['kind']==='eoa'||a5['state']==='fetched');}),z=new Map(),A=new Map();for(const a4 of y){const a5=h['graph']['nodes']['get'](a4);for(const a6 of EDGE_SCHEMAS){if(a6['read']['kind']!=='reverse'||!f['allows'](a6,p))continue;if(!sourceMatches(a6['source'],a5))continue;const a7=a6['read']['parent'],a8=a4+'|'+a7;if(j['has'](a8))continue;if(!z['has'](a7))z['set'](a7,[]);z['get'](a7)['push'](a4);const a9=a4+'|'+a7+'|schema',aa=A['get'](a9)??[];aa['push'](a6),A['set'](a9,aa);}}for(const [ab,ac]of z){for(const ae of ac)j['add'](ae+'|'+ab);let ad=new Map();try{ad=await a['getKeyedFields'](ab,ac);if(readStats(a)['batches']>=e['maxRpcs'])h['exhausted']['rpcs']=!![];}catch{h['graph']['gaps']['push']('reverse:'+ab);continue;}for(const af of ac){const ag=A['get'](af+'|'+ab+'|schema')??[],ah=lookupMapLower(ad,af);if(!ah)continue;const ai=extractReverseRefs(ab,ah['data']??ah);for(const aj of ag){const ak=aj['read'];for(const al of ai){if(al['schemaId']!==REVERSE_GROUP_WILDCARD&&al['schemaId']!==aj['id'])continue;let am=al['refs']['map'](an=>an['to']?an:{...an,'to':af});ak['kind']==='reverse'&&ak['filterType']&&(am=am['filter'](an=>inferObjectType(an['to'])===ak['filterType']));if(am['length']===0x0)continue;w['push']({'schema':aj,'sourceId':af,'refs':am,'observed':am['length']});}}}}for(const an of EDGE_SCHEMAS){const ao=an['read'];if(ao['kind']!=='event'||!f['allowsEvent'](an,p))continue;const ap=[...o]['filter'](ar=>{if(n['has'](ar+'|'+an['id']))return![];return sourceMatches(an['source'],h['graph']['nodes']['get'](ar));});if(ap['length']===0x0)continue;let aq=m['get'](ao['eventType']);if(!aq){aq={'events':[],'truncated':![],'failed':![]};try{const ar=await a['getEvents'](ao['eventType'],{'maxPages':e['maxEventPages']});if(readStats(a)['batches']>=e['maxRpcs'])h['exhausted']['rpcs']=!![];aq['events']=ar['events'],aq['truncated']=ar['truncated'],ar['truncated']&&ar['events']['length']===0x0&&(aq['failed']=!![],h['graph']['gaps']['push']('events:'+ao['eventType']));}catch{aq['failed']=!![],h['graph']['gaps']['push']('events:'+ao['eventType']);}m['set'](ao['eventType'],aq);}if(aq['failed']){for(const as of ap)n['add'](as+'|'+an['id']);continue;}if(aq['truncated']){h['exhausted']['eventPages']=!![];for(const at of ap){h['markTruncation']({'nodeId':at,'schema':an['id'],'observed':aq['events']['length'],'limit':e['maxEventPages'],'reason':'event_pages'});}}for(const au of ap){n['add'](au+'|'+an['id']);const av=extractEventRefs(ao,au,aq['events']);if(av['length']===0x0)continue;w['push']({'schema':an,'sourceId':au,'refs':av,'observed':av['length'],'truncated':aq['truncated']});}}const B=new Set(),C=new Map();for(const aw of w){const ax=e['perKindCaps'][aw['schema']['id']]??e['maxFanoutPerNode'],ay=C['get'](aw['sourceId'])??0x0,az=Math['max'](0x0,e['maxFanoutPerNode']-ay),aA=Math['min'](ax,az),aB=aw['refs']['slice'](0x0,aA);aw['refs']['length']>aA&&h['markTruncation']({'nodeId':aw['sourceId'],'schema':aw['schema']['id'],'observed':aw['refs']['length'],'limit':a95a,'reason':'fanout'});const aC=new Map();for(const aD of aB){const aE=aD['from']??aw['sourceId'],aF=isWfNodeId(aD['to'])?p:p+0x1,aG=h['graph']['nodes']['has'](aD['to']),aH=f['effectiveMaxHops'](aw['schema']);if(aH!==undefined){const aJ=(t(aE,new Set())['get'](aw['schema']['id'])??0x0)+0x1;if(aJ>aH&&!aG){aC['set'](aE,(aC['get'](aE)??0x0)+0x1);continue;}}if(aF>e['maxDepth']&&!aG){h['exhausted']['depth']=!![];continue;}const aI=h['addNode'](aD['to'],Math['min'](aF,e['maxDepth']),{'schema':aw['schema']['id'],'from':aE});if(!aI)break;h['addEdge'](aw['schema'],aE,aD,q,aw['truncated']===!![]||aw['refs']['length']>aA),C['set'](aw['sourceId'],ay+0x1);if(!isWfNodeId(aD['to'])&&aF<=e['maxDepth'])B['add'](aD['to']);}for(const [aK,aL]of aC){h['markTruncation']({'nodeId':aK,'schema':aw['schema']['id'],'observed':aL,'limit':f['effectiveMaxHops'](aw['schema'])??0x0,'reason':'schema_hops'});}}if(h['exhausted']['rpcs']){h['graph']['gaps']['push']('budget:maxRpcs');break;}o=B;}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});}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{applyExposureGate as
|
|
1
|
+
import{applyExposureGate as a98a}from'../../config/exposure.js';export{resolveViability,factRef,parseFactRef}from'../../config/exposure.js';export const EXPOSURE_ROLES={'buyer':'buyer','merchant':'merchant','supplier':'supplier','collaborator':'collaborator','arbitrator':'arbitrator','system':'system','neutral':'neutral'};export function applyExposureGate(a,b){return a98a(a,b);}export function lossParty(a,b){return{'role':a,'basis':b};}export function gainPath(a,b,c,d){return{'role':a,'path':b,'viability':c,'gate':d};}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{RETENTION_RANK,pathConfidence,findingWhere}from'./analyze.js';import{orderCompletionInGraph}from'./expand.js';import{profileOf}from'./viewport.js';const STATE_RANK={'present':0x0,'empty':0x1,'gap':0x2};function worstState(c,d){return STATE_RANK[c]>=STATE_RANK[d]?c:d;}export const COVERAGE_VOCABULARY={'present':'present\x20—\x20evidence\x20retrieved\x20and\x20non-empty;\x20real\x20material\x20the\x20rules\x20can\x20score.','empty':'empty\x20—\x20the\x20read\x20completed\x20and\x20verified\x20the\x20absence\x20of\x20data\x20(e.g.\x20no\x20review\x20votes);\x20an\x20answered\x20fact\x20the\x20rules\x20may\x20score,\x20never\x20a\x20fetch\x20failure.','gap':'gap\x20—\x20the\x20evidence\x20was\x20not\x20retrieved,\x20errored,\x20or\x20was\x20truncated;\x20it\x20is\x20unverifiable,\x20so\x20it\x20is\x20excluded\x20from\x20scoring\x20and\x20listed\x20in\x20unverified,\x20never\x20defaulted\x20to\x20a\x20low\x20score.','unverified':'unverified\x20—\x20rule\x20ids\x20excluded\x20from\x20the\x20score\x20because\x20their\x20evidence\x20is\x20gap-state;\x20missing\x20here\x20means\x20every\x20rule\x20was\x20scored\x20on\x20fetched\x20facts.','completeness':'completeness\x20—\x20percentage\x20of\x20required\x20evidence\x20slots\x20that\x20carry\x20material\x20(present);\x20verified-empty\x20slots\x20lower\x20it\x20but\x20stay\x20fully\x20scoreable.'};const REQUIRED_SLOTS=[{'slot':'service_snapshot','label':'Service\x20snapshot','gloss':'The\x20service\x27s\x20own\x20on-chain\x20record\x20(publish/pause\x20status,\x20price,\x20fund\x20and\x20bindings),\x20fetched\x20directly\x20from\x20chain.'},{'slot':'arbitration','label':'Arbitration\x20binding','gloss':'Dispute-resolution\x20services\x20bound\x20to\x20this\x20shop\x20—\x20whether\x20one\x20exists,\x20carries\x20a\x20voter\x20roster,\x20has\x20a\x20funded\x20fee,\x20and\x20is\x20not\x20paused.'},{'slot':'reviews','label':'Review\x20votes','gloss':'On-chain\x20like/dislike\x20votes\x20left\x20by\x20completed-order\x20counterparties;\x20an\x20empty\x20window\x20means\x20nobody\x20voted\x20yet,\x20not\x20a\x20bad\x20rating.'},{'slot':'fulfillment_orders','label':'Recent\x20orders','gloss':'Orders\x20in\x20the\x20shop\x27s\x20recent\x20order\x20window\x20with\x20completion\x20and\x20refund\x20outcomes,\x20used\x20to\x20measure\x20real\x20fulfillment.'},{'slot':'fulfillment_workflow','label':'Fulfillment\x20workflow','gloss':'The\x20bound\x20machine\x27s\x20nodes\x20and\x20forwards\x20that\x20every\x20paid\x20order\x20must\x20progress\x20through\x20to\x20reach\x20completion\x20or\x20refund.'},{'slot':'fund_safety','label':'Compensation\x20fund\x20vs\x20exposure','gloss':'The\x20merchant\x27s\x20compensation\x20fund\x20balance\x20measured\x20against\x20recent\x20order\x20volume\x20(the\x20safety\x20buffer\x20for\x20payouts).'},{'slot':'transparency','label':'Transparency\x20profile','gloss':'The\x20shop\x27s\x20public\x20on-chain\x20profile\x20—\x20description\x20and\x20publish/pause\x20flags\x20a\x20buyer\x20can\x20verify\x20before\x20paying.'}],SLOT_FACTS={'service_snapshot':[],'arbitration':['arbitration.binding'],'reviews':['reviews.votes'],'fulfillment_orders':['fulfillment.orders'],'fulfillment_workflow':['fulfillment.workflow'],'fund_safety':['fund.compensation','fund.exposure'],'transparency':['transparency.profile']},RISK_RULE_SOURCES={'risk_workflow':{'slots':['fulfillment_workflow'],'ruleIds':['R4']},'risk_fund':{'slots':['fund_safety','fulfillment_orders'],'ruleIds':['R2','R7','AC3','AC4']},'risk_trust':{'slots':['arbitration','transparency'],'ruleIds':['R1','R3','R6']},'risk_behavior':{'slots':['fulfillment_orders'],'ruleIds':['AC1','AC2']}};function nodeData(a,b){const c=a['graph']['nodes']['get'](b['toLowerCase']()),e=c?.['raw'],f=e?.['data']??e;return f&&typeof f==='object'?f:undefined;}function isFetched(a,b){const c=a['graph']['nodes']['get'](b['toLowerCase']());return!!c&&a['visibleNodes']['has'](c['id'])&&!!c['raw']&&c['state']!=='error'&&c['state']!=='stub';}function truncationOf(a,b,c){const d=a['graph']['truncations']['find'](e=>e['nodeId']===b&&e['schema']===c);return d?{'observed':d['observed'],'limit':d['limit']}:undefined;}function outEdges(a,b,c){return a['visibleEdges']['filter'](d=>d['from']===b['toLowerCase']()&&d['schema']===c);}function incEdges(a,b,c){return a['visibleEdges']['filter'](d=>d['to']===b['toLowerCase']()&&d['schema']===c);}function toBigInt(a){if(a==null)return 0x0n;try{return BigInt(typeof a==='number'?Math['trunc'](a):String(a));}catch{return 0x0n;}}function flag(a){return a===!![]||a===0x1||a==='1';}function snapProvenance(a){return{'path':a,'retention':'complete','confidence':'exact'};}function edgeProvenance(a,b,c){const {confidence:d,window:e}=pathConfidence(a,c),f=c['reduce']((g,h)=>RETENTION_RANK[h['retention']]>RETENTION_RANK[g]?h['retention']:g,'complete');return{'path':b,'retention':f,'confidence':d,...e?{'window':e}:{}};}export function projectEvaluationFacts(a,b,c){const f=b['toLowerCase'](),g=[],h=new Map(),i=new Map(),j=(U,V,W='exact')=>{h['set'](U,V),i['set'](U,W);},k=a['graph']['nodes']['get'](f),l=a['visibleNodes']['has'](f),m=!!(l&&k&&k['raw']&&k['state']!=='error'&&k['state']!=='stub'&&k['objectType']==='Service'),o=m?nodeData(a,f)??{}:{},q=k?.['coinType'];j('service_snapshot',m?'present':'gap');const r=Array['isArray'](o['arbitrations'])?o['arbitrations']['map'](String)['filter'](Boolean):[],u=outEdges(a,f,'service.arbitration'),w=[];let x=!![];for(const U of r){if(!isFetched(a,U)){x=![];continue;}const V=nodeData(a,U)??{},W=Array['isArray'](V['voting_guard'])?V['voting_guard']:[];w['push']({'id':U['toLowerCase'](),'paused':flag(V['bPaused']),'fee':toBigInt(V['fee'])['toString'](),'votingGuards':W['length'],'usageGuard':typeof V['usage_guard']==='string'&&V['usage_guard']!==''});}if(!m)j('arbitration','gap'),g['push']({'dimension':'arbitration','key':'arbitration.binding','state':'gap','provenance':snapProvenance([f]),'evidence':'Arbitration\x20configuration\x20unverifiable:\x20the\x20service\x20snapshot\x20is\x20missing.'});else{if(r['length']===0x0)j('arbitration','empty'),g['push']({'dimension':'arbitration','key':'arbitration.binding','state':'empty','value':[],'provenance':snapProvenance([f,'Service.arbitrations']),'evidence':'Service\x20snapshot\x20shows\x20no\x20arbitration\x20service\x20configured\x20(verified\x20absence).'});else!x?(j('arbitration','gap'),g['push']({'dimension':'arbitration','key':'arbitration.binding','state':'gap','value':w,'provenance':u['length']>0x0?edgeProvenance(a,[f,'service.arbitration'],u):snapProvenance([f,'Service.arbitrations']),'evidence':w['length']+'/'+r['length']+'\x20arbitration\x20service(s)\x20resolved;\x20the\x20rest\x20failed\x20to\x20fetch.'})):(j('arbitration','present',u['length']>0x0?edgeProvenance(a,[f,'service.arbitration'],u)['confidence']:'exact'),g['push']({'dimension':'arbitration','key':'arbitration.binding','state':'present','value':w,'provenance':u['length']>0x0?edgeProvenance(a,[f,'service.arbitration'],u):snapProvenance([f,'Service.arbitrations']),'evidence':w['length']+'\x20arbitration\x20service(s)\x20resolved\x20from\x20the\x20snapshot\x20with\x20voting\x20rosters.'}));}const y=outEdges(a,f,'target.vote'),z=truncationOf(a,f,'target.vote'),A={'total':y['length'],'like':0x0,'dislike':0x0,'favor':0x0};for(const X of y){const Y=typeof X['payload']?.['voteBits']==='number'?X['payload']['voteBits']:0x0;if(Y&0x2)A['like']+=0x1;if(Y&0x4)A['dislike']+=0x1;if(Y&0x8)A['favor']+=0x1;}const B=y['length']>0x0?edgeProvenance(a,[f,'target.vote'],y):snapProvenance([f,'registrar.votes']);if(!m)j('reviews','gap'),g['push']({'dimension':'reviews','key':'reviews.votes','state':'gap','provenance':snapProvenance([f]),'evidence':'Reputation\x20unverifiable:\x20the\x20service\x20snapshot\x20is\x20missing.'});else{if(z)j('reviews','gap',B['confidence']),g['push']({'dimension':'reviews','key':'reviews.votes','state':'gap','value':A,'provenance':{...B,'window':z},'evidence':'Vote\x20window\x20truncated\x20at\x20'+z['limit']+';\x20'+A['total']+'\x20vote(s)\x20visible\x20—\x20counts\x20are\x20a\x20floor.'});else A['total']===0x0?(j('reviews','empty'),g['push']({'dimension':'reviews','key':'reviews.votes','state':'empty','value':A,'provenance':B,'evidence':'No\x20registrar\x20votes\x20recorded\x20for\x20the\x20service\x20(window\x20read\x20empty,\x20no\x20truncation).'})):(j('reviews','present',B['confidence']),g['push']({'dimension':'reviews','key':'reviews.votes','state':'present','value':A,'provenance':B,'evidence':A['total']+'\x20registrar\x20vote(s):\x20'+A['like']+'\x20like,\x20'+A['dislike']+'\x20dislike,\x20'+A['favor']+'\x20favor.'}));}const C=outEdges(a,f,'service.order'),D=truncationOf(a,f,'service.order'),E={'observed':C['length'],'completed':0x0,'inProgress':0x0,'unknown':0x0,'windowedAmount':'0'};let F=0x0n;for(const Z of C){const a0=orderCompletionInGraph(a['graph'],Z['to'])['status'];if(a0==='completed')E['completed']+=0x1;else{if(a0==='in_progress')E['inProgress']+=0x1;else E['unknown']+=0x1;}F+=toBigInt(nodeData(a,Z['to'])?.['amount']);}E['windowedAmount']=F['toString']();const G=C['length']>0x0?edgeProvenance(a,[f,'service.order','Order'],C):snapProvenance([f,'service.order']);let H;if(!m)H='gap';else{if(D)H='gap';else H=C['length']===0x0?'empty':'present';}j('fulfillment_orders',H,G['confidence']);if(H==='gap'&&m)g['push']({'dimension':'fulfillment','key':'fulfillment.orders','state':'gap','value':E,'provenance':{...G,'window':D},'evidence':'Order\x20window\x20truncated\x20at\x20'+D?.['limit']+'\x20(observed\x20'+D?.['observed']+');\x20'+E['observed']+'\x20order(s)\x20visible\x20—\x20completion\x20stats\x20are\x20a\x20partial\x20floor.'});else{if(H==='empty')g['push']({'dimension':'fulfillment','key':'fulfillment.orders','state':'empty','value':E,'provenance':G,'evidence':'No\x20orders\x20in\x20the\x20service\x20window\x20(verified\x20absence).'});else H==='present'?g['push']({'dimension':'fulfillment','key':'fulfillment.orders','state':'present','value':E,'provenance':G,'evidence':E['observed']+'\x20recent\x20order(s):\x20'+E['completed']+'\x20completed,\x20'+E['inProgress']+'\x20in\x20progress,\x20'+E['unknown']+'\x20unresolved.'}):g['push']({'dimension':'fulfillment','key':'fulfillment.orders','state':'gap','provenance':snapProvenance([f]),'evidence':'Order\x20window\x20unverifiable:\x20the\x20service\x20snapshot\x20is\x20missing.'});}const I=typeof o['machine']==='string'?o['machine']:'',J=I!==''&&isFetched(a,I),K=I===''?'':I['toLowerCase']()+'::node::',L=K===''?[]:a['graph']['edges']['filter'](a1=>a1['schema']==='wf.transition'&&a1['from']['startsWith'](K)),M=new Set();for(const a1 of L){M['add'](a1['from']);const a2=String(a1['payload']?.['node']??'');if(a2!=='')M['add'](''+K+a2);}let N,O;if(!m)N='gap',O='Workflow\x20unverifiable:\x20the\x20service\x20snapshot\x20is\x20missing.';else{if(I==='')N='empty',O='No\x20workflow\x20template\x20configured\x20(verified\x20absence).';else{if(!J)N='gap',O='Machine\x20template\x20referenced\x20but\x20not\x20fetched\x20(fetch\x20gap).';else L['length']===0x0?(N='gap',O='Machine\x20fetched\x20but\x20no\x20wf.transition\x20edges\x20—\x20terminal\x20set\x20unverifiable;\x20completion\x20states\x20stay\x20unknown.'):(N='present',O='Machine\x20template\x20resolved\x20with\x20'+M['size']+'\x20workflow\x20node(s);\x20terminal\x20set\x20verifiable.');}}j('fulfillment_workflow',N,N==='present'?'exact':N==='empty'?'exact':'windowed'),g['push']({'dimension':'fulfillment','key':'fulfillment.workflow','state':N,...I!==''&&J?{'value':{'machine':I['toLowerCase'](),'nodes':M['size']}}:{},'provenance':N==='present'?edgeProvenance(a,[f,'service.machine','wf.transition'],L):snapProvenance([f,'Service.machine']),'evidence':O});const P=toBigInt(o['compensation_fund']);if(!m)j('fund_safety','gap'),g['push']({'dimension':'fund_safety','key':'fund.compensation','state':'gap','provenance':snapProvenance([f]),'evidence':'Fund\x20backing\x20unverifiable:\x20the\x20service\x20snapshot\x20is\x20missing.'}),g['push']({'dimension':'fund_safety','key':'fund.exposure','state':'gap','provenance':snapProvenance([f]),'evidence':'Payout\x20exposure\x20unverifiable:\x20the\x20service\x20snapshot\x20is\x20missing.'});else{j('fund_safety','present'),g['push']({'dimension':'fund_safety','key':'fund.compensation','state':'present','value':{'fund':P['toString'](),...q?{'coinType':q}:{}},'provenance':snapProvenance([f,'Service.compensation_fund']),'evidence':'Compensation\x20fund\x20'+P['toString']()+'\x20base\x20units'+(q?'\x20in\x20'+q:'')+'.'});const a3=F*0x3n,a4=worstState('present',H),a5=c['find'](a6=>a6['id']==='R2:'+f);g['push']({'dimension':'fund_safety','key':'fund.exposure','state':a4,'value':{'fund':P['toString'](),'windowedCount':E['observed'],'windowedAmount':F['toString'](),'neededCeiling':a3['toString'](),'coverageMet':P>=a3},'provenance':C['length']>0x0?edgeProvenance(a,[f,'service.order','Order.amount','Service.compensation_fund'],C):snapProvenance([f,'Service.compensation_fund']),'findingIds':a5?[a5['id']]:undefined,'evidence':H==='empty'?'No\x20recent\x20orders;\x20no\x20payout\x20exposure\x20to\x20cover.':'Recent\x20orders\x20total\x20'+F['toString']()+'\x20base\x20units'+(q?'\x20in\x20'+q:'')+'\x20across\x20'+E['observed']+'\x20order(s);\x20the\x20compensation\x20fund\x20should\x20cover\x20at\x20least\x203x\x20that\x20('+a3['toString']()+'\x20base\x20units'+(q?'\x20in\x20'+q:'')+')\x20—\x20coverage\x20'+(P>=a3?'met':'not\x20met')+(D?'\x20(older\x20orders\x20outside\x20the\x20fetch\x20window,\x20floor\x20value\x20only)':'')+'.'});}if(!m)j('transparency','gap'),g['push']({'dimension':'transparency','key':'transparency.profile','state':'gap','provenance':snapProvenance([f]),'evidence':'Transparency\x20unverifiable:\x20the\x20service\x20snapshot\x20is\x20missing.'});else{const a6=typeof o['setting_lock_duration']==='number'?o['setting_lock_duration']:Number(toBigInt(o['setting_lock_duration'])),a7=flag(o['bPublished']);j('transparency','present'),g['push']({'dimension':'transparency','key':'transparency.profile','state':'present','value':{'description':typeof o['description']==='string'?o['description']:'','location':typeof o['location']==='string'?o['location']:'','settingLockDuration':Number['isFinite'](a6)?a6:0x0,'published':a7,'paused':flag(o['bPaused'])},'provenance':snapProvenance([f,'Service.bPublished','Service.setting_lock_duration']),'findingIds':c['some'](a8=>a8['id']==='R6:'+f)?['R6:'+f]:undefined,'evidence':'Service\x20profile:\x20description\x20'+(typeof o['description']==='string'&&o['description']!==''?'provided':'not\x20provided')+',\x20location\x20'+(typeof o['location']==='string'&&o['location']!==''?'provided':'not\x20provided')+',\x20service\x20lock\x20'+a6+'\x20ms,\x20'+(a7?'published':'unpublished')+'.'});}for(const a8 of['risk_workflow','risk_fund','risk_trust','risk_behavior']){const a9=RISK_RULE_SOURCES[a8];let aa='present',ab,ac=-0x1;for(const aj of a9['slots']){const ak=h['get'](aj)??'gap';STATE_RANK[ak]>ac&&(ac=STATE_RANK[ak],aa=ak,ab=aj);}let ae;if(aa==='gap')ae='windowed';else{if(aa==='empty')ae='bounded';else ae=ab&&i['get'](ab)||'exact';}const af=f['toLowerCase'](),ag=new Set([af,...[...a['graph']['nodes']['keys']()]['map'](al=>al['toLowerCase']())]),ah=(al,am)=>{if(!al['startsWith'](am+':'))return![];const an=al['slice'](am['length']+0x1)['toLowerCase'](),ao=an['split']('#')[0x0]['split'](':')[0x0]['split']('|')[0x0];return ao['length']===0x0||ag['has'](ao);},ai=c['filter'](al=>a9['ruleIds']['some'](am=>al['id']['startsWith'](am+String['fromCharCode'](0x3a))));g['push']({'dimension':a8,'key':a8+'.findings','state':aa,'value':{'findings':ai['map'](al=>({'id':al['id'],'severity':al['severity'],'title':al['title']})),'where':ai['map'](al=>findingWhere(al))},'provenance':{'path':[f,...a9['slots']],'retention':'derived','confidence':ae},'findingIds':ai['map'](al=>al['id']),'evidence':aa==='gap'?'Input\x20evidence\x20has\x20fetch\x20gaps;\x20the\x20risk\x20conclusion\x20is\x20unverifiable.':aa==='empty'?'Input\x20evidence\x20is\x20configured-empty;\x20the\x20risk\x20rules\x20are\x20not\x20applicable.':ai['length']>0x0?ai['length']+'\x20structural\x20risk\x20finding(s)\x20on\x20this\x20object,\x20from\x20the\x20analyzer\x20registry.':'No\x20risk\x20fired\x20on\x20this\x20object;\x20input\x20evidence\x20slots\x20are\x20fully\x20materialized.'});}const Q=[];for(const al of a['visibleNodes']){const am=profileOf(a,al);if(!am)continue;const an=Array['isArray'](am['profileRecords'])?am['profileRecords']:undefined;Q['push']({'nodeId':al,...typeof am['registeredAt']==='number'?{'registeredAt':am['registeredAt']}:{},'hasDescription':!!am['hasDescription']||typeof am['description']==='string','recordCount':typeof am['recordCount']==='number'?am['recordCount']:an?.['length']??0x0,...typeof am['description']==='string'?{'description':am['description']}:{},...an?{'profileRecords':an}:{}});}const R=REQUIRED_SLOTS['length'],S=REQUIRED_SLOTS['filter'](({slot:ao})=>h['get'](ao)==='present')['length'],T=R===0x0?0x64:Math['round'](S/R*0x64);return{'target':f,'role':String(a['role']),'facts':g,'slots':REQUIRED_SLOTS['map'](({slot:ao,label:ap,gloss:aq})=>({'slot':ao,'label':ap,'gloss':aq,'required':!![],'state':h['get'](ao)??'gap','facts':[...SLOT_FACTS[ao]??[]]})),'completeness':T,'profiles':Q};}
|
|
1
|
+
import{RETENTION_RANK,pathConfidence,findingWhere}from'./analyze.js';import{orderCompletionInGraph}from'./expand.js';import{profileOf}from'./viewport.js';const STATE_RANK={'present':0x0,'empty':0x1,'gap':0x2};function worstState(c,d){return STATE_RANK[c]>=STATE_RANK[d]?c:d;}export const COVERAGE_VOCABULARY={'present':'present\x20—\x20evidence\x20retrieved\x20and\x20non-empty;\x20real\x20material\x20the\x20rules\x20can\x20score.','empty':'empty\x20—\x20the\x20read\x20completed\x20and\x20verified\x20the\x20absence\x20of\x20data\x20(e.g.\x20no\x20review\x20votes);\x20an\x20answered\x20fact\x20the\x20rules\x20may\x20score,\x20never\x20a\x20fetch\x20failure.','gap':'gap\x20—\x20the\x20evidence\x20was\x20not\x20retrieved,\x20errored,\x20or\x20was\x20truncated;\x20it\x20is\x20unverifiable,\x20so\x20it\x20is\x20excluded\x20from\x20scoring\x20and\x20listed\x20in\x20unverified,\x20never\x20defaulted\x20to\x20a\x20low\x20score.','unverified':'unverified\x20—\x20rule\x20ids\x20excluded\x20from\x20the\x20score\x20because\x20their\x20evidence\x20is\x20gap-state;\x20missing\x20here\x20means\x20every\x20rule\x20was\x20scored\x20on\x20fetched\x20facts.','completeness':'completeness\x20—\x20percentage\x20of\x20required\x20evidence\x20slots\x20that\x20carry\x20material\x20(present);\x20verified-empty\x20slots\x20lower\x20it\x20but\x20stay\x20fully\x20scoreable.'};const REQUIRED_SLOTS=[{'slot':'service_snapshot','label':'Service\x20snapshot','gloss':'The\x20service\x27s\x20own\x20on-chain\x20record\x20(publish/pause\x20status,\x20price,\x20fund\x20and\x20bindings),\x20fetched\x20directly\x20from\x20chain.'},{'slot':'arbitration','label':'Arbitration\x20binding','gloss':'Dispute-resolution\x20services\x20bound\x20to\x20this\x20shop\x20—\x20whether\x20one\x20exists,\x20carries\x20a\x20voter\x20roster,\x20has\x20a\x20funded\x20fee,\x20and\x20is\x20not\x20paused.'},{'slot':'reviews','label':'Review\x20votes','gloss':'On-chain\x20like/dislike\x20votes\x20left\x20by\x20completed-order\x20counterparties;\x20an\x20empty\x20window\x20means\x20nobody\x20voted\x20yet,\x20not\x20a\x20bad\x20rating.'},{'slot':'fulfillment_orders','label':'Recent\x20orders','gloss':'Orders\x20in\x20the\x20shop\x27s\x20recent\x20order\x20window\x20with\x20completion\x20and\x20refund\x20outcomes,\x20used\x20to\x20measure\x20real\x20fulfillment.'},{'slot':'fulfillment_workflow','label':'Fulfillment\x20workflow','gloss':'The\x20bound\x20machine\x27s\x20nodes\x20and\x20forwards\x20that\x20every\x20paid\x20order\x20must\x20progress\x20through\x20to\x20reach\x20completion\x20or\x20refund.'},{'slot':'fund_safety','label':'Compensation\x20fund\x20vs\x20exposure','gloss':'The\x20merchant\x27s\x20compensation\x20fund\x20balance\x20measured\x20against\x20recent\x20order\x20volume\x20(the\x20safety\x20buffer\x20for\x20payouts).'},{'slot':'transparency','label':'Transparency\x20profile','gloss':'The\x20shop\x27s\x20public\x20on-chain\x20profile\x20—\x20description\x20and\x20publish/pause\x20flags\x20a\x20buyer\x20can\x20verify\x20before\x20paying.'}],SLOT_FACTS={'service_snapshot':[],'arbitration':['arbitration.binding'],'reviews':['reviews.votes'],'fulfillment_orders':['fulfillment.orders'],'fulfillment_workflow':['fulfillment.workflow'],'fund_safety':['fund.compensation','fund.exposure'],'transparency':['transparency.profile']},RISK_RULE_SOURCES={'risk_workflow':{'slots':['fulfillment_workflow'],'ruleIds':['R4']},'risk_fund':{'slots':['fund_safety','fulfillment_orders'],'ruleIds':['R2','R7','AC3','AC4']},'risk_trust':{'slots':['arbitration','transparency'],'ruleIds':['R1','R3','R6']},'risk_behavior':{'slots':['fulfillment_orders'],'ruleIds':['AC1','AC2']}};function nodeData(a,b){const c=a['graph']['nodes']['get'](b['toLowerCase']()),e=c?.['raw'],f=e?.['data']??e;return f&&typeof f==='object'?f:undefined;}function isFetched(a,b){const c=a['graph']['nodes']['get'](b['toLowerCase']());return!!c&&a['visibleNodes']['has'](c['id'])&&!!c['raw']&&c['state']!=='error'&&c['state']!=='stub';}function truncationOf(a,b,c){const d=a['graph']['truncations']['find'](e=>e['nodeId']===b&&e['schema']===c);return d?{'observed':d['observed'],'limit':d['limit']}:undefined;}function outEdges(a,b,c){return a['visibleEdges']['filter'](d=>d['from']===b['toLowerCase']()&&d['schema']===c);}function incEdges(a,b,c){return a['visibleEdges']['filter'](d=>d['to']===b['toLowerCase']()&&d['schema']===c);}function toBigInt(a){if(a==null)return 0x0n;try{return BigInt(typeof a==='number'?Math['trunc'](a):String(a));}catch{return 0x0n;}}function flag(a){return a===!![]||a===0x1||a==='1';}function snapProvenance(a){return{'path':a,'retention':'complete','confidence':'exact'};}function edgeProvenance(a,b,c){const {confidence:d,window:e}=pathConfidence(a,c),f=c['reduce']((g,h)=>RETENTION_RANK[h['retention']]>RETENTION_RANK[g]?h['retention']:g,'complete');return{'path':b,'retention':f,'confidence':d,...e?{'window':e}:{}};}export function projectEvaluationFacts(a,b,c){const f=b['toLowerCase'](),g=[],h=new Map(),i=new Map(),j=(U,V,W='exact')=>{h['set'](U,V),i['set'](U,W);},k=a['graph']['nodes']['get'](f),l=a['visibleNodes']['has'](f),m=!!(l&&k&&k['raw']&&k['state']!=='error'&&k['state']!=='stub'&&k['objectType']==='Service'),o=m?nodeData(a,f)??{}:{},q=k?.['coinType'];j('service_snapshot',m?'present':'gap');const r=Array['isArray'](o['arbitrations'])?o['arbitrations']['map'](String)['filter'](Boolean):[],u=outEdges(a,f,'service.arbitration'),w=[];let x=!![];for(const U of r){if(!isFetched(a,U)){x=![];continue;}const V=nodeData(a,U)??{},W=Array['isArray'](V['voting_guard'])?V['voting_guard']:[];w['push']({'id':U['toLowerCase'](),'paused':flag(V['bPaused']),'fee':toBigInt(V['fee'])['toString'](),'votingGuards':W['length'],'usageGuard':typeof V['usage_guard']==='string'&&V['usage_guard']!==''});}if(!m)j('arbitration','gap'),g['push']({'dimension':'arbitration','key':'arbitration.binding','state':'gap','provenance':snapProvenance([f]),'evidence':'Arbitration\x20configuration\x20unverifiable:\x20the\x20service\x20snapshot\x20is\x20missing.'});else{if(r['length']===0x0)j('arbitration','empty'),g['push']({'dimension':'arbitration','key':'arbitration.binding','state':'empty','value':[],'provenance':snapProvenance([f,'Service.arbitrations']),'evidence':'Service\x20snapshot\x20shows\x20no\x20arbitration\x20service\x20configured\x20(verified\x20absence).'});else!x?(j('arbitration','gap'),g['push']({'dimension':'arbitration','key':'arbitration.binding','state':'gap','value':w,'provenance':u['length']>0x0?edgeProvenance(a,[f,'service.arbitration'],u):snapProvenance([f,'Service.arbitrations']),'evidence':w['length']+'/'+r['length']+'\x20arbitration\x20service(s)\x20resolved;\x20the\x20rest\x20failed\x20to\x20fetch.'})):(j('arbitration','present',u['length']>0x0?edgeProvenance(a,[f,'service.arbitration'],u)['confidence']:'exact'),g['push']({'dimension':'arbitration','key':'arbitration.binding','state':'present','value':w,'provenance':u['length']>0x0?edgeProvenance(a,[f,'service.arbitration'],u):snapProvenance([f,'Service.arbitrations']),'evidence':w['length']+'\x20arbitration\x20service(s)\x20resolved\x20from\x20the\x20snapshot\x20with\x20voting\x20rosters.'}));}const y=outEdges(a,f,'target.vote'),z=truncationOf(a,f,'target.vote'),A={'total':y['length'],'like':0x0,'dislike':0x0,'favor':0x0};for(const X of y){const Y=typeof X['payload']?.['voteBits']==='number'?X['payload']['voteBits']:0x0;if(Y&0x2)A['like']+=0x1;if(Y&0x4)A['dislike']+=0x1;if(Y&0x8)A['favor']+=0x1;}const B=y['length']>0x0?edgeProvenance(a,[f,'target.vote'],y):snapProvenance([f,'registrar.votes']);if(!m)j('reviews','gap'),g['push']({'dimension':'reviews','key':'reviews.votes','state':'gap','provenance':snapProvenance([f]),'evidence':'Reputation\x20unverifiable:\x20the\x20service\x20snapshot\x20is\x20missing.'});else{if(z)j('reviews','gap',B['confidence']),g['push']({'dimension':'reviews','key':'reviews.votes','state':'gap','value':A,'provenance':{...B,'window':z},'evidence':'Vote\x20window\x20truncated\x20at\x20'+z['limit']+';\x20'+A['total']+'\x20vote(s)\x20visible\x20—\x20counts\x20are\x20a\x20floor.'});else A['total']===0x0?(j('reviews','empty'),g['push']({'dimension':'reviews','key':'reviews.votes','state':'empty','value':A,'provenance':B,'evidence':'No\x20registrar\x20votes\x20recorded\x20for\x20the\x20service\x20(window\x20read\x20empty,\x20no\x20truncation).'})):(j('reviews','present',B['confidence']),g['push']({'dimension':'reviews','key':'reviews.votes','state':'present','value':A,'provenance':B,'evidence':A['total']+'\x20registrar\x20vote(s):\x20'+A['like']+'\x20like,\x20'+A['dislike']+'\x20dislike,\x20'+A['favor']+'\x20favor.'}));}const C=outEdges(a,f,'service.order'),D=truncationOf(a,f,'service.order'),E={'observed':C['length'],'completed':0x0,'inProgress':0x0,'unknown':0x0,'windowedAmount':'0'};let F=0x0n;for(const Z of C){const a0=orderCompletionInGraph(a['graph'],Z['to'])['status'];if(a0==='completed')E['completed']+=0x1;else{if(a0==='in_progress')E['inProgress']+=0x1;else E['unknown']+=0x1;}F+=toBigInt(nodeData(a,Z['to'])?.['amount']);}E['windowedAmount']=F['toString']();const G=C['length']>0x0?edgeProvenance(a,[f,'service.order','Order'],C):snapProvenance([f,'service.order']);let H;if(!m)H='gap';else{if(D)H='gap';else H=C['length']===0x0?'empty':'present';}j('fulfillment_orders',H,G['confidence']);if(H==='gap'&&m)g['push']({'dimension':'fulfillment','key':'fulfillment.orders','state':'gap','value':E,'provenance':{...G,'window':D},'evidence':'Order\x20window\x20truncated\x20at\x20'+D?.['limit']+'\x20(observed\x20'+D?.['observed']+');\x20'+E['observed']+'\x20order(s)\x20visible\x20—\x20completion\x20stats\x20are\x20a\x20partial\x20floor.'});else{if(H==='empty')g['push']({'dimension':'fulfillment','key':'fulfillment.orders','state':'empty','value':E,'provenance':G,'evidence':'No\x20orders\x20in\x20the\x20service\x20window\x20(verified\x20absence).'});else H==='present'?g['push']({'dimension':'fulfillment','key':'fulfillment.orders','state':'present','value':E,'provenance':G,'evidence':E['observed']+'\x20recent\x20order(s):\x20'+E['completed']+'\x20completed,\x20'+E['inProgress']+'\x20in\x20progress,\x20'+E['unknown']+'\x20unresolved.'}):g['push']({'dimension':'fulfillment','key':'fulfillment.orders','state':'gap','provenance':snapProvenance([f]),'evidence':'Order\x20window\x20unverifiable:\x20the\x20service\x20snapshot\x20is\x20missing.'});}const I=typeof o['machine']==='string'?o['machine']:'',J=I!==''&&isFetched(a,I),K=I===''?'':I['toLowerCase']()+'::node::',L=K===''?[]:a['graph']['edges']['filter'](a1=>a1['schema']==='wf.transition'&&a1['from']['startsWith'](K)),M=new Set();for(const a1 of L){M['add'](a1['from']);const a2=String(a1['payload']?.['node']??'');if(a2!=='')M['add'](''+K+a2);}let N,O;if(!m)N='gap',O='Workflow\x20unverifiable:\x20the\x20service\x20snapshot\x20is\x20missing.';else{if(I==='')N='empty',O='No\x20workflow\x20template\x20configured\x20(verified\x20absence).';else{if(!J)N='gap',O='Machine\x20template\x20referenced\x20but\x20not\x20fetched\x20(fetch\x20gap).';else L['length']===0x0?(N='gap',O='Machine\x20fetched\x20but\x20no\x20wf.transition\x20edges\x20—\x20terminal\x20set\x20unverifiable;\x20completion\x20states\x20stay\x20unknown.'):(N='present',O='Machine\x20template\x20resolved\x20with\x20'+M['size']+'\x20workflow\x20node(s);\x20terminal\x20set\x20verifiable.');}}j('fulfillment_workflow',N,N==='present'?'exact':N==='empty'?'exact':'windowed'),g['push']({'dimension':'fulfillment','key':'fulfillment.workflow','state':N,...I!==''&&J?{'value':{'machine':I['toLowerCase'](),'nodes':M['size']}}:{},'provenance':N==='present'?edgeProvenance(a,[f,'service.machine','wf.transition'],L):snapProvenance([f,'Service.machine']),'evidence':O});const P=toBigInt(o['compensation_fund']);if(!m)j('fund_safety','gap'),g['push']({'dimension':'fund_safety','key':'fund.compensation','state':'gap','provenance':snapProvenance([f]),'evidence':'Fund\x20backing\x20unverifiable:\x20the\x20service\x20snapshot\x20is\x20missing.'}),g['push']({'dimension':'fund_safety','key':'fund.exposure','state':'gap','provenance':snapProvenance([f]),'evidence':'Payout\x20exposure\x20unverifiable:\x20the\x20service\x20snapshot\x20is\x20missing.'});else{j('fund_safety','present'),g['push']({'dimension':'fund_safety','key':'fund.compensation','state':'present','value':{'fund':P['toString'](),...q?{'coinType':q}:{}},'provenance':snapProvenance([f,'Service.compensation_fund']),'evidence':'Compensation\x20fund\x20'+P['toString']()+'\x20base\x20units'+(q?'\x20in\x20'+q:'')+'.'});const a3=F*0x3n,a4=worstState('present',H),a5=c['find'](a6=>a6['id']==='R2:'+f);g['push']({'dimension':'fund_safety','key':'fund.exposure','state':a4,'value':{'fund':P['toString'](),'windowedCount':E['observed'],'windowedAmount':F['toString'](),'neededCeiling':a3['toString'](),'coverageMet':P>=a3},'provenance':C['length']>0x0?edgeProvenance(a,[f,'service.order','Order.amount','Service.compensation_fund'],C):snapProvenance([f,'Service.compensation_fund']),'findingIds':a5?[a5['id']]:undefined,'evidence':H==='empty'?'No\x20recent\x20orders;\x20no\x20payout\x20exposure\x20to\x20cover.':'Recent\x20orders\x20total\x20'+F['toString']()+'\x20base\x20units'+(q?'\x20in\x20'+q:'')+'\x20across\x20'+E['observed']+'\x20order(s);\x20the\x20compensation\x20fund\x20should\x20cover\x20at\x20least\x203x\x20that\x20('+a3['toString']()+'\x20base\x20units'+(q?'\x20in\x20'+q:'')+')\x20—\x20coverage\x20'+(P>=a3?'met':'not\x20met')+(D?'\x20(older\x20orders\x20outside\x20the\x20fetch\x20window,\x20floor\x20value\x20only)':'')+'.'});}if(!m)j('transparency','gap'),g['push']({'dimension':'transparency','key':'transparency.profile','state':'gap','provenance':snapProvenance([f]),'evidence':'Transparency\x20unverifiable:\x20the\x20service\x20snapshot\x20is\x20missing.'});else{const a6=typeof o['setting_lock_duration']==='number'?o['setting_lock_duration']:Number(toBigInt(o['setting_lock_duration'])),a7=flag(o['bPublished']);j('transparency','present'),g['push']({'dimension':'transparency','key':'transparency.profile','state':'present','value':{'description':typeof o['description']==='string'?o['description']:'','location':typeof o['location']==='string'?o['location']:'','settingLockDuration':Number['isFinite'](a6)?a6:0x0,'published':a7,'paused':flag(o['bPaused'])},'provenance':snapProvenance([f,'Service.bPublished','Service.setting_lock_duration']),'findingIds':c['some'](a8=>a8['id']==='R6:'+f)?['R6:'+f]:undefined,'evidence':'Service\x20profile:\x20description\x20'+(typeof o['description']==='string'&&o['description']!==''?'provided':'not\x20provided')+',\x20location\x20'+(typeof o['location']==='string'&&o['location']!==''?'provided':'not\x20provided')+',\x20service\x20lock\x20'+a6+'\x20ms,\x20'+(a7?'published':'unpublished')+'.'});}for(const a8 of['risk_workflow','risk_fund','risk_trust','risk_behavior']){const a9=RISK_RULE_SOURCES[a8];let aa='present',ab,ac=-0x1;for(const aj of a9['slots']){const ak=h['get'](aj)??'gap';STATE_RANK[ak]>ac&&(ac=STATE_RANK[ak],aa=ak,ab=aj);}let ae;if(aa==='gap')ae='windowed';else{if(aa==='empty')ae='bounded';else ae=ab&&i['get'](ab)||'exact';}const af=f['toLowerCase'](),ag=new Set([af,...[...a['graph']['nodes']['keys']()]['map'](al=>al['toLowerCase']())]),ah=(al,am)=>{if(!al['startsWith'](am+':'))return![];const an=al['slice'](am['length']+0x1)['toLowerCase'](),ao=an['split']('#')[0x0]['split']('|')[0x0];return ao['split'](':')['some'](ap=>ap['length']===0x0||ag['has'](ap));},ai=c['filter'](al=>a9['ruleIds']['some'](am=>ah(al['id'],am)));g['push']({'dimension':a8,'key':a8+'.findings','state':aa,'value':{'findings':ai['map'](al=>({'id':al['id'],'severity':al['severity'],'title':al['title']})),'where':ai['map'](al=>findingWhere(al))},'provenance':{'path':[f,...a9['slots']],'retention':'derived','confidence':ae},'findingIds':ai['map'](al=>al['id']),'evidence':aa==='gap'?'Input\x20evidence\x20has\x20fetch\x20gaps;\x20the\x20risk\x20conclusion\x20is\x20unverifiable.':aa==='empty'?'Input\x20evidence\x20is\x20configured-empty;\x20the\x20risk\x20rules\x20are\x20not\x20applicable.':ai['length']>0x0?ai['length']+'\x20structural\x20risk\x20finding(s)\x20on\x20this\x20object,\x20from\x20the\x20analyzer\x20registry.':'No\x20risk\x20fired\x20on\x20this\x20object;\x20input\x20evidence\x20slots\x20are\x20fully\x20materialized.'});}const Q=[];for(const al of a['visibleNodes']){const am=profileOf(a,al);if(!am)continue;const an=Array['isArray'](am['profileRecords'])?am['profileRecords']:undefined;Q['push']({'nodeId':al,...typeof am['registeredAt']==='number'?{'registeredAt':am['registeredAt']}:{},'hasDescription':!!am['hasDescription']||typeof am['description']==='string','recordCount':typeof am['recordCount']==='number'?am['recordCount']:an?.['length']??0x0,...typeof am['description']==='string'?{'description':am['description']}:{},...an?{'profileRecords':an}:{}});}const R=REQUIRED_SLOTS['length'],S=REQUIRED_SLOTS['filter'](({slot:ao})=>h['get'](ao)==='present')['length'],T=R===0x0?0x64:Math['round'](S/R*0x64);return{'target':f,'role':String(a['role']),'facts':g,'slots':REQUIRED_SLOTS['map'](({slot:ao,label:ap,gloss:aq})=>({'slot':ao,'label':ap,'gloss':aq,'required':!![],'state':h['get'](ao)??'gap','facts':[...SLOT_FACTS[ao]??[]]})),'completeness':T,'profiles':Q};}
|
|
@@ -27,6 +27,13 @@ export interface SettlementDetectorDeps {
|
|
|
27
27
|
formatAmount?(balance: bigint, tokenType: string | undefined, network: string): Promise<string | undefined>;
|
|
28
28
|
}
|
|
29
29
|
export declare function detectSettlementPending(scope: ScopeSnapshot, network: string, deps: SettlementDetectorDeps, maxObjects: number): Promise<KeeperDesiredItem[]>;
|
|
30
|
+
export interface TimeoutDetectorDeps {
|
|
31
|
+
fetchProgressFields(addrs: string[], network: string): Promise<Map<string, any>>;
|
|
32
|
+
fetchMachineNodes(machine: string, network: string): Promise<ParsedMachineNode[]>;
|
|
33
|
+
nowMs(): number;
|
|
34
|
+
}
|
|
35
|
+
export declare function detectTimeoutIntermediate(scope: ScopeSnapshot, network: string, deps: TimeoutDetectorDeps, maxObjects: number, timeoutMs: number): Promise<KeeperDesiredItem[]>;
|
|
30
36
|
export declare function realPaymentDetectorDeps(): PaymentDetectorDeps;
|
|
31
37
|
export declare function realProgressDetectorDeps(): ProgressDetectorDeps;
|
|
32
38
|
export declare function realSettlementDetectorDeps(): SettlementDetectorDeps;
|
|
39
|
+
export declare function realTimeoutDetectorDeps(): TimeoutDetectorDeps;
|
package/dist/keeper/detectors.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{query_received,query_objects}from'@wowok/wowok';import{batchQueryObjectsByIds,fetchMachineNodes,fetchOrderContext,fetchPermissionContext}from'../graph/onchain/sdk-batch.js';import{extractCoinType}from'../graph/onchain/extract.js';import{enumerateActionableForwards}from'../knowledge/index.js';import{formatChainValue}from'../knowledge/fund-layer.js';import{formatShortAddress}from'../persona/address-format.js';export async function detectPaymentUnclaimed(a,b,c){const d=[];for(const e of a){const f=e['toLowerCase']();let g=null;try{g=await c['queryUnclaimed'](f,b);}catch{g=null;}if(!g||g['balance']<=0x0n||g['count']<=0x0)continue;let h;try{h=await c['formatAmount']?.(g['balance'],g['token_type'],b);}catch{h=undefined;}const i=h??g['balance']['toString']()+'\x20(smallest\x20unit)';d['push']({'dedupe_key':'payment_unclaimed:'+f,'detector':'payment_unclaimed','beneficiary':f,'operation':{'operation_type':'payment','data':{'receive':!![]}},'title':'Unclaimed\x20funds\x20—\x20'+i+'\x20waiting\x20to\x20be\x20received','detail':g['count']+'\x20CoinWrapper\x20object(s)\x20hold\x20'+i+'\x20for\x20this\x20account.\x20'+'They\x20are\x20owned\x20but\x20NOT\x20spendable\x20until\x20unwrapped.\x20Execute\x20payment\x20{receive:true}\x20'+'as\x20this\x20account\x20to\x20unwrap\x20all\x20of\x20them\x20into\x20the\x20wallet\x20in\x20one\x20transaction\x20(keeper\x20can\x20'+'auto-execute\x20this\x20when\x20a\x20payment_unclaimed\x20auto-exec\x20rule\x20covers\x20the\x20account).','benefit':'Receive\x20'+i+'\x20into\x20your\x20wallet','state_fingerprint':g['count']+':'+g['balance']['toString']()});}return d;}export async function detectProgressActionable(a,b,c,d){const e=(a['order_children']??[])['filter'](n=>n['type']==='progress'&&typeof n['object']==='string')['map'](n=>n['object'])['filter'](n=>n['startsWith']('0x')),f=(a['focus']??[])['map'](n=>n['object'])['filter'](n=>typeof n==='string'&&n['startsWith']('0x')),g=[...new Set([...e,...f])]['slice'](0x0,Math['max'](0x1,d));if(g['length']===0x0||(a['accounts']??[])['length']===0x0)return[];let h;try{h=await c['fetchProgressFields'](g,b);}catch{return[];}const i=new Map(),j=new Map(),k=new Map(),l=a['accounts'],m=[];for(const [n,o]of h){const p=typeof o?.['machine']==='string'?o['machine']:undefined;if(!p)continue;const q=p['toLowerCase']();let r=i['get'](q);if(!r){try{r=await c['fetchMachineNodes'](p,b);}catch{r=[];}i['set'](q,r);}if(r['length']===0x0)continue;let s;if(!j['has'](q)){let z;try{z=await c['fetchMachinePermissionAddr'](p,b);}catch{z=undefined;}let A;if(z)try{A=await c['fetchPermissionContext'](z,b);}catch{A=undefined;}j['set'](q,A);}s=j['get'](q);const t=typeof o?.['task']==='string'?o['task']:undefined;let u;if(t){const B=t['toLowerCase']();if(!k['has'](B))try{k['set'](B,await c['fetchOrderContext'](t,b));}catch{k['set'](B,undefined);}u=k['get'](B);}const v=(Array['isArray'](o?.['namedOperator'])?o['namedOperator']:[])['map'](C=>({'name':String(C?.['name']??''),'operators':(Array['isArray'](C?.['operators'])?C['operators']:[])['map'](D=>String(D))})),w=enumerateActionableForwards(o,r,l,v,u,s),x=typeof o?.['current']==='string'?o['current']:'',y=t?'order\x20'+formatShortAddress(t):'no\x20bound\x20order';for(const C of w){for(const D of C['executable_accounts']){const E=C['threshold']>0x1?'\x20—\x20cooperation\x20threshold\x20'+C['threshold']+'\x20(weight\x20'+C['weight']+');\x20other\x20distinct\x20forwards\x20may\x20still\x20be\x20needed':'',F=C['guard']?'\x20—\x20guard\x20'+formatShortAddress(C['guard'])+'\x20must\x20be\x20satisfied\x20(submissions\x20may\x20be\x20required)':'',G=u&&D===u['builder']['toLowerCase']()?'You\x20are\x20the\x20order\x20owner':C['operator_kind']==='named_operator'?'You\x20hold\x20the\x20named-operator\x20role\x20\x27'+C['named_operator']+'\x27':'You\x20hold\x20the\x20required\x20permission\x20index';m['push']({'dedupe_key':'progress_actionable:'+n+':'+D+':'+C['next_node']+'|'+C['forward'],'detector':'progress_actionable','beneficiary':D,'object':n,'title':'Workflow\x20action\x20available:\x20\x27'+C['forward']+'\x27\x20→\x20'+C['next_node'],'detail':'Progress\x20'+formatShortAddress(n)+'\x20('+y+')\x20sits\x20at\x20node\x20\x27'+x+'\x27.\x20'+(G+'\x20—\x20you\x20can\x20execute\x20forward\x20\x27'+C['forward']+'\x27\x20into\x20\x27'+C['next_node']+'\x27')+(''+E+F+'.\x20Advance\x20it\x20via\x20workflow_operation\x20')+'(action=\x27list\x27\x20to\x20review,\x20action=\x27operate\x27\x20to\x20execute).\x20'+'Who\x20benefits,\x20who\x20pushes:\x20waiting\x20does\x20not\x20move\x20the\x20order\x20—\x20the\x20party\x20that\x20'+'gains\x20from\x20the\x20next\x20step\x20sends\x20the\x20transaction.','benefit':benefitOfNode(C['next_node']),'state_fingerprint':C['weight']+':'+C['threshold']+':'+(C['guard']??'')+':'+C['operator_kind']});}}}return m;}function benefitOfNode(a){if(/(^|_)(completed?|done|finished|received|delivered|accepted|confirmed|finalized|success|approved)(_|$)/i['test'](a))return'Completing\x20this\x20step\x20settles\x20the\x20order\x20—\x20funds\x20are\x20released\x20to\x20the\x20provider';if(/(^|_)(cancel(led)?|refund(ed)?|return(ed|_approved)?)(_|$)/i['test'](a))return'This\x20step\x20routes\x20to\x20cancellation/refund\x20—\x20funds\x20return\x20to\x20the\x20buyer';if(/(^|_)(interrupt(ed)?|exception|dispute(d)?|fail(ed)?|abort(ed)?|reject(ed)?)(_|$)/i['test'](a))return'This\x20step\x20opens\x20the\x20exception\x20path\x20—\x20review\x20before\x20advancing';return'Advancing\x20keeps\x20the\x20order\x20moving\x20toward\x20settlement';}const REFUND_FLAVOR_RE=/(^|_)(cancel(led)?|refund(ed)?|return(ed|_approved)?|expired)(_|$)/i;export async function detectSettlementPending(a,b,c,e){const f=(a['accounts']??[])['map'](s=>s['toLowerCase']());if(f['length']===0x0)return[];const g=(a['orders']??[])['slice'](0x0,Math['max'](0x1,e));if(g['length']===0x0)return[];const h=g['map'](s=>s['order'])['filter'](s=>typeof s==='string'&&s['startsWith']('0x'));let i;try{i=await c['fetchOrderFields'](h,b);}catch{return[];}const j=[],k=[];for(const s of i['values']()){const t=s?.['data']??s;if(typeof t?.['allocation']==='string'&&t['allocation']['startsWith']('0x'))j['push'](t['allocation']);if(typeof t?.['progress']==='string'&&t['progress']['startsWith']('0x'))k['push'](t['progress']);}let l=new Map(),m=new Map();try{l=await c['fetchAllocationFields']([...new Set(j)],b);}catch{return[];}try{m=await c['fetchProgressFields']([...new Set(k)],b);}catch{m=new Map();}const o=new Set((a['services']??[])['map'](u=>u['toLowerCase']())),q=new Map(),r=[];for(const [u,v]of i){const w=v?.['data']??v,x=typeof w?.['allocation']==='string'?w['allocation']:undefined;if(!x)continue;const y=l['get'](x['toLowerCase']());if(!y)continue;const z=y?.['data']??y,A=typeof z['balance']==='bigint'?z['balance']:BigInt(z['balance']??0x0);if(A<=0x0n)continue;const B=Array['isArray'](z['payment'])?z['payment']:[];if(B['length']>0x0)continue;const C=typeof w?.['progress']==='string'?w['progress']:undefined,D=C?m['get'](C['toLowerCase']()):undefined,E=typeof D?.['current']==='string'?D['current']:'',F=typeof D?.['machine']==='string'?D['machine']:typeof w?.['machine']==='string'?w['machine']:undefined;if(!E||!F)continue;let G=q['get'](F['toLowerCase']());if(!G){try{G=await c['fetchMachineNodes'](F,b);}catch{G=[];}q['set'](F['toLowerCase'](),G);}if(G['length']===0x0)continue;const H=new Set();for(const P of G){for(const Q of P['pairs']){if((Q['forwards']??[])['length']>0x0)H['add'](P['name']);}}if(H['has'](E))continue;const I=REFUND_FLAVOR_RE['test'](E),J=[];if(I){const R=typeof w?.['builder']==='string'?w['builder']['toLowerCase']():'';if(R&&f['includes'](R))J['push'](R);}else{const S=typeof w?.['service']==='string'?w['service']['toLowerCase']():'';if(S&&o['has'](S))J['push'](...f);}if(J['length']===0x0)continue;const K=(Array['isArray'](z['allocators']?.['allocators'])?z['allocators']['allocators']:[])['map'](T=>String(T?.['guard']??''))['filter'](T=>T),L=K['length']>0x0?'Candidate\x20settle\x20guards\x20on\x20this\x20pool:\x20'+K['map'](T=>formatShortAddress(T))['join'](',\x20')+'.':'This\x20pool\x20exposes\x20no\x20readable\x20allocator\x20guards\x20—\x20inspect\x20it\x20before\x20acting.';let M;try{M=await c['formatAmount']?.(A,extractCoinType(y?.['type_raw']),b);}catch{M=undefined;}const N=M??A['toString']()+'\x20(smallest\x20unit)',O=I?'refund/cancel':'completion';for(const T of J){r['push']({'dedupe_key':'settlement_pending:'+u+':'+x,'detector':'settlement_pending','beneficiary':T,'object':x,'title':'Unsettled\x20escrow\x20—\x20'+N+'\x20on\x20a\x20'+O+'\x20terminal','detail':'Order\x20'+formatShortAddress(u)+'\x20sits\x20on\x20terminal\x20node\x20\x27'+E+'\x27\x20but\x20its\x20Allocation\x20'+(formatShortAddress(x)+'\x20still\x20holds\x20'+N+'\x20and\x20has\x20emitted\x20no\x20Payment.\x20The\x20chain\x20never\x20')+('auto-settles:\x20someone\x20must\x20trigger\x20the\x20matching\x20guard.\x20'+L+'\x20Execute\x20via\x20allocation_operation\x20')+'(operation_type=\x27allocation\x27,\x20alloc_by_guard=<guard>)\x20as\x20an\x20account\x20that\x20can\x20satisfy\x20the\x20guard,\x20then\x20'+'recipients\x20claim\x20their\x20CoinWrappers\x20(payment\x20receive).\x20Trigger\x20ONCE\x20and\x20verify\x20the\x20pool\x20drained\x20—\x20a\x20'+'fully-drained\x20pool\x20aborts\x20on\x20re-trigger,\x20but\x20a\x20max-capped\x20pool\x20re-splits\x20the\x20remainder.\x20'+'Who\x20benefits,\x20who\x20pushes:\x20waiting\x20keeps\x20the\x20funds\x20frozen\x20and\x20leaves\x20the\x20dispute\x20window\x20open.','benefit':'Release\x20'+N+'\x20from\x20escrow\x20to\x20its\x20rightful\x20recipients','state_fingerprint':A['toString']()+':'+B['length']+':'+E});}}return r;}export function realPaymentDetectorDeps(){return{'queryUnclaimed':async(a,b)=>{const c=await query_received({'name_or_address':{'name_or_address':a},'type':'CoinWrapper','network':b});if(!c||typeof c!=='object'||!Array['isArray'](c['received']))return null;const d=typeof c['balance']==='bigint'?c['balance']:BigInt(c['balance']??0x0);return{'balance':d,'count':c['received']['length'],'token_type':typeof c['token_type']==='string'&&c['token_type']?c['token_type']:undefined};},'formatAmount':async(a,b,c)=>{if(!b)return undefined;const e=await formatChainValue(a,b,c),f=e['symbol']?'\x20'+e['symbol']:'';return e['precision_known']?''+e['display']+f:''+e['raw']+f;}};}export function realProgressDetectorDeps(){return{'fetchProgressFields':async(a,b)=>{const c=await batchQueryObjectsByIds(a,b,![]),e=new Map();for(const f of c??[]){const g=f?.['data']??f;if(f?.['type']!=='Progress')continue;const h=String(f?.['query_name']??f?.['object']??'')['toLowerCase']();if(h)e['set'](h,g);}return e;},'fetchMachineNodes':(a,b)=>fetchMachineNodes(a,b,![]),'fetchMachinePermissionAddr':async(a,b)=>{const c=await query_objects({'objects':[a],'network':b}),d=c?.['objects']?.[0x0],e=(d?.['data']??d)?.['permission'];return typeof e==='string'&&e?e:undefined;},'fetchPermissionContext':(a,b)=>fetchPermissionContext(a,b,![]),'fetchOrderContext':(a,b)=>fetchOrderContext(a,b,![])};}async function fieldsByType(a,b,c){const d=await batchQueryObjectsByIds(a,b,![]),e=new Map();for(const f of d??[]){if(f?.['type']!==c)continue;const g=String(f?.['query_name']??f?.['object']??'')['toLowerCase']();if(g)e['set'](g,f);}return e;}export function realSettlementDetectorDeps(){return{'fetchOrderFields':(a,b)=>fieldsByType(a,b,'Order'),'fetchAllocationFields':(a,b)=>fieldsByType(a,b,'Allocation'),'fetchProgressFields':async(a,b)=>{const c=await fieldsByType(a,b,'Progress'),d=new Map();for(const [e,f]of c)d['set'](e,f?.['data']??f);return d;},'fetchMachineNodes':(a,b)=>fetchMachineNodes(a,b,![]),'formatAmount':async(a,b,c)=>{if(!b)return undefined;const e=await formatChainValue(a,b,c),f=e['symbol']?'\x20'+e['symbol']:'';return e['precision_known']?''+e['display']+f:''+e['raw']+f;}};}
|
|
1
|
+
import{query_received,query_objects}from'@wowok/wowok';import{batchQueryObjectsByIds,fetchMachineNodes,fetchOrderContext,fetchPermissionContext}from'../graph/onchain/sdk-batch.js';import{extractCoinType}from'../graph/onchain/extract.js';import{enumerateActionableForwards}from'../knowledge/index.js';import{formatChainValue}from'../knowledge/fund-layer.js';import{formatShortAddress}from'../persona/address-format.js';export async function detectPaymentUnclaimed(a,b,c){const d=[];for(const e of a){const f=e['toLowerCase']();let g=null;try{g=await c['queryUnclaimed'](f,b);}catch{g=null;}if(!g||g['balance']<=0x0n||g['count']<=0x0)continue;let h;try{h=await c['formatAmount']?.(g['balance'],g['token_type'],b);}catch{h=undefined;}const i=h??g['balance']['toString']()+'\x20(smallest\x20unit)';d['push']({'dedupe_key':'payment_unclaimed:'+f,'detector':'payment_unclaimed','beneficiary':f,'operation':{'operation_type':'payment','data':{'receive':!![]}},'title':'Unclaimed\x20funds\x20—\x20'+i+'\x20waiting\x20to\x20be\x20received','detail':g['count']+'\x20CoinWrapper\x20object(s)\x20hold\x20'+i+'\x20for\x20this\x20account.\x20'+'They\x20are\x20owned\x20but\x20NOT\x20spendable\x20until\x20unwrapped.\x20Execute\x20payment\x20{receive:true}\x20'+'as\x20this\x20account\x20to\x20unwrap\x20all\x20of\x20them\x20into\x20the\x20wallet\x20in\x20one\x20transaction\x20(keeper\x20can\x20'+'auto-execute\x20this\x20when\x20a\x20payment_unclaimed\x20auto-exec\x20rule\x20covers\x20the\x20account).','benefit':'Receive\x20'+i+'\x20into\x20your\x20wallet','state_fingerprint':g['count']+':'+g['balance']['toString']()});}return d;}export async function detectProgressActionable(a,b,c,d){const e=(a['order_children']??[])['filter'](n=>n['type']==='progress'&&typeof n['object']==='string')['map'](n=>n['object'])['filter'](n=>n['startsWith']('0x')),f=(a['focus']??[])['map'](n=>n['object'])['filter'](n=>typeof n==='string'&&n['startsWith']('0x')),g=[...new Set([...e,...f])]['slice'](0x0,Math['max'](0x1,d));if(g['length']===0x0||(a['accounts']??[])['length']===0x0)return[];let h;try{h=await c['fetchProgressFields'](g,b);}catch{return[];}const i=new Map(),j=new Map(),k=new Map(),l=a['accounts'],m=[];for(const [n,o]of h){const p=typeof o?.['machine']==='string'?o['machine']:undefined;if(!p)continue;const q=p['toLowerCase']();let r=i['get'](q);if(!r){try{r=await c['fetchMachineNodes'](p,b);}catch{r=[];}i['set'](q,r);}if(r['length']===0x0)continue;let s;if(!j['has'](q)){let z;try{z=await c['fetchMachinePermissionAddr'](p,b);}catch{z=undefined;}let A;if(z)try{A=await c['fetchPermissionContext'](z,b);}catch{A=undefined;}j['set'](q,A);}s=j['get'](q);const t=typeof o?.['task']==='string'?o['task']:undefined;let u;if(t){const B=t['toLowerCase']();if(!k['has'](B))try{k['set'](B,await c['fetchOrderContext'](t,b));}catch{k['set'](B,undefined);}u=k['get'](B);}const v=(Array['isArray'](o?.['namedOperator'])?o['namedOperator']:[])['map'](C=>({'name':String(C?.['name']??''),'operators':(Array['isArray'](C?.['operators'])?C['operators']:[])['map'](D=>String(D))})),w=enumerateActionableForwards(o,r,l,v,u,s),x=typeof o?.['current']==='string'?o['current']:'',y=t?'order\x20'+formatShortAddress(t):'no\x20bound\x20order';for(const C of w){for(const D of C['executable_accounts']){const E=C['threshold']>0x1?'\x20—\x20cooperation\x20threshold\x20'+C['threshold']+'\x20(weight\x20'+C['weight']+');\x20other\x20distinct\x20forwards\x20may\x20still\x20be\x20needed':'',F=C['guard']?'\x20—\x20guard\x20'+formatShortAddress(C['guard'])+'\x20must\x20be\x20satisfied\x20(submissions\x20may\x20be\x20required)':'',G=u&&D===u['builder']['toLowerCase']()?'You\x20are\x20the\x20order\x20owner':C['operator_kind']==='named_operator'?'You\x20hold\x20the\x20named-operator\x20role\x20\x27'+C['named_operator']+'\x27':'You\x20hold\x20the\x20required\x20permission\x20index';m['push']({'dedupe_key':'progress_actionable:'+n+':'+D+':'+C['next_node']+'|'+C['forward'],'detector':'progress_actionable','beneficiary':D,'object':n,'title':'Workflow\x20action\x20available:\x20\x27'+C['forward']+'\x27\x20→\x20'+C['next_node'],'detail':'Progress\x20'+formatShortAddress(n)+'\x20('+y+')\x20sits\x20at\x20node\x20\x27'+x+'\x27.\x20'+(G+'\x20—\x20you\x20can\x20execute\x20forward\x20\x27'+C['forward']+'\x27\x20into\x20\x27'+C['next_node']+'\x27')+(''+E+F+'.\x20Advance\x20it\x20via\x20workflow_operation\x20')+'(action=\x27list\x27\x20to\x20review,\x20action=\x27operate\x27\x20to\x20execute).\x20'+'Who\x20benefits,\x20who\x20pushes:\x20waiting\x20does\x20not\x20move\x20the\x20order\x20—\x20the\x20party\x20that\x20'+'gains\x20from\x20the\x20next\x20step\x20sends\x20the\x20transaction.','benefit':benefitOfNode(C['next_node']),'state_fingerprint':C['weight']+':'+C['threshold']+':'+(C['guard']??'')+':'+C['operator_kind']});}}}return m;}function benefitOfNode(a){if(/(^|_)(completed?|done|finished|received|delivered|accepted|confirmed|finalized|success|approved)(_|$)/i['test'](a))return'Completing\x20this\x20step\x20settles\x20the\x20order\x20—\x20funds\x20are\x20released\x20to\x20the\x20provider';if(/(^|_)(cancel(led)?|refund(ed)?|return(ed|_approved)?)(_|$)/i['test'](a))return'This\x20step\x20routes\x20to\x20cancellation/refund\x20—\x20funds\x20return\x20to\x20the\x20buyer';if(/(^|_)(interrupt(ed)?|exception|dispute(d)?|fail(ed)?|abort(ed)?|reject(ed)?)(_|$)/i['test'](a))return'This\x20step\x20opens\x20the\x20exception\x20path\x20—\x20review\x20before\x20advancing';return'Advancing\x20keeps\x20the\x20order\x20moving\x20toward\x20settlement';}const REFUND_FLAVOR_RE=/(^|_)(cancel(led)?|refund(ed)?|return(ed|_approved)?|expired)(_|$)/i;export async function detectSettlementPending(a,b,c,e){const f=(a['accounts']??[])['map'](s=>s['toLowerCase']());if(f['length']===0x0)return[];const g=(a['orders']??[])['slice'](0x0,Math['max'](0x1,e));if(g['length']===0x0)return[];const h=g['map'](s=>s['order'])['filter'](s=>typeof s==='string'&&s['startsWith']('0x'));let i;try{i=await c['fetchOrderFields'](h,b);}catch{return[];}const j=[],k=[];for(const s of i['values']()){const t=s?.['data']??s;if(typeof t?.['allocation']==='string'&&t['allocation']['startsWith']('0x'))j['push'](t['allocation']);if(typeof t?.['progress']==='string'&&t['progress']['startsWith']('0x'))k['push'](t['progress']);}let l=new Map(),m=new Map();try{l=await c['fetchAllocationFields']([...new Set(j)],b);}catch{return[];}try{m=await c['fetchProgressFields']([...new Set(k)],b);}catch{m=new Map();}const o=new Set((a['services']??[])['map'](u=>u['toLowerCase']())),q=new Map(),r=[];for(const [u,v]of i){const w=v?.['data']??v,x=typeof w?.['allocation']==='string'?w['allocation']:undefined;if(!x)continue;const y=l['get'](x['toLowerCase']());if(!y)continue;const z=y?.['data']??y,A=typeof z['balance']==='bigint'?z['balance']:BigInt(z['balance']??0x0);if(A<=0x0n)continue;const B=Array['isArray'](z['payment'])?z['payment']:[];if(B['length']>0x0)continue;const C=typeof w?.['progress']==='string'?w['progress']:undefined,D=C?m['get'](C['toLowerCase']()):undefined,E=typeof D?.['current']==='string'?D['current']:'',F=typeof D?.['machine']==='string'?D['machine']:typeof w?.['machine']==='string'?w['machine']:undefined;if(!E||!F)continue;let G=q['get'](F['toLowerCase']());if(!G){try{G=await c['fetchMachineNodes'](F,b);}catch{G=[];}q['set'](F['toLowerCase'](),G);}if(G['length']===0x0)continue;const H=new Set();for(const P of G){for(const Q of P['pairs']){if((Q['forwards']??[])['length']>0x0)H['add'](P['name']);}}if(H['has'](E))continue;const I=REFUND_FLAVOR_RE['test'](E),J=[];if(I){const R=typeof w?.['builder']==='string'?w['builder']['toLowerCase']():'';if(R&&f['includes'](R))J['push'](R);}else{const S=typeof w?.['service']==='string'?w['service']['toLowerCase']():'';if(S&&o['has'](S))J['push'](...f);}if(J['length']===0x0)continue;const K=(Array['isArray'](z['allocators']?.['allocators'])?z['allocators']['allocators']:[])['map'](T=>String(T?.['guard']??''))['filter'](T=>T),L=K['length']>0x0?'Candidate\x20settle\x20guards\x20on\x20this\x20pool:\x20'+K['map'](T=>formatShortAddress(T))['join'](',\x20')+'.':'This\x20pool\x20exposes\x20no\x20readable\x20allocator\x20guards\x20—\x20inspect\x20it\x20before\x20acting.';let M;try{M=await c['formatAmount']?.(A,extractCoinType(y?.['type_raw']),b);}catch{M=undefined;}const N=M??A['toString']()+'\x20(smallest\x20unit)',O=I?'refund/cancel':'completion';for(const T of J){r['push']({'dedupe_key':'settlement_pending:'+u+':'+x,'detector':'settlement_pending','beneficiary':T,'object':x,'title':'Unsettled\x20escrow\x20—\x20'+N+'\x20on\x20a\x20'+O+'\x20terminal','detail':'Order\x20'+formatShortAddress(u)+'\x20sits\x20on\x20terminal\x20node\x20\x27'+E+'\x27\x20but\x20its\x20Allocation\x20'+(formatShortAddress(x)+'\x20still\x20holds\x20'+N+'\x20and\x20has\x20emitted\x20no\x20Payment.\x20The\x20chain\x20never\x20')+('auto-settles:\x20someone\x20must\x20trigger\x20the\x20matching\x20guard.\x20'+L+'\x20Execute\x20via\x20allocation_operation\x20')+'(operation_type=\x27allocation\x27,\x20alloc_by_guard=<guard>)\x20as\x20an\x20account\x20that\x20can\x20satisfy\x20the\x20guard,\x20then\x20'+'recipients\x20claim\x20their\x20CoinWrappers\x20(payment\x20receive).\x20Trigger\x20ONCE\x20and\x20verify\x20the\x20pool\x20drained\x20—\x20a\x20'+'fully-drained\x20pool\x20aborts\x20on\x20re-trigger,\x20but\x20a\x20max-capped\x20pool\x20re-splits\x20the\x20remainder.\x20'+'Who\x20benefits,\x20who\x20pushes:\x20waiting\x20keeps\x20the\x20funds\x20frozen\x20and\x20leaves\x20the\x20dispute\x20window\x20open.','benefit':'Release\x20'+N+'\x20from\x20escrow\x20to\x20its\x20rightful\x20recipients','state_fingerprint':A['toString']()+':'+B['length']+':'+E});}}return r;}export async function detectTimeoutIntermediate(a,b,c,d,e){const f=(a['order_children']??[])['filter'](m=>m['type']==='progress'&&typeof m['object']==='string')['map'](m=>m['object'])['filter'](m=>m['startsWith']('0x')),g=(a['focus']??[])['map'](m=>m['object'])['filter'](m=>typeof m==='string'&&m['startsWith']('0x')),h=[...new Set([...f,...g])]['slice'](0x0,Math['max'](0x1,d));if(h['length']===0x0||(a['accounts']??[])['length']===0x0)return[];let i;try{i=await c['fetchProgressFields'](h,b);}catch{return[];}const j=c['nowMs'](),k=new Map(),l=[];for(const [m,n]of i){const o=typeof n?.['current']==='string'?n['current']:'',p=typeof n?.['current_time']==='number'?n['current_time']:0x0;if(!o||p<=0x0)continue;const q=typeof n?.['machine']==='string'?n['machine']:undefined;if(!q)continue;const r=q['toLowerCase']();let s=k['get'](r);if(!s){try{s=await c['fetchMachineNodes'](q,b);}catch{s=[];}k['set'](r,s);}const t=s['find'](A=>A['name']===o);if(!t)continue;const u=t['pairs']['some'](A=>(A['forwards']??[])['length']>0x0);if(!u)continue;const v=j-p;if(v<e)continue;const w=typeof n?.['task']==='string'?n['task']:undefined,x=(a['accounts']??[])['map'](A=>A['toLowerCase']()),y=x[0x0];if(!y)continue;const z=Math['floor'](v/(0x3e8*0x3c*0x3c));l['push']({'dedupe_key':'timeout_intermediate:'+m+':'+o,'detector':'timeout_intermediate','beneficiary':y,'object':m,'title':'Possible\x20stuck\x20intermediate\x20state\x20—\x20\x27'+o+'\x27\x20for\x20'+z+'h','detail':'Progress\x20'+formatShortAddress(m)+'\x20has\x20been\x20on\x20node\x20\x27'+o+'\x27\x20for\x20'+z+'\x20hours\x20'+('(since\x20'+new Date(p)['toISOString']()+').\x20This\x20node\x20has\x20outgoing\x20forwards\x20but\x20none\x20have\x20fired.\x20')+'If\x20this\x20node\x20has\x20a\x20time-lock\x20guard\x20(confirm\x20timeout,\x20acceptance\x20timeout,\x20inspection\x20timeout,\x20etc.),\x20'+'the\x20keeper\x20may\x20need\x20to\x20advance\x20it.\x20Check\x20the\x20template\x27s\x20keeper_dependencies\x20and\x20the\x20guard\x27s\x20time\x20window\x20'+'before\x20acting.\x20Who\x20benefits,\x20who\x20pushes:\x20a\x20stuck\x20intermediate\x20state\x20blocks\x20the\x20order\x27s\x20funds\x20and\x20'+'business\x20flow\x20—\x20the\x20party\x20that\x20gains\x20from\x20unblocking\x20it\x20sends\x20the\x20transaction.','benefit':'Unblock\x20the\x20order\x20stuck\x20at\x20\x27'+o+'\x27','state_fingerprint':o+':'+p+':'+v});}return l;}export function realPaymentDetectorDeps(){return{'queryUnclaimed':async(a,b)=>{const c=await query_received({'name_or_address':{'name_or_address':a},'type':'CoinWrapper','network':b});if(!c||typeof c!=='object'||!Array['isArray'](c['received']))return null;const d=typeof c['balance']==='bigint'?c['balance']:BigInt(c['balance']??0x0);return{'balance':d,'count':c['received']['length'],'token_type':typeof c['token_type']==='string'&&c['token_type']?c['token_type']:undefined};},'formatAmount':async(a,b,c)=>{if(!b)return undefined;const e=await formatChainValue(a,b,c),f=e['symbol']?'\x20'+e['symbol']:'';return e['precision_known']?''+e['display']+f:''+e['raw']+f;}};}export function realProgressDetectorDeps(){return{'fetchProgressFields':async(a,b)=>{const c=await batchQueryObjectsByIds(a,b,![]),e=new Map();for(const f of c??[]){const g=f?.['data']??f;if(f?.['type']!=='Progress')continue;const h=String(f?.['query_name']??f?.['object']??'')['toLowerCase']();if(h)e['set'](h,g);}return e;},'fetchMachineNodes':(a,b)=>fetchMachineNodes(a,b,![]),'fetchMachinePermissionAddr':async(a,b)=>{const c=await query_objects({'objects':[a],'network':b}),d=c?.['objects']?.[0x0],e=(d?.['data']??d)?.['permission'];return typeof e==='string'&&e?e:undefined;},'fetchPermissionContext':(a,b)=>fetchPermissionContext(a,b,![]),'fetchOrderContext':(a,b)=>fetchOrderContext(a,b,![])};}async function fieldsByType(a,b,c){const d=await batchQueryObjectsByIds(a,b,![]),e=new Map();for(const f of d??[]){if(f?.['type']!==c)continue;const g=String(f?.['query_name']??f?.['object']??'')['toLowerCase']();if(g)e['set'](g,f);}return e;}export function realSettlementDetectorDeps(){return{'fetchOrderFields':(a,b)=>fieldsByType(a,b,'Order'),'fetchAllocationFields':(a,b)=>fieldsByType(a,b,'Allocation'),'fetchProgressFields':async(a,b)=>{const c=await fieldsByType(a,b,'Progress'),d=new Map();for(const [e,f]of c)d['set'](e,f?.['data']??f);return d;},'fetchMachineNodes':(a,b)=>fetchMachineNodes(a,b,![]),'formatAmount':async(a,b,c)=>{if(!b)return undefined;const e=await formatChainValue(a,b,c),f=e['symbol']?'\x20'+e['symbol']:'';return e['precision_known']?''+e['display']+f:''+e['raw']+f;}};}export function realTimeoutDetectorDeps(){return{'fetchProgressFields':async(a,b)=>{const c=await fieldsByType(a,b,'Progress'),d=new Map();for(const [e,f]of c)d['set'](e,f?.['data']??f);return d;},'fetchMachineNodes':(a,b)=>fetchMachineNodes(a,b,![]),'nowMs':()=>Date['now']()};}
|
package/dist/keeper/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type KeeperDetectorKind = "payment_unclaimed" | "progress_actionable" | "settlement_pending";
|
|
1
|
+
export type KeeperDetectorKind = "payment_unclaimed" | "progress_actionable" | "settlement_pending" | "timeout_intermediate";
|
|
2
2
|
export declare const KEEPER_DETECTORS: readonly KeeperDetectorKind[];
|
|
3
3
|
export declare const AUTO_EXECUTABLE_DETECTORS: readonly KeeperDetectorKind[];
|
|
4
4
|
export type KeeperTaskStatus = "pending" | "executed" | "dismissed" | "superseded";
|
package/dist/keeper/types.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const KEEPER_DETECTORS=['payment_unclaimed','progress_actionable','settlement_pending'];export const AUTO_EXECUTABLE_DETECTORS=['payment_unclaimed'];export const KEEPER_DEFAULTS={'scan_interval_ms':0x1d4c0,'max_scan_objects':0x14,'max_auto_execute_per_scan':0x5,'auto_retry_cooldown_ms':0x1b7740};export const KEEPER_MIN={'scan_interval_ms':0x7530,'max_scan_objects':0x1,'max_auto_execute_per_scan':0x1,'auto_retry_cooldown_ms':0xea60};export function defaultKeeperConfig(){return{'enabled':!![],'detectors':{'payment_unclaimed':!![],'progress_actionable':!![],'settlement_pending':!![]},'scan_interval_ms':KEEPER_DEFAULTS['scan_interval_ms'],'max_scan_objects':KEEPER_DEFAULTS['max_scan_objects'],'max_auto_execute_per_scan':KEEPER_DEFAULTS['max_auto_execute_per_scan'],'auto_retry_cooldown_ms':KEEPER_DEFAULTS['auto_retry_cooldown_ms']};}export function clampKeeperConfig(a){const b=(c,d,e)=>{const f=Number(c);return Number['isFinite'](f)?Math['max'](e,Math['floor'](f)):d;};return{...a,'scan_interval_ms':b(a['scan_interval_ms'],KEEPER_DEFAULTS['scan_interval_ms'],KEEPER_MIN['scan_interval_ms']),'max_scan_objects':b(a['max_scan_objects'],KEEPER_DEFAULTS['max_scan_objects'],KEEPER_MIN['max_scan_objects']),'max_auto_execute_per_scan':b(a['max_auto_execute_per_scan'],KEEPER_DEFAULTS['max_auto_execute_per_scan'],KEEPER_MIN['max_auto_execute_per_scan']),'auto_retry_cooldown_ms':b(a['auto_retry_cooldown_ms'],KEEPER_DEFAULTS['auto_retry_cooldown_ms'],KEEPER_MIN['auto_retry_cooldown_ms'])};}export function newKeeperTaskId(){return'ktask_'+Date['now']()['toString'](0x24)+'_'+Math['random']()['toString'](0x24)['slice'](0x2,0x8);}export function newKeeperRuleId(){return'krule_'+Date['now']()['toString'](0x24)+'_'+Math['random']()['toString'](0x24)['slice'](0x2,0x8);}
|
|
1
|
+
export const KEEPER_DETECTORS=['payment_unclaimed','progress_actionable','settlement_pending','timeout_intermediate'];export const AUTO_EXECUTABLE_DETECTORS=['payment_unclaimed'];export const KEEPER_DEFAULTS={'scan_interval_ms':0x1d4c0,'max_scan_objects':0x14,'max_auto_execute_per_scan':0x5,'auto_retry_cooldown_ms':0x1b7740};export const KEEPER_MIN={'scan_interval_ms':0x7530,'max_scan_objects':0x1,'max_auto_execute_per_scan':0x1,'auto_retry_cooldown_ms':0xea60};export function defaultKeeperConfig(){return{'enabled':!![],'detectors':{'payment_unclaimed':!![],'progress_actionable':!![],'settlement_pending':!![],'timeout_intermediate':!![]},'scan_interval_ms':KEEPER_DEFAULTS['scan_interval_ms'],'max_scan_objects':KEEPER_DEFAULTS['max_scan_objects'],'max_auto_execute_per_scan':KEEPER_DEFAULTS['max_auto_execute_per_scan'],'auto_retry_cooldown_ms':KEEPER_DEFAULTS['auto_retry_cooldown_ms']};}export function clampKeeperConfig(a){const b=(c,d,e)=>{const f=Number(c);return Number['isFinite'](f)?Math['max'](e,Math['floor'](f)):d;};return{...a,'scan_interval_ms':b(a['scan_interval_ms'],KEEPER_DEFAULTS['scan_interval_ms'],KEEPER_MIN['scan_interval_ms']),'max_scan_objects':b(a['max_scan_objects'],KEEPER_DEFAULTS['max_scan_objects'],KEEPER_MIN['max_scan_objects']),'max_auto_execute_per_scan':b(a['max_auto_execute_per_scan'],KEEPER_DEFAULTS['max_auto_execute_per_scan'],KEEPER_MIN['max_auto_execute_per_scan']),'auto_retry_cooldown_ms':b(a['auto_retry_cooldown_ms'],KEEPER_DEFAULTS['auto_retry_cooldown_ms'],KEEPER_MIN['auto_retry_cooldown_ms'])};}export function newKeeperTaskId(){return'ktask_'+Date['now']()['toString'](0x24)+'_'+Math['random']()['toString'](0x24)['slice'](0x2,0x8);}export function newKeeperRuleId(){return'krule_'+Date['now']()['toString'](0x24)+'_'+Math['random']()['toString'](0x24)['slice'](0x2,0x8);}
|