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,254 @@
1
+ "use strict";
2
+ /**
3
+ * Sprint 13: Rule Specificity Analyzer — attack RULE_TOO_BROAD.
4
+ *
5
+ * Not "optimize VI." Not "add features."
6
+ * Identify the weakest rules and fix them. One sprint, one root cause.
7
+ *
8
+ * Target: RULE_TOO_BROAD 61% → 45%
9
+ *
10
+ * How it works:
11
+ * 1. Load SSG rules from benchmark data
12
+ * 2. Score each rule by discriminative power (specificity, cross-repo, FP rate)
13
+ * 3. Rank weakest rules → these are the FP factories
14
+ * 4. Suggest concrete fixes (add pre_states, add post_states, add invalidate)
15
+ * 5. Output Sprint 13 backlog
16
+ *
17
+ * Usage:
18
+ * npx ts-node --transpile-only src/rule-specificity.ts
19
+ * npx ts-node --transpile-only src/rule-specificity.ts --repo curl
20
+ */
21
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
22
+ if (k2 === undefined) k2 = k;
23
+ var desc = Object.getOwnPropertyDescriptor(m, k);
24
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
25
+ desc = { enumerable: true, get: function() { return m[k]; } };
26
+ }
27
+ Object.defineProperty(o, k2, desc);
28
+ }) : (function(o, m, k, k2) {
29
+ if (k2 === undefined) k2 = k;
30
+ o[k2] = m[k];
31
+ }));
32
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
33
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
34
+ }) : function(o, v) {
35
+ o["default"] = v;
36
+ });
37
+ var __importStar = (this && this.__importStar) || (function () {
38
+ var ownKeys = function(o) {
39
+ ownKeys = Object.getOwnPropertyNames || function (o) {
40
+ var ar = [];
41
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
42
+ return ar;
43
+ };
44
+ return ownKeys(o);
45
+ };
46
+ return function (mod) {
47
+ if (mod && mod.__esModule) return mod;
48
+ var result = {};
49
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
50
+ __setModuleDefault(result, mod);
51
+ return result;
52
+ };
53
+ })();
54
+ Object.defineProperty(exports, "__esModule", { value: true });
55
+ exports.generateSprint13Backlog = generateSprint13Backlog;
56
+ exports.formatSprint13Backlog = formatSprint13Backlog;
57
+ const fs = __importStar(require("fs"));
58
+ const path = __importStar(require("path"));
59
+ const auto_protocol_synthesizer_1 = require("./auto-protocol-synthesizer");
60
+ /**
61
+ * Score a single rule's discriminative power.
62
+ *
63
+ * Weak rules have:
64
+ * - Empty pre_states (matches ANY state)
65
+ * - Single or no post_states (no meaningful state transition)
66
+ * - No invalidate (no resource management)
67
+ */
68
+ function scoreRule(fn, rule, fnFrequency) {
69
+ const preCount = rule.pre_states.length;
70
+ const postCount = rule.post_states.length;
71
+ const hasInvalidate = (rule.invalidate || []).length > 0;
72
+ // Specificity: more pre/post states = more specific = fewer FPs
73
+ // 0 states = 0 points, 1-2 = 30, 3-4 = 60, 5+ = 100
74
+ const totalStates = preCount + postCount + (hasInvalidate ? 1 : 0);
75
+ const specificityScore = Math.min(100, totalStates * 20);
76
+ // Cross-repo: not applicable at rule level — use frequency as proxy
77
+ const freq = fnFrequency.get(fn) || 1;
78
+ const crossRepoScore = Math.min(100, freq * 5); // 20+ occurrences = full score
79
+ // FP contribution estimate: lower specificity → more FPs
80
+ const fpContribution = Math.max(1, Math.round((100 - specificityScore) / 10));
81
+ // Diagnose weakness
82
+ let weakness = "";
83
+ let suggestedFix = "";
84
+ if (preCount === 0 && postCount === 0) {
85
+ weakness = "No states — matches everything";
86
+ suggestedFix = "Add at least 1 pre_state and 1 post_state";
87
+ }
88
+ else if (preCount === 0) {
89
+ weakness = "Empty pre_states — matches any initial state";
90
+ suggestedFix = "Add pre_state from call context (what must be true before this call?)";
91
+ }
92
+ else if (postCount === 0 && !hasInvalidate) {
93
+ weakness = "No post_states or invalidate — no state transition";
94
+ suggestedFix = "Add post_state (what changes after this call?) or invalidate (what does it release?)";
95
+ }
96
+ else if (totalStates <= 2) {
97
+ weakness = `Only ${totalStates} state${totalStates > 1 ? 's' : ''} — too broad`;
98
+ suggestedFix = `Add ${3 - totalStates} more pre/post/invalidate states`;
99
+ }
100
+ else {
101
+ weakness = "Adequate specificity but still producing FPs";
102
+ suggestedFix = "Add negative evidence (forbidden transitions) or context filter";
103
+ }
104
+ // Priority
105
+ let priority = "P2";
106
+ if (specificityScore <= 20)
107
+ priority = "P0";
108
+ else if (specificityScore <= 40)
109
+ priority = "P1";
110
+ return {
111
+ function: fn,
112
+ specificityScore,
113
+ crossRepoScore,
114
+ fpContribution,
115
+ weakness,
116
+ suggestedFix,
117
+ priority,
118
+ };
119
+ }
120
+ // ═══════════════════════════════════════════════════════════════
121
+ // Sprint 13 Backlog Generator
122
+ // ═══════════════════════════════════════════════════════════════
123
+ function generateSprint13Backlog(repoName = "curl") {
124
+ const labelFile = path.join(process.cwd(), "benchmarks", `${repoName}-labels.json`);
125
+ if (!fs.existsSync(labelFile)) {
126
+ throw new Error(`Labels not found: ${labelFile}`);
127
+ }
128
+ const data = JSON.parse(fs.readFileSync(labelFile, "utf-8"));
129
+ const labels = data.labels || {};
130
+ const sequences = data.sequences || {};
131
+ const labeledIndices = Object.keys(labels).map(Number);
132
+ // Get clean sequences
133
+ const cleanSeqs = [];
134
+ for (const idx of labeledIndices) {
135
+ if (labels[idx] === "clean" && sequences[idx]) {
136
+ cleanSeqs.push(sequences[idx]);
137
+ }
138
+ }
139
+ // Generate rules
140
+ const protocols = (0, auto_protocol_synthesizer_1.synthesizeProtocols)(cleanSeqs);
141
+ // Build rules map
142
+ const rules = new Map();
143
+ for (const proto of protocols) {
144
+ for (const r of proto.rules) {
145
+ rules.set(r.function, {
146
+ pre_states: r.pre_states,
147
+ post_states: r.post_states,
148
+ invalidate: r.invalidate,
149
+ namespace: proto.inferredPattern || "discovered",
150
+ });
151
+ }
152
+ }
153
+ // Count function frequency across sequences
154
+ const fnFrequency = new Map();
155
+ for (const seq of cleanSeqs) {
156
+ const seen = new Set();
157
+ for (const fn of seq) {
158
+ if (!seen.has(fn)) {
159
+ fnFrequency.set(fn, (fnFrequency.get(fn) || 0) + 1);
160
+ seen.add(fn);
161
+ }
162
+ }
163
+ }
164
+ // Score all rules
165
+ const scored = [];
166
+ for (const [fn, rule] of rules) {
167
+ scored.push(scoreRule(fn, rule, fnFrequency));
168
+ }
169
+ // Sort: weakest (lowest specificity) first
170
+ scored.sort((a, b) => a.specificityScore - b.specificityScore);
171
+ // Count weak rules (specificity < 40)
172
+ const weakRules = scored.filter(r => r.specificityScore < 40).length;
173
+ const estimatedFPImpact = scored
174
+ .filter(r => r.specificityScore < 40)
175
+ .reduce((s, r) => s + r.fpContribution, 0);
176
+ return {
177
+ repo: repoName,
178
+ totalRules: rules.size,
179
+ weakRules,
180
+ estimatedFPImpact,
181
+ backlog: scored,
182
+ sprintGoal: `Reduce RULE_TOO_BROAD FPs from 61% to 45% by fixing the ${weakRules} weakest rules (est. ${estimatedFPImpact} FP impact)`,
183
+ };
184
+ }
185
+ // ═══════════════════════════════════════════════════════════════
186
+ // Formatter
187
+ // ═══════════════════════════════════════════════════════════════
188
+ function bar(value, max, width = 15) {
189
+ const filled = Math.round((value / max) * width);
190
+ return "█".repeat(filled) + "░".repeat(width - filled);
191
+ }
192
+ function formatSprint13Backlog(b) {
193
+ const lines = [];
194
+ lines.push("");
195
+ lines.push("╔══════════════════════════════════════════════════════════════╗");
196
+ lines.push("║ Sprint 13: Attack RULE_TOO_BROAD ║");
197
+ lines.push("╠══════════════════════════════════════════════════════════════╣");
198
+ lines.push(`║ Repo: ${b.repo}`.padEnd(63) + "║");
199
+ lines.push(`║ Total rules: ${b.totalRules} | Weak rules: ${b.weakRules} | Est. FP impact: ${b.estimatedFPImpact}`.padEnd(63) + "║");
200
+ lines.push("╠══════════════════════════════════════════════════════════════╣");
201
+ lines.push(`║ Goal: ${b.sprintGoal.slice(0, 55)}`.padEnd(63) + "║");
202
+ lines.push("╚══════════════════════════════════════════════════════════════╝");
203
+ lines.push("");
204
+ // P0 — Critical (specificity ≤ 20)
205
+ const p0 = b.backlog.filter(r => r.priority === "P0");
206
+ if (p0.length > 0) {
207
+ lines.push("── P0: Critical (specificity ≤ 20) — Fix these first ──");
208
+ lines.push("");
209
+ for (const r of p0.slice(0, 15)) {
210
+ const specBar = bar(r.specificityScore, 100);
211
+ lines.push(` ${r.function.padEnd(35)} spec:${String(r.specificityScore).padStart(3)} ${specBar} est.${r.fpContribution} FP`);
212
+ lines.push(` Weakness: ${r.weakness}`);
213
+ lines.push(` Fix: ${r.suggestedFix}`);
214
+ lines.push("");
215
+ }
216
+ if (p0.length > 15) {
217
+ lines.push(` ... and ${p0.length - 15} more P0 rules`);
218
+ lines.push("");
219
+ }
220
+ }
221
+ // P1 — High (specificity 21-40)
222
+ const p1 = b.backlog.filter(r => r.priority === "P1");
223
+ if (p1.length > 0) {
224
+ lines.push("── P1: High (specificity 21-40) — Fix in Sprint 13-14 ──");
225
+ lines.push("");
226
+ for (const r of p1.slice(0, 10)) {
227
+ lines.push(` ${r.function.padEnd(35)} spec:${String(r.specificityScore).padStart(3)} ${bar(r.specificityScore, 100)} est.${r.fpContribution} FP`);
228
+ lines.push(` → ${r.suggestedFix}`);
229
+ }
230
+ if (p1.length > 10) {
231
+ lines.push(` ... and ${p1.length - 10} more P1 rules`);
232
+ }
233
+ lines.push("");
234
+ }
235
+ // Summary
236
+ const totalFPImpact = b.backlog.reduce((s, r) => s + r.fpContribution, 0);
237
+ lines.push("── Sprint 13 Completion Criteria ──");
238
+ lines.push(` Fix P0 rules (${p0.length} rules, est. ${p0.reduce((s, r) => s + r.fpContribution, 0)} FP impact)`);
239
+ lines.push(` Fix P1 rules (${p1.length} rules, est. ${p1.reduce((s, r) => s + r.fpContribution, 0)} FP impact)`);
240
+ lines.push(` Total estimated FP reduction: ${p0.reduce((s, r) => s + r.fpContribution, 0) + p1.reduce((s, r) => s + r.fpContribution, 0)}/${b.totalRules} rules`);
241
+ lines.push(` Dashboard K5: RULE_TOO_BROAD 61% → target 45%`);
242
+ lines.push("");
243
+ return lines.join("\n");
244
+ }
245
+ // ═══════════════════════════════════════════════════════════════
246
+ // CLI
247
+ // ═══════════════════════════════════════════════════════════════
248
+ if (require.main === module) {
249
+ const args = process.argv.slice(2);
250
+ const repoIdx = args.findIndex(a => a === "--repo");
251
+ const repo = repoIdx >= 0 ? args[repoIdx + 1] : "curl";
252
+ const backlog = generateSprint13Backlog(repo);
253
+ console.log(formatSprint13Backlog(backlog));
254
+ }
@@ -37,6 +37,9 @@ var __importStar = (this && this.__importStar) || (function () {
37
37
  Object.defineProperty(exports, "__esModule", { value: true });
38
38
  exports.replayLedger = exports.replaySession = exports.getMinimalFixSet = exports.generateRepairSummary = exports.validateProposal = exports.applyProposalAsBranch = exports.suggestInvariantRepair = exports.suggestProtocolRepair = exports.suggestRepairs = exports.describeBranchTree = exports.unwrapBranchTree = exports.wrapAsBranch = exports.findRootBranch = exports.buildBranchMap = exports.replayBranch = exports.getBranchPath = exports.flattenBranch = exports.mergeBranches = exports.forkBranch = exports.createBranch = exports.createRootBranch = exports.registerAllMissingFingerprints = exports.verifyAllFingerprints = exports.verifyFingerprint = exports.getFingerprintRegistry = exports.getFingerprint = exports.registerFingerprint = exports.assertLedgerInvariants = exports.assertTransitionOrder = exports.assertRuleHashMatch = exports.assertDeltaConsistency = exports.assertLedgerConsistency = exports.InvariantViolationError = exports.listAllStates = exports.findTransition = exports.findViolations = exports.findConsumer = exports.findProducer = exports.rejectionToJSON = exports.explainRejection = exports.diffLedgers = exports.hashLedger = exports.hashRules = exports.findFixPathStatic = exports.checkLedgerConsistency = exports.validateTransition = exports.applyTransitionDelta = exports.rebuildState = exports.parseProtocolsFromJSON = exports.StateMachineValidator = void 0;
39
39
  exports.replayWithDetail = void 0;
40
+ exports.mapLegacyFCode = mapLegacyFCode;
41
+ exports.ok = ok;
42
+ exports.err = err;
40
43
  exports.generateAttemptId = generateAttemptId;
41
44
  exports.generateSessionId = generateSessionId;
42
45
  exports.generatePlannerSeed = generatePlannerSeed;
@@ -105,6 +108,30 @@ var deterministic_replay_1 = require("./deterministic-replay");
105
108
  Object.defineProperty(exports, "replaySession", { enumerable: true, get: function () { return deterministic_replay_1.replaySession; } });
106
109
  Object.defineProperty(exports, "replayLedger", { enumerable: true, get: function () { return deterministic_replay_1.replayLedger; } });
107
110
  Object.defineProperty(exports, "replayWithDetail", { enumerable: true, get: function () { return deterministic_replay_1.replayWithDetail; } });
111
+ /** Legacy F-code → ViolationType mapping. */
112
+ function mapLegacyFCode(fCode) {
113
+ const map = {
114
+ F01: "unexported_function",
115
+ F02: "wrong_import_path",
116
+ F03: "type_name_error",
117
+ F04: "wrong_arg_count",
118
+ F05: "wrong_arg_type",
119
+ F06: "undefined_variable",
120
+ F07: "planning_failure",
121
+ F08: "return_type_error",
122
+ F09: "protocol_violation",
123
+ F10: "other",
124
+ };
125
+ return map[fCode] || "other";
126
+ }
127
+ /** Create an Ok result. */
128
+ function ok(value) {
129
+ return { ok: true, value };
130
+ }
131
+ /** Create an Err result. */
132
+ function err(error) {
133
+ return { ok: false, error };
134
+ }
108
135
  // ── ID生成工具 ──
109
136
  function generateAttemptId() {
110
137
  return `att_${Date.now()}_${Math.random().toString(36).slice(2, 7)}`;
@@ -0,0 +1,208 @@
1
+ "use strict";
2
+ /**
3
+ * Phase 9: Scaffold Engine
4
+ *
5
+ * Template-based code generation for full project files.
6
+ * Complements the function-call-chain model (planner) for
7
+ * architecture-level code: Express servers, CLI tools, static sites.
8
+ *
9
+ * Registered as `progmune_scaffold` MCP tool.
10
+ */
11
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ var desc = Object.getOwnPropertyDescriptor(m, k);
14
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
+ desc = { enumerable: true, get: function() { return m[k]; } };
16
+ }
17
+ Object.defineProperty(o, k2, desc);
18
+ }) : (function(o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ o[k2] = m[k];
21
+ }));
22
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
24
+ }) : function(o, v) {
25
+ o["default"] = v;
26
+ });
27
+ var __importStar = (this && this.__importStar) || (function () {
28
+ var ownKeys = function(o) {
29
+ ownKeys = Object.getOwnPropertyNames || function (o) {
30
+ var ar = [];
31
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
32
+ return ar;
33
+ };
34
+ return ownKeys(o);
35
+ };
36
+ return function (mod) {
37
+ if (mod && mod.__esModule) return mod;
38
+ var result = {};
39
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
40
+ __setModuleDefault(result, mod);
41
+ return result;
42
+ };
43
+ })();
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ exports.SCAFFOLD_TYPES = void 0;
46
+ exports.scaffold = scaffold;
47
+ exports.listScaffolds = listScaffolds;
48
+ const fs = __importStar(require("fs"));
49
+ const path = __importStar(require("path"));
50
+ const llm_1 = require("./llm");
51
+ const extract_ir_1 = require("./extract-ir");
52
+ const feedback_1 = require("./feedback");
53
+ const execute_1 = require("./execute");
54
+ // ── Scaffold types ──
55
+ exports.SCAFFOLD_TYPES = [
56
+ "express-api", // Express REST API with SQLite
57
+ "cli-tool", // CLI tool with argument parsing
58
+ "static-site", // HTML/CSS/JS static site
59
+ ];
60
+ const TEMPLATES = {
61
+ "express-api": {
62
+ description: "Express REST API server with SQLite database",
63
+ systemPrompt: `You are a TypeScript Express server generator. Generate complete, production-ready code.
64
+
65
+ RULES:
66
+ - Use express, better-sqlite3
67
+ - Include input validation, proper HTTP status codes, error handling
68
+ - Use TypeScript types everywhere
69
+ - Generate ONLY the server file content, no explanation
70
+ - The code must be complete and runnable
71
+ - Use async/await where appropriate`,
72
+ prerequisiteHint: "Project should have database functions (init, CRUD) and validation utilities defined in separate files.",
73
+ },
74
+ "cli-tool": {
75
+ description: "CLI tool with argument parsing",
76
+ systemPrompt: `You are a TypeScript CLI tool generator. Generate complete, production-ready code.
77
+
78
+ RULES:
79
+ - Parse command-line arguments (process.argv or a simple arg parser)
80
+ - Support --help, --version flags
81
+ - Clear error messages for invalid input
82
+ - Use TypeScript types everywhere
83
+ - Generate ONLY the CLI file content, no explanation
84
+ - The code must be complete and runnable`,
85
+ prerequisiteHint: "Project should have utility functions for the CLI's domain logic.",
86
+ },
87
+ "static-site": {
88
+ description: "Static HTML site with CSS and vanilla JavaScript",
89
+ systemPrompt: `You are a frontend HTML/CSS/JS generator. Generate a complete, self-contained single-file HTML page.
90
+
91
+ RULES:
92
+ - Inline all CSS in <style> and JS in <script> tags
93
+ - Dark theme by default
94
+ - Mobile-responsive (max-width 640px)
95
+ - No external dependencies (no CDN, no framework)
96
+ - No social features, no images, no audio/video
97
+ - Clean, minimal design
98
+ - Generate ONLY the HTML file content, no explanation`,
99
+ prerequisiteHint: "Page should interact with a backend API if specified in the intent.",
100
+ },
101
+ };
102
+ // ── Scaffold engine ──
103
+ async function scaffold(scaffoldType, intent, projectPath, filePath) {
104
+ const template = TEMPLATES[scaffoldType];
105
+ if (!template) {
106
+ return {
107
+ success: false,
108
+ code: "",
109
+ scaffoldType,
110
+ error: `Unknown scaffold type: ${scaffoldType}. Available: ${exports.SCAFFOLD_TYPES.join(", ")}`,
111
+ };
112
+ }
113
+ // 1. Extract IR to understand project context
114
+ let irContext = "";
115
+ try {
116
+ const ir = (0, extract_ir_1.extractIR)(projectPath);
117
+ if (ir.length > 0) {
118
+ const funcList = ir
119
+ .map((f) => ` - ${f.name}(${(f.params || []).map((p) => `${p.name}: ${p.type || "any"}`).join(", ")}): ${f.returnType || "void"}`)
120
+ .join("\n");
121
+ irContext = `\n\nAvailable project functions (from IR):\n${funcList}\n\nYou MUST use these functions where applicable. For imports, use relative paths appropriate for the project structure.`;
122
+ }
123
+ }
124
+ catch { /* IR extraction is best-effort */ }
125
+ // 2. Build prompt
126
+ const fileHint = filePath
127
+ ? `Write the generated code to: ${filePath}`
128
+ : "Return the generated code as the response.";
129
+ const prompt = `${template.systemPrompt}
130
+
131
+ Project: ${path.basename(projectPath)}
132
+ File: ${filePath || "(auto-detect)"}
133
+ Intent: ${intent}
134
+ ${irContext}
135
+
136
+ ${fileHint}
137
+
138
+ Generate the complete file content now. Output ONLY the code, no markdown fences, no explanation.`;
139
+ // 3. Call LLM
140
+ let code;
141
+ try {
142
+ code = await (0, llm_1.generate)(prompt);
143
+ // Strip markdown fences if LLM adds them anyway
144
+ code = code.replace(/^```(?:typescript|javascript|html|ts|js)?\s*\n?/i, "").replace(/\n?```\s*$/i, "").trim();
145
+ }
146
+ catch (e) {
147
+ return {
148
+ success: false,
149
+ code: "",
150
+ scaffoldType,
151
+ error: `LLM generation failed: ${e.message}`,
152
+ };
153
+ }
154
+ if (!code || code.length < 50) {
155
+ return {
156
+ success: false,
157
+ code: "",
158
+ scaffoldType,
159
+ error: "LLM returned empty or too-short response",
160
+ };
161
+ }
162
+ // 4. Add Progmune marker
163
+ const sessionId = `scaffold_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
164
+ let marker = "";
165
+ if (filePath && (filePath.endsWith(".ts") || filePath.endsWith(".tsx"))) {
166
+ marker = `// @progmune-scaffolded type=${scaffoldType} session=${sessionId} timestamp=${new Date().toISOString()}\n\n`;
167
+ }
168
+ else if (filePath && filePath.endsWith(".html")) {
169
+ marker = `<!-- @progmune-scaffolded type=${scaffoldType} session=${sessionId} timestamp=${new Date().toISOString()} -->\n`;
170
+ }
171
+ code = marker + code;
172
+ // 5. Write to file
173
+ if (filePath) {
174
+ const resolved = path.isAbsolute(filePath) ? filePath : path.resolve(projectPath, filePath);
175
+ const dir = path.dirname(resolved);
176
+ if (!fs.existsSync(dir)) {
177
+ fs.mkdirSync(dir, { recursive: true });
178
+ }
179
+ fs.writeFileSync(resolved, code, "utf-8");
180
+ // Record generation for metrics
181
+ (0, execute_1.recordGeneration)({
182
+ sessionId,
183
+ timestamp: Date.now(),
184
+ filePath: resolved,
185
+ repaired: false,
186
+ repairCount: 0,
187
+ irFunctionCount: irContext ? irContext.split("\n").filter(l => l.includes(" - ")).length : 0,
188
+ });
189
+ }
190
+ // Record for immune memory
191
+ try {
192
+ (0, feedback_1.recordRun)(intent, [{ kind: "scaffold", scaffoldType, filePath: filePath || "" }], true);
193
+ }
194
+ catch { /* non-critical */ }
195
+ return {
196
+ success: true,
197
+ code,
198
+ filePath: filePath || undefined,
199
+ scaffoldType,
200
+ };
201
+ }
202
+ /** List available scaffold types with descriptions */
203
+ function listScaffolds() {
204
+ return exports.SCAFFOLD_TYPES.map((t) => ({
205
+ type: t,
206
+ description: TEMPLATES[t].description,
207
+ }));
208
+ }
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ /**
3
+ * Scale Trajectory Collector + Reward Model Integration 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 scale_trajectory_collector_1 = require("./scale-trajectory-collector");
41
+ const learning_ranker_1 = require("./learning-ranker");
42
+ const logistic_reward_1 = require("./logistic-reward");
43
+ const planner_telemetry_1 = require("./planner-telemetry");
44
+ const repair_ranker_1 = require("./repair-ranker");
45
+ const fs = __importStar(require("fs"));
46
+ const path = __importStar(require("path"));
47
+ const SCALE_DIR = path.resolve(__dirname, "..", "test-scale-collector");
48
+ process.env.PROGMUNE_PROJECT_DIR = SCALE_DIR;
49
+ fs.mkdirSync(SCALE_DIR, { recursive: true });
50
+ fs.mkdirSync(path.join(SCALE_DIR, ".progmune_corpus", "telemetry"), { recursive: true });
51
+ fs.mkdirSync(path.join(SCALE_DIR, ".progmune_corpus", "trajectories"), { recursive: true });
52
+ (0, vitest_1.describe)("Scale Trajectory Collector", () => {
53
+ (0, vitest_1.it)("collects 200+ validated trajectories from all sources", () => {
54
+ const { sequences, report } = (0, scale_trajectory_collector_1.collectTrajectoriesAtScale)();
55
+ (0, vitest_1.expect)(report.sourceRepos).toBeGreaterThanOrEqual(20);
56
+ (0, vitest_1.expect)(report.sourceSequences).toBeGreaterThan(50);
57
+ (0, vitest_1.expect)(report.finalCorpusSize).toBeGreaterThan(50);
58
+ // All sequences should be valid physics patterns
59
+ for (const seq of sequences.slice(0, 10)) {
60
+ (0, vitest_1.expect)(seq.length).toBeGreaterThanOrEqual(2);
61
+ }
62
+ (0, scale_trajectory_collector_1.printCollectionReport)(report);
63
+ });
64
+ });
65
+ (0, vitest_1.describe)("Reward Model Integration", () => {
66
+ (0, vitest_1.it)("LearningRanker accepts optional LogisticRewardModel", () => {
67
+ const telemetry = new planner_telemetry_1.PlannerTelemetry(path.join(SCALE_DIR, ".progmune_corpus", "telemetry", `rl-${Date.now()}.jsonl`));
68
+ // Seed some telemetry data
69
+ for (let i = 0; i < 100; i++) {
70
+ const a = ["open_file", "write_file", "close_file"];
71
+ const fp = (0, planner_telemetry_1.candidateFingerprint)("FileProtocol", a, "resource_leak");
72
+ const id = telemetry.recordDecision({
73
+ goal: "write", protocol: "FileProtocol", violationType: "resource_leak",
74
+ candidates: [{ candidateId: fp, source: "protocol", evidenceSources: ["protocol"], actions: a, explanation: "full" }],
75
+ selectedCandidateId: fp,
76
+ });
77
+ telemetry.recordFeedback(id, {
78
+ decision: i < 80 ? "accepted" : "rejected",
79
+ executionResult: i < 80 ? { success: true, violations: [] } : { success: false, violations: ["leak"] },
80
+ timestamp: Date.now(),
81
+ });
82
+ }
83
+ // Train reward model
84
+ const model = logistic_reward_1.LogisticRewardModel.train(telemetry);
85
+ // Create LearningRanker with reward model
86
+ const base = (0, repair_ranker_1.createLinearRanker)();
87
+ const ranker = new learning_ranker_1.LearningRanker(base, telemetry, undefined, model, 0.5);
88
+ (0, vitest_1.expect)(ranker).toBeDefined();
89
+ // Rank candidates
90
+ const candidates = [
91
+ { id: "safe", source: "protocol", actions: [{ kind: "call", function: "open_file", args: [] }, { kind: "call", function: "write_file", args: [] }, { kind: "call", function: "close_file", args: [] }], explanation: "safe" },
92
+ { id: "leaky", source: "corpus", actions: [{ kind: "call", function: "open_file", args: [] }, { kind: "call", function: "write_file", args: [] }], explanation: "leaky" },
93
+ ];
94
+ const ctx = { protocol: "FileProtocol", currentState: ["FILE_OPEN"], targetState: [], violationType: "resource_leak", constraints: [], rules: new Map() };
95
+ const features = candidates.map(c => (0, repair_ranker_1.extractFeatures)(c, ctx));
96
+ const ranked = ranker.rank(candidates, features, { protocol: "FileProtocol", violationType: "resource_leak" });
97
+ (0, vitest_1.expect)(ranked.length).toBe(2);
98
+ // Safe candidate should score higher (was accepted 80% vs leaky rejected)
99
+ (0, vitest_1.expect)(ranked[0].id).toBe("safe");
100
+ });
101
+ });