@wowok/skills 1.3.4 → 2.0.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.
@@ -1,6 +1,6 @@
1
1
  # Iceland Travel Service Example
2
2
 
3
- A complete example demonstrating how to create an Iceland travel service using WoWok protocol. This service integrates weather-dependent activities, insurance sub-orders, and multi-node workflow management.
3
+ A complete example demonstrating how to create an Iceland travel service using WoWok protocol. This service integrates weather-dependent activities and multi-node workflow management. (Note: "Buy Insurance" is just the name of the first workflow node in this example — there is no real insurance sub-order mechanism.)
4
4
 
5
5
  ---
6
6
 
@@ -320,13 +320,46 @@ Create a Permission object to manage access control for the travel service. Add
320
320
  }
321
321
  ```
322
322
 
323
- > **Note**: Permission indices 1000-1009 are used for different workflow forwards. Index 306 is a reserved administrative permission. The travel_provider account is granted all these permissions.
323
+ > **Note**: Permission indices 1000-1009 are used for different workflow forwards. Index 306 is the built-in `SERVICE_MACHINE` permission — it governs binding or changing a Service's Machine (`service::machine_set`), and is required in Step 5 when the Service binds `travel_machine`. The travel_provider account is granted all these permissions.
324
+
325
+ ---
326
+
327
+ ## Step 1.5: Create Arbitration Permission
328
+
329
+ Create a dedicated Permission object for the Arbitration. No special permission indices are needed — the creator (`travel_provider`) automatically becomes the admin of the new Permission.
330
+
331
+ > **Why a separate Permission?** When a Service binds an Arbitration, the contract asserts `arbitration.permission != service.permission` (error `E_ARBITRATION_PERMISSION_CONFLICT`). If the Arbitration shared the Service's permission, the Service owner would control dispute resolution, breaking fairness. The Arbitration must therefore use an independent Permission object.
332
+
333
+ **Prompt**: Create a Permission object named "travel_arbitration_permission" for the arbitration.
334
+
335
+ ```json
336
+ {
337
+ "tool": "onchain_operations",
338
+ "data": {
339
+ "operation_type": "permission",
340
+ "data": {
341
+ "object": {
342
+ "name": "travel_arbitration_permission",
343
+ "tags": ["travel", "arbitration"],
344
+ "replaceExistName": true
345
+ },
346
+ "description": "Independent permission for travel arbitration (must differ from the Service permission)"
347
+ },
348
+ "env": {
349
+ "account": "travel_provider",
350
+ "network": "testnet",
351
+ "no_cache": true,
352
+ "confirmed": true
353
+ }
354
+ }
355
+ }
356
+ ```
324
357
 
325
358
  ---
326
359
 
327
360
  ## Step 2: Create Arbitration Object
328
361
 
329
- Create an Arbitration object for dispute resolution.
362
+ Create an Arbitration object for dispute resolution. It uses the independent `travel_arbitration_permission` created in Step 1.5.
330
363
 
331
364
  **Prompt**: Create an Arbitration named "travel_arbitration".
332
365
 
@@ -338,7 +371,7 @@ Create an Arbitration object for dispute resolution.
338
371
  "data": {
339
372
  "object": {
340
373
  "name": "travel_arbitration",
341
- "permission": "travel_permission",
374
+ "permission": "travel_arbitration_permission",
342
375
  "replaceExistName": true
343
376
  },
344
377
  "description": "Arbitration for Iceland travel service disputes"
@@ -1063,7 +1096,7 @@ Create a Machine to define the travel service workflow with all nodes and forwar
1063
1096
  | Complete | Ice Scooting | complete_trip | 1002 | travel_complete_guard |
1064
1097
  | Cancel | Ice Scooting | cancel_trip | 1003 | travel_cancel_guard |
1065
1098
 
1066
- > **Note**: The `prev_node` field uses an empty string `""` to denote the entry point. Each node defines how to enter it from a previous node. The `threshold` field (required) specifies the minimum forward weight needed to trigger node advancement.
1099
+ > **Note**: The `prev_node` field uses an empty string `""` to denote the entry point. Each node defines how to enter it from a previous node. The `threshold` field (optional, defaults to `0`) specifies the minimum forward weight needed to trigger node advancement.
1067
1100
 
1068
1101
  ---
1069
1102
 
@@ -1114,7 +1147,6 @@ Configure the travel service (created unpublished in Step 2.5) with all bindings
1114
1147
  "allocators": [
1115
1148
  {
1116
1149
  "guard": "merchant_victory_guard",
1117
- "fix": "0",
1118
1150
  "sharing": [
1119
1151
  {
1120
1152
  "who": {"Entity": {"name_or_address": "travel_treasury"}},
@@ -1125,7 +1157,6 @@ Configure the travel service (created unpublished in Step 2.5) with all bindings
1125
1157
  },
1126
1158
  {
1127
1159
  "guard": "no_ice_scooting_guard",
1128
- "fix": "0",
1129
1160
  "sharing": [
1130
1161
  {
1131
1162
  "who": {"Entity": {"name_or_address": "travel_treasury"}},
@@ -1141,7 +1172,6 @@ Configure the travel service (created unpublished in Step 2.5) with all bindings
1141
1172
  },
1142
1173
  {
1143
1174
  "guard": "no_spa_guard",
1144
- "fix": "0",
1145
1175
  "sharing": [
1146
1176
  {
1147
1177
  "who": {"Entity": {"name_or_address": "travel_treasury"}},
@@ -1281,7 +1311,8 @@ Move from initial node ("") to "Buy Insurance" node.
1281
1311
  "operation": {
1282
1312
  "next_node_name": "Buy Insurance",
1283
1313
  "forward": "buy_insurance"
1284
- }
1314
+ },
1315
+ "op": "next"
1285
1316
  }
1286
1317
  },
1287
1318
  "env": {
@@ -1310,7 +1341,8 @@ Move from "Buy Insurance" to "SPA" node.
1310
1341
  "operation": {
1311
1342
  "next_node_name": "SPA",
1312
1343
  "forward": "go_spa"
1313
- }
1344
+ },
1345
+ "op": "next"
1314
1346
  }
1315
1347
  },
1316
1348
  "env": {
@@ -1339,7 +1371,8 @@ Move from "SPA" to "Ice Scooting" node. This forward has a Guard (`weather_check
1339
1371
  "operation": {
1340
1372
  "next_node_name": "Ice Scooting",
1341
1373
  "forward": "go_ice_scooting"
1342
- }
1374
+ },
1375
+ "op": "next"
1343
1376
  }
