@wowok/skills 1.1.6 → 1.1.8

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.
@@ -9,7 +9,7 @@ description: |
9
9
  Covers Machine architecture (Nodes, Pairs, Forwards, Guards, Thresholds),
10
10
  lifecycle management (create, configure, publish, pause), node operations
11
11
  (add, exchange, rename, granular forward/prior-node manipulation),
12
- Progress integration, cross-service sub-order creation, privacy-preserving
12
+ Progress integration, cross-Machine supply chain composition via Guard verification, privacy-preserving
13
13
  consensus patterns, and export/import workflows via machineNode2file.
14
14
  when_to_use:
15
15
  - User wants to create or modify a Machine workflow
@@ -24,108 +24,69 @@ when_to_use:
24
24
 
25
25
  Design, build, and operate automated workflow templates.
26
26
 
27
- > **Role**: Service Provider or Workflow Designer
28
- > **Key Tools**: `onchain_operations` with `operation_type: "machine"`
27
+ > **Role**: Service Provider or Workflow Designer
28
+ > **Key Tools**: `onchain_operations` with `operation_type: "machine"`
29
29
  > **Related Skills**: [wowok-guard](../wowok-guard/SKILL.md) (Guards), [wowok-provider](../wowok-provider/SKILL.md) (Service binding), [wowok-order](../wowok-order/SKILL.md) (customer perspective), [wowok-messenger](../wowok-messenger/SKILL.md) (privacy), [wowok-safety](../wowok-safety/SKILL.md) (safety), [wowok-tools](../wowok-tools/SKILL.md) (schema reference)
30
30
 
31
31
  ---
32
32
 
33
33
  ## Core Concepts
34
34
 
35
- ### What is a Machine?
35
+ **Machine** = workflow blueprint (directed graph of Nodes → Pairs → Forwards). **Progress** = live workflow instance, one per order.
36
36
 
37
- A Machine is a **workflow template** a directed graph that defines how orders progress from creation to completion. Machines can be bound to Services (one-to-many) or operate standalone for collaborative workflows. When bound to a Service, the Machine is instantiated as a **Progress** object when an order is created. The Machine defines the rules; the Progress tracks the live execution.
38
-
39
- **Key Analogy**: Machine = workflow blueprint, Progress = live workflow instance.
40
-
41
- ### Immutability Rules
42
-
43
- | Object | When Immutable | Impact |
44
- |--------|---------------|--------|
45
- | **Machine** | After `publish: true` | All nodes are locked; workflow topology frozen |
46
- | **Guard** | After creation | CREATE-only, cannot modify |
47
-
48
- Because published Machines are immutable, you must design the complete workflow before publishing. However, before publishing, nodes can be freely added, removed, renamed, and reorganized.
49
-
50
- ---
37
+ Machines are **immutable after `publish: true`**; Guards are **CREATE-only**. Design the complete workflow before publishing.
51
38
 
52
39
  ## Machine Architecture
53
40
 
54
- ### The Building Blocks
55
-
56
- A Machine is composed of three structural layers:
57
-
58
41
  ```
59
42
  Machine
60
- └── Nodes (up to 200)
61
- └── Pairs (up to 40 per node)
62
- ├── prev_node: which prior node this pair connects from
43
+ └── Nodes
44
+ └── Pairs
45
+ ├── prev_node: which prior node ("" = entry point, multiple allowed)
63
46
  ├── threshold: required total forward weight to advance
64
- └── Forwards (up to 20 per pair)
65
- ├── name: operation identifier
66
- ├── weight: contribution toward threshold
47
+ └── Forwards (MachineForward)
48
+ ├── name, weight
67
49
  ├── permissionIndex | namedOperator: who can execute
68
50
  └── guard (optional): condition that must pass
69
51
  ```
70
52
 
