@wowok/agent-mcp 3.1.3 → 3.1.5
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/config-audit.spec.d.ts +1 -0
- package/dist/config/config-audit.spec.js +1 -0
- package/dist/config/exposure.d.ts +108 -0
- package/dist/config/exposure.js +1 -0
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.js +1 -1
- package/dist/config/judgment.d.ts +1228 -0
- package/dist/config/judgment.js +1 -0
- package/dist/config/judgment.spec.d.ts +1 -0
- package/dist/config/judgment.spec.js +1 -0
- package/dist/config/rule-engine.d.ts +299 -0
- package/dist/config/rule-engine.js +1 -0
- package/dist/config/rule-engine.spec.d.ts +1 -0
- package/dist/config/rule-engine.spec.js +1 -0
- package/dist/config/severity.d.ts +7 -0
- package/dist/config/severity.js +1 -0
- package/dist/customer/order-monitor.d.ts +3 -1
- package/dist/customer/order-monitor.js +1 -1
- package/dist/evaluation/acceptance.d.ts +1 -0
- package/dist/evaluation/acceptance.js +1 -1
- package/dist/evaluation/arbitration-game.js +1 -1
- package/dist/evaluation/builtins/demand-match.js +1 -1
- package/dist/evaluation/builtins/graph-service.js +1 -1
- package/dist/evaluation/builtins/graph-service.spec.js +1 -1
- package/dist/evaluation/engine.js +1 -1
- package/dist/evaluation/game-strategy.d.ts +2 -2
- package/dist/evaluation/game-strategy.js +1 -1
- package/dist/evaluation/match-operation.d.ts +2 -2
- package/dist/evaluation/match-operation.js +1 -1
- package/dist/evaluation/standards.d.ts +3 -25
- package/dist/evaluation/standards.js +1 -1
- package/dist/evaluation/types.d.ts +2 -1
- package/dist/experience/realtime-feedback.js +1 -1
- package/dist/extensions/business-modules.js +1 -1
- package/dist/extensions/custom-registry-file.js +1 -1
- package/dist/extensions/industry-audit.spec.d.ts +1 -0
- package/dist/extensions/industry-audit.spec.js +1 -0
- package/dist/extensions/industry-layers.d.ts +8 -0
- package/dist/extensions/industry-layers.js +1 -1
- package/dist/extensions/industry-pack.d.ts +2 -0
- package/dist/extensions/industry-pack.js +1 -1
- package/dist/extensions/mode-evaluator.js +1 -1
- package/dist/extensions/modes.js +1 -1
- package/dist/graph/onchain/analyze.d.ts +3 -1
- package/dist/graph/onchain/analyze.js +1 -1
- package/dist/graph/onchain/analyze.spec.js +1 -1
- package/dist/graph/onchain/edge-schema.d.ts +1 -0
- package/dist/graph/onchain/edge-schema.js +1 -1
- package/dist/graph/onchain/expand.js +1 -1
- package/dist/graph/onchain/exploration.d.ts +28 -0
- package/dist/graph/onchain/exploration.js +1 -0
- package/dist/graph/onchain/exploration.spec.d.ts +1 -0
- package/dist/graph/onchain/exploration.spec.js +1 -0
- package/dist/graph/onchain/exposure.d.ts +18 -0
- package/dist/graph/onchain/exposure.js +1 -0
- package/dist/graph/onchain/exposure.spec.d.ts +1 -0
- package/dist/graph/onchain/exposure.spec.js +1 -0
- package/dist/graph/onchain/graph-policy.spec.d.ts +1 -0
- package/dist/graph/onchain/graph-policy.spec.js +1 -0
- package/dist/graph/onchain/index.d.ts +6 -0
- package/dist/graph/onchain/index.js +1 -1
- package/dist/graph/onchain/interest.js +1 -1
- package/dist/graph/onchain/interest.spec.js +1 -1
- package/dist/graph/onchain/names.js +1 -1
- package/dist/graph/onchain/names.spec.js +1 -1
- package/dist/graph/onchain/policy.d.ts +8 -0
- package/dist/graph/onchain/policy.js +1 -0
- package/dist/graph/onchain/proposal-graph.js +1 -1
- package/dist/graph/onchain/proposal-graph.spec.js +1 -1
- package/dist/graph/onchain/synthesis.d.ts +20 -0
- package/dist/graph/onchain/synthesis.js +1 -0
- package/dist/graph/onchain/synthesis.spec.d.ts +1 -0
- package/dist/graph/onchain/synthesis.spec.js +1 -0
- package/dist/graph/onchain/types.d.ts +11 -1
- package/dist/keeper/keeper.spec.js +1 -1
- package/dist/knowledge/alloc-audit-policy.spec.d.ts +1 -0
- package/dist/knowledge/alloc-audit-policy.spec.js +1 -0
- package/dist/knowledge/allocation-ledger.js +1 -1
- package/dist/knowledge/allocation-puzzle.d.ts +1 -1
- package/dist/knowledge/allocation-puzzle.js +1 -1
- package/dist/knowledge/allocation-risk.d.ts +4 -1
- package/dist/knowledge/allocation-risk.js +1 -1
- package/dist/knowledge/allocation-templates.js +1 -1
- package/dist/knowledge/arb-risk.d.ts +6 -5
- package/dist/knowledge/arb-risk.js +1 -1
- package/dist/knowledge/arbitration-ledger.d.ts +4 -4
- package/dist/knowledge/arbitration-ledger.js +1 -1
- package/dist/knowledge/arbitration-puzzle.d.ts +1 -1
- package/dist/knowledge/arbitration-puzzle.js +1 -1
- package/dist/knowledge/arbitration-risk.d.ts +4 -1
- package/dist/knowledge/arbitration-risk.js +1 -1
- package/dist/knowledge/arbitration-templates.js +1 -1
- package/dist/knowledge/baselines/judgment-baselines.json +289 -0
- package/dist/knowledge/baselines/risk-baselines.spec.js +1 -1
- package/dist/knowledge/baselines/rules/alloc_audit.json +290 -0
- package/dist/knowledge/baselines/rules/allocation.json +492 -0
- package/dist/knowledge/baselines/rules/arb.json +155 -0
- package/dist/knowledge/baselines/rules/arbitration.json +366 -0
- package/dist/knowledge/baselines/rules/bridge.json +197 -0
- package/dist/knowledge/baselines/rules/contact.json +152 -0
- package/dist/knowledge/baselines/rules/demand.json +158 -0
- package/dist/knowledge/baselines/rules/graph.json +453 -0
- package/dist/knowledge/baselines/rules/guard.json +981 -0
- package/dist/knowledge/baselines/rules/machine.json +706 -0
- package/dist/knowledge/baselines/rules/order.json +549 -0
- package/dist/knowledge/baselines/rules/payment.json +205 -0
- package/dist/knowledge/baselines/rules/permission.json +330 -0
- package/dist/knowledge/baselines/rules/personal.json +139 -0
- package/dist/knowledge/baselines/rules/progress.json +346 -0
- package/dist/knowledge/baselines/rules/proof.json +158 -0
- package/dist/knowledge/baselines/rules/registrar.json +159 -0
- package/dist/knowledge/baselines/rules/repository.json +244 -0
- package/dist/knowledge/baselines/rules/resource.json +117 -0
- package/dist/knowledge/baselines/rules/reward.json +471 -0
- package/dist/knowledge/baselines/rules/service.json +595 -0
- package/dist/knowledge/baselines/rules/treasury.json +440 -0
- package/dist/knowledge/baselines/rules/util.json +101 -0
- package/dist/knowledge/bridge-risk.d.ts +6 -5
- package/dist/knowledge/bridge-risk.js +1 -1
- package/dist/knowledge/builtin-templates.d.ts +26 -0
- package/dist/knowledge/builtin-templates.js +1 -0
- package/dist/knowledge/contact-risk.d.ts +6 -5
- package/dist/knowledge/contact-risk.js +1 -1
- package/dist/knowledge/demand-risk.d.ts +6 -5
- package/dist/knowledge/demand-risk.js +1 -1
- package/dist/knowledge/event-semantics.js +1 -1
- package/dist/knowledge/facts-sync.spec.d.ts +1 -0
- package/dist/knowledge/facts-sync.spec.js +1 -0
- package/dist/knowledge/getting-started.js +1 -1
- package/dist/knowledge/guard-design-patterns.js +1 -1
- package/dist/knowledge/guard-field-cognition.d.ts +1 -1
- package/dist/knowledge/guard-field-cognition.js +1 -1
- package/dist/knowledge/guard-ledger.js +1 -1
- package/dist/knowledge/guard-risk.d.ts +4 -1
- package/dist/knowledge/guard-risk.js +1 -1
- package/dist/knowledge/guard-templates.js +1 -1
- package/dist/knowledge/guard-translation.js +1 -1
- package/dist/knowledge/index.d.ts +10 -2
- package/dist/knowledge/index.js +1 -1
- package/dist/knowledge/industry-registry.js +1 -1
- package/dist/knowledge/industry-strategy.js +1 -1
- package/dist/knowledge/jsonrpc-enum.js +1 -1
- package/dist/knowledge/machine-ledger.js +1 -1
- package/dist/knowledge/machine-risk.d.ts +4 -1
- package/dist/knowledge/machine-risk.js +1 -1
- package/dist/knowledge/machine-templates.js +1 -1
- package/dist/knowledge/machine-translation.js +1 -1
- package/dist/knowledge/migration-preflight.js +1 -1
- package/dist/knowledge/operation-dictionary.js +1 -1
- package/dist/knowledge/order-ledger.js +1 -1
- package/dist/knowledge/order-puzzle.d.ts +3 -3
- package/dist/knowledge/order-puzzle.js +1 -1
- package/dist/knowledge/order-risk.d.ts +6 -3
- package/dist/knowledge/order-risk.js +1 -1
- package/dist/knowledge/order-templates.js +1 -1
- package/dist/knowledge/passport-ledger.js +1 -1
- package/dist/knowledge/passport-templates.js +1 -1
- package/dist/knowledge/payment-risk.d.ts +8 -6
- package/dist/knowledge/payment-risk.js +1 -1
- package/dist/knowledge/payment-tracker.js +1 -1
- package/dist/knowledge/permission-ledger.js +1 -1
- package/dist/knowledge/permission-puzzle.d.ts +12 -12
- package/dist/knowledge/permission-puzzle.js +1 -1
- package/dist/knowledge/permission-risk.d.ts +4 -7
- package/dist/knowledge/permission-risk.js +1 -1
- package/dist/knowledge/permission-templates.js +1 -1
- package/dist/knowledge/personal-risk.d.ts +6 -5
- package/dist/knowledge/personal-risk.js +1 -1
- package/dist/knowledge/progress-ledger.js +1 -1
- package/dist/knowledge/progress-puzzle.d.ts +2 -2
- package/dist/knowledge/progress-puzzle.js +1 -1
- package/dist/knowledge/progress-risk.d.ts +4 -1
- package/dist/knowledge/progress-risk.js +1 -1
- package/dist/knowledge/progress-templates.js +1 -1
- package/dist/knowledge/proof-risk.d.ts +6 -5
- package/dist/knowledge/proof-risk.js +1 -1
- package/dist/knowledge/puzzle-projections.js +1 -1
- package/dist/knowledge/recipient-constraint.d.ts +20 -1
- package/dist/knowledge/recipient-constraint.js +1 -1
- package/dist/knowledge/registrar-risk.d.ts +6 -5
- package/dist/knowledge/registrar-risk.js +1 -1
- package/dist/knowledge/repository-risk.d.ts +7 -6
- package/dist/knowledge/repository-risk.js +1 -1
- package/dist/knowledge/resource-risk.d.ts +6 -5
- package/dist/knowledge/resource-risk.js +1 -1
- package/dist/knowledge/reward-ledger.d.ts +1 -1
- package/dist/knowledge/reward-ledger.js +1 -1
- package/dist/knowledge/reward-puzzle.d.ts +2 -2
- package/dist/knowledge/reward-puzzle.js +1 -1
- package/dist/knowledge/reward-risk.d.ts +4 -1
- package/dist/knowledge/reward-risk.js +1 -1
- package/dist/knowledge/rule-node-analyzers.spec.js +1 -1
- package/dist/knowledge/rule-outcome.js +1 -1
- package/dist/knowledge/scenario-modes.d.ts +2 -2
- package/dist/knowledge/scenario-modes.js +1 -1
- package/dist/knowledge/scenario-topology.js +1 -1
- package/dist/knowledge/service-allocator-audit-node.js +1 -1
- package/dist/knowledge/service-ledger.js +1 -1
- package/dist/knowledge/service-puzzle.d.ts +2 -2
- package/dist/knowledge/service-puzzle.js +1 -1
- package/dist/knowledge/service-risk-node.js +1 -1
- package/dist/knowledge/service-risk.d.ts +4 -1
- package/dist/knowledge/service-risk.js +1 -1
- package/dist/knowledge/service-templates.js +1 -1
- package/dist/knowledge/strategy-manuals.d.ts +1 -1
- package/dist/knowledge/strategy-manuals.js +1 -1
- package/dist/knowledge/template-loader.d.ts +84 -0
- package/dist/knowledge/template-loader.js +1 -0
- package/dist/knowledge/template-loader.spec.d.ts +1 -0
- package/dist/knowledge/template-loader.spec.js +1 -0
- package/dist/knowledge/template-registry.js +1 -1
- package/dist/knowledge/template-scanner.d.ts +17 -0
- package/dist/knowledge/template-scanner.js +1 -0
- package/dist/knowledge/template-scanner.spec.d.ts +1 -0
- package/dist/knowledge/template-scanner.spec.js +1 -0
- package/dist/knowledge/tools-reference.js +1 -1
- package/dist/knowledge/treasury-ledger.d.ts +1 -1
- package/dist/knowledge/treasury-ledger.js +1 -1
- package/dist/knowledge/treasury-puzzle.d.ts +3 -3
- package/dist/knowledge/treasury-puzzle.js +1 -1
- package/dist/knowledge/treasury-risk.d.ts +4 -1
- package/dist/knowledge/treasury-risk.js +1 -1
- package/dist/knowledge/treasury-templates.js +1 -1
- package/dist/knowledge/util-risk.d.ts +6 -5
- package/dist/knowledge/util-risk.js +1 -1
- package/dist/knowledge/workflow-guidance.d.ts +4 -0
- package/dist/knowledge/workflow-guidance.js +1 -1
- package/dist/knowledge/workspace-lists.js +1 -1
- package/dist/monitor/MonitorLoop.js +1 -1
- package/dist/participation/arbitrator-interest.js +1 -1
- package/dist/participation/radar-core.js +1 -1
- package/dist/persona/analyzer.js +1 -1
- package/dist/persona/index.js +1 -1
- package/dist/persona/model.js +1 -1
- package/dist/persona/persona-audit.spec.d.ts +1 -0
- package/dist/persona/persona-audit.spec.js +1 -0
- package/dist/persona/types.d.ts +2 -0
- package/dist/playbooks/service-build/business-puzzle.js +1 -1
- package/dist/playbooks/service-build/facet-money.d.ts +11 -0
- package/dist/playbooks/service-build/facet-money.js +1 -1
- package/dist/playbooks/service-build/machine-panorama.d.ts +17 -0
- package/dist/playbooks/service-build/machine-panorama.js +1 -1
- package/dist/playbooks/service-build/merchant-guide.d.ts +2 -2
- package/dist/playbooks/service-build/migration-planner.d.ts +43 -0
- package/dist/playbooks/service-build/migration-planner.js +1 -0
- package/dist/playbooks/service-build/object-panorama.d.ts +42 -1
- package/dist/playbooks/service-build/object-panorama.js +1 -1
- package/dist/playbooks/service-build/participation-radar.js +1 -1
- package/dist/playbooks/service-build/pipeline-actions.d.ts +1 -1
- package/dist/playbooks/service-build/reverse-mapping.d.ts +1 -0
- package/dist/playbooks/service-build/reverse-mapping.js +1 -1
- package/dist/playbooks/service-build/risk-aggregator.d.ts +2 -1
- package/dist/playbooks/service-build/risk-aggregator.js +1 -1
- package/dist/playbooks/service-build/semantic-graph.js +1 -1
- package/dist/playbooks/service-build/service-panorama.d.ts +53 -1
- package/dist/playbooks/service-build/service-panorama.js +1 -1
- package/dist/playbooks/service-build/topology-evaluation.spec.js +1 -1
- package/dist/playbooks/service-build/topology-query.js +1 -1
- package/dist/playbooks/service-build/workflow-design-assessment.d.ts +2 -2
- package/dist/playbooks/service-build/workflow-design-assessment.js +1 -1
- package/dist/relationship/registry.js +1 -1
- package/dist/review/machine.js +1 -1
- package/dist/review/order.js +1 -1
- package/dist/review/service.js +1 -1
- package/dist/review/types.d.ts +7 -0
- package/dist/safety/confirm-gate.js +1 -1
- package/dist/schema/benchmark-migration/index.d.ts +207 -0
- package/dist/schema/benchmark-migration/index.js +1 -0
- package/dist/schema/call/allocation.d.ts +1 -1
- package/dist/schema/call/allocation.js +1 -1
- package/dist/schema/call/arbitration.d.ts +1 -1
- package/dist/schema/call/arbitration.js +1 -1
- package/dist/schema/call/base.d.ts +5 -5
- package/dist/schema/call/base.js +1 -1
- package/dist/schema/call/contact.d.ts +1 -1
- package/dist/schema/call/demand.d.ts +1 -1
- package/dist/schema/call/guard.d.ts +3 -3
- package/dist/schema/call/machine.d.ts +5 -5
- package/dist/schema/call/order.d.ts +3 -3
- package/dist/schema/call/payment.js +1 -1
- package/dist/schema/call/permission-handler.d.ts +1 -1
- package/dist/schema/call/permission-handler.js +1 -1
- package/dist/schema/call/permission.d.ts +16 -16
- package/dist/schema/call/permission.js +1 -1
- package/dist/schema/call/personal.d.ts +8 -8
- package/dist/schema/call/personal.js +1 -1
- package/dist/schema/call/progress.d.ts +3 -3
- package/dist/schema/call/repository.d.ts +11 -11
- package/dist/schema/call/repository.js +1 -1
- package/dist/schema/call/reward.d.ts +1 -1
- package/dist/schema/call/semantic.js +1 -1
- package/dist/schema/call/service.d.ts +7 -7
- package/dist/schema/call/service.js +1 -1
- package/dist/schema/call/treasury.d.ts +1 -1
- package/dist/schema/common/index.d.ts +6 -6
- package/dist/schema/common/index.js +1 -1
- package/dist/schema/config/index.d.ts +50 -1
- package/dist/schema/config/index.js +1 -1
- package/dist/schema/evaluation/index.d.ts +27 -11
- package/dist/schema/evaluation/index.js +1 -1
- package/dist/schema/goal/index.d.ts +5 -5
- package/dist/schema/goal/planning.d.ts +15 -15
- package/dist/schema/goal/planning.js +1 -1
- package/dist/schema/index.d.ts +1 -0
- package/dist/schema/index.js +1 -1
- package/dist/schema/interaction/index.d.ts +1 -1
- package/dist/schema/local/index.js +1 -1
- package/dist/schema/messenger/index.d.ts +26 -26
- package/dist/schema/operations.d.ts +33 -33
- package/dist/schema/operations.js +1 -1
- package/dist/schema/persona/index.d.ts +4708 -0
- package/dist/schema/persona/index.js +1 -1
- package/dist/schema/query/bi.d.ts +232 -25
- package/dist/schema/query/bi.js +1 -1
- package/dist/schema/query/index.d.ts +35 -35
- package/dist/schema/query/index.js +1 -1
- package/dist/schema/schema-version.js +1 -1
- package/dist/schema/workflow/index.d.ts +1 -1
- package/dist/schema/workspace/index.d.ts +53 -0
- package/dist/schema/workspace/index.js +1 -1
- package/dist/schema-query-impl/index.d.ts +9 -0
- package/dist/schema-query-impl/index.js +1 -1
- package/dist/schemas/benchmark_migration_operation.output.json +793 -0
- package/dist/schemas/benchmark_migration_operation.schema.json +83 -0
- package/dist/schemas/bridge_operation.schema.json +5 -5
- package/dist/schemas/config_operation.output.json +252 -0
- package/dist/schemas/config_operation.schema.json +21 -1
- package/dist/schemas/evaluation_operation.output.json +22 -10
- package/dist/schemas/goal_operation.schema.json +8 -8
- package/dist/schemas/guard2file.schema.json +1 -1
- package/dist/schemas/index.json +7 -1
- package/dist/schemas/machineNode2file.schema.json +1 -1
- package/dist/schemas/messenger_operation.schema.json +24 -12
- package/dist/schemas/onchain_events.output.json +1 -1
- package/dist/schemas/onchain_operations.output.json +4 -2
- package/dist/schemas/onchain_operations.schema.json +189 -139
- package/dist/schemas/onchain_operations_allocation.schema.json +13 -11
- package/dist/schemas/onchain_operations_arbitration.schema.json +10 -8
- package/dist/schemas/onchain_operations_contact.schema.json +7 -5
- package/dist/schemas/onchain_operations_demand.schema.json +7 -5
- package/dist/schemas/onchain_operations_gen_passport.schema.json +5 -3
- package/dist/schemas/onchain_operations_gen_proof.schema.json +1 -1
- package/dist/schemas/onchain_operations_guard.schema.json +5 -3
- package/dist/schemas/onchain_operations_machine.schema.json +22 -18
- package/dist/schemas/onchain_operations_order.schema.json +11 -7
- package/dist/schemas/onchain_operations_payment.schema.json +3 -3
- package/dist/schemas/onchain_operations_permission.schema.json +19 -11
- package/dist/schemas/onchain_operations_personal.schema.json +16 -10
- package/dist/schemas/onchain_operations_progress.schema.json +11 -7
- package/dist/schemas/onchain_operations_proof.schema.json +5 -3
- package/dist/schemas/onchain_operations_repository.schema.json +12 -8
- package/dist/schemas/onchain_operations_reward.schema.json +11 -9
- package/dist/schemas/onchain_operations_service.schema.json +28 -22
- package/dist/schemas/onchain_operations_treasury.schema.json +11 -9
- package/dist/schemas/onchain_table_data.output.json +27 -17
- package/dist/schemas/persona_operation.output.json +15875 -1
- package/dist/schemas/persona_operation.schema.json +3056 -478
- package/dist/schemas/query_toolkit.output.json +343 -63
- package/dist/schemas/query_toolkit.schema.json +1 -1
- package/dist/schemas/workflow_operation.schema.json +4 -2
- package/dist/schemas/workspace_operation.output.json +181 -1
- package/dist/schemas/workspace_operation.schema.json +61 -2
- package/dist/strategy/scorecard.js +1 -1
- package/dist/tools/handlers/benchmark-migration.d.ts +2 -0
- package/dist/tools/handlers/benchmark-migration.js +1 -0
- package/dist/tools/handlers/config.js +1 -1
- package/dist/tools/handlers/industry-pack.js +1 -1
- package/dist/tools/handlers/onchain.js +1 -1
- package/dist/tools/handlers/query.js +1 -1
- package/dist/tools/handlers/schema-query.js +1 -1
- package/dist/tools/handlers/workspace.js +1 -1
- package/dist/tools/index.js +1 -1
- package/dist/tools/move-fn-index.gen.d.ts +3 -0
- package/dist/tools/move-fn-index.gen.js +1 -0
- package/dist/tools/registry/business.js +1 -1
- package/dist/tools/registry/config.js +1 -1
- package/dist/tools/registry/evaluation.js +1 -1
- package/dist/tools/registry/onchain.js +1 -1
- package/dist/tools/sanitize-output.d.ts +3 -0
- package/dist/tools/sanitize-output.js +1 -0
- package/dist/tools/sanitize-output.spec.d.ts +1 -0
- package/dist/tools/sanitize-output.spec.js +1 -0
- package/package.json +9 -4
- package/dist/knowledge/baselines/evaluation-baselines.json +0 -79
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
{
|
|
2
|
+
"comment": "Bridge rule pack (R-BRIDGE) — declarative form of the retired in-code Bridge risk rules. Facts are produced by the kernel extractor (bridge-risk.ts, bound to the bridge constants and the idempotency bound); rules only reference fact names. Levels/wording can be retuned per rule and rules can be disabled (enabled=false, trace left) via the judgment document — factory rules can never be deleted or invented here.",
|
|
3
|
+
"facts": {
|
|
4
|
+
"assumes_committee_infallible": "The caller assumes committee signatures cannot be forged (they are the single trust root for cross-chain message verification).",
|
|
5
|
+
"is_non_mainnet": "The caller is operating on a non-mainnet environment (the Bridge role is configured on mainnet only).",
|
|
6
|
+
"transfer_amount": "Transfer amount in base units, provided for limiter heuristics.",
|
|
7
|
+
"assumes_per_user_evm_account": "The caller assumes activeEvmAccount is per-user (it is a single global account, transparent to users).",
|
|
8
|
+
"uses_public_evm_rpc": "The caller uses a public EVM RPC endpoint (frequent HTTP 429 rate-limit risk).",
|
|
9
|
+
"is_paused": "The Bridge is currently paused (EmergencyOp) — cross-chain operations stall and in-flight assets cannot be claimed.",
|
|
10
|
+
"unsupported_token": "The token symbol the caller attempts to bridge (must be one of the supported tokens).",
|
|
11
|
+
"idempotency_key_length": "Length of the idempotency key the caller generates (on-chain bound: 1..128 chars).",
|
|
12
|
+
"expects_simple_error_codes": "The caller is debugging and expects a small error-code surface (the bridge defines 20 numeric abort codes).",
|
|
13
|
+
"versioned_upgrade_in_progress": "A Versioned schema upgrade of the Bridge package is in progress (inner-version migration risk).",
|
|
14
|
+
"constants_synced": "Whether the Bridge constants are synced to onchain-constants.ts.",
|
|
15
|
+
"idempotency_key_over_limit": "KERNEL — the submitted idempotency key length exceeds the live on-chain bound (max_idempotency_key_length).",
|
|
16
|
+
"supported_token_count": "KERNEL CONSTANT — number of tokens the bridge supports.",
|
|
17
|
+
"supported_tokens_display": "KERNEL CONSTANT — the supported token symbols, comma-space separated (display form).",
|
|
18
|
+
"supported_tokens_csv": "KERNEL CONSTANT — the supported token symbols, comma separated (compact form).",
|
|
19
|
+
"max_idempotency_key_length": "KERNEL CONSTANT — maximum idempotency key length accepted by the bridge (128).",
|
|
20
|
+
"error_code_count": "KERNEL CONSTANT — number of numeric abort codes the bridge defines (20).",
|
|
21
|
+
"bridge_message_version": "KERNEL CONSTANT — live BRIDGE_MESSAGE_VERSION from the published package.",
|
|
22
|
+
"bridge_current_version": "KERNEL CONSTANT — live BRIDGE_CURRENT_VERSION of the Versioned wrapper.",
|
|
23
|
+
"bridge_evm_address_length": "KERNEL CONSTANT — live BRIDGE_EVM_ADDRESS_LENGTH in bytes.",
|
|
24
|
+
"always_true": "Always true — marks the unconditional informational rule (the TransferLimiter reminder fires for every transfer scenario)."
|
|
25
|
+
},
|
|
26
|
+
"rules": [
|
|
27
|
+
{
|
|
28
|
+
"rule_id": "R-BRIDGE-01",
|
|
29
|
+
"dimension": "permission",
|
|
30
|
+
"trigger": "caller assumes committee signatures cannot be forged",
|
|
31
|
+
"cases": [
|
|
32
|
+
{
|
|
33
|
+
"when": { "field": "assumes_committee_infallible", "op": "eq", "value": true },
|
|
34
|
+
"level": "critical",
|
|
35
|
+
"title": "Cross-chain asset security — committee signature verification is the single trust root",
|
|
36
|
+
"description": "Bridge committee signatures are the only thing preventing forged cross-chain messages from minting tokens out of thin air. If a committee key is compromised, or if the verification logic has a bug, an attacker can claim arbitrary amounts of ETH/WETH/WBTC/USDC/USDT. The TransferLimiter caps single-transfer amounts but does not prevent repeated small attacks.",
|
|
37
|
+
"scenario": "Committee private key leaks; attacker forges an approved transfer and claims funds",
|
|
38
|
+
"mitigation": "Committee members MUST use HSM-backed multi-sig. Rotate keys on a schedule. Audit committee membership and signature verification logic on every release. Monitor limiter utilization for suspicious patterns. Have an EmergencyOp pause plan ready.",
|
|
39
|
+
"evidence": "assumes_committee_infallible=true (trust root is single-point)",
|
|
40
|
+
"stakeholders": ["user", "committee", "system"]
|
|
41
|
+
}
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"rule_id": "R-BRIDGE-02",
|
|
46
|
+
"dimension": "cross_object",
|
|
47
|
+
"trigger": "caller operates on a non-mainnet environment",
|
|
48
|
+
"cases": [
|
|
49
|
+
{
|
|
50
|
+
"when": { "field": "is_non_mainnet", "op": "eq", "value": true },
|
|
51
|
+
"level": "high",
|
|
52
|
+
"title": "Bridge is mainnet-only — testnet operations will fail",
|
|
53
|
+
"description": "The Bridge is only configured on mainnet. testnet nodes do not have the bridge role configured, so any cross-chain operation (cross_chain_wow_to_evm, cross_chain_evm_to_wow, claim_wow_to_evm, etc.) will abort. Developers who test on testnet will see EBridgeUnavailable (8) and may misdiagnose it as a code bug.",
|
|
54
|
+
"scenario": "Developer runs cross_chain_wow_to_evm on testnet; aborts with EBridgeUnavailable",
|
|
55
|
+
"mitigation": "MCP layer MUST validate mainnet environment before submitting Bridge ops. Document the mainnet-only restriction prominently. For testing, use mainnet small-amount transactions or fork tests.",
|
|
56
|
+
"evidence": "is_non_mainnet=true (Bridge unavailable)",
|
|
57
|
+
"stakeholders": ["user", "operator"]
|
|
58
|
+
}
|
|
59
|
+
]
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"rule_id": "R-BRIDGE-04",
|
|
63
|
+
"dimension": "permission",
|
|
64
|
+
"trigger": "caller assumes activeEvmAccount is per-user",
|
|
65
|
+
"cases": [
|
|
66
|
+
{
|
|
67
|
+
"when": { "field": "assumes_per_user_evm_account", "op": "eq", "value": true },
|
|
68
|
+
"level": "medium",
|
|
69
|
+
"title": "activeEvmAccount is a single global EVM account — key leak affects all assets",
|
|
70
|
+
"description": "Bridge uses a single global activeEvmAccount that is auto-generated and transparent to users. All cross-chain EVM-side operations flow through this one account. If its private key leaks, every supported token (ETH/WETH/WBTC/USDC/USDT) on every supported chain is at risk. There is no per-user EVM account isolation.",
|
|
71
|
+
"scenario": "activeEvmAccount private key leaks; attacker drains all bridged EVM assets",
|
|
72
|
+
"mitigation": "Store the activeEvmAccount key in an HSM. Rotate the key on a schedule and via Versioned upgrade. Monitor EVM-side balances for anomalous outflows. Have an EmergencyOp pause plan ready.",
|
|
73
|
+
"evidence": "assumes_per_user_evm_account=true (it is global)",
|
|
74
|
+
"stakeholders": ["user", "system"]
|
|
75
|
+
}
|
|
76
|
+
]
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"rule_id": "R-BRIDGE-05",
|
|
80
|
+
"dimension": "cross_object",
|
|
81
|
+
"trigger": "caller uses a public EVM RPC endpoint",
|
|
82
|
+
"cases": [
|
|
83
|
+
{
|
|
84
|
+
"when": { "field": "uses_public_evm_rpc", "op": "eq", "value": true },
|
|
85
|
+
"level": "medium",
|
|
86
|
+
"title": "Public EVM RPCs may rate-limit (HTTP 429) — cross-chain ops stall",
|
|
87
|
+
"description": "Bridge ops that query EVM state (query_active_evm_account, query_supported_evm_chains, query_transfer_status, etc.) depend on an EVM RPC. Public RPCs (e.g. Infura free tier, Alchemy free tier) frequently return HTTP 429 under load. A 429 mid-flow stalls the cross-chain operation and may confuse the user. manage_evm_rpc supports multi-RPC rotation, but it must be configured in advance.",
|
|
88
|
+
"scenario": "User queries transfer status; public RPC returns 429; UI shows generic error",
|
|
89
|
+
"mitigation": "Configure multiple EVM RPCs via manage_evm_rpc and enable failover. Use a paid RPC tier for production. Surface 429 as 'RPC busy, retry' rather than 'operation failed'.",
|
|
90
|
+
"evidence": "uses_public_evm_rpc=true (429 risk)",
|
|
91
|
+
"stakeholders": ["user", "operator"]
|
|
92
|
+
}
|
|
93
|
+
]
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"rule_id": "R-BRIDGE-06",
|
|
97
|
+
"dimension": "lifecycle",
|
|
98
|
+
"trigger": "the Bridge is currently paused",
|
|
99
|
+
"cases": [
|
|
100
|
+
{
|
|
101
|
+
"when": { "field": "is_paused", "op": "eq", "value": true },
|
|
102
|
+
"level": "medium",
|
|
103
|
+
"title": "EmergencyOp can pause the Bridge — assets lock during pause",
|
|
104
|
+
"description": "EmergencyOp can pause the entire Bridge. While paused, no cross-chain operations proceed — assets in flight cannot be claimed, new transfers cannot be initiated. The pause is intended for incident response, but a prolonged pause locks user funds for the duration.",
|
|
105
|
+
"scenario": "Bridge is paused for incident response; users cannot claim in-flight transfers",
|
|
106
|
+
"mitigation": "Document the pause scenario and the emergency plan. Provide a status page showing pause state. Set expectations on pause duration and recovery. Operators should practice un-pause drills.",
|
|
107
|
+
"evidence": "is_paused=true (assets locked)",
|
|
108
|
+
"stakeholders": ["user", "operator"]
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"rule_id": "R-BRIDGE-07",
|
|
114
|
+
"dimension": "structural",
|
|
115
|
+
"trigger": "caller attempts to bridge a token outside the supported list",
|
|
116
|
+
"cases": [
|
|
117
|
+
{
|
|
118
|
+
"when": { "field": "unsupported_token", "op": "truthy" },
|
|
119
|
+
"level": "low",
|
|
120
|
+
"title": "Only ${supported_token_count} tokens supported — unsupported tokens cannot bridge",
|
|
121
|
+
"description": "Bridge supports exactly ${supported_token_count} tokens: ${supported_tokens_display}. Any other token (e.g. DAI, LINK, custom tokens) cannot be bridged. Users holding unsupported tokens will see their transfer rejected with EUnexpectedTokenType (3).",
|
|
122
|
+
"scenario": "User attempts to bridge DAI; aborts with EUnexpectedTokenType",
|
|
123
|
+
"mitigation": "Document the supported token list prominently. UI should filter the token picker to supported tokens only. For unsupported tokens, recommend an alternative bridge.",
|
|
124
|
+
"evidence": "unsupported_token=${unsupported_token} (supported: ${supported_tokens_csv})",
|
|
125
|
+
"stakeholders": ["user"]
|
|
126
|
+
}
|
|
127
|
+
]
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"rule_id": "R-BRIDGE-08",
|
|
131
|
+
"dimension": "structural",
|
|
132
|
+
"trigger": "idempotency key length exceeds the on-chain bound (128)",
|
|
133
|
+
"cases": [
|
|
134
|
+
{
|
|
135
|
+
"when": { "field": "idempotency_key_over_limit", "op": "eq", "value": true },
|
|
136
|
+
"level": "medium",
|
|
137
|
+
"title": "Idempotency key max ${max_idempotency_key_length} chars — long keys truncate or reject",
|
|
138
|
+
"description": "BridgeIdempotencyKeySchema accepts strings of length 1-${max_idempotency_key_length}. Callers who generate idempotency keys from long sources (e.g. full JSON payloads, UUIDs with prefixes) may exceed the limit and see the operation rejected. The limit exists to keep on-chain storage bounded.",
|
|
139
|
+
"scenario": "Caller uses a 200-char idempotency key; operation rejected",
|
|
140
|
+
"mitigation": "Generate idempotency keys from a hash (e.g. keccak256 of the payload, hex-encoded = 66 chars) or a UUID (36 chars). Validate length client-side before submission.",
|
|
141
|
+
"evidence": "idempotency_key_length=${idempotency_key_length}, limit=${max_idempotency_key_length}",
|
|
142
|
+
"stakeholders": ["user"]
|
|
143
|
+
}
|
|
144
|
+
]
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"rule_id": "R-BRIDGE-09",
|
|
148
|
+
"dimension": "structural",
|
|
149
|
+
"trigger": "caller is debugging and expects a small error-code surface",
|
|
150
|
+
"cases": [
|
|
151
|
+
{
|
|
152
|
+
"when": { "field": "expects_simple_error_codes", "op": "eq", "value": true },
|
|
153
|
+
"level": "low",
|
|
154
|
+
"title": "${error_code_count} error codes — debugging requires a lookup table",
|
|
155
|
+
"description": "Bridge defines ${error_code_count} error codes (EUnexpectedMessageType=0 through ETokenValueIsZero=19). Debugging an abort requires mapping the numeric code back to its name and meaning. New contributors often misread codes because they are not enumerated in the abort message.",
|
|
156
|
+
"scenario": "Bridge aborts with code 15; developer does not know what ETokenAlreadyClaimedOrHitLimit means",
|
|
157
|
+
"mitigation": "Publish an error-code lookup table in the docs. SDK should decode abort codes into human-readable strings. MCP layer should surface the decoded name in error messages.",
|
|
158
|
+
"evidence": "expects_simple_error_codes=true (there are ${error_code_count})",
|
|
159
|
+
"stakeholders": ["user", "operator"]
|
|
160
|
+
}
|
|
161
|
+
]
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
"rule_id": "R-BRIDGE-10",
|
|
165
|
+
"dimension": "lifecycle",
|
|
166
|
+
"trigger": "a Versioned schema upgrade of the Bridge is in progress",
|
|
167
|
+
"cases": [
|
|
168
|
+
{
|
|
169
|
+
"when": { "field": "versioned_upgrade_in_progress", "op": "eq", "value": true },
|
|
170
|
+
"level": "medium",
|
|
171
|
+
"title": "Versioned upgrade (current=${bridge_current_version}) can brick the Bridge if botched",
|
|
172
|
+
"description": "Bridge uses Versioned to wrap BridgeInner, supporting schema upgrades. The current version is BRIDGE_CURRENT_VERSION=${bridge_current_version}. An upgrade that mishandles the inner version migration can permanently brick the Bridge — funds in flight would be locked, and recovery requires a new package version. The message_version (current=${bridge_message_version}) and EVM address length (${bridge_evm_address_length} bytes) are also versioned.",
|
|
173
|
+
"scenario": "Upgrade mishandles BridgeInner migration; Bridge becomes unusable",
|
|
174
|
+
"mitigation": "Test upgrades on a fork with full state replay. Keep a rollback package version ready. Stage upgrades with a pause window so users can complete in-flight ops. Audit message_version and EVM address length compatibility on every upgrade.",
|
|
175
|
+
"evidence": "versioned_upgrade_in_progress=true (current=${bridge_current_version})",
|
|
176
|
+
"stakeholders": ["user", "operator", "system"]
|
|
177
|
+
}
|
|
178
|
+
]
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
"rule_id": "R-BRIDGE-03",
|
|
182
|
+
"dimension": "structural",
|
|
183
|
+
"trigger": "any transfer scenario (unconditional informational limiter reminder)",
|
|
184
|
+
"cases": [
|
|
185
|
+
{
|
|
186
|
+
"when": { "field": "always_true", "op": "eq", "value": true },
|
|
187
|
+
"level": "high",
|
|
188
|
+
"title": "TransferLimiter caps single and cumulative transfer amounts — large transfers reject",
|
|
189
|
+
"description": "The TransferLimiter enforces both per-transfer and cumulative transfer caps per token type. A transfer that exceeds the cap aborts with ETokenAlreadyClaimedOrHitLimit (15) or similar. Users attempting large cross-chain moves will see their transactions rejected and may misdiagnose it as a bug.",
|
|
190
|
+
"scenario": "User attempts to bridge 1000 ETH; limiter rejects the transfer",
|
|
191
|
+
"mitigation": "Document the limiter semantics. Before submitting, query the current limiter utilization. For large amounts, split into batches across multiple transactions and/or time windows. Surface the remaining cap in the UI.",
|
|
192
|
+
"stakeholders": ["user"]
|
|
193
|
+
}
|
|
194
|
+
]
|
|
195
|
+
}
|
|
196
|
+
]
|
|
197
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
{
|
|
2
|
+
"comment": "Contact rule pack (R-CONTACT) — declarative form of the retired in-code Contact risk rules. Facts are produced by the kernel extractor (contact-risk.ts, bound to the on-chain IM roster limit); rules only reference fact names. Levels/wording can be retuned per rule and rules can be disabled (enabled=false, trace left) via the judgment document — factory rules can never be deleted or invented here. R-CONTACT-03 stays LAST in the array: it is the unconditional no-events reminder the retired check appended after every evaluation.",
|
|
3
|
+
"facts": {
|
|
4
|
+
"im_count": "Raw IM entry count for a single Contact, passed through for evidence text.",
|
|
5
|
+
"im_count_over_limit": "True when im_count is provided and meets or exceeds the chain IM roster limit.",
|
|
6
|
+
"change_status_no_permission": "The status self-update is invoked without a Permission check (any IM member may rewrite their status string).",
|
|
7
|
+
"location_empty": "The location field is the empty-string default (indistinguishable from 'unset').",
|
|
8
|
+
"im_add_description_uses_long_name": "The IM-entry description is validated with the LONG_NAME validator instead of DESCRIPTION (different length cap).",
|
|
9
|
+
"bound_to_permission_um": "The Contact is bound as a Permission's um (bidirectional dependency; deletion requires unbinding first).",
|
|
10
|
+
"my_status_from_non_member": "The status self-update is invoked by an address not in the ims list (silently ignored on-chain).",
|
|
11
|
+
"constants_synced": "True when the contact constants are in sync with the published chain constants (false = knowledge-layer regression).",
|
|
12
|
+
"always_true": "Unconditional marker fact — rules that fire for every evaluation reference it.",
|
|
13
|
+
"max_im_count": "KERNEL CONSTANT — maximum IM entries a single Contact may hold."
|
|
14
|
+
},
|
|
15
|
+
"rules": [
|
|
16
|
+
{
|
|
17
|
+
"rule_id": "R-CONTACT-01",
|
|
18
|
+
"dimension": "permission",
|
|
19
|
+
"trigger": "status self-update invoked without a Permission check",
|
|
20
|
+
"cases": [
|
|
21
|
+
{
|
|
22
|
+
"when": { "field": "change_status_no_permission", "op": "eq", "value": true },
|
|
23
|
+
"level": "medium",
|
|
24
|
+
"title": "IM member status self-update has no permission check — IM list pollution risk",
|
|
25
|
+
"description": "The status self-update lets any IM member rewrite their status string without Permission verification. If an attacker's address is added to the ims list (an operation gated by permission index 453), the attacker can freely pollute their status field (e.g. set status to 'fraud'). The risk is bounded by the permission gate on adding IM entries, but a misconfigured Permission could expose the IM list.",
|
|
26
|
+
"scenario": "Contact's IM list is misconfigured to allow public adds; attacker pollutes status",
|
|
27
|
+
"mitigation": "Restrict permission index 453 (CONTACT_IM) to trusted guardians. Audit the IM list periodically. Business layer may validate status strings against an allowlist.",
|
|
28
|
+
"evidence": "change_status_no_permission=true",
|
|
29
|
+
"stakeholders": ["creator", "im_member"]
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"rule_id": "R-CONTACT-02",
|
|
35
|
+
"dimension": "structural",
|
|
36
|
+
"trigger": "IM roster count meets or exceeds the chain limit",
|
|
37
|
+
"cases": [
|
|
38
|
+
{
|
|
39
|
+
"when": { "field": "im_count_over_limit", "op": "eq", "value": true },
|
|
40
|
+
"level": "low",
|
|
41
|
+
"title": "MAX_IM_COUNT=${max_im_count} is permissive — on-chain storage cost",
|
|
42
|
+
"description": "A single Contact may hold up to MAX_IM_COUNT=${max_im_count} IM entries. Aborting with E_IM_COUNT_EXCEEDED (1) only triggers at the boundary. 200 entries is relatively permissive for a social scenario; loading the full list on every read increases gas and storage cost.",
|
|
43
|
+
"scenario": "Caller adds 200 IM entries to a single Contact",
|
|
44
|
+
"mitigation": "Business layer should self-limit IM count well below 200. For high-volume contact lists, shard across multiple Contact objects and aggregate off-chain.",
|
|
45
|
+
"evidence": "im_count=${im_count}, limit=${max_im_count}",
|
|
46
|
+
"stakeholders": ["creator"]
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"rule_id": "R-CONTACT-04",
|
|
52
|
+
"dimension": "semantic",
|
|
53
|
+
"trigger": "location field left at the empty-string default",
|
|
54
|
+
"cases": [
|
|
55
|
+
{
|
|
56
|
+
"when": { "field": "location_empty", "op": "eq", "value": true },
|
|
57
|
+
"level": "low",
|
|
58
|
+
"title": "location defaults to empty string — may be misread as 'unset'",
|
|
59
|
+
"description": "A freshly created Contact has location=\"\" (empty String). The Move type does not distinguish 'unset' from 'empty', so consumers may misinterpret an empty location as 'globally applicable' or as 'missing data'.",
|
|
60
|
+
"scenario": "Consumer reads location=\"\" and treats the Contact as global when it was never set",
|
|
61
|
+
"mitigation": "Document that empty location means 'not specified'. If a default region is required, set location explicitly at creation time.",
|
|
62
|
+
"evidence": "location=\"\" (empty, default)",
|
|
63
|
+
"stakeholders": ["creator", "consumer"]
|
|
64
|
+
}
|
|
65
|
+
]
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"rule_id": "R-CONTACT-05",
|
|
69
|
+
"dimension": "lifecycle",
|
|
70
|
+
"trigger": "status self-update invoked by a non-IM-member",
|
|
71
|
+
"cases": [
|
|
72
|
+
{
|
|
73
|
+
"when": { "field": "my_status_from_non_member", "op": "eq", "value": true },
|
|
74
|
+
"level": "medium",
|
|
75
|
+
"title": "my_status silently fails for non-IM-members",
|
|
76
|
+
"description": "my_status only updates the caller's status entry if the caller is in the ims list. For a non-IM-member, the call silently succeeds without any state change — there is no abort and no event. Users get no feedback, making it impossible to distinguish 'status updated' from 'operation ignored'.",
|
|
77
|
+
"scenario": "Non-IM-member calls my_status expecting an error; operation is silently ignored",
|
|
78
|
+
"mitigation": "SDK layer should pre-validate IM membership before submitting my_status and return a clear error. UI should show 'not an IM member' instead of 'success'.",
|
|
79
|
+
"evidence": "my_status_from_non_member=true (will be silently ignored)",
|
|
80
|
+
"stakeholders": ["im_member"]
|
|
81
|
+
}
|
|
82
|
+
]
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"rule_id": "R-CONTACT-06",
|
|
86
|
+
"dimension": "semantic",
|
|
87
|
+
"trigger": "IM-entry description validated with LONG_NAME semantics",
|
|
88
|
+
"cases": [
|
|
89
|
+
{
|
|
90
|
+
"when": { "field": "im_add_description_uses_long_name", "op": "eq", "value": true },
|
|
91
|
+
"level": "low",
|
|
92
|
+
"title": "The IM-entry description uses LONG_NAME validation (not DESCRIPTION) — different length cap",
|
|
93
|
+
"description": "The description parameter for adding an IM entry is validated with common::LONG_NAME rather than common::DESCRIPTION. The two validators have different length limits; callers expecting DESCRIPTION semantics may submit overly long strings and hit an unexpected abort.",
|
|
94
|
+
"scenario": "Caller submits an IM-entry description sized for DESCRIPTION but hits LONG_NAME limit",
|
|
95
|
+
"mitigation": "Document that the IM-entry description uses LONG_NAME validation. SDK should expose the exact limit so callers size their strings correctly.",
|
|
96
|
+
"evidence": "IM entry description validated with LONG_NAME",
|
|
97
|
+
"stakeholders": ["creator"]
|
|
98
|
+
}
|
|
99
|
+
]
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"rule_id": "R-CONTACT-07",
|
|
103
|
+
"dimension": "cross_object",
|
|
104
|
+
"trigger": "Contact bound as a Permission's um",
|
|
105
|
+
"cases": [
|
|
106
|
+
{
|
|
107
|
+
"when": { "field": "bound_to_permission_um", "op": "eq", "value": true },
|
|
108
|
+
"level": "medium",
|
|
109
|
+
"title": "Binding a Contact as a Permission's um creates a bidirectional dependency",
|
|
110
|
+
"description": "When a Contact is bound as a Permission's um, a bidirectional dependency forms: Permission.um → Contact, and Contact.permission → Permission. Deleting the Contact without first clearing the um reference leaves a dangling pointer in Permission.um.",
|
|
111
|
+
"scenario": "Contact is deleted while still bound as Permission.um; Permission.um becomes dangling",
|
|
112
|
+
"mitigation": "Document the deletion order: (1) unbind Permission.um (set it to null) first, (2) then delete the Contact. SDK should refuse to delete a Contact that is still bound as a um.",
|
|
113
|
+
"evidence": "bound_to_permission_um=true (deletion requires unbinding)",
|
|
114
|
+
"stakeholders": ["creator", "consumer"]
|
|
115
|
+
}
|
|
116
|
+
]
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"rule_id": "R-CONTACT-08",
|
|
120
|
+
"dimension": "knowledge",
|
|
121
|
+
"trigger": "contact constants not synced to the knowledge constant table",
|
|
122
|
+
"cases": [
|
|
123
|
+
{
|
|
124
|
+
"when": { "field": "constants_synced", "op": "falsy" },
|
|
125
|
+
"level": "low",
|
|
126
|
+
"title": "Knowledge layer & constant sync — RESOLVED",
|
|
127
|
+
"description": "MAX_IM_COUNT is now synced to onchain-constants.ts (${max_im_count}). The MCP Knowledge layer now includes contact-risk.ts. This risk rule is retained for historical audit and to detect future regressions.",
|
|
128
|
+
"scenario": "Future regression: someone removes MAX_IM_COUNT from onchain-constants.ts",
|
|
129
|
+
"mitigation": "Run the onchain-constants sync test to detect drift.",
|
|
130
|
+
"evidence": "constants_synced=false",
|
|
131
|
+
"stakeholders": ["system"]
|
|
132
|
+
}
|
|
133
|
+
]
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"rule_id": "R-CONTACT-03",
|
|
137
|
+
"dimension": "semantic",
|
|
138
|
+
"trigger": "unconditional — fires for every evaluation (appended last by the retired check)",
|
|
139
|
+
"cases": [
|
|
140
|
+
{
|
|
141
|
+
"when": { "field": "always_true", "op": "eq", "value": true },
|
|
142
|
+
"level": "medium",
|
|
143
|
+
"title": "IM list mutations emit no events — external indexers must poll",
|
|
144
|
+
"description": "Adding, removing, or clearing IM entries emits no events. External indexers and notification systems cannot rely on event streams to track IM list changes; they must poll the ims field directly, increasing latency and RPC cost.",
|
|
145
|
+
"scenario": "Indexer expects an event when an IM entry is added but none is emitted; UI fails to refresh",
|
|
146
|
+
"mitigation": "External indexers should poll the Contact.ims field on a cadence. A future version may add IMEvent; until then, do not build critical UX on IM event streams.",
|
|
147
|
+
"stakeholders": ["creator", "consumer"]
|
|
148
|
+
}
|
|
149
|
+
]
|
|
150
|
+
}
|
|
151
|
+
]
|
|
152
|
+
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
{
|
|
2
|
+
"comment": "Demand rule pack (R-DEM) — declarative form of the retired in-code Demand risk rules. Facts are produced by the kernel extractor (demand-risk.ts, bound to the on-chain demand limits and the SDK feedback batch cap); rules only reference fact names. Levels/wording can be retuned per rule and rules can be disabled (enabled=false, trace left) via the judgment document — factory rules can never be deleted or invented here.",
|
|
3
|
+
"facts": {
|
|
4
|
+
"reward_count": "Number of reward addresses in Demand.rewards.",
|
|
5
|
+
"reward_count_over_limit": "reward_count exceeds MAX_REWARD_COUNT (chain-limit comparison sunk into the extractor).",
|
|
6
|
+
"guard_count": "Number of ServiceGuard entries in Demand.guards.",
|
|
7
|
+
"guard_count_over_limit": "guard_count exceeds MAX_GUARD_COUNT_DEMAND (chain-limit comparison sunk into the extractor).",
|
|
8
|
+
"feedback_count": "Number of feedback entries being submitted in a single SDK batch.",
|
|
9
|
+
"feedback_count_over_limit": "feedback_count exceeds the SDK MAX_FEEDBACK_COUNT batch cap (chain-limit comparison sunk into the extractor).",
|
|
10
|
+
"using_present_without_passport": "The caller is trying to call present (not the passport-guarded path).",
|
|
11
|
+
"guards_non_empty": "Demand.guards is non-empty.",
|
|
12
|
+
"constants_synced": "Whether the knowledge constants are synced (false keeps the four RESOLVED regression-watch rules audible).",
|
|
13
|
+
"max_reward_count": "KERNEL CONSTANT — rewards vector cap (MAX_REWARD_COUNT).",
|
|
14
|
+
"max_guard_count_demand": "KERNEL CONSTANT — guards vector cap (MAX_GUARD_COUNT_DEMAND).",
|
|
15
|
+
"max_feedback_count": "KERNEL CONSTANT — SDK feedback batch cap, 20 (SDK-only limit, not an on-chain constant)."
|
|
16
|
+
},
|
|
17
|
+
"rules": [
|
|
18
|
+
{
|
|
19
|
+
"rule_id": "R-DEM-01",
|
|
20
|
+
"dimension": "structural",
|
|
21
|
+
"trigger": "rewards vector exceeds MAX_REWARD_COUNT",
|
|
22
|
+
"cases": [
|
|
23
|
+
{
|
|
24
|
+
"when": { "field": "reward_count_over_limit", "op": "eq", "value": true },
|
|
25
|
+
"level": "high",
|
|
26
|
+
"title": "rewards count exceeds MAX_REWARD_COUNT (${max_reward_count})",
|
|
27
|
+
"description": "The 'rewards' vector is bounded by MAX_REWARD_COUNT=${max_reward_count}. Exceeding this limit aborts with E_MAX_REWARD_COUNT_EXCEEDED (1). Each reward is bound through an affiliation link, so adding a reward also re-affirms that link. Use reward removal/clearing to free slots before adding new ones if the limit is reached.",
|
|
28
|
+
"scenario": "Caller adds a reward when 20 rewards are already affiliated",
|
|
29
|
+
"mitigation": "Track the current reward count. Before adding a new reward, remove or clear existing rewards to free a slot. Consider consolidating rewards into a single Reward object with multiple tiers if the Demand needs to offer more than 20 distinct reward paths.",
|
|
30
|
+
"evidence": "reward_count=${reward_count}, limit=${max_reward_count}",
|
|
31
|
+
"stakeholders": ["creator"]
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"rule_id": "R-DEM-02",
|
|
37
|
+
"dimension": "structural",
|
|
38
|
+
"trigger": "guards vector exceeds MAX_GUARD_COUNT_DEMAND",
|
|
39
|
+
"cases": [
|
|
40
|
+
{
|
|
41
|
+
"when": { "field": "guard_count_over_limit", "op": "eq", "value": true },
|
|
42
|
+
"level": "high",
|
|
43
|
+
"title": "guards count exceeds MAX_GUARD_COUNT_DEMAND (${max_guard_count_demand})",
|
|
44
|
+
"description": "The 'guards' vector is bounded by MAX_GUARD_COUNT_DEMAND=${max_guard_count_demand}. Exceeding this limit aborts with E_MAX_GUARD_COUNT_EXCEEDED (2). Each guard carries an optional service_identifier (u8) that routes passport-guarded presentations to a specific Service submission extracted from the Passport. Adding a duplicate guard updates the service_identifier instead of pushing.",
|
|
45
|
+
"scenario": "Caller calls guard_add when 20 guards are already affiliated and the address is new",
|
|
46
|
+
"mitigation": "Track the current guard count. Before adding a new guard, remove or clear guards. If updating an existing guard's service_identifier, call guard_add with the same address (it updates in place rather than pushing).",
|
|
47
|
+
"evidence": "guard_count=${guard_count}, limit=${max_guard_count_demand}",
|
|
48
|
+
"stakeholders": ["creator", "presenter"]
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"rule_id": "R-DEM-03",
|
|
54
|
+
"dimension": "structural",
|
|
55
|
+
"trigger": "SDK feedback batch exceeds MAX_FEEDBACK_COUNT",
|
|
56
|
+
"cases": [
|
|
57
|
+
{
|
|
58
|
+
"when": { "field": "feedback_count_over_limit", "op": "eq", "value": true },
|
|
59
|
+
"level": "medium",
|
|
60
|
+
"title": "feedback batch exceeds MAX_FEEDBACK_COUNT (${max_feedback_count})",
|
|
61
|
+
"description": "The feedback call updates ONE presenter per call (the internal implementation iterates no vector). The SDK batches multiple feedback calls and caps the batch at MAX_FEEDBACK_COUNT=${max_feedback_count} (SDK-only limit, NOT in onchain-constants.ts — Move has no aggregate feedback-count check). Exceeding the SDK batch limit causes the SDK to refuse the call before transaction building. Each feedback entry writes a String (bounded by common::DESCRIPTION, 4000 chars) and an optional u8 acceptance_score to a presenter's ServiceInfo record.",
|
|
62
|
+
"scenario": "Caller attempts to submit 21 feedback entries in a single SDK call",
|
|
63
|
+
"mitigation": "Split the feedback batch into chunks of ≤ 20 entries. If the Demand has more than 20 presenters to give feedback on, submit multiple transactions. Consider whether bulk feedback is appropriate — individualized feedback per presenter is often more meaningful.",
|
|
64
|
+
"evidence": "feedback_count=${feedback_count}, limit=${max_feedback_count}",
|
|
65
|
+
"stakeholders": ["creator"]
|
|
66
|
+
}
|
|
67
|
+
]
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"rule_id": "R-DEM-04",
|
|
71
|
+
"dimension": "semantic",
|
|
72
|
+
"trigger": "plain present called on a Demand whose guards vector is non-empty",
|
|
73
|
+
"cases": [
|
|
74
|
+
{
|
|
75
|
+
"when": { "all": [
|
|
76
|
+
{ "field": "using_present_without_passport", "op": "eq", "value": true },
|
|
77
|
+
{ "field": "guards_non_empty", "op": "eq", "value": true }
|
|
78
|
+
] },
|
|
79
|
+
"level": "high",
|
|
80
|
+
"title": "present called without passport when guards vector is non-empty",
|
|
81
|
+
"description": "The Move present function asserts the guards vector is empty and aborts with E_NEED_PASSPORT (3) if the guards vector is non-empty. When guards exist, every presenter MUST go through the passport-guarded presentation path (or its service-specific variant), which routes through the guarded presentation implementation. That path looks up the specified Guard in the guards vector, runs the passport verification against it to verify the Passport, and (if service_identifier is set) extracts the submission address from the Passport. Calling plain `present` on a guarded Demand always aborts — there is no fallback path.",
|
|
82
|
+
"scenario": "Demand has 2 guards; a presenter calls present() instead of the passport-guarded presentation",
|
|
83
|
+
"mitigation": "Before presenting, query the Demand's guards vector. If non-empty, use the passport-guarded presentation and supply a Guard + Passport. The Guard address must already be in the guards vector (otherwise E_GUARD_NOT_FOUND (4) aborts). If service_identifier is set on the matching guard, the submission address is extracted from the Passport — do not pass a separate service parameter.",
|
|
84
|
+
"evidence": "guards_non_empty=true, using present (no passport)",
|
|
85
|
+
"stakeholders": ["presenter", "creator"]
|
|
86
|
+
}
|
|
87
|
+
]
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"rule_id": "R-DEM-05",
|
|
91
|
+
"dimension": "lifecycle",
|
|
92
|
+
"trigger": "regression watch — constants_synced false keeps the RESOLVED um-binding fix audible",
|
|
93
|
+
"cases": [
|
|
94
|
+
{
|
|
95
|
+
"when": { "field": "constants_synced", "op": "falsy" },
|
|
96
|
+
"level": "info",
|
|
97
|
+
"title": "um binding update object-linker dependency leak — RESOLVED (P-DEM-P1-1)",
|
|
98
|
+
"description": "PREVIOUS RISK: the um binding update previously set self.um to the new Contact address BEFORE disaffiliating the old um, causing the old Contact to retain a stale object-linker binding record in the object_linker. The affiliation-change routine was not called for the old um, leading to an object-linker dependency leak.\n\nFIX (P-DEM-P1-1): the um binding update now disaffiliates the old um through a disaffiliation transaction BEFORE setting the new one. The new um is then affiliated through an affiliation link. This matches the pattern used by the permission rebind path (which uses the affiliation-change routine). The um-clearing path also disaffiliates before clearing.\n\nThis rule is retained for historical audit and to detect regressions.",
|
|
99
|
+
"scenario": "Future regression: someone reorders the um binding update to set new before disaffiliating old",
|
|
100
|
+
"mitigation": "Keep the disaffiliate-then-set ordering. The Move invariant: any path that mutates self.um MUST run the disaffiliation on the old value before assigning a new one.",
|
|
101
|
+
"evidence": "constants_synced=false (regression check)",
|
|
102
|
+
"stakeholders": ["creator", "system"]
|
|
103
|
+
}
|
|
104
|
+
]
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"rule_id": "R-DEM-06",
|
|
108
|
+
"dimension": "semantic",
|
|
109
|
+
"trigger": "regression watch — constants_synced false keeps the RESOLVED guard-add type-check fix audible",
|
|
110
|
+
"cases": [
|
|
111
|
+
{
|
|
112
|
+
"when": { "field": "constants_synced", "op": "falsy" },
|
|
113
|
+
"level": "info",
|
|
114
|
+
"title": "guard-add service_identifier type check skipped on early return — RESOLVED (P-DEM-P1-2)",
|
|
115
|
+
"description": "PREVIOUS RISK: the guard-add path previously had the service_identifier type check AFTER the early-return path that updates an existing guard's service_identifier. When a guard with the same address already existed, the function returned before validating the new service_identifier against the guard's submission object-type check. This allowed setting an invalid service_identifier that would later fail at passport-guarded presentation time with E_INVALID_SERVICE_OBJECT_TYPE.\n\nFIX (P-DEM-P1-2): The service_identifier type check now runs FIRST, BEFORE the duplicate-detection loop. The service object-type assertion is called for any non-None service_identifier, ensuring both the insert and update paths validate the type.\n\nThis rule is retained for historical audit and to detect regressions.",
|
|
116
|
+
"scenario": "Future regression: someone moves the type check back to after the duplicate-detection loop",
|
|
117
|
+
"mitigation": "Keep the type check at the top of the guard-add path. The Move invariant: any service_identifier provided to guard_add MUST be validated via the submission object-type and service object-type checks BEFORE any mutation of the guards vector.",
|
|
118
|
+
"evidence": "constants_synced=false (regression check)",
|
|
119
|
+
"stakeholders": ["creator", "presenter"]
|
|
120
|
+
}
|
|
121
|
+
]
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"rule_id": "R-DEM-07",
|
|
125
|
+
"dimension": "knowledge",
|
|
126
|
+
"trigger": "regression watch — constants_synced false keeps the RESOLVED enrichment contract audible",
|
|
127
|
+
"cases": [
|
|
128
|
+
{
|
|
129
|
+
"when": { "field": "constants_synced", "op": "falsy" },
|
|
130
|
+
"level": "info",
|
|
131
|
+
"title": "Demand matching must not read non-existent Move fields — RESOLVED (P-DEM-P1-3)",
|
|
132
|
+
"description": "PREVIOUS RISK: the retired demand-matching.ts engine (matchDemand/extractDemandInfo) read fields (tags, maxPrice, scenario, minTrustScore, keywords) that do NOT exist on the Move Demand struct. The Move struct only has: description, location, rewards, guards, presenters, um, permission. This caused the matching engine to silently produce undefined values when fed raw on-chain query results.\n\nFIX (P-DEM-P1-3): the capability-vector engine (evaluation/builtins/demand-match.ts) enriches via evaluation/extract.ts (extractDemandCapability/extractServiceCapability). Only `location` maps directly to the Move Demand struct; all other signals (industry/tags/keywords/region/trust/price budget) are enriched from description NLP, the industry generalizer, or caller-injected overrides/data sources.\n\nThis rule is retained for historical audit and to detect regressions.",
|
|
133
|
+
"scenario": "Future regression: someone removes the enrichment contract docs from evaluation/extract.ts",
|
|
134
|
+
"mitigation": "Keep the enrichment contract in evaluation/extract.ts (non-chain-derivable fields are enriched there, not read as on-chain fact). The matching engine must never query on-chain data directly — it scores over already-enriched capability vectors.",
|
|
135
|
+
"evidence": "constants_synced=false (regression check)",
|
|
136
|
+
"stakeholders": ["system"]
|
|
137
|
+
}
|
|
138
|
+
]
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"rule_id": "R-DEM-08",
|
|
142
|
+
"dimension": "knowledge",
|
|
143
|
+
"trigger": "regression watch — constants_synced false keeps the RESOLVED rebinding exposure audible",
|
|
144
|
+
"cases": [
|
|
145
|
+
{
|
|
146
|
+
"when": { "field": "constants_synced", "op": "falsy" },
|
|
147
|
+
"level": "info",
|
|
148
|
+
"title": "direct Permission rebinding not exposed in SDK — RESOLVED (DE-D-2=A)",
|
|
149
|
+
"description": "PREVIOUS GAP: The Move permission-rebinding function was not exposed as a standalone function in the SDK's call/demand.ts. Callers could not change the Permission object bound to a Demand after creation.\n\nRESOLUTION (DE-D-2=A): the rebinding is now exposed via the CallPermission.apply mechanism. The SDK wraps it by routing through CallPermission, which performs the owner assert on the old Permission and updates the Demand's bound permission. The object-linker affiliation-change routine is called to migrate the binding from the old Permission to the new one.\n\nPermission indices for Demand: 400=DEMAND_NEW, 401=DEMAND_DESCRIPTION, 402=DEMAND_LOCATION, 404=DEMAND_GUARD, 405=DEMAND_REWARD, 406=DEMAND_FEEDBACK, 407=DEMAND_OWNER_RECEIVE, 408=DEMAND_UM.\n\nThis rule is retained for historical audit and to detect regressions.",
|
|
150
|
+
"scenario": "Future regression: someone removes the CallPermission.apply path for the permission rebinding",
|
|
151
|
+
"mitigation": "Keep the permission rebinding exposed via CallPermission.apply. The Move invariant: rebinding requires the owner assert on the old Permission and MUST run the affiliation-change routine to migrate the binding.",
|
|
152
|
+
"evidence": "constants_synced=false (regression check)",
|
|
153
|
+
"stakeholders": ["creator", "system"]
|
|
154
|
+
}
|
|
155
|
+
]
|
|
156
|
+
}
|
|
157
|
+
]
|
|
158
|
+
}
|