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,215 @@
1
+ "use strict";
2
+ /**
3
+ * Risk Model — Pattern × Severity × Policy
4
+ *
5
+ * Upgrades detection from boolean (valid/invalid) to structured risk assessment.
6
+ *
7
+ * Architecture:
8
+ * Protocol → Concept → DetectionPattern → RiskObject → Policy → Decision
9
+ *
10
+ * Completeness becomes a knowledge-layer metric. Risk drives governance.
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.DETECTION_PATTERNS = void 0;
14
+ exports.assessRisk = assessRisk;
15
+ // ═══════════════════════════════════════════════════════════════
16
+ // Detection Patterns (evidence-backed, weighted by severity)
17
+ // ═══════════════════════════════════════════════════════════════
18
+ exports.DETECTION_PATTERNS = [
19
+ // ── TLS Patterns ──
20
+ {
21
+ id: "TLS-MISSING-FINISHED",
22
+ name: "Missing Finished",
23
+ description: "TLS handshake started but Finished message not sent — handshake incomplete. Attacker may intercept before authentication completes.",
24
+ protocolName: "TLS Handshake",
25
+ conceptName: "Finished",
26
+ severity: "Critical",
27
+ confidence: 91,
28
+ evidenceSequences: 135,
29
+ detect: (calls) => {
30
+ const hasInit = calls.some(c => /\b(\w*ssl\w*init|\w*SSL\w*new|\w*tls\w*init)\b/i.test(c));
31
+ const hasConnect = calls.some(c => /\b(\w*ssl\w*connect|\w*ssl\w*handshake|\w*tls\w*connect)\b/i.test(c));
32
+ const hasFree = calls.some(c => /\b(\w*ssl\w*free|\w*SSL\w*cleanup|\w*SSL_CTX_free)\b/i.test(c));
33
+ return (hasInit || hasConnect) && !hasFree;
34
+ },
35
+ detail: "TLS handshake initiated but no Finished/free step detected. Connection may remain open or unverified.",
36
+ },
37
+ {
38
+ id: "TLS-NO-INIT",
39
+ name: "TLS Without Init",
40
+ description: "TLS connect or read without prior initialization — possible use of uninitialized SSL context.",
41
+ protocolName: "TLS Handshake",
42
+ conceptName: "ClientHello",
43
+ severity: "High",
44
+ confidence: 85,
45
+ evidenceSequences: 135,
46
+ detect: (calls) => {
47
+ const hasInit = calls.some(c => /\b(\w*ssl\w*init|\w*SSL\w*new|\w*tls\w*init)\b/i.test(c));
48
+ const hasConnect = calls.some(c => /\b(\w*ssl\w*connect|\w*ssl\w*handshake)\b/i.test(c));
49
+ return hasConnect && !hasInit;
50
+ },
51
+ detail: "SSL connect/handshake called without prior context initialization. Missing SSL_CTX_new or equivalent.",
52
+ },
53
+ {
54
+ id: "TLS-DOUBLE-FREE",
55
+ name: "TLS Double Free",
56
+ description: "SSL free called on same object twice, or free without matching init. Normal cleanup (SSL_free + SSL_CTX_free for SSL_new + SSL_CTX_new) is safe.",
57
+ protocolName: "TLS Handshake",
58
+ conceptName: "Finished",
59
+ severity: "Critical",
60
+ confidence: 88,
61
+ evidenceSequences: 135,
62
+ detect: (calls) => {
63
+ // Count distinct SSL object types freed (not just total free calls)
64
+ const sslFreeCount = calls.filter(c => /\bSSL_free\b/i.test(c)).length;
65
+ const ctxFreeCount = calls.filter(c => /\bSSL_CTX_free\b/i.test(c)).length;
66
+ const sslNewCount = calls.filter(c => /\bSSL_new\b/i.test(c)).length;
67
+ const ctxNewCount = calls.filter(c => /\bSSL_CTX_new\b/i.test(c)).length;
68
+ // Violation: more frees than news for the SAME object type
69
+ const sslDoubleFree = sslFreeCount > sslNewCount;
70
+ const ctxDoubleFree = ctxFreeCount > ctxNewCount;
71
+ return (sslDoubleFree || ctxDoubleFree) && (sslFreeCount + ctxFreeCount >= 2);
72
+ },
73
+ detail: "SSL_free or SSL_CTX_free called more times than their matching init. Normal cleanup (1 SSL_free + 1 SSL_CTX_free for 1 SSL_new + 1 SSL_CTX_new) is safe.",
74
+ },
75
+ // ── SSH Patterns ──
76
+ {
77
+ id: "SSH-NO-AUTH",
78
+ name: "SSH Without Auth",
79
+ description: "SSH connection established but no authentication step — possible unauthorized access.",
80
+ protocolName: "SSH Connection",
81
+ conceptName: "Authentication",
82
+ severity: "Critical",
83
+ confidence: 78,
84
+ evidenceSequences: 135,
85
+ detect: (calls) => {
86
+ const hasInit = calls.some(c => /\b(\w*ssh\w*init|ssh\w*setup)\b/i.test(c));
87
+ const hasAuth = calls.some(c => /\b(\w*ssh\w*auth|\w*ssh\w*login)\b/i.test(c));
88
+ return hasInit && !hasAuth;
89
+ },
90
+ detail: "SSH session initialized but no authentication step. Connection may be unauthenticated.",
91
+ },
92
+ {
93
+ id: "SSH-NO-CLEANUP",
94
+ name: "SSH Missing Cleanup",
95
+ description: "SSH session started but never properly closed — potential resource leak or session hijacking.",
96
+ protocolName: "SSH Connection",
97
+ conceptName: "Channel",
98
+ severity: "High",
99
+ confidence: 78,
100
+ evidenceSequences: 135,
101
+ detect: (calls) => {
102
+ const hasInit = calls.some(c => /\b(\w*ssh\w*init)\b/i.test(c));
103
+ const hasDone = calls.some(c => /\b(\w*ssh\w*done|\w*ssh\w*close|\w*ssh\w*free|\w*ssh\w*disconnect)\b/i.test(c));
104
+ return hasInit && !hasDone;
105
+ },
106
+ detail: "SSH session initialized but never closed. Resource leak or session fixation risk.",
107
+ },
108
+ // ── HTTP Patterns ──
109
+ {
110
+ id: "HTTP-NO-RESPONSE",
111
+ name: "HTTP Without Response",
112
+ description: "HTTP request sent but no response processed — possible incomplete request handling.",
113
+ protocolName: "HTTP Request",
114
+ conceptName: "Response",
115
+ severity: "Medium",
116
+ confidence: 80,
117
+ evidenceSequences: 150,
118
+ detect: (calls) => {
119
+ const hasInit = calls.some(c => /\b(\w*http\w*init|\w*http\w*handler)\b/i.test(c));
120
+ const hasSend = calls.some(c => /\b(\w*http\w*send|\w*http\w*process|ap_pass_brigade)\b/i.test(c));
121
+ return (hasInit || hasSend) && !calls.some(c => /\b(\w*http\w*cleanup|\w*http\w*finalize)\b/i.test(c));
122
+ },
123
+ detail: "HTTP request initiated but no cleanup/finalize step. Connection may hang.",
124
+ },
125
+ // ── Resource Patterns ──
126
+ {
127
+ id: "RES-ACQUIRE-NO-RELEASE",
128
+ name: "Resource Acquire Without Release",
129
+ description: "Resource acquired (malloc, open, SSL_new) but never released — definite resource leak.",
130
+ protocolName: "Resource Lifecycle",
131
+ severity: "Critical",
132
+ confidence: 98,
133
+ evidenceSequences: 250,
134
+ detect: (calls) => {
135
+ const acquireRe = /\b(malloc|calloc|SSL_CTX_new|SSL_new|BIO_new|open|fopen|socket)\b/i;
136
+ const releaseRe = /\b(free|SSL_CTX_free|SSL_free|BIO_free|close|fclose)\b/i;
137
+ const hasAcquire = calls.some(c => acquireRe.test(c) && !/\b(create|alloc|new|init)\w*\b/i.test(c));
138
+ const hasRelease = calls.some(c => releaseRe.test(c));
139
+ return hasAcquire && !hasRelease;
140
+ },
141
+ detail: "Resource acquired but no matching release call. Definite resource leak.",
142
+ },
143
+ ];
144
+ // ═══════════════════════════════════════════════════════════════
145
+ // Risk Assessment Engine
146
+ // ═══════════════════════════════════════════════════════════════
147
+ function assessRisk(calls, protocolName) {
148
+ const patterns = exports.DETECTION_PATTERNS.filter(p => {
149
+ if (protocolName && p.protocolName !== protocolName)
150
+ return false;
151
+ return p.detect(calls);
152
+ });
153
+ if (patterns.length === 0) {
154
+ return {
155
+ riskLevel: "Low",
156
+ patterns: [],
157
+ knowledgeUnit: { id: "", name: protocolName || "Unknown", version: "", rfc: undefined },
158
+ recommendation: "Allow",
159
+ summary: "No known risk patterns detected.",
160
+ };
161
+ }
162
+ // Highest severity pattern determines risk level
163
+ const severityOrder = ["Critical", "High", "Medium", "Low"];
164
+ const maxSeverity = patterns.reduce((max, p) => {
165
+ const i1 = severityOrder.indexOf(p.severity);
166
+ const i2 = severityOrder.indexOf(max);
167
+ return i1 < i2 ? p.severity : max;
168
+ }, "Low");
169
+ // Recommendation based on highest severity
170
+ let recommendation;
171
+ if (maxSeverity === "Critical")
172
+ recommendation = "Block";
173
+ else if (maxSeverity === "High")
174
+ recommendation = "Warn";
175
+ else
176
+ recommendation = "Allow";
177
+ // Look up Knowledge Unit
178
+ let unitId = "", unitVersion = "", unitRfc;
179
+ try {
180
+ const { buildKnowledgeBase } = require("./protocol-knowledge");
181
+ const kb = buildKnowledgeBase();
182
+ const unit = kb.units.find((u) => u.name === patterns[0].protocolName);
183
+ if (unit) {
184
+ unitId = unit.id;
185
+ unitVersion = unit.currentVersion;
186
+ unitRfc = unit.rfcReference;
187
+ }
188
+ }
189
+ catch { /* KB unavailable */ }
190
+ return {
191
+ riskLevel: maxSeverity,
192
+ patterns: patterns.map(p => ({
193
+ patternId: p.id,
194
+ patternName: p.name,
195
+ severity: p.severity,
196
+ confidence: p.confidence,
197
+ concept: p.conceptName,
198
+ detail: p.detail || p.description,
199
+ })),
200
+ knowledgeUnit: { id: unitId, name: patterns[0].protocolName, version: unitVersion, rfc: unitRfc },
201
+ recommendation,
202
+ summary: patterns.length === 1
203
+ ? `${patterns[0].name}: ${patterns[0].detail || patterns[0].description}`
204
+ : `${patterns.length} risk patterns detected. Highest: ${patterns[0].name} (${maxSeverity}).`,
205
+ };
206
+ }
207
+ // ═══════════════════════════════════════════════════════════════
208
+ // CLI
209
+ // ═══════════════════════════════════════════════════════════════
210
+ if (require.main === module) {
211
+ const args = process.argv.slice(2);
212
+ const calls = args.length > 0 ? args : ["SSL_CTX_new", "SSL_connect"];
213
+ const risk = assessRisk(calls);
214
+ console.log(JSON.stringify(risk, null, 2));
215
+ }
@@ -1,10 +1,237 @@
1
1
  "use strict";
