@wowok/skills 1.3.4 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,7 @@
2
2
  name: wowok-order
3
3
  description: |
4
4
  WoWok Customer Guide — complete buyer order lifecycle: pre-purchase due diligence
5
- (E1-E10), consensus building, order creation, progress advancement, and arbitration.
5
+ (E1-E11), consensus building, order creation, progress advancement, and arbitration.
6
6
  when_to_use:
7
7
  - User is a customer/buyer placing or managing orders
8
8
  - User wants to evaluate services before purchasing
@@ -15,7 +15,8 @@ when_to_use:
15
15
  # WoWok Customer Guide
16
16
 
17
17
  > **Role**: Customer (Buyer/Order Holder)
18
- > **Provider Guide**: [wowok-provider](../wowok-provider/SKILL.md) | **Arbitration Guide**: [wowok-arbitrator](../wowok-arbitrator/SKILL.md) | **Guard Design**: [wowok-guard](../wowok-guard/SKILL.md) | **Machine**: [wowok-machine](../wowok-machine/SKILL.md) | **Messenger**: [wowok-messenger](../wowok-messenger/SKILL.md) | **Safety**: [wowok-safety](../wowok-safety/SKILL.md) | **Tools**: [wowok-tools](../wowok-tools/SKILL.md)
18
+ > **Provider Guide**: [wowok-provider](../wowok-provider/SKILL.md) | **Arbitration Guide**: [wowok-arbitrator](../wowok-arbitrator/SKILL.md) | **Machine**: [wowok-machine](../wowok-machine/SKILL.md) | **Messenger**: [wowok-messenger](../wowok-messenger/SKILL.md)
19
+ > Guard design patterns, safety rules, and tool references now live in the MCP knowledge layer — query via `schema_query` actions `get_guard_design_patterns`, `get_safety_rules`, `get_tool_reference`.
19
20
 
20
21
  ---
21
22
 
