@wowok/agent-mcp 2.6.7 → 2.6.9

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 (53) hide show
  1. package/dist/customer/customer-advice.js +1 -0
  2. package/dist/customer/info-puzzle.js +1 -0
  3. package/dist/customer/reminder-system.d.ts +1 -0
  4. package/dist/customer/reminder-system.js +20 -0
  5. package/dist/customer/types.d.ts +1 -0
  6. package/dist/examples/{insurance-machine-create-publish.json → insurance-machine-create.json} +9 -9
  7. package/dist/examples/insurance-service-allocators.json +55 -0
  8. package/dist/examples/machine-publish.json +30 -0
  9. package/dist/examples/rental-ziroom-service-create.json +12 -64
  10. package/dist/examples/retail-myshop-service-create.json +14 -64
  11. package/dist/examples/retail-myshop-service-customer-required.json +31 -0
  12. package/dist/examples/threebody-machine-create.json +9 -10
  13. package/dist/examples/threebody-service-allocators.json +3 -4
  14. package/dist/examples/travel-machine-create.json +9 -10
  15. package/dist/examples/travel-service-create.json +11 -79
  16. package/dist/harness/index.d.ts +6 -1
  17. package/dist/harness/index.js +4 -1
  18. package/dist/harness/plan.d.ts +13 -0
  19. package/dist/harness/plan.js +24 -0
  20. package/dist/harness/recover.js +2 -2
  21. package/dist/index.js +10 -0
  22. package/dist/project/context-assembly.d.ts +9 -0
  23. package/dist/project/context-assembly.js +122 -6
  24. package/dist/project/graph-builder.d.ts +6 -1
  25. package/dist/project/graph-builder.js +1 -1
  26. package/dist/project/handlers.d.ts +1 -0
  27. package/dist/project/handlers.js +22 -9
  28. package/dist/schema/call/allocation.js +1 -1
  29. package/dist/schema/call/payment.d.ts +11 -11
  30. package/dist/schema/call/payment.js +5 -3
  31. package/dist/schema/call/semantic.js +10 -1
  32. package/dist/schema/call/service.d.ts +6 -6
  33. package/dist/schema/call/service.js +14 -3
  34. package/dist/schema/operations.d.ts +11 -11
  35. package/dist/schema/project/index.d.ts +105 -0
  36. package/dist/schema/project/index.js +53 -0
  37. package/dist/schema/query/index.d.ts +571 -0
  38. package/dist/schema/query/index.js +42 -1
  39. package/dist/schema/sync-layer4.js +25 -4
  40. package/dist/schemas/index.json +1 -1
  41. package/dist/schemas/onchain_operations.schema.json +7 -8
  42. package/dist/schemas/onchain_operations_allocation.schema.json +1 -1
  43. package/dist/schemas/onchain_operations_payment.schema.json +3 -4
  44. package/dist/schemas/onchain_operations_service.schema.json +3 -3
  45. package/dist/schemas/project_operation.output.json +79 -0
  46. package/dist/schemas/project_operation.schema.json +13 -0
  47. package/dist/schemas/query_toolkit.output.json +39 -1
  48. package/dist/schemas/wowok_buildin_info.output.json +132 -0
  49. package/dist/schemas/wowok_buildin_info.schema.json +14 -0
  50. package/dist/tools/handlers/onchain.js +94 -4
  51. package/dist/tools/index.js +3 -3
  52. package/package.json +2 -2
  53. package/dist/examples/insurance-service-allocators-publish.json +0 -56
@@ -79,6 +79,7 @@ function buildReminderContext(puzzle, risk, overrides) {
79
79
  risk_level: risk.level,
80
80
  has_refund_path: wf?.has_refund_path,
81
81
  has_messenger: trust?.has_messenger,
82
+ customer_required: puzzle.service_basics.customer_required,
82
83
  ...overrides,
83
84
  };
84
85
  }
