@wowok/agent-mcp 2.5.2 → 2.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/dist/customer/index.d.ts +2 -2
  2. package/dist/customer/index.js +1 -1
  3. package/dist/customer/info-puzzle.d.ts +39 -2
  4. package/dist/customer/info-puzzle.js +370 -29
  5. package/dist/customer/risk-assessment.js +51 -14
  6. package/dist/customer/types.d.ts +85 -0
  7. package/dist/index.js +46 -6
  8. package/dist/knowledge/guard-design-patterns.js +104 -1
  9. package/dist/knowledge/guard-ledger.js +3 -3
  10. package/dist/knowledge/guard-lint.js +3 -3
  11. package/dist/knowledge/guard-risk.js +23 -15
  12. package/dist/knowledge/guard-templates.js +174 -2
  13. package/dist/knowledge/guard-translation.js +3 -3
  14. package/dist/knowledge/index.d.ts +3 -0
  15. package/dist/knowledge/index.js +9 -0
  16. package/dist/knowledge/machine-context.d.ts +1 -1
  17. package/dist/knowledge/machine-context.js +21 -0
  18. package/dist/knowledge/machine-ledger.d.ts +1 -0
  19. package/dist/knowledge/machine-ledger.js +60 -37
  20. package/dist/knowledge/machine-risk.js +23 -0
  21. package/dist/knowledge/machine-templates.js +150 -164
  22. package/dist/knowledge/overrides-loader.d.ts +13 -0
  23. package/dist/knowledge/overrides-loader.js +67 -0
  24. package/dist/knowledge/payment-risk.d.ts +4 -0
  25. package/dist/knowledge/payment-risk.js +67 -0
  26. package/dist/knowledge/repository-confirm.d.ts +4 -0
  27. package/dist/knowledge/repository-confirm.js +44 -0
  28. package/dist/knowledge/repository-risk.d.ts +8 -2
  29. package/dist/knowledge/repository-risk.js +61 -0
  30. package/dist/knowledge/repository-translation.js +23 -0
  31. package/dist/knowledge/reward-templates.d.ts +1 -1
  32. package/dist/knowledge/reward-templates.js +77 -5
  33. package/dist/knowledge/scenario-modes.js +22 -5
  34. package/dist/knowledge/service-templates.js +38 -0
  35. package/dist/knowledge/treasury-templates.js +42 -0
  36. package/dist/knowledge/trust-metrics.d.ts +4 -0
  37. package/dist/knowledge/trust-metrics.js +67 -7
  38. package/dist/loop-engineering/context-collect.d.ts +7 -0
  39. package/dist/loop-engineering/context-collect.js +83 -0
  40. package/dist/loop-engineering/improve.d.ts +29 -0
  41. package/dist/loop-engineering/improve.js +178 -0
  42. package/dist/project/context-assembly.d.ts +16 -0
  43. package/dist/project/context-assembly.js +130 -0
  44. package/dist/project/deployment-doc.d.ts +115 -0
  45. package/dist/project/deployment-doc.js +595 -0
  46. package/dist/project/index.js +37 -1
  47. package/dist/project/migration.d.ts +22 -0
  48. package/dist/project/migration.js +125 -0
  49. package/dist/project/project-store.d.ts +110 -0
  50. package/dist/project/project-store.js +425 -0
  51. package/dist/project/rollback-policy.d.ts +45 -0
  52. package/dist/project/rollback-policy.js +290 -0
  53. package/dist/project/stage-gate.d.ts +49 -0
  54. package/dist/project/stage-gate.js +310 -0
  55. package/dist/schema/call/allocation.d.ts +5 -0
  56. package/dist/schema/call/arbitration.d.ts +59 -54
  57. package/dist/schema/call/base.d.ts +3 -0
  58. package/dist/schema/call/base.js +1 -0
  59. package/dist/schema/call/bridge.d.ts +24 -0
  60. package/dist/schema/call/contact.d.ts +5 -0
  61. package/dist/schema/call/demand.d.ts +53 -48
  62. package/dist/schema/call/guard.d.ts +15 -0
  63. package/dist/schema/call/machine.d.ts +10 -0
  64. package/dist/schema/call/order.d.ts +5 -0
  65. package/dist/schema/call/payment.d.ts +5 -0
  66. package/dist/schema/call/permission.d.ts +5 -0
  67. package/dist/schema/call/personal.d.ts +5 -0
  68. package/dist/schema/call/progress.d.ts +5 -0
  69. package/dist/schema/call/proof.d.ts +10 -0
  70. package/dist/schema/call/repository.d.ts +5 -0
  71. package/dist/schema/call/reward.d.ts +5 -0
  72. package/dist/schema/call/service.d.ts +5 -0
  73. package/dist/schema/call/treasury.d.ts +5 -0
  74. package/dist/schema/operations.d.ts +286 -76
  75. package/dist/schema/operations.js +24 -0
  76. package/dist/schema/project/index.d.ts +2633 -120
  77. package/dist/schema/project/index.js +622 -2
  78. package/dist/schema/query/index.d.ts +601 -0
  79. package/dist/schema/query/index.js +61 -0
  80. package/dist/schema/trust/index.d.ts +10 -10
  81. package/dist/schemas/bridge_operation.schema.json +4 -0
  82. package/dist/schemas/guard2file.schema.json +4 -0
  83. package/dist/schemas/index.json +1 -1
  84. package/dist/schemas/machineNode2file.schema.json +4 -0
  85. package/dist/schemas/onchain_operations.schema.json +20 -0
  86. package/dist/schemas/onchain_operations_allocation.schema.json +4 -0
  87. package/dist/schemas/onchain_operations_arbitration.schema.json +4 -0
  88. package/dist/schemas/onchain_operations_contact.schema.json +4 -0
  89. package/dist/schemas/onchain_operations_demand.schema.json +4 -0
  90. package/dist/schemas/onchain_operations_gen_passport.schema.json +8 -0
  91. package/dist/schemas/onchain_operations_gen_proof.schema.json +8 -0
  92. package/dist/schemas/onchain_operations_guard.schema.json +4 -0
  93. package/dist/schemas/onchain_operations_machine.schema.json +4 -0
  94. package/dist/schemas/onchain_operations_order.schema.json +4 -0
  95. package/dist/schemas/onchain_operations_payment.schema.json +4 -0
  96. package/dist/schemas/onchain_operations_permission.schema.json +4 -0
  97. package/dist/schemas/onchain_operations_personal.schema.json +4 -0
  98. package/dist/schemas/onchain_operations_progress.schema.json +4 -0
  99. package/dist/schemas/onchain_operations_proof.schema.json +4 -0
  100. package/dist/schemas/onchain_operations_repository.schema.json +4 -0
  101. package/dist/schemas/onchain_operations_reward.schema.json +4 -0
  102. package/dist/schemas/onchain_operations_service.schema.json +4 -0
  103. package/dist/schemas/onchain_operations_treasury.schema.json +4 -0
  104. package/dist/schemas/project_operation.output.json +1798 -0
  105. package/dist/schemas/project_operation.schema.json +132 -2
  106. package/dist/schemas/query_toolkit.output.json +407 -1
  107. package/dist/schemas/query_toolkit.schema.json +132 -0
  108. package/dist/tools/handlers/project.js +742 -1
  109. package/dist/tools/handlers/query.js +38 -2
  110. package/package.json +2 -2
