@wowok/skills 1.1.13 → 1.2.1

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.
@@ -6,6 +6,24 @@ An advanced e-commerce example demonstrating escrow with multiple order fund all
6
6
 
7
7
  ***
8
8
 
9
+ ## ⚠️ Running Principle
10
+
11
+ > **Run the example in full every time (repeatable).** This example uses `replaceExistName: true` on all object creations — each run generates new objects with new addresses. If you skip build steps, operations may silently act on orphaned objects from previous runs, producing incorrect results. Old objects' configurations do not reflect the current document version.
12
+
13
+ - **Execution order**: Part 1 (read) → Part 2 Steps 1–14 (build all) → Part 3 (customer flow) → Part 4 (fund allocation). Do not skip steps — each depends on objects created by prior steps.
14
+ - **Prerequisites**: `myshop_merchant` ≥ 0.05 WOW (gas), `myshop_customer` ≥ 0.15 WOW (gas + order payment). All on-chain operations require `env.confirmed: true`.
15
+
16
+ ### 🔐 Two-Step Confirmation Flow (Production Safety)
17
+
18
+ This example sets `env.confirmed: true` on irreversible operations (e.g., `publish: true` on Machine) for brevity. In real deployments, follow the two-step flow enforced by the ConfirmGate safety layer:
19
+
20
+ 1. **Phase 1 — Preview**: Call the tool **without** `env.confirmed`. The server returns `{ status: "pending_confirmation", confirmation_text: "..." }` containing the full operation summary, risk assessment, and irreversible-action warnings.
21
+ 2. **Phase 2 — Confirm**: Review `confirmation_text` with the user. Only after explicit user approval, call the tool again **with** `env.confirmed: true` to actually execute the on-chain transaction.
22
+
23
+ > Skipping Phase 1 means the user never sees the risk summary before gas is spent. Always preview first, then confirm.
24
+
25
+ ***
26
+
9
27
  ## Core Requirements & Features
10
28
 
11
29
  | Requirement | Description | Implementation |
@@ -23,7 +41,7 @@ An advanced e-commerce example demonstrating escrow with multiple order fund all
23
41
  2. **Privacy-Preserving Logistics**: Merchant handles logistics independently using any logistics provider. Tracking numbers are shared privately via Messenger (not on-chain), with only Merkle Root submitted on-chain as proof of communication
24
42
  3. **Reward Incentive Model**: Additional reward pool for excellent service (Wonderful reward) and compensation for lost packages
25
43
  4. **Multi-Path Workflow**: Order can complete through normal delivery, wonderful rating, or various return paths
26
- 5. **Dual-Signature Returns**: Return processes require both customer and merchant confirmation (threshold=2)
44
+ 5. **Dual-Signature Returns**: Receipt return processes require both customer and merchant confirmation (threshold=2). Non-receipt returns (customer never received goods) require only merchant confirmation of goods recovery (threshold=1), since the customer has nothing to return and their non-receipt was already confirmed when entering the Non-receipt Return node.
27
45
 
28
46
  ### Important Design Principle: "Who Completes the Key Action, Who Submits the Proof"
29
47
 
@@ -43,7 +61,7 @@ This advanced example demonstrates an enterprise-grade e-commerce system with:
43
61
 
44
62
  - **Single WIP-Verified Product**: One product listing ("The Three-Body Problem + Author Signature") with WIP file verification
45
63
  - **Multi-Path Workflow**: Order progress with delivery confirmation, wonderful rating, lost handling, and multiple return paths
46
- - **Dual-Signature Returns**: Return processes require confirmation from both customer and merchant
64
+ - **Dual-Signature Returns**: Receipt returns require both customer and merchant confirmation; non-receipt returns require only merchant confirmation of goods recovery
47
65
  - **Reward Incentive System**: Reward pool for excellent service and compensation for lost packages
48
66
  - **Time-Based Auto-Completion**: Orders auto-complete after time thresholds
49
67
 
@@ -101,7 +119,7 @@ graph TD
101
119
 
102
120
  RR["Receipt Return (Dual-Sig)<br/>Threshold = 2"]:::dualsig
103
121
  RF["Return Fail (Merchant)<br/>Time >= 10 days"]:::merchant
104
- RC["Return Complete (Dual-Sig)<br/>Threshold = 2"]:::dualsig
122
+ RC["Return Complete<br/>From Receipt: Dual-Sig (threshold=2)<br/>From Non-receipt: Merchant only (threshold=1)"]:::dualsig
105
123
 
106
124
  START --> OC
107
125
  START --> OR
@@ -167,6 +185,13 @@ Understanding the correct order for creating WoWok objects is crucial for a succ
167
185
  │ └────────┬────────┘ │
168
186
  │ │ │
169
187
  │ ▼ │
188
+ │ ┌─────────────────┐ │
189
+ │ │ Treasury │◄─── Requires: Permission (same as Service) │
190
+ │ │(myshop_treasury │ Aggregates merchant revenue │
191
+ │ │ _v2) │ Referenced by order_allocators (Phase 6) │
192
+ │ └────────┬────────┘ │
193
+ │ │ │
194
+ │ ▼ │
170
195
  │ Phase 2: Guard Creation │
171
196
  │ ═══════════════════════ │
172
197
  │ │
@@ -251,6 +276,7 @@ Understanding the correct order for creating WoWok objects is crucial for a succ
251
276
  | 1 | **Permission** | None | Permission is the foundation. Machine and Service both reference a permission object for access control. |
252
277
  | 1b | **Permission Indexes** | Permission | Grant permission indexes 1000 and 1001 to merchant. Required for Machine node operations. |
253
278
  | 2 | **Service (Empty)** | Permission | Create Service without publishing first to obtain its name. This name is used in Guard verification. |
279
+ | 2b | **Treasury** | Permission | Treasury aggregates merchant revenue. Uses same Permission as Service. Referenced by order\_allocators in Phase 7. |
254
280
  | 3 | **Guards** | Service Name | Guards must verify that orders belong to the correct Service. They query Service name and Progress state. |
255
281
  | 4 | **Machine** | Permission, Guards | Machine requires guards for node verification. Guards need Service name which is now available. |
256
282
  | 5 | **Machine Binding** | Service, Machine | Bind Machine to Service before publishing. Once published, Machine cannot be bound. |
@@ -266,6 +292,7 @@ Understanding the correct order for creating WoWok objects is crucial for a succ
266
292
  1. **Permission First**: Every major object (Machine, Service) requires a permission object. Create this first.
267
293
  2. **Permission Indexes**: Grant permission indexes 1000 and 1001 to merchant account. These are used in Machine node forwards.
268
294
  3. **Service Before Guards**: Create Service without publishing to get its name. Guards use Service name to verify orders belong to the correct service.
