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.
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 +326 -59
  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,454 @@
1
+ "use strict";
2
+ /**
3
+ * P2→P4 Evolution Path Verification Tests
4
+ *
5
+ * These tests verify that the refactored architecture truly opens
6
+ * the path from Counterfactual Planner → Reward Model.
7
+ *
8
+ * Five architecture-level invariants:
9
+ * 1. Strategy never knows about ranking
10
+ * 2. Same candidate from multiple sources = merged evidence
11
+ * 3. Same candidate ranks differently under different objectives
12
+ * 4. Feedback + cost survive trajectory persistence (P4 pre-burial)
13
+ * 5. Goal → Repair → Feedback → Corpus closed loop (the flywheel)
14
+ */
15
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ var desc = Object.getOwnPropertyDescriptor(m, k);
18
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
19
+ desc = { enumerable: true, get: function() { return m[k]; } };
20
+ }
21
+ Object.defineProperty(o, k2, desc);
22
+ }) : (function(o, m, k, k2) {
23
+ if (k2 === undefined) k2 = k;
24
+ o[k2] = m[k];
25
+ }));
26
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
27
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
28
+ }) : function(o, v) {
29
+ o["default"] = v;
30
+ });
31
+ var __importStar = (this && this.__importStar) || (function () {
32
+ var ownKeys = function(o) {
33
+ ownKeys = Object.getOwnPropertyNames || function (o) {
34
+ var ar = [];
35
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
36
+ return ar;
37
+ };
38
+ return ownKeys(o);
39
+ };
40
+ return function (mod) {
41
+ if (mod && mod.__esModule) return mod;
42
+ var result = {};
43
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
44
+ __setModuleDefault(result, mod);
45
+ return result;
46
+ };
47
+ })();
48
+ Object.defineProperty(exports, "__esModule", { value: true });
49
+ const vitest_1 = require("vitest");
50
+ const fs = __importStar(require("fs"));
51
+ const path = __importStar(require("path"));
52
+ const repair_ranker_1 = require("./repair-ranker");
53
+ const counterfactual_engine_1 = require("./counterfactual-engine");
54
+ const ssg_validator_1 = require("./ssg-validator");
55
+ // ── Helpers ──
56
+ function fileProtocolRules() {
57
+ const protoDef = JSON.parse(fs.readFileSync(path.resolve(__dirname, "..", "protocols.json"), "utf-8"));
58
+ const protocols = (0, ssg_validator_1.parseProtocolsFromJSON)(protoDef);
59
+ const rules = new Map();
60
+ for (const p of protocols)
61
+ rules.set(p.function, p.protocol);
62
+ return rules;
63
+ }
64
+ function fileProtocolContext(targetState) {
65
+ return {
66
+ protocol: "_global",
67
+ currentState: ["FILE_OPEN"],
68
+ targetState: targetState || [],
69
+ violationType: "resource_leak",
70
+ constraints: [],
71
+ rules: fileProtocolRules(),
72
+ };
73
+ }
74
+ // ════════════════════════════════════════════════════════
75
+ // Test 1: Strategy completely unaware of ranking
76
+ // ════════════════════════════════════════════════════════
77
+ class DummyStrategy {
78
+ constructor() {
79
+ this.name = "dummy";
80
+ }
81
+ search(_) {
82
+ return [{
83
+ id: "dummy-1",
84
+ source: "protocol",
85
+ actions: [
86
+ { kind: "call", function: "open_file", args: [] },
87
+ { kind: "call", function: "write_file", args: [] },
88
+ { kind: "call", function: "close_file", args: [] },
89
+ ],
90
+ explanation: "dummy test candidate",
91
+ }];
92
+ }
93
+ }
94
+ (0, vitest_1.describe)("Test 1: Strategy unaware of ranking", () => {
95
+ (0, vitest_1.it)("strategy returns candidates without score or rank", () => {
96
+ const s = new DummyStrategy();
97
+ const result = s.search({});
98
+ (0, vitest_1.expect)(result.length).toBe(1);
99
+ (0, vitest_1.expect)(result[0].score).toBeUndefined();
100
+ (0, vitest_1.expect)(result[0].rank).toBeUndefined();
101
+ // Has required RepairCandidate shape
102
+ (0, vitest_1.expect)(result[0].id).toBeDefined();
103
+ (0, vitest_1.expect)(result[0].source).toBe("protocol");
104
+ (0, vitest_1.expect)(result[0].actions.length).toBe(3);
105
+ (0, vitest_1.expect)(result[0].explanation).toBeDefined();
106
+ });
107
+ (0, vitest_1.it)("future LLMRepairStrategy would not need Ranker changes", () => {
108
+ // Any class implementing CandidateSearchStrategy works
109
+ const iface = new DummyStrategy();
110
+ (0, vitest_1.expect)(iface.name).toBe("dummy");
111
+ (0, vitest_1.expect)(typeof iface.search).toBe("function");
112
+ // The Ranker consumes RepairCandidate[], not strategy-specific types
113
+ const ranker = (0, repair_ranker_1.createLinearRanker)();
114
+ const ctx = {
115
+ protocol: "test", currentState: [], targetState: ["DONE"],
116
+ violationType: "test", constraints: [], rules: new Map(),
117
+ };
118
+ const candidate = iface.search(ctx)[0];
119
+ const features = (0, repair_ranker_1.extractFeatures)(candidate, ctx);
120
+ const score = ranker.score(features);
121
+ (0, vitest_1.expect)(score).toBeGreaterThanOrEqual(0);
122
+ (0, vitest_1.expect)(score).toBeLessThanOrEqual(1);
123
+ });
124
+ });
125
+ // ════════════════════════════════════════════════════════
126
+ // Test 2: Cross-source evidence merging
127
+ // ════════════════════════════════════════════════════════
128
+ (0, vitest_1.describe)("Test 2: Cross-source evidence merge", () => {
129
+ (0, vitest_1.it)("merges identical action sequences from different sources", () => {
130
+ const candidates = [
131
+ {
132
+ id: "corpus-close",
133
+ source: "corpus",
134
+ actions: [{ kind: "call", function: "close_file", args: [] }],
135
+ explanation: "From historical data: close the file",
136
+ evidence: 42,
137
+ metadata: { historicalSuccessRate: 0.85 },
138
+ },
139
+ {
140
+ id: "protocol-close",
141
+ source: "protocol",
142
+ actions: [{ kind: "call", function: "close_file", args: [] }],
143
+ explanation: "From SSG: close_file invalidates FILE_OPEN",
144
+ evidence: 0,
145
+ metadata: { pathLength: 1 },
146
+ },
147
+ {
148
+ id: "antibody-close",
149
+ source: "antibody",
150
+ actions: [{ kind: "call", function: "close_file", args: [] }],
151
+ explanation: "From antibody: resource leak → close_file",
152
+ evidence: 0,
153
+ metadata: { avgSuccessRate: 0.5 },
154
+ },
155
+ ];
156
+ const merged = (0, counterfactual_engine_1.deduplicateCandidates)(candidates);
157
+ (0, vitest_1.expect)(merged.length).toBe(1);
158
+ (0, vitest_1.expect)(merged[0].evidenceSources).toBeDefined();
159
+ (0, vitest_1.expect)(merged[0].evidenceSources.sort()).toEqual(["antibody", "corpus", "protocol"]);
160
+ // Evidence count takes max from all sources
161
+ (0, vitest_1.expect)(merged[0].evidence).toBe(42);
162
+ // Metadata merges: highest historicalSuccessRate survives
163
+ (0, vitest_1.expect)(merged[0].metadata?.historicalSuccessRate).toBe(0.85);
164
+ });
165
+ (0, vitest_1.it)("single-source candidate has evidenceSources = [source]", () => {
166
+ const candidates = [{
167
+ id: "solo",
168
+ source: "protocol",
169
+ actions: [{ kind: "call", function: "verify_email", args: [] }],
170
+ explanation: "Only from protocol",
171
+ }];
172
+ const merged = (0, counterfactual_engine_1.deduplicateCandidates)(candidates);
173
+ (0, vitest_1.expect)(merged.length).toBe(1);
174
+ (0, vitest_1.expect)(merged[0].evidenceSources).toEqual(["protocol"]);
175
+ });
176
+ (0, vitest_1.it)("different action sequences stay separate", () => {
177
+ const candidates = [
178
+ {
179
+ id: "a", source: "protocol",
180
+ actions: [{ kind: "call", function: "close_file", args: [] }],
181
+ explanation: "close",
182
+ },
183
+ {
184
+ id: "b", source: "corpus",
185
+ actions: [
186
+ { kind: "call", function: "flush", args: [] },
187
+ { kind: "call", function: "close_file", args: [] },
188
+ ],
189
+ explanation: "flush then close",
190
+ },
191
+ ];
192
+ const merged = (0, counterfactual_engine_1.deduplicateCandidates)(candidates);
193
+ (0, vitest_1.expect)(merged.length).toBe(2);
194
+ // Each has its own evidenceSources
195
+ for (const m of merged) {
196
+ (0, vitest_1.expect)(m.evidenceSources.length).toBe(1);
197
+ }
198
+ });
199
+ });
200
+ // ════════════════════════════════════════════════════════
201
+ // Test 3: Ranking mode switching
202
+ // ════════════════════════════════════════════════════════
203
+ (0, vitest_1.describe)("Test 3: Ranking mode switching", () => {
204
+ const safeCandidate = {
205
+ id: "safe", source: "protocol",
206
+ actions: [
207
+ { kind: "call", function: "open_file", args: [] },
208
+ { kind: "call", function: "write_file", args: [] },
209
+ { kind: "call", function: "close_file", args: [] },
210
+ ],
211
+ explanation: "Safe: full open-write-close sequence",
212
+ };
213
+ const fastCandidate = {
214
+ id: "fast", source: "corpus",
215
+ actions: [
216
+ { kind: "call", function: "atomic_write", args: [] },
217
+ ],
218
+ explanation: "Fast: single atomic operation",
219
+ evidence: 42,
220
+ metadata: { historicalSuccessRate: 0.99, corpusEvidenceCount: 42 },
221
+ };
222
+ const safeFeatures = {
223
+ protocolSafety: 1.0,
224
+ historicalSuccessRate: 0.5,
225
+ actionCount: 3,
226
+ latencyCost: 0.6,
227
+ auditability: 0.8,
228
+ corpusEvidence: 0,
229
+ source: "protocol",
230
+ goalMatch: 0,
231
+ };
232
+ const fastFeatures = {
233
+ protocolSafety: 0.7,
234
+ historicalSuccessRate: 0.99,
235
+ actionCount: 1,
236
+ latencyCost: 0.1,
237
+ auditability: 0.5,
238
+ corpusEvidence: 42,
239
+ source: "corpus",
240
+ goalMatch: 0,
241
+ };
242
+ (0, vitest_1.it)("ranks safe higher under safety objective", () => {
243
+ const ranker = (0, repair_ranker_1.createLinearRanker)();
244
+ const ranked = ranker.rankSafety([fastCandidate, safeCandidate], [fastFeatures, safeFeatures]);
245
+ (0, vitest_1.expect)(ranked[0].id).toBe("safe");
246
+ });
247
+ (0, vitest_1.it)("ranks fast higher under performance objective", () => {
248
+ const ranker = (0, repair_ranker_1.createLinearRanker)();
249
+ const ranked = ranker.rankPerformance([safeCandidate, fastCandidate], [safeFeatures, fastFeatures]);
250
+ (0, vitest_1.expect)(ranked[0].id).toBe("fast");
251
+ });
252
+ (0, vitest_1.it)("different objectives produce different orderings", () => {
253
+ const ranker = (0, repair_ranker_1.createLinearRanker)();
254
+ const bySafety = ranker.rankSafety([safeCandidate, fastCandidate], [safeFeatures, fastFeatures]);
255
+ const byPerf = ranker.rankPerformance([safeCandidate, fastCandidate], [safeFeatures, fastFeatures]);
256
+ // Same candidates, different orderings
257
+ (0, vitest_1.expect)(bySafety[0].id).not.toBe(byPerf[0].id);
258
+ });
259
+ (0, vitest_1.it)("future RewardModelRanker would use same interface", () => {
260
+ // The Ranker interface is { score(features: CandidateFeatures): number }
261
+ // Any implementation works — linear weights, learned model, etc.
262
+ const ranker = (0, repair_ranker_1.createLinearRanker)();
263
+ const score = ranker.score(safeFeatures);
264
+ (0, vitest_1.expect)(score).toBeGreaterThanOrEqual(0);
265
+ (0, vitest_1.expect)(score).toBeLessThanOrEqual(1);
266
+ });
267
+ });
268
+ // ════════════════════════════════════════════════════════
269
+ // Test 4: P4 pre-burial — feedback + cost persistence
270
+ // ════════════════════════════════════════════════════════
271
+ // Set env BEFORE importing from failure-corpus
272
+ const FEEDBACK_DIR = path.resolve(__dirname, "..", "test-evolution-feedback");
273
+ process.env.PROGMUNE_PROJECT_DIR = FEEDBACK_DIR;
274
+ fs.mkdirSync(FEEDBACK_DIR, { recursive: true });
275
+ fs.mkdirSync(path.join(FEEDBACK_DIR, ".progmune_corpus"), { recursive: true });
276
+ fs.mkdirSync(path.join(FEEDBACK_DIR, ".progmune_corpus", "trajectories"), { recursive: true });
277
+ const failure_corpus_1 = require("./failure-corpus");
278
+ // ── Wait helper (recordTrajectory writes via setImmediate) ──
279
+ function flushWrites() {
280
+ return new Promise(resolve => setImmediate(resolve));
281
+ }
282
+ (0, vitest_1.describe)("Test 4: P4 pre-burial", () => {
283
+ (0, vitest_1.it)("feedback {accepted, rejected} survives write→read roundtrip", async () => {
284
+ const uniqueSig = `test-evo-accepted-${Date.now()}`;
285
+ (0, failure_corpus_1.recordTrajectory)({
286
+ protocol: "FileProtocol",
287
+ initialState: ["FILE_OPEN"],
288
+ finalState: [],
289
+ trajectory: ["open_file", "write_file", "close_file"],
290
+ result: "repair",
291
+ violationType: "resource_leak",
292
+ violationDesc: uniqueSig,
293
+ fixPath: ["close_file"],
294
+ successRate: 1.0,
295
+ source: "planner",
296
+ feedback: { accepted: true, rejected: false },
297
+ cost: { latency: 12, actions: 3 },
298
+ });
299
+ await flushWrites();
300
+ const loaded = (0, failure_corpus_1.loadTrajectories)();
301
+ const repair = loaded.find(t => t.result === "repair" && t.violation?.description === uniqueSig);
302
+ (0, vitest_1.expect)(repair).toBeDefined();
303
+ (0, vitest_1.expect)(repair.feedback?.accepted).toBe(true);
304
+ (0, vitest_1.expect)(repair.feedback?.rejected).toBe(false);
305
+ (0, vitest_1.expect)(repair.cost?.latency).toBe(12);
306
+ (0, vitest_1.expect)(repair.cost?.actions).toBe(3);
307
+ });
308
+ (0, vitest_1.it)("rejected repair is also recorded", async () => {
309
+ const uniqueSig = `test-evo-rejected-${Date.now()}`;
310
+ (0, failure_corpus_1.recordTrajectory)({
311
+ protocol: "FileProtocol",
312
+ initialState: ["FILE_OPEN"],
313
+ finalState: ["FILE_OPEN"],
314
+ trajectory: ["open_file", "write_file"],
315
+ result: "repair",
316
+ violationType: "resource_leak",
317
+ violationDesc: uniqueSig,
318
+ fixPath: ["close_file"],
319
+ successRate: 0.0,
320
+ source: "llm",
321
+ feedback: { accepted: false, rejected: true },
322
+ cost: { latency: 7, actions: 2 },
323
+ });
324
+ await flushWrites();
325
+ const loaded = (0, failure_corpus_1.loadTrajectories)();
326
+ const rejected = loaded.filter(t => t.result === "repair" && t.feedback?.rejected === true && t.violation?.description === uniqueSig);
327
+ (0, vitest_1.expect)(rejected.length).toBe(1);
328
+ (0, vitest_1.expect)(rejected[0].cost?.latency).toBe(7);
329
+ });
330
+ (0, vitest_1.it)("getRepairStats aggregates feedback for P4 Reward Model", async () => {
331
+ (0, failure_corpus_1.recordTrajectory)({
332
+ protocol: "AuthProtocol",
333
+ initialState: ["UNAUTHENTICATED"],
334
+ finalState: ["SESSION_ACTIVE"],
335
+ trajectory: ["verify_password", "generate_jwt", "create_session"],
336
+ result: "repair",
337
+ violationType: "missing_prerequisite",
338
+ violationDesc: "Skipped verification",
339
+ fixPath: ["verify_password"],
340
+ successRate: 1.0,
341
+ source: "planner",
342
+ feedback: { accepted: true, rejected: false },
343
+ cost: { latency: 25, actions: 3 },
344
+ });
345
+ await flushWrites();
346
+ const stats = (0, failure_corpus_1.getRepairStats)();
347
+ (0, vitest_1.expect)(stats.totalRepairs).toBeGreaterThanOrEqual(3);
348
+ (0, vitest_1.expect)(stats.acceptedRepairs).toBeGreaterThanOrEqual(2);
349
+ (0, vitest_1.expect)(stats.rejectedRepairs).toBeGreaterThanOrEqual(1);
350
+ (0, vitest_1.expect)(stats.acceptanceRate).toBeGreaterThan(0);
351
+ (0, vitest_1.expect)(stats.acceptanceRate).toBeLessThanOrEqual(1);
352
+ (0, vitest_1.expect)(stats.avgLatency).toBeGreaterThan(0);
353
+ });
354
+ });
355
+ // ════════════════════════════════════════════════════════
356
+ // Test 5: Goal → Repair → Feedback → Corpus closed loop
357
+ // ════════════════════════════════════════════════════════
358
+ // Separate corpus dir for the flywheel test
359
+ const FLYWHEEL_DIR = path.resolve(__dirname, "..", "test-evolution-flywheel");
360
+ fs.mkdirSync(FLYWHEEL_DIR, { recursive: true });
361
+ const flywheelCorpus = path.join(FLYWHEEL_DIR, ".progmune_corpus");
362
+ fs.mkdirSync(flywheelCorpus, { recursive: true });
363
+ fs.mkdirSync(path.join(flywheelCorpus, "trajectories"), { recursive: true });
364
+ (0, vitest_1.describe)("Test 5: Goal → Repair → Feedback → Corpus flywheel", () => {
365
+ (0, vitest_1.it)("accepted repair feeds back into corpus as future evidence", async () => {
366
+ // Point to flywheel corpus for this test
367
+ process.env.PROGMUNE_PROJECT_DIR = FLYWHEEL_DIR;
368
+ const flywheelId = `flywheel-accepted-${Date.now()}`;
369
+ // Step 1: Generate a repair plan via the Planner
370
+ const rules = fileProtocolRules();
371
+ const alts = await (0, counterfactual_engine_1.suggestAlternatives)({
372
+ violation: {
373
+ svl: 4,
374
+ violatedConstraint: "resource_leak",
375
+ actionIndex: 2,
376
+ currentStates: ["FILE_OPEN"],
377
+ requiredStates: [],
378
+ description: "File not closed after write",
379
+ },
380
+ protocol: "_global",
381
+ currentState: ["FILE_OPEN"],
382
+ targetState: [],
383
+ constraints: [],
384
+ rules,
385
+ });
386
+ (0, vitest_1.expect)(alts.length).toBeGreaterThan(0);
387
+ const topRepair = alts[0];
388
+ // Step 2: Simulate user accepting the repair
389
+ (0, failure_corpus_1.recordTrajectory)({
390
+ protocol: "FileProtocol",
391
+ initialState: ["FILE_OPEN"],
392
+ finalState: [],
393
+ trajectory: ["open_file", "write_file", ...topRepair.fixPath],
394
+ result: "repair",
395
+ violationType: "resource_leak",
396
+ violationDesc: flywheelId,
397
+ fixPath: topRepair.fixPath,
398
+ successRate: 1.0,
399
+ source: "planner",
400
+ intent: "safely write config file",
401
+ feedback: { accepted: true, rejected: false },
402
+ cost: { latency: 15, actions: topRepair.fixPath.length + 2 },
403
+ });
404
+ await flushWrites();
405
+ // Step 3: Verify corpus has the accepted repair
406
+ const loaded = (0, failure_corpus_1.loadTrajectories)();
407
+ const repairs = loaded.filter(t => t.result === "repair" && t.violation?.description === flywheelId);
408
+ (0, vitest_1.expect)(repairs.length).toBe(1);
409
+ (0, vitest_1.expect)(repairs[0].feedback?.accepted).toBe(true);
410
+ (0, vitest_1.expect)(repairs[0].metadata.intent).toBe("safely write config file");
411
+ (0, vitest_1.expect)(repairs[0].violation?.fixPath?.length).toBeGreaterThan(0);
412
+ // Step 4: The flywheel is spinning
413
+ // Goal → Planner → Repair → Accepted → Corpus → (future) Planner
414
+ const stats = {
415
+ accepted: repairs.length,
416
+ hasIntent: repairs.filter(r => r.metadata.intent).length,
417
+ hasFixPath: repairs.filter(r => r.violation?.fixPath?.length).length,
418
+ };
419
+ (0, vitest_1.expect)(stats.accepted).toBeGreaterThanOrEqual(1);
420
+ (0, vitest_1.expect)(stats.hasIntent).toBeGreaterThanOrEqual(1);
421
+ (0, vitest_1.expect)(stats.hasFixPath).toBeGreaterThanOrEqual(1);
422
+ });
423
+ (0, vitest_1.it)("rejected repair also feeds the flywheel (negative signal)", async () => {
424
+ process.env.PROGMUNE_PROJECT_DIR = FLYWHEEL_DIR;
425
+ const flywheelId = `flywheel-rejected-${Date.now()}`;
426
+ (0, failure_corpus_1.recordTrajectory)({
427
+ protocol: "FileProtocol",
428
+ initialState: ["FILE_OPEN"],
429
+ finalState: ["FILE_OPEN"], // still open — repair failed
430
+ trajectory: ["open_file", "write_file"],
431
+ result: "repair",
432
+ violationType: "resource_leak",
433
+ violationDesc: flywheelId,
434
+ fixPath: [],
435
+ successRate: 0.0,
436
+ source: "llm",
437
+ intent: "safely write config file",
438
+ feedback: { accepted: false, rejected: true },
439
+ cost: { latency: 8, actions: 2 },
440
+ });
441
+ await flushWrites();
442
+ const loaded = (0, failure_corpus_1.loadTrajectories)();
443
+ const myRecord = loaded.filter(t => t.violation?.description === flywheelId);
444
+ (0, vitest_1.expect)(myRecord.length).toBe(1);
445
+ (0, vitest_1.expect)(myRecord[0].feedback?.accepted).toBe(false);
446
+ (0, vitest_1.expect)(myRecord[0].feedback?.rejected).toBe(true);
447
+ // Both signals present — P4 Reward Model can learn from both
448
+ const allRepairs = loaded.filter(t => t.result === "repair");
449
+ const accepted = allRepairs.filter(t => t.feedback?.accepted === true).length;
450
+ const rejected = allRepairs.filter(t => t.feedback?.rejected === true).length;
451
+ (0, vitest_1.expect)(accepted).toBeGreaterThanOrEqual(1);
452
+ (0, vitest_1.expect)(rejected).toBeGreaterThanOrEqual(1);
453
+ });
454
+ });