@@ -14,6 +14,7 @@ export function assembleServiceBasics(serviceId, raw, wipVerified = false) {
14
14
  machine_id: raw.machine,
15
15
  buy_guard_id: raw.buy_guard,
16
16
  customer_required_count: raw.customer_required?.length ?? 0,
17
+ customer_required: (raw.customer_required ?? []).filter((x) => typeof x === "string"),
17
18
  arbitrations_count: raw.arbitrations?.length ?? 0,
18
19
  compensation_fund_balance: raw.compensation_fund?.balance ?? 0n,
19
20
  compensation_lock_duration: raw.compensation_lock_duration ?? 0,
@@ -20,6 +20,7 @@ export interface ReminderContext {
20
20
  has_refund_path?: boolean;
21
21
  has_user_operable?: boolean;
22
22
  has_messenger?: boolean;
23
+ customer_required?: string[];
23
24
  ambiguous_guards?: string[];
24
25
  current_node?: string;
25
26
  expected_progress_hours?: number;
@@ -145,6 +145,26 @@ const REMINDER_RULES = [
145
145
  applies: (ctx) => ctx.has_messenger === false,
146
146
  dedup_key: "no_messenger",
147
147
  },
148
+ {
149
+ id: "preorder_customer_required_no_contact",
150
+ stage: "preorder",
151
+ priority: "required",
152
+ message: (ctx) => `🔴 This Service requires private information (${(ctx.customer_required ?? []).join(", ")}), ` +
153
+ `but it has NO Contact/Messenger channel configured. Your private information cannot be delivered securely ` +
154
+ `— do NOT order until the merchant binds a Contact (um) so the info can be sent end-to-end encrypted.`,
155
+ applies: (ctx) => (ctx.customer_required?.length ?? 0) > 0 && ctx.has_messenger === false,
156
+ dedup_key: "customer_required_no_contact",
157
+ },
158
+ {
159
+ id: "preorder_customer_required_send_info",
160
+ stage: "preorder",
161
+ priority: "recommended",
162
+ message: (ctx) => `🔐 After ordering you MUST send your private information (${(ctx.customer_required ?? []).join(", ")}) ` +
163
+ `to the merchant's Contact via end-to-end encrypted Messenger, and obtain a confirmation reply. ` +
164
+ `Your private information is encrypted end-to-end and never stored in plaintext by the service.`,
165
+ applies: (ctx) => (ctx.customer_required?.length ?? 0) > 0 && ctx.has_messenger === true,
166
+ dedup_key: "customer_required_send_info",
167
+ },
148
168
  {
149
169
  id: "in_progress_progress_stalled",
150
170
  stage: "in_progress",
@@ -11,6 +11,7 @@ export interface ServiceBasics {
11
11
  machine_id?: string;
12
12
  buy_guard_id?: string;
13
13
  customer_required_count: number;
14
+ customer_required: string[];
14
15
  arbitrations_count: number;
15
16
  compensation_fund_balance: bigint;
16
17
  compensation_lock_duration: number;
@@ -1,10 +1,10 @@
1
1
  {
2
- "title": "Create and Publish Insurance Claim Machine (Start -> Complete)",
3
- "description": "Create a two-node insurance claim workflow Machine and publish it in a single transaction: entry forward 'start_claim' into Start (permissionIndex 1000), and 'complete_claim' from Start into Complete (permissionIndex 1001) gated by the time-lock Guard insurance_complete_guard_v1.",
4
- "tags": ["machine", "insurance", "claim", "workflow", "publish"],
2
+ "title": "Create Insurance Claim Machine DRAFT (Start -> Complete)",
3
+ "description": "Step 4 of the 12-step deploy plan: create the two-node insurance claim workflow Machine in DRAFT (unpublished): entry forward 'start_claim' into Start (permissionIndex 1000), and 'complete_claim' from Start into Complete (permissionIndex 1001) gated by the time-lock Guard insurance_complete_guard_v1. Publish is a separate later step (machine-publish.json).",
4
+ "tags": ["machine", "insurance", "claim", "workflow", "draft", "12-step"],
5
5
  "industry": "insurance",
6
6
  "operation_type": "machine",
7
- "source": "docs/examples/Insurance — schema-validated, not chain-verified",
7
+ "source": "docs/examples/Insurance — adapted to the 12-step plan (DRAFT only, schema-validated)",
8
8
  "verified": false,
9
9
  "network": "testnet",
10
10
  "call": {
@@ -56,8 +56,7 @@
56
56
  ]
57
57
  }
58
58
  ]
59
- },
60
- "publish": true
59
+ }
61
60
  },
62
61
  "env": {
63
62
  "account": "insurance_provider_v1",
@@ -65,10 +64,11 @@
65
64
  }
66
65
  },
67
66
  "notes": [
68
- "Insurance-claim Machine pattern: a minimal two-node Start -> Complete workflow where the completion forward is gated by a time-lock Guard. Demonstrates create-with-nodes + publish in ONE transaction (nodes become immutable after publish).",
69
- "Schema check (call/machine.ts CallMachine_DataSchema): 'object' uses the OBJECT form of WithPermissionObjectSchema (NamedObjectWithPermissionSchema — name, permission, replaceExistName); node uses NodeSchema op='add' with nodes array; publish=true on NEW machine creation triggers the FIX-02 entry-forward refine — satisfied because the Start pair has prev_node='' with at least one forward (FIX-002 also requires the initial pair to have a non-empty forwards list).",
67
+ "12-STEP PLAN alignment: this is ONE step (Step 4 Machine DRAFT). Do NOT bundle publish:true here — publish is Step 6 (see machine-publish.json). The 12-step order is Service DRAFT → Machine (nodes/forwards) → Guard → bind Guards → Machine publish.",
68
+ "Insurance-claim Machine pattern: a minimal two-node Start -> Complete workflow where the completion forward is gated by a time-lock Guard. This creates the Machine in DRAFT (nodes remain editable until publish).",
69
+ "Schema check (call/machine.ts CallMachine_DataSchema): 'object' uses the OBJECT form of WithPermissionObjectSchema (NamedObjectWithPermissionSchema — name, permission, replaceExistName); node uses NodeSchema op='add' with nodes array; publish omitted → DRAFT. The FIX-02 entry-forward refine (applied at publish time) is satisfied because the Start pair has prev_node='' with at least one forward (FIX-002 also requires the initial pair to have a non-empty forwards list).",
70
70
  "Forward check (query/index.ts MachineForwardSchema): every forward provides permissionIndex (1000/1001) satisfying the one-of namedOperator/permissionIndex rule; the Complete forward uses the OBJECT guard form {guard: 'insurance_complete_guard_v1'} (MachineForwardGuardSchema; a plain string shorthand is also accepted via preprocess).",
71
- "The referenced Guard (insurance_complete_guard_v1) and Permission (insurance_permission_v1, with indexes 1000/1001 granted to the operator) must exist before this call — see the sibling insurance-guard-claim-timelock example and the Insurance doc Steps 1/3.",
71
+ "The referenced Guard (insurance_complete_guard_v1) and Permission (insurance_permission_v1, with indexes 1000/1001 granted to the operator) must exist before publish — see the sibling insurance-guard-claim-timelock example and the Insurance doc Steps 1/3.",
72
72
  "PREREQUISITE for advancing claims: the Permission must grant index 1000 (start_claim) and 1001 (complete_claim) to the operating account, otherwise progress advancement aborts with MoveAbort code 7.",
73
73
  "Desensitization: doc payload already uses generic local-mark names only (insurance_provider_v1, insurance_machine_v1, insurance_permission_v1); no real personal data present, nothing replaced."
74
74
  ]