71
- **Schema Reference**: `schema_query({ action: "get", name: "onchain_operations_machine" })`
72
-
73
- ### Node
74
-
75
- A Node represents a **stage or state** in the workflow. Each node has a unique name and contains one or more Pairs defining how to reach it and what Forwards are available from it.
76
-
77
- Node names must be unique within a Machine. The empty string (`""`) represents the initial state — any Pair with `prev_node: ""` is an entry point. A Machine can have multiple entry nodes, each with its own threshold configuration.
78
-
79
- ### Pair (NodePair)
53
+ > **Schema**: `schema_query({ action: "get", name: "onchain_operations_machine" })` — all field types, limits, valid values. This document focuses on design decisions **not captured** by the schema.
80
54
 
81
- A Pair connects a previous node to the current node, defining:
82
- - **`prev_node`**: Source node name (`""` for entry point)
83
- - **`threshold`**: Total weight required to trigger advancement
84
- - **`forwards`**: Available operations from this Pair
55
+ ### Forward Permission Model
85
56
 
86
- A Node can have multiple Pairs, enabling multi-path entry (e.g., "Completed" from both "Normal" and "Express" delivery).
87
-
88
- ### Forward
89
-
90
- A Forward is a **named operation** that users execute to advance the workflow. Each Forward has:
91
-
92
- - **`name`**: A descriptive operation identifier (e.g., "Confirm Order", "Ship Goods", "Complete Signature").
93
- - **`weight`**: A 16-bit unsigned integer (0-65535) representing this Forward's contribution toward the threshold. When the sum of completed Forward weights in the current session meets or exceeds the Pair's threshold, the node transition triggers.
94
- - **`permissionIndex`** and/or **`namedOperator`**: At least one must be specified — both can be set simultaneously, in which case the executor needs EITHER permission to execute the Forward.
95
-
96
- **Permission Model**:
97
-
98
- | Field | Scope | Typical Use |
57
+ | Field | Scope | When to Use |
99
58
  |-------|-------|-------------|
100
- | `permissionIndex` | Shared across ALL Progress instances from this Machine | Internal roles (merchant operators, admins) — same personnel handle all workflow instances |
101
- | `namedOperator` | Per-Progress namespace | External roles that differ per workflow instance |
102
-
103
- - Use `namedOperator: ""` (empty string) to grant order owner and their agents the right to execute the Forward. This is the standard way to let customers operate on their own orders.
104
- - Use `namedOperator: "<role_name>"` for role-based operators managed per Progress instance — ideal when different orders have different delivery personnel or reviewers.
105
- - **Both set**: When `permissionIndex` AND `namedOperator` are both specified, the executor needs EITHER permission to execute the Forward — the permissions act as alternatives. This is useful when the same operation should be executable by either internal staff (via `permissionIndex`) or external roles (via `namedOperator`).
59
+ | `permissionIndex` | Shared across ALL Progress instances | Internal staff (warehouse, admin, platform) — same for every order |
60
+ | `namedOperator` | Per-Progress namespace | Roles that differ per order (delivery person, reviewer, agent) |
106
61
 
107
- **Best Practice**: Forwards should use **custom permissions** rather than built-in indices to avoid management chaos. Either create a dedicated Permission object via `onchain_operations` with `operation_type: "permission"`, or add custom indices to an existing Permission object. Define workflow-specific roles, then reference those indices in your Forwards. Query the Permission schema via `schema_query({ action: "get", name: "onchain_operations_permission" })`.
62
+ - `namedOperator: ""` (empty string): grants **order owner and agents** the right to execute. Standard way to let customers operate.
63
+ - `namedOperator: "<role_name>"`: role-based operators managed per Progress instance. Each Progress independently assigns addresses to role names.
64
+ - **Both fields set**: executor needs EITHER permission — internal staff OR external roles.
65
+ - **Design principle**: Use custom permissions (dedicated Permission object with custom indices), not built-in indices. Define workflow-specific roles, reference those indices in Forwards.
108
66
 
109
67
  ### Guard on Forwards
110
68
 
