@wowok/skills 1.1.11 → 1.1.13
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.
- package/examples/Insurance/Insurance.md +142 -23
- package/examples/MyShop/MyShop.md +216 -218
- package/examples/MyShop/myshop_machine_nodes.json +14 -8
- package/examples/MyShop_Advanced/MyShop_Advanced.md +57 -56
- package/examples/ThreeBody_Signature/ThreeBody_Signature.md +431 -111
- package/examples/Travel/Travel.md +64 -18
- package/package.json +1 -1
- package/wowok-arbitrator/APPENDIX.md +545 -0
- package/wowok-arbitrator/SKILL.md +8 -535
- package/wowok-auditor/APPENDIX.md +487 -0
- package/wowok-auditor/SKILL.md +9 -480
- package/wowok-guard/APPENDIX.md +428 -0
- package/wowok-guard/SKILL.md +117 -421
- package/wowok-machine/APPENDIX.md +407 -0
- package/wowok-machine/SKILL.md +9 -400
- package/wowok-messenger/APPENDIX.md +550 -0
- package/wowok-messenger/SKILL.md +9 -543
- package/wowok-onboard/APPENDIX.md +472 -0
- package/wowok-onboard/SKILL.md +10 -465
- package/wowok-order/APPENDIX.md +777 -0
- package/wowok-order/SKILL.md +110 -506
- package/wowok-output/APPENDIX.md +575 -0
- package/wowok-output/SKILL.md +9 -568
- package/wowok-planner/APPENDIX.md +700 -0
- package/wowok-planner/SKILL.md +9 -693
- package/wowok-provider/APPENDIX.md +425 -0
- package/wowok-provider/SKILL.md +8 -415
- package/wowok-safety/APPENDIX.md +561 -0
- package/wowok-safety/SKILL.md +9 -554
- package/wowok-scenario/APPENDIX.md +97 -0
- package/wowok-scenario/MODE-DETAILS.md +275 -0
- package/wowok-scenario/SKILL.md +20 -353
- package/wowok-tools/APPENDIX.md +388 -0
- package/wowok-tools/SKILL.md +9 -381
package/wowok-guard/SKILL.md
CHANGED
|
@@ -53,7 +53,30 @@ Every Guard is built from three layers, each with a distinct role:
|
|
|
53
53
|
|
|
54
54
|
**The root is the question**: It must return Bool. Intermediate nodes return numbers, strings, addresses, or vectors. Guard is **strongly typed** — the type system is strictly enforced at creation time. Type mismatches (e.g., passing a string to a numeric comparison node) will cause validation errors and prevent Guard creation.
|
|
55
55
|
|
|
56
|
-
**The rely is composition**: Up to 4 dependent Guards. When `rely.logic_or` is false (default), all dependencies must pass (AND). When true, any passing is sufficient (OR). A Guard can only depend on Guards with `rep: true` — `rep`
|
|
56
|
+
**The rely is composition**: Up to 4 dependent Guards. When `rely.logic_or` is false (default), all dependencies must pass (AND). When true, any passing is sufficient (OR). A Guard can only depend on Guards with `rep: true` — `rep` indicates the Guard's `repository.data` queries (query 1167) do not depend on runtime submissions, so results are deterministic and the Guard can serve as a dependency. Guards with `rep: false` cannot appear in `rely` lists. Violations are caught by the contract layer at creation time.
|
|
57
|
+
|
|
58
|
+
### Data Source 4 Classification — The Foundation of Guard Semantics
|
|
59
|
+
|
|
60
|
+
A Guard is fundamentally a **data computation tree**: deterministic data (on-chain constants + system context) + submitted data (runtime, semi-open) → derived through finite operation rules → a single boolean result. Every leaf node in the computation tree draws data from one of **4 data source classifications**. Understanding these 4 classifications is essential for designing and interpreting Guards.
|
|
61
|
+
|
|
62
|
+
| Type | Name | SDK Manifestation | Native Opcode | Trust Level | Typical Scenario |
|
|
63
|
+
|------|------|-------------------|---------------|-------------|------------------|
|
|
64
|
+
| **Type 1** | OnChainConstant | `query` + `identifier` (`b_submission: false`, no witness) | TYPE_QUERY + TYPE_CONSTANT | Highest | Query fields of already-published Service/Machine/Reward objects |
|
|
65
|
+
| **Type 2** | WitnessDerived | `query` + `identifier` + `convert_witness` (100-108) | TYPE_QUERY + witness_byte | High (source trusted + deterministic derivation) | Order → Progress query via witness=100 |
|
|
66
|
+
| **Type 3** | SubmittedObject | `query` + `identifier` (`b_submission: true`, no witness) | TYPE_QUERY + TYPE_CONSTANT | Medium (requires constraint rules) | User submits Order address for field query |
|
|
67
|
+
| **Type 4** | SystemContext | `context` (Signer/Clock/Guard) | TYPE_SIGNER / TYPE_CLOCK / TYPE_GUARD | Highest | Identity verification, time-locks |
|
|
68
|
+
|
|
69
|
+
**Key insights**:
|
|
70
|
+
1. **Type 1 and Type 3 are isomorphic at the native layer** — both use TYPE_QUERY+TYPE_CONSTANT; the only difference is the `b_submission` flag (false vs true)
|
|
71
|
+
2. **Type 2 can overlay on Type 1 or Type 3** — the source object can be a constant (Type 1) or a submission (Type 3), then witness derives the target object
|
|
72
|
+
3. **Type 4 is fully independent** — does not depend on the table
|
|
73
|
+
4. **Except for Type 4, all data must be declared in the table** — the table is the complete data contract between Guard and caller
|
|
74
|
+
|
|
75
|
+
**The table as data contract**: The table declares:
|
|
76
|
+
- **Deterministic data** (`b_submission: false`): type + value, baked at creation, immutable
|
|
77
|
+
- **Submitted data** (`b_submission: true`): type only (1-byte placeholder), value provided by caller at runtime — **must have constraint rules designed, otherwise empty data is meaningless**
|
|
78
|
+
|
|
79
|
+
**Guard essence**: A deterministic data set (Type 1 + Type 4) + submitted data (Type 3, must have constraint rules and defined types) → derived through finite operation rules → a single boolean result. The semantics are deterministic — you only need to fill in the "data object source meaning" and "field meaning" (e.g., "the permission address of service A", "the current node time of workflow B").
|
|
57
80
|
|
|
58
81
|
### Where Guards Attach in the Ecosystem
|
|
59
82
|
|
|
@@ -148,26 +171,43 @@ The Guard table is the **complete declaration of information** the Guard consume
|
|
|
148
171
|
- **No duplicate identifiers.** Each index number must appear exactly once.
|
|
149
172
|
- **Non-submission entries must have a value.** These are baked into the Guard immutably.
|
|
150
173
|
- **Submission entries use placeholder values.** The actual value is provided by the caller at runtime.
|
|
151
|
-
- **Query target objects must be of type Address in the table.**
|
|
174
|
+
- **Query target objects must be of type Address in the table.** The `object_type` field is **automatically filled by the SDK** based on the first query node referencing this identifier (it is NOT a user-provided field). The SDK infers the object type from the query instruction's target object type (Progress, Order, Machine, Reward, etc.).
|
|
152
175
|
- **Querying EntityRegistrar or EntityLinker requires system address table entries.** Add entries for `ENTITY_REGISTRAR_ADDRESS` (`0xaab`) or `ENTITY_LINKER_ADDRESS` (`0xaaa`) to the table as Address-type constants when your query instruction targets these global registries. Without them, creation fails.
|
|
153
176
|
- **Maximum 256 table entries** (identifiers 0–255). The total serialized table size must not exceed 40000 bytes.
|
|
154
177
|
- **Submission entries must have descriptive `name` values.** For `b_submission: true` entries, `name` is the contract between Guard and caller — it tells callers what data they must provide. Use natural language that explains the purpose and necessity: "The order ID that identifies the target Order for verification" not `"order_id"`, "The signer's account address that will be compared against the authorized list" not `"addr"`. This is critical because callers see only this name when submitting data.
|
|
155
178
|
|
|
156
179
|
### The convert_witness Mechanism
|
|
157
180
|
|
|
158
|
-
`convert_witness` transforms a
|
|
181
|
+
`convert_witness` transforms a source object ID into its associated target object — enabling queries across object relationships without requiring the caller to submit multiple IDs. This is the **Type 2 (WitnessDerived)** data source.
|
|
159
182
|
|
|
160
|
-
**Core principle**: Caller submits what they have (e.g., Order ID); Guard queries what it needs (e.g., Progress state) via witness conversion.
|
|
183
|
+
**Core principle**: Witness is a "read the source object's associated field" mechanism (not a lookup table, not an independent index). It is a one-to-one deterministic derivation of object relationships with only 9 derivation types. Caller submits what they have (e.g., Order ID); Guard queries what it needs (e.g., Progress state) via witness conversion.
|
|
161
184
|
|
|
162
185
|
**Rules**:
|
|
163
186
|
- Witness type encodes source→target transformation
|
|
164
|
-
- Table entry's `object_type` must match witness source type
|
|
187
|
+
- Table entry's `object_type` (auto-filled by SDK) must match witness source type
|
|
165
188
|
- Query instruction's object type must match witness target type
|
|
166
189
|
- Type mismatches cause Guard creation to fail
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
190
|
+
- Multi-hop witnesses (106-108) require intermediate objects to exist
|
|
191
|
+
|
|
192
|
+
**Complete 9 witness types** (defined in `guard.rs#L34-L65`):
|
|
193
|
+
|
|
194
|
+
| Code | Name | Source → Target | Derivation | Hops |
|
|
195
|
+
|------|------|-----------------|------------|------|
|
|
196
|
+
| 100 | TypeOrderProgress | Order → Progress | read order.progress field | 1 |
|
|
197
|
+
| 101 | TypeOrderMachine | Order → Machine | read order.machine field | 1 |
|
|
198
|
+
| 102 | TypeOrderService | Order → Service | read order.service field | 1 |
|
|
199
|
+
| 103 | TypeProgressMachine | Progress → Machine | read progress.machine field | 1 |
|
|
200
|
+
| 104 | TypeArbOrder | Arb → Order | read arb.order field | 1 |
|
|
201
|
+
| 105 | TypeArbArbitration | Arb → Arbitration | read arb.arbitration field | 1 |
|
|
202
|
+
| 106 | TypeArbProgress | Arb → Progress | arb.order → order.progress | 2 (multi-hop) |
|
|
203
|
+
| 107 | TypeArbMachine | Arb → Machine | arb.order → order.machine | 2 (multi-hop) |
|
|
204
|
+
| 108 | TypeArbService | Arb → Service | arb.order → order.service | 2 (multi-hop) |
|
|
205
|
+
|
|
206
|
+
**Key notes**:
|
|
207
|
+
- **Type 2 can overlay on Type 1 or Type 3**: The source object can be a constant (Type 1, `b_submission: false`) or a submission (Type 3, `b_submission: true`). The witness then derives the target object.
|
|
208
|
+
- **Multi-hop witnesses (106-108)**: Arb → Progress/Machine/Service uses two hops (Arb → Order → target). The intermediate Order object must exist for the derivation to succeed.
|
|
209
|
+
- **TypeArbArbitration (105)**: Arb and Arbitration are **different on-chain objects**. The witness queries the Arbitration (parent service) from an Arb (case) address — the binding is set when Arbitration creates the Arb.
|
|
210
|
+
- **Available witness types** are also discoverable via `wowok_buildin_info` with info `"guard instructions"`.
|
|
171
211
|
|
|
172
212
|
---
|
|
173
213
|
|
|
@@ -281,6 +321,8 @@ Machine's forward `guard` validates state transitions. If `retained_submission`
|
|
|
281
321
|
|
|
282
322
|
Repository's `write_guard` validates writes. If `id_from_submission` is set, reads entity ID from that submission index — **the index must be Address type**. If `data_from_submission` is set, reads data value from that index — **the value type must match the Repository's declared value_type**. Guard table must include entries for the data being extracted.
|
|
283
323
|
|
|
324
|
+
**Important — impack_list semantics in verify phase**: When a Guard queries Repository data (query 1167 `repository.data`) with a policy that has a `quote_guard` set, the verification checks whether the quote_guard address is in the `impack_list`. However, `impack_list` is **always empty during the `verify_guard` phase** — `Passport.new()` initializes `impack:vector[]` and the verify loop never modifies it; `impack` is only populated in `result_for_permission` (after verify completes). This means a Repository query with `quote_guard = Some(addr)` will always fail with `IMPACK_GUARD_NOT_FOUND` in the gen_passport flow; only `quote_guard = None` passes. Verify the quote_guard mechanism's design intent before relying on it.
|
|
325
|
+
|
|
284
326
|
---
|
|
285
327
|
|
|
286
328
|
**Key Principle**: Design your Guard table based on what data the target object needs to read. Objects don't just validate — they consume Guard submissions as structured data inputs.
|
|
@@ -303,460 +345,114 @@ Each object extracts Guard data with precise type expectations. Mismatches cause
|
|
|
303
345
|
|
|
304
346
|
### Common Pitfalls
|
|
305
347
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
2. **Type mismatches in comparison nodes**: A `logic_equal` comparing a String to a U64 fails validation. Use explicit conversion nodes (`convert_string_number`, `convert_number_string`) when types differ. Numeric comparisons use `logic_as_u256_*` variants which auto-widen to U256.
|
|
309
|
-
|
|
310
|
-
3. **Wrong query instruction IDs or parameter counts**: Query instructions are system-defined. Always discover them through `wowok_buildin_info` with info `"guard instructions"`. The parameter count and types in your query node must match the instruction exactly — off-by-one parameter counts are a common failure.
|
|
311
|
-
|
|
312
|
-
4. **Missing convert_witness**: When accessing Progress data from an Order ID in the table, the query node needs `convert_witness` with the appropriate witness type. Without it, the runtime looks for a Progress at the Order's address — which does not exist as a Progress object. The creation-time validation catches this mismatch.
|
|
313
|
-
|
|
314
|
-
5. **Testing with production durations**: Set time-lock durations to small values (e.g., 1000 milliseconds) during testing. Increase to production values only after verifying the logic works correctly. A Guard with a 30-day lock tested with real durations cannot produce results for a month.
|
|
315
|
-
|
|
316
|
-
6. **Forgetting to export before recreating**: Guards are immutable. If you need to change one, export it first with `guard2file` so you have the exact on-chain definition as a reference. Then create a new Guard with a versioned name and update all references.
|
|
317
|
-
|
|
318
|
-
7. **Root not returning Bool**: The outermost node of the tree must produce Bool. Logic and comparison nodes return Bool; arithmetic, conversion, and string operation nodes do not. Ensure your tree terminates at a logic or comparison node — the creation validation will reject non-Bool roots.
|
|
319
|
-
|
|
320
|
-
8. **Dependency on non-standalone Guards**: A Guard's `rely` entries must reference Guards with `rep: true` — meaning they have no external Repository dependency. Guards that depend on a Repository (`rep: false`) cannot serve as dependencies. The contract layer catches violations at creation time.
|
|
321
|
-
|
|
322
|
-
9. **Forgetting voting_guard weight type validation**: When using `GuardIdentifier`, the referenced identifier must exist in the guard's table and its value type must be numeric. The system checks this when the VotingGuard is added to the Arbitration — if the identifier does not exist or is non-numeric, the operation reverts with `E_GUARD_IDENTIFIER_NOT_NUMBER`.
|
|
323
|
-
|
|
324
|
-
10. **Not checking Arbitration pause state**: Even with a valid usage_guard Passport, the dispute fails if the Arbitration is paused (`bPaused: true`). The pause check happens before the guard check — advise customers to verify the Arbitration is active before generating Passports.
|
|
325
|
-
|
|
326
|
-
---
|
|
327
|
-
|
|
328
|
-
## Tool Reference
|
|
329
|
-
|
|
330
|
-
| Tool | Purpose |
|
|
331
|
-
|------|---------|
|
|
332
|
-
| `wowok_buildin_info` (`info: "guard instructions"`) | Discover all available query instructions — their IDs, parameter types, return types, and target object types |
|
|
333
|
-
| `wowok_buildin_info` (`info: "value types"`) | Discover the numeric codes for all supported value types used in table entries |
|
|
334
|
-
| `wowok_buildin_info` (`info: "built-in permissions"`) | Discover all built-in permission index codes for use with `permission.entity.perm has` queries |
|
|
335
|
-
| `onchain_operations` (`operation_type: "gen_passport"`) | Test Guard validation with runtime submissions and generate a verified on-chain credential on success |
|
|
336
|
-
| `guard2file` | Export an existing Guard's complete definition (description, table, root tree, dependencies) to a local JSON or Markdown file |
|
|
337
|
-
| `query_toolkit` (`query_type: "onchain_objects"`) | Query any Guard object on-chain by name or address to inspect its full definition |
|
|
338
|
-
| `schema_query` (`name: "onchain_operations_guard"`) | Retrieve the complete Guard operation schema with all parameter definitions |
|
|
339
|
-
|
|
340
|
-
---
|
|
341
|
-
|
|
342
|
-
## Dialogue Scripts (R1-R10)
|
|
343
|
-
|
|
344
|
-
A 10-round dialogue for the Guard authoring journey: from "I need a validation rule" through "tested, bound, and live". Guards are CREATE-only and immutable — this dialogue is deliberately heavy on design (R1-R6) before any on-chain write (R7), because there is no edit phase after creation. The sequence covers the four canonical Guard contexts (buy_guard, machine Forward guard, Allocator guard, Arbitration voting_guard) but the same shape applies to reward, repository, and demand Guards.
|
|
345
|
-
|
|
346
|
-
### R1: Validation Intent Capture
|
|
347
|
-
|
|
348
|
-
**AI Goal**: Articulate the business requirement the Guard will enforce, in plain language, before any technical design. Identify which of the §Quick Decision patterns fits.
|
|
349
|
-
|
|
350
|
-
**Key Questions**:
|
|
351
|
-
- What action is being protected? (Buying, advancing a node, releasing funds, voting, filing a dispute, claiming a reward, writing to a repository?)
|
|
352
|
-
- What single sentence describes the rule? (e.g., "Only the author can purchase this service", "Customer must wait 8 hours before completing", "Only sunny weather on the activity date".)
|
|
353
|
-
- What should cause the Guard to FAIL? (Listing the failure conditions often clarifies the logic more than listing success conditions.)
|
|
354
|
-
|
|
355
|
-
**Tool Calls**:
|
|
356
|
-
1. `wowok_buildin_info` → `info: "guard instructions"` — pre-fetch the full query instruction catalog so R3's design references real IDs.
|
|
357
|
-
2. `wowok_buildin_info` → `info: "value types"` — pre-fetch the type code mapping so R2's table uses correct `value_type` strings.
|
|
358
|
-
3. (Internal) Map the user's intent to one of the §Quick Decision patterns: identity check, time-lock, external data, progress state, one-time claim, dynamic weight, repository data, entity reputation.
|
|
359
|
-
|
|
360
|
-
**Success Criteria**: AI restates the validation intent as "The Guard passes when X, Y, Z are all true; otherwise it fails." The user confirms.
|
|
361
|
-
|
|
362
|
-
**Fallback**: User's intent doesn't fit any pattern → treat as a multi-condition Guard (combine multiple `query` nodes with `logic_and`). User's intent is genuinely unclear → ask for a concrete scenario: "Walk me through a case where the Guard should pass, and a case where it should fail."
|
|
363
|
-
|
|
364
|
-
**Checkpoint**: Persist `{ round: R1, intent: <sentence>, pattern: <name>, host_object: <Service|Machine|Arbitration|...> }` via `local_info_operation`.
|
|
365
|
-
|
|
366
|
-
### R2: Table Declaration
|
|
367
|
-
|
|
368
|
-
**AI Goal**: Define every piece of data the Guard touches — constants (`b_submission: false`) and runtime submissions (`b_submission: true`) — each with a unique `identifier` (0–255) and a `value_type`.
|
|
369
|
-
|
|
370
|
-
**Key Questions**:
|
|
371
|
-
- For each piece of data: is it a constant baked in at creation, or a value the caller submits at runtime?
|
|
372
|
-
- For each submission entry: what is its `value_type`? (Bool, Address, String, U8–U256, or vector types — confirm codes via `wowok_buildin_info`.)
|
|
373
|
-
- For each submission entry: what should its `name` field say? (The `name` is the contract with callers — natural language describing what they must provide.)
|
|
374
|
-
- Will the Guard query EntityRegistrar (`0xaab`) or EntityLinker (`0xaaa`)? If yes, add Address-type constant entries for these system addresses.
|
|
375
|
-
|
|
376
|
-
**Tool Calls**:
|
|
377
|
-
1. (Internal) Build the table: `[{identifier, b_submission, value_type, value?, name, object_type?}]`.
|
|
378
|
-
2. Validate: no duplicate identifiers; every non-submission entry has a `value`; query target objects are Address-type with correct `object_type`; max 256 entries; total serialized size ≤ 40000 bytes.
|
|
379
|
-
3. For submission entries, draft the `name` in natural language (per §Design Rules): e.g., "The order ID that identifies the target Order for verification", not "order_id".
|
|
380
|
-
|
|
381
|
-
**Success Criteria**: AI presents the full table with all fields populated. The user confirms each submission entry's `name` is clear enough that a caller would know what to provide.
|
|
382
|
-
|
|
383
|
-
**Fallback**: User wants more than 256 entries → decompose into multiple Guards composed via `rely`. User wants to query an object whose type is ambiguous → confirm the `object_type` field per §Design Rules. User submits a Value type 19 → block, cite [wowok-safety](../wowok-safety/SKILL.md) §8.1 ("Never use Value type 19").
|
|
384
|
-
|
|
385
|
-
**Checkpoint**: Persist `{ round: R2, table: [...], submission_count, constant_count }`.
|
|
386
|
-
|
|
387
|
-
### R3: Computation Tree Sketch
|
|
388
|
-
|
|
389
|
-
**AI Goal**: Sketch the root computation tree that produces the final Bool verdict. Identify each node's type and return type before writing any JSON.
|
|
390
|
-
|
|
391
|
-
**Key Questions**:
|
|
392
|
-
- What is the root node? (Must return Bool — typically `logic_and`, `logic_or`, `logic_equal`, or a comparison.)
|
|
393
|
-
- What are the data source nodes? (`identifier` for table values, `context` for Clock/Signer/self-ID, `query` for on-chain objects.)
|
|
394
|
-
- What are the intermediate transformation nodes? (`calc_number_*` for arithmetic, `convert_*` for type transformations, `vec_*` for vector operations, `query_progress_history_*` / `query_reward_record_*` for historical data.)
|
|
395
|
-
- Are there cross-object queries? If yes, which `convert_witness` type derives the target from a submitted ID?
|
|
396
|
-
|
|
397
|
-
**Tool Calls**:
|
|
398
|
-
1. `schema_query` → `get` for `onchain_operations_guard` — retrieve the complete `GuardNodeSchema` with every node type, its required fields, and input/output types.
|
|
399
|
-
2. `wowok_buildin_info` → `info: "guard instructions"` (filtered by `name`, `return_type`, `param_count`, or `object_type`) — confirm each `query` node's instruction ID and parameter count.
|
|
400
|
-
3. (Internal) Walk the tree: every `identifier` index exists in the table; every comparison receives compatible operand types; every `query` node's parameter count matches the instruction; the root returns Bool.
|
|
401
|
-
|
|
402
|
-
**Success Criteria**: AI presents the tree as an indented outline showing each node's type and the data flow. The user confirms the logic matches their R1 intent.
|
|
403
|
-
|
|
404
|
-
**Fallback**: Type mismatch at a comparison node → insert an explicit `convert_*` node (e.g., `convert_string_number`, `convert_number_string`) or use `logic_as_u256_*` variants for cross-width numeric comparisons. Root returns non-Bool → wrap with a final `logic_equal` or `logic_and` that produces Bool. `query` node parameter count off-by-one → re-check the instruction definition, fix the parameter list.
|
|
405
|
-
|
|
406
|
-
**Checkpoint**: Persist `{ round: R3, root_node_type, tree_depth, query_nodes: [{instruction_id, param_count, convert_witness?}] }`.
|
|
407
|
-
|
|
408
|
-
### R4: `rely` Composition (Optional)
|
|
409
|
-
|
|
410
|
-
**AI Goal**: Decide whether the Guard depends on other Guards via `rely` (up to 4 dependencies, AND/OR logic). Use composition to avoid monolithic trees.
|
|
411
|
-
|
|
412
|
-
**Key Questions**:
|
|
413
|
-
- Does this Guard's logic naturally decompose into independent sub-rules? (e.g., " KYC verified AND amount within cap AND not blacklisted" = 3 sub-Guards.)
|
|
414
|
-
- For each candidate dependency: does it have `rep: true`? (Guards with `rep: false` — those depending on a Repository — cannot serve as dependencies.)
|
|
415
|
-
- AND or OR logic? (Default AND — all must pass. OR — any passing is sufficient.)
|
|
416
|
-
|
|
417
|
-
**Tool Calls**:
|
|
418
|
-
1. `query_toolkit` → `onchain_objects` for each candidate dependency Guard — confirm it exists and inspect its `rep` field.
|
|
419
|
-
2. (Internal) Validate: max 4 dependencies; all dependencies have `rep: true`; logic_or flag set correctly.
|
|
420
|
-
|
|
421
|
-
**Success Criteria**: Either: the Guard has no dependencies (skip R4), OR the `rely` list is finalized with verified `rep: true` Guards and the AND/OR logic is set.
|
|
422
|
-
|
|
423
|
-
**Fallback**: A desired dependency has `rep: false` → either inline its logic into the current Guard's tree, or create a new standalone Guard with `rep: true` that captures the same logic. User wants more than 4 dependencies → consolidate by combining related sub-rules into fewer Guards.
|
|
424
|
-
|
|
425
|
-
**Checkpoint**: Persist `{ round: R4, rely: [{guard_id, guard_name}], logic_or: bool }`.
|
|
426
|
-
|
|
427
|
-
### R5: Host Object & Binding Plan
|
|
428
|
-
|
|
429
|
-
**AI Goal**: Decide where the Guard attaches and confirm the binding pattern (especially the circular reference pattern for object-Guard mutual references).
|
|
348
|
+
> The full constraint system has **33 rules: 22 creation-phase + 11 runtime-phase**. The 22 creation-phase constraints below are all enforced by SDK + native `validate_guard_data`; runtime constraints are enforced by native `verify_guard`.
|
|
430
349
|
|
|
431
|
-
|
|
432
|
-
- Which host object will this Guard bind to? (Service `buy_guard`, Service `order_allocators[].guard`, Machine Forward `guard`, Arbitration `usage_guard` / `voting_guard[]`, Reward `guard`, Repository `write_guard`, Demand `ServiceGuard`.)
|
|
433
|
-
- Does the Guard reference the object it protects? (If yes, use the circular reference pattern: CREATE object without Guard → CREATE Guard referencing object by NAME → MODIFY object to bind Guard.)
|
|
434
|
-
- For Arbitration `voting_guard` with `GuardIdentifier`: is the referenced table entry numeric (U8–U256)? (Required — the value is cast to u32 as vote weight.)
|
|
435
|
-
- For Repository `write_guard`: are `id_from_submission` entries Address-type and `data_from_submission` entries matching the Repository's `value_type`?
|
|
350
|
+
#### Creation-Phase Constraints (22 items, enforced by SDK + native `validate_guard_data`)
|
|
436
351
|
|
|
437
|
-
**
|
|
438
|
-
1. (Internal) Classify the binding target per the §Where Guards Attach table.
|
|
439
|
-
2. For circular references: confirm the object's NAME (string) is used in the Guard table, NOT the object's address (which doesn't exist yet at Guard creation time). The SDK resolves the name at runtime.
|
|
440
|
-
3. For Arbitration `voting_guard`: validate the `GuardIdentifier` index points to a numeric table entry.
|
|
441
|
-
4. For Repository `write_guard`: validate `id_from_submission` and `data_from_submission` index types.
|
|
352
|
+
**Root (1 item)**
|
|
442
353
|
|
|
443
|
-
**
|
|
354
|
+
1. **ROOT_01 — Root must return Bool**: The outermost node of the tree must produce Bool. Logic and comparison nodes return Bool; arithmetic, conversion, and string operation nodes do not. Ensure your tree terminates at a logic or comparison node — the creation validation will reject non-Bool roots.
|
|
444
355
|
|
|
445
|
-
**
|
|
356
|
+
**Table (5 items)**
|
|
446
357
|
|
|
447
|
-
**
|
|
358
|
+
2. **TABLE_01 — Identifier uniqueness**: Every `identifier` in the table must be unique (0–255). Duplicate identifiers cause creation failure. SDK uses `lodash.groupBy` to detect duplicates.
|
|
448
359
|
|
|
449
|
-
|
|
360
|
+
3. **TABLE_02 — Identifier referential integrity**: Every `identifier` node in the computation tree must match an entry in the table. Missing entries cause creation failure — validate your tree against your table before submitting.
|
|
450
361
|
|
|
451
|
-
**
|
|
362
|
+
4. **TABLE_03 — Constant value non-empty**: When `b_submission=false`, the `value` field must be non-empty. These values are baked into the Guard immutably at creation time.
|
|
452
363
|
|
|
453
|
-
**
|
|
454
|
-
- Confirm: every `identifier` in the tree exists in the table? (Trap 1.)
|
|
455
|
-
- Confirm: every comparison node receives compatible operand types? (Trap 2 — use explicit `convert_*` nodes where types differ.)
|
|
456
|
-
- Confirm: every `query` node's instruction ID and parameter count match the spec from `wowok_buildin_info`? (Trap 3.)
|
|
457
|
-
- Confirm: every cross-object query has the correct `convert_witness`? (Trap 4 — e.g., `TypeOrderProgress` = 100 to query Progress from an Order ID.)
|
|
458
|
-
- Confirm: time-lock durations are small (e.g., 1000ms) for testing, not production values? (Trap 5.)
|
|
459
|
-
- Confirm: root returns Bool? (Trap 7.)
|
|
460
|
-
- Confirm: all `rely` dependencies have `rep: true`? (Trap 8.)
|
|
364
|
+
5. **TABLE_04 — Table size limits**: Maximum 256 table entries (identifiers 0–255), and the total serialized table size must not exceed 40000 bytes (BCS). Enforced by Move `guard::new`.
|
|
461
365
|
|
|
462
|
-
**
|
|
463
|
-
1. (Internal) Run the §10 Common Pitfalls checklist.
|
|
464
|
-
2. `guard2file` → (if iterating on an existing Guard) export the previous version as a reference. The new Guard will be a fresh CREATE with a versioned name.
|
|
465
|
-
3. (Optional) Write the full Guard definition to a local scratch file via `local_info_operation` for the user to review before CREATE.
|
|
366
|
+
6. **TABLE_05 — Submission value is 1-byte type code**: When `b_submission=true`, the `value` field is only a 1-byte type code placeholder (the actual value is provided at runtime). Enforced by native `deserialize_constants`.
|
|
466
367
|
|
|
467
|
-
**
|
|
368
|
+
**Query (4 items)**
|
|
468
369
|
|
|
469
|
-
**
|
|
370
|
+
7. **QUERY_01 — Query instruction ID valid**: Query instruction IDs are system-defined. Always discover them through `wowok_buildin_info` with info `"guard instructions"`. Invalid IDs cause creation failure.
|
|
470
371
|
|
|
471
|
-
**
|
|
372
|
+
8. **QUERY_02 — Parameter count matches**: The parameter count and types in your query node must match the instruction exactly — off-by-one parameter counts are a common failure.
|
|
472
373
|
|
|
473
|
-
|
|
374
|
+
9. **QUERY_03 — Return type compatible**: The query node's return type must be compatible with the parent node's expected input. A `logic_equal` comparing a String to a U64 fails validation. Use explicit conversion nodes (`convert_string_number`, `convert_number_string`) when types differ. Numeric comparisons use `logic_as_u256_*` variants which auto-widen to U256.
|
|
474
375
|
|
|
475
|
-
**
|
|
376
|
+
10. **QUERY_04 — Object identifier is Address type**: The table entry referenced by a query node's `object.identifier` must have `value_type: Address`. SDK `buildNode` validates this at L603-609.
|
|
476
377
|
|
|
477
|
-
**
|
|
478
|
-
- Confirm the Guard name (versioned: `<project>_guard_<purpose>_v1` per [wowok-safety](../wowok-safety/SKILL.md) §4).
|
|
479
|
-
- Confirm `root.type`: `"node"` (inline tree) or `"file"` (from a `guard2file` export).
|
|
480
|
-
- Confirm the operating account and `env.no_cache: true`.
|
|
378
|
+
**Witness (3 items)**
|
|
481
379
|
|
|
482
|
-
**
|
|
483
|
-
1. `onchain_operations` → `operation_type: "guard"` CREATE with the full `data`: `name`, `description`, `table`, `root`, `rely` (if any).
|
|
484
|
-
2. If CREATE succeeds: `query_toolkit` → `onchain_objects` for the new `guard_id` — verify the table and tree are present and `rep` is set correctly.
|
|
485
|
-
3. `local_mark_operation` → tag the Guard (e.g., `freelance_buy_guard_v1`).
|
|
380
|
+
11. **WITNESS_01 — Witness type valid (100-108)**: The `convert_witness` value must be one of the 9 valid witness types (100-108). Invalid witness types cause creation failure.
|
|
486
381
|
|
|
487
|
-
**
|
|
382
|
+
12. **WITNESS_02 — Witness target matches query objectType**: The witness's target object type must match the query instruction's expected object type. For example, `TypeOrderProgress` (100) derives a Progress, so the query must target a Progress object. SDK `buildNode` validates this at L613-619.
|
|
488
383
|
|
|
489
|
-
**
|
|
384
|
+
13. **WITNESS_03 — Witness source matches table object_type**: If the table entry has an `object_type` declared (auto-filled by SDK), it must match the witness's source object type. For example, `TypeOrderProgress` (100) expects an Order source, so the table entry's `object_type` must be Order. SDK `buildNode` validates this at L622-631. **Missing convert_witness** is a related failure: when accessing Progress data from an Order ID, the query node needs `convert_witness` with the appropriate witness type. Without it, the runtime looks for a Progress at the Order's address — which does not exist as a Progress object.
|
|
490
385
|
|
|
491
|
-
**
|
|
386
|
+
**Rely (3 items)**
|
|
492
387
|
|
|
493
|
-
|
|
388
|
+
14. **RELY_01 — Dependency count ≤ 4**: A Guard can depend on at most 4 other Guards (`MAX_DEPENDED_COUNT`). SDK `reliesAdd` enforces this limit.
|
|
494
389
|
|
|
495
|
-
**
|
|
390
|
+
15. **RELY_02 — Dependencies must have rep=true**: A Guard's `rely` entries must reference Guards with `rep: true` — meaning their `repository.data` queries do not depend on runtime submissions. Guards that depend on a Repository via submitted addresses (`rep: false`) cannot serve as dependencies. Move `guard::relies_add` catches violations at creation time.
|
|
496
391
|
|
|
497
|
-
**
|
|
498
|
-
- For each submission entry, what test value should I use? (Use edge cases: empty, boundary values, unusual addresses per [wowok-guard](../wowok-guard/SKILL.md) §Phase 5.)
|
|
499
|
-
- Should I test multiple scenarios? (Pass case, fail case, edge case.)
|
|
500
|
-
- For time-lock Guards: is the test duration small (1000ms)? (Production durations like 30 days cannot produce results for a month — trap 5.)
|
|
392
|
+
16. **RELY_03 — No self-reference**: A Guard cannot depend on itself. SDK `reliesAdd` prevents self-referential rely entries.
|
|
501
393
|
|
|
502
|
-
**
|
|
503
|
-
1. `onchain_operations` → `operation_type: "gen_passport"` with the Guard ID and mock `info` submissions. (Each Guard's submission is passed independently via `info` — NOT via `data.submission`.)
|
|
504
|
-
2. Omit `info` to auto-fetch existing submissions from the Guard (if any) — useful for re-testing with the same data.
|
|
505
|
-
3. Capture the result: PASS (Passport generated) or FAIL (which logic/query node returned false).
|
|
506
|
-
4. On PASS: `query_toolkit` → `onchain_objects` for the new Passport — inspect its data, validated Guards, and timestamp.
|
|
394
|
+
**Binding (3 items)**
|
|
507
395
|
|
|
508
|
-
**
|
|
396
|
+
17. **BINDING_01 — voting_guard GuardIdentifier must be numeric**: When using `GuardIdentifier` for Arbitration `voting_guard`, the referenced table entry must have a numeric `value_type` (U8–U256). The system checks this when the VotingGuard is added to the Arbitration — if the identifier does not exist or is non-numeric, the operation reverts with `E_GUARD_IDENTIFIER_NOT_NUMBER`.
|
|
509
397
|
|
|
510
|
-
**
|
|
398
|
+
18. **BINDING_02 — Repository id_from_submission must be Address**: When a Repository `write_guard` uses `id_from_submission`, the referenced table entry must have `value_type: Address`. Move Repository enforces this at binding time.
|
|
511
399
|
|
|
512
|
-
**
|
|
400
|
+
19. **BINDING_03 — Repository data_from_submission type must match**: When a Repository `write_guard` uses `data_from_submission`, the referenced table entry's `value_type` must match the Repository's declared `value_type`. Move Repository enforces this at binding time.
|
|
513
401
|
|
|
514
|
-
|
|
402
|
+
**Input (2 items)**
|
|
515
403
|
|
|
516
|
-
**
|
|
404
|
+
20. **INPUT_01 — Root bytecode non-empty**: The serialized root computation tree must not be empty. SDK `newGuard` validates this before submission.
|
|
517
405
|
|
|
518
|
-
**
|
|
519
|
-
- Confirm the host object exists and is in the right state (e.g., Machine unpublished for Forward Guards, Arbitration paused for voting_guard).
|
|
520
|
-
- For circular references: is the host object's NAME used in the Guard table? (The SDK resolves it at runtime — the address didn't exist when the Guard was created.)
|
|
406
|
+
21. **INPUT_02 — Root bytecode size ≤ MAX_INPUT_SIZE**: The serialized root computation tree must not exceed `MAX_INPUT_SIZE`. SDK `newGuard` validates this before submission.
|
|
521
407
|
|
|
522
|
-
**
|
|
523
|
-
1. For Machine Forward binding: `onchain_operations` → `operation_type: "machine"` MODIFY, using `node` operations (`add forward` or `set` with `bReplace: false`) to set the Forward's `guard` field (with optional `retained_submission`).
|
|
524
|
-
2. For Service `buy_guard`: `onchain_operations` → `operation_type: "service"` MODIFY to set `buy_guard`.
|
|
525
|
-
3. For Service `order_allocators[].guard`: `onchain_operations` → `operation_type: "service"` MODIFY to set the Allocator's `guard`.
|
|
526
|
-
4. For Arbitration `voting_guard` / `usage_guard`: `onchain_operations` → `operation_type: "arbitration"` MODIFY.
|
|
527
|
-
5. For Reward `guard_add`: `onchain_operations` → `operation_type: "reward"` MODIFY.
|
|
528
|
-
6. For Repository `write_guard`: `onchain_operations` → `operation_type: "repository"` MODIFY.
|
|
529
|
-
7. `guard2file` → export the bound Guard for the audit trail.
|
|
408
|
+
**Immutable (1 item)**
|
|
530
409
|
|
|
531
|
-
**
|
|
410
|
+
22. **IMMUTABLE_01 — Guard becomes immutable after creation**: Once `guard::create` is called, the Guard's `immutable` flag is set to `true` and no further modifications are possible. This is the foundation of the immutability contract — to change a Guard, export via `guard2file`, create a new Guard, and update all references.
|
|
532
411
|
|
|
533
|
-
|
|
412
|
+
#### Practical Tips (not strict constraints, but strongly recommended)
|
|
534
413
|
|
|
535
|
-
**
|
|
414
|
+
- **Testing with production durations**: Set time-lock durations to small values (e.g., 1000 milliseconds) during testing. Increase to production values only after verifying the logic works correctly. A Guard with a 30-day lock tested with real durations cannot produce results for a month.
|
|
415
|
+
- **Forgetting to export before recreating**: Guards are immutable. If you need to change one, export it first with `guard2file` so you have the exact on-chain definition as a reference. Then create a new Guard with a versioned name and update all references.
|
|
416
|
+
- **Not checking Arbitration pause state**: Even with a valid usage_guard Passport, the dispute fails if the Arbitration is paused (`bPaused: true`). The pause check happens before the guard check — advise customers to verify the Arbitration is active before generating Passports.
|
|
536
417
|
|
|
537
|
-
|
|
418
|
+
#### Runtime-Phase Constraints (enforced by native `verify_guard`)
|
|
538
419
|
|
|
539
|
-
|
|
420
|
+
These constraints are checked at Guard verification time (gen_passport or actual usage), not at creation. They are often overlooked because creation succeeds but runtime fails:
|
|
540
421
|
|
|
541
|
-
**
|
|
542
|
-
-
|
|
543
|
-
-
|
|
544
|
-
-
|
|
545
|
-
|
|
546
|
-
**
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
4. `local_info_operation` → persist the iteration workflow: "To change this Guard: (1) `guard2file` export, (2) edit JSON, (3) CREATE new Guard with versioned name, (4) re-test via `gen_passport`, (5) rebind to host object, (6) update all references."
|
|
551
|
-
|
|
552
|
-
**Success Criteria**: Guard is live, verified, and the iteration workflow is documented. Handoff packet produced for the host object's Skill ([wowok-provider](../wowok-provider/SKILL.md), [wowok-machine](../wowok-machine/SKILL.md), [wowok-arbitrator](../wowok-arbitrator/SKILL.md), etc.).
|
|
553
|
-
|
|
554
|
-
**Fallback**: Post-bind verification shows the Guard isn't where expected → check the binding field name (common mistake: binding to `buy_guard` when the user meant `order_allocators[].guard`). Re-call the MODIFY with the correct field. If the host object is now immutable → create a new host object.
|
|
555
|
-
|
|
556
|
-
**Checkpoint**: Persist `{ round: R10, verified: true, iteration_workflow_documented: true, handoff_emitted: true }`. Mark Guard design COMPLETE.
|
|
422
|
+
- **RUN_IMMUTABLE_01**: Guard must have `immutable=true` to be verified. A Guard that hasn't been finalized via `guard::create` cannot be used.
|
|
423
|
+
- **RUN_SUB_01**: The submission's `value[0]` (type byte) must match the table declaration. A submission with the wrong type byte is rejected.
|
|
424
|
+
- **RUN_SUB_02**: Every table entry with `b_submission=true` must have a corresponding submission value. Missing submissions cause failure.
|
|
425
|
+
- **RUN_SUB_03**: Total submission bytes must be ≤ `MAX_SUBMISSION_SIZE` (256).
|
|
426
|
+
- **RUN_WITNESS_01/02**: When witness conversion runs, the source object must have the associated field, and the derived target object must exist. Multi-hop witnesses (106-108) require the intermediate Order object to exist.
|
|
427
|
+
- **RUN_QUERY_01**: The query target object must exist and its type must match.
|
|
428
|
+
- **RUN_IMPACK_01/02**: At least one impack guard is required; an impack guard failure fails the entire passport. **Note**: `impack_list` is always empty during verify (see Repository section above), so quote_guard queries will fail unless `quote_guard = None`.
|
|
429
|
+
- **RUN_TX_01**: The Passport's `tx_hash` must match the current transaction.
|
|
430
|
+
- **RUN_RELY_01**: Rely guards must have been added to the passport.
|
|
557
431
|
|
|
558
432
|
---
|
|
559
433
|
|
|
560
|
-
##
|
|
561
|
-
|
|
562
|
-
### D1: Guard Pattern Selection
|
|
563
|
-
|
|
564
|
-
```
|
|
565
|
-
What are you validating?
|
|
566
|
-
├── Identity (single address or allowlist)? ──→ context(Signer) + logic_equal / vec_contains_address
|
|
567
|
-
├── Time constraint? ──→ context(Clock) + calc_number_* comparisons
|
|
568
|
-
├── External on-chain data? ──→ query + table entry declaring target object address
|
|
569
|
-
├── Progress state / forward history? ──→ query_progress_history_* + convert_witness (TypeOrderProgress=100)
|
|
570
|
-
├── One-time claim (no prior record)? ──→ query_reward_record_count + logic_equal(0)
|
|
571
|
-
├── Dynamic vote weight? ──→ GuardIdentifier + numeric table entry (b_submission: true)
|
|
572
|
-
├── External Repository data? ──→ query + table entry declaring Repository address
|
|
573
|
-
├── Entity reputation / tier? ──→ query + table entry for ENTITY_REGISTRAR_ADDRESS (0xaab) or ENTITY_LINKER_ADDRESS (0xaaa)
|
|
574
|
-
└── Multi-condition (combine above)? ──→ multiple query/logic nodes joined with logic_and / logic_or
|
|
575
|
-
```
|
|
576
|
-
|
|
577
|
-
### D2: Submission vs Constant Table Entry
|
|
578
|
-
|
|
579
|
-
```
|
|
580
|
-
For each piece of data the Guard touches:
|
|
581
|
-
├── Value known at Guard creation time and never changes? ──→ CONSTANT (b_submission: false, value: <baked_in>)
|
|
582
|
-
│ ├── System address (EntityRegistrar, EntityLinker)? ──→ Address-type constant with the system address
|
|
583
|
-
│ ├── Query target object address? ──→ Address-type constant OR name reference (circular pattern)
|
|
584
|
-
│ └── Threshold / cap / duration? ──→ Numeric constant (use small values for testing per trap 5)
|
|
585
|
-
├── Value provided by the caller at runtime? ──→ SUBMISSION (b_submission: true, value: <placeholder>)
|
|
586
|
-
│ ├── Will the host object read this value? ──→ ensure type matches host's extraction field (e.g., Repository data_from_submission must match value_type)
|
|
587
|
-
│ └── Will this value be retained in Progress? ──→ ensure Machine Forward's retained_submission references the right index
|
|
588
|
-
└── Value derived from another submitted object? ──→ SUBMISSION of the source ID + convert_witness in the query node
|
|
589
|
-
```
|
|
590
|
-
|
|
591
|
-
### D3: `convert_witness` Selection
|
|
592
|
-
|
|
593
|
-
```
|
|
594
|
-
Guard needs to query object B, but caller submits object A's ID:
|
|
595
|
-
├── A = Order, B = Progress? ──→ convert_witness: TypeOrderProgress (100)
|
|
596
|
-
├── A = Arb (case), B = Arbitration (parent service)? ──→ convert_witness: TypeArbArbitration (105)
|
|
597
|
-
├── A = Order, B = Service? ──→ convert_witness: TypeOrderService
|
|
598
|
-
├── A = Progress, B = Machine? ──→ convert_witness: TypeProgressMachine
|
|
599
|
-
├── A = Reward, B = Service? ──→ convert_witness: TypeRewardService
|
|
600
|
-
├── Other source→target pairs? ──→ query wowok_buildin_info (info: "guard instructions") for the complete witness type catalog
|
|
601
|
-
└── No conversion needed (caller submits the exact object the Guard queries)? ──→ omit convert_witness
|
|
602
|
-
```
|
|
603
|
-
|
|
604
|
-
### D4: Binding Target & Circular Reference
|
|
605
|
-
|
|
606
|
-
```
|
|
607
|
-
Where will this Guard attach?
|
|
608
|
-
├── Service buy_guard? ──→ CREATE Service (no guard) → CREATE Guard (reference Service by name in table) → MODIFY Service (set buy_guard)
|
|
609
|
-
├── Service order_allocators[].guard? ──→ CREATE Service (no allocators) → CREATE Guard (may reference Service) → MODIFY Service (set order_allocators with guard)
|
|
610
|
-
├── Machine Forward guard? ──→ CREATE Machine (unpublished, no guard) → CREATE Guard (reference Machine if needed) → MODIFY Machine (set Forward.guard)
|
|
611
|
-
├── Arbitration voting_guard / usage_guard? ──→ CREATE Arbitration (paused, no guards) → CREATE Guard → MODIFY Arbitration (add voting_guard / set usage_guard)
|
|
612
|
-
├── Reward guard? ──→ CREATE Reward (no guard) → CREATE Guard (reference Reward by name) → MODIFY Reward (guard_add)
|
|
613
|
-
├── Repository write_guard? ──→ CREATE Repository (no guard) → CREATE Guard → MODIFY Repository (set write_guard)
|
|
614
|
-
└── Demand ServiceGuard? ──→ CREATE Demand (no guard) → CREATE Guard → MODIFY Demand (set ServiceGuard)
|
|
615
|
-
```
|
|
616
|
-
|
|
617
|
-
### D5: Iteration Workflow (When Guard Logic Must Change)
|
|
434
|
+
## Tool Reference
|
|
618
435
|
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
│ │ └── Host is immutable (published Machine/Service)? ──→ must create new host object too
|
|
629
|
-
│ └── Update all references? ──→ update Machine Forwards, Service allocators, Arbitration voting_guard, etc.
|
|
630
|
-
└── Guard not yet created? ──→ just edit the design and CREATE
|
|
631
|
-
```
|
|
436
|
+
| Tool | Purpose |
|
|
437
|
+
|------|---------|
|
|
438
|
+
| `wowok_buildin_info` (`info: "guard instructions"`) | Discover all available query instructions — their IDs, parameter types, return types, and target object types |
|
|
439
|
+
| `wowok_buildin_info` (`info: "value types"`) | Discover the numeric codes for all supported value types used in table entries |
|
|
440
|
+
| `wowok_buildin_info` (`info: "built-in permissions"`) | Discover all built-in permission index codes for use with `permission.entity.perm has` queries |
|
|
441
|
+
| `onchain_operations` (`operation_type: "gen_passport"`) | Test Guard validation with runtime submissions and generate a verified on-chain credential on success |
|
|
442
|
+
| `guard2file` | Export an existing Guard's complete definition (description, table, root tree, dependencies) to a local JSON or Markdown file |
|
|
443
|
+
| `query_toolkit` (`query_type: "onchain_objects"`) | Query any Guard object on-chain by name or address to inspect its full definition |
|
|
444
|
+
| `schema_query` (`name: "onchain_operations_guard"`) | Retrieve the complete Guard operation schema with all parameter definitions |
|
|
632
445
|
|
|
633
446
|
---
|
|
634
447
|
|
|
635
|
-
## Failure Playbooks
|
|
636
|
-
|
|
637
|
-
### F1: Guard CREATE Fails with Type Mismatch
|
|
638
|
-
|
|
639
|
-
**Trigger**: `onchain_operations` → `operation_type: "guard"` CREATE reverts with a type-validation error naming a specific node and the expected vs actual types.
|
|
640
|
-
|
|
641
|
-
**Diagnosis**: The computation tree has a type incompatibility. Common variants: (a) `logic_equal` comparing String to U64; (b) `query` node's parameter count off-by-one; (c) missing `convert_witness` when querying Progress from an Order; (d) `rely` referencing a Guard with `rep: false`.
|
|
642
|
-
|
|
643
|
-
**Recovery**:
|
|
644
|
-
1. Read the error message — it identifies the offending node and the type mismatch.
|
|
645
|
-
2. Cross-reference `wowok_buildin_info` → `info: "value types"` to confirm numeric codes if any are used.
|
|
646
|
-
3. Cross-reference `wowok_buildin_info` → `info: "guard instructions"` to confirm the `query` node's instruction ID and parameter count.
|
|
647
|
-
4. Insert an explicit `convert_*` node where types differ, or use `logic_as_u256_*` variants for cross-width numeric comparisons.
|
|
648
|
-
5. Re-attempt CREATE. Guards are CREATE-only — there is no MODIFY, so a failed CREATE simply retries with the fixed tree.
|
|
649
|
-
|
|
650
|
-
**Prevention**: R6's pre-create review walks the tree and checks every comparison node's operand types. The §10 Common Pitfalls traps 1–4 catch 90% of these issues before CREATE.
|
|
651
|
-
|
|
652
|
-
### F2: `gen_passport` Returns FAIL
|
|
653
|
-
|
|
654
|
-
**Trigger**: The static test returns FAIL — the Guard rejected the mock submission when it was expected to pass.
|
|
655
|
-
|
|
656
|
-
**Diagnosis**: Either the Guard's logic is wrong, or the mock submission doesn't match what the Guard expects. The error usually indicates which `logic_*` or `query` node returned false.
|
|
657
|
-
|
|
658
|
-
**Recovery**:
|
|
659
|
-
1. `guard2file` → export the failing Guard to a JSON/Markdown file.
|
|
660
|
-
2. Walk the computation tree manually, evaluating each node with the mock submission values.
|
|
661
|
-
3. Identify the first node that returns an unexpected value.
|
|
662
|
-
4. Common causes: (a) `query` node returns empty because the target object doesn't exist or the wrong ID was submitted; (b) `convert_witness` produces the wrong target type; (c) time-lock duration is in milliseconds but the test used seconds; (d) `logic_equal` compares Address to String representation.
|
|
663
|
-
5. If the logic is genuinely wrong: CREATE a new Guard with corrected logic (immutable — cannot edit the original), re-test.
|
|
664
|
-
6. If the submission was wrong: re-run `gen_passport` with corrected mock data.
|
|
665
|
-
|
|
666
|
-
**Prevention**: R6's pre-create review includes a mental walkthrough with edge cases. R8's test should include both an expected-pass scenario and an expected-fail scenario — if the expected-fail scenario passes, the logic is inverted.
|
|
667
|
-
|
|
668
|
-
### F3: Guard Bound to Wrong Host Field
|
|
669
|
-
|
|
670
|
-
**Trigger**: The Guard was bound to `buy_guard` when the user meant `order_allocators[].guard`, or vice versa. The Guard is live but in the wrong place.
|
|
671
|
-
|
|
672
|
-
**Diagnosis**: Querying the host object shows the Guard in the wrong field. The intended field is empty or has a different Guard.
|
|
673
|
-
|
|
674
|
-
**Recovery** (host object still mutable):
|
|
675
|
-
1. `onchain_operations` → MODIFY the host object: clear the wrong field (set to null/empty), set the correct field to the Guard.
|
|
676
|
-
2. Re-query to confirm the Guard is now in the intended field.
|
|
677
|
-
|
|
678
|
-
**Recovery** (host object immutable — published Machine/Service):
|
|
679
|
-
1. Cannot modify the host. The Guard is permanently in the wrong field.
|
|
680
|
-
2. If the wrong field is harmless (e.g., `buy_guard` set when no buy was intended) → the Service may reject all purchases. Must create a new Service.
|
|
681
|
-
3. If the wrong field leaves the intended field empty → the intended gate has no validation. Must create a new host object with correct binding.
|
|
682
|
-
|
|
683
|
-
**Prevention**: R5's binding plan explicitly documents `host_object` and `binding_field` before R9's MODIFY call. R9 lists the exact field name for each binding target. Always re-query the host object after binding to confirm the Guard is in the expected field.
|
|
684
|
-
|
|
685
|
-
### F4: Circular Reference Fails to Resolve
|
|
686
|
-
|
|
687
|
-
**Trigger**: Guard CREATE fails because a table entry references an object by NAME, but the SDK cannot resolve the name to an address.
|
|
688
|
-
|
|
689
|
-
**Diagnosis**: The object either (a) doesn't exist yet (circular reference pattern not followed — object should be CREATEd first), (b) was created but under a different name (typo), or (c) was created on a different account/network.
|
|
690
|
-
|
|
691
|
-
**Recovery**:
|
|
692
|
-
1. Confirm the object exists via `query_toolkit` → `onchain_objects` with the intended name.
|
|
693
|
-
2. If it doesn't exist: CREATE the object first (without the Guard), then CREATE the Guard referencing the object's name, then MODIFY the object to bind the Guard.
|
|
694
|
-
3. If it exists under a different name: fix the table entry's `value` to match the actual name.
|
|
695
|
-
4. If it's on a different account/network: switch `env.account` / `env.network` to match, or re-create the object on the current account.
|
|
696
|
-
|
|
697
|
-
**Prevention**: R5's binding plan explicitly documents the circular reference steps. The §Object-Guard Circular Reference Pattern in [wowok-tools](../wowok-tools/SKILL.md) is the universal three-step pattern: CREATE object → CREATE Guard (reference by name) → MODIFY object (bind Guard). Never CREATE the Guard before the object it references.
|
|
698
|
-
|
|
699
|
-
### F5: `voting_guard` Weight Type Error
|
|
700
|
-
|
|
701
|
-
**Trigger**: Adding a `voting_guard` with `GuardIdentifier` to an Arbitration reverts with `E_GUARD_IDENTIFIER_NOT_NUMBER`.
|
|
702
|
-
|
|
703
|
-
**Diagnosis**: The table entry at the `GuardIdentifier` index is either (a) not `b_submission: true`, or (b) not a numeric type (U8–U256). The Arbitration's `voting_guard` validation requires a numeric submission to cast as u32 vote weight.
|
|
704
|
-
|
|
705
|
-
**Recovery**:
|
|
706
|
-
1. `guard2file` → export the Guard, inspect the table entry at the `GuardIdentifier` index.
|
|
707
|
-
2. If `b_submission` is false → CREATE a new Guard with `b_submission: true` at that index.
|
|
708
|
-
3. If `value_type` is non-numeric (e.g., Address, String) → CREATE a new Guard with a numeric `value_type` (U8/U16/U32/U64/U128/U256).
|
|
709
|
-
4. Re-test via `gen_passport` with a numeric mock submission.
|
|
710
|
-
5. Re-add the new Guard to the Arbitration's `voting_guard[]`.
|
|
711
|
-
|
|
712
|
-
**Prevention**: R5's binding plan explicitly checks the `GuardIdentifier` type constraint for Arbitration `voting_guard`. The §Type Requirements by Object table lists this constraint. Always validate before CREATE.
|
|
713
|
-
|
|
714
|
-
### F6: Guard Logic Correct but Host Object Rejects Operation
|
|
715
|
-
|
|
716
|
-
**Trigger**: The Guard passes `gen_passport` in isolation, but when bound to a live Machine Forward, the operation still fails.
|
|
717
|
-
|
|
718
|
-
**Diagnosis**: The Guard's logic is correct in isolation but the host object's context provides different data. Common causes: (a) the Machine Forward's `retained_submission` index doesn't match the Guard's table; (b) the Service's `order_allocators` evaluation order means a different Allocator's Guard wins first (first-Guard-wins); (c) the Arbitration is paused (`bPaused: true`), which blocks before the Guard is even evaluated.
|
|
719
|
-
|
|
720
|
-
**Recovery**:
|
|
721
|
-
1. Query the host object via `query_toolkit` → `onchain_objects` — check `bPaused`, `order_allocators` order, Forward `retained_submission` indices.
|
|
722
|
-
2. If Arbitration is paused → unpause first (after confirming all config is ready).
|
|
723
|
-
3. If `order_allocators` order is wrong → MODIFY the Service to reorder (pre-publish only; post-publish, `order_allocators` is immutable).
|
|
724
|
-
4. If `retained_submission` index mismatches → CREATE a new Guard with the correct index, rebind.
|
|
725
|
-
5. Re-test the live operation.
|
|
726
|
-
|
|
727
|
-
**Prevention**: R9's binding verifies the host object's state. For Arbitration, confirm `pause: false` before expecting Guard evaluation. For Service `order_allocators`, confirm the evaluation order matches the intended priority. For Machine Forwards, confirm `retained_submission` indices align with the Guard's table.
|
|
728
|
-
|
|
729
448
|
---
|
|
730
449
|
|
|
731
|
-
##
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
-
|
|
736
|
-
-
|
|
737
|
-
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
- Trigger: user is new, or the validation rule is genuinely simple.
|
|
741
|
-
|
|
742
|
-
### Advanced Tier — Multi-Condition & Cross-Object
|
|
743
|
-
|
|
744
|
-
- Guards combine multiple conditions via `logic_and` / `logic_or`. Tables have 4–10 entries including submissions and constants.
|
|
745
|
-
- Cross-object queries via `convert_witness` (e.g., query Progress from an Order ID, query Machine from a Progress).
|
|
746
|
-
- `rely` composition with up to 4 standalone (`rep: true`) Guards for modular logic.
|
|
747
|
-
- Time-lock Guards with `context(Clock)` and `calc_number_*` arithmetic.
|
|
748
|
-
- R1-R6 are full design sessions. R8 tests multiple scenarios (pass, fail, edge).
|
|
749
|
-
- The §Phase 1-5 design phases and §Quick Decision pattern table are the primary references.
|
|
750
|
-
- Trigger: user says "I want a complex Guard" or has completed prior single-purpose Guards.
|
|
751
|
-
|
|
752
|
-
### Expert Tier — Dynamic Data & Composition
|
|
753
|
-
|
|
754
|
-
- Guards provide dynamic data to host objects: Arbitration `voting_guard` with `GuardIdentifier` for weighted voting, Repository `write_guard` with `id_from_submission` and `data_from_submission` for data extraction.
|
|
755
|
-
- `rely` composition with OR logic (any dependency passing is sufficient) for flexible eligibility.
|
|
756
|
-
- Cross-Machine Guards querying sub-Progress and sub-Orders via `convert_witness` (per [wowok-machine](../wowok-machine/SKILL.md) §Cross-Machine Composition).
|
|
757
|
-
- `retained_submission` on Machine Forwards for audit trails and subsequent validation.
|
|
758
|
-
- Multi-Guard `gen_passport` calls (up to 20 Guards AND-ed) for complex credential issuance.
|
|
759
|
-
- Off-chain Passport use cases: Guards as credential issuers for off-chain permission verification, not just on-chain gates.
|
|
760
|
-
- R1-R6 are expert design sessions; the AI's role is to validate types and constraints, not to suggest patterns.
|
|
761
|
-
- The §Guard Data Flow and §Type Requirements by Object tables are the primary references.
|
|
762
|
-
- Trigger: user explicitly asks for "expert mode", references `convert_witness` types by number, or designs Guards for Arbitration voting / Repository data extraction.
|
|
450
|
+
## Appendices (Progressive Disclosure)
|
|
451
|
+
|
|
452
|
+
> The following sections have been extracted to [APPENDIX.md](./APPENDIX.md) for on-demand loading:
|
|
453
|
+
> - Dialogue Scripts (R1-R10) — guided conversation scripts
|
|
454
|
+
> - Decision Trees — branching logic reference
|
|
455
|
+
> - Failure Playbooks — recovery scenarios
|
|
456
|
+
> - Tier Layering — expertise-tier based guidance
|
|
457
|
+
>
|
|
458
|
+
> Load APPENDIX.md when the user needs guided dialogue, recovery help, or tier-specific guidance.
|