@wowok/agent-mcp 2.4.1 → 2.5.0
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/dist/config/runtime.d.ts +4 -0
- package/dist/config/runtime.js +29 -5
- package/dist/harness/auto-escalation.d.ts +27 -0
- package/dist/harness/auto-escalation.js +68 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +29 -1621
- package/dist/knowledge/allocation-confirm.d.ts +115 -0
- package/dist/knowledge/allocation-confirm.js +534 -0
- package/dist/knowledge/allocation-context.d.ts +58 -0
- package/dist/knowledge/allocation-context.js +249 -0
- package/dist/knowledge/allocation-ledger.d.ts +67 -0
- package/dist/knowledge/allocation-ledger.js +463 -0
- package/dist/knowledge/allocation-puzzle.d.ts +135 -0
- package/dist/knowledge/allocation-puzzle.js +298 -0
- package/dist/knowledge/allocation-risk.d.ts +78 -0
- package/dist/knowledge/allocation-risk.js +568 -0
- package/dist/knowledge/allocation-templates.d.ts +38 -0
- package/dist/knowledge/allocation-templates.js +970 -0
- package/dist/knowledge/allocation-translation.d.ts +72 -0
- package/dist/knowledge/allocation-translation.js +585 -0
- package/dist/knowledge/arb-risk.d.ts +37 -0
- package/dist/knowledge/arb-risk.js +210 -0
- package/dist/knowledge/arbitration-confirm.d.ts +135 -0
- package/dist/knowledge/arbitration-confirm.js +559 -0
- package/dist/knowledge/arbitration-context.d.ts +81 -0
- package/dist/knowledge/arbitration-context.js +505 -0
- package/dist/knowledge/arbitration-ledger.d.ts +62 -0
- package/dist/knowledge/arbitration-ledger.js +521 -0
- package/dist/knowledge/arbitration-puzzle.d.ts +84 -0
- package/dist/knowledge/arbitration-puzzle.js +304 -0
- package/dist/knowledge/arbitration-risk.d.ts +112 -0
- package/dist/knowledge/arbitration-risk.js +433 -0
- package/dist/knowledge/arbitration-templates.d.ts +38 -0
- package/dist/knowledge/arbitration-templates.js +276 -0
- package/dist/knowledge/arbitration-translation.d.ts +91 -0
- package/dist/knowledge/arbitration-translation.js +487 -0
- package/dist/knowledge/bridge-risk.d.ts +36 -0
- package/dist/knowledge/bridge-risk.js +263 -0
- package/dist/knowledge/contact-risk.d.ts +32 -0
- package/dist/knowledge/contact-risk.js +200 -0
- package/dist/knowledge/demand-confirm.d.ts +32 -0
- package/dist/knowledge/demand-confirm.js +206 -0
- package/dist/knowledge/demand-risk.d.ts +30 -0
- package/dist/knowledge/demand-risk.js +240 -0
- package/dist/knowledge/demand-translation.d.ts +55 -0
- package/dist/knowledge/demand-translation.js +354 -0
- package/dist/knowledge/deployment-scanner.d.ts +63 -0
- package/dist/knowledge/deployment-scanner.js +762 -0
- package/dist/knowledge/examples-scanner-cli.d.ts +1 -0
- package/dist/knowledge/examples-scanner-cli.js +26 -0
- package/dist/knowledge/examples-scanner.d.ts +121 -0
- package/dist/knowledge/examples-scanner.js +825 -0
- package/dist/knowledge/flywheel-loop.d.ts +3 -0
- package/dist/knowledge/flywheel-loop.js +32 -3
- package/dist/knowledge/glossary.js +3 -1
- package/dist/knowledge/guard-confirm.d.ts +86 -0
- package/dist/knowledge/guard-confirm.js +406 -0
- package/dist/knowledge/guard-context.d.ts +56 -0
- package/dist/knowledge/guard-context.js +287 -0
- package/dist/knowledge/guard-design-patterns.d.ts +37 -0
- package/dist/knowledge/guard-design-patterns.js +257 -0
- package/dist/knowledge/guard-ledger.js +14 -0
- package/dist/knowledge/guard-lint.d.ts +1 -0
- package/dist/knowledge/guard-lint.js +83 -3
- package/dist/knowledge/guard-migration.d.ts +48 -0
- package/dist/knowledge/guard-migration.js +228 -0
- package/dist/knowledge/guard-puzzle.js +3 -2
- package/dist/knowledge/guard-risk.d.ts +3 -1
- package/dist/knowledge/guard-risk.js +832 -64
- package/dist/knowledge/guard-templates.d.ts +1 -0
- package/dist/knowledge/guard-templates.js +278 -2
- package/dist/knowledge/guard-translation.js +6 -5
- package/dist/knowledge/index.d.ts +342 -0
- package/dist/knowledge/index.js +344 -0
- package/dist/knowledge/machine-confirm.d.ts +102 -0
- package/dist/knowledge/machine-confirm.js +559 -0
- package/dist/knowledge/machine-context.d.ts +160 -0
- package/dist/knowledge/machine-context.js +812 -0
- package/dist/knowledge/machine-ledger.d.ts +41 -0
- package/dist/knowledge/machine-ledger.js +315 -0
- package/dist/knowledge/machine-puzzle.d.ts +206 -0
- package/dist/knowledge/machine-puzzle.js +494 -0
- package/dist/knowledge/machine-risk.d.ts +75 -0
- package/dist/knowledge/machine-risk.js +644 -0
- package/dist/knowledge/machine-templates.d.ts +92 -0
- package/dist/knowledge/machine-templates.js +1592 -0
- package/dist/knowledge/machine-topology.d.ts +57 -0
- package/dist/knowledge/machine-topology.js +234 -0
- package/dist/knowledge/machine-translation.d.ts +96 -0
- package/dist/knowledge/machine-translation.js +513 -0
- package/dist/knowledge/mcp-schema-audit-cli.d.ts +1 -0
- package/dist/knowledge/mcp-schema-audit-cli.js +45 -0
- package/dist/knowledge/mcp-schema-audit.d.ts +90 -0
- package/dist/knowledge/mcp-schema-audit.js +772 -0
- package/dist/knowledge/onchain-constants.d.ts +4 -0
- package/dist/knowledge/onchain-constants.js +35 -0
- package/dist/knowledge/order-confirm.d.ts +115 -0
- package/dist/knowledge/order-confirm.js +573 -0
- package/dist/knowledge/order-context.d.ts +66 -0
- package/dist/knowledge/order-context.js +390 -0
- package/dist/knowledge/order-ledger.d.ts +69 -0
- package/dist/knowledge/order-ledger.js +341 -0
- package/dist/knowledge/order-puzzle.d.ts +159 -0
- package/dist/knowledge/order-puzzle.js +255 -0
- package/dist/knowledge/order-risk.d.ts +66 -0
- package/dist/knowledge/order-risk.js +653 -0
- package/dist/knowledge/order-templates.d.ts +50 -0
- package/dist/knowledge/order-templates.js +368 -0
- package/dist/knowledge/order-translation.d.ts +78 -0
- package/dist/knowledge/order-translation.js +550 -0
- package/dist/knowledge/passport-confirm.d.ts +130 -0
- package/dist/knowledge/passport-confirm.js +531 -0
- package/dist/knowledge/passport-context.d.ts +59 -0
- package/dist/knowledge/passport-context.js +306 -0
- package/dist/knowledge/passport-ledger.d.ts +48 -0
- package/dist/knowledge/passport-ledger.js +282 -0
- package/dist/knowledge/passport-puzzle.d.ts +108 -0
- package/dist/knowledge/passport-puzzle.js +333 -0
- package/dist/knowledge/passport-risk.d.ts +70 -0
- package/dist/knowledge/passport-risk.js +450 -0
- package/dist/knowledge/passport-templates.d.ts +40 -0
- package/dist/knowledge/passport-templates.js +568 -0
- package/dist/knowledge/passport-translation.d.ts +68 -0
- package/dist/knowledge/passport-translation.js +516 -0
- package/dist/knowledge/payment-risk.d.ts +33 -0
- package/dist/knowledge/payment-risk.js +182 -0
- package/dist/knowledge/permission-confirm.d.ts +110 -0
- package/dist/knowledge/permission-confirm.js +426 -0
- package/dist/knowledge/permission-context.d.ts +58 -0
- package/dist/knowledge/permission-context.js +224 -0
- package/dist/knowledge/permission-ledger.d.ts +38 -0
- package/dist/knowledge/permission-ledger.js +403 -0
- package/dist/knowledge/permission-puzzle.d.ts +122 -0
- package/dist/knowledge/permission-puzzle.js +173 -0
- package/dist/knowledge/permission-risk.d.ts +76 -0
- package/dist/knowledge/permission-risk.js +411 -0
- package/dist/knowledge/permission-templates.d.ts +38 -0
- package/dist/knowledge/permission-templates.js +234 -0
- package/dist/knowledge/permission-translation.d.ts +57 -0
- package/dist/knowledge/permission-translation.js +350 -0
- package/dist/knowledge/personal-risk.d.ts +36 -0
- package/dist/knowledge/personal-risk.js +212 -0
- package/dist/knowledge/progress-confirm.d.ts +108 -0
- package/dist/knowledge/progress-confirm.js +456 -0
- package/dist/knowledge/progress-context.d.ts +123 -0
- package/dist/knowledge/progress-context.js +452 -0
- package/dist/knowledge/progress-ledger.d.ts +63 -0
- package/dist/knowledge/progress-ledger.js +327 -0
- package/dist/knowledge/progress-puzzle.d.ts +82 -0
- package/dist/knowledge/progress-puzzle.js +219 -0
- package/dist/knowledge/progress-risk.d.ts +74 -0
- package/dist/knowledge/progress-risk.js +461 -0
- package/dist/knowledge/progress-templates.d.ts +38 -0
- package/dist/knowledge/progress-templates.js +228 -0
- package/dist/knowledge/progress-translation.d.ts +52 -0
- package/dist/knowledge/progress-translation.js +401 -0
- package/dist/knowledge/proof-confirm.d.ts +31 -0
- package/dist/knowledge/proof-confirm.js +187 -0
- package/dist/knowledge/proof-risk.d.ts +33 -0
- package/dist/knowledge/proof-risk.js +207 -0
- package/dist/knowledge/proof-translation.d.ts +52 -0
- package/dist/knowledge/proof-translation.js +283 -0
- package/dist/knowledge/registrar-risk.d.ts +34 -0
- package/dist/knowledge/registrar-risk.js +217 -0
- package/dist/knowledge/repository-confirm.d.ts +36 -0
- package/dist/knowledge/repository-confirm.js +242 -0
- package/dist/knowledge/repository-risk.d.ts +40 -0
- package/dist/knowledge/repository-risk.js +312 -0
- package/dist/knowledge/repository-translation.d.ts +58 -0
- package/dist/knowledge/repository-translation.js +422 -0
- package/dist/knowledge/resource-risk.d.ts +32 -0
- package/dist/knowledge/resource-risk.js +157 -0
- package/dist/knowledge/reward-confirm.d.ts +113 -0
- package/dist/knowledge/reward-confirm.js +496 -0
- package/dist/knowledge/reward-context.d.ts +127 -0
- package/dist/knowledge/reward-context.js +504 -0
- package/dist/knowledge/reward-ledger.d.ts +96 -0
- package/dist/knowledge/reward-ledger.js +502 -0
- package/dist/knowledge/reward-puzzle.d.ts +97 -0
- package/dist/knowledge/reward-puzzle.js +288 -0
- package/dist/knowledge/reward-risk.d.ts +84 -0
- package/dist/knowledge/reward-risk.js +545 -0
- package/dist/knowledge/reward-translation.d.ts +58 -0
- package/dist/knowledge/reward-translation.js +501 -0
- package/dist/knowledge/safety-rules.js +11 -3
- package/dist/knowledge/scenario-modes.d.ts +53 -0
- package/dist/knowledge/scenario-modes.js +302 -0
- package/dist/knowledge/service-confirm.d.ts +152 -0
- package/dist/knowledge/service-confirm.js +699 -0
- package/dist/knowledge/service-context.d.ts +66 -0
- package/dist/knowledge/service-context.js +403 -0
- package/dist/knowledge/service-ledger.d.ts +71 -0
- package/dist/knowledge/service-ledger.js +609 -0
- package/dist/knowledge/service-puzzle.d.ts +158 -0
- package/dist/knowledge/service-puzzle.js +236 -0
- package/dist/knowledge/service-risk.d.ts +108 -0
- package/dist/knowledge/service-risk.js +615 -0
- package/dist/knowledge/service-templates.d.ts +39 -0
- package/dist/knowledge/service-templates.js +418 -0
- package/dist/knowledge/service-translation.d.ts +103 -0
- package/dist/knowledge/service-translation.js +622 -0
- package/dist/knowledge/tools-reference.d.ts +17 -0
- package/dist/knowledge/tools-reference.js +151 -0
- package/dist/knowledge/treasury-confirm.d.ts +133 -0
- package/dist/knowledge/treasury-confirm.js +512 -0
- package/dist/knowledge/treasury-context.d.ts +64 -0
- package/dist/knowledge/treasury-context.js +363 -0
- package/dist/knowledge/treasury-ledger.d.ts +42 -0
- package/dist/knowledge/treasury-ledger.js +300 -0
- package/dist/knowledge/treasury-puzzle.d.ts +163 -0
- package/dist/knowledge/treasury-puzzle.js +216 -0
- package/dist/knowledge/treasury-risk.d.ts +86 -0
- package/dist/knowledge/treasury-risk.js +440 -0
- package/dist/knowledge/treasury-templates.d.ts +38 -0
- package/dist/knowledge/treasury-templates.js +316 -0
- package/dist/knowledge/treasury-translation.d.ts +78 -0
- package/dist/knowledge/treasury-translation.js +498 -0
- package/dist/knowledge/util-risk.d.ts +30 -0
- package/dist/knowledge/util-risk.js +135 -0
- package/dist/project/business-puzzle.d.ts +47 -0
- package/dist/project/business-puzzle.js +372 -0
- package/dist/project/deployment-doc.d.ts +61 -0
- package/dist/project/deployment-doc.js +432 -0
- package/dist/project/graph.d.ts +1 -0
- package/dist/project/graph.js +27 -1
- package/dist/project/index.d.ts +1 -0
- package/dist/project/index.js +39 -2
- package/dist/project/namespace.d.ts +11 -1
- package/dist/project/namespace.js +27 -2
- package/dist/project/query.d.ts +2 -0
- package/dist/project/query.js +56 -15
- package/dist/project/risk-aggregator.d.ts +50 -0
- package/dist/project/risk-aggregator.js +280 -0
- package/dist/project/substep-trace.d.ts +130 -0
- package/dist/project/substep-trace.js +332 -0
- package/dist/rules.d.ts +12 -0
- package/dist/rules.js +9 -0
- package/dist/schema/call/allocation.d.ts +44 -44
- package/dist/schema/call/arbitration.d.ts +141 -141
- package/dist/schema/call/base.d.ts +386 -386
- package/dist/schema/call/base.js +6 -6
- package/dist/schema/call/bridge-handler.d.ts +5 -2
- package/dist/schema/call/bridge.d.ts +159 -159
- package/dist/schema/call/contact.d.ts +110 -110
- package/dist/schema/call/demand.d.ts +76 -76
- package/dist/schema/call/handler.d.ts +2 -3
- package/dist/schema/call/handler.js +1 -1
- package/dist/schema/call/machine.d.ts +96 -96
- package/dist/schema/call/order.d.ts +98 -110
- package/dist/schema/call/permission-handler.d.ts +5 -0
- package/dist/schema/call/permission-handler.js +54 -0
- package/dist/schema/call/permission.d.ts +108 -108
- package/dist/schema/call/personal.d.ts +14 -14
- package/dist/schema/call/progress.d.ts +57 -72
- package/dist/schema/call/progress.js +7 -4
- package/dist/schema/call/proof.d.ts +18 -18
- package/dist/schema/call/proof.js +12 -7
- package/dist/schema/call/repository.d.ts +154 -154
- package/dist/schema/call/reward.d.ts +55 -55
- package/dist/schema/call/semantic.js +1 -1
- package/dist/schema/call/service.d.ts +238 -238
- package/dist/schema/call/treasury.d.ts +93 -93
- package/dist/schema/config/index.d.ts +178 -5
- package/dist/schema/config/index.js +52 -1
- package/dist/schema/local/index.d.ts +3554 -836
- package/dist/schema/local/index.js +2 -1
- package/dist/schema/messenger/index.d.ts +162 -162
- package/dist/schema/operations.d.ts +1102 -1118
- package/dist/schema/operations.js +7 -1
- package/dist/schema/project/index.d.ts +1392 -6
- package/dist/schema/project/index.js +426 -2
- package/dist/schema/query/index.d.ts +818 -818
- package/dist/schema/query/index.js +15 -9
- package/dist/schema/schema-query/index.d.ts +23 -3
- package/dist/schema/schema-query/index.js +13 -2
- package/dist/schema/sync-layer4.d.ts +21 -0
- package/dist/schema/sync-layer4.js +261 -0
- package/dist/schema/trust/index.d.ts +26 -26
- package/dist/schema/utils/guard-query-utils.d.ts +7 -0
- package/dist/schema/utils/guard-query-utils.js +14 -1
- package/dist/schemas/account_operation.output.json +718 -0
- package/dist/schemas/bridge_operation.output.json +1 -1
- package/dist/schemas/config_operation.output.json +173 -0
- package/dist/schemas/index.json +9 -1
- package/dist/schemas/local_info_operation.output.json +718 -0
- package/dist/schemas/local_mark_operation.output.json +718 -0
- package/dist/schemas/messenger_operation.output.json +1 -1
- package/dist/schemas/onchain_events.output.json +1 -1
- package/dist/schemas/onchain_operations.output.json +5 -4
- package/dist/schemas/onchain_operations.schema.json +1813 -333
- package/dist/schemas/onchain_operations_allocation.schema.json +9 -11
- package/dist/schemas/onchain_operations_arbitration.schema.json +2 -1
- package/dist/schemas/onchain_operations_contact.schema.json +2 -1
- package/dist/schemas/onchain_operations_demand.schema.json +2 -1
- package/dist/schemas/onchain_operations_gen_passport.schema.json +878 -872
- package/dist/schemas/onchain_operations_gen_proof.schema.json +273 -0
- package/dist/schemas/onchain_operations_guard.schema.json +584 -70
- package/dist/schemas/onchain_operations_machine.schema.json +4 -6
- package/dist/schemas/onchain_operations_order.schema.json +13 -9
- package/dist/schemas/onchain_operations_payment.schema.json +2 -1
- package/dist/schemas/onchain_operations_permission.schema.json +2 -1
- package/dist/schemas/onchain_operations_personal.schema.json +2 -1
- package/dist/schemas/onchain_operations_progress.schema.json +14 -10
- package/dist/schemas/onchain_operations_proof.schema.json +699 -0
- package/dist/schemas/onchain_operations_repository.schema.json +2 -1
- package/dist/schemas/onchain_operations_reward.schema.json +2 -1
- package/dist/schemas/onchain_operations_service.schema.json +4 -6
- package/dist/schemas/onchain_operations_treasury.schema.json +2 -1
- package/dist/schemas/onchain_table_data.output.json +6 -12
- package/dist/schemas/onchain_table_data.schema.json +32 -1
- package/dist/schemas/project_operation.output.json +879 -0
- package/dist/schemas/project_operation.schema.json +473 -2
- package/dist/schemas/query_toolkit.output.json +14906 -6
- package/dist/schemas/schema_query.output.json +38 -1
- package/dist/telemetry/index.d.ts +1 -1
- package/dist/tools/handlers/bridge.d.ts +1 -0
- package/dist/tools/handlers/bridge.js +1 -0
- package/dist/tools/handlers/config.d.ts +2 -0
- package/dist/tools/handlers/config.js +74 -0
- package/dist/tools/handlers/file-export.d.ts +3 -0
- package/dist/tools/handlers/file-export.js +90 -0
- package/dist/tools/handlers/local.d.ts +3 -0
- package/dist/tools/handlers/local.js +38 -0
- package/dist/tools/handlers/messenger.d.ts +16 -0
- package/dist/tools/handlers/messenger.js +188 -0
- package/dist/tools/handlers/onchain.d.ts +2 -0
- package/dist/tools/handlers/onchain.js +248 -0
- package/dist/tools/handlers/project.d.ts +2 -0
- package/dist/tools/handlers/project.js +293 -0
- package/dist/tools/handlers/query.d.ts +5 -0
- package/dist/tools/handlers/query.js +256 -0
- package/dist/tools/handlers/schema-query.d.ts +2 -0
- package/dist/tools/handlers/schema-query.js +93 -0
- package/dist/tools/handlers/trust.d.ts +2 -0
- package/dist/tools/handlers/trust.js +194 -0
- package/dist/tools/handlers/wip.d.ts +2 -0
- package/dist/tools/handlers/wip.js +44 -0
- package/dist/tools/index.d.ts +13 -0
- package/dist/tools/index.js +526 -0
- package/dist/tools/rules-hook.d.ts +2 -0
- package/dist/tools/rules-hook.js +23 -0
- package/dist/tools/shared.d.ts +20 -0
- package/dist/tools/shared.js +130 -0
- package/dist/tools/types.d.ts +35 -0
- package/dist/tools/types.js +1 -0
- package/dist/tools/wrap.d.ts +14 -0
- package/dist/tools/wrap.js +267 -0
- package/package.json +20 -6
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
import { GUARD_SCENES, findScene, } from "./guard-ledger.js";
|
|
2
|
+
import { getTemplatesByScene, } from "./guard-templates.js";
|
|
3
|
+
import { matchSemanticPattern, } from "./guard-translation.js";
|
|
4
|
+
import { getAllRiskRules, assessGuardRisks, } from "./guard-risk.js";
|
|
5
|
+
import { initPuzzleFromIntent, checkPuzzleCompleteness, } from "./guard-puzzle.js";
|
|
6
|
+
import { GUARD_PUBLISH_CHECKLIST, GUARD_CONFIRMATION_QUESTIONS, } from "./guard-confirm.js";
|
|
7
|
+
import { MAX_TABLE_SIZE, MAX_DESCRIPTION_LENGTH, } from "@wowok/wowok";
|
|
8
|
+
import { MACHINE_SCENES, } from "./machine-ledger.js";
|
|
9
|
+
export const GUARD_CONTEXT_VERSION = "1.0.0";
|
|
10
|
+
export function buildGuardContext(input) {
|
|
11
|
+
const max_length = input.max_length ?? 4000;
|
|
12
|
+
let matched_scene;
|
|
13
|
+
if (input.intent) {
|
|
14
|
+
matched_scene = findSceneByIntentKeywords(input.intent);
|
|
15
|
+
}
|
|
16
|
+
else if (input.guard_json?.binding_scene_id) {
|
|
17
|
+
matched_scene = GUARD_SCENES.find(s => s.id === input.guard_json.binding_scene_id);
|
|
18
|
+
}
|
|
19
|
+
else if (input.target_host_object && input.target_binding_field) {
|
|
20
|
+
matched_scene = findScene(input.target_host_object, input.target_binding_field);
|
|
21
|
+
}
|
|
22
|
+
let matched_template;
|
|
23
|
+
if (matched_scene) {
|
|
24
|
+
const templates = getTemplatesByScene(matched_scene.id);
|
|
25
|
+
if (templates.length > 0)
|
|
26
|
+
matched_template = templates[0];
|
|
27
|
+
}
|
|
28
|
+
let matched_pattern;
|
|
29
|
+
if (input.intent) {
|
|
30
|
+
const patterns = matchSemanticPattern(input.intent);
|
|
31
|
+
if (patterns.length > 0)
|
|
32
|
+
matched_pattern = patterns[0];
|
|
33
|
+
}
|
|
34
|
+
let puzzle_state;
|
|
35
|
+
let puzzle_completeness;
|
|
36
|
+
if (input.mode === "initial_design" && input.intent) {
|
|
37
|
+
puzzle_state = initPuzzleFromIntent({ rule_sentence: input.intent });
|
|
38
|
+
puzzle_completeness = checkPuzzleCompleteness(puzzle_state);
|
|
39
|
+
}
|
|
40
|
+
else if (input.mode === "mid_design_review" && input.guard_json) {
|
|
41
|
+
puzzle_completeness = checkPuzzleCompleteness({});
|
|
42
|
+
}
|
|
43
|
+
const relevant_risks = filterRiskRules(input.mode, input.stakeholder, matched_scene);
|
|
44
|
+
let risk_assessment;
|
|
45
|
+
if (input.mode === "pre_publish" && input.guard_json) {
|
|
46
|
+
const guard_data = input.guard_json.root;
|
|
47
|
+
risk_assessment = assessGuardRisks({
|
|
48
|
+
table: guard_data?.table ?? [],
|
|
49
|
+
root: input.guard_json.root,
|
|
50
|
+
rely: guard_data?.rely,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
const relevant_checklist = filterChecklist(input.mode);
|
|
54
|
+
const relevant_questions = filterQuestions(input.mode);
|
|
55
|
+
const cross_object_refs = buildCrossObjectRefs(matched_scene);
|
|
56
|
+
const onchain_constraints = buildOnchainConstraints();
|
|
57
|
+
const rendering_hints = buildRenderingHints(input.mode, max_length);
|
|
58
|
+
return {
|
|
59
|
+
version: GUARD_CONTEXT_VERSION,
|
|
60
|
+
mode: input.mode,
|
|
61
|
+
stakeholder_perspective: input.stakeholder,
|
|
62
|
+
matched_scene,
|
|
63
|
+
matched_template,
|
|
64
|
+
matched_pattern,
|
|
65
|
+
puzzle_state,
|
|
66
|
+
puzzle_completeness,
|
|
67
|
+
relevant_risks,
|
|
68
|
+
risk_assessment,
|
|
69
|
+
relevant_checklist,
|
|
70
|
+
relevant_questions,
|
|
71
|
+
cross_object_refs,
|
|
72
|
+
onchain_constraints,
|
|
73
|
+
rendering_hints,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function filterRiskRules(mode, stakeholder, scene) {
|
|
77
|
+
let rules = getAllRiskRules();
|
|
78
|
+
if (scene) {
|
|
79
|
+
rules = rules.filter(r => !r.id.startsWith("R-X") || true);
|
|
80
|
+
}
|
|
81
|
+
if (stakeholder && stakeholder !== "system") {
|
|
82
|
+
}
|
|
83
|
+
if (mode === "initial_design") {
|
|
84
|
+
return rules.filter(r => r.id.startsWith("R-C1") ||
|
|
85
|
+
r.id.startsWith("R-C4"));
|
|
86
|
+
}
|
|
87
|
+
if (mode === "pre_publish") {
|
|
88
|
+
return rules;
|
|
89
|
+
}
|
|
90
|
+
if (mode === "stakeholder_review" && stakeholder) {
|
|
91
|
+
return rules;
|
|
92
|
+
}
|
|
93
|
+
return rules;
|
|
94
|
+
}
|
|
95
|
+
function filterChecklist(mode) {
|
|
96
|
+
if (mode === "initial_design") {
|
|
97
|
+
return GUARD_PUBLISH_CHECKLIST.filter(item => ["GC-01", "GC-05", "GC-12"].includes(item.id));
|
|
98
|
+
}
|
|
99
|
+
if (mode === "pre_publish") {
|
|
100
|
+
return GUARD_PUBLISH_CHECKLIST;
|
|
101
|
+
}
|
|
102
|
+
return GUARD_PUBLISH_CHECKLIST.filter(item => !item.id.startsWith("GC-0"));
|
|
103
|
+
}
|
|
104
|
+
function filterQuestions(mode) {
|
|
105
|
+
if (mode === "pre_publish") {
|
|
106
|
+
return GUARD_CONFIRMATION_QUESTIONS;
|
|
107
|
+
}
|
|
108
|
+
if (mode === "mid_design_review") {
|
|
109
|
+
return GUARD_CONFIRMATION_QUESTIONS.filter(q => q.id === "QG1" || q.id === "QG2");
|
|
110
|
+
}
|
|
111
|
+
return [];
|
|
112
|
+
}
|
|
113
|
+
function buildCrossObjectRefs(scene) {
|
|
114
|
+
const refs = [];
|
|
115
|
+
for (const machine_scene of MACHINE_SCENES) {
|
|
116
|
+
refs.push({
|
|
117
|
+
object: "Machine",
|
|
118
|
+
field: "Forward.guard",
|
|
119
|
+
scene_id: machine_scene.id,
|
|
120
|
+
description: `Machine scene "${machine_scene.id}" can reference Guards via Forward.guard`,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
if (scene && scene.host_object !== "Standalone") {
|
|
124
|
+
refs.push({
|
|
125
|
+
object: scene.host_object,
|
|
126
|
+
field: scene.binding_field,
|
|
127
|
+
scene_id: scene.id,
|
|
128
|
+
description: scene.validation_scene,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
return refs;
|
|
132
|
+
}
|
|
133
|
+
function buildOnchainConstraints() {
|
|
134
|
+
return [
|
|
135
|
+
{ name: "MAX_TABLE_SIZE", value: MAX_TABLE_SIZE, description: "Maximum entries in Guard table" },
|
|
136
|
+
{ name: "MAX_DESCRIPTION_LENGTH", value: MAX_DESCRIPTION_LENGTH, description: "Maximum description length" },
|
|
137
|
+
];
|
|
138
|
+
}
|
|
139
|
+
function buildRenderingHints(mode, max_length) {
|
|
140
|
+
switch (mode) {
|
|
141
|
+
case "initial_design":
|
|
142
|
+
return {
|
|
143
|
+
include_puzzle_template: true,
|
|
144
|
+
include_risk_details: false,
|
|
145
|
+
include_questions: false,
|
|
146
|
+
include_immutability_warning: true,
|
|
147
|
+
max_length,
|
|
148
|
+
};
|
|
149
|
+
case "mid_design_review":
|
|
150
|
+
return {
|
|
151
|
+
include_puzzle_template: false,
|
|
152
|
+
include_risk_details: true,
|
|
153
|
+
include_questions: false,
|
|
154
|
+
include_immutability_warning: true,
|
|
155
|
+
max_length,
|
|
156
|
+
};
|
|
157
|
+
case "pre_publish":
|
|
158
|
+
return {
|
|
159
|
+
include_puzzle_template: false,
|
|
160
|
+
include_risk_details: true,
|
|
161
|
+
include_questions: true,
|
|
162
|
+
include_immutability_warning: true,
|
|
163
|
+
max_length,
|
|
164
|
+
};
|
|
165
|
+
case "stakeholder_review":
|
|
166
|
+
return {
|
|
167
|
+
include_puzzle_template: false,
|
|
168
|
+
include_risk_details: true,
|
|
169
|
+
include_questions: false,
|
|
170
|
+
include_immutability_warning: false,
|
|
171
|
+
max_length,
|
|
172
|
+
};
|
|
173
|
+
default:
|
|
174
|
+
return {
|
|
175
|
+
include_puzzle_template: false,
|
|
176
|
+
include_risk_details: false,
|
|
177
|
+
include_questions: false,
|
|
178
|
+
include_immutability_warning: true,
|
|
179
|
+
max_length,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
function findSceneByIntentKeywords(intent) {
|
|
184
|
+
const lower = intent.toLowerCase();
|
|
185
|
+
for (const scene of GUARD_SCENES) {
|
|
186
|
+
if (scene.id.split("_").some(keyword => lower.includes(keyword))) {
|
|
187
|
+
return scene;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return undefined;
|
|
191
|
+
}
|
|
192
|
+
export function buildPromptFromGuardContext(bundle) {
|
|
193
|
+
const lines = [];
|
|
194
|
+
const h = bundle.rendering_hints;
|
|
195
|
+
lines.push("═══════════════════════════════════════════════════════════");
|
|
196
|
+
lines.push(` GUARD CONTEXT (mode: ${bundle.mode})`);
|
|
197
|
+
lines.push("═══════════════════════════════════════════════════════════");
|
|
198
|
+
if (bundle.matched_scene) {
|
|
199
|
+
lines.push("");
|
|
200
|
+
lines.push(`Matched Scene: ${bundle.matched_scene.name}`);
|
|
201
|
+
lines.push(` Host Object: ${bundle.matched_scene.host_object}`);
|
|
202
|
+
lines.push(` Binding Field: ${bundle.matched_scene.binding_field}`);
|
|
203
|
+
lines.push(` Validation: ${bundle.matched_scene.validation_scene}`);
|
|
204
|
+
}
|
|
205
|
+
if (bundle.matched_template) {
|
|
206
|
+
lines.push("");
|
|
207
|
+
lines.push(`Recommended Template: ${bundle.matched_template.name}`);
|
|
208
|
+
lines.push(` Patterns: ${bundle.matched_template.recommended_patterns.join(", ")}`);
|
|
209
|
+
}
|
|
210
|
+
if (bundle.matched_pattern) {
|
|
211
|
+
lines.push("");
|
|
212
|
+
lines.push(`Semantic Pattern: ${bundle.matched_pattern.id} — ${bundle.matched_pattern.pattern_name}`);
|
|
213
|
+
lines.push(` Intent: ${bundle.matched_pattern.semantic_intent}`);
|
|
214
|
+
}
|
|
215
|
+
if (h.include_puzzle_template && bundle.puzzle_state) {
|
|
216
|
+
lines.push("");
|
|
217
|
+
lines.push("─ Puzzle State ──────────────────────────────────────────");
|
|
218
|
+
const completeness = bundle.puzzle_completeness;
|
|
219
|
+
if (completeness) {
|
|
220
|
+
lines.push(`Complete: ${completeness.complete ? "YES" : "NO"}`);
|
|
221
|
+
if (completeness.missing.length > 0) {
|
|
222
|
+
lines.push(`Missing: ${completeness.missing.join(", ")}`);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
if (h.include_risk_details && bundle.relevant_risks.length > 0) {
|
|
227
|
+
lines.push("");
|
|
228
|
+
lines.push(`─ Relevant Risk Rules (${bundle.relevant_risks.length}) ──────────────────────`);
|
|
229
|
+
for (const r of bundle.relevant_risks.slice(0, 5)) {
|
|
230
|
+
lines.push(` ${r.id} — ${r.trigger}`);
|
|
231
|
+
}
|
|
232
|
+
if (bundle.relevant_risks.length > 5) {
|
|
233
|
+
lines.push(` ... and ${bundle.relevant_risks.length - 5} more`);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
if (bundle.risk_assessment) {
|
|
237
|
+
lines.push("");
|
|
238
|
+
lines.push("─ Risk Assessment ───────────────────────────────────────");
|
|
239
|
+
lines.push(`Overall: ${bundle.risk_assessment.overall_risk.toUpperCase()}`);
|
|
240
|
+
lines.push(`Detected: ${bundle.risk_assessment.risks?.length ?? 0} risks`);
|
|
241
|
+
}
|
|
242
|
+
if (h.include_questions && bundle.relevant_questions.length > 0) {
|
|
243
|
+
lines.push("");
|
|
244
|
+
lines.push("─ Confirmation Questions ────────────────────────────────");
|
|
245
|
+
for (const q of bundle.relevant_questions) {
|
|
246
|
+
lines.push(` ${q.id} (blocking=${q.blocking}): ${q.question}`);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
if (bundle.cross_object_refs.length > 0) {
|
|
250
|
+
lines.push("");
|
|
251
|
+
lines.push("─ Cross-Object References ───────────────────────────────");
|
|
252
|
+
for (const ref of bundle.cross_object_refs.slice(0, 3)) {
|
|
253
|
+
lines.push(` ${ref.object}.${ref.field} (${ref.scene_id})`);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
if (bundle.onchain_constraints.length > 0) {
|
|
257
|
+
lines.push("");
|
|
258
|
+
lines.push("─ On-Chain Constraints ──────────────────────────────────");
|
|
259
|
+
for (const c of bundle.onchain_constraints) {
|
|
260
|
+
lines.push(` ${c.name} = ${c.value} (${c.description})`);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
if (h.include_immutability_warning) {
|
|
264
|
+
lines.push("");
|
|
265
|
+
lines.push("⚠️ Guard is IMMUTABLE after creation — no update path exists.");
|
|
266
|
+
lines.push(" Review the validation rule twice before publishing.");
|
|
267
|
+
}
|
|
268
|
+
lines.push("");
|
|
269
|
+
lines.push("═══════════════════════════════════════════════════════════");
|
|
270
|
+
return lines.join("\n");
|
|
271
|
+
}
|
|
272
|
+
export function getGuardContextSummary(bundle) {
|
|
273
|
+
const parts = [];
|
|
274
|
+
parts.push(`Guard Context v${bundle.version}`);
|
|
275
|
+
parts.push(`Mode: ${bundle.mode}`);
|
|
276
|
+
if (bundle.matched_scene)
|
|
277
|
+
parts.push(`Scene: ${bundle.matched_scene.id}`);
|
|
278
|
+
if (bundle.matched_template)
|
|
279
|
+
parts.push(`Template: ${bundle.matched_template.id}`);
|
|
280
|
+
if (bundle.matched_pattern)
|
|
281
|
+
parts.push(`Pattern: ${bundle.matched_pattern.id}`);
|
|
282
|
+
parts.push(`Risks: ${bundle.relevant_risks.length} relevant`);
|
|
283
|
+
parts.push(`Checklist: ${bundle.relevant_checklist.length} items`);
|
|
284
|
+
parts.push(`Questions: ${bundle.relevant_questions.length}`);
|
|
285
|
+
parts.push(`Cross-refs: ${bundle.cross_object_refs.length}`);
|
|
286
|
+
return parts.join(" | ");
|
|
287
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { IndustryModeName } from "./scenario-modes.js";
|
|
2
|
+
export type GuardDataSourceClass = "OnChainConstant" | "WitnessDerived" | "SubmittedObject" | "SystemContext";
|
|
3
|
+
export type VerifierConstraintLevel = "level1_strict_single" | "level2_identity_set" | "level3_scene_combined" | "none";
|
|
4
|
+
export type GuardHostObject = "service_buy_guard" | "service_allocator_guard" | "machine_forward" | "progress_submission" | "reward_claim" | "repository_write" | "arbitration_usage" | "arbitration_voting" | "gen_passport";
|
|
5
|
+
export interface GuardDesignPattern {
|
|
6
|
+
id: string;
|
|
7
|
+
business_requirement: string;
|
|
8
|
+
data_source: GuardDataSourceClass;
|
|
9
|
+
host: GuardHostObject;
|
|
10
|
+
verifier_level: VerifierConstraintLevel;
|
|
11
|
+
logic_summary: string;
|
|
12
|
+
key_queries: string[];
|
|
13
|
+
witness_types?: string[];
|
|
14
|
+
mitigated_risks?: string[];
|
|
15
|
+
applicable_industries?: IndustryModeName[];
|
|
16
|
+
notes?: string[];
|
|
17
|
+
}
|
|
18
|
+
export declare const GUARD_DESIGN_PATTERNS: GuardDesignPattern[];
|
|
19
|
+
export interface VerifierLevelGuidance {
|
|
20
|
+
level: VerifierConstraintLevel;
|
|
21
|
+
pattern: string;
|
|
22
|
+
when_to_use: string;
|
|
23
|
+
risk_rules: string[];
|
|
24
|
+
recommendation: "avoid" | "use_with_justification" | "recommended" | "default";
|
|
25
|
+
}
|
|
26
|
+
export declare const VERIFIER_LEVEL_GUIDANCE: VerifierLevelGuidance[];
|
|
27
|
+
export declare function getGuardDesignPattern(id: string): GuardDesignPattern | undefined;
|
|
28
|
+
export declare function searchGuardDesignPatterns(query: string): GuardDesignPattern[];
|
|
29
|
+
export declare function getPatternsByHost(host: GuardHostObject): GuardDesignPattern[];
|
|
30
|
+
export declare function getPatternsByIndustry(industry: IndustryModeName): GuardDesignPattern[];
|
|
31
|
+
export declare function getPatternsByDataSourceClass(source: GuardDataSourceClass): GuardDesignPattern[];
|
|
32
|
+
export declare function getVerifierLevelGuidance(level: VerifierConstraintLevel): VerifierLevelGuidance | undefined;
|
|
33
|
+
export declare function suggestPatternForRequirement(requirement: string): {
|
|
34
|
+
best: GuardDesignPattern;
|
|
35
|
+
alternatives: GuardDesignPattern[];
|
|
36
|
+
};
|
|
37
|
+
export declare const GUARD_DESIGN_PATTERNS_VERSION = 1;
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
export const GUARD_DESIGN_PATTERNS = [
|
|
2
|
+
{
|
|
3
|
+
id: "pattern.identity_check_single",
|
|
4
|
+
business_requirement: "Only the author can purchase this service (strict single-identity)",
|
|
5
|
+
data_source: "SystemContext",
|
|
6
|
+
host: "service_buy_guard",
|
|
7
|
+
verifier_level: "level1_strict_single",
|
|
8
|
+
logic_summary: "logic_equal[context(Signer), identifier[N](fixed_address)]",
|
|
9
|
+
key_queries: [],
|
|
10
|
+
mitigated_risks: ["R-C4-04"],
|
|
11
|
+
notes: [
|
|
12
|
+
"Maximally secure but maximally inconvenient",
|
|
13
|
+
"If address is unavailable (key loss, rotation), Guard permanently blocks",
|
|
14
|
+
"Avoid unless role is permanently tied to one address",
|
|
15
|
+
],
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
id: "pattern.identity_check_allowlist",
|
|
19
|
+
business_requirement: "Customer must be in an allowlist to purchase",
|
|
20
|
+
data_source: "SystemContext",
|
|
21
|
+
host: "service_buy_guard",
|
|
22
|
+
verifier_level: "level2_identity_set",
|
|
23
|
+
logic_summary: "vec_contains_address[identifier[N](allowlist_vec), context(Signer)]",
|
|
24
|
+
key_queries: [],
|
|
25
|
+
mitigated_risks: ["R-C4-04"],
|
|
26
|
+
notes: ["Allowlist stored as Address vector in table constant"],
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
id: "pattern.identity_check_order_holder",
|
|
30
|
+
business_requirement: "Only order owner or agent can perform operation",
|
|
31
|
+
data_source: "OnChainConstant",
|
|
32
|
+
host: "machine_forward",
|
|
33
|
+
verifier_level: "level2_identity_set",
|
|
34
|
+
logic_summary: "logic_or[logic_equal[query(1562 order.owner), context(Signer)], query(1567 order.agent has, Signer)]",
|
|
35
|
+
key_queries: ["order.owner", "order.agent has"],
|
|
36
|
+
mitigated_risks: ["R-C4-04", "R-C3-06"],
|
|
37
|
+
notes: [
|
|
38
|
+
"1562 returns Address → wrap in logic_equal",
|
|
39
|
+
"1567 returns Bool → use directly as logic_or child",
|
|
40
|
+
"Recommended Level 2 alternative to Level 1 strict binding",
|
|
41
|
+
],
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
id: "pattern.identity_check_service_provider_dynamic",
|
|
45
|
+
business_requirement: "Verify caller is service's current permission owner (survives permission rotation)",
|
|
46
|
+
data_source: "SubmittedObject",
|
|
47
|
+
host: "machine_forward",
|
|
48
|
+
verifier_level: "level2_identity_set",
|
|
49
|
+
logic_summary: "logic_and[logic_equal[query(1488 service.permission), identifier[N](submitted_perm)], logic_or[logic_equal[query(1002 permission.owner), context(Signer)], query(1004 permission.admin has, Signer)]]",
|
|
50
|
+
key_queries: ["service.permission", "permission.owner", "permission.admin has"],
|
|
51
|
+
mitigated_risks: ["R-C4-04", "R-C3-05"],
|
|
52
|
+
notes: [
|
|
53
|
+
"Dynamic permission address (RECOMMENDED) — survives Service permission rotation",
|
|
54
|
+
"Caller submits permission address; Guard verifies match then checks identity",
|
|
55
|
+
"More complex than static but far more robust",
|
|
56
|
+
],
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
id: "pattern.time_lock_progress",
|
|
60
|
+
business_requirement: "Customer must wait N hours before completing (time-lock)",
|
|
61
|
+
data_source: "WitnessDerived",
|
|
62
|
+
host: "machine_forward",
|
|
63
|
+
verifier_level: "none",
|
|
64
|
+
logic_summary: "logic_as_u256_ge[context(Clock), calc_number_add[query(1272 progress.current_time, witness=OrderProgress), identifier[N](duration_ms)]]",
|
|
65
|
+
key_queries: ["progress.current_time"],
|
|
66
|
+
witness_types: ["OrderProgress"],
|
|
67
|
+
mitigated_risks: [],
|
|
68
|
+
notes: [
|
|
69
|
+
"Use convert_witness=100 (OrderProgress) to derive Progress from submitted Order ID",
|
|
70
|
+
"Duration in milliseconds — test with small values first",
|
|
71
|
+
],
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
id: "pattern.time_lock_absolute",
|
|
75
|
+
business_requirement: "Operation allowed only after a fixed timestamp",
|
|
76
|
+
data_source: "SystemContext",
|
|
77
|
+
host: "service_buy_guard",
|
|
78
|
+
verifier_level: "none",
|
|
79
|
+
logic_summary: "logic_as_u256_ge[context(Clock), identifier[N](release_timestamp)]",
|
|
80
|
+
key_queries: [],
|
|
81
|
+
mitigated_risks: [],
|
|
82
|
+
notes: ["Useful for pre-sale windows, embargo periods"],
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
id: "pattern.repository_data_check",
|
|
86
|
+
business_requirement: "External data must match expected value (e.g., weather, price feed)",
|
|
87
|
+
data_source: "OnChainConstant",
|
|
88
|
+
host: "machine_forward",
|
|
89
|
+
verifier_level: "none",
|
|
90
|
+
logic_summary: "logic_equal[query(1167 repository.data, policy, key), identifier[N](expected_value)]",
|
|
91
|
+
key_queries: ["repository.data"],
|
|
92
|
+
mitigated_risks: [],
|
|
93
|
+
notes: [
|
|
94
|
+
"Repository address declared as table constant",
|
|
95
|
+
"Timestamp keys may need convert_number_address",
|
|
96
|
+
"quote_guard = Some(addr) always fails in verify phase (impack_list empty) — use quote_guard = None",
|
|
97
|
+
],
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
id: "pattern.progress_state_check",
|
|
101
|
+
business_requirement: "Specific forward has been accomplished (customer confirms delivery)",
|
|
102
|
+
data_source: "WitnessDerived",
|
|
103
|
+
host: "reward_claim",
|
|
104
|
+
verifier_level: "none",
|
|
105
|
+
logic_summary: "logic_equal[query_progress_history_find(...).accomplished, identifier[N](true)]",
|
|
106
|
+
key_queries: ["progress.current", "progress.current_time"],
|
|
107
|
+
witness_types: ["OrderProgress"],
|
|
108
|
+
mitigated_risks: [],
|
|
109
|
+
notes: ["Chain query_progress_history_find → query_progress_history_session_forward_find"],
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
id: "pattern.reward_one_time_claim",
|
|
113
|
+
business_requirement: "User can only claim reward once (no prior claims)",
|
|
114
|
+
data_source: "OnChainConstant",
|
|
115
|
+
host: "reward_claim",
|
|
116
|
+
verifier_level: "none",
|
|
117
|
+
logic_summary: "logic_equal[query_reward_record_count(recipient=Signer), identifier[N](0)]",
|
|
118
|
+
key_queries: ["reward.record_count"],
|
|
119
|
+
mitigated_risks: [],
|
|
120
|
+
notes: ["Record count check prevents double-claim"],
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
id: "pattern.reward_multi_condition",
|
|
124
|
+
business_requirement: "Order payment > threshold AND reached 'complete' to claim reward",
|
|
125
|
+
data_source: "WitnessDerived",
|
|
126
|
+
host: "reward_claim",
|
|
127
|
+
verifier_level: "none",
|
|
128
|
+
logic_summary: "logic_and[logic_as_u256_gt[query(order.amount), threshold], logic_equal[query(progress.current), 'complete'], logic_equal[query(order.service), identifier[N](expected_service)]]",
|
|
129
|
+
key_queries: ["order.amount", "progress.current", "order.service"],
|
|
130
|
+
witness_types: ["OrderProgress"],
|
|
131
|
+
mitigated_risks: ["R-C3-05"],
|
|
132
|
+
notes: ["Multi-condition: amount + progress state + service match"],
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
id: "pattern.arbitration_voting_weight",
|
|
136
|
+
business_requirement: "Vote weight equals reputation score (dynamic weight from Passport)",
|
|
137
|
+
data_source: "SubmittedObject",
|
|
138
|
+
host: "arbitration_voting",
|
|
139
|
+
verifier_level: "none",
|
|
140
|
+
logic_summary: "GuardIdentifier extracts numeric value from Passport submission",
|
|
141
|
+
key_queries: [],
|
|
142
|
+
mitigated_risks: ["R-C3-02"],
|
|
143
|
+
notes: [
|
|
144
|
+
"Table needs numeric submission entry at referenced index",
|
|
145
|
+
"Weight must come from on-chain EntityRegistrar, not submission",
|
|
146
|
+
"BINDING_01: voting_guard GuardIdentifier must be numeric (U8-U256)",
|
|
147
|
+
],
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
id: "pattern.arbitration_membership_check",
|
|
151
|
+
business_requirement: "Only premium members can file disputes",
|
|
152
|
+
data_source: "OnChainConstant",
|
|
153
|
+
host: "arbitration_usage",
|
|
154
|
+
verifier_level: "none",
|
|
155
|
+
logic_summary: "logic_and[query(entity exists), logic_as_u256_ge[query(entity tier), identifier[N](premium_tier)]]",
|
|
156
|
+
key_queries: ["entity.registrar", "entity.linker"],
|
|
157
|
+
mitigated_risks: [],
|
|
158
|
+
notes: ["ENTITY_REGISTRAR_ADDRESS (0xaab) / ENTITY_LINKER_ADDRESS (0xaaa) must be in table"],
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
id: "pattern.scene_allocator_entity_recipient",
|
|
162
|
+
business_requirement: "Service allocator with sharing.who=Entity — no Signer binding needed",
|
|
163
|
+
data_source: "OnChainConstant",
|
|
164
|
+
host: "service_allocator_guard",
|
|
165
|
+
verifier_level: "level3_scene_combined",
|
|
166
|
+
logic_summary: "Scene verifies fund flow safety — Guard only validates allocation rules",
|
|
167
|
+
key_queries: ["service.permission", "order.amount"],
|
|
168
|
+
mitigated_risks: ["R-C3-06"],
|
|
169
|
+
notes: [
|
|
170
|
+
"Funds flow to fixed Treasury/address regardless of caller",
|
|
171
|
+
"sharing.who=Entity already guarantees recipient safety",
|
|
172
|
+
"No Signer binding required — R-C3-06 safe",
|
|
173
|
+
],
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
id: "pattern.scene_machine_forward_operator",
|
|
177
|
+
business_requirement: "Machine forward with permissionIndex/namedOperator already verifies operator",
|
|
178
|
+
data_source: "OnChainConstant",
|
|
179
|
+
host: "machine_forward",
|
|
180
|
+
verifier_level: "level3_scene_combined",
|
|
181
|
+
logic_summary: "Forward's permissionIndex/namedOperator verifies operator — Guard only validates submitted data",
|
|
182
|
+
key_queries: [],
|
|
183
|
+
mitigated_risks: [],
|
|
184
|
+
notes: [
|
|
185
|
+
"Scene verifies operator permission via permissionIndex/namedOperator",
|
|
186
|
+
"Signer binding only needed if submitted data must belong to operator",
|
|
187
|
+
"Evaluate scene before adding Signer binding",
|
|
188
|
+
],
|
|
189
|
+
},
|
|
190
|
+
];
|
|
191
|
+
export const VERIFIER_LEVEL_GUIDANCE = [
|
|
192
|
+
{
|
|
193
|
+
level: "level1_strict_single",
|
|
194
|
+
pattern: "logic_equal[context(Signer), identifier[N](fixed_address)]",
|
|
195
|
+
when_to_use: "Role permanently tied to one address AND designer accepts lock-in risk",
|
|
196
|
+
risk_rules: ["R-C4-04"],
|
|
197
|
+
recommendation: "avoid",
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
level: "level2_identity_set",
|
|
201
|
+
pattern: "logic_or of multiple identity checks",
|
|
202
|
+
when_to_use: "Role-based access — multiple authorized identities",
|
|
203
|
+
risk_rules: ["R-C4-04 (suppressed)"],
|
|
204
|
+
recommendation: "recommended",
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
level: "level3_scene_combined",
|
|
208
|
+
pattern: "Scene itself verifies identity — no Signer binding needed",
|
|
209
|
+
when_to_use: "Scene's host object already verifies operator (e.g., Machine forward, sharing.who=Entity)",
|
|
210
|
+
risk_rules: [],
|
|
211
|
+
recommendation: "default",
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
level: "none",
|
|
215
|
+
pattern: "No Signer binding required",
|
|
216
|
+
when_to_use: "Resource flow matters more than caller identity",
|
|
217
|
+
risk_rules: [],
|
|
218
|
+
recommendation: "default",
|
|
219
|
+
},
|
|
220
|
+
];
|
|
221
|
+
export function getGuardDesignPattern(id) {
|
|
222
|
+
return GUARD_DESIGN_PATTERNS.find((p) => p.id === id);
|
|
223
|
+
}
|
|
224
|
+
export function searchGuardDesignPatterns(query) {
|
|
225
|
+
const q = query.toLowerCase();
|
|
226
|
+
return GUARD_DESIGN_PATTERNS.filter((p) => {
|
|
227
|
+
if (p.business_requirement.toLowerCase().includes(q))
|
|
228
|
+
return true;
|
|
229
|
+
if (p.logic_summary.toLowerCase().includes(q))
|
|
230
|
+
return true;
|
|
231
|
+
if (p.key_queries.some((k) => k.toLowerCase().includes(q)))
|
|
232
|
+
return true;
|
|
233
|
+
return false;
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
export function getPatternsByHost(host) {
|
|
237
|
+
return GUARD_DESIGN_PATTERNS.filter((p) => p.host === host);
|
|
238
|
+
}
|
|
239
|
+
export function getPatternsByIndustry(industry) {
|
|
240
|
+
return GUARD_DESIGN_PATTERNS.filter((p) => p.applicable_industries?.includes(industry));
|
|
241
|
+
}
|
|
242
|
+
export function getPatternsByDataSourceClass(source) {
|
|
243
|
+
return GUARD_DESIGN_PATTERNS.filter((p) => p.data_source === source);
|
|
244
|
+
}
|
|
245
|
+
export function getVerifierLevelGuidance(level) {
|
|
246
|
+
return VERIFIER_LEVEL_GUIDANCE.find((g) => g.level === level);
|
|
247
|
+
}
|
|
248
|
+
export function suggestPatternForRequirement(requirement) {
|
|
249
|
+
const matches = searchGuardDesignPatterns(requirement);
|
|
250
|
+
if (matches.length === 0) {
|
|
251
|
+
const fallback = GUARD_DESIGN_PATTERNS[0];
|
|
252
|
+
return { best: fallback, alternatives: [] };
|
|
253
|
+
}
|
|
254
|
+
const [best, ...alternatives] = matches;
|
|
255
|
+
return { best, alternatives };
|
|
256
|
+
}
|
|
257
|
+
export const GUARD_DESIGN_PATTERNS_VERSION = 1;
|
|
@@ -13,6 +13,7 @@ export const GUARD_SCENES = [
|
|
|
13
13
|
"The name of b_submission=true entries must be a natural-language description (the contract the customer sees)",
|
|
14
14
|
"If the Guard references the Service itself, use the circular reference pattern (CREATE Service → CREATE Guard → MODIFY Service)",
|
|
15
15
|
"buy_guard can still be modified after Service is published (via MODIFY Service)",
|
|
16
|
+
"Reentrancy: LOW — Each purchase creates a fresh Order; no existing Order state is modified. Default: no reentrancy risk. IF business intent is 'limit one purchase per user' (limited-edition goods, whitelist single-buy), an anti-reentrancy check is REQUIRED but no direct GUARDQUERY primitive exists for per-user purchase history — use a Repository to record prior purchases and add `repository.data has` (query 1166) + `logic_not` to root, or revoke EntityRegistrar membership after first buy",
|
|
16
17
|
],
|
|
17
18
|
common_patterns: [
|
|
18
19
|
"Identity check: context(Signer) + logic_equal (single address) / vec_contains_address (whitelist)",
|
|
@@ -39,12 +40,18 @@ export const GUARD_SCENES = [
|
|
|
39
40
|
"Guard usually queries Order/Progress state to determine allocation conditions",
|
|
40
41
|
"Common queries: order.amount, progress.current_node, order.completed, etc.",
|
|
41
42
|
"GuardIdentifier can be used for dynamic amounts (extract u64 value from table as allocation ratio)",
|
|
43
|
+
"Guard+sharing coupling: Guard determines IF allocation happens; sharing.who determines WHERE funds go. If sharing.who=Signer, the caller receives funds — the Guard MUST bind Signer (context(Signer)==authorized) to prevent theft. PREFERRED: use sharing.who=Entity (Treasury or fixed address) so funds always go to the legitimate recipient regardless of caller.",
|
|
44
|
+
"allocators require unique guard addresses: no two allocators may reference the same Guard object (create separate Guard objects with identical root/table but different descriptions if needed).",
|
|
45
|
+
"First-match-wins: only the first allocator whose Guard passes executes; subsequent allocators are skipped. Multiple allocators represent alternative strategies, not a simultaneous split.",
|
|
46
|
+
"If sharing.who=Entity references a Treasury object, verify the Treasury's permission is consistent with the Service's permission (different permissions = different permission organizations = minor risk).",
|
|
47
|
+
"Reentrancy: LOW — Protocol-level protection: order::on_allocation (order.move L116-119) asserts `allocation` field is None (E_ALLOCATION_ALREADY_SPECIFIED), enforcing ONE Allocation object per Order, ever. After alloc() executes, typical Rate-mode allocators (sum=10000, validated at allocation.move L162-163) and any Surplus-mode allocator drain balance to 0 via balance::withdraw_all (L254), making a second alloc() fail at `assert!(balance >= threshold)` (L193). EDGE CASE: Amount-mode-only allocators (no Surplus, total < full balance) leave remainder; a second alloc() could extract more — mitigated by preferring Rate/Surplus modes. External deposit via receive() (L291) is possible but irrational (attacker funds the Allocation they attack). Optional anti-reentrancy primitive: `order.allocation some` (query 1568) + logic_not",
|
|
42
48
|
],
|
|
43
49
|
common_patterns: [
|
|
44
50
|
"Node state check: query(Progress.current_node) + logic_equal('Completed')",
|
|
45
51
|
"Amount threshold: query(Order.amount) + logic_as_u256_greater_or_equal(threshold)",
|
|
46
52
|
"Multi-condition combination: logic_and (node state + amount + time)",
|
|
47
53
|
"GuardIdentifier dynamic ratio: table[u64] extracts allocation ratio",
|
|
54
|
+
"Treasury+personal 2-allocator pattern: 2 Guard objects (identical root/table, different descriptions) + 2 allocators (sharing.who=Entity Treasury / Entity personal) — 2 alternative merchant collection approaches; first-match-wins means only the first executes.",
|
|
48
55
|
],
|
|
49
56
|
mutable_after_publish: false,
|
|
50
57
|
r_rounds_focus: ["R1", "R2", "R3", "R5", "R6", "R7"],
|
|
@@ -64,6 +71,7 @@ export const GUARD_SCENES = [
|
|
|
64
71
|
"retained_submission indices must correspond to the Guard table",
|
|
65
72
|
"Common queries: progress.current_node, progress.session_forward, order.service, etc.",
|
|
66
73
|
"Time lock: context(Clock) + calc_number_add(progress.entry_time, duration) tested with 1000ms",
|
|
74
|
+
"Reentrancy: ALLOWED — By design, Forward moves progress.current_node to next_node (progress.move L443), naturally invalidating the Guard at the old node. Re-submission at the SAME node (before forward completes) is intentional: users may fix prior submission data or accumulate session weight toward threshold. No anti-reentrancy primitive needed. Optional observability queries: `progress.session_forward` (1262), `progress.history` (1273), `query_progress_history_find` (1274)",
|
|
67
75
|
],
|
|
68
76
|
common_patterns: [
|
|
69
77
|
"Identity check: context(Signer) + logic_equal (only specific parties can advance)",
|
|
@@ -88,6 +96,7 @@ export const GUARD_SCENES = [
|
|
|
88
96
|
"Works in concert with Forward.guard: Forward.guard validates eligibility, submission guard validates data",
|
|
89
97
|
"retained_submission stores submission data in Progress session for audit",
|
|
90
98
|
"Common queries: progress.session_forward, progress.session_weight, etc.",
|
|
99
|
+
"Reentrancy: ALLOWED — Multiple submissions accumulate session weight toward threshold by design (progress.move session_accomplish_imp). Re-submission is the intended mechanism for reaching threshold; no anti-reentrancy primitive needed",
|
|
91
100
|
],
|
|
92
101
|
common_patterns: [
|
|
93
102
|
"Signature validation: identifier(signature_submission) + logic_equal(expected)",
|
|
@@ -110,6 +119,7 @@ export const GUARD_SCENES = [
|
|
|
110
119
|
"Common query_reward_record_count prevents duplicate claims (one-time claim)",
|
|
111
120
|
"Guard usually queries history records + time conditions + identity validation",
|
|
112
121
|
"If the Reward references a Service, use the circular reference pattern",
|
|
122
|
+
"Reentrancy: CRITICAL — Guard pass distributes reward funds to the Claimant AND creates a reward_record, but the Guard conditions (identity, time, node state) do NOT naturally invalidate after a claim. Without an explicit anti-reentrancy primitive, the same Claimant can repeatedly pass the Guard and DRAIN THE ENTIRE POOL. This is the most severe reentrancy scene. REQUIRED anti-reentrancy primitive (any one): `reward.record has` (query 1613, Bool) + `logic_not`; OR `reward.record count` (query 1612, U64) + `logic_equal(0)`; OR `reward.record.find_first` (query 1626, U64) + `logic_not`/`logic_equal(0)`. Reference template: MyShop_Advanced Guard 7 condition 4 — `logic_not(query_reward_record_exists(where.storeFromId=order_id))`",
|
|
113
123
|
],
|
|
114
124
|
common_patterns: [
|
|
115
125
|
"One-time claim: query_reward_record_count(recipient) + logic_equal(0)",
|
|
@@ -134,6 +144,7 @@ export const GUARD_SCENES = [
|
|
|
134
144
|
"The table entry referenced by data_from_submission must match the Repository's value_type",
|
|
135
145
|
"Type mismatch leads to write failure or data corruption",
|
|
136
146
|
"Commonly used for oracle data writes, third-party credential attestation, etc.",
|
|
147
|
+
"Reentrancy: LOW — Default writes are idempotent (same ID overwrites, different ID appends); no fund flow. IF business intent is 'one write per ID' (e.g. voting, immutable credential, single-attestation), an anti-reentrancy check is needed. Optional primitive: `repository.data has` (query 1166, Bool) + `logic_not`",
|
|
137
148
|
],
|
|
138
149
|
common_patterns: [
|
|
139
150
|
"Authorized writer: context(Signer) + vec_contains_address(authorized_writers)",
|
|
@@ -157,6 +168,7 @@ export const GUARD_SCENES = [
|
|
|
157
168
|
"The customer must first generate a Passport (gen_passport passes usage_guard)",
|
|
158
169
|
"Common queries: order.completed, order.service, entity.has, etc.",
|
|
159
170
|
"Guard validates customer identity + order status + dispute eligibility",
|
|
171
|
+
"Reentrancy: HIGH — Guard pass creates a new Arb case. Without anti-reentrancy, a customer can create multiple Arb cases for the SAME Order (up to MAX_DISPUTE_COUNT=10 per order.move L96), harassing the counterparty and inflating arbitration system load. Not direct fund loss, but severe system abuse. Note: order::dispute (order.move L93-99) deduplicates by Arb address but does NOT prevent multiple distinct Arbs for the same Order. REQUIRED anti-reentrancy primitive (any one): `order.dispute has` (query 1565, Bool, per-Arb check) + `logic_not`; OR `order.dispute count` (query 1564, U64) + `logic_equal(0)` (strict: block any prior dispute) or `logic_as_u256_less_or_equal(N)` (lenient: allow up to N disputes)",
|
|
160
172
|
],
|
|
161
173
|
common_patterns: [
|
|
162
174
|
"Order status validation: query(Order.status) + logic_equal('completed')",
|
|
@@ -182,6 +194,7 @@ export const GUARD_SCENES = [
|
|
|
182
194
|
"b_submission must be true (weight is submitted at runtime by the voter)",
|
|
183
195
|
"Multiple voting_guards can be configured, each corresponding to a different voter group",
|
|
184
196
|
"When Arbitration bPaused=true, voting is blocked",
|
|
197
|
+
"Reentrancy: CRITICAL — Guard pass counts the vote with the extracted weight. Without anti-reentrancy, the same voter can vote MULTIPLE times, multiplying their weight and skewing the arbitration result (which directly determines fund ownership via compensation). The voter's eligibility (identity, reputation) does NOT naturally invalidate after voting. REQUIRED anti-reentrancy primitive (any one): `arb.voted has` (query 1404, Bool, per-voter) + `logic_not`; OR `arb.voted.agree has` (query 1406, Bool, per-voter-per-proposition) + `logic_not`; OR `arb.voted.agree count` (query 1405, U64, per-voter) + `logic_equal(0)`. Note: `arb.voted_count` (1403) is total voter count (NOT per-voter) and does NOT serve as an anti-reentrancy primitive for individual voters",
|
|
185
198
|
],
|
|
186
199
|
common_patterns: [
|
|
187
200
|
"Reputation score weight: query(EntityRegistrar.records[reputation]) + GuardIdentifier(u64)",
|
|
@@ -208,6 +221,7 @@ export const GUARD_SCENES = [
|
|
|
208
221
|
"Guard can be created standalone (not bound to a specific Host Object)",
|
|
209
222
|
"Guard can be depended on by other Guards via rely (requires rep=true)",
|
|
210
223
|
"The Passport generated by gen_passport can be used as submission data for subsequent operations",
|
|
224
|
+
"Reentrancy: LOW — Each gen_passport call generates an independent Passport (one Passport per operation). Multiple Passports for the same user are usually valid (each serves a different subsequent operation). IF business intent is 'one active Passport per user', an anti-reentrancy check is needed but no direct GUARDQUERY primitive exists — use off-chain tracking or a Repository to record issued Passport IDs",
|
|
211
225
|
],
|
|
212
226
|
common_patterns: [
|
|
213
227
|
"Identity validation: context(Signer) + logic_equal (single address/whitelist)",
|