2
+ /**
3
+ * Rule Miner — generates actionable protocol rules from failure patterns.
4
+ *
5
+ * Upgrades the passive diagnostic to an active rule generator:
6
+ * 1. Analyses the failure corpus for recurring SVL-4 violations
7
+ * 2. Generates FunctionProtocol entries from fix paths
8
+ * 3. Can merge rules into protocols.json (dry-run by default)
9
+ */
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
22
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
23
+ }) : function(o, v) {
24
+ o["default"] = v;
25
+ });
26
+ var __importStar = (this && this.__importStar) || (function () {
27
+ var ownKeys = function(o) {
28
+ ownKeys = Object.getOwnPropertyNames || function (o) {
29
+ var ar = [];
30
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
31
+ return ar;
32
+ };
33
+ return ownKeys(o);
34
+ };
35
+ return function (mod) {
36
+ if (mod && mod.__esModule) return mod;
37
+ var result = {};
38
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
39
+ __setModuleDefault(result, mod);
40
+ return result;
41
+ };
42
+ })();
2
43
  Object.defineProperty(exports, "__esModule", { value: true });
44
+ exports.mineRules = mineRules;
45
+ exports.toProtocolEntries = toProtocolEntries;
46
+ exports.applyMinedRules = applyMinedRules;
47
+ exports.mineAntibodiesV2 = mineAntibodiesV2;
48
+ const fs = __importStar(require("fs"));
49
+ const path = __importStar(require("path"));
3
50
  const failure_corpus_1 = require("./failure-corpus");