1344
1377
  },
1345
1378
  "submission": {
@@ -1395,7 +1428,8 @@ Move from "Ice Scooting" to "Complete" node. This forward has a Guard (`travel_c
1395
1428
  "operation": {
1396
1429
  "next_node_name": "Complete",
1397
1430
  "forward": "complete_trip"
1398
- }
1431
+ },
1432
+ "op": "next"
1399
1433
  }
1400
1434
  },
1401
1435
  "submission": {
@@ -1430,7 +1464,7 @@ Move from "Ice Scooting" to "Complete" node. This forward has a Guard (`travel_c
1430
1464
  }
1431
1465
  ```
1432
1466
 
1433
- > **Note**: Replace `<ORDER_OBJECT_ID>` with the actual Order object ID (e.g., `0x7cc9f2228e130c2f6b585bb9c4666fd4d03252d38048355678f46e31b682eb38`). You can query the Progress object to find the `task` field which contains the Order ID.
1467
+ > **Note**: Replace `<ORDER_OBJECT_ID>` with the actual Order object ID (a 64-hex-character string starting with `0x`). You can query the Progress object to find the `task` field which contains the Order ID.
1434
1468
  >
1435
1469
  > **Key**: The `submission` field is at the **top level** of the input (alongside `data` and `env`), NOT inside `data`. The `impack: true` means the Guard verification result affects the final outcome.
1436
1470
 
@@ -1451,7 +1485,8 @@ Move from "Ice Scooting" to "Complete" node. This forward has a Guard (`travel_c
1451
1485
  "operation": {
1452
1486
  "next_node_name": "Cancel",
1453
1487
  "forward": "cancel_trip"
1454
- }
1488
+ },
1489
+ "op": "next"
1455
1490
  }
1456
1491
  },
