@wowok/agent-mcp 3.3.3 → 3.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/composition/compile.d.ts +4 -1
- package/dist/composition/compile.js +1 -1
- package/dist/evaluation/node-game.d.ts +3 -0
- package/dist/evaluation/node-game.js +1 -1
- package/dist/harness/recover.js +1 -1
- package/dist/knowledge/builtin-templates.d.ts +1 -1
- package/dist/knowledge/builtin-templates.js +1 -1
- package/dist/knowledge/guard-templates.d.ts +1 -1
- package/dist/knowledge/guard-templates.js +1 -1
- package/dist/knowledge/recipient-constraint.d.ts +9 -0
- package/dist/knowledge/recipient-constraint.js +1 -1
- package/dist/knowledge/scenario-modes.d.ts +1 -0
- package/dist/knowledge/template-loader.d.ts +1 -0
- package/dist/knowledge/template-loader.js +1 -1
- package/dist/knowledge/template-scanner.js +1 -1
- package/dist/participation/node-action-advisor.js +1 -1
- package/dist/playbooks/service-build/service-quote.js +1 -1
- package/dist/playbooks/service-build/service-quote.spec.js +1 -1
- package/dist/schema/call/base.d.ts +25 -0
- package/dist/schema/call/base.js +1 -1
- package/dist/schema/call/bridge.d.ts +1 -0
- package/dist/schema/call/error-codes.d.ts +1 -1
- package/dist/schema/call/error-codes.js +1 -1
- package/dist/schema/call/handler.js +1 -1
- package/dist/schema/call/order.d.ts +12 -0
- package/dist/schema/call/order.js +1 -1
- package/dist/schema/call/progress.js +1 -1
- package/dist/schema/call/semantic.js +1 -1
- package/dist/schema/local/index.d.ts +10 -0
- package/dist/schema/operations.d.ts +4 -0
- package/dist/schema/query/bi.d.ts +4 -0
- package/dist/schema/query/bi.js +1 -1
- package/dist/schema/query/index.d.ts +147 -0
- package/dist/schema/query/index.js +1 -1
- package/dist/schemas/account_operation.output.json +2 -1
- package/dist/schemas/bridge_operation.output.json +2 -1
- package/dist/schemas/index.json +1 -1
- package/dist/schemas/keeper_operation.output.json +1 -1
- package/dist/schemas/local_cache_operation.output.json +2 -1
- package/dist/schemas/local_history_operation.output.json +2 -1
- package/dist/schemas/local_info_operation.output.json +2 -1
- package/dist/schemas/local_mark_operation.output.json +2 -1
- package/dist/schemas/messenger_operation.output.json +1 -1
- package/dist/schemas/monitor_events.output.json +1 -1
- package/dist/schemas/monitor_subscription.output.json +1 -1
- package/dist/schemas/onchain_events.output.json +1 -1
- package/dist/schemas/onchain_operations.output.json +35 -4
- package/dist/schemas/onchain_operations.schema.json +21 -3
- package/dist/schemas/onchain_operations_order.schema.json +19 -1
- package/dist/schemas/onchain_operations_progress.schema.json +2 -2
- package/dist/schemas/onchain_table_data.output.json +2 -2
- package/dist/schemas/query_toolkit.output.json +17 -1
- package/dist/schemas/query_toolkit.schema.json +1 -1
- package/dist/schemas/wowok_buildin_info.output.json +259 -0
- package/dist/schemas/wowok_buildin_info.schema.json +121 -0
- package/dist/tools/build-fingerprint.d.ts +28 -0
- package/dist/tools/build-fingerprint.js +1 -0
- package/dist/tools/handlers/config.js +1 -1
- package/dist/tools/handlers/onchain.d.ts +6 -0
- package/dist/tools/handlers/onchain.js +1 -1
- package/dist/tools/handlers/query.js +1 -1
- package/dist/tools/handlers/review-chain.d.ts +9 -13
- package/dist/tools/handlers/review-chain.js +1 -1
- package/dist/tools/upgrade-check.d.ts +1 -0
- package/dist/tools/upgrade-check.js +1 -1
- package/package.json +2 -2
|
@@ -127,6 +127,15 @@ export interface RecipientConstraintAudit {
|
|
|
127
127
|
summary: string;
|
|
128
128
|
}
|
|
129
129
|
export declare function classifyRecipient(who: unknown): RecipientSpec | null;
|
|
130
|
+
export type DualPayoutTrack = {
|
|
131
|
+
track: "entity-directed";
|
|
132
|
+
recipients: string[];
|
|
133
|
+
} | {
|
|
134
|
+
track: "order-directed";
|
|
135
|
+
} | {
|
|
136
|
+
track: "unknown";
|
|
137
|
+
};
|
|
138
|
+
export declare function classifyDualPayoutTrack(allocators: unknown): DualPayoutTrack;
|
|
130
139
|
export declare const RECIPIENT_CONSTRAINT_VERSION = "1.2.0";
|
|
131
140
|
export declare function analyzeRecipientConstraints(input: RecipientConstraintInput): RecipientConstraintAudit;
|
|
132
141
|
export declare function derivePayoffFromSharing(sharing: Array<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ValueType}from'@wowok/wowok';import{getGuardQueryByIdOrName}from'../schema/utils/guard-query-utils.js';function asNode(a){if(typeof a!=='object'||a===null)return null;const b=a['type'];return typeof b==='string'?a:null;}function queryMeta(a){if(typeof a!=='number'&&typeof a!=='string')return null;const b=getGuardQueryByIdOrName(a);return b?{'id':b['id'],'name':b['name']}:null;}function childNodes(a){const b=[];if(Array['isArray'](a['nodes']))a['nodes']['forEach'](d=>{const e=asNode(d);if(e)b['push'](e);});if(asNode(a['node']))b['push'](asNode(a['node']));return[a['nodeLeft'],a['nodeRight']]['forEach'](d=>{const e=asNode(d);if(e)b['push'](e);}),b;}export function classifyRecipient(a){if(typeof a!=='object'||a===null)return null;const b=a;if(typeof b['Entity']==='string')return{'kind':'entity','address':b['Entity']};const c=b['Entity'];if(c&&typeof c==='object'&&typeof c['name_or_address']==='string')return{'kind':'entity','address':c['name_or_address']};if(b['Signer']==='signer'||b['Signer']===!![])return{'kind':'signer'};if(typeof b['GuardIdentifier']==='number')return{'kind':'submission','identifier':b['GuardIdentifier']};return null;}function leafInfo(a,b){if(a['type']==='context'&&typeof a['context']==='string'){if(a['context']==='Signer')return{'kind':'signer'};if(a['context']==='Clock')return{'kind':'clock'};}if(a['type']==='query'){const c=queryMeta(a['query']),d=a['object'];if(c&&d&&typeof d['identifier']==='number')return{'kind':'query','query_name':c['name'],'query_id':c['id'],'object_identifier':d['identifier'],'convert_witness':d['convert_witness']};}if(a['type']==='identifier'){const e=typeof a['identifier']==='number'?a['identifier']:-0x1,f=b['find'](g=>g['identifier']===e);if(f){const g=typeof f['value']==='string'?f['value']:undefined,h=normalizeValueType(f['value_type']);if(h===ValueType['Address'])return{'kind':'static_address','value':g};if(h===ValueType['String'])return{'kind':'static_string','value':g};}}return{'kind':'other'};}function comparisonLeaves(a,b){if(a['type']==='logic_equal'){const c=childNodes(a)['map'](d=>flattenLeaf(d,b));return c;}return[];}function flattenLeaf(a,b){if(a['type']==='logic_not'){const d=childNodes(a)[0x0];return d?flattenLeaf(d,b):{'kind':'other'};}return leafInfo(a,b);}function isOrderProgressWitness(a){if(a===0x64)return!![];return typeof a==='string'&&a['toLowerCase']()['includes']('orderprogress');}function describe(a){switch(a){case'service_binding':return'Submitted\x20object\x20must\x20belong\x20to\x20the\x20expected\x20service';case'progress_node_state':return'Submitted\x20order\x20must\x20be\x20at\x20a\x20qualifying\x20workflow\x20node';case'signer_is_submitted_object_owner':return'Caller\x20must\x20be\x20the\x20owner\x20of\x20the\x20submitted\x20object';case'signer_authorized_entity':return'Caller\x20must\x20equal\x20a\x20fixed\x20authorized\x20address';case'signer_permission_member':return'Caller\x20must\x20satisfy\x20a\x20Permission\x20membership\x20rule';case'time_lock':return'Current\x20time\x20must\x20satisfy\x20the\x20time-lock';case'repository_crosscheck':return'Repository\x20data\x20must\x20satisfy\x20the\x20cross-check';default:return'Other\x20guard\x20constraint';}}function extractConstraints(a,b){const c=[],d=new Set(),e=h=>{const i=h['code']+':'+(h['slot']??'-');!d['has'](i)&&(d['add'](i),c['push'](h));},f=(h,i)=>({'path':h,'queries':i}),g=(h,i)=>{const j=comparisonLeaves(h,b);if(j['length']>=0x2){const k=j['find'](r=>r['kind']==='signer'),l=j['find'](r=>r['kind']==='query'&&r['query_name']==='order.owner'),m=j['find'](r=>r['kind']==='query'&&r['query_name']==='order.service'),n=j['find'](r=>r['kind']==='query'&&r['query_name']==='progress.current'),o=j['find'](r=>r['kind']==='static_address'),p=j['find'](r=>r['kind']==='static_string');k&&l&&e({'code':'signer_is_submitted_object_owner','slot':l['object_identifier'],'description':describe('signer_is_submitted_object_owner'),'caller_constraint':!![],'evidence':f(i,['Signer','order.owner'])});k&&o&&e({'code':'signer_authorized_entity','description':describe('signer_authorized_entity'),'caller_constraint':!![],'evidence':f(i,['Signer'])});m&&o&&e({'code':'service_binding','slot':m['object_identifier'],'description':describe('service_binding'),'caller_constraint':![],'evidence':f(i,['order.service'])});if(n&&p){const r=n['object_identifier'];isOrderProgressWitness(n['convert_witness'])&&e({'code':'progress_node_state','slot':r,'description':describe('progress_node_state'),'caller_constraint':![],'evidence':f(i,['progress.current'])});}}if(h['type']['startsWith']('logic_as_u256')||h['type']==='calc_number_add'){const s=[h,...childNodes(h)]['map'](t=>flattenLeaf(t,b));if(s['some'](t=>t['kind']==='clock')&&s['some'](t=>t['kind']==='query'&&(t['query_name']==='progress.current_time'||t['query_name']==='progress.session.forward.time'))){const t=s['find'](u=>u['kind']==='query');e({'code':'time_lock','slot':t['object_identifier'],'description':describe('time_lock'),'caller_constraint':![],'evidence':f(i,['Clock',t['query_name']])});}}if(h['type']==='query'){const u=queryMeta(h['query']);if(u&&u['name']['startsWith']('repository.')){const v=h['object'];e({'code':'repository_crosscheck','slot':v?.['identifier'],'description':describe('repository_crosscheck'),'caller_constraint':![],'evidence':f(i,[u['name']])});}}childNodes(h)['forEach']((w,x)=>g(w,i+'/'+x));};return g(a,'/root'),c;}function findSessionQueries(a){const b=[],c=(d,e)=>{if(d['type']==='query'){const f=queryMeta(d['query']);if(f&&(f['id']===0x4f6||f['id']===0x4f7))b['push'](e);}childNodes(d)['forEach']((g,h)=>c(g,e+'/'+h));};return c(a,'/root'),b;}function collectSlotUsages(a){const b=[],c=(d,e)=>{if(d['type']==='query'){const f=queryMeta(d['query']),g=d['object'];f&&g&&typeof g['identifier']==='number'&&b['push']({'slot':g['identifier'],'path':e,'query_id':f['id'],'query_name':f['name'],...g['convert_witness']!==undefined?{'convert_witness':g['convert_witness']}:{}});}childNodes(d)['forEach']((h,j)=>c(h,e+'/'+j));};return c(a,'/root'),b;}function deriveReceiptRight(a,b){const c=b['find'](e=>e['code']==='progress_node_state'&&e['slot']===a),d=b['find'](e=>e['code']==='signer_is_submitted_object_owner'&&e['slot']===a);if(c||d)return{'object_type':'order','receive_entry':'owner-side\x20extraction\x20on\x20the\x20order','guarantee':'Delivered\x20funds\x20are\x20owned\x20by\x20the\x20submitted\x20Order;\x20only\x20its\x20current\x20owner\x20can\x20'+'extract\x20them\x20(&mut\x20Order\x20input),\x20and\x20coins\x20transfer\x20to\x20that\x20owner.'};return undefined;}function deriveBeneficialOwner(a,b){switch(a['kind']){case'entity':return'Fixed\x20entity\x20'+a['address'];case'signer':return'Transaction\x20caller\x20(Signer)\x20—\x20direct\x20wallet';case'submission':return b?'Owner\x20of\x20the\x20submitted\x20object\x20at\x20table['+a['identifier']+']\x20(object\x20receipt\x20=\x20owner\x20receipt)':'Address\x20submitted\x20at\x20table['+a['identifier']+']\x20(caller-provided)';}}function buildSlotModels(a,b,c,d){const e=[...new Set(c['map'](f=>f['spec'])['filter'](f=>f['kind']==='submission')['map'](f=>f['identifier']))];return e['map'](f=>{const g=a['find'](p=>p['identifier']===f),h=g?normalizeValueType(g['value_type']):undefined,i=h===ValueType['Address'],j=b['filter'](p=>p['slot']===f),k=c['filter'](p=>p['spec']['kind']==='submission'&&p['spec']['identifier']===f)['map'](p=>p['mode']??'Unknown'),l=d['filter'](p=>p['slot']===undefined||p['slot']===f),m=deriveReceiptRight(f,d),n=l['some'](p=>p['code']==='service_binding'||p['code']==='repository_crosscheck'||p['code']==='signer_permission_member'),o=[];if(h!==undefined&&!i)o['push']('RC-FIND-07');if(!n)o['push']('RC-FIND-02');if(m?.['object_type']==='order')o['push']('RC-FIND-03');return{'identifier':f,'externally_submitted':g?.['b_submission']??!![],...h!==undefined?{'declared_value_type':h}:{},'is_address':i,'usages':j,'recipient_modes':k,'constraints':l,...m?{'receipt':m}:{},'beneficial_owner':deriveBeneficialOwner({'kind':'submission','identifier':f},m),'assessment':{'address_typed':i,'scope_bound':n,'object_receipt':m?.['object_type']==='order'},'findings':o};});}function buildSlotFinding(a,b,c){const d=a['identifier'];switch(b){case'RC-FIND-07':return{'code':b,'severity':'medium','title':'Submission\x20slot\x20'+d+'\x20is\x20not\x20address-typed','explanation':'GuardIdentifier\x20recipients\x20require\x20an\x20address-typed\x20table\x20entry\x20'+'(enforced\x20at\x20allocator\x20registration\x20/\x20ERECIPIENT_IDENTIFIER_NOT_ADDRESS).','evidence_paths':c,'mitigation':'Set\x20the\x20slot\x20value_type\x20to\x20Address,\x20or\x20use\x20an\x20Entity\x20recipient.','unavoidable':![]};case'RC-FIND-02':return{'code':b,'severity':'high','title':'Submission\x20slot\x20'+d+'\x20has\x20no\x20scope\x20binding','explanation':'Nothing\x20constrains\x20which\x20submitted\x20objects/addresses\x20qualify:\x20no\x20'+'service\x20binding,\x20repository\x20cross-check\x20or\x20permission\x20membership.\x20A\x20caller\x20'+'can\x20submit\x20arbitrary\x20qualifying-by-other-conditions\x20inputs.','evidence_paths':c,'mitigation':'Add\x20a\x20constraint\x20binding\x20the\x20slot\x20(e.g.\x20order.service\x20==\x20host\x20service).','unavoidable':![]};case'RC-FIND-03':return{'code':b,'severity':'medium','title':'Cross-allocation\x20settlement\x20residual','explanation':'The\x20submitted\x20order\x20is\x20not\x20bound\x20to\x20the\x20Allocation\x20being\x20settled\x20'+'(alloc\x20is\x20permissionless\x20and\x20allocation\x20context\x20is\x20not\x20a\x20Guard\x20input).\x20A\x20'+'caller\x20owning\x20ANY\x20qualifying\x20order\x20can\x20settle\x20OTHER\x20allocations;\x20funds\x20land\x20'+'at\x20the\x20submitted\x20order\x20and\x20are\x20receivable\x20by\x20its\x20owner.\x20Destination\x20is\x20safe\x20'+'(an\x20order\x20owner),\x20allocation\x20choice\x20is\x20the\x20residual.','evidence_paths':c,'mitigation':'Pick\x20ONE\x20resolution\x20and\x20record\x20it\x20in\x20the\x20service\x20description:\x20'+'(1)\x20competition\x20semantics\x20—\x20declare\x20that\x20any\x20qualifying\x20order\x20may\x20settle\x20'+'this\x20allocation\x20and\x20cap\x20the\x20exposure\x20(sharing\x20threshold\x20/\x20max\x20amount);\x20'+'(2)\x20Entity\x20routing\x20—\x20use\x20a\x20fixed\x20Entity\x20(treasury)\x20recipient,\x20the\x20only\x20'+'exclusive\x20choice\x20on\x20the\x20automatic\x20order_allocators\x20route\x20(trust\x20shifts\x20to\x20'+'the\x20entity\x20operator);\x20'+'(3)\x20per-order\x20pinned\x20Guards\x20—\x20abandon\x20automatic\x20order_allocators\x20and\x20attach\x20'+'a\x20per-order\x20Guard\x20pinning\x20the\x20order\x20id\x20(order.owner\x20==\x20constant),\x20the\x20'+'trustless\x20exclusive\x20route.','unavoidable':!![],'resolution_required':!![]};default:return{'code':b,'severity':'low','title':'Slot\x20'+d+'\x20finding\x20'+b,'explanation':'','evidence_paths':c,'mitigation':'','unavoidable':![]};}}function buildFindings(a,b){const c=[];let d=![],e=![];for(const f of b){const g=f['recipients']['flatMap'](h=>h['constraints'])['filter'](h=>h['caller_constraint']);if(g['length']>0x0)d=!![];if(f['slots']['some'](h=>h['assessment']['scope_bound']))e=!![];for(const h of f['recipients']){const i=h['constraints']['map'](j=>j['evidence']['path']);h['spec']['kind']==='signer'&&g['length']===0x0&&c['push']({'code':'RC-FIND-01','severity':'critical','title':'Signer\x20recipient\x20without\x20caller\x20constraint\x20—\x20fund\x20theft','explanation':'Funds\x20are\x20delivered\x20directly\x20to\x20the\x20transaction\x20caller,\x20but\x20the\x20Guard\x20'+'does\x20not\x20bind\x20the\x20Signer\x20to\x20an\x20authorized\x20identity.\x20Anyone\x20who\x20satisfies\x20the\x20'+'other\x20conditions\x20steals\x20the\x20funds.','evidence_paths':i,'mitigation':'Bind\x20the\x20Signer\x20(signer==order.owner\x20or\x20signer==fixed\x20address),\x20or\x20change\x20'+'the\x20recipient\x20to\x20an\x20Entity\x20/\x20submitted\x20object\x20slot.','unavoidable':![]});}for(const j of f['slots']){const k=j['constraints']['map'](l=>l['evidence']['path']);for(const l of j['findings']){c['push'](buildSlotFinding(j,l,k));}}a['trigger_source']==='service_order_allocators'&&f['recipients']['length']>0x0&&!f['recipients']['some'](m=>m['spec']['kind']==='submission')&&c['push']({'code':'RC-FIND-09','severity':'low','title':'Allocator\x20Guard\x20'+f['guard']+'\x20has\x20no\x20GuardIdentifier\x20sharing\x20row\x20—\x20bound\x20to\x20no\x20particular\x20order','explanation':'Every\x20sharing\x20row\x20is\x20a\x20fixed\x20recipient\x20(Entity/Signer),\x20which\x20resolves\x20no\x20'+'submission.\x20The\x20Guard\x20therefore\x20cannot\x20read\x20the\x20paying\x20order\x20(order.*\x20queries\x20have\x20'+'no\x20binding\x20target),\x20and\x20the\x20allocation\x20pays\x20the\x20same\x20fixed\x20destinations\x20for\x20EVERY\x20order.\x20'+'This\x20is\x20often\x20intended\x20—\x20confirm\x20it\x20is.','evidence_paths':[],'mitigation':'If\x20the\x20Guard\x20should\x20distinguish\x20orders,\x20add\x20a\x20zero-share\x20{GuardIdentifier:\x200}\x20'+'anchor\x20row\x20(Rate\x200)\x20so\x20the\x20Identifier\x20slot\x20resolves\x20to\x20the\x20paying\x20order\x20'+'(pattern.allocator_order_anchor).\x20If\x20fixed-pay\x20is\x20intended,\x20no\x20action.','unavoidable':![]});}a['trigger_source']==='standalone'&&!d&&c['push']({'code':'RC-FIND-04','severity':'high','title':'Standalone\x20allocation\x20without\x20issuer\x20identity\x20constraint','explanation':'Standalone\x20allocations\x20have\x20no\x20Service/Arbitration\x20access-control\x20layer.\x20'+'Without\x20a\x20Signer/permission\x20binding\x20in\x20the\x20Guard,\x20anyone\x20can\x20trigger\x20distribution.','evidence_paths':[],'mitigation':'Bind\x20the\x20issuer\x20(Signer==owner/admin)\x20or\x20move\x20the\x20allocation\x20into\x20a\x20Service.','unavoidable':![]});c['push']({'code':'RC-FIND-06','severity':'low','title':'Permissionless\x20alloc\x20—\x20forced\x20settlement\x20timing','explanation':'Once\x20the\x20Guard\x27s\x20conditions\x20are\x20satisfiable,\x20anyone\x20can\x20trigger\x20settlement\x20of\x20an\x20'+'order\x27s\x20allocation.\x20With\x20Entity/object\x20recipients\x20this\x20affects\x20timing\x20only,\x20not\x20destination.','evidence_paths':[],'mitigation':'Monitor\x20settlements;\x20constrain\x20time-sensitivity\x20via\x20Guard\x20conditions.','unavoidable':!![]});for(const [m,n]of Object['entries'](a['guards']??{})){const o=asNode(n['root']);if(!o)continue;for(const q of findSessionQueries(o)){c['push']({'code':'RC-FIND-05','severity':'medium','title':'Guard\x20'+m+'\x20uses\x20session-only\x20query\x20at\x20'+q,'explanation':'Queries\x201270/1271\x20read\x20the\x20active\x20session;\x20after\x20the\x20session\x20migrates\x20to\x20'+'history\x20the\x20query\x20aborts\x20(W_FIELD_NOT_FOUND)\x20and\x20the\x20Guard\x20permanently\x20fails.','evidence_paths':[q],'mitigation':'Use\x20progress.current_time\x20(1272)\x20or\x20history\x20queries\x20(1274-1280).','unavoidable':![]});}}for(const [s,t]of Object['entries'](a['guards']??{})){const u=(t['relies']??[])['filter'](v=>typeof v==='string'&&v);if(u['length']===0x0)continue;c['push']({'code':'RC-FIND-08','severity':'low','title':'Guard\x20'+s+'\x20relies\x20on\x20'+u['length']+'\x20sub-guard(s)\x20—\x20not\x20credited\x20by\x20this\x20audit','explanation':'Guard\x20composition\x20(relies,\x20one\x20level,\x20≤4,\x20'+((t['relies_logic_and']===![]?'OR':'AND')+'-logic)\x20may\x20carry\x20the\x20scope/signer\x20')+'constraints\x20in\x20the\x20relied\x20sub-guards.\x20This\x20audit\x20evaluates\x20only\x20the\x20guard\x27s\x20own\x20root:\x20'+'sub-guard\x20constraints\x20are\x20NOT\x20credited,\x20so\x20scope-binding\x20gaps\x20(RC-FIND-02)\x20may\x20be\x20'+'over-reported\x20and\x20sub-guard-only\x20conditions\x20stay\x20unverified.','evidence_paths':u,'mitigation':'Resolve\x20the\x20relied\x20sub-guards\x20and\x20verify\x20their\x20constraints\x20manually,\x20or\x20re-run\x20'+'with\x20the\x20sub-guard\x20defs\x20included\x20(read-side\x20resolvers\x20attach\x20them\x20automatically).','unavoidable':![]});}if(!e&&a['trigger_source']==='service_order_allocators'){}return c;}function buildPayoff(a,b){const c=a['recipients']['some'](h=>h['constraints']['some'](i=>i['caller_constraint'])),d=c?'Caller\x20must\x20satisfy\x20the\x20Guard\x27s\x20Signer/identity\x20binding':b==='standalone'?'Any\x20caller\x20(no\x20identity\x20binding)':'Any\x20caller\x20who\x20satisfies\x20the\x20Guard\x27s\x20object/state\x20conditions',e=a['recipients']['map'](h=>h['beneficial_owner'])['join'](';\x20')||'(none)',f={},g=a['recipients']['some'](h=>h['spec']['kind']==='signer'&&!c);return f['caller']=g?'gains':c?'conditional':'neutral',f['provider']=a['recipients']['some'](h=>h['spec']['kind']==='entity')?'gains':'conditional',f['customer']=a['recipients']['some'](h=>h['receipt']?.['object_type']==='order')?'conditional':'neutral',f['system']='neutral',{'caller_eligibility':d,'beneficial_recipient':e,'positions':f};}export const RECIPIENT_CONSTRAINT_VERSION='1.2.0';export function analyzeRecipientConstraints(a){const b=a['allocators']['map'](h=>{const i=a['guards']?.[h['guard']],j=asNode(i?.['root']),k=i?.['table']??[],l=j?extractConstraints(j,k):[],m=j?collectSlotUsages(j):[],n=h['sharing']['map'](q=>{const r=classifyRecipient(q['who']);if(!r)return{'spec':{'kind':'entity','address':'(unclassifiable)'},'constraints':l,'beneficial_owner':'Unclassifiable\x20recipient\x20—\x20check\x20allocator\x20config'};const t=r['kind']==='submission'?r['identifier']:undefined,u=t!==undefined?k['find'](w=>w['identifier']===t):undefined,v=t!==undefined?deriveReceiptRight(t,l):undefined;return{'spec':r,'slot_value_type':u?normalizeValueType(u['value_type']):undefined,'constraints':t!==undefined?l['filter'](w=>w['slot']===undefined||w['slot']===t):l,'receipt':v,'beneficial_owner':deriveBeneficialOwner(r,v)};}),o=buildSlotModels(k,m,h['sharing']['map'](q=>({'spec':classifyRecipient(q['who'])??{'kind':'entity','address':'(unclassifiable)'},'mode':q['mode']})),l),p={'guard':h['guard'],'recipients':n,'slots':o,'payoff':{'caller_eligibility':'','beneficial_recipient':'','positions':{}}};return p['payoff']=buildPayoff(p,a['trigger_source']),p;}),c=buildFindings(a,b),d=c['some'](h=>h['severity']==='critical')?'critical':c['some'](h=>h['severity']==='high')?'high':c['some'](h=>h['severity']==='medium')?'medium':'low',e=!c['some'](h=>h['code']==='RC-FIND-01'),f=c['some'](h=>h['resolution_required']),g=[{'code':'RC-FIND-03','title':'Cross-allocation\x20settlement','detail':'Submitted\x20order\x20is\x20not\x20bound\x20to\x20the\x20settled\x20allocation;\x20destination\x20stays\x20at\x20an\x20order\x20owner.'},{'code':'RC-FIND-06','title':'Forced\x20settlement\x20timing','detail':'alloc\x20is\x20permissionless;\x20settlement\x20can\x20be\x20triggered\x20by\x20anyone\x20once\x20conditions\x20hold.'},{'code':'RC-RES-01','title':'Published\x20immutability','detail':'order_allocators,\x20Machine\x20and\x20Guards\x20are\x20immutable\x20after\x20publish.'},{'code':'RC-RES-03','title':'Off-chain\x20arbitration\x20backstop','detail':'No\x20on-chain\x20clawback;\x20post-incident\x20recovery\x20relies\x20on\x20arbitration.'}];return{'version':RECIPIENT_CONSTRAINT_VERSION,'scope':{'trigger_source':a['trigger_source'],'host_service':a['host_service'],'allocation':a['allocation']},'allocators':b,'findings':c,'unavoidable':g,'safe_destination':e,'resolution_required':f,'overall':d,'summary':'Analyzed\x20'+b['length']+'\x20allocator(s):\x20'+c['filter'](h=>!h['unavoidable'])['length']+'\x20actionable,\x20'+(c['filter'](h=>h['unavoidable'])['length']+'\x20structural\x20finding(s).\x20Safe\x20destination:\x20'+e+'.')+(''+(f?'\x20Resolution\x20REQUIRED:\x20at\x20least\x20one\x20residual\x20demands\x20an\x20explicit\x20design\x20decision\x20before\x20publish.':''))};}export function derivePayoffFromSharing(a,b,c){const d=asNode(c?.['root']),e=c?.['table']??[],f=d?extractConstraints(d,e):[],g=a['map'](i=>{const j=classifyRecipient(i['who'])??{'kind':'entity','address':'(unclassifiable)'},k=j['kind']==='submission'?j['identifier']:undefined,l=k!==undefined?e['find'](n=>n['identifier']===k):undefined,m=k!==undefined?deriveReceiptRight(k,f):undefined;return{'spec':j,'slot_value_type':l?normalizeValueType(l['value_type']):undefined,'constraints':k!==undefined?f['filter'](n=>n['slot']===undefined||n['slot']===k):f,'receipt':m,'beneficial_owner':deriveBeneficialOwner(j,m)};}),h={'guard':'','recipients':g,'slots':[],'payoff':{'caller_eligibility':'','beneficial_recipient':'','positions':{}}};return buildPayoff(h,b);}function normalizeValueType(a){if(typeof a==='number')return a;const b={'bool':ValueType['Bool'],'address':ValueType['Address'],'string':ValueType['String'],'u64':ValueType['U64'],'u256':ValueType['U256']};return b[a['toLowerCase']()];}export function isUnboundSignerTheft(a){return a['recipient_is_signer']&&!a['caller_identity_constrained'];}export function canonicalDoctrine(a){switch(a){case'RC-FIND-01':return{'severity':'critical','title':'Signer\x20recipient\x20without\x20caller\x20constraint\x20—\x20fund\x20theft','mitigation':'Bind\x20the\x20Signer\x20(signer==order.owner\x20or\x20signer==fixed\x20address),\x20or\x20change\x20'+'the\x20recipient\x20to\x20an\x20Entity\x20/\x20submitted\x20object\x20slot.'};case'RC-FIND-03':return{'severity':'medium','title':'Cross-allocation\x20settlement\x20residual','mitigation':'Pick\x20ONE\x20resolution\x20and\x20record\x20it\x20in\x20the\x20service\x20description:\x20'+'(1)\x20competition\x20semantics\x20with\x20capped\x20exposure\x20(threshold\x20/\x20max\x20amount);\x20'+'(2)\x20Entity\x20routing\x20(treasury)\x20—\x20the\x20only\x20exclusive\x20choice\x20on\x20the\x20automatic\x20'+'order_allocators\x20route;\x20'+'(3)\x20per-order\x20pinned\x20Guards\x20(order.owner\x20==\x20constant)\x20—\x20the\x20trustless\x20'+'exclusive\x20route.','resolution_required':!![]};case'RC-FIND-06':return{'severity':'low','title':'Permissionless\x20alloc\x20—\x20forced\x20settlement\x20timing','mitigation':'Monitor\x20settlements;\x20constrain\x20time-sensitivity\x20via\x20Guard\x20conditions.'};}}export const RECIPIENT_DESIGN_OPTIONS=[{'id':'entity','move_recipient':'Recipient::Entity(address)','semantics':'Funds\x20flow\x20to\x20a\x20fixed\x20address\x20(a\x20constrained\x20user\x20account\x20/\x20treasury).\x20'+'Destination\x20never\x20depends\x20on\x20the\x20caller.','required_constraints':['The\x20address\x20is\x20chosen\x20at\x20design\x20time\x20and\x20recorded\x20in\x20the\x20allocator\x20table.']},{'id':'submitted_object','move_recipient':'Recipient::GuardIdentifier(u8)','semantics':'Funds\x20flow\x20to\x20the\x20object\x20submitted\x20under\x20protocol\x20context\x20(e.g.\x20the\x20order\x20being\x20settled).\x20'+'Receivable\x20only\x20by\x20that\x20object\x27s\x20owner\x20—\x20object\x20receipt\x20=\x20owner\x20receipt.','required_constraints':['The\x20Guard\x20binds\x20the\x20submission\x27s\x20scope\x20(which\x20query/object\x20type\x20the\x20slot\x20carries).','The\x20slot\x27s\x20table\x20value\x20type\x20is\x20address\x20(enforced\x20at\x20allocator\x20registration).'],'finding_if_unmet':'RC-FIND-02\x20/\x20RC-FIND-07'},{'id':'signer','move_recipient':'Recipient::Signer','semantics':'Funds\x20flow\x20to\x20the\x20caller\x20who\x20executes\x20the\x20permissionless\x20alloc.\x20'+'Safe\x20only\x20when\x20the\x20Guard\x20proves\x20exactly\x20who\x20the\x20caller\x20may\x20be.','required_constraints':['The\x20Guard\x20constrains\x20the\x20Signer\x20identity\x20(signer\x20==\x20a\x20fixed\x20address\x20or\x20a\x20derived\x20legitimate\x20owner).'],'finding_if_unmet':'RC-FIND-01'},{'id':'constrained_submission','move_recipient':'Recipient::GuardIdentifier(u8)','semantics':'Funds\x20flow\x20to\x20an\x20object\x20address\x20supplied\x20by\x20the\x20signer,\x20but\x20the\x20Guard\x20constrains\x20'+'both\x20the\x20submission\x20scope\x20and\x20the\x20signer\x27s\x20relation\x20to\x20it\x20(e.g.\x20the\x20signer\x20owns\x20the\x20submitted\x20order).','required_constraints':['The\x20Guard\x20binds\x20the\x20submission\x27s\x20scope\x20(object/query\x20type).','The\x20Guard\x20binds\x20the\x20signer\x20to\x20the\x20submitted\x20object.','The\x20slot\x27s\x20table\x20value\x20type\x20is\x20address\x20(enforced\x20at\x20allocator\x20registration).'],'finding_if_unmet':'RC-FIND-01\x20/\x20RC-FIND-02\x20/\x20RC-FIND-07'}];export function recipientDesignGuidance(){return RECIPIENT_DESIGN_OPTIONS;}export const OBJECT_DRIVEABILITY=[{'object_type':'order','receive_entries':['owner-side\x20coin\x20extraction\x20from\x20the\x20order','owner-side\x20object\x20extraction\x20from\x20the\x20order'],'anyone_drivable':!![],'funds_settle_to':'order.owner','rationale':'Order\x20is\x20a\x20shared\x20object\x20and\x20extraction\x20has\x20no\x20signer\x20gate;\x20'+'Receiving\x20is\x20restricted\x20to\x20objects\x20actually\x20delivered\x20to\x20that\x20order,\x20and\x20coins\x20settle\x20to\x20its\x20owner.'},{'object_type':'permission','receive_entries':['owner-side\x20coin\x20extraction\x20via\x20the\x20permission\x20object','owner-side\x20object\x20extraction\x20via\x20the\x20permission\x20object'],'anyone_drivable':!![],'funds_settle_to':'permission.owner','rationale':'Permission\x20is\x20the\x20final\x20authority;\x20anyone\x20can\x20drive\x20extraction\x20of\x20funds\x20sent\x20to\x20its\x20address,\x20but\x20the\x20destination\x20is\x20its\x20owner.'},{'object_type':'service','receive_entries':['owner-side\x20coin\x20extraction\x20from\x20the\x20service','owner-side\x20object\x20extraction\x20from\x20the\x20service'],'anyone_drivable':![],'permission_index':0x13f,'funds_settle_to':'permission.owner','rationale':'Business\x20permission\x20gate\x20(index\x20319);\x20members\x20drive,\x20value\x20settles\x20to\x20the\x20organization\x20owner.'},{'object_type':'treasury','receive_entries':['owner-side\x20coin\x20extraction\x20from\x20the\x20treasury','owner-side\x20object\x20extraction\x20from\x20the\x20treasury'],'anyone_drivable':![],'permission_index':0x101,'funds_settle_to':'permission.owner','rationale':'Business\x20permission\x20gate\x20(index\x20257).'},{'object_type':'arbitration','receive_entries':['owner-side\x20coin\x20extraction\x20from\x20the\x20arbitration','owner-side\x20object\x20extraction\x20from\x20the\x20arbitration'],'anyone_drivable':![],'permission_index':0x16f,'funds_settle_to':'permission.owner','rationale':'Business\x20permission\x20gate\x20(index\x20367).'},{'object_type':'machine','receive_entries':['owner-side\x20coin\x20extraction\x20from\x20the\x20machine','owner-side\x20object\x20extraction\x20from\x20the\x20machine'],'anyone_drivable':![],'permission_index':0xcf,'funds_settle_to':'permission.owner','rationale':'Business\x20permission\x20gate\x20(index\x20207).'},{'object_type':'progress','receive_entries':['owner-side\x20coin\x20extraction\x20from\x20the\x20progress','owner-side\x20object\x20extraction\x20from\x20the\x20progress'],'anyone_drivable':![],'permission_index':0xe1,'funds_settle_to':'machine\x27s\x20permission.owner','rationale':'Business\x20permission\x20gate\x20(index\x20225),\x20scoped\x20to\x20the\x20Machine\x20permission.'},{'object_type':'demand','receive_entries':['owner-side\x20coin\x20extraction\x20from\x20the\x20demand','owner-side\x20object\x20extraction\x20from\x20the\x20demand'],'anyone_drivable':![],'permission_index':0x197,'funds_settle_to':'permission.owner','rationale':'Business\x20permission\x20gate\x20(index\x20407).'},{'object_type':'contact','receive_entries':['owner-side\x20coin\x20extraction\x20from\x20the\x20contact','owner-side\x20object\x20extraction\x20from\x20the\x20contact'],'anyone_drivable':![],'permission_index':0x1c6,'funds_settle_to':'permission.owner','rationale':'Business\x20permission\x20gate\x20(index\x20454).'}];export function driveabilityOf(a){return OBJECT_DRIVEABILITY['find'](b=>b['object_type']===a);}function rewardRecipientKind(a){if(typeof a==='string'){const e=a['toLowerCase']();if(e==='signer')return{'kind':'signer'};return{'kind':'entity'};}if(typeof a!=='object'||a===null)return{'kind':'entity'};const b=a,c=f=>typeof b[f]==='number'?b[f]:undefined,d=c('GuardIdentifier')??c('guard_identifier')??c('identifier');if(d!==undefined)return{'kind':'submission','slot':d};if(b['Signer']!==undefined||b['signer']!==undefined)return{'kind':'signer'};return{'kind':'entity'};}const SLOT_BINDING_CODES=new Set(['service_binding','progress_node_state','signer_is_submitted_object_owner','repository_crosscheck','signer_permission_member']);export function analyzeRewardClaimGuard(a){const {kind:b,slot:c}=rewardRecipientKind(a['recipient']),d={'entry_index':a['entry_index'],'guard':a['guard'],'recipient_kind':b,...c!==undefined?{'recipient_slot':c}:{},'guard_resolved':![],'constraint_codes':[],'recipient_slot_usages':0x0,'caller_identity_constrained':![],'viability':'unverifiable','reason':'Guard\x20table/root\x20not\x20fetched\x20with\x20the\x20topology\x20—\x20the\x20deciding\x20predicate\x20is\x20outside\x20the\x20evidence;\x20the\x20owner\x20must\x20disclose\x20the\x20full\x20guard\x20definitions.'},e=asNode(a['guard_def']?.['root']);if(!e)return d;const f=a['guard_def']?.['table']??[],g=extractConstraints(e,f);d['guard_resolved']=!![],d['constraint_codes']=g['map'](k=>k['code']),d['caller_identity_constrained']=g['some'](k=>k['caller_constraint']);if(b==='entity')return d['viability']='blocked',d['reason']='Payout\x20address\x20is\x20fixed\x20at\x20guard\x20registration\x20(Entity\x20recipient);\x20the\x20claim\x20path\x20cannot\x20redirect\x20it.',d;if(b==='signer')return d['caller_identity_constrained']?(d['viability']='blocked',d['reason']='Recipient\x20is\x20the\x20caller\x20(Signer)\x20but\x20the\x20guard\x20binds\x20the\x20caller\x20identity\x20—\x20only\x20the\x20authorized\x20party\x20can\x20claim.'):(d['viability']='viable',d['reason']='Recipient\x20is\x20the\x20caller\x20(Signer)\x20with\x20no\x20identity\x20binding\x20—\x20anyone\x20satisfying\x20the\x20remaining\x20conditions\x20claims\x20to\x20their\x20own\x20address.'),d;const h=c??-0x1,i=collectSlotUsages(e)['filter'](k=>k['slot']===h);d['recipient_slot_usages']=i['length'];const j=g['filter'](k=>k['slot']===h&&SLOT_BINDING_CODES['has'](k['code']));if(j['length']>0x0)d['viability']='blocked',d['reason']='Submitted\x20address\x20is\x20constrained\x20inside\x20the\x20guard\x20('+j['map'](k=>k['code'])['join'](',\x20')+')\x20—\x20a\x20passerby\x20cannot\x20fill\x20the\x20slot\x20with\x20an\x20arbitrary\x20address.';else i['length']>0x0?(d['viability']='conditional',d['reason']='The\x20guard\x20reads\x20the\x20submitted\x20slot\x20('+i['length']+'\x20query\x20usage(s))\x20but\x20no\x20recognized\x20scope/equality\x20constraint\x20was\x20matched\x20—\x20manual\x20predicate\x20review\x20required.'):(d['viability']='viable',d['reason']='No\x20guard\x20query\x20consumes\x20the\x20submitted\x20slot\x20—\x20the\x20predicate\x20cannot\x20constrain\x20the\x20payout\x20address;\x20any\x20passing\x20party\x20claims\x20to\x20their\x20own\x20address.');return d;}
|
|
1
|
+
import{ValueType}from'@wowok/wowok';import{getGuardQueryByIdOrName}from'../schema/utils/guard-query-utils.js';function asNode(a){if(typeof a!=='object'||a===null)return null;const b=a['type'];return typeof b==='string'?a:null;}function queryMeta(a){if(typeof a!=='number'&&typeof a!=='string')return null;const b=getGuardQueryByIdOrName(a);return b?{'id':b['id'],'name':b['name']}:null;}function childNodes(a){const b=[];if(Array['isArray'](a['nodes']))a['nodes']['forEach'](d=>{const e=asNode(d);if(e)b['push'](e);});if(asNode(a['node']))b['push'](asNode(a['node']));return[a['nodeLeft'],a['nodeRight']]['forEach'](d=>{const e=asNode(d);if(e)b['push'](e);}),b;}export function classifyRecipient(a){if(typeof a!=='object'||a===null)return null;const b=a;if(typeof b['Entity']==='string')return{'kind':'entity','address':b['Entity']};const c=b['Entity'];if(c&&typeof c==='object'&&typeof c['name_or_address']==='string')return{'kind':'entity','address':c['name_or_address']};if(b['Signer']==='signer'||b['Signer']===!![])return{'kind':'signer'};if(typeof b['GuardIdentifier']==='number')return{'kind':'submission','identifier':b['GuardIdentifier']};return null;}export function classifyDualPayoutTrack(a){let b=[];if(Array['isArray'](a))b=a;else{if(a&&typeof a==='object'){const e=a['allocators'];if(Array['isArray'](e))b=e;}}const c=[];for(const f of b){const h=f?.['sharing'];if(Array['isArray'](h))c['push'](...h);}if(c['length']===0x0)return{'track':'unknown'};const d=[];for(const i of c){const j=i?.['who'],k=classifyRecipient(typeof j==='string'?j==='Signer'?{'Signer':!![]}:{'Entity':j}:j);if(!k||k['kind']==='signer')return{'track':'unknown'};if(k['kind']==='submission')return{'track':'order-directed'};d['push'](k['address']);}return{'track':'entity-directed','recipients':d};}function leafInfo(a,b){if(a['type']==='context'&&typeof a['context']==='string'){if(a['context']==='Signer')return{'kind':'signer'};if(a['context']==='Clock')return{'kind':'clock'};}if(a['type']==='query'){const c=queryMeta(a['query']),d=a['object'];if(c&&d&&typeof d['identifier']==='number')return{'kind':'query','query_name':c['name'],'query_id':c['id'],'object_identifier':d['identifier'],'convert_witness':d['convert_witness']};}if(a['type']==='identifier'){const e=typeof a['identifier']==='number'?a['identifier']:-0x1,f=b['find'](g=>g['identifier']===e);if(f){const g=typeof f['value']==='string'?f['value']:undefined,h=normalizeValueType(f['value_type']);if(h===ValueType['Address'])return{'kind':'static_address','value':g};if(h===ValueType['String'])return{'kind':'static_string','value':g};}}return{'kind':'other'};}function comparisonLeaves(a,b){if(a['type']==='logic_equal'){const c=childNodes(a)['map'](d=>flattenLeaf(d,b));return c;}return[];}function flattenLeaf(a,b){if(a['type']==='logic_not'){const d=childNodes(a)[0x0];return d?flattenLeaf(d,b):{'kind':'other'};}return leafInfo(a,b);}function isOrderProgressWitness(a){if(a===0x64)return!![];return typeof a==='string'&&a['toLowerCase']()['includes']('orderprogress');}function describe(a){switch(a){case'service_binding':return'Submitted\x20object\x20must\x20belong\x20to\x20the\x20expected\x20service';case'progress_node_state':return'Submitted\x20order\x20must\x20be\x20at\x20a\x20qualifying\x20workflow\x20node';case'signer_is_submitted_object_owner':return'Caller\x20must\x20be\x20the\x20owner\x20of\x20the\x20submitted\x20object';case'signer_authorized_entity':return'Caller\x20must\x20equal\x20a\x20fixed\x20authorized\x20address';case'signer_permission_member':return'Caller\x20must\x20satisfy\x20a\x20Permission\x20membership\x20rule';case'time_lock':return'Current\x20time\x20must\x20satisfy\x20the\x20time-lock';case'repository_crosscheck':return'Repository\x20data\x20must\x20satisfy\x20the\x20cross-check';default:return'Other\x20guard\x20constraint';}}function extractConstraints(a,b){const c=[],d=new Set(),e=h=>{const i=h['code']+':'+(h['slot']??'-');!d['has'](i)&&(d['add'](i),c['push'](h));},f=(h,i)=>({'path':h,'queries':i}),g=(h,i)=>{const j=comparisonLeaves(h,b);if(j['length']>=0x2){const k=j['find'](r=>r['kind']==='signer'),l=j['find'](r=>r['kind']==='query'&&r['query_name']==='order.owner'),m=j['find'](r=>r['kind']==='query'&&r['query_name']==='order.service'),n=j['find'](r=>r['kind']==='query'&&r['query_name']==='progress.current'),o=j['find'](r=>r['kind']==='static_address'),p=j['find'](r=>r['kind']==='static_string');k&&l&&e({'code':'signer_is_submitted_object_owner','slot':l['object_identifier'],'description':describe('signer_is_submitted_object_owner'),'caller_constraint':!![],'evidence':f(i,['Signer','order.owner'])});k&&o&&e({'code':'signer_authorized_entity','description':describe('signer_authorized_entity'),'caller_constraint':!![],'evidence':f(i,['Signer'])});m&&o&&e({'code':'service_binding','slot':m['object_identifier'],'description':describe('service_binding'),'caller_constraint':![],'evidence':f(i,['order.service'])});if(n&&p){const r=n['object_identifier'];isOrderProgressWitness(n['convert_witness'])&&e({'code':'progress_node_state','slot':r,'description':describe('progress_node_state'),'caller_constraint':![],'evidence':f(i,['progress.current'])});}}if(h['type']['startsWith']('logic_as_u256')||h['type']==='calc_number_add'){const s=[h,...childNodes(h)]['map'](t=>flattenLeaf(t,b));if(s['some'](t=>t['kind']==='clock')&&s['some'](t=>t['kind']==='query'&&(t['query_name']==='progress.current_time'||t['query_name']==='progress.session.forward.time'))){const t=s['find'](u=>u['kind']==='query');e({'code':'time_lock','slot':t['object_identifier'],'description':describe('time_lock'),'caller_constraint':![],'evidence':f(i,['Clock',t['query_name']])});}}if(h['type']==='query'){const u=queryMeta(h['query']);if(u&&u['name']['startsWith']('repository.')){const v=h['object'];e({'code':'repository_crosscheck','slot':v?.['identifier'],'description':describe('repository_crosscheck'),'caller_constraint':![],'evidence':f(i,[u['name']])});}}childNodes(h)['forEach']((w,x)=>g(w,i+'/'+x));};return g(a,'/root'),c;}function findSessionQueries(a){const b=[],c=(d,e)=>{if(d['type']==='query'){const f=queryMeta(d['query']);if(f&&(f['id']===0x4f6||f['id']===0x4f7))b['push'](e);}childNodes(d)['forEach']((g,h)=>c(g,e+'/'+h));};return c(a,'/root'),b;}function collectSlotUsages(a){const b=[],c=(d,e)=>{if(d['type']==='query'){const f=queryMeta(d['query']),g=d['object'];f&&g&&typeof g['identifier']==='number'&&b['push']({'slot':g['identifier'],'path':e,'query_id':f['id'],'query_name':f['name'],...g['convert_witness']!==undefined?{'convert_witness':g['convert_witness']}:{}});}childNodes(d)['forEach']((h,j)=>c(h,e+'/'+j));};return c(a,'/root'),b;}function deriveReceiptRight(a,b){const c=b['find'](e=>e['code']==='progress_node_state'&&e['slot']===a),d=b['find'](e=>e['code']==='signer_is_submitted_object_owner'&&e['slot']===a);if(c||d)return{'object_type':'order','receive_entry':'owner-side\x20extraction\x20on\x20the\x20order','guarantee':'Delivered\x20funds\x20are\x20owned\x20by\x20the\x20submitted\x20Order;\x20only\x20its\x20current\x20owner\x20can\x20'+'extract\x20them\x20(&mut\x20Order\x20input),\x20and\x20coins\x20transfer\x20to\x20that\x20owner.'};return undefined;}function deriveBeneficialOwner(a,b){switch(a['kind']){case'entity':return'Fixed\x20entity\x20'+a['address'];case'signer':return'Transaction\x20caller\x20(Signer)\x20—\x20direct\x20wallet';case'submission':return b?'Owner\x20of\x20the\x20submitted\x20object\x20at\x20table['+a['identifier']+']\x20(object\x20receipt\x20=\x20owner\x20receipt)':'Address\x20submitted\x20at\x20table['+a['identifier']+']\x20(caller-provided)';}}function buildSlotModels(a,b,c,d){const e=[...new Set(c['map'](f=>f['spec'])['filter'](f=>f['kind']==='submission')['map'](f=>f['identifier']))];return e['map'](f=>{const g=a['find'](p=>p['identifier']===f),h=g?normalizeValueType(g['value_type']):undefined,i=h===ValueType['Address'],j=b['filter'](p=>p['slot']===f),k=c['filter'](p=>p['spec']['kind']==='submission'&&p['spec']['identifier']===f)['map'](p=>p['mode']??'Unknown'),l=d['filter'](p=>p['slot']===undefined||p['slot']===f),m=deriveReceiptRight(f,d),n=l['some'](p=>p['code']==='service_binding'||p['code']==='repository_crosscheck'||p['code']==='signer_permission_member'),o=[];if(h!==undefined&&!i)o['push']('RC-FIND-07');if(!n)o['push']('RC-FIND-02');if(m?.['object_type']==='order')o['push']('RC-FIND-03');return{'identifier':f,'externally_submitted':g?.['b_submission']??!![],...h!==undefined?{'declared_value_type':h}:{},'is_address':i,'usages':j,'recipient_modes':k,'constraints':l,...m?{'receipt':m}:{},'beneficial_owner':deriveBeneficialOwner({'kind':'submission','identifier':f},m),'assessment':{'address_typed':i,'scope_bound':n,'object_receipt':m?.['object_type']==='order'},'findings':o};});}function buildSlotFinding(a,b,c){const d=a['identifier'];switch(b){case'RC-FIND-07':return{'code':b,'severity':'medium','title':'Submission\x20slot\x20'+d+'\x20is\x20not\x20address-typed','explanation':'GuardIdentifier\x20recipients\x20require\x20an\x20address-typed\x20table\x20entry\x20'+'(enforced\x20at\x20allocator\x20registration\x20/\x20ERECIPIENT_IDENTIFIER_NOT_ADDRESS).','evidence_paths':c,'mitigation':'Set\x20the\x20slot\x20value_type\x20to\x20Address,\x20or\x20use\x20an\x20Entity\x20recipient.','unavoidable':![]};case'RC-FIND-02':return{'code':b,'severity':'high','title':'Submission\x20slot\x20'+d+'\x20has\x20no\x20scope\x20binding','explanation':'Nothing\x20constrains\x20which\x20submitted\x20objects/addresses\x20qualify:\x20no\x20'+'service\x20binding,\x20repository\x20cross-check\x20or\x20permission\x20membership.\x20A\x20caller\x20'+'can\x20submit\x20arbitrary\x20qualifying-by-other-conditions\x20inputs.','evidence_paths':c,'mitigation':'Add\x20a\x20constraint\x20binding\x20the\x20slot\x20(e.g.\x20order.service\x20==\x20host\x20service).','unavoidable':![]};case'RC-FIND-03':return{'code':b,'severity':'medium','title':'Cross-allocation\x20settlement\x20residual','explanation':'The\x20submitted\x20order\x20is\x20not\x20bound\x20to\x20the\x20Allocation\x20being\x20settled\x20'+'(alloc\x20is\x20permissionless\x20and\x20allocation\x20context\x20is\x20not\x20a\x20Guard\x20input).\x20A\x20'+'caller\x20owning\x20ANY\x20qualifying\x20order\x20can\x20settle\x20OTHER\x20allocations;\x20funds\x20land\x20'+'at\x20the\x20submitted\x20order\x20and\x20are\x20receivable\x20by\x20its\x20owner.\x20Destination\x20is\x20safe\x20'+'(an\x20order\x20owner),\x20allocation\x20choice\x20is\x20the\x20residual.','evidence_paths':c,'mitigation':'Pick\x20ONE\x20resolution\x20and\x20record\x20it\x20in\x20the\x20service\x20description:\x20'+'(1)\x20competition\x20semantics\x20—\x20declare\x20that\x20any\x20qualifying\x20order\x20may\x20settle\x20'+'this\x20allocation\x20and\x20cap\x20the\x20exposure\x20(sharing\x20threshold\x20/\x20max\x20amount);\x20'+'(2)\x20Entity\x20routing\x20—\x20use\x20a\x20fixed\x20Entity\x20(treasury)\x20recipient,\x20the\x20only\x20'+'exclusive\x20choice\x20on\x20the\x20automatic\x20order_allocators\x20route\x20(trust\x20shifts\x20to\x20'+'the\x20entity\x20operator);\x20'+'(3)\x20per-order\x20pinned\x20Guards\x20—\x20abandon\x20automatic\x20order_allocators\x20and\x20attach\x20'+'a\x20per-order\x20Guard\x20pinning\x20the\x20order\x20id\x20(order.owner\x20==\x20constant),\x20the\x20'+'trustless\x20exclusive\x20route.','unavoidable':!![],'resolution_required':!![]};default:return{'code':b,'severity':'low','title':'Slot\x20'+d+'\x20finding\x20'+b,'explanation':'','evidence_paths':c,'mitigation':'','unavoidable':![]};}}function buildFindings(a,b){const c=[];let d=![],e=![];for(const f of b){const g=f['recipients']['flatMap'](h=>h['constraints'])['filter'](h=>h['caller_constraint']);if(g['length']>0x0)d=!![];if(f['slots']['some'](h=>h['assessment']['scope_bound']))e=!![];for(const h of f['recipients']){const i=h['constraints']['map'](j=>j['evidence']['path']);h['spec']['kind']==='signer'&&g['length']===0x0&&c['push']({'code':'RC-FIND-01','severity':'critical','title':'Signer\x20recipient\x20without\x20caller\x20constraint\x20—\x20fund\x20theft','explanation':'Funds\x20are\x20delivered\x20directly\x20to\x20the\x20transaction\x20caller,\x20but\x20the\x20Guard\x20'+'does\x20not\x20bind\x20the\x20Signer\x20to\x20an\x20authorized\x20identity.\x20Anyone\x20who\x20satisfies\x20the\x20'+'other\x20conditions\x20steals\x20the\x20funds.','evidence_paths':i,'mitigation':'Bind\x20the\x20Signer\x20(signer==order.owner\x20or\x20signer==fixed\x20address),\x20or\x20change\x20'+'the\x20recipient\x20to\x20an\x20Entity\x20/\x20submitted\x20object\x20slot.','unavoidable':![]});}for(const j of f['slots']){const k=j['constraints']['map'](l=>l['evidence']['path']);for(const l of j['findings']){c['push'](buildSlotFinding(j,l,k));}}a['trigger_source']==='service_order_allocators'&&f['recipients']['length']>0x0&&!f['recipients']['some'](m=>m['spec']['kind']==='submission')&&c['push']({'code':'RC-FIND-09','severity':'low','title':'Allocator\x20Guard\x20'+f['guard']+'\x20has\x20no\x20GuardIdentifier\x20sharing\x20row\x20—\x20bound\x20to\x20no\x20particular\x20order','explanation':'Every\x20sharing\x20row\x20is\x20a\x20fixed\x20recipient\x20(Entity/Signer),\x20which\x20resolves\x20no\x20'+'submission.\x20The\x20Guard\x20therefore\x20cannot\x20read\x20the\x20paying\x20order\x20(order.*\x20queries\x20have\x20'+'no\x20binding\x20target),\x20and\x20the\x20allocation\x20pays\x20the\x20same\x20fixed\x20destinations\x20for\x20EVERY\x20order.\x20'+'This\x20is\x20often\x20intended\x20—\x20confirm\x20it\x20is.','evidence_paths':[],'mitigation':'If\x20the\x20Guard\x20should\x20distinguish\x20orders,\x20add\x20a\x20zero-share\x20{GuardIdentifier:\x200}\x20'+'anchor\x20row\x20(Rate\x200)\x20so\x20the\x20Identifier\x20slot\x20resolves\x20to\x20the\x20paying\x20order\x20'+'(pattern.allocator_order_anchor).\x20If\x20fixed-pay\x20is\x20intended,\x20no\x20action.','unavoidable':![]});}a['trigger_source']==='standalone'&&!d&&c['push']({'code':'RC-FIND-04','severity':'high','title':'Standalone\x20allocation\x20without\x20issuer\x20identity\x20constraint','explanation':'Standalone\x20allocations\x20have\x20no\x20Service/Arbitration\x20access-control\x20layer.\x20'+'Without\x20a\x20Signer/permission\x20binding\x20in\x20the\x20Guard,\x20anyone\x20can\x20trigger\x20distribution.','evidence_paths':[],'mitigation':'Bind\x20the\x20issuer\x20(Signer==owner/admin)\x20or\x20move\x20the\x20allocation\x20into\x20a\x20Service.','unavoidable':![]});c['push']({'code':'RC-FIND-06','severity':'low','title':'Permissionless\x20alloc\x20—\x20forced\x20settlement\x20timing','explanation':'Once\x20the\x20Guard\x27s\x20conditions\x20are\x20satisfiable,\x20anyone\x20can\x20trigger\x20settlement\x20of\x20an\x20'+'order\x27s\x20allocation.\x20With\x20Entity/object\x20recipients\x20this\x20affects\x20timing\x20only,\x20not\x20destination.','evidence_paths':[],'mitigation':'Monitor\x20settlements;\x20constrain\x20time-sensitivity\x20via\x20Guard\x20conditions.','unavoidable':!![]});for(const [m,n]of Object['entries'](a['guards']??{})){const o=asNode(n['root']);if(!o)continue;for(const q of findSessionQueries(o)){c['push']({'code':'RC-FIND-05','severity':'medium','title':'Guard\x20'+m+'\x20uses\x20session-only\x20query\x20at\x20'+q,'explanation':'Queries\x201270/1271\x20read\x20the\x20active\x20session;\x20after\x20the\x20session\x20migrates\x20to\x20'+'history\x20the\x20query\x20aborts\x20(W_FIELD_NOT_FOUND)\x20and\x20the\x20Guard\x20permanently\x20fails.','evidence_paths':[q],'mitigation':'Use\x20progress.current_time\x20(1272)\x20or\x20history\x20queries\x20(1274-1280).','unavoidable':![]});}}for(const [s,t]of Object['entries'](a['guards']??{})){const u=(t['relies']??[])['filter'](v=>typeof v==='string'&&v);if(u['length']===0x0)continue;c['push']({'code':'RC-FIND-08','severity':'low','title':'Guard\x20'+s+'\x20relies\x20on\x20'+u['length']+'\x20sub-guard(s)\x20—\x20not\x20credited\x20by\x20this\x20audit','explanation':'Guard\x20composition\x20(relies,\x20one\x20level,\x20≤4,\x20'+((t['relies_logic_and']===![]?'OR':'AND')+'-logic)\x20may\x20carry\x20the\x20scope/signer\x20')+'constraints\x20in\x20the\x20relied\x20sub-guards.\x20This\x20audit\x20evaluates\x20only\x20the\x20guard\x27s\x20own\x20root:\x20'+'sub-guard\x20constraints\x20are\x20NOT\x20credited,\x20so\x20scope-binding\x20gaps\x20(RC-FIND-02)\x20may\x20be\x20'+'over-reported\x20and\x20sub-guard-only\x20conditions\x20stay\x20unverified.','evidence_paths':u,'mitigation':'Resolve\x20the\x20relied\x20sub-guards\x20and\x20verify\x20their\x20constraints\x20manually,\x20or\x20re-run\x20'+'with\x20the\x20sub-guard\x20defs\x20included\x20(read-side\x20resolvers\x20attach\x20them\x20automatically).','unavoidable':![]});}if(!e&&a['trigger_source']==='service_order_allocators'){}return c;}function buildPayoff(a,b){const c=a['recipients']['some'](h=>h['constraints']['some'](i=>i['caller_constraint'])),d=c?'Caller\x20must\x20satisfy\x20the\x20Guard\x27s\x20Signer/identity\x20binding':b==='standalone'?'Any\x20caller\x20(no\x20identity\x20binding)':'Any\x20caller\x20who\x20satisfies\x20the\x20Guard\x27s\x20object/state\x20conditions',e=a['recipients']['map'](h=>h['beneficial_owner'])['join'](';\x20')||'(none)',f={},g=a['recipients']['some'](h=>h['spec']['kind']==='signer'&&!c);return f['caller']=g?'gains':c?'conditional':'neutral',f['provider']=a['recipients']['some'](h=>h['spec']['kind']==='entity')?'gains':'conditional',f['customer']=a['recipients']['some'](h=>h['receipt']?.['object_type']==='order')?'conditional':'neutral',f['system']='neutral',{'caller_eligibility':d,'beneficial_recipient':e,'positions':f};}export const RECIPIENT_CONSTRAINT_VERSION='1.2.0';export function analyzeRecipientConstraints(a){const b=a['allocators']['map'](h=>{const i=a['guards']?.[h['guard']],j=asNode(i?.['root']),k=i?.['table']??[],l=j?extractConstraints(j,k):[],m=j?collectSlotUsages(j):[],n=h['sharing']['map'](q=>{const r=classifyRecipient(q['who']);if(!r)return{'spec':{'kind':'entity','address':'(unclassifiable)'},'constraints':l,'beneficial_owner':'Unclassifiable\x20recipient\x20—\x20check\x20allocator\x20config'};const t=r['kind']==='submission'?r['identifier']:undefined,u=t!==undefined?k['find'](w=>w['identifier']===t):undefined,v=t!==undefined?deriveReceiptRight(t,l):undefined;return{'spec':r,'slot_value_type':u?normalizeValueType(u['value_type']):undefined,'constraints':t!==undefined?l['filter'](w=>w['slot']===undefined||w['slot']===t):l,'receipt':v,'beneficial_owner':deriveBeneficialOwner(r,v)};}),o=buildSlotModels(k,m,h['sharing']['map'](q=>({'spec':classifyRecipient(q['who'])??{'kind':'entity','address':'(unclassifiable)'},'mode':q['mode']})),l),p={'guard':h['guard'],'recipients':n,'slots':o,'payoff':{'caller_eligibility':'','beneficial_recipient':'','positions':{}}};return p['payoff']=buildPayoff(p,a['trigger_source']),p;}),c=buildFindings(a,b),d=c['some'](h=>h['severity']==='critical')?'critical':c['some'](h=>h['severity']==='high')?'high':c['some'](h=>h['severity']==='medium')?'medium':'low',e=!c['some'](h=>h['code']==='RC-FIND-01'),f=c['some'](h=>h['resolution_required']),g=[{'code':'RC-FIND-03','title':'Cross-allocation\x20settlement','detail':'Submitted\x20order\x20is\x20not\x20bound\x20to\x20the\x20settled\x20allocation;\x20destination\x20stays\x20at\x20an\x20order\x20owner.'},{'code':'RC-FIND-06','title':'Forced\x20settlement\x20timing','detail':'alloc\x20is\x20permissionless;\x20settlement\x20can\x20be\x20triggered\x20by\x20anyone\x20once\x20conditions\x20hold.'},{'code':'RC-RES-01','title':'Published\x20immutability','detail':'order_allocators,\x20Machine\x20and\x20Guards\x20are\x20immutable\x20after\x20publish.'},{'code':'RC-RES-03','title':'Off-chain\x20arbitration\x20backstop','detail':'No\x20on-chain\x20clawback;\x20post-incident\x20recovery\x20relies\x20on\x20arbitration.'}];return{'version':RECIPIENT_CONSTRAINT_VERSION,'scope':{'trigger_source':a['trigger_source'],'host_service':a['host_service'],'allocation':a['allocation']},'allocators':b,'findings':c,'unavoidable':g,'safe_destination':e,'resolution_required':f,'overall':d,'summary':'Analyzed\x20'+b['length']+'\x20allocator(s):\x20'+c['filter'](h=>!h['unavoidable'])['length']+'\x20actionable,\x20'+(c['filter'](h=>h['unavoidable'])['length']+'\x20structural\x20finding(s).\x20Safe\x20destination:\x20'+e+'.')+(''+(f?'\x20Resolution\x20REQUIRED:\x20at\x20least\x20one\x20residual\x20demands\x20an\x20explicit\x20design\x20decision\x20before\x20publish.':''))};}export function derivePayoffFromSharing(a,b,c){const d=asNode(c?.['root']),e=c?.['table']??[],f=d?extractConstraints(d,e):[],g=a['map'](i=>{const j=classifyRecipient(i['who'])??{'kind':'entity','address':'(unclassifiable)'},k=j['kind']==='submission'?j['identifier']:undefined,l=k!==undefined?e['find'](n=>n['identifier']===k):undefined,m=k!==undefined?deriveReceiptRight(k,f):undefined;return{'spec':j,'slot_value_type':l?normalizeValueType(l['value_type']):undefined,'constraints':k!==undefined?f['filter'](n=>n['slot']===undefined||n['slot']===k):f,'receipt':m,'beneficial_owner':deriveBeneficialOwner(j,m)};}),h={'guard':'','recipients':g,'slots':[],'payoff':{'caller_eligibility':'','beneficial_recipient':'','positions':{}}};return buildPayoff(h,b);}function normalizeValueType(a){if(typeof a==='number')return a;const b={'bool':ValueType['Bool'],'address':ValueType['Address'],'string':ValueType['String'],'u64':ValueType['U64'],'u256':ValueType['U256']};return b[a['toLowerCase']()];}export function isUnboundSignerTheft(a){return a['recipient_is_signer']&&!a['caller_identity_constrained'];}export function canonicalDoctrine(a){switch(a){case'RC-FIND-01':return{'severity':'critical','title':'Signer\x20recipient\x20without\x20caller\x20constraint\x20—\x20fund\x20theft','mitigation':'Bind\x20the\x20Signer\x20(signer==order.owner\x20or\x20signer==fixed\x20address),\x20or\x20change\x20'+'the\x20recipient\x20to\x20an\x20Entity\x20/\x20submitted\x20object\x20slot.'};case'RC-FIND-03':return{'severity':'medium','title':'Cross-allocation\x20settlement\x20residual','mitigation':'Pick\x20ONE\x20resolution\x20and\x20record\x20it\x20in\x20the\x20service\x20description:\x20'+'(1)\x20competition\x20semantics\x20with\x20capped\x20exposure\x20(threshold\x20/\x20max\x20amount);\x20'+'(2)\x20Entity\x20routing\x20(treasury)\x20—\x20the\x20only\x20exclusive\x20choice\x20on\x20the\x20automatic\x20'+'order_allocators\x20route;\x20'+'(3)\x20per-order\x20pinned\x20Guards\x20(order.owner\x20==\x20constant)\x20—\x20the\x20trustless\x20'+'exclusive\x20route.','resolution_required':!![]};case'RC-FIND-06':return{'severity':'low','title':'Permissionless\x20alloc\x20—\x20forced\x20settlement\x20timing','mitigation':'Monitor\x20settlements;\x20constrain\x20time-sensitivity\x20via\x20Guard\x20conditions.'};}}export const RECIPIENT_DESIGN_OPTIONS=[{'id':'entity','move_recipient':'Recipient::Entity(address)','semantics':'Funds\x20flow\x20to\x20a\x20fixed\x20address\x20(a\x20constrained\x20user\x20account\x20/\x20treasury).\x20'+'Destination\x20never\x20depends\x20on\x20the\x20caller.','required_constraints':['The\x20address\x20is\x20chosen\x20at\x20design\x20time\x20and\x20recorded\x20in\x20the\x20allocator\x20table.']},{'id':'submitted_object','move_recipient':'Recipient::GuardIdentifier(u8)','semantics':'Funds\x20flow\x20to\x20the\x20object\x20submitted\x20under\x20protocol\x20context\x20(e.g.\x20the\x20order\x20being\x20settled).\x20'+'Receivable\x20only\x20by\x20that\x20object\x27s\x20owner\x20—\x20object\x20receipt\x20=\x20owner\x20receipt.','required_constraints':['The\x20Guard\x20binds\x20the\x20submission\x27s\x20scope\x20(which\x20query/object\x20type\x20the\x20slot\x20carries).','The\x20slot\x27s\x20table\x20value\x20type\x20is\x20address\x20(enforced\x20at\x20allocator\x20registration).'],'finding_if_unmet':'RC-FIND-02\x20/\x20RC-FIND-07'},{'id':'signer','move_recipient':'Recipient::Signer','semantics':'Funds\x20flow\x20to\x20the\x20caller\x20who\x20executes\x20the\x20permissionless\x20alloc.\x20'+'Safe\x20only\x20when\x20the\x20Guard\x20proves\x20exactly\x20who\x20the\x20caller\x20may\x20be.','required_constraints':['The\x20Guard\x20constrains\x20the\x20Signer\x20identity\x20(signer\x20==\x20a\x20fixed\x20address\x20or\x20a\x20derived\x20legitimate\x20owner).'],'finding_if_unmet':'RC-FIND-01'},{'id':'constrained_submission','move_recipient':'Recipient::GuardIdentifier(u8)','semantics':'Funds\x20flow\x20to\x20an\x20object\x20address\x20supplied\x20by\x20the\x20signer,\x20but\x20the\x20Guard\x20constrains\x20'+'both\x20the\x20submission\x20scope\x20and\x20the\x20signer\x27s\x20relation\x20to\x20it\x20(e.g.\x20the\x20signer\x20owns\x20the\x20submitted\x20order).','required_constraints':['The\x20Guard\x20binds\x20the\x20submission\x27s\x20scope\x20(object/query\x20type).','The\x20Guard\x20binds\x20the\x20signer\x20to\x20the\x20submitted\x20object.','The\x20slot\x27s\x20table\x20value\x20type\x20is\x20address\x20(enforced\x20at\x20allocator\x20registration).'],'finding_if_unmet':'RC-FIND-01\x20/\x20RC-FIND-02\x20/\x20RC-FIND-07'}];export function recipientDesignGuidance(){return RECIPIENT_DESIGN_OPTIONS;}export const OBJECT_DRIVEABILITY=[{'object_type':'order','receive_entries':['owner-side\x20coin\x20extraction\x20from\x20the\x20order','owner-side\x20object\x20extraction\x20from\x20the\x20order'],'anyone_drivable':!![],'funds_settle_to':'order.owner','rationale':'Order\x20is\x20a\x20shared\x20object\x20and\x20extraction\x20has\x20no\x20signer\x20gate;\x20'+'Receiving\x20is\x20restricted\x20to\x20objects\x20actually\x20delivered\x20to\x20that\x20order,\x20and\x20coins\x20settle\x20to\x20its\x20owner.'},{'object_type':'permission','receive_entries':['owner-side\x20coin\x20extraction\x20via\x20the\x20permission\x20object','owner-side\x20object\x20extraction\x20via\x20the\x20permission\x20object'],'anyone_drivable':!![],'funds_settle_to':'permission.owner','rationale':'Permission\x20is\x20the\x20final\x20authority;\x20anyone\x20can\x20drive\x20extraction\x20of\x20funds\x20sent\x20to\x20its\x20address,\x20but\x20the\x20destination\x20is\x20its\x20owner.'},{'object_type':'service','receive_entries':['owner-side\x20coin\x20extraction\x20from\x20the\x20service','owner-side\x20object\x20extraction\x20from\x20the\x20service'],'anyone_drivable':![],'permission_index':0x13f,'funds_settle_to':'permission.owner','rationale':'Business\x20permission\x20gate\x20(index\x20319);\x20members\x20drive,\x20value\x20settles\x20to\x20the\x20organization\x20owner.'},{'object_type':'treasury','receive_entries':['owner-side\x20coin\x20extraction\x20from\x20the\x20treasury','owner-side\x20object\x20extraction\x20from\x20the\x20treasury'],'anyone_drivable':![],'permission_index':0x101,'funds_settle_to':'permission.owner','rationale':'Business\x20permission\x20gate\x20(index\x20257).'},{'object_type':'arbitration','receive_entries':['owner-side\x20coin\x20extraction\x20from\x20the\x20arbitration','owner-side\x20object\x20extraction\x20from\x20the\x20arbitration'],'anyone_drivable':![],'permission_index':0x16f,'funds_settle_to':'permission.owner','rationale':'Business\x20permission\x20gate\x20(index\x20367).'},{'object_type':'machine','receive_entries':['owner-side\x20coin\x20extraction\x20from\x20the\x20machine','owner-side\x20object\x20extraction\x20from\x20the\x20machine'],'anyone_drivable':![],'permission_index':0xcf,'funds_settle_to':'permission.owner','rationale':'Business\x20permission\x20gate\x20(index\x20207).'},{'object_type':'progress','receive_entries':['owner-side\x20coin\x20extraction\x20from\x20the\x20progress','owner-side\x20object\x20extraction\x20from\x20the\x20progress'],'anyone_drivable':![],'permission_index':0xe1,'funds_settle_to':'machine\x27s\x20permission.owner','rationale':'Business\x20permission\x20gate\x20(index\x20225),\x20scoped\x20to\x20the\x20Machine\x20permission.'},{'object_type':'demand','receive_entries':['owner-side\x20coin\x20extraction\x20from\x20the\x20demand','owner-side\x20object\x20extraction\x20from\x20the\x20demand'],'anyone_drivable':![],'permission_index':0x197,'funds_settle_to':'permission.owner','rationale':'Business\x20permission\x20gate\x20(index\x20407).'},{'object_type':'contact','receive_entries':['owner-side\x20coin\x20extraction\x20from\x20the\x20contact','owner-side\x20object\x20extraction\x20from\x20the\x20contact'],'anyone_drivable':![],'permission_index':0x1c6,'funds_settle_to':'permission.owner','rationale':'Business\x20permission\x20gate\x20(index\x20454).'}];export function driveabilityOf(a){return OBJECT_DRIVEABILITY['find'](b=>b['object_type']===a);}function rewardRecipientKind(a){if(typeof a==='string'){const e=a['toLowerCase']();if(e==='signer')return{'kind':'signer'};return{'kind':'entity'};}if(typeof a!=='object'||a===null)return{'kind':'entity'};const b=a,c=f=>typeof b[f]==='number'?b[f]:undefined,d=c('GuardIdentifier')??c('guard_identifier')??c('identifier');if(d!==undefined)return{'kind':'submission','slot':d};if(b['Signer']!==undefined||b['signer']!==undefined)return{'kind':'signer'};return{'kind':'entity'};}const SLOT_BINDING_CODES=new Set(['service_binding','progress_node_state','signer_is_submitted_object_owner','repository_crosscheck','signer_permission_member']);export function analyzeRewardClaimGuard(a){const {kind:b,slot:c}=rewardRecipientKind(a['recipient']),d={'entry_index':a['entry_index'],'guard':a['guard'],'recipient_kind':b,...c!==undefined?{'recipient_slot':c}:{},'guard_resolved':![],'constraint_codes':[],'recipient_slot_usages':0x0,'caller_identity_constrained':![],'viability':'unverifiable','reason':'Guard\x20table/root\x20not\x20fetched\x20with\x20the\x20topology\x20—\x20the\x20deciding\x20predicate\x20is\x20outside\x20the\x20evidence;\x20the\x20owner\x20must\x20disclose\x20the\x20full\x20guard\x20definitions.'},e=asNode(a['guard_def']?.['root']);if(!e)return d;const f=a['guard_def']?.['table']??[],g=extractConstraints(e,f);d['guard_resolved']=!![],d['constraint_codes']=g['map'](k=>k['code']),d['caller_identity_constrained']=g['some'](k=>k['caller_constraint']);if(b==='entity')return d['viability']='blocked',d['reason']='Payout\x20address\x20is\x20fixed\x20at\x20guard\x20registration\x20(Entity\x20recipient);\x20the\x20claim\x20path\x20cannot\x20redirect\x20it.',d;if(b==='signer')return d['caller_identity_constrained']?(d['viability']='blocked',d['reason']='Recipient\x20is\x20the\x20caller\x20(Signer)\x20but\x20the\x20guard\x20binds\x20the\x20caller\x20identity\x20—\x20only\x20the\x20authorized\x20party\x20can\x20claim.'):(d['viability']='viable',d['reason']='Recipient\x20is\x20the\x20caller\x20(Signer)\x20with\x20no\x20identity\x20binding\x20—\x20anyone\x20satisfying\x20the\x20remaining\x20conditions\x20claims\x20to\x20their\x20own\x20address.'),d;const h=c??-0x1,i=collectSlotUsages(e)['filter'](k=>k['slot']===h);d['recipient_slot_usages']=i['length'];const j=g['filter'](k=>k['slot']===h&&SLOT_BINDING_CODES['has'](k['code']));if(j['length']>0x0)d['viability']='blocked',d['reason']='Submitted\x20address\x20is\x20constrained\x20inside\x20the\x20guard\x20('+j['map'](k=>k['code'])['join'](',\x20')+')\x20—\x20a\x20passerby\x20cannot\x20fill\x20the\x20slot\x20with\x20an\x20arbitrary\x20address.';else i['length']>0x0?(d['viability']='conditional',d['reason']='The\x20guard\x20reads\x20the\x20submitted\x20slot\x20('+i['length']+'\x20query\x20usage(s))\x20but\x20no\x20recognized\x20scope/equality\x20constraint\x20was\x20matched\x20—\x20manual\x20predicate\x20review\x20required.'):(d['viability']='viable',d['reason']='No\x20guard\x20query\x20consumes\x20the\x20submitted\x20slot\x20—\x20the\x20predicate\x20cannot\x20constrain\x20the\x20payout\x20address;\x20any\x20passing\x20party\x20claims\x20to\x20their\x20own\x20address.');return d;}
|
|
@@ -57,6 +57,7 @@ export declare const TemplateFrontmatterSchema: z.ZodObject<{
|
|
|
57
57
|
id_from: z.ZodOptional<z.ZodString>;
|
|
58
58
|
value_type: z.ZodOptional<z.ZodString>;
|
|
59
59
|
}, z.core.$strip>>;
|
|
60
|
+
params: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
60
61
|
}, z.core.$strip>>;
|
|
61
62
|
allocator: z.ZodObject<{
|
|
62
63
|
recipient: z.ZodEnum<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{copyFileSync,existsSync,mkdirSync,readdirSync,readFileSync,renameSync,rmdirSync,statSync,writeFileSync}from'node:fs';import{join,relative,sep}from'node:path';import{z}from'zod';import{getWowokDataDir,getWowokIndustryDir}from'@wowok/wowok';import{SUPPORTED_INDUSTRIES}from'../customer/user-preferences.js';import{isRegisteredIndustry}from'./industry-registry.js';import{BUILTIN_TEMPLATES,BUILTIN_TEMPLATES_VERSION}from'./builtin-templates.js';import{releaseBodyHash,releaseSentinelLine,stripReleaseSentinel}from'./release-sentinel.js';export const TEMPLATES_SUBDIR='templates';export function resolveTemplatesDir(){return process['env']['WOWOK_TEMPLATES_DIR']||getWowokIndustryDir();}function resolveLegacyTemplatesDir(){return process['env']['WOWOK_LEGACY_TEMPLATES_DIR']||join(getWowokDataDir(),'templates');}const MachineEdgeSchema=z['object']({'prev':z['string'](),'forward':z['string']()['min'](0x1)['optional'](),'operator':z['enum'](['merchant','order_payer'])['optional'](),'permission_index':z['number']()['int']()['min'](0x3e8)['optional'](),'guard_key':z['string']()['min'](0x1)['optional']()}),MachineNodeSchema=z['object']({'name':z['string']()['min'](0x1),'role':z['string']()['min'](0x1),'operator':z['enum'](['merchant','order_payer'])['optional'](),'semantic_role':z['enum'](['draft','active','delivered','final','cancelled'])['optional'](),'optional':z['boolean']()['optional'](),'threshold':z['number']()['int']()['min'](0x0)['optional'](),'from':z['array'](z['union']([z['string'](),MachineEdgeSchema]))['optional']()}),GuardRefSchema=z['object']({'template_id':z['string']()['regex'](/^(pattern\.[a-z0-9_]+|tpl_[a-z0-9_]+)$/,'guard\x20template_id\x20must\x20be\x20a\x20\x27pattern.*\x27\x20design\x20pattern\x20or\x20\x27tpl_*\x27\x20guard\x20template'),'host':z['enum'](['service','machine','reward','repository','arbitration']),'purpose':z['string']()['min'](0x1),'key':z['string']()['min'](0x1)['optional'](),'policy':z['object']({'name':z['string']()['min'](0x1)['optional'](),'description':z['string']()['min'](0x1)['optional'](),'id_from':z['string']()['min'](0x1)['optional'](),'value_type':z['string']()['min'](0x1)['optional']()})['optional']()}),ConditionalGuardEmissionSchema=z['object']({'guard_key':z['string']()['min'](0x1),'param':z['string']()['min'](0x1),'values':z['array'](z['string']()['min'](0x1))['min'](0x2),'emit_value':z['string']()['min'](0x1),'question':z['string']()['min'](0x1)})['strict'](),AllocatorRowSchema=z['object']({'track':z['enum'](['settlement','refund']),'recipient':z['enum'](['entity','guard_identifier','signer']),'recipient_key':z['string']()['min'](0x1)['optional'](),'mode':z['enum'](['amount','rate','surplus']),'value':z['union']([z['string'](),z['number']()])['optional'](),'value_from':z['string']()['optional'](),'fix':z['union']([z['string'](),z['number']()])['optional'](),'fix_from':z['string']()['optional'](),'guard_key':z['string']()['min'](0x1)['optional'](),'note':z['string']()['optional']()})['strict'](),AllocatorSchema=z['object']({'recipient':z['enum'](['signer','entity','fixed']),'recipient_key':z['string']()['min'](0x1)['optional'](),'refund_track':z['enum'](['order_anchored'])['optional'](),'count':z['number']()['int']()['positive'](),'mode':z['enum'](['amount','rate','surplus']),'once_per_order':z['boolean']()['optional'](),'rows':z['array'](AllocatorRowSchema)['optional'](),'description':z['string']()['min'](0x1)})['strict'](),IndustryNameSchema=z['string']()['regex'](/^[a-z][a-z0-9_]*$/,'industry\x20must\x20be\x20lowercase\x20snake_case\x20(a-z,\x200-9,\x20_)')['refine'](a=>isRegisteredIndustry(a),{'message':'unknown\x20industry\x20—\x20register\x20it\x20first\x20via\x20an\x20industry\x20pack\x20'+'(industry_pack_operation\x20action=\x27scaffold\x27)\x20or\x20the\x20industry\x20generalizer;\x20'+('builtin\x20industries:\x20'+SUPPORTED_INDUSTRIES['join'](',\x20'))});export const TemplateFrontmatterSchema=z['object']({'id':z['string']()['regex'](/^[a-z][a-z0-9_-]*\/[a-z][a-z0-9_-]*$/,'id\x20must\x20be\x20\x27<industry>/<variant>\x27'),'industry':IndustryNameSchema,'variant':z['string']()['regex'](/^[a-z][a-z0-9_-]*$/),'product_ref':z['string']()['regex'](/^[a-z][a-z0-9._-]*$/,'product_ref\x20must\x20be\x20a\x20lowercase\x20product\x20slug')['optional'](),'archetype':z['enum'](['leader','challenger']),'phase':z['number']()['int']()['min'](0x1)['max'](0x3),'machine_shape':z['array'](MachineNodeSchema)['min'](0x1),'guards':z['array'](GuardRefSchema),'allocator':AllocatorSchema,'fee_params':z['record'](z['string'](),z['union']([z['number'](),z['string']()])),'trust_mechanisms':z['array'](z['string']()),'keeper_dependencies':z['array'](z['string']()),'recommended_role':z['enum'](['merchant','supplier','both']),'role_rationale':z['string']()['min'](0x1),'differences':z['array'](z['string']()),'user_inputs':z['array'](z['string']()),'key_risk':z['string']()['min'](0x1)['max'](0x12c,'key_risk\x20must\x20be\x20a\x20one-line\x20risk\x20statement\x20(<=\x20300\x20chars)\x20—\x20rules\x20and\x20doctrine\x20do\x20not\x20belong\x20in\x20this\x20field')['refine'](a=>!/STANDING RULE|TECHNOLOGY PROVIDER|NOT A PARTY TO THE DEAL|Full text:/i['test'](a),{'message':'key_risk\x20carries\x20an\x20instruction-block\x20fragment\x20(STANDING\x20RULE\x20/\x20provider\x20doctrine\x20/\x20\x27Full\x20text:\x27\x20reference)\x20—\x20keep\x20doctrine\x20in\x20body\x20prose\x20or\x20playbooks,\x20not\x20in\x20this\x20field'}),'build_notes':z['array'](z['string']()),'evidence_refs':z['array'](z['string']())['optional'](),'conditional_guards':z['array'](ConditionalGuardEmissionSchema)['optional'](),'time_anchors':z['record'](z['string'](),z['string']())['optional'](),'payment_model':z['enum'](['milestone','subscription','escrow'])['optional'](),'arbitration_mode':z['enum'](['none','merchant_pick','mutual_pick','third_party'])['optional'](),'reward_claim_policy':z['object']({'kind':z['enum'](['once','periodic','capped']),'min_claim_interval_ms':z['number']()['optional'](),'max_total_per_recipient':z['string']()['optional']()})['optional'](),'review_mode':z['enum'](['none','review','review_reward'])['optional'](),'after_sales_mode':z['enum'](['none','return','exchange','warranty'])['optional'](),'acceptance_mode':z['enum'](['none','milestone','contest','bounty','agent'])['optional'](),'installment_mode':z['enum'](['none','deposit_balance','milestone_n'])['optional'](),'affiliate_mode':z['enum'](['none','commission'])['optional'](),'crowdfunding_mode':z['enum'](['none','threshold','flexible'])['optional'](),'compensation_fund_policy':z['enum'](['allowed','forbidden'])['optional'](),'reentry_kind':z['enum'](['none','review-loop','paid-cycle'])['optional']()})['strict']();import{validateAllocatorRows}from'./template-validation.js';export{validateAllocatorRows};export function platformShareBps(a){const b=Object['keys'](a)['find'](c=>/(?:platform|commission|service_fee)[a-z_]*_bps$/['test'](c)&&!/^attributed_/['test'](c)&&typeof a[c]==='number');return b!==undefined?a[b]:undefined;}export function parseTemplateFile(a){const b=a['replace'](/^\uFEFF/,'')['replace'](/^<!-- builtin:[a-z0-9-]+:v\d+:[0-9a-f]+ -->\r?\n/,''),c=b['split'](/\r?\n/);if(c[0x0]?.['trim']()!=='---')throw new Error('template\x20must\x20start\x20with\x20a\x20\x27---\x27\x20frontmatter\x20block');let d=-0x1;for(let f=0x1;f<c['length'];f++){if(c[f]['trim']()==='---'){d=f;break;}}if(d===-0x1)throw new Error('unterminated\x20frontmatter\x20block\x20(missing\x20closing\x20\x27---\x27)');const e={};for(let g=0x1;g<d;g++){const h=c[g];if(!h['trim']()||h['trim']()['startsWith']('#'))continue;const j=h['indexOf'](':');if(j===-0x1)throw new Error('invalid\x20frontmatter\x20line\x20'+(g+0x1)+':\x20\x27'+h['trim']()+'\x27\x20(expected\x20\x27key:\x20value\x27)');const k=h['slice'](0x0,j)['trim'](),l=h['slice'](j+0x1)['trim']();if(!k)throw new Error('invalid\x20frontmatter\x20line\x20'+(g+0x1)+':\x20empty\x20key');if(l['startsWith']('[')||l['startsWith']('{'))try{e[k]=JSON['parse'](l);}catch(m){throw new Error('frontmatter\x20key\x20\x27'+k+'\x27\x20is\x20not\x20valid\x20JSON:\x20'+m['message']);}else{if(/^-?\d+(\.\d+)?$/['test'](l))e[k]=Number(l);else{if(l['startsWith']('\x22')&&l['endsWith']('\x22')&&l['length']>=0x2||l['startsWith']('\x27')&&l['endsWith']('\x27')&&l['length']>=0x2){if(l[0x0]==='\x22')try{e[k]=JSON['parse'](l);}catch(n){throw new Error('frontmatter\x20key\x20\x27'+k+'\x27\x20is\x20not\x20valid\x20JSON:\x20'+n['message']);}else e[k]=l['slice'](0x1,-0x1);}else e[k]=l;}}}return{'frontmatter':e,'body':c['slice'](d+0x1)['join']('\x0a')['trim']()};}function frontmatterLine(a,b){if(typeof b==='number')return a+':\x20'+b;if(typeof b==='string')return a+':\x20'+b;return a+':\x20'+JSON['stringify'](b);}export const TEMPLATE_SENTINEL_KIND='industry-template';export function canonicalTemplateContent(a){const b=[['id',a['id']],['industry',a['industry']],['variant',a['variant']],['product_ref',a['product_ref']],['archetype',a['archetype']],['phase',a['phase']],['recommended_role',a['recommended_role']],['role_rationale',a['role_rationale']],['key_risk',a['key_risk']],['machine_shape',a['machine_shape']],['guards',a['guards']],['allocator',a['allocator']],['fee_params',a['fee_params']],['trust_mechanisms',a['trust_mechanisms']],['keeper_dependencies',a['keeper_dependencies']],['differences',a['differences']],['user_inputs',a['user_inputs']],['build_notes',a['build_notes']],...a['evidence_refs']?[['evidence_refs',a['evidence_refs']]]:[],...a['conditional_guards']?[['conditional_guards',a['conditional_guards']]]:[],...a['time_anchors']?[['time_anchors',a['time_anchors']]]:[],...a['payment_model']?[['payment_model',a['payment_model']]]:[],...a['arbitration_mode']?[['arbitration_mode',a['arbitration_mode']]]:[],...a['review_mode']?[['review_mode',a['review_mode']]]:[],...a['after_sales_mode']?[['after_sales_mode',a['after_sales_mode']]]:[],...a['acceptance_mode']?[['acceptance_mode',a['acceptance_mode']]]:[],...a['installment_mode']?[['installment_mode',a['installment_mode']]]:[],...a['affiliate_mode']?[['affiliate_mode',a['affiliate_mode']]]:[],...a['crowdfunding_mode']?[['crowdfunding_mode',a['crowdfunding_mode']]]:[],...a['reward_claim_policy']?[['reward_claim_policy',a['reward_claim_policy']]]:[],...a['compensation_fund_policy']?[['compensation_fund_policy',a['compensation_fund_policy']]]:[],...a['reentry_kind']&&a['reentry_kind']!=='none'?[['reentry_kind',a['reentry_kind']]]:[]],c=['---',...b['map'](([e,f])=>frontmatterLine(e,f)),'---'],d=['','#\x20'+a['industry']+'\x20/\x20'+a['variant']+'\x20('+a['archetype']+')','','>\x20Industry\x20archetype\x20template.\x20Editable\x20and\x20migratable:\x20the\x20frontmatter\x20is','>\x20zod-validated\x20on\x20every\x20load;\x20the\x20body\x20is\x20free-form\x20guidance\x20for\x20the\x20AI.','','##\x20Key\x20risk','',a['key_risk'],'','##\x20Differences\x20vs\x20the\x20sibling\x20variant','',...a['differences']['map'](e=>'-\x20'+e),'','##\x20User\x20inputs\x20(inject\x20at\x20build\x20time)','',...a['user_inputs']['map'](e=>'-\x20'+e),'','##\x20Risk-avoidance\x20checklist\x20(R1-R10)','',...a['trust_mechanisms']['map'](e=>'-\x20'+e),'','##\x20Build\x20notes','',...a['build_notes']['map'](e=>'-\x20'+e),''];return[...c,...d]['join']('\x0a');}export function renderTemplateFile(a){const b=canonicalTemplateContent(a);return releaseSentinelLine(TEMPLATE_SENTINEL_KIND,BUILTIN_TEMPLATES_VERSION,releaseBodyHash(b))+'\x0a'+b;}export function matchBuiltinTemplateFile(a){const b=relative(resolveTemplatesDir(),a);if(!b||b['startsWith']('..'))return null;const c=b['split'](sep);if(c['length']!==0x3||c[0x1]!==TEMPLATES_SUBDIR||!c[0x2]['endsWith']('.md'))return null;const d=c[0x2]['slice'](0x0,-'.md'['length']);return BUILTIN_TEMPLATES['find'](e=>e['industry']===c[0x0]&&e['variant']===d)??null;}let seeded=![];function migrateLegacyTemplates(a){const b=resolveLegacyTemplatesDir();if(b===a)return;if(!existsSync(b))return;try{for(const c of readdirSync(b,{'withFileTypes':!![]})){if(!c['isDirectory']())continue;const d=join(b,c['name']),e=join(a,c['name'],TEMPLATES_SUBDIR);for(const g of readdirSync(d,{'withFileTypes':!![]})){if(!g['isFile']()||!g['name']['endsWith']('.md'))continue;const h=join(e,g['name']);if(existsSync(h))continue;mkdirSync(e,{'recursive':!![]}),renameSync(join(d,g['name']),h);}try{rmdirSync(d);}catch{}}try{rmdirSync(b);}catch{}}catch{}}export function seedBuiltinTemplates(){const a=[],b=resolveTemplatesDir();migrateLegacyTemplates(b);for(const c of BUILTIN_TEMPLATES){const d=join(b,c['industry'],TEMPLATES_SUBDIR),e=join(d,c['variant']+'.md'),f=canonicalTemplateContent(c),g={'template':c['id'],'status':'written','path':e};try{if(!existsSync(e))mkdirSync(d,{'recursive':!![]}),writeFileSync(e,renderTemplateFile(c),'utf-8');else{const h=readFileSync(e,'utf-8'),{sentinel:i,content:j}=stripReleaseSentinel(h,TEMPLATE_SENTINEL_KIND);!i?j===f?(writeFileSync(e,renderTemplateFile(c),'utf-8'),g['status']='restamped',g['detail']='body\x20matches\x20canonical\x20but\x20no\x20sentinel\x20present;\x20sentinel\x20header\x20added,\x20body\x20untouched'):(g['status']='skipped_user_file',g['detail']='template\x20file\x20exists\x20without\x20builtin\x20sentinel\x20and\x20body\x20differs\x20from\x20canonical;\x20leaving\x20user\x20file\x20untouched'):j===f?i['version']!==BUILTIN_TEMPLATES_VERSION||releaseBodyHash(j)!==i['hash']?(writeFileSync(e,renderTemplateFile(c),'utf-8'),g['status']='restamped',g['detail']='body\x20matches\x20canonical\x20but\x20sentinel\x20stale/wrong;\x20header\x20refreshed,\x20body\x20untouched'):g['status']='current':(g['status']='skipped_modified',g['detail']='body\x20differs\x20from\x20canonical;\x20not\x20overwritten\x20by\x20seeding\x20—\x20use\x20repair_builtin_templates\x20(preview→confirm)\x20to\x20reseed');}}catch(k){g['status']='error',g['detail']=k['message'];}a['push'](g);}return a;}export function summarizeTemplateDiff(a,b){let c,d;try{c=parseTemplateFile(a);}catch(g){return'on-disk\x20file\x20is\x20not\x20parseable\x20('+g['message']+');\x20full\x20content\x20will\x20be\x20replaced';}try{d=parseTemplateFile(b);}catch{return'canonical\x20render\x20is\x20not\x20parseable\x20(code\x20defect);\x20full\x20content\x20will\x20be\x20replaced';}const e=[],f=new Set([...Object['keys'](c['frontmatter']),...Object['keys'](d['frontmatter'])]);for(const h of[...f]['sort']()){const i=h in c['frontmatter'],j=h in d['frontmatter'];if(i&&!j)e['push']('-'+h);else{if(!i&&j)e['push']('+'+h);else{if(JSON['stringify'](c['frontmatter'][h])!==JSON['stringify'](d['frontmatter'][h]))e['push']('~'+h);}}}return c['body']!==d['body']&&e['push']('~body\x20('+c['body']['split']('\x0a')['length']+'\x20->\x20'+d['body']['split']('\x0a')['length']+'\x20lines)'),e['length']>0x0?e['join'](',\x20'):'whitespace/ordering\x20only';}export function repairBuiltinTemplates(a){const b=[],c=resolveTemplatesDir(),d=a?.['backup']!==![],e=a?.['dryRun']===!![],f=new Set(a?.['includeUserEdited']??[]);for(const g of BUILTIN_TEMPLATES){const h=join(c,g['industry'],TEMPLATES_SUBDIR),i=join(h,g['variant']+'.md');if(!existsSync(i))continue;const j=canonicalTemplateContent(g);let k=null,l='';const m={'template':g['id'],'status':'would_update','path':i};try{const p=stripReleaseSentinel(readFileSync(i,'utf-8'),TEMPLATE_SENTINEL_KIND);k=p['sentinel'],l=p['content'];}catch(q){m['status']='error',m['detail']=q['message'],b['push'](m);continue;}if(l===j)continue;let n;if(k){if(k['version']>BUILTIN_TEMPLATES_VERSION){m['status']='error',m['detail']='newer\x20release\x20on\x20disk\x20(sentinel\x20v'+k['version']+'\x20>\x20running\x20catalog\x20v'+BUILTIN_TEMPLATES_VERSION+')\x20—\x20'+'repair\x20would\x20DOWNGRADE\x20and\x20lose\x20the\x20newer\x20release\x27s\x20content;\x20refused.\x20Upgrade\x20the\x20MCP\x20server\x20instead',b['push'](m);continue;}if(releaseBodyHash(l)!==k['hash']){if(!f['has'](g['id']))continue;n='sentinel-body\x20hash\x20mismatch\x20(sentinel\x20v'+k['version']+'\x20no\x20longer\x20binds\x20the\x20body)\x20'+'reseeded\x20under\x20EXPLICIT\x20include_user_edited\x20authorization';}else n='untouched\x20older\x20release\x20(sentinel\x20v'+k['version']+',\x20current\x20v'+BUILTIN_TEMPLATES_VERSION+')';}else{let r;try{r=String(parseTemplateFile(l)['frontmatter']['id']??'');}catch{continue;}if(r!==g['id'])continue;n='legacy\x20sentinel-less\x20builtin\x20file';}const o=summarizeTemplateDiff(l,j);if(e){m['status']='would_update',m['detail']=n+'\x20would\x20be\x20reseeded\x20from\x20BUILTIN_TEMPLATES\x20('+g['id']+')\x20—\x20diff\x20vs\x20canonical:\x20'+o+(d?';\x20previous\x20body\x20would\x20be\x20saved\x20as\x20<file>.bak':'')+'\x20—\x20execute\x20with\x20authorize=true\x20after\x20the\x20user\x20explicitly\x20confirms',b['push'](m);continue;}try{if(d)copyFileSync(i,i+'.bak');writeFileSync(i,renderTemplateFile(g),'utf-8'),cache['delete'](i),m['status']='updated',m['detail']=n+'\x20reseeded\x20from\x20BUILTIN_TEMPLATES\x20('+g['id']+')\x20—\x20diff\x20was:\x20'+o+(d?';\x20previous\x20body\x20saved\x20as\x20<file>.bak':'');}catch(s){m['status']='error',m['detail']=s['message'];}b['push'](m);}return b;}export function builtinTemplateDrift(a){const b=new Set(a?.['includeUserEdited']??[]),c=[],d=resolveTemplatesDir();for(const e of BUILTIN_TEMPLATES){const f=join(d,e['industry'],TEMPLATES_SUBDIR,e['variant']+'.md');if(!existsSync(f)){c['push']({'template':e['id'],'path':f,'state':'missing','repairable':!![],'detail':'no\x20file\x20on\x20disk;\x20seeding\x20will\x20create\x20it'});continue;}const g=canonicalTemplateContent(e);let h=null,i='';try{const k=stripReleaseSentinel(readFileSync(f,'utf-8'),TEMPLATE_SENTINEL_KIND);h=k['sentinel'],i=k['content'];}catch(l){c['push']({'template':e['id'],'path':f,'state':'modified','repairable':![],'detail':'unreadable:\x20'+l['message']});continue;}if(i===g)continue;const j=summarizeTemplateDiff(i,g);if(!h){let m;try{m=String(parseTemplateFile(i)['frontmatter']['id']??'');}catch{m=undefined;}m===e['id']?c['push']({'template':e['id'],'path':f,'state':'modified','repairable':!![],'detail':'legacy\x20sentinel-less\x20builtin\x20file\x20—\x20seeding\x20never\x20rewrites\x20it\x20and\x20no\x20sentinel\x20proves\x20provenance;\x20repair\x20can\x20reseed\x20—\x20diff\x20vs\x20canonical:\x20'+j}):c['push']({'template':e['id'],'path':f,'state':'modified','repairable':![],'detail':'no\x20release\x20sentinel\x20and\x20id\x20\x27'+(m??'<unparseable>')+'\x27\x20does\x20not\x20match\x20the\x20builtin\x20id\x20—\x20a\x20user\x20file\x20occupies\x20this\x20path;\x20never\x20touched\x20(rename\x20it\x20to\x20free\x20the\x20slot)'});continue;}if(releaseBodyHash(i)===h['hash'])h['version']>BUILTIN_TEMPLATES_VERSION?c['push']({'template':e['id'],'path':f,'state':'modified','repairable':![],'detail':'newer\x20release\x20(sentinel\x20v'+h['version']+'\x20>\x20running\x20catalog\x20v'+BUILTIN_TEMPLATES_VERSION+')\x20—\x20'+'repair\x20would\x20DOWNGRADE\x20and\x20lose\x20the\x20newer\x20release\x27s\x20content;\x20repairable:\x20false.\x20'+'Upgrade\x20the\x20MCP\x20server\x20to\x20match\x20—\x20diff\x20vs\x20canonical:\x20'+j}):c['push']({'template':e['id'],'path':f,'state':'modified','repairable':!![],'detail':'untouched\x20older\x20release\x20(sentinel\x20v'+h['version']+',\x20current\x20v'+BUILTIN_TEMPLATES_VERSION+')\x20—\x20repair\x20can\x20upgrade\x20—\x20diff\x20vs\x20canonical:\x20'+j});else{const n=b['has'](e['id']);c['push']({'template':e['id'],'path':f,'state':'modified','repairable':n,'detail':n?'sentinel-body\x20hash\x20mismatch\x20(sentinel\x20v'+h['version']+'\x20no\x20longer\x20binds\x20the\x20body)\x20—\x20reseedable\x20under\x20the\x20explicit\x20include_user_edited\x20authorization\x20for\x20this\x20id\x20—\x20diff\x20vs\x20canonical:\x20'+j:'user-edited\x20body\x20—\x20kept\x20by\x20design;\x20repair\x20never\x20overwrites\x20user\x20edits\x20—\x20diff\x20vs\x20canonical:\x20'+j});}}return c;}const cache=new Map();export function reloadTemplates(){cache['clear'](),seeded=![];}export function loadAndValidate(a){const b=readFileSync(a,'utf-8');let c;try{c=parseTemplateFile(b);}catch(f){throw new Error('template\x20\x27'+a+'\x27\x20failed\x20to\x20parse:\x20'+f['message']);}const d=TemplateFrontmatterSchema['safeParse'](c['frontmatter']);if(!d['success']){const g=d['error']['issues']['map'](h=>(h['path']['join']('.')||'<root>')+':\x20'+h['message'])['join'](';\x20');throw new Error('template\x20\x27'+a+'\x27\x20failed\x20validation:\x20'+g);}const e=validateAllocatorRows(d['data']);if(e['length']>0x0)throw new Error('template\x20\x27'+a+'\x27\x20failed\x20allocator-row\x20validation:\x20'+e['join'](';\x20'));return{...d['data'],'body':c['body'],'source_path':a};}function templateFilesOnDisk(a){const b=[];if(!existsSync(a))return b;for(const c of readdirSync(a,{'withFileTypes':!![]})){if(!c['isDirectory']())continue;const d=join(a,c['name'],TEMPLATES_SUBDIR);if(!existsSync(d))continue;for(const e of readdirSync(d,{'withFileTypes':!![]})){if(e['isFile']()&&e['name']['endsWith']('.md'))b['push'](join(d,e['name']));}}return b['sort']();}export function listTemplates(){!seeded&&(seedBuiltinTemplates(),seeded=!![]);const a=resolveTemplatesDir(),b=[],c=[],d=new Set();for(const e of templateFilesOnDisk(a)){d['add'](e);try{const f=statSync(e)['mtimeMs'],g=cache['get'](e);if(g&&g['mtimeMs']===f){b['push'](g['template']);continue;}const h=loadAndValidate(e);cache['set'](e,{'mtimeMs':f,'template':h}),b['push'](h);}catch(i){cache['delete'](e),c['push'](i['message']);}}for(const j of[...cache['keys']()]){if(!d['has'](j))cache['delete'](j);}return b['sort']((k,l)=>k['id']['localeCompare'](l['id'])),{'templates':b,'errors':c};}export function getTemplate(a){return listTemplates()['templates']['find'](b=>b['id']===a);}export function getTemplatesByIndustry(a){return listTemplates()['templates']['filter'](b=>b['industry']===a);}
|
|
1
|
+
import{copyFileSync,existsSync,mkdirSync,readdirSync,readFileSync,renameSync,rmdirSync,statSync,writeFileSync}from'node:fs';import{join,relative,sep}from'node:path';import{z}from'zod';import{getWowokDataDir,getWowokIndustryDir}from'@wowok/wowok';import{SUPPORTED_INDUSTRIES}from'../customer/user-preferences.js';import{isRegisteredIndustry}from'./industry-registry.js';import{BUILTIN_TEMPLATES,BUILTIN_TEMPLATES_VERSION}from'./builtin-templates.js';import{releaseBodyHash,releaseSentinelLine,stripReleaseSentinel}from'./release-sentinel.js';export const TEMPLATES_SUBDIR='templates';export function resolveTemplatesDir(){return process['env']['WOWOK_TEMPLATES_DIR']||getWowokIndustryDir();}function resolveLegacyTemplatesDir(){return process['env']['WOWOK_LEGACY_TEMPLATES_DIR']||join(getWowokDataDir(),'templates');}const MachineEdgeSchema=z['object']({'prev':z['string'](),'forward':z['string']()['min'](0x1)['optional'](),'operator':z['enum'](['merchant','order_payer'])['optional'](),'permission_index':z['number']()['int']()['min'](0x3e8)['optional'](),'guard_key':z['string']()['min'](0x1)['optional']()}),MachineNodeSchema=z['object']({'name':z['string']()['min'](0x1),'role':z['string']()['min'](0x1),'operator':z['enum'](['merchant','order_payer'])['optional'](),'semantic_role':z['enum'](['draft','active','delivered','final','cancelled'])['optional'](),'optional':z['boolean']()['optional'](),'threshold':z['number']()['int']()['min'](0x0)['optional'](),'from':z['array'](z['union']([z['string'](),MachineEdgeSchema]))['optional']()}),GuardRefSchema=z['object']({'template_id':z['string']()['regex'](/^(pattern\.[a-z0-9_]+|tpl_[a-z0-9_]+)$/,'guard\x20template_id\x20must\x20be\x20a\x20\x27pattern.*\x27\x20design\x20pattern\x20or\x20\x27tpl_*\x27\x20guard\x20template'),'host':z['enum'](['service','machine','reward','repository','arbitration']),'purpose':z['string']()['min'](0x1),'key':z['string']()['min'](0x1)['optional'](),'policy':z['object']({'name':z['string']()['min'](0x1)['optional'](),'description':z['string']()['min'](0x1)['optional'](),'id_from':z['string']()['min'](0x1)['optional'](),'value_type':z['string']()['min'](0x1)['optional']()})['optional'](),'params':z['record'](z['string'](),z['unknown']())['optional']()}),ConditionalGuardEmissionSchema=z['object']({'guard_key':z['string']()['min'](0x1),'param':z['string']()['min'](0x1),'values':z['array'](z['string']()['min'](0x1))['min'](0x2),'emit_value':z['string']()['min'](0x1),'question':z['string']()['min'](0x1)})['strict'](),AllocatorRowSchema=z['object']({'track':z['enum'](['settlement','refund']),'recipient':z['enum'](['entity','guard_identifier','signer']),'recipient_key':z['string']()['min'](0x1)['optional'](),'mode':z['enum'](['amount','rate','surplus']),'value':z['union']([z['string'](),z['number']()])['optional'](),'value_from':z['string']()['optional'](),'fix':z['union']([z['string'](),z['number']()])['optional'](),'fix_from':z['string']()['optional'](),'guard_key':z['string']()['min'](0x1)['optional'](),'note':z['string']()['optional']()})['strict'](),AllocatorSchema=z['object']({'recipient':z['enum'](['signer','entity','fixed']),'recipient_key':z['string']()['min'](0x1)['optional'](),'refund_track':z['enum'](['order_anchored'])['optional'](),'count':z['number']()['int']()['positive'](),'mode':z['enum'](['amount','rate','surplus']),'once_per_order':z['boolean']()['optional'](),'rows':z['array'](AllocatorRowSchema)['optional'](),'description':z['string']()['min'](0x1)})['strict'](),IndustryNameSchema=z['string']()['regex'](/^[a-z][a-z0-9_]*$/,'industry\x20must\x20be\x20lowercase\x20snake_case\x20(a-z,\x200-9,\x20_)')['refine'](a=>isRegisteredIndustry(a),{'message':'unknown\x20industry\x20—\x20register\x20it\x20first\x20via\x20an\x20industry\x20pack\x20'+'(industry_pack_operation\x20action=\x27scaffold\x27)\x20or\x20the\x20industry\x20generalizer;\x20'+('builtin\x20industries:\x20'+SUPPORTED_INDUSTRIES['join'](',\x20'))});export const TemplateFrontmatterSchema=z['object']({'id':z['string']()['regex'](/^[a-z][a-z0-9_-]*\/[a-z][a-z0-9_-]*$/,'id\x20must\x20be\x20\x27<industry>/<variant>\x27'),'industry':IndustryNameSchema,'variant':z['string']()['regex'](/^[a-z][a-z0-9_-]*$/),'product_ref':z['string']()['regex'](/^[a-z][a-z0-9._-]*$/,'product_ref\x20must\x20be\x20a\x20lowercase\x20product\x20slug')['optional'](),'archetype':z['enum'](['leader','challenger']),'phase':z['number']()['int']()['min'](0x1)['max'](0x3),'machine_shape':z['array'](MachineNodeSchema)['min'](0x1),'guards':z['array'](GuardRefSchema),'allocator':AllocatorSchema,'fee_params':z['record'](z['string'](),z['union']([z['number'](),z['string']()])),'trust_mechanisms':z['array'](z['string']()),'keeper_dependencies':z['array'](z['string']()),'recommended_role':z['enum'](['merchant','supplier','both']),'role_rationale':z['string']()['min'](0x1),'differences':z['array'](z['string']()),'user_inputs':z['array'](z['string']()),'key_risk':z['string']()['min'](0x1)['max'](0x12c,'key_risk\x20must\x20be\x20a\x20one-line\x20risk\x20statement\x20(<=\x20300\x20chars)\x20—\x20rules\x20and\x20doctrine\x20do\x20not\x20belong\x20in\x20this\x20field')['refine'](a=>!/STANDING RULE|TECHNOLOGY PROVIDER|NOT A PARTY TO THE DEAL|Full text:/i['test'](a),{'message':'key_risk\x20carries\x20an\x20instruction-block\x20fragment\x20(STANDING\x20RULE\x20/\x20provider\x20doctrine\x20/\x20\x27Full\x20text:\x27\x20reference)\x20—\x20keep\x20doctrine\x20in\x20body\x20prose\x20or\x20playbooks,\x20not\x20in\x20this\x20field'}),'build_notes':z['array'](z['string']()),'evidence_refs':z['array'](z['string']())['optional'](),'conditional_guards':z['array'](ConditionalGuardEmissionSchema)['optional'](),'time_anchors':z['record'](z['string'](),z['string']())['optional'](),'payment_model':z['enum'](['milestone','subscription','escrow'])['optional'](),'arbitration_mode':z['enum'](['none','merchant_pick','mutual_pick','third_party'])['optional'](),'reward_claim_policy':z['object']({'kind':z['enum'](['once','periodic','capped']),'min_claim_interval_ms':z['number']()['optional'](),'max_total_per_recipient':z['string']()['optional']()})['optional'](),'review_mode':z['enum'](['none','review','review_reward'])['optional'](),'after_sales_mode':z['enum'](['none','return','exchange','warranty'])['optional'](),'acceptance_mode':z['enum'](['none','milestone','contest','bounty','agent'])['optional'](),'installment_mode':z['enum'](['none','deposit_balance','milestone_n'])['optional'](),'affiliate_mode':z['enum'](['none','commission'])['optional'](),'crowdfunding_mode':z['enum'](['none','threshold','flexible'])['optional'](),'compensation_fund_policy':z['enum'](['allowed','forbidden'])['optional'](),'reentry_kind':z['enum'](['none','review-loop','paid-cycle'])['optional']()})['strict']();import{validateAllocatorRows}from'./template-validation.js';export{validateAllocatorRows};export function platformShareBps(a){const b=Object['keys'](a)['find'](c=>/(?:platform|commission|service_fee)[a-z_]*_bps$/['test'](c)&&!/^attributed_/['test'](c)&&typeof a[c]==='number');return b!==undefined?a[b]:undefined;}export function parseTemplateFile(a){const b=a['replace'](/^\uFEFF/,'')['replace'](/^<!-- builtin:[a-z0-9-]+:v\d+:[0-9a-f]+ -->\r?\n/,''),c=b['split'](/\r?\n/);if(c[0x0]?.['trim']()!=='---')throw new Error('template\x20must\x20start\x20with\x20a\x20\x27---\x27\x20frontmatter\x20block');let d=-0x1;for(let f=0x1;f<c['length'];f++){if(c[f]['trim']()==='---'){d=f;break;}}if(d===-0x1)throw new Error('unterminated\x20frontmatter\x20block\x20(missing\x20closing\x20\x27---\x27)');const e={};for(let g=0x1;g<d;g++){const h=c[g];if(!h['trim']()||h['trim']()['startsWith']('#'))continue;const j=h['indexOf'](':');if(j===-0x1)throw new Error('invalid\x20frontmatter\x20line\x20'+(g+0x1)+':\x20\x27'+h['trim']()+'\x27\x20(expected\x20\x27key:\x20value\x27)');const k=h['slice'](0x0,j)['trim'](),l=h['slice'](j+0x1)['trim']();if(!k)throw new Error('invalid\x20frontmatter\x20line\x20'+(g+0x1)+':\x20empty\x20key');if(l['startsWith']('[')||l['startsWith']('{'))try{e[k]=JSON['parse'](l);}catch(m){throw new Error('frontmatter\x20key\x20\x27'+k+'\x27\x20is\x20not\x20valid\x20JSON:\x20'+m['message']);}else{if(/^-?\d+(\.\d+)?$/['test'](l))e[k]=Number(l);else{if(l['startsWith']('\x22')&&l['endsWith']('\x22')&&l['length']>=0x2||l['startsWith']('\x27')&&l['endsWith']('\x27')&&l['length']>=0x2){if(l[0x0]==='\x22')try{e[k]=JSON['parse'](l);}catch(n){throw new Error('frontmatter\x20key\x20\x27'+k+'\x27\x20is\x20not\x20valid\x20JSON:\x20'+n['message']);}else e[k]=l['slice'](0x1,-0x1);}else e[k]=l;}}}return{'frontmatter':e,'body':c['slice'](d+0x1)['join']('\x0a')['trim']()};}function frontmatterLine(a,b){if(typeof b==='number')return a+':\x20'+b;if(typeof b==='string')return a+':\x20'+b;return a+':\x20'+JSON['stringify'](b);}export const TEMPLATE_SENTINEL_KIND='industry-template';export function canonicalTemplateContent(a){const b=[['id',a['id']],['industry',a['industry']],['variant',a['variant']],['product_ref',a['product_ref']],['archetype',a['archetype']],['phase',a['phase']],['recommended_role',a['recommended_role']],['role_rationale',a['role_rationale']],['key_risk',a['key_risk']],['machine_shape',a['machine_shape']],['guards',a['guards']],['allocator',a['allocator']],['fee_params',a['fee_params']],['trust_mechanisms',a['trust_mechanisms']],['keeper_dependencies',a['keeper_dependencies']],['differences',a['differences']],['user_inputs',a['user_inputs']],['build_notes',a['build_notes']],...a['evidence_refs']?[['evidence_refs',a['evidence_refs']]]:[],...a['conditional_guards']?[['conditional_guards',a['conditional_guards']]]:[],...a['time_anchors']?[['time_anchors',a['time_anchors']]]:[],...a['payment_model']?[['payment_model',a['payment_model']]]:[],...a['arbitration_mode']?[['arbitration_mode',a['arbitration_mode']]]:[],...a['review_mode']?[['review_mode',a['review_mode']]]:[],...a['after_sales_mode']?[['after_sales_mode',a['after_sales_mode']]]:[],...a['acceptance_mode']?[['acceptance_mode',a['acceptance_mode']]]:[],...a['installment_mode']?[['installment_mode',a['installment_mode']]]:[],...a['affiliate_mode']?[['affiliate_mode',a['affiliate_mode']]]:[],...a['crowdfunding_mode']?[['crowdfunding_mode',a['crowdfunding_mode']]]:[],...a['reward_claim_policy']?[['reward_claim_policy',a['reward_claim_policy']]]:[],...a['compensation_fund_policy']?[['compensation_fund_policy',a['compensation_fund_policy']]]:[],...a['reentry_kind']&&a['reentry_kind']!=='none'?[['reentry_kind',a['reentry_kind']]]:[]],c=['---',...b['map'](([e,f])=>frontmatterLine(e,f)),'---'],d=['','#\x20'+a['industry']+'\x20/\x20'+a['variant']+'\x20('+a['archetype']+')','','>\x20Industry\x20archetype\x20template.\x20Editable\x20and\x20migratable:\x20the\x20frontmatter\x20is','>\x20zod-validated\x20on\x20every\x20load;\x20the\x20body\x20is\x20free-form\x20guidance\x20for\x20the\x20AI.','','##\x20Key\x20risk','',a['key_risk'],'','##\x20Differences\x20vs\x20the\x20sibling\x20variant','',...a['differences']['map'](e=>'-\x20'+e),'','##\x20User\x20inputs\x20(inject\x20at\x20build\x20time)','',...a['user_inputs']['map'](e=>'-\x20'+e),'','##\x20Risk-avoidance\x20checklist\x20(R1-R10)','',...a['trust_mechanisms']['map'](e=>'-\x20'+e),'','##\x20Build\x20notes','',...a['build_notes']['map'](e=>'-\x20'+e),''];return[...c,...d]['join']('\x0a');}export function renderTemplateFile(a){const b=canonicalTemplateContent(a);return releaseSentinelLine(TEMPLATE_SENTINEL_KIND,BUILTIN_TEMPLATES_VERSION,releaseBodyHash(b))+'\x0a'+b;}export function matchBuiltinTemplateFile(a){const b=relative(resolveTemplatesDir(),a);if(!b||b['startsWith']('..'))return null;const c=b['split'](sep);if(c['length']!==0x3||c[0x1]!==TEMPLATES_SUBDIR||!c[0x2]['endsWith']('.md'))return null;const d=c[0x2]['slice'](0x0,-'.md'['length']);return BUILTIN_TEMPLATES['find'](e=>e['industry']===c[0x0]&&e['variant']===d)??null;}let seeded=![];function migrateLegacyTemplates(a){const b=resolveLegacyTemplatesDir();if(b===a)return;if(!existsSync(b))return;try{for(const c of readdirSync(b,{'withFileTypes':!![]})){if(!c['isDirectory']())continue;const d=join(b,c['name']),e=join(a,c['name'],TEMPLATES_SUBDIR);for(const g of readdirSync(d,{'withFileTypes':!![]})){if(!g['isFile']()||!g['name']['endsWith']('.md'))continue;const h=join(e,g['name']);if(existsSync(h))continue;mkdirSync(e,{'recursive':!![]}),renameSync(join(d,g['name']),h);}try{rmdirSync(d);}catch{}}try{rmdirSync(b);}catch{}}catch{}}export function seedBuiltinTemplates(){const a=[],b=resolveTemplatesDir();migrateLegacyTemplates(b);for(const c of BUILTIN_TEMPLATES){const d=join(b,c['industry'],TEMPLATES_SUBDIR),e=join(d,c['variant']+'.md'),f=canonicalTemplateContent(c),g={'template':c['id'],'status':'written','path':e};try{if(!existsSync(e))mkdirSync(d,{'recursive':!![]}),writeFileSync(e,renderTemplateFile(c),'utf-8');else{const h=readFileSync(e,'utf-8'),{sentinel:i,content:j}=stripReleaseSentinel(h,TEMPLATE_SENTINEL_KIND);!i?j===f?(writeFileSync(e,renderTemplateFile(c),'utf-8'),g['status']='restamped',g['detail']='body\x20matches\x20canonical\x20but\x20no\x20sentinel\x20present;\x20sentinel\x20header\x20added,\x20body\x20untouched'):(g['status']='skipped_user_file',g['detail']='template\x20file\x20exists\x20without\x20builtin\x20sentinel\x20and\x20body\x20differs\x20from\x20canonical;\x20leaving\x20user\x20file\x20untouched'):j===f?i['version']!==BUILTIN_TEMPLATES_VERSION||releaseBodyHash(j)!==i['hash']?(writeFileSync(e,renderTemplateFile(c),'utf-8'),g['status']='restamped',g['detail']='body\x20matches\x20canonical\x20but\x20sentinel\x20stale/wrong;\x20header\x20refreshed,\x20body\x20untouched'):g['status']='current':(g['status']='skipped_modified',g['detail']='body\x20differs\x20from\x20canonical;\x20not\x20overwritten\x20by\x20seeding\x20—\x20use\x20repair_builtin_templates\x20(preview→confirm)\x20to\x20reseed');}}catch(k){g['status']='error',g['detail']=k['message'];}a['push'](g);}return a;}export function summarizeTemplateDiff(a,b){let c,d;try{c=parseTemplateFile(a);}catch(g){return'on-disk\x20file\x20is\x20not\x20parseable\x20('+g['message']+');\x20full\x20content\x20will\x20be\x20replaced';}try{d=parseTemplateFile(b);}catch{return'canonical\x20render\x20is\x20not\x20parseable\x20(code\x20defect);\x20full\x20content\x20will\x20be\x20replaced';}const e=[],f=new Set([...Object['keys'](c['frontmatter']),...Object['keys'](d['frontmatter'])]);for(const h of[...f]['sort']()){const i=h in c['frontmatter'],j=h in d['frontmatter'];if(i&&!j)e['push']('-'+h);else{if(!i&&j)e['push']('+'+h);else{if(JSON['stringify'](c['frontmatter'][h])!==JSON['stringify'](d['frontmatter'][h]))e['push']('~'+h);}}}return c['body']!==d['body']&&e['push']('~body\x20('+c['body']['split']('\x0a')['length']+'\x20->\x20'+d['body']['split']('\x0a')['length']+'\x20lines)'),e['length']>0x0?e['join'](',\x20'):'whitespace/ordering\x20only';}export function repairBuiltinTemplates(a){const b=[],c=resolveTemplatesDir(),d=a?.['backup']!==![],e=a?.['dryRun']===!![],f=new Set(a?.['includeUserEdited']??[]);for(const g of BUILTIN_TEMPLATES){const h=join(c,g['industry'],TEMPLATES_SUBDIR),i=join(h,g['variant']+'.md');if(!existsSync(i))continue;const j=canonicalTemplateContent(g);let k=null,l='';const m={'template':g['id'],'status':'would_update','path':i};try{const p=stripReleaseSentinel(readFileSync(i,'utf-8'),TEMPLATE_SENTINEL_KIND);k=p['sentinel'],l=p['content'];}catch(q){m['status']='error',m['detail']=q['message'],b['push'](m);continue;}if(l===j)continue;let n;if(k){if(k['version']>BUILTIN_TEMPLATES_VERSION){m['status']='error',m['detail']='newer\x20release\x20on\x20disk\x20(sentinel\x20v'+k['version']+'\x20>\x20running\x20catalog\x20v'+BUILTIN_TEMPLATES_VERSION+')\x20—\x20'+'repair\x20would\x20DOWNGRADE\x20and\x20lose\x20the\x20newer\x20release\x27s\x20content;\x20refused.\x20Upgrade\x20the\x20MCP\x20server\x20instead',b['push'](m);continue;}if(releaseBodyHash(l)!==k['hash']){if(!f['has'](g['id']))continue;n='sentinel-body\x20hash\x20mismatch\x20(sentinel\x20v'+k['version']+'\x20no\x20longer\x20binds\x20the\x20body)\x20'+'reseeded\x20under\x20EXPLICIT\x20include_user_edited\x20authorization';}else n='untouched\x20older\x20release\x20(sentinel\x20v'+k['version']+',\x20current\x20v'+BUILTIN_TEMPLATES_VERSION+')';}else{let r;try{r=String(parseTemplateFile(l)['frontmatter']['id']??'');}catch{continue;}if(r!==g['id'])continue;n='legacy\x20sentinel-less\x20builtin\x20file';}const o=summarizeTemplateDiff(l,j);if(e){m['status']='would_update',m['detail']=n+'\x20would\x20be\x20reseeded\x20from\x20BUILTIN_TEMPLATES\x20('+g['id']+')\x20—\x20diff\x20vs\x20canonical:\x20'+o+(d?';\x20previous\x20body\x20would\x20be\x20saved\x20as\x20<file>.bak':'')+'\x20—\x20execute\x20with\x20authorize=true\x20after\x20the\x20user\x20explicitly\x20confirms',b['push'](m);continue;}try{if(d)copyFileSync(i,i+'.bak');writeFileSync(i,renderTemplateFile(g),'utf-8'),cache['delete'](i),m['status']='updated',m['detail']=n+'\x20reseeded\x20from\x20BUILTIN_TEMPLATES\x20('+g['id']+')\x20—\x20diff\x20was:\x20'+o+(d?';\x20previous\x20body\x20saved\x20as\x20<file>.bak':'');}catch(s){m['status']='error',m['detail']=s['message'];}b['push'](m);}return b;}export function builtinTemplateDrift(a){const b=new Set(a?.['includeUserEdited']??[]),c=[],d=resolveTemplatesDir();for(const e of BUILTIN_TEMPLATES){const f=join(d,e['industry'],TEMPLATES_SUBDIR,e['variant']+'.md');if(!existsSync(f)){c['push']({'template':e['id'],'path':f,'state':'missing','repairable':!![],'detail':'no\x20file\x20on\x20disk;\x20seeding\x20will\x20create\x20it'});continue;}const g=canonicalTemplateContent(e);let h=null,i='';try{const k=stripReleaseSentinel(readFileSync(f,'utf-8'),TEMPLATE_SENTINEL_KIND);h=k['sentinel'],i=k['content'];}catch(l){c['push']({'template':e['id'],'path':f,'state':'modified','repairable':![],'detail':'unreadable:\x20'+l['message']});continue;}if(i===g)continue;const j=summarizeTemplateDiff(i,g);if(!h){let m;try{m=String(parseTemplateFile(i)['frontmatter']['id']??'');}catch{m=undefined;}m===e['id']?c['push']({'template':e['id'],'path':f,'state':'modified','repairable':!![],'detail':'legacy\x20sentinel-less\x20builtin\x20file\x20—\x20seeding\x20never\x20rewrites\x20it\x20and\x20no\x20sentinel\x20proves\x20provenance;\x20repair\x20can\x20reseed\x20—\x20diff\x20vs\x20canonical:\x20'+j}):c['push']({'template':e['id'],'path':f,'state':'modified','repairable':![],'detail':'no\x20release\x20sentinel\x20and\x20id\x20\x27'+(m??'<unparseable>')+'\x27\x20does\x20not\x20match\x20the\x20builtin\x20id\x20—\x20a\x20user\x20file\x20occupies\x20this\x20path;\x20never\x20touched\x20(rename\x20it\x20to\x20free\x20the\x20slot)'});continue;}if(releaseBodyHash(i)===h['hash'])h['version']>BUILTIN_TEMPLATES_VERSION?c['push']({'template':e['id'],'path':f,'state':'modified','repairable':![],'detail':'newer\x20release\x20(sentinel\x20v'+h['version']+'\x20>\x20running\x20catalog\x20v'+BUILTIN_TEMPLATES_VERSION+')\x20—\x20'+'repair\x20would\x20DOWNGRADE\x20and\x20lose\x20the\x20newer\x20release\x27s\x20content;\x20repairable:\x20false.\x20'+'Upgrade\x20the\x20MCP\x20server\x20to\x20match\x20—\x20diff\x20vs\x20canonical:\x20'+j}):c['push']({'template':e['id'],'path':f,'state':'modified','repairable':!![],'detail':'untouched\x20older\x20release\x20(sentinel\x20v'+h['version']+',\x20current\x20v'+BUILTIN_TEMPLATES_VERSION+')\x20—\x20repair\x20can\x20upgrade\x20—\x20diff\x20vs\x20canonical:\x20'+j});else{const n=b['has'](e['id']);c['push']({'template':e['id'],'path':f,'state':'modified','repairable':n,'detail':n?'sentinel-body\x20hash\x20mismatch\x20(sentinel\x20v'+h['version']+'\x20no\x20longer\x20binds\x20the\x20body)\x20—\x20reseedable\x20under\x20the\x20explicit\x20include_user_edited\x20authorization\x20for\x20this\x20id\x20—\x20diff\x20vs\x20canonical:\x20'+j:'user-edited\x20body\x20—\x20kept\x20by\x20design;\x20repair\x20never\x20overwrites\x20user\x20edits\x20—\x20diff\x20vs\x20canonical:\x20'+j});}}return c;}const cache=new Map();export function reloadTemplates(){cache['clear'](),seeded=![];}export function loadAndValidate(a){const b=readFileSync(a,'utf-8');let c;try{c=parseTemplateFile(b);}catch(f){throw new Error('template\x20\x27'+a+'\x27\x20failed\x20to\x20parse:\x20'+f['message']);}const d=TemplateFrontmatterSchema['safeParse'](c['frontmatter']);if(!d['success']){const g=d['error']['issues']['map'](h=>(h['path']['join']('.')||'<root>')+':\x20'+h['message'])['join'](';\x20');throw new Error('template\x20\x27'+a+'\x27\x20failed\x20validation:\x20'+g);}const e=validateAllocatorRows(d['data']);if(e['length']>0x0)throw new Error('template\x20\x27'+a+'\x27\x20failed\x20allocator-row\x20validation:\x20'+e['join'](';\x20'));return{...d['data'],'body':c['body'],'source_path':a};}function templateFilesOnDisk(a){const b=[];if(!existsSync(a))return b;for(const c of readdirSync(a,{'withFileTypes':!![]})){if(!c['isDirectory']())continue;const d=join(a,c['name'],TEMPLATES_SUBDIR);if(!existsSync(d))continue;for(const e of readdirSync(d,{'withFileTypes':!![]})){if(e['isFile']()&&e['name']['endsWith']('.md'))b['push'](join(d,e['name']));}}return b['sort']();}export function listTemplates(){!seeded&&(seedBuiltinTemplates(),seeded=!![]);const a=resolveTemplatesDir(),b=[],c=[],d=new Set();for(const e of templateFilesOnDisk(a)){d['add'](e);try{const f=statSync(e)['mtimeMs'],g=cache['get'](e);if(g&&g['mtimeMs']===f){b['push'](g['template']);continue;}const h=loadAndValidate(e);cache['set'](e,{'mtimeMs':f,'template':h}),b['push'](h);}catch(i){cache['delete'](e),c['push'](i['message']);}}for(const j of[...cache['keys']()]){if(!d['has'](j))cache['delete'](j);}return b['sort']((k,l)=>k['id']['localeCompare'](l['id'])),{'templates':b,'errors':c};}export function getTemplate(a){return listTemplates()['templates']['find'](b=>b['id']===a);}export function getTemplatesByIndustry(a){return listTemplates()['templates']['filter'](b=>b['industry']===a);}
|