progmune-runtime 2.1.6 → 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.
Files changed (356) hide show
  1. package/README.md +108 -468
  2. package/dist/ablation-study.js +144 -0
  3. package/dist/ablation-study.test.js +18 -0
  4. package/dist/action-runtime.js +3 -1
  5. package/dist/active-learning.js +211 -0
  6. package/dist/analytics.js +139 -0
  7. package/dist/asset-factory.js +309 -0
  8. package/dist/asset-growth.js +244 -0
  9. package/dist/asset-promotion.js +382 -0
  10. package/dist/asset-quality.js +550 -0
  11. package/dist/audit/business-translator.js +285 -0
  12. package/dist/audit/cli.js +66 -0
  13. package/dist/audit/formatters/html.js +379 -0
  14. package/dist/audit/formatters/json.js +11 -0
  15. package/dist/audit/formatters/markdown.js +192 -0
  16. package/dist/audit/formatters/terminal.js +189 -0
  17. package/dist/audit/index.js +25 -0
  18. package/dist/audit/report-builder.js +318 -0
  19. package/dist/audit/types.js +8 -0
  20. package/dist/audit.js +3 -3
  21. package/dist/auto-benchmark-generator.js +137 -0
  22. package/dist/auto-benchmark-generator.test.js +45 -0
  23. package/dist/auto-protocol-synthesizer.js +362 -0
  24. package/dist/auto-protocol-synthesizer.test.js +82 -0
  25. package/dist/autonomous-patch.js +175 -0
  26. package/dist/autonomous-patch.test.js +128 -0
  27. package/dist/badge/badge-server.js +98 -0
  28. package/dist/behavior-miner.js +442 -0
  29. package/dist/belief-layer.js +475 -0
  30. package/dist/benchmark-count.js +5 -0
  31. package/dist/benchmark-generator.js +211 -0
  32. package/dist/benchmark-harness.js +201 -0
  33. package/dist/benchmark-pass-rate.js +7 -0
  34. package/dist/benchmark-report.js +8 -3
  35. package/dist/benchmark-save.js +14 -1
  36. package/dist/bootstrap-validation.js +197 -0
  37. package/dist/bootstrap-validation.test.js +51 -0
  38. package/dist/branch-ledger.js +1 -1
  39. package/dist/capability-gap.js +130 -0
  40. package/dist/certify-html.js +351 -0
  41. package/dist/certify.js +326 -0
  42. package/dist/check.js +4 -4
  43. package/dist/compliance-miner.js +447 -0
  44. package/dist/continuous-benchmark.js +194 -0
  45. package/dist/continuous-benchmark.test.js +116 -0
  46. package/dist/corpus-stats.js +173 -0
  47. package/dist/counterfactual-engine.js +288 -0
  48. package/dist/coverage-dashboard.js +109 -0
  49. package/dist/coverage-system.test.js +205 -0
  50. package/dist/cross-repo-precision.js +352 -0
  51. package/dist/cve-benchmark.js +180 -0
  52. package/dist/cve-benchmark.test.js +28 -0
  53. package/dist/cve-collector.js +73 -0
  54. package/dist/data-quality.js +141 -0
  55. package/dist/decision-engine.js +388 -0
  56. package/dist/derive-metadata.js +250 -0
  57. package/dist/difficulty-active.test.js +198 -0
  58. package/dist/difficulty-map.js +244 -0
  59. package/dist/discovery-analytics.js +125 -0
  60. package/dist/discovery-model.js +149 -0
  61. package/dist/discovery-optimize.test.js +199 -0
  62. package/dist/discovery-trace.js +276 -0
  63. package/dist/discovery-trace.test.js +97 -0
  64. package/dist/emitter.js +83 -1
  65. package/dist/enterprise-dashboard.js +405 -0
  66. package/dist/eval-hardening.js +297 -0
  67. package/dist/eval-hardening.test.js +85 -0
  68. package/dist/evaluation-campaign.js +359 -0
  69. package/dist/evaluation-campaign.test.js +181 -0
  70. package/dist/evidence-growth.js +143 -0
  71. package/dist/evidence-repository.js +209 -0
  72. package/dist/evidence-system.js +441 -0
  73. package/dist/execute.js +15 -7
  74. package/dist/experimental/software-physics.js +291 -0
  75. package/dist/experimental/state-inference.js +516 -0
  76. package/dist/experimental/unsupervised-physics.js +230 -0
  77. package/dist/extract-ir-python.js +54 -7
  78. package/dist/extract-ir.js +376 -12
  79. package/dist/failure-collector.js +2 -2
  80. package/dist/failure-corpus.js +322 -9
  81. package/dist/feedback.js +16 -5
  82. package/dist/feedback.test.js +49 -0
  83. package/dist/file-lock.js +1 -1
  84. package/dist/flywheel-batch.js +292 -0
  85. package/dist/frameworks/express-cli.js +237 -0
  86. package/dist/frameworks/express-detector.js +445 -0
  87. package/dist/frameworks/express-detector.test.js +206 -0
  88. package/dist/frameworks/index.js +30 -0
  89. package/dist/frameworks/nestjs-detector.js +302 -0
  90. package/dist/frameworks/trpc-detector.js +161 -0
  91. package/dist/frameworks/version-awareness.js +179 -0
  92. package/dist/function-synonyms.js +164 -0
  93. package/dist/function-synonyms.test.js +68 -0
  94. package/dist/generalization.test.js +352 -0
  95. package/dist/goal-annotator.js +113 -0
  96. package/dist/goal-planner.js +563 -0
  97. package/dist/gold-cve.js +164 -0
  98. package/dist/gold-cve.test.js +104 -0
  99. package/dist/gold-quality.js +206 -0
  100. package/dist/gold-tiers.js +241 -0
  101. package/dist/governance-dashboard.js +327 -0
  102. package/dist/graph-viz.js +240 -0
  103. package/dist/guided-frontier.js +195 -0
  104. package/dist/hierarchical-planner.js +148 -0
  105. package/dist/identifier-parser.js +260 -0
  106. package/dist/immune-metrics.js +93 -0
  107. package/dist/immune-receiver.js +158 -0
  108. package/dist/immune-reporter.js +1 -1
  109. package/dist/improvement-orchestrator.js +206 -0
  110. package/dist/inject-p0-vocabulary.js +300 -0
  111. package/dist/intent-parser.js +218 -0
  112. package/dist/invariant-algebra.js +476 -0
  113. package/dist/invariant-calculus.js +533 -0
  114. package/dist/ir-utils.js +70 -0
  115. package/dist/ir-utils.test.js +50 -0
  116. package/dist/knowledge-api.js +312 -0
  117. package/dist/knowledge-evolution.js +452 -0
  118. package/dist/knowledge-explorer.js +506 -0
  119. package/dist/knowledge-flywheel.js +274 -0
  120. package/dist/knowledge-governance.js +338 -0
  121. package/dist/knowledge-governance.test.js +150 -0
  122. package/dist/knowledge-graph.js +181 -0
  123. package/dist/knowledge-guided-synth.js +246 -0
  124. package/dist/knowledge-loop.test.js +77 -0
  125. package/dist/knowledge-object.js +316 -0
  126. package/dist/knowledge-package.js +98 -0
  127. package/dist/kpi-dashboard.js +561 -0
  128. package/dist/l3-cross-function.js +280 -0
  129. package/dist/learning-ranker.js +148 -0
  130. package/dist/learning-ranker.test.js +291 -0
  131. package/dist/ledger/accountability.js +322 -0
  132. package/dist/ledger/chain-builder.js +185 -0
  133. package/dist/ledger/cli.js +222 -0
  134. package/dist/ledger/index.js +13 -0
  135. package/dist/ledger/signatures.js +193 -0
  136. package/dist/ledger/types.js +9 -0
  137. package/dist/llm.js +74 -3
  138. package/dist/load-benchmarks.js +8 -3
  139. package/dist/logger.js +66 -0
  140. package/dist/logger.test.js +37 -0
  141. package/dist/logistic-reward.js +339 -0
  142. package/dist/logistic-reward.test.js +180 -0
  143. package/dist/macro-graph.js +193 -0
  144. package/dist/macro-repair.js +183 -0
  145. package/dist/mcp-server.mjs +1202 -483
  146. package/dist/memory-layer.js +42 -5
  147. package/dist/multi-repo-precision.js +422 -0
  148. package/dist/name-free-protocol.js +425 -0
  149. package/dist/name-free-protocol.test.js +170 -0
  150. package/dist/name-scrambling.js +138 -0
  151. package/dist/name-scrambling.test.js +16 -0
  152. package/dist/p3-observability.test.js +281 -0
  153. package/dist/p5-orchestrator.test.js +225 -0
  154. package/dist/pairwise-preference.js +294 -0
  155. package/dist/pairwise-preference.test.js +140 -0
  156. package/dist/planner-constraints.js +104 -0
  157. package/dist/planner-prompts.js +155 -0
  158. package/dist/planner-telemetry.js +415 -0
  159. package/dist/planner-trace.js +214 -0
  160. package/dist/planner.js +162 -167
  161. package/dist/plsb/artifact.js +116 -0
  162. package/dist/plsb/cli.js +71 -0
  163. package/dist/plsb/index.js +19 -0
  164. package/dist/plsb/leaderboard.js +249 -0
  165. package/dist/plsb/report-md.js +156 -0
  166. package/dist/plsb/schema.js +179 -0
  167. package/dist/plsb-benchmark.js +284 -0
  168. package/dist/plsb-benchmark.test.js +119 -0
  169. package/dist/policy/cli.js +134 -0
  170. package/dist/policy/engine.js +333 -0
  171. package/dist/policy/index.js +12 -0
  172. package/dist/policy/types.js +59 -0
  173. package/dist/policy-miner.js +505 -0
  174. package/dist/precision-analyze.js +229 -0
  175. package/dist/precision-benchmark.js +147 -0
  176. package/dist/precision-label-c.js +134 -0
  177. package/dist/precision-label.js +193 -0
  178. package/dist/precision-report-c.js +149 -0
  179. package/dist/precision-report.js +246 -0
  180. package/dist/progmune-status.js +108 -0
  181. package/dist/proof-engine.js +479 -0
  182. package/dist/proof-provenance.js +315 -0
  183. package/dist/protocol-coverage.js +294 -0
  184. package/dist/protocol-detector.js +1189 -0
  185. package/dist/protocol-embedding-expanded.js +297 -0
  186. package/dist/protocol-embedding-expanded.test.js +97 -0
  187. package/dist/protocol-embedding.js +195 -0
  188. package/dist/protocol-embedding.test.js +82 -0
  189. package/dist/protocol-extractor-v2.js +354 -0
  190. package/dist/protocol-extractor-v2.test.js +140 -0
  191. package/dist/protocol-extractor.js +310 -0
  192. package/dist/protocol-extractor.test.js +113 -0
  193. package/dist/protocol-foundation.js +322 -0
  194. package/dist/protocol-foundation.test.js +163 -0
  195. package/dist/protocol-frontier.js +243 -0
  196. package/dist/protocol-frontier.test.js +92 -0
  197. package/dist/protocol-gap-analyzer.js +228 -0
  198. package/dist/protocol-gap-analyzer.test.js +49 -0
  199. package/dist/protocol-invariants.js +276 -0
  200. package/dist/protocol-invariants.test.js +111 -0
  201. package/dist/protocol-knowledge.js +464 -0
  202. package/dist/protocol-miner.js +343 -0
  203. package/dist/protocol-mining.js +207 -0
  204. package/dist/protocol-mining.test.js +37 -0
  205. package/dist/protocol-registry.js +1 -1
  206. package/dist/protocol-security-benchmark.js +222 -0
  207. package/dist/protocol-vulnerability.js +257 -0
  208. package/dist/protocol-vulnerability.test.js +60 -0
  209. package/dist/python-benchmark.js +120 -0
  210. package/dist/python-emitter.js +163 -45
  211. package/dist/python-protocol-extractor.js +187 -0
  212. package/dist/python-protocol-extractor.test.js +116 -0
  213. package/dist/realworld-benchmark.js +646 -0
  214. package/dist/realworld-benchmark.test.js +36 -0
  215. package/dist/repair-arch.test.js +411 -0
  216. package/dist/repair-evolution.test.js +454 -0
  217. package/dist/repair-executor.js +719 -0
  218. package/dist/repair-proposal.js +4 -4
  219. package/dist/repair-ranker.js +141 -0
  220. package/dist/repair-strategies.js +419 -0
  221. package/dist/repair-taxonomy.js +234 -0
  222. package/dist/repair-types.js +12 -0
  223. package/dist/repo-evaluator.js +250 -0
  224. package/dist/repo-evaluator.test.js +128 -0
  225. package/dist/resource-abstraction.js +242 -0
  226. package/dist/resource-detector.js +211 -0
  227. package/dist/result.test.js +43 -0
  228. package/dist/reward-system.js +411 -0
  229. package/dist/reward-system.test.js +175 -0
  230. package/dist/risk-model.js +215 -0
  231. package/dist/rule-miner.js +234 -7
  232. package/dist/rule-specificity.js +254 -0
  233. package/dist/runtime-types.js +27 -0
  234. package/dist/scaffold.js +208 -0
  235. package/dist/scale-collector.test.js +101 -0
  236. package/dist/scale-trajectory-collector.js +128 -0
  237. package/dist/sdk.js +250 -0
  238. package/dist/search-planner.js +4 -41
  239. package/dist/semantic-snapshot.js +1 -1
  240. package/dist/semantic-topology.js +121 -0
  241. package/dist/semantic-trace.js +310 -317
  242. package/dist/sequence-extractor.js +343 -0
  243. package/dist/skill-library.js +245 -0
  244. package/dist/skill-planner.test.js +189 -0
  245. package/dist/software-physics.js +291 -0
  246. package/dist/software-physics.test.js +81 -0
  247. package/dist/ssg-precision.js +478 -0
  248. package/dist/ssg-validator.js +71 -21
  249. package/dist/state-inference-doubleblind.test.js +160 -0
  250. package/dist/state-inference.js +516 -0
  251. package/dist/state-inference.test.js +115 -0
  252. package/dist/state-machine-fingerprint.js +345 -0
  253. package/dist/state-machine-fingerprint.test.js +120 -0
  254. package/dist/state-miner.js +386 -0
  255. package/dist/state-name-inference.js +213 -0
  256. package/dist/state-name-inference.test.js +69 -0
  257. package/dist/strategy-planner.js +262 -96
  258. package/dist/strategy-planner.test.js +135 -0
  259. package/dist/telemetry-analytics.test.js +402 -0
  260. package/dist/terminal-format.js +68 -0
  261. package/dist/terminal-format.test.js +83 -0
  262. package/dist/topology-factory.js +196 -0
  263. package/dist/topology-representation.js +242 -0
  264. package/dist/topology-representation.test.js +27 -0
  265. package/dist/trajectory-augmentation.js +254 -0
  266. package/dist/trajectory-augmentation.test.js +63 -0
  267. package/dist/trajectory-corpus.js +440 -0
  268. package/dist/trajectory-corpus.test.js +32 -0
  269. package/dist/trajectory-feedback.test.js +116 -0
  270. package/dist/transition-synthesizer.js +286 -0
  271. package/dist/transition-synthesizer.test.js +123 -0
  272. package/dist/trust/api-semantic-mapper.js +809 -0
  273. package/dist/trust/call-graph-propagator.js +225 -0
  274. package/dist/trust/cli.js +122 -0
  275. package/dist/trust/compliance-scorer.js +283 -0
  276. package/dist/trust/confidence-calculator.js +261 -0
  277. package/dist/trust/engine.js +1145 -0
  278. package/dist/trust/explainability.js +85 -0
  279. package/dist/trust/formatters/ci.js +42 -0
  280. package/dist/trust/formatters/json.js +11 -0
  281. package/dist/trust/formatters/terminal.js +152 -0
  282. package/dist/trust/index.js +39 -0
  283. package/dist/trust/phase1-verify.js +171 -0
  284. package/dist/trust/protocol-domain-validator.js +697 -0
  285. package/dist/trust/score-calculator.js +282 -0
  286. package/dist/trust/ssg-bridge.js +641 -0
  287. package/dist/trust/ssg-bridge.test.js +269 -0
  288. package/dist/trust/types.js +67 -0
  289. package/dist/trust/violation-trace.js +335 -0
  290. package/dist/trust-api.js +179 -0
  291. package/dist/trust-calibration.js +279 -0
  292. package/dist/unknown-protocol-discovery.js +339 -0
  293. package/dist/unknown-protocol-discovery.test.js +102 -0
  294. package/dist/unsupervised-physics.js +230 -0
  295. package/dist/unsupervised-physics.test.js +95 -0
  296. package/dist/utils.test.js +37 -0
  297. package/dist/validator.js +187 -10
  298. package/dist/verification-intelligence.js +475 -0
  299. package/dist/verify-api.js +432 -0
  300. package/dist/vi-impact-report.js +293 -0
  301. package/dist/wl-fingerprint.js +162 -0
  302. package/dist/wl-fingerprint.test.js +130 -0
  303. package/dist/zeroshot-strategy.js +139 -0
  304. 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
  305. package/docs/Progmune_/351/241/271/347/233/256/345/205/250/350/247/243.html +710 -0
  306. package/package.json +74 -7
  307. package/protocols.json +1956 -50
  308. package/.dockerignore +0 -14
  309. package/.mcp.json +0 -11
  310. package/.progmune_allowlist +0 -50
  311. package/.test_report/test_report.md +0 -87
  312. package/Dockerfile +0 -9
  313. package/FAQ.md +0 -167
  314. package/WHITEPAPER.md +0 -540
  315. package/demo-project/auth.ts +0 -55
  316. package/demo-project/tsconfig.json +0 -8
  317. package/dist/acl-breakdown.js +0 -13
  318. package/dist/all-sessions.js +0 -11
  319. package/dist/antibody-stats.js +0 -11
  320. package/dist/branch-tree-count.js +0 -14
  321. package/dist/common-fixpath.js +0 -12
  322. package/dist/constraint-types.js +0 -12
  323. package/dist/exec-metrics.js +0 -11
  324. package/dist/failure-report.js +0 -11
  325. package/dist/fast-path-hits.js +0 -13
  326. package/dist/fingerprint-list.js +0 -15
  327. package/dist/gen-history-log.js +0 -13
  328. package/dist/heatmap-data.js +0 -11
  329. package/dist/recent-session.js +0 -12
  330. package/dist/svl-distribution.js +0 -11
  331. package/dist/terminal-status.js +0 -11
  332. package/dist/token-savings.js +0 -11
  333. package/dist/total-repairs.js +0 -12
  334. package/dist/unresolved-count.js +0 -12
  335. package/dist/valid-fingerprints.js +0 -13
  336. package/dist/verify-ledgers.js +0 -11
  337. package/docs/whitepaper-style.css +0 -77
  338. package/docs/whitepaper-v2.1.md +0 -609
  339. package/docs/whitepaper-v2.2.md +0 -1064
  340. package/docs/whitepaper-v2.2.pdf +0 -0
  341. package/fly.toml +0 -31
  342. package/public/dashboard.html +0 -119
  343. package/server/hub.js +0 -116
  344. package/test/replay-golden/sess_1780063202050_mgeld.json +0 -9
  345. package/test/replay-golden/sess_1780064032560_gocld.json +0 -354
  346. package/test/replay-golden/sess_1780064413331_s2709.json +0 -606
  347. package/test/replay-golden/sess_1780064792710_y3avo.json +0 -614
  348. package/test/replay-golden.ts +0 -84
  349. package/test_benchmark.js +0 -165
  350. package/test_comprehensive.mjs +0 -638
  351. package/test_concurrency.js +0 -129
  352. package/test_ir_robustness.js +0 -85
  353. package/test_semantic_contracts.js +0 -269
  354. package/test_ssg_stress.js +0 -156
  355. package/test_svl3.js +0 -58
  356. 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
+ });