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
@@ -37,6 +37,19 @@ exports.saveCheckpoint = saveCheckpoint;
37
37
  exports.loadCheckpoint = loadCheckpoint;
38
38
  exports.clearCheckpoint = clearCheckpoint;
39
39
  exports.recordFailure = recordFailure;
40
+ exports.recordTrajectory = recordTrajectory;
41
+ exports.recordSuccess = recordSuccess;
42
+ exports.recordRepair = recordRepair;
43
+ exports.recordFailureV2 = recordFailureV2;
44
+ exports.loadFailuresV2 = loadFailuresV2;
45
+ exports.loadTrajectories = loadTrajectories;
46
+ exports.queryByResult = queryByResult;
47
+ exports.queryByViolationType = queryByViolationType;
48
+ exports.queryByProtocol = queryByProtocol;
49
+ exports.getTopPatterns = getTopPatterns;
50
+ exports.corpusTrajectoryStats = corpusTrajectoryStats;
51
+ exports.getRepairStats = getRepairStats;
52
+ exports.corpusV2Size = corpusV2Size;
40
53
  exports.recordSession = recordSession;
41
54
  exports.getAllFailures = getAllFailures;
42
55
  exports.getFailuresBySVL = getFailuresBySVL;
@@ -47,6 +60,8 @@ exports.getLearnedPatterns = getLearnedPatterns;
47
60
  exports.queryAntibodies = queryAntibodies;
48
61
  exports.getSemanticHeatmap = getSemanticHeatmap;
49
62
  exports.getAntibodyStats = getAntibodyStats;
63
+ exports.recordEdgeRejection = recordEdgeRejection;
64
+ exports.getEdgeConfidence = getEdgeConfidence;
50
65
  exports.generateCandidateRules = generateCandidateRules;
51
66
  const fs = __importStar(require("fs"));
52
67
  const path = __importStar(require("path"));
@@ -91,7 +106,7 @@ function clearCheckpoint(intent) {
91
106
  try {
92
107
  fs.unlinkSync(checkpointPath(intent));
93
108
  }
94
- catch { }
109
+ catch { /* checkpoint file may not exist */ }
95
110
  }
96
111
  /** Record a constraint violation to the failure corpus. */
97
112
  function recordFailure(record) {
@@ -105,7 +120,7 @@ function recordFailure(record) {
105
120
  try {
106
121
  seq = parseInt(fs.readFileSync(seqFile, 'utf-8'), 10);
107
122
  }
108
- catch { }
123
+ catch { /* checkpoint file may not exist */ }
109
124
  seq++;
110
125
  fs.writeFileSync(seqFile, String(seq));
111
126
  const id = `fail_${Date.now()}_${seq}`;
@@ -121,6 +136,228 @@ function recordFailure(record) {
121
136
  console.error(`[FailureCorpus] ${record.violatedSVL} | 尝试 ${record.plannerAttempt}/${record.plannerRetryTotal} | ${id}`);
122
137
  });
123
138
  }