111
- A Forward can include a **Guard** an on-chain validation rule that must pass for the Forward to complete. Guards are IMMUTABLE after creation.
69
+ A Guard validates the Forward's execution condition. **Retained submissions**: when `retained_submission` is set on a Guard, submitted values are stored in Progress history, uniquely located by `(current_node, next_node, forward_name)`. Later nodes query these values from history.
112
70
 
113
- **Common uses**: Time-locks, external condition checks, sub-order validation, penalty verification.
71
+ > **Guard construction**: See [wowok-guard](../wowok-guard/SKILL.md) for table design, computation trees, and query instructions.
114
72
 
115
- **Retained submissions**: When a Forward's Guard has `retained_submission` set, the submitted values are stored in Progress history. Each retained value is uniquely located by the triple `(current_node, next_node, forward_name)` — subsequent nodes query these via `query_progress_history_*`. Design Guard tables with this in mind: any `b_submission: true` entry that should carry forward to later nodes must be included in `retained_submission`.
73
+ ### Threshold Mechanics
116
74
 
117
- > **Guard Design Reference**: See [wowok-guard](../wowok-guard/SKILL.md) for full Guard construction table design, computation trees, data extraction patterns, and the type constraints each object imposes on Guard submissions.
75
+ Users execute Forwards from the current node, accumulating weight within a **session**. When the sum of completed Forward weights meets or exceeds the Pair's threshold, the session finalizes and the workflow advances.
118
76
 
119
- ### Threshold Mechanics
77
+ **Session behavior**: Each Forward is counted once per session. Repeated execution of the same Forward within one session adds no extra weight. A completed Forward cannot be re-executed until session reset (on node transition).
120
78
 
121
- The threshold is the **trigger value** for node advancement. Users execute Forwards from the current node, accumulating weight. When the **sum of completed Forward weights threshold**, the session finalizes: completed Forwards move to history, and the workflow advances to the next node.
79
+ **Competing Transitions**: If a node has multiple Pairs to different targets, the **first Pair to meet its threshold wins** — remaining incomplete Forwards in other Pairs are **abandoned**. Competing paths are mutually exclusive by design. A Pair whose threshold can never be met because users always prefer another path creates a **dead branch**.
122
80
 
123
- **Competing Transitions**: If a node has multiple Pairs leading to different next nodes, the first Pair to meet its threshold wins — subsequent completions go to the newly active node. This enables competitive workflows where different paths race to completion.
81
+ **Execution Patterns**:
124
82
 
125
- **Parallel vs Sequential Execution**: By configuring thresholds and weights, you control task coordination:
126
- - **Sequential**: `threshold = 1`, single Forward with `weight = 1` — one completion triggers advancement
127
- - **Parallel (AND)**: `threshold = N`, N Forwards each with `weight = 1` all must complete before advancing
128
- - **Parallel (OR)**: Multiple Pairs from same node, each with `threshold = 1` first completion wins, enabling branching paths like `A→B→C` vs `A→C` where B is optional
83
+ | Pattern | Mechanism | Use Case |
84
+ |---------|-----------|----------|
85
+ | Sequential | `threshold=1`, single Forward `weight=1` | Single actor each step |
86
+ | Parallel AND | `threshold=N`, N Forwards `weight=1` | All parties must contribute |
87
+ | Parallel OR | Multiple Pairs, each `threshold=1` | Mutually exclusive branches |
88
+ | Weighted Voting | `threshold=100`, varied weights (e.g., 60+40) | Unequal stakeholder power |
89
+ | Hybrid | `threshold=5`, mixed weights (3+1+1) | Key party required, others optional |
129
90
 
130
91
  ---
131
92
 
@@ -133,56 +94,82 @@ The threshold is the **trigger value** for node advancement. Users execute Forwa
133
94
 
134
95
  ### Dependency-First Construction
135
96
 
136
- A Machine depends on a **Permission** object. Build in this order:
97
+ Build in this exact order:
137
98
 