@@ -0,0 +1,55 @@
1
+ {
2
+ "title": "Configure Order Allocators (Insurance, Entity-Sharing)",
3
+ "description": "Pre-publish Service configuration step (12-step plan: order_allocators). Update the unpublished insurance Service with two alternative order_allocators (Treasury collection and personal collection, first-match-wins) whose sharing recipients are FIXED Entity addresses — the fund-theft-safe pattern. Publish is a SEPARATE later step (Step 12) and is intentionally NOT bundled here.",
4
+ "tags": ["service", "insurance", "order_allocators", "entity-sharing", "12-step"],
5
+ "industry": "insurance",
6
+ "operation_type": "service",
7
+ "source": "docs/examples/Insurance — adapted to the 12-step plan (allocators only, schema-validated)",
8
+ "verified": false,
9
+ "network": "testnet",
10
+ "call": {
11
+ "tool": "onchain_operations",
12
+ "operation_type": "service",
13
+ "data": {
14
+ "object": "insurance_service_v1",
15
+ "order_allocators": {
16
+ "description": "Insurance order revenue allocation — 2 alternative merchant collection approaches (first-match-wins means only the first passing allocator executes)",
17
+ "threshold": 0,
18
+ "allocators": [
19
+ {
20
+ "guard": "insurance_withdraw_guard_treasury_v1",
21
+ "sharing": [
22
+ {
23
+ "who": { "Entity": { "name_or_address": "insurance_treasury_v1" } },
24
+ "sharing": 10000,
25
+ "mode": "Rate"
26
+ }
27
+ ]
28
+ },
29
+ {
30
+ "guard": "insurance_withdraw_guard_personal_v1",
31
+ "sharing": [
32
+ {
33
+ "who": { "Entity": { "name_or_address": "insurance_provider_v1" } },
34
+ "sharing": 10000,
35
+ "mode": "Rate"
36
+ }
37
+ ]
38
+ }
39
+ ]
40
+ }
41
+ },
42
+ "env": {
43
+ "account": "insurance_provider_v1",
44
+ "network": "testnet"
45
+ }
46
+ },
47
+ "notes": [
48
+ "12-STEP PLAN alignment: this file is ONE step (Step 9 order_allocators). Do NOT bundle publish:true here — publish is Step 12. order_allocators is PERMANENTLY IMMUTABLE after publish (service.move E_ALREADY_PUBLISHED), so it MUST be set in this pre-publish step.",
49
+ "Fund-safety pattern: who = {Entity: {name_or_address: ...}} pins the recipient to a FIXED address (Treasury object or provider account) resolved via LocalMark at build time. Even if the withdraw Guard were bypassed, funds still flow to the fixed Entity — the caller cannot redirect them. NEVER use {Signer: 'signer'} for merchant collection.",
50
+ "first-match-wins: the TWO allocators illustrate 2 alternative collection designs (Treasury vs personal); only the FIRST allocator whose Guard passes executes. In production pick ONE and delete the other. Each allocator's Guard must be a UNIQUE Guard object.",
51
+ "Schema check (call/service.ts CallService_DataSchema + query/index.ts AllocatorsSchema/AllocatorSchema/AllocationSharingSchema/RecipientSchema): object is the STRING form (existing service); order_allocators = {description, threshold, allocators[]} with per-allocator {guard: NameOrAddress, sharing: [{who: {Entity: {name_or_address}}, sharing, mode}]}; mode 'Rate' with a single sharing of 10000 satisfies the Rate-sum == 10000 (basis points, 100%) rule with no Surplus item; threshold 0 allows any balance.",
52
+ "PREREQUISITES (created by separate calls, not shown): insurance_service_v1 (unpublished, with machine + sales), both withdraw Guards, and insurance_treasury_v1; Machine published. If this Service declares customer_required, it must also bind a Contact via um (hard linkage) — see the Contact step.",
53
+ "Desensitization: generic local-mark names only (insurance_service_v1, insurance_treasury_v1, insurance_provider_v1, insurance_withdraw_guard_*_v1); no real personal data present."
54
+ ]
55
+ }
@@ -0,0 +1,30 @@
1
+ {
2
+ "title": "Publish a Machine (Freeze Workflow)",
3
+ "description": "Step 6 of the 12-step deploy plan: publish an existing DRAFT Machine to make its nodes/forwards immutable. This is a single-concept operation — create the Machine in DRAFT first (see *-machine-create.json), then bind Guards to forwards, then publish. Replace 'my_machine' with your Machine's name.",
4
+ "tags": ["machine", "publish", "freeze", "immutable", "12-step"],
5
+ "industry": "general",
6
+ "operation_type": "machine",
7
+ "source": "12-step deploy plan (Step 6 Machine publish) — schema-validated",
8
+ "verified": false,
9
+ "network": "testnet",
10
+ "call": {
11
+ "tool": "onchain_operations",
12
+ "operation_type": "machine",
13
+ "data": {
14
+ "object": "my_machine",
15
+ "publish": true
16
+ },
17
+ "env": {
18
+ "account": "service_provider",
19
+ "network": "testnet",
20
+ "confirmed": true
21
+ }
22
+ },
23
+ "notes": [
24
+ "12-STEP PLAN alignment: this is ONE step (Step 6 Machine publish). Create the Machine in DRAFT first (Step 4), then create/bind Guards to forwards (Step 5), THEN publish here. Publishing is IRREVERSIBLE — nodes/pairs/forwards become permanently frozen.",
25
+ "object is the STRING form (existing DRAFT Machine name/ID). publish:true is the only data field needed — node/progress_new/description are NOT re-specified.",
26
+ "env.confirmed:true is REQUIRED (ConfirmGate) because publish is irreversible.",
27
+ "FIX-02: publish:true validates that the on-chain nodes contain at least one entry forward (prev_node=''), else the Machine would be stuck at Progress current=''.",
28
+ "Only a PUBLISHED Machine can be bound to a Service (service.machine asserts bPublished). Publish the Machine BEFORE the Service's machine-binding step."
29
+ ]
30
+ }
@@ -1,11 +1,11 @@
1
1
  {
2
- "title": "Create Service with 3-path Allocation (Ziroom Rental)",
3
- "description": "Create a Service with machine, buy_guard, contact, and 3-path order_allocators (rent to operator / refund to customer signer / damage deduction to operator)",
4
- "tags": ["service", "allocation", "rental", "order_allocators", "guard"],
2
+ "title": "Create Rental Service DRAFT (Ziroom)",
3
+ "description": "Step 3 of the 12-step deploy plan: create the Ziroom rental Service object in DRAFT (unpublished) with only its identity — name, permission, payment token type, description, and location. Machine binding, buy_guard, sales (WIP), order_allocators, Contact (um), and publish are each separate later steps and are intentionally NOT bundled here.",
4
+ "tags": ["service", "rental", "draft", "create", "12-step"],
5
5
  "industry": "rental",
6
6
  "operation_type": "service",
7
- "source": "ziroom testnet deployment 2026-07-29 (repaired to current schema)",
8
- "verified": true,
7
+ "source": "ziroom testnet deployment 2026-07-29 — adapted to the 12-step plan (DRAFT only, schema-validated)",
8
+ "verified": false,
9
9
  "network": "testnet",
10
10
  "call": {
11
11
  "tool": "onchain_operations",
@@ -18,58 +18,8 @@
18
18
  "permission": "ziroom_permission_v1",
19
19
  "type_parameter": "0x2::wow::WOW"
20
20
  },
21
- "machine": "ziroom_machine_v1",
22
- "buy_guard": "ziroom_buy_guard_v1",
23
- "um": "ziroom_contact_v1",
24
- "sales": {
25
- "op": "add",
26
- "sales": [
27
- {
28
- "name": "ziroom_apartment_v1",
29
- "price": 2000000000,
30
- "stock": 1,
31
- "suspension": false,
32
- "wip": "",
33
- "wip_hash": ""
34
- }
35
- ]
36
- },
37
- "order_allocators": {
38
- "description": "3-path allocation: rent to operator, refund to customer, damage deductions",
39
- "threshold": 1000000000,
40
- "allocators": [
41
- {
42
- "guard": "ziroom_buy_guard_v1",
43
- "sharing": [
44
- {
45
- "who": { "Entity": { "name_or_address": "ziroom_operator" } },
46
- "sharing": 1000000000,
47
- "mode": "Amount"
48
- }
49
- ]
50
- },
51
- {
52
- "guard": "ziroom_refund_guard_v1",
53
- "sharing": [
54
- {
55
- "who": { "Signer": "signer" },
56
- "sharing": 1000000000,
57
- "mode": "Amount"
58
- }
59
- ]
60
- },
61
- {
62
- "guard": "ziroom_damage_guard_v1",
63
- "sharing": [
64
- {
65
- "who": { "Entity": { "name_or_address": "ziroom_operator" } },
66
- "sharing": 1000000000,
67
- "mode": "Amount"
68
- }
69
- ]
70
- }
71
- ]
72
- }
21
+ "description": "Ziroom apartment rental service",
22
+ "location": "Beijing"
73
23
  },
