@wowok/skills 1.2.1 → 1.2.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 +2 -1
- package/references/glossary.ts +297 -0
- package/references/guard-scenario-ledger.md +353 -0
- package/references/guard-template-library.md +481 -0
- package/references/machine-design-reference.md +398 -0
- package/references/machine-scenario-ledger.md +227 -0
- package/references/machine-template-library.md +522 -0
- package/references/merchant-scenario-coordination.md +383 -0
- package/references/object-collaboration.md +362 -0
- package/references/onchain-constants.md +81 -0
- package/scripts/install.js +15 -0
- package/wowok-auditor/APPENDIX.md +2 -2
- package/wowok-auditor/SKILL.md +1 -1
- package/wowok-onboard/APPENDIX.md +32 -4
- package/wowok-planner/APPENDIX.md +25 -1
- package/wowok-provider/APPENDIX.md +28 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wowok/skills",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.3",
|
|
4
4
|
"description": "WoWok AI Skills for Claude and other AI assistants - Helping AI use WoWok MCP tools correctly",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
11
|
"dist/",
|
|
12
|
+
"references/",
|
|
12
13
|
"wowok-provider/",
|
|
13
14
|
"wowok-arbitrator/",
|
|
14
15
|
"wowok-guard/",
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
// Copyright (c) Wowok.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
// Phase 2 L3' Knowledge Layer — Concept Glossary (Topic 6)
|
|
5
|
+
// Single source of truth for authoritative terms. Schema fields and Skills must
|
|
6
|
+
// align with this table; aliases are deprecated and detected by validateText().
|
|
7
|
+
|
|
8
|
+
import { USER_DEFINED_PERM_INDEX_START } from "./onchain-constants.js";
|
|
9
|
+
|
|
10
|
+
export type GlossaryCategory =
|
|
11
|
+
| "role"
|
|
12
|
+
| "object"
|
|
13
|
+
| "operation"
|
|
14
|
+
| "acceptance"
|
|
15
|
+
| "permission"
|
|
16
|
+
| "fund";
|
|
17
|
+
|
|
18
|
+
export interface GlossaryEntry {
|
|
19
|
+
/** Authoritative term (canonical, used in schema & docs). */
|
|
20
|
+
term: string;
|
|
21
|
+
/** Short definition. */
|
|
22
|
+
definition: string;
|
|
23
|
+
/** Deprecated aliases that should resolve to `term`. */
|
|
24
|
+
aliases: string[];
|
|
25
|
+
category: GlossaryCategory;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Canonical glossary. Order is stable for deterministic scans.
|
|
30
|
+
* When adding entries, keep `aliases` lowercase to match validateText().
|
|
31
|
+
*/
|
|
32
|
+
export const CONCEPT_GLOSSARY: GlossaryEntry[] = [
|
|
33
|
+
// ── Permission triple (the three core permission definitions) ───────────
|
|
34
|
+
{
|
|
35
|
+
term: "Permission",
|
|
36
|
+
definition:
|
|
37
|
+
`Organization-wide permission object. indices 0-${USER_DEFINED_PERM_INDEX_START - 1} builtin, ` +
|
|
38
|
+
`${USER_DEFINED_PERM_INDEX_START}-65535 custom. ` +
|
|
39
|
+
"Shared across all Progress instances of a Service. Use for internal staff roles.",
|
|
40
|
+
aliases: ["permission object"],
|
|
41
|
+
category: "permission",
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
term: "NamedOperator",
|
|
45
|
+
definition:
|
|
46
|
+
"Per-order role assignment inside a Progress. Each Progress node can map a role " +
|
|
47
|
+
"string to an address. Use for external collaborators whose identity varies per order.",
|
|
48
|
+
aliases: ["named operator", "namedoperator"],
|
|
49
|
+
category: "permission",
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
term: "OrderHolder",
|
|
53
|
+
definition:
|
|
54
|
+
"The order holder and their agents. Represented by namedOperator=\"\" (empty string) " +
|
|
55
|
+
"on a Forward. Lets the customer operate their own order.",
|
|
56
|
+
aliases: ["order owner", "orderholder", "order holder"],
|
|
57
|
+
category: "permission",
|
|
58
|
+
},
|
|
59
|
+
// ── Process definition ───────────────────────────────────────────────────
|
|
60
|
+
{
|
|
61
|
+
term: "Forward",
|
|
62
|
+
definition:
|
|
63
|
+
"A state-transition edge in a Machine. Carries weight, a permission " +
|
|
64
|
+
"(Permission index / NamedOperator / OrderHolder), and an optional Guard. " +
|
|
65
|
+
"Every Forward MUST define at least one permission.",
|
|
66
|
+
aliases: ["transition"],
|
|
67
|
+
category: "operation",
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
term: "Pair",
|
|
71
|
+
definition:
|
|
72
|
+
"A prev_node → next_node transition group in a Machine with a threshold. " +
|
|
73
|
+
"When the cumulative weight of executed Forwards meets the threshold, the Pair fires.",
|
|
74
|
+
aliases: ["transition pair"],
|
|
75
|
+
category: "operation",
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
term: "Machine",
|
|
79
|
+
definition:
|
|
80
|
+
"Workflow blueprint (directed graph). Becomes immutable after publish. " +
|
|
81
|
+
"A Progress instance is created per order from the Machine.",
|
|
82
|
+
aliases: ["machine template"],
|
|
83
|
+
category: "object",
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
term: "Progress",
|
|
87
|
+
definition:
|
|
88
|
+
"A workflow instance bound to one order. Advances via Forwards; " +
|
|
89
|
+
"carries retained_submission values for Guard verification.",
|
|
90
|
+
aliases: ["progress instance"],
|
|
91
|
+
category: "object",
|
|
92
|
+
},
|
|
93
|
+
// ── Acceptance ────────────────────────────────────────────────────────────
|
|
94
|
+
{
|
|
95
|
+
term: "Guard",
|
|
96
|
+
definition:
|
|
97
|
+
"Immutable static validation rule. Verifies submissions and on-chain object data. " +
|
|
98
|
+
"Returns boolean. Cannot be mutated after creation.",
|
|
99
|
+
aliases: ["guard object"],
|
|
100
|
+
category: "acceptance",
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
term: "Repository",
|
|
104
|
+
definition:
|
|
105
|
+
"Mutable dynamic acceptance store. Keyed by (name, entity). " +
|
|
106
|
+
"Used for data that can change over time (e.g. SLA config, review records).",
|
|
107
|
+
aliases: ["repository object"],
|
|
108
|
+
category: "acceptance",
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
term: "Acceptance",
|
|
112
|
+
definition:
|
|
113
|
+
"The verification standard for a process step. Composed of static Guard + " +
|
|
114
|
+
"dynamic Repository. Drives whether a Forward can execute.",
|
|
115
|
+
aliases: ["acceptance standard"],
|
|
116
|
+
category: "acceptance",
|
|
117
|
+
},
|
|
118
|
+
// ─── Objects ──────────────────────────────────────────────────────────────
|
|
119
|
+
{
|
|
120
|
+
term: "Service",
|
|
121
|
+
definition:
|
|
122
|
+
"A merchant's service listing. References Machine, order_allocators, arbitrations, " +
|
|
123
|
+
"compensation_fund, rewards, buy_guard. machine & order_allocators lock after publish.",
|
|
124
|
+
aliases: ["service object"],
|
|
125
|
+
category: "object",
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
term: "Order",
|
|
129
|
+
definition:
|
|
130
|
+
"An order against a Service. Funds are escrowed; released via Progress + Allocation. " +
|
|
131
|
+
"Arb cases attach to orders for dispute resolution.",
|
|
132
|
+
aliases: ["order instance"],
|
|
133
|
+
category: "object",
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
term: "Allocator",
|
|
137
|
+
definition:
|
|
138
|
+
"Fund distribution rules. Priority: Amount → Rate → Surplus. first-Guard-wins. " +
|
|
139
|
+
"Locked on Service publish (order_allocators).",
|
|
140
|
+
aliases: ["allocation"],
|
|
141
|
+
category: "fund",
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
term: "Allocation",
|
|
145
|
+
definition:
|
|
146
|
+
"The act of distributing escrowed funds to recipients per an Allocator. " +
|
|
147
|
+
"Executed by the order holder or Permission holder.",
|
|
148
|
+
aliases: ["allocation act"],
|
|
149
|
+
category: "fund",
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
term: "Arbitration",
|
|
153
|
+
definition:
|
|
154
|
+
"Independent arbitration service object. Configured with voting_guard, usage_guard, " +
|
|
155
|
+
"fee. Generates Arb cases per dispute. Third-party preferred over self-built.",
|
|
156
|
+
aliases: ["arb service"],
|
|
157
|
+
category: "object",
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
term: "Arb",
|
|
161
|
+
definition:
|
|
162
|
+
"A single dispute case instance of an Arbitration. Has a state machine " +
|
|
163
|
+
"(dispute → confirm → vote → verdict → settle).",
|
|
164
|
+
aliases: ["arb case"],
|
|
165
|
+
category: "object",
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
term: "compensation_fund",
|
|
169
|
+
definition:
|
|
170
|
+
"A fund attached to a Service. Arbitration indemnity is drawn from it. " +
|
|
171
|
+
"Adequacy is a key trust signal for customers.",
|
|
172
|
+
aliases: ["compensation fund"],
|
|
173
|
+
category: "fund",
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
term: "buy_guard",
|
|
177
|
+
definition:
|
|
178
|
+
"A Guard attached to a Service that gates purchasing. Validates customer eligibility.",
|
|
179
|
+
aliases: ["buy guard"],
|
|
180
|
+
category: "acceptance",
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
term: "Sub-Order",
|
|
184
|
+
definition:
|
|
185
|
+
"A child order in a cross-Machine supply chain. Introduced at a node with transparent " +
|
|
186
|
+
"suppliers; verified by Guard to originate from one of the declared suppliers.",
|
|
187
|
+
aliases: ["suborder", "sub order"],
|
|
188
|
+
category: "object",
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
term: "Reward",
|
|
192
|
+
definition:
|
|
193
|
+
"Incentive pool. claim is Guard-gated. guard_add supports Fixed or GuardU64Identifier " +
|
|
194
|
+
"(dynamic). Used for marketing (first-order, cumulative, referral).",
|
|
195
|
+
aliases: ["reward pool"],
|
|
196
|
+
category: "fund",
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
term: "Demand",
|
|
200
|
+
definition:
|
|
201
|
+
"A user's posted service request with optional reward. presenters submit proposals; " +
|
|
202
|
+
"Guard filters them. Matches Services for personalized acquisition.",
|
|
203
|
+
aliases: ["demand request"],
|
|
204
|
+
category: "object",
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
term: "Personal",
|
|
208
|
+
definition:
|
|
209
|
+
"Permanently public on-chain identity profile. Social links, reputation (likes/dislikes), " +
|
|
210
|
+
"personal info records. CRITICAL: everything here is PUBLIC forever.",
|
|
211
|
+
aliases: ["personal profile"],
|
|
212
|
+
category: "object",
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
term: "Contact",
|
|
216
|
+
definition:
|
|
217
|
+
"Bridges a Service's um (contact) and the Messenger ims (messaging). Enables " +
|
|
218
|
+
"off-chain encrypted communication for pre-order negotiation & evidence.",
|
|
219
|
+
aliases: ["contact bridge"],
|
|
220
|
+
category: "object",
|
|
221
|
+
},
|
|
222
|
+
];
|
|
223
|
+
|
|
224
|
+
/** Lowercased alias → canonical term index. */
|
|
225
|
+
const ALIAS_INDEX: Map<string, string> = (() => {
|
|
226
|
+
const m = new Map<string, string>();
|
|
227
|
+
for (const e of CONCEPT_GLOSSARY) {
|
|
228
|
+
m.set(e.term.toLowerCase(), e.term);
|
|
229
|
+
for (const a of e.aliases) m.set(a.toLowerCase(), e.term);
|
|
230
|
+
}
|
|
231
|
+
return m;
|
|
232
|
+
})();
|
|
233
|
+
|
|
234
|
+
/** Resolve a (possibly deprecated) alias to the canonical term. Returns the input unchanged if unknown. */
|
|
235
|
+
export function resolveTerm(alias: string): string {
|
|
236
|
+
if (!alias) return alias;
|
|
237
|
+
return ALIAS_INDEX.get(alias.toLowerCase()) ?? alias;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/** Look up a glossary entry by canonical term (case-insensitive). */
|
|
241
|
+
export function lookupEntry(term: string): GlossaryEntry | undefined {
|
|
242
|
+
const t = term.toLowerCase();
|
|
243
|
+
return CONCEPT_GLOSSARY.find(
|
|
244
|
+
(e) => e.term.toLowerCase() === t || e.aliases.some((a) => a.toLowerCase() === t),
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
export interface GlossaryDrift {
|
|
249
|
+
/** The deprecated alias found. */
|
|
250
|
+
alias: string;
|
|
251
|
+
/** Canonical term to use instead. */
|
|
252
|
+
canonical: string;
|
|
253
|
+
/** 1-based line number where the alias appeared (when scanning a file). */
|
|
254
|
+
line?: number;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Scan free text for deprecated aliases.
|
|
259
|
+
* Returns a list of drift findings. Empty = clean.
|
|
260
|
+
*
|
|
261
|
+
* Note: this is a simple substring/word scan. For schema-field alignment use
|
|
262
|
+
* `auditSchemaFields` which checks object key names directly.
|
|
263
|
+
*/
|
|
264
|
+
export function validateText(text: string): GlossaryDrift[] {
|
|
265
|
+
const findings: GlossaryDrift[] = [];
|
|
266
|
+
if (!text) return findings;
|
|
267
|
+
const lower = text.toLowerCase();
|
|
268
|
+
for (const entry of CONCEPT_GLOSSARY) {
|
|
269
|
+
for (const alias of entry.aliases) {
|
|
270
|
+
const a = alias.toLowerCase();
|
|
271
|
+
// Avoid matching the canonical term inside its own definition
|
|
272
|
+
if (entry.term.toLowerCase() === a) continue;
|
|
273
|
+
if (lower.includes(a)) {
|
|
274
|
+
findings.push({ alias, canonical: entry.term });
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return findings;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Audit an object's keys against the glossary. Returns aliases found among the
|
|
283
|
+
* top-level keys. Used to keep schema field names canonical.
|
|
284
|
+
*/
|
|
285
|
+
export function auditSchemaFields(obj: Record<string, unknown>): GlossaryDrift[] {
|
|
286
|
+
const findings: GlossaryDrift[] = [];
|
|
287
|
+
for (const key of Object.keys(obj)) {
|
|
288
|
+
const canonical = ALIAS_INDEX.get(key.toLowerCase());
|
|
289
|
+
if (canonical && canonical !== key) {
|
|
290
|
+
findings.push({ alias: key, canonical });
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return findings;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/** Stable version of the glossary for offline-flywheel audits & rollback. */
|
|
297
|
+
export const CONCEPT_GLOSSARY_VERSION = 1;
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
# Guard Scenario Ledger
|
|
2
|
+
|
|
3
|
+
> Compiled from the WoWok Guard system documentation. This is a standalone reference covering all 9 Guard binding scenarios, their host objects, binding fields, verification results, constraints, and the scenario matching function.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 9 Guard Binding Scenarios — Overview
|
|
8
|
+
|
|
9
|
+
| # | Scenario | Host Object | Binding Field | Pass Result | Fail Result | Iterable |
|
|
10
|
+
|---|----------|-------------|---------------|-------------|-------------|----------|
|
|
11
|
+
| 1 | Service Purchase Verification | Service | `buy_guard` | Order created, enters payment | Transaction rejected | Yes |
|
|
12
|
+
| 2 | Allocation Strategy Selection | Service | `order_allocators` | Allocator executed for split | Skipped, next allocator tried | No (after publish) |
|
|
13
|
+
| 3 | Workflow Forward Verification | Machine | `Forward.guard` | Progress advances | Forward blocked | No (after publish) |
|
|
14
|
+
| 4 | Submission Data Verification | Progress | `submission` | Forward completed | Awaiting resubmission | No |
|
|
15
|
+
| 5 | Reward Claim Verification | Reward | `guard` | Reward disbursed | Claim rejected | Yes |
|
|
16
|
+
| 6 | Repository Write Verification | Repository | `write_guard` | Write success + optional data extraction | Write rejected | Yes |
|
|
17
|
+
| 7 | Dispute Initiation Verification | Arbitration | `usage_guard` | Arb case created | Dispute rejected | Yes |
|
|
18
|
+
| 8 | Arbitration Vote Verification | Arbitration | `voting_guard` | Vote counted (weight from GuardIdentifier) | Vote rejected | Yes |
|
|
19
|
+
| 9 | gen_passport Verification | Standalone | none | Standalone Guard, passport test | Test failure | Yes |
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Detailed Scenario Descriptions
|
|
24
|
+
|
|
25
|
+
### 1. Service Purchase Verification (Service.buy_guard)
|
|
26
|
+
|
|
27
|
+
- **Host Object**: Service
|
|
28
|
+
- **Binding Field**: `buy_guard`
|
|
29
|
+
- **Pass Result**: Order created, enters payment
|
|
30
|
+
- **Fail Result**: Transaction rejected (buy operation fails directly)
|
|
31
|
+
- **Iterable**: Yes (replaceable before Service is published; after publish, only by recreating Service)
|
|
32
|
+
|
|
33
|
+
**Typical Validation Rules**:
|
|
34
|
+
- Authorized address check (Signer == Provider)
|
|
35
|
+
- Whitelist check (Signer ∈ authorized address list)
|
|
36
|
+
- Service paused status check (service.paused == false)
|
|
37
|
+
- Service published status check (service.published == true)
|
|
38
|
+
- Membership verification (EntityRegistrar records query)
|
|
39
|
+
|
|
40
|
+
**Typical Patterns**: P03 (single-address identity), P04 (whitelist), P02 (published object + system context), P11 (entity registration check)
|
|
41
|
+
|
|
42
|
+
**Key Risks**: R-C4-01 (Signer check direction error), R-X1-08 (bound to immutable object)
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
### 2. Allocation Strategy Selection (Service.order_allocators)
|
|
47
|
+
|
|
48
|
+
- **Host Object**: Service
|
|
49
|
+
- **Binding Field**: `order_allocators`
|
|
50
|
+
- **Pass Result**: Allocator executed (funds distributed per sharing config)
|
|
51
|
+
- **Fail Result**: Skipped, next allocator tried
|
|
52
|
+
- **Iterable**: No (not replaceable after Service publish)
|
|
53
|
+
|
|
54
|
+
**Key Constraints**:
|
|
55
|
+
- **First-match-wins**: Multiple allocators are evaluated in order; the first passing Guard's allocator executes
|
|
56
|
+
- **sharing.who couples fund flow**: `sharing.who=Signer` → funds flow to caller (Guard must bind Signer); `sharing.who=Entity` → funds flow to fixed address (no Signer binding needed)
|
|
57
|
+
|
|
58
|
+
**Typical Validation Rules**:
|
|
59
|
+
- Order node status check (progress.current == "Complete" / "Cancelled" / etc.)
|
|
60
|
+
- Service ownership verification (order.service == service_address)
|
|
61
|
+
- Merchant win node check (order in {"Order Complete", "Wonderful", "Return Fail"})
|
|
62
|
+
- Customer win node check (order in {"Lost", "Return Complete"})
|
|
63
|
+
|
|
64
|
+
**Key Risks**: R-X1-05 (first-match-wins gaming), R-C3-05 (cross-project submission bypass), R-C3-06 (allocator fund theft)
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
### 3. Workflow Forward Verification (Machine.Forward.guard)
|
|
69
|
+
|
|
70
|
+
- **Host Object**: Machine
|
|
71
|
+
- **Binding Field**: `Forward.guard` (bound to a specific Forward: from_node → to_node)
|
|
72
|
+
- **Pass Result**: Progress advances to the next node
|
|
73
|
+
- **Fail Result**: Forward blocked, Progress stays at current node
|
|
74
|
+
- **Iterable**: No (not replaceable after Machine publish)
|
|
75
|
+
|
|
76
|
+
**Key Constraints**:
|
|
77
|
+
- A Forward is a node pair: from_node, to_node, permissionIndex, guard
|
|
78
|
+
- Guard is verified before Forward execution
|
|
79
|
+
- Old Guard becomes inactive after node switch
|
|
80
|
+
- Re-entry is ALLOWED (same forward on same node can be triggered repeatedly)
|
|
81
|
+
|
|
82
|
+
**Typical Validation Rules**:
|
|
83
|
+
- Submission data format (Merkle Root length == 66)
|
|
84
|
+
- Time lock (Clock > progress.current_time + duration)
|
|
85
|
+
- Provider authorization (Signer == Provider or Customer timeout override)
|
|
86
|
+
- Service ownership (order.service == service_address)
|
|
87
|
+
- Repository data query (specified data exists in weather_repo)
|
|
88
|
+
|
|
89
|
+
**Key Risks**: R-C2-03 (Progress data depends on Machine immutability), R-X1-08 (Machine immutable after publish), R-X1-06 (time lock direction), R-C3-05 (cross-project bypass)
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
### 4. Submission Data Verification (Progress.submission)
|
|
94
|
+
|
|
95
|
+
- **Host Object**: Progress
|
|
96
|
+
- **Binding Field**: `submission` (submission data Guard during Forward execution)
|
|
97
|
+
- **Pass Result**: Forward completed, submission data written to Progress history
|
|
98
|
+
- **Fail Result**: Awaiting resubmission, Forward does not advance
|
|
99
|
+
- **Iterable**: No (immutable once set)
|
|
100
|
+
|
|
101
|
+
**Typical Validation Rules**:
|
|
102
|
+
- Submission string length validation
|
|
103
|
+
- Submission numeric range validation
|
|
104
|
+
- Submission data format (signature, Merkle Root, JSON structure)
|
|
105
|
+
- Submission data consistency with Repository data
|
|
106
|
+
|
|
107
|
+
**Typical Patterns**: P15 (retained_submission), P17 (query parameter translation)
|
|
108
|
+
|
|
109
|
+
**Key Risks**: R-X1-12 (retained_submission ambiguous name), R-C3-01 (submission not bound to Signer)
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
### 5. Reward Claim Verification (Reward.guard)
|
|
114
|
+
|
|
115
|
+
- **Host Object**: Reward
|
|
116
|
+
- **Binding Field**: `guard`
|
|
117
|
+
- **Pass Result**: Reward disbursed (funds transferred to caller)
|
|
118
|
+
- **Fail Result**: Claim rejected (Guard not passed)
|
|
119
|
+
- **Iterable**: Yes (replaceable)
|
|
120
|
+
|
|
121
|
+
**Typical Validation Rules**:
|
|
122
|
+
- Node status check (progress.current == "Wonderful" / "Lost" / "Shipping")
|
|
123
|
+
- Order owner verification (order.owner == Signer)
|
|
124
|
+
- Service ownership (order.service == service_address)
|
|
125
|
+
- One-time claim check (query_reward_record_count == 0 or query_reward_record_exists == false)
|
|
126
|
+
- Reward expiration check (reward.guard.expiration_time >= Clock)
|
|
127
|
+
|
|
128
|
+
**Key Risks**: R-X1-14 (reentrancy — CRITICAL; REQUIRED: use query 1613 + logic_not, or 1612 + logic_equal(0), or 1626 + logic_not), R-C3-01 (order_id not bound to Signer)
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
### 6. Repository Write Verification (Repository.write_guard)
|
|
133
|
+
|
|
134
|
+
- **Host Object**: Repository
|
|
135
|
+
- **Binding Field**: `write_guard`
|
|
136
|
+
- **Pass Result**: Write success + optional data extraction
|
|
137
|
+
- **Fail Result**: Write rejected
|
|
138
|
+
- **Iterable**: Yes (replaceable)
|
|
139
|
+
|
|
140
|
+
**Special Constraints**:
|
|
141
|
+
- **id_from_submission must be Address**: The write key (id) from submission must be Address type
|
|
142
|
+
- **data_from_submission type matching**: The written data type must match Repository's value_type
|
|
143
|
+
- **quote_guard fails in verify phase**: impack_list is always empty during verify phase (passport.move#L289), causing Repository queries with quote_guard (query 1167) to fail with `IMPACK_GUARD_NOT_FOUND` in gen_passport flow
|
|
144
|
+
|
|
145
|
+
**Typical Validation Rules**:
|
|
146
|
+
- Writer permission verification (Signer == authorized_address)
|
|
147
|
+
- Write data format validation
|
|
148
|
+
- Repository policy validation
|
|
149
|
+
- Write idempotency (optional anti-reentrancy: query 1166 + logic_not)
|
|
150
|
+
|
|
151
|
+
**Key Risks**: R-C1-03 (Repository data manipulable), R-C3-04 (id_from_submission type not verified), R-X1-10 (quote_guard fails in verify phase)
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
### 7. Dispute Initiation Verification (Arbitration.usage_guard)
|
|
156
|
+
|
|
157
|
+
- **Host Object**: Arbitration
|
|
158
|
+
- **Binding Field**: `usage_guard`
|
|
159
|
+
- **Pass Result**: Arb case created
|
|
160
|
+
- **Fail Result**: Dispute rejected
|
|
161
|
+
- **Iterable**: Yes (replaceable)
|
|
162
|
+
|
|
163
|
+
**Key Constraints**:
|
|
164
|
+
- **Arbitration bPaused=true blocks first**: Dispute initiation is rejected before Guard check when Arbitration is paused
|
|
165
|
+
- **Protocol limit**: `MAX_DISPUTE_COUNT = 10` (order.move)
|
|
166
|
+
- **Threshold balance**: Too high prevents disputes, too low enables malicious filings
|
|
167
|
+
|
|
168
|
+
**Typical Validation Rules**:
|
|
169
|
+
- Dispute initiator permission verification
|
|
170
|
+
- Dispute reason format validation
|
|
171
|
+
- Dispute count limit (query 1565 + logic_not or 1564 + logic_equal(0))
|
|
172
|
+
- Time window verification
|
|
173
|
+
|
|
174
|
+
**Key Risks**: R-X1-07 (too many AND conditions), R-X1-14 (reentrancy — HIGH; REQUIRED: use query 1565 + logic_not or 1564 + logic_equal(0))
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
### 8. Arbitration Vote Verification (Arbitration.voting_guard)
|
|
179
|
+
|
|
180
|
+
- **Host Object**: Arbitration
|
|
181
|
+
- **Binding Field**: `voting_guard`
|
|
182
|
+
- **Pass Result**: Vote counted (GuardIdentifier extracts weight)
|
|
183
|
+
- **Fail Result**: Vote rejected
|
|
184
|
+
- **Iterable**: Yes (replaceable)
|
|
185
|
+
|
|
186
|
+
**Key Constraints**:
|
|
187
|
+
- **GuardIdentifier must be numeric**: voting_guard's GuardIdentifier must be numeric (U8/U256), otherwise `E_GUARD_IDENTIFIER_NOT_NUMBER`. Used to extract weight value from voting_guard output.
|
|
188
|
+
- **bPaused=true blocks first**: Same as usage_guard — blocks before Guard check
|
|
189
|
+
- **Voter address typically from submission**: Type3 submission, must be paired with Signer verification to prevent forgery
|
|
190
|
+
|
|
191
|
+
**Typical Validation Rules**:
|
|
192
|
+
- Voter identity verification (Signer == submitted.voter_address)
|
|
193
|
+
- Vote weight equals reputation score (query EntityRegistrar records + numeric comparison)
|
|
194
|
+
- Voter has not already voted (query 1404 + logic_not or 1405 + logic_equal(0))
|
|
195
|
+
- Vote time window verification
|
|
196
|
+
|
|
197
|
+
**Key Risks**: R-C3-02 (voting weight from submission — forgeable; must use numeric identifier), R-X1-14 (reentrancy — CRITICAL; REQUIRED: use query 1404 + logic_not, 1406 + logic_not, or 1405 + logic_equal(0); NOTE: 1403 is total count, NOT per-voter)
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
### 9. gen_passport Verification (Standalone)
|
|
202
|
+
|
|
203
|
+
- **Host Object**: Standalone (no binding)
|
|
204
|
+
- **Binding Field**: none
|
|
205
|
+
- **Pass Result**: Standalone Guard, used for passport testing
|
|
206
|
+
- **Fail Result**: Test failure (does not block business flow)
|
|
207
|
+
- **Iterable**: Yes (not bound to any object, can create new tests anytime)
|
|
208
|
+
|
|
209
|
+
**Use Cases**:
|
|
210
|
+
- Test Guard logic via `onchain_operations(gen_passport)` without binding to any Host Object
|
|
211
|
+
- Verify Guard behavior under mock submission
|
|
212
|
+
- Verify expected-pass and expected-fail boundary scenarios
|
|
213
|
+
- Protected by `guard_gen_passport_test` confirmation rule (standard level)
|
|
214
|
+
|
|
215
|
+
**No business risks** (testing-only purpose).
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## Scenario Special Constraints
|
|
220
|
+
|
|
221
|
+
### voting_guard GuardIdentifier Must Be Numeric
|
|
222
|
+
|
|
223
|
+
Arbitration voting_guard's GuardIdentifier must be numeric (U8/U16/U32/U64/U128/U256), otherwise `E_GUARD_IDENTIFIER_NOT_NUMBER`. The root output is a weighted numeric value used as vote weight, not a Bool. A Bool or non-numeric output cannot compute weight.
|
|
224
|
+
|
|
225
|
+
**Impact**: BINDING_01 constraint (creation-time validation), voting_guard root cannot return a Bool constant (e.g., P14 variant always-true Guard is inapplicable), must have a query returning a numeric value.
|
|
226
|
+
|
|
227
|
+
### Repository write_guard Type Matching
|
|
228
|
+
|
|
229
|
+
- **id_from_submission must be Address**: The write key from submission must be Address type
|
|
230
|
+
- **data_from_submission type match**: The written data type must match Repository's value_type
|
|
231
|
+
|
|
232
|
+
**Impact**: BINDING_02 (Repository id_from_submission must be Address), BINDING_03 (Repository data_from_submission type match), R-C3-04 risk rule
|
|
233
|
+
|
|
234
|
+
### Arbitration bPaused=true Blocks First
|
|
235
|
+
|
|
236
|
+
When Arbitration's `bPaused=true`:
|
|
237
|
+
- Blocks before Guard check: directly rejects usage_guard and voting_guard verification
|
|
238
|
+
- Used for emergency pause of the entire Arbitration flow (vulnerability, attack, or governance decision)
|
|
239
|
+
|
|
240
|
+
**Impact**: Guard passing does not guarantee execution — Arbitration must also not be paused.
|
|
241
|
+
|
|
242
|
+
### order_allocators Sequential First-Match-Wins
|
|
243
|
+
|
|
244
|
+
Service's `order_allocators` is an ordered array evaluated at runtime:
|
|
245
|
+
- First Guard-passing allocator executes
|
|
246
|
+
- Subsequent Guards do not execute (even if conditions are met)
|
|
247
|
+
- If no Guard passes, no allocation occurs
|
|
248
|
+
|
|
249
|
+
**Impact**: R-X1-05 (first-match-wins gaming), Guard order must be carefully designed (merchant win Guard typically before customer win Guard), multiple Guard root conditions should be mutually exclusive.
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## Scenario Auto-Matching (inferSceneFromAction)
|
|
254
|
+
|
|
255
|
+
### Function Signature
|
|
256
|
+
|
|
257
|
+
```typescript
|
|
258
|
+
inferSceneFromAction(action: string): GuardScene | undefined
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### Action → Scene Mapping
|
|
262
|
+
|
|
263
|
+
| Action | Matched Scene ID | Scenario Name |
|
|
264
|
+
|--------|------------------|---------------|
|
|
265
|
+
| `buy` | `service_buy_guard` | Service Purchase Verification |
|
|
266
|
+
| `allocate` | `service_order_allocators_guard` | Allocation Strategy Selection |
|
|
267
|
+
| `forward` | `machine_forward_guard` | Workflow Forward Verification |
|
|
268
|
+
| `submit_progress` | `progress_submission_guard` | Submission Data Verification |
|
|
269
|
+
| `claim_reward` | `reward_guard` | Reward Claim Verification |
|
|
270
|
+
| `write_repository` | `repository_write_guard` | Repository Write Verification |
|
|
271
|
+
| `dispute` | `arbitration_usage_guard` | Dispute Initiation Verification |
|
|
272
|
+
| `vote` | `arbitration_voting_guard` | Arbitration Vote Verification |
|
|
273
|
+
| `gen_passport` | `gen_passport_guard` | gen_passport Verification |
|
|
274
|
+
| `custom` | undefined | Custom (no match) |
|
|
275
|
+
|
|
276
|
+
### Usage Context
|
|
277
|
+
|
|
278
|
+
`inferSceneFromAction` is called during the R5 binding planning round. It automatically infers the Host Object, binding field, and scenario-specific constraints from the user-described action. The result populates `GuardAdvice.matched_scene` and `GuardAdvice.scene_constraints`, guiding the AI to satisfy scenario constraints during subsequent design.
|
|
279
|
+
|
|
280
|
+
### Example
|
|
281
|
+
|
|
282
|
+
```typescript
|
|
283
|
+
// User says: "I want to design a reward Guard so customers can claim rewards after reaching the Wonderful node"
|
|
284
|
+
inferSceneFromAction("claim_reward")
|
|
285
|
+
// → Returns reward_guard scene with special_constraints:
|
|
286
|
+
// - Reentrancy: CRITICAL — use query 1613 + logic_not to prevent duplicate claims
|
|
287
|
+
// - One-time claim: query_reward_record_count == 0
|
|
288
|
+
// - Reward expiration: reward.guard.expiration_time >= Clock
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
## Scenario Iterability Analysis
|
|
294
|
+
|
|
295
|
+
### Immutable Scenes (getImmutableScenes)
|
|
296
|
+
|
|
297
|
+
Scenes where Guard cannot be replaced after the Host Object is published:
|
|
298
|
+
|
|
299
|
+
| Scene ID | Scenario Name | Reason |
|
|
300
|
+
|----------|---------------|--------|
|
|
301
|
+
| `machine_forward_guard` | Workflow Forward Verification | Machine Forward.guard not replaceable after publish |
|
|
302
|
+
| `service_order_allocators_guard` | Allocation Strategy Selection | Service order_allocators not replaceable after publish |
|
|
303
|
+
|
|
304
|
+
**Impact**: Guard design must be 100% accurate (cannot be fixed after creation). Confirmation flow must be strict (`guard_create_immutable`, irreversible level).
|
|
305
|
+
|
|
306
|
+
### Numeric Identifier Scenes (getNumericIdentifierScenes)
|
|
307
|
+
|
|
308
|
+
Scenes requiring numeric GuardIdentifier:
|
|
309
|
+
|
|
310
|
+
| Scene ID | Scenario Name | Numeric Reason |
|
|
311
|
+
|----------|---------------|----------------|
|
|
312
|
+
| `arbitration_voting_guard` | Arbitration Vote Verification | GuardIdentifier extracts weight value, must be numeric |
|
|
313
|
+
|
|
314
|
+
**Impact**: BINDING_01 constraint (Move Arbitration layer validation), voting_guard root cannot directly return Bool (P14 variant always-true Guard inapplicable)
|
|
315
|
+
|
|
316
|
+
### Iterable Scene Replacement Flow
|
|
317
|
+
|
|
318
|
+
For iterable scenes (buy_guard, Reward.guard, Repository.write_guard, Arbitration usage_guard/voting_guard, gen_passport):
|
|
319
|
+
|
|
320
|
+
1. **Export old Guard**: `guard2file` exports JSON backup
|
|
321
|
+
2. **Edit JSON**: Modify based on old JSON (preserve identifier order, update table/root)
|
|
322
|
+
3. **Create new Guard**: `onchain_operations(guard) CREATE`
|
|
323
|
+
4. **Rebind**: MODIFY Host Object's binding_field to point to new Guard
|
|
324
|
+
5. **gen_passport test**: Run `gen_passport` on the new Guard
|
|
325
|
+
6. **Post-verification**: Verify new Guard is active
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
## Example Scenario Cases
|
|
330
|
+
|
|
331
|
+
### Pattern Coverage Across Examples
|
|
332
|
+
|
|
333
|
+
| Pattern | Count | Description |
|
|
334
|
+
|---------|-------|-------------|
|
|
335
|
+
| P04 (Whitelist — single address) | 1 | Signer == authorized address |
|
|
336
|
+
| P05 (Time lock) | 4 | Clock-based time checks |
|
|
337
|
+
| P06 (Node status check) | 8 | progress.current == specified node |
|
|
338
|
+
| P07 (One-time claim) | 3 | Anti-reentrancy claims |
|
|
339
|
+
| P08 (Submission identity) | 3 | Signer == order.owner |
|
|
340
|
+
| P09 (Witness derivation) | 12 | convert_witness=100 (Order→Progress) |
|
|
341
|
+
| P10 (Multi-condition combo) | 6 | Combined node + Signer + service checks |
|
|
342
|
+
| P13 (Repository data query) | 1 | Repository existence check |
|
|
343
|
+
| P14 variant (Always-true / pure dependency) | 1 | Permission controlled by Forward permissionIndex |
|
|
344
|
+
| P15 (Retained submission) | 1 | Submission data validation |
|
|
345
|
+
|
|
346
|
+
### Data Source Usage
|
|
347
|
+
|
|
348
|
+
| Source | Usage Count | Typical Scenarios |
|
|
349
|
+
|--------|-------------|-------------------|
|
|
350
|
+
| Type 1 (Constant objects/values) | 20 | Node names, durations, service addresses, author addresses |
|
|
351
|
+
| Type 2 (Witness derivation) | 14 | convert_witness=100 (Order→Progress) |
|
|
352
|
+
| Type 3 (Submission objects/values) | 18 | order_id, Merkle Root, timestamps |
|
|
353
|
+
| Type 4 (System context) | 8 | Clock (time lock), Signer (identity verification) |
|