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,229 @@
1
+ "use strict";
2
+ /**
3
+ * FP Taxonomy Analyzer
4
+ *
5
+ * Classifies every false positive from a precision report into
6
+ * root cause categories. This tells us WHY precision is low
7
+ * before we attempt to fix anything.
8
+ *
9
+ * Usage:
10
+ * npx ts-node src/precision-analyze.ts benchmarks/curl
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 fs = __importStar(require("fs"));
47
+ const path = __importStar(require("path"));
48
+ const resource_detector_1 = require("./resource-detector");
49
+ // ── Classification Logic ──
50
+ function classifyFP(calls, funcName, reason) {
51
+ // 1. State inference noise: SSG auto-discovered rule rejected valid ordering
52
+ // Pattern: reason contains "requires [C0_S...] but state has [INIT,C0_S...]"
53
+ if (reason.includes("requires [C") && reason.includes("but state has [")) {
54
+ return "state_inference_noise";
55
+ }
56
+ // 2. Check if this is a resource lifecycle false positive
57
+ const resourceVios = (0, resource_detector_1.detectResourceViolations)(calls);
58
+ // 3. Allocator-return: function name suggests it's a factory/allocator
59
+ const allocatorPatterns = /\b(create|alloc|new|init|open|dup|clone|copy|build|make)\w*\b/i;
60
+ const isAllocator = allocatorPatterns.test(funcName);
61
+ if (isAllocator && resourceVios.some(v => v.type === "missing_release")) {
62
+ return "allocator_return";
63
+ }
64
+ // 4. Cross-function cleanup: resource acquired here, released elsewhere
65
+ // Pattern: has acquire calls + has no matching release in this function
66
+ const hasAcquire = /\b(malloc|calloc|open|connect|SSL_new|BIO_new|Curl_open|ngx_.*_init|ngx_.*_create)\b/i;
67
+ const hasRelease = /\b(free|close|disconnect|SSL_free|BIO_free|Curl_close|ngx_.*_free|ngx_.*_cleanup)\b/i;
68
+ const callsStr = calls.join(" ");
69
+ if (hasAcquire.test(callsStr) && !hasRelease.test(callsStr) && !isAllocator) {
70
+ return "cross_function_cleanup";
71
+ }
72
+ // 5. Callback ownership: common async/event pattern
73
+ const callbackPatterns = /\b(callback|cb_|_cb|handler|on_|_done|_complete|_finish)\b/i;
74
+ if (callbackPatterns.test(funcName) || calls.some(c => callbackPatterns.test(c))) {
75
+ return "callback_ownership";
76
+ }
77
+ // 6. Noise call: logging/debug/trace functions in the call list
78
+ const noisePatterns = /\b(infof|failf|DEBUGF|DEBUGASSERT|log|trace|debug|print|dump|assert)\b/i;
79
+ const noiseCount = calls.filter(c => noisePatterns.test(c)).length;
80
+ if (noiseCount >= calls.length * 0.3) {
81
+ return "noise_call";
82
+ }
83
+ // 7. Protocol extraction error: calls don't form a meaningful protocol sequence
84
+ const protocolPatterns = /\b(init|open|connect|send|recv|read|write|close|free|cleanup|finish|done|stop|start)\b/i;
85
+ const protocolCount = calls.filter(c => protocolPatterns.test(c)).length;
86
+ if (protocolCount < calls.length * 0.3) {
87
+ return "protocol_extraction_error";
88
+ }
89
+ return "unknown";
90
+ }
91
+ function classifyFN(calls, funcName, reason) {
92
+ // FN: human said violation, detector said clean
93
+ // Why didn't the detector catch this?
94
+ const callsStr = calls.join(" ");
95
+ // State machine functions that are missing transitions
96
+ const stateMachinePatterns = /\b(state|statemachine|_step|_phase)\w*\b/i;
97
+ if (stateMachinePatterns.test(funcName)) {
98
+ return "state_inference_noise"; // Detector didn't learn the state machine correctly
99
+ }
100
+ // Missing acquire before release
101
+ const hasRelease = /\b(free|close|disconnect|SSL_free|BIO_free|cleanup|destroy)\b/i;
102
+ const hasAcquire = /\b(malloc|open|connect|SSL_new|BIO_new|init|create)\b/i;
103
+ if (hasRelease.test(callsStr) && !hasAcquire.test(callsStr)) {
104
+ return "cross_function_cleanup"; // Release without acquire in same function
105
+ }
106
+ return "unknown";
107
+ }
108
+ // ── Main Analyzer ──
109
+ function analyze(repoPath) {
110
+ const precFile = path.join(path.dirname(repoPath), `${path.basename(repoPath)}-precision.json`);
111
+ if (!fs.existsSync(precFile)) {
112
+ console.error(`❌ Precision report not found: ${precFile}`);
113
+ process.exit(1);
114
+ }
115
+ const report = JSON.parse(fs.readFileSync(precFile, "utf-8"));
116
+ const details = report.details || [];
117
+ const fpCases = details.filter((d) => d.expected === "clean" && d.detected === "violation");
118
+ const fnCases = details.filter((d) => d.expected === "violation" && d.detected === "clean");
119
+ console.error(`\nAnalyzing ${report.total} samples: ${report.fp} FP, ${report.fn} FN`);
120
+ // Classify FPs
121
+ const fpByCategory = new Map();
122
+ for (const d of fpCases) {
123
+ const cat = classifyFP(d.calls || [], d.calls?.[0] || "", d.reason || "");
124
+ if (!fpByCategory.has(cat))
125
+ fpByCategory.set(cat, []);
126
+ fpByCategory.get(cat).push(d);
127
+ }
128
+ // Classify FNs
129
+ const fnByCategory = new Map();
130
+ for (const d of fnCases) {
131
+ const cat = classifyFN(d.calls || [], d.calls?.[0] || "", d.reason || "");
132
+ if (!fnByCategory.has(cat))
133
+ fnByCategory.set(cat, []);
134
+ fnByCategory.get(cat).push(d);
135
+ }
136
+ // ═══ FP Taxonomy Report ═══
137
+ const C = {
138
+ reset: "\x1b[0m", bold: "\x1b[1m", dim: "\x1b[2m",
139
+ green: "\x1b[32m", red: "\x1b[31m", yellow: "\x1b[33m", cyan: "\x1b[36m",
140
+ };
141
+ const CATEGORY_LABELS = {
142
+ state_inference_noise: {
143
+ label: "State inference noise",
144
+ desc: "Auto-discovered SSG rules overfit to call order. Valid protocol sequences flagged because they don't match the learned adjacency pattern.",
145
+ fix: "Replace auto-discovered rules with hand-written protocol definitions. Increase clean training sequences from 29 to 100+.",
146
+ },
147
+ cross_function_cleanup: {
148
+ label: "Cross-function cleanup",
149
+ desc: "Resource acquired in this function but released elsewhere (caller, callback, cleanup phase). Detector assumes acquire+release must be in same scope.",
150
+ fix: "Model protocol lifecycle across function boundaries. Recognize that acquire in step1() may be released in cleanup().",
151
+ },
152
+ allocator_return: {
153
+ label: "Allocator-return pattern",
154
+ desc: "Function allocates resource and returns it to caller. Detector sees malloc without free and flags as leak — but the caller is responsible for cleanup.",
155
+ fix: "Identify factory/allocator functions by name pattern. Exclude them from acquire-without-release checks.",
156
+ },
157
+ callback_ownership: {
158
+ label: "Callback ownership",
159
+ desc: "Resource passed to async callback. Ownership transfers — cleanup responsibility moves to callback or event handler.",
160
+ fix: "Track resource ownership across callback boundaries. Recognize event-driven cleanup patterns.",
161
+ },
162
+ noise_call: {
163
+ label: "Noise call in sequence",
164
+ desc: "Logging, debug, or trace calls mixed into protocol sequences. These create false adjacency patterns in SSG rule discovery.",
165
+ fix: "Filter noise calls (infof, failf, DEBUGF, etc.) before rule discovery.",
166
+ },
167
+ protocol_extraction_error: {
168
+ label: "Protocol extraction error",
169
+ desc: "Extracted calls don't form a real protocol sequence. C function call extraction picked up utility calls rather than protocol steps.",
170
+ fix: "Improve C call extraction: filter utility functions, focus on named protocol operations.",
171
+ },
172
+ unknown: {
173
+ label: "Unknown / Other",
174
+ desc: "Doesn't match any known FP pattern. Requires manual inspection.",
175
+ fix: "Manual review of individual cases.",
176
+ },
177
+ };
178
+ console.log(`\n${C.bold}${C.cyan}╔══════════════════════════════════════════════════════════════╗${C.reset}`);
179
+ console.log(`${C.bold}${C.cyan}║${C.reset} ${C.bold}FP Taxonomy Report — curl${C.reset} ${C.bold}${C.cyan}║${C.reset}`);
180
+ console.log(`${C.bold}${C.cyan}╚══════════════════════════════════════════════════════════════╝${C.reset}`);
181
+ console.log("");
182
+ // FP Breakdown
183
+ console.log(`${C.bold}False Positives (${fpCases.length}):${C.reset}\n`);
184
+ const fpSorted = [...fpByCategory.entries()].sort((a, b) => b[1].length - a[1].length);
185
+ for (const [cat, cases] of fpSorted) {
186
+ const pct = ((cases.length / fpCases.length) * 100).toFixed(0);
187
+ const bar = "█".repeat(Math.round(cases.length / fpCases.length * 30));
188
+ const info = CATEGORY_LABELS[cat];
189
+ console.log(` ${C.red}${bar}${C.reset} ${pct}% ${C.bold}${info.label}${C.reset} (${cases.length} cases)`);
190
+ console.log(` ${C.dim}${info.desc}${C.reset}`);
191
+ // Show 2 examples
192
+ for (const ex of cases.slice(0, 2)) {
193
+ console.log(` ${C.dim} ex: ${(ex.calls || []).slice(0, 4).join(" → ")}${C.reset}`);
194
+ }
195
+ console.log("");
196
+ }
197
+ // FN Breakdown
198
+ console.log(`${C.bold}False Negatives (${fnCases.length}):${C.reset}\n`);
199
+ const fnSorted = [...fnByCategory.entries()].sort((a, b) => b[1].length - a[1].length);
200
+ for (const [cat, cases] of fnSorted) {
201
+ const pct = ((cases.length / fnCases.length) * 100).toFixed(0);
202
+ const bar = "█".repeat(Math.round(cases.length / Math.max(1, fnCases.length) * 30));
203
+ const info = CATEGORY_LABELS[cat];
204
+ console.log(` ${C.yellow}${bar}${C.reset} ${pct}% ${C.bold}${info.label}${C.reset} (${cases.length} cases)`);
205
+ for (const ex of cases.slice(0, 2)) {
206
+ console.log(` ${C.dim} ex: ${(ex.calls || []).slice(0, 4).join(" → ")}${C.reset}`);
207
+ }
208
+ console.log("");
209
+ }
210
+ // Fix priority
211
+ console.log(`${C.bold}Fix Priority:${C.reset}`);
212
+ const topFP = fpSorted[0];
213
+ if (topFP) {
214
+ const info = CATEGORY_LABELS[topFP[0]];
215
+ console.log(` 1. ${C.red}${info.label}${C.reset} — ${topFP[1].length} cases (${((topFP[1].length / fpCases.length) * 100).toFixed(0)}% of FP)`);
216
+ console.log(` ${C.dim}→ ${info.fix}${C.reset}`);
217
+ }
218
+ if (fpSorted[1]) {
219
+ const info = CATEGORY_LABELS[fpSorted[1][0]];
220
+ console.log(` 2. ${info.label} — ${fpSorted[1][1].length} cases`);
221
+ }
222
+ console.log(` 3. Expand curl labels from ${report.total} to 100-150 samples`);
223
+ console.log(` 4. Re-measure Precision after fixing top category`);
224
+ console.log("");
225
+ }
226
+ // CLI
227
+ const args = process.argv.slice(2);
228
+ const repoPath = path.resolve(args.find(a => !a.startsWith("--")) || ".");
229
+ analyze(repoPath);
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.runPrecisionBenchmark = runPrecisionBenchmark;
37
+ const fs = __importStar(require("fs"));
38
+ const state_inference_1 = require("./experimental/state-inference");
39
+ /**
40
+ * Run precision benchmark with labeled data.
41
+ *
42
+ * Detection logic (structural, not template-matching):
43
+ * 1. Build REFERENCE SM from clean-labeled sequences
44
+ * 2. For each test sequence, build its SM
45
+ * 3. Compare: if a sequence has ≥2 fewer states than the reference,
46
+ * OR has illegal transitions not in the reference, it's flagged.
47
+ * 4. Measure TP/FP/TN/FN against labels.
48
+ */
49
+ function runPrecisionBenchmark(sequences, labels) {
50
+ // Build reference SM from clean sequences only
51
+ const cleanSeqs = sequences
52
+ .filter(s => labels[s.index] === 'clean' && s.calls.length >= 2)
53
+ .map(s => s.calls);
54
+ if (cleanSeqs.length === 0) {
55
+ return { total: 0, truePositive: 0, falsePositive: 0, trueNegative: 0, falseNegative: 0, precision: 0, recall: 0, f1: 0, mismatches: [] };
56
+ }
57
+ const referenceSM = (0, state_inference_1.inferStateMachine)(cleanSeqs);
58
+ const refStateCount = referenceSM.stateCount;
59
+ // Extract reference edge set (what transitions are "normal")
60
+ const refEdges = new Set();
61
+ for (let i = 0; i < referenceSM.stateTransitions.length; i++)
62
+ for (let j = 0; j < (referenceSM.stateTransitions[i] || []).length; j++)
63
+ if (referenceSM.stateTransitions[i][j] > 0)
64
+ refEdges.add(`${i}→${j}`);
65
+ let tp = 0, fp = 0, tn = 0, fn = 0;
66
+ const mismatches = [];
67
+ for (const seq of sequences) {
68
+ const expected = labels[seq.index] || 'skip';
69
+ if (expected === 'skip')
70
+ continue;
71
+ if (seq.calls.length < 2) {
72
+ tn++;
73
+ continue;
74
+ }
75
+ const testSM = (0, state_inference_1.inferStateMachine)([seq.calls]);
76
+ const stateDiff = refStateCount - testSM.stateCount;
77
+ // Detection: flagged if ≥2 fewer states than reference
78
+ const detected = stateDiff >= 2 ? 'violation' : 'clean';
79
+ let matched = false;
80
+ if (expected === 'clean' && detected === 'clean') {
81
+ tn++;
82
+ matched = true;
83
+ }
84
+ else if (expected === 'violation' && detected === 'violation') {
85
+ tp++;
86
+ matched = true;
87
+ }
88
+ else if (expected === 'clean' && detected === 'violation') {
89
+ fp++;
90
+ }
91
+ else if (expected === 'violation' && detected === 'clean') {
92
+ fn++;
93
+ }
94
+ if (!matched) {
95
+ mismatches.push({
96
+ index: seq.index,
97
+ functionName: seq.functionName,
98
+ expected,
99
+ detected,
100
+ stateDiff,
101
+ calls: seq.calls,
102
+ });
103
+ }
104
+ }
105
+ const total = tp + fp + tn + fn;
106
+ const precision = total > 0 ? tp / (tp + fp) : 0;
107
+ const recall = total > 0 ? tp / (tp + fn) : 0;
108
+ const f1 = precision + recall > 0 ? 2 * precision * recall / (precision + recall) : 0;
109
+ return { total, truePositive: tp, falsePositive: fp, trueNegative: tn, falseNegative: fn, precision, recall, f1, mismatches };
110
+ }
111
+ // ================ CLI ================
112
+ const args = process.argv.slice(2);
113
+ const seqFile = args[0];
114
+ const labelFile = args[1];
115
+ if (!seqFile || !labelFile) {
116
+ console.error('Usage: npx tsx src/precision-benchmark.ts <sequences.json> <labels.json>');
117
+ process.exit(1);
118
+ }
119
+ const seqData = JSON.parse(fs.readFileSync(seqFile, 'utf-8'));
120
+ const sequences = seqData.sequences || seqData;
121
+ const labels = JSON.parse(fs.readFileSync(labelFile, 'utf-8'));
122
+ console.log('Running precision benchmark...');
123
+ const result = runPrecisionBenchmark(sequences, labels);
124
+ console.log('\n=== Precision Benchmark Results ===');
125
+ console.log(`Total sequences evaluated: ${result.total}`);
126
+ console.log(`True Positives: ${result.truePositive}`);
127
+ console.log(`False Positives: ${result.falsePositive}`);
128
+ console.log(`True Negatives: ${result.trueNegative}`);
129
+ console.log(`False Negatives: ${result.falseNegative}`);
130
+ console.log(`\nPrecision: ${(result.precision * 100).toFixed(1)}%`);
131
+ console.log(`Recall: ${(result.recall * 100).toFixed(1)}%`);
132
+ console.log(`F1 Score: ${(result.f1 * 100).toFixed(1)}%`);
133
+ // 显示不匹配的详情
134
+ const mismatches = (result.details || []).filter((d) => !d.matched);
135
+ if (mismatches.length > 0) {
136
+ console.log(`\n--- Mismatches (${mismatches.length}) ---`);
137
+ for (const m of mismatches) {
138
+ console.log(` [${m.index}] ${m.functionName}: expected=${m.expected}, detected=${m.detected}`);
139
+ }
140
+ }
141
+ // 保存报告
142
+ const report = {
143
+ timestamp: new Date().toISOString(),
144
+ result
145
+ };
146
+ fs.writeFileSync('benchmarks/precision-report.json', JSON.stringify(report, null, 2));
147
+ console.log('\nReport saved to benchmarks/precision-report.json');
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ /**
3
+ * Precision Labeling Tool for C/C++ projects
4
+ *
5
+ * Reads pre-extracted sequences JSON and saves labels.
6
+ * For TypeScript projects, use precision-label.ts instead.
7
+ *
8
+ * Usage:
9
+ * npx ts-node src/precision-label-c.ts benchmarks/curl
10
+ */
11
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ var desc = Object.getOwnPropertyDescriptor(m, k);
14
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
+ desc = { enumerable: true, get: function() { return m[k]; } };
16
+ }
17
+ Object.defineProperty(o, k2, desc);
18
+ }) : (function(o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ o[k2] = m[k];
21
+ }));
22
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
24
+ }) : function(o, v) {
25
+ o["default"] = v;
26
+ });
27
+ var __importStar = (this && this.__importStar) || (function () {
28
+ var ownKeys = function(o) {
29
+ ownKeys = Object.getOwnPropertyNames || function (o) {
30
+ var ar = [];
31
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
32
+ return ar;
33
+ };
34
+ return ownKeys(o);
35
+ };
36
+ return function (mod) {
37
+ if (mod && mod.__esModule) return mod;
38
+ var result = {};
39
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
40
+ __setModuleDefault(result, mod);
41
+ return result;
42
+ };
43
+ })();
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ const fs = __importStar(require("fs"));
46
+ const path = __importStar(require("path"));
47
+ const readline = __importStar(require("readline"));
48
+ const C = {
49
+ reset: "\x1b[0m", bold: "\x1b[1m", dim: "\x1b[2m",
50
+ green: "\x1b[32m", red: "\x1b[31m", yellow: "\x1b[33m", cyan: "\x1b[36m",
51
+ };
52
+ async function main() {
53
+ const args = process.argv.slice(2);
54
+ const repoPath = path.resolve(args.find(a => !a.startsWith("--")) || ".");
55
+ const maxSeq = parseInt(args.includes("--max") ? args[args.indexOf("--max") + 1] : "50", 10);
56
+ const resume = args.includes("--resume");
57
+ const seqFile = path.join(path.dirname(repoPath), `${path.basename(repoPath)}-sequences.json`);
58
+ const labelFile = path.join(path.dirname(repoPath), `${path.basename(repoPath)}-labels.json`);
59
+ if (!fs.existsSync(seqFile)) {
60
+ console.error(`❌ Sequences file not found: ${seqFile}`);
61
+ console.error(` Run C extraction first to generate this file.`);
62
+ process.exit(1);
63
+ }
64
+ // Load sequences
65
+ const allSeqs = JSON.parse(fs.readFileSync(seqFile, "utf-8"));
66
+ const sequences = allSeqs.slice(0, maxSeq);
67
+ // Load existing labels (resume)
68
+ let data = { repo: repoPath, labeledAt: "", total: 0, labels: {}, sequences: {} };
69
+ if (fs.existsSync(labelFile) && resume) {
70
+ data = JSON.parse(fs.readFileSync(labelFile, "utf-8"));
71
+ }
72
+ else if (fs.existsSync(labelFile)) {
73
+ data = JSON.parse(fs.readFileSync(labelFile, "utf-8"));
74
+ }
75
+ const alreadyLabeled = Object.keys(data.labels).length;
76
+ console.error(`\n${C.bold}${C.cyan}Precision Labeling — C/C++ Projects${C.reset}`);
77
+ console.error(` Sequences: ${sequences.length} (${alreadyLabeled} already labeled)`);
78
+ console.error(` Commands: ${C.green}c${C.reset}=clean ${C.red}v${C.reset}=violation ${C.yellow}s${C.reset}=skip q=quit\n`);
79
+ console.error(` ${C.dim}clean = protocol looks complete (init→use→cleanup present)${C.reset}`);
80
+ console.error(` ${C.dim}violation = protocol incomplete (missing init/cleanup, wrong order)${C.reset}`);
81
+ console.error(``);
82
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
83
+ const ask = (q) => new Promise(resolve => rl.question(q, resolve));
84
+ let labeled = 0;
85
+ let skipped = 0;
86
+ for (let i = 0; i < sequences.length; i++) {
87
+ if (data.labels[i] !== undefined)
88
+ continue;
89
+ const seq = sequences[i];
90
+ const calls = seq.calls.slice(0, 8);
91
+ const more = seq.calls.length > 8 ? ` … (+${seq.calls.length - 8} more)` : "";
92
+ console.error(`${C.bold}[${i + 1}/${sequences.length}]${C.reset} ${C.dim}${seq.file || ""}${C.reset}`);
93
+ console.error(` ${C.cyan}${seq.function}${C.reset}`);
94
+ console.error(` → ${calls.join(" → ")}${more}`);
95
+ const answer = await ask(` ${C.green}[c]lean${C.reset} ${C.red}[v]iolation${C.reset} ${C.yellow}[s]kip${C.reset} [q]uit: `);
96
+ switch (answer) {
97
+ case "q":
98
+ console.error(`\n Quit. Saving ${labeled} new labels...`);
99
+ rl.close();
100
+ saveLabels(labelFile, data, labeled + alreadyLabeled);
101
+ return;
102
+ case "s":
103
+ skipped++;
104
+ console.error(` ${C.yellow}↻ skipped${C.reset}\n`);
105
+ continue;
106
+ case "c":
107
+ data.labels[i] = "clean";
108
+ data.sequences[i] = seq.calls;
109
+ labeled++;
110
+ console.error(` ${C.green}✓ clean${C.reset}\n`);
111
+ break;
112
+ case "v":
113
+ data.labels[i] = "violation";
114
+ data.sequences[i] = seq.calls;
115
+ labeled++;
116
+ console.error(` ${C.red}✗ violation${C.reset}\n`);
117
+ break;
118
+ default:
119
+ console.error(` ${C.yellow}? unknown — use c/v/s/q${C.reset}\n`);
120
+ break;
121
+ }
122
+ }
123
+ rl.close();
124
+ saveLabels(labelFile, data, labeled + alreadyLabeled);
125
+ console.error(`\n Clean: ${Object.values(data.labels).filter((l) => l === "clean").length}`);
126
+ console.error(` Violation: ${Object.values(data.labels).filter((l) => l === "violation").length}`);
127
+ console.error(`\n Next: npx ts-node src/precision-report-c.ts ${repoPath}\n`);
128
+ }
129
+ function saveLabels(filePath, data, total) {
130
+ data.labeledAt = new Date().toISOString();
131
+ data.total = total;
132
+ fs.writeFileSync(filePath, JSON.stringify(data, null, 2), "utf-8");
133
+ }
134
+ main().catch(e => { console.error(e); process.exit(1); });