4
- console.log("═══ 失败模式分析 ═══");
5
- const patterns = (0, failure_corpus_1.getTopFailurePatterns)(5);
6
- console.log("Top 5 失败模式:");
7
- patterns.forEach(p => console.log(` ${p.pattern}: ${p.count} 次`));
8
- console.log("\n候选规则建议:");
9
- const rules = (0, failure_corpus_1.generateCandidateRules)();
10
- rules.forEach(r => console.log(` - ${r}`));
51
+ /**
52
+ * Mine protocol rules from failure patterns.
53
+ *
54
+ * Analyses SVL-4 protocol violations to infer state transitions
55
+ * that should be encoded as permanent protocol rules.
56
+ */
57
+ function mineRules() {
58
+ const genome = (0, failure_corpus_1.getFailureGenome)();
59
+ const patterns = (0, failure_corpus_1.getTopFailurePatterns)(10);
60
+ const mined = [];
61
+ // Strategy 1: Convert common fix paths into protocol rules
62
+ const ssgFixes = genome.commonFixPaths.filter(f => f.violation === "SVL-4");
63
+ for (const fix of ssgFixes) {
64
+ if (fix.fixPath.length < 2)
65
+ continue;
66
+ for (let i = 0; i < fix.fixPath.length - 1; i++) {
67
+ const currentFn = fix.fixPath[i];
68
+ const nextFn = fix.fixPath[i + 1];
69
+ mined.push({
70
+ function: currentFn,
71
+ pre_states: [],
72
+ post_states: [`READY_FOR_${nextFn.toUpperCase()}`],
73
+ namespace: "_global",
74
+ reason: `Fix path ${fix.fixPath.join(" → ")} observed ${fix.count} times`,
75
+ confidence: fix.count,
76
+ });
77
+ mined.push({
78
+ function: nextFn,
79
+ pre_states: [`READY_FOR_${nextFn.toUpperCase()}`],
80
+ post_states: ["COMPLETED"],
81
+ namespace: "_global",
82
+ reason: `Fix path continuation: ${currentFn} → ${nextFn}`,
83
+ confidence: fix.count,
84
+ });
85
+ }
86
+ }
87
+ // Strategy 2: Pattern-based rules from top violations
88
+ const PATTERN_RULES = {
89
+ symbol_existence: { pre: [], post: ["IR_VALIDATED"], desc: "只使用 IR 中已导出的函数,禁止编造函数名" },
90
+ type_mismatch: { pre: [], post: ["TYPE_CHECKED"], desc: "检查参数类型与 IR 签名一致后再调用" },
91
+ dataflow: { pre: [], post: ["DATAFLOW_VALID"], desc: "变量必须先声明再使用,避免循环引用" },
92
+ protocol: { pre: ["INIT"], post: ["PROTOCOL_COMPLIANT"], desc: "严格遵循 SSG 协议状态顺序调用函数" },
93
+ missing_import: { pre: [], post: ["IMPORT_RESOLVED"], desc: "只从已导出的模块导入符号" },
94
+ params_undefined: { pre: [], post: ["PARAMS_SAFE"], desc: "调用 .map/.filter 前检查对象是否为数组,使用 (obj || [])" },
95
+ };
96
+ for (const p of patterns) {
97
+ // Extract constraint type from pattern (e.g. "SVL-1:symbol_existence" → "symbol_existence")
98
+ const constraintMatch = p.pattern.match(/SVL-\d:(.+)/);
99
+ if (!constraintMatch)
100
+ continue;
101
+ const constraintType = constraintMatch[1];
102
+ const rule = PATTERN_RULES[constraintType];
103
+ if (rule) {
104
+ mined.push({
105
+ function: constraintType,
106
+ pre_states: rule.pre,
107
+ post_states: rule.post,
108
+ namespace: "mined",
109
+ reason: `Pattern "${constraintType}" occurred ${p.count} times → ${rule.desc}`,
110
+ confidence: p.count,
111
+ });
112
+ }
113
+ else {
114
+ // Generic fallback for unknown patterns
115
+ mined.push({
116
+ function: constraintType,
117
+ pre_states: ["INIT"],
118
+ post_states: ["VALIDATED"],
119
+ namespace: "mined",
120
+ reason: `Unknown pattern "${constraintType}" occurred ${p.count} times`,
121
+ confidence: p.count,
122
+ });
123
+ }
124
+ }
125
+ // Deduplicate by function name (keep highest confidence)
126
+ const seen = new Map();
127
+ for (const rule of mined) {
128
+ const key = `${rule.function}:${rule.namespace}`;
129
+ if (!seen.has(key) || seen.get(key).confidence < rule.confidence) {
130
+ seen.set(key, rule);
131
+ }
132
+ }
133
+ return [...seen.values()].sort((a, b) => b.confidence - a.confidence);
134
+ }
135
+ /**
136
+ * Convert mined rules to FunctionProtocol format compatible with protocols.json.
137
+ */
138
+ function toProtocolEntries(rules) {
139
+ const entries = {};
140
+ for (const r of rules) {
141
+ entries[r.function] = {
142
+ pre_states: r.pre_states,
143
+ post_states: r.post_states,
144
+ ...(r.invalidate && r.invalidate.length > 0 ? { invalidate: r.invalidate } : {}),
145
+ ...(r.namespace !== "_global" ? { namespace: r.namespace } : {}),
146
+ _mined: { reason: r.reason, confidence: r.confidence },
147
+ };
148
+ }
149
+ return entries;
150
+ }
151
+ /**
152
+ * Merge mined rules into protocols.json.
153
+ * Dry-run by default — set apply=true to write.
154
+ */
155
+ function applyMinedRules(apply = false) {
156
+ const mined = mineRules();
157
+ const protocolsPath = path.resolve(__dirname, "..", "protocols.json");
158
+ let existing = {};
159
+ if (fs.existsSync(protocolsPath)) {
160
+ existing = JSON.parse(fs.readFileSync(protocolsPath, "utf-8"));
161
+ }
162
+ const newEntries = toProtocolEntries(mined);
163
+ let merged = 0;
164
+ let skipped = 0;
165
+ for (const [fn, rule] of Object.entries(newEntries)) {
166
+ if (existing[fn]) {
167
+ skipped++;
168
+ continue; // Don't overwrite existing rules
169
+ }
170
+ existing[fn] = rule;
171
+ merged++;
172
+ }
173
+ if (apply && merged > 0) {
174
+ // Backup original
175
+ const backup = protocolsPath + ".bak";
176
+ if (fs.existsSync(protocolsPath)) {
177
+ fs.copyFileSync(protocolsPath, backup);
178
+ }
179
+ fs.writeFileSync(protocolsPath, JSON.stringify(existing, null, 2));
180
+ console.error(`[规则挖掘] 已将 ${merged} 条规则写入 ${protocolsPath}(备份: ${backup})`);
181
+ }
182
+ return { rules: mined, merged, skipped, dryRun: !apply };
183
+ }
184
+ /**
185
+ * Mine antibody candidates from Schema v2 failure records.
186
+ * Returns patterns that recurred >= minCount times.
187
+ */
188
+ function mineAntibodiesV2(minCount = 3) {
189
+ const all = (0, failure_corpus_1.loadTrajectories)().filter(t => t.result === "violation");
190
+ if (all.length === 0)
191
+ return [];
192
+ const groups = {};
193
+ for (const t of all) {
194
+ const key = `${t.violation?.type || "other"}|${t.protocol}`;
195
+ if (!groups[key])
196
+ groups[key] = [];
197
+ groups[key].push(t);
198
+ }
199
+ const candidates = [];
200
+ for (const [key, records] of Object.entries(groups)) {
201
+ if (records.length < minCount)
202
+ continue;
203
+ const [violationType, protocol] = key.split("|");
204
+ const avgDepth = Math.round(records.reduce((s, t) => s + t.context.nestingDepth, 0) / records.length);
205
+ const fixPaths = [...new Set(records.flatMap(t => t.violation?.fixPath || []))];
206
+ const avgSuccess = records.length > 0
207
+ ? records.reduce((s, t) => s + t.successRate, 0) / records.length
208
+ : 0;
209
+ const timestamps = records.map(f => f.timestamp).sort();
210
+ candidates.push({
211
+ id: `ab2_${violationType}_${protocol}_${Date.now()}`,
212
+ violationType: violationType,
213
+ protocol,
214
+ contextPattern: { nestingDepth: avgDepth },
215
+ fixPath: fixPaths.slice(0, 5),
216
+ promoteToStatic: ["resource_leak", "protocol_violation", "illegal_state_transition"].includes(violationType),
217
+ occurrenceCount: records.length,
218
+ avgSuccessRate: avgSuccess,
219
+ firstSeen: timestamps[0] || "N/A",
220
+ lastSeen: timestamps[timestamps.length - 1] || "N/A",
221
+ minedAt: new Date().toISOString(),
222
+ });
223
+ }
224
+ return candidates.sort((a, b) => b.occurrenceCount - a.occurrenceCount);
225
+ }
226
+ /** CLI entry point: print mined rules without applying. */
227
+ if (require.main === module) {
228
+ const result = applyMinedRules(false);
229
+ console.log(`\n挖掘到 ${result.rules.length} 条候选规则(dry-run):`);
230
+ for (const r of result.rules) {
231
+ console.log(` ${r.function}: [${r.pre_states.join(",")}] → [${r.post_states.join(",")}] (置信度: ${r.confidence})`);
232
+ console.log(` 原因: ${r.reason}`);
233
+ }
234
+ if (result.rules.length > 0) {
235
+ console.log(`\n应用规则: node -e "require('./dist/rule-miner').applyMinedRules(true)"`);
236
+ }
237
+ }