progmune-runtime 2.1.5 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (356) hide show
  1. package/README.md +108 -468
  2. package/dist/ablation-study.js +144 -0
  3. package/dist/ablation-study.test.js +18 -0
  4. package/dist/action-runtime.js +3 -1
  5. package/dist/active-learning.js +211 -0
  6. package/dist/analytics.js +139 -0
  7. package/dist/asset-factory.js +309 -0
  8. package/dist/asset-growth.js +244 -0
  9. package/dist/asset-promotion.js +382 -0
  10. package/dist/asset-quality.js +550 -0
  11. package/dist/audit/business-translator.js +285 -0
  12. package/dist/audit/cli.js +66 -0
  13. package/dist/audit/formatters/html.js +379 -0
  14. package/dist/audit/formatters/json.js +11 -0
  15. package/dist/audit/formatters/markdown.js +192 -0
  16. package/dist/audit/formatters/terminal.js +189 -0
  17. package/dist/audit/index.js +25 -0
  18. package/dist/audit/report-builder.js +318 -0
  19. package/dist/audit/types.js +8 -0
  20. package/dist/audit.js +3 -3
  21. package/dist/auto-benchmark-generator.js +137 -0
  22. package/dist/auto-benchmark-generator.test.js +45 -0
  23. package/dist/auto-protocol-synthesizer.js +362 -0
  24. package/dist/auto-protocol-synthesizer.test.js +82 -0
  25. package/dist/autonomous-patch.js +175 -0
  26. package/dist/autonomous-patch.test.js +128 -0
  27. package/dist/badge/badge-server.js +98 -0
  28. package/dist/behavior-miner.js +442 -0
  29. package/dist/belief-layer.js +475 -0
  30. package/dist/benchmark-count.js +5 -0
  31. package/dist/benchmark-generator.js +211 -0
  32. package/dist/benchmark-harness.js +201 -0
  33. package/dist/benchmark-pass-rate.js +7 -0
  34. package/dist/benchmark-report.js +8 -3
  35. package/dist/benchmark-save.js +14 -1
  36. package/dist/bootstrap-validation.js +197 -0
  37. package/dist/bootstrap-validation.test.js +51 -0
  38. package/dist/branch-ledger.js +1 -1
  39. package/dist/capability-gap.js +130 -0
  40. package/dist/certify-html.js +351 -0
  41. package/dist/certify.js +326 -0
  42. package/dist/check.js +4 -4
  43. package/dist/compliance-miner.js +447 -0
  44. package/dist/continuous-benchmark.js +194 -0
  45. package/dist/continuous-benchmark.test.js +116 -0
  46. package/dist/corpus-stats.js +173 -0
  47. package/dist/counterfactual-engine.js +288 -0
  48. package/dist/coverage-dashboard.js +109 -0
  49. package/dist/coverage-system.test.js +205 -0
  50. package/dist/cross-repo-precision.js +352 -0
  51. package/dist/cve-benchmark.js +180 -0
  52. package/dist/cve-benchmark.test.js +28 -0
  53. package/dist/cve-collector.js +73 -0
  54. package/dist/data-quality.js +141 -0
  55. package/dist/decision-engine.js +388 -0
  56. package/dist/derive-metadata.js +250 -0
  57. package/dist/difficulty-active.test.js +198 -0
  58. package/dist/difficulty-map.js +244 -0
  59. package/dist/discovery-analytics.js +125 -0
  60. package/dist/discovery-model.js +149 -0
  61. package/dist/discovery-optimize.test.js +199 -0
  62. package/dist/discovery-trace.js +276 -0
  63. package/dist/discovery-trace.test.js +97 -0
  64. package/dist/emitter.js +83 -1
  65. package/dist/enterprise-dashboard.js +405 -0
  66. package/dist/eval-hardening.js +297 -0
  67. package/dist/eval-hardening.test.js +85 -0
  68. package/dist/evaluation-campaign.js +359 -0
  69. package/dist/evaluation-campaign.test.js +181 -0
  70. package/dist/evidence-growth.js +143 -0
  71. package/dist/evidence-repository.js +209 -0
  72. package/dist/evidence-system.js +441 -0
  73. package/dist/execute.js +15 -7
  74. package/dist/experimental/software-physics.js +291 -0
  75. package/dist/experimental/state-inference.js +516 -0
  76. package/dist/experimental/unsupervised-physics.js +230 -0
  77. package/dist/extract-ir-python.js +54 -7
  78. package/dist/extract-ir.js +376 -12
  79. package/dist/failure-collector.js +2 -2
  80. package/dist/failure-corpus.js +322 -9
  81. package/dist/feedback.js +16 -5
  82. package/dist/feedback.test.js +49 -0
  83. package/dist/file-lock.js +1 -1
  84. package/dist/flywheel-batch.js +292 -0
  85. package/dist/frameworks/express-cli.js +237 -0
  86. package/dist/frameworks/express-detector.js +445 -0
  87. package/dist/frameworks/express-detector.test.js +206 -0
  88. package/dist/frameworks/index.js +30 -0
  89. package/dist/frameworks/nestjs-detector.js +302 -0
  90. package/dist/frameworks/trpc-detector.js +161 -0
  91. package/dist/frameworks/version-awareness.js +179 -0
  92. package/dist/function-synonyms.js +164 -0
  93. package/dist/function-synonyms.test.js +68 -0
  94. package/dist/generalization.test.js +352 -0
  95. package/dist/goal-annotator.js +113 -0
  96. package/dist/goal-planner.js +563 -0
  97. package/dist/gold-cve.js +164 -0
  98. package/dist/gold-cve.test.js +104 -0
  99. package/dist/gold-quality.js +206 -0
  100. package/dist/gold-tiers.js +241 -0
  101. package/dist/governance-dashboard.js +327 -0
  102. package/dist/graph-viz.js +240 -0
  103. package/dist/guided-frontier.js +195 -0
  104. package/dist/hierarchical-planner.js +148 -0
  105. package/dist/identifier-parser.js +260 -0
  106. package/dist/immune-metrics.js +93 -0
  107. package/dist/immune-receiver.js +158 -0
  108. package/dist/immune-reporter.js +1 -1
  109. package/dist/improvement-orchestrator.js +206 -0
  110. package/dist/inject-p0-vocabulary.js +300 -0
  111. package/dist/intent-parser.js +218 -0
  112. package/dist/invariant-algebra.js +476 -0
  113. package/dist/invariant-calculus.js +533 -0
  114. package/dist/ir-utils.js +70 -0
  115. package/dist/ir-utils.test.js +50 -0
  116. package/dist/knowledge-api.js +312 -0
  117. package/dist/knowledge-evolution.js +452 -0
  118. package/dist/knowledge-explorer.js +506 -0
  119. package/dist/knowledge-flywheel.js +274 -0
  120. package/dist/knowledge-governance.js +338 -0
  121. package/dist/knowledge-governance.test.js +150 -0
  122. package/dist/knowledge-graph.js +181 -0
  123. package/dist/knowledge-guided-synth.js +246 -0
  124. package/dist/knowledge-loop.test.js +77 -0
  125. package/dist/knowledge-object.js +316 -0
  126. package/dist/knowledge-package.js +98 -0
  127. package/dist/kpi-dashboard.js +561 -0
  128. package/dist/l3-cross-function.js +280 -0
  129. package/dist/learning-ranker.js +148 -0
  130. package/dist/learning-ranker.test.js +291 -0
  131. package/dist/ledger/accountability.js +322 -0
  132. package/dist/ledger/chain-builder.js +185 -0
  133. package/dist/ledger/cli.js +222 -0
  134. package/dist/ledger/index.js +13 -0
  135. package/dist/ledger/signatures.js +193 -0
  136. package/dist/ledger/types.js +9 -0
  137. package/dist/llm.js +74 -3
  138. package/dist/load-benchmarks.js +8 -3
  139. package/dist/logger.js +66 -0
  140. package/dist/logger.test.js +37 -0
  141. package/dist/logistic-reward.js +339 -0
  142. package/dist/logistic-reward.test.js +180 -0
  143. package/dist/macro-graph.js +193 -0
  144. package/dist/macro-repair.js +183 -0
  145. package/dist/mcp-server.mjs +1202 -483
  146. package/dist/memory-layer.js +42 -5
  147. package/dist/multi-repo-precision.js +422 -0
  148. package/dist/name-free-protocol.js +425 -0
  149. package/dist/name-free-protocol.test.js +170 -0
  150. package/dist/name-scrambling.js +138 -0
  151. package/dist/name-scrambling.test.js +16 -0
  152. package/dist/p3-observability.test.js +281 -0
  153. package/dist/p5-orchestrator.test.js +225 -0
  154. package/dist/pairwise-preference.js +294 -0
  155. package/dist/pairwise-preference.test.js +140 -0
  156. package/dist/planner-constraints.js +104 -0
  157. package/dist/planner-prompts.js +155 -0
  158. package/dist/planner-telemetry.js +415 -0
  159. package/dist/planner-trace.js +214 -0
  160. package/dist/planner.js +162 -167
  161. package/dist/plsb/artifact.js +116 -0
  162. package/dist/plsb/cli.js +71 -0
  163. package/dist/plsb/index.js +19 -0
  164. package/dist/plsb/leaderboard.js +249 -0
  165. package/dist/plsb/report-md.js +156 -0
  166. package/dist/plsb/schema.js +179 -0
  167. package/dist/plsb-benchmark.js +284 -0
  168. package/dist/plsb-benchmark.test.js +119 -0
  169. package/dist/policy/cli.js +134 -0
  170. package/dist/policy/engine.js +333 -0
  171. package/dist/policy/index.js +12 -0
  172. package/dist/policy/types.js +59 -0
  173. package/dist/policy-miner.js +505 -0
  174. package/dist/precision-analyze.js +229 -0
  175. package/dist/precision-benchmark.js +147 -0
  176. package/dist/precision-label-c.js +134 -0
  177. package/dist/precision-label.js +193 -0
  178. package/dist/precision-report-c.js +149 -0
  179. package/dist/precision-report.js +246 -0
  180. package/dist/progmune-status.js +108 -0
  181. package/dist/proof-engine.js +479 -0
  182. package/dist/proof-provenance.js +315 -0
  183. package/dist/protocol-coverage.js +294 -0
  184. package/dist/protocol-detector.js +1189 -0
  185. package/dist/protocol-embedding-expanded.js +297 -0
  186. package/dist/protocol-embedding-expanded.test.js +97 -0
  187. package/dist/protocol-embedding.js +195 -0
  188. package/dist/protocol-embedding.test.js +82 -0
  189. package/dist/protocol-extractor-v2.js +354 -0
  190. package/dist/protocol-extractor-v2.test.js +140 -0
  191. package/dist/protocol-extractor.js +310 -0
  192. package/dist/protocol-extractor.test.js +113 -0
  193. package/dist/protocol-foundation.js +322 -0
  194. package/dist/protocol-foundation.test.js +163 -0
  195. package/dist/protocol-frontier.js +243 -0
  196. package/dist/protocol-frontier.test.js +92 -0
  197. package/dist/protocol-gap-analyzer.js +228 -0
  198. package/dist/protocol-gap-analyzer.test.js +49 -0
  199. package/dist/protocol-invariants.js +276 -0
  200. package/dist/protocol-invariants.test.js +111 -0
  201. package/dist/protocol-knowledge.js +464 -0
  202. package/dist/protocol-miner.js +343 -0
  203. package/dist/protocol-mining.js +207 -0
  204. package/dist/protocol-mining.test.js +37 -0
  205. package/dist/protocol-registry.js +1 -1
  206. package/dist/protocol-security-benchmark.js +222 -0
  207. package/dist/protocol-vulnerability.js +257 -0
  208. package/dist/protocol-vulnerability.test.js +60 -0
  209. package/dist/python-benchmark.js +120 -0
  210. package/dist/python-emitter.js +163 -45
  211. package/dist/python-protocol-extractor.js +187 -0
  212. package/dist/python-protocol-extractor.test.js +116 -0
  213. package/dist/realworld-benchmark.js +646 -0
  214. package/dist/realworld-benchmark.test.js +36 -0
  215. package/dist/repair-arch.test.js +411 -0
  216. package/dist/repair-evolution.test.js +454 -0
  217. package/dist/repair-executor.js +719 -0
  218. package/dist/repair-proposal.js +4 -4
  219. package/dist/repair-ranker.js +141 -0
  220. package/dist/repair-strategies.js +419 -0
  221. package/dist/repair-taxonomy.js +234 -0
  222. package/dist/repair-types.js +12 -0
  223. package/dist/repo-evaluator.js +250 -0
  224. package/dist/repo-evaluator.test.js +128 -0
  225. package/dist/resource-abstraction.js +242 -0
  226. package/dist/resource-detector.js +211 -0
  227. package/dist/result.test.js +43 -0
  228. package/dist/reward-system.js +411 -0
  229. package/dist/reward-system.test.js +175 -0
  230. package/dist/risk-model.js +215 -0
  231. package/dist/rule-miner.js +234 -7
  232. package/dist/rule-specificity.js +254 -0
  233. package/dist/runtime-types.js +27 -0
  234. package/dist/scaffold.js +208 -0
  235. package/dist/scale-collector.test.js +101 -0
  236. package/dist/scale-trajectory-collector.js +128 -0
  237. package/dist/sdk.js +250 -0
  238. package/dist/search-planner.js +4 -41
  239. package/dist/semantic-snapshot.js +1 -1
  240. package/dist/semantic-topology.js +121 -0
  241. package/dist/semantic-trace.js +310 -317
  242. package/dist/sequence-extractor.js +343 -0
  243. package/dist/skill-library.js +245 -0
  244. package/dist/skill-planner.test.js +189 -0
  245. package/dist/software-physics.js +291 -0
  246. package/dist/software-physics.test.js +81 -0
  247. package/dist/ssg-precision.js +478 -0
  248. package/dist/ssg-validator.js +71 -21
  249. package/dist/state-inference-doubleblind.test.js +160 -0
  250. package/dist/state-inference.js +516 -0
  251. package/dist/state-inference.test.js +115 -0
  252. package/dist/state-machine-fingerprint.js +345 -0
  253. package/dist/state-machine-fingerprint.test.js +120 -0
  254. package/dist/state-miner.js +386 -0
  255. package/dist/state-name-inference.js +213 -0
  256. package/dist/state-name-inference.test.js +69 -0
  257. package/dist/strategy-planner.js +326 -59
  258. package/dist/strategy-planner.test.js +135 -0
  259. package/dist/telemetry-analytics.test.js +402 -0
  260. package/dist/terminal-format.js +68 -0
  261. package/dist/terminal-format.test.js +83 -0
  262. package/dist/topology-factory.js +196 -0
  263. package/dist/topology-representation.js +242 -0
  264. package/dist/topology-representation.test.js +27 -0
  265. package/dist/trajectory-augmentation.js +254 -0
  266. package/dist/trajectory-augmentation.test.js +63 -0
  267. package/dist/trajectory-corpus.js +440 -0
  268. package/dist/trajectory-corpus.test.js +32 -0
  269. package/dist/trajectory-feedback.test.js +116 -0
  270. package/dist/transition-synthesizer.js +286 -0
  271. package/dist/transition-synthesizer.test.js +123 -0
  272. package/dist/trust/api-semantic-mapper.js +809 -0
  273. package/dist/trust/call-graph-propagator.js +225 -0
  274. package/dist/trust/cli.js +122 -0
  275. package/dist/trust/compliance-scorer.js +283 -0
  276. package/dist/trust/confidence-calculator.js +261 -0
  277. package/dist/trust/engine.js +1145 -0
  278. package/dist/trust/explainability.js +85 -0
  279. package/dist/trust/formatters/ci.js +42 -0
  280. package/dist/trust/formatters/json.js +11 -0
  281. package/dist/trust/formatters/terminal.js +152 -0
  282. package/dist/trust/index.js +39 -0
  283. package/dist/trust/phase1-verify.js +171 -0
  284. package/dist/trust/protocol-domain-validator.js +697 -0
  285. package/dist/trust/score-calculator.js +282 -0
  286. package/dist/trust/ssg-bridge.js +641 -0
  287. package/dist/trust/ssg-bridge.test.js +269 -0
  288. package/dist/trust/types.js +67 -0
  289. package/dist/trust/violation-trace.js +335 -0
  290. package/dist/trust-api.js +179 -0
  291. package/dist/trust-calibration.js +279 -0
  292. package/dist/unknown-protocol-discovery.js +339 -0
  293. package/dist/unknown-protocol-discovery.test.js +102 -0
  294. package/dist/unsupervised-physics.js +230 -0
  295. package/dist/unsupervised-physics.test.js +95 -0
  296. package/dist/utils.test.js +37 -0
  297. package/dist/validator.js +187 -10
  298. package/dist/verification-intelligence.js +475 -0
  299. package/dist/verify-api.js +432 -0
  300. package/dist/vi-impact-report.js +293 -0
  301. package/dist/wl-fingerprint.js +162 -0
  302. package/dist/wl-fingerprint.test.js +130 -0
  303. package/dist/zeroshot-strategy.js +139 -0
  304. package/docs/Progmune_/346/212/225/350/265/204/344/272/272/347/231/275/347/232/256/344/271/246_v2.0.html +576 -0
  305. package/docs/Progmune_/351/241/271/347/233/256/345/205/250/350/247/243.html +710 -0
  306. package/package.json +74 -7
  307. package/protocols.json +1956 -50
  308. package/.dockerignore +0 -14
  309. package/.mcp.json +0 -11
  310. package/.progmune_allowlist +0 -50
  311. package/.test_report/test_report.md +0 -87
  312. package/Dockerfile +0 -9
  313. package/FAQ.md +0 -167
  314. package/WHITEPAPER.md +0 -540
  315. package/demo-project/auth.ts +0 -55
  316. package/demo-project/tsconfig.json +0 -8
  317. package/dist/acl-breakdown.js +0 -13
  318. package/dist/all-sessions.js +0 -11
  319. package/dist/antibody-stats.js +0 -11
  320. package/dist/branch-tree-count.js +0 -14
  321. package/dist/common-fixpath.js +0 -12
  322. package/dist/constraint-types.js +0 -12
  323. package/dist/exec-metrics.js +0 -11
  324. package/dist/failure-report.js +0 -11
  325. package/dist/fast-path-hits.js +0 -13
  326. package/dist/fingerprint-list.js +0 -15
  327. package/dist/gen-history-log.js +0 -13
  328. package/dist/heatmap-data.js +0 -11
  329. package/dist/recent-session.js +0 -12
  330. package/dist/svl-distribution.js +0 -11
  331. package/dist/terminal-status.js +0 -11
  332. package/dist/token-savings.js +0 -11
  333. package/dist/total-repairs.js +0 -12
  334. package/dist/unresolved-count.js +0 -12
  335. package/dist/valid-fingerprints.js +0 -13
  336. package/dist/verify-ledgers.js +0 -11
  337. package/docs/whitepaper-style.css +0 -77
  338. package/docs/whitepaper-v2.1.md +0 -609
  339. package/docs/whitepaper-v2.2.md +0 -1064
  340. package/docs/whitepaper-v2.2.pdf +0 -0
  341. package/fly.toml +0 -31
  342. package/public/dashboard.html +0 -119
  343. package/server/hub.js +0 -116
  344. package/test/replay-golden/sess_1780063202050_mgeld.json +0 -9
  345. package/test/replay-golden/sess_1780064032560_gocld.json +0 -354
  346. package/test/replay-golden/sess_1780064413331_s2709.json +0 -606
  347. package/test/replay-golden/sess_1780064792710_y3avo.json +0 -614
  348. package/test/replay-golden.ts +0 -84
  349. package/test_benchmark.js +0 -165
  350. package/test_comprehensive.mjs +0 -638
  351. package/test_concurrency.js +0 -129
  352. package/test_ir_robustness.js +0 -85
  353. package/test_semantic_contracts.js +0 -269
  354. package/test_ssg_stress.js +0 -156
  355. package/test_svl3.js +0 -58
  356. package/tsconfig.json +0 -17