74
24
  "env": {
75
25
  "network": "testnet",
@@ -78,12 +28,10 @@
78
28
  }
79
29
  },
80
30
  "notes": [
81
- "order_allocators is PERMANENTLY IMMUTABLE after publish (service.move:503) — set it BEFORE publish=true.",
82
- "Signer recipient means the tx sender at alloc() time — the customer must call alloc_by_guard THEMSELVES for refunds (if the operator calls it, the operator receives the funds).",
83
- "Amount mode: fixed amount in smallest unit, not percentage. Use Rate mode (10000=100%) for proportional splits; Rate items must sum to exactly 10000 when no Surplus item exists.",
84
- "sales is an op discriminated union: {op:'add'|'set', sales:[...]} or {op:'remove', sales_name:[...]} or {op:'clear'} — never a bare array.",
85
- "permission and type_parameter live INSIDE 'object' (TypeNamedObjectWithPermissionSchema). wip/wip_hash empty strings skip verification (TESTING ONLY — production must use real WIP URLs).",
86
- "machine must be PUBLISHED before binding here; buy_guard may use a LocalMark NAME to break the Guard↔Service circular dependency (Phase-1 create without publish, then publish in Phase 2).",
87
- "Entity recipient shown as local mark name 'ziroom_operator' (desensitization repair 2026-07-30): the original deployment used the operator's raw 0x address; Entity resolves names via LocalMark to a FIXED static address, so the name form is equivalent and recommended."
31
+ "12-STEP PLAN alignment: this file is ONE step (Step 3 Service DRAFT). The full order is Account → Permission → Service DRAFT → Machine → Guard → Machine publish → Sales(WIP) → Treasury(optional) → order_allocators → Contact(um) → Arbitration → Service publish. Do NOT bundle machine/buy_guard/um/sales/order_allocators into the create call.",
32
+ "object uses the OBJECT form of TypeNamedObjectWithPermissionSchema: name/permission/type_parameter go INSIDE object; description and location are top-level Service fields. No publish:true here — the Service stays unpublished until Step 12.",
33
+ "Rental is a PHYSICAL-goods scenario and SHOULD declare customer_required (name/phone/shipping_address/id_number for deposit-backed rental). Per the SDK-enforced HARD LINKAGE, customer_required must be set TOGETHER with a Contact bound as um — the buyer's private info is delivered only through the Contact's end-to-end encrypted Messenger. Therefore customer_required is NOT set in this DRAFT; it is set together with um in the Contact step (create the Contact, then bind um + customer_required in one update).",
34
+ "permission references the pre-created ziroom_permission_v1 (Step 2); type_parameter '0x2::wow::WOW' sets the payment token (WOW, 9 decimals).",
35
+ "machine, order_allocators, and arbitrations become immutable after publish — set them in their own pre-publish steps, not here."
88
36
  ]
