@wowok/skills 1.1.2 → 1.1.3
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/package.json +1 -1
- package/wowok-arbitrator/SKILL.md +192 -192
- package/wowok-guard/SKILL.md +189 -285
- package/wowok-machine/SKILL.md +167 -328
- package/wowok-order/SKILL.md +6 -6
- package/wowok-provider/SKILL.md +3 -1
- package/wowok-safety/SKILL.md +20 -2
- package/wowok-tools/SKILL.md +141 -536
package/wowok-guard/SKILL.md
CHANGED
|
@@ -1,401 +1,305 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: wowok-guard
|
|
3
3
|
description: |
|
|
4
|
-
WoWok Guard
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
Guards are the most complex WoWok component; incorrect node types cause
|
|
12
|
-
immediate runtime failures.
|
|
4
|
+
WoWok Guard — on-chain programmable validation rules that control access,
|
|
5
|
+
verify eligibility, and provide dynamic data to objects. Guards serve as
|
|
6
|
+
the trust layer for Services (buy_guard), Arbitration (voting_guard weight,
|
|
7
|
+
usage_guard), Machines (forward validation), Demands (recommendation filtering),
|
|
8
|
+
Rewards (claim eligibility), and Repositories (write validation with data extraction).
|
|
9
|
+
Guards also enable off-chain use cases: generate a Passport via `gen_passport` to
|
|
10
|
+
obtain a signed, time-bound credential for off-chain permission verification.
|
|
13
11
|
when_to_use:
|
|
14
12
|
- User wants to create or modify a Guard
|
|
15
|
-
- User asks about Guard logic, validation rules, trust rules
|
|
16
|
-
- User encounters Guard validation errors
|
|
13
|
+
- User asks about Guard logic, validation rules, trust rules, programmable conditions
|
|
14
|
+
- User encounters Guard validation errors or needs to debug a Guard
|
|
17
15
|
- User mentions "guard", "validation", "trust rules", "verify", "condition"
|
|
18
|
-
|
|
16
|
+
- User asks about buy_guard, allocator guard, reward guard, machine node guard
|
|
17
|
+
- User asks about arbitration voting_guard or usage_guard
|
|
18
|
+
- User needs identity checks, time-locks, multi-condition verification, or entity queries
|
|
19
|
+
- User wants to understand how Guards integrate with other WoWok objects
|
|
19
20
|
---
|
|
20
21
|
|
|
21
22
|
# WoWok Guard Design Reference
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
> **Role**: Service Provider, Arbitrator, or any builder needing programmable on-chain validation
|
|
25
|
+
> **Prerequisites**: Understand CREATE vs MODIFY pattern — Guards are CREATE-only; once deployed on-chain their logic is frozen forever
|
|
26
|
+
> **Machine Integration**: See [wowok-machine](../wowok-machine/SKILL.md) for how Guards attach to workflow node forwards
|
|
27
|
+
> **Service Provider**: See [wowok-provider](../wowok-provider/SKILL.md) for buy_guard, allocator guards, and reward guard configuration
|
|
28
|
+
> **Customer Order Operations**: See [wowok-order](../wowok-order/SKILL.md) for Guard submissions during Progress advancement and the arbitration dispute process from the customer's perspective
|
|
29
|
+
> **Arbitrator Operations**: See [wowok-arbitrator](../wowok-arbitrator/SKILL.md) for voting_guard and usage_guard configuration, vote organization, and the full Arb case lifecycle from the arbitrator's perspective
|
|
30
|
+
> **Messenger**: See [wowok-messenger](../wowok-messenger/SKILL.md) for encrypted evidence exchange
|
|
31
|
+
> **Tools**: See [wowok-tools](../wowok-tools/SKILL.md)
|
|
24
32
|
|
|
25
|
-
|
|
33
|
+
---
|
|
26
34
|
|
|
27
|
-
##
|
|
35
|
+
## Core Concepts
|
|
28
36
|
|
|
29
|
-
|
|
37
|
+
### What a Guard IS
|
|
30
38
|
|
|
31
|
-
|
|
39
|
+
A Guard is an **immutable, on-chain programmable validator** — a single-purpose computational tree that returns a boolean: **pass** or **fail**. Every operation protected by a Guard must satisfy its validation logic before the operation can proceed.
|
|
32
40
|
|
|
33
|
-
**
|
|
34
|
-
- `namedNew`: Object creation options (name, tags, onChain, replaceExistName)
|
|
35
|
-
- `description`: Guard description
|
|
36
|
-
- `table`: Data table defining what the Guard validates
|
|
37
|
-
- `identifier`: 0-255, unique within this Guard
|
|
38
|
-
- `b_submission`: Must user submit this value?
|
|
39
|
-
- `value_type`: Expected type (0-18, see ValueType enum)
|
|
40
|
-
- `value`: Default value (if b_submission = false)
|
|
41
|
-
- `name`: Human-readable field name
|
|
42
|
-
- `root`: The computational tree
|
|
43
|
-
- `type: "node"`: Inline node definition
|
|
44
|
-
- `type: "file"`: Load from JSON/Markdown file
|
|
45
|
-
- `rely`: Dependencies on other Guards
|
|
46
|
-
- `guards`: Array of Guard IDs or names
|
|
47
|
-
- `logic_or`: OR (true) vs AND (false/default)
|
|
48
|
-
|
|
49
|
-
**CRITICAL**: The Guard's `table` defines ALL data the Guard uses — both submitted values and values passed from the calling object. Every `identifier` node in the tree references a table entry.
|
|
41
|
+
Think of a Guard as a **computational tree of typed nodes** that query on-chain data, compare values, perform arithmetic, and compute one final answer. It has no side effects. It stores no mutable state. It exists purely to answer: "Should this action be allowed?"
|
|
50
42
|
|
|
51
|
-
|
|
43
|
+
### The Immutability Contract
|
|
52
44
|
|
|
53
|
-
|
|
45
|
+
Guards are **CREATE-only**. Once frozen on-chain, logic cannot be altered — this is the foundation of trust. To change a Guard: export via `guard2file`, create a new Guard, and update all references. See wowok-safety skill for naming conventions.
|
|
54
46
|
|
|
55
|
-
The
|
|
47
|
+
### The Three Structural Layers
|
|
56
48
|
|
|
57
|
-
|
|
49
|
+
Every Guard is built from three layers, each with a distinct role:
|
|
58
50
|
|
|
59
|
-
|
|
51
|
+
| Layer | Component | Role | Immutable? |
|
|
52
|
+
|-------|-----------|------|------------|
|
|
53
|
+
| **Declaration** | `table` | Declares every piece of data the Guard touches — constants and runtime submissions — each with a unique identifier (0–255) | Yes |
|
|
54
|
+
| **Computation** | `root` | A computational tree of GuardNode types that computes the final boolean result by combining data sources, comparisons, arithmetic, and logic | Yes |
|
|
55
|
+
| **Composition** | `rely` (optional) | References to other Guards; the current Guard's result is AND-ed or OR-ed with dependencies, enabling modular Guard composition | Yes |
|
|
60
56
|
|
|
61
|
-
**
|
|
57
|
+
**The table is the contract with callers**: It tells them exactly what data they must provide at runtime (`b_submission: true`) versus what the Guard already knows (`b_submission: false`). Every `identifier` node in the computation tree references exactly one table entry.
|
|
62
58
|
|
|
63
|
-
**
|
|
64
|
-
- `identifier`: Guard table index (0-255)
|
|
59
|
+
**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.
|
|
65
60
|
|
|
66
|
-
|
|
61
|
+
**The rely is composition**: Up to 4 dependent Guards. When `rely.logic_or` is false (default), all dependencies must pass. When true, any dependency passing is sufficient. This lets you build complex validation from simple, tested components. A Guard can only depend on Guards that are themselves standalone (`immutable: true` and `rep: true`) — no circular or transitive dependency chains.
|
|
67
62
|
|
|
68
|
-
|
|
63
|
+
### 4. Where Guards Attach in the Ecosystem
|
|
69
64
|
|
|
70
|
-
**
|
|
65
|
+
Guards are not standalone — they plug into other WoWok objects as validation rules. Understanding these integration points is essential because the **context** of the Guard determines what data is available to it and what happens when it fails.
|
|
71
66
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
67
|
+
| Host Object | Guard Field | What It Controls | Operator | Who Provides Submission Data |
|
|
68
|
+
|-------------|-------------|-----------------|----------|------------------------------|
|
|
69
|
+
| **Service** | `buy_guard` | Who can purchase from this service | Customer | Customer (signer, credentials) |
|
|
70
|
+
| **Service** | `order_allocators[].guard` | Which fund distribution strategy executes | System (auto-evaluated) | System derives from Progress state |
|
|
71
|
+
| **Machine** | Forward `guard` | Who can advance to the next workflow node | Customer or Provider | The party executing the forward |
|
|
72
|
+
| **Progress** | Submission guard | Whether submitted data satisfies conditions during forward execution | Customer or Provider | The party submitting data |
|
|
73
|
+
| **Reward** | `guard` | Who can claim from the reward pool | Claimant | Claimant (address, credentials) |
|
|
74
|
+
| **Repository** | Write/quote guard | Who can write to or read from on-chain storage | Writer/Reader | Writer/Reader |
|
|
75
|
+
| **Arbitration** | `usage_guard` | Who can file a dispute against this arbitration | Customer | Customer (Passport credential) |
|
|
76
|
+
| **Arbitration** | `voting_guard[]` | Who can vote on arbitration proposals and with what weight | Voters (authenticated via Arbitrator) | Voter (Passport credential with weight data) |
|
|
77
|
+
| **Gen Passport** | Guard verification | Generating verified credentials after successful validation | Passport holder | Passport applicant |
|
|
76
78
|
|
|
77
79
|
---
|
|
78
80
|
|
|
79
|
-
|
|
81
|
+
## Phase 1: Design — Analyze the Validation Intent
|
|
80
82
|
|
|
81
|
-
**
|
|
83
|
+
Before constructing any node, articulate **what** you are validating and **why**. Start from the business requirement, not the data structure.
|
|
82
84
|
|
|
83
|
-
|
|
84
|
-
- `query`: Query instruction ID (number) or name (string)
|
|
85
|
-
- `object`: Target object specification
|
|
86
|
-
- `identifier`: Guard table index for target object
|
|
87
|
-
- `convert_witness`: Optional witness conversion ID
|
|
88
|
-
- `parameters`: Array of GuardNode parameters for the query
|
|
85
|
+
### The Central Questions
|
|
89
86
|
|
|
90
|
-
|
|
87
|
+
Every Guard answers these questions:
|
|
91
88
|
|
|
92
|
-
**
|
|
89
|
+
1. **What action is being protected?** — Buying a service? Advancing a workflow node? Claiming a reward? Casting a weighted vote? Filing a dispute?
|
|
93
90
|
|
|
94
|
-
**
|
|
91
|
+
2. **What data does the Guard have access to?** — Guards see only:
|
|
92
|
+
- Their own `table` (pre-set constants plus runtime submissions from the caller)
|
|
93
|
+
- On-chain state queried through `query` nodes targeting live WoWok objects
|
|
94
|
+
- Transaction context (the current Clock timestamp, the signer's address, the Guard's own object ID)
|
|
95
95
|
|
|
96
|
-
**
|
|
97
|
-
| Constant | Value | Use For |
|
|
98
|
-
|----------|-------|---------|
|
|
99
|
-
| ENTITY_LINKER_ADDRESS | 0xaaa | EntityLinker queries |
|
|
100
|
-
| ENTITY_REGISTRAR_ADDRESS | 0xaab | EntityRegistrar queries |
|
|
96
|
+
3. **What should the verdict be?** — A single boolean: pass or fail. The root of every Guard tree must return Bool.
|
|
101
97
|
|
|
102
|
-
|
|
98
|
+
### Map Business Requirements to Guard Patterns
|
|
103
99
|
|
|
104
|
-
|
|
100
|
+
| Business Requirement | Guard Pattern | Key Mechanism | Implementation Notes |
|
|
101
|
+
|----------------------|---------------|---------------|---------------------|
|
|
102
|
+
| "Only the author can purchase this service" | Identity check | Signer address equals stored authorized address | `context(Signer)` vs table constant via `logic_equal`. Variation: use `vec_contains_address` for allowlists |
|
|
103
|
+
| "Customer must wait 8 hours before completing" | Time-lock | Clock timestamp exceeds progress entry time plus duration | `context(Clock)` vs `calc_number_add` of Progress query + duration constant. Use `convert_witness=100` to derive Progress from submitted Order ID |
|
|
104
|
+
| "Only sunny weather on the activity date" | Repository data check | External data matches expected value | `query` on Repository with policy name and data key. Timestamp keys may need `convert_number_address` |
|
|
105
|
+
| "Customer must confirm delivery via signature" | Progress history check | Specific forward has been accomplished | Chain `query_progress_history_find` → `query_progress_history_session_forward_find`. Check `accomplished` flag with `logic_equal` |
|
|
106
|
+
| "User can only claim reward once" | Reward record count check | No prior claims exist | `query_reward_record_count` with recipient filter; compare count to zero via `logic_equal` |
|
|
107
|
+
| "Order payment > 1,000,000 and reached 'complete' to claim reward" | Multi-condition | Order amount + progress state + service match | Combine multiple `query` nodes with `logic_and`. Use `convert_witness=TypeOrderProgress` to access Progress from Order |
|
|
108
|
+
| "Vote weight equals reputation score" | Dynamic weight | GuardIdentifier extracts numeric value from Passport | Table needs numeric submission entry at referenced index. Guard validates eligibility AND weight range |
|
|
109
|
+
| "Only premium members can file disputes" | Membership verification | Entity registration or tier check | `query` on ENTITY_REGISTRAR_ADDRESS or Repository. Combine entity existence check with tier comparison via `logic_and` |
|
|
105
110
|
|
|
106
|
-
|
|
111
|
+
### Design Before Building
|
|
107
112
|
|
|
108
|
-
|
|
113
|
+
The Guard design process is entirely upfront. There is no "draft" or "edit" phase after creation. Design thoroughly before calling the create operation:
|
|
109
114
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
+
1. **Query available query instructions first**: Before designing any Guard that queries on-chain data, use `wowok_buildin_info` with query `"guard queries"` to retrieve the complete list of available query instructions. Each query has a specific ID, name, parameters, and return type — you MUST verify these details before constructing your Guard. Never guess query instruction names or parameter types.
|
|
116
|
+
2. List every data dependency — what must the caller provide? What constants are baked in?
|
|
117
|
+
3. Sketch the logic tree — what comparisons, arithmetic, and logical combinations produce the final boolean?
|
|
118
|
+
4. Verify types — does every comparison receive compatible operands? Are all conversions explicit?
|
|
119
|
+
5. Test the tree mentally — what happens with edge case inputs? What happens if a query returns empty?
|
|
115
120
|
|
|
116
|
-
|
|
121
|
+
---
|
|
117
122
|
|
|
118
|
-
|
|
119
|
-
|------|----------|-------------|
|
|
120
|
-
| `logic_equal` | `nodes[]` | Type+value equality; all must match first |
|
|
121
|
-
| `logic_string_nocase_equal` | `nodes[]` | Case-insensitive string equality |
|
|
123
|
+
## Phase 2: Declare the Data Table
|
|
122
124
|
|
|
123
|
-
|
|
125
|
+
The Guard table is the **complete declaration of information** the Guard consumes. Every `identifier` node in the computation tree references exactly one table entry by its index number (0–255). Nothing outside the table is accessible.
|
|
124
126
|
|
|
125
|
-
|
|
126
|
-
|------|----------|-------------|
|
|
127
|
-
| `logic_string_contains` | `nodes[]` | First contains all others (case-sensitive) |
|
|
128
|
-
| `logic_string_nocase_contains` | `nodes[]` | First contains all others (case-insensitive) |
|
|
127
|
+
### Table Entry Fields
|
|
129
128
|
|
|
130
|
-
|
|
129
|
+
| Field | Meaning | Required When |
|
|
130
|
+
|-------|---------|---------------|
|
|
131
|
+
| `identifier` | Unique index (0–255). The computation tree uses this number to reference the entry. | Always |
|
|
132
|
+
| `b_submission` | Whether the **caller** must provide this value at runtime. `true` = runtime submission; `false` = pre-set constant. | Always |
|
|
133
|
+
| `value_type` | The type of the value: Bool, Address, String, U8–U256, or vector types. Uses numeric type codes (use `wowok_buildin_info` with query `"value types"` for the complete mapping). | Always |
|
|
134
|
+
| `value` | The constant value when `b_submission` is false; a placeholder when `b_submission` is true. | When `b_submission` is false |
|
|
135
|
+
| `name` | Human-readable label describing what this entry represents. | Always |
|
|
131
136
|
|
|
132
|
-
|
|
133
|
-
|------|----------|-------------|
|
|
134
|
-
| `logic_as_u256_equal` | `nodes[]` | First == all others |
|
|
135
|
-
| `logic_as_u256_greater` | `nodes[]` | First > all others |
|
|
136
|
-
| `logic_as_u256_lesser` | `nodes[]` | First < all others |
|
|
137
|
-
| `logic_as_u256_greater_or_equal` | `nodes[]` | First >= all others |
|
|
138
|
-
| `logic_as_u256_lesser_or_equal` | `nodes[]` | First <= all others |
|
|
137
|
+
### Design Rules
|
|
139
138
|
|
|
140
|
-
|
|
139
|
+
- **Every identifier in the tree must exist in the table.** Missing references cause creation to fail.
|
|
140
|
+
- **No duplicate identifiers.** Each index number must appear exactly once.
|
|
141
|
+
- **Non-submission entries must have a value.** These are baked into the Guard immutably.
|
|
142
|
+
- **Submission entries use placeholder values.** The actual value is provided by the caller at runtime.
|
|
143
|
+
- **Query target objects must be of type Address in the table.** Their `object_type` field should match the expected query target type (Progress, Order, Machine, Reward, etc.).
|
|
144
|
+
- **Maximum 256 table entries** (identifiers 0–255). The total serialized table size must not exceed 40000 bytes.
|
|
141
145
|
|
|
142
|
-
###
|
|
146
|
+
### The convert_witness Mechanism
|
|
143
147
|
|
|
144
|
-
|
|
148
|
+
`convert_witness` transforms a submitted object ID into its associated object — enabling queries across object relationships without requiring the caller to submit multiple IDs.
|
|
145
149
|
|
|
146
|
-
|
|
147
|
-
|------|-----------|
|
|
148
|
-
| `calc_number_add` | first + second + third + ... |
|
|
149
|
-
| `calc_number_subtract` | first - second - third - ... |
|
|
150
|
-
| `calc_number_multiply` | first × second × third × ... |
|
|
151
|
-
| `calc_number_divide` | (first / second) / third / ... (throws on zero) |
|
|
152
|
-
| `calc_number_mod` | (first % second) % third % ... (throws on zero) |
|
|
150
|
+
**Core principle**: Caller submits what they have (e.g., Order ID); Guard queries what it needs (e.g., Progress state) via witness conversion.
|
|
153
151
|
|
|
154
|
-
|
|
152
|
+
**Rules**:
|
|
153
|
+
- Witness type encodes source→target transformation (e.g., `100` = Order→Progress)
|
|
154
|
+
- Table entry's `object_type` must match witness source type
|
|
155
|
+
- Query instruction's object type must match witness target type
|
|
156
|
+
- Type mismatches cause Guard creation to fail
|
|
155
157
|
|
|
156
|
-
|
|
157
|
-
|------|----------|---------|-------------|
|
|
158
|
-
| `calc_string_length` | `node` (1) | U64 | UTF-8 byte length |
|
|
159
|
-
| `calc_string_contains` | `nodes[]` (2-8) | Bool | cs substring check |
|
|
160
|
-
| `calc_string_nocase_contains` | `nodes[]` (2-8) | Bool | ci substring check |
|
|
161
|
-
| `calc_string_nocase_equal` | `nodes[]` (2-8) | Bool | ci equality |
|
|
158
|
+
**Available Witness Types**:
|
|
162
159
|
|
|
163
|
-
|
|
160
|
+
| Witness Type | Value | Source → Target | Use Case |
|
|
161
|
+
|--------------|-------|-----------------|----------|
|
|
162
|
+
| TypeOrderProgress | 100 | Order → Progress | Check if order has reached a specific workflow node (e.g., 'complete') before allowing reward claims |
|
|
163
|
+
| TypeOrderMachine | 101 | Order → Machine | Verify the workflow structure or check node configurations |
|
|
164
|
+
| TypeOrderService | 102 | Order → Service | Validate the service offering details or check service-level configurations |
|
|
165
|
+
| TypeProgressMachine | 103 | Progress → Machine | Access workflow definition from a Progress context |
|
|
166
|
+
| TypeArbOrder | 104 | Arb → Order | In arbitration voting guards, verify order details like payment amount or service ID |
|
|
167
|
+
| TypeArbArbitration | 105 | Arb → Arbitration | Access arbitration configuration or fee settings from within an Arb case |
|
|
168
|
+
| TypeArbProgress | 106 | Arb → Progress | Check order workflow state during arbitration validation |
|
|
169
|
+
| TypeArbMachine | 107 | Arb → Machine | Access workflow definition for dispute context analysis |
|
|
170
|
+
| TypeArbService | 108 | Arb → Service | Verify service terms or compensation fund status during arbitration |
|
|
164
171
|
|
|
165
|
-
|
|
166
|
-
|------|----------|-------------|
|
|
167
|
-
| `calc_string_indexof` | `nodeLeft` + `nodeRight` + `order` | Find substring index (cs). `order`: "forward" or "backward". Not found → u64::MAX |
|
|
168
|
-
| `calc_string_nocase_indexof` | `nodeLeft` + `nodeRight` + `order` | Find substring index (ci) |
|
|
172
|
+
**Example**: To validate that an order has reached the 'complete' node, query the Order with `convert_witness=100` (TypeOrderProgress) and check the Progress's `current_node` field.
|
|
169
173
|
|
|
170
174
|
---
|
|
171
175
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
All take single `node` child.
|
|
176
|
+
## Phase 3: Build the Computational Tree
|
|
175
177
|
|
|
176
|
-
|
|
177
|
-
|------|---------------|-------------|
|
|
178
|
-
| `convert_number_address` | Number → Address | Numeric to Address type |
|
|
179
|
-
| `convert_address_number` | Address → U256 | Address to numeric |
|
|
180
|
-
| `convert_number_string` | Number → String | Numeric to string |
|
|
181
|
-
| `convert_string_number` | String → U256 | Parse string as number (throws if invalid) |
|
|
182
|
-
| `convert_safe_u8` | any → U8 | Safe cast to U8 (throws on overflow) |
|
|
183
|
-
| `convert_safe_u16` | any → U16 | Safe cast to U16 |
|
|
184
|
-
| `convert_safe_u32` | any → U32 | Safe cast to U32 |
|
|
185
|
-
| `convert_safe_u64` | any → U64 | Safe cast to U64 |
|
|
186
|
-
| `convert_safe_u128` | any → U128 | Safe cast to U128 |
|
|
187
|
-
| `convert_safe_u256` | any → U256 | Safe cast to U256 |
|
|
188
|
-
|
|
189
|
-
---
|
|
178
|
+
The root tree is a computational expression whose terminal nodes read data and whose intermediate nodes transform, compare, and combine that data. The root must return Bool.
|
|
190
179
|
|
|
191
|
-
###
|
|
180
|
+
### Tree Principles
|
|
192
181
|
|
|
193
|
-
|
|
182
|
+
- **Type safety is enforced at creation time.** Every node validates that its children return types compatible with its operation. A `logic_equal` node that receives a String child and a U64 child will fail validation.
|
|
183
|
+
- **Evaluation order is stack-based.** Children are evaluated in reverse, so the first child in the array appears at the top of the evaluation stack.
|
|
184
|
+
- **The root must return Bool.** Logic and comparison nodes produce Bool. Arithmetic nodes produce numbers. Conversion nodes produce the target type. Ensure your outermost node is a logic or comparison type.
|
|
185
|
+
- **Every `identifier` node's index must exist in the table.** This is validated at creation time.
|
|
194
186
|
|
|
195
|
-
|
|
196
|
-
|------|----------|---------|-------------|
|
|
197
|
-
| `vec_length` | `node` (1) | U64 | Number of elements |
|
|
187
|
+
### Discovering Available Node Types
|
|
198
188
|
|
|
199
|
-
|
|
189
|
+
Guard computational trees are built from typed nodes. Rather than listing all possible nodes (which evolves with the system), query the authoritative schema dynamically:
|
|
200
190
|
|
|
201
|
-
|
|
191
|
+
**Tool**: `schema_query({ action: "get", name: "onchain_operations_guard" })`
|
|
202
192
|
|
|
203
|
-
|
|
204
|
-
|------|------------|--------------|
|
|
205
|
-
| `vec_contains_bool` | VecBool (9) or Value (19) | Bool (0) or Value (19) |
|
|
206
|
-
| `vec_contains_address` | VecAddress (10) or Value (19) | Address (1) or Value (19) |
|
|
207
|
-
| `vec_contains_string` | VecString (11) or Value (19) | String (2) or Value (19) |
|
|
208
|
-
| `vec_contains_string_nocase` | VecString or Value (19) | String or Value (19), ci |
|
|
209
|
-
| `vec_contains_number` | VecU8-VecU256 or Value (19) | U8-U256 or Value (19) |
|
|
193
|
+
This returns the complete `GuardNodeSchema` definition — every node type, its required fields, input/output types, and validation rules. Node categories include:
|
|
210
194
|
|
|
211
|
-
|
|
195
|
+
- **Data source nodes**: `identifier`, `context`, `query` — read values from the Guard table, transaction context, or on-chain objects
|
|
196
|
+
- **Logic & Arithmetic nodes**: `logic_*`, `calc_number_*` — combine values into boolean decisions and compute numeric results
|
|
197
|
+
- **String, Conversion & Vector nodes**: `calc_string_*`, `convert_*`, `vec_*` — manipulate strings, transform types, search arrays
|
|
198
|
+
- **Record query nodes**: `query_reward_record_*`, `query_progress_history_*` — search on-chain historical data
|
|
212
199
|
|
|
213
|
-
|
|
214
|
-
|------|----------|-------------|
|
|
215
|
-
| `vec_indexof_bool` | `nodeLeft` + `nodeRight` + `order` | Find bool index |
|
|
216
|
-
| `vec_indexof_address` | `nodeLeft` + `nodeRight` + `order` | Find address index |
|
|
217
|
-
| `vec_indexof_string` | `nodeLeft` + `nodeRight` + `order` | Find string index (cs) |
|
|
218
|
-
| `vec_indexof_string_nocase` | `nodeLeft` + `nodeRight` + `order` | Find string index (ci) |
|
|
219
|
-
| `vec_indexof_number` | `nodeLeft` + `nodeRight` + `order` | Find number index |
|
|
200
|
+
**Key principle**: Every node declares its return type and the types it expects from children. The schema enforces these constraints at Guard creation time — type mismatches cause creation to fail. All numeric comparisons normalize to U256, enabling cross-type comparisons without explicit conversion.
|
|
220
201
|
|
|
221
|
-
`
|
|
202
|
+
**Query instructions**: For the `query` node, discover available instructions via `wowok_buildin_info` with query `"guard instructions"`. Use the `filter` parameter to narrow results by name, return type, parameter count, or object type — more effective than browsing raw ID ranges.
|
|
222
203
|
|
|
223
204
|
---
|
|
224
205
|
|
|
225
|
-
|
|
206
|
+
## Phase 4: Create the Guard
|
|
226
207
|
|
|
227
|
-
|
|
208
|
+
Guard creation is a **single atomic operation** — it either succeeds (the Guard is frozen on-chain) or fails (nothing is created). There is no intermediate draft state, no editing phase, and no deletion mechanism.
|
|
228
209
|
|
|
229
|
-
|
|
210
|
+
### Operation
|
|
230
211
|
|
|
231
|
-
|
|
232
|
-
|------|---------------|-------------|
|
|
233
|
-
| `record_check_recipient_order` | `receipt_type` + `recipient` | Check order count/status by recipient |
|
|
234
|
-
| `record_check_recipient_progress` | `recipient` | Check progress count by recipient |
|
|
235
|
-
| `record_check_recipient_reward` | `recipient` | Check reward claims by recipient |
|
|
236
|
-
| `record_check_treasury_history_item` | `historyIdx` + `sessionIdx` | Verify treasury operation |
|
|
237
|
-
| `record_check_treasury_history_item_no_um` | `historyIdx` + `sessionIdx` | Same but ignores Contact |
|
|
238
|
-
| `record_check_treasury_history_session` | `historyIdx` | Count treasury sessions |
|
|
239
|
-
| `record_check_progress_history_item` | `historyIdx` + `sessionIdx` + `forwardIdx` | Verify progress step |
|
|
240
|
-
| `record_check_progress_history_item_no_um` | `historyIdx` + `sessionIdx` + `forwardIdx` | Same but ignores Contact |
|
|
241
|
-
| `record_check_progress_history_session` | `historyIdx` + `sessionIdx` | Session info |
|
|
242
|
-
| `record_check_progress_history` | `historyIdx` | Count progress history |
|
|
212
|
+
Use `onchain_operations` with `operation_type: "guard"`.
|
|
243
213
|
|
|
244
|
-
|
|
214
|
+
**Schema Reference**: `schema_query({ action: "get", name: "onchain_operations_guard" })`
|
|
245
215
|
|
|
246
216
|
---
|
|
247
217
|
|
|
248
|
-
##
|
|
218
|
+
## Phase 5: Test, Export, and Query
|
|
249
219
|
|
|
250
|
-
###
|
|
220
|
+
### Test Independently with Gen Passport
|
|
251
221
|
|
|
252
|
-
|
|
222
|
+
Before embedding a Guard into a live Machine, Service, or Arbitration, test it in isolation.
|
|
253
223
|
|
|
254
|
-
|
|
224
|
+
**Tool**: `gen_passport`
|
|
255
225
|
|
|
256
|
-
|
|
226
|
+
**Schema Reference**: `schema_query({ action: "get", name: "gen_passport" })`
|
|
257
227
|
|
|
258
|
-
|
|
228
|
+
This tool verifies one or more Guards and, on success, generates an immutable Passport — a verified credential stored on-chain. Use it to:
|
|
259
229
|
|
|
260
|
-
|
|
261
|
-
-
|
|
262
|
-
- U8=3, U16=4, U32=5, U64=6, U128=7, U256=8
|
|
263
|
-
- VecBool=9, VecAddress=10, VecString=11
|
|
264
|
-
- VecU8=12, VecU16=13, VecU32=14, VecU64=15, VecU128=16, VecU256=17
|
|
265
|
-
- VecVecU8=18
|
|
230
|
+
- **Test edge cases**: What happens with empty submissions, boundary values, or unusual addresses?
|
|
231
|
+
- **Debug failures**: If the Guard rejects valid data, the error helps identify type mismatches or missing table entries.
|
|
266
232
|
|
|
267
|
-
|
|
233
|
+
The Passport itself is useful beyond testing — it serves as a reusable on-chain credential for offline verification, transaction condition checking, and multi-guard validation. A single Passport can satisfy multiple Guards in a single transaction.
|
|
268
234
|
|
|
269
|
-
|
|
270
|
-
- **Submitted data** (b_submission = true): User provides at operation time
|
|
271
|
-
- **Passed data** (b_submission = false): Object provides automatically
|
|
235
|
+
### Query On-Chain Guards
|
|
272
236
|
|
|
273
|
-
|
|
237
|
+
**Tool**: `query_toolkit` with `query_type: "onchain_objects"`
|
|
274
238
|
|
|
275
|
-
|
|
276
|
-
- Add child nodes for each condition
|
|
277
|
-
- Use `query` + `identifier` patterns for data fetching
|
|
278
|
-
- Use comparison nodes for validation
|
|
239
|
+
Guards are **public consensus**. Once bound to objects (Service, Machine, Arbitration), they become the trusted executor of rights and obligations. All parties can inspect the exact validation rules — this transparency is the foundation of trustless interaction. Query Guards before engaging with any protected operation.
|
|
279
240
|
|
|
280
|
-
|
|
241
|
+
---
|
|
281
242
|
|
|
282
|
-
|
|
243
|
+
## Guard Data Flow: How Objects Read Guard Data
|
|
283
244
|
|
|
284
|
-
**
|
|
285
|
-
- `namedNew`: Guard creation options with name
|
|
286
|
-
- `description`: Guard purpose
|
|
287
|
-
- `table`: Data table array
|
|
288
|
-
- `root`: Computational tree with `type: "node"` and `node` containing the tree
|
|
245
|
+
Guards are not just validators — they are **data sources**. When bound to objects, Guards provide structured data that the object reads and uses for decision-making. This section explains how different object types interact with Guard data.
|
|
289
246
|
|
|
290
|
-
|
|
247
|
+
### Arbitration: Voting Weight from Guard
|
|
291
248
|
|
|
292
|
-
|
|
249
|
+
Arbitration uses `usage_guard` for eligibility (pass/fail) and `voting_guard` for vote weight — either fixed or dynamically read from a Guard table submission index (`GuardIdentifier`). Table must have a numeric entry at the `GuardIdentifier` index; the value becomes the voter's weight (cast to u32).
|
|
293
250
|
|
|
294
|
-
|
|
251
|
+
### Demand: ServiceGuard with Identifier Mapping
|
|
295
252
|
|
|
296
|
-
|
|
297
|
-
- `guard`: Guard ID or name
|
|
298
|
-
- `file_path`: Output file path
|
|
299
|
-
- `format`: Output format ("json" or "markdown")
|
|
253
|
+
Demand's `ServiceGuard` validates recommendations. If `service_identifier` is set, the Guard submission value at that index is passed to the service for validation; if unset, only Guard pass/fail is checked.
|
|
300
254
|
|
|
301
|
-
###
|
|
255
|
+
### Machine: Forward Guard with Retained Submission
|
|
302
256
|
|
|
303
|
-
|
|
257
|
+
Machine's forward `guard` validates state transitions. If `retained_submission` is set, those submission values are stored in Progress for audit or subsequent validation.
|
|
304
258
|
|
|
305
|
-
|
|
259
|
+
### Repository: Policy Write Guard with Data Extraction
|
|
306
260
|
|
|
307
|
-
|
|
261
|
+
Repository's `write_guard` validates writes. If `id_from_submission` is set, reads entity ID from that submission index; if `data_from_submission` is set, reads data value from that index. Guard table must include entries for the data being extracted.
|
|
308
262
|
|
|
309
|
-
|
|
263
|
+
---
|
|
310
264
|
|
|
311
|
-
**
|
|
312
|
-
- Type: `logic_equal`
|
|
313
|
-
- Nodes: Two `identifier` nodes
|
|
314
|
-
- First: identifier 0 (submitted address)
|
|
315
|
-
- Second: identifier 1 (stored address)
|
|
265
|
+
**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.
|
|
316
266
|
|
|
317
|
-
|
|
267
|
+
---
|
|
318
268
|
|
|
319
|
-
|
|
320
|
-
- Type: `logic_as_u256_greater_or_equal`
|
|
321
|
-
- Nodes:
|
|
322
|
-
- First: `query` node
|
|
323
|
-
- query: "balance" (check wowok_buildin_info for correct ID)
|
|
324
|
-
- object: { identifier: 0 } (account from table[0])
|
|
325
|
-
- parameters: [ { type: "identifier", identifier: 1 } ] (coin_type from table[1])
|
|
326
|
-
- Second: `identifier` node with identifier 2 (minimum balance from table[2])
|
|
269
|
+
## Best Practices
|
|
327
270
|
|
|
328
|
-
###
|
|
271
|
+
### Common Pitfalls
|
|
329
272
|
|
|
330
|
-
**
|
|
331
|
-
- Type: `logic_as_u256_greater`
|
|
332
|
-
- Nodes:
|
|
333
|
-
- First: `query` node
|
|
334
|
-
- query: "entity_registrar_records_length"
|
|
335
|
-
- object: { identifier: 0 } (ENTITY_REGISTRAR_ADDRESS 0xaab)
|
|
336
|
-
- parameters: []
|
|
337
|
-
- Second: `identifier` node with identifier 1 (0 to check count > 0)
|
|
273
|
+
1. **Undefined table identifiers**: Every `identifier` node in the tree must match an entry in the table. Missing entries cause creation failure — validate your tree against your table before submitting.
|
|
338
274
|
|
|
339
|
-
|
|
275
|
+
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.
|
|
340
276
|
|
|
341
|
-
**
|
|
342
|
-
- Type: `logic_not`
|
|
343
|
-
- Node:
|
|
344
|
-
- Type: `record_check_recipient_order`
|
|
345
|
-
- receipt_type: "specific_value"
|
|
346
|
-
- recipient: { type: "identifier", identifier: 0 }
|
|
277
|
+
3. **Wrong query instruction IDs or parameter counts**: Query instructions are system-defined. Always discover them through `wowok_buildin_info` with `"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.
|
|
347
278
|
|
|
348
|
-
|
|
279
|
+
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.
|
|
349
280
|
|
|
350
|
-
|
|
281
|
+
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.
|
|
351
282
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
1. **`identifier` nodes reference table indices** — NOT arbitrary names. Every identifier must be defined in `table[]`.
|
|
355
|
-
2. **`query` nodes need `object.identifier`** — the target object comes from the Guard table.
|
|
356
|
-
3. **`query` instruction IDs come from `wowok_buildin_info`** — never guess query instruction IDs.
|
|
357
|
-
4. **Entity queries use system addresses** — ENTITY_LINKER_ADDRESS (0xaaa) and ENTITY_REGISTRAR_ADDRESS (0xaab).
|
|
358
|
-
5. **Root should return Bool** — final result determines pass/fail.
|
|
359
|
-
6. **node type names are lower_snake_case** — `logic_and`, `calc_number_add`, `convert_number_address`, etc.
|
|
360
|
-
7. **Guards are IMMUTABLE** — after creation, they cannot be modified. Export → Edit → Create New.
|
|
361
|
-
8. **Use `guard2file` for review** — always export and verify Guard logic before executing.
|
|
362
|
-
|
|
363
|
-
## Common Errors
|
|
364
|
-
|
|
365
|
-
| Error | Cause | Fix |
|
|
366
|
-
|-------|-------|-----|
|
|
367
|
-
| "unknown node type" | Wrong type name | Use exact names from this reference |
|
|
368
|
-
| "identifier out of range" | Table index mismatch | Verify identifiers match table indices |
|
|
369
|
-
| "query not found" | Invalid instruction ID | Query `wowok_buildin_info` for valid IDs |
|
|
370
|
-
| "type mismatch" | Wrong ValueType in table | Match table type to actual value type |
|
|
371
|
-
| "table field required" | Missing table array | Guards MUST have `table[]` |
|
|
372
|
-
| "guard validation failed" | Logic error | Export with `guard2file`, review logic |
|
|
373
|
-
| "object not found" | Wrong query object | Verify object addresses/identifiers |
|
|
283
|
+
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.
|
|
374
284
|
|
|
375
|
-
|
|
285
|
+
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.
|
|
376
286
|
|
|
377
|
-
|
|
287
|
+
8. **Dependency on non-standalone Guards**: A Guard's `rely` entries must reference Guards that are themselves standalone (`immutable: true` and `rep: true`). Guards with their own dependencies cannot be used as dependencies for others — this is a strict no-transitive-dependency rule.
|
|
378
288
|
|
|
379
|
-
When using
|
|
289
|
+
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`.
|
|
380
290
|
|
|
381
|
-
|
|
382
|
-
|-----------|-----|-------------|
|
|
383
|
-
| TypeOrderProgress | 100 | From Order, get its Progress |
|
|
384
|
-
| TypeOrderMachine | 101 | From Order, get its Machine |
|
|
385
|
-
| TypeOrderService | 102 | From Order, get its Service |
|
|
386
|
-
| TypeProgressMachine | 103 | From Progress, get its Machine |
|
|
387
|
-
| TypeArbOrder | 104 | From Arb, get its Order |
|
|
291
|
+
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.
|
|
388
292
|
|
|
389
293
|
---
|
|
390
294
|
|
|
391
|
-
##
|
|
392
|
-
|
|
393
|
-
|
|
|
394
|
-
|
|
395
|
-
|
|
|
396
|
-
|
|
|
397
|
-
|
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
295
|
+
## Tool Reference
|
|
296
|
+
|
|
297
|
+
| Tool | Purpose |
|
|
298
|
+
|------|---------|
|
|
299
|
+
| `wowok_buildin_info` (`query: "guard instructions"`) | Discover all available query instructions — their IDs, parameter types, return types, and target object types |
|
|
300
|
+
| `wowok_buildin_info` (`query: "value types"`) | Discover the numeric codes for all supported value types used in table entries |
|
|
301
|
+
| `wowok_buildin_info` (`query: "built-in permissions"`) | Discover all built-in permission index codes for use with `permission.entity.perm has` queries |
|
|
302
|
+
| `gen_passport` | Test Guard validation with runtime submissions and generate a verified on-chain credential on success |
|
|
303
|
+
| `guard2file` | Export an existing Guard's complete definition (description, table, root tree, dependencies) to a local JSON or Markdown file |
|
|
304
|
+
| `query_toolkit` (`query_type: "onchain_objects"`) | Query any Guard object on-chain by name or address to inspect its full definition |
|
|
305
|
+
| `schema_query` (`name: "onchain_operations_guard"`) | Retrieve the complete Guard operation schema with all parameter definitions |
|