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,242 @@
1
+ "use strict";
2
+ /**
3
+ * Resource Abstraction Layer — from words to semantics.
4
+ *
5
+ * The detector used to work like this:
6
+ * createPost → Post Asset → Protocol
7
+ *
8
+ * Now it works like this:
9
+ * create<X> → X is a MutableResource → needs Ownership + Validation + Authorization
10
+ *
11
+ * This is the generalization breakthrough:
12
+ * Post, Issue, Ticket, Task, Order, Artifact → ALL automatically recognized
13
+ *
14
+ * Three components:
15
+ * 1. Resource Classifier — identifies what kind of resource an entity is
16
+ * 2. Protocol Deriver — derives required protocols from resource type
17
+ * 3. Lexical Generalization — maps unknown entity names to known categories
18
+ */
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ exports.parseResourceName = parseResourceName;
21
+ exports.classifyResource = classifyResource;
22
+ exports.abstractResource = abstractResource;
23
+ exports.isMutatingOperation = isMutatingOperation;
24
+ exports.isReadOperation = isReadOperation;
25
+ exports.getRequiredProtocols = getRequiredProtocols;
26
+ exports.testLexicalGeneralization = testLexicalGeneralization;
27
+ // ═══════════════════════════════════════════════════════════════
28
+ // Verb → Resource Kind mapping
29
+ // ═══════════════════════════════════════════════════════════════
30
+ const MUTABLE_VERBS = new Set([
31
+ "create", "add", "insert", "new", "make", "build",
32
+ "update", "edit", "modify", "change", "set", "put",
33
+ "delete", "remove", "destroy", "drop", "clear", "erase",
34
+ ]);
35
+ const READ_VERBS = new Set([
36
+ "get", "fetch", "find", "query", "read", "load", "list", "search", "lookup",
37
+ ]);
38
+ const AUTH_VERBS = new Set([
39
+ "login", "logout", "register", "signup", "signin", "authenticate", "authorize",
40
+ "verify", "validate", "check",
41
+ ]);
42
+ // ═══════════════════════════════════════════════════════════════
43
+ // Entity → Resource Kind heuristics
44
+ // ═══════════════════════════════════════════════════════════════
45
+ /**
46
+ * Known entity suffixes that indicate resource kinds.
47
+ * These are generalizable — they work for ANY entity name.
48
+ */
49
+ const RESOURCE_SUFFIX_PATTERNS = [
50
+ {
51
+ // Mutable resources: Post, Issue, Ticket, Task, Order, Product, Project, etc.
52
+ // These need: Ownership + Validation + Authorization + DataIntegrity
53
+ pattern: /^(Post|Issue|Ticket|Task|Order|Product|Project|Item|Entry|Record|Document|Article|Page|Thread|Topic|Subject|Object|Entity|Artifact|Asset|Resource|Job|Workflow|Pipeline|Deployment|Release)$/i,
54
+ kind: "mutable_resource",
55
+ protocols: ["ownership_check", "input_validation", "authorization", "data_integrity"],
56
+ },
57
+ {
58
+ // Comments/Replies: always reference a parent resource
59
+ pattern: /^(Comment|Reply|Response|Note|Annotation|Feedback|Review|Remark)$/i,
60
+ kind: "mutable_resource",
61
+ protocols: ["ownership_check", "input_validation", "data_integrity", "authorization"],
62
+ },
63
+ {
64
+ // Credential material
65
+ pattern: /^(Password|Token|Key|Secret|Credential|ApiKey|AccessKey|Certificate)$/i,
66
+ kind: "credential",
67
+ protocols: ["password_hashing", "token_security", "secure_storage"],
68
+ },
69
+ {
70
+ // File assets
71
+ pattern: /^(File|Attachment|Image|Photo|Video|Audio|Document|Media|Asset|Binary|Blob|Upload|Download)$/i,
72
+ kind: "file_asset",
73
+ protocols: ["file_validation", "ownership_check", "authorization"],
74
+ },
75
+ {
76
+ // Reference data
77
+ pattern: /^(Category|Tag|Label|Status|Type|State|Priority|Severity|Role|Permission|Group|Team|Organization)$/i,
78
+ kind: "reference_data",
79
+ protocols: ["authorization"],
80
+ },
81
+ {
82
+ // Session/connection
83
+ pattern: /^(Session|Connection|Stream|Channel|Socket|WebSocket|SSE)$/i,
84
+ kind: "session",
85
+ protocols: ["tls_enforcement", "token_verification"],
86
+ },
87
+ ];
88
+ // ═══════════════════════════════════════════════════════════════
89
+ // Core Engine
90
+ // ═══════════════════════════════════════════════════════════════
91
+ /**
92
+ * Parse a function name into verb + entity.
93
+ *
94
+ * Examples:
95
+ * createPost → { verb: "create", entity: "Post" }
96
+ * deleteUser → { verb: "delete", entity: "User" }
97
+ * addProductItem → { verb: "add", entity: "ProductItem" }
98
+ * getNotifications → { verb: "get", entity: "Notifications" }
99
+ */
100
+ function parseResourceName(functionName) {
101
+ // Common verb prefixes
102
+ const verbPatterns = [
103
+ "create", "delete", "update", "remove", "destroy",
104
+ "add", "insert", "new", "make", "build",
105
+ "get", "fetch", "find", "query", "read", "load", "list",
106
+ "edit", "modify", "change", "set", "put",
107
+ "login", "logout", "register", "signup", "signin",
108
+ "verify", "validate", "check", "authorize", "authenticate",
109
+ "upload", "download", "send", "receive",
110
+ "toggle", "lock", "unlock", "enable", "disable",
111
+ "follow", "unfollow", "like", "unlike",
112
+ "hash", "generate", "sign", "encrypt", "decrypt",
113
+ ];
114
+ for (const verb of verbPatterns) {
115
+ if (functionName.toLowerCase().startsWith(verb.toLowerCase())) {
116
+ const entity = functionName.slice(verb.length);
117
+ if (entity.length >= 2) {
118
+ return { verb: verb.toLowerCase(), entity };
119
+ }
120
+ }
121
+ }
122
+ return null;
123
+ }
124
+ /**
125
+ * Classify a resource by its entity name.
126
+ * Uses suffix patterns for known categories, heuristics for unknown ones.
127
+ */
128
+ function classifyResource(entity) {
129
+ // Normalize: handle plurals, camelCase suffixes
130
+ const normalized = entity.replace(/s$/, ""); // Remove trailing 's' for plurals
131
+ // Check known patterns
132
+ for (const { pattern, kind, protocols } of RESOURCE_SUFFIX_PATTERNS) {
133
+ if (pattern.test(entity) || pattern.test(normalized)) {
134
+ return { kind, protocols, confidence: 0.9 };
135
+ }
136
+ }
137
+ // Heuristic: if the entity starts with an uppercase letter (camelCase), it's likely a resource
138
+ // Unknown entities default to mutable_resource with full protocol requirements
139
+ if (/^[A-Z]/.test(entity)) {
140
+ return {
141
+ kind: "mutable_resource",
142
+ protocols: ["ownership_check", "input_validation", "authorization", "data_integrity"],
143
+ confidence: 0.5, // Lower confidence for unknown entities
144
+ };
145
+ }
146
+ return { kind: "unknown", protocols: [], confidence: 0.1 };
147
+ }
148
+ /**
149
+ * Full resource abstraction pipeline:
150
+ * functionName → verb + entity → resource kind → required protocols
151
+ */
152
+ function abstractResource(functionName) {
153
+ const parsed = parseResourceName(functionName);
154
+ if (!parsed)
155
+ return null;
156
+ const { kind, protocols, confidence } = classifyResource(parsed.entity);
157
+ // Read operations on mutable resources: classify as reference_data
158
+ // (accessing a resource doesn't mutate it; the entity type reflects the access mode)
159
+ const adjustedKind = READ_VERBS.has(parsed.verb) && kind === "mutable_resource"
160
+ ? "reference_data"
161
+ : kind;
162
+ return {
163
+ original: functionName,
164
+ verb: parsed.verb,
165
+ entity: parsed.entity,
166
+ kind: adjustedKind,
167
+ requiredProtocols: protocols,
168
+ confidence,
169
+ };
170
+ }
171
+ /**
172
+ * Check if a given function name is a mutating operation on a resource.
173
+ * Mutations require: Ownership + Authorization + (optionally) Validation
174
+ */
175
+ function isMutatingOperation(functionName) {
176
+ const parsed = parseResourceName(functionName);
177
+ if (!parsed)
178
+ return false;
179
+ return MUTABLE_VERBS.has(parsed.verb);
180
+ }
181
+ /**
182
+ * Check if a given function name is a read operation.
183
+ */
184
+ function isReadOperation(functionName) {
185
+ const parsed = parseResourceName(functionName);
186
+ if (!parsed)
187
+ return false;
188
+ return READ_VERBS.has(parsed.verb);
189
+ }
190
+ /**
191
+ * Get the protocols required for a given function.
192
+ * Combines verb semantics with resource classification.
193
+ */
194
+ function getRequiredProtocols(functionName) {
195
+ const abs = abstractResource(functionName);
196
+ if (!abs)
197
+ return [];
198
+ const protocols = [...abs.requiredProtocols];
199
+ // Mutating operations ALWAYS need authorization
200
+ if (MUTABLE_VERBS.has(abs.verb) && !protocols.includes("authorization")) {
201
+ protocols.push("authorization");
202
+ }
203
+ // Mutating operations on mutable resources need ownership checks
204
+ if (MUTABLE_VERBS.has(abs.verb) && abs.kind === "mutable_resource" && !protocols.includes("ownership_check")) {
205
+ protocols.push("ownership_check");
206
+ }
207
+ return protocols;
208
+ }
209
+ // ═══════════════════════════════════════════════════════════════
210
+ // Lexical Generalization Test
211
+ // ═══════════════════════════════════════════════════════════════
212
+ /**
213
+ * Test whether the resource abstraction correctly identifies
214
+ * that DIFFERENT entity names with the SAME semantics require
215
+ * the SAME protocols.
216
+ *
217
+ * Known entities: Post, Comment, Task, Order, Product → should all require ownership_check
218
+ * Unknown entities: Ticket, Issue, Artifact, Foo → should ALSO require ownership_check
219
+ */
220
+ function testLexicalGeneralization() {
221
+ const knownEntities = ["Post", "Comment", "Task", "Order", "Product", "Project", "Item"];
222
+ const unknownEntities = ["Ticket", "Issue", "Artifact", "Document", "Foo", "Widget", "Thing"];
223
+ const expectedProtocol = "ownership_check";
224
+ let knownCorrect = 0;
225
+ for (const entity of knownEntities) {
226
+ const { protocols } = classifyResource(entity);
227
+ if (protocols.includes(expectedProtocol))
228
+ knownCorrect++;
229
+ }
230
+ let unknownCorrect = 0;
231
+ for (const entity of unknownEntities) {
232
+ const { protocols } = classifyResource(entity);
233
+ if (protocols.includes(expectedProtocol))
234
+ unknownCorrect++;
235
+ }
236
+ return {
237
+ knownEntities,
238
+ unknownEntities,
239
+ knownRecall: knownCorrect / knownEntities.length,
240
+ unknownRecall: unknownCorrect / unknownEntities.length,
241
+ };
242
+ }
@@ -0,0 +1,211 @@
1
+ "use strict";
2
+ /**
3
+ * Resource Lifecycle Detector
4
+ *
5
+ * Focused detection of resource acquire/release violations.
6
+ * Replaces noisy auto-discovered call-ordering rules with
7
+ * explicit acquire→release pair analysis.
8
+ *
9
+ * Strategy:
10
+ * 1. Identify resource-acquiring calls (malloc, open, connect, SSL_new, ...)
11
+ * 2. Identify resource-releasing calls (free, close, disconnect, SSL_free, ...)
12
+ * 3. Flag violations: acquire without corresponding release in same scope
13
+ * 4. Exclude "allocation-return" pattern (function allocates for caller)
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.detectResourceViolations = detectResourceViolations;
17
+ exports.validateResourceLifecycle = validateResourceLifecycle;
18
+ // ── Known resource pairs ──
19
+ const RESOURCE_PAIRS = [
20
+ // Memory
21
+ { acquire: /\b(malloc|calloc|realloc|curlx_malloc|curlx_calloc|curlx_realloc|zmalloc|zcalloc|zrealloc|ngx_alloc|ngx_calloc|ngx_palloc)\b/i, release: /\b(free|curlx_free|zfree|ngx_free|ngx_pfree)\b/i, category: "memory" },
22
+ // File descriptors (accept removed — listening sockets stay open)
23
+ { acquire: /\b(open|fopen|socket|curlx_open)\b/i, release: /\b(close|fclose|closesocket|curlx_close|shutdown)\b/i, category: "file" },
24
+ // SSL/TLS (expanded with CTX and bio patterns)
25
+ { acquire: /\b(SSL_new|TLS_new|wolfSSL_new|gtls_new|BIO_new|ossl_new|nghttp2_session_new|SSL_CTX_new|BIO_new_mem_buf|BIO_s_file|BIO_read_filename)\b/i, release: /\b(SSL_free|TLS_free|wolfSSL_free|gtls_free|BIO_free|ossl_free|nghttp2_session_del|SSL_CTX_free|BIO_free_all)\b/i, category: "ssl" },
26
+ // Connections (accept removed — server socket, not per-connection resource)
27
+ { acquire: /\b(connect|Curl_connect|ngx_connect|redisConnect)\b/i, release: /\b(disconnect|Curl_disconnect|ngx_disconnect|redisFree)\b/i, category: "connection" },
28
+ // General lifecycle — only for double-release / UAF checks, not missing-release
29
+ { acquire: /\b(_init|_create|_setup|_start|_begin|_open|_alloc|_connect|init|create|setup|start|open|alloc)\b/i, release: /\b(_free|_destroy|_cleanup|_close|_stop|_end|_release|_unlock|_done|_finish|_remove|_delete|cleanup|destroy|close|free)\b/i, category: "lifecycle" },
30
+ // C error-handling: goto cleanup/fail pattern (synthetic calls from sequence-extractor)
31
+ { acquire: /\b(goto_cleanup|goto_fail|goto_err|goto_error|goto_out)\b/i, release: /\b(_free|_destroy|_cleanup|_close|_release|free|destroy|cleanup|close)\b/i, category: "lifecycle" },
32
+ // Python resource pairs
33
+ { acquire: /\b(sqlite3\.connect|psycopg2\.connect|create_engine|pymongo\.MongoClient|redis\.Redis|redis\.StrictRedis)\b/i, release: /\b(close|disconnect)\b/i, category: "connection" },
34
+ { acquire: /\b(socket\.socket|socket\.create_connection|socket\.socketpair)\b/i, release: /\b(close)\b/i, category: "file" },
35
+ { acquire: /\b(asyncio\.(Lock|Semaphore|Event|Condition)|threading\.(Lock|RLock|Semaphore|Condition))\b/i, release: /\b(release)\b/i, category: "lock" },
36
+ { acquire: /\b(tempfile\.(TemporaryFile|NamedTemporaryFile|mkstemp|mkdtemp|SpooledTemporaryFile))\b/i, release: /\b(close|cleanup)\b/i, category: "file" },
37
+ ];
38
+ // ── Allocation-return patterns (functions that allocate and return to caller) ──
39
+ const ALLOCATOR_PATTERNS = [
40
+ /\b(create|alloc|new|init|open|dup|clone|copy|build|make|setup|construct)\w*\b/i,
41
+ ];
42
+ // ── Cleanup/destructor functions (expected to call release without acquire) ──
43
+ const CLEANUP_PATTERNS = [
44
+ /\b(remove|cleanup|destroy|free|close|delete|detach|release|shutdown|teardown|done|finish)\w*\b/i,
45
+ // Curl-specific cleanup functions (cross-function alloc/free patterns)
46
+ /\b(Curl_close|curl_multi_cleanup|Curl_detach_connection|curl_easy_cleanup|Curl_expire_clear|Curl_resolv_destroy_all|Curl_conncache_remove|Curl_ssl_close_all|Curl_req_free)\b/i,
47
+ ];
48
+ function isAllocatorFunction(funcName) {
49
+ return ALLOCATOR_PATTERNS.some(p => p.test(funcName));
50
+ }
51
+ function isCleanupFunction(funcName) {
52
+ return CLEANUP_PATTERNS.some(p => p.test(funcName));
53
+ }
54
+ function detectResourceViolations(calls, enclosingFuncName) {
55
+ const violations = [];
56
+ const funcName = enclosingFuncName || "";
57
+ for (const pair of RESOURCE_PAIRS) {
58
+ const acquires = [];
59
+ const releases = [];
60
+ for (let i = 0; i < calls.length; i++) {
61
+ const c = calls[i];
62
+ if (pair.acquire.test(c) && !isAllocatorFunction(c))
63
+ acquires.push(i);
64
+ if (pair.release.test(c))
65
+ releases.push(i);
66
+ }
67
+ // Rule 1: more acquires than releases → potential leak
68
+ // Exception: allocator functions (return resource to caller)
69
+ // Exception: cleanup functions (release resources allocated elsewhere)
70
+ // Exception: lifecycle category (too broad for missing-release check)
71
+ if (acquires.length > releases.length && acquires.length > 0 && pair.category !== "lifecycle") {
72
+ if (!isAllocatorFunction(funcName) && !isCleanupFunction(funcName)) {
73
+ for (let i = releases.length; i < acquires.length; i++) {
74
+ violations.push({
75
+ type: "missing_release",
76
+ category: pair.category,
77
+ acquireCall: calls[acquires[i]],
78
+ detail: `${calls[acquires[i]]} acquired without matching ${pair.release.source} — possible resource leak`,
79
+ });
80
+ }
81
+ }
82
+ }
83
+ // Rule 2: release without acquire → only flag if 2+ releases (true double-free)
84
+ // Single release without acquire = cross-function cleanup (normal in C code)
85
+ // Exception: cleanup/destructor functions always exempt
86
+ if (releases.length >= 2 && acquires.length === 0) {
87
+ if (!isCleanupFunction(funcName)) {
88
+ violations.push({
89
+ type: "double_free",
90
+ category: pair.category,
91
+ releaseCall: calls[releases[0]],
92
+ detail: `${calls[releases[0]]} → ${calls[releases[releases.length - 1]]}: multiple releases without any acquire — possible double-free`,
93
+ });
94
+ }
95
+ }
96
+ // Rule 3: release before corresponding acquire (interleaved)
97
+ if (acquires.length > 0 && releases.length > 0) {
98
+ for (const ri of releases) {
99
+ // A release at position ri must have at least one acquire before it
100
+ const hasPriorAcquire = acquires.some(ai => ai < ri);
101
+ if (!hasPriorAcquire) {
102
+ violations.push({
103
+ type: "use_after_release",
104
+ category: pair.category,
105
+ releaseCall: calls[ri],
106
+ detail: `${calls[ri]} called before any ${pair.acquire.source} — possible double-free`,
107
+ });
108
+ }
109
+ }
110
+ }
111
+ }
112
+ return violations;
113
+ }
114
+ /**
115
+ * Validate a call sequence using resource lifecycle analysis.
116
+ * Returns valid=true if no resource violations found.
117
+ */
118
+ function validateResourceLifecycle(calls, enclosingFuncName) {
119
+ const violations = detectResourceViolations(calls, enclosingFuncName);
120
+ const missingCount = violations.filter(v => v.type === "missing_release").length;
121
+ const otherCount = violations.length - missingCount;
122
+ let detail = "";
123
+ if (violations.length === 0) {
124
+ detail = "Resource lifecycle clean";
125
+ }
126
+ else {
127
+ const parts = [];
128
+ if (missingCount > 0)
129
+ parts.push(`${missingCount} potential resource leak(s)`);
130
+ if (otherCount > 0)
131
+ parts.push(`${otherCount} ordering violation(s)`);
132
+ detail = parts.join(", ");
133
+ }
134
+ return {
135
+ valid: violations.length === 0,
136
+ violations,
137
+ detail,
138
+ };
139
+ }
140
+ // ═══════════════════════════════════════════════════════════════
141
+ // CLI — Precision Report
142
+ // ═══════════════════════════════════════════════════════════════
143
+ if (require.main === module) {
144
+ const fs = require("fs");
145
+ const path = require("path");
146
+ const args = process.argv.slice(2);
147
+ const repoPath = path.resolve(args.find(a => !a.startsWith("--")) || ".");
148
+ const baseDir = path.dirname(repoPath);
149
+ const repoName = path.basename(repoPath);
150
+ const seqFile = path.join(baseDir, `${repoName}-sequences.json`);
151
+ const labelFile = path.join(baseDir, `${repoName}-labels.json`);
152
+ if (!fs.existsSync(seqFile) || !fs.existsSync(labelFile)) {
153
+ console.error(`❌ Files not found: ${seqFile}, ${labelFile}`);
154
+ process.exit(1);
155
+ }
156
+ const seqData = JSON.parse(fs.readFileSync(seqFile, "utf-8"));
157
+ const labelData = JSON.parse(fs.readFileSync(labelFile, "utf-8"));
158
+ const sequences = seqData.sequences || seqData;
159
+ const labels = labelData.labels || labelData;
160
+ let tp = 0, fp = 0, tn = 0, fn = 0;
161
+ const mismatches = [];
162
+ for (const seq of sequences) {
163
+ const idx = sequences.indexOf(seq);
164
+ const expected = labels[idx];
165
+ if (!expected || expected === "s" || expected === "skip")
166
+ continue;
167
+ const result = validateResourceLifecycle(seq.calls || [], seq.function);
168
+ const detected = result.valid ? "clean" : "violation";
169
+ if (expected === "clean" && detected === "clean")
170
+ tn++;
171
+ else if (expected === "violation" && detected === "violation")
172
+ tp++;
173
+ else if (expected === "clean" && detected === "violation")
174
+ fp++;
175
+ else if (expected === "violation" && detected === "clean")
176
+ fn++;
177
+ if (expected !== detected || result.violations.length > 0) {
178
+ mismatches.push({ idx, fn: seq.function, expected, detected, calls: (seq.calls || []).slice(0, 5), vios: result.violations.map(v => v.detail) });
179
+ }
180
+ }
181
+ const total = tp + fp + tn + fn;
182
+ const precision = tp + fp > 0 ? tp / (tp + fp) : 0;
183
+ const recall = tp + fn > 0 ? tp / (tp + fn) : 0;
184
+ const f1 = precision + recall > 0 ? 2 * precision * recall / (precision + recall) : 0;
185
+ const pct = (v) => `${(v * 100).toFixed(0)}%`;
186
+ const C = { reset: "\x1b[0m", bold: "\x1b[1m", dim: "\x1b[2m", green: "\x1b[32m", red: "\x1b[31m", yellow: "\x1b[33m", cyan: "\x1b[36m" };
187
+ const color = (v) => v >= 0.7 ? C.green : v >= 0.5 ? C.yellow : C.red;
188
+ console.log(`\n${C.bold}${C.cyan}╔══════════════════════════════════════════════╗${C.reset}`);
189
+ console.log(`${C.bold}${C.cyan}║${C.reset} ${C.bold}Resource Lifecycle Precision — ${repoName}${C.reset}${" ".repeat(Math.max(0, 19 - repoName.length))}${C.bold}${C.cyan}║${C.reset}`);
190
+ console.log(`${C.bold}${C.cyan}╚══════════════════════════════════════════════╝${C.reset}`);
191
+ console.log("");
192
+ console.log(` Samples: ${total}`);
193
+ console.log(` TP: ${C.green}${tp}${C.reset} FP: ${C.red}${fp}${C.reset} TN: ${C.green}${tn}${C.reset} FN: ${C.red}${fn}${C.reset}`);
194
+ console.log("");
195
+ console.log(` Precision: ${color(precision)}${pct(precision)}${C.reset}`);
196
+ console.log(` Recall: ${color(recall)}${pct(recall)}${C.reset}`);
197
+ console.log(` F1: ${color(f1)}${pct(f1)}${C.reset}`);
198
+ console.log("");
199
+ if (mismatches.length > 0) {
200
+ console.log(` ${C.yellow}Details:${C.reset}`);
201
+ for (const m of mismatches.slice(0, 12)) {
202
+ const icon = m.expected === "violation" ? `${C.red}FN${C.reset}` : `${C.yellow}FP${C.reset}`;
203
+ console.log(` ${icon} [${m.idx}] ${m.expected}→${m.detected} ${(m.calls || []).join(" → ")}`);
204
+ if (m.vios.length)
205
+ console.log(` ${C.dim}${m.vios[0]}${C.reset}`);
206
+ }
207
+ }
208
+ console.log("");
209
+ const rating = f1 >= 0.7 ? `${C.green}GOOD${C.reset}` : f1 >= 0.5 ? `${C.yellow}FAIR${C.reset}` : `${C.red}NEEDS IMPROVEMENT${C.reset}`;
210
+ console.log(` Rating: ${rating}\n`);
211
+ }
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * Unit tests for the Result<T,E> type and factory functions.
5
+ */
6
+ const vitest_1 = require("vitest");
7
+ const runtime_types_1 = require("./runtime-types");
8
+ (0, vitest_1.describe)("Result type", () => {
9
+ (0, vitest_1.it)("ok() returns { ok: true, value }", () => {
10
+ const r = (0, runtime_types_1.ok)(42);
11
+ (0, vitest_1.expect)(r.ok).toBe(true);
12
+ if (r.ok)
13
+ (0, vitest_1.expect)(r.value).toBe(42);
14
+ });
15
+ (0, vitest_1.it)("err() returns { ok: false, error }", () => {
16
+ const r = (0, runtime_types_1.err)("something broke");
17
+ (0, vitest_1.expect)(r.ok).toBe(false);
18
+ if (!r.ok)
19
+ (0, vitest_1.expect)(r.error).toBe("something broke");
20
+ });
21
+ (0, vitest_1.it)("supports discriminated union narrowing", () => {
22
+ function divide(a, b) {
23
+ if (b === 0)
24
+ return (0, runtime_types_1.err)("division by zero");
25
+ return (0, runtime_types_1.ok)(a / b);
26
+ }
27
+ const good = divide(10, 2);
28
+ if (good.ok)
29
+ (0, vitest_1.expect)(good.value).toBe(5);
30
+ const bad = divide(1, 0);
31
+ if (!bad.ok)
32
+ (0, vitest_1.expect)(bad.error).toBe("division by zero");
33
+ });
34
+ (0, vitest_1.it)("supports typed ValidationError", () => {
35
+ const e = { message: "type mismatch", code: "SVL-2", index: 3 };
36
+ const r = (0, runtime_types_1.err)([e]);
37
+ (0, vitest_1.expect)(r.ok).toBe(false);
38
+ if (!r.ok) {
39
+ (0, vitest_1.expect)(r.error[0].code).toBe("SVL-2");
40
+ (0, vitest_1.expect)(r.error[0].index).toBe(3);
41
+ }
42
+ });
43
+ });