138
99
  ```
139
- 1. Permission (CREATE or MODIFY to add indices) → provides access control foundation; add custom indices anytime for Forwards
140
- 2. Machine (CREATE, unpublished) → define structure and ALL nodes
141
- 3. Guards (CREATE) → build conditions needed by Forwards
142
- 4. Bind Guards to Forwards (MODIFY Machine) → add guard references to specific forwards
143
- 5. Publish Machine → nodes become IMMUTABLE
144
- 6. Bind Machine to Service (MODIFY Service) machine field
100
+ 1. Permission (CREATE/MODIFY) → access control foundation
101
+ 2. Machine (CREATE, unpublished) → define all nodes
102
+ 3. Guards (CREATE) → build validation conditions
103
+ 4. Bind Guards to Forwards (MODIFY Machine) → set `guard` on each Forward; all operations (`add`, `set`, `add forward`) accept full `MachineForward` including `guard` + `retained_submission`
104
+ 5. Publish Machine → nodes IMMUTABLE
105
+ 6. Bind Machine to Service workflow goes live
145
106
  ```
146
107
 
147
- **Schema Reference**: Query all Machine operations via `schema_query({ action: "get", name: "onchain_operations_machine" })`. This includes configuration (description, repository binding, pause control, publish, owner receive, contact binding, progress creation, etc.) and node manipulation operations.
108
+ **Why this order matters**: Publishing locks the Machine. Guards are immutable. Publishing before Guards are ready means Guards can never be added the Machine is frozen without validation rules. **Create Guards, test them, then publish.**
148
109
 
149
110
  ### Node Operations (Pre-Publish Only)
150
111
 
151
- Use the `node` field with `op` value: `"add"`, `"set"`, `"remove"`, `"clear"`, `"exchange"`, `"rename"`, `"remove prior node"`, `"add forward"`, `"remove forward"`.
112
+ Nine operations are available via the `node` field. Query schema for full parameters. Key design notes not captured by schema:
113
+
114
+ - `add` / `set` with `bReplace: false` (default) **merges** into existing nodes; `true` replaces all.
115
+ - `clear` is **irreversible** — instant wipe with no undo. Export via `machineNode2file` first.
116
+ - `exchange` swaps two node positions without delete/recreate. `rename` auto-updates all Pair references.
117
+ - `add forward` supports the full `MachineForward` structure including `guard` with `retained_submission`.
152
118
 
153
- **File-based Workflow**: Export via `machineNode2file`, edit, then import via `node.json_or_markdown_file`.
119
+ > **Schema**: `schema_query({ action: "get", name: "onchain_operations_machine" })` for full operation parameters.
120
+
121
+ ### File-Based Workflow
122
+
123
+ ```
124
+ 1. machineNode2file → export nodes to JSON/Markdown
125
+ 2. Edit locally
126
+ 3. node.json_or_markdown_file → COMPLETE REPLACEMENT of all nodes
127
+ ```
128
+
129
+ Always start from an on-chain export when available — exact current state beats rebuilding from scratch.
154
130
 
155
131
  ---
156
132
 
157
133
  ## Progress: The Live Workflow Instance
158
134
 
135
+ ### Machine vs Progress
136
+
137
+ - **Machine**: Workflow blueprint — defines the topology, permissions, thresholds, and Guards. Shared across all orders.
138
+ - **Progress**: Live instance — tracks current node, session state, history. One per order (when Service-bound) or standalone.
139
+
159
140
  ### Progress Creation
160
141
 
161
- Progress objects are created in two ways:
162
- - **Service Order**: When an Order is created on a Service with a bound Machine, Progress is automatically instantiated
163
- - **Direct Creation**: Via `progress_new` operation with appropriate permissions
142
+ Two paths: **Service Order** (automatic when Order created on Service with bound Machine) or **Direct Creation** (via `progress_new`). For direct creation, pre-configure via `progress_new` fields on the Machine operation — this sets initial named operators, task binding, and repository list before the first Progress is spawned.
164
143
 