@@ -4,7 +4,8 @@ export const MACHINE_TEMPLATES = [
4
4
  id: "tpl_machine_ecommerce_standard",
5
5
  scene_id: "ecommerce_standard",
6
6
  name: "Standard E-commerce Flow",
7
- description: "Linear e-commerce workflow: Order -> Pay -> Ship -> Receive -> Complete. " +
7
+ description: "Linear e-commerce workflow: Paid (entry) -> Ship -> Receive -> Complete. " +
8
+ "Payment is handled by Service.buy() atomically; Machine starts at post-payment state. " +
8
9
  "Funds auto-allocated to merchant at Complete node. Recommended baseline for new merchants.",
9
10
  recommended_patterns: ["P-M-SEQ"],
10
11
  recommended_topology: ["P-M-LINEAR"],
@@ -31,13 +32,6 @@ export const MACHINE_TEMPLATES = [
31
32
  default: "Receive",
32
33
  description: "Forward name for customer receipt confirmation",
33
34
  },
34
- {
35
- name: "pay_guard_name",
36
- type: "guard_ref",
37
- required: true,
38
- description: "Guard name verifying payment completion on Ship forward",
39
- constraint: "Must be CREATE-only Guard; use tpl_buy_guard_whitelist pattern",
40
- },
41
35
  {
42
36
  name: "complete_node_name",
43
37
  type: "string",
@@ -47,8 +41,7 @@ export const MACHINE_TEMPLATES = [
47
41
  },
48
42
  ],
49
43
  example_nodes: [
50
- { name: "OrderCreated", description: "Order placed, awaiting payment" },
51
- { name: "Paid", description: "Payment confirmed, awaiting shipment" },
44
+ { name: "Paid", description: "Entry: order created and paid via Service.buy(); Machine starts here" },
52
45
  { name: "Shipped", description: "Goods dispatched" },
53
46
  { name: "Received", description: "Customer confirmed receipt" },
54
47
  { name: "${complete_node_name}", description: "Terminal: triggers allocation" },
@@ -56,24 +49,10 @@ export const MACHINE_TEMPLATES = [
56
49
  example_pairs: [
57
50
  {
58
51
  prev_node: "",
59
- next_node: "OrderCreated",
60
- threshold: 1,
61
- forwards: [
62
- { name: "Enter", weight: 1, named_operator: "", permission_index: 0 },
63
- ],
64
- },
65
- {
66
- prev_node: "OrderCreated",
67
52
  next_node: "Paid",
68
53
  threshold: 1,
69
54
  forwards: [
70
- {
71
- name: "Pay",
72
- weight: 1,
73
- named_operator: "",
74
- permission_index: 0,
75
- guard: "${pay_guard_name}",
76
- },
55
+ { name: "Enter", weight: 1, named_operator: "", permission_index: 0 },
77
56
  ],
78
57
  },
79
58
  {
@@ -106,13 +85,7 @@ export const MACHINE_TEMPLATES = [
106
85
  ],
107
86
  },
108
87
  ],
109
- required_guards: [
110
- {
111
- guard_template_id: "tpl_buy_guard_whitelist",
112
- bound_to_forward: "Pay",
113
- purpose: "Verify payment completion",
114
- },
115
- ],
88
+ required_guards: [],
116
89
  required_permissions: [
117
90
  { index: 2, name: "merchant", description: "Merchant role for Ship + Finish" },
118
91
  { index: 3, name: "admin", description: "Admin override (optional)" },
@@ -129,16 +102,16 @@ export const MACHINE_TEMPLATES = [
129
102
  relevant_risks: ["R-M1-01", "R-M1-02", "R-M1-08", "R-M2-01", "R-M3-02", "R-M4-01"],
130
103
  creation_notes: [
131
104
  "Build order: Permission -> Machine (unpublished) -> Guards -> Bind guards -> Publish -> Bind to Service",
132
- "Pay forward's Guard must verify order.amount is fully paid — use query 1563 (order.service) cross-check",
133
- "Entry point: prev_node='' (empty string) — at least one Pair must exist with empty prev_node",
105
+ "First node 'Paid' represents post-payment state — Service.buy() completes payment atomically before Progress is created",
106
+ "No separate 'Order' or 'Pay' nodes needed — payment is handled by Service.buy(), not Machine",
107
+ "Entry point: prev_node='' (empty string) targets 'Paid' — at least one Pair must exist with empty prev_node",
134
108
  "If using P16 circular reference for Service, use name not address (Service not yet published)",
135
109
  ],
136
110
  example_use_case: "Small e-commerce shop selling camera accessories. Linear flow with no exceptions. " +
137
111
  "Funds allocated to merchant personal address on Complete.",
138
112
  publish_checklist: [
139
- "All 5 nodes have at least one outgoing Forward (except terminal)",
140
- "Entry Pair exists (prev_node='')",
141
- "Pay forward Guard created and tested via gen_passport",
113
+ "All 4 nodes have at least one outgoing Forward (except terminal)",
114
+ "Entry Pair exists (prev_node='' targets 'Paid')",
142
115
  "permissionIndex values match Permission object indices",
143
116
  "Test Progress run on testnet",
144
117
  "machineNode2file export as backup",
@@ -148,7 +121,8 @@ export const MACHINE_TEMPLATES = [
148
121
  id: "tpl_machine_ecommerce_exceptions",
149
122
  scene_id: "ecommerce_with_exceptions",
150
123
  name: "E-commerce Flow with Exception Branches",
151
- description: "Multi-path workflow: Pay -> Ship -> Receive/Lost/Return. Lost uses dual-sig (threshold=2). " +
124
+ description: "Multi-path workflow: Paid (entry) -> Ship -> Receive/Lost/Return. Lost uses dual-sig (threshold=2). " +
125
+ "Payment is handled by Service.buy() atomically; Machine starts at post-payment state. " +
152
126
  "Return path opens Refund -> Complete. Competing pairs first-wins.",
153
127
  recommended_patterns: ["P-M-SEQ", "P-M-COMPETING"],
154
128
  recommended_topology: ["P-M-LINEAR", "P-M-COMPETING"],
@@ -190,8 +164,7 @@ export const MACHINE_TEMPLATES = [
190
164
  },
191
165
  ],
192
166
  example_nodes: [
193
- { name: "OrderCreated" },
194
- { name: "Paid" },
167
+ { name: "Paid", description: "Entry: order created and paid via Service.buy(); Machine starts here" },
195
168
  { name: "Shipped" },
196
169
  { name: "Received" },
197
170
  { name: "Lost" },
@@ -202,15 +175,9 @@ export const MACHINE_TEMPLATES = [
202
175
  example_pairs: [
203
176
  {
204
177
  prev_node: "",
205
- next_node: "OrderCreated",
206
- threshold: 1,
207
- forwards: [{ name: "Enter", weight: 1, named_operator: "" }],
208
- },
209
- {
210
- prev_node: "OrderCreated",
211
178
  next_node: "Paid",
212
179
  threshold: 1,
213
- forwards: [{ name: "Pay", weight: 1, named_operator: "" }],
180
+ forwards: [{ name: "Enter", weight: 1, named_operator: "" }],
214
181
  },
215
182
  {
216
183
  prev_node: "Paid",
@@ -267,11 +234,6 @@ export const MACHINE_TEMPLATES = [
267
234
  },
268
235
  ],
269
236
  required_guards: [
270
- {
271
- guard_template_id: "tpl_forward_node_check",
272
- bound_to_forward: "Pay",
273
- purpose: "Verify payment completion",
274
- },
275
237
  {
276
238
  guard_template_id: "tpl_forward_node_check",
277
239
  bound_to_forward: "MerchantConfirm",
@@ -311,6 +273,8 @@ export const MACHINE_TEMPLATES = [
311
273
  "R-M3-02", "R-M3-04", "R-M3-05", "R-M4-01", "R-M5-03",
312
274
  ],
313
275
  creation_notes: [
276
+ "First node 'Paid' represents post-payment state — Service.buy() completes payment atomically before Progress is created",
277
+ "No separate 'Order' or 'Pay' nodes needed — payment is handled by Service.buy(), not Machine",
314
278
  "Competing Pairs (Shipped -> Received/Lost/Return) are mutually exclusive — first threshold met wins",
315
279
  "Lost node threshold=2 means BOTH customer and merchant Forwards must execute",
316
280
  "TimeGuard must use context(Clock) >= progress.entry_time + duration",
@@ -331,7 +295,8 @@ export const MACHINE_TEMPLATES = [
331
295
  id: "tpl_machine_rental",
332
296
  scene_id: "rental_standard",
333
297
  name: "Equipment Rental Flow",
334
- description: "Rental flow: Reserve -> Pay Deposit -> Pickup -> In Use -> Return -> Refund Deposit. " +
298
+ description: "Rental flow: DepositPaid (entry) -> Pickup -> In Use -> Return -> Refund Deposit. " +
299
+ "Payment is handled by Service.buy() atomically; Machine starts at post-deposit state. " +
335
300
  "Separates deposit from rental fee (two Allocators). Damage report via retained_submission.",
336
301
  recommended_patterns: ["P-M-SEQ"],
337
302
  recommended_topology: ["P-M-LINEAR"],
@@ -360,8 +325,7 @@ export const MACHINE_TEMPLATES = [
360
325
  },
361
326
  ],
362
327
  example_nodes: [
363
- { name: "Reserved" },
364
- { name: "DepositPaid" },
328
+ { name: "DepositPaid", description: "Entry: deposit paid via Service.buy(); Machine starts here" },
365
329
  { name: "PickedUp" },
366
330
  { name: "InUse" },
367
331
  { name: "Return" },
@@ -372,17 +336,9 @@ export const MACHINE_TEMPLATES = [
372
336
  example_pairs: [
373
337
  {
374
338
  prev_node: "",
375
- next_node: "Reserved",
376
- threshold: 1,
377
- forwards: [{ name: "Reserve", weight: 1, named_operator: "" }],
378
- },
379
- {
380
- prev_node: "Reserved",
381
339
  next_node: "DepositPaid",
382
340
  threshold: 1,
383
- forwards: [
384
- { name: "PayDeposit", weight: 1, named_operator: "", guard: "deposit_guard" },
385
- ],
341
+ forwards: [{ name: "Enter", weight: 1, named_operator: "" }],
386
342
  },
387
343
  {
388
344
  prev_node: "DepositPaid",
@@ -435,11 +391,6 @@ export const MACHINE_TEMPLATES = [
435
391
  },
436
392
  ],
437
393
  required_guards: [
438
- {
439
- guard_template_id: "tpl_allocator_threshold",
440
- bound_to_forward: "PayDeposit",
441
- purpose: "Verify deposit amount >= required amount",
442
- },
443
394
  {
444
395
  guard_template_id: "tpl_forward_privacy_delivery_proof",
445
396
  bound_to_forward: "Inspect",
@@ -473,9 +424,10 @@ export const MACHINE_TEMPLATES = [
473
424
  "R-M4-01", "R-M5-02",
474
425
  ],
475
426
  creation_notes: [
427
+ "First node 'DepositPaid' represents post-payment state — Service.buy() completes deposit payment atomically before Progress is created",
428
+ "No separate 'Reserve' or 'PayDeposit' nodes needed — reservation and payment are handled by Service.buy(), not Machine",
476
429
  "Damage report uses retained_submission — values stored uniquely by (current_node, next_node, forward_name)",
477
430
  "Two competing Pairs at Return node: DamageCheck vs Complete (clean return)",
478
- "Deposit Guard must verify amount via order.amount query, not hardcoded value",
479
431
  "DamageDeduction Allocation uses sharing.who=Entity (merchant), not OrderHolder",
480
432
  ],
481
433
  example_use_case: "Camera equipment rental: customer pays 1000 WOW deposit, returns equipment, " +
@@ -860,7 +812,7 @@ export const MACHINE_TEMPLATES = [
860
812
  },
861
813
  ],
862
814
  example_nodes: [
863
- { name: "OrderCreated" },
815
+ { name: "Paid", description: "Entry: order created and paid via Service.buy(); Machine starts here" },
864
816
  { name: "${proof_node_name}", description: "Customer submits Proof via Messenger" },
865
817
  { name: "${delivery_node_name}" },
866
818
  { name: "Complete" },
@@ -868,12 +820,12 @@ export const MACHINE_TEMPLATES = [
868
820
  example_pairs: [
869
821
  {
870
822
  prev_node: "",
871
- next_node: "OrderCreated",
823
+ next_node: "Paid",
872
824
  threshold: 1,
873
825
  forwards: [{ name: "Enter", weight: 1, named_operator: "" }],
874
826
  },
875
827
  {
876
- prev_node: "OrderCreated",
828
+ prev_node: "Paid",
877
829
  next_node: "${proof_node_name}",
878
830
  threshold: 1,
879
831
  forwards: [
@@ -1041,142 +993,174 @@ export const MACHINE_TEMPLATES = [
1041
993
  ],
1042
994
  },
1043
995
  {
1044
- id: "tpl_machine_arbitration",
1045
- scene_id: "arbitration_flow",
1046
- name: "Arbitration Flow",
1047
- description: "Dispute -> Submit -> Vote -> Ruling -> Execute. Uses arbitration_usage_guard + arbitration_voting_guard. " +
1048
- "MAX_DISPUTE_COUNT=10 per order. Dual-vote prevention mandatory.",
1049
- recommended_patterns: ["P-M-VOTE", "P-M-SEQ"],
1050
- recommended_topology: ["P-M-LINEAR"],
996
+ id: "tpl_machine_wonder_feedback",
997
+ scene_id: "wonder_feedback",
998
+ name: "Wonder Feedback Flow (Post-Completion Rating)",
999
+ description: "Post-completion rating flow: Paid (entry) → Shipped → Received → Completed → {Wonder | NoWonder}. " +
1000
+ "After the order reaches 'Completed' (terminal business state, funds already allocated to merchant), " +
1001
+ "the OrderHolder (namedOperator='') can advance Progress to 'wonder' (positive review) or 'no_wonder' " +
1002
+ "(negative review). A bound Reward object's claim_guard verifies Progress.current == 'wonder' before " +
1003
+ "paying out — reward claim needs NO Permission. Dispute is NEVER modeled here: it flows through " +
1004
+ "Order → Arbitration.dispute() → Arb → arbitration() ruling → arb_withdraw, fully off-Machine.",
1005
+ recommended_patterns: ["P-M-SEQ", "P-M-COMPETING"],
1006
+ recommended_topology: ["P-M-LINEAR", "P-M-COMPETING"],
1051
1007
  parameters: [
1052
1008
  {
1053
- name: "arbitration_ref",
1054
- type: "arbitration_ref",
1009
+ name: "merchant_permission",
1010
+ type: "permission_ref",
1055
1011
  required: true,
1056
- description: "Arbitration object address",
1012
+ description: "Merchant Permission object (index 2 = merchant, index 3 = admin)",
1057
1013
  },
1058
1014
  {
1059
- name: "max_disputes",
1060
- type: "number",
1015
+ name: "wonder_node_name",
1016
+ type: "string",
1061
1017
  required: true,
1062
- default: "10",
1063
- description: "Hard limit: MAX_DISPUTE_COUNT=10 per order",
1018
+ default: "wonder",
1019
+ description: "Node name for positive feedback (好评) terminal",
1020
+ constraint: "Must match /^(wonder|praise|thumbs_up)$/i OR be a custom name; must NOT match dispute anti-pattern regex",
1064
1021
  },
1065
1022
  {
1066
- name: "voting_threshold",
1067
- type: "number",
1023
+ name: "no_wonder_node_name",
1024
+ type: "string",
1068
1025
  required: true,
1069
- default: "100",
1070
- description: "Weight threshold required for a voting decision to pass",
1026
+ default: "no_wonder",
1027
+ description: "Node name for negative feedback (差评) terminal",
1028
+ constraint: "Must match /^(no_wonder|complain|thumbs_down)$/i OR be a custom name; must NOT match dispute anti-pattern regex",
1029
+ },
1030
+ {
1031
+ name: "reward_ref",
1032
+ type: "reward_ref",
1033
+ required: false,
1034
+ description: "Reward object address (optional). If bound, its claim_guard should verify Progress.current == wonder_node_name AND order.holder == signer. Use wonder_praise or wonder_feedback reward template.",
1035
+ },
1036
+ {
1037
+ name: "rating_time_limit_days",
1038
+ type: "number",
1039
+ required: false,
1040
+ default: "30",
1041
+ description: "Days after completion during which the customer can rate (enforced by Guard on Praise/Complain forwards via context(Clock))",
1042
+ constraint: "Must be > 0; reasonable range 7-90",
1071
1043
  },
1072
1044
  ],
1073
1045
  example_nodes: [
1074
- { name: "DisputeOpened" },
1075
- { name: "EvidenceSubmitted" },
1076
- { name: "Voting" },
1077
- { name: "Ruling" },
1078
- { name: "Executed" },
1046
+ { name: "Paid", description: "Entry: order created and paid via Service.buy(); Machine starts here" },
1047
+ { name: "Shipped", description: "Merchant dispatched goods/service" },
1048
+ { name: "Received", description: "Customer confirmed receipt" },
1049
+ { name: "Completed", description: "Terminal business state — triggers merchant Allocation. Funds settled." },
1050
+ { name: "${wonder_node_name}", description: "Positive feedback terminal (好评). OrderHolder-only. Reward-eligible." },
1051
+ { name: "${no_wonder_node_name}", description: "Negative feedback terminal (差评). OrderHolder-only. Optional Repository write for analytics." },
1079
1052
  ],
1080
1053
  example_pairs: [
1081
1054
  {
1082
1055
  prev_node: "",
1083
- next_node: "DisputeOpened",
1056
+ next_node: "Paid",
1084
1057
  threshold: 1,
1085
- forwards: [
1086
- {
1087
- name: "OpenDispute",
1088
- weight: 1,
1089
- named_operator: "",
1090
- guard: "arb_usage_guard",
1091
- retained_submission: "dispute_record",
1092
- },
1093
- ],
1058
+ forwards: [{ name: "Enter", weight: 1, named_operator: "" }],
1094
1059
  },
1095
1060
  {
1096
- prev_node: "DisputeOpened",
1097
- next_node: "EvidenceSubmitted",
1061
+ prev_node: "Paid",
1062
+ next_node: "Shipped",
1098
1063
  threshold: 1,
1099
- forwards: [{ name: "SubmitEvidence", weight: 1, named_operator: "" }],
1064
+ forwards: [{ name: "Ship", weight: 1, permission_index: 2, named_operator: "" }],
1100
1065
  },
1101
1066
  {
1102
- prev_node: "EvidenceSubmitted",
1103
- next_node: "Voting",
1067
+ prev_node: "Shipped",
1068
+ next_node: "Received",
1104
1069
  threshold: 1,
1105
- forwards: [{ name: "StartVote", weight: 1, permission_index: 3 }],
1070
+ forwards: [{ name: "ConfirmReceive", weight: 1, named_operator: "" }],
1106
1071
  },
1107
1072
  {
1108
- prev_node: "Voting",
1109
- next_node: "Ruling",
1110
- threshold: "${voting_threshold}",
1073
+ prev_node: "Received",
1074
+ next_node: "Completed",
1075
+ threshold: 1,
1076
+ forwards: [{ name: "Finish", weight: 1, permission_index: 2, named_operator: "" }],
1077
+ },
1078
+ {
1079
+ prev_node: "Completed",
1080
+ next_node: "${wonder_node_name}",
1081
+ threshold: 1,
1111
1082
  forwards: [
1112
1083
  {
1113
- name: "ChiefVote",
1114
- weight: 60,
1115
- permission_index: 2,
1116
- guard: "arb_voting_guard",
1117
- },
1118
- {
1119
- name: "MemberVote",
1120
- weight: 8,
1121
- named_operator: "arbitrator",
1122
- guard: "arb_voting_guard",
1084
+ name: "Praise",
1085
+ weight: 1,
1086
+ named_operator: "",
1087
+ guard: "rating_window_guard",
1088
+ retained_submission: "rating_record",
1123
1089
  },
1124
1090
  ],
1125
1091
  },
1126
1092
  {
1127
- prev_node: "Ruling",
1128
- next_node: "Executed",
1093
+ prev_node: "Completed",
1094
+ next_node: "${no_wonder_node_name}",
1129
1095
  threshold: 1,
1130
- forwards: [{ name: "Execute", weight: 1, permission_index: 3 }],
1096
+ forwards: [
1097
+ {
1098
+ name: "Complain",
1099
+ weight: 1,
1100
+ named_operator: "",
1101
+ guard: "rating_window_guard",
1102
+ retained_submission: "rating_record",
1103
+ },
1104
+ ],
1131
1105
  },
1132
1106
  ],
1133
1107
  required_guards: [
1134
1108
  {
1135
- guard_template_id: "tpl_usage_guard_threshold",
1136
- bound_to_forward: "OpenDispute",
1137
- purpose: "Verify dispute count < MAX_DISPUTE_COUNT (10)",
1138
- },
1139
- {
1140
- guard_template_id: "tpl_voting_guard_numeric_weight",
1141
- bound_to_forward: "ChiefVote",
1142
- purpose: "Verify voting eligibility + weight extraction",
1109
+ guard_template_id: "tpl_forward_node_check",
1110
+ bound_to_forward: "Praise",
1111
+ purpose: "Verify Progress.current == 'Completed' (rating only allowed after completion) AND context(Clock) <= progress.entry_time + rating_time_limit_days",
1143
1112
  },
1144
1113
  {
1145
- guard_template_id: "tpl_voting_guard_numeric_weight",
1146
- bound_to_forward: "MemberVote",
1147
- purpose: "Verify voting eligibility + prevent double-vote (R-X1-14 CRITICAL)",
1114
+ guard_template_id: "tpl_forward_node_check",
1115
+ bound_to_forward: "Complain",
1116
+ purpose: "Verify Progress.current == 'Completed' (rating only allowed after completion) AND context(Clock) <= progress.entry_time + rating_time_limit_days",
1148
1117
  },
1149
1118
  ],
1150
1119
  required_permissions: [
1151
- { index: 2, name: "chief_arbitrator", description: "High-weight voter" },
1152
- { index: 3, name: "admin", description: "Vote starter / executor" },
1120
+ { index: 2, name: "merchant", description: "Merchant role for Ship + Finish (NOT for rating — rating is OrderHolder-only via named_operator='')" },
1121
+ { index: 3, name: "admin", description: "Admin override (optional)" },
1153
1122
  ],
1154
1123
  required_allocators: [
1155
1124
  {
1156
- name: "RulingAllocation",
1157
- trigger_node: "Executed",
1158
- description: "Allocation based on ruling outcome",
1125
+ name: "MerchantAllocation",
1126
+ trigger_node: "Completed",
1127
+ description: "100% to merchant Treasury or personal address. Fires at Completion — NOT at Wonder/NoWonder (those are reputation-only terminals with no fund flow).",
1159
1128
  },
1160
1129
  ],
1161
- forkable_fields: ["voting_threshold", "voter_count", "evidence_steps"],
1162
- applicable_industries: ["arbitration", "ecommerce", "service", "rental"],
1130
+ forkable_fields: ["wonder_node_name", "no_wonder_node_name", "rating_time_limit_days", "additional_rating_nodes"],
1131
+ applicable_industries: ["ecommerce", "service", "rental", "subscription", "education"],
1163
1132
  relevant_risks: [
1164
- "R-M1-08", "R-M2-05", "R-M3-04", "R-M5-04",
1165
- "R-X1-14",
1133
+ "R-M1-01", "R-M1-02", "R-M1-08", "R-M1-11",
1134
+ "R-M2-01", "R-M2-05",
1135
+ "R-M3-02", "R-M3-04",
1136
+ "R-M4-01", "R-M5-03",
1166
1137
  ],
1167
1138
  creation_notes: [
1168
- "Arbitration object MUST be created before this Machine",
1169
- "Anti-double-dispute: query arb.dispute_count < 10 (R-X1-14 HIGH)",
1170
- "Anti-double-vote: query arb.voted has [Signer] (R-X1-14 CRITICAL)",
1171
- "MAX_DISPUTE_COUNT=10 hard limit per order (on-chain constant)",
1172
- ],
1173
- example_use_case: "E-commerce dispute: customer claims item not as described. Arbitration panel (1 chief + 3 members) " +
1174
- "votes to rule. Up to 10 disputes per order allowed.",
1139
+ "DISPUTE INDEPENDENCE: This Machine MUST NOT contain 'disputed', 'refunded', 'arb', 'arbitration' nodes (R-M1-11 critical). Disputes are filed off-Machine via arbitration::dispute(order, arbitration).",
1140
+ "Build order: Permission → Machine (unpublished) → Guards → Bind guards → Publish → Bind to Service → Bind Reward (optional)",
1141
+ "First node 'Paid' represents post-payment state — Service.buy() completes payment atomically before Progress is created",
1142
+ "No separate 'Order' or 'Pay' nodes needed — payment is handled by Service.buy(), not Machine",
1143
+ "Wonder/NoWonder forwards have named_operator='' (empty) — this delegates to the OrderHolder (customer). No Permission index needed for rating.",
1144
+ "Completed node triggers MerchantAllocation — funds are settled BEFORE the rating window opens. Rating does NOT affect fund flow.",
1145
+ "Competing Pair: Praise vs Complain (first-wins) — one rating per order, enforced by Guard + retained_submission audit trail.",
1146
+ "Reward object (if bound) is INDEPENDENT of Allocator: Reward.claim() requires Guard+passport, not Permission. Guard checks Progress.current == 'wonder' AND order.holder == signer.",
1147
+ "rating_window_guard enforces time limit: context(Clock) <= progress.entry_time + rating_time_limit_days. After window closes, no rating possible (Completed becomes true terminal).",
1148
+ "Optional: bind a Repository to record feedback node for analytics. Repository write happens via Guard's data extraction (NOT auto-passed — see 06 §14.4).",
1149
+ ],
1150
+ example_use_case: "Photography service: Paid → Shipped (booking confirmed) → Received (session delivered) → Completed " +
1151
+ "(photos delivered, funds released to photographer) → customer advances to 'wonder' (loved the work) " +
1152
+ "or 'no_wonder' (didn't love it). Bound Reward pays 1 WOW to customers who advance to 'wonder'. " +
1153
+ "Merchant's wonder/no_wonder ratio becomes an on-chain reputation signal. Disputes (if any) are " +
1154
+ "filed separately via Arbitration object — never enter this Machine.",
1175
1155
  publish_checklist: [
1176
- "Arbitration object created and tested",
1177
- "Both anti-double Guards tested (dispute + vote)",
1178
- "Voting threshold verified with different weight distributions",
1179
- "MAX_DISPUTE_COUNT boundary tested (10th dispute OK, 11th fails)",
1156
+ "All 6 nodes verified: no 'disputed'/'refunded'/'arb'/'arbitration' names (R-M1-11 PASS)",
1157
+ "Entry Pair exists (prev_node='' targets 'Paid')",
1158
+ "Competing Pair tested: Praise vs Complain — first-wins semantics verified on testnet",
1159
+ "rating_window_guard tested: rating blocked after time limit expires",
1160
+ "MerchantAllocation fires ONLY at Completed (NOT at Wonder/NoWonder)",
1161
+ "Reward object (if bound): claim_guard tested — Progress.current == 'wonder' required, claim fails at 'no_wonder' or 'Completed'",
1162
+ "named_operator='' on Praise/Complain forwards verified (OrderHolder-only operation)",
1163
+ "machineNode2file export as backup",
1180
1164
  ],
1181
1165
  },
1182
1166
  {
@@ -1204,7 +1188,7 @@ export const MACHINE_TEMPLATES = [
1204
1188
  },
1205
1189
  ],
1206
1190
  example_nodes: [
1207
- { name: "Subscribed" },
1191
+ { name: "Paid", description: "Entry: subscription created and paid via Service.buy(); Machine starts here" },
1208
1192
  { name: "Active" },
1209
1193
  { name: "RenewEligible" },
1210
1194
  { name: "Renewed" },
@@ -1215,12 +1199,12 @@ export const MACHINE_TEMPLATES = [
1215
1199
  example_pairs: [
1216
1200
  {
1217
1201
  prev_node: "",
1218
- next_node: "Subscribed",
1202
+ next_node: "Paid",
1219
1203
  threshold: 1,
1220
- forwards: [{ name: "Subscribe", weight: 1, named_operator: "" }],
1204
+ forwards: [{ name: "Enter", weight: 1, named_operator: "" }],
1221
1205
  },
1222
1206
  {
1223
- prev_node: "Subscribed",
1207
+ prev_node: "Paid",
1224
1208
  next_node: "Active",
1225
1209
  threshold: 1,
1226
1210
  forwards: [
@@ -1324,6 +1308,8 @@ export const MACHINE_TEMPLATES = [
1324
1308
  "R-M3-02", "R-M3-04", "R-M4-01", "R-M5-04",
1325
1309
  ],
1326
1310
  creation_notes: [
1311
+ "First node 'Paid' represents post-payment state — Service.buy() completes subscription payment atomically before Progress is created",
1312
+ "No separate 'Subscribe' or 'Pay' nodes needed — subscription and payment are handled by Service.buy(), not Machine",
1327
1313
  "Time-lock uses context(Clock) — verify Clock address in Guard table",
1328
1314
  "Competing Pair: Renew vs Expire vs Cancel — first-wins",
1329
1315
  "Renewed node loops back to Active (recurring subscription)",
@@ -1337,7 +1323,7 @@ export const MACHINE_TEMPLATES = [
1337
1323
  "Time-lock Guards tested on testnet (both TimeUnlock + AutoExpire)",
1338
1324
  "Competing Pair semantics verified (Renew vs Expire vs Cancel)",
1339
1325
  "Repository write tested (subscription status queryable)",
1340
- "Renewal loop tested: Subscribed -> Active -> RenewEligible -> Renewed -> Active",
1326
+ "Renewal loop tested: Paid -> Active -> RenewEligible -> Renewed -> Active",
1341
1327
  ],
1342
1328
  },
1343
1329
  ];
@@ -0,0 +1,13 @@
1
+ import type { OverrideCategory } from "../loop-engineering/improve.js";
2
+ export interface OverrideConfig {
3
+ "risk-thresholds"?: Record<string, unknown>;
4
+ "descriptions"?: Record<string, unknown>;
5
+ "industry-profiles"?: Record<string, unknown>;
6
+ "scenario-defaults"?: Record<string, unknown>;
7
+ "recovery-priorities"?: Record<string, unknown>;
8
+ }
9
+ export declare function loadOverrides(forceReload?: boolean): OverrideConfig;
10
+ export declare function getOverride(category: OverrideCategory): Record<string, unknown> | undefined;
11
+ export declare function clearOverrideCache(): void;
12
+ export declare function listOverrideFiles(): string[];
13
+ export declare function getOverridesDirPath(): string;
@@ -0,0 +1,67 @@
1
+ import { readFileSync, existsSync, readdirSync } from "fs";
2
+ import { join } from "path";
3
+ import { homedir } from "os";
4
+ function wowokRootDir() {
5
+ return process.env.WOWOK_CONFIG_DIR
6
+ ? process.env.WOWOK_CONFIG_DIR
7
+ : join(homedir(), ".wowok");
8
+ }
9
+ function overridesDir() {
10
+ return join(wowokRootDir(), "overrides");
11
+ }
12
+ let overrideCache;
13
+ export function loadOverrides(forceReload = false) {
14
+ if (overrideCache && !forceReload)
15
+ return overrideCache;
16
+ const config = {};
17
+ const dir = overridesDir();
18
+ if (!existsSync(dir)) {
19
+ overrideCache = config;
20
+ return config;
21
+ }
22
+ const categories = [
23
+ "risk-thresholds",
24
+ "descriptions",
25
+ "industry-profiles",
26
+ "scenario-defaults",
27
+ "recovery-priorities",
28
+ ];
29
+ for (const cat of categories) {
30
+ const filePath = join(dir, `${cat}.json`);
31
+ if (!existsSync(filePath))
32
+ continue;
33
+ try {
34
+ const raw = readFileSync(filePath, "utf-8");
35
+ const parsed = JSON.parse(raw);
36
+ const { _last_applied_proposal, _last_applied_at, ...userFields } = parsed;
37
+ void _last_applied_proposal;
38
+ void _last_applied_at;
39
+ config[cat] = userFields;
40
+ }
41
+ catch {
42
+ }
43
+ }
44
+ overrideCache = config;
45
+ return config;
46
+ }
47
+ export function getOverride(category) {
48
+ const config = loadOverrides();
49
+ return config[category];
50
+ }
51
+ export function clearOverrideCache() {
52
+ overrideCache = undefined;
53
+ }
54
+ export function listOverrideFiles() {
55
+ const dir = overridesDir();
56
+ if (!existsSync(dir))
57
+ return [];
58
+ try {
59
+ return readdirSync(dir).filter((f) => f.endsWith(".json"));
60
+ }
61
+ catch {
62
+ return [];
63
+ }
64
+ }
65
+ export function getOverridesDirPath() {
66
+ return overridesDir();
67
+ }
@@ -23,6 +23,10 @@ export interface PaymentRiskCheckContext {
23
23
  uses_signer_for_provenance?: boolean;
24
24
  coin_field_lint_reviewed?: boolean;
25
25
  constants_synced?: boolean;
26
+ uses_scene_binding?: boolean;
27
+ has_for_object?: boolean;
28
+ has_for_guard?: boolean;
29
+ has_index?: boolean;
26
30
  }
27
31
  export declare const PAYMENT_RISK_RULES: {
28
32
  rule: PaymentRisk;