1457
1492
  "submission": {
@@ -1487,6 +1522,7 @@ Move from "Ice Scooting" to "Complete" node. This forward has a Guard (`travel_c
1487
1522
  | `data.object` | string | Progress object name/ID |
1488
1523
  | `data.operate.operation.next_node_name` | string | Target node name to move to |
1489
1524
  | `data.operate.operation.forward` | string | Forward name defined in Machine |
1525
+ | `data.operate.op` | string | **Required.** Operation type: `"next"` (advance the forward), `"hold"`, `"unhold"`, or `"adminUnhold"` |
1490
1526
  | `submission` | object | Guard verification data (top-level, required when forward has Guard) |
1491
1527
  | `env.no_cache` | boolean | Set to `true` to avoid stale cache issues |
1492
1528
 
@@ -1524,7 +1560,7 @@ The allocation Guard requires the Order ID as a submission (identifier: 0). Quer
1524
1560
 
1525
1561
  ### 8.2 Execute Allocation (Merchant Victory Path)
1526
1562
 
1527
- When the Progress is "Complete", the `merchant_victory_guard` passes, and 100% of funds go to the Service object.
1563
+ When the Progress is "Complete", the `merchant_victory_guard` passes, and 100% of funds go to the Treasury (`travel_treasury`).
1528
1564
 
1529
1565
  **Prompt**: Execute fund allocation with the merchant_victory_guard, submitting the Order ID.
1530
1566
 
@@ -1577,7 +1613,7 @@ When the Progress is "Complete", the `merchant_victory_guard` passes, and 100% o
1577
1613
 
1578
1614
  For refund scenarios (Cancel or SPA), use the corresponding Guard. The same submission structure applies — the Order ID is submitted to identifier 0.
1579
1615
 
1580
- **Cancel/Ice Scooting path** (80% Service, 20% Order):
1616
+ **Cancel/Ice Scooting path** (80% Treasury, 20% Order (escrow, claimable by the order owner)):
1581
1617
 
1582
1618
  ```json
1583
1619
  {
@@ -1601,7 +1637,7 @@ For refund scenarios (Cancel or SPA), use the corresponding Guard. The same subm
1601
1637
  }
1602
1638
  ```
1603
1639
 
1604
- **SPA path** (5% Service, 95% Order):
1640
+ **SPA path** (5% Treasury, 95% Order (escrow, claimable by the order owner)):
1605
1641
 
1606
1642
  ```json
1607
1643
  {
@@ -1660,6 +1696,57 @@ After allocation, query the Allocation and Payment objects to verify the fund di
1660
1696
 
1661
1697
  > **Important**: `alloc_by_guard` accepts Guard names (e.g., `"merchant_victory_guard"`) or Guard object IDs. The Guard must exist in the Allocation's `allocators` list. Only the first Guard that passes (first-Guard-wins) triggers fund distribution.
1662
1698
 
1699
+ ### 8.5 Claim Allocated Funds (Unwrap CoinWrapper)
1700
+
1701
+ Allocation does not deposit spendable coins directly. `alloc_by_guard` distributes **CoinWrapper objects** to each recipient address — these must be claimed/unwrapped before the funds are spendable:
1702
+
1703
+ - **Treasury share** (`Entity` → `travel_treasury`): the CoinWrapper is sent to the Treasury object address. The travel provider deposits it into the Treasury balance via the Treasury `receive` operation.
1704
+ - **Customer share** (`GuardIdentifier: 0` → the Order object address submitted at runtime, i.e. escrow): the CoinWrapper is sent to the Order object address. The order owner (Alice) claims it via the Order `receive` operation, which unwraps it and transfers the coins to her wallet.
1705
+
1706
+ **Prompt**: Alice claims the customer share escrowed to the Order (refund paths only).
1707
+
1708
+ ```json
1709
+ {
1710
+ "tool": "onchain_operations",
1711
+ "data": {
1712
+ "operation_type": "order",
1713
+ "data": {
1714
+ "object": "alice_travel_order",
1715
+ "receive": "recently"
1716
+ },
1717
+ "env": {
1718
+ "account": "alice",
1719
+ "network": "testnet",
1720
+ "no_cache": true,
1721
+ "confirmed": true
1722
+ }
1723
+ }
1724
+ }
1725
+ ```
1726
+
1727
+ **Prompt**: The travel provider deposits the Treasury's share into the Treasury balance.
1728
+
1729
+ ```json
1730
+ {
1731
+ "tool": "onchain_operations",
1732
+ "data": {
1733
+ "operation_type": "treasury",
1734
+ "data": {
1735
+ "object": "travel_treasury",
1736
+ "receive": "recently"
1737
+ },
1738
+ "env": {
1739
+ "account": "travel_provider",
1740
+ "network": "testnet",
1741
+ "no_cache": true,
1742
+ "confirmed": true
1743
+ }
1744
+ }
1745
+ }
1746
+ ```
1747
+
1748
+ > **Note**: `"receive": "recently"` auto-queries and claims all recently received CoinWrapper objects. For the Order, `receive` unwraps them and transfers the coins to the order owner (Alice); for the Treasury, `receive` deposits the unwrapped coins into the Treasury's balance. In the merchant-victory path (100% to Treasury) only the Treasury claim is needed; the Order claim applies only to refund paths (8.3) where the customer has a share.
1749
+
1663
1750
  ---
1664
1751
 
1665
1752
  ## Best Practices
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@wowok/skills",
3
- "version": "1.3.4",
4
- "description": "WoWok AI Skills for Claude and other AI assistants - Helping AI use WoWok MCP tools correctly",
3
+ "version": "2.0.1",
4
+ "description": "WoWok AI Skills for Claude and other AI assistants - Dialogue orchestration layer on top of the WoWok MCP server (rules/reference knowledge is served by MCP directly since v2.0.0)",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "bin": {
@@ -11,15 +11,11 @@
11
11
  "dist/",
12
12
  "wowok-provider/",
13
13
  "wowok-arbitrator/",
14
- "wowok-guard/",
15
- "wowok-tools/",
16
- "wowok-safety/",
17
14
  "wowok-machine/",
18
15
  "wowok-order/",
19
16
  "wowok-messenger/",
20
17
  "wowok-output/",
21
18
  "wowok-onboard/",
22
- "wowok-scenario/",
23
19
  "wowok-planner/",
24
20
  "wowok-auditor/",
25
21
  "examples/",
@@ -16,22 +16,47 @@ const path = require('path');
16
16
  const os = require('os');
17
17
  const { execSync } = require('child_process');
18
18
 
19
+ /**
20
+ * Retained skills (post GLM5-31 sink refactor) — only these are installed.
21
+ * The 4 rule-reference skills (wowok-safety/tools/scenario/guard) were sunk
22
+ * into the MCP knowledge layer and are served by the MCP server directly:
23
+ * - wowok-safety → schema_query action='get_safety_rules'
24
+ * - wowok-tools → schema_query action='get_tool_reference'
25
+ * - wowok-scenario → project_operation recommend_industry / create_project
26
+ * - wowok-guard → schema_query action='get_guard_design_patterns'
27
+ */
19
28
  const SKILL_DIRS = [
20
29
  'wowok-provider',
21
30
  'wowok-arbitrator',
22
31
  'wowok-order',
23
32
  'wowok-messenger',
24
- 'wowok-guard',
25
33
  'wowok-machine',
26
34
  'wowok-output',
27
- 'wowok-tools',
28
- 'wowok-safety',
29
35
  'wowok-onboard',
30
- 'wowok-scenario',
31
36
  'wowok-planner',
32
37
  'wowok-auditor',
33
38
  ];
34
39
 
40
+ /**
41
+ * Deprecated skills removed in the GLM5-31 sink refactor. They are NEVER
42
+ * installed, but preuninstall/init still clean them up from legacy installs
43
+ * and warn the user where the content now lives.
44
+ */
45
+ const LEGACY_SKILL_DIRS = [
46
+ 'wowok-guard',
47
+ 'wowok-tools',
48
+ 'wowok-safety',
49
+ 'wowok-scenario',
50
+ ];
51
+
52
+ /** Where each deprecated skill's content now lives (migration message). */
53
+ const SKILL_MIGRATION_MAP = {
54
+ 'wowok-safety': "MCP schema_query action='get_safety_rules'",
55
+ 'wowok-tools': "MCP schema_query action='get_tool_reference'",
56
+ 'wowok-scenario': "MCP project_operation action='recommend_industry' / 'create_project'",
57
+ 'wowok-guard': "MCP schema_query action='get_guard_design_patterns'",
58
+ };
59
+
35
60
  const CLIENT_DIRS = {
36
61
  claude: path.join(os.homedir(), '.claude', 'skills'),
37
62
  cursor: path.join(os.homedir(), '.cursor', 'rules'),
@@ -172,7 +197,9 @@ function installSkills(targetDir, target) {
172
197
  function uninstallSkills(targetDir) {
173
198
  let count = 0;
174
199
 
175
- for (const dir of SKILL_DIRS) {
200
+ // Remove both retained and legacy (deprecated) skills — legacy dirs may
201
+ // still exist from pre-refactor installs and must be cleaned up.
202
+ for (const dir of [...SKILL_DIRS, ...LEGACY_SKILL_DIRS]) {
176
203
  const dirPath = path.join(targetDir, dir);
177
204
  if (fs.existsSync(dirPath)) {
178
205
  removeDir(dirPath);
@@ -184,6 +211,23 @@ function uninstallSkills(targetDir) {
184
211
  return count;
185
212
  }
186
213
 
214
+ /**
215
+ * Detect deprecated skills still present in a target dir and print a
216
+ * migration hint (GLM5-31 §3.2). Returns the list of legacy dirs found.
217
+ */
218
+ function warnLegacySkills(targetDir) {
219
+ const found = LEGACY_SKILL_DIRS.filter((dir) => fs.existsSync(path.join(targetDir, dir)));
220
+ if (found.length > 0) {
221
+ console.warn(`[wowok-skills] ⚠ MIGRATION: deprecated skills detected in ${targetDir}:`);
222
+ for (const dir of found) {
223
+ console.warn(`[wowok-skills] - ${dir} → content now served by ${SKILL_MIGRATION_MAP[dir]}`);
224
+ }
225
+ console.warn('[wowok-skills] These skills are stale (MCP knowledge layer is the source of truth).');
226
+ console.warn('[wowok-skills] Remove them with: wowok-skills uninit (or delete the folders above)');
227
+ }
228
+ return found;
229
+ }
230
+
187
231
  function getTargets() {
188
232
  const envTargets = process.env.WOWOK_SKILLS_TARGETS;
189
233
  if (!envTargets) {
@@ -206,6 +250,8 @@ function main() {
206
250
  console.log(`[wowok-skills] → ${dir}`);
207
251
  const count = installSkills(dir, target);
208
252
  total += count;
253
+ // GLM5-31 §3.2: warn about stale pre-refactor skills still present.
254
+ warnLegacySkills(dir);
209
255
  }
210
256
 
211
257
  console.log(`[wowok-skills] Done — ${total} skills installed across ${targets.length} client(s).`);
@@ -256,7 +302,7 @@ function main() {
256
302
 
257
303
  function countExisting(targetDir) {
258
304
  let count = 0;
259
- for (const dir of SKILL_DIRS) {
305
+ for (const dir of [...SKILL_DIRS, ...LEGACY_SKILL_DIRS]) {
260
306
  if (fs.existsSync(path.join(targetDir, dir))) {
261
307
  count++;
262
308
  }
@@ -30,7 +30,7 @@ The following content has been pushed down to the MCP knowledge layer and is app
30
30
  |---------|---------------------|-------------|
31
31
  | Guard design rules (structural layers, data source classification, voting_guard table design) | `knowledge/guard-design-patterns.ts` (`GUARD_DESIGN_PATTERNS`) | `project_operation.evaluate_project` (via `assessGuardRisks`) |
32
32
  | Safety rules (confirmation levels, immutability, object reuse) | `knowledge/safety-rules.ts` (`CONFIRMATION_RULES`) | Pre-publish checks + `project_operation.evaluate_project` |
33
- | Arbitration-specific risks | `knowledge/arb-risk.ts` (`assessArbitrationRisks`) | `project_operation.evaluate_project` |
33
+ | Arbitration-specific risks | `knowledge/arbitration-risk.ts` (`assessArbitrationRisks`) | `project_operation.evaluate_project` |
34
34
 
35
35
  This Skill keeps the arbitration **conversation flow**, **evidence collection** scripts, and **dispute resolution** guidance — the MCP layer handles the rule evaluation.
36
36
 
@@ -53,7 +53,7 @@ This Skill keeps the **audit flow**, the **4 audit dimensions** (Guard completen
53
53
  3. **FAIL blocks, WARN asks**: A FAIL verdict blocks R10 publish until fixed. A WARN verdict proceeds after explicit user acknowledgement. PASS is silent.
54
54
  4. **Blast-radius first**: Before reporting, classify each issue by irreversibility — a Guard logic bug post-publish is permanent; an untested Guard is recoverable.
55
55
  5. **Semantic-aware**: Use the `semantic` field returned by recent operations (`semantic.created`, `semantic.modified`, `semantic.released`, `semantic.events`) to cross-check that the intended roles were actually created/modified/released.
56
- 6. **Tiered**: A Tier-1 audit (single Service + single Guard) skips R4 Machine soundness if no Machine is bound. Tier-3 runs every rule including cross-Machine dependency chains.
56
+ 6. **Tiered**: A Tier-1 audit (single Service + single Guard) skips Machine soundness if no Machine is bound. Tier-3 runs every rule including cross-Machine dependency chains.
57
57
 
58
58
  ---
59
59
 
@@ -234,7 +234,7 @@ All stem from the same root: **every on-chain object has a publish/create freeze
234
234
  | `refunded` (terminal) | `refund_routing` (routing) → Allocator fires |
235
235
  | N/A (dispute) | `arbiter_rule` (routing) → Arbitration off-Machine (no Allocator) |
236
236
 
237
- See [wowok-scenario](../wowok-scenario/SKILL.md) "Rental Mode Template (R-M1-11 Compliant)" for a complete 10-node rental topology.
237
+ A complete R-M1-11-compliant rental topology is auto-generated by `project_operation.create_project` with `project_industry='rental'` (MCP `knowledge/scenario-modes.ts`).
238
238
 
239
239
  ### Pre-Publish Validation Checklist
240
240
 
@@ -245,7 +245,7 @@ Before `publish: true`, verify:
245
245
  - [ ] **Every node has outgoing Forwards** (except terminals): no dead-end nodes
246
246
  - [ ] **Every node has incoming Pair** (except entry): no orphaned nodes
247
247
  - [ ] **All thresholds independently achievable**: no dead branches (competing Pair always wins first)
248
- - [ ] **⚠ R-M1-11 Compliance** (CRITICAL for deposit/refund scenarios): NO terminal nodes named `deposit_refunded`, `deposit_deducted`, `refunded`, or any name implying Machine-internal refund/deduction. Refund/deduction MUST flow through an **Allocator** triggered by a routing node (e.g., `return_approved`, `damage_confirmed`, `arbiter_rule`). Violating this causes funds to lock in the Machine with no Allocator path. See [wowok-scenario](../wowok-scenario/SKILL.md) "Rental Mode Template (R-M1-11 Compliant)".
248
+ - [ ] **⚠ R-M1-11 Compliance** (CRITICAL for deposit/refund scenarios): NO terminal nodes named `deposit_refunded`, `deposit_deducted`, `refunded`, or any name implying Machine-internal refund/deduction. Refund/deduction MUST flow through an **Allocator** triggered by a routing node (e.g., `return_approved`, `damage_confirmed`, `arbiter_rule`). Violating this causes funds to lock in the Machine with no Allocator path. Auto-enforced by MCP pre-publish checks and `project_operation.evaluate_project`.
249
249
  - [ ] All Guards exist on-chain and tested (use `gen_passport`)
250
250
  - [ ] `namedOperator` vs `permissionIndex` correct per Forward
251
251
  - [ ] Every Forward has at least one of `namedOperator` or `permissionIndex`
@@ -25,8 +25,9 @@ always: false
25
25
  End-to-end encrypted messaging with tamper-proof audit trails.
26
26
 
27
27
  > **Role**: Any WoWok participant
28
- > All 16 operations with full parameter types and constraints are in the MCP schema (`messenger_operation`). This document focuses on **design decisions and strategy** not captured by the schema.
29
- > **Related Skills**: [wowok-guard](../wowok-guard/SKILL.md) (guard design), [wowok-arbitrator](../wowok-arbitrator/SKILL.md) (WTS evidence in disputes), [wowok-order](../wowok-order/SKILL.md) (customer perspective), [wowok-provider](../wowok-provider/SKILL.md) (service provider perspective), [wowok-safety](../wowok-safety/SKILL.md) (safety)
28
+ > All 17 operations with full parameter types and constraints are in the MCP schema (`messenger_operation`). This document focuses on **design decisions and strategy** not captured by the schema.
29
+ > **Related Skills**: [wowok-arbitrator](../wowok-arbitrator/SKILL.md) (WTS evidence in disputes), [wowok-order](../wowok-order/SKILL.md) (customer perspective), [wowok-provider](../wowok-provider/SKILL.md) (service provider perspective)
30
+ > Guard design patterns and safety rules now live in the MCP knowledge layer — query via `schema_query` actions `get_guard_design_patterns` / `get_safety_rules`.
30
31
 
31
32
  ---
32
33
 
@@ -71,7 +72,7 @@ The on-chain **Contact** object (`operation_type: "contact"`) is the bridge betw
71
72
 
72
73
  **When to create**: Before Service publish, when `customer_required` is set (Service.um must point to a Contact). Reuse an existing Contact if you serve multiple Services with the same support channel.
73
74
 
74
- **Lifecycle**: Contact is mutable (unlike Proof/Guard). `im_add`/`im_remove` require permission index 453 (CONTACT_IM). No events emitted on IM mutations — poll `ims[]` field. If Contact is bound to `Permission.um` via `permission_um_set`, clear that binding BEFORE deleting the Contact (else dangling pointer). Full business guidance: [wowok-tools](../wowok-tools/SKILL.md) §"Contact (Service.um Bridge)".
75
+ **Lifecycle**: Contact is mutable (unlike Proof/Guard). `im_add`/`im_remove` require permission index 453 (CONTACT_IM). No events emitted on IM mutations — poll `ims[]` field. If Contact is bound to `Permission.um` via `permission_um_set`, clear that binding BEFORE deleting the Contact (else dangling pointer). Full field constraints: MCP `schema_query` action='get' name='contact'.
75
76
 
76
77
  ---
77
78
 
@@ -85,6 +86,7 @@ Two approaches, depending on need:
85
86
 
86
87
  - **Quick glance** — `watch_conversations` with `unreadOnly: true` lists all conversations with unread messages, sorted by activity. Each conversation shows a preview of the last messages.
87
88
  - **Deep dive** — `watch_messages` with a specific `peerAddress` to view the full conversation with a particular counterparty. Supports keyword search, time-range filtering, direction filter, and status filter.
89
+ - **Server sync** — `pull_messages` fetches the latest messages from the server into local storage (optional `limit` caps batch size). Use this first when the local view looks stale (e.g. after downtime or on a new device session), then read via `watch_conversations` / `watch_messages`.
88
90
 
89
91
  **Design note**: By default, retrieving messages auto-marks them as viewed (`viewedAt` timestamp). Set `skipAutoMarkViewed: true` if you want to peek without marking read.
90
92
 
@@ -50,7 +50,7 @@ The onboarding skill dismantles the "16 operation_type × 14 object_type" wall.
50
50
 
51
51
  - Converts "I want to open a shop" into a 10-round guided build plan
52
52
  - Industry defaults auto-applied via `project_operation.create_project` (pass `project_industry` parameter; defaults sourced from MCP `knowledge/scenario-modes.ts`)
53
- - Enforces dependency order: Permission → ServiceMachineProgressGuardAllocation → Order → Publish
53
+ - Enforces dependency order: Permission → Machine (create) GuardsMachine (bind guards+publish) Service Phase 1 (configure) Service Phase 2 (publish) Test Order → Mainnet
54
54
  - Persists checkpoints after each round via `local_info_operation` so users can resume
55
55
  - Hands off to [wowok-provider](../wowok-provider/SKILL.md) once the Service is published
56
56
 
@@ -63,7 +63,7 @@ The onboarding skill dismantles the "16 operation_type × 14 object_type" wall.
63
63
 
64
64
  ### Output Contract
65
65
 
66
- A published Service with: published Machine, bound Progress, validated Guards, configured order_allocators, and one successful test order digest. Handoff packet includes all object IDs and the post-publish verification report.
66
+ A published Service with: published Machine, published Service, validated Guards, configured order_allocators, and one successful test order digest (order → progress advance → allocation). Handoff packet includes all object IDs and the post-publish verification report.
67
67
 
68
68
  ---
69
69
 
@@ -74,24 +74,43 @@ The onboarding flow is backed by the MCP SQLite-based project pipeline. Each ste
74
74
  | Step | Rounds | MCP Action | Gate |
75
75
  |------|--------|------------|------|
76
76
  | 1. Create Project | R1-R2 | `create_project` (pass `project_industry`) → project record + scenario defaults | — |
77
- | 2. Add Objects | R3-R8 | `add_object` for each on-chain object (Service, Machine, Guards, Allocators) | — |
78
- | 3. Build Graph | After R8 | `build_graph` → object dependency graph from added objects | — |
77
+ | 2. Add Objects | R2-R7 | `add_object` for each on-chain object (Permission, Machine, Guards, Service) | — |
78
+ | 3. Build Graph | After R7 | `build_graph` → object dependency graph from added objects | — |
79
79
  | 4. Evaluate | After graph built | `evaluate_project` (evaluation_type='risk') → risk assessment | CRITICAL risks block R9 |
80
80
 
81
- ## R1-R10 Build Order
82
-
83
- | Round | Object | MCP Operation | Key Decision |
84
- |-------|--------|---------------|--------------|
85
- | R1 | Account | `account_operation.gen` + `faucet` | New or reuse? |
86
- | R2 | Industry mode | `project_operation.create_project` (pass `project_industry`) | Which driving mode? |
87
- | R3 | Service | `onchain_operations.service` CREATE | Name, type_parameter, description |
88
- | R4 | Permission | `onchain_operations.permission` CREATE/REUSE | Index 1000 = provider/merchant (customer uses `namedOperator:""` = OrderHolder; arbiter is NOT a Permission index — arbiters live in `Arbitration.voting_guard`) |
89
- | R5 | Machine | `onchain_operations.machine` CREATE | Nodes, forwards (mode defaults from MCP) |
90
- | R6 | Progress | `onchain_operations.progress` CREATE + bind | Mirror Machine nodes |
91
- | R7 | Guards | `onchain_operations.guard` CREATE + `gen_passport` test | 5 Guard templates (mode defaults from MCP) |
92
- | R8 | Allocation | `onchain_operations.allocation` CREATE + `service.order_allocators` | Fund split (mode defaults from MCP) |
93
- | R9 | Test order | `onchain_operations.order` CREATE + `progress` advance + `allocation.alloc_by_guard` | Full flow dry run |
94
- | R10 | Publish | `onchain_operations.machine` publish + `service` publish | Pre-publish audit must PASS |
81
+ > **Async mode**: `build_graph` / `evaluate_project` accept `async_mode: true` for large projects — the call returns immediately with a `task_id`. Poll `query_task_status` with that `task_id` until `status: "completed"` before reading results / proceeding to the next step. Default is synchronous (`async_mode` omitted) — fine for the ≤10-object onboarding scale.
82
+
83
+ ## R1-R10 Build Order (MCP-Validated)
84
+
85
+ **Core principles (from MCP schema):**
86
+ - `service.machine` must reference a **published** Machine (Service cannot bind unpublished Machine)
87
+ - `service.order_allocators` is L1-locked MUST be set BEFORE `service.publish` (per service.move:503)
88
+ - Guard uses **LocalMark NAME** in table to break circular dependency (Guard→Service→Guard)
89
+ - `order_new` (test order) only works when `service.bPublished=true` (else E_NOT_PUBLISHED)
90
+ - **Recommended order**: Permission Machine (create nodes/forwards) → Guards → Machine (bind guards to forwards) → Machine (publish) → Service Phase 1 (configure) → Service Phase 2 (publish) → Test Order
91
+
92
+ | Round | Phase | Object | MCP Operation | Key Decision |
93
+ |-------|-------|--------|---------------|--------------|
94
+ | R1 | Foundation | Project + Account | `project_operation.create_project` (pass `project_industry`) + `account_operation.gen` + `faucet` | Industry mode + new/reuse account |
95
+ | R2 | Foundation | Permission | `onchain_operations.permission` CREATE/REUSE | Index 1000 = provider |
96
+ | R3 | Foundation | Machine | `onchain_operations.machine` CREATE (nodes/forwards, guards optional inline) | Nodes, forwards, optional inline guards |
97
+ | R4 | Foundation | Guards | `onchain_operations.guard` CREATE (multiple) | Buy guard, accept guard, refund guard — use LocalMark NAME for Service references |
98
+ | R5 | Foundation | Machine guard binding | `onchain_operations.machine` MODIFY (bind guards to forwards) | `op: "add forward"` or `op: "set"` to update forward guard fields; Machine must still be unpublished |
99
+ | R6 | Foundation | Machine publish | `onchain_operations.machine` publish | Machine must be published before Service can reference it |
100
+ | R7 | Revenue | Service Phase 1 | `onchain_operations.service` CREATE (no publish) + set `machine` + `order_allocators` + `buy_guard` + `sales` + `arbitrations` (if compensation) | All L1-locked fields (machine, order_allocators) MUST be set here |
101
+ | R8 | Audit | Pre-publish audit | `machineNode2file` export + `guard2file` export + `project_operation.evaluate_project` | All CRITICAL risks must be fixed before R9 |
102
+ | R9 | Publish | Service Phase 2 | `onchain_operations.service` publish=true | Only flips publish flag; L1 fields already locked |
103
+ | R10 | Test + Mainnet | Test order + Mainnet | `onchain_operations.service` `order_new` → `onchain_operations.progress` advance → `onchain_operations.allocation` `alloc_by_guard` → Re-run R2-R9 on mainnet | Full flow dry run: order → progress → allocation; Recommend testnet first, then mainnet |
104
+
105
+ **Guard binding to Machine forwards**: Two approaches:
106
+ 1. **Inline (R3)**: Set guards directly in `MachineForwardSchema.guard` during Machine CREATE — guards must already exist
107
+ 2. **Deferred (R5)**: Create Machine first without guards (R3), create Guards (R4), then bind guards to forwards via `op: "add forward"` or `op: "set"` — allows Guards to reference Machine by LocalMark name
108
+
109
+ Use approach 2 when Guards need to reference the Machine (e.g., verify current node or forward name). Use approach 1 for simple Guards that don't reference the Machine.
110
+
111
+ **Circular dependency handling**: Guard that references Service → create Guard first with LocalMark NAME in table (not address), then reference Guard by name in Service Phase 1. LocalMark name is resolved to address at transaction build time.
112
+
113
+ **R-M1-11 compliance** (rental/refund scenarios): Machine MUST use routing nodes (`return_approved`, `damage_confirmed`, `arbiter_rule`), NOT terminal nodes (`deposit_refunded`, `refunded`). Refund is handled by Allocator, not Machine terminal nodes.
95
114
 
96
115
  ---
97
116
 
@@ -104,13 +123,13 @@ When the user describes their business (R2), match to one of the supported indus
104
123
  | `general` | `general` | Free-form / hybrid — no presets, full manual control |
105
124
  | `retail` | `general` (retail profile) | Physical goods sales with stock + WIP product listings |
106
125
  | `service` | `general` (service profile) | Intangible services (consulting, design) — milestone delivery |
107
- | `rental` | `rental` | Equipment / vehicle / property rental with deposit escrow + return inspection (R-M1-11 compliant — uses `return_approved`/`damage_confirmed`/`arbiter_rule` routing nodes, NO `deposit_refunded`/`deposit_deducted`/`refunded` terminal nodes; see [wowok-scenario](../wowok-scenario/SKILL.md) "Rental Mode Template") |
126
+ | `rental` | `rental` | Equipment / vehicle / property rental with deposit escrow + return inspection (R-M1-11 compliant — uses `return_approved`/`damage_confirmed`/`arbiter_rule` routing nodes, NO `deposit_refunded`/`deposit_deducted`/`refunded` terminal nodes; topology auto-applied by `project_operation.create_project` with `project_industry='rental'` from MCP `knowledge/scenario-modes.ts`) |
108
127
  | `freelance` | `freelance` | Design / dev / consulting — milestone allocation + acceptance gate |
109
128
  | `education` | `education` | Courses / training / tutoring — periodic release per session attendance |
110
129
  | `travel` | `travel` | Custom tours / multi-segment trips — multi-tier allocation per segment |
111
130
  | `subscription` | `subscription` | SaaS / content membership / periodic service — periodic charge + cancel guard |
112
131
 
113
- > If unsure which fits, default to `general`. Users can switch modes mid-onboarding (see wowok-scenario "Escape Hatch"). For mode composition (e.g., freelance + subscription retainer), see [wowok-scenario](../wowok-scenario/SKILL.md).
132
+ > If unsure which fits, call `project_operation` action='recommend_industry' with the user's business description — it returns top-3 industry matches with reference examples. To iterate a mode mid-onboarding, use action='derive_user_mode' / 'evolve_user_mode' (user mode registry in MCP).
114
133
 
115
134
  ---
116
135
 
@@ -127,7 +146,7 @@ Before declaring onboarding complete, verify ALL items. Each is a hard gate —
127
146
  | 4 | Allocators configured | Each Allocator `sharing[].sharing` Rate entries sum to **10000** (Rate mode); or `Amount` mode values set. For rental/refund scenarios, verify Allocators' `trigger_node` references the routing nodes (e.g., `return_approved`) — NOT missing (else R-M1-11 refund path is broken) |
128
147
  | 5 | Service created with all bindings | `query_toolkit` (onchain_objects, type=service) → machine, order_allocators, buy_guard all non-empty |
129
148
  | 6 | Service published | `query_toolkit` (onchain_objects, type=service) → `bPublished: true` |
130
- | 7 | Test order placed | R9 test order created + Progress advanced + Allocator triggered successfully |
149
+ | 7 | Test order placed | R9 test order created via `service.order_new` + Progress advanced + Allocator triggered successfully |
131
150
 
132
151
  > If any item fails, do NOT proceed to handoff. Fix the underlying issue, then re-verify. Use `project_operation.evaluate_project` (risk) to auto-detect missing bindings.
133
152
 
@@ -138,9 +157,9 @@ Before declaring onboarding complete, verify ALL items. Each is a hard gate —
138
157
  | Error | Cause | Fix |
139
158
  |-------|-------|-----|
140
159
  | `dynamicFieldNotFound` | SDK cannot resolve a dynamic field reference | Set `env.account` (account not configured) — pass account in the tool call wrapper |
141
- | `Circular dependency` (Guard ↔ Service creation) | Guard needs Service address; Service needs Guard address | Use **LocalMark NAME** (not address) in Guard query table — see [wowok-guard](../wowok-guard/SKILL.md) "Circular Dependency Handling" |
160
+ | `Circular dependency` (Guard ↔ Service creation) | Guard needs Service address; Service needs Guard address | Use **LocalMark NAME** (not address) in Guard query table — pattern documented in MCP `schema_query` action='get_guard_design_patterns' |
142
161
  | `order.balance invalid` | Used wrong field for order amount | Use `order.amount` (not `order.balance` — `balance` is residual escrow, `amount` is original payment) |
143
162
  | Allocator `rate sum != 10000` | Rate-mode Allocator sharing percentages don't sum to 100% | Ensure all `sharing[].sharing` values in Rate mode sum to exactly **10000** basis points (e.g., 80% = 8000) |
144
- | `IMPACK_GUARD_NOT_FOUND` (gen_passport) | Repository query with `quote_guard = Some(addr)` | `impack_list` is empty during verify phase — only `quote_guard = None` passes; see [wowok-guard](../wowok-guard/SKILL.md) |
163
+ | `IMPACK_GUARD_NOT_FOUND` (gen_passport) | Repository query with `quote_guard = Some(addr)` | `impack_list` is empty during verify phase — only `quote_guard = None` passes; see MCP `schema_query` action='get_guard_design_patterns' |
145
164
  | `Permission denied` (Progress advance, abort code 5) | Wrong operation path for forward's `namedOperator` | Empty `namedOperator` → use `order.progress`; non-empty → use `progress.operate`; `permissionIndex` → use `progress.operate` |
146
- | Allocator never fires (refund stuck) — R-M1-11 violation | Machine has a node like `deposit_refunded` instead of routing node `return_approved`; or Allocator's `trigger_node` is missing/mispelled | Rename node to `return_approved` / `damage_confirmed`; bind Allocator to that node; see [wowok-scenario](../wowok-scenario/SKILL.md) "Rental Mode Template (R-M1-11 Compliant)" |
165
+ | Allocator never fires (refund stuck) — R-M1-11 violation | Machine has a node like `deposit_refunded` instead of routing node `return_approved`; or Allocator's `trigger_node` is missing/mispelled | Rename node to `return_approved` / `damage_confirmed`; bind Allocator to that node; R-M1-11 is auto-enforced by MCP pre-publish checks and `project_operation.evaluate_project` |