165
- ### Progress Operations
144
+ ### Execution Paths
166
145
 
167
- **Order-associated Progress** (when Forward with `namedOperator: ""`): Must advance via `order` operations.
146
+ - **Order-associated Progress**: When a Forward uses `namedOperator: ""`, the order owner/agents execute via `order` operations.
147
+ - **Standalone Progress**: All other cases — advance via direct `progress` operations.
168
148
 
169
- **All other cases**: Advance via direct `progress` operations.
149
+ Two-phase operations (`hold`/`unhold`) allow locking resources during multi-step operations; `adminUnhold` force-releases stale locks.
170
150
 
171
- **Advancing Progress**:
151
+ > **Querying**: Progress state via `onchain_objects`, history via `onchain_table` / `onchain_table_item_progress_history`. Schema: `schema_query({ action: "get", name: "onchain_table_data" })`.
172
152
 
173
- Use `operate` field with `next_node_name`, `forward`, and optional `hold` for two-phase operation (lock with `hold: true`, submit with `hold: false`). Use `adminUnhold: true` to force-release locks.
153
+ ### Runtime: Advancing the Workflow
174
154
 
175
- **Progress-level config**: `repository`, `progress_namedOperator`, `task(cannot be changed once set)`.
155
+ The runtime loop (schema: `onchain_operations` with `operation_type: "progress"` or `"order"`):
176
156
 
177
- ### Querying Progress State
157
+ ```
158
+ 1. Query active Forwards → onchain_objects reveals current node name and available Pairs/Forwards
159
+ 2. Execute Forward → weight accumulates in session; Guard validates (pass/fail);
160
+ retained_submission stores values indexed by (current_node, next_node, forward_name)
161
+ 3. Threshold met → session commits to history (all completed Forwards recorded);
162
+ node transitions; session resets; new Forwards unlocked
163
+ 4. OR threshold NOT met → session stays open; more Forwards can execute in same session;
164
+ weight from repeated same Forwards ignored
165
+ 5. OR competing Pair wins first → other incomplete Pairs abandoned; next session starts on winner node
166
+ ```
178
167
 
179
- **Tools**:
168
+ **What the user sees**: At any node, callers can discover which Forwards are available (by querying the Machine definition and cross-referencing with their permissions). Executing a Forward that requires a Guard triggers Guard verification — the caller must submit required data. Successful Forward execution is recorded on-chain; failed Guard rejections are visible as transaction errors.
180
169
 
181
- - `query_toolkit` with `query_type: "onchain_objects"` query the Progress object to see its current node, sessions, and metadata.
182
- - `query_toolkit` with `query_type: "onchain_table"` — query all history records from Progress table (paginated)
183
- - `query_toolkit` with `query_type: "onchain_table_item_progress_history"` — query single history record by sequence number
170
+ **Session lifecycle**: A session begins when the first Forward executes from a new node. It stays open until threshold is met (closing the session and advancing) or the order completes/aborts. No session timeout — sessions persist until resolved. `hold`/`unhold` lock the session during multi-step external operations; `adminUnhold` force-releases stale locks.
184
171
 
185
- **Schema Reference**: `schema_query({ action: "get", name: "onchain_table_data" })`
172
+ > **Order-associated execution**: Forwards with `namedOperator: ""` are executable via `order` operations by the order owner/agents. All other Forwards use `progress` operations. See [wowok-order](../wowok-order/SKILL.md) for the customer execution flow.
186
173
 
187
174
  ---
188
175
 
@@ -202,85 +189,84 @@ Shipping → Delivery Complete → Order Complete
202
189
  └──→ Return Complete
