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,225 @@
1
+ "use strict";
2
+ /**
3
+ * Phase 5: Cross-Function Call Graph Propagator
4
+ *
5
+ * Uses the project's IR (Intermediate Representation) to trace protocol
6
+ * operations across function boundaries. When function A calls function B,
7
+ * B's semantic domains are propagated up to enrich A's analysis window.
8
+ *
9
+ * This addresses the single-function window limitation:
10
+ * Before: analyze only direct calls in function A
11
+ * After: analyze direct calls + propagated domains from callees
12
+ *
13
+ * Architecture:
14
+ * IR (call graph) → Build propagation index → Enrich semantic sequences
15
+ *
16
+ * For C projects without IR, heuristic-based inference is used instead
17
+ * (see TLS_INFERRED_NO_CERT_VERIFY check in protocol-domain-validator.ts).
18
+ */
19
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
20
+ if (k2 === undefined) k2 = k;
21
+ var desc = Object.getOwnPropertyDescriptor(m, k);
22
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
23
+ desc = { enumerable: true, get: function() { return m[k]; } };
24
+ }
25
+ Object.defineProperty(o, k2, desc);
26
+ }) : (function(o, m, k, k2) {
27
+ if (k2 === undefined) k2 = k;
28
+ o[k2] = m[k];
29
+ }));
30
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
31
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
32
+ }) : function(o, v) {
33
+ o["default"] = v;
34
+ });
35
+ var __importStar = (this && this.__importStar) || (function () {
36
+ var ownKeys = function(o) {
37
+ ownKeys = Object.getOwnPropertyNames || function (o) {
38
+ var ar = [];
39
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
40
+ return ar;
41
+ };
42
+ return ownKeys(o);
43
+ };
44
+ return function (mod) {
45
+ if (mod && mod.__esModule) return mod;
46
+ var result = {};
47
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
48
+ __setModuleDefault(result, mod);
49
+ return result;
50
+ };
51
+ })();
52
+ Object.defineProperty(exports, "__esModule", { value: true });
53
+ exports.buildCallGraphFromIR = buildCallGraphFromIR;
54
+ exports.propagateDomains = propagateDomains;
55
+ exports.enrichWithPropagatedDomains = enrichWithPropagatedDomains;
56
+ exports.annotateGraphWithDomains = annotateGraphWithDomains;
57
+ exports.enrichSequence = enrichSequence;
58
+ exports.inferDomainsFromFunctionName = inferDomainsFromFunctionName;
59
+ const path = __importStar(require("path"));
60
+ // ═══════════════════════════════════════════════════════════════
61
+ // IR Loading & Call Graph Construction
62
+ // ═══════════════════════════════════════════════════════════════
63
+ /**
64
+ * Build a call graph index from the project IR.
65
+ * The IR must have function definitions with callee information.
66
+ */
67
+ function buildCallGraphFromIR(irPath) {
68
+ const nodes = new Map();
69
+ let totalEdges = 0;
70
+ try {
71
+ const fs = require("fs");
72
+ const resolvedPath = irPath || path.resolve(process.cwd(), "ir.json");
73
+ if (!fs.existsSync(resolvedPath)) {
74
+ return { nodes, totalFunctions: 0, totalEdges: 0 };
75
+ }
76
+ const raw = JSON.parse(fs.readFileSync(resolvedPath, "utf-8"));
77
+ const functions = Array.isArray(raw) ? raw : raw.functions || [];
78
+ for (const fn of functions) {
79
+ if (!fn.name)
80
+ continue;
81
+ const callees = [];
82
+ // Extract callees from various IR formats
83
+ if (Array.isArray(fn.calls)) {
84
+ callees.push(...fn.calls.map((c) => (typeof c === "string" ? c : c.name || c.function)));
85
+ }
86
+ if (Array.isArray(fn.callees)) {
87
+ callees.push(...fn.callees);
88
+ }
89
+ // Infer callees from call graph edges
90
+ if (Array.isArray(fn.edges)) {
91
+ callees.push(...fn.edges.map((e) => (typeof e === "string" ? e : e.to || e.target)));
92
+ }
93
+ totalEdges += callees.length;
94
+ nodes.set(fn.name, {
95
+ name: fn.name,
96
+ file: fn.file || "",
97
+ callees: [...new Set(callees)], // deduplicate
98
+ domains: [], // populated later by semantic mapper
99
+ });
100
+ }
101
+ }
102
+ catch {
103
+ // IR unavailable — return empty index
104
+ }
105
+ return { nodes, totalFunctions: nodes.size, totalEdges };
106
+ }
107
+ // ═══════════════════════════════════════════════════════════════
108
+ // Domain Propagation
109
+ // ═══════════════════════════════════════════════════════════════
110
+ /**
111
+ * Propagate semantic domains from callees to caller.
112
+ *
113
+ * Given a function name and a call graph index, returns the set of
114
+ * protocol domains from all reachable callees (up to maxDepth).
115
+ *
116
+ * This allows the Trust Engine to see protocol operations that happen
117
+ * inside called functions, not just in the immediate call sequence.
118
+ */
119
+ function propagateDomains(functionName, graph, maxDepth = 3) {
120
+ if (graph.totalFunctions === 0)
121
+ return [];
122
+ const visited = new Set();
123
+ const domains = new Set();
124
+ function dfs(name, depth) {
125
+ if (depth > maxDepth || visited.has(name))
126
+ return;
127
+ visited.add(name);
128
+ const node = graph.nodes.get(name);
129
+ if (!node)
130
+ return;
131
+ // Add this node's domains
132
+ for (const d of node.domains) {
133
+ domains.add(d);
134
+ }
135
+ // Recurse into callees
136
+ for (const callee of node.callees) {
137
+ dfs(callee, depth + 1);
138
+ }
139
+ }
140
+ dfs(functionName, 0);
141
+ return [...domains];
142
+ }
143
+ /**
144
+ * Enrich a semantic step with propagated domains from callees.
145
+ * Returns additional domains that should be considered present
146
+ * in the analysis window.
147
+ */
148
+ function enrichWithPropagatedDomains(step, graph) {
149
+ if (graph.totalFunctions === 0)
150
+ return [];
151
+ return propagateDomains(step.api, graph, 3);
152
+ }
153
+ /**
154
+ * Annotate call graph nodes with semantic domains extracted from
155
+ * their direct call sequences.
156
+ *
157
+ * This should be called after the semantic mapper has processed
158
+ * each function's call sequence.
159
+ */
160
+ function annotateGraphWithDomains(graph, functionDomains) {
161
+ for (const [funcName, domains] of functionDomains) {
162
+ const node = graph.nodes.get(funcName);
163
+ if (node) {
164
+ node.domains = domains;
165
+ }
166
+ }
167
+ }
168
+ /**
169
+ * Enrich a call sequence with cross-function context.
170
+ *
171
+ * For each function call in the sequence, looks up its callees in the
172
+ * call graph and propagates their protocol domains into the analysis window.
173
+ */
174
+ function enrichSequence(steps, graph) {
175
+ const propagatedDomains = new Set();
176
+ for (const step of steps) {
177
+ const calleeDomains = enrichWithPropagatedDomains(step, graph);
178
+ for (const d of calleeDomains) {
179
+ propagatedDomains.add(d);
180
+ }
181
+ }
182
+ return {
183
+ directSteps: steps,
184
+ propagatedDomains: [...propagatedDomains],
185
+ graphAvailable: graph.totalFunctions > 0,
186
+ };
187
+ }
188
+ // ═══════════════════════════════════════════════════════════════
189
+ // Inference for C projects (no IR available)
190
+ // ═══════════════════════════════════════════════════════════════
191
+ /**
192
+ * Heuristic domain propagation for C projects without IR.
193
+ * Uses function name patterns to infer what domains a called function
194
+ * likely contains.
195
+ */
196
+ function inferDomainsFromFunctionName(functionName) {
197
+ const name = functionName.toLowerCase();
198
+ const domains = [];
199
+ // SSL/TLS connection functions internally perform handshake + cert verify
200
+ if (name.includes("ssl_connect") ||
201
+ name.includes("tls_connect") ||
202
+ name.includes("do_connect") ||
203
+ name.includes("ssl_cfilter") ||
204
+ name.includes("ssl_setup")) {
205
+ domains.push("tls_handshake", "tls_cert");
206
+ }
207
+ // SSL context creation functions
208
+ if (name.includes("ssl_ctx_new") ||
209
+ name.includes("ssl_new") ||
210
+ name.includes("ssl_init")) {
211
+ domains.push("tls_handshake");
212
+ }
213
+ // Certificate loading/verification functions
214
+ if (name.includes("ssl_verify") ||
215
+ name.includes("cert_verify") ||
216
+ name.includes("check_cert") ||
217
+ name.includes("x509_verify")) {
218
+ domains.push("tls_cert");
219
+ }
220
+ // Connection functions that internally do TLS
221
+ if (name.includes("_connect") && !name.includes("disconnect")) {
222
+ domains.push("tls_handshake");
223
+ }
224
+ return domains;
225
+ }
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ /**
3
+ * Phase 1: Trust CLI — `progmune trust` command
4
+ *
5
+ * Usage:
6
+ * npx ts-node src/trust/cli.ts <projectPath> [options]
7
+ *
8
+ * Options:
9
+ * --commit <sha> Git commit SHA
10
+ * --branch <name> Git branch name
11
+ * --policy <path> Policy config file (default: .progmune-policy.json)
12
+ * --language <lang> Project language
13
+ * --json Output as JSON
14
+ * --help, -h Show help
15
+ */
16
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ var desc = Object.getOwnPropertyDescriptor(m, k);
19
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
20
+ desc = { enumerable: true, get: function() { return m[k]; } };
21
+ }
22
+ Object.defineProperty(o, k2, desc);
23
+ }) : (function(o, m, k, k2) {
24
+ if (k2 === undefined) k2 = k;
25
+ o[k2] = m[k];
26
+ }));
27
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
28
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
29
+ }) : function(o, v) {
30
+ o["default"] = v;
31
+ });
32
+ var __importStar = (this && this.__importStar) || (function () {
33
+ var ownKeys = function(o) {
34
+ ownKeys = Object.getOwnPropertyNames || function (o) {
35
+ var ar = [];
36
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
37
+ return ar;
38
+ };
39
+ return ownKeys(o);
40
+ };
41
+ return function (mod) {
42
+ if (mod && mod.__esModule) return mod;
43
+ var result = {};
44
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
45
+ __setModuleDefault(result, mod);
46
+ return result;
47
+ };
48
+ })();
49
+ Object.defineProperty(exports, "__esModule", { value: true });
50
+ const path = __importStar(require("path"));
51
+ const engine_1 = require("./engine");
52
+ const terminal_1 = require("./formatters/terminal");
53
+ const json_1 = require("./formatters/json");
54
+ const ci_1 = require("./formatters/ci");
55
+ const args = process.argv.slice(2);
56
+ async function main() {
57
+ // Help flag
58
+ if (args.includes("--help") || args.includes("-h")) {
59
+ console.log(`
60
+ Progmune Trust CLI — AI Trust Decision Engine
61
+
62
+ Usage:
63
+ npx ts-node src/trust/cli.ts <projectPath> [options]
64
+
65
+ Options:
66
+ --commit <sha> Git commit SHA for audit trail
67
+ --branch <name> Git branch name
68
+ --policy <path> Policy config file (default: .progmune-policy.json)
69
+ --language <lang> Project language (typescript, python, etc.)
70
+ --json Output machine-readable JSON
71
+ --help, -h Show this help
72
+
73
+ Example:
74
+ npx ts-node src/trust/cli.ts . --commit HEAD --json
75
+ `);
76
+ process.exit(0);
77
+ }
78
+ // Extract positional arg (project path)
79
+ const positional = args.filter((a) => !a.startsWith("--"));
80
+ const projectPath = positional[0] || process.cwd();
81
+ // Parse flags
82
+ const getFlag = (name) => {
83
+ const idx = args.indexOf(`--${name}`);
84
+ if (idx >= 0 && idx + 1 < args.length) {
85
+ return args[idx + 1];
86
+ }
87
+ return undefined;
88
+ };
89
+ const isJson = args.includes("--json");
90
+ const isCi = args.includes("--ci");
91
+ const commit = getFlag("commit") || "unknown";
92
+ const branch = getFlag("branch");
93
+ const policy = getFlag("policy");
94
+ const language = getFlag("language");
95
+ const ctx = {
96
+ projectPath: path.resolve(projectPath),
97
+ projectName: path.basename(path.resolve(projectPath)),
98
+ commit,
99
+ branch,
100
+ policyName: policy,
101
+ language,
102
+ };
103
+ try {
104
+ const decision = await (0, engine_1.evaluateTrust)(ctx);
105
+ if (isJson) {
106
+ console.log((0, json_1.formatTrustJSON)(decision));
107
+ }
108
+ else if (isCi) {
109
+ console.log((0, ci_1.formatTrustCI)(decision));
110
+ }
111
+ else {
112
+ console.log((0, terminal_1.formatTrustTerminal)(decision));
113
+ }
114
+ // Exit code reflects decision
115
+ process.exit((0, ci_1.ciExitCode)(decision));
116
+ }
117
+ catch (e) {
118
+ console.error(`❌ Trust evaluation failed: ${e.message}`);
119
+ process.exit(3);
120
+ }
121
+ }
122
+ main();
@@ -0,0 +1,283 @@
1
+ "use strict";
2
+ /**
3
+ * Compliance Scoring Engine
4
+ *
5
+ * Upgrades Progmune's verification from binary (violation/clean) to
6
+ * multi-dimensional continuous scores (0-1 per protocol dimension).
7
+ *
8
+ * The insight: SSG rules already encode what "perfect compliance" looks like.
9
+ * We just need to measure distance from that perfect state, dimension by
10
+ * dimension, instead of returning a single pass/fail.
11
+ *
12
+ * This is the first step toward a reward model — proving that continuous
13
+ * compliance scores are actionable for AI code generators.
14
+ *
15
+ * No ML. Pure rule-based scoring using existing PROTOCOLS + SAFEGUARD_RULES.
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.scoreCompliance = scoreCompliance;
19
+ exports.scoreFunction = scoreFunction;
20
+ exports.formatComplianceReport = formatComplianceReport;
21
+ /**
22
+ * Protocol dimensions — mirrors the SSG PROTOCOLS but expressed as
23
+ * scorable dimensions rather than binary checks.
24
+ */
25
+ const DIMENSIONS = [
26
+ {
27
+ id: "auth",
28
+ label: "认证与授权",
29
+ weight: 0.30,
30
+ triggers: [
31
+ /login|register|signin|signup|authenticate|auth|token|session|password|credential/i,
32
+ ],
33
+ requiredSteps: [
34
+ { pattern: /\b(login|signin|authenticate|getSessionUser|requirePermission|verifyToken|validateSession)\b/i, label: "auth_check", description: "身份验证" },
35
+ { pattern: /\b(requirePermission|hasPermission|checkAccess|hasRole|adminCheck|isAuthorized)\b/i, label: "authz_check", description: "权限检查" },
36
+ { pattern: /\b(logout|destroySession|revokeToken|endSession|invalidate)\b/i, label: "auth_cleanup", description: "会话清理" },
37
+ ],
38
+ bonusPatterns: [
39
+ { pattern: /\b(bcrypt|argon2|scrypt|pbkdf2|hashPassword|compare)\b/i, label: "secure_hash", description: "安全哈希" },
40
+ { pattern: /\b(rateLimit|rate_limit|throttle|maxAttempts|loginLimiter)\b/i, label: "rate_limit", description: "速率限制" },
41
+ { pattern: /\b(2fa|twoFactor|mfa|otp|verifyCode|totp)\b/i, label: "mfa", description: "多因素认证" },
42
+ ],
43
+ },
44
+ {
45
+ id: "tls",
46
+ label: "TLS/加密",
47
+ weight: 0.15,
48
+ triggers: [
49
+ /ssl|tls|https|cert|certificate|encrypt|decrypt|createServer/i,
50
+ ],
51
+ requiredSteps: [
52
+ { pattern: /\b(ssl|tls|cert|https|createSecureContext|credentials)\b/i, label: "tls_config", description: "TLS 配置" },
53
+ { pattern: /\b(ssl.*free|ssl.*cleanup|close.*ssl|disconnect)\b/i, label: "tls_cleanup", description: "TLS 清理" },
54
+ ],
55
+ bonusPatterns: [
56
+ { pattern: /\b(helmet|csp|hsts|secure.*header)\b/i, label: "security_headers", description: "安全响应头" },
57
+ ],
58
+ },
59
+ {
60
+ id: "payment",
61
+ label: "支付安全",
62
+ weight: 0.20,
63
+ triggers: [
64
+ /payment|pay|checkout|refund|charge|transaction|order.*create|order.*process/i,
65
+ ],
66
+ requiredSteps: [
67
+ { pattern: /\b(verifyOrder|getOrder|checkOrder|findOrder|orderExists)\b/i, label: "order_check", description: "订单验证" },
68
+ { pattern: /\b(payment.*intent|pay.*create|create.*payment|initiate.*payment)\b/i, label: "pay_init", description: "支付发起" },
69
+ { pattern: /\b(verify.*sign|check.*sign|webhook.*secret|hmac|signature)\b/i, label: "sig_check", description: "签名验证" },
70
+ { pattern: /\b(capture.*payment|confirm.*order|payment.*done|payment.*success)\b/i, label: "pay_complete", description: "支付完成" },
71
+ ],
72
+ bonusPatterns: [
73
+ { pattern: /\b(idempotent|retry|rollback|compensat)\b/i, label: "idempotency", description: "幂等性" },
74
+ ],
75
+ },
76
+ {
77
+ id: "data_integrity",
78
+ label: "数据完整性",
79
+ weight: 0.15,
80
+ triggers: [
81
+ /create|update|delete|insert|modify|save|write|mutate/i,
82
+ ],
83
+ requiredSteps: [
84
+ { pattern: /\b(validate|sanitize|check|verify|schema|zod|yup|joi)\b/i, label: "input_check", description: "输入校验" },
85
+ { pattern: /\b(audit|log.*change|change.*log|track.*change|record.*mutation)\b/i, label: "audit_trail", description: "审计追踪" },
86
+ ],
87
+ bonusPatterns: [
88
+ { pattern: /\b(transaction|rollback|commit)\b/i, label: "transaction", description: "事务保护" },
89
+ { pattern: /\b(parameterize|prepared.*statement|%s|\$1)\b/i, label: "sql_safe", description: "SQL 安全" },
90
+ ],
91
+ },
92
+ {
93
+ id: "resource",
94
+ label: "资源管理",
95
+ weight: 0.10,
96
+ triggers: [
97
+ /file|socket|connection|pool|stream|buffer|handle|upload|download/i,
98
+ ],
99
+ requiredSteps: [
100
+ { pattern: /\b(open|create|init|connect|start)\b/i, label: "resource_init", description: "资源获取" },
101
+ { pattern: /\b(close|free|cleanup|destroy|disconnect|release|end)\b/i, label: "resource_free", description: "资源释放" },
102
+ ],
103
+ bonusPatterns: [
104
+ { pattern: /\b(try.*finally|defer|using|RAII)\b/i, label: "cleanup_guarantee", description: "清理保证" },
105
+ ],
106
+ },
107
+ {
108
+ id: "session",
109
+ label: "会话管理",
110
+ weight: 0.10,
111
+ triggers: [
112
+ /session|token|jwt|cookie|bearer/i,
113
+ ],
114
+ requiredSteps: [
115
+ { pattern: /\b(session.*create|create.*session|session.*init|token.*generate|jwt.*sign)\b/i, label: "sess_create", description: "会话创建" },
116
+ { pattern: /\b(session.*check|session.*valid|validate.*session|verify.*token|token.*check)\b/i, label: "sess_validate", description: "会话验证" },
117
+ { pattern: /\b(session.*destroy|session.*delete|token.*revoke|session.*expire|session.*timeout)\b/i, label: "sess_destroy", description: "会话销毁" },
118
+ ],
119
+ bonusPatterns: [
120
+ { pattern: /\b(httpOnly|secure.*cookie|sameSite|csrf)\b/i, label: "secure_cookie", description: "安全Cookie" },
121
+ ],
122
+ },
123
+ ];
124
+ // ── Scoring Logic ──
125
+ /**
126
+ * Score a function call sequence against all protocol dimensions.
127
+ *
128
+ * @param calls - Array of function call names in order
129
+ * @param functionPurpose - Optional function purpose for context (e.g., "退款处理", "用户注册")
130
+ * @returns ComplianceScore with per-dimension breakdown
131
+ */
132
+ function scoreCompliance(calls, functionPurpose) {
133
+ const dimensions = [];
134
+ const allCallText = calls.join(" ");
135
+ const purposeText = functionPurpose || "";
136
+ for (const dim of DIMENSIONS) {
137
+ // Check if this dimension is relevant
138
+ const isRelevant = dim.triggers.some((t) => t.test(allCallText)) ||
139
+ dim.triggers.some((t) => t.test(purposeText));
140
+ if (!isRelevant && calls.length > 0) {
141
+ // Skip irrelevant dimensions — don't penalize what doesn't apply
142
+ dimensions.push({
143
+ dimension: dim.id,
144
+ score: 1.0,
145
+ maxScore: 1.0,
146
+ strengths: ["N/A — 不适用"],
147
+ gaps: [],
148
+ fixes: [],
149
+ });
150
+ continue;
151
+ }
152
+ // Score required steps: what % are present?
153
+ const requiredResults = dim.requiredSteps.map((step) => ({
154
+ ...step,
155
+ present: step.pattern.test(allCallText),
156
+ }));
157
+ const requiredScore = dim.requiredSteps.length > 0
158
+ ? requiredResults.filter((r) => r.present).length / dim.requiredSteps.length
159
+ : 1.0;
160
+ // Score bonus patterns: each present adds 0.1 to the ceiling
161
+ const bonusHits = dim.bonusPatterns.filter((b) => b.pattern.test(allCallText));
162
+ const bonusBoost = Math.min(bonusHits.length * 0.1, 0.2); // cap at +0.2
163
+ // Calculate strengths and gaps
164
+ const strengths = [
165
+ ...requiredResults.filter((r) => r.present).map((r) => r.description),
166
+ ...bonusHits.map((b) => b.description),
167
+ ];
168
+ const gaps = [
169
+ ...requiredResults.filter((r) => !r.present).map((r) => r.description),
170
+ ];
171
+ // Generate fixes for missing steps
172
+ const fixes = requiredResults
173
+ .filter((r) => !r.present)
174
+ .map((r) => `添加 ${r.label}: ${r.description}`);
175
+ // Final score: required completion + bonus boost, clamped to [0, 1]
176
+ const rawScore = Math.min(requiredScore + bonusBoost, 1.0);
177
+ dimensions.push({
178
+ dimension: dim.id,
179
+ score: Math.round(rawScore * 100) / 100,
180
+ maxScore: 1.0,
181
+ strengths: strengths.length > 0 ? strengths : ["无"],
182
+ gaps,
183
+ fixes,
184
+ });
185
+ }
186
+ // Calculate overall score (weighted average of relevant dimensions)
187
+ const relevantDims = dimensions.filter((d) => d.score < 1.0 || d.strengths[0] !== "N/A — 不适用");
188
+ const weights = DIMENSIONS.map((d) => d.weight);
189
+ const weightsMap = new Map(DIMENSIONS.map((d, i) => [d.id, weights[i] ?? 0]));
190
+ let overall = 0;
191
+ let totalWeight = 0;
192
+ for (const dim of dimensions) {
193
+ const w = weightsMap.get(dim.dimension) || 0.1;
194
+ // Only count relevant dimensions in the weighted average
195
+ if (dim.strengths[0] !== "N/A — 不适用") {
196
+ overall += dim.score * w;
197
+ totalWeight += w;
198
+ }
199
+ }
200
+ overall = totalWeight > 0 ? overall / totalWeight : 1.0;
201
+ overall = Math.round(overall * 100) / 100;
202
+ // Find weakest dimension
203
+ const scoredDims = dimensions.filter((d) => d.strengths[0] !== "N/A — 不适用");
204
+ const weakest = scoredDims.length > 0
205
+ ? scoredDims.reduce((min, d) => (d.score < min.score ? d : min), scoredDims[0])
206
+ : null;
207
+ // Find top fix (from the weakest dimension)
208
+ const topFix = weakest?.fixes[0] || "无需修复";
209
+ // Build suggested sequence: existing present calls + missing calls
210
+ const presentCalls = calls.filter((c) => {
211
+ for (const dim of DIMENSIONS) {
212
+ for (const step of dim.requiredSteps) {
213
+ if (step.pattern.test(c))
214
+ return true;
215
+ }
216
+ }
217
+ return false;
218
+ });
219
+ const missingCalls = weakest?.fixes.map((f) => f.replace("添加 ", "")) || [];
220
+ return {
221
+ overall,
222
+ dimensions,
223
+ weakestDimension: weakest?.dimension || "all_clear",
224
+ topFix,
225
+ suggestedSequence: [
226
+ ...presentCalls,
227
+ ...missingCalls.map((m) => `[需添加] ${m}`),
228
+ ],
229
+ presentCalls,
230
+ missingCalls,
231
+ };
232
+ }
233
+ /**
234
+ * Score a specific function for compliance given its purpose.
235
+ * Convenience wrapper for scoring a single function context.
236
+ */
237
+ function scoreFunction(functionName, calls, purpose) {
238
+ const allCalls = [functionName, ...calls];
239
+ return scoreCompliance(allCalls, purpose);
240
+ }
241
+ /**
242
+ * Format a compliance score as a human-readable report.
243
+ */
244
+ function formatComplianceReport(score) {
245
+ const lines = [
246
+ "═══════════════════════════════════════",
247
+ " Progmune Compliance Score",
248
+ "═══════════════════════════════════════",
249
+ "",
250
+ ` Overall: ${renderScoreBar(score.overall)} ${(score.overall * 100).toFixed(0)}%`,
251
+ ` Weakest: ${score.weakestDimension}`,
252
+ ` Top Fix: ${score.topFix}`,
253
+ "",
254
+ " Dimensions:",
255
+ ];
256
+ for (const dim of score.dimensions) {
257
+ const bar = renderScoreBar(dim.score);
258
+ lines.push(` ${bar} ${dim.dimension.padEnd(16)} ${(dim.score * 100).toFixed(0)}%`);
259
+ if (dim.gaps.length > 0) {
260
+ lines.push(` ⚠️ 缺失: ${dim.gaps.join(", ")}`);
261
+ }
262
+ if (dim.fixes.length > 0) {
263
+ lines.push(` 🔧 ${dim.fixes.join("; ")}`);
264
+ }
265
+ }
266
+ if (score.missingCalls.length > 0) {
267
+ lines.push("");
268
+ lines.push(" 建议添加的调用:");
269
+ for (const c of score.missingCalls) {
270
+ lines.push(` → ${c}`);
271
+ }
272
+ }
273
+ return lines.join("\n");
274
+ }
275
+ function renderScoreBar(score) {
276
+ if (score >= 0.9)
277
+ return "🟢";
278
+ if (score >= 0.7)
279
+ return "🟡";
280
+ if (score >= 0.5)
281
+ return "🟠";
282
+ return "🔴";
283
+ }