89
37
  }
@@ -1,12 +1,12 @@
1
1
  {
2
- "title": "Create Retail Service with 2-path Allocation (MyShop E-Commerce)",
3
- "description": "Simple e-commerce Service with machine, withdraw/refund guards, contact, and toy products. 2-path order_allocators: merchant withdraw after completion, customer refund after cancellation.",
4
- "tags": ["service", "allocation", "retail", "ecommerce", "guard", "order_allocators"],
2
+ "title": "Create Retail Service DRAFT (MyShop E-Commerce)",
3
+ "description": "Step 3 of the 12-step deploy plan: create the MyShop retail Service object in DRAFT (unpublished) with only its identity — name, permission, payment token type, description, and location. Machine binding, sales (WIP), order_allocators, Contact (um), and publish are each separate later steps and are intentionally NOT bundled here.",
4
+ "tags": ["service", "retail", "ecommerce", "draft", "create", "12-step"],
5
5
  "industry": "retail",
6
6
  "operation_type": "service",
7
- "source": "myshop mainnet deployment 2026-07-29",
8
- "verified": true,
9
- "network": "mainnet",
7
+ "source": "myshop deployment walkthrough (docs/examples/MyShop) — adapted to the 12-step plan + testnet (DRAFT only, schema-validated)",
8
+ "verified": false,
9
+ "network": "testnet",
10
10
  "call": {
11
11
  "tool": "onchain_operations",
12
12
  "operation_type": "service",
@@ -20,69 +20,19 @@
20
20
  "replaceExistName": true
21
21
  },
22
22
  "description": "MyShop - Top quality toys for children",
23
- "location": "Online Store",
24
- "machine": "myshop_machine_v2",
25
- "order_allocators": {
26
- "description": "Order revenue allocation - merchant withdraw after completion",
27
- "threshold": 0,
28
- "allocators": [
29
- {
30
- "guard": "myshop_withdraw_guard_v2",
31
- "sharing": [
32
- {
33
- "who": { "Signer": "signer" },
34
- "sharing": 10000,
35
- "mode": "Rate"
36
- }
37
- ]
38
- },
39
- {
40
- "guard": "myshop_refund_guard_v2",
41
- "sharing": [
42
- {
43
- "who": { "GuardIdentifier": 0 },
44
- "sharing": 10000,
45
- "mode": "Rate"
46
- }
47
- ]
48
- }
49
- ]
50
- },
51
- "sales": {
52
- "op": "add",
53
- "sales": [
54
- {
55
- "name": "Play Purse Set 35PCS",
56
- "price": 50000000,
57
- "stock": 100,
58
- "suspension": false,
59
- "wip": "https://wowok.net/test/three_body.wip",
60
- "wip_hash": ""
61
- },
62
- {
63
- "name": "Tree House Building Set",
64
- "price": 30000000,
65
- "stock": 75,
66
- "suspension": false,
67
- "wip": "https://wowok.net/test/three_body.wip",
68
- "wip_hash": ""
69
- }
70
- ]
71
- },
72
- "um": "myshop_aftersales_contact_v2",
73
- "publish": true
23
+ "location": "Online Store"
74
24
  },
75
25
  "env": {
76
26
  "account": "myshop_merchant",
77
- "network": "mainnet",
78
- "confirmed": true
27
+ "network": "testnet",
28
+ "no_cache": true
79
29
  }
80
30
  },
