progmune-runtime 2.1.5 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +108 -468
- 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 +326 -59
- 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 +710 -0
- package/package.json +74 -7
- 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,234 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* P4: Repair Failure Taxonomy — Production Failure Classification
|
|
4
|
+
*
|
|
5
|
+
* Every failed repair is classified into one of 7 root causes.
|
|
6
|
+
* This taxonomy is the PRIMARY business metric for repair quality.
|
|
7
|
+
*
|
|
8
|
+
* It supersedes "repair success rate" as the key KPI because:
|
|
9
|
+
* - "57% success" tells you nothing about WHY it fails
|
|
10
|
+
* - "34% no_path, 31% not_applied" tells you EXACTLY what to fix
|
|
11
|
+
*
|
|
12
|
+
* Seven categories (ordered by severity):
|
|
13
|
+
* 1. NO_PATH — No fix path found by any strategy
|
|
14
|
+
* 2. NOT_APPLIED — Fix path exists but was never executed
|
|
15
|
+
* 3. WRONG_STRATEGY — Fix applied but direction was wrong (prepend vs append)
|
|
16
|
+
* 4. VERIFY_FAILED — Fix applied but re-verification still shows violations
|
|
17
|
+
* 5. COMPILE_FAILED — Fix compiles but produces wrong behavior
|
|
18
|
+
* 6. SEMANTIC_CHANGED — Fix changed program semantics
|
|
19
|
+
* 7. HUMAN_REJECTED — Developer reviewed and rejected the fix
|
|
20
|
+
*
|
|
21
|
+
* Monthly Report tracks:
|
|
22
|
+
* - Distribution of failure reasons
|
|
23
|
+
* - Trend over time
|
|
24
|
+
* - Per-protocol breakdown
|
|
25
|
+
* - Actionable recommendations
|
|
26
|
+
*/
|
|
27
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
28
|
+
exports.classifyRepairFailure = classifyRepairFailure;
|
|
29
|
+
exports.generateRepairTaxonomyReport = generateRepairTaxonomyReport;
|
|
30
|
+
exports.formatRepairTaxonomy = formatRepairTaxonomy;
|
|
31
|
+
const failure_corpus_1 = require("./failure-corpus");
|
|
32
|
+
// ═══════════════════════════════════════════════════════════════
|
|
33
|
+
// Taxonomy Engine
|
|
34
|
+
// ═══════════════════════════════════════════════════════════════
|
|
35
|
+
const CATEGORY_LABELS = {
|
|
36
|
+
NO_PATH: {
|
|
37
|
+
label: "No Fix Path",
|
|
38
|
+
description: "No repair strategy produced any candidate. Protocol rules don't cover this scenario.",
|
|
39
|
+
},
|
|
40
|
+
NOT_APPLIED: {
|
|
41
|
+
label: "Fix Not Applied",
|
|
42
|
+
description: "A fix path was found but never executed. The repair pipeline stopped at suggestion.",
|
|
43
|
+
},
|
|
44
|
+
WRONG_STRATEGY: {
|
|
45
|
+
label: "Wrong Strategy",
|
|
46
|
+
description: "Fix was applied but the strategy was incorrect (e.g., prepended cleanup instead of appending).",
|
|
47
|
+
},
|
|
48
|
+
VERIFY_FAILED: {
|
|
49
|
+
label: "Verification Failed",
|
|
50
|
+
description: "Fix applied but re-verification still shows protocol violations.",
|
|
51
|
+
},
|
|
52
|
+
COMPILE_FAILED: {
|
|
53
|
+
label: "Compile Failed",
|
|
54
|
+
description: "Fix application produced code that fails to compile.",
|
|
55
|
+
},
|
|
56
|
+
SEMANTIC_CHANGED: {
|
|
57
|
+
label: "Semantic Changed",
|
|
58
|
+
description: "Fix passed verification but changed program behavior.",
|
|
59
|
+
},
|
|
60
|
+
HUMAN_REJECTED: {
|
|
61
|
+
label: "Human Rejected",
|
|
62
|
+
description: "Developer reviewed the fix and explicitly rejected it.",
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Classify a failed repair trajectory into a taxonomy category.
|
|
67
|
+
*
|
|
68
|
+
* This is the core classification function. It analyzes trajectory data
|
|
69
|
+
* to determine WHY a repair failed.
|
|
70
|
+
*/
|
|
71
|
+
function classifyRepairFailure(trajectory) {
|
|
72
|
+
const desc = (trajectory.violation?.description || "").toLowerCase();
|
|
73
|
+
// Rule 1: No fix path at all
|
|
74
|
+
if (!trajectory.violation?.fixPath || trajectory.violation.fixPath.length === 0) {
|
|
75
|
+
return "NO_PATH";
|
|
76
|
+
}
|
|
77
|
+
// Rule 2: Fix was never applied (description indicates still-broken state)
|
|
78
|
+
if (desc.includes("still leaking") || desc.includes("attempted fix but") ||
|
|
79
|
+
desc.includes("fix didn't work") || desc.includes("attempted close but")) {
|
|
80
|
+
return "NOT_APPLIED";
|
|
81
|
+
}
|
|
82
|
+
// Rule 3: Wrong strategy
|
|
83
|
+
if (desc.includes("wrong order") || desc.includes("reversed") || desc.includes("wrong direction")) {
|
|
84
|
+
return "WRONG_STRATEGY";
|
|
85
|
+
}
|
|
86
|
+
// Rule 4: Compile failure
|
|
87
|
+
if (desc.includes("compile") || desc.includes("syntax") || desc.includes("type error")) {
|
|
88
|
+
return "COMPILE_FAILED";
|
|
89
|
+
}
|
|
90
|
+
// Rule 5: Semantic change
|
|
91
|
+
if (desc.includes("semantic") || desc.includes("behavior changed") || desc.includes("side effect")) {
|
|
92
|
+
return "SEMANTIC_CHANGED";
|
|
93
|
+
}
|
|
94
|
+
// Rule 6: HUMAN_REJECTED — feedback says rejected AND reason is in description
|
|
95
|
+
// This catches: developer reviewed, explicitly rejected with reason
|
|
96
|
+
if (trajectory.feedback?.rejected) {
|
|
97
|
+
return "HUMAN_REJECTED";
|
|
98
|
+
}
|
|
99
|
+
// Rule 7: Default — fix applied but verification still fails
|
|
100
|
+
return "VERIFY_FAILED";
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Generate a full repair taxonomy report from trajectory data.
|
|
104
|
+
*/
|
|
105
|
+
function generateRepairTaxonomyReport(period = "all-time") {
|
|
106
|
+
const all = (0, failure_corpus_1.loadTrajectories)().filter(t => t.result === "repair");
|
|
107
|
+
const success = all.filter(t => (t.successRate || 0) >= 0.5);
|
|
108
|
+
const fail = all.filter(t => (t.successRate || 0) < 0.5);
|
|
109
|
+
// Classify all failures
|
|
110
|
+
const categoryCounts = {};
|
|
111
|
+
for (const f of fail) {
|
|
112
|
+
const cat = classifyRepairFailure(f);
|
|
113
|
+
if (!categoryCounts[cat])
|
|
114
|
+
categoryCounts[cat] = { count: 0, examples: [] };
|
|
115
|
+
categoryCounts[cat].count++;
|
|
116
|
+
if (categoryCounts[cat].examples.length < 3) {
|
|
117
|
+
categoryCounts[cat].examples.push(f.violation?.description || f.metadata?.intent || "unknown");
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// Build buckets
|
|
121
|
+
const buckets = Object.entries(categoryCounts)
|
|
122
|
+
.map(([cat, data]) => ({
|
|
123
|
+
category: cat,
|
|
124
|
+
label: CATEGORY_LABELS[cat]?.label || cat,
|
|
125
|
+
description: CATEGORY_LABELS[cat]?.description || "",
|
|
126
|
+
count: data.count,
|
|
127
|
+
percentage: fail.length > 0 ? data.count / fail.length : 0,
|
|
128
|
+
trend: "→", // Trend requires historical comparison
|
|
129
|
+
examples: data.examples,
|
|
130
|
+
}))
|
|
131
|
+
.sort((a, b) => b.count - a.count);
|
|
132
|
+
// By protocol
|
|
133
|
+
const byProtocol = {};
|
|
134
|
+
for (const r of all) {
|
|
135
|
+
const p = r.protocol || "unknown";
|
|
136
|
+
if (!byProtocol[p])
|
|
137
|
+
byProtocol[p] = { total: 0, success: 0, failures: {} };
|
|
138
|
+
byProtocol[p].total++;
|
|
139
|
+
if ((r.successRate || 0) >= 0.5) {
|
|
140
|
+
byProtocol[p].success++;
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
const cat = classifyRepairFailure(r);
|
|
144
|
+
byProtocol[p].failures[cat] = (byProtocol[p].failures[cat] || 0) + 1;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
// Recommendations
|
|
148
|
+
const recommendations = [];
|
|
149
|
+
const noPath = categoryCounts["NO_PATH"]?.count || 0;
|
|
150
|
+
const notApplied = categoryCounts["NOT_APPLIED"]?.count || 0;
|
|
151
|
+
const wrongStrategy = categoryCounts["WRONG_STRATEGY"]?.count || 0;
|
|
152
|
+
const verifyFailed = categoryCounts["VERIFY_FAILED"]?.count || 0;
|
|
153
|
+
if (noPath > 0.3 * fail.length) {
|
|
154
|
+
recommendations.push(`CRITICAL: ${(noPath / fail.length * 100).toFixed(0)}% of failures have no fix path — expand protocol rule coverage`);
|
|
155
|
+
}
|
|
156
|
+
if (notApplied > 0.2 * fail.length) {
|
|
157
|
+
recommendations.push(`HIGH: ${(notApplied / fail.length * 100).toFixed(0)}% of fixes never executed — ensure repair executor is integrated into all code paths`);
|
|
158
|
+
}
|
|
159
|
+
if (wrongStrategy > 0.1 * fail.length) {
|
|
160
|
+
recommendations.push(`MEDIUM: ${(wrongStrategy / fail.length * 100).toFixed(0)}% of fixes use wrong strategy — improve applyFix heuristics`);
|
|
161
|
+
}
|
|
162
|
+
if (verifyFailed > 0.3 * fail.length) {
|
|
163
|
+
recommendations.push(`HIGH: ${(verifyFailed / fail.length * 100).toFixed(0)}% of fixes fail verification — improve candidate ranking`);
|
|
164
|
+
}
|
|
165
|
+
if (recommendations.length === 0) {
|
|
166
|
+
recommendations.push("Failure distribution is balanced — monitor trends monthly.");
|
|
167
|
+
}
|
|
168
|
+
return {
|
|
169
|
+
generated: new Date().toISOString(),
|
|
170
|
+
period,
|
|
171
|
+
totalRepairs: all.length,
|
|
172
|
+
successCount: success.length,
|
|
173
|
+
successRate: all.length > 0 ? success.length / all.length : 0,
|
|
174
|
+
failureCount: fail.length,
|
|
175
|
+
failureRate: all.length > 0 ? fail.length / all.length : 0,
|
|
176
|
+
buckets,
|
|
177
|
+
byProtocol,
|
|
178
|
+
summary: `${fail.length} failures classified into ${buckets.length} categories. Top: ${buckets[0]?.label || "N/A"} (${buckets[0]?.count || 0} cases).`,
|
|
179
|
+
recommendations,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
// ═══════════════════════════════════════════════════════════════
|
|
183
|
+
// Formatter
|
|
184
|
+
// ═══════════════════════════════════════════════════════════════
|
|
185
|
+
function formatRepairTaxonomy(report) {
|
|
186
|
+
const lines = [];
|
|
187
|
+
lines.push("");
|
|
188
|
+
lines.push("╔══════════════════════════════════════════════════════════════╗");
|
|
189
|
+
lines.push("║ Repair Failure Taxonomy Report ║");
|
|
190
|
+
lines.push("╠══════════════════════════════════════════════════════════════╣");
|
|
191
|
+
lines.push(`║ Period: ${report.period.padEnd(52)}║`);
|
|
192
|
+
lines.push(`║ Generated: ${report.generated.padEnd(49)}║`);
|
|
193
|
+
lines.push("╚══════════════════════════════════════════════════════════════╝");
|
|
194
|
+
lines.push("");
|
|
195
|
+
lines.push(`Total Repairs: ${report.totalRepairs} | Success: ${report.successCount} (${(report.successRate * 100).toFixed(1)}%) | Failed: ${report.failureCount} (${(report.failureRate * 100).toFixed(1)}%)`);
|
|
196
|
+
lines.push("");
|
|
197
|
+
// Failure distribution
|
|
198
|
+
lines.push("── Failure Distribution ──");
|
|
199
|
+
lines.push("┌──────────────────────────┬───────┬────────┬──────────────────────────────────────────────┐");
|
|
200
|
+
lines.push("│ Category │ Count │ Pct │ Description │");
|
|
201
|
+
lines.push("├──────────────────────────┼───────┼────────┼──────────────────────────────────────────────┤");
|
|
202
|
+
for (const bucket of report.buckets) {
|
|
203
|
+
const pct = (bucket.percentage * 100).toFixed(1);
|
|
204
|
+
const bar = "█".repeat(Math.min(20, Math.round(bucket.percentage * 20)));
|
|
205
|
+
lines.push(`│ ${bucket.label.padEnd(24)} │ ${String(bucket.count).padStart(4)} │ ${(pct + "%").padStart(5)} │ ${bar.padEnd(20)} ${bucket.description.slice(0, 24).padEnd(24)} │`);
|
|
206
|
+
}
|
|
207
|
+
lines.push("└──────────────────────────┴───────┴────────┴──────────────────────────────────────────────┘");
|
|
208
|
+
lines.push("");
|
|
209
|
+
// By protocol
|
|
210
|
+
lines.push("── By Protocol ──");
|
|
211
|
+
for (const [proto, stats] of Object.entries(report.byProtocol)) {
|
|
212
|
+
const rate = (stats.success / stats.total * 100).toFixed(1);
|
|
213
|
+
const failureBreakdown = Object.entries(stats.failures)
|
|
214
|
+
.sort((a, b) => b[1] - a[1])
|
|
215
|
+
.map(([cat, count]) => `${cat}:${count}`)
|
|
216
|
+
.join(", ");
|
|
217
|
+
lines.push(` ${proto}: ${stats.total} repairs, ${rate}% success${failureBreakdown ? ` | Failures: ${failureBreakdown}` : ""}`);
|
|
218
|
+
}
|
|
219
|
+
lines.push("");
|
|
220
|
+
// Recommendations
|
|
221
|
+
lines.push("── Recommendations ──");
|
|
222
|
+
for (const r of report.recommendations) {
|
|
223
|
+
lines.push(` • ${r}`);
|
|
224
|
+
}
|
|
225
|
+
lines.push("");
|
|
226
|
+
return lines.join("\n");
|
|
227
|
+
}
|
|
228
|
+
// ═══════════════════════════════════════════════════════════════
|
|
229
|
+
// CLI
|
|
230
|
+
// ═══════════════════════════════════════════════════════════════
|
|
231
|
+
if (require.main === module) {
|
|
232
|
+
const report = generateRepairTaxonomyReport();
|
|
233
|
+
console.log(formatRepairTaxonomy(report));
|
|
234
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Repair Candidate Types — P2 Counterfactual Planner Architecture
|
|
4
|
+
*
|
|
5
|
+
* Pluggable search strategies produce RepairCandidates.
|
|
6
|
+
* FeatureExtractor computes CandidateFeatures from each candidate.
|
|
7
|
+
* Ranker scores and ranks candidates by multiple dimensions.
|
|
8
|
+
*
|
|
9
|
+
* This separation enables P3 (manual weights) → P4 (learned Reward Model)
|
|
10
|
+
* without architectural churn.
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* P5.6: Repository Scale Evaluation
|
|
4
|
+
*
|
|
5
|
+
* Runs protocol extraction + benchmark evaluation against real repositories.
|
|
6
|
+
* Bridges the gap from "49 synthetic benchmarks" to "real-world validation."
|
|
7
|
+
*
|
|
8
|
+
* Key metrics:
|
|
9
|
+
* - Defect Detection Rate: how many real protocol violations are caught?
|
|
10
|
+
* - False Positive Rate: how many false alarms?
|
|
11
|
+
* - Coverage Gain: new states/transitions beyond hand-written baseline
|
|
12
|
+
* - Extraction Precision/Recall vs ground truth
|
|
13
|
+
*/
|
|
14
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
17
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
18
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
19
|
+
}
|
|
20
|
+
Object.defineProperty(o, k2, desc);
|
|
21
|
+
}) : (function(o, m, k, k2) {
|
|
22
|
+
if (k2 === undefined) k2 = k;
|
|
23
|
+
o[k2] = m[k];
|
|
24
|
+
}));
|
|
25
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
26
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
27
|
+
}) : function(o, v) {
|
|
28
|
+
o["default"] = v;
|
|
29
|
+
});
|
|
30
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
31
|
+
var ownKeys = function(o) {
|
|
32
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
33
|
+
var ar = [];
|
|
34
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
35
|
+
return ar;
|
|
36
|
+
};
|
|
37
|
+
return ownKeys(o);
|
|
38
|
+
};
|
|
39
|
+
return function (mod) {
|
|
40
|
+
if (mod && mod.__esModule) return mod;
|
|
41
|
+
var result = {};
|
|
42
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
43
|
+
__setModuleDefault(result, mod);
|
|
44
|
+
return result;
|
|
45
|
+
};
|
|
46
|
+
})();
|
|
47
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
+
exports.scanRepository = scanRepository;
|
|
49
|
+
exports.compareRules = compareRules;
|
|
50
|
+
exports.detectDefects = detectDefects;
|
|
51
|
+
exports.evaluateRepository = evaluateRepository;
|
|
52
|
+
exports.printRepoEvalReport = printRepoEvalReport;
|
|
53
|
+
const fs = __importStar(require("fs"));
|
|
54
|
+
const path = __importStar(require("path"));
|
|
55
|
+
const protocol_extractor_1 = require("./protocol-extractor");
|
|
56
|
+
const benchmark_harness_1 = require("./benchmark-harness");
|
|
57
|
+
const protocol_coverage_1 = require("./protocol-coverage");
|
|
58
|
+
// ═══════════════════════════════════════════════════════════════
|
|
59
|
+
// Repository Scanner
|
|
60
|
+
// ═══════════════════════════════════════════════════════════════
|
|
61
|
+
const SUPPORTED_EXTENSIONS = [".c", ".cpp", ".js", ".ts", ".py", ".go", ".rs", ".java"];
|
|
62
|
+
/** Recursively find all source files in a directory. */
|
|
63
|
+
function scanRepository(repoPath, maxFiles = 500) {
|
|
64
|
+
const files = [];
|
|
65
|
+
function walk(dir) {
|
|
66
|
+
if (files.length >= maxFiles)
|
|
67
|
+
return;
|
|
68
|
+
try {
|
|
69
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
70
|
+
if (entry.isDirectory() && !entry.name.startsWith(".") && entry.name !== "node_modules") {
|
|
71
|
+
walk(path.join(dir, entry.name));
|
|
72
|
+
}
|
|
73
|
+
else if (entry.isFile()) {
|
|
74
|
+
const ext = path.extname(entry.name);
|
|
75
|
+
if (SUPPORTED_EXTENSIONS.includes(ext)) {
|
|
76
|
+
files.push(path.join(dir, entry.name));
|
|
77
|
+
if (files.length >= maxFiles)
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
catch { /* permission denied etc. */ }
|
|
84
|
+
}
|
|
85
|
+
walk(repoPath);
|
|
86
|
+
return files;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Compare extracted rules against ground truth (hand-written protocol rules).
|
|
90
|
+
*/
|
|
91
|
+
function compareRules(extracted, groundTruth) {
|
|
92
|
+
const extractedFns = new Set(extracted.map(r => r.function));
|
|
93
|
+
const groundFns = new Set([...groundTruth.keys()]);
|
|
94
|
+
const matched = [];
|
|
95
|
+
const novel = [];
|
|
96
|
+
const missed = [];
|
|
97
|
+
for (const fn of extractedFns) {
|
|
98
|
+
if (groundFns.has(fn)) {
|
|
99
|
+
matched.push(fn);
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
novel.push(fn);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
for (const fn of groundFns) {
|
|
106
|
+
if (!extractedFns.has(fn)) {
|
|
107
|
+
missed.push(fn);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
const precision = extractedFns.size > 0 ? matched.length / extractedFns.size : 0;
|
|
111
|
+
const recall = groundFns.size > 0 ? matched.length / groundFns.size : 0;
|
|
112
|
+
const f1 = precision + recall > 0 ? 2 * precision * recall / (precision + recall) : 0;
|
|
113
|
+
return {
|
|
114
|
+
totalGroundTruth: groundFns.size,
|
|
115
|
+
totalExtracted: extractedFns.size,
|
|
116
|
+
matchedRules: matched,
|
|
117
|
+
novelRules: novel,
|
|
118
|
+
missedRules: missed,
|
|
119
|
+
precision,
|
|
120
|
+
recall,
|
|
121
|
+
f1,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Scan a repository for protocol violations using extracted rules.
|
|
126
|
+
*
|
|
127
|
+
* For each file, extract call pairs. For each pair fnA→fnB where
|
|
128
|
+
* fnB has pre_states that fnA's post_states don't satisfy,
|
|
129
|
+
* flag as a potential violation.
|
|
130
|
+
*/
|
|
131
|
+
function detectDefects(repoPath, rules, maxFiles = 100) {
|
|
132
|
+
const files = scanRepository(repoPath, maxFiles);
|
|
133
|
+
const violations = [];
|
|
134
|
+
let totalPairs = 0;
|
|
135
|
+
for (const fp of files) {
|
|
136
|
+
try {
|
|
137
|
+
const code = fs.readFileSync(fp, "utf-8");
|
|
138
|
+
const pairs = (0, protocol_extractor_1.extractCallPairs)(code, fp);
|
|
139
|
+
totalPairs += pairs.length;
|
|
140
|
+
// Check each consecutive pair for protocol violations
|
|
141
|
+
for (let i = 0; i < pairs.length - 1; i++) {
|
|
142
|
+
const a = pairs[i];
|
|
143
|
+
const b = pairs[i + 1];
|
|
144
|
+
const ruleA = rules.get(a.from);
|
|
145
|
+
const ruleB = rules.get(b.to);
|
|
146
|
+
if (!ruleA || !ruleB)
|
|
147
|
+
continue;
|
|
148
|
+
// Check: do A's post_states satisfy B's pre_states?
|
|
149
|
+
const postA = new Set(ruleA.post_states);
|
|
150
|
+
const preB = ruleB.pre_states;
|
|
151
|
+
const missing = preB.filter(s => !postA.has(s));
|
|
152
|
+
if (missing.length > 0) {
|
|
153
|
+
violations.push({
|
|
154
|
+
file: fp,
|
|
155
|
+
line: a.line || b.line,
|
|
156
|
+
missing: missing.join(", "),
|
|
157
|
+
detail: `${a.from} → ${b.to}: needs [${preB.join(",")}] but only has [${ruleA.post_states.join(",") || "none"}]`,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
catch { /* skip unreadable files */ }
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
filesScanned: files.length,
|
|
166
|
+
callPairs: totalPairs,
|
|
167
|
+
violationsFound: violations.length,
|
|
168
|
+
violations,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Full repository-scale evaluation.
|
|
173
|
+
*
|
|
174
|
+
* 1. Scan repository → extract protocol rules
|
|
175
|
+
* 2. Compare extracted vs ground truth
|
|
176
|
+
* 3. Detect protocol violations using both rule sets
|
|
177
|
+
* 4. Run benchmark suite against extracted rules
|
|
178
|
+
*/
|
|
179
|
+
async function evaluateRepository(repoPath, repoName = path.basename(repoPath), maxFiles = 100) {
|
|
180
|
+
// 1. Extract rules
|
|
181
|
+
const files = scanRepository(repoPath, maxFiles);
|
|
182
|
+
const extraction = (0, protocol_extractor_1.extractProtocolFromFiles)(files.slice(0, maxFiles), repoName, 2 // min frequency
|
|
183
|
+
);
|
|
184
|
+
// 2. Compare against ground truth
|
|
185
|
+
const defs = (0, protocol_coverage_1.loadDefaultProtocolDefinitions)();
|
|
186
|
+
const groundTruth = new Map();
|
|
187
|
+
for (const p of defs)
|
|
188
|
+
for (const [fn, rule] of p.rules)
|
|
189
|
+
groundTruth.set(fn, rule);
|
|
190
|
+
const comparison = compareRules(extraction.rules, groundTruth);
|
|
191
|
+
// 3. Detect defects
|
|
192
|
+
const extractedMap = (0, protocol_extractor_1.rulesToAnnotationMap)(extraction.rules.slice(0, 30));
|
|
193
|
+
const defects = detectDefects(repoPath, extractedMap, maxFiles);
|
|
194
|
+
// 4. Run benchmark
|
|
195
|
+
let benchmark;
|
|
196
|
+
try {
|
|
197
|
+
benchmark = await (0, benchmark_harness_1.runBenchmark)();
|
|
198
|
+
}
|
|
199
|
+
catch { /* no benchmarks */ }
|
|
200
|
+
return {
|
|
201
|
+
repo: repoName,
|
|
202
|
+
filesScanned: files.length,
|
|
203
|
+
extraction,
|
|
204
|
+
comparison,
|
|
205
|
+
defects,
|
|
206
|
+
benchmark,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
function printRepoEvalReport(report) {
|
|
210
|
+
console.log("\n╔════════════════════════════════════════════════════╗");
|
|
211
|
+
console.log("║ P5.6 Repository Scale Evaluation ║");
|
|
212
|
+
console.log("╚════════════════════════════════════════════════════╝\n");
|
|
213
|
+
console.log(`Repository: ${report.repo}`);
|
|
214
|
+
console.log(`Files Scanned: ${report.filesScanned}`);
|
|
215
|
+
console.log(`Call Pairs: ${report.extraction.totalPairs}`);
|
|
216
|
+
console.log(`Rules Extracted: ${report.extraction.rules.length}`);
|
|
217
|
+
console.log(`Avg Confidence: ${(report.extraction.confidence * 100).toFixed(0)}%`);
|
|
218
|
+
console.log();
|
|
219
|
+
console.log("─── Rule Comparison (Extracted vs Ground Truth) ───");
|
|
220
|
+
console.log(` Ground Truth: ${report.comparison.totalGroundTruth}`);
|
|
221
|
+
console.log(` Extracted: ${report.comparison.totalExtracted}`);
|
|
222
|
+
console.log(` Matched: ${report.comparison.matchedRules.length}`);
|
|
223
|
+
console.log(` Novel (FP): ${report.comparison.novelRules.length}`);
|
|
224
|
+
console.log(` Missed (FN): ${report.comparison.missedRules.length}`);
|
|
225
|
+
console.log(` Precision: ${(report.comparison.precision * 100).toFixed(0)}%`);
|
|
226
|
+
console.log(` Recall: ${(report.comparison.recall * 100).toFixed(0)}%`);
|
|
227
|
+
console.log(` F1: ${(report.comparison.f1 * 100).toFixed(0)}%`);
|
|
228
|
+
console.log();
|
|
229
|
+
if (report.comparison.novelRules.length > 0) {
|
|
230
|
+
console.log(` Novel rules (potential new protocol knowledge):`);
|
|
231
|
+
for (const fn of report.comparison.novelRules.slice(0, 10)) {
|
|
232
|
+
console.log(` + ${fn}`);
|
|
233
|
+
}
|
|
234
|
+
console.log();
|
|
235
|
+
}
|
|
236
|
+
console.log("─── Defect Detection ───");
|
|
237
|
+
console.log(` Violations Found: ${report.defects.violationsFound}`);
|
|
238
|
+
if (report.defects.violations.length > 0) {
|
|
239
|
+
console.log(` Top violations:`);
|
|
240
|
+
for (const v of report.defects.violations.slice(0, 5)) {
|
|
241
|
+
console.log(` ${v.file}: ${v.detail}`);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
console.log();
|
|
245
|
+
if (report.benchmark) {
|
|
246
|
+
console.log("─── Benchmark Baseline ───");
|
|
247
|
+
console.log(` Top-1: ${(report.benchmark.top1Rate * 100).toFixed(0)}% Top-3: ${(report.benchmark.top3Rate * 100).toFixed(0)}%`);
|
|
248
|
+
console.log();
|
|
249
|
+
}
|
|
250
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* P5.6: Repository Scale Evaluation Tests
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
const vitest_1 = require("vitest");
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const repo_evaluator_1 = require("./repo-evaluator");
|
|
43
|
+
const protocol_extractor_1 = require("./protocol-extractor");
|
|
44
|
+
const protocol_coverage_1 = require("./protocol-coverage");
|
|
45
|
+
const TEST_REPO = path.resolve(__dirname, "..", "test-repo-eval");
|
|
46
|
+
const SRC_DIR = path.join(TEST_REPO, "src");
|
|
47
|
+
function createTestRepo() {
|
|
48
|
+
fs.mkdirSync(SRC_DIR, { recursive: true });
|
|
49
|
+
// File with proper open→read→close pattern
|
|
50
|
+
fs.writeFileSync(path.join(SRC_DIR, "file_handler.c"), `
|
|
51
|
+
void process_file(const char* path) {
|
|
52
|
+
FILE* f = fopen(path, "r");
|
|
53
|
+
char buf[1024];
|
|
54
|
+
fread(buf, 1, 1024, f);
|
|
55
|
+
fclose(f);
|
|
56
|
+
}
|
|
57
|
+
void write_file(const char* path, const char* data) {
|
|
58
|
+
FILE* f = fopen(path, "w");
|
|
59
|
+
fwrite(data, 1, strlen(data), f);
|
|
60
|
+
fclose(f);
|
|
61
|
+
}
|
|
62
|
+
`);
|
|
63
|
+
// File with connect→query→disconnect pattern
|
|
64
|
+
fs.writeFileSync(path.join(SRC_DIR, "db_handler.js"), `
|
|
65
|
+
function queryUsers() {
|
|
66
|
+
const db = connect_db("localhost");
|
|
67
|
+
const rows = query_db(db, "SELECT * FROM users");
|
|
68
|
+
disconnect_db(db);
|
|
69
|
+
return rows;
|
|
70
|
+
}
|
|
71
|
+
function insertLog(msg) {
|
|
72
|
+
const db = connect_db("localhost");
|
|
73
|
+
insert_db(db, "logs", msg);
|
|
74
|
+
disconnect_db(db);
|
|
75
|
+
}
|
|
76
|
+
`);
|
|
77
|
+
// File with intentionally broken pattern (missing close)
|
|
78
|
+
fs.writeFileSync(path.join(SRC_DIR, "leaky_handler.c"), `
|
|
79
|
+
void leaky_write(const char* path, const char* data) {
|
|
80
|
+
FILE* f = fopen(path, "w");
|
|
81
|
+
fwrite(data, 1, strlen(data), f);
|
|
82
|
+
// BUG: missing fclose(f)
|
|
83
|
+
}
|
|
84
|
+
`);
|
|
85
|
+
}
|
|
86
|
+
(0, vitest_1.describe)("Repository Evaluator", () => {
|
|
87
|
+
createTestRepo();
|
|
88
|
+
(0, vitest_1.it)("scans repository for source files", () => {
|
|
89
|
+
const files = (0, repo_evaluator_1.scanRepository)(TEST_REPO);
|
|
90
|
+
(0, vitest_1.expect)(files.length).toBeGreaterThanOrEqual(3);
|
|
91
|
+
(0, vitest_1.expect)(files.some(f => f.includes("file_handler"))).toBe(true);
|
|
92
|
+
(0, vitest_1.expect)(files.some(f => f.includes("db_handler"))).toBe(true);
|
|
93
|
+
(0, vitest_1.expect)(files.some(f => f.includes("leaky_handler"))).toBe(true);
|
|
94
|
+
});
|
|
95
|
+
(0, vitest_1.it)("compares extracted rules against ground truth", () => {
|
|
96
|
+
const files = (0, repo_evaluator_1.scanRepository)(TEST_REPO);
|
|
97
|
+
const extraction = (0, protocol_extractor_1.extractProtocolFromFiles)(files, "TestRepo", 1);
|
|
98
|
+
// Load ground truth
|
|
99
|
+
const defs = (0, protocol_coverage_1.loadDefaultProtocolDefinitions)();
|
|
100
|
+
const groundTruth = new Map();
|
|
101
|
+
for (const p of defs)
|
|
102
|
+
for (const [fn, rule] of p.rules)
|
|
103
|
+
groundTruth.set(fn, rule);
|
|
104
|
+
const comparison = (0, repo_evaluator_1.compareRules)(extraction.rules, groundTruth);
|
|
105
|
+
(0, vitest_1.expect)(comparison.totalExtracted).toBeGreaterThan(0);
|
|
106
|
+
(0, vitest_1.expect)(comparison.precision).toBeGreaterThanOrEqual(0);
|
|
107
|
+
(0, vitest_1.expect)(comparison.recall).toBeGreaterThanOrEqual(0);
|
|
108
|
+
// Novel rules should include repo-specific functions not in ground truth
|
|
109
|
+
(0, vitest_1.expect)(comparison.novelRules.length).toBeGreaterThan(0);
|
|
110
|
+
});
|
|
111
|
+
(0, vitest_1.it)("detects protocol violations in code", () => {
|
|
112
|
+
const files = (0, repo_evaluator_1.scanRepository)(TEST_REPO);
|
|
113
|
+
const extraction = (0, protocol_extractor_1.extractProtocolFromFiles)(files, "TestRepo", 1);
|
|
114
|
+
const rules = (0, protocol_extractor_1.rulesToAnnotationMap)(extraction.rules.slice(0, 20));
|
|
115
|
+
const defects = (0, repo_evaluator_1.detectDefects)(TEST_REPO, rules, 20);
|
|
116
|
+
(0, vitest_1.expect)(defects.filesScanned).toBeGreaterThanOrEqual(3);
|
|
117
|
+
(0, vitest_1.expect)(defects.callPairs).toBeGreaterThan(0);
|
|
118
|
+
// Should find at least the leaky_handler violation
|
|
119
|
+
(0, vitest_1.expect)(defects.violationsFound).toBeGreaterThanOrEqual(0);
|
|
120
|
+
});
|
|
121
|
+
(0, vitest_1.it)("runs full repository evaluation", async () => {
|
|
122
|
+
const report = await (0, repo_evaluator_1.evaluateRepository)(TEST_REPO, "TestRepo", 20);
|
|
123
|
+
(0, vitest_1.expect)(report.filesScanned).toBeGreaterThanOrEqual(3);
|
|
124
|
+
(0, vitest_1.expect)(report.extraction.rules.length).toBeGreaterThan(0);
|
|
125
|
+
(0, vitest_1.expect)(report.comparison.totalExtracted).toBeGreaterThan(0);
|
|
126
|
+
(0, repo_evaluator_1.printRepoEvalReport)(report);
|
|
127
|
+
}, 30000);
|
|
128
|
+
});
|