@@ -41,7 +42,7 @@ Allocation evaluates when Progress reaches **any** configured node (not just exi
41
42
 
42
43
  ## Phase 1: Pre-Purchase Due Diligence (MANDATORY GATE)
43
44
 
44
- > **⛔ Complete E1-E10 in order. User must explicitly confirm every item.**
45
+ > **⛔ Complete E1-E11 in order. User must explicitly confirm every item.**
45
46
  > **⚠️ = explain risk, wait for decision. 🔴 = strongly advise against purchase.**
46
47
 
47
48
  ---
@@ -62,7 +63,7 @@ From E1 `sales[]`. Skip `suspension === true` items.
62
63
 
63
64
  **WIP Verification** (mandatory when `wip_hash` non-empty):
64
65
 
65
- Use `wip_file` → `op: "verify"`, `wipFilePath: "<wip_url>"`, `hash_equal: "<wip_hash>"`.
66
+ Use `wip_file` → `type: "verify"`, `wipFilePath: "<wip_url>"`, `hash_equal: "<wip_hash>"`.
66
67
 
67
68
  - `wip_hash` empty → no on-chain commitment (auto-verified, weaker evidence)
68
69
  - Verification fails → 🔴 **WIP tampered after publish**
@@ -112,7 +113,7 @@ Use `wip_file` → `op: "verify"`, `wipFilePath: "<wip_url>"`, `hash_equal: "<wi
112
113
 
113
114
  ### E4 — Guards Analysis
114
115
 
115
- Guard structure and instruction reference: [wowok-guard](../wowok-guard/SKILL.md).
116
+ Guard structure and instruction reference: MCP `schema_query` action='get_guard_design_patterns' (design patterns) and action='get_guard_templates' (ready-made templates).
116
117
 
117
118
  **Step 1**: Collect unique Guard IDs from E3 Machine JSON (`forward.guard.guard`), E1 `order_allocators`, E1 `buy_guard`. Deduplicate.
118
119
 
@@ -200,9 +201,23 @@ For matched: present value, ask "correct?" and "OK to send?". For missing: ask u
200
201
 
201
202
  ---
202
203
 
204
+ ### E11 — Trust Score Synthesis (Preorder Advice)
205
+
206
+ Aggregate E1–E10 into a decision-grade assessment via `trust_score`:
207
+
208
+ `wowok({ tool: "trust_score", data: { service: "<service_id>", depth: "preorder", order_amount: "<planned_amount>" } })`
209
+
210
+ - Returns trust score + per-dimension risks + preorder advice (order confidence, game strategies, preference match, industry risks, `blocking_reminders`); non-empty `blocking_reminders` → ⛔ resolve with user BEFORE Phase 2.
211
+ - Comparing multiple candidates → add `compare_with: ["<id2>", ...]` (1–9, same `depth: "preorder"`): output gains a `comparison` block with per-metric bests — **NO overall ranking**; present trade-offs, the buyer decides.
212
+ - Optional `preferences` / `user_metrics` reflect the buyer's own priorities.
213
+
214
+ > Fast pre-screen: at E1 you may call `depth: "evaluate"` (default) for a quick score; 🔴 `risk_score` (<50) → advise early abort, skip E2–E10.
215
+
216
+ ---
217
+
203
218
  ### Pre-Purchase GATE
204
219
 
205
- **Abort conditions**: E1 `bPublished=false`/`bPaused=true` → ABORT; E8 `um=null` → ABORT; E3 no-refund + E6 no-arb → strongly advise ABORT; E4 ambiguous Guards → user MUST manually review.
220
+ **Abort conditions**: E1 `bPublished=false`/`bPaused=true` → ABORT; E8 `um=null` → ABORT; E3 no-refund + E6 no-arb → strongly advise ABORT; E4 ambiguous Guards → user MUST manually review; E11 `blocking_reminders` → resolve with user BEFORE proceeding.
206
221
 
207
222
  **Any ⚠️** → explain risk, wait for user decision. **All OK** → Phase 2.
208
223
 
@@ -369,7 +384,7 @@ For precise control, pass an explicit array of `{id, type}` objects, or pass the
369
384
 
370
385
  ### Phase Dependency
371
386
 
372
- E1 (Service) → E2 (Products/WIP), E8 (Contact), E10 (Privacy), E7 (Compensation), E6 (Arbitrations) run in parallel after E1. E3 (Machine) → E4 (Guards) → E5 (Allocators) is a strict chain. E9 (Reputation) follows E3.
387
+ E1 (Service) → E2 (Products/WIP), E8 (Contact), E10 (Privacy), E7 (Compensation), E6 (Arbitrations) run in parallel after E1. E3 (Machine) → E4 (Guards) → E5 (Allocators) is a strict chain. E9 (Reputation) follows E3. E11 (Trust Score) runs LAST — it aggregates all prior findings.
373
388
 
374
389
  ### ⚠️ Critical Attention Items
375
390
 
@@ -134,11 +134,11 @@ When user asks about field meanings:
134
134
 
135
135
  # Related Skills
136
136
 
137
- | Skill | Purpose |
137
+ | Skill / MCP Knowledge | Purpose |
138
138
  |-------|---------|
139
- | [wowok-safety](../wowok-safety/SKILL.md) | Pre-operation safety checks |
140
- | [wowok-guard](../wowok-guard/SKILL.md) | Guard design & validation |
141
- | [wowok-tools](../wowok-tools/SKILL.md) | Tool selection patterns |
139
+ | MCP `schema_query` action='get_safety_rules' | Pre-operation safety checks (sunk from wowok-safety) |
140
+ | MCP `schema_query` action='get_guard_design_patterns' | Guard design & validation (sunk from wowok-guard) |
141
+ | MCP `schema_query` action='get_tool_reference' | Tool selection patterns (sunk from wowok-tools) |
142
142
  | [wowok-order](../wowok-order/SKILL.md) | Order lifecycle (buyer) |
143
143
  | [wowok-provider](../wowok-provider/SKILL.md) | Service management (merchant) |
144
144
  | [wowok-arbitrator](../wowok-arbitrator/SKILL.md) | Dispute resolution |
@@ -26,7 +26,8 @@ when_to_use:
26
26
  Converts natural-language intent into an executable Object Dependency Graph (ODG) and phased execution plan. Deterministic-first: rules and scenario templates decide the shape; the LLM only clarifies ambiguity and translates free text into typed fields.
27
27
 
28
28
  > **Layer**: L3 Skill, primary planner for L4 Harness Plan Loop
29
- > **Related Skills**: [wowok-onboard](../wowok-onboard/SKILL.md) (guided execution), [wowok-scenario](../wowok-scenario/SKILL.md) (scenario templates), [wowok-tools](../wowok-tools/SKILL.md) (MCP reference), [wowok-machine](../wowok-machine/SKILL.md) (workflow design), [wowok-guard](../wowok-guard/SKILL.md) (Guard design), [wowok-safety](../wowok-safety/SKILL.md) (immutability rules), [wowok-provider](../wowok-provider/SKILL.md) (post-plan operations)
29
+ > **Related Skills**: [wowok-onboard](../wowok-onboard/SKILL.md) (guided execution), [wowok-machine](../wowok-machine/SKILL.md) (workflow design), [wowok-provider](../wowok-provider/SKILL.md) (post-plan operations)
30
+ > Industry modes, Guard design patterns, safety rules, and tool references now live in the MCP knowledge layer — query via `project_operation` (`recommend_industry` / `list_modes`) and `schema_query` (`get_guard_design_patterns` / `get_safety_rules` / `get_tool_reference`).
30
31
 
31
32
  ---
32
33
 
@@ -112,10 +112,9 @@ All Tool: references below are sub-tools invoked via wowok({ tool: "<name>", dat
112
112
  STEP 1: Foundation
113
113
  ├── Permission — REUSE existing (strongly recommended)
114
114
  │ Tool: "onchain_operations" (permission) | Fields: name, type_parameter
115
- ├── Service (unpublished) — CREATE new
116
- │ Tool: "onchain_operations" (service) | Fields: name, type_parameter, permission
117
115
  └── Machine (unpublished) — CREATE new or REUSE template
118
116
  Tool: "onchain_operations" (machine) | Fields: nodes, pairs, forwards
117
+ ⚠️ Machine nodes define the workflow; forward guards can be set inline here
119
118
  Discovery: "query_toolkit" (account_list, local_mark_list, onchain_objects)
120
119
  Template: "machineNode2file" (export existing for editing)
121
120
 
@@ -130,40 +129,41 @@ STEP 2: Trust Layer
130
129
  - Reward guard → pass/fail only
131
130
  Guard design patterns: MCP `knowledge/guard-design-patterns.ts` (auto-applied via `evaluate_project`)
132
131
 
133
- STEP 3: Business Logic (MODIFY)
134
- ├── Machine — bind Guards to forwards
135
- │ Tool: "onchain_operations" (machine)
136
- ├── Serviceset Allocators
137
- │ Tool: "onchain_operations" (service) | Fields: order_allocators
138
- ├── Arbitrations (optional) REUSE existing Arb services
139
- Tool: "onchain_operations" (service) | Fields: arbitrations.list
140
- ├── Compensation Fund (optional): compensation_fund_add + setting_lock_duration_add (default 30 days, configurable)
141
- Tool: "onchain_operations" (service)
142
- └── Reward (optional) incentive pools
132
+ STEP 3: Business Logic (MODIFY Machine)
133
+ ├── Machine — bind Guards to forwards (update existing forwards with guard fields)
134
+ │ Tool: "onchain_operations" (machine) | Fields: node (op: "add forward" / "set" with updated forwards including guard)
135
+ │ ⚠️ Machine is still unpublished here guards can be freely bound/unbound
136
+ ├── Machine — publish (locks nodes/pairs/forwards permanently)
137
+ │ Tool: "onchain_operations" (machine) | publish: true
138
+ ⚠️ After publish, nodes/forwards are IMMUTABLE — verify via machineNode2file first
139
+ └── Service (unpublished) CREATE with machine + order_allocators + buy_guard + sales
140
+ Tool: "onchain_operations" (service) | Fields: object (with permission), machine, order_allocators, buy_guard, sales
141
+ ⚠️ machine must reference a PUBLISHED Machine (else Service publish will fail)
142
+ ⚠️ order_allocators is L1-locked — MUST be set before Service publish
143
143
 
144
144
  STEP 4: Publication
145
- ├── Publish Machine IMMUTABLE
146
- Tool: "onchain_operations" (machine) | publish: true
147
- ├── Bind Machine to Service
148
- Tool: "onchain_operations" (service) | machine: "<machine_id>"
149
- └── Publish Service machine/allocators LOCKED
150
- Tool: "onchain_operations" (service) | publish: true
151
-
152
- ⚠️ Pre-Publish Verification:
153
- 1. Re-check PRE-FLIGHT: all R1-R7 still confirmed?
154
- 2. guard2file export Guards → review
155
- 3. machineNode2file export Machine review
156
- 4. Allocator splits match user's stated model?
157
- 5. Permission indexes: every permissionIndex in Machine forwards has entities granted? (call permission "add perm by index" for missing ones)
158
- 6. Arbitration Permission isolation: Arbitration uses a SEPARATE Permission object (not the Service's Permission)? Different owner/admin? (critical for mainnet trust)
159
- 7. Warn: publish = immutable. Proceed?
145
+ ├── Pre-Publish Verification (export and review):
146
+ 1. machineNode2file verify Machine nodes/forwards (published, immutable)
147
+ │ 2. guard2file verify Guard logic
148
+ 3. project_operation evaluate_project (risk) fix CRITICAL findings
149
+ │ 4. Permission indexes: every permissionIndex in Machine forwards has entities granted?
150
+ │ 5. Arbitration Permission isolation (if compensation_fund > 0)
151
+ ├── Service — publish (locks machine/order_allocators)
152
+ │ Tool: "onchain_operations" (service) | object: "<service_name>", publish: true
153
+ │ ⚠️ L1-LOCKED: machine and order_allocators are permanently frozen
154
+ └── Post-publish (mutable fields):
155
+ description, location, sales, discount, buy_guard, customer_required, um (Contact), rewards (add), arbitrations (add), repositories (add)
160
156
 
161
157
  STEP 5: Post-Publish (MODIFY Service — mutable after publish)
162
158
  ├── description, location
163
159
  ├── sales (products with WIP) — ⛔ user MUST provide: name, price, stock, WIP
164
160
  ├── customer_required
165
- └── um — Contact (REUSE existing or CREATE new)
166
- ⚠️ If customer_required is set → um MUST be set
161
+ ├── um — Contact (REUSE existing or CREATE new)
162
+ ⚠️ If customer_required is set → um MUST be set
163
+ └── Test Order — verify full flow works
164
+ Tool: "onchain_operations" (service) | order_new: { buy: { items, total_pay } }
165
+ ⚠️ Requires Service bPublished=true (else E_NOT_PUBLISHED)
166
+ After order: progress advance → allocation.alloc_by_guard → verify fund distribution
167
167
  ```
168
168
 
169
169
  ### Object Reuse & Immutability
@@ -181,17 +181,17 @@ STEP 5: Post-Publish (MODIFY Service — mutable after publish)
181
181
 
182
182
  Deploy a Service in two phases to handle Guard↔Service circular dependencies via LocalMark names. Both phases call `onchain_operations` (operation_type: "service"); they differ by `publish` flag and binding completeness.
183
183
 
184
- **Phase 1 — CREATE (no publish)**: Build the full object graph with LocalMark name references so addresses can resolve later.
184
+ **Phase 1 — CREATE (no publish)**: Build the full object graph with LocalMark name references so addresses can resolve later. Machine must be PUBLISHED before this phase.
185
185
 
186
186
  ```
187
187
  onchain_operations.service {
188
- name: "<service_local_mark>",
189
- type_parameter, permission,
190
- machine: "<machine_local_mark>", # reference by name
188
+ object: {name: "<service_name>", type_parameter, permission},
189
+ machine: "<published_machine_name_or_address>", # must be published
191
190
  order_allocators: [{ guard: "<guard_local_mark>", sharing: [...] }, ...],
192
191
  arbitrations: { list: ["<arb_local_mark>", ...] },
193
- buy_guard: "<buy_guard_local_mark>", # reference by name — defers resolution
194
- publish: false # CRITICAL: do not publish yet
192
+ buy_guard: "<buy_guard_local_mark>", # LocalMark name — defers resolution
193
+ sales: [{ name, price, stock, wip: "<URL>" }],
194
+ publish: false # CRITICAL: do not publish yet
195
195
  }
196
196
  ```
197
197
 
@@ -199,7 +199,7 @@ onchain_operations.service {
199
199
 
200
200
  ```
201
201
  onchain_operations.service {
202
- object: "<service_local_mark>", # target the existing draft by name
202
+ object: "<service_name>", # target the existing draft by name
203
203
  publish: true
204
204
  }
205
205
  ```
@@ -244,7 +244,7 @@ Order (per purchase, runtime-created)
244
244
  └── allocation → Allocation (optional, created at runtime; triggered via Progress.forward)
245
245
 
246
246
  Cross-object references:
247
- - Guard is referenced by 9 object types via diverse nested paths (see wowok-guard SKILL for full schema):
247
+ - Guard is referenced by 9 object types via diverse nested paths (full schema via MCP `schema_query` action='get_guard_design_patterns'):
248
248
  - Service.buy_guard (top-level Option<address>)
249
249
  - Machine.forward.guard (per-node dynamic table; SDK does not expose — requires query_table)
250
250
  - Allocation.allocators[].guard (array element — graph-builder edge fieldName: allocator_guard)
@@ -314,7 +314,7 @@ Required submission: Order ID (matching the Guard's b_submission identifier)
314
314
  Immutable product commitment for arbitration evidence.
315
315
 
316
316
  ```
317
- Create: wowok({ tool: "wip_file", data: { op: "generate", ... } }) → markdown_text + images → outputPath
317
+ Create: wowok({ tool: "wip_file", data: { type: "generate", ... } }) → markdown_text + images → outputPath
318
318
  Attach: wowok({ tool: "onchain_operations", data: { operation_type: "service", ... } }) → sales.sales[{
319
319
  name, price, stock, wip: "<URL>", wip_hash: "" (auto)
320
320
  }]
@@ -325,6 +325,16 @@ Attach: wowok({ tool: "onchain_operations", data: { operation_type: "service", .
325
325
  - Add: `compensation_fund_add` | Lock: `setting_lock_duration_add` (default 30 days = 2592000000ms, configurable via `setting_lock_duration_add`)
326
326
  - **Withdraw**: Pause Service → Wait lock duration → `compensation_fund_receive`
327
327
 
328
+ ### Payment Tokens & Stablecoin Bridging (Mainnet Only)
329
+
330
+ WOW is the default settlement token. For stablecoin-denominated revenue (fiat-pegged pricing, large cross-period escrow), mainnet funds move via `bridge_operation`:
331
+
332
+ - `query_supported_tokens` / `query_supported_evm_chains` — discover supported Bridge tokens (ETH/WETH/WBTC/USDC/USDT) and chains
333
+ - `cross_chain_wow_to_evm` / `cross_chain_evm_to_wow` — WOW↔EVM transfer (mainnet env required; assets route through the auto-managed activeEvmAccount)
334
+ - `query_transfer_status` / `query_transfer_list` — track transfers; `manage_evm_rpc` — handle EVM RPC rate limits (429)
335
+
336
+ > Supported token addresses per network: `wowok_buildin_info` → 'mainnet bridge tokens'. Bridge is mainnet-only — testnet has no cross-chain path.
337
+
328
338
  ---
329
339
 
330
340
  ## Project Iteration: Fork vs In-Place
@@ -1,359 +0,0 @@
1
- ---
2
- name: wowok-guard
3
- description: |
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 `onchain_operations` (`operation_type: "gen_passport"`) to
10
- obtain a signed, time-bound credential for off-chain permission verification.
11
- when_to_use:
12
- - User wants to create or modify a Guard
13
- - User asks about Guard logic, validation rules, trust rules, programmable conditions
14
- - User encounters Guard validation errors or needs to debug a Guard
15
- - User mentions "guard", "validation", "trust rules", "verify", "condition"
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
20
- ---
21
-
22
- # WoWok Guard Design Reference
23
-
24
- > **Role**: Service Provider, Arbitrator, or any builder needing programmable on-chain validation
25
- > **Prerequisites**: Guards are CREATE-only; frozen on-chain once deployed
26
- > **Related Skills**: [wowok-machine](../wowok-machine/SKILL.md) (forward guards), [wowok-provider](../wowok-provider/SKILL.md) (buy_guard, allocator guards), [wowok-order](../wowok-order/SKILL.md) (guard submissions), [wowok-arbitrator](../wowok-arbitrator/SKILL.md) (voting_guard, usage_guard), [wowok-messenger](../wowok-messenger/SKILL.md) (encrypted evidence), [wowok-safety](../wowok-safety/SKILL.md) (naming, confirmation), [wowok-tools](../wowok-tools/SKILL.md) (tool reference)
27
-
28
- ---
29
-
30
- ## Core Concepts
31
-
32
- ### What a Guard IS
33
-
34
- 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.
35
-
36
- 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?"
37
-
38
- ### The Immutability Contract
39
-
40
- 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.
41
-
42
- ### The Three Structural Layers
43
-
44
- Every Guard is built from three layers, each with a distinct role:
45
-
46
- | Layer | Component | Role | Immutable? |
47
- |-------|-----------|------|------------|
48
- | **Declaration** | `table` | Declares every piece of data the Guard touches — constants and runtime submissions — each with a unique identifier (0–255) | Yes |
49
- | **Computation** | `root` | A computational tree of GuardNode types that computes the final boolean result by combining data sources, comparisons, arithmetic, and logic | Yes |
50
- | **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 |
51
-
52
- **The table is the contract with callers**: It declares what data they must provide at runtime (`b_submission: true`) versus what the Guard already knows (`b_submission: false`). Every `identifier` node references exactly one table entry. **The root is the question**: It must return Bool; intermediate nodes return numbers/strings/addresses/vectors. Guard is **strongly typed** — type mismatches cause creation failure. **The rely is composition**: Up to 4 dependent Guards (AND by default, OR if `logic_or: true`). A Guard can only depend on Guards with `rep: true` (deterministic `repository.data` queries independent of runtime submissions). `rep: false` Guards cannot appear in `rely` lists — violations caught at creation time.
53
-
54
- ### Data Source 4 Classification — The Foundation of Guard Semantics
55
-
56
- 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.
57
-
58
- | Type | Name | SDK Manifestation | Native Opcode | Trust Level | Typical Scenario |
59
- |------|------|-------------------|---------------|-------------|------------------|
60
- | **Type 1** | OnChainConstant | `query` + `identifier` (`b_submission: false`, no witness) | TYPE_QUERY + TYPE_CONSTANT | Highest | Query fields of already-published Service/Machine/Reward objects |
61
- | **Type 2** | WitnessDerived | `query` + `identifier` + `convert_witness` (100-108) | TYPE_QUERY + witness_byte | High (source trusted + deterministic derivation) | Order → Progress query via witness=100 |
62
- | **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 |
63
- | **Type 4** | SystemContext | `context` (Signer/Clock/Guard) | TYPE_SIGNER / TYPE_CLOCK / TYPE_GUARD | Highest | Identity verification, time-locks |
64
-
65
- **Key insights**: Type 1 and Type 3 are isomorphic at the native layer (both TYPE_QUERY+TYPE_CONSTANT; difference is `b_submission` flag). Type 2 overlays on Type 1 or Type 3 (source object can be constant or submission, then witness derives target). Type 4 is fully independent (no table dependency). Except for Type 4, all data must be declared in the table — the table is the complete data contract: deterministic data (`b_submission: false`, type+value baked at creation) + submitted data (`b_submission: true`, type only, value from caller at runtime — **must have constraint rules designed, otherwise empty data is meaningless**).
66
-
67
- **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. 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").
68
-
69
- ### Verifier Constraint Levels — Designing Who Can Pass
70
-
71
- Three levels trade off **security** vs **convenience** when using `context(Signer)`:
72
-
73
- **Level 1 — Single-Identity** (`logic_equal[context(Signer), identifier[N](fixed_address)]`): Only ONE address passes. ⚠️ Avoid — if address unavailable (key loss, rotation), Guard permanently blocks. Risk rule `R-C4-04` flags this.
74
-
75
- **Level 2 — Identity-Set** (recommended): `logic_or` of multiple identity checks. Key distinction:
76
- - **Address-returning queries** (`order.owner`, `permission.owner`, `service.permission`): wrap in `logic_equal[query, context(Signer)]`
77
- - **Bool-returning queries** (suffix "has": `order.agent has`, `permission.admin has`): use directly as `logic_or` child, pass `context(Signer)` as parameter
78
- - **Dynamic permission** (RECOMMENDED): caller submits permission address; Guard verifies `service.permission == submitted_perm` then checks `permission.owner`/`permission.admin has`. Survives permission rotation.
79
-
80
- **Level 3 — Scene-Combined** (verify if Signer binding is even needed):
81
-
82
- | Scene | Signer needed? | Why |
83
- |-------|---------------|-----|
84
- | Allocators + `sharing.who=Entity` | NO | Funds to fixed recipient (R-C3-06 safe) |
85
- | Allocators + `sharing.who=Signer` | YES (Level 2) | Funds to caller — must bind |
86
- | Machine `forward` guard | MAYBE | `permissionIndex`/`namedOperator` may suffice |
87
- | `buy_guard` | Usually NO | Customer is caller; whitelist/credentials suffice |
88
- | `voting_guard` | NO | Weight from EntityRegistrar, not Signer (R-C3-02) |
89
-
90
- **Decision**: If host object already verifies operator OR `sharing.who` routes to fixed recipient → no Signer binding needed. Only add Level 2 when resources flow to caller AND no other layer verifies identity.
91
-
92
- #### One Guard One Purpose Principle
93
-
94
- Each Guard should serve **ONE specific purpose**, documented in its `description`:
95
- - **Scenario**: where the Guard is attached (which host object, which binding field)
96
- - **Verification rules**: concise statement of what conditions are checked
97
- - **Risk notes**: which risks are mitigated (R-C3-01/05/06, etc.) and which trade-offs apply
98
- - **Verifier constraint level**: which Level (1/2/3) is used and why
99
-
100
- General-purpose Guards designed for `rely` composition are the exception — they need explicit general rules and composition documentation. All other Guards should be single-purpose.
101
-
102
- ### Where Guards Attach in the Ecosystem
103
-
104
- 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.
105
-
106
- | Host Object | Guard Field | What It Controls | Operator | Who Provides Submission Data |
107
- |-------------|-------------|-----------------|----------|------------------------------|
108
- | **Service** | `buy_guard` | Who can purchase from this service | Customer | Customer (signer, credentials) |
109
- | **Service** | `order_allocators[].guard` | Which fund distribution strategy executes | System (auto-evaluated) | System derives from Progress state |
110
- | **Machine** | Forward `guard` | Who can advance to the next workflow node | Customer or Provider | The party executing the forward |
111
- | **Progress** | Submission guard | Whether submitted data satisfies conditions during forward execution | Customer or Provider | The party submitting data |
112
- | **Reward** | `guard` | Who can claim from the reward pool | Claimant | Claimant (address, credentials) |
113
- | **Repository** | Write/quote guard | Who can write to or read from on-chain storage | Writer/Reader | Writer/Reader |
114
- | **Arbitration** | `usage_guard` | Who can file a dispute against this arbitration | Customer | Customer (Passport credential) |
115
- | **Arbitration** | `voting_guard[]` | Who can vote on arbitration proposals and with what weight | Voters (authenticated via Arbitrator) | Voter (Passport credential with weight data) |
116
- | **Gen Passport** | Guard verification | Generating verified credentials after successful validation | Passport holder | Passport applicant |
117
-
118
- ---
119
-
120
- ## Phase 1: Design — Analyze the Validation Intent
121
-
122
- Before constructing any node, articulate **what** you are validating and **why**. Start from the business requirement, not the data structure.
123
-
124
- ### The Central Questions
125
-
126
- Every Guard answers these questions:
127
-
128
- 1. **What action is being protected?** — Buying a service? Advancing a workflow node? Claiming a reward? Casting a weighted vote? Filing a dispute?
129
-
130
- 2. **What data does the Guard have access to?** — Guards see only:
131
- - Their own `table` (pre-set constants plus runtime submissions from the caller)
132
- - On-chain state queried through `query` nodes targeting live WoWok objects
133
- - Transaction context (the current Clock timestamp, the signer's address, the Guard's own object ID)
134
-
135
- 3. **What should the verdict be?** — A single boolean: pass or fail. The root of every Guard tree must return Bool.
136
-
137
- ### Map Business Requirements to Guard Patterns
138
-
139
- | Business Requirement | Guard Pattern | Key Mechanism | Implementation Notes |
140
- |----------------------|---------------|---------------|---------------------|
141
- | "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 |
142
- | "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 |
143
- | "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` |
144
- | "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` |
145
- | "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` |
146
- | "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 |
147
- | "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 |
148
- | "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` |
149
-
150
- ### Quick Decision: What Guard Pattern Fits?
151
-
152
- ```
153
- Identity check? → context(Signer) + logic_equal (single address) / vec_contains_address (allowlist)
154
- Time constraint? → context(Clock) + calc_number_* comparisons
155
- External data? → query + table entry declaring target object address
156
- Progress state? → query_progress_history_find + convert_witness
157
- One-time claim? → query_reward_record_count + logic_equal(0)
158
- Dynamic weight? → GuardIdentifier + numeric table entry (b_submission: true)
159
- External Repository? → query + table entry declaring Repository address
160
- Entity reputation? → query + table entry declaring ENTITY_REGISTRAR_ADDRESS(0xaab) / ENTITY_LINKER_ADDRESS(0xaaa)
161
- ```
162
-
163
- ### Circular Dependency Handling (Service ↔ Guard)
164
-
165
- When a Guard needs to query a Service that doesn't exist yet (classic chicken-and-egg: `buy_guard` validates Service fields, but Service creation needs `buy_guard` address), use **LocalMark NAME** (not address) in the Guard's query table. LocalMark is resolved by the SDK at publish time, deferring the address binding until after both objects exist.
166
-
167
- **Workflow** (4-step safe pattern):
168
- 1. **Create Service (no publish)** — Service exists as draft with a LocalMark name
169
- 2. **Create Guard** — In the Guard table, reference the Service via `name_or_address: "<service_local_mark_name>"` (NOT a hardcoded address)
170
- 3. **Update Service** — Set `service.buy_guard = <guard_address>` (now resolvable since Guard is created)
171
- 4. **Publish Service** — SDK resolves LocalMark → on-chain address; both objects now bound
172
-
173
- > **Why LocalMark**: A Guard that hardcodes a Service address fails creation if the Service doesn't exist yet. LocalMark defers resolution, allowing the Guard to be created first (or in either order). This pattern also applies to Allocator guards that query Service fields.
174
-
175
- ### Triple Verification Template (withdraw / refund Guards)
176
-
177
- Withdraw and refund guards protect fund flow — the highest-risk operations. They should verify **three independent conditions** (AND-ed):
178
-
179
- | # | Verification | What to Check | Typical Query |
180
- |---|---------------|---------------|---------------|
181
- | (a) | Order status | Order is in expected state (not cancelled / disputed) | `order.service` + `order.balance` |
182
- | (b) | Progress node completion | Progress.current == expected node (e.g. "completion" / "refund") | `progress.current` (via witness 100 from Order) |
183
- | (c) | Permission / role | Caller is authorized (merchant / arbiter / customer) | `permission.owner` / `permission.admin has` (Level 2 identity-set) |
184
-
185
- > **Why all three**: (a) alone is insufficient — Order may be in correct state but Progress not advanced. (b) alone is insufficient — Progress may be at correct node but Order cancelled. (c) alone is insufficient — caller may be authorized but state wrong. AND-combine all three at the Guard root.
186
-
187
- ### Design Before Building
188
-
189
- **Design thoroughly before calling the create operation** — there is no edit phase after creation (see The Immutability Contract above).
190
-
191
- 1. **Query available query instructions first**: Before designing any Guard that queries on-chain data, use `wowok_buildin_info` with info `"guard instructions"` 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.
192
- 2. List every data dependency — what must the caller provide? What constants are baked in?
193
- 3. Sketch the logic tree — what comparisons, arithmetic, and logical combinations produce the final boolean?
194
- 4. Verify types — does every comparison receive compatible operands? Are all conversions explicit?
195
- 5. Test the tree mentally — what happens with edge case inputs? What happens if a query returns empty?
196
-
197
- ---
198
-
199
- ## Phase 2: Declare the Data Table
200
-
201
- 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.
202
-
203
- ### Table Entry Fields
204
-
205
- | Field | Meaning | Required When |
206
- |-------|---------|---------------|
207
- | `identifier` | Unique index (0–255). The computation tree uses this number to reference the entry. | Always |
208
- | `b_submission` | Whether the **caller** must provide this value at runtime. `true` = runtime submission; `false` = pre-set constant. | Always |
209
- | `value_type` | The type of the value: Bool, Address, String, U8–U256, or vector types. Accepts both string names (preferred, e.g., `"Address"`, `"U64"`) and numeric codes (e.g., `1`, `6`). Use `wowok_buildin_info` with info `"value types"` for the complete mapping. SDK deserialization returns string names. | Always |
210
- | `value` | The constant value when `b_submission` is false; a placeholder when `b_submission` is true. | When `b_submission` is false |
211
- | `name` | Human-readable label describing what this entry represents. | Always |
212
-
213
- ### Design Rules
214
-
215
- - **Every identifier in the tree must exist in the table.** Missing references cause creation to fail.
216
- - **No duplicate identifiers.** Each index number must appear exactly once.
217
- - **Non-submission entries must have a value.** These are baked into the Guard immutably.
218
- - **Submission entries use placeholder values.** The actual value is provided by the caller at runtime.
219
- - **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.).
220
- - **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.
221
- - **Maximum 256 table entries** (identifiers 0–255). The total serialized table size must not exceed 40000 bytes.
222
- - **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.
223
-
224
- ### The convert_witness Mechanism
225
-
226
- `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.
227
-
228
- **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.
229
-
230
- **Rules**:
231
- - Witness type encodes source→target transformation
232
- - Table entry's `object_type` (auto-filled by SDK) must match witness source type
233
- - Query instruction's object type must match witness target type
234
- - Type mismatches cause Guard creation to fail
235
- - Multi-hop witnesses (106-108) require intermediate objects to exist
236
-
237
- **Complete 9 witness types** (defined in `guard.rs#L34-L65`):
238
-
239
- | Code | Name | Source → Target | Derivation | Hops |
240
- |------|------|-----------------|------------|------|
241
- | 100 | TypeOrderProgress | Order → Progress | read order.progress field | 1 |
242
- | 101 | TypeOrderMachine | Order → Machine | read order.machine field | 1 |
243
- | 102 | TypeOrderService | Order → Service | read order.service field | 1 |
244
- | 103 | TypeProgressMachine | Progress → Machine | read progress.machine field | 1 |
245
- | 104 | TypeArbOrder | Arb → Order | read arb.order field | 1 |
246
- | 105 | TypeArbArbitration | Arb → Arbitration | read arb.arbitration field | 1 |
247
- | 106 | TypeArbProgress | Arb → Progress | arb.order → order.progress | 2 (multi-hop) |
248
- | 107 | TypeArbMachine | Arb → Machine | arb.order → order.machine | 2 (multi-hop) |
249
- | 108 | TypeArbService | Arb → Service | arb.order → order.service | 2 (multi-hop) |
250
-
251
- **Key notes**:
252
- - **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.
253
- - **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.
254
- - **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.
255
- - **Available witness types** are also discoverable via `wowok_buildin_info` with info `"guard instructions"`.
256
-
257
- ---
258
-
259
- ## Phase 3: Build the Computational Tree
260
-
261
- 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.
262
-
263
- ### Tree Principles
264
-
265
- - **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.
266
- - **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.
267
- - **Every `identifier` node's index must exist in the table.** This is validated at creation time.
268
-
269
- ### Discovering Available Node Types
270
-
271
- Query the authoritative `GuardNodeSchema` via `schema_query` (name: `onchain_operations_guard`) — it returns every node type, required fields, input/output types, and validation rules. Categories include: data source nodes (`identifier`, `context`, `query`), logic/arithmetic nodes (`logic_*`, `calc_number_*`), string/conversion/vector nodes (`calc_string_*`, `convert_*`, `vec_*`), and record query nodes (`query_reward_record_*`, `query_progress_history_*`).
272
-
273
- **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. For the `query` node, discover available instructions via `wowok_buildin_info` ("guard instructions") with `filter` to narrow by name/return type/parameter count/object type.
274
-
275
- ---
276
-
277
- ## Phase 4: Create the Guard
278
-
279
- 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.
280
-
281
- Use `onchain_operations` (`operation_type: "guard"`) with `root.type: "node"` (inline tree) or `root.type: "file"` (load from `guard2file`-exported JSON/MD — use this to iterate on existing Guards: export → edit → create new).
282
-
283
- ---
284
-
285
- ## Phase 5: Test, Export, and Query
286
-
287
- **Test**: `gen_passport` verifies one or more Guards (AND-ed) and generates an immutable Passport on success. Omit `info` to auto-fetch submissions, or provide explicitly for custom test inputs.
288
-
289
- **Query**: `query_toolkit` → `onchain_objects` for any Guard. Results include `_guard_node_comments` (human-readable annotations per node). Guards are public consensus — all parties can inspect validation rules.
290
-
291
- **Iteration**: `guard2file` → edit JSON/MD → create new Guard via `root.type:"file"` → update all references.
292
-
293
- ---
294
-
295
- ## Guard Data Flow: How Objects Read Guard Data
296
-
297
- Guards are validators AND data sources. When bound, objects read structured data for decisions. 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.
298
-
299
- ### Type Requirements by Object
300
-
301
- Each object extracts Guard data with precise type expectations. Mismatches cause creation or runtime failure:
302
-
303
- | Object | Extraction Field | Table Index Requirement | Type Constraint |
304
- |--------|-----------------|------------------------|-----------------|
305
- | **Arbitration** `voting_guard` | Vote weight via `GuardIdentifier(u8)` | Index must be `b_submission: true` | **Numeric** (U8–U256, cast to u32) |
306
- | **Demand** `ServiceGuard` | `service_identifier` mapping | Index must be `b_submission: true` | Depends on Service validation |
307
- | **Machine** Forward | `retained_submission` | Index must be `b_submission: true`; uniquely located by `node→next_node→forward` triple | As declared in table |
308
- | **Repository** | `id_from_submission` | Index must be `b_submission: true` | **Must be Address** |
309
- | **Repository** | `data_from_submission` | Index must be `b_submission: true` | **Must match Repository's value_type** |
310
-
311
- **Notes**: Arbitration uses `usage_guard` for eligibility (pass/fail) and `voting_guard` for weight (fixed or dynamic via `GuardIdentifier`). Demand's `ServiceGuard` passes the submission value at `service_identifier` to the service for validation (if unset, only pass/fail checked). Machine's `retained_submission` stores submission values in Progress for audit. Repository's `id_from_submission`/`data_from_submission` extract structured data from Guard submissions.
312
-
313
- **⚠️ Critical — 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.
314
-
315
- ---
316
-
317
- ## Best Practices
318
-
319
- ### Common Pitfalls
320
-
321
- > 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`.
322
-
323
- #### Creation-Phase Constraints (22 rules, all enforced by SDK + `validate_guard_data`)
324
-
325
- **Root**: Must return Bool (logic/comparison nodes only).
326
- **Table**: Unique identifiers (0–255), tree-to-table referential integrity, non-empty constants, max 256 entries / 40KB BCS, submission entries = 1-byte type code.
327
- **Query**: Discover valid IDs via `wowok_buildin_info` ("guard instructions"); parameter count/types must match; return type must be compatible with parent (use `convert_string_number`/`convert_number_string` for type mismatches; `logic_as_u256_*` for numeric comparisons); `object.identifier` must be Address type.
328
- **Witness**: 100–108 only; target type must match query's expected object; source type must match table's `object_type`. **Missing `convert_witness`** when accessing Progress from Order ID = runtime failure (looks for Progress at Order's address).
329
- **Rely**: Max 4; must have `rep:true`; no self-reference.
330
- **Binding**: `voting_guard` identifier must be numeric (U8–U256); Repository `id_from_submission` must be Address; `data_from_submission` type must match Repository's `value_type`.
331
- **Immutable**: Guard frozen after `guard::create` — to change, export via `guard2file` and create new.
332
-
333
- #### Practical Tips (not strict constraints, but strongly recommended)
334
-
335
- - **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.
336
- - **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.
337
- - **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.
338
-
339
- #### Runtime-Phase Constraints (enforced by native `verify_guard`)
340
-
341
- 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:
342
-
343
- - **RUN_IMMUTABLE_01**: Guard must have `immutable=true` to be verified. A Guard that hasn't been finalized via `guard::create` cannot be used.
344
- - **RUN_SUB_01**: The submission's `value[0]` (type byte) must match the table declaration. A submission with the wrong type byte is rejected.
345
- - **RUN_SUB_02**: Every table entry with `b_submission=true` must have a corresponding submission value. Missing submissions cause failure.
346
- - **RUN_SUB_03**: Total submission bytes must be ≤ `MAX_SUBMISSION_SIZE` (256).
347
- - **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.
348
- - **RUN_QUERY_01**: The query target object must exist and its type must match.
349
- - **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`.
350
- - **RUN_TX_01**: The Passport's `tx_hash` must match the current transaction.
351
- - **RUN_RELY_01**: Rely guards must have been added to the passport.
352
-
353
- ### Readability Convention — Prefer String Names
354
-
355
- **Always use string names** (not numeric IDs) for `query` (`"order.service"` not `1563`), `value_type` (`"Address"` not `1`), `convert_witness` (`"OrderProgress"` not `100`), and `context` (`"Signer"`). Matching is case-insensitive. SDK deserialization (`guard2file`/`query_objects`) returns all constants as strings. Discover valid query names via `wowok_buildin_info` with info `"guard instructions"`.
356
-
357
- Common allocator-guard queries: `order.service` (theft protection), `order.owner` (refund binding), `progress.current` (node check), `progress.current_time` (time-lock), `service.permission`, `permission.owner`, `permission.admin has` (identity-set).
358
-
359
- ---