81
31
  "notes": [
82
- "order_allocators is PERMANENTLY IMMUTABLE after publish (service.move:503)",
83
- "Withdraw allocator uses Signer recipient — safe ONLY because withdraw_guard binds Signer to myshop_merchant",
84
- "Refund allocator uses GuardIdentifier 0 (Order object address) as escrow — customer claims separately",
85
- "Rate mode uses 0-10000 scale (10000 = 100%)",
86
- "Machine, order_allocators, and arbitrations become immutable after publish"
32
+ "12-STEP PLAN alignment: this file is ONE step (Step 3 Service DRAFT). The full order is Account → Permission → Service DRAFT → Machine → Guard → Machine publish → Sales(WIP) → Treasury(optional) → order_allocators → Contact(um) → Arbitration → Service publish. Do NOT bundle machine/sales/order_allocators/um/publish into the create call.",
33
+ "object uses the OBJECT form of TypeNamedObjectWithPermissionSchema: name/permission/type_parameter go INSIDE object; description and location are top-level Service fields. No publish:true here — the Service stays unpublished until Step 12.",
34
+ "Physical-goods services SHOULD declare customer_required (e.g. name/phone/shipping_address) so the buyer's delivery info is captured. Per the SDK-enforced HARD LINKAGE, customer_required must be set TOGETHER with a Contact bound as um (the private info is delivered only through the Contact's end-to-end encrypted Messenger). Therefore customer_required is NOT set in this DRAFT — it is set together with um in the Contact step (see retail-myshop-contact-create.json, then bind um + customer_required in one update).",
35
+ "permission references the pre-created myshop_permission_v2 (Step 2); type_parameter '0x2::wow::WOW' sets the payment token (WOW, 9 decimals). onChain:false keeps the local name private (not published on-chain).",
36
+ "machine, order_allocators, and arbitrations become immutable after publish — set them in their own pre-publish steps, not here."
87
37
  ]
88
38
  }
@@ -0,0 +1,31 @@
1
+ {
2
+ "title": "Bind Contact (um) + customer_required Together (MyShop Retail)",
3
+ "description": "Contact step (12-step plan): set the Service's customer_required labels and bind its Contact (um) in ONE operation. The SDK enforces the HARD LINKAGE — customer_required without um is rejected, because the buyer's private information (name/phone/shipping_address) is delivered only through the Contact's end-to-end encrypted Messenger.",
4
+ "tags": ["service", "customer_required", "um", "contact", "messenger", "retail", "hard-linkage", "12-step"],
5
+ "industry": "retail",
6
+ "operation_type": "service",
7
+ "source": "adapted to the 12-step plan + SDK customer_required⟶um hard linkage (schema-validated)",
8
+ "verified": false,
9
+ "network": "testnet",
10
+ "call": {
11
+ "tool": "onchain_operations",
12
+ "operation_type": "service",
13
+ "data": {
14
+ "object": "myshop_service_v2",
15
+ "customer_required": ["name", "phone", "shipping_address"],
16
+ "um": "myshop_aftersales_contact_v2"
17
+ },
18
+ "env": {
19
+ "account": "myshop_merchant",
20
+ "network": "testnet",
21
+ "no_cache": true
22
+ }
23
+ },
24
+ "notes": [
25
+ "HARD LINKAGE (SDK-enforced, service.ts checkCustomerRequiredNeedsUm): customer_required and um MUST be set together. The buyer's private info is delivered via end-to-end encrypted Messenger, which routes to the Contact bound as um — without um there is no channel and the SDK rejects the call with InvalidParam.",
26
+ "object is the STRING form (existing unpublished service); customer_required is an array of info labels (NotEmptyNameSchema); um is the Contact name/ID created in the Contact step (see retail-myshop-contact-create.json).",
27
+ "ORDER FLOW: after a customer places an order on this Service, they MUST send each customer_required field to this Contact's Messenger (messenger_operation → send_message) and obtain an explicit confirmation reply; the resulting Contact ID or WTS Proof can be recorded on the Order via OrderNewSchema.order_required_info.",
28
+ "customer_required and um remain MUTABLE after publish (L3 in the immutability matrix), but for physical goods set them BEFORE publish so customers get the right flow from day one.",
29
+ "The referenced Contact (myshop_aftersales_contact_v2) must exist and have an ims[] entry pointing at the merchant's Messenger account (account name, not messenger name)."
30
+ ]
31
+ }
@@ -1,10 +1,10 @@
1
1
  {
2
- "title": "Create Signature-Approval Machine with Permission-Gated Forwards (ThreeBody Signature)",
3
- "description": "Two-node signing workflow 'Book Delivered -> Signature Completed'. Each forward is gated by its own permissionIndex (1000/1001), so only accounts granted that index in the Permission object can advance that stage. Extendable to M-of-N multi-signature gates by adding weighted forwards and raising pair threshold.",
4
- "tags": ["machine", "multisig", "signature", "approval-gate", "permissionIndex", "publish"],
2
+ "title": "Create Signature-Approval Machine DRAFT (ThreeBody Signature)",
3
+ "description": "Step 4 of the 12-step deploy plan: create the two-node signing workflow 'Book Delivered -> Signature Completed' in DRAFT (unpublished). Each forward is gated by its own permissionIndex (1000/1001), so only accounts granted that index in the Permission object can advance that stage. Publish is a separate later step (machine-publish.json) — do NOT bundle publish here.",
4
+ "tags": ["machine", "multisig", "signature", "approval-gate", "permissionIndex", "draft", "12-step"],
5
5
  "industry": "general",
6
6
  "operation_type": "machine",
7
- "source": "docs/examples/ThreeBody_Signature — schema-validated, not chain-verified",
7
+ "source": "docs/examples/ThreeBody_Signature — adapted to the 12-step plan (DRAFT only, schema-validated)",
8
8
  "verified": false,
9
9
  "network": "testnet",
10
10
  "call": {
@@ -53,20 +53,19 @@
53
53
  ]
54
54
  }
