@wowok/agent-mcp 2.3.16 → 2.3.18

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.
Files changed (106) hide show
  1. package/dist/customer/index.d.ts +9 -0
  2. package/dist/customer/index.js +9 -0
  3. package/dist/customer/industry-risks.d.ts +4 -0
  4. package/dist/customer/industry-risks.js +14 -0
  5. package/dist/customer/user-preferences.d.ts +3 -0
  6. package/dist/customer/user-preferences.js +9 -0
  7. package/dist/experience/realtime-feedback.js +17 -0
  8. package/dist/index.js +360 -273
  9. package/dist/knowledge/acquisition-flywheel.d.ts +3 -0
  10. package/dist/knowledge/acquisition-flywheel.js +9 -0
  11. package/dist/knowledge/guard-ledger.d.ts +19 -0
  12. package/dist/knowledge/guard-ledger.js +219 -0
  13. package/dist/knowledge/guard-puzzle.d.ts +93 -0
  14. package/dist/knowledge/guard-puzzle.js +278 -0
  15. package/dist/knowledge/guard-risk.d.ts +60 -0
  16. package/dist/knowledge/guard-risk.js +474 -0
  17. package/dist/knowledge/guard-translation.d.ts +46 -0
  18. package/dist/knowledge/guard-translation.js +487 -0
  19. package/dist/knowledge/index.d.ts +13 -0
  20. package/dist/knowledge/index.js +13 -0
  21. package/dist/knowledge/industry-registry.d.ts +1 -2
  22. package/dist/knowledge/industry-registry.js +23 -3
  23. package/dist/knowledge/safety-rules.js +61 -0
  24. package/dist/knowledge/tool-constraints.js +12 -22
  25. package/dist/safety/confirm-gate.d.ts +4 -2
  26. package/dist/safety/confirm-gate.js +48 -4
  27. package/dist/schema/call/allocation.d.ts +24 -14
  28. package/dist/schema/call/arbitration.d.ts +142 -132
  29. package/dist/schema/call/base.d.ts +901 -43
  30. package/dist/schema/call/base.js +66 -2
  31. package/dist/schema/call/bridge-handler.js +15 -2
  32. package/dist/schema/call/bridge.d.ts +769 -1
  33. package/dist/schema/call/bridge.js +37 -0
  34. package/dist/schema/call/contact.d.ts +10 -0
  35. package/dist/schema/call/demand.d.ts +10 -0
  36. package/dist/schema/call/guard.d.ts +76 -46
  37. package/dist/schema/call/handler.js +46 -14
  38. package/dist/schema/call/machine.d.ts +158 -138
  39. package/dist/schema/call/order.d.ts +10 -0
  40. package/dist/schema/call/payment.d.ts +10 -0
  41. package/dist/schema/call/permission.d.ts +232 -222
  42. package/dist/schema/call/personal.d.ts +10 -0
  43. package/dist/schema/call/progress.d.ts +10 -0
  44. package/dist/schema/call/proof.d.ts +20 -0
  45. package/dist/schema/call/repository.d.ts +32 -22
  46. package/dist/schema/call/reward.d.ts +10 -0
  47. package/dist/schema/call/semantic.d.ts +9 -2
  48. package/dist/schema/call/semantic.js +409 -21
  49. package/dist/schema/call/service.d.ts +20 -10
  50. package/dist/schema/call/treasury.d.ts +10 -0
  51. package/dist/schema/config/index.d.ts +18 -0
  52. package/dist/schema/config/index.js +17 -0
  53. package/dist/schema/index.d.ts +6 -0
  54. package/dist/schema/index.js +5 -0
  55. package/dist/schema/local/index.d.ts +9 -9
  56. package/dist/schema/local/index.js +9 -0
  57. package/dist/schema/messenger/index.d.ts +350 -29
  58. package/dist/schema/messenger/index.js +17 -17
  59. package/dist/schema/operations.d.ts +1667 -545
  60. package/dist/schema/operations.js +91 -96
  61. package/dist/schema/project/index.d.ts +21 -0
  62. package/dist/schema/project/index.js +32 -0
  63. package/dist/schema/query/index.d.ts +1074 -168
  64. package/dist/schema/query/index.js +8 -8
  65. package/dist/schema/schema-query/index.d.ts +33 -0
  66. package/dist/schema/schema-query/index.js +36 -0
  67. package/dist/schema/schema-version.d.ts +25 -0
  68. package/dist/schema/schema-version.js +76 -0
  69. package/dist/schema/trust/index.d.ts +407 -0
  70. package/dist/schema/trust/index.js +113 -0
  71. package/dist/schemas/bridge_operation.output.json +224 -0
  72. package/dist/schemas/bridge_operation.schema.json +67 -8
  73. package/dist/schemas/config_operation.output.json +18 -0
  74. package/dist/schemas/config_operation.schema.json +34 -0
  75. package/dist/schemas/guard-node-schema.json +82 -0
  76. package/dist/schemas/guard2file.schema.json +8 -0
  77. package/dist/schemas/index.json +19 -1
  78. package/dist/schemas/machineNode2file.schema.json +8 -0
  79. package/dist/schemas/messenger_operation.output.json +224 -0
  80. package/dist/schemas/onchain_events.output.json +718 -0
  81. package/dist/schemas/onchain_operations.output.json +277 -2
  82. package/dist/schemas/onchain_operations.schema.json +19 -16
  83. package/dist/schemas/onchain_operations_allocation.schema.json +8 -0
  84. package/dist/schemas/onchain_operations_arbitration.schema.json +8 -0
  85. package/dist/schemas/onchain_operations_contact.schema.json +8 -0
  86. package/dist/schemas/onchain_operations_demand.schema.json +8 -0
  87. package/dist/schemas/onchain_operations_gen_passport.schema.json +16 -0
  88. package/dist/schemas/onchain_operations_guard.schema.json +11 -16
  89. package/dist/schemas/onchain_operations_machine.schema.json +8 -0
  90. package/dist/schemas/onchain_operations_order.schema.json +8 -0
  91. package/dist/schemas/onchain_operations_payment.schema.json +8 -0
  92. package/dist/schemas/onchain_operations_permission.schema.json +8 -0
  93. package/dist/schemas/onchain_operations_personal.schema.json +8 -0
  94. package/dist/schemas/onchain_operations_progress.schema.json +8 -0
  95. package/dist/schemas/onchain_operations_repository.schema.json +8 -0
  96. package/dist/schemas/onchain_operations_reward.schema.json +8 -0
  97. package/dist/schemas/onchain_operations_service.schema.json +8 -0
  98. package/dist/schemas/onchain_operations_treasury.schema.json +8 -0
  99. package/dist/schemas/onchain_table_data.output.json +718 -0
  100. package/dist/schemas/project_operation.output.json +18 -0
  101. package/dist/schemas/project_operation.schema.json +42 -0
  102. package/dist/schemas/query_toolkit.schema.json +360 -368
  103. package/dist/schemas/schema_query.schema.json +6 -3
  104. package/dist/schemas/trust_score.output.json +327 -0
  105. package/dist/schemas/trust_score.schema.json +46 -0
  106. package/package.json +2 -2
