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,280 @@
1
+ "use strict";
2
+ /**
3
+ * L3 Cross-Function Resource Lifecycle Analysis
4
+ *
5
+ * Same-file alloc/free pairing check.
6
+ * For each function that calls an allocator,
7
+ * verifies there exists a call-graph path to a function that calls
8
+ * the corresponding deallocator.
9
+ *
10
+ * Phase 1: Experimental — curl openssl.c + redis server.c
11
+ */
12
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ var desc = Object.getOwnPropertyDescriptor(m, k);
15
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
16
+ desc = { enumerable: true, get: function() { return m[k]; } };
17
+ }
18
+ Object.defineProperty(o, k2, desc);
19
+ }) : (function(o, m, k, k2) {
20
+ if (k2 === undefined) k2 = k;
21
+ o[k2] = m[k];
22
+ }));
23
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
24
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
25
+ }) : function(o, v) {
26
+ o["default"] = v;
27
+ });
28
+ var __importStar = (this && this.__importStar) || (function () {
29
+ var ownKeys = function(o) {
30
+ ownKeys = Object.getOwnPropertyNames || function (o) {
31
+ var ar = [];
32
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
33
+ return ar;
34
+ };
35
+ return ownKeys(o);
36
+ };
37
+ return function (mod) {
38
+ if (mod && mod.__esModule) return mod;
39
+ var result = {};
40
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
41
+ __setModuleDefault(result, mod);
42
+ return result;
43
+ };
44
+ })();
45
+ Object.defineProperty(exports, "__esModule", { value: true });
46
+ exports.analyzeL3 = analyzeL3;
47
+ exports.runL3Experiment = runL3Experiment;
48
+ const fs = __importStar(require("fs"));
49
+ const path = __importStar(require("path"));
50
+ const ALLOC_FREE_PAIRS = [
51
+ // OpenSSL
52
+ { type: "SSL_CTX", allocPattern: /\bSSL_CTX_new\b/, freePattern: /\bSSL_CTX_free\b/ },
53
+ { type: "SSL", allocPattern: /\bSSL_new\b/, freePattern: /\bSSL_free\b/ },
54
+ { type: "BIO", allocPattern: /\bBIO_new\b/, freePattern: /\bBIO_free\b/ },
55
+ { type: "EVP_PKEY", allocPattern: /\bEVP_PKEY_new\b/, freePattern: /\bEVP_PKEY_free\b/ },
56
+ // curl
57
+ { type: "curl_easy", allocPattern: /\bcurl_easy_init\b/, freePattern: /\bcurl_easy_cleanup\b/ },
58
+ { type: "curl_multi", allocPattern: /\bcurl_multi_init\b/, freePattern: /\bcurl_multi_cleanup\b/ },
59
+ { type: "curl_slist", allocPattern: /\bcurl_slist_append\b/, freePattern: /\bcurl_slist_free_all\b/ },
60
+ // nghttp2
61
+ { type: "nghttp2_session", allocPattern: /\bnghttp2_session_(new|server_new|client_new)\b/, freePattern: /\bnghttp2_session_del\b/ },
62
+ { type: "nghttp2_mem", allocPattern: /\bnghttp2_mem_(malloc|calloc|realloc)\b/, freePattern: /\bnghttp2_mem_free\b/ },
63
+ // libssh
64
+ { type: "ssh_session", allocPattern: /\bssh_(new|session_new)\b/, freePattern: /\bssh_free\b/ },
65
+ { type: "ssh_string", allocPattern: /\bssh_string_(new|from_char)\b/, freePattern: /\bssh_string_(free|burn)\b/ },
66
+ // redis
67
+ { type: "sds", allocPattern: /\bsds(new|newlen|empty|dup)\b/, freePattern: /\bsds(free|clear)\b/ },
68
+ { type: "zmalloc", allocPattern: /\bz(malloc|calloc|realloc|trymalloc)\b/, freePattern: /\bzfree\b/ },
69
+ // nginx
70
+ { type: "ngx_pool", allocPattern: /\bngx_(create_pool|palloc|pcalloc)\b/, freePattern: /\bngx_(destroy_pool|pfree)\b/ },
71
+ { type: "ngx_array", allocPattern: /\bngx_(array_create|array_push)\b/, freePattern: /\bngx_array_destroy\b/ },
72
+ // Apache
73
+ { type: "apr_pool", allocPattern: /\bapr_p(alloc|calloc|create)\b/, freePattern: /\bapr_p(free|ool_destroy|ool_clear)\b/ },
74
+ // Generic C
75
+ { type: "malloc", allocPattern: /\b(malloc|calloc|realloc)\b/, freePattern: /\bfree\b/ },
76
+ ];
77
+ // ── Call Graph ──
78
+ function buildCallGraph(funcs) {
79
+ const callers = new Map();
80
+ const callees = new Map();
81
+ const funcFiles = new Map();
82
+ for (const f of funcs) {
83
+ funcFiles.set(f.name, f.file);
84
+ if (!callees.has(f.name))
85
+ callees.set(f.name, []);
86
+ callees.get(f.name).push(...f.calls);
87
+ for (const c of f.calls) {
88
+ if (!callers.has(c))
89
+ callers.set(c, []);
90
+ callers.get(c).push(f.name);
91
+ }
92
+ }
93
+ return { callers, callees, funcFiles };
94
+ }
95
+ // ── Path Finding (BFS from alloc function to any free function) ──
96
+ function canReach(start, targets, callees, maxDepth = 5) {
97
+ if (targets.includes(start))
98
+ return { reachable: true, path: [start] };
99
+ const visited = new Set();
100
+ const queue = [{ func: start, path: [start] }];
101
+ visited.add(start);
102
+ while (queue.length > 0) {
103
+ const { func, path: currentPath } = queue.shift();
104
+ if (currentPath.length > maxDepth)
105
+ continue;
106
+ const called = callees.get(func) || [];
107
+ for (const c of called) {
108
+ if (targets.includes(c)) {
109
+ return { reachable: true, path: [...currentPath, c] };
110
+ }
111
+ if (!visited.has(c)) {
112
+ visited.add(c);
113
+ queue.push({ func: c, path: [...currentPath, c] });
114
+ }
115
+ }
116
+ }
117
+ return { reachable: false, path: [] };
118
+ }
119
+ function analyzeL3(repo, sequences) {
120
+ const { callees, funcFiles } = buildCallGraph(sequences);
121
+ // Find alloc/free sites
122
+ const allocSites = [];
123
+ const freeSites = [];
124
+ for (const func of sequences) {
125
+ for (const call of func.calls) {
126
+ for (const pair of ALLOC_FREE_PAIRS) {
127
+ if (pair.allocPattern.test(call)) {
128
+ allocSites.push({
129
+ func: func.name,
130
+ file: func.file,
131
+ allocCall: call,
132
+ allocType: pair.type,
133
+ });
134
+ }
135
+ if (pair.freePattern.test(call)) {
136
+ freeSites.push({
137
+ func: func.name,
138
+ file: func.file,
139
+ freeCall: call,
140
+ allocType: pair.type,
141
+ });
142
+ }
143
+ }
144
+ }
145
+ }
146
+ // Group by file
147
+ const fileAllocs = new Map();
148
+ const fileFrees = new Map();
149
+ for (const a of allocSites) {
150
+ if (!fileAllocs.has(a.file))
151
+ fileAllocs.set(a.file, []);
152
+ fileAllocs.get(a.file).push(a);
153
+ }
154
+ for (const f of freeSites) {
155
+ if (!fileFrees.has(f.file))
156
+ fileFrees.set(f.file, []);
157
+ fileFrees.get(f.file).push(f);
158
+ }
159
+ // For each same-file alloc/free pair, check reachability
160
+ const violations = [];
161
+ let sameFilePairs = 0;
162
+ for (const [file, allocs] of fileAllocs) {
163
+ const frees = fileFrees.get(file) || [];
164
+ if (frees.length === 0)
165
+ continue;
166
+ for (const alloc of allocs) {
167
+ // Find matching free functions (same type)
168
+ const matchingFrees = frees.filter(f => f.allocType === alloc.allocType);
169
+ if (matchingFrees.length === 0)
170
+ continue;
171
+ sameFilePairs++;
172
+ const matchingFreeFuncs = matchingFrees.map(f => f.func);
173
+ const { reachable, path: foundPath } = canReach(alloc.func, matchingFreeFuncs, callees);
174
+ if (!reachable) {
175
+ violations.push({
176
+ allocFunc: alloc.func,
177
+ freeFunc: matchingFreeFuncs[0] || null,
178
+ file,
179
+ allocCall: alloc.allocCall,
180
+ allocType: alloc.allocType,
181
+ reason: foundPath.length > 0
182
+ ? `path too deep (${foundPath.length} > 5)`
183
+ : `no path from ${alloc.func} to any of [${matchingFreeFuncs.join(", ")}]`,
184
+ reachableFrees: matchingFreeFuncs,
185
+ });
186
+ }
187
+ }
188
+ }
189
+ return {
190
+ repo,
191
+ totalFuncs: sequences.length,
192
+ allocSites: allocSites.length,
193
+ freeSites: freeSites.length,
194
+ sameFilePairs,
195
+ violations,
196
+ };
197
+ }
198
+ // ── CLI ──
199
+ function runL3Experiment() {
200
+ const BENCH_DIR = path.resolve(__dirname, "..", "benchmarks");
201
+ // Try full IR first, fall back to sequence data
202
+ for (const repo of ["curl"]) {
203
+ const irFile = path.join(BENCH_DIR, repo, "ir.json");
204
+ const seqFile = path.join(BENCH_DIR, `${repo}-sequences.json`);
205
+ let seqs = [];
206
+ if (fs.existsSync(irFile)) {
207
+ const data = JSON.parse(fs.readFileSync(irFile, "utf-8"));
208
+ seqs = (data.functions || []).map((f) => ({
209
+ name: f.name || "",
210
+ file: f.file || "",
211
+ calls: f.calls || [],
212
+ }));
213
+ console.error(`Loaded ${seqs.length} functions from ir.json`);
214
+ }
215
+ else if (fs.existsSync(seqFile)) {
216
+ const data = JSON.parse(fs.readFileSync(seqFile, "utf-8"));
217
+ seqs = (data.sequences || data).map((s) => ({
218
+ name: s.function || "",
219
+ file: s.file || "",
220
+ calls: s.calls || [],
221
+ }));
222
+ console.error(`Loaded ${seqs.length} functions from sequences (no ir.json)`);
223
+ }
224
+ else {
225
+ console.log(`${repo}: no data`);
226
+ continue;
227
+ }
228
+ const result = analyzeL3(repo, seqs);
229
+ console.log(`\n═══ L3 Analysis: ${repo} (FULL IR) ═══`);
230
+ console.log(` Functions: ${result.totalFuncs}`);
231
+ console.log(` Alloc sites: ${result.allocSites}`);
232
+ console.log(` Free sites: ${result.freeSites}`);
233
+ console.log(` Same-file pairs: ${result.sameFilePairs}`);
234
+ console.log(` Unreachable (violations): ${result.violations.length}`);
235
+ // Show top files with violations
236
+ const byFile = new Map();
237
+ for (const v of result.violations) {
238
+ if (!byFile.has(v.file))
239
+ byFile.set(v.file, []);
240
+ byFile.get(v.file).push(v);
241
+ }
242
+ const sortedFiles = [...byFile.entries()].sort((a, b) => b[1].length - a[1].length);
243
+ console.log(`\n Top files with L3 violations:`);
244
+ for (const [file, viols] of sortedFiles.slice(0, 10)) {
245
+ console.log(` ${file}: ${viols.length} violations`);
246
+ // Show most common alloc types
247
+ const types = new Map();
248
+ for (const v of viols) {
249
+ types.set(v.allocType, (types.get(v.allocType) || 0) + 1);
250
+ }
251
+ const topTypes = [...types.entries()].sort((a, b) => b[1] - a[1]).slice(0, 3);
252
+ console.log(` types: ${topTypes.map(([t, c]) => `${t}(${c})`).join(", ")}`);
253
+ }
254
+ // Sample violations from top file
255
+ if (sortedFiles.length > 0) {
256
+ const [topFile, topViols] = sortedFiles[0];
257
+ console.log(`\n Sample violations (${topFile}):`);
258
+ for (const v of topViols.slice(0, 5)) {
259
+ const isKnownFP = /return|caller|library/i.test(v.reason);
260
+ const verdict = isKnownFP ? "FP" : "?";
261
+ console.log(` [${verdict}] ${v.allocFunc} → ${v.allocCall} (${v.allocType})`);
262
+ console.log(` free: [${v.reachableFrees.slice(0, 3).join(", ")}] | ${v.reason}`);
263
+ }
264
+ }
265
+ // Summary: potential TPs vs known FPs
266
+ const potentialTPs = result.violations.filter(v => {
267
+ // Heuristic: functions that allocate and return (not library constructors)
268
+ return !/new$|init$|create$/.test(v.allocFunc) && v.reachableFrees.length <= 3;
269
+ });
270
+ console.log(`\n Summary:`);
271
+ console.log(` Total violations: ${result.violations.length}`);
272
+ console.log(` Potential TPs (narrow free targets): ${potentialTPs.length}`);
273
+ console.log(` FP rate estimate: ${result.violations.length > 0 ? ((1 - potentialTPs.length / result.violations.length) * 100).toFixed(0) : 0}%`);
274
+ console.log();
275
+ }
276
+ }
277
+ // Run if called directly
278
+ if (require.main === module) {
279
+ runL3Experiment();
280
+ }
@@ -0,0 +1,148 @@
1
+ "use strict";
2
+ /**
3
+ * P2.6: Learning Ranker — Feedback-Weighted Ranking
4
+ *
5
+ * Wraps a base Ranker and adjusts scores using real acceptance data
6
+ * from the TelemetryIndex. This is the first self-improving loop:
7
+ *
8
+ * Planner → Feedback → Telemetry → LearningRanker → Better Ranking
9
+ *
10
+ * Architecture:
11
+ * LearningRanker WRAPS Ranker (does not implement it).
12
+ * Base Ranker handles protocolSafety / performance / auditability.
13
+ * LearningRanker adds feedback correction on top.
14
+ *
15
+ * Evolution path:
16
+ * HeuristicRanker (P3) → LearningRanker (P2.6) → RewardModelRanker (P4)
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.LearningRanker = void 0;
20
+ exports.createLearningRanker = createLearningRanker;
21
+ const planner_telemetry_1 = require("./planner-telemetry");
22
+ const repair_ranker_1 = require("./repair-ranker");
23
+ const DEFAULT_CONFIG = {
24
+ baseWeight: 0.7,
25
+ feedbackWeight: 0.3,
26
+ minSamples: 5,
27
+ };
28
+ /**
29
+ * LearningRanker wraps a base CandidateRanker and applies
30
+ * feedback correction from the TelemetryIndex.
31
+ *
32
+ * Usage:
33
+ * const base = createLinearRanker();
34
+ * const learner = new LearningRanker(base, telemetry);
35
+ * const ranked = learner.rank(candidates, features, ctx);
36
+ */
37
+ class LearningRanker {
38
+ constructor(baseRanker, telemetry, config, rewardModel, modelWeight = 0.5) {
39
+ this.base = baseRanker;
40
+ this.telemetry = telemetry;
41
+ this.config = { ...DEFAULT_CONFIG, ...config };
42
+ this.rewardModel = rewardModel;
43
+ this.modelWeight = modelWeight;
44
+ }
45
+ /**
46
+ * Rank candidates by base heuristic score, then adjust
47
+ * using acceptance data from the telemetry index.
48
+ *
49
+ * @param candidates Repair candidates to rank
50
+ * @param features Feature vectors (same index as candidates)
51
+ * @param ctx Search context (for protocol/violationType)
52
+ */
53
+ rank(candidates, features, ctx) {
54
+ // 1. Score with base ranker
55
+ const baseScores = features.map(f => this.base.score(f));
56
+ // 2. Adjust with telemetry feedback + reward model (if available)
57
+ const ranked = candidates.map((c, i) => {
58
+ const fp = this.fingerprintFor(c, ctx);
59
+ const acceptance = this.telemetry.getCandidateAcceptance(fp, this.config.minSamples);
60
+ const effectiveReward = this.telemetry.getCandidateReward(fp, this.config.minSamples);
61
+ const baseScore = baseScores[i];
62
+ let adjustedScore;
63
+ if (this.rewardModel && this.rewardModel.isTrained) {
64
+ // Reward model: blend base + telemetry + model prediction
65
+ const acceptTotal = acceptance;
66
+ const execTotal = this.telemetry.getCandidateStats(fp);
67
+ const execRate = (execTotal.executionSuccess + execTotal.executionFailure) > 0
68
+ ? execTotal.executionSuccess / (execTotal.executionSuccess + execTotal.executionFailure) : 0.5;
69
+ const modelScore = this.rewardModel.score(features[i], { acceptanceRate: acceptTotal, executionSuccessRate: execRate });
70
+ adjustedScore =
71
+ baseScore * this.config.baseWeight * 0.5 +
72
+ effectiveReward * this.config.feedbackWeight * 0.3 +
73
+ modelScore * this.modelWeight;
74
+ }
75
+ else {
76
+ // Fallback: base + telemetry feedback only
77
+ adjustedScore =
78
+ baseScore * this.config.baseWeight +
79
+ effectiveReward * this.config.feedbackWeight;
80
+ }
81
+ return {
82
+ ...c,
83
+ score: adjustedScore,
84
+ acceptance,
85
+ effectiveReward,
86
+ baseScore,
87
+ };
88
+ });
89
+ // 3. Sort by adjusted score descending
90
+ ranked.sort((a, b) => b.score - a.score);
91
+ return ranked;
92
+ }
93
+ /**
94
+ * Single-candidate score (used by backwards-compat code).
95
+ */
96
+ score(candidate, features, ctx) {
97
+ const fp = this.fingerprintFor(candidate, ctx);
98
+ const baseScore = this.base.score(features);
99
+ const effectiveReward = this.telemetry.getCandidateReward(fp, this.config.minSamples);
100
+ return (baseScore * this.config.baseWeight +
101
+ effectiveReward * this.config.feedbackWeight);
102
+ }
103
+ /**
104
+ * Record a single feedback event for incremental learning.
105
+ * Convenience method for integration tests and CLI usage.
106
+ */
107
+ onFeedback(event) {
108
+ const fp = this.fingerprintFor({ id: event.candidateId, source: "protocol", actions: event.fixPath.map(fn => ({ kind: "call", function: fn, args: [] })), explanation: "" }, { protocol: "default", violationType: undefined });
109
+ if (event.accepted) {
110
+ this.telemetry.recordFeedback(event.candidateId, {
111
+ decision: "accepted",
112
+ executionResult: { success: event.accepted, violations: [] },
113
+ timestamp: Date.now(),
114
+ });
115
+ }
116
+ }
117
+ /** Compute the v2 fingerprint for a candidate. */
118
+ fingerprintFor(candidate, ctx) {
119
+ const actions = candidate.actions
120
+ .filter(a => a.kind === "call")
121
+ .map(a => a.function);
122
+ return (0, planner_telemetry_1.candidateFingerprint)(ctx.protocol, actions, ctx.violationType);
123
+ }
124
+ }
125
+ exports.LearningRanker = LearningRanker;
126
+ // ═══════════════════════════════════════════════════════════════
127
+ // Convenience factory
128
+ // ═══════════════════════════════════════════════════════════════
129
+ /**
130
+ * Create a fully wired learning ranker:
131
+ * LinearRanker (base) + TelemetryIndex (feedback) = LearningRanker
132
+ */
133
+ function createLearningRanker(baseRankerOrTelemetry, telemetryOrConfig, compatConfig) {
134
+ // Backward compat: createLearningRanker(baseRanker, telemetry, config)
135
+ if (telemetryOrConfig instanceof planner_telemetry_1.PlannerTelemetry) {
136
+ const base = baseRankerOrTelemetry;
137
+ const telemetry = telemetryOrConfig;
138
+ // Map learningRate/feedbackWindow to baseWeight/feedbackWeight/minSamples
139
+ const config = {};
140
+ if (compatConfig?.learningRate !== undefined)
141
+ config.feedbackWeight = compatConfig.learningRate;
142
+ if (compatConfig?.feedbackWindow !== undefined)
143
+ config.minSamples = compatConfig.feedbackWindow;
144
+ return new LearningRanker(base, telemetry, { ...config, ...compatConfig });
145
+ }
146
+ // New API: createLearningRanker(telemetry, config)
147
+ return new LearningRanker((0, repair_ranker_1.createLinearRanker)(), baseRankerOrTelemetry, telemetryOrConfig);
148
+ }