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,274 @@
1
+ "use strict";
2
+ /**
3
+ * Knowledge Flywheel — Self-reinforcing knowledge growth pipeline
4
+ *
5
+ * Repo → Scan → Evidence → Confidence → Version Suggestion → Human Review → Merge
6
+ * ↑ │
7
+ * └──────────── More Repos ←────────────────────────┘
8
+ *
9
+ * Usage:
10
+ * npx ts-node src/knowledge-flywheel.ts scan benchmarks/nginx
11
+ * npx ts-node src/knowledge-flywheel.ts status
12
+ * npx ts-node src/knowledge-flywheel.ts metrics
13
+ */
14
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ var desc = Object.getOwnPropertyDescriptor(m, k);
17
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
18
+ desc = { enumerable: true, get: function() { return m[k]; } };
19
+ }
20
+ Object.defineProperty(o, k2, desc);
21
+ }) : (function(o, m, k, k2) {
22
+ if (k2 === undefined) k2 = k;
23
+ o[k2] = m[k];
24
+ }));
25
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
26
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
27
+ }) : function(o, v) {
28
+ o["default"] = v;
29
+ });
30
+ var __importStar = (this && this.__importStar) || (function () {
31
+ var ownKeys = function(o) {
32
+ ownKeys = Object.getOwnPropertyNames || function (o) {
33
+ var ar = [];
34
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
35
+ return ar;
36
+ };
37
+ return ownKeys(o);
38
+ };
39
+ return function (mod) {
40
+ if (mod && mod.__esModule) return mod;
41
+ var result = {};
42
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
43
+ __setModuleDefault(result, mod);
44
+ return result;
45
+ };
46
+ })();
47
+ Object.defineProperty(exports, "__esModule", { value: true });
48
+ exports.scanRepo = scanRepo;
49
+ exports.loadMetrics = loadMetrics;
50
+ const fs = __importStar(require("fs"));
51
+ const path = __importStar(require("path"));
52
+ const protocol_detector_1 = require("./protocol-detector");
53
+ const protocol_knowledge_1 = require("./protocol-knowledge");
54
+ // ═══════════════════════════════════════════════════════════════
55
+ // Scanner
56
+ // ═══════════════════════════════════════════════════════════════
57
+ const PROPOSALS_DIR = ".progmune_corpus/flywheel";
58
+ function scanRepo(repoPath) {
59
+ const repoName = path.basename(repoPath);
60
+ const seqFile = path.join(path.dirname(repoPath), `${repoName}-sequences.json`);
61
+ if (!fs.existsSync(seqFile))
62
+ throw new Error(`No sequences: ${seqFile}`);
63
+ const sequences = JSON.parse(fs.readFileSync(seqFile, "utf-8"));
64
+ const kb = (0, protocol_knowledge_1.buildKnowledgeBase)();
65
+ const proposals = [];
66
+ // Match sequences against KB
67
+ const matchCounts = {};
68
+ for (const seq of sequences.slice(0, 50)) {
69
+ const result = (0, protocol_detector_1.validateProtocolState)(seq.calls || []);
70
+ for (const p of result.matchedProtocols)
71
+ matchCounts[p] = (matchCounts[p] || 0) + 1;
72
+ }
73
+ for (const [proto, count] of Object.entries(matchCounts)) {
74
+ const unit = kb.units.find(u => u.name === proto);
75
+ if (!unit || count < 3)
76
+ continue;
77
+ const alreadyEvidenced = (unit.evidence || []).some(e => e.repo === repoName);
78
+ if (alreadyEvidenced)
79
+ continue;
80
+ let suggestion;
81
+ let proposedVersion = unit.currentVersion;
82
+ let proposedConf = unit.confidence;
83
+ let reason = "";
84
+ if (count >= 10 && unit.maturity !== "stable") {
85
+ // Enough evidence to promote
86
+ suggestion = "promote";
87
+ const [major, minor] = unit.currentVersion.split(".").map(Number);
88
+ proposedVersion = `${major + 1}.0.0`;
89
+ proposedConf = Math.min(95, unit.confidence + 15);
90
+ reason = `${count}/50 sequences matched — strong evidence for promotion to stable. Would add ${repoName} as ${(unit.validatedRepos.length + 1)}th validated repo.`;
91
+ }
92
+ else if (count >= 5 && unit.confidence < 80) {
93
+ suggestion = "bump";
94
+ const [major, minor, patch] = unit.currentVersion.split(".").map(Number);
95
+ proposedVersion = `${major}.${minor}.${(patch || 0) + 1}`;
96
+ proposedConf = Math.min(90, unit.confidence + 8);
97
+ reason = `${count}/50 sequences matched — confidence bump warranted.`;
98
+ }
99
+ else if (count >= 3) {
100
+ suggestion = "evidence_only";
101
+ proposedConf = Math.min(90, unit.confidence + 3);
102
+ reason = `${count}/50 matched — evidence addition only. Confidence +3%.`;
103
+ }
104
+ else {
105
+ suggestion = "insufficient";
106
+ reason = `Only ${count}/50 matched — insufficient for any action.`;
107
+ }
108
+ const proposal = {
109
+ id: `FLY-${Date.now().toString(36)}-${unit.id}`,
110
+ repo: repoName,
111
+ timestamp: new Date().toISOString(),
112
+ unitId: unit.id,
113
+ unitName: unit.name,
114
+ currentVersion: unit.currentVersion,
115
+ proposedVersion,
116
+ currentConfidence: unit.confidence,
117
+ proposedConfidence: proposedConf,
118
+ evidenceCount: count,
119
+ matchRate: `${count}/50`,
120
+ suggestion,
121
+ reason,
122
+ status: "pending",
123
+ };
124
+ proposals.push(proposal);
125
+ }
126
+ // Save proposals
127
+ if (!fs.existsSync(PROPOSALS_DIR))
128
+ fs.mkdirSync(PROPOSALS_DIR, { recursive: true });
129
+ for (const p of proposals) {
130
+ fs.writeFileSync(path.join(PROPOSALS_DIR, `${p.id}.json`), JSON.stringify(p, null, 2));
131
+ }
132
+ // Update metrics
133
+ updateMetrics(repoName, proposals);
134
+ return proposals.sort((a, b) => b.evidenceCount - a.evidenceCount);
135
+ }
136
+ // ═══════════════════════════════════════════════════════════════
137
+ // Metrics
138
+ // ═══════════════════════════════════════════════════════════════
139
+ const METRICS_FILE = ".progmune_corpus/flywheel-metrics.json";
140
+ function loadMetrics() {
141
+ try {
142
+ return JSON.parse(fs.readFileSync(METRICS_FILE, "utf-8"));
143
+ }
144
+ catch {
145
+ return { totalScans: 0, totalProposals: 0, acceptedProposals: 0, rejectedProposals: 0, pendingProposals: 0, knowledgeVelocity: 0, averageConfidenceGain: 0, reposScanned: [], history: [] };
146
+ }
147
+ }
148
+ function updateMetrics(repo, proposals) {
149
+ const m = loadMetrics();
150
+ if (!m.reposScanned.includes(repo))
151
+ m.reposScanned.push(repo);
152
+ m.totalScans++;
153
+ m.totalProposals += proposals.length;
154
+ m.pendingProposals += proposals.filter(p => p.suggestion !== "insufficient").length;
155
+ m.history.push(...proposals);
156
+ if (m.totalScans > 0)
157
+ m.knowledgeVelocity = Math.round((m.totalProposals / m.totalScans) * 10) / 10;
158
+ m.averageConfidenceGain = m.history.filter(p => p.suggestion !== "insufficient").reduce((s, p) => s + (p.proposedConfidence - p.currentConfidence), 0) / Math.max(1, m.history.filter(p => p.suggestion !== "insufficient").length);
159
+ if (!fs.existsSync(".progmune_corpus"))
160
+ fs.mkdirSync(".progmune_corpus");
161
+ fs.writeFileSync(METRICS_FILE, JSON.stringify(m, null, 2));
162
+ }
163
+ // ═══════════════════════════════════════════════════════════════
164
+ // CLI
165
+ // ═══════════════════════════════════════════════════════════════
166
+ if (require.main === module) {
167
+ const args = process.argv.slice(2);
168
+ const C = { r: "\x1b[0m", b: "\x1b[1m", d: "\x1b[2m", g: "\x1b[32m", y: "\x1b[33m", r2: "\x1b[31m", c: "\x1b[36m" };
169
+ if (args[0] === "scan" && args[1]) {
170
+ console.error(`\n${C.b}${C.c}Flywheel: Scanning ${args[1]}${C.r}\n`);
171
+ const proposals = scanRepo(args[1]);
172
+ const actionable = proposals.filter(p => p.suggestion !== "insufficient");
173
+ for (const p of proposals) {
174
+ const icon = p.suggestion === "promote" ? "⭐" : p.suggestion === "bump" ? "📈" : p.suggestion === "evidence_only" ? "✅" : "—";
175
+ console.log(` ${icon} ${p.unitName}: ${p.matchRate} → ${p.suggestion}`);
176
+ console.log(` v${p.currentVersion} → v${p.proposedVersion} | ${p.currentConfidence}% → ${p.proposedConfidence}%`);
177
+ console.log(` ${p.reason}`);
178
+ if (p.suggestion !== "insufficient")
179
+ console.log(` ${C.d}Review: ${PROPOSALS_DIR}/${p.id}.json${C.r}`);
180
+ }
181
+ if (actionable.length > 0) {
182
+ console.log(`\n ${C.g}${actionable.length} actionable proposal(s) saved.${C.r}`);
183
+ console.log(` ${C.d}Review proposals in ${PROPOSALS_DIR}/ and accept to grow Knowledge Base.${C.r}`);
184
+ }
185
+ console.log("");
186
+ }
187
+ else if (args[0] === "status") {
188
+ const m = loadMetrics();
189
+ console.log(`\n${C.b}${C.c}Knowledge Flywheel${C.r}\n`);
190
+ console.log(` Scans: ${m.totalScans} repos (${m.reposScanned.join(", ") || "none"})`);
191
+ console.log(` Proposals: ${m.totalProposals} total, ${m.acceptedProposals} accepted, ${m.rejectedProposals} rejected, ${m.pendingProposals} pending`);
192
+ console.log(` Velocity: ${m.knowledgeVelocity} proposals/scan`);
193
+ console.log(` Avg Gain: +${m.averageConfidenceGain.toFixed(1)}% confidence per proposal`);
194
+ const recent = m.history.slice(-5);
195
+ if (recent.length > 0) {
196
+ console.log(`\n Recent proposals:`);
197
+ for (const p of recent) {
198
+ const icon = p.status === "accepted" ? C.g + "✓" : p.status === "rejected" ? C.r2 + "✗" : C.y + "⏳";
199
+ console.log(` ${icon}${C.r} ${p.unitName}: ${p.matchRate} → ${p.suggestion} (${p.repo})`);
200
+ }
201
+ }
202
+ console.log("");
203
+ }
204
+ else if (args[0] === "debt") {
205
+ const kb = (0, protocol_knowledge_1.buildKnowledgeBase)();
206
+ console.log(`\n${C.b}${C.c}Knowledge Debt Dashboard${C.r}\n`);
207
+ for (const u of kb.units.filter(u => u.maturity === "stable" || u.maturity === "validated")) {
208
+ const b = u.confidenceBreakdown;
209
+ if (!b)
210
+ continue;
211
+ const sDebt = 100 - b.structural;
212
+ const cDebt = 100 - b.crossRepo;
213
+ const dDebt = 100 - b.deployment;
214
+ const total = Math.round(sDebt * 0.3 + cDebt * 0.3 + dDebt * 0.4);
215
+ const bar = "█".repeat(Math.min(10, Math.round(total / 10))) + "░".repeat(Math.max(0, 10 - Math.round(total / 10)));
216
+ const rec = dDebt > 30 ? "Need more deployment observations" : sDebt > 10 ? "Refine state machine" : "Healthy";
217
+ console.log(` ${bar} ${C.b}${u.name}${C.r} Debt: ${total}%`);
218
+ console.log(` Structural: ${b.structural}% (gap: ${sDebt}%) | Cross-Repo: ${b.crossRepo}% (gap: ${cDebt}%) | Deployment: ${b.deployment}% (gap: ${dDebt}%)`);
219
+ console.log(` → ${rec}`);
220
+ }
221
+ console.log(`\n ${C.d}Debt = weighted gap from 100%. Fix deployment debt first — it's the weakest link.${C.r}\n`);
222
+ }
223
+ else if (args[0] === "roi") {
224
+ const m = loadMetrics();
225
+ const kb = (0, protocol_knowledge_1.buildKnowledgeBase)();
226
+ console.log(`\n${C.b}${C.c}Knowledge ROI Report${C.r}\n`);
227
+ console.log(` Flywheel Stats:`);
228
+ console.log(` Scans: ${m.totalScans} repos`);
229
+ console.log(` Proposals: ${m.totalProposals} generated, ${m.acceptedProposals} accepted`);
230
+ console.log(` Velocity: ${m.knowledgeVelocity} proposals/scan`);
231
+ console.log(` Avg Gain: +${m.averageConfidenceGain.toFixed(1)}% per proposal`);
232
+ console.log(`\n Knowledge Growth:`);
233
+ const stableCount = kb.units.filter(u => u.maturity === "stable").length;
234
+ console.log(` Stable Units: ${stableCount} (from 0)`);
235
+ console.log(` Repos: ${kb.summary.totalValidatedRepos} validated`);
236
+ console.log(` Evidence: ${kb.summary.totalValidatedSequences} sequences`);
237
+ console.log(`\n Per-Unit ROI:`);
238
+ for (const u of kb.units.filter(u => u.maturity === "stable")) {
239
+ const breakdown = u.confidenceBreakdown;
240
+ console.log(` ${C.b}${u.name}${C.r} v${u.currentVersion}`);
241
+ if (breakdown) {
242
+ console.log(` Structural: ${breakdown.structural}% (state machine stability)`);
243
+ console.log(` Cross-Repo: ${breakdown.crossRepo}% (multi-repo validation)`);
244
+ console.log(` Deployment: ${breakdown.deployment}% (real-world acceptance)`);
245
+ }
246
+ const obs = u.observations?.length || 0;
247
+ console.log(` Observations: ${obs} deployment feedback events`);
248
+ }
249
+ console.log(`\n ${C.d}Flywheel: ${m.totalScans} scans → ${m.totalProposals} proposals → ${m.acceptedProposals} accepted → ${stableCount} stable → +${m.averageConfidenceGain.toFixed(1)}% avg confidence${C.r}\n`);
250
+ }
251
+ else if (args[0] === "metrics") {
252
+ console.log(JSON.stringify(loadMetrics(), null, 2));
253
+ }
254
+ else {
255
+ console.log(`
256
+ ${C.b}Knowledge Flywheel${C.r}
257
+
258
+ ${C.d}Usage:${C.r}
259
+ npx ts-node src/knowledge-flywheel.ts scan <repoPath>
260
+ Scan a repo and generate evidence proposals
261
+
262
+ npx ts-node src/knowledge-flywheel.ts status
263
+ View flywheel metrics and recent proposals
264
+
265
+ npx ts-node src/knowledge-flywheel.ts metrics
266
+ Export full metrics as JSON
267
+
268
+ ${C.d}The Flywheel:${C.r}
269
+ Repo → Scan → Evidence → Confidence → Version → Review → Merge
270
+ ↑ │
271
+ └──────────────── More Repos ←─────────────────────────┘
272
+ `);
273
+ }
274
+ }
@@ -0,0 +1,338 @@
1
+ "use strict";
2
+ /**
3
+ * P3.21-23: Knowledge Governance Layer
4
+ *
5
+ * P3.21: Multi-source inference validation.
6
+ * benchark support + trajectory support - contradiction = trustworthiness.
7
+ * Status: proposed → verified → rejected.
8
+ *
9
+ * P3.22: Knowledge versioning.
10
+ * Every inferred transition is a versioned patch with audit trail.
11
+ * Planner reads Base Rules + Approved Patches (never modifies originals).
12
+ *
13
+ * P3.23: Regression testing.
14
+ * Run benchmark suite against proposed patches. Auto-approve only
15
+ * if Top-1 and Top-3 don't regress.
16
+ *
17
+ * Philosophy:
18
+ * Wrong knowledge + perfect Reward Model = confidently wrong.
19
+ * Right knowledge + basic Ranker = steadily improving.
20
+ */
21
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
22
+ if (k2 === undefined) k2 = k;
23
+ var desc = Object.getOwnPropertyDescriptor(m, k);
24
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
25
+ desc = { enumerable: true, get: function() { return m[k]; } };
26
+ }
27
+ Object.defineProperty(o, k2, desc);
28
+ }) : (function(o, m, k, k2) {
29
+ if (k2 === undefined) k2 = k;
30
+ o[k2] = m[k];
31
+ }));
32
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
33
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
34
+ }) : function(o, v) {
35
+ o["default"] = v;
36
+ });
37
+ var __importStar = (this && this.__importStar) || (function () {
38
+ var ownKeys = function(o) {
39
+ ownKeys = Object.getOwnPropertyNames || function (o) {
40
+ var ar = [];
41
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
42
+ return ar;
43
+ };
44
+ return ownKeys(o);
45
+ };
46
+ return function (mod) {
47
+ if (mod && mod.__esModule) return mod;
48
+ var result = {};
49
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
50
+ __setModuleDefault(result, mod);
51
+ return result;
52
+ };
53
+ })();
54
+ Object.defineProperty(exports, "__esModule", { value: true });
55
+ exports.KnowledgePatchStore = void 0;
56
+ exports.validateInferences = validateInferences;
57
+ exports.regressionTestPatch = regressionTestPatch;
58
+ exports.autoApprovePatch = autoApprovePatch;
59
+ exports.runKnowledgeGovernance = runKnowledgeGovernance;
60
+ exports.printGovernanceReport = printGovernanceReport;
61
+ const fs = __importStar(require("fs"));
62
+ const path = __importStar(require("path"));
63
+ const transition_synthesizer_1 = require("./transition-synthesizer");
64
+ const protocol_frontier_1 = require("./protocol-frontier");
65
+ const protocol_coverage_1 = require("./protocol-coverage");
66
+ const VALIDATION_THRESHOLDS = {
67
+ benchmarkMin: 3,
68
+ trajectoryMin: 5,
69
+ contradictionMax: 0,
70
+ };
71
+ /**
72
+ * Validate inferred transitions against multi-source evidence.
73
+ *
74
+ * - benchmarkSupport: how many benchmark cases need this transition
75
+ * - trajectorySupport: how many real trajectory records show this pattern
76
+ * - contradictionCount: how many counter-examples exist
77
+ *
78
+ * Status logic:
79
+ * proposed — insufficient evidence yet
80
+ * verified — ≥3 benchmark + ≥5 trajectory + 0 contradictions
81
+ * rejected — contradictionCount > 0
82
+ */
83
+ function validateInferences(inferences, trajectoryCount = 0) {
84
+ return inferences.map(inf => {
85
+ const benchmarkSupport = inf.evidenceCount;
86
+ const trajectorySupport = trajectoryCount;
87
+ const contradictionCount = 0; // no contradiction detection yet
88
+ let status;
89
+ if (contradictionCount > VALIDATION_THRESHOLDS.contradictionMax) {
90
+ status = "rejected";
91
+ }
92
+ else if (benchmarkSupport >= VALIDATION_THRESHOLDS.benchmarkMin &&
93
+ trajectorySupport >= VALIDATION_THRESHOLDS.trajectoryMin) {
94
+ status = "verified";
95
+ }
96
+ else {
97
+ status = "proposed";
98
+ }
99
+ return {
100
+ ...inf,
101
+ validation: { benchmarkSupport, trajectorySupport, contradictionCount, status },
102
+ };
103
+ });
104
+ }
105
+ const KNOWLEDGE_DIR = path.resolve(process.env.PROGMUNE_PROJECT_DIR || process.cwd(), ".progmune_corpus", "knowledge");
106
+ class KnowledgePatchStore {
107
+ constructor(persistPath) {
108
+ this.patches = [];
109
+ this.persistPath = persistPath || path.join(KNOWLEDGE_DIR, "patches.json");
110
+ this.load();
111
+ }
112
+ /** Propose a new knowledge patch from an inferred transition. */
113
+ propose(inference) {
114
+ const id = `KP-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
115
+ const patch = {
116
+ id,
117
+ generatedBy: "transition-synthesizer",
118
+ protocol: inference.protocol,
119
+ change: inference.action,
120
+ fromState: inference.from,
121
+ toState: inference.to,
122
+ confidence: inference.confidence,
123
+ evidenceCount: inference.evidenceCount,
124
+ createdAt: new Date().toISOString(),
125
+ status: "proposed",
126
+ };
127
+ this.patches.push(patch);
128
+ this.save();
129
+ return patch;
130
+ }
131
+ /** Approve a patch (with benchmark metrics). */
132
+ approve(id, metrics) {
133
+ const patch = this.patches.find(p => p.id === id);
134
+ if (!patch || patch.status !== "proposed")
135
+ return false;
136
+ patch.status = "approved";
137
+ patch.approvedAt = new Date().toISOString();
138
+ patch.approvalMetrics = metrics;
139
+ this.save();
140
+ return true;
141
+ }
142
+ /** Reject a patch. */
143
+ reject(id) {
144
+ const patch = this.patches.find(p => p.id === id);
145
+ if (!patch || patch.status !== "proposed")
146
+ return false;
147
+ patch.status = "rejected";
148
+ this.save();
149
+ return true;
150
+ }
151
+ /** Rollback an approved patch. */
152
+ rollback(id) {
153
+ const patch = this.patches.find(p => p.id === id);
154
+ if (!patch || patch.status !== "approved")
155
+ return false;
156
+ patch.status = "rolled_back";
157
+ patch.rolledBackAt = new Date().toISOString();
158
+ this.save();
159
+ return true;
160
+ }
161
+ /** Get all approved patches (these augment the base rules). */
162
+ get approved() {
163
+ return this.patches.filter(p => p.status === "approved");
164
+ }
165
+ /** Get all proposed patches. */
166
+ get proposed() {
167
+ return this.patches.filter(p => p.status === "proposed");
168
+ }
169
+ /** Build augmented rules: base rules + approved patches as virtual rules. */
170
+ buildAugmentedRules(baseRules) {
171
+ const augmented = new Map(baseRules);
172
+ for (const patch of this.approved) {
173
+ const [fnA, fnB] = patch.change.split(" → ");
174
+ const bridgeName = `_patch_${fnA}_to_${fnB}`;
175
+ augmented.set(bridgeName, {
176
+ pre_states: [patch.fromState],
177
+ post_states: [patch.toState],
178
+ namespace: "knowledge-patch",
179
+ });
180
+ }
181
+ return augmented;
182
+ }
183
+ get all() { return this.patches; }
184
+ get size() { return this.patches.length; }
185
+ save() {
186
+ try {
187
+ if (!fs.existsSync(path.dirname(this.persistPath))) {
188
+ fs.mkdirSync(path.dirname(this.persistPath), { recursive: true });
189
+ }
190
+ fs.writeFileSync(this.persistPath, JSON.stringify(this.patches, null, 2));
191
+ }
192
+ catch { /* best-effort */ }
193
+ }
194
+ load() {
195
+ try {
196
+ if (fs.existsSync(this.persistPath)) {
197
+ this.patches = JSON.parse(fs.readFileSync(this.persistPath, "utf-8"));
198
+ }
199
+ }
200
+ catch { /* start fresh */ }
201
+ }
202
+ }
203
+ exports.KnowledgePatchStore = KnowledgePatchStore;
204
+ /**
205
+ * Test whether a proposed patch improves or degrades benchmark performance.
206
+ *
207
+ * Uses the frontier explorer to simulate: given currentState, can the Planner
208
+ * find paths that it couldn't before? If the augmented rules produce more
209
+ * successful paths without breaking existing ones, the patch passes.
210
+ */
211
+ function regressionTestPatch(patch, baseRules, testCases, store) {
212
+ // Top-1/Top-3 BEFORE patch (using base rules only)
213
+ let top1Before = 0;
214
+ let top3Before = 0;
215
+ for (const tc of testCases) {
216
+ const result = (0, protocol_frontier_1.searchFrontier)(baseRules, tc.currentState, tc.targetState, 8);
217
+ if (result.found && result.cost <= 1)
218
+ top1Before++;
219
+ if (result.found && result.cost <= 3)
220
+ top3Before++;
221
+ }
222
+ const top1RateBefore = testCases.length > 0 ? top1Before / testCases.length : 0;
223
+ const top3RateBefore = testCases.length > 0 ? top3Before / testCases.length : 0;
224
+ // Top-1/Top-3 AFTER patch (base + this patch)
225
+ const augmented = store.buildAugmentedRules(baseRules);
226
+ let top1After = 0;
227
+ let top3After = 0;
228
+ for (const tc of testCases) {
229
+ const result = (0, protocol_frontier_1.searchFrontier)(augmented, tc.currentState, tc.targetState, 8);
230
+ if (result.found && result.cost <= 1)
231
+ top1After++;
232
+ if (result.found && result.cost <= 3)
233
+ top3After++;
234
+ }
235
+ const top1RateAfter = testCases.length > 0 ? top1After / testCases.length : 0;
236
+ const top3RateAfter = testCases.length > 0 ? top3After / testCases.length : 0;
237
+ // Patch passes if: Top-1 doesn't decrease AND Top-3 doesn't decrease
238
+ const passed = top1RateAfter >= top1RateBefore && top3RateAfter >= top3RateBefore;
239
+ const reason = passed
240
+ ? `Top-1: ${(top1RateBefore * 100).toFixed(0)}% → ${(top1RateAfter * 100).toFixed(0)}%, Top-3: ${(top3RateBefore * 100).toFixed(0)}% → ${(top3RateAfter * 100).toFixed(0)}%`
241
+ : `Degradation detected. Top-1: ${(top1RateBefore * 100).toFixed(0)}% → ${(top1RateAfter * 100).toFixed(0)}%`;
242
+ return {
243
+ patchId: patch.id,
244
+ change: patch.change,
245
+ top1Before: top1RateBefore,
246
+ top1After: top1RateAfter,
247
+ top3Before: top3RateBefore,
248
+ top3After: top3RateAfter,
249
+ passed,
250
+ reason,
251
+ };
252
+ }
253
+ /**
254
+ * Full auto-approval pipeline:
255
+ * 1. Validate proposal against all test cases
256
+ * 2. Auto-approve if no regression
257
+ * 3. Record approval metrics
258
+ */
259
+ function autoApprovePatch(patch, baseRules, testCases, store) {
260
+ const result = regressionTestPatch(patch, baseRules, testCases, store);
261
+ if (result.passed) {
262
+ store.approve(patch.id, {
263
+ top1Before: result.top1Before,
264
+ top1After: result.top1After,
265
+ top3Before: result.top3Before,
266
+ top3After: result.top3After,
267
+ });
268
+ }
269
+ else {
270
+ store.reject(patch.id);
271
+ }
272
+ return result;
273
+ }
274
+ /**
275
+ * Run the full knowledge governance pipeline:
276
+ * Synthesize → Validate → Propose → Regression Test → Auto-Approve
277
+ */
278
+ function runKnowledgeGovernance(failures, testCases, store) {
279
+ const patchStore = store || new KnowledgePatchStore();
280
+ // 1. Synthesize
281
+ const inferences = (0, transition_synthesizer_1.synthesizeTransitions)(failures);
282
+ // 2. Validate
283
+ const validated = validateInferences(inferences);
284
+ // 3. Propose verified inferences
285
+ let proposed = 0;
286
+ let approved = 0;
287
+ let rejected = 0;
288
+ const regressionResults = [];
289
+ const defs = (0, protocol_coverage_1.loadDefaultProtocolDefinitions)();
290
+ const baseRules = new Map();
291
+ for (const p of defs)
292
+ for (const [fn, rule] of p.rules)
293
+ baseRules.set(fn, rule);
294
+ for (const inf of validated) {
295
+ if (inf.validation.status === "rejected") {
296
+ rejected++;
297
+ continue;
298
+ }
299
+ // 4. Propose
300
+ const patch = patchStore.propose(inf);
301
+ proposed++;
302
+ // 5. Regression test and auto-approve
303
+ const result = autoApprovePatch(patch, baseRules, testCases, patchStore);
304
+ regressionResults.push(result);
305
+ if (result.passed)
306
+ approved++;
307
+ else
308
+ rejected++;
309
+ }
310
+ return {
311
+ proposed,
312
+ verified: validated.filter(v => v.validation.status === "verified").length,
313
+ approved,
314
+ rejected,
315
+ rolledBack: patchStore.all.filter(p => p.status === "rolled_back").length,
316
+ regressionResults,
317
+ };
318
+ }
319
+ function printGovernanceReport(report) {
320
+ console.log("\n╔════════════════════════════════════════════════════╗");
321
+ console.log("║ Knowledge Governance Report ║");
322
+ console.log("╚════════════════════════════════════════════════════╝\n");
323
+ console.log(`Proposed: ${report.proposed}`);
324
+ console.log(`Verified: ${report.verified}`);
325
+ console.log(`Approved: ${report.approved}`);
326
+ console.log(`Rejected: ${report.rejected}`);
327
+ console.log(`Rolled Back: ${report.rolledBack}`);
328
+ console.log();
329
+ if (report.regressionResults.length > 0) {
330
+ console.log("─── Regression Results ───");
331
+ for (const r of report.regressionResults) {
332
+ const icon = r.passed ? "✅" : "❌";
333
+ console.log(` ${icon} ${r.change}`);
334
+ console.log(` ${r.reason}`);
335
+ }
336
+ console.log();
337
+ }
338
+ }