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,388 @@
1
+ "use strict";
2
+ /**
3
+ * P7.5: Unified Decision Engine — the "operating system kernel" of Progmune.
4
+ *
5
+ * All decisions in the system — verification, promotion, repair, policy —
6
+ * are driven by ONE engine with ONE consistent model.
7
+ *
8
+ * The three core concepts:
9
+ * 1. Verification Asset — the data (knowledge, rules, benchmarks, protocols)
10
+ * 2. Promotion Pipeline — the lifecycle (evidence → candidate → ... → stable)
11
+ * 3. Decision Engine — the kernel (this file)
12
+ *
13
+ * Everything else is just an Asset Type.
14
+ *
15
+ * Decision model:
16
+ * Input: Asset + Context → Decision { action, confidence, reason, provenance }
17
+ * Output: BLOCK/WARN/ALLOW | promote/demote/hold | fix/retry/rollback | accept/reject
18
+ *
19
+ * Importance is COMPUTED, not configured:
20
+ * Importance = Impact × Universality × Criticality
21
+ */
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.DecisionEngine = void 0;
24
+ exports.computeImportance = computeImportance;
25
+ exports.classifyCodeContext = classifyCodeContext;
26
+ exports.getDecisionEngine = getDecisionEngine;
27
+ // ═══════════════════════════════════════════════════════════════
28
+ // Importance Computation
29
+ // ═══════════════════════════════════════════════════════════════
30
+ /**
31
+ * Impact: how severe are the consequences of getting this wrong?
32
+ *
33
+ * 1.0 = security/critical (TLS Finished, password verify)
34
+ * 0.7 = resource management (file close, memory free)
35
+ * 0.4 = correctness (data validation, type checking)
36
+ * 0.1 = informational (logging, formatting)
37
+ */
38
+ function computeImpact(asset) {
39
+ const domain = asset.domain.toLowerCase();
40
+ const name = asset.name.toLowerCase();
41
+ // Security-critical
42
+ if (domain === "tls" || domain === "ssl" || domain === "auth" ||
43
+ /tls|ssl|auth|encrypt|decrypt|verify|cert|key|token|password/i.test(name)) {
44
+ return 1.0;
45
+ }
46
+ // Resource management
47
+ if (/close|free|destroy|release|cleanup|disconnect|logout/i.test(name)) {
48
+ return 0.7;
49
+ }
50
+ // Correctness
51
+ if (/validate|check|assert|verify|compare|match/i.test(name)) {
52
+ return 0.4;
53
+ }
54
+ // Informational
55
+ return 0.1;
56
+ }
57
+ /**
58
+ * Universality: how broadly does this apply across codebases?
59
+ *
60
+ * 1.0 = universal (memory management, error handling)
61
+ * 0.7 = common (HTTP, file I/O, auth)
62
+ * 0.4 = domain-specific (TLS, SSH, DB protocols)
63
+ * 0.1 = repo-specific (custom internal patterns)
64
+ */
65
+ function computeUniversality(asset) {
66
+ const crossRepo = asset.evidence.crossRepoCount;
67
+ if (crossRepo >= 5)
68
+ return 1.0;
69
+ if (crossRepo >= 3)
70
+ return 0.7;
71
+ if (crossRepo >= 2)
72
+ return 0.4;
73
+ return 0.1;
74
+ }
75
+ /**
76
+ * Criticality: how essential is this to correct program behavior?
77
+ *
78
+ * 1.0 = program fails without this (init, close, free)
79
+ * 0.7 = security/privacy risk (auth, encrypt)
80
+ * 0.4 = correctness risk (validate, check)
81
+ * 0.1 = quality risk (style, format)
82
+ */
83
+ function computeCriticality(asset) {
84
+ const name = asset.name.toLowerCase();
85
+ // Program fails without this
86
+ if (/^(init_|create_|open_|close_|free_|destroy_)/i.test(name) ||
87
+ /_(init|cleanup|setup|teardown)$/i.test(name)) {
88
+ return 1.0;
89
+ }
90
+ // Security risk
91
+ if (/auth|encrypt|decrypt|token|password|verify|ssl|tls/i.test(name)) {
92
+ return 0.7;
93
+ }
94
+ // Correctness risk
95
+ if (/validate|check|assert|enforce|policy/i.test(name)) {
96
+ return 0.4;
97
+ }
98
+ return 0.1;
99
+ }
100
+ /**
101
+ * Compute Importance from Impact × Universality × Criticality.
102
+ * This is NOT configured — it's derived from evidence and semantics.
103
+ */
104
+ function computeImportance(asset) {
105
+ const impact = computeImpact(asset);
106
+ const universality = computeUniversality(asset);
107
+ const criticality = computeCriticality(asset);
108
+ // Weighted product: Impact is most important, Universality is secondary
109
+ return Math.round((impact * 0.4 + universality * 0.25 + criticality * 0.35) * 100);
110
+ }
111
+ /**
112
+ * Sprint 14: Classify code context from function names and patterns.
113
+ *
114
+ * Production code gets strict thresholds.
115
+ * Test/example/benchmark code gets relaxed thresholds.
116
+ * Enterprises only care about Production FP.
117
+ */
118
+ function classifyCodeContext(functions) {
119
+ const all = functions.join(" ").toLowerCase();
120
+ // Test patterns
121
+ if (/test|_test|testing|mock|stub|fake|assert|expect/i.test(all))
122
+ return "test";
123
+ // Example patterns
124
+ if (/example|demo|sample|tutorial|showcase/i.test(all))
125
+ return "example";
126
+ // Benchmark patterns
127
+ if (/bench|benchmark|perf|performance|stress|soak|load/i.test(all))
128
+ return "benchmark";
129
+ // Init/setup patterns
130
+ if (/^(init_|setup|config|bootstrap|startup)/i.test(all))
131
+ return "init";
132
+ return "production";
133
+ }
134
+ /** Sprint 14: Per-context confidence thresholds. */
135
+ const CONTEXT_THRESHOLDS = {
136
+ production: { block: 0.80, warn: 0.60, allow: 0.40 },
137
+ test: { block: 0.95, warn: 0.85, allow: 0.70 },
138
+ example: { block: 0.95, warn: 0.85, allow: 0.70 },
139
+ benchmark: { block: 0.90, warn: 0.80, allow: 0.60 },
140
+ init: { block: 0.85, warn: 0.70, allow: 0.50 },
141
+ unknown: { block: 0.80, warn: 0.60, allow: 0.40 },
142
+ };
143
+ class DecisionEngine {
144
+ constructor() {
145
+ this.history = [];
146
+ }
147
+ /**
148
+ * Make a verification decision: should we alert?
149
+ */
150
+ decideVerification(asset, context = {}) {
151
+ const importance = computeImportance(asset);
152
+ const fpRate = (context.recentFPs || 0) / Math.max(1, (context.recentFPs || 0) + (context.recentTPs || 0));
153
+ // Confidence = asset confidence × (1 - FP rate) × environment factor
154
+ let envFactor = 1.0;
155
+ if (context.environment === "production")
156
+ envFactor = 0.7; // More conservative in prod
157
+ if (context.environment === "test")
158
+ envFactor = 1.0;
159
+ const confidence = asset.confidence * (1 - fpRate) * envFactor;
160
+ // Sprint 14: Context-aware thresholds
161
+ const ctx = context.codeContext || "production";
162
+ const thresholds = CONTEXT_THRESHOLDS[ctx];
163
+ let action;
164
+ if (confidence >= thresholds.block)
165
+ action = "BLOCK";
166
+ else if (confidence >= thresholds.warn)
167
+ action = "WARN";
168
+ else if (confidence >= thresholds.allow)
169
+ action = "ALLOW";
170
+ else
171
+ action = "SUPPRESS";
172
+ // Importance override: high-importance assets alert even at lower confidence
173
+ if (importance >= 70 && action === "ALLOW")
174
+ action = "WARN";
175
+ if (importance >= 85 && action === "WARN")
176
+ action = "BLOCK";
177
+ return this.recordDecision({
178
+ kind: "verification",
179
+ action,
180
+ confidence,
181
+ reason: action === "BLOCK"
182
+ ? `High-confidence violation (${(confidence * 100).toFixed(0)}%, importance ${importance})`
183
+ : action === "SUPPRESS"
184
+ ? `Low confidence (${(confidence * 100).toFixed(0)}%), ${context.recentFPs || 0} recent FPs`
185
+ : `Moderate confidence (${(confidence * 100).toFixed(0)}%) — ${action}`,
186
+ provenance: {
187
+ assets: [asset.id],
188
+ evidence: [
189
+ ...asset.evidence.rfcRefs.map(r => `RFC ${r}`),
190
+ ...asset.evidence.repos,
191
+ `importance=${importance}`,
192
+ ],
193
+ chain: [],
194
+ decider: "system",
195
+ timestamp: new Date().toISOString(),
196
+ },
197
+ recommendations: action === "SUPPRESS"
198
+ ? ["Add RFC reference to increase confidence", "Validate across more repos"]
199
+ : action === "WARN"
200
+ ? ["Review manually before blocking", "Check deployment observations"]
201
+ : [],
202
+ });
203
+ }
204
+ /**
205
+ * Make a promotion decision: should this asset move to the next stage?
206
+ */
207
+ decidePromotion(asset, context = {}) {
208
+ const importance = computeImportance(asset);
209
+ const hasDeployment = (context.deploymentObservations || 0) > 0;
210
+ // Promotion confidence depends on:
211
+ // 1. Asset evidence strength (cross-repo, RFC, sequence count)
212
+ // 2. Importance (high-importance assets are promoted faster)
213
+ // 3. Deployment observations (real-world validation)
214
+ let confidence = asset.confidence;
215
+ // Deployment bonus: real-world observation significantly boosts confidence
216
+ if (hasDeployment)
217
+ confidence = Math.min(1.0, confidence + 0.15);
218
+ // Importance bonus: high-importance assets get promotion priority
219
+ if (importance >= 70)
220
+ confidence = Math.min(1.0, confidence + 0.05);
221
+ let action;
222
+ if (confidence >= 0.80 && hasDeployment)
223
+ action = "promote";
224
+ else if (confidence >= 0.60)
225
+ action = "promote";
226
+ else if (confidence >= 0.30)
227
+ action = "hold";
228
+ else
229
+ action = "demote";
230
+ return this.recordDecision({
231
+ kind: "promotion",
232
+ action,
233
+ confidence,
234
+ reason: action === "promote"
235
+ ? `Ready for promotion: ${asset.evidence.crossRepoCount} repos, importance ${importance}${hasDeployment ? ", deployment-validated" : ""}`
236
+ : action === "hold"
237
+ ? `Holding at ${asset.stage}: need more evidence${!hasDeployment ? " (no deployment data)" : ""}`
238
+ : `Demoting: confidence ${(confidence * 100).toFixed(0)}% below threshold`,
239
+ provenance: {
240
+ assets: [asset.id],
241
+ evidence: [
242
+ `${asset.evidence.crossRepoCount} repos`,
243
+ `${asset.evidence.sequenceCount} sequences`,
244
+ ...asset.evidence.rfcRefs.map(r => `RFC ${r}`),
245
+ hasDeployment ? `${context.deploymentObservations} deployments` : "no deployment data",
246
+ ],
247
+ chain: asset.history.map(h => `${h.from}→${h.to}: ${h.reason}`),
248
+ decider: "system",
249
+ timestamp: new Date().toISOString(),
250
+ },
251
+ recommendations: !hasDeployment
252
+ ? ["Deploy to staging for real-world validation", "Collect production observations"]
253
+ : action === "hold"
254
+ ? ["Add cross-repo evidence", "Seek human review"]
255
+ : [],
256
+ });
257
+ }
258
+ /**
259
+ * Make a repair decision: should we fix this, retry, or rollback?
260
+ */
261
+ decideRepair(asset, context = {}) {
262
+ const importance = computeImportance(asset);
263
+ // Repair is only worth attempting for high-importance assets
264
+ // AND when confidence is high enough
265
+ let action;
266
+ let confidence = asset.confidence;
267
+ if (importance >= 70 && confidence >= 0.60) {
268
+ action = "fix";
269
+ }
270
+ else if (importance >= 50 && confidence >= 0.40) {
271
+ action = "retry";
272
+ }
273
+ else if (context.environment === "production") {
274
+ action = "rollback";
275
+ }
276
+ else {
277
+ action = "report";
278
+ }
279
+ if (context.humanOverride) {
280
+ action = context.humanOverride;
281
+ }
282
+ return this.recordDecision({
283
+ kind: "repair",
284
+ action,
285
+ confidence,
286
+ reason: action === "fix"
287
+ ? `Auto-repair recommended: importance ${importance}, confidence ${(confidence * 100).toFixed(0)}%`
288
+ : action === "rollback"
289
+ ? `Rollback: too risky for production (importance ${importance}, confidence ${(confidence * 100).toFixed(0)}%)`
290
+ : `Report-only: insufficient confidence for auto-repair`,
291
+ provenance: {
292
+ assets: [asset.id],
293
+ evidence: [`importance=${importance}`, `confidence=${(confidence * 100).toFixed(0)}%`],
294
+ chain: [],
295
+ decider: context.humanOverride ? "human" : "system",
296
+ timestamp: new Date().toISOString(),
297
+ },
298
+ recommendations: action === "fix"
299
+ ? ["Apply fix and re-verify", "Record outcome for learning"]
300
+ : action === "report"
301
+ ? ["Flag for human review", "Collect more evidence before auto-repair"]
302
+ : [],
303
+ });
304
+ }
305
+ /**
306
+ * Make a deployment decision: is this asset ready for production?
307
+ */
308
+ decideDeployment(asset, context = {}) {
309
+ const importance = computeImportance(asset);
310
+ // Deployment requires:
311
+ // 1. Asset at "validated" stage or higher
312
+ // 2. Deployment observations (staging OK)
313
+ // 3. Acceptable FP rate (< 30% in staging)
314
+ const stageOk = ["validated", "stable"].includes(asset.stage);
315
+ const hasDeployment = (context.deploymentObservations || 0) > 0;
316
+ const fpRate = (context.recentFPs || 0) / Math.max(1, (context.recentFPs || 0) + (context.recentTPs || 0));
317
+ const fpOk = fpRate < 0.30;
318
+ let action;
319
+ let confidence = asset.confidence;
320
+ if (stageOk && hasDeployment && fpOk) {
321
+ action = "deploy";
322
+ confidence = Math.min(1.0, confidence + 0.1);
323
+ }
324
+ else if (stageOk && !hasDeployment) {
325
+ action = "hold";
326
+ }
327
+ else if (!fpOk) {
328
+ action = "rollback";
329
+ }
330
+ else {
331
+ action = "hold";
332
+ }
333
+ return this.recordDecision({
334
+ kind: "deployment",
335
+ action,
336
+ confidence,
337
+ reason: action === "deploy"
338
+ ? `Production-ready: stage=${asset.stage}, ${context.deploymentObservations} deployments, FP rate ${(fpRate * 100).toFixed(0)}%`
339
+ : action === "hold"
340
+ ? !hasDeployment ? "Needs staging deployment first" : "Not ready for production"
341
+ : `Rollback: FP rate ${(fpRate * 100).toFixed(0)}% exceeds 30% threshold`,
342
+ provenance: {
343
+ assets: [asset.id],
344
+ evidence: [
345
+ `stage=${asset.stage}`,
346
+ `deployments=${context.deploymentObservations || 0}`,
347
+ `FP rate=${(fpRate * 100).toFixed(0)}%`,
348
+ ],
349
+ chain: asset.history.map(h => `${h.from}→${h.to}`),
350
+ decider: "system",
351
+ timestamp: new Date().toISOString(),
352
+ },
353
+ recommendations: !hasDeployment
354
+ ? ["Deploy to staging environment", "Collect FP/TP metrics"]
355
+ : !fpOk
356
+ ? ["Investigate FP sources", "Suppress noisy rules before re-deploying"]
357
+ : [],
358
+ });
359
+ }
360
+ /**
361
+ * Get full decision history for provenance tracking.
362
+ */
363
+ getHistory() {
364
+ return [...this.history];
365
+ }
366
+ /**
367
+ * Get decision history for a specific asset.
368
+ */
369
+ getAssetDecisions(assetId) {
370
+ return this.history.filter(d => d.provenance.assets.includes(assetId));
371
+ }
372
+ recordDecision(partial) {
373
+ const id = `DEC-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`;
374
+ const decision = { id, ...partial };
375
+ this.history.push(decision);
376
+ return decision;
377
+ }
378
+ }
379
+ exports.DecisionEngine = DecisionEngine;
380
+ // ═══════════════════════════════════════════════════════════════
381
+ // Singleton
382
+ // ═══════════════════════════════════════════════════════════════
383
+ let _decisionEngine = null;
384
+ function getDecisionEngine() {
385
+ if (!_decisionEngine)
386
+ _decisionEngine = new DecisionEngine();
387
+ return _decisionEngine;
388
+ }
@@ -0,0 +1,250 @@
1
+ "use strict";
2
+ /**
3
+ * Auto-derive capability metadata (@requires, @produces, @purpose, @tags)
4
+ * from existing code patterns:
5
+ * 1. @protocol pre_states → @requires, post_states → @produces
6
+ * 2. Function name → @purpose (humanized)
7
+ * 3. File path → @tags
8
+ * 4. Import chain → @requires (dependency)
9
+ *
10
+ * This bridges the gap from 30% → 80% metadata coverage without
11
+ * requiring manual annotation of every function.
12
+ */
13
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ var desc = Object.getOwnPropertyDescriptor(m, k);
16
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
17
+ desc = { enumerable: true, get: function() { return m[k]; } };
18
+ }
19
+ Object.defineProperty(o, k2, desc);
20
+ }) : (function(o, m, k, k2) {
21
+ if (k2 === undefined) k2 = k;
22
+ o[k2] = m[k];
23
+ }));
24
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
25
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
26
+ }) : function(o, v) {
27
+ o["default"] = v;
28
+ });
29
+ var __importStar = (this && this.__importStar) || (function () {
30
+ var ownKeys = function(o) {
31
+ ownKeys = Object.getOwnPropertyNames || function (o) {
32
+ var ar = [];
33
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
34
+ return ar;
35
+ };
36
+ return ownKeys(o);
37
+ };
38
+ return function (mod) {
39
+ if (mod && mod.__esModule) return mod;
40
+ var result = {};
41
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
42
+ __setModuleDefault(result, mod);
43
+ return result;
44
+ };
45
+ })();
46
+ Object.defineProperty(exports, "__esModule", { value: true });
47
+ exports.deriveMetadata = deriveMetadata;
48
+ exports.applyDerivedMetadata = applyDerivedMetadata;
49
+ const fs = __importStar(require("fs"));
50
+ const path = __importStar(require("path"));
51
+ /**
52
+ * Humanize a camelCase/PascalCase function name into a readable purpose.
53
+ */
54
+ function humanize(name) {
55
+ return name
56
+ .replace(/([A-Z])/g, " $1")
57
+ .replace(/_/g, " ")
58
+ .replace(/\s+/g, " ")
59
+ .trim()
60
+ .toLowerCase();
61
+ }
62
+ /**
63
+ * Infer tags from file path.
64
+ */
65
+ function inferTags(filePath) {
66
+ const dir = path.dirname(filePath).replace(/^src\//, "");
67
+ const parts = dir.split("/").filter(Boolean);
68
+ return parts.length > 0 ? parts : ["core"];
69
+ }
70
+ /**
71
+ * Parse @protocol annotations from raw source text.
72
+ */
73
+ function parseProtocolAnnotation(source) {
74
+ const match = source.match(/@protocol\s+.*?pre_states\s*=\s*\[(.*?)\]\s*.*?post_states\s*=\s*\[(.*?)\]/s);
75
+ if (!match)
76
+ return null;
77
+ const pre = match[1].split(",").map(s => s.replace(/["'\s]/g, "")).filter(Boolean);
78
+ const post = match[2].split(",").map(s => s.replace(/["'\s]/g, "")).filter(Boolean);
79
+ return { pre, post };
80
+ }
81
+ /**
82
+ * Scan source files and auto-derive capability metadata for functions that lack it.
83
+ */
84
+ function deriveMetadata(srcDir = "src") {
85
+ const results = [];
86
+ function walk(dir) {
87
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
88
+ const fullPath = path.join(dir, entry.name);
89
+ if (entry.isDirectory()) {
90
+ if (entry.name === "node_modules" || entry.name === "dist" || entry.name.startsWith("."))
91
+ continue;
92
+ walk(fullPath);
93
+ }
94
+ else if (entry.name.endsWith(".ts") && !entry.name.endsWith(".test.ts")) {
95
+ const source = fs.readFileSync(fullPath, "utf-8");
96
+ processFile(fullPath, source, results);
97
+ }
98
+ }
99
+ }
100
+ walk(srcDir);
101
+ return results;
102
+ }
103
+ function processFile(filePath, source, results) {
104
+ // Match: export function name | export async function name
105
+ const funcRegex = /\/\*\*[\s\S]*?\*\/\s*(?:export\s+)?(?:async\s+)?function\s+(\w+)/g;
106
+ const protocolRegex = /@protocol\s+.*?pre_states\s*=\s*\[([^\]]*)\].*?post_states\s*=\s*\[([^\]]*)\]/g;
107
+ let match;
108
+ // Strategy 1: Extract from @protocol annotations
109
+ // Reset regex
110
+ while ((match = protocolRegex.exec(source)) !== null) {
111
+ // Find the nearest function name before or after this annotation
112
+ const before = source.slice(0, match.index);
113
+ const after = source.slice(match.index);
114
+ const funcMatch = after.match(/function\s+(\w+)/);
115
+ if (!funcMatch)
116
+ continue;
117
+ const name = funcMatch[1];
118
+ const pre = match[1].split(",").map(s => s.replace(/["'\s]/g, "")).filter(Boolean);
119
+ const post = match[2].split(",").map(s => s.replace(/["'\s]/g, "")).filter(Boolean);
120
+ // Don't overwrite existing metadata
121
+ const existing = results.find(r => r.function === name);
122
+ if (existing) {
123
+ if (existing.requires.length === 0)
124
+ existing.requires = pre;
125
+ if (existing.produces.length === 0)
126
+ existing.produces = post;
127
+ }
128
+ else {
129
+ results.push({
130
+ function: name,
131
+ file: filePath,
132
+ requires: pre,
133
+ produces: post,
134
+ purpose: humanize(name),
135
+ tags: inferTags(filePath),
136
+ });
137
+ }
138
+ }
139
+ // Strategy 2: Extract from @requires/@produces tags in JSDoc
140
+ while ((match = funcRegex.exec(source)) !== null) {
141
+ const name = match[1];
142
+ const jsdoc = match[0];
143
+ // Skip if already covered by Strategy 1
144
+ const existing = results.find(r => r.function === name);
145
+ const requires = existing?.requires || [];
146
+ const produces = existing?.produces || [];
147
+ // Parse @requires tag
148
+ const reqMatch = jsdoc.match(/@requires\s+(\S+)/g);
149
+ if (reqMatch) {
150
+ for (const r of reqMatch) {
151
+ const val = r.replace("@requires ", "").trim();
152
+ if (val && !requires.includes(val))
153
+ requires.push(val);
154
+ }
155
+ }
156
+ // Parse @produces tag
157
+ const prodMatch = jsdoc.match(/@produces\s+(\S+)/g);
158
+ if (prodMatch) {
159
+ for (const p of prodMatch) {
160
+ const val = p.replace("@produces ", "").trim();
161
+ if (val && !produces.includes(val))
162
+ produces.push(val);
163
+ }
164
+ }
165
+ // Parse @purpose
166
+ const purposeMatch = jsdoc.match(/@purpose\s+(.+?)(?:\n|\*\/)/);
167
+ const purpose = purposeMatch
168
+ ? purposeMatch[1].trim()
169
+ : humanize(name);
170
+ // Parse @tags
171
+ const tagsMatch = jsdoc.match(/@tags?\s+(.+?)(?:\n|\*\/)/);
172
+ const tags = tagsMatch
173
+ ? tagsMatch[1].split(/[,\s]+/).map(s => s.trim()).filter(Boolean)
174
+ : inferTags(filePath);
175
+ if (existing) {
176
+ if (existing.requires.length === 0)
177
+ existing.requires = requires;
178
+ if (existing.produces.length === 0)
179
+ existing.produces = produces;
180
+ if (!existing.purpose || existing.purpose === humanize(name))
181
+ existing.purpose = purpose;
182
+ }
183
+ else {
184
+ results.push({ function: name, file: filePath, requires, produces, purpose, tags });
185
+ }
186
+ }
187
+ }
188
+ /**
189
+ * Apply derived metadata back to source files.
190
+ * Inserts @requires/@produces/@purpose/@tags tags into existing JSDoc comments.
191
+ */
192
+ function applyDerivedMetadata(dryRun = true) {
193
+ const derived = deriveMetadata();
194
+ let updated = 0;
195
+ let skipped = 0;
196
+ for (const meta of derived) {
197
+ const filePath = meta.file;
198
+ if (!fs.existsSync(filePath))
199
+ continue;
200
+ let source = fs.readFileSync(filePath, "utf-8");
201
+ // Find the function's JSDoc block
202
+ const funcPattern = new RegExp(`(\\/\\*\\*[\\s\\S]*?\\*\\/)\\s*(?:export\\s+)?(?:async\\s+)?function\\s+${meta.function}\\b`);
203
+ const match = funcPattern.exec(source);
204
+ if (!match) {
205
+ skipped++;
206
+ continue;
207
+ }
208
+ const existingJSDoc = match[1];
209
+ let newJSDoc = existingJSDoc;
210
+ // Add missing tags
211
+ if (!existingJSDoc.includes("@requires") && meta.requires.length > 0) {
212
+ newJSDoc = newJSDoc.replace(/\*\/$/, ` * @requires ${meta.requires.join(" ")}\n */`);
213
+ }
214
+ if (!existingJSDoc.includes("@produces") && meta.produces.length > 0) {
215
+ newJSDoc = newJSDoc.replace(/\*\/$/, ` * @produces ${meta.produces.join(" ")}\n */`);
216
+ }
217
+ if (!existingJSDoc.includes("@purpose") && meta.purpose) {
218
+ newJSDoc = newJSDoc.replace(/\*\/$/, ` * @purpose ${meta.purpose}\n */`);
219
+ }
220
+ if (!existingJSDoc.includes("@tags") && meta.tags.length > 0) {
221
+ newJSDoc = newJSDoc.replace(/\*\/$/, ` * @tags ${meta.tags.join(", ")}\n */`);
222
+ }
223
+ if (newJSDoc !== existingJSDoc) {
224
+ if (!dryRun) {
225
+ source = source.replace(existingJSDoc, newJSDoc);
226
+ fs.writeFileSync(filePath, source, "utf-8");
227
+ }
228
+ updated++;
229
+ }
230
+ else {
231
+ skipped++;
232
+ }
233
+ }
234
+ return { updated, skipped };
235
+ }
236
+ /** CLI: preview derivable metadata */
237
+ if (require.main === module) {
238
+ const derived = deriveMetadata();
239
+ console.log(`Derived metadata for ${derived.length} functions:\n`);
240
+ const withR = derived.filter(d => d.requires.length > 0);
241
+ const withP = derived.filter(d => d.produces.length > 0);
242
+ const withPurpose = derived.filter(d => d.purpose && d.purpose !== humanize(d.function));
243
+ console.log(` requires: ${withR.length} produces: ${withP.length} purpose: ${withPurpose.length}`);
244
+ // Show sample
245
+ console.log("\nSample derived metadata:");
246
+ for (const d of derived.filter(d => d.requires.length > 0 && d.produces.length > 0).slice(0, 5)) {
247
+ console.log(` ${d.function}: ${d.requires.join(",")} → ${d.produces.join(",")}`);
248
+ console.log(` purpose: ${d.purpose} tags: [${d.tags.join(", ")}]`);
249
+ }
250
+ }