203
190
  ```
204
191
 
205
- ### Sub-Order Creation (Supply Chain)
192
+ ### Cross-Machine Supply Chain Composition
206
193
 
207
- **Business Intent**: When advancing a Forward, automatically create a sub-order on another Service committing to use a trusted supplier.
194
+ Decompose complex workflows into multiple Machines connected by Guard-based validationavoiding monolithic bloat.
208
195
 
209
- ```
210
- Start → Buy Insurance (creates sub-order on Insurance Service) → Main Activity → Complete
211
- ```
212
-
213
- **Key Characteristics**:
214
- - The Forward uses `forward_to_order_create` to specify the target Service for the sub-order
215
- - The Guard on the Forward validates that the sub-order was successfully created
216
- - Useful for supply chain transparency: "We use X supplier" becomes verifiable on-chain
196
+ **Sub-Progress Dependency**: Machine A's Forward Guards query Machine B's Progress to verify it has reached a target node before advancing.
217
197
 
218
- **Real Example Travel** (insurance sub-order):
219
- - Forward "Buy Insurance" on the "Start" node creates a sub-order on the Insurance Service
220
- - The Insurance sub-order follows its own Machine workflow independently
221
- - Both workflows (Travel and Insurance) progress in parallel
198
+ **Sub-Order Verification**: Machine A's Forward Guard validates an Order exists on another Service with its Progress at the required state. The sub-order is created independently — the Guard only verifies.
222
199
 
223
- ### Dual-Signature Consensus
224
-
225
- Require both parties (customer and merchant) to confirm before advancing — used for sensitive operations like returns, lost packages, and completion.
200
+ **Multi-Party Chain**: Supplier → Manufacturer → Retailer, each Machine's entry condition verifies upstream completion via Guards querying `retained_submission` values.
226
201
 
227
- - Threshold: 2 with two Forwards each of weight: 1
228
- - One Forward uses `namedOperator: ""` (customer), the other uses `permissionIndex` (merchant)
229
- - Both must execute before the node transitions
202
+ **When to decompose** into multiple Machines:
203
+ - A sub-process is independently valuable as a standalone Service
204
+ - Different participant sets operate in different phases
205
+ - The sub-process is reusable across multiple parent workflows
230
206
 
231
- ---
207
+ **When to keep in one**:
208
+ - Same participants and permission model throughout
209
+ - Dense sequential data flow with no clear boundary
232
210
 
233
- ## Privacy & Off-Chain Consensus
211
+ **Questions to ask the user**:
212
+ 1. "Are there phases handled by different teams or services?"
213
+ 2. "Could any part be offered as a standalone service?"
214
+ 3. "Does any step depend on an external process completing first?"
215
+ 4. "Which party creates the sub-order, and which party verifies it?"
234
216
 
235
- ### The Messenger Pattern
217
+ > **Guard construction**: Cross-Machine Guards use `convert_witness` with Progress query instructions. See [wowok-guard](../wowok-guard/SKILL.md). Query available Guard instructions via `wowok_buildin_info`.
236
218
 
237
- Sensitive data (addresses, tracking numbers) flows through Messenger's end-to-end encryption — never stored on-chain. Only **Merkle Root** (cryptographic proof) goes on-chain.
219
+ ### Dual-Signature Consensus
238
220
 
239
- **The principle**: **Who performs the key action, submits the proof.** The other party confirms.
221
+ Require both customer and merchant to confirm: `threshold=2` with two Forwards (`namedOperator: ""` for customer, `permissionIndex` for merchant), each `weight=1`. Both must execute to advance.
240
222
 
241
- | Scenario | Off-Chain Action | On-Chain Proof |
242
- |----------|-----------------|----------------|
243
- | Merchant ships order | Receives address via Messenger, replies with tracking number | Merchant submits Merkle Root to Guard on Forward |
244
- | Customer returns item | Sends return tracking number via Messenger | Customer submits Merkle Root to Guard on Forward |
245
- | Mutual confirmation | Both parties sign via Messenger | Both submit confirmation proofs |
223
+ ### Privacy (Messenger)
246
224
 
247
- The Merkle Root Guard validates that the communication matches the expected content pattern, ensuring accountability without exposing private data.
225
+ Sensitive data flows through Messenger's end-to-end encryption; only Merkle Root proofs go on-chain. The principle: **who performs the action submits the proof**.
248
226
 
249
227
  > **Full Guide**: See [wowok-messenger](../wowok-messenger/SKILL.md) for WTS evidence generation.
250
228
 
251
229
  ---
252
230
 
253
- ## Service Penalty Pattern
254
-
255
- Handle service failures through automated compensation workflows. Guards validate penalty payments before allowing continuation.
256
-
257
- ### Late Delivery Penalty Pattern
231
+ ## Common Pitfalls
258
232
 
259
- **Design**: The Shipping node has two Forwards — one for on-time delivery (no guard), one for late delivery (guard checks if past deadline). The late path requires a Guard that verifies a Payment from the merchant to the customer's Order before allowing progression.
233
+ ### Mutability Traps
260
234
 
261
- **Benefits**:
262
- - Automatic enforcement late delivery cannot proceed without compensation
263
- - Cryptographically verified payment
264
- - Customer protection guarantee
265
- - Service accountability
235
+ All stem from the same root: **every on-chain object has a publish/create freeze point**. See [Guard + Machine Immutability Deadlock](#guard--machine-immutability-deadlock). Key rules:
236
+ - Never publish before all Guards are created, tested, and bound.
237
+ - `clear` is irreversible — export via `machineNode2file` first.
266
238
 
267
- > **Schema**: `schema_query({ action: "get", name: "onchain_operations_payment" })`
239
+ ### Pre-Publish Validation Checklist
268
240
 
269
- ---
241
+ Before `publish: true`, verify:
270
242
 
271
- ## Common Pitfalls
272
-
273
- - **Publish before Guards ready** Cannot add after publish
274
- - **No entry pair** (`prev_node: ""`) Workflow cannot start
275
- - **Orphaned paths** Orders get stuck
276
- - **Wrong permission model** Unauthorized access or lockout
277
- - **Machine without Allocator design** Fund distribution mismatch (map terminal nodes to allocators)
243
+ - [ ] **Entry point exists**: at least one Pair with `prev_node: ""` — workflow cannot start otherwise
244
+ - [ ] **Every node has outgoing Forwards** (except terminals): no dead-end nodes
245
+ - [ ] **Every node has incoming Pair** (except entry): no orphaned nodes
246
+ - [ ] **All thresholds independently achievable**: no dead branches (competing Pair always wins first)
247
+ - [ ] All Guards exist on-chain and tested (use `gen_passport`)
248
+ - [ ] `namedOperator` vs `permissionIndex` correct per Forward
249
+ - [ ] Every Forward has at least one of `namedOperator` or `permissionIndex`
250
+ - [ ] Terminal nodes mapped to Allocator entries for fund distribution
251
+ - [ ] Tested end-to-end on testnet via a test Progress
252
+ - [ ] Current state exported via `machineNode2file` as backup
278
253
 
279
254
  **Always test on testnet before mainnet** — Machines are immutable after publish.
280
255
 
281
256
  ---
282
257
 
283
- ## Quick Reference
258
+ ## Guard + Machine Immutability Deadlock
259
+
260
+ Both Guards and published Machines are **immutable**:
261
+
262
+ ```
263
+ Guard created with bug → Cannot fix (immutable)
264
+ → Must create new Guard
265
+ → Must rebind to Machine
266
+ → Machine already published? Cannot modify (immutable)
267
+ → DEADLOCK: new Guard exists but cannot be attached
268
+ ```
284
269
 
285
- **Limits**: 200 nodes, 40 Pairs/node, 20 Forwards/Pair | Weight: u16 | Threshold: u32
270
+ **Prevention**: Test every Guard via `gen_passport` before binding. Verify computation tree, submission types, and query instructions against all scenarios.
286
271
 
272
+ **If deadlocked**: Only recovery is a completely new Machine with new nodes and Guard bindings, then rebind to Service. Keep Machines unpublished until all Guards are verified.