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,476 @@
1
+ "use strict";
2
+ /**
3
+ * Progmune V4 — Invariant Algebra
4
+ * ================================
5
+ * 将业务协议提升为可推理、可组合、可证明的代数系统。
6
+ *
7
+ * 核心理念:
8
+ * Protocol 不只是规则列表。它们是数学对象。
9
+ * 两个 Protocol 可以 Merge、Intersect、Compose。
10
+ * 从一个 Protocol 可以推导出另一个 Protocol(Closure)。
11
+ * 跨实体的一致性可以用 Functor 来描述和验证。
12
+ *
13
+ * 从规则到定理:
14
+ * 输入: 一组 Invariant(谓词逻辑语句)
15
+ * 输出: (1) 闭包 — 自动推导的新不变量
16
+ * (2) 组合 — 两个 Protocol 合并后的不变量
17
+ * (3) 函子保持 — 跨实体一致性验证
18
+ * (4) 定理 — 从 Protocol 系统中可证明的性质
19
+ */
20
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
21
+ if (k2 === undefined) k2 = k;
22
+ var desc = Object.getOwnPropertyDescriptor(m, k);
23
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
24
+ desc = { enumerable: true, get: function() { return m[k]; } };
25
+ }
26
+ Object.defineProperty(o, k2, desc);
27
+ }) : (function(o, m, k, k2) {
28
+ if (k2 === undefined) k2 = k;
29
+ o[k2] = m[k];
30
+ }));
31
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
32
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
33
+ }) : function(o, v) {
34
+ o["default"] = v;
35
+ });
36
+ var __importStar = (this && this.__importStar) || (function () {
37
+ var ownKeys = function(o) {
38
+ ownKeys = Object.getOwnPropertyNames || function (o) {
39
+ var ar = [];
40
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
41
+ return ar;
42
+ };
43
+ return ownKeys(o);
44
+ };
45
+ return function (mod) {
46
+ if (mod && mod.__esModule) return mod;
47
+ var result = {};
48
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
49
+ __setModuleDefault(result, mod);
50
+ return result;
51
+ };
52
+ })();
53
+ Object.defineProperty(exports, "__esModule", { value: true });
54
+ exports.runAlgebraEngine = runAlgebraEngine;
55
+ const fs = __importStar(require("fs"));
56
+ const path = __importStar(require("path"));
57
+ // ══════════════════════════════════════════════
58
+ // L1: PARSER — 将原始谓词解析为结构化表达式
59
+ // ══════════════════════════════════════════════
60
+ function parseInvariant(raw) {
61
+ const pred = raw.predicate || "";
62
+ const desc = raw.description || "";
63
+ // Parse "Production ⇒ Paid" pattern
64
+ const impliesMatch = pred.match(/(\w+)\s*⇒\s*(\w+)/);
65
+ // Parse "¬(A → B)" pattern
66
+ const notImpliesMatch = pred.match(/¬\((\w+)\s*→\s*(\w+)\)/);
67
+ // Parse "¬∃ next_state" pattern (terminal)
68
+ const terminalMatch = pred.includes("¬∃ next_state");
69
+ // Parse "at most one" / "unique" pattern
70
+ const uniqueMatch = pred.includes("|payments") || pred.includes("≤ 1");
71
+ let atom = "";
72
+ let requires = null;
73
+ let isTerminal = false;
74
+ let isUnique = false;
75
+ if (impliesMatch) {
76
+ atom = impliesMatch[1].toLowerCase();
77
+ if (impliesMatch[2] !== atom) { // Skip self-referential
78
+ requires = impliesMatch[2].toLowerCase();
79
+ }
80
+ }
81
+ else if (notImpliesMatch) {
82
+ atom = notImpliesMatch[1].toLowerCase();
83
+ requires = notImpliesMatch[2].toLowerCase();
84
+ }
85
+ if (terminalMatch) {
86
+ isTerminal = true;
87
+ // Extract atom: "shipped ⇒ ¬∃ next_state" → atom = "shipped"
88
+ const termAtom = pred.match(/(\w+)\s*⇒\s*¬/);
89
+ if (termAtom)
90
+ atom = termAtom[1].toLowerCase();
91
+ }
92
+ if (uniqueMatch) {
93
+ isUnique = true;
94
+ }
95
+ return {
96
+ id: raw.id || "",
97
+ description: desc,
98
+ rawPredicate: pred,
99
+ source: raw.sources?.[0] || "unknown",
100
+ confidence: raw.confidence || 50,
101
+ domain: raw.domain || "",
102
+ atom,
103
+ requires,
104
+ isTerminal,
105
+ isUnique,
106
+ };
107
+ }
108
+ // ══════════════════════════════════════════════
109
+ // L2: CLOSURE — 推导传递性
110
+ // ══════════════════════════════════════════════
111
+ /**
112
+ * Given a set of implications A⇒B, B⇒C, deduce A⇒C.
113
+ * This is transitive closure of the implication graph.
114
+ *
115
+ * Also derive:
116
+ * - If A requires B and B requires C, then A requires C (transitivity)
117
+ * - If A is terminal and B requires A, then B is also terminal (terminal propagation)
118
+ * - If A is unique and B requires A, then B is also de-facto unique
119
+ */
120
+ function computeClosure(proto) {
121
+ const deduced = [];
122
+ const graph = proto.impliesGraph;
123
+ let idCounter = 9000;
124
+ // ── Transitivity: A⇒B ∧ B⇒C ⊢ A⇒C ──
125
+ for (const [a, depsOfA] of graph) {
126
+ for (const b of depsOfA) {
127
+ const depsOfB = graph.get(b);
128
+ if (depsOfB) {
129
+ for (const c of depsOfB) {
130
+ // A ⇒ B and B ⇒ C, so A ⇒ C
131
+ if (!depsOfA.includes(c) && a !== c) {
132
+ const desc = `${a} → ${b} 且 ${b} → ${c},因此 ${a} ⇒ ${c}`;
133
+ const existing = proto.invariants.find(i => i.atom === a && i.requires === c);
134
+ const existingDeduced = deduced.find(i => i.atom === a && i.requires === c);
135
+ if (!existing && !existingDeduced) {
136
+ deduced.push({
137
+ id: `DED-${idCounter++}`,
138
+ description: desc,
139
+ rawPredicate: `${a} ⇒ ${c}`,
140
+ source: `closure: ${a}⇒${b} + ${b}⇒${c}`,
141
+ confidence: 70,
142
+ domain: proto.domain,
143
+ atom: a,
144
+ requires: c,
145
+ isTerminal: false,
146
+ isUnique: false,
147
+ });
148
+ }
149
+ }
150
+ }
151
+ }
152
+ }
153
+ }
154
+ // ── Terminal Propagation: A is terminal ∧ B ⇒ A ⊢ B is also on terminal path ──
155
+ const terminalAtoms = new Set(proto.invariants.filter(i => i.isTerminal).map(i => i.atom));
156
+ for (const [a, depsOfA] of graph) {
157
+ for (const b of depsOfA) {
158
+ if (terminalAtoms.has(b) && !terminalAtoms.has(a)) {
159
+ const existing = deduced.find(i => i.atom === a && i.isTerminal);
160
+ if (!existing) {
161
+ deduced.push({
162
+ id: `DED-${idCounter++}`,
163
+ description: `${a} ⇒ ${b} 且 ${b} 是终态,因此 ${a} 的路径必然通向终态`,
164
+ rawPredicate: `${a} ⇒ TerminalPath`,
165
+ source: `closure: ${a}⇒${b} + terminal(${b})`,
166
+ confidence: 60,
167
+ domain: proto.domain,
168
+ atom: a,
169
+ requires: null,
170
+ isTerminal: true,
171
+ isUnique: false,
172
+ });
173
+ }
174
+ }
175
+ }
176
+ }
177
+ return deduced;
178
+ }
179
+ // ══════════════════════════════════════════════
180
+ // L3: COMPOSITION — 合并两个 Protocol
181
+ // ══════════════════════════════════════════════
182
+ /**
183
+ * Compose two protocols into one.
184
+ * If Protocol A covers "Order" and Protocol B covers "Payment",
185
+ * the composed protocol covers "Order + Payment" and preserves
186
+ * the invariants of both.
187
+ *
188
+ * Cross-domain invariants are discovered when:
189
+ * - A state name appears in both protocols (shared atom)
190
+ * - An invariant in A's closure implies a constraint on B's domain
191
+ */
192
+ function composeProtocols(a, b) {
193
+ const sharedAtoms = [...a.atoms].filter(atom => b.atoms.has(atom));
194
+ // Cross-domain invariants: if both protocols share a state atom,
195
+ // the invariants from both apply to the composition
196
+ const crossInvariants = [];
197
+ let idCounter = 9500;
198
+ for (const shared of sharedAtoms) {
199
+ const invA = a.invariants.filter(i => i.atom === shared);
200
+ const invB = b.invariants.filter(i => i.atom === shared);
201
+ for (const ia of invA) {
202
+ for (const ib of invB) {
203
+ if (ia.requires && ib.requires && ia.requires !== ib.requires) {
204
+ crossInvariants.push({
205
+ id: `CROSS-${idCounter++}`,
206
+ description: `在 ${a.domain} 和 ${b.domain} 的组合中,${shared} 同时要求 ${ia.requires}(来自 ${a.domain})和 ${ib.requires}(来自 ${b.domain})`,
207
+ rawPredicate: `${shared} ⇒ (${ia.requires} ∧ ${ib.requires})`,
208
+ source: `composition: ${a.domain} + ${b.domain} on ${shared}`,
209
+ confidence: Math.min(ia.confidence, ib.confidence) - 10,
210
+ domain: `${a.domain}+${b.domain}`,
211
+ atom: shared,
212
+ requires: null, // Composite: requires both
213
+ isTerminal: ia.isTerminal || ib.isTerminal,
214
+ isUnique: ia.isUnique || ib.isUnique,
215
+ });
216
+ }
217
+ }
218
+ }
219
+ }
220
+ // Merge implies graphs
221
+ const mergedGraph = new Map();
222
+ for (const [k, v] of a.impliesGraph) {
223
+ mergedGraph.set(k, [...(mergedGraph.get(k) || []), ...v]);
224
+ }
225
+ for (const [k, v] of b.impliesGraph) {
226
+ mergedGraph.set(k, [...(mergedGraph.get(k) || []), ...v]);
227
+ }
228
+ return {
229
+ name: `${a.name} + ${b.name}`,
230
+ domain: `${a.domain}+${b.domain}`,
231
+ invariants: [...a.invariants, ...b.invariants, ...crossInvariants],
232
+ atoms: new Set([...a.atoms, ...b.atoms]),
233
+ impliesGraph: mergedGraph,
234
+ closure: [],
235
+ };
236
+ }
237
+ // ══════════════════════════════════════════════
238
+ // L4: FUNCTOR — 跨实体一致性映射
239
+ // ══════════════════════════════════════════════
240
+ /**
241
+ * A functor maps states from one entity to another.
242
+ * If Order.paid maps to Inventory.reserved, then:
243
+ * ∀ transition in Order: ∃ corresponding transition in Inventory
244
+ *
245
+ * Functor preservation check:
246
+ * For each invariant A⇒B in the source protocol,
247
+ * check that F(A)⇒F(B) holds in the target protocol.
248
+ * If not, the functor is NOT preserved → governance violation.
249
+ */
250
+ function checkFunctorPreservation(source, target, mapping) {
251
+ const violations = [];
252
+ const deduced = [];
253
+ for (const inv of source.invariants) {
254
+ if (!inv.requires || inv.isTerminal)
255
+ continue;
256
+ // Find the mapping for this invariant's atoms
257
+ const mapFrom = mapping.find(m => m.fromEntity === source.domain &&
258
+ m.fromState === inv.atom);
259
+ const mapTo = mapping.find(m => m.fromEntity === source.domain &&
260
+ m.fromState === inv.requires);
261
+ if (!mapFrom || !mapTo)
262
+ continue;
263
+ // Check: does the target protocol have F(A) ⇒ F(B)?
264
+ const targetInv = target.invariants.find(i => i.atom === mapFrom.toState &&
265
+ i.requires === mapTo.toState);
266
+ const targetDeduced = target.closure.find(i => i.atom === mapFrom.toState &&
267
+ i.requires === mapTo.toState);
268
+ if (targetInv || targetDeduced) {
269
+ // Functor preserved!
270
+ deduced.push(`${source.domain}.${inv.atom} ⇒ ${source.domain}.${inv.requires} ` +
271
+ `→ ${target.domain}.${mapFrom.toState} ⇒ ${target.domain}.${mapTo.toState} ✓`);
272
+ }
273
+ else {
274
+ // Functor NOT preserved — possible governance gap
275
+ violations.push(`${source.domain}.${inv.atom} ⇒ ${source.domain}.${inv.requires} ` +
276
+ `has no corresponding mapping in ${target.domain}: ` +
277
+ `${mapFrom.toState} ⇒ ${mapTo.toState} is MISSING`);
278
+ }
279
+ }
280
+ return {
281
+ isValid: violations.length === 0,
282
+ violatedInvariants: violations,
283
+ deducedInvariants: deduced,
284
+ message: violations.length === 0
285
+ ? `Functor ${source.domain} → ${target.domain} is preserved (${deduced.length} mappings verified)`
286
+ : `Functor NOT preserved: ${violations.length} missing cross-entity constraints`,
287
+ };
288
+ }
289
+ // ══════════════════════════════════════════════
290
+ // L5: THEOREM GENERATION
291
+ // ══════════════════════════════════════════════
292
+ /**
293
+ * From a protocol system, generate theorems.
294
+ * A theorem is a statement that MUST hold for any AI-generated code
295
+ * that satisfies the discovered protocols.
296
+ *
297
+ * Theorem forms:
298
+ * 1. "Any valid order must pass through payment before production"
299
+ * 2. "No valid order can skip from created directly to shipped"
300
+ * 3. "Every payment callback implies a ledger write"
301
+ */
302
+ function generateTheorems(protocols) {
303
+ const theorems = [];
304
+ for (const proto of protocols) {
305
+ // Theorem 1: Path existence
306
+ // If there's a chain A→B→C in the impliesGraph, then no valid path skips B
307
+ for (const [a, depsOfA] of proto.impliesGraph) {
308
+ for (const b of depsOfA) {
309
+ const depsOfB = proto.impliesGraph.get(b);
310
+ if (depsOfB) {
311
+ for (const c of depsOfB) {
312
+ if (!depsOfA.includes(c) && a !== c) {
313
+ theorems.push(`Theorem (${proto.domain}): 任何有效的 ${a} → ${c} 路径必须经过 ${b}。` +
314
+ `禁止直接从 ${a} 跳转到 ${c}。`);
315
+ }
316
+ }
317
+ }
318
+ }
319
+ }
320
+ // Theorem 2: Terminal irreversibility
321
+ const terminals = proto.invariants.filter(i => i.isTerminal);
322
+ for (const t of terminals) {
323
+ theorems.push(`Theorem (${proto.domain}): 一旦进入 ${t.atom} 状态,系统不可回退。` +
324
+ `所有前序状态均已完成。`);
325
+ }
326
+ }
327
+ // Remove duplicates
328
+ return [...new Set(theorems)];
329
+ }
330
+ function runAlgebraEngine(projectPath) {
331
+ console.log("🔬 Progmune Invariant Algebra Engine — V4");
332
+ console.log(" Project:", projectPath);
333
+ // Load protocols from V3.4
334
+ const protoPath = path.join(projectPath, ".progmune_protocols.json");
335
+ if (!fs.existsSync(protoPath)) {
336
+ console.log(" No protocols found. Run V3.4 first.");
337
+ return { timestamp: new Date().toISOString(), protocols: [], closureResults: [], compositionResult: null, functorResult: null, theorems: [] };
338
+ }
339
+ const v34 = JSON.parse(fs.readFileSync(protoPath, "utf-8"));
340
+ const rawProtocols = v34.protocols || [];
341
+ // ── Step 1: Parse all invariants ──
342
+ console.log("\nL1 · Parsing invariants...");
343
+ const protocols = [];
344
+ for (const rp of rawProtocols) {
345
+ const invariants = (rp.invariants || []).map(parseInvariant);
346
+ const atoms = new Set();
347
+ const impliesGraph = new Map();
348
+ for (const inv of invariants) {
349
+ if (inv.atom)
350
+ atoms.add(inv.atom);
351
+ if (inv.requires) {
352
+ atoms.add(inv.requires);
353
+ if (!impliesGraph.has(inv.atom))
354
+ impliesGraph.set(inv.atom, []);
355
+ if (!impliesGraph.get(inv.atom).includes(inv.requires)) {
356
+ impliesGraph.get(inv.atom).push(inv.requires);
357
+ }
358
+ }
359
+ }
360
+ protocols.push({
361
+ name: rp.name || rp.domain,
362
+ domain: rp.domain || "unknown",
363
+ invariants,
364
+ atoms,
365
+ impliesGraph,
366
+ closure: [],
367
+ });
368
+ }
369
+ // ── Step 2: Compute closure for each protocol ──
370
+ console.log("\nL2 · Computing closure...");
371
+ const closureResults = [];
372
+ for (const proto of protocols) {
373
+ const deduced = computeClosure(proto);
374
+ proto.closure = deduced;
375
+ closureResults.push({ domain: proto.domain, deduced: deduced.length });
376
+ if (deduced.length > 0) {
377
+ console.log(` ${proto.domain}: ${deduced.length} new invariants deduced`);
378
+ for (const d of deduced.slice(0, 3)) {
379
+ console.log(` ⊢ ${d.description}`);
380
+ }
381
+ }
382
+ }
383
+ // ── Step 3: Composition (if 2+ protocols exist) ──
384
+ console.log("\nL3 · Composition...");
385
+ let compositionResult = null;
386
+ if (protocols.length >= 2) {
387
+ // Find two protocols with overlapping atoms — those are composable
388
+ let bestA = protocols[0], bestB = protocols[1], bestOverlap = 0;
389
+ for (let i = 0; i < protocols.length; i++) {
390
+ for (let j = i + 1; j < protocols.length; j++) {
391
+ const overlap = [...protocols[i].atoms].filter(a => protocols[j].atoms.has(a)).length;
392
+ if (overlap > bestOverlap) {
393
+ bestOverlap = overlap;
394
+ bestA = protocols[i];
395
+ bestB = protocols[j];
396
+ }
397
+ }
398
+ }
399
+ if (bestOverlap > 0) {
400
+ compositionResult = composeProtocols(bestA, bestB);
401
+ // Compute closure on the composition
402
+ compositionResult.closure = computeClosure(compositionResult);
403
+ console.log(` Composed ${bestA.domain} + ${bestB.domain}: ${bestOverlap} shared atoms, ${compositionResult.invariants.length} total invariants, ${compositionResult.closure.length} new deductions`);
404
+ }
405
+ else {
406
+ console.log(" No overlapping atoms — protocols are independent");
407
+ }
408
+ }
409
+ // ── Step 4: Functor check ──
410
+ console.log("\nL4 · Functor preservation...");
411
+ let functorResult = null;
412
+ // Known functor mappings for PrintLab:
413
+ // Order.paid → Inventory.reserved
414
+ // Order.production → Inventory.consumed
415
+ // Order.shipped → Notification.sent
416
+ const mappings = [
417
+ { fromEntity: "order_suppliers", fromState: "paid", toEntity: "inventory", toState: "reserved", description: "付款 → 库存预留" },
418
+ { fromEntity: "order_suppliers", fromState: "production", toEntity: "inventory", toState: "consumed", description: "生产 → 库存消耗" },
419
+ { fromEntity: "order_suppliers", fromState: "shipped", toEntity: "notifications", toState: "sent", description: "发货 → 通知发送" },
420
+ ];
421
+ const orderProto = protocols.find(p => p.domain.includes("order"));
422
+ const inventoryProto = protocols.find(p => p.domain.includes("inventory"));
423
+ if (orderProto) {
424
+ // For now, check against self (since we don't have inventory protocol)
425
+ // In production, this would check against the actual inventory protocol
426
+ const targetProto = inventoryProto || orderProto; // Fallback to self for demo
427
+ const relevantMappings = mappings.filter(m => m.fromEntity.includes(orderProto.domain));
428
+ if (relevantMappings.length > 0) {
429
+ functorResult = checkFunctorPreservation(orderProto, targetProto, relevantMappings);
430
+ console.log(` ${functorResult.message}`);
431
+ if (functorResult.violatedInvariants.length > 0) {
432
+ for (const v of functorResult.violatedInvariants.slice(0, 3)) {
433
+ console.log(` ❌ ${v}`);
434
+ }
435
+ }
436
+ }
437
+ }
438
+ // ── Step 5: Theorem generation ──
439
+ console.log("\nL5 · Theorem generation...");
440
+ const theorems = generateTheorems(protocols);
441
+ console.log(` ${theorems.length} theorems generated`);
442
+ for (const t of theorems.slice(0, 4)) {
443
+ console.log(` 📐 ${t.slice(0, 120)}...`);
444
+ }
445
+ const report = {
446
+ timestamp: new Date().toISOString(),
447
+ protocols,
448
+ closureResults,
449
+ compositionResult,
450
+ functorResult,
451
+ theorems,
452
+ };
453
+ return report;
454
+ }
455
+ // ══════════════════════════════════════════════
456
+ // CLI
457
+ // ══════════════════════════════════════════════
458
+ if (require.main === module) {
459
+ const targetProject = process.argv[2];
460
+ if (!targetProject) {
461
+ console.error("Usage: npx ts-node src/invariant-algebra.ts <project-path>");
462
+ process.exit(1);
463
+ }
464
+ const report = runAlgebraEngine(targetProject);
465
+ const outputPath = path.join(targetProject, ".progmune_algebra.json");
466
+ fs.writeFileSync(outputPath, JSON.stringify(report, null, 2));
467
+ console.log(`\n✅ Algebra report saved to: ${outputPath}`);
468
+ const totalDeduced = report.closureResults.reduce((s, c) => s + c.deduced, 0);
469
+ console.log("\n═══ Invariant Algebra Summary ═══");
470
+ console.log(` Protocols: ${report.protocols.length}`);
471
+ console.log(` Deduced: ${totalDeduced} new invariants via closure`);
472
+ console.log(` Composed: ${report.compositionResult ? 'yes' : 'no'}`);
473
+ console.log(` Functor: ${report.functorResult?.isValid ? 'preserved' : 'violations found'}`);
474
+ console.log(` Theorems: ${report.theorems.length}`);
475
+ console.log();
476
+ }