295
+ 3b. **Treasury for Fund Aggregation**: Create Treasury with the same Permission as the Service. Merchant revenue flows to the Treasury (not the Service address), making allocators inherently safe (R-C3-06) and aggregating public funds for operational distribution.
269
296
  4. **Guards Before Machine**: Machine nodes reference guards for verification. Create all guards first, then create Machine with guard references.
270
297
  5. **Machine Binding Before Publish**: Bind Machine to Service before publishing. Once published, Machine cannot be bound.
271
298
  6. **Arbitration Before Service Update**: Arbitration must be created before Service update so it can be bound to Service.
@@ -285,6 +312,12 @@ Phase 2: Service Creation
285
312
  ├── Publish: FALSE
286
313
  └── Record the Service address for Guard creation
287
314
 
315
+ Phase 2b: Treasury Creation
316
+ └── 2b. Create Treasury (myshop_treasury_v2)
317
+ ├── Permission: myshop_perm_v2 (same as Service)
318
+ ├── Type parameter: 0x2::wow::WOW
319
+ └── Aggregates merchant revenue; referenced by order_allocators (Phase 7)
320
+
288
321
  Phase 3: Guard Creation (Machine Guards)
289
322
  └── 3. Create Machine Guards (4 guards)
290
323
  ├── machine_merkle_root_v2 (verify string length = 66)
@@ -474,6 +507,39 @@ Create the Service without publishing to obtain its address for Guard creation.
474
507
 
475
508
  ***
476
509
 
510
+ ### Step 3b: Create Treasury (Merchant Revenue Aggregation)
511
+
512
+ Create a Treasury object to aggregate merchant revenue. The Treasury uses the **same Permission** as the Service (`myshop_perm_v2`) for consistency — a single permission organization governs both fund collection and service operations.
513
+
514
+ **Prompt**: Create Treasury "myshop\_treasury\_v2" with permission "myshop\_perm\_v2", type parameter "0x2::wow::WOW".
515
+
516
+ ```json
517
+ {
518
+ "operation_type": "treasury",
519
+ "data": {
520
+ "object": {
521
+ "name": "myshop_treasury_v2",
522
+ "type_parameter": "0x2::wow::WOW",
523
+ "permission": "myshop_perm_v2",
524
+ "replaceExistName": true
525
+ },
526
+ "description": "Treasury for aggregating MyShop merchant revenue. Uses the same Permission as the Service (myshop_perm_v2) for consistency — a single permission organization governs both fund collection and service operations."
527
+ },
528
+ "env": {
529
+ "account": "myshop_merchant",
530
+ "network": "mainnet",
531
+ "no_cache": true
532
+ }
533
+ }
534
+ ```
535
+
536
+ > **Treasury-First Rule**: Following the fund-flow design pattern established in the Insurance example, merchant revenue flows to `myshop_treasury_v2` (not directly to the Service address). This:
537
+ > 1. **Aggregates public funds** for operational distribution and accounting
538
+ > 2. **Makes allocators inherently safe** (R-C3-06) — funds always flow to the fixed Treasury regardless of caller, so no Signer binding is needed in the Guard
539
+ > 3. **Uses permission consistency** — Treasury and Service share `myshop_perm_v2`, ensuring unified governance
540
+
541
+ ***
542
+
477
543
  ### Step 4: Create Guards (Machine Guards)
478
544
 
479
545
  Create Guards using the Service address. Guards verify order state and service ownership.
@@ -522,6 +588,85 @@ Create Guards using the Service address. Guards verify order state and service o
522
588
  }
523
589
  ```
524
590
 
591
+ **Guard 1b: machine_messenger_proof_v2** - Strict-mode privacy delivery (alternative to Guard 1)
592
+
593
+ > **Two standard modes for "privacy info delivered via Messenger but not suitable for on-chain publication":**
594
+ >
595
+ > | Mode | Guard | Submission | Verification | Trust model |
596
+ > |------|-------|-----------|-------------|-------------|
597
+ > | **Broad** | `machine_merkle_root_v2` (Guard 1) | String (Merkle Root) | Length == 66 | Trusts submitter honesty; counterparty disputes via own Messenger log. Arbitration basis. |
598
+ > | **Strict** | `machine_messenger_proof_v2` (Guard 1b) | Proof addr + Order addr | Signer==proof.signer ∧ proof.time>order.time ∧ order.service==service | Submitter accountability (谁得利谁举证); no content verification. |
599
+ >
600
+ > Machine forwards may reference **either** Guard 1 or Guard 1b — choose before publishing (Forward.guard is immutable). The same strict Guard can be reused across all forwards that need Merkle-Root verification (shipping, lost, returns, etc.).
601
+
602
+ ```json
603
+ {
604
+ "operation_type": "guard",
605
+ "data": {
606
+ "namedNew": {
607
+ "name": "machine_messenger_proof_v2",
608
+ "replaceExistName": true
609
+ },
610
+ "description": "Strict-mode privacy delivery: verify Signer==proof.signer AND proof.time>order.time AND order.service==service (verifier submits Proof+Order object addresses)",
611
+ "table": [
612
+ {"identifier": 0, "b_submission": true, "value_type": "Address", "name": "Proof object from submitChainProof"},
613
+ {"identifier": 1, "b_submission": true, "value_type": "Address", "name": "Order object submitted by verifier"},
614
+ {"identifier": 2, "b_submission": false, "value_type": "Address", "name": "service_address", "value": "three_body_signature_service_v2"}
615
+ ],
616
+ "root": {
617
+ "type": "logic_and",
618
+ "nodes": [
619
+ {
620
+ "type": "logic_equal",
621
+ "nodes": [
622
+ {"type": "context", "context": "Signer"},
623
+ {"type": "query", "query": "proof.signer", "object": {"identifier": 0}, "parameters": []}
624
+ ]
625
+ },
626
+ {
627
+ "type": "logic_as_u256_greater",
628
+ "nodes": [
629
+ {"type": "query", "query": "proof.time", "object": {"identifier": 0}, "parameters": []},
630
+ {"type": "query", "query": "order.time", "object": {"identifier": 1}, "parameters": []}
631
+ ]
632
+ },
633
+ {
634
+ "type": "logic_equal",
635
+ "nodes": [
636
+ {"type": "query", "query": "order.service", "object": {"identifier": 1}, "parameters": []},
637
+ {"type": "identifier", "identifier": 2}
638
+ ]
639
+ }
640
+ ]
641
+ }
642
+ },
643
+ "env": {
644
+ "account": "myshop_merchant",
645
+ "network": "mainnet",
646
+ "no_cache": true
647
+ }
648
+ }
649
+ ```
650
+
651
+ **Three conditions (logic_and):**
652
+ 1. **Submitter accountability** — `logic_equal[context(Signer), query("proof.signer", obj=proof)]`: the transaction signer must be the Proof's signer (the party who generated the Proof via `submitChainProof`). Suppresses R-C3-01.
653
+ 2. **Freshness** — `logic_as_u256_greater[query("proof.time", obj=proof), query("order.time", obj=order)]`: the Proof was created after the order, preventing stale-proof replay. (`proof.time` has invariant `clock_derived`, always > 0.)
654
+ 3. **Project binding** — `logic_equal[query("order.service", obj=order), identifier[2]]`: the submitted Order belongs to `three_body_signature_service_v2`. Suppresses R-C3-05 (cross-project bypass).
655
+
656
+ **Generating the Proof (provider side, before submitting to the forward):**
657
+ ```json
658
+ // SDK call: messenger.submitChainProof(env, peerAddress, description?)
659
+ // - about_address is set to peerAddress (the customer's address)
660
+ // - pass the order_id in description to associate the Proof with the order
661
+ // Returns: { proofAddress, txHash }
662
+ ```
663
+
664
+ **Runtime submission (verifier side, advancing the Machine forward):**
665
+ - Broad mode (Guard 1): submit one String identifier — the Merkle Root.
666
+ - Strict mode (Guard 1b): submit two Address identifiers — the Proof object address (identifier 0) and the Order object address (identifier 1).
667
+
668
+ > No content verification is performed in either mode — only submission responsibility. The counterparty can dispute a fraudulent claim by checking their own Messenger conversation for the alleged dialogue. This follows the 谁得利谁举证 (whoever benefits bears the burden of proof) principle.
669
+
525
670
  **Guard 2: machine_time_10d_v2** - Verify 10-day timeout (864000000 ms)
526
671
 
527
672
  ```json