139
+ const TRAJECTORY_DIR = path.join(CORPUS_DIR, "trajectories");
140
+ function writeTrajectoryFile(record) {
141
+ setImmediate(() => {
142
+ try {
143
+ const date = record.timestamp.slice(0, 10);
144
+ const dateDir = path.join(TRAJECTORY_DIR, date);
145
+ ensureDir(dateDir);
146
+ fs.writeFileSync(path.join(dateDir, `${record.id}.json`), JSON.stringify(record, null, 2));
147
+ }
148
+ catch { /* corpus write must never crash */ }
149
+ });
150
+ }
151
+ let _trajSeq = 0;
152
+ function nextTrajId() {
153
+ if (_trajSeq === 0) {
154
+ const seqFile = path.join(TRAJECTORY_DIR, ".seq");
155
+ try {
156
+ _trajSeq = parseInt(fs.readFileSync(seqFile, "utf-8"), 10);
157
+ }
158
+ catch { }
159
+ }
160
+ _trajSeq++;
161
+ setImmediate(() => {
162
+ try {
163
+ fs.writeFileSync(path.join(TRAJECTORY_DIR, ".seq"), String(_trajSeq));
164
+ }
165
+ catch { }
166
+ });
167
+ return `T-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
168
+ }
169
+ /**
170
+ * Record any trajectory — success, violation, repair, or optimal.
171
+ * This is the single entry point for the Code World Model Dataset.
172
+ */
173
+ function recordTrajectory(params) {
174
+ ensureDir(TRAJECTORY_DIR);
175
+ const defaultCtx = { nestingDepth: 0, exceptionHandled: false, insideLoop: false, branchCount: 0, asyncContext: false };
176
+ const defaultReward = { safety: 0.5, latency: 0.5, maintainability: 0.5, security: 0.5, auditability: 0.5, custom: {} };
177
+ const record = {
178
+ id: nextTrajId(),
179
+ timestamp: new Date().toISOString(),
180
+ protocol: params.protocol,
181
+ initialState: params.initialState,
182
+ finalState: params.finalState,
183
+ trajectory: params.trajectory,
184
+ result: params.result,
185
+ reward: params.result === "success" || params.result === "optimal" ? (params.reward || defaultReward) : undefined,
186
+ violation: params.result === "violation" || params.result === "repair" ? {
187
+ type: params.violationType || "other",
188
+ failingStepIndex: params.failingStepIndex || 0,
189
+ expectedStates: params.finalState,
190
+ actualStates: params.initialState,
191
+ fixPath: params.fixPath,
192
+ description: params.violationDesc || "",
193
+ } : undefined,
194
+ repairFrom: params.repairFrom,
195
+ context: params.context || defaultCtx,
196
+ successRate: params.successRate || 0,
197
+ metadata: {
198
+ source: params.source || "llm",
199
+ intent: params.intent,
200
+ sessionId: params.sessionId,
201
+ },
202
+ goal: params.goal,
203
+ feedback: params.feedback,
204
+ cost: params.cost,
205
+ };
206
+ writeTrajectoryFile(record);
207
+ console.error(`[Trajectory] ${record.result} | ${params.protocol} | ${record.id}`);
208
+ }
209
+ /**
210
+ * Record a successful trajectory — positive sample for reward learning.
211
+ * Call this when validation passes without violations.
212
+ */
213
+ function recordSuccess(params) {
214
+ recordTrajectory({ ...params, result: "success", successRate: 1.0 });
215
+ }
216
+ /**
217
+ * Record a repair trajectory — shows what fix was applied and whether it worked.
218
+ */
219
+ function recordRepair(params) {
220
+ recordTrajectory({
221
+ ...params,
222
+ result: "repair",
223
+ successRate: params.success ? 1.0 : 0.0,
224
+ failingStepIndex: 0,
225
+ });
226
+ }
227
+ // ── Backward-compatible wrappers ──
228
+ /** @deprecated Use recordTrajectory() with result: "violation" instead. */
229
+ function recordFailureV2(record) {
230
+ recordTrajectory({
231
+ protocol: record.protocol,
232
+ initialState: record.actualStateSequence,
233
+ finalState: record.expectedStateSequence,
234
+ trajectory: record.actionSequence,
235
+ result: "violation",
236
+ violationType: record.violationType,
237
+ violationDesc: record.violationType,
238
+ failingStepIndex: record.failingStepIndex,
239
+ fixPath: record.ssgFixPath,
240
+ context: record.contextFeatures,
241
+ successRate: record.successRate,
242
+ intent: record.intent,
243
+ sessionId: record.parentSessionId,
244
+ });
245
+ }
246
+ /** @deprecated Use loadTrajectories() instead. */
247
+ function loadFailuresV2() {
248
+ return loadTrajectories()
249
+ .filter(t => t.result === "violation")
250
+ .map(t => ({
251
+ failureId: t.id,
252
+ timestamp: t.timestamp,
253
+ protocol: t.protocol,
254
+ codeSnippet: (t.trajectory || []).join("; "),
255
+ expectedStateSequence: t.finalState || [],
256
+ actualStateSequence: t.initialState || [],
257
+ violationType: t.violation?.type || "other",
258
+ failingStepIndex: t.violation?.failingStepIndex || 0,
259
+ contextFeatures: t.context,
260
+ repairAttempts: [],
261
+ successRate: t.successRate,
262
+ actionSequence: t.trajectory || [],
263
+ ssgStateAtViolation: t.initialState || [],
264
+ ssgFixPath: t.violation?.fixPath || [],
265
+ parentSessionId: t.metadata?.sessionId,
266
+ intent: t.metadata?.intent || "",
267
+ }));
268
+ }
269
+ // ═══════════════════════════════════════════════════════════════
270
+ // P0: Trajectory query API
271
+ // ═══════════════════════════════════════════════════════════════
272
+ /** Load all trajectory records from the corpus. */
273
+ function loadTrajectories() {
274
+ const results = [];
275
+ if (!fs.existsSync(TRAJECTORY_DIR))
276
+ return results;
277
+ const dateDirs = fs.readdirSync(TRAJECTORY_DIR, { withFileTypes: true });
278
+ for (const entry of dateDirs) {
279
+ if (!entry.isDirectory())
280
+ continue;
281
+ const files = fs.readdirSync(path.join(TRAJECTORY_DIR, entry.name));
282
+ for (const file of files) {
283
+ if (!file.endsWith(".json"))
284
+ continue;
285
+ try {
286
+ const raw = fs.readFileSync(path.join(TRAJECTORY_DIR, entry.name, file), "utf-8");
287
+ results.push(JSON.parse(raw));
288
+ }
289
+ catch { /* skip corrupted files */ }
290
+ }
291
+ }
292
+ return results.sort((a, b) => b.timestamp.localeCompare(a.timestamp));
293
+ }
294
+ /** Query trajectories by result type. */
295
+ function queryByResult(result) {
296
+ return loadTrajectories().filter(t => t.result === result);
297
+ }
298
+ /** Query violations by type. */
299
+ function queryByViolationType(type) {
300
+ return loadTrajectories().filter(t => t.violation?.type === type);
301
+ }
302
+ /** Query trajectories by protocol. */
303
+ function queryByProtocol(protocol) {
304
+ return loadTrajectories().filter(t => t.protocol === protocol);
305
+ }
306
+ /** Get top N violation patterns across all trajectories. */
307
+ function getTopPatterns(limit = 10) {
308
+ const all = loadTrajectories().filter(t => t.result === "violation");
309
+ const buckets = {};
310
+ for (const t of all) {
311
+ const ctx = t.context;
312
+ const key = `${t.violation?.type || "other"}|d${ctx.nestingDepth}|${ctx.exceptionHandled ? "try" : "no-try"}|${ctx.insideLoop ? "loop" : "no-loop"}`;
313
+ if (!buckets[key])
314
+ buckets[key] = { records: [] };
315
+ buckets[key].records.push(t);
316
+ }
317
+ return Object.entries(buckets)
318
+ .sort((a, b) => b[1].records.length - a[1].records.length)
319
+ .slice(0, limit)
320
+ .map(([key, bucket]) => {
321
+ const [vt, ...rest] = key.split("|");
322
+ const avg = bucket.records.reduce((s, t) => s + t.successRate, 0) / bucket.records.length;
323
+ return {
324
+ violationType: vt,
325
+ contextKey: rest.join(" "),
326
+ count: bucket.records.length,
327
+ avgSuccessRate: avg,
328
+ };
329
+ });
330
+ }
331
+ /** Get total trajectory count and breakdown by result type. */
332
+ function corpusTrajectoryStats() {
333
+ const all = loadTrajectories();
334
+ return {
335
+ total: all.length,
336
+ success: all.filter(t => t.result === "success").length,
337
+ violation: all.filter(t => t.result === "violation").length,
338
+ repair: all.filter(t => t.result === "repair").length,
339
+ optimal: all.filter(t => t.result === "optimal").length,
340
+ };
341
+ }
342
+ /** Get repair acceptance statistics for P4 Reward Model training data. */
343
+ function getRepairStats() {
344
+ const all = loadTrajectories().filter(t => t.result === "repair");
345
+ const accepted = all.filter(t => t.feedback?.accepted === true).length;
346
+ const rejected = all.filter(t => t.feedback?.rejected === true).length;
347
+ const total = all.length;
348
+ const acceptanceRate = total > 0 ? accepted / total : 0;
349
+ const costs = all
350
+ .map(t => t.cost?.latency)
351
+ .filter((l) => l !== undefined);
352
+ const avgLatency = costs.length > 0
353
+ ? costs.reduce((s, l) => s + l, 0) / costs.length
354
+ : 0;
355
+ return { acceptedRepairs: accepted, rejectedRepairs: rejected, totalRepairs: total, acceptanceRate, avgLatency };
356
+ }
357
+ /** @deprecated Use corpusTrajectoryStats() instead. */
358
+ function corpusV2Size() {
359
+ return corpusTrajectoryStats().total;
360
+ }
124
361
  /** 记录一个完整的意图会话(支持 ExecutionSession 和旧 IntentSession) */
125
362
  /**
126
363
  * 保存执行会话(含所有尝试、违规、状态转移)。
@@ -179,7 +416,7 @@ function getAllFailures() {
179
416
  try {
180
417
  records.push(JSON.parse(fs.readFileSync(path.join(dirPath, file), "utf-8")));
181
418
  }
182
- catch { }
419
+ catch { /* checkpoint file may not exist */ }
183
420
  }
184
421
  }
185
422
  }
@@ -287,7 +524,7 @@ function getAllSessions() {
287
524
  const raw = JSON.parse(fs.readFileSync(path.join(SESSIONS_DIR, file), "utf-8"));
288
525
  sessions.push(normalizeSession(raw));
289
526
  }
290
- catch { }
527
+ catch { /* checkpoint file may not exist */ }
291
528
  }
292
529
  }
293
530
  return sessions;
@@ -379,11 +616,11 @@ function getLearnedPatterns() {
379
616
  for (const v of a.violations) {
380
617
  if (!v.fixPath || v.fixPath.length === 0)
381
618
  continue;
382
- if (v.svl !== 4)
383
- continue; // only SVL-4 has fix paths
384
619
  const violatedLabel = `SVL-${v.svl}`;
385
- const missingKey = (v.missingStates || ["unknown"]).join(",");
386
- const signature = `${violatedLabel}:${missingKey}`;
620
+ // Use violatedConstraint if available, otherwise fall back to missingStates
621
+ const constraintKey = v.violatedConstraint
622
+ || (v.missingStates || ["unknown"]).join(",");
623
+ const signature = `${violatedLabel}:${constraintKey}`;
387
624
  const existing = agg.get(signature);
388
625
  const ts = new Date(s.startedAt).toISOString();
389
626
  if (existing) {
@@ -396,7 +633,7 @@ function getLearnedPatterns() {
396
633
  }
397
634
  else {
398
635
  agg.set(signature, {
399
- violation: `${violatedLabel}: ${(v.missingStates || ["unknown"]).join(", ")}`,
636
+ violation: `${violatedLabel}: ${constraintKey}`,
400
637
  fixPath: v.fixPath,
401
638
  count: 1,
402
639
  intents: new Set([s.intent]),
@@ -566,6 +803,82 @@ function getAntibodyStats() {
566
803
  .slice(0, 10);
567
804
  return { totalHits, fastPathHits, injectedHintHits, totalLLMCallsSaved, totalTokensSaved, byLevel, topSignatures };
568
805
  }
806
+ // ── Edge rejection tracking ──
807
+ const MEMORY_DIR = path.join(CORPUS_DIR, "..", ".progmune_memory");
808
+ const REJECTION_FILE = path.join(MEMORY_DIR, "edge_rejections.json");
809
+ /** Record that the LLM rejected a recommended edge (picked a different function). */
810
+ function recordEdgeRejection(producer, consumer) {
811
+ (0, file_lock_1.withLock)("edge_rejections", () => {
812
+ let data = {};
813
+ try {
814
+ if (fs.existsSync(REJECTION_FILE))
815
+ data = JSON.parse(fs.readFileSync(REJECTION_FILE, "utf-8"));
816
+ }
817
+ catch { }
818
+ const key = `${producer}→${consumer}`;
819
+ data[key] = (data[key] || 0) + 1;
820
+ fs.writeFileSync(REJECTION_FILE, JSON.stringify(data, null, 2));
821
+ });
822
+ }
823
+ function getEdgeRejections() {
824
+ try {
825
+ if (!fs.existsSync(REJECTION_FILE))
826
+ return new Map();
827
+ const data = JSON.parse(fs.readFileSync(REJECTION_FILE, "utf-8"));
828
+ return new Map(Object.entries(data));
829
+ }
830
+ catch {
831
+ return new Map();
832
+ }
833
+ }
834
+ function getEdgeConfidence(producer, consumer) {
835
+ const sessions = getAllSessions();
836
+ const edgeStats = new Map();
837
+ for (const s of sessions) {
838
+ for (const a of s.attempts) {
839
+ const calls = a.transitions
840
+ .filter(t => t.function)
841
+ .sort((x, y) => x.actionIndex - y.actionIndex);
842
+ const isSuccess = a.outcome === "success";
843
+ for (let i = 0; i < calls.length - 1; i++) {
844
+ const edgeKey = `${calls[i].function}→${calls[i + 1].function}`;
845
+ if (!edgeStats.has(edgeKey)) {
846
+ edgeStats.set(edgeKey, { success: 0, failure: 0 });
847
+ }
848
+ const stats = edgeStats.get(edgeKey);
849
+ if (isSuccess)
850
+ stats.success++;
851
+ else
852
+ stats.failure++;
853
+ }
854
+ }
855
+ }
856
+ const rejections = getEdgeRejections();
857
+ const results = [];
858
+ for (const [key, stats] of edgeStats) {
859
+ const [prod, cons] = key.split("→");
860
+ if (producer && prod !== producer)
861
+ continue;
862
+ if (consumer && cons !== consumer)
863
+ continue;
864
+ // Factor in explicit LLM rejections as negative signal
865
+ const rejectionCount = rejections.get(key) || 0;
866
+ const effectiveSuccess = Math.max(0, stats.success - rejectionCount);
867
+ const effectiveTotal = stats.success + stats.failure + rejectionCount;
868
+ // Laplace smoothing: Beta(1,1) prior
869
+ const confidence = (effectiveSuccess + 1) / (effectiveTotal + 2);
870
+ results.push({
871
+ producer: prod,
872
+ consumer: cons,
873
+ successCount: stats.success,
874
+ failureCount: stats.failure,
875
+ totalCount: effectiveTotal,
876
+ confidence: Math.round(confidence * 100) / 100,
877
+ });
878
+ }
879
+ results.sort((a, b) => b.confidence * b.totalCount - a.confidence * a.totalCount);
880
+ return results;
881
+ }
569
882
  /** Generate candidate immune rules from failure patterns. */
570
883
  function generateCandidateRules() {
571
884
  const genome = getFailureGenome();
package/dist/feedback.js CHANGED
@@ -87,16 +87,26 @@ function getWeightedSuccessRate(funcName) {
87
87
  return totalWeight > 0 ? weightedSuccess / totalWeight : 0.5;
88
88
  }
89
89
  /** @requires FUNCTION_NAME @produces FAILURE_ADJUSTED_CREDIT
90
- * Credit score adjusted by failure severity.
91
- * SVL-4 (protocol) violations penalize 2x more than SVL-1.
92
- * Time-weighted + severity-weighted. */
90
+ * Credit score adjusted by failure severity with Laplace smoothing.
91
+ *
92
+ * Laplace (add-1) smoothing eliminates small-sample bias:
93
+ * - 1/1 success → ~0.67 (not 1.0 — still uncertain)
94
+ * - 99/100 success → ~0.98 (approaches empirical rate)
95
+ * - 0/1 failure → ~0.33 (not 0.0 — allows redemption)
96
+ * - Cold start → 0.5 (neutral prior)
97
+ *
98
+ * SVL-4 protocol violations are penalized 3× more than SVL-1.
99
+ * Time-weighted via exponential decay (half-life = 1 day). */
93
100
  function getFailureAdjustedCredit(funcName) {
94
101
  const records = loadFeedback();
95
102
  const funcRecords = records
96
103
  .filter(r => r.functionName === funcName)
97
104
  .map(r => ({ ...r, age: (Date.now() - new Date(r.timestamp).getTime()) / 86400000 }));
105
+ // Laplace prior: Beta(1,1) → pseudocount of 1 success + 1 failure
106
+ const LAPLACE_PRIOR_SUCCESS = 1;
107
+ const LAPLACE_PRIOR_TOTAL = 2;
98
108
  if (funcRecords.length === 0)
99
- return 0.5;
109
+ return LAPLACE_PRIOR_SUCCESS / LAPLACE_PRIOR_TOTAL; // 0.5
100
110
  const SVL_PENALTY = {
101
111
  "SVL-1": 1.0, // missing function — minor
102
112
  "SVL-2": 1.5, // type mismatch — moderate
@@ -116,7 +126,8 @@ function getFailureAdjustedCredit(funcName) {
116
126
  // weightedSuccess stays 0 for failures
117
127
  }
118
128
  }
119
- return totalWeight > 0 ? weightedSuccess / totalWeight : 0.5;
129
+ // Laplace smoothing: (success + 1) / (total + 2)
130
+ return (weightedSuccess + LAPLACE_PRIOR_SUCCESS) / (totalWeight + LAPLACE_PRIOR_TOTAL);
120
131
  }
121
132
  /** @requires EXECUTION_DATA @produces RUN_ID */
122
133
  function recordRun(intent, actions, success, error) {
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * Unit tests for feedback module — pure functions only.
5
+ * Does NOT hit the filesystem (file I/O functions are integration-tested separately).
6
+ */
7
+ const vitest_1 = require("vitest");
8
+ // We test the pure scoring math indirectly by reading the source patterns.
9
+ // The key behaviors to verify:
10
+ // 1. Cold start returns neutral (no penalty)
11
+ // 2. Consistent success returns high credit
12
+ // 3. SVL-severity affects penalty proportionally
13
+ // Since these functions read from feedback.json on disk,
14
+ // we verify the module exports and type contracts.
15
+ const feedback_1 = require("./feedback");
16
+ (0, vitest_1.describe)("feedback module", () => {
17
+ (0, vitest_1.it)("loadFeedback returns an array", () => {
18
+ const records = (0, feedback_1.loadFeedback)();
19
+ (0, vitest_1.expect)(Array.isArray(records)).toBe(true);
20
+ });
21
+ (0, vitest_1.it)("getFunctionSuccessRate returns 0.5 for unknown function (no history)", () => {
22
+ const rate = (0, feedback_1.getFunctionSuccessRate)("__nonexistent_func_xyz__");
23
+ (0, vitest_1.expect)(rate).toBe(0.5);
24
+ });
25
+ (0, vitest_1.it)("getWeightedSuccessRate returns 0.5 for unknown function", () => {
26
+ const rate = (0, feedback_1.getWeightedSuccessRate)("__nonexistent_func_xyz__");
27
+ (0, vitest_1.expect)(rate).toBe(0.5);
28
+ });
29
+ (0, vitest_1.it)("getFailureAdjustedCredit returns 0.5 for unknown function (Laplace prior: neutral)", () => {
30
+ const credit = (0, feedback_1.getFailureAdjustedCredit)("__nonexistent_func_xyz__");
31
+ (0, vitest_1.expect)(credit).toBe(0.5);
32
+ });
33
+ (0, vitest_1.it)("getFailureAdjustedCredit returns a number between 0 and 1", () => {
34
+ const credit = (0, feedback_1.getFailureAdjustedCredit)("generateJWT");
35
+ (0, vitest_1.expect)(credit).toBeGreaterThanOrEqual(0);
36
+ (0, vitest_1.expect)(credit).toBeLessThanOrEqual(1);
37
+ });
38
+ (0, vitest_1.it)("Laplace smoothing: cold start = 0.5 (neutral prior)", () => {
39
+ // No records → prior Beta(1,1) → 1/(1+1) = 0.5
40
+ (0, vitest_1.expect)((0, feedback_1.getFailureAdjustedCredit)("__unknown_fn__")).toBe(0.5);
41
+ });
42
+ (0, vitest_1.it)("Laplace smoothing: 0/1 record is not zero (allows redemption)", () => {
43
+ // Laplace: (0+1)/(1+2) ≈ 0.33, not 0.0
44
+ // This is only true if there are real records (not cold start).
45
+ // Cold start with no records returns 0.5 by definition.
46
+ const credit = (0, feedback_1.getFailureAdjustedCredit)("svl1_test_1780509556916");
47
+ (0, vitest_1.expect)(credit).toBeGreaterThan(0);
48
+ });
49
+ });
package/dist/file-lock.js CHANGED
@@ -64,7 +64,7 @@ function withLock(name, fn) {
64
64
  try {
65
65
  fs.rmdirSync(lock);
66
66
  }
67
- catch { }
67
+ catch { /* best-effort cleanup */ }
68
68
  }
69
69
  }
70
70
  catch (err) {