@@ -0,0 +1,339 @@
1
+ "use strict";
2
+ /**
3
+ * P8.2: Unknown Protocol Discovery — Zero-Shot Transfer
4
+ *
5
+ * The decisive test for protocol structure learning:
6
+ * 1. Train on known repos (Redis, SQLite)
7
+ * 2. Discover protocols in an UNSEEN repo (PostgreSQL)
8
+ * 3. Repair defects using ONLY discovered knowledge
9
+ *
10
+ * Success = the system can understand code it has NEVER seen before.
11
+ * This is the bridge from "protocol library" to "software world model."
12
+ *
13
+ * Pipeline:
14
+ * Known repos → state machine fingerprints → fingerprint library
15
+ * Unknown repo → extract sequences → cluster → synthesize → state machine
16
+ * Match unknown state machines against known library → transfer or infer
17
+ *
18
+ * North star metric: zero-shot repair success rate on unseen repos.
19
+ */
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.buildKnownFingerprintLibrary = buildKnownFingerprintLibrary;
22
+ exports.extractUnknownRepoSequences = extractUnknownRepoSequences;
23
+ exports.discoverProtocolsFromSequences = discoverProtocolsFromSequences;
24
+ exports.evaluateZeroShotRepair = evaluateZeroShotRepair;
25
+ exports.runZeroShotDiscovery = runZeroShotDiscovery;
26
+ exports.printZeroShotResult = printZeroShotResult;
27
+ const state_machine_fingerprint_1 = require("./state-machine-fingerprint");
28
+ const unsupervised_physics_1 = require("./experimental/unsupervised-physics");
29
+ const auto_protocol_synthesizer_1 = require("./auto-protocol-synthesizer");
30
+ const protocol_frontier_1 = require("./protocol-frontier");
31
+ const protocol_coverage_1 = require("./protocol-coverage");
32
+ // ═══════════════════════════════════════════════════════════════
33
+ // Step 1: Build known fingerprint library
34
+ // ═══════════════════════════════════════════════════════════════
35
+ /**
36
+ * Build a fingerprint library from known protocol groups.
37
+ * Each entry maps a protocol name to its state machine fingerprint.
38
+ */
39
+ function buildKnownFingerprintLibrary() {
40
+ const defs = (0, protocol_coverage_1.loadDefaultProtocolDefinitions)();
41
+ const library = new Map();
42
+ for (const p of defs) {
43
+ if (p.rules.size === 0)
44
+ continue;
45
+ library.set(p.name, (0, state_machine_fingerprint_1.extractStateMachine)(p.rules));
46
+ }
47
+ return library;
48
+ }
49
+ // ═══════════════════════════════════════════════════════════════
50
+ // Step 2: Extract call sequences from an unknown repo
51
+ // ═══════════════════════════════════════════════════════════════
52
+ /**
53
+ * Extract raw call sequences from a repo by name.
54
+ * Uses CROSS_REPO_SEQUENCES as the data source.
55
+ */
56
+ function extractUnknownRepoSequences(repoName) {
57
+ return unsupervised_physics_1.CROSS_REPO_SEQUENCES[repoName] || [];
58
+ }
59
+ // ═══════════════════════════════════════════════════════════════
60
+ // Step 3: Discover protocols from raw sequences
61
+ // ═══════════════════════════════════════════════════════════════
62
+ /**
63
+ * Discover protocols from raw call sequences using P8.1 state machine fingerprints.
64
+ *
65
+ * Algorithm:
66
+ * 1. Synthesize protocol rules from sequences via auto-protocol-synthesizer
67
+ * 2. Build name-free state machine fingerprints from synthesized rules
68
+ * 3. Match against known fingerprint library
69
+ * 4. Return discovered protocols with transfer annotations
70
+ */
71
+ function discoverProtocolsFromSequences(sequences, repoName, knownLibrary) {
72
+ if (sequences.length === 0)
73
+ return [];
74
+ // 1. Synthesize protocol rules from sequences (P6.4)
75
+ const synthesized = (0, auto_protocol_synthesizer_1.synthesizeProtocols)(sequences);
76
+ if (synthesized.length === 0) {
77
+ // Fallback: create a simple linear chain synthesization
78
+ return [buildFallbackProtocol(sequences, repoName, knownLibrary)];
79
+ }
80
+ const discovered = [];
81
+ for (const synth of synthesized) {
82
+ // 2. Convert synthesized rules to StateAnnotation map for fingerprint extraction
83
+ const ruleMap = new Map();
84
+ for (const r of synth.rules) {
85
+ ruleMap.set(r.function, {
86
+ pre_states: r.pre_states,
87
+ post_states: r.post_states,
88
+ invalidate: r.invalidate,
89
+ });
90
+ }
91
+ // 3. Extract name-free state machine fingerprint
92
+ const fingerprint = (0, state_machine_fingerprint_1.extractStateMachine)(ruleMap);
93
+ // 4. Match against known library
94
+ let closestKnown;
95
+ let matchConfidence = 0;
96
+ if (knownLibrary && knownLibrary.size > 0) {
97
+ for (const [name, knownFp] of knownLibrary) {
98
+ const comp = (0, state_machine_fingerprint_1.compareStateMachines)(fingerprint, knownFp);
99
+ if (comp.similarity > matchConfidence) {
100
+ matchConfidence = comp.similarity;
101
+ closestKnown = name;
102
+ }
103
+ }
104
+ }
105
+ discovered.push({
106
+ name: `${repoName}_${synth.clusterId}`,
107
+ fingerprint,
108
+ rules: synth.rules,
109
+ prototype: synth.prototype,
110
+ closestKnown,
111
+ matchConfidence: Math.round(matchConfidence * 10000) / 10000,
112
+ });
113
+ }
114
+ return discovered;
115
+ }
116
+ /** Fallback: build a simple protocol from sequences when synthesizer fails. */
117
+ function buildFallbackProtocol(sequences, repoName, knownLibrary) {
118
+ // Find the most common pattern: longest common subsequence
119
+ const prototype = sequences.reduce((a, b) => a.length >= b.length ? a : b, sequences[0] || []);
120
+ const rules = prototype.map((fn, i) => ({
121
+ function: fn,
122
+ pre_states: i === 0 ? [] : [`STATE_${i - 1}`],
123
+ post_states: i < prototype.length - 1 ? [`STATE_${i}`] : [],
124
+ invalidate: i === prototype.length - 1 ? [`STATE_${i - 1}`] : undefined,
125
+ }));
126
+ const ruleMap = new Map();
127
+ for (const r of rules) {
128
+ ruleMap.set(r.function, {
129
+ pre_states: r.pre_states,
130
+ post_states: r.post_states,
131
+ invalidate: r.invalidate,
132
+ });
133
+ }
134
+ const fingerprint = (0, state_machine_fingerprint_1.extractStateMachine)(ruleMap);
135
+ let closestKnown;
136
+ let matchConfidence = 0;
137
+ if (knownLibrary) {
138
+ for (const [name, knownFp] of knownLibrary) {
139
+ const comp = (0, state_machine_fingerprint_1.compareStateMachines)(fingerprint, knownFp);
140
+ if (comp.similarity > matchConfidence) {
141
+ matchConfidence = comp.similarity;
142
+ closestKnown = name;
143
+ }
144
+ }
145
+ }
146
+ return {
147
+ name: `${repoName}_fallback`,
148
+ fingerprint,
149
+ rules,
150
+ prototype,
151
+ closestKnown,
152
+ matchConfidence: Math.round(matchConfidence * 10000) / 10000,
153
+ };
154
+ }
155
+ /**
156
+ * Attempt zero-shot repair using discovered protocol knowledge.
157
+ *
158
+ * For each defect case:
159
+ * 1. Build a state machine from the discovered protocol's rules
160
+ * 2. Use frontier exploration to find a path from the broken state to the expected completion
161
+ * 3. Check if any discovered fix path covers the missing steps
162
+ *
163
+ * @returns { success, total } counts for repair rate calculation
164
+ */
165
+ function evaluateZeroShotRepair(discovered, defectCases) {
166
+ let success = 0;
167
+ const details = [];
168
+ for (const defect of defectCases) {
169
+ let repaired = false;
170
+ for (const proto of discovered) {
171
+ // Build rule map from discovered protocol
172
+ const rules = new Map();
173
+ for (const r of proto.rules) {
174
+ rules.set(r.function, {
175
+ pre_states: r.pre_states,
176
+ post_states: r.post_states,
177
+ invalidate: r.invalidate,
178
+ });
179
+ }
180
+ if (rules.size === 0)
181
+ continue;
182
+ // Build reverse index: for each function in the discovered rules,
183
+ // find the closest matching function in the defect by edit distance.
184
+ // This bridges the name gap between original names and normalized names.
185
+ const ruleFns = [...rules.keys()];
186
+ const defectFns = new Set([...defect.broken, ...defect.expected]);
187
+ const nameMap = new Map(); // defect name → rule name
188
+ for (const dfn of defectFns) {
189
+ let bestFn = "";
190
+ let bestDist = Infinity;
191
+ const lower = dfn.toLowerCase();
192
+ for (const rfn of ruleFns) {
193
+ // Simple substring match first, then edit distance
194
+ if (lower.includes(rfn) || rfn.includes(lower)) {
195
+ bestFn = rfn;
196
+ break;
197
+ }
198
+ const dist = levenshtein(lower, rfn);
199
+ if (dist < bestDist) {
200
+ bestDist = dist;
201
+ bestFn = rfn;
202
+ }
203
+ }
204
+ if (bestFn)
205
+ nameMap.set(dfn, bestFn);
206
+ }
207
+ // Map broken sequence through the name map
208
+ const mappedBroken = defect.broken.map(fn => nameMap.get(fn) || fn);
209
+ const mappedExpected = defect.expected.map(fn => nameMap.get(fn) || fn);
210
+ // Simulate state machine with mapped sequence
211
+ // Initialize with namespace initial states (INIT is the universal default)
212
+ const currentStates = new Set(["INIT"]);
213
+ for (const fn of mappedBroken) {
214
+ const rule = rules.get(fn);
215
+ if (!rule)
216
+ continue;
217
+ if (!rule.pre_states.every(s => currentStates.has(s)) && rule.pre_states.length > 0)
218
+ continue;
219
+ if (rule.invalidate)
220
+ rule.invalidate.forEach(s => currentStates.delete(s));
221
+ for (const s of rule.post_states)
222
+ currentStates.add(s);
223
+ }
224
+ // Frontier exploration for completion paths
225
+ const paths = (0, protocol_frontier_1.exploreFrontier)(rules, [...currentStates], 20, 8);
226
+ // Check if any path + broken covers the expected (using mapped names)
227
+ for (const path of paths) {
228
+ const full = [...mappedBroken, ...path];
229
+ const allExpected = mappedExpected.every(fn => full.includes(fn));
230
+ if (allExpected && path.length > 0) {
231
+ repaired = true;
232
+ details.push(`${defect.description}: ✅ via ${proto.name} (${path.join(" → ")})`);
233
+ break;
234
+ }
235
+ }
236
+ if (repaired)
237
+ break;
238
+ }
239
+ if (!repaired) {
240
+ details.push(`${defect.description}: ❌`);
241
+ }
242
+ if (repaired)
243
+ success++;
244
+ }
245
+ return { success, total: defectCases.length, details };
246
+ }
247
+ /** Levenshtein edit distance between two strings. */
248
+ function levenshtein(a, b) {
249
+ const m = a.length, n = b.length;
250
+ const dp = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
251
+ for (let i = 0; i <= m; i++)
252
+ dp[i][0] = i;
253
+ for (let j = 0; j <= n; j++)
254
+ dp[0][j] = j;
255
+ for (let i = 1; i <= m; i++) {
256
+ for (let j = 1; j <= n; j++) {
257
+ dp[i][j] = a[i - 1] === b[j - 1] ? dp[i - 1][j - 1] : 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);
258
+ }
259
+ }
260
+ return dp[m][n];
261
+ }
262
+ // ═══════════════════════════════════════════════════════════════
263
+ // Full Pipeline
264
+ // ═══════════════════════════════════════════════════════════════
265
+ /**
266
+ * Run the full zero-shot discovery pipeline:
267
+ * 1. Build known library from TRAIN repos
268
+ * 2. Discover protocols in TEST repo
269
+ * 3. Evaluate zero-shot repair
270
+ *
271
+ * @param trainRepos Repos used to build the known fingerprint library
272
+ * @param testRepo Unseen repo for zero-shot discovery
273
+ * @param defectCases Defect cases to test repair on
274
+ */
275
+ function runZeroShotDiscovery(trainRepos, testRepo, defectCases) {
276
+ // 1. Build known fingerprint library from train repos
277
+ const knownLibrary = new Map();
278
+ for (const repo of trainRepos) {
279
+ const seqs = extractUnknownRepoSequences(repo);
280
+ if (seqs.length === 0)
281
+ continue;
282
+ // Discover protocols in training repos
283
+ const trainDiscovered = discoverProtocolsFromSequences(seqs, repo, undefined);
284
+ for (const proto of trainDiscovered) {
285
+ knownLibrary.set(proto.name, proto.fingerprint);
286
+ }
287
+ }
288
+ // Add hand-written protocol fingerprints to the library
289
+ const handWritten = buildKnownFingerprintLibrary();
290
+ for (const [name, fp] of handWritten) {
291
+ knownLibrary.set(name, fp);
292
+ }
293
+ // 2. Discover protocols in test repo (zero-shot)
294
+ const testSeqs = extractUnknownRepoSequences(testRepo);
295
+ const discovered = discoverProtocolsFromSequences(testSeqs, testRepo, knownLibrary);
296
+ // 3. Evaluate zero-shot repair
297
+ const repairResult = evaluateZeroShotRepair(discovered, defectCases);
298
+ return {
299
+ discoveredCount: discovered.length,
300
+ discovered,
301
+ repairSuccess: repairResult.success,
302
+ repairTotal: repairResult.total,
303
+ repairRate: repairResult.total > 0 ? repairResult.success / repairResult.total : 0,
304
+ };
305
+ }
306
+ // ═══════════════════════════════════════════════════════════════
307
+ // Reporting
308
+ // ═══════════════════════════════════════════════════════════════
309
+ function printZeroShotResult(result) {
310
+ console.log("\n╔════════════════════════════════════════════════════╗");
311
+ console.log("║ P8.2 Unknown Protocol Discovery — Zero-Shot ║");
312
+ console.log("╚════════════════════════════════════════════════════╝\n");
313
+ console.log(` Discovered: ${result.discoveredCount} protocol(s)`);
314
+ for (const proto of result.discovered) {
315
+ console.log(`\n ── ${proto.name} ──`);
316
+ console.log(` Prototype: ${proto.prototype.join(" → ")}`);
317
+ console.log(` States: ${proto.fingerprint.stateCount}`);
318
+ console.log(` Transitions: ${proto.fingerprint.transitions.length}`);
319
+ console.log(` Entry points: ${proto.fingerprint.entryStates.length}`);
320
+ console.log(` Exit points: ${proto.fingerprint.exitStates.length}`);
321
+ console.log(` Branch states: ${proto.fingerprint.branchStates.length}`);
322
+ console.log(` DAG: ${proto.fingerprint.isDAG}`);
323
+ if (proto.closestKnown) {
324
+ console.log(` Closest known: ${proto.closestKnown} (${(proto.matchConfidence * 100).toFixed(0)}%)`);
325
+ }
326
+ else {
327
+ console.log(` Closest known: none (novel protocol)`);
328
+ }
329
+ }
330
+ console.log(`\n ── Zero-Shot Repair ──`);
331
+ console.log(` Success: ${result.repairSuccess}/${result.repairTotal}`);
332
+ console.log(` Rate: ${(result.repairRate * 100).toFixed(0)}%`);
333
+ const verdict = result.repairRate > 0.5
334
+ ? "✅ ZERO-SHOT TRANSFER ACHIEVED"
335
+ : result.repairRate > 0
336
+ ? "⚠️ PARTIAL — structure signal present but repair gap remains"
337
+ : "❌ No transfer — protocol structure not yet generalizing";
338
+ console.log(` Verdict: ${verdict}\n`);
339
+ }
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * P8.2: Unknown Protocol Discovery Tests
5
+ *
6
+ * Zero-shot transfer: train on Redis+SQLite, test on PostgreSQL.
7
+ * The system must discover protocol structure in an UNSEEN repo
8
+ * and repair defects using only discovered knowledge.
9
+ */
10
+ const vitest_1 = require("vitest");
11
+ const unknown_protocol_discovery_1 = require("./unknown-protocol-discovery");
12
+ const unsupervised_physics_1 = require("./experimental/unsupervised-physics");
13
+ (0, vitest_1.describe)("P8.2 Unknown Protocol Discovery", () => {
14
+ (0, vitest_1.it)("extracts sequences from known repos", () => {
15
+ const redis = (0, unknown_protocol_discovery_1.extractUnknownRepoSequences)("Redis");
16
+ const sqlite = (0, unknown_protocol_discovery_1.extractUnknownRepoSequences)("SQLite");
17
+ const pg = (0, unknown_protocol_discovery_1.extractUnknownRepoSequences)("PostgreSQL");
18
+ (0, vitest_1.expect)(redis.length).toBeGreaterThan(0);
19
+ (0, vitest_1.expect)(sqlite.length).toBeGreaterThan(0);
20
+ (0, vitest_1.expect)(pg.length).toBeGreaterThan(0);
21
+ });
22
+ (0, vitest_1.it)("builds known fingerprint library from protocols.json", () => {
23
+ const library = (0, unknown_protocol_discovery_1.buildKnownFingerprintLibrary)();
24
+ (0, vitest_1.expect)(library.size).toBeGreaterThanOrEqual(8);
25
+ (0, vitest_1.expect)(library.has("AuthProtocol")).toBe(true);
26
+ (0, vitest_1.expect)(library.has("FileProtocol")).toBe(true);
27
+ });
28
+ (0, vitest_1.it)("discovers protocols from unseen repo sequences", () => {
29
+ const seqs = (0, unknown_protocol_discovery_1.extractUnknownRepoSequences)("PostgreSQL");
30
+ const known = (0, unknown_protocol_discovery_1.buildKnownFingerprintLibrary)();
31
+ const discovered = (0, unknown_protocol_discovery_1.discoverProtocolsFromSequences)(seqs, "PostgreSQL", known);
32
+ (0, vitest_1.expect)(discovered.length).toBeGreaterThan(0);
33
+ for (const proto of discovered) {
34
+ (0, vitest_1.expect)(proto.fingerprint.stateCount).toBeGreaterThan(0);
35
+ (0, vitest_1.expect)(proto.prototype.length).toBeGreaterThan(0);
36
+ }
37
+ });
38
+ (0, vitest_1.it)("clusters structurally identical repos together (Redis ↔ SQLite)", () => {
39
+ const known = (0, unknown_protocol_discovery_1.buildKnownFingerprintLibrary)();
40
+ const redisDiscovered = (0, unknown_protocol_discovery_1.discoverProtocolsFromSequences)(unsupervised_physics_1.CROSS_REPO_SEQUENCES["Redis"], "Redis", known);
41
+ const sqliteDiscovered = (0, unknown_protocol_discovery_1.discoverProtocolsFromSequences)(unsupervised_physics_1.CROSS_REPO_SEQUENCES["SQLite"], "SQLite", known);
42
+ // Both Redis and SQLite should match the same known protocol family
43
+ // (both are acquire→use→release chains)
44
+ const redisMatch = redisDiscovered[0]?.closestKnown;
45
+ const sqliteMatch = sqliteDiscovered[0]?.closestKnown;
46
+ console.log(` Redis closest: ${redisMatch || "none"}`);
47
+ console.log(` SQLite closest: ${sqliteMatch || "none"}`);
48
+ // They should both match to FileProtocol or DBProtocol (resource lifecycle)
49
+ (0, vitest_1.expect)(redisMatch).toBeTruthy();
50
+ (0, vitest_1.expect)(sqliteMatch).toBeTruthy();
51
+ });
52
+ (0, vitest_1.it)("ZERO-SHOT: PostgreSQL defects repaired using Redis+SQLite knowledge", () => {
53
+ // Train on Redis + SQLite (known repos)
54
+ const trainRepos = ["Redis", "SQLite"];
55
+ // Test: PostgreSQL defects
56
+ // Common PG defects: missing commit, missing disconnect, missing begin
57
+ const defectCases = [
58
+ {
59
+ broken: ["PQconnectdb", "PQexec"],
60
+ expected: ["PQconnectdb", "PQexec", "PQfinish"],
61
+ description: "PG: missing disconnect after query",
62
+ },
63
+ {
64
+ broken: ["begin_transaction", "execute_query"],
65
+ expected: ["begin_transaction", "execute_query", "commit_transaction"],
66
+ description: "PG: missing commit after execute",
67
+ },
68
+ {
69
+ broken: ["PQconnectdb"],
70
+ expected: ["PQconnectdb", "PQexec", "PQfinish"],
71
+ description: "PG: only connect, no query or finish",
72
+ },
73
+ {
74
+ broken: ["PQconnectdb", "begin_transaction"],
75
+ expected: ["PQconnectdb", "begin_transaction", "execute_query", "commit_transaction", "PQfinish"],
76
+ description: "PG: full lifecycle missing middle+end",
77
+ },
78
+ ];
79
+ const result = (0, unknown_protocol_discovery_1.runZeroShotDiscovery)(trainRepos, "PostgreSQL", defectCases);
80
+ (0, unknown_protocol_discovery_1.printZeroShotResult)(result);
81
+ // Discovery: should find at least 1 protocol
82
+ (0, vitest_1.expect)(result.discoveredCount).toBeGreaterThan(0);
83
+ // Zero-shot repair: should repair at least SOME defects
84
+ // (PG sequences are structurally similar to Redis/SQLite acquire→use→release)
85
+ (0, vitest_1.expect)(result.repairRate).toBeGreaterThan(0);
86
+ });
87
+ (0, vitest_1.it)("CROSS-REPO: all 5 repos discoverable with cluster transfer", () => {
88
+ const known = (0, unknown_protocol_discovery_1.buildKnownFingerprintLibrary)();
89
+ const repos = Object.keys(unsupervised_physics_1.CROSS_REPO_SEQUENCES);
90
+ console.log(`\n Cross-repo discovery (${repos.length} repos):`);
91
+ console.log(` ${'Repo'.padEnd(14)} ${'Discovered'.padEnd(12)} ${'Closest Known'.padEnd(22)} ${'Confidence'}`);
92
+ console.log(` ${'─'.repeat(65)}`);
93
+ for (const repo of repos) {
94
+ const seqs = unsupervised_physics_1.CROSS_REPO_SEQUENCES[repo];
95
+ const discovered = (0, unknown_protocol_discovery_1.discoverProtocolsFromSequences)(seqs, repo, known);
96
+ const top = discovered[0];
97
+ console.log(` ${repo.padEnd(14)} ${String(discovered.length).padEnd(12)} ` +
98
+ `${(top?.closestKnown || "novel").padEnd(22)} ${top ? (top.matchConfidence * 100).toFixed(0) + '%' : 'N/A'}`);
99
+ (0, vitest_1.expect)(discovered.length).toBeGreaterThan(0);
100
+ }
101
+ });
102
+ });
@@ -0,0 +1,230 @@
1
+ "use strict";
2
+ /**
3
+ * P6.3: Unsupervised Physics Discovery
4
+ *
5
+ * Discovers protocol patterns WITHOUT hand-crafted keywords.
6
+ * Input: raw call sequences. Output: structural clusters.
7
+ *
8
+ * The test: if the system clusters [open,read,close] with
9
+ * [connect,query,disconnect] WITHOUT knowing the function names,
10
+ * it has genuinely learned the Acquire→Use→Release pattern.
11
+ *
12
+ * Algorithm:
13
+ * 1. Extract structural fingerprints from call sequences
14
+ * 2. Cluster by structural similarity (no keyword matching)
15
+ * 3. Compare discovered clusters to known physics patterns
16
+ * 4. Measure: are Acquire/Release clusters emergent?
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.CROSS_REPO_SEQUENCES = void 0;
20
+ exports.fingerprint = fingerprint;
21
+ exports.fingerprintSequences = fingerprintSequences;
22
+ exports.clusterByStructure = clusterByStructure;
23
+ exports.evaluateUnsupervisedDiscovery = evaluateUnsupervisedDiscovery;
24
+ exports.runUnsupervisedDiscovery = runUnsupervisedDiscovery;
25
+ exports.printUnsupervisedReport = printUnsupervisedReport;
26
+ /**
27
+ * Extract structural fingerprint from a function in context.
28
+ * Uses ONLY positional and structural features — NO function names.
29
+ */
30
+ function fingerprint(fn, index, sequence) {
31
+ const uniqueFns = new Set(sequence);
32
+ // Check if sequence forms a closed loop: first and last functions
33
+ // have structural similarity (both are single-occurrence "boundary" functions)
34
+ const firstFn = sequence[0];
35
+ const lastFn = sequence[sequence.length - 1];
36
+ const firstCount = sequence.filter(f => f === firstFn).length;
37
+ const lastCount = sequence.filter(f => f === lastFn).length;
38
+ // Closed loop: first and last are "boundary" functions (appear only once)
39
+ const isClosedLoop = firstCount === 1 && lastCount === 1 && sequence.length >= 2;
40
+ return {
41
+ seqId: sequence.join("→"),
42
+ length: sequence.length,
43
+ position: index / Math.max(1, sequence.length - 1),
44
+ isFirst: index === 0,
45
+ isLast: index === sequence.length - 1,
46
+ isClosedLoop,
47
+ uniqueCount: uniqueFns.size,
48
+ phase: index === 0 ? 0 : index === sequence.length - 1 ? 2 : 1,
49
+ };
50
+ }
51
+ /**
52
+ * Build fingerprints for all functions in a set of sequences.
53
+ */
54
+ function fingerprintSequences(sequences) {
55
+ const fps = new Map();
56
+ for (const seq of sequences) {
57
+ for (let i = 0; i < seq.length; i++) {
58
+ const fp = fingerprint(seq[i], i, seq);
59
+ fps.set(`${seq[i]}@${i}`, fp);
60
+ }
61
+ }
62
+ return fps;
63
+ }
64
+ /**
65
+ * Cluster sequences by structural similarity ONLY.
66
+ * No function names. No keywords. Pure topology.
67
+ */
68
+ function clusterByStructure(sequences) {
69
+ const features = sequences.map(seq => {
70
+ const uniqueFns = new Set(seq);
71
+ const firstFn = seq[0];
72
+ const lastFn = seq[seq.length - 1];
73
+ const firstCount = seq.filter(f => f === firstFn).length;
74
+ const lastCount = seq.filter(f => f === lastFn).length;
75
+ const closedLoop = firstCount === 1 && lastCount === 1 && seq.length >= 2;
76
+ // Phase profile: how many functions are at each phase
77
+ const profile = [0, 0, 0];
78
+ for (let i = 0; i < seq.length; i++) {
79
+ const phase = i === 0 ? 0 : i === seq.length - 1 ? 2 : 1;
80
+ profile[phase]++;
81
+ }
82
+ return { seq, length: seq.length, closedLoop, uniqueCount: uniqueFns.size, phaseProfile: profile };
83
+ });
84
+ // Clustering: group by [length bucket, closedLoop, uniqueCount]
85
+ const clusters = new Map();
86
+ for (const f of features) {
87
+ const lenBucket = f.length <= 2 ? "short" : f.length <= 4 ? "medium" : "long";
88
+ const loopKey = f.closedLoop ? "closed" : "open";
89
+ const key = `${lenBucket}-${loopKey}-${f.uniqueCount}`;
90
+ if (!clusters.has(key))
91
+ clusters.set(key, []);
92
+ clusters.get(key).push(f);
93
+ }
94
+ // Convert to DiscoveredCluster
95
+ const results = [];
96
+ let id = 0;
97
+ for (const [key, members] of clusters) {
98
+ if (members.length < 1)
99
+ continue;
100
+ const avgLen = members.reduce((s, m) => s + m.length, 0) / members.length;
101
+ const closedRate = members.filter(m => m.closedLoop).length / members.length;
102
+ // Infer physics pattern based on STRUCTURE, not names
103
+ let inferredPattern;
104
+ if (closedRate > 0.5 && avgLen >= 3) {
105
+ inferredPattern = "RESOURCE_ACQUIRE"; // Acquire-Use-Release structure
106
+ }
107
+ else if (closedRate > 0.5 && avgLen === 2) {
108
+ inferredPattern = "LOCK_ACQUIRE"; // Lock-Unlock structure
109
+ }
110
+ results.push({
111
+ id: `C${id++}`,
112
+ sequences: members.map(m => m.seq),
113
+ avgLength: avgLen,
114
+ closedLoopRate: closedRate,
115
+ signature: key,
116
+ inferredPattern,
117
+ });
118
+ }
119
+ return results.sort((a, b) => b.sequences.length - a.sequences.length);
120
+ }
121
+ /**
122
+ * Evaluate whether structural clustering discovers physics patterns.
123
+ *
124
+ * This is the KEY test: input raw sequences, output clusters.
125
+ * If Acquire-Use-Release clusters emerge WITHOUT keyword matching,
126
+ * the system has genuinely learned protocol structure.
127
+ */
128
+ function evaluateUnsupervisedDiscovery(sequences) {
129
+ const clusters = clusterByStructure(sequences);
130
+ // Check: do clusters match known physics patterns by STRUCTURE alone?
131
+ let structuralMatches = 0;
132
+ let sequencesInMatches = 0;
133
+ for (const c of clusters) {
134
+ if (c.inferredPattern) {
135
+ structuralMatches++;
136
+ sequencesInMatches += c.sequences.length;
137
+ }
138
+ }
139
+ const total = sequences.length;
140
+ const emergent = structuralMatches > 0 && sequencesInMatches / total > 0.5;
141
+ return {
142
+ totalSequences: total,
143
+ clusters,
144
+ structuralCoverage: clusters.length > 0 ? structuralMatches / clusters.length : 0,
145
+ sequenceCoverage: total > 0 ? sequencesInMatches / total : 0,
146
+ emergent,
147
+ };
148
+ }
149
+ // ═══════════════════════════════════════════════════════════════
150
+ // Cross-Repo Unsupervised Benchmark
151
+ // ═══════════════════════════════════════════════════════════════
152
+ exports.CROSS_REPO_SEQUENCES = {
153
+ Redis: [
154
+ ["createClient", "sendCommand", "closeClient"],
155
+ ["selectDB", "getKey"],
156
+ ["createClient", "sendCommand", "readReply", "closeClient"],
157
+ ],
158
+ SQLite: [
159
+ ["sqlite3_open", "sqlite3_exec", "sqlite3_close"],
160
+ ["sqlite3_prepare", "sqlite3_step", "sqlite3_finalize"],
161
+ ["sqlite3_open", "sqlite3_prepare", "sqlite3_step", "sqlite3_finalize", "sqlite3_close"],
162
+ ],
163
+ nginx: [
164
+ ["ngx_accept_connection", "ngx_read_request", "ngx_close_connection"],
165
+ ["ngx_parse_headers", "ngx_send_response"],
166
+ ["ngx_accept_connection", "ngx_process_request", "ngx_send_response", "ngx_close_connection"],
167
+ ],
168
+ PostgreSQL: [
169
+ ["PQconnectdb", "PQexec", "PQfinish"],
170
+ ["begin_transaction", "execute_query", "commit_transaction"],
171
+ ["PQconnectdb", "begin_transaction", "execute_query", "commit_transaction", "PQfinish"],
172
+ ],
173
+ LevelDB: [
174
+ ["DB_Open", "DB_Get", "DB_Close"],
175
+ ["DB_Open", "DB_Put", "DB_Close"],
176
+ ["DB_Open", "DB_Write", "DB_Compact", "DB_Close"],
177
+ ],
178
+ };
179
+ /**
180
+ * Full unsupervised discovery across all known repos.
181
+ */
182
+ function runUnsupervisedDiscovery() {
183
+ const perRepo = {};
184
+ const allSeqs = [];
185
+ for (const [repo, seqs] of Object.entries(exports.CROSS_REPO_SEQUENCES)) {
186
+ const eval_ = evaluateUnsupervisedDiscovery(seqs);
187
+ perRepo[repo] = eval_;
188
+ allSeqs.push(...seqs);
189
+ }
190
+ const allEval = evaluateUnsupervisedDiscovery(allSeqs);
191
+ const emergent = Object.values(perRepo).every(e => e.emergent);
192
+ return {
193
+ perRepo,
194
+ allSequences: allEval,
195
+ emergent,
196
+ summary: emergent
197
+ ? "ACQUIRE→USE→RELEASE clusters emerged WITHOUT keyword matching. Software Physics is REAL."
198
+ : "Structural clustering found some patterns, but not consistently across repos. More data needed.",
199
+ };
200
+ }
201
+ function printUnsupervisedReport(report) {
202
+ console.log("\n╔════════════════════════════════════════════════════╗");
203
+ console.log("║ P6.3 Unsupervised Physics Discovery ║");
204
+ console.log("║ (NO keywords. NO function names. Pure topology.) ║");
205
+ console.log("╚════════════════════════════════════════════════════╝\n");
206
+ console.log(`Emergent Physics: ${report.emergent ? "✅ YES" : "❌ NO"}`);
207
+ console.log(`Summary: ${report.summary}`);
208
+ console.log();
209
+ console.log("─── Per-Repo Discovery ───");
210
+ console.log("Repo Seqs Clusters StructCov Emergent");
211
+ console.log("──────────────────────────────────────────────────");
212
+ for (const [repo, eval_] of Object.entries(report.perRepo)) {
213
+ const sc = (eval_.structuralCoverage * 100).toFixed(0).padStart(4);
214
+ const icon = eval_.emergent ? "✅" : "❌";
215
+ console.log(` ${repo.padEnd(12)} ${String(eval_.totalSequences).padStart(4)} ${String(eval_.clusters.length).padStart(8)} ${sc}% ${icon}`);
216
+ }
217
+ console.log();
218
+ console.log("─── Discovered Clusters ───");
219
+ for (const c of report.allSequences.clusters.slice(0, 10)) {
220
+ const pattern = c.inferredPattern || "unknown";
221
+ const closed = c.closedLoopRate > 0.5 ? "closed-loop" : "open";
222
+ console.log(` ${c.id}: ${c.sequences.length} seqs, avgLen=${c.avgLength.toFixed(1)}, ${closed}, → ${pattern}`);
223
+ if (c.sequences.length <= 3) {
224
+ for (const s of c.sequences) {
225
+ console.log(` ${s.join(" → ")}`);
226
+ }
227
+ }
228
+ }
229
+ console.log();
230
+ }