@@ -0,0 +1,60 @@
1
+ import type { GuardScene } from "./guard-ledger.js";
2
+ export type GuardStakeholder = "customer" | "provider" | "arbitrator" | "claimant" | "system";
3
+ export type RiskLevel = "critical" | "high" | "medium" | "low" | "info";
4
+ export type RiskCategory = "data_source_trust" | "submission_forgery" | "game_theory" | "logic_gap" | "binding_risk" | "dependency_risk";
5
+ export interface GuardRisk {
6
+ id: string;
7
+ level: RiskLevel;
8
+ category: RiskCategory;
9
+ title: string;
10
+ description: string;
11
+ affected_stakeholders: GuardStakeholder[];
12
+ scenario: string;
13
+ mitigation: string;
14
+ evidence?: string;
15
+ }
16
+ export interface GuardRiskAssessment {
17
+ guard_summary: string;
18
+ scene?: GuardScene;
19
+ risks: GuardRisk[];
20
+ overall_risk: RiskLevel;
21
+ stakeholder_advice: Partial<Record<GuardStakeholder, string[]>>;
22
+ needs_human_review: boolean;
23
+ }
24
+ export interface RiskRule {
25
+ id: string;
26
+ trigger: string;
27
+ check: (ctx: RiskCheckContext) => GuardRisk | null;
28
+ }
29
+ export interface RiskCheckContext {
30
+ table: Array<{
31
+ identifier: number;
32
+ b_submission: boolean;
33
+ value_type: string;
34
+ value?: unknown;
35
+ name?: string;
36
+ object_type?: string;
37
+ }>;
38
+ root: any;
39
+ rely?: {
40
+ guards: string[];
41
+ logic_or?: boolean;
42
+ };
43
+ scene?: GuardScene;
44
+ operation_type?: string;
45
+ }
46
+ export declare function assessGuardRisks(params: {
47
+ table: RiskCheckContext["table"];
48
+ root: any;
49
+ rely?: RiskCheckContext["rely"];
50
+ scene?: GuardScene;
51
+ operation_type?: string;
52
+ }): GuardRiskAssessment;
53
+ export declare function assessGuardRisksForOperation(operation_type: string, data: any): GuardRiskAssessment | null;
54
+ export declare function getRiskSummary(assessment: GuardRiskAssessment): {
55
+ risk_count: number;
56
+ critical_count: number;
57
+ high_count: number;
58
+ needs_human_review: boolean;
59
+ top_risks: string[];
60
+ };
@@ -0,0 +1,474 @@
1
+ const RISK_RULES = [
2
+ {
3
+ id: "R-DST-01",
4
+ trigger: "Guard 查询 Repository 数据但未验证写入者权限",
5
+ check: (ctx) => {
6
+ const rootStr = JSON.stringify(ctx.root).toLowerCase();
7
+ if (rootStr.includes('"query"') && rootStr.includes('repository')) {
8
+ const hasSignerCheck = rootStr.includes('"signer"') || rootStr.includes('"context"');
9
+ if (!hasSignerCheck) {
10
+ return {
11
+ id: "R-DST-01",
12
+ level: "high",
13
+ category: "data_source_trust",
14
+ title: "Repository 数据源未验证写入者权限",
15
+ description: "Guard 查询 Repository 数据,但未验证谁有权写入该 Repository。" +
16
+ "恶意写入者可以操纵 Repository 数据来欺骗 Guard。",
17
+ affected_stakeholders: ["customer", "provider"],
18
+ scenario: "数据源操纵:攻击者写入虚假数据使 Guard 通过",
19
+ mitigation: "1) 在 Repository write_guard 中限制写入者权限;" +
20
+ "2) 在当前 Guard 中添加 context(Signer) 验证写入者身份;" +
21
+ "3) 使用多点数据源交叉验证",
22
+ };
23
+ }
24
+ }
25
+ return null;
26
+ },
27
+ },
28
+ {
29
+ id: "R-DST-02",
30
+ trigger: "Guard 查询 Progress 状态但未验证 Machine 发布状态",
31
+ check: (ctx) => {
32
+ const rootStr = JSON.stringify(ctx.root).toLowerCase();
33
+ if (rootStr.includes('progress') && ctx.scene?.host_object === "Machine") {
34
+ return {
35
+ id: "R-DST-02",
36
+ level: "medium",
37
+ category: "data_source_trust",
38
+ title: "Progress 数据依赖 Machine 不可变性",
39
+ description: "Guard 查询 Progress 状态。如果 Machine 未发布,Provider 可以修改 Machine 节点结构," +
40
+ "导致 Guard 验证的节点名失效或被重命名。",
41
+ affected_stakeholders: ["customer"],
42
+ scenario: "Provider 修改 Machine 节点名使 Guard 验证失效",
43
+ mitigation: "1) 确保 Machine 已发布(bPublished=true)再绑定 Guard;" +
44
+ "2) 在 Guard 中查询 Machine.bPublished 字段验证;" +
45
+ "3) 使用节点 ID 而非节点名进行比较",
46
+ };
47
+ }
48
+ return null;
49
+ },
50
+ },
51
+ {
52
+ id: "R-SF-01",
53
+ trigger: "Guard 依赖提交数据但未验证签名者身份(无 Signer 检查=high;有 Signer 检查=info 降级)",
54
+ check: (ctx) => {
55
+ const hasSubmission = ctx.table.some((e) => e.b_submission);
56
+ if (!hasSubmission)
57
+ return null;
58
+ if (ctx.scene?.binding_field === "voting_guard")
59
+ return null;
60
+ const rootStr = JSON.stringify(ctx.root);
61
+ const hasSignerCheck = rootStr.includes('"Signer"');
62
+ if (!hasSignerCheck) {
63
+ return {
64
+ id: "R-SF-01",
65
+ level: "high",
66
+ category: "submission_forgery",
67
+ title: "提交数据未与签名者身份绑定",
68
+ description: "Guard 接受运行时提交数据,但未验证提交者是否为当前交易签名者。" +
69
+ "攻击者可以提交他人的数据(如他人的地址、他人的凭证)来通过 Guard。",
70
+ affected_stakeholders: ["customer", "provider"],
71
+ scenario: "身份伪造:攻击者提交他人的地址冒充授权用户",
72
+ mitigation: "1) 添加 context(Signer) 与提交数据绑定验证;" +
73
+ "2) 使用 vec_contains_address 验证签名者在白名单中;" +
74
+ "3) 使用 Passport 凭证替代裸地址提交",
75
+ };
76
+ }
77
+ return {
78
+ id: "R-SF-01",
79
+ level: "info",
80
+ category: "submission_forgery",
81
+ title: "提交数据已通过 context(Signer) 间接绑定(请确认绑定方向正确)",
82
+ description: "Guard 接受运行时提交数据,且 root 子树中包含 context(Signer) 检查," +
83
+ "提交数据与签名者形成间接绑定,伪造风险已降低。" +
84
+ "但需人工确认:context(Signer) 比较的常量是正确角色(如 Provider 地址而非 Customer 地址)," +
85
+ "且提交数据确实应由该签名者提供。",
86
+ affected_stakeholders: ["customer", "provider"],
87
+ scenario: "间接绑定待确认:Signer 检查方向与提交数据归属是否匹配",
88
+ mitigation: "1) 确认 context(Signer) 与正确的 table 常量比较(Provider 地址而非 Customer 地址);" +
89
+ "2) 确认提交数据的来源角色与 Signer 检查一致;" +
90
+ "3) 如需更严格绑定,使用 query 验证提交者链上身份",
91
+ };
92
+ },
93
+ },
94
+ {
95
+ id: "R-SF-02",
96
+ trigger: "voting_guard 权重来自提交数据但未验证来源",
97
+ check: (ctx) => {
98
+ if (ctx.scene?.binding_field === "voting_guard") {
99
+ const numericEntries = ctx.table.filter((e) => e.b_submission && ["U8", "U16", "U32", "U64", "U128", "U256"].includes(e.value_type));
100
+ if (numericEntries.length > 0) {
101
+ return {
102
+ id: "R-SF-02",
103
+ level: "critical",
104
+ category: "submission_forgery",
105
+ title: "投票权重来自用户提交,可能被伪造",
106
+ description: "voting_guard 的权重数据来自 b_submission=true 的 table 条目。" +
107
+ "如果未通过 EntityRegistrar 或其他可信来源验证权重," +
108
+ "投票者可以提交任意高权重操纵投票结果。",
109
+ affected_stakeholders: ["arbitrator"],
110
+ scenario: "权重伪造:投票者提交虚假高分操纵仲裁结果",
111
+ mitigation: "1) 权重应从 EntityRegistrar 查询而非用户提交;" +
112
+ "2) 使用 query(entity.records) 获取链上注册的声誉分;" +
113
+ "3) 在 Guard 中验证提交权重与链上记录一致",
114
+ };
115
+ }
116
+ }
117
+ return null;
118
+ },
119
+ },
120
+ {
121
+ id: "R-GT-01",
122
+ trigger: "分账 Guard 可能导致某些参与者被跳过",
123
+ check: (ctx) => {
124
+ if (ctx.scene?.binding_field === "order_allocators") {
125
+ return {
126
+ id: "R-GT-01",
127
+ level: "medium",
128
+ category: "game_theory",
129
+ title: "order_allocators first-match-wins 可能导致分账不公",
130
+ description: "order_allocators 采用 first-match-wins 策略:第一个 Guard 通过的 Allocator 执行分账。" +
131
+ "如果顺序设计不当,某些参与者可能永远无法获得分账。" +
132
+ "例如:如果第一个 Allocator 的 Guard 条件过宽,后续更精确的 Allocator 永远不会执行。",
133
+ affected_stakeholders: ["provider"],
134
+ scenario: "分账跳过:Provider 的分账 Allocator 被前面的宽泛条件跳过",
135
+ mitigation: "1) 确保 order_allocators 顺序从严格到宽松;" +
136
+ "2) 每个 Allocator 的 Guard 条件应互斥;" +
137
+ "3) 考虑使用逻辑_or 依赖而非顺序排列",
138
+ };
139
+ }
140
+ return null;
141
+ },
142
+ },
143
+ {
144
+ id: "R-GT-02",
145
+ trigger: "流程 Guard 时间锁可能锁定弱势方",
146
+ check: (ctx) => {
147
+ const rootStr = JSON.stringify(ctx.root);
148
+ if (rootStr.includes("Clock") && rootStr.includes("calc_number_add")) {
149
+ return {
150
+ id: "R-GT-02",
151
+ level: "medium",
152
+ category: "game_theory",
153
+ title: "时间锁可能锁定处于弱势的一方",
154
+ description: "Guard 使用时间锁(context(Clock) + calc_number_add)。时间锁本身是中性的," +
155
+ "但需检查锁定方向:如果锁定 Customer 先付款但不能及时验收,Provider 获得优势;" +
156
+ "如果锁定 Provider 先交付但不能及时收款,Customer 获得优势。",
157
+ affected_stakeholders: ["customer", "provider"],
158
+ scenario: "时间不对等:一方被时间锁定,另一方有行动自由",
159
+ mitigation: "1) 确保时间锁对称(双方都有时间约束);" +
160
+ "2) 时间锁到期后提供退出机制(如自动退款/自动完成);" +
161
+ "3) 在 Machine 中设计对应的超时 Forward 节点",
162
+ };
163
+ }
164
+ return null;
165
+ },
166
+ },
167
+ {
168
+ id: "R-GT-03",
169
+ trigger: "Arbitration usage_guard 可能阻止合法争议",
170
+ check: (ctx) => {
171
+ if (ctx.scene?.binding_field === "usage_guard") {
172
+ const rootStr = JSON.stringify(ctx.root);
173
+ const andCount = (rootStr.match(/"logic_and"/g) || []).length;
174
+ if (andCount >= 3) {
175
+ return {
176
+ id: "R-GT-03",
177
+ level: "high",
178
+ category: "game_theory",
179
+ title: "usage_guard 条件过多可能阻止合法争议",
180
+ description: `检测到 ${andCount} 个 logic_and 组合。过多 AND 条件使争议门槛过高,` +
181
+ "Customer 可能无法发起合法争议,Provider 获得不正当优势。",
182
+ affected_stakeholders: ["customer"],
183
+ scenario: "争议门槛过高:Customer 无法发起合法争议",
184
+ mitigation: "1) 重新评估每个 AND 条件的必要性;" +
185
+ "2) 考虑使用 logic_or 降低门槛;" +
186
+ "3) 将非必要条件移到 voting_guard 而非 usage_guard",
187
+ };
188
+ }
189
+ }
190
+ return null;
191
+ },
192
+ },
193
+ {
194
+ id: "R-LG-01",
195
+ trigger: "Guard root 为 identifier 直接返回 Bool",
196
+ check: (ctx) => {
197
+ if (ctx.root?.type === "identifier") {
198
+ return {
199
+ id: "R-LG-01",
200
+ level: "medium",
201
+ category: "logic_gap",
202
+ title: "Root 直接返回提交的 Bool 值,可被操纵",
203
+ description: "Guard root 是 identifier 节点,直接返回 table 中的 Bool 值。" +
204
+ "如果该条目 b_submission=true,调用者可以直接提交 true 绕过所有验证。",
205
+ affected_stakeholders: ["customer", "provider"],
206
+ scenario: "绕过验证:调用者提交 true 直接通过 Guard",
207
+ mitigation: "1) 确保 identifier 引用的条目 b_submission=false(常量);" +
208
+ "2) 或添加额外的 logic_and 条件进行交叉验证",
209
+ };
210
+ }
211
+ return null;
212
+ },
213
+ },
214
+ {
215
+ id: "R-LG-02",
216
+ trigger: "Guard 使用 logic_as_u256_greater 但未处理空值",
217
+ check: (ctx) => {
218
+ const rootStr = JSON.stringify(ctx.root);
219
+ if (rootStr.includes("logic_as_u256_greater") && rootStr.includes("query")) {
220
+ return {
221
+ id: "R-LG-02",
222
+ level: "medium",
223
+ category: "logic_gap",
224
+ title: "数值比较未处理查询返回空值的情况",
225
+ description: "Guard 使用 logic_as_u256_greater 进行数值比较,且操作数来自 query。" +
226
+ "如果 query 返回空值(如对象不存在、字段未设置),比较结果可能不确定。" +
227
+ "WoWok 协议中空值通常被视为 0,可能导致非预期通过。",
228
+ affected_stakeholders: ["customer", "provider"],
229
+ scenario: "空值误判:query 返回 0 导致 > 0 条件意外通过或失败",
230
+ mitigation: "1) 在比较前添加 query 结果存在性检查;" +
231
+ "2) 使用 query_reward_record_exists 或 query_progress_history_find 先验证;" +
232
+ "3) 考虑添加 logic_and(对象存在, 数值比较) 组合",
233
+ };
234
+ }
235
+ return null;
236
+ },
237
+ },
238
+ {
239
+ id: "R-LG-03",
240
+ trigger: "Guard 使用 logic_string_contains 可能被子串匹配绕过",
241
+ check: (ctx) => {
242
+ const rootStr = JSON.stringify(ctx.root);
243
+ if (rootStr.includes("logic_string_contains") && !rootStr.includes("logic_string_nocase")) {
244
+ return {
245
+ id: "R-LG-03",
246
+ level: "low",
247
+ category: "logic_gap",
248
+ title: "logic_string_contains 子串匹配可能被绕过",
249
+ description: "Guard 使用 logic_string_contains 进行字符串匹配。" +
250
+ "子串匹配可能被绕过:例如检查 'Completed' 时,'NotCompleted' 也包含 'Completed'。" +
251
+ "此外,大小写敏感可能导致非预期失败。",
252
+ affected_stakeholders: ["customer", "provider"],
253
+ scenario: "子串误匹配:'NotCompleted' 包含 'Completed' 导致误通过",
254
+ mitigation: "1) 优先使用 logic_equal 进行精确匹配;" +
255
+ "2) 如需子串匹配,添加边界条件(如前缀+后缀);" +
256
+ "3) 确认是否需要大小写不敏感(使用 nocase 变体)",
257
+ };
258
+ }
259
+ return null;
260
+ },
261
+ },
262
+ {
263
+ id: "R-LG-04",
264
+ trigger: "时间锁 query 返回 0 导致 logic_as_u256_greater_or_equal 比较永远为 true",
265
+ check: (ctx) => {
266
+ const rootStr = JSON.stringify(ctx.root);
267
+ const hasGreaterOrEqual = rootStr.includes("logic_as_u256_greater_or_equal");
268
+ const hasClock = rootStr.includes('"Clock"');
269
+ const hasCalcAdd = rootStr.includes("calc_number_add");
270
+ const hasQuery = rootStr.includes('"query"');
271
+ if (hasGreaterOrEqual && hasClock && hasCalcAdd && hasQuery) {
272
+ return {
273
+ id: "R-LG-04",
274
+ level: "medium",
275
+ category: "logic_gap",
276
+ title: "时间锁查询可能返回 0 导致 >= 比较永远为 true",
277
+ description: "Guard 使用 logic_as_u256_greater_or_equal 进行时间锁比较,且被比较的基准值来自 query。" +
278
+ "如果 query 返回 0(如查询尚未发生的操作时间戳、未设置的节点进入时间)," +
279
+ "则 Clock >= 0 + timeout 永远为 true,时间锁形同虚设,弱势方可以立即绕过时间约束。",
280
+ affected_stakeholders: ["customer", "provider"],
281
+ scenario: "时间锁失效:query 返回 0 使 >= 条件永远通过",
282
+ mitigation: "1) 使用返回当前节点进入时间的 query(如 progress.current_time, id=1272)" +
283
+ "而非操作时间戳(如 progress.session.forward.time, id=1271);" +
284
+ "2) 在时间锁前添加 query > 0 的前置检查;" +
285
+ "3) 确认 query 在 Guard 执行时必然有值(查询当前节点属性而非历史操作)",
286
+ };
287
+ }
288
+ return null;
289
+ },
290
+ },
291
+ {
292
+ id: "R-BR-01",
293
+ trigger: "Guard 绑定到已发布的 Machine/Service(不可变)",
294
+ check: (ctx) => {
295
+ if (ctx.scene && !ctx.scene.mutable_after_publish) {
296
+ return {
297
+ id: "R-BR-01",
298
+ level: "info",
299
+ category: "binding_risk",
300
+ title: `Guard 绑定到不可变的 ${ctx.scene.host_object}(发布后不可修改)`,
301
+ description: `${ctx.scene.host_object} 发布后 ${ctx.scene.binding_field} 不可修改。` +
302
+ "如果 Guard 设计有误,需要新建 Machine/Service 并迁移所有引用。" +
303
+ "这是设计约束而非风险,但需要确保 Guard 设计正确后再发布。",
304
+ affected_stakeholders: ["provider"],
305
+ scenario: "不可逆绑定:发布后发现 Guard 设计有误无法修改",
306
+ mitigation: "1) 发布前使用 gen_passport 进行充分测试;" +
307
+ "2) 测试 expected-pass 和 expected-fail 两种场景;" +
308
+ "3) 发布前导出 Guard 备份(guard2file)",
309
+ };
310
+ }
311
+ return null;
312
+ },
313
+ },
314
+ {
315
+ id: "R-BR-02",
316
+ trigger: "Repository write_guard 未验证 id_from_submission 类型",
317
+ check: (ctx) => {
318
+ if (ctx.scene?.binding_field === "write_guard") {
319
+ return {
320
+ id: "R-BR-02",
321
+ level: "high",
322
+ category: "binding_risk",
323
+ title: "Repository write_guard 需验证 id_from_submission 类型",
324
+ description: "Repository write_guard 的 id_from_submission 引用的 table 条目必须 Address 类型。" +
325
+ "data_from_submission 引用的条目必须匹配 Repository value_type。" +
326
+ "类型不匹配会导致写入失败或数据损坏。",
327
+ affected_stakeholders: ["provider"],
328
+ scenario: "类型不匹配:写入失败或数据损坏",
329
+ mitigation: "1) 确认 id_from_submission 引用的条目 value_type=Address;" +
330
+ "2) 确认 data_from_submission 引用的条目 value_type 匹配 Repository;" +
331
+ "3) 在 gen_passport 测试中覆盖写入场景",
332
+ };
333
+ }
334
+ return null;
335
+ },
336
+ },
337
+ {
338
+ id: "R-DR-01",
339
+ trigger: "Guard 使用 rely 但依赖的 Guard 可能失效",
340
+ check: (ctx) => {
341
+ if (ctx.rely && ctx.rely.guards.length > 0) {
342
+ const logic = ctx.rely.logic_or ? "OR" : "AND";
343
+ return {
344
+ id: "R-DR-01",
345
+ level: ctx.rely.logic_or ? "low" : "medium",
346
+ category: "dependency_risk",
347
+ title: `rely ${logic} 依赖 ${ctx.rely.guards.length} 个外部 Guard`,
348
+ description: `Guard 使用 rely ${logic} 依赖 ${ctx.rely.guards.length} 个外部 Guard。` +
349
+ (ctx.rely.logic_or
350
+ ? "OR 逻辑:任一依赖通过即可。如果某个依赖 Guard 设计宽松,可能成为绕过入口。"
351
+ : "AND 逻辑:所有依赖必须通过。如果某个依赖 Guard 失效或被删除,当前 Guard 将永远失败。"),
352
+ affected_stakeholders: ["customer", "provider"],
353
+ scenario: ctx.rely.logic_or
354
+ ? "依赖绕过:宽松的依赖 Guard 成为攻击入口"
355
+ : "依赖失效:依赖 Guard 被删除导致当前 Guard 永远失败",
356
+ mitigation: ctx.rely.logic_or
357
+ ? "1) 审查每个依赖 Guard 的严格程度;2) 确保所有依赖 Guard 至少与当前 Guard 同等严格"
358
+ : "1) 确认所有依赖 Guard 的 rep=true 且不可删除;2) 考虑是否真的需要 AND 依赖",
359
+ };
360
+ }
361
+ return null;
362
+ },
363
+ },
364
+ ];
365
+ export function assessGuardRisks(params) {
366
+ const ctx = {
367
+ table: params.table,
368
+ root: params.root,
369
+ rely: params.rely,
370
+ scene: params.scene,
371
+ operation_type: params.operation_type,
372
+ };
373
+ const risks = [];
374
+ for (const rule of RISK_RULES) {
375
+ try {
376
+ const risk = rule.check(ctx);
377
+ if (risk)
378
+ risks.push(risk);
379
+ }
380
+ catch {
381
+ }
382
+ }
383
+ const overall_risk = getOverallRiskLevel(risks);
384
+ const stakeholder_advice = generateStakeholderAdvice(risks, params.scene);
385
+ const needs_human_review = risks.some((r) => r.level === "critical") ||
386
+ risks.filter((r) => r.level === "high").length >= 2;
387
+ const guard_summary = generateGuardSummary(params);
388
+ return {
389
+ guard_summary,
390
+ scene: params.scene,
391
+ risks,
392
+ overall_risk,
393
+ stakeholder_advice,
394
+ needs_human_review,
395
+ };
396
+ }
397
+ function getOverallRiskLevel(risks) {
398
+ if (risks.some((r) => r.level === "critical"))
399
+ return "critical";
400
+ if (risks.some((r) => r.level === "high"))
401
+ return "high";
402
+ if (risks.some((r) => r.level === "medium"))
403
+ return "medium";
404
+ if (risks.some((r) => r.level === "low"))
405
+ return "low";
406
+ return "info";
407
+ }
408
+ function generateStakeholderAdvice(risks, scene) {
409
+ const advice = {};
410
+ for (const risk of risks) {
411
+ for (const stakeholder of risk.affected_stakeholders) {
412
+ if (!advice[stakeholder])
413
+ advice[stakeholder] = [];
414
+ advice[stakeholder].push(`[${risk.level.toUpperCase()}] ${risk.title}: ${risk.mitigation}`);
415
+ }
416
+ }
417
+ if (scene) {
418
+ switch (scene.binding_field) {
419
+ case "buy_guard":
420
+ if (!advice.customer)
421
+ advice.customer = [];
422
+ advice.customer.push("购买前确认 buy_guard 的验证逻辑,确保你的身份/凭证能通过验证");
423
+ break;
424
+ case "order_allocators":
425
+ if (!advice.provider)
426
+ advice.provider = [];
427
+ advice.provider.push("确认 order_allocators 顺序,确保你的分账 Allocator 不会被前面的条件跳过");
428
+ break;
429
+ case "voting_guard":
430
+ if (!advice.arbitrator)
431
+ advice.arbitrator = [];
432
+ advice.arbitrator.push("确认投票权重来源可信,建议从 EntityRegistrar 查询而非用户提交");
433
+ break;
434
+ case "Forward.guard":
435
+ if (!advice.customer)
436
+ advice.customer = [];
437
+ advice.customer.push("确认 Forward.guard 的条件,确保你能满足推进条件,避免资金被锁定");
438
+ break;
439
+ }
440
+ }
441
+ return advice;
442
+ }
443
+ function generateGuardSummary(params) {
444
+ const parts = [];
445
+ parts.push(`table 条目数: ${params.table.length}`);
446
+ const submissions = params.table.filter((e) => e.b_submission).length;
447
+ parts.push(`提交数据: ${submissions} 条`);
448
+ parts.push(`root 类型: ${params.root?.type ?? "unknown"}`);
449
+ if (params.rely) {
450
+ parts.push(`rely: ${params.rely.guards.length} 个依赖 (${params.rely.logic_or ? "OR" : "AND"})`);
451
+ }
452
+ return parts.join(", ");
453
+ }
454
+ export function assessGuardRisksForOperation(operation_type, data) {
455
+ if (operation_type !== "guard")
456
+ return null;
457
+ const table = data?.table ?? [];
458
+ const root = data?.root;
459
+ const rely = data?.rely;
460
+ let scene;
461
+ return assessGuardRisks({ table, root, rely, scene, operation_type });
462
+ }
463
+ export function getRiskSummary(assessment) {
464
+ return {
465
+ risk_count: assessment.risks.length,
466
+ critical_count: assessment.risks.filter((r) => r.level === "critical").length,
467
+ high_count: assessment.risks.filter((r) => r.level === "high").length,
468
+ needs_human_review: assessment.needs_human_review,
469
+ top_risks: assessment.risks
470
+ .filter((r) => r.level === "critical" || r.level === "high")
471
+ .slice(0, 3)
472
+ .map((r) => r.title),
473
+ };
474
+ }
@@ -0,0 +1,46 @@
1
+ export interface SemanticToSchemaRule {
2
+ id: string;
3
+ pattern_name: string;
4
+ semantic_intent: string;
5
+ match_keywords: string[];
6
+ schema_elements: {
7
+ root_type: string;
8
+ table_entries: Array<{
9
+ value_type: string;
10
+ b_submission: boolean;
11
+ purpose: string;
12
+ }>;
13
+ query_nodes?: Array<{
14
+ query_name: string;
15
+ object_type: string;
16
+ convert_witness?: number;
17
+ }>;
18
+ tree_structure: string;
19
+ };
20
+ constraints: string[];
21
+ example: Record<string, unknown>;
22
+ }
23
+ export declare const SEMANTIC_TO_SCHEMA_RULES: SemanticToSchemaRule[];
24
+ export interface SchemaToSemanticRule {
25
+ element_type: "node" | "table_entry" | "query" | "witness" | "rely";
26
+ type_name: string;
27
+ semantic: string;
28
+ return_type?: string;
29
+ child_constraints?: string;
30
+ discovery_tool?: string;
31
+ }
32
+ export declare const SCHEMA_TO_SEMANTIC_RULES: SchemaToSemanticRule[];
33
+ export interface GuardConstraintRule {
34
+ id: string;
35
+ name: string;
36
+ description: string;
37
+ category: "root" | "table" | "query" | "witness" | "rely" | "binding";
38
+ validation_logic: string;
39
+ failure_message: string;
40
+ pitfall_number?: number;
41
+ }
42
+ export declare const GUARD_CONSTRAINT_RULES: GuardConstraintRule[];
43
+ export declare function matchSemanticPattern(userIntent: string): SemanticToSchemaRule[];
44
+ export declare function explainNode(nodeType: string): SchemaToSemanticRule | undefined;
45
+ export declare function explainWitness(witnessType: number): SchemaToSemanticRule | undefined;
46
+ export declare function getConstraintsByCategory(category: GuardConstraintRule["category"]): GuardConstraintRule[];