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,180 @@
1
+ "use strict";
2
+ /**
3
+ * P4.0: Logistic Reward Model Tests
4
+ *
5
+ * Verifying:
6
+ * 1. Model trains on telemetry data and converges
7
+ * 2. Feature importance is interpretable
8
+ * 3. Score produces valid probabilities [0,1]
9
+ * 4. Off-policy comparison shows improvement over baseline
10
+ * 5. Export/import roundtrip preserves weights
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
+ const vitest_1 = require("vitest");
47
+ const fs = __importStar(require("fs"));
48
+ const path = __importStar(require("path"));
49
+ const logistic_reward_1 = require("./logistic-reward");
50
+ const planner_telemetry_1 = require("./planner-telemetry");
51
+ const LR_DIR = path.resolve(__dirname, "..", "test-logistic-reward");
52
+ process.env.PROGMUNE_PROJECT_DIR = LR_DIR;
53
+ fs.mkdirSync(LR_DIR, { recursive: true });
54
+ fs.mkdirSync(path.join(LR_DIR, ".progmune_corpus", "telemetry"), { recursive: true });
55
+ function seedTrainingData(telemetry, samples) {
56
+ // Pattern: safe repairs (close_file) are usually accepted + executed successfully
57
+ // Pattern: leaky repairs (skip close) are usually rejected or fail execution
58
+ for (let i = 0; i < samples; i++) {
59
+ const safe = i % 3 !== 0; // 2/3 are safe repairs
60
+ const fp = safe
61
+ ? (0, planner_telemetry_1.candidateFingerprint)("FileProtocol", ["open_file", "write_file", "close_file"], "resource_leak")
62
+ : (0, planner_telemetry_1.candidateFingerprint)("FileProtocol", ["open_file", "write_file"], "resource_leak");
63
+ const id = telemetry.recordDecision({
64
+ goal: `train goal ${i}`,
65
+ protocol: "FileProtocol", violationType: "resource_leak",
66
+ candidates: [
67
+ { candidateId: fp, source: "protocol", evidenceSources: ["protocol"],
68
+ actions: safe ? ["open_file", "write_file", "close_file"] : ["open_file", "write_file"],
69
+ explanation: safe ? "safe close" : "skip close" },
70
+ ],
71
+ selectedCandidateId: fp,
72
+ });
73
+ // Safe: 90% accepted + executed. Leaky: 80% rejected.
74
+ const acceptRoll = Math.random();
75
+ if (safe) {
76
+ const accepted = acceptRoll < 0.9;
77
+ telemetry.recordFeedback(id, {
78
+ decision: accepted ? "accepted" : "rejected",
79
+ executionResult: accepted ? { success: true, violations: [] } : { success: false, violations: ["resource_leak"] },
80
+ timestamp: Date.now(),
81
+ });
82
+ }
83
+ else {
84
+ const accepted = acceptRoll < 0.2;
85
+ telemetry.recordFeedback(id, {
86
+ decision: accepted ? "accepted" : "rejected",
87
+ executionResult: accepted ? { success: false, violations: ["resource_leak"] } : undefined,
88
+ timestamp: Date.now(),
89
+ });
90
+ }
91
+ }
92
+ }
93
+ (0, vitest_1.describe)("LogisticRewardModel", () => {
94
+ (0, vitest_1.it)("trains on telemetry data and converges", () => {
95
+ const telemetry = new planner_telemetry_1.PlannerTelemetry(path.join(LR_DIR, ".progmune_corpus", "telemetry", `lr-train-${Date.now()}.jsonl`));
96
+ seedTrainingData(telemetry, 200);
97
+ const model = logistic_reward_1.LogisticRewardModel.train(telemetry);
98
+ (0, vitest_1.expect)(model.isTrained).toBe(true);
99
+ (0, vitest_1.expect)(model.sampleCount).toBeGreaterThanOrEqual(50);
100
+ (0, vitest_1.expect)(model.finalLoss).toBeLessThan(1.0); // should be better than random
101
+ // Weights should be non-zero after training
102
+ (0, vitest_1.expect)(model.weights.some(w => Math.abs(w) > 1e-6)).toBe(true);
103
+ model.printWeights();
104
+ });
105
+ (0, vitest_1.it)("produces valid probability scores [0,1]", () => {
106
+ const telemetry = new planner_telemetry_1.PlannerTelemetry(path.join(LR_DIR, ".progmune_corpus", "telemetry", `lr-score-${Date.now()}.jsonl`));
107
+ seedTrainingData(telemetry, 100);
108
+ const model = logistic_reward_1.LogisticRewardModel.train(telemetry);
109
+ // Safe repair should score higher than leaky repair
110
+ const safeFeatures = {
111
+ protocolSafety: 1.0, historicalSuccessRate: 0.8, actionCount: 3,
112
+ latencyCost: 0.4, auditability: 0.75, corpusEvidence: 5, source: "protocol",
113
+ };
114
+ const leakyFeatures = {
115
+ protocolSafety: 0.3, historicalSuccessRate: 0.3, actionCount: 2,
116
+ latencyCost: 0.3, auditability: 0.4, corpusEvidence: 1, source: "corpus",
117
+ };
118
+ const safeScore = model.score(safeFeatures, { acceptanceRate: 0.85, executionSuccessRate: 0.9 });
119
+ const leakyScore = model.score(leakyFeatures, { acceptanceRate: 0.15, executionSuccessRate: 0.1 });
120
+ (0, vitest_1.expect)(safeScore).toBeGreaterThanOrEqual(0);
121
+ (0, vitest_1.expect)(safeScore).toBeLessThanOrEqual(1);
122
+ (0, vitest_1.expect)(leakyScore).toBeGreaterThanOrEqual(0);
123
+ (0, vitest_1.expect)(leakyScore).toBeLessThanOrEqual(1);
124
+ // Safe should score higher than leaky
125
+ (0, vitest_1.expect)(safeScore).toBeGreaterThan(leakyScore);
126
+ });
127
+ (0, vitest_1.it)("falls back gracefully with insufficient data", () => {
128
+ const telemetry = new planner_telemetry_1.PlannerTelemetry(path.join(LR_DIR, ".progmune_corpus", "telemetry", `lr-fallback-${Date.now()}.jsonl`));
129
+ // Only 5 samples — below minSamples=50
130
+ seedTrainingData(telemetry, 5);
131
+ const model = logistic_reward_1.LogisticRewardModel.train(telemetry);
132
+ (0, vitest_1.expect)(model.isTrained).toBe(false);
133
+ (0, vitest_1.expect)(model.sampleCount).toBe(5);
134
+ // Should still produce valid scores (weights are initialized to 0)
135
+ const score = model.score({ protocolSafety: 0.5, historicalSuccessRate: 0.5, actionCount: 2, latencyCost: 0.3, auditability: 0.5, corpusEvidence: 0, source: "protocol" }, { acceptanceRate: 0.5, executionSuccessRate: 0.5 });
136
+ (0, vitest_1.expect)(score).toBeCloseTo(0.5, 1); // sigmoid(0) = 0.5
137
+ });
138
+ (0, vitest_1.it)("feature importance is interpretable", () => {
139
+ const telemetry = new planner_telemetry_1.PlannerTelemetry(path.join(LR_DIR, ".progmune_corpus", "telemetry", `lr-importance-${Date.now()}.jsonl`));
140
+ seedTrainingData(telemetry, 150);
141
+ const model = logistic_reward_1.LogisticRewardModel.train(telemetry);
142
+ const importance = model.featureImportance();
143
+ (0, vitest_1.expect)(importance.length).toBe(7);
144
+ // Top features should have positive importance
145
+ (0, vitest_1.expect)(importance[0].importance).toBeGreaterThan(0);
146
+ model.printWeights();
147
+ });
148
+ (0, vitest_1.it)("export/import roundtrip preserves weights", () => {
149
+ const telemetry = new planner_telemetry_1.PlannerTelemetry(path.join(LR_DIR, ".progmune_corpus", "telemetry", `lr-export-${Date.now()}.jsonl`));
150
+ seedTrainingData(telemetry, 100);
151
+ const original = logistic_reward_1.LogisticRewardModel.train(telemetry);
152
+ const exported = original.exportWeights();
153
+ const imported = logistic_reward_1.LogisticRewardModel.importWeights(exported);
154
+ (0, vitest_1.expect)(imported.isTrained).toBe(true);
155
+ (0, vitest_1.expect)(imported.sampleCount).toBe(original.sampleCount);
156
+ (0, vitest_1.expect)(imported.weights).toEqual(original.weights);
157
+ (0, vitest_1.expect)(imported.bias).toBe(original.bias);
158
+ // Scores should be identical
159
+ const features = { protocolSafety: 0.7, historicalSuccessRate: 0.5, actionCount: 2, latencyCost: 0.3, auditability: 0.6, corpusEvidence: 3, source: "protocol" };
160
+ const stats = { acceptanceRate: 0.8, executionSuccessRate: 0.9 };
161
+ (0, vitest_1.expect)(imported.score(features, stats)).toBe(original.score(features, stats));
162
+ });
163
+ });
164
+ (0, vitest_1.describe)("Model Comparison", () => {
165
+ (0, vitest_1.it)("compares LogisticReward against baseline", () => {
166
+ const telemetry = new planner_telemetry_1.PlannerTelemetry(path.join(LR_DIR, ".progmune_corpus", "telemetry", `lr-compare-${Date.now()}.jsonl`));
167
+ seedTrainingData(telemetry, 300);
168
+ const comparisons = (0, logistic_reward_1.compareModels)(telemetry);
169
+ (0, vitest_1.expect)(comparisons.length).toBeGreaterThanOrEqual(1);
170
+ const lr = comparisons.find(c => c.model === "LogisticReward");
171
+ if (lr.trained) {
172
+ (0, vitest_1.expect)(lr.accuracy).toBeGreaterThan(0.5); // better than random
173
+ (0, vitest_1.expect)(lr.logLoss).toBeLessThan(1.0);
174
+ }
175
+ console.log("\n─── Model Comparison ───");
176
+ for (const c of comparisons) {
177
+ console.log(` ${c.model.padEnd(22)} acc=${(c.accuracy * 100).toFixed(1)}% logLoss=${c.logLoss.toFixed(4)}`);
178
+ }
179
+ });
180
+ });
@@ -0,0 +1,193 @@
1
+ "use strict";
2
+ /**
3
+ * P5.0: Hierarchical Macro Graph
4
+ *
5
+ * Lifts MacroRepairs from a flat catalog into a composable skill graph.
6
+ * Each MacroNode is a "skill" with preconditions, actions, postconditions,
7
+ * and reward, enabling hierarchical planning.
8
+ *
9
+ * AlphaGo Zero analogy:
10
+ * Primitive action = single function call
11
+ * Macro = 定式 (joseki) — a proven sequence that achieves a known outcome
12
+ * MacroGraph = opening book + pattern library
13
+ *
14
+ * Planner search depth is reduced by an order of magnitude when it
15
+ * can search macro nodes instead of individual actions.
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.MacroGraphBuilder = void 0;
19
+ const macro_repair_1 = require("./macro-repair");
20
+ // ═══════════════════════════════════════════════════════════════
21
+ // State Inference
22
+ // ═══════════════════════════════════════════════════════════════
23
+ /** Infer pre/post conditions — only preconditions NOT produced by the chain are true preconditions. */
24
+ function inferConditions(actions, rules) {
25
+ const allPre = new Set();
26
+ const produced = new Set();
27
+ const invalidated = new Set();
28
+ let current = new Set();
29
+ for (const fn of actions) {
30
+ const rule = rules.get(fn);
31
+ if (!rule)
32
+ continue;
33
+ // Collect all preconditions needed at any step
34
+ for (const p of rule.pre_states) {
35
+ if (p.length > 0)
36
+ allPre.add(p);
37
+ }
38
+ // Apply: invalidate current, then produce
39
+ if (rule.invalidate)
40
+ rule.invalidate.forEach(s => { invalidated.add(s); current.delete(s); });
41
+ for (const p of rule.post_states) {
42
+ current.add(p);
43
+ produced.add(p);
44
+ }
45
+ }
46
+ // True preconditions: needed but NOT produced by any action in the chain
47
+ const preconditions = [...allPre].filter(p => !produced.has(p));
48
+ // Postconditions: active states + invalidated states
49
+ const postconditions = [...current, ...invalidated].filter(s => s.length > 0);
50
+ return { preconditions, postconditions };
51
+ }
52
+ // ═══════════════════════════════════════════════════════════════
53
+ // Macro Graph Builder
54
+ // ═══════════════════════════════════════════════════════════════
55
+ class MacroGraphBuilder {
56
+ constructor() {
57
+ this._graph = { nodes: new Map(), edges: [] };
58
+ }
59
+ /**
60
+ * Learn macro nodes from telemetry data.
61
+ * Mines MacroRepairs and converts them into MacroNodes with state conditions.
62
+ */
63
+ learnMacros(telemetry, rules, minAcceptance = 0.7, minFrequency = 3) {
64
+ const macros = (0, macro_repair_1.mineMacroRepairs)(telemetry, minAcceptance, minFrequency);
65
+ for (const macro of macros) {
66
+ const { preconditions, postconditions } = inferConditions(macro.actions, rules);
67
+ const nodeId = macro.id;
68
+ if (this._graph.nodes.has(nodeId))
69
+ continue;
70
+ this._graph.nodes.set(nodeId, {
71
+ id: nodeId,
72
+ name: macro.actions.join(" → "),
73
+ protocol: macro.protocol,
74
+ preconditions,
75
+ actions: macro.actions,
76
+ postconditions,
77
+ reward: macro.acceptanceRate * 0.7 + macro.executionSuccessRate * 0.3,
78
+ frequency: macro.frequency,
79
+ source: macro,
80
+ });
81
+ }
82
+ // Link macros: find composable pairs (post of A matches pre of B)
83
+ this.linkMacros();
84
+ return this._graph;
85
+ }
86
+ /** Link macros into a composable graph based on state matching. */
87
+ linkMacros() {
88
+ const nodeList = [...this._graph.nodes.values()];
89
+ for (const a of nodeList) {
90
+ for (const b of nodeList) {
91
+ if (a.id === b.id)
92
+ continue;
93
+ // Check if A's postconditions satisfy B's preconditions
94
+ const overlap = b.preconditions.filter(p => a.postconditions.includes(p));
95
+ if (overlap.length > 0 || a.postconditions.length === 0 || b.preconditions.length === 0) {
96
+ this._graph.edges.push({
97
+ from: a.id, to: b.id,
98
+ frequency: Math.min(a.frequency, b.frequency),
99
+ successRate: a.reward * b.reward,
100
+ });
101
+ }
102
+ }
103
+ }
104
+ }
105
+ /**
106
+ * Compose a chain of macros from start state to goal state.
107
+ *
108
+ * Uses the macro graph to find multi-step skill chains,
109
+ * reducing the planner's search depth compared to action-level BFS.
110
+ */
111
+ compose(currentStates, targetStates, maxDepth = 5) {
112
+ const chains = [];
113
+ const currentSet = new Set(currentStates);
114
+ const targetSet = new Set(targetStates);
115
+ // Find macros whose preconditions are satisfied by current state
116
+ const startable = [...this._graph.nodes.values()].filter(n => n.preconditions.length === 0 || n.preconditions.every(p => currentSet.has(p)));
117
+ // BFS over macro nodes
118
+ const visited = new Set();
119
+ const queue = startable.map(m => ({ macros: [m], states: new Set([...currentStates, ...m.postconditions]), depth: 1 }));
120
+ while (queue.length > 0 && chains.length < 10) {
121
+ const { macros, states, depth } = queue.shift();
122
+ if (depth > maxDepth)
123
+ continue;
124
+ // Check if target reached
125
+ if (targetSet.size > 0 && targetStates.every(t => states.has(t))) {
126
+ chains.push(macros);
127
+ continue;
128
+ }
129
+ // Find next macro
130
+ for (const node of this._graph.nodes.values()) {
131
+ if (macros.some(m => m.id === node.id))
132
+ continue; // no cycles
133
+ const preOk = node.preconditions.length === 0 || node.preconditions.every(p => states.has(p));
134
+ if (!preOk)
135
+ continue;
136
+ const nextStates = new Set(states);
137
+ for (const p of node.postconditions)
138
+ nextStates.add(p);
139
+ const key = macros.map(m => m.id).join("→") + "→" + node.id;
140
+ if (visited.has(key))
141
+ continue;
142
+ visited.add(key);
143
+ queue.push({ macros: [...macros, node], states: nextStates, depth: depth + 1 });
144
+ }
145
+ }
146
+ // Sort by total reward
147
+ chains.sort((a, b) => {
148
+ const rewardA = a.reduce((s, m) => s + m.reward, 0) / a.length;
149
+ const rewardB = b.reduce((s, m) => s + m.reward, 0) / b.length;
150
+ return rewardB - rewardA;
151
+ });
152
+ return chains;
153
+ }
154
+ /** Get all macro chains from the graph. */
155
+ getAllMacroChains(maxDepth = 3) {
156
+ const chains = [];
157
+ const nodeList = [...this._graph.nodes.values()];
158
+ for (const start of nodeList) {
159
+ // Find chains starting from this node (using graph edges)
160
+ const visited = new Set();
161
+ const queue = [{ macros: [start], depth: 1 }];
162
+ while (queue.length > 0 && chains.length < 50) {
163
+ const { macros, depth } = queue.shift();
164
+ if (depth > maxDepth)
165
+ continue;
166
+ if (macros.length > 1)
167
+ chains.push(macros);
168
+ const last = macros[macros.length - 1];
169
+ const nextEdges = this._graph.edges.filter(e => e.from === last.id);
170
+ for (const edge of nextEdges) {
171
+ const next = this._graph.nodes.get(edge.to);
172
+ if (!next)
173
+ continue;
174
+ const key = macros.map(m => m.id).join("→") + "→" + next.id;
175
+ if (visited.has(key))
176
+ continue;
177
+ visited.add(key);
178
+ queue.push({ macros: [...macros, next], depth: depth + 1 });
179
+ }
180
+ }
181
+ }
182
+ chains.sort((a, b) => {
183
+ const rA = a.reduce((s, m) => s + m.reward, 0) / a.length;
184
+ const rB = b.reduce((s, m) => s + m.reward, 0) / b.length;
185
+ return rB - rA;
186
+ });
187
+ return chains;
188
+ }
189
+ get graph() { return this._graph; }
190
+ get nodeCount() { return this._graph.nodes.size; }
191
+ get edgeCount() { return this._graph.edges.length; }
192
+ }
193
+ exports.MacroGraphBuilder = MacroGraphBuilder;
@@ -0,0 +1,183 @@
1
+ "use strict";
2
+ /**
3
+ * P4.6: Macro Repair Mining
4
+ *
5
+ * Mines high-acceptance trajectory patterns from Telemetry
6
+ * and converts them into reusable MacroRepair templates.
7
+ *
8
+ * A MacroRepair is a frequently-accepted action sequence that
9
+ * can be directly suggested as a repair candidate — serving
10
+ * as a fourth candidate source alongside Corpus/Protocol/Antibody.
11
+ *
12
+ * Example mined macro:
13
+ * verify_password → generate_jwt → create_session
14
+ * (acceptance: 92%, frequency: 45)
15
+ */
16
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ var desc = Object.getOwnPropertyDescriptor(m, k);
19
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
20
+ desc = { enumerable: true, get: function() { return m[k]; } };
21
+ }
22
+ Object.defineProperty(o, k2, desc);
23
+ }) : (function(o, m, k, k2) {
24
+ if (k2 === undefined) k2 = k;
25
+ o[k2] = m[k];
26
+ }));
27
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
28
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
29
+ }) : function(o, v) {
30
+ o["default"] = v;
31
+ });
32
+ var __importStar = (this && this.__importStar) || (function () {
33
+ var ownKeys = function(o) {
34
+ ownKeys = Object.getOwnPropertyNames || function (o) {
35
+ var ar = [];
36
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
37
+ return ar;
38
+ };
39
+ return ownKeys(o);
40
+ };
41
+ return function (mod) {
42
+ if (mod && mod.__esModule) return mod;
43
+ var result = {};
44
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
45
+ __setModuleDefault(result, mod);
46
+ return result;
47
+ };
48
+ })();
49
+ Object.defineProperty(exports, "__esModule", { value: true });
50
+ exports.mineMacroRepairs = mineMacroRepairs;
51
+ exports.saveMacroRepairs = saveMacroRepairs;
52
+ exports.loadMacroRepairs = loadMacroRepairs;
53
+ exports.printMacroReport = printMacroReport;
54
+ const planner_telemetry_1 = require("./planner-telemetry");
55
+ const fs = __importStar(require("fs"));
56
+ const path = __importStar(require("path"));
57
+ const MACRO_DIR = path.resolve(process.env.PROGMUNE_PROJECT_DIR || process.cwd(), ".progmune_corpus", "macros");
58
+ function ensureDir(dir) {
59
+ if (!fs.existsSync(dir))
60
+ fs.mkdirSync(dir, { recursive: true });
61
+ }
62
+ // ═══════════════════════════════════════════════════════════════
63
+ // Mining
64
+ // ═══════════════════════════════════════════════════════════════
65
+ /**
66
+ * Mine high-acceptance action sequences from telemetry data.
67
+ *
68
+ * Scans all decisions with feedback, groups by action signature,
69
+ * and identifies sequences that meet minimum acceptance + frequency thresholds.
70
+ */
71
+ function mineMacroRepairs(telemetry, minAcceptance = 0.7, minFrequency = 3) {
72
+ const decisions = telemetry.all();
73
+ // Group by action signature + protocol
74
+ const groups = new Map();
75
+ for (const d of decisions) {
76
+ if (!d.feedback || !d.selectedCandidateId || !d.protocol)
77
+ continue;
78
+ const sel = d.candidates.find(c => c.candidateId === d.selectedCandidateId);
79
+ if (!sel || sel.actions.length === 0)
80
+ continue;
81
+ const key = `${d.protocol}:${sel.actions.join("→")}`;
82
+ const entry = groups.get(key);
83
+ if (entry) {
84
+ entry.count++;
85
+ if (d.feedback.decision === "accepted")
86
+ entry.accepted++;
87
+ else
88
+ entry.rejected++;
89
+ if (d.feedback.executionResult?.success === true)
90
+ entry.execSuccess++;
91
+ else if (d.feedback.executionResult?.success === false)
92
+ entry.execFailure++;
93
+ if (d.cost?.latencyMs)
94
+ entry.totalLatency += d.cost.latencyMs;
95
+ entry.goals.set(d.goal, (entry.goals.get(d.goal) || 0) + 1);
96
+ entry.violationTypes.set(d.violationType || "unknown", (entry.violationTypes.get(d.violationType || "unknown") || 0) + 1);
97
+ }
98
+ else {
99
+ groups.set(key, {
100
+ accepted: d.feedback.decision === "accepted" ? 1 : 0,
101
+ rejected: d.feedback.decision === "rejected" ? 1 : 0,
102
+ execSuccess: d.feedback.executionResult?.success === true ? 1 : 0,
103
+ execFailure: d.feedback.executionResult?.success === false ? 1 : 0,
104
+ totalLatency: d.cost?.latencyMs || 0,
105
+ count: 1,
106
+ goals: new Map([[d.goal, 1]]),
107
+ violationTypes: new Map([[d.violationType || "unknown", 1]]),
108
+ });
109
+ }
110
+ }
111
+ const macros = [];
112
+ for (const [key, entry] of groups) {
113
+ if (entry.count < minFrequency)
114
+ continue;
115
+ const totalFeedback = entry.accepted + entry.rejected;
116
+ const acceptanceRate = totalFeedback > 0 ? entry.accepted / totalFeedback : 0;
117
+ if (acceptanceRate < minAcceptance)
118
+ continue;
119
+ const execTotal = entry.execSuccess + entry.execFailure;
120
+ const executionSuccessRate = execTotal > 0 ? entry.execSuccess / execTotal : 0;
121
+ const [protocol, actionStr] = key.split(":");
122
+ const actions = actionStr.split("→");
123
+ const topGoal = [...entry.goals.entries()].sort((a, b) => b[1] - a[1])[0]?.[0] || "unknown";
124
+ const topViolation = [...entry.violationTypes.entries()].sort((a, b) => b[1] - a[1])[0]?.[0] || "unknown";
125
+ macros.push({
126
+ id: `macro-${(0, planner_telemetry_1.candidateFingerprint)(protocol, actions, topViolation)}`,
127
+ actions,
128
+ protocol,
129
+ violationType: topViolation,
130
+ acceptanceRate,
131
+ executionSuccessRate,
132
+ frequency: entry.count,
133
+ avgLatencyMs: entry.count > 0 ? entry.totalLatency / entry.count : 0,
134
+ goal: topGoal,
135
+ });
136
+ }
137
+ return macros.sort((a, b) => b.acceptanceRate - a.acceptanceRate);
138
+ }
139
+ /**
140
+ * Persist mined macros for reuse across sessions.
141
+ */
142
+ function saveMacroRepairs(macros) {
143
+ ensureDir(MACRO_DIR);
144
+ const filepath = path.join(MACRO_DIR, `macros-${new Date().toISOString().slice(0, 10)}.json`);
145
+ fs.writeFileSync(filepath, JSON.stringify(macros, null, 2));
146
+ return filepath;
147
+ }
148
+ /**
149
+ * Load previously mined macros.
150
+ */
151
+ function loadMacroRepairs() {
152
+ if (!fs.existsSync(MACRO_DIR))
153
+ return [];
154
+ const macros = [];
155
+ const files = fs.readdirSync(MACRO_DIR).filter(f => f.endsWith(".json"));
156
+ for (const file of files) {
157
+ try {
158
+ const data = JSON.parse(fs.readFileSync(path.join(MACRO_DIR, file), "utf-8"));
159
+ if (Array.isArray(data))
160
+ macros.push(...data);
161
+ }
162
+ catch { /* skip */ }
163
+ }
164
+ return macros.sort((a, b) => b.acceptanceRate - a.acceptanceRate);
165
+ }
166
+ function printMacroReport(macros) {
167
+ console.log("\n─── Macro Repair Mining Report ───");
168
+ console.log(`Mined ${macros.length} high-acceptance repair templates\n`);
169
+ if (macros.length === 0) {
170
+ console.log(" No macros meet the minimum thresholds. Collect more feedback data.");
171
+ return;
172
+ }
173
+ console.log("Top 10 Macros:");
174
+ console.log("Accept ExecOk Freq Actions");
175
+ console.log("──────────────────────────────────────────────────");
176
+ for (const m of macros.slice(0, 10)) {
177
+ const acc = (m.acceptanceRate * 100).toFixed(0).padStart(4);
178
+ const exec = (m.executionSuccessRate * 100).toFixed(0).padStart(4);
179
+ const freq = String(m.frequency).padStart(4);
180
+ console.log(` ${acc}% ${exec}% ${freq} ${m.actions.join(" → ")}`);
181
+ }
182
+ console.log();
183
+ }