progmune-runtime 2.1.6 → 3.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +119 -461
- package/dist/ablation-study.js +144 -0
- package/dist/ablation-study.test.js +18 -0
- package/dist/action-runtime.js +3 -1
- package/dist/active-learning.js +211 -0
- package/dist/analytics.js +139 -0
- package/dist/asset-factory.js +309 -0
- package/dist/asset-growth.js +244 -0
- package/dist/asset-promotion.js +382 -0
- package/dist/asset-quality.js +550 -0
- package/dist/audit/business-translator.js +285 -0
- package/dist/audit/cli.js +66 -0
- package/dist/audit/formatters/html.js +379 -0
- package/dist/audit/formatters/json.js +11 -0
- package/dist/audit/formatters/markdown.js +192 -0
- package/dist/audit/formatters/terminal.js +189 -0
- package/dist/audit/index.js +25 -0
- package/dist/audit/report-builder.js +318 -0
- package/dist/audit/types.js +8 -0
- package/dist/audit.js +3 -3
- package/dist/auto-benchmark-generator.js +137 -0
- package/dist/auto-benchmark-generator.test.js +45 -0
- package/dist/auto-protocol-synthesizer.js +362 -0
- package/dist/auto-protocol-synthesizer.test.js +82 -0
- package/dist/autonomous-patch.js +175 -0
- package/dist/autonomous-patch.test.js +128 -0
- package/dist/badge/badge-server.js +98 -0
- package/dist/behavior-miner.js +442 -0
- package/dist/belief-layer.js +475 -0
- package/dist/benchmark-count.js +5 -0
- package/dist/benchmark-generator.js +211 -0
- package/dist/benchmark-harness.js +201 -0
- package/dist/benchmark-pass-rate.js +7 -0
- package/dist/benchmark-report.js +8 -3
- package/dist/benchmark-save.js +14 -1
- package/dist/bootstrap-validation.js +197 -0
- package/dist/bootstrap-validation.test.js +51 -0
- package/dist/branch-ledger.js +1 -1
- package/dist/capability-gap.js +130 -0
- package/dist/certify-html.js +351 -0
- package/dist/certify.js +326 -0
- package/dist/check.js +4 -4
- package/dist/compliance-miner.js +447 -0
- package/dist/continuous-benchmark.js +194 -0
- package/dist/continuous-benchmark.test.js +116 -0
- package/dist/corpus-stats.js +173 -0
- package/dist/counterfactual-engine.js +288 -0
- package/dist/coverage-dashboard.js +109 -0
- package/dist/coverage-system.test.js +205 -0
- package/dist/cross-repo-precision.js +352 -0
- package/dist/cve-benchmark.js +180 -0
- package/dist/cve-benchmark.test.js +28 -0
- package/dist/cve-collector.js +73 -0
- package/dist/data-quality.js +141 -0
- package/dist/decision-engine.js +388 -0
- package/dist/derive-metadata.js +250 -0
- package/dist/difficulty-active.test.js +198 -0
- package/dist/difficulty-map.js +244 -0
- package/dist/discovery-analytics.js +125 -0
- package/dist/discovery-model.js +149 -0
- package/dist/discovery-optimize.test.js +199 -0
- package/dist/discovery-trace.js +276 -0
- package/dist/discovery-trace.test.js +97 -0
- package/dist/emitter.js +83 -1
- package/dist/enterprise-dashboard.js +405 -0
- package/dist/eval-hardening.js +297 -0
- package/dist/eval-hardening.test.js +85 -0
- package/dist/evaluation-campaign.js +359 -0
- package/dist/evaluation-campaign.test.js +181 -0
- package/dist/evidence-growth.js +143 -0
- package/dist/evidence-repository.js +209 -0
- package/dist/evidence-system.js +441 -0
- package/dist/execute.js +15 -7
- package/dist/experimental/software-physics.js +291 -0
- package/dist/experimental/state-inference.js +516 -0
- package/dist/experimental/unsupervised-physics.js +230 -0
- package/dist/extract-ir-python.js +54 -7
- package/dist/extract-ir.js +376 -12
- package/dist/failure-collector.js +2 -2
- package/dist/failure-corpus.js +322 -9
- package/dist/feedback.js +16 -5
- package/dist/feedback.test.js +49 -0
- package/dist/file-lock.js +1 -1
- package/dist/flywheel-batch.js +292 -0
- package/dist/frameworks/express-cli.js +237 -0
- package/dist/frameworks/express-detector.js +445 -0
- package/dist/frameworks/express-detector.test.js +206 -0
- package/dist/frameworks/index.js +30 -0
- package/dist/frameworks/nestjs-detector.js +302 -0
- package/dist/frameworks/trpc-detector.js +161 -0
- package/dist/frameworks/version-awareness.js +179 -0
- package/dist/function-synonyms.js +164 -0
- package/dist/function-synonyms.test.js +68 -0
- package/dist/generalization.test.js +352 -0
- package/dist/goal-annotator.js +113 -0
- package/dist/goal-planner.js +563 -0
- package/dist/gold-cve.js +164 -0
- package/dist/gold-cve.test.js +104 -0
- package/dist/gold-quality.js +206 -0
- package/dist/gold-tiers.js +241 -0
- package/dist/governance-dashboard.js +327 -0
- package/dist/graph-viz.js +240 -0
- package/dist/guided-frontier.js +195 -0
- package/dist/hierarchical-planner.js +148 -0
- package/dist/identifier-parser.js +260 -0
- package/dist/immune-metrics.js +93 -0
- package/dist/immune-receiver.js +158 -0
- package/dist/immune-reporter.js +1 -1
- package/dist/improvement-orchestrator.js +206 -0
- package/dist/inject-p0-vocabulary.js +300 -0
- package/dist/intent-parser.js +218 -0
- package/dist/invariant-algebra.js +476 -0
- package/dist/invariant-calculus.js +533 -0
- package/dist/ir-utils.js +70 -0
- package/dist/ir-utils.test.js +50 -0
- package/dist/knowledge-api.js +312 -0
- package/dist/knowledge-evolution.js +452 -0
- package/dist/knowledge-explorer.js +506 -0
- package/dist/knowledge-flywheel.js +274 -0
- package/dist/knowledge-governance.js +338 -0
- package/dist/knowledge-governance.test.js +150 -0
- package/dist/knowledge-graph.js +181 -0
- package/dist/knowledge-guided-synth.js +246 -0
- package/dist/knowledge-loop.test.js +77 -0
- package/dist/knowledge-object.js +316 -0
- package/dist/knowledge-package.js +98 -0
- package/dist/kpi-dashboard.js +561 -0
- package/dist/l3-cross-function.js +280 -0
- package/dist/learning-ranker.js +148 -0
- package/dist/learning-ranker.test.js +291 -0
- package/dist/ledger/accountability.js +322 -0
- package/dist/ledger/chain-builder.js +185 -0
- package/dist/ledger/cli.js +222 -0
- package/dist/ledger/index.js +13 -0
- package/dist/ledger/signatures.js +193 -0
- package/dist/ledger/types.js +9 -0
- package/dist/llm.js +74 -3
- package/dist/load-benchmarks.js +8 -3
- package/dist/logger.js +66 -0
- package/dist/logger.test.js +37 -0
- package/dist/logistic-reward.js +339 -0
- package/dist/logistic-reward.test.js +180 -0
- package/dist/macro-graph.js +193 -0
- package/dist/macro-repair.js +183 -0
- package/dist/mcp-server.mjs +1202 -483
- package/dist/memory-layer.js +42 -5
- package/dist/multi-repo-precision.js +422 -0
- package/dist/name-free-protocol.js +425 -0
- package/dist/name-free-protocol.test.js +170 -0
- package/dist/name-scrambling.js +138 -0
- package/dist/name-scrambling.test.js +16 -0
- package/dist/p3-observability.test.js +281 -0
- package/dist/p5-orchestrator.test.js +225 -0
- package/dist/pairwise-preference.js +294 -0
- package/dist/pairwise-preference.test.js +140 -0
- package/dist/planner-constraints.js +104 -0
- package/dist/planner-prompts.js +155 -0
- package/dist/planner-telemetry.js +415 -0
- package/dist/planner-trace.js +214 -0
- package/dist/planner.js +162 -167
- package/dist/plsb/artifact.js +116 -0
- package/dist/plsb/cli.js +71 -0
- package/dist/plsb/index.js +19 -0
- package/dist/plsb/leaderboard.js +249 -0
- package/dist/plsb/report-md.js +156 -0
- package/dist/plsb/schema.js +179 -0
- package/dist/plsb-benchmark.js +284 -0
- package/dist/plsb-benchmark.test.js +119 -0
- package/dist/policy/cli.js +134 -0
- package/dist/policy/engine.js +333 -0
- package/dist/policy/index.js +12 -0
- package/dist/policy/types.js +59 -0
- package/dist/policy-miner.js +505 -0
- package/dist/precision-analyze.js +229 -0
- package/dist/precision-benchmark.js +147 -0
- package/dist/precision-label-c.js +134 -0
- package/dist/precision-label.js +193 -0
- package/dist/precision-report-c.js +149 -0
- package/dist/precision-report.js +246 -0
- package/dist/progmune-status.js +108 -0
- package/dist/proof-engine.js +479 -0
- package/dist/proof-provenance.js +315 -0
- package/dist/protocol-coverage.js +294 -0
- package/dist/protocol-detector.js +1189 -0
- package/dist/protocol-embedding-expanded.js +297 -0
- package/dist/protocol-embedding-expanded.test.js +97 -0
- package/dist/protocol-embedding.js +195 -0
- package/dist/protocol-embedding.test.js +82 -0
- package/dist/protocol-extractor-v2.js +354 -0
- package/dist/protocol-extractor-v2.test.js +140 -0
- package/dist/protocol-extractor.js +310 -0
- package/dist/protocol-extractor.test.js +113 -0
- package/dist/protocol-foundation.js +322 -0
- package/dist/protocol-foundation.test.js +163 -0
- package/dist/protocol-frontier.js +243 -0
- package/dist/protocol-frontier.test.js +92 -0
- package/dist/protocol-gap-analyzer.js +228 -0
- package/dist/protocol-gap-analyzer.test.js +49 -0
- package/dist/protocol-invariants.js +276 -0
- package/dist/protocol-invariants.test.js +111 -0
- package/dist/protocol-knowledge.js +464 -0
- package/dist/protocol-miner.js +343 -0
- package/dist/protocol-mining.js +207 -0
- package/dist/protocol-mining.test.js +37 -0
- package/dist/protocol-registry.js +1 -1
- package/dist/protocol-security-benchmark.js +222 -0
- package/dist/protocol-vulnerability.js +257 -0
- package/dist/protocol-vulnerability.test.js +60 -0
- package/dist/python-benchmark.js +120 -0
- package/dist/python-emitter.js +163 -45
- package/dist/python-protocol-extractor.js +187 -0
- package/dist/python-protocol-extractor.test.js +116 -0
- package/dist/realworld-benchmark.js +646 -0
- package/dist/realworld-benchmark.test.js +36 -0
- package/dist/repair-arch.test.js +411 -0
- package/dist/repair-evolution.test.js +454 -0
- package/dist/repair-executor.js +719 -0
- package/dist/repair-proposal.js +4 -4
- package/dist/repair-ranker.js +141 -0
- package/dist/repair-strategies.js +419 -0
- package/dist/repair-taxonomy.js +234 -0
- package/dist/repair-types.js +12 -0
- package/dist/repo-evaluator.js +250 -0
- package/dist/repo-evaluator.test.js +128 -0
- package/dist/resource-abstraction.js +242 -0
- package/dist/resource-detector.js +211 -0
- package/dist/result.test.js +43 -0
- package/dist/reward-system.js +411 -0
- package/dist/reward-system.test.js +175 -0
- package/dist/risk-model.js +215 -0
- package/dist/rule-miner.js +234 -7
- package/dist/rule-specificity.js +254 -0
- package/dist/runtime-types.js +27 -0
- package/dist/scaffold.js +208 -0
- package/dist/scale-collector.test.js +101 -0
- package/dist/scale-trajectory-collector.js +128 -0
- package/dist/sdk.js +250 -0
- package/dist/search-planner.js +4 -41
- package/dist/semantic-snapshot.js +1 -1
- package/dist/semantic-topology.js +121 -0
- package/dist/semantic-trace.js +310 -317
- package/dist/sequence-extractor.js +343 -0
- package/dist/skill-library.js +245 -0
- package/dist/skill-planner.test.js +189 -0
- package/dist/software-physics.js +291 -0
- package/dist/software-physics.test.js +81 -0
- package/dist/ssg-precision.js +478 -0
- package/dist/ssg-validator.js +71 -21
- package/dist/state-inference-doubleblind.test.js +160 -0
- package/dist/state-inference.js +516 -0
- package/dist/state-inference.test.js +115 -0
- package/dist/state-machine-fingerprint.js +345 -0
- package/dist/state-machine-fingerprint.test.js +120 -0
- package/dist/state-miner.js +386 -0
- package/dist/state-name-inference.js +213 -0
- package/dist/state-name-inference.test.js +69 -0
- package/dist/strategy-planner.js +262 -96
- package/dist/strategy-planner.test.js +135 -0
- package/dist/telemetry-analytics.test.js +402 -0
- package/dist/terminal-format.js +68 -0
- package/dist/terminal-format.test.js +83 -0
- package/dist/topology-factory.js +196 -0
- package/dist/topology-representation.js +242 -0
- package/dist/topology-representation.test.js +27 -0
- package/dist/trajectory-augmentation.js +254 -0
- package/dist/trajectory-augmentation.test.js +63 -0
- package/dist/trajectory-corpus.js +440 -0
- package/dist/trajectory-corpus.test.js +32 -0
- package/dist/trajectory-feedback.test.js +116 -0
- package/dist/transition-synthesizer.js +286 -0
- package/dist/transition-synthesizer.test.js +123 -0
- package/dist/trust/api-semantic-mapper.js +809 -0
- package/dist/trust/call-graph-propagator.js +225 -0
- package/dist/trust/cli.js +122 -0
- package/dist/trust/compliance-scorer.js +283 -0
- package/dist/trust/confidence-calculator.js +261 -0
- package/dist/trust/engine.js +1145 -0
- package/dist/trust/explainability.js +85 -0
- package/dist/trust/formatters/ci.js +42 -0
- package/dist/trust/formatters/json.js +11 -0
- package/dist/trust/formatters/terminal.js +152 -0
- package/dist/trust/index.js +39 -0
- package/dist/trust/phase1-verify.js +171 -0
- package/dist/trust/protocol-domain-validator.js +697 -0
- package/dist/trust/score-calculator.js +282 -0
- package/dist/trust/ssg-bridge.js +641 -0
- package/dist/trust/ssg-bridge.test.js +269 -0
- package/dist/trust/types.js +67 -0
- package/dist/trust/violation-trace.js +335 -0
- package/dist/trust-api.js +179 -0
- package/dist/trust-calibration.js +279 -0
- package/dist/unknown-protocol-discovery.js +339 -0
- package/dist/unknown-protocol-discovery.test.js +102 -0
- package/dist/unsupervised-physics.js +230 -0
- package/dist/unsupervised-physics.test.js +95 -0
- package/dist/utils.test.js +37 -0
- package/dist/validator.js +187 -10
- package/dist/verification-intelligence.js +475 -0
- package/dist/verify-api.js +432 -0
- package/dist/vi-impact-report.js +293 -0
- package/dist/wl-fingerprint.js +162 -0
- package/dist/wl-fingerprint.test.js +130 -0
- package/dist/zeroshot-strategy.js +139 -0
- package/docs/Progmune_/346/212/225/350/265/204/344/272/272/347/231/275/347/232/256/344/271/246_v2.0.html +576 -0
- package/docs/Progmune_/351/241/271/347/233/256/345/205/250/350/247/243.html +721 -0
- package/package.json +73 -6
- package/protocols.json +1956 -50
- package/.dockerignore +0 -14
- package/.mcp.json +0 -11
- package/.progmune_allowlist +0 -50
- package/.test_report/test_report.md +0 -87
- package/Dockerfile +0 -9
- package/FAQ.md +0 -167
- package/WHITEPAPER.md +0 -540
- package/demo-project/auth.ts +0 -55
- package/demo-project/tsconfig.json +0 -8
- package/dist/acl-breakdown.js +0 -13
- package/dist/all-sessions.js +0 -11
- package/dist/antibody-stats.js +0 -11
- package/dist/branch-tree-count.js +0 -14
- package/dist/common-fixpath.js +0 -12
- package/dist/constraint-types.js +0 -12
- package/dist/exec-metrics.js +0 -11
- package/dist/failure-report.js +0 -11
- package/dist/fast-path-hits.js +0 -13
- package/dist/fingerprint-list.js +0 -15
- package/dist/gen-history-log.js +0 -13
- package/dist/heatmap-data.js +0 -11
- package/dist/recent-session.js +0 -12
- package/dist/svl-distribution.js +0 -11
- package/dist/terminal-status.js +0 -11
- package/dist/token-savings.js +0 -11
- package/dist/total-repairs.js +0 -12
- package/dist/unresolved-count.js +0 -12
- package/dist/valid-fingerprints.js +0 -13
- package/dist/verify-ledgers.js +0 -11
- package/docs/whitepaper-style.css +0 -77
- package/docs/whitepaper-v2.1.md +0 -609
- package/docs/whitepaper-v2.2.md +0 -1064
- package/docs/whitepaper-v2.2.pdf +0 -0
- package/fly.toml +0 -31
- package/public/dashboard.html +0 -119
- package/server/hub.js +0 -116
- package/test/replay-golden/sess_1780063202050_mgeld.json +0 -9
- package/test/replay-golden/sess_1780064032560_gocld.json +0 -354
- package/test/replay-golden/sess_1780064413331_s2709.json +0 -606
- package/test/replay-golden/sess_1780064792710_y3avo.json +0 -614
- package/test/replay-golden.ts +0 -84
- package/test_benchmark.js +0 -165
- package/test_comprehensive.mjs +0 -638
- package/test_concurrency.js +0 -129
- package/test_ir_robustness.js +0 -85
- package/test_semantic_contracts.js +0 -269
- package/test_ssg_stress.js +0 -156
- package/test_svl3.js +0 -58
- package/tsconfig.json +0 -17
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* P5.7: Real-world Defect Benchmark Tests
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const vitest_1 = require("vitest");
|
|
7
|
+
const realworld_benchmark_1 = require("./realworld-benchmark");
|
|
8
|
+
(0, vitest_1.describe)("Real-world Defect Benchmark", () => {
|
|
9
|
+
(0, vitest_1.it)("all curated defects have valid structure", () => {
|
|
10
|
+
(0, vitest_1.expect)(realworld_benchmark_1.REAL_WORLD_DEFECTS.length).toBeGreaterThanOrEqual(8);
|
|
11
|
+
for (const d of realworld_benchmark_1.REAL_WORLD_DEFECTS) {
|
|
12
|
+
(0, vitest_1.expect)(d.id).toMatch(/^RW-\d{3}$/);
|
|
13
|
+
(0, vitest_1.expect)(d.broken.length).toBeGreaterThan(0);
|
|
14
|
+
(0, vitest_1.expect)(d.expected.length).toBeGreaterThan(0);
|
|
15
|
+
(0, vitest_1.expect)(["critical", "high", "medium", "low"]).toContain(d.severity);
|
|
16
|
+
(0, vitest_1.expect)(["resource_leak", "auth_bypass", "data_corruption", "use_after_free", "race_condition"]).toContain(d.category);
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
(0, vitest_1.it)("covers all severity levels", () => {
|
|
20
|
+
const severities = new Set(realworld_benchmark_1.REAL_WORLD_DEFECTS.map(d => d.severity));
|
|
21
|
+
(0, vitest_1.expect)(severities.has("critical")).toBe(true);
|
|
22
|
+
(0, vitest_1.expect)(severities.has("high")).toBe(true);
|
|
23
|
+
(0, vitest_1.expect)(severities.has("medium")).toBe(true);
|
|
24
|
+
});
|
|
25
|
+
(0, vitest_1.it)("covers all defect categories", () => {
|
|
26
|
+
const categories = new Set(realworld_benchmark_1.REAL_WORLD_DEFECTS.map(d => d.category));
|
|
27
|
+
(0, vitest_1.expect)(categories.size).toBeGreaterThanOrEqual(4);
|
|
28
|
+
});
|
|
29
|
+
(0, vitest_1.it)("runs planner against real-world defects", async () => {
|
|
30
|
+
const report = await (0, realworld_benchmark_1.runRealWorldBenchmark)();
|
|
31
|
+
(0, vitest_1.expect)(report.totalDefects).toBe(20);
|
|
32
|
+
(0, vitest_1.expect)(report.detectionRate).toBeGreaterThanOrEqual(0);
|
|
33
|
+
(0, vitest_1.expect)(report.top3RepairRate).toBeGreaterThanOrEqual(0.45); // 10 new protocol types reduce ceiling
|
|
34
|
+
(0, realworld_benchmark_1.printRealWorldReport)(report);
|
|
35
|
+
}, 30000);
|
|
36
|
+
});
|
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Architecture Boundary Tests — P2 Counterfactual Planner
|
|
4
|
+
*
|
|
5
|
+
* Verifying:
|
|
6
|
+
* P0: Missing close() scenario (user-visible demo capability)
|
|
7
|
+
* P0: Planner aggregation (multi-strategy merge)
|
|
8
|
+
* P0: Deduplication (no duplicate repair plans)
|
|
9
|
+
* P1: Ranker logic (prefers safer candidate)
|
|
10
|
+
* P1: Strategy independence (produces candidates, never scores)
|
|
11
|
+
* P2: Trajectory feedback (pre-burial for P4 Reward Model)
|
|
12
|
+
*/
|
|
13
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
16
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
17
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
18
|
+
}
|
|
19
|
+
Object.defineProperty(o, k2, desc);
|
|
20
|
+
}) : (function(o, m, k, k2) {
|
|
21
|
+
if (k2 === undefined) k2 = k;
|
|
22
|
+
o[k2] = m[k];
|
|
23
|
+
}));
|
|
24
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
25
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
26
|
+
}) : function(o, v) {
|
|
27
|
+
o["default"] = v;
|
|
28
|
+
});
|
|
29
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
30
|
+
var ownKeys = function(o) {
|
|
31
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
32
|
+
var ar = [];
|
|
33
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
34
|
+
return ar;
|
|
35
|
+
};
|
|
36
|
+
return ownKeys(o);
|
|
37
|
+
};
|
|
38
|
+
return function (mod) {
|
|
39
|
+
if (mod && mod.__esModule) return mod;
|
|
40
|
+
var result = {};
|
|
41
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
42
|
+
__setModuleDefault(result, mod);
|
|
43
|
+
return result;
|
|
44
|
+
};
|
|
45
|
+
})();
|
|
46
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
47
|
+
const vitest_1 = require("vitest");
|
|
48
|
+
const fs = __importStar(require("fs"));
|
|
49
|
+
const path = __importStar(require("path"));
|
|
50
|
+
const repair_strategies_1 = require("./repair-strategies");
|
|
51
|
+
const repair_ranker_1 = require("./repair-ranker");
|
|
52
|
+
const counterfactual_engine_1 = require("./counterfactual-engine");
|
|
53
|
+
const ssg_validator_1 = require("./ssg-validator");
|
|
54
|
+
// ── Helpers ──
|
|
55
|
+
/** Build a SearchContext for a FileProtocol "missing close()" scenario. */
|
|
56
|
+
function fileProtocolContext(actions) {
|
|
57
|
+
// open_file → write_file → ... missing close_file
|
|
58
|
+
const currentStates = ["FILE_OPEN"];
|
|
59
|
+
const targetStates = []; // should invalidate FILE_OPEN
|
|
60
|
+
const protoDef = JSON.parse(fs.readFileSync(path.resolve(__dirname, "..", "protocols.json"), "utf-8"));
|
|
61
|
+
const protocols = (0, ssg_validator_1.parseProtocolsFromJSON)(protoDef);
|
|
62
|
+
const rules = new Map();
|
|
63
|
+
for (const p of protocols) {
|
|
64
|
+
rules.set(p.function, p.protocol);
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
protocol: "_global",
|
|
68
|
+
currentState: currentStates,
|
|
69
|
+
targetState: targetStates,
|
|
70
|
+
violationType: "resource_leak",
|
|
71
|
+
constraints: [{ type: "safety", value: 0.9, description: "文件安全关闭" }],
|
|
72
|
+
rules,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
// ════════════════════════════════════════════════════════
|
|
76
|
+
// P0: Missing close() — real user-visible scenario
|
|
77
|
+
// ════════════════════════════════════════════════════════
|
|
78
|
+
(0, vitest_1.describe)("P0: Missing close() repair", () => {
|
|
79
|
+
(0, vitest_1.it)("suggests close_file as a repair candidate", async () => {
|
|
80
|
+
const rules = fileProtocolContext(["open_file", "write_file"]).rules;
|
|
81
|
+
const alts = await (0, counterfactual_engine_1.suggestAlternatives)({
|
|
82
|
+
violation: {
|
|
83
|
+
svl: 4,
|
|
84
|
+
violatedConstraint: "resource_leak",
|
|
85
|
+
actionIndex: 2,
|
|
86
|
+
currentStates: ["FILE_OPEN"],
|
|
87
|
+
requiredStates: [],
|
|
88
|
+
description: "File not closed after write",
|
|
89
|
+
},
|
|
90
|
+
protocol: "_global",
|
|
91
|
+
currentState: ["FILE_OPEN"],
|
|
92
|
+
targetState: [],
|
|
93
|
+
constraints: [{ type: "safety", value: 0.9, description: "文件安全关闭" }],
|
|
94
|
+
rules,
|
|
95
|
+
});
|
|
96
|
+
const functionNames = alts.flatMap(a => a.fixPath);
|
|
97
|
+
// At least one candidate must include close_file
|
|
98
|
+
(0, vitest_1.expect)(functionNames).toContain("close_file");
|
|
99
|
+
});
|
|
100
|
+
(0, vitest_1.it)("repair plan closes the file with open → write → close", async () => {
|
|
101
|
+
const ctx = fileProtocolContext(["open_file", "write_file"]);
|
|
102
|
+
const alts = await (0, counterfactual_engine_1.suggestAlternatives)({
|
|
103
|
+
violation: {
|
|
104
|
+
svl: 4,
|
|
105
|
+
violatedConstraint: "resource_leak",
|
|
106
|
+
actionIndex: 2,
|
|
107
|
+
currentStates: ["FILE_OPEN"],
|
|
108
|
+
requiredStates: [],
|
|
109
|
+
description: "File not closed after write",
|
|
110
|
+
},
|
|
111
|
+
protocol: "_global",
|
|
112
|
+
currentState: ["FILE_OPEN"],
|
|
113
|
+
targetState: [],
|
|
114
|
+
constraints: [{ type: "safety", value: 0.9, description: "文件安全关闭" }],
|
|
115
|
+
rules: ctx.rules,
|
|
116
|
+
});
|
|
117
|
+
const signatures = alts.map(a => a.fixPath.join(","));
|
|
118
|
+
// Should have a candidate whose fix path includes close_file
|
|
119
|
+
const hasClose = signatures.some(s => s.includes("close_file"));
|
|
120
|
+
(0, vitest_1.expect)(hasClose).toBe(true);
|
|
121
|
+
});
|
|
122
|
+
(0, vitest_1.it)("close_file ranks higher than a longer alternative on safety", () => {
|
|
123
|
+
const ctx = fileProtocolContext(["open_file", "write_file"]);
|
|
124
|
+
const strategies = (0, repair_strategies_1.createDefaultStrategies)();
|
|
125
|
+
const allCandidates = [];
|
|
126
|
+
for (const s of strategies)
|
|
127
|
+
allCandidates.push(...s.search(ctx));
|
|
128
|
+
if (allCandidates.length >= 2) {
|
|
129
|
+
const maxActions = Math.max(...allCandidates.map(c => c.actions.length), 8);
|
|
130
|
+
const features = allCandidates.map(c => (0, repair_ranker_1.extractFeatures)(c, ctx, { maxActions }));
|
|
131
|
+
const ranker = (0, repair_ranker_1.createLinearRanker)();
|
|
132
|
+
const ranked = ranker.rankSafety(allCandidates, features);
|
|
133
|
+
// The top-ranked by safety should be relatively safe (score >= 0.5)
|
|
134
|
+
const topFeature = features[allCandidates.indexOf(ranked[0])];
|
|
135
|
+
(0, vitest_1.expect)(topFeature.protocolSafety).toBeGreaterThanOrEqual(0.5);
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
// ════════════════════════════════════════════════════════
|
|
140
|
+
// P1: Strategy independence — no scoring in strategies
|
|
141
|
+
// ════════════════════════════════════════════════════════
|
|
142
|
+
(0, vitest_1.describe)("P1: Strategy independence", () => {
|
|
143
|
+
const ctx = fileProtocolContext(["open_file"]);
|
|
144
|
+
(0, vitest_1.it)("CorpusStrategy returns candidates without score fields", () => {
|
|
145
|
+
const strategies = (0, repair_strategies_1.createDefaultStrategies)();
|
|
146
|
+
for (const strategy of strategies) {
|
|
147
|
+
const results = strategy.search(ctx);
|
|
148
|
+
for (const r of results) {
|
|
149
|
+
(0, vitest_1.expect)(r.source).toBe(strategy.name);
|
|
150
|
+
(0, vitest_1.expect)(r.score).toBeUndefined();
|
|
151
|
+
(0, vitest_1.expect)(r.rank).toBeUndefined();
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
(0, vitest_1.it)("every candidate has required RepairCandidate shape", () => {
|
|
156
|
+
const strategies = (0, repair_strategies_1.createDefaultStrategies)();
|
|
157
|
+
for (const strategy of strategies) {
|
|
158
|
+
const results = strategy.search(ctx);
|
|
159
|
+
for (const r of results) {
|
|
160
|
+
(0, vitest_1.expect)(r).toHaveProperty("id");
|
|
161
|
+
(0, vitest_1.expect)(r).toHaveProperty("source");
|
|
162
|
+
(0, vitest_1.expect)(r).toHaveProperty("actions");
|
|
163
|
+
(0, vitest_1.expect)(r).toHaveProperty("explanation");
|
|
164
|
+
(0, vitest_1.expect)(["corpus", "protocol", "antibody"]).toContain(r.source);
|
|
165
|
+
(0, vitest_1.expect)(Array.isArray(r.actions)).toBe(true);
|
|
166
|
+
(0, vitest_1.expect)(r.actions.length).toBeGreaterThan(0);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
(0, vitest_1.it)("ProtocolStrategy finds protocol-based candidates for FileProtocol", () => {
|
|
171
|
+
const strategies = (0, repair_strategies_1.createDefaultStrategies)();
|
|
172
|
+
// ProtocolStrategy is index 1
|
|
173
|
+
const protoStrat = strategies.find(s => s.name === "protocol");
|
|
174
|
+
(0, vitest_1.expect)(protoStrat).toBeDefined();
|
|
175
|
+
const results = protoStrat.search(ctx);
|
|
176
|
+
(0, vitest_1.expect)(results.length).toBeGreaterThan(0);
|
|
177
|
+
for (const r of results) {
|
|
178
|
+
(0, vitest_1.expect)(r.source).toBe("protocol");
|
|
179
|
+
// FileProtocol candidates must include file operations
|
|
180
|
+
const fns = r.actions
|
|
181
|
+
.filter(a => a.kind === "call")
|
|
182
|
+
.map(a => a.function);
|
|
183
|
+
(0, vitest_1.expect)(fns.length).toBeGreaterThan(0);
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
// ════════════════════════════════════════════════════════
|
|
188
|
+
// P1: Ranker logic — prefers safer/shorter candidates
|
|
189
|
+
// ════════════════════════════════════════════════════════
|
|
190
|
+
(0, vitest_1.describe)("P1: LinearRanker", () => {
|
|
191
|
+
// Construct two candidates with different safety profiles
|
|
192
|
+
const safeFeatures = {
|
|
193
|
+
protocolSafety: 0.95,
|
|
194
|
+
historicalSuccessRate: 0.3,
|
|
195
|
+
actionCount: 2,
|
|
196
|
+
latencyCost: 0.25,
|
|
197
|
+
auditability: 0.75,
|
|
198
|
+
corpusEvidence: 0,
|
|
199
|
+
source: "protocol",
|
|
200
|
+
};
|
|
201
|
+
const fastFeatures = {
|
|
202
|
+
protocolSafety: 0.4,
|
|
203
|
+
historicalSuccessRate: 0.99,
|
|
204
|
+
actionCount: 1,
|
|
205
|
+
latencyCost: 0.1,
|
|
206
|
+
auditability: 0.8,
|
|
207
|
+
corpusEvidence: 42,
|
|
208
|
+
source: "corpus",
|
|
209
|
+
};
|
|
210
|
+
const safeCandidate = {
|
|
211
|
+
id: "safe",
|
|
212
|
+
source: "protocol",
|
|
213
|
+
actions: [
|
|
214
|
+
{ kind: "call", function: "open_file", args: [] },
|
|
215
|
+
{ kind: "call", function: "close_file", args: [] },
|
|
216
|
+
],
|
|
217
|
+
explanation: "Safe: properly close the file",
|
|
218
|
+
};
|
|
219
|
+
const fastCandidate = {
|
|
220
|
+
id: "fast",
|
|
221
|
+
source: "corpus",
|
|
222
|
+
actions: [{ kind: "call", function: "flush_and_close", args: [] }],
|
|
223
|
+
explanation: "Fast: single atomic operation",
|
|
224
|
+
evidence: 42,
|
|
225
|
+
metadata: { historicalSuccessRate: 0.99, corpusEvidenceCount: 42 },
|
|
226
|
+
};
|
|
227
|
+
(0, vitest_1.it)("rankSafety prefers the safer candidate", () => {
|
|
228
|
+
const ranker = (0, repair_ranker_1.createLinearRanker)();
|
|
229
|
+
const ranked = ranker.rankSafety([fastCandidate, safeCandidate], [fastFeatures, safeFeatures]);
|
|
230
|
+
(0, vitest_1.expect)(ranked[0].id).toBe("safe");
|
|
231
|
+
});
|
|
232
|
+
(0, vitest_1.it)("rankPerformance prefers the faster candidate (fewer actions)", () => {
|
|
233
|
+
const ranker = (0, repair_ranker_1.createLinearRanker)();
|
|
234
|
+
const ranked = ranker.rankPerformance([safeCandidate, fastCandidate], [safeFeatures, fastFeatures]);
|
|
235
|
+
(0, vitest_1.expect)(ranked[0].id).toBe("fast");
|
|
236
|
+
});
|
|
237
|
+
(0, vitest_1.it)("rankOverall with default weights prefers overall best", () => {
|
|
238
|
+
const ranker = (0, repair_ranker_1.createLinearRanker)();
|
|
239
|
+
const scoreSafe = ranker.score(safeFeatures);
|
|
240
|
+
const scoreFast = ranker.score(fastFeatures);
|
|
241
|
+
// Both scores in 0-1 range
|
|
242
|
+
(0, vitest_1.expect)(scoreSafe).toBeGreaterThanOrEqual(0);
|
|
243
|
+
(0, vitest_1.expect)(scoreSafe).toBeLessThanOrEqual(1);
|
|
244
|
+
(0, vitest_1.expect)(scoreFast).toBeGreaterThanOrEqual(0);
|
|
245
|
+
(0, vitest_1.expect)(scoreFast).toBeLessThanOrEqual(1);
|
|
246
|
+
// Scores are deterministic
|
|
247
|
+
(0, vitest_1.expect)(scoreSafe).toBe(scoreSafe); // idempotent
|
|
248
|
+
});
|
|
249
|
+
(0, vitest_1.it)("custom weights change the ranking", () => {
|
|
250
|
+
const safetyFirst = (0, repair_ranker_1.createLinearRanker)({ safety: 0.9, successRate: 0.05, performance: 0.03, auditability: 0.02 });
|
|
251
|
+
const speedFirst = (0, repair_ranker_1.createLinearRanker)({ safety: 0.05, successRate: 0.1, performance: 0.8, auditability: 0.05 });
|
|
252
|
+
const bySafety = safetyFirst.score(safeFeatures);
|
|
253
|
+
const bySpeed = speedFirst.score(fastFeatures);
|
|
254
|
+
// With safety-first weights, safe candidate should score higher
|
|
255
|
+
(0, vitest_1.expect)(bySafety).toBeGreaterThan(speedFirst.score(safeFeatures));
|
|
256
|
+
// With speed-first weights, fast candidate should score higher
|
|
257
|
+
(0, vitest_1.expect)(bySpeed).toBeGreaterThan(safetyFirst.score(fastFeatures));
|
|
258
|
+
});
|
|
259
|
+
(0, vitest_1.it)("rankAuditability prefers shorter path (more auditable)", () => {
|
|
260
|
+
const ranker = (0, repair_ranker_1.createLinearRanker)();
|
|
261
|
+
const ranked = ranker.rankAuditability([safeCandidate, fastCandidate], [safeFeatures, fastFeatures]);
|
|
262
|
+
// fast has actionCount=1 vs safe has actionCount=2
|
|
263
|
+
// auditability = 1 - actionCount/maxActions → fast is more auditable
|
|
264
|
+
(0, vitest_1.expect)(ranked[0].id).toBe("fast");
|
|
265
|
+
});
|
|
266
|
+
});
|
|
267
|
+
// ════════════════════════════════════════════════════════
|
|
268
|
+
// P0: Planner aggregation — multi-strategy merge
|
|
269
|
+
// ════════════════════════════════════════════════════════
|
|
270
|
+
(0, vitest_1.describe)("P0: Planner aggregation", () => {
|
|
271
|
+
(0, vitest_1.it)("merges candidates from all three strategies via suggestAlternatives", async () => {
|
|
272
|
+
const ctx = fileProtocolContext(["open_file", "write_file"]);
|
|
273
|
+
const alts = await (0, counterfactual_engine_1.suggestAlternatives)({
|
|
274
|
+
violation: {
|
|
275
|
+
svl: 4,
|
|
276
|
+
violatedConstraint: "resource_leak",
|
|
277
|
+
actionIndex: 2,
|
|
278
|
+
currentStates: ["FILE_OPEN"],
|
|
279
|
+
requiredStates: [],
|
|
280
|
+
description: "File not closed after write",
|
|
281
|
+
},
|
|
282
|
+
protocol: "_global",
|
|
283
|
+
currentState: ["FILE_OPEN"],
|
|
284
|
+
targetState: [],
|
|
285
|
+
constraints: [{ type: "safety", value: 0.9, description: "文件安全关闭" }],
|
|
286
|
+
rules: ctx.rules,
|
|
287
|
+
});
|
|
288
|
+
(0, vitest_1.expect)(alts.length).toBeGreaterThan(0);
|
|
289
|
+
const sources = new Set(alts.map(a => a.source));
|
|
290
|
+
// At least one strategy produced results
|
|
291
|
+
(0, vitest_1.expect)(sources.has("corpus") || sources.has("ssg_bfs") || sources.has("antibody")).toBe(true);
|
|
292
|
+
});
|
|
293
|
+
});
|
|
294
|
+
// ════════════════════════════════════════════════════════
|
|
295
|
+
// P0: Deduplication — no duplicate repair plans
|
|
296
|
+
// ════════════════════════════════════════════════════════
|
|
297
|
+
(0, vitest_1.describe)("P0: Deduplication", () => {
|
|
298
|
+
(0, vitest_1.it)("removes candidates with identical action sequences", () => {
|
|
299
|
+
// Pre-seed corpus: record a trajectory with a known fix path
|
|
300
|
+
// so CorpusStrategy returns a duplicate of what ProtocolStrategy finds
|
|
301
|
+
process.env.PROGMUNE_CORPUS_DIR = path.resolve(__dirname, "..", "test-corpus-dedup", ".progmune_corpus");
|
|
302
|
+
const trajDir = path.resolve(process.env.PROGMUNE_CORPUS_DIR, "trajectories", new Date().toISOString().slice(0, 10));
|
|
303
|
+
fs.mkdirSync(trajDir, { recursive: true });
|
|
304
|
+
// Write a trajectory that has the same close_file fix path
|
|
305
|
+
const trajRecord = {
|
|
306
|
+
id: `dedup-test-${Date.now()}`,
|
|
307
|
+
timestamp: new Date().toISOString(),
|
|
308
|
+
protocol: "_global",
|
|
309
|
+
initialState: ["FILE_OPEN"],
|
|
310
|
+
finalState: [],
|
|
311
|
+
trajectory: ["open_file", "write_file", "close_file"],
|
|
312
|
+
result: "violation",
|
|
313
|
+
violation: {
|
|
314
|
+
type: "resource_leak",
|
|
315
|
+
failingStepIndex: 2,
|
|
316
|
+
expectedStates: [],
|
|
317
|
+
actualStates: ["FILE_OPEN"],
|
|
318
|
+
fixPath: ["close_file"],
|
|
319
|
+
description: "File not closed",
|
|
320
|
+
},
|
|
321
|
+
context: { nestingDepth: 0, exceptionHandled: false, insideLoop: false, branchCount: 0, asyncContext: false },
|
|
322
|
+
successRate: 0.9,
|
|
323
|
+
metadata: { source: "planner" },
|
|
324
|
+
};
|
|
325
|
+
fs.writeFileSync(path.join(trajDir, `${trajRecord.id}.json`), JSON.stringify(trajRecord));
|
|
326
|
+
const ctx = fileProtocolContext(["open_file", "write_file"]);
|
|
327
|
+
const strategies = (0, repair_strategies_1.createDefaultStrategies)();
|
|
328
|
+
const allCandidates = [];
|
|
329
|
+
for (const s of strategies) {
|
|
330
|
+
allCandidates.push(...s.search(ctx));
|
|
331
|
+
}
|
|
332
|
+
// Now we have at least 2 candidates: one from ProtocolStrategy, one from CorpusStrategy
|
|
333
|
+
// Both suggest close_file → same action signature
|
|
334
|
+
(0, vitest_1.expect)(allCandidates.length).toBeGreaterThanOrEqual(2);
|
|
335
|
+
const signatures = allCandidates.map(c => c.actions
|
|
336
|
+
.filter(a => a.kind === "call")
|
|
337
|
+
.map(a => a.function)
|
|
338
|
+
.join("→"));
|
|
339
|
+
const unique = new Set(signatures);
|
|
340
|
+
// After dedup, unique should be LESS than total (duplicates removed)
|
|
341
|
+
(0, vitest_1.expect)(unique.size).toBeLessThan(signatures.length);
|
|
342
|
+
});
|
|
343
|
+
(0, vitest_1.it)("suggestAlternatives returns deduplicated results", async () => {
|
|
344
|
+
const alts = await (0, counterfactual_engine_1.suggestAlternatives)({
|
|
345
|
+
violation: {
|
|
346
|
+
svl: 4,
|
|
347
|
+
violatedConstraint: "resource_leak",
|
|
348
|
+
actionIndex: 2,
|
|
349
|
+
currentStates: ["FILE_OPEN"],
|
|
350
|
+
requiredStates: [],
|
|
351
|
+
description: "File not closed after write",
|
|
352
|
+
},
|
|
353
|
+
protocol: "_global",
|
|
354
|
+
currentState: ["FILE_OPEN"],
|
|
355
|
+
targetState: [],
|
|
356
|
+
constraints: [{ type: "safety", value: 0.9, description: "安全关闭" }],
|
|
357
|
+
rules: fileProtocolContext(["open_file", "write_file"]).rules,
|
|
358
|
+
});
|
|
359
|
+
const fixPaths = alts.map(a => a.fixPath.join("→"));
|
|
360
|
+
const unique = new Set(fixPaths);
|
|
361
|
+
(0, vitest_1.expect)(unique.size).toBe(fixPaths.length);
|
|
362
|
+
});
|
|
363
|
+
});
|
|
364
|
+
// ════════════════════════════════════════════════════════
|
|
365
|
+
// FeatureExtractor boundary
|
|
366
|
+
// ════════════════════════════════════════════════════════
|
|
367
|
+
(0, vitest_1.describe)("FeatureExtractor", () => {
|
|
368
|
+
const ctx = fileProtocolContext(["open_file"]);
|
|
369
|
+
(0, vitest_1.it)("returns exactly 7 feature dimensions", () => {
|
|
370
|
+
const candidate = {
|
|
371
|
+
id: "test",
|
|
372
|
+
source: "protocol",
|
|
373
|
+
actions: [
|
|
374
|
+
{ kind: "call", function: "close_file", args: [] },
|
|
375
|
+
],
|
|
376
|
+
explanation: "close the file",
|
|
377
|
+
};
|
|
378
|
+
const features = (0, repair_ranker_1.extractFeatures)(candidate, ctx);
|
|
379
|
+
const keys = Object.keys(features);
|
|
380
|
+
(0, vitest_1.expect)(keys.length).toBeGreaterThanOrEqual(7); // P7.3: 8 with goalMatch
|
|
381
|
+
(0, vitest_1.expect)(keys).toContain("protocolSafety");
|
|
382
|
+
(0, vitest_1.expect)(keys).toContain("historicalSuccessRate");
|
|
383
|
+
(0, vitest_1.expect)(keys).toContain("actionCount");
|
|
384
|
+
(0, vitest_1.expect)(keys).toContain("latencyCost");
|
|
385
|
+
(0, vitest_1.expect)(keys).toContain("auditability");
|
|
386
|
+
(0, vitest_1.expect)(keys).toContain("corpusEvidence");
|
|
387
|
+
(0, vitest_1.expect)(keys).toContain("source");
|
|
388
|
+
});
|
|
389
|
+
(0, vitest_1.it)("all features in [0,1] range (except actionCount and corpusEvidence)", () => {
|
|
390
|
+
const candidate = {
|
|
391
|
+
id: "test",
|
|
392
|
+
source: "protocol",
|
|
393
|
+
actions: [
|
|
394
|
+
{ kind: "call", function: "a", args: [] },
|
|
395
|
+
{ kind: "call", function: "b", args: [] },
|
|
396
|
+
],
|
|
397
|
+
explanation: "test",
|
|
398
|
+
metadata: { historicalSuccessRate: 0.75, corpusEvidenceCount: 10 },
|
|
399
|
+
};
|
|
400
|
+
const features = (0, repair_ranker_1.extractFeatures)(candidate, ctx, { maxActions: 8 });
|
|
401
|
+
(0, vitest_1.expect)(features.protocolSafety).toBeGreaterThanOrEqual(0);
|
|
402
|
+
(0, vitest_1.expect)(features.protocolSafety).toBeLessThanOrEqual(1);
|
|
403
|
+
(0, vitest_1.expect)(features.historicalSuccessRate).toBe(0.75);
|
|
404
|
+
(0, vitest_1.expect)(features.actionCount).toBe(2); // raw integer, not clamped
|
|
405
|
+
(0, vitest_1.expect)(features.latencyCost).toBeGreaterThanOrEqual(0);
|
|
406
|
+
(0, vitest_1.expect)(features.latencyCost).toBeLessThanOrEqual(1);
|
|
407
|
+
(0, vitest_1.expect)(features.auditability).toBeGreaterThanOrEqual(0);
|
|
408
|
+
(0, vitest_1.expect)(features.auditability).toBeLessThanOrEqual(1);
|
|
409
|
+
(0, vitest_1.expect)(features.corpusEvidence).toBe(10);
|
|
410
|
+
});
|
|
411
|
+
});
|