@@ -606,9 +751,10 @@ Create Guards using the Service address. Guards verify order state and service o
606
751
  "data": {
607
752
  "namedNew": {
608
753
  "name": "service_merchant_win_v2",
754
+ "tags": ["order", "merchant-win", "level3-scene-combined"],
609
755
  "replaceExistName": true
610
756
  },
611
- "description": "Verify order at merchant win nodes (Order Complete, Wonderful, Return Fail) AND order belongs to three_body_signature_service_v2",
757
+ "description": "Verify order at merchant win nodes (Order Complete, Wonderful, Return Fail) AND order belongs to three_body_signature_service_v2. VERIFIER CONSTRAINT LEVEL 3 (scene-combined): No Signer binding needed because the allocator uses sharing.who=Entity (myshop_treasury_v2) — funds always flow to the Treasury regardless of caller (R-C3-06 safe). Two-fold verification: (1) order at merchant win node, (2) order belongs to this service (prevents cross-service theft, R-C3-05).",
612
758
  "table": [
613
759
  {"identifier": 0, "b_submission": true, "value_type": "Address", "name": "order_id"},
614
760
  {"identifier": 1, "b_submission": false, "value_type": "String", "value": "Order Complete"},
@@ -625,21 +771,21 @@ Create Guards using the Service address. Guards verify order state and service o
625
771
  {
626
772
  "type": "logic_string_nocase_equal",
627
773
  "nodes": [
628
- {"type": "query", "query": 1253, "object": {"identifier": 0, "convert_witness": 100}, "parameters": []},
774
+ {"type": "query", "query": "progress.current", "object": {"identifier": 0, "convert_witness": "OrderProgress"}, "parameters": []},
629
775
  {"type": "identifier", "identifier": 1}
630
776
  ]
631
777
  },
632
778
  {
633
779
  "type": "logic_string_nocase_equal",
634
780
  "nodes": [
635
- {"type": "query", "query": 1253, "object": {"identifier": 0, "convert_witness": 100}, "parameters": []},
781
+ {"type": "query", "query": "progress.current", "object": {"identifier": 0, "convert_witness": "OrderProgress"}, "parameters": []},
636
782
  {"type": "identifier", "identifier": 2}
637
783
  ]
638
784
  },
639
785
  {
640
786
  "type": "logic_string_nocase_equal",
641
787
  "nodes": [
642
- {"type": "query", "query": 1253, "object": {"identifier": 0, "convert_witness": 100}, "parameters": []},
788
+ {"type": "query", "query": "progress.current", "object": {"identifier": 0, "convert_witness": "OrderProgress"}, "parameters": []},
643
789
  {"type": "identifier", "identifier": 3}
644
790
  ]
645
791
  }
@@ -648,7 +794,7 @@ Create Guards using the Service address. Guards verify order state and service o
648
794
  {
649
795
  "type": "logic_equal",
650
796
  "nodes": [
651
- {"type": "query", "query": 1563, "object": {"identifier": 0}, "parameters": []},
797
+ {"type": "query", "query": "order.service", "object": {"identifier": 0}, "parameters": []},
652
798
  {"type": "identifier", "identifier": 4}
653
799
  ]
654
800
  }
@@ -663,11 +809,85 @@ Create Guards using the Service address. Guards verify order state and service o
663
809
  }
664
810
  ```
665
811
 
666
- **Guard Logic:**
667
- 1. 验证订单当前节点是 Order Complete、Wonderful Return Fail(商家胜利节点)
668
- 2. 验证订单的 Service 地址等于当前 Guard 所属的 Service 地址(使用 `order.service` 查询指令 ID 1563)
812
+ **Guard Explanation (Two-fold Verification — Level 3 Scene-Combined):**
813
+ - **Table Item 0**: Order address (submitted at runtime)
814
+ - **Table Items 1-3**: Constant strings "Order Complete", "Wonderful", "Return Fail" (merchant win node names)
815
+ - **Table Item 4**: Constant address `three_body_signature_service_v2` (this service's on-chain address)
816
+ - **Condition 1 — Merchant Win Node**: `logic_or` of three `logic_string_nocase_equal` checks against `query("progress.current", witness="OrderProgress")` — verifies the order is at one of the merchant win nodes
817
+ - **Condition 2 — Service Ownership**: `logic_equal[query("order.service"), identifier[4]]` — verifies the submitted Order's `service` field equals `three_body_signature_service_v2`, **preventing cross-service theft** where someone submits another service's order (R-C3-05)
818
+ - **root**: `logic_and` of both conditions — all must pass for allocation to proceed
819
+
820
+ > **Risk Elimination (R-C3-06) — Level 3 Scene-Combined Design**: The allocator uses `"who": {"Entity": {"name_or_address": "myshop_treasury_v2"}}` (funds flow to the fixed Treasury address). This is inherently safe because funds go to a fixed recipient regardless of caller — **no Signer binding is needed**. The scene itself (Entity sharing to Treasury) ensures fund-flow safety, which is the Level 3 scene-combined pattern. Removing the Signer binding also eliminates R-C4-04 (Level 1 strict binding convenience warning) and avoids the lock-in risk of binding to a fixed merchant address.
669
821
  ```
670
822
 
823
+ **Guard 4 — Alternative Shorthand Form (VecString + vec_contains_string_nocase)**
824
+
825
+ The `logic_or` of three `logic_string_nocase_equal` checks above can be collapsed into a single `vec_contains_string_nocase` over a `VecString` constant. Both forms are **semantically equivalent** (verified by `guard-examples-lint.spec.ts` → "Semantic Equivalence" tests: identical risk diagnostics, identical `root_type`, identical `errors`/`ready` state). The shorthand is preferred when the candidate set has ≥ 2 entries — it scales linearly with the vector length instead of duplicating the query node N times.
826
+
827
+ ```json
828
+ {
829
+ "operation_type": "guard",
830
+ "data": {
831
+ "namedNew": {
832
+ "name": "service_merchant_win_v2",
833
+ "tags": ["order", "merchant-win", "level3-scene-combined"],
834
+ "replaceExistName": true
835
+ },
836
+ "description": "Verify order at merchant win nodes (Order Complete, Wonderful, Return Fail) AND order belongs to three_body_signature_service_v2. SHORTHAND: collapses three String constants + logic_or[logic_string_nocase_equal x 3] into a single VecString + vec_contains_string_nocase. Semantically equivalent to the original form (see guard-examples-lint 'Semantic Equivalence' tests).",
837
+ "table": [
838
+ {"identifier": 0, "b_submission": true, "value_type": "Address", "name": "order_id"},
839
+ {"identifier": 1, "b_submission": false, "value_type": "VecString", "value": ["Order Complete", "Wonderful", "Return Fail"], "name": "merchant_win_nodes"},
840
+ {"identifier": 2, "b_submission": false, "value_type": "Address", "name": "service_address", "value": "three_body_signature_service_v2"}
841
+ ],
842
+ "root": {
843
+ "type": "logic_and",
844
+ "nodes": [
845
+ {
846
+ "type": "vec_contains_string_nocase",
847
+ "nodes": [
848
+ {"type": "identifier", "identifier": 1},
849
+ {"type": "query", "query": "progress.current", "object": {"identifier": 0, "convert_witness": "OrderProgress"}, "parameters": []}
850
+ ]
851
+ },
852
+ {
853
+ "type": "logic_equal",
854
+ "nodes": [
855
+ {"type": "query", "query": "order.service", "object": {"identifier": 0}, "parameters": []},
856
+ {"type": "identifier", "identifier": 2}
857
+ ]
858
+ }
859
+ ]
860
+ }
861
+ },
862
+ "env": {
863
+ "account": "myshop_merchant",
864
+ "network": "mainnet",
865
+ "no_cache": true
866
+ }
867
+ }
868
+ ```
869
+
870
+ **Shorthand Equivalence Explanation:**
871
+
872
+ | Aspect | Original Form | Shorthand Form |
873
+ |---|---|---|
874
+ | `table` count | 5 entries (1 Address + 3 String + 1 Address) | 3 entries (1 Address + 1 VecString + 1 Address) |
875
+ | Condition 1 node | `logic_or` of 3 × `logic_string_nocase_equal` | `vec_contains_string_nocase` (single node) |
876
+ | Condition 2 node | `logic_equal` (unchanged) | `logic_equal` (unchanged) |
877
+ | `root` type | `logic_and` | `logic_and` (identical) |
878
+ | Risk diagnostics (R-C3-*) | identical | identical (security-equivalent) |
879
+ | Lint diagnostics (LE-04, SG-01, SG-03) | identical | identical |
880
+ | SH-03 warnings (missing `name`) | 3 (the 3 unnamed String constants) | 0 (the VecString is named `merchant_win_nodes`) |
881
+ | Total warnings | 5 | 2 (3 fewer — the eliminated SH-03s) |
882
+
883
+ **Why the shorthand is preferred:**
884
+ - **Fewer table entries**: 3 vs 5 (40% reduction). Adding a new merchant-win node is a one-line edit to the `value` array instead of a new identifier + new `logic_string_nocase_equal` branch.
885
+ - **No SH-03 nits**: The single `VecString` entry is naturally named (`merchant_win_nodes`), eliminating the 3 missing-name warnings.
886
+ - **Linear scaling**: For N candidate nodes, the original grows as O(N) identifiers + O(N) `logic_string_nocase_equal` branches under one `logic_or` (capped at 8 children). The shorthand stays at 1 identifier + 1 `vec_contains_string_nocase` node regardless of N.
887
+ - **Same security posture**: Risk-layer diagnostics are byte-identical (R-C3-05, R-C3-06, etc. all evaluate the same), so the Level 3 scene-combined design and R-C3-06 suppression are preserved.
888
+
889
+ **Equivalence verification**: See `d:\wowok\agent\mcp\src\knowledge\__tests__\guard-examples-lint.spec.ts` → describe block `"Semantic Equivalence — Shorthand vs Original (VecString + vec_contains_string_nocase)"`. The 8-test suite verifies: identical `root_type`, identical `errors`/`ready`, identical risk diagnostic codes, identical lint diagnostic codes (excluding SH-03), fewer SH-03 warnings, reduced `table_count`, no SDK syntax errors, and complete `risk_assessment`.
890
+
671
891
  **Guard 5: machine_service_order_v2** - Verify order belongs to this Service
672
892
 
673
893
  ```json
@@ -688,7 +908,7 @@ Create Guards using the Service address. Guards verify order state and service o
688
908
  "nodes": [
689
909
  {
690
910
  "type": "query",
691
- "query": 1563,
911
+ "query": "order.service",
692
912
  "object": {"identifier": 0},
693
913
  "parameters": []
694
914
  },
@@ -717,9 +937,10 @@ Create Guards using the Service address. Guards verify order state and service o
717
937
  "data": {
718
938
  "namedNew": {
719
939
  "name": "service_customer_win_v2",
940
+ "tags": ["order", "customer-win", "level2-dynamic-binding"],
720
941
  "replaceExistName": true
721
942
  },
722
- "description": "Verify order at customer win nodes (Lost, Return Complete) AND order belongs to three_body_signature_service_v2",
943
+ "description": "Verify order at customer win nodes (Lost, Return Complete) AND order belongs to three_body_signature_service_v2. VERIFIER CONSTRAINT LEVEL 2 (dynamic identity binding): Signer bound to query('order.owner') — only the order's rightful owner can trigger the refund. RISK ELIMINATION: Three-fold verification - (1) order at customer win node, (2) signer is order.owner (dynamic query, prevents fund theft - only order owner can trigger their own refund), (3) order belongs to three_body_signature_service_v2 (prevents cross-service theft).",
723
944
  "table": [
724
945
  {"identifier": 0, "b_submission": true, "value_type": "Address", "name": "order_id"},
725
946
  {"identifier": 1, "b_submission": false, "value_type": "String", "value": "Lost"},
@@ -735,14 +956,14 @@ Create Guards using the Service address. Guards verify order state and service o
735
956
  {
736
957
  "type": "logic_string_nocase_equal",
737
958
  "nodes": [
738
- {"type": "query", "query": 1253, "object": {"identifier": 0, "convert_witness": 100}, "parameters": []},
959
+ {"type": "query", "query": "progress.current", "object": {"identifier": 0, "convert_witness": "OrderProgress"}, "parameters": []},
739
960
  {"type": "identifier", "identifier": 1}
740
961
  ]
741
962
  },
742
963
  {
743
964
  "type": "logic_string_nocase_equal",
744
965
  "nodes": [
745
- {"type": "query", "query": 1253, "object": {"identifier": 0, "convert_witness": 100}, "parameters": []},
966
+ {"type": "query", "query": "progress.current", "object": {"identifier": 0, "convert_witness": "OrderProgress"}, "parameters": []},
746
967
  {"type": "identifier", "identifier": 2}
747
968
  ]
748
969
  }
@@ -751,7 +972,14 @@ Create Guards using the Service address. Guards verify order state and service o
751
972
  {
752
973
  "type": "logic_equal",
753
974
  "nodes": [
754
- {"type": "query", "query": 1563, "object": {"identifier": 0}, "parameters": []},
975
+ {"type": "query", "query": "order.owner", "object": {"identifier": 0}, "parameters": []},
976
+ {"type": "context", "context": "Signer"}
977
+ ]
978
+ },
979
+ {
980
+ "type": "logic_equal",
981
+ "nodes": [
982
+ {"type": "query", "query": "order.service", "object": {"identifier": 0}, "parameters": []},
755
983
  {"type": "identifier", "identifier": 3}
756
984
  ]
757
985
  }
@@ -766,11 +994,90 @@ Create Guards using the Service address. Guards verify order state and service o
766
994
  }
767
995
  ```
768
996
 
769
- **Guard Logic:**
770
- 1. 验证订单当前节点是 Lost Return Complete(客户胜利节点)
771
- 2. 验证订单的 Service 地址等于当前 Guard 所属的 Service 地址(使用 `order.service` 查询指令 ID 1563)
997
+ **Guard Explanation (Three-fold Verification — Level 2 Dynamic Binding):**
998
+ - **Table Item 0**: Order address (submitted at runtime)
999
+ - **Table Items 1-2**: Constant strings "Lost", "Return Complete" (customer win node names)
1000
+ - **Table Item 3**: Constant address `three_body_signature_service_v2` (this service's on-chain address)
1001
+ - **Condition 1 — Customer Win Node**: `logic_or` of two `logic_string_nocase_equal` checks against `query("progress.current", witness="OrderProgress")` — verifies the order is at one of the customer win nodes
1002
+ - **Condition 2 — Signer is Order Owner (Level 2 Dynamic)**: `logic_equal[query("order.owner"), context(Signer)]` — verifies the transaction caller is the order's owner (dynamic query, not a fixed address). This is the **Level 2 dynamic identity binding** pattern: the Signer is bound to a query result (not a fixed address), so it survives personnel changes and avoids the R-C4-04 lock-in risk. **Prevents fund theft by unauthorized callers** (R-C3-01/R-C3-06). Only the customer who placed the order can trigger the refund.
1003
+ - **Condition 3 — Service Ownership**: `logic_equal[query("order.service"), identifier[3]]` — verifies the submitted Order's `service` field equals `three_body_signature_service_v2`, **preventing cross-service theft** where someone submits another service's order (R-C3-05)
1004
+ - **root**: `logic_and` of all three conditions — all must pass for allocation to proceed
1005
+
1006
+ > **Risk Elimination (R-C3-06) — CRITICAL — Level 2 Dynamic Binding**: The allocator uses `"who": {"Signer": "signer"}` (funds go to the caller). This is safe ONLY because Condition 2 binds the Signer to `query("order.owner")` (dynamic query — Level 2). Without this binding, anyone could submit any Lost/Return Complete order and steal 100% of funds. The dynamic query pattern ensures funds always flow to the order's rightful owner, regardless of who calls the transaction. Unlike Level 1 (fixed address), Level 2 dynamic binding does NOT trigger R-C4-04 because the bound identity is a query result, not an immutable address constant.
772
1007
  ```
773
1008
 
1009
+ **Guard 6 — Alternative Shorthand Form (VecString + vec_contains_string_nocase)**
1010
+
1011
+ The `logic_or` of two `logic_string_nocase_equal` checks above can be collapsed into a single `vec_contains_string_nocase` over a `VecString` constant. Both forms are **semantically equivalent** (verified by `guard-examples-lint.spec.ts` → "Semantic Equivalence — Guard 6 Shorthand" tests: identical risk diagnostics, identical `root_type`, identical `errors`/`ready` state).
1012
+
1013
+ ```json
1014
+ {
1015
+ "operation_type": "guard",
1016
+ "data": {
1017
+ "namedNew": {
1018
+ "name": "service_customer_win_v2",
1019
+ "tags": ["order", "customer-win", "level2-dynamic-binding"],
1020
+ "replaceExistName": true
1021
+ },
1022
+ "description": "Verify order at customer win nodes (Lost, Return Complete) AND order belongs to three_body_signature_service_v2. SHORTHAND: collapses two String constants + logic_or[logic_string_nocase_equal x 2] into a single VecString + vec_contains_string_nocase. Semantically equivalent to the original form (see guard-examples-lint 'Semantic Equivalence — Guard 6 Shorthand' tests).",
1023
+ "table": [
1024
+ {"identifier": 0, "b_submission": true, "value_type": "Address", "name": "order_id"},
1025
+ {"identifier": 1, "b_submission": false, "value_type": "VecString", "value": ["Lost", "Return Complete"], "name": "customer_win_nodes"},
1026
+ {"identifier": 2, "b_submission": false, "value_type": "Address", "name": "service_address", "value": "three_body_signature_service_v2"}
1027
+ ],
1028
+ "root": {
1029
+ "type": "logic_and",
1030
+ "nodes": [
1031
+ {
1032
+ "type": "vec_contains_string_nocase",
1033
+ "nodes": [
1034
+ {"type": "identifier", "identifier": 1},
1035
+ {"type": "query", "query": "progress.current", "object": {"identifier": 0, "convert_witness": "OrderProgress"}, "parameters": []}
1036
+ ]
1037
+ },
1038
+ {
1039
+ "type": "logic_equal",
1040
+ "nodes": [
1041
+ {"type": "query", "query": "order.owner", "object": {"identifier": 0}, "parameters": []},
1042
+ {"type": "context", "context": "Signer"}
1043
+ ]
1044
+ },
1045
+ {
1046
+ "type": "logic_equal",
1047
+ "nodes": [
1048
+ {"type": "query", "query": "order.service", "object": {"identifier": 0}, "parameters": []},
1049
+ {"type": "identifier", "identifier": 2}
1050
+ ]
1051
+ }
1052
+ ]
1053
+ }
1054
+ },
1055
+ "env": {
1056
+ "account": "myshop_merchant",
1057
+ "network": "mainnet",
1058
+ "no_cache": true
1059
+ }
1060
+ }
1061
+ ```
1062
+
1063
+ **Shorthand Equivalence Explanation:**
1064
+
1065
+ | Aspect | Original Form | Shorthand Form |
1066
+ |---|---|---|
1067
+ | `table` count | 4 entries (1 Address + 2 String + 1 Address) | 3 entries (1 Address + 1 VecString + 1 Address) |
1068
+ | Condition 1 node | `logic_or` of 2 × `logic_string_nocase_equal` | `vec_contains_string_nocase` (single node) |
1069
+ | Condition 2 node (Signer binding) | `logic_equal` (unchanged) | `logic_equal` (unchanged) |
1070
+ | Condition 3 node (Service ownership) | `logic_equal` (unchanged) | `logic_equal` (unchanged) |
1071
+ | `root` type | `logic_and` | `logic_and` (identical) |
1072
+ | Risk diagnostics (R-C3-*) | identical | identical (security-equivalent) |
1073
+ | Lint diagnostics (LE-04, SG-01, SG-03) | identical | identical |
1074
+ | SH-03 warnings (missing `name`) | 2 (the 2 unnamed String constants) | 0 (the VecString is named `customer_win_nodes`) |
1075
+ | Total warnings | 4 | 2 (2 fewer — the eliminated SH-03s) |
1076
+
1077
+ **Case-sensitivity note (critical)**: The source uses `logic_string_nocase_equal` (case-insensitive), so the target is `vec_contains_string_nocase` (case-insensitive). If the source had used `logic_equal` on String (case-sensitive — "Lost" ≠ "lost"), the target would have to be `vec_contains_string` (case-sensitive) to preserve semantics. **Mixing case-sensitive and case-insensitive operators in the same `logic_or` is NOT convertible** — the original `logic_or` must be kept because there is no single `vec_contains_*` variant that captures both behaviors. This is a fundamental limitation of the contains shorthand: it is syntactic sugar, not a universal replacement.
1078
+
1079
+ **Equivalence verification**: See `d:\wowok\agent\mcp\src\knowledge\__tests__\guard-examples-lint.spec.ts` → describe block `"Semantic Equivalence — Guard 6 Shorthand (service_customer_win_v2: VecString + vec_contains_string_nocase)"`. The 8-test suite verifies: identical `root_type`, identical `errors`/`ready`, identical risk diagnostic codes, identical lint diagnostic codes (excluding SH-03), fewer SH-03 warnings, reduced `table_count`, no SDK syntax errors, and complete `risk_assessment`.
1080
+
774
1081
  ***
775
1082
 
776
1083
  ### Step 5: Create Machine (Multi-Path Workflow)
@@ -1007,25 +1314,19 @@ Create Machine with all nodes and guards in a single operation.
1007
1314
  },
1008
1315
  {
1009
1316
  "name": "Confirm Return Received",
1010
- "weight": 1,
1011
- "namedOperator": ""
1317
+ "permissionIndex": 1001,
1318
+ "weight": 1
1012
1319
  }
1013
1320
  ]
1014
1321
  },
1015
1322
  {
1016
1323
  "prev_node": "Non-receipt Return",
1017
- "threshold": 2,
1324
+ "threshold": 1,
1018
1325
  "forwards": [
1019
1326
  {
1020
- "name": "Submit Return Merkle Root",
1021
- "weight": 1,
1022
- "namedOperator": "",
1023
- "guard": { "guard": "machine_merkle_root_v2" }
1024
- },
1025
- {
1026
- "name": "Confirm Return Received",
1027
- "weight": 1,
1028
- "namedOperator": ""
1327
+ "name": "Confirm Goods Recovered",
1328
+ "permissionIndex": 1001,
1329
+ "weight": 1
1029
1330
  }
1030
1331
  ]
1031
1332
  }
@@ -1199,14 +1500,14 @@ Configure order_allocators to define fund distribution rules, then publish the S
1199
1500
  ]
1200
1501
  },
1201
1502
  "order_allocators": {
1202
- "description": "Order fund allocation - 100% to Service when order complete/wonderful/return fail, 100% to Order when lost/return complete",
1503
+ "description": "Order fund allocation - 100% to Treasury when order complete/wonderful/return fail, 100% to Order owner when lost/return complete",
1203
1504
  "threshold": 1,
1204
1505
  "allocators": [
1205
1506
  {
1206
1507
  "guard": "service_merchant_win_v2",
1207
1508
  "sharing": [
1208
1509
  {
1209
- "who": {"Entity": {"name_or_address": "three_body_signature_service_v2"}},
1510
+ "who": {"Entity": {"name_or_address": "myshop_treasury_v2"}},
1210
1511
  "sharing": 10000,
1211
1512
  "mode": "Rate"
1212
1513
  }
@@ -1244,16 +1545,51 @@ Configure order_allocators to define fund distribution rules, then publish the S
1244
1545
 
1245
1546
  **Fund Allocation Rules:**
1246
1547
 
1247
- | Guard | Condition | Recipient | Amount |
1248
- |-------|-----------|-----------|--------|
1249
- | service_merchant_win_v2 | Node is Order Complete / Wonderful / Return Fail | Service (merchant) | 100% |
1250
- | service_customer_win_v2 | Node is Lost / Return Complete | Order (customer) | 100% |
1548
+ | Guard | Condition | Recipient | Amount | Verifier Level |
1549
+ |-------|-----------|-----------|--------|----------------|
1550
+ | service_merchant_win_v2 | Node is Order Complete / Wonderful / Return Fail | Treasury (merchant revenue aggregation) | 100% | Level 3 (no Signer binding) |
1551
+ | service_customer_win_v2 | Node is Lost / Return Complete | Order owner (customer, via Signer) | 100% | Level 2 dynamic (Signer == order.owner) |
1251
1552
 
1252
1553
  **Recipient Types:**
1253
- - **Service**: 资金分配给 Service 对象(商家收款)
1254
- - **Order**: 资金分配给 Order 对象(客户收款,订单所有者可以提取)
1554
+ - `{ "Entity": { "name_or_address": "myshop_treasury_v2" } }` - Funds flow to the fixed Treasury address (merchant revenue aggregation). Safest — funds go to a fixed recipient regardless of caller. Uses the same Permission as the Service for governance consistency. **No Signer binding needed in the Guard** (R-C3-06 safe, Level 3 scene-combined).
1555
+ - `{ "Signer": "signer" }` - Transaction sender (caller). **⚠️ R-C3-06 Risk**: If the Guard does NOT bind the Signer to an authorized address, anyone who passes the Guard can steal 100% of funds. Safe ONLY when the Guard includes a `logic_equal[context(Signer), <authorized_address_or_query>]` check. This example uses Level 2 dynamic binding (`query("order.owner")`) — funds flow to the order's rightful owner.
1556
+
1557
+ > **R-C3-06 Risk Elimination — Guard + Sharing Coupling**: The `order_allocators` scene couples Guard verification (WHO can trigger) with sharing recipient (WHERE funds go). This example uses two verifier constraint levels:
1558
+ > - **Merchant win allocator** (`sharing.who = Entity → myshop_treasury_v2`, **Level 3 scene-combined**): Funds flow to the fixed Treasury address. Inherently safe — funds go to a fixed recipient regardless of caller. The `service_merchant_win_v2` Guard does NOT bind `context(Signer)` — the scene itself (Entity sharing to Treasury) ensures fund-flow safety. This is the recommended Level 3 pattern: no Signer binding, no R-C4-04 lock-in risk, no inconvenience.
1559
+ > - **Customer win allocator** (`sharing.who = Signer`, **Level 2 dynamic binding**): Funds flow to the caller. Safe ONLY because `service_customer_win_v2` Guard binds `context(Signer)` to `query("order.owner")` (dynamic query — Level 2). This ensures funds always flow to the order's rightful owner — only the customer who placed the order can receive the refund.
1560
+ >
1561
+ > **Treasury-First Rule**: Following the fund-flow design pattern established in the Insurance example, merchant revenue flows to `myshop_treasury_v2` (not the Service address). This aggregates public funds for operational distribution and makes the allocator inherently safe (R-C3-06). The Treasury uses the same Permission as the Service (`myshop_perm_v2`) for governance consistency.
1255
1562
  ```
1256
1563
 
1564
+ ### Verifier Constraint Design Notes
1565
+
1566
+ This example demonstrates all three verifier constraint levels across its Guards. The verifier constraint level classifies how strictly the Signer identity is constrained, trading off security against convenience.
1567
+
1568
+ | Guard | Level | Pattern | Why |
1569
+ |-------|-------|---------|-----|
1570
+ | Guard 1-3 (machine_merkle_root_v2, machine_service_order_v2, machine_time_*) | Level 3 | No Signer binding | Machine forward's `permissionIndex` already verifies operator identity — Signer binding is redundant |
1571
+ | Guard 4 (service_merchant_win_v2) | Level 3 | No Signer binding | Allocator uses `sharing.who=Entity` (myshop_treasury_v2) — funds flow to fixed Treasury regardless of caller (R-C3-06 safe). Two-fold verification: node + order.service binding |
1572
+ | Guard 5 (machine_service_order_v2) | Level 3 | No Signer binding | Project-binding only (order.service check); machine forward verifies operator |
1573
+ | Guard 6 (service_customer_win_v2) | Level 2 dynamic | Signer == query("order.owner") | Allocator uses `sharing.who=Signer` — funds flow to caller, must bind to order owner to prevent theft |
1574
+ | Reward guards (reward_wonderful_v2, reward_lost_v2, reward_shipping_timeout_v2) | Level 3 | No Signer binding | One-time claim via record count; funds flow to fixed reward pool recipient |
1575
+
1576
+ **Key design decisions**:
1577
+
1578
+ 1. **Merchant funds → Treasury (not Service)**: Following the Treasury-first rule, merchant revenue flows to `myshop_treasury_v2` (created with the same Permission as the Service). This aggregates public funds for operations and distribution, and makes the allocator inherently safe (R-C3-06) — no Signer binding needed (Level 3).
1579
+
1580
+ 2. **Customer refunds → order.owner (dynamic)**: Customer refunds must go to the actual customer who placed the order. The Level 2 dynamic binding (`query("order.owner")`) ensures only the rightful owner receives the refund, regardless of who calls the transaction. Unlike Level 1 (fixed address), this survives customer account changes.
1581
+
1582
+ 3. **No Level 1 strict binding anywhere**: No Guard uses `logic_equal[context(Signer), fixed_address]` because:
1583
+ - The merchant role may change (personnel rotation) — Level 1 would lock the Guard to one address permanently
1584
+ - The Treasury pattern makes Signer binding unnecessary for the merchant allocator (Level 3)
1585
+ - The dynamic `order.owner` query is more appropriate for customer refunds (Level 2 dynamic)
1586
+ - Level 1 would trigger R-C4-04 (convenience warning) and create operational risk
1587
+
1588
+ **Alternative designs considered**:
1589
+ - **Guard 4 could use Level 2 identity-set** (merchant OR admin via permission.owner OR has admin) — **rejected** because Treasury (Entity sharing) already makes Signer binding redundant. Adding Level 2 would add complexity without safety benefit.
1590
+ - **Guard 6 could use Level 2 identity-set** (order.owner OR order.agent via 1562 OR 1567) — **viable** if agents should be able to trigger refunds on behalf of customers. The current single-customer design (Level 2 dynamic, `order.owner` only) is simpler and sufficient for this example. See `tpl_allocator_identity_set_order_holder` template for the identity-set construction pattern.
1591
+ - **Guard 4 could use Level 2 dynamic permission** (permission.owner OR has admin, with dynamic permission via 1488) — **viable** for scenarios where the Service may rotate its permission. See `tpl_allocator_identity_set_service_provider_dynamic` template for this pattern. Rejected here because the Treasury pattern already provides fund-flow safety without Signer binding.
1592
+
1257
1593
  ***
1258
1594
 
1259
1595
  ### Step 11: Create Empty Reward Object (Optional)
@@ -1314,21 +1650,21 @@ Create guards for reward verification with double-claim protection:
1314
1650
  {
1315
1651
  "type": "logic_string_nocase_equal",
1316
1652
  "nodes": [
1317
- {"type": "query", "query": 1253, "object": {"identifier": 0, "convert_witness": 100}, "parameters": []},
1653
+ {"type": "query", "query": "progress.current", "object": {"identifier": 0, "convert_witness": "OrderProgress"}, "parameters": []},
1318
1654
  {"type": "identifier", "identifier": 1}
1319
1655
  ]
1320
1656
  },
1321
1657
  {
1322
1658
  "type": "logic_equal",
1323
1659
  "nodes": [
1324
- {"type": "query", "query": 1562, "object": {"identifier": 0}, "parameters": []},
1660
+ {"type": "query", "query": "order.owner", "object": {"identifier": 0}, "parameters": []},
1325
1661
  {"type": "context", "context": "Signer"}
1326
1662
  ]
1327
1663
  },
1328
1664
  {
1329
1665
  "type": "logic_equal",
1330
1666
  "nodes": [
1331
- {"type": "query", "query": 1563, "object": {"identifier": 0}, "parameters": []},
1667
+ {"type": "query", "query": "order.service", "object": {"identifier": 0}, "parameters": []},
1332
1668
  {"type": "identifier", "identifier": 3}
1333
1669
  ]
1334
1670
  },
@@ -1376,21 +1712,21 @@ Create guards for reward verification with double-claim protection:
1376
1712
  {
1377
1713
  "type": "logic_string_nocase_equal",
1378
1714
  "nodes": [
1379
- {"type": "query", "query": 1253, "object": {"identifier": 0, "convert_witness": 100}, "parameters": []},
1715
+ {"type": "query", "query": "progress.current", "object": {"identifier": 0, "convert_witness": "OrderProgress"}, "parameters": []},
1380
1716
  {"type": "identifier", "identifier": 1}
1381
1717
  ]
1382
1718
  },
1383
1719
  {
1384
1720
  "type": "logic_equal",
1385
1721
  "nodes": [
1386
- {"type": "query", "query": 1562, "object": {"identifier": 0}, "parameters": []},
1722
+ {"type": "query", "query": "order.owner", "object": {"identifier": 0}, "parameters": []},
1387
1723
  {"type": "context", "context": "Signer"}
1388
1724
  ]
1389
1725
  },
1390
1726
  {
1391
1727
  "type": "logic_equal",
1392
1728
  "nodes": [
1393
- {"type": "query", "query": 1563, "object": {"identifier": 0}, "parameters": []},
1729
+ {"type": "query", "query": "order.service", "object": {"identifier": 0}, "parameters": []},
1394
1730
  {"type": "identifier", "identifier": 3}
1395
1731
  ]
1396
1732
  },
@@ -1438,21 +1774,21 @@ Create guards for reward verification with double-claim protection:
1438
1774
  {
1439
1775
  "type": "logic_string_nocase_equal",
1440
1776
  "nodes": [
1441
- {"type": "query", "query": 1253, "object": {"identifier": 0, "convert_witness": 100}, "parameters": []},
1777
+ {"type": "query", "query": "progress.current", "object": {"identifier": 0, "convert_witness": "OrderProgress"}, "parameters": []},
1442
1778
  {"type": "identifier", "identifier": 1}
1443
1779
  ]
1444
1780
  },
1445
1781
  {
1446
1782
  "type": "logic_equal",
1447
1783
  "nodes": [
1448
- {"type": "query", "query": 1562, "object": {"identifier": 0}, "parameters": []},
1784
+ {"type": "query", "query": "order.owner", "object": {"identifier": 0}, "parameters": []},
1449
1785
  {"type": "context", "context": "Signer"}
1450
1786
  ]
1451
1787
  },
1452
1788
  {
1453
1789
  "type": "logic_equal",
1454
1790
  "nodes": [
1455
- {"type": "query", "query": 1563, "object": {"identifier": 0}, "parameters": []},
1791
+ {"type": "query", "query": "order.service", "object": {"identifier": 0}, "parameters": []},
1456
1792
  {"type": "identifier", "identifier": 3}
1457
1793
  ]
1458
1794
  },
@@ -2138,6 +2474,36 @@ Customer requests return after delivery confirmation.
2138
2474
  }
2139
2475
  ```
2140
2476
 
2477
+ > **Receipt Return path**: Steps 9.3 + 9.4 complete the Receipt Return → Return Complete transition (threshold=2, dual-signature). The customer submits return tracking (Merkle Root), and the merchant confirms receipt of the returned goods.
2478
+
2479
+ **Step 9.5: Merchant Confirms Goods Recovered (Non-receipt Return path)**
2480
+
2481
+ For the Non-receipt Return path, the customer never received the goods and has nothing to return. The customer's non-receipt was already confirmed when entering the Non-receipt Return node (dual-signature at entry). The transition to Return Complete requires only the merchant to confirm goods recovery (threshold=1).
2482
+
2483
+ ```json
2484
+ {
2485
+ "operation_type": "progress",
2486
+ "data": {
2487
+ "object": "myshop_progress_v2",
2488
+ "operate": {
2489
+ "operation": {
2490
+ "next_node_name": "Return Complete",
2491
+ "forward": "Confirm Goods Recovered"
2492
+ },
2493
+ "hold": false,
2494
+ "message": "Goods recovered by merchant - non-receipt return complete"
2495
+ }
2496
+ },
2497
+ "env": {
2498
+ "account": "myshop_merchant",
2499
+ "network": "mainnet",
2500
+ "no_cache": true
2501
+ }
2502
+ }
2503
+ ```
2504
+
2505
+ > **Non-receipt Return path**: Only Step 9.5 is needed (threshold=1, merchant-only). No customer action required — the customer never received the goods and has nothing to return or submit. The merchant confirms the goods have been recovered (e.g., returned by logistics to the merchant).
2506
+
2141
2507
  ***
2142
2508
 
2143
2509
  ### Step 10: Return Fail (Timeout)
@@ -2285,7 +2651,7 @@ When order reaches Lost or Return Complete, customer can withdraw funds.
2285
2651
  This advanced e-commerce example demonstrates:
2286
2652
 
2287
2653
  1. **Multi-Path Workflow**: Orders can complete through normal delivery, wonderful rating, or various return paths
2288
- 2. **Dual-Signature Returns**: Return processes require confirmation from both parties (threshold=2)
2654
+ 2. **Dual-Signature Returns**: Receipt returns require confirmation from both parties (threshold=2); non-receipt returns require only merchant confirmation of goods recovery (threshold=1)
2289
2655
  3. **Time-Based Auto-Completion**: Orders auto-complete after time thresholds (10 days from shipping, 2 days from delivery)
2290
2656
  4. **Guard-Based Verification**: All state transitions and fund allocations are protected by guards
2291
2657
  5. **Reward Incentive System**: Wonderful ratings receive rewards, lost packages and shipping delays receive compensation