55
55
  ]
56
- },
57
- "publish": true
56
+ }
58
57
  },
59
58
  "env": {
60
59
  "account": "signer_author",
61
- "network": "testnet",
62
- "confirmed": true
60
+ "network": "testnet"
63
61
  }
64
62
  },
65
63
  "notes": [
64
+ "12-STEP PLAN alignment: this is ONE step (Step 4 Machine DRAFT). Do NOT bundle publish:true here — publish is Step 6 (see machine-publish.json). The 12-step order is Service DRAFT → Machine (nodes/forwards) → Guard → bind Guards → Machine publish.",
66
65
  "Shapes verified against MachineNodeSchema / MachineNodePairSchema / MachineForwardSchema (schema/query/index.ts) + CallMachine_DataSchema (schema/call/machine.ts). Forwards use camelCase permissionIndex (namedOperator is the alternative); the schema-level one-of refine requires namedOperator OR permissionIndex on every forward.",
67
- "Entry-forward invariants satisfied: pair with prev_node='' has >=1 forward (FIX-002), and publish:true on a NEW machine requires an entry forward (FIX-02 refine) — 'Confirm Delivery' covers both.",
66
+ "Entry-forward invariant satisfied: pair with prev_node='' has >=1 forward (FIX-002). The FIX-02 publish-time entry-forward refine will also pass when this DRAFT is later published — 'Confirm Delivery' covers both.",
68
67
  "Threshold semantics: pair 1 threshold 0 is exempt (single-forward pair — one signature advances). Pair 2 threshold 1 equals the summed weight of its single forward. MULTI-SIG EXTENSION: add more forwards {permissionIndex or namedOperator, weight} to the pair and set threshold > 1 — the node only advances once accumulated signature weight >= threshold (e.g. 2-of-3 approvers).",
69
- "publish: true IRREVERSIBLY locks nodes/pairs/forwards — env.confirmed: true required (ConfirmGate).",
68
+ "This is a DRAFT (no publish:true). Once published, nodes/pairs/forwards become irreversibly locked and env.confirmed:true is required at publish time.",
70
69
  "DESENSITIZED: doc account 'three_body_author' -> 'signer_author'; objects renamed to local marks 'threebody_machine' / 'threebody_permission'."
71
70
  ]
72
71
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "title": "Configure Order Allocators with Entity-Treasury Recipient (ThreeBody Signature)",
3
- "description": "Pre-publish Service configuration: 100% of completed-order funds route to the fixed Treasury object via an allocator Guard that verifies order.service == this service. Entity(treasury) recipient makes the fund flow caller-independent (no Signer binding needed). Also sets customer_required contact fields.",
3
+ "description": "Pre-publish Service configuration step (12-step plan: order_allocators): 100% of completed-order funds route to the fixed Treasury object via an allocator Guard that verifies order.service == this service. Entity(treasury) recipient makes the fund flow caller-independent (no Signer binding needed).",
4
4
  "tags": ["service", "order_allocators", "treasury-first", "allocation", "guard", "signature"],
5
5
  "industry": "general",
6
6
  "operation_type": "service",
@@ -29,8 +29,7 @@
29
29
  ]
30
30
  }
31
31
  ]
32
- },
33
- "customer_required": ["phone", "email", "shipping_address"]
32
+ }
34
33
  },
35
34
  "env": {
36
35
  "account": "signer_author",
@@ -43,7 +42,7 @@
43
42
  "Rate mode: sharing 10000 = 100% (basis points); Rate items in one allocator must sum to 10000 when no Surplus item exists. threshold 0 allows allocation of any balance.",
44
43
  "ORDER_ALLOCATORS IS PERMANENTLY IMMUTABLE AFTER PUBLISH (service.move:503) — this call must run BEFORE publish:true; the Service must also be unpublished when the machine field was bound earlier.",
45
44
  "Prerequisite objects (created by separate calls, not shown): 'threebody_signature_service' (service, unpublished), 'threebody_allocator_guard' (guard: logic_equal[query order.service, identifier(service)]), 'threebody_treasury' (treasury sharing this service's permission).",
46
- "customer_required entries validated against NotEmptyNameSchema (non-empty, <=64 bcs chars).",
45
+ "HARD LINKAGE: if this Service also declares customer_required (private info the buyer must send), it MUST set customer_required TOGETHER with a Contact bound via `um` (same operation, in a pre-publish step) — the SDK rejects customer_required without um because the buyer's private info is delivered only through the Contact's end-to-end encrypted Messenger.",
47
46
  "DESENSITIZED: doc account 'three_body_author' -> 'signer_author'; objects renamed to local marks ('threebody_signature_service', 'threebody_treasury', 'threebody_allocator_guard')."
48
47
  ]
49
48
  }
