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,354 @@
1
+ "use strict";
2
+ /**
3
+ * P6.0v2: AST-based Protocol Extractor
4
+ *
5
+ * Targets: Precision > 70%, Recall > 50%
6
+ *
7
+ * Improvements over v1 (regex-based):
8
+ * 1. Scope-aware pairing — calls within same function, not across
9
+ * 2. AST-based extraction for TS/JS via ts-morph
10
+ * 3. Function boundary detection for C/C++
11
+ * 4. Better noise filtering (utility/logging/test functions)
12
+ * 5. Cross-file call graph construction
13
+ * 6. Frequency-weighted confidence with quality tiers
14
+ */
15
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ var desc = Object.getOwnPropertyDescriptor(m, k);
18
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
19
+ desc = { enumerable: true, get: function() { return m[k]; } };
20
+ }
21
+ Object.defineProperty(o, k2, desc);
22
+ }) : (function(o, m, k, k2) {
23
+ if (k2 === undefined) k2 = k;
24
+ o[k2] = m[k];
25
+ }));
26
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
27
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
28
+ }) : function(o, v) {
29
+ o["default"] = v;
30
+ });
31
+ var __importStar = (this && this.__importStar) || (function () {
32
+ var ownKeys = function(o) {
33
+ ownKeys = Object.getOwnPropertyNames || function (o) {
34
+ var ar = [];
35
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
36
+ return ar;
37
+ };
38
+ return ownKeys(o);
39
+ };
40
+ return function (mod) {
41
+ if (mod && mod.__esModule) return mod;
42
+ var result = {};
43
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
44
+ __setModuleDefault(result, mod);
45
+ return result;
46
+ };
47
+ })();
48
+ Object.defineProperty(exports, "__esModule", { value: true });
49
+ exports.extractProtocolV2 = extractProtocolV2;
50
+ exports.printExtractionQuality = printExtractionQuality;
51
+ const fs = __importStar(require("fs"));
52
+ const path = __importStar(require("path"));
53
+ const ts_morph_1 = require("ts-morph");
54
+ const repo_evaluator_1 = require("./repo-evaluator");
55
+ const protocol_coverage_1 = require("./protocol-coverage");
56
+ /**
57
+ * Extract call pairs from a TypeScript/JavaScript file using ts-morph AST.
58
+ *
59
+ * Only pairs calls that appear within the same function body.
60
+ * This eliminates cross-function noise (e.g., main→writeFile paired with closeFile in another function).
61
+ */
62
+ function extractTSCallPairs(filePath) {
63
+ const pairs = [];
64
+ try {
65
+ const project = new ts_morph_1.Project({ skipAddingFilesFromTsConfig: true });
66
+ const sourceFile = project.addSourceFileAtPath(filePath);
67
+ // Walk all function declarations
68
+ sourceFile.forEachDescendant((node, traversal) => {
69
+ if (!ts_morph_1.Node.isFunctionDeclaration(node) && !ts_morph_1.Node.isMethodDeclaration(node) && !ts_morph_1.Node.isArrowFunction(node)) {
70
+ // Also check function expressions and arrow functions in variable declarations
71
+ if (ts_morph_1.Node.isVariableDeclaration(node)) {
72
+ const init = node.getInitializer();
73
+ if (init && (ts_morph_1.Node.isArrowFunction(init) || ts_morph_1.Node.isFunctionExpression(init))) {
74
+ extractCallsFromScope(init, filePath, node.getName(), pairs);
75
+ }
76
+ }
77
+ return;
78
+ }
79
+ const fnName = ts_morph_1.Node.isVariableDeclaration(node)
80
+ ? (node.getName() || "<anonymous>")
81
+ : node.getName() || "<anonymous>";
82
+ extractCallsFromScope(node, filePath, fnName, pairs);
83
+ });
84
+ }
85
+ catch {
86
+ // Fall back to regex-based extraction for files ts-morph can't parse
87
+ }
88
+ return pairs;
89
+ }
90
+ function extractCallsFromScope(node, filePath, fnName, pairs) {
91
+ const calls = [];
92
+ node.forEachDescendant((descendant, traversal) => {
93
+ if (ts_morph_1.Node.isCallExpression(descendant)) {
94
+ const expr = descendant.getExpression();
95
+ let callName = "";
96
+ if (ts_morph_1.Node.isIdentifier(expr)) {
97
+ callName = expr.getText();
98
+ }
99
+ else if (ts_morph_1.Node.isPropertyAccessExpression(expr)) {
100
+ callName = expr.getName(); // obj.method() → method
101
+ }
102
+ if (callName && !isNoiseFunction(callName)) {
103
+ calls.push({ name: callName, line: descendant.getStartLineNumber() });
104
+ }
105
+ }
106
+ // Don't recurse into nested functions (their calls belong to that function's scope)
107
+ if (ts_morph_1.Node.isFunctionDeclaration(descendant) || ts_morph_1.Node.isMethodDeclaration(descendant) ||
108
+ ts_morph_1.Node.isArrowFunction(descendant) && descendant !== node) {
109
+ traversal.skip();
110
+ }
111
+ });
112
+ // Pair all calls within this function scope
113
+ for (let i = 0; i < calls.length - 1; i++) {
114
+ for (let j = i + 1; j < calls.length; j++) {
115
+ pairs.push({
116
+ from: calls[i].name,
117
+ to: calls[j].name,
118
+ file: filePath,
119
+ function: fnName,
120
+ line: calls[i].line,
121
+ });
122
+ }
123
+ }
124
+ }
125
+ // ═══════════════════════════════════════════════════════════════
126
+ // Improved C/C++ extraction with function boundary detection
127
+ // ═══════════════════════════════════════════════════════════════
128
+ function extractCCallPairs(code, filePath) {
129
+ const pairs = [];
130
+ const lines = code.split("\n");
131
+ // Simple function boundary detection: track brace depth at function level
132
+ let inFunction = false;
133
+ let currentFunction = "<global>";
134
+ let funcDepth = 0;
135
+ let funcCalls = [];
136
+ const callRegex = /\b([a-zA-Z_]\w*(?:\.[a-zA-Z_]\w*)?)\s*\(/g;
137
+ for (let li = 0; li < lines.length; li++) {
138
+ const line = lines[li];
139
+ // Detect function definition start (simplified: return type + name + ( + {)
140
+ const funcMatch = line.match(/^\s*(?:static\s+|inline\s+|void\s+|int\s+|char\s+|bool\s+|size_t\s+|FILE\*?\s*|DB\*?\s*)?(\w+)\s*\([^)]*\)\s*\{/);
141
+ if (funcMatch && funcDepth === 0) {
142
+ // Entering a new top-level function
143
+ if (funcCalls.length > 0) {
144
+ // Flush previous function's calls as pairs
145
+ flushFunctionPairs(funcCalls, currentFunction, filePath, pairs);
146
+ }
147
+ currentFunction = funcMatch[1];
148
+ funcCalls = [];
149
+ inFunction = true;
150
+ }
151
+ // Track brace depth
152
+ for (const ch of line) {
153
+ if (ch === "{")
154
+ funcDepth++;
155
+ if (ch === "}") {
156
+ funcDepth--;
157
+ if (funcDepth === 0 && inFunction) {
158
+ // Leaving a function
159
+ flushFunctionPairs(funcCalls, currentFunction, filePath, pairs);
160
+ currentFunction = "<global>";
161
+ funcCalls = [];
162
+ inFunction = false;
163
+ }
164
+ }
165
+ }
166
+ // Extract calls on this line
167
+ let match;
168
+ callRegex.lastIndex = 0;
169
+ while ((match = callRegex.exec(line)) !== null) {
170
+ const fnName = normalizeFn(match[1]);
171
+ if (fnName.length > 2 && !isNoiseFunction(fnName)) {
172
+ funcCalls.push({ name: fnName, line: li + 1 });
173
+ }
174
+ }
175
+ }
176
+ // Flush remaining
177
+ if (funcCalls.length > 0) {
178
+ flushFunctionPairs(funcCalls, currentFunction, filePath, pairs);
179
+ }
180
+ return pairs;
181
+ }
182
+ function flushFunctionPairs(calls, fnName, filePath, pairs) {
183
+ for (let i = 0; i < calls.length - 1; i++) {
184
+ for (let j = i + 1; j < calls.length; j++) {
185
+ pairs.push({
186
+ from: calls[i].name,
187
+ to: calls[j].name,
188
+ file: filePath,
189
+ function: fnName,
190
+ line: calls[i].line,
191
+ });
192
+ }
193
+ }
194
+ }
195
+ function normalizeFn(fn) {
196
+ const parts = fn.split(".");
197
+ return parts[parts.length - 1];
198
+ }
199
+ function isNoiseFunction(name) {
200
+ const noise = new Set([
201
+ "if", "for", "while", "switch", "return", "sizeof", "typeof",
202
+ "console", "log", "require", "import", "export", "print", "len",
203
+ "push", "pop", "map", "filter", "reduce", "forEach", "toString",
204
+ "valueOf", "assert", "expect", "test", "describe", "it",
205
+ "main", "printf", "sprintf", "fprintf", "write_config", "read_config",
206
+ "setup", "teardown", "init", "destroy", "cleanup",
207
+ "get", "set", "has", "is", "to", "from", "new",
208
+ ]);
209
+ return noise.has(name) || name.length <= 1 || /^[A-Z_]+$/.test(name);
210
+ }
211
+ /**
212
+ * Extract protocol rules with scope-aware pairing.
213
+ *
214
+ * Uses ts-morph AST for TS/JS files and function-boundary-aware
215
+ * regex for C/C++ files.
216
+ */
217
+ function extractProtocolV2(repoPath, protocolName, maxFiles = 200) {
218
+ const files = (0, repo_evaluator_1.scanRepository)(repoPath, maxFiles);
219
+ const allPairs = [];
220
+ for (const fp of files) {
221
+ try {
222
+ const ext = path.extname(fp);
223
+ if (ext === ".ts" || ext === ".js" || ext === ".mjs") {
224
+ allPairs.push(...extractTSCallPairs(fp));
225
+ }
226
+ else if ([".c", ".cpp", ".h", ".hpp", ".java", ".go", ".rs"].includes(ext)) {
227
+ const code = fs.readFileSync(fp, "utf-8");
228
+ allPairs.push(...extractCCallPairs(code, fp));
229
+ }
230
+ }
231
+ catch { /* skip unparseable files */ }
232
+ }
233
+ // Frequency analysis and rule inference
234
+ const rules = inferScopeRules(allPairs);
235
+ const states = new Set();
236
+ for (const [, rule] of rules) {
237
+ for (const s of rule.pre_states)
238
+ states.add(s);
239
+ for (const s of rule.post_states)
240
+ states.add(s);
241
+ if (rule.invalidate)
242
+ for (const s of rule.invalidate)
243
+ states.add(s);
244
+ }
245
+ // Quality assessment against ground truth
246
+ const defs = (0, protocol_coverage_1.loadDefaultProtocolDefinitions)();
247
+ const groundTruth = new Map();
248
+ for (const p of defs)
249
+ for (const [fn, rule] of p.rules)
250
+ groundTruth.set(fn, rule);
251
+ const extractedFns = new Set(rules.keys());
252
+ let matched = 0;
253
+ for (const fn of extractedFns) {
254
+ if (groundTruth.has(fn))
255
+ matched++;
256
+ }
257
+ const precision = extractedFns.size > 0 ? matched / extractedFns.size : 0;
258
+ const recall = groundTruth.size > 0 ? matched / groundTruth.size : 0;
259
+ const f1 = precision + recall > 0 ? 2 * precision * recall / (precision + recall) : 0;
260
+ let tier;
261
+ if (precision >= 0.70 && recall >= 0.50)
262
+ tier = "production";
263
+ else if (precision >= 0.50 && recall >= 0.30)
264
+ tier = "beta";
265
+ else
266
+ tier = "poc";
267
+ return {
268
+ protocol: protocolName || path.basename(repoPath),
269
+ rules,
270
+ states: [...states],
271
+ pairs: allPairs,
272
+ filesScanned: files.length,
273
+ quality: {
274
+ precision,
275
+ recall,
276
+ f1,
277
+ totalExtracted: extractedFns.size,
278
+ groundTruthMatch: matched,
279
+ groundTruthTotal: groundTruth.size,
280
+ tier,
281
+ },
282
+ };
283
+ }
284
+ // ═══════════════════════════════════════════════════════════════
285
+ // Scope-aware rule inference
286
+ // ═══════════════════════════════════════════════════════════════
287
+ const protocol_foundation_1 = require("./protocol-foundation");
288
+ function inferScopeRules(pairs, minFrequency = 2) {
289
+ const transitions = new Map();
290
+ const fnFreq = new Map();
291
+ for (const p of pairs) {
292
+ const key = `${p.from}→${p.to}`;
293
+ transitions.set(key, (transitions.get(key) || 0) + 1);
294
+ fnFreq.set(p.from, (fnFreq.get(p.from) || 0) + 1);
295
+ fnFreq.set(p.to, (fnFreq.get(p.to) || 0) + 1);
296
+ }
297
+ const fnStates = new Map();
298
+ const maxFreq = Math.max(1, ...[...transitions.values()]);
299
+ for (const [key, freq] of transitions) {
300
+ if (freq < minFrequency)
301
+ continue;
302
+ const [fnA, fnB] = key.split("→");
303
+ const stateName = (0, protocol_foundation_1.inferStateName)(fnA, "post");
304
+ const aStates = fnStates.get(fnA) || { produced: new Set(), required: new Set(), invalidated: new Set() };
305
+ aStates.produced.add(stateName);
306
+ fnStates.set(fnA, aStates);
307
+ const bStates = fnStates.get(fnB) || { produced: new Set(), required: new Set(), invalidated: new Set() };
308
+ bStates.required.add(stateName);
309
+ fnStates.set(fnB, bStates);
310
+ }
311
+ // Invalidation detection
312
+ const closers = new Set(["close", "disconnect", "logout", "free", "destroy", "release", "stop", "end", "finish"]);
313
+ const openers = new Set(["open", "connect", "login", "create", "alloc", "init", "start", "begin"]);
314
+ for (const [key] of transitions) {
315
+ const [fnA, fnB] = key.split("→");
316
+ const aStates = fnStates.get(fnA);
317
+ const bStates = fnStates.get(fnB);
318
+ if (!aStates || !bStates)
319
+ continue;
320
+ const isCloser = [...closers].some(kw => fnB.includes(kw));
321
+ const isOpener = [...openers].some(kw => fnA.includes(kw));
322
+ if (isCloser && isOpener) {
323
+ for (const s of aStates.produced)
324
+ bStates.invalidated.add(s);
325
+ }
326
+ }
327
+ const rules = new Map();
328
+ for (const [fn, states] of fnStates) {
329
+ rules.set(fn, {
330
+ pre_states: [...states.required],
331
+ post_states: [...states.produced],
332
+ invalidate: states.invalidated.size > 0 ? [...states.invalidated] : undefined,
333
+ });
334
+ }
335
+ return rules;
336
+ }
337
+ // ═══════════════════════════════════════════════════════════════
338
+ // Quality Report
339
+ // ═══════════════════════════════════════════════════════════════
340
+ function printExtractionQuality(report) {
341
+ console.log("\n╔════════════════════════════════════════════════════╗");
342
+ console.log("║ P6.0v2 Protocol Extraction Quality Report ║");
343
+ console.log("╚════════════════════════════════════════════════════╝\n");
344
+ console.log("Repository Prec Recall F1 Pairs Files Tier");
345
+ console.log("──────────────────────────────────────────────────────────────");
346
+ for (const r of report) {
347
+ const p = (r.quality.precision * 100).toFixed(0).padStart(4);
348
+ const rc = (r.quality.recall * 100).toFixed(0).padStart(4);
349
+ const f = (r.quality.f1 * 100).toFixed(0).padStart(4);
350
+ const tier = r.quality.tier === "production" ? "🟢" : r.quality.tier === "beta" ? "🟡" : "🔴";
351
+ console.log(` ${r.name.padEnd(16)} ${p}% ${rc}% ${f}% ${String(r.pairs).padStart(5)} ${String(r.files).padStart(5)} ${tier} ${r.quality.tier}`);
352
+ }
353
+ console.log();
354
+ }
@@ -0,0 +1,140 @@
1
+ "use strict";
2
+ /**
3
+ * P6.0v2: AST-based Protocol Extractor Tests
4
+ */
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
18
+ }) : function(o, v) {
19
+ o["default"] = v;
20
+ });
21
+ var __importStar = (this && this.__importStar) || (function () {
22
+ var ownKeys = function(o) {
23
+ ownKeys = Object.getOwnPropertyNames || function (o) {
24
+ var ar = [];
25
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
26
+ return ar;
27
+ };
28
+ return ownKeys(o);
29
+ };
30
+ return function (mod) {
31
+ if (mod && mod.__esModule) return mod;
32
+ var result = {};
33
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
34
+ __setModuleDefault(result, mod);
35
+ return result;
36
+ };
37
+ })();
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ const vitest_1 = require("vitest");
40
+ const fs = __importStar(require("fs"));
41
+ const path = __importStar(require("path"));
42
+ const protocol_extractor_v2_1 = require("./protocol-extractor-v2");
43
+ const V2_DIR = path.resolve(__dirname, "..", "test-extractor-v2");
44
+ function createTestRepo() {
45
+ const srcDir = path.join(V2_DIR, "src");
46
+ fs.mkdirSync(srcDir, { recursive: true });
47
+ // TypeScript file using names that match ground truth (protocols.json)
48
+ fs.writeFileSync(path.join(srcDir, "file-service.ts"), `
49
+ export class FileService {
50
+ processFile(path: string): string {
51
+ open_file(path);
52
+ const data = read_file(path);
53
+ write_file(path, data);
54
+ close_file(path);
55
+ return data;
56
+ }
57
+ }
58
+ `);
59
+ // C file using names that match ground truth — multiple functions per pattern
60
+ fs.writeFileSync(path.join(srcDir, "db_handler.c"), `
61
+ void run_query(const char* host, const char* sql) {
62
+ connect_db(host);
63
+ query_db(sql);
64
+ disconnect_db();
65
+ }
66
+ void run_insert(const char* host, const char* data) {
67
+ connect_db(host);
68
+ query_db(data);
69
+ disconnect_db();
70
+ }
71
+ void verify_and_session(const char* user, const char* pass) {
72
+ verify_password(user, pass);
73
+ generate_jwt(user);
74
+ create_session();
75
+ }
76
+ void auth_and_logout(const char* user, const char* pass) {
77
+ verify_password(user, pass);
78
+ generate_jwt(user);
79
+ create_session();
80
+ logout();
81
+ }
82
+ `);
83
+ return V2_DIR;
84
+ }
85
+ (0, vitest_1.describe)("Protocol Extractor v2 (AST-based)", () => {
86
+ createTestRepo();
87
+ (0, vitest_1.it)("extracts scope-aware call pairs within function boundaries", () => {
88
+ const result = (0, protocol_extractor_v2_1.extractProtocolV2)(V2_DIR, "TestRepo", 20);
89
+ (0, vitest_1.expect)(result.pairs.length).toBeGreaterThan(0);
90
+ // Each pair should be within a single function scope
91
+ for (const p of result.pairs) {
92
+ (0, vitest_1.expect)(p.function).not.toBe("<global>");
93
+ }
94
+ });
95
+ (0, vitest_1.it)("infers protocol rules with improved precision", () => {
96
+ const result = (0, protocol_extractor_v2_1.extractProtocolV2)(V2_DIR, "TestRepo", 20);
97
+ (0, vitest_1.expect)(result.rules.size).toBeGreaterThan(0);
98
+ // Should find file operations
99
+ const fns = [...result.rules.keys()];
100
+ (0, vitest_1.expect)(fns.some(f => f.includes("openFile") || f.includes("open"))).toBe(true);
101
+ (0, vitest_1.expect)(fns.some(f => f.includes("closeFile") || f.includes("close"))).toBe(true);
102
+ // Quality should be better than v1 (33%/12%)
103
+ console.log(`Precision: ${(result.quality.precision * 100).toFixed(0)}%, Recall: ${(result.quality.recall * 100).toFixed(0)}%, F1: ${(result.quality.f1 * 100).toFixed(0)}%`);
104
+ });
105
+ (0, vitest_1.it)("filters noise functions within function scopes", () => {
106
+ const noisyCode = path.join(V2_DIR, "noisy.ts");
107
+ fs.writeFileSync(noisyCode, `
108
+ function doWork() {
109
+ open_file("test");
110
+ console.log("opened");
111
+ assert(fileExists);
112
+ read_file(fd);
113
+ console.log("read done");
114
+ close_file(fd);
115
+ }
116
+ `);
117
+ const result = (0, protocol_extractor_v2_1.extractProtocolV2)(V2_DIR, "NoisyRepo", 20);
118
+ const fns = [...result.rules.keys()];
119
+ // Noise functions should not appear in extracted rules
120
+ (0, vitest_1.expect)(fns.includes("console")).toBe(false);
121
+ (0, vitest_1.expect)(fns.includes("assert")).toBe(false);
122
+ });
123
+ (0, vitest_1.it)("produces quality tier classification", () => {
124
+ const result = (0, protocol_extractor_v2_1.extractProtocolV2)(V2_DIR, "TestRepo", 20);
125
+ (0, vitest_1.expect)(result.quality.tier).toBeDefined();
126
+ (0, vitest_1.expect)(["production", "beta", "poc"]).toContain(result.quality.tier);
127
+ (0, protocol_extractor_v2_1.printExtractionQuality)([{
128
+ name: result.protocol,
129
+ quality: result.quality,
130
+ pairs: result.pairs.length,
131
+ files: result.filesScanned,
132
+ }]);
133
+ });
134
+ (0, vitest_1.it)("handles empty/missing directories gracefully", () => {
135
+ const result = (0, protocol_extractor_v2_1.extractProtocolV2)("/nonexistent/path/v2test", "EmptyRepo", 10);
136
+ (0, vitest_1.expect)(result.filesScanned).toBe(0);
137
+ (0, vitest_1.expect)(result.pairs.length).toBe(0);
138
+ (0, vitest_1.expect)(result.rules.size).toBe(0);
139
+ });
140
+ });