@@ -1,10 +1,10 @@
1
1
  {
2
- "title": "Create and Publish Multi-Segment Travel Machine with Forward Guards",
3
- "description": "Create a 5-node Iceland travel workflow Machine (entry -> Buy Insurance -> SPA -> Ice Scooting -> Complete/Cancel) and publish it in one transaction. Three forwards are gated by Guards: weather oracle check (go_ice_scooting), time-lock (complete_trip), and always-pass cancel (cancel_trip). Each forward uses a distinct permissionIndex.",
4
- "tags": ["machine", "travel", "workflow", "forward-guard", "publish", "multi-node"],
2
+ "title": "Create Multi-Segment Travel Machine DRAFT with Forward Guards",
3
+ "description": "Step 4 of the 12-step deploy plan: create a 5-node Iceland travel workflow Machine in DRAFT (unpublished): (init) -> Buy Insurance -> SPA -> Ice Scooting -> Complete/Cancel. Three forwards are gated by Guards: weather oracle check (go_ice_scooting), time-lock (complete_trip), and always-pass cancel (cancel_trip). Publish is a separate later step (machine-publish.json).",
4
+ "tags": ["machine", "travel", "workflow", "forward-guard", "multi-node", "draft", "12-step"],
5
5
  "industry": "travel",
6
6
  "operation_type": "machine",
7
- "source": "docs/examples/Travel — schema-validated, not chain-verified",
7
+ "source": "docs/examples/Travel — adapted to the 12-step plan (DRAFT only, schema-validated)",
8
8
  "verified": false,
9
9
  "network": "testnet",
10
10
  "call": {
@@ -114,23 +114,22 @@
114
114
  ]
115
115
  }
116
116
  ]
117
- },
118
- "publish": true
117
+ }
119
118
  },
120
119
  "env": {
121
120
  "account": "travel_provider",
122
121
  "network": "testnet",
123
- "no_cache": true,
124
- "confirmed": true
122
+ "no_cache": true
125
123
  }
126
124
  },
127
125
  "notes": [
126
+ "12-STEP PLAN alignment: this is ONE step (Step 4 Machine DRAFT). Do NOT bundle publish:true here — publish is Step 6 (see machine-publish.json). The 12-step order is Service DRAFT → Machine (nodes/forwards) → Guard → bind Guards → Machine publish.",
128
127
  "Multi-segment workflow pattern: 5 nodes form a linear chain with a terminal fork — Ice Scooting has TWO outgoing paths (complete_trip -> Complete, cancel_trip -> Cancel), each guarded differently. Demonstrates per-forward Guard binding (Forward.guard) combined with per-forward permissionIndex, the canonical way to put conditional gates on workflow transitions.",
129
- "Schema check (call/machine.ts CallMachine_DataSchema, strict): 'object' uses the OBJECT form of WithPermissionObjectSchema (NamedObjectWithPermissionSchema — name, permission, replaceExistName); node uses NodeSchema op='add' with bReplace:true + nodes array; publish=true on NEW machine creation triggers the FIX-02 entry-forward refine — satisfied because the 'Buy Insurance' pair has prev_node='' with a non-empty forwards list (FIX-002).",
128
+ "Schema check (call/machine.ts CallMachine_DataSchema, strict): 'object' uses the OBJECT form of WithPermissionObjectSchema (NamedObjectWithPermissionSchema — name, permission, replaceExistName); node uses NodeSchema op='add' with bReplace:true + nodes array; publish omitted → DRAFT. The FIX-02 entry-forward refine (applied at publish time) is satisfied because the 'Buy Insurance' pair has prev_node='' with a non-empty forwards list (FIX-002).",
130
129
  "Pair/forward semantics (query/index.ts MachineNodePairSchema): forwards describe INCOMING transitions — the forward in a node's pair (prev_node='X') is the action that advances Progress FROM X INTO this node. Field is 'prev_node' (NOT 'prior_node' — that name only appears in the separate 'add forward'/'remove forward' ops). threshold is per-pair; weight sums across the pair's forwards must reach threshold to advance.",
131
130
  "Forward check (query/index.ts MachineForwardSchema, strict — only name/namedOperator/permissionIndex/weight/guard allowed): every forward provides permissionIndex (1000-1004), satisfying the one-of namedOperator/permissionIndex refine (namedOperator:'' is the order-owner wildcard alternative). Guarded forwards use the OBJECT guard form {guard: '<name>', retained_submission: []} (MachineForwardGuardSchema); a plain string shorthand 'guard': '<name>' is also accepted via preprocess when no retained_submission is needed.",
132
131
  "Guard evaluation order: Forward.guard verifies BEFORE the transition executes, so a forward Guard querying THIS progress's progress.current sees the SOURCE node, not the target. Here weather_check_guard queries an external Repository (safe) and travel_complete_guard queries time-lock data (safe); neither checks progress.current == target, which would always fail.",
133
- "publish:true is IRREVERSIBLE and freezes the node set — nodes cannot be changed after publish, and only published Machines can bind to a Service (service.machine). Guards referenced by name (weather_check_guard, travel_complete_guard, travel_cancel_guard) and the Permission (travel_permission, with indexes 1000-1004 granted to the operator) must exist BEFORE this call — see the sibling travel-guard-weather-oracle / travel-guard-time-lock examples and Travel doc Steps 1/3.",
132
+ "This is a DRAFT (no publish:true). Once published, nodes are irreversibly frozen and env.confirmed:true is required at publish time. Only published Machines can bind to a Service (service.machine). Guards referenced by name (weather_check_guard, travel_complete_guard, travel_cancel_guard) and the Permission (travel_permission, with indexes 1000-1004 granted to the operator) must exist BEFORE publish — see the sibling travel-guard-weather-oracle / travel-guard-time-lock examples and Travel doc Steps 1/3.",
134
133
  "Desensitization: doc payload already uses generic local-mark names only (travel_provider, travel_machine, travel_permission, guard names); no real personal data, phone numbers, or raw 0x object addresses present — nothing replaced."
135
134
  ]
136
135
  }