@quantakrypto/core 0.4.4 → 0.6.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 (302) hide show
  1. package/README.md +76 -27
  2. package/dist/cbom-merge.d.ts.map +1 -1
  3. package/dist/cbom-merge.js +30 -8
  4. package/dist/cbom-merge.js.map +1 -1
  5. package/dist/cbom.d.ts +5 -0
  6. package/dist/cbom.d.ts.map +1 -1
  7. package/dist/cbom.js +132 -37
  8. package/dist/cbom.js.map +1 -1
  9. package/dist/comments.d.ts +2 -23
  10. package/dist/comments.d.ts.map +1 -1
  11. package/dist/comments.js +24 -5
  12. package/dist/comments.js.map +1 -1
  13. package/dist/crypto-agility.d.ts +158 -0
  14. package/dist/crypto-agility.d.ts.map +1 -0
  15. package/dist/crypto-agility.js +285 -0
  16. package/dist/crypto-agility.js.map +1 -0
  17. package/dist/dependencies.d.ts.map +1 -1
  18. package/dist/dependencies.js +180 -18
  19. package/dist/dependencies.js.map +1 -1
  20. package/dist/detect-utils.d.ts +55 -21
  21. package/dist/detect-utils.d.ts.map +1 -1
  22. package/dist/detect-utils.js +133 -7
  23. package/dist/detect-utils.js.map +1 -1
  24. package/dist/detectors/age.d.ts +16 -0
  25. package/dist/detectors/age.d.ts.map +1 -0
  26. package/dist/detectors/age.js +40 -0
  27. package/dist/detectors/age.js.map +1 -0
  28. package/dist/detectors/ansible.d.ts +13 -0
  29. package/dist/detectors/ansible.d.ts.map +1 -0
  30. package/dist/detectors/ansible.js +108 -0
  31. package/dist/detectors/ansible.js.map +1 -0
  32. package/dist/detectors/bicep.d.ts +20 -0
  33. package/dist/detectors/bicep.d.ts.map +1 -0
  34. package/dist/detectors/bicep.js +74 -0
  35. package/dist/detectors/bicep.js.map +1 -0
  36. package/dist/detectors/c.d.ts.map +1 -1
  37. package/dist/detectors/c.js +30 -3
  38. package/dist/detectors/c.js.map +1 -1
  39. package/dist/detectors/cicd.d.ts.map +1 -1
  40. package/dist/detectors/cicd.js +18 -5
  41. package/dist/detectors/cicd.js.map +1 -1
  42. package/dist/detectors/cloud-kms.d.ts +8 -5
  43. package/dist/detectors/cloud-kms.d.ts.map +1 -1
  44. package/dist/detectors/cloud-kms.js +62 -20
  45. package/dist/detectors/cloud-kms.js.map +1 -1
  46. package/dist/detectors/cloudformation.d.ts +8 -0
  47. package/dist/detectors/cloudformation.d.ts.map +1 -1
  48. package/dist/detectors/cloudformation.js +41 -10
  49. package/dist/detectors/cloudformation.js.map +1 -1
  50. package/dist/detectors/codesign.d.ts +50 -0
  51. package/dist/detectors/codesign.d.ts.map +1 -0
  52. package/dist/detectors/codesign.js +143 -0
  53. package/dist/detectors/codesign.js.map +1 -0
  54. package/dist/detectors/csharp.d.ts.map +1 -1
  55. package/dist/detectors/csharp.js +13 -3
  56. package/dist/detectors/csharp.js.map +1 -1
  57. package/dist/detectors/dart.d.ts +35 -0
  58. package/dist/detectors/dart.d.ts.map +1 -0
  59. package/dist/detectors/dart.js +177 -0
  60. package/dist/detectors/dart.js.map +1 -0
  61. package/dist/detectors/database.d.ts +5 -3
  62. package/dist/detectors/database.d.ts.map +1 -1
  63. package/dist/detectors/database.js +45 -8
  64. package/dist/detectors/database.js.map +1 -1
  65. package/dist/detectors/dkim.d.ts +54 -0
  66. package/dist/detectors/dkim.d.ts.map +1 -0
  67. package/dist/detectors/dkim.js +92 -0
  68. package/dist/detectors/dkim.js.map +1 -0
  69. package/dist/detectors/dnssec.d.ts.map +1 -1
  70. package/dist/detectors/dnssec.js +19 -10
  71. package/dist/detectors/dnssec.js.map +1 -1
  72. package/dist/detectors/elixir.d.ts.map +1 -1
  73. package/dist/detectors/elixir.js +34 -2
  74. package/dist/detectors/elixir.js.map +1 -1
  75. package/dist/detectors/java.d.ts.map +1 -1
  76. package/dist/detectors/java.js +33 -3
  77. package/dist/detectors/java.js.map +1 -1
  78. package/dist/detectors/jose.d.ts.map +1 -1
  79. package/dist/detectors/jose.js +13 -3
  80. package/dist/detectors/jose.js.map +1 -1
  81. package/dist/detectors/jwk.d.ts +7 -7
  82. package/dist/detectors/jwk.d.ts.map +1 -1
  83. package/dist/detectors/jwk.js +44 -8
  84. package/dist/detectors/jwk.js.map +1 -1
  85. package/dist/detectors/k8s.d.ts.map +1 -1
  86. package/dist/detectors/k8s.js +5 -2
  87. package/dist/detectors/k8s.js.map +1 -1
  88. package/dist/detectors/keystore.d.ts +19 -0
  89. package/dist/detectors/keystore.d.ts.map +1 -0
  90. package/dist/detectors/keystore.js +76 -0
  91. package/dist/detectors/keystore.js.map +1 -0
  92. package/dist/detectors/mesh.d.ts +7 -8
  93. package/dist/detectors/mesh.d.ts.map +1 -1
  94. package/dist/detectors/mesh.js +17 -35
  95. package/dist/detectors/mesh.js.map +1 -1
  96. package/dist/detectors/messaging.d.ts +2 -2
  97. package/dist/detectors/messaging.d.ts.map +1 -1
  98. package/dist/detectors/messaging.js +19 -12
  99. package/dist/detectors/messaging.js.map +1 -1
  100. package/dist/detectors/objc.d.ts +41 -0
  101. package/dist/detectors/objc.d.ts.map +1 -0
  102. package/dist/detectors/objc.js +146 -0
  103. package/dist/detectors/objc.js.map +1 -0
  104. package/dist/detectors/openpgp.d.ts +20 -0
  105. package/dist/detectors/openpgp.d.ts.map +1 -0
  106. package/dist/detectors/openpgp.js +151 -0
  107. package/dist/detectors/openpgp.js.map +1 -0
  108. package/dist/detectors/pem.d.ts.map +1 -1
  109. package/dist/detectors/pem.js +32 -0
  110. package/dist/detectors/pem.js.map +1 -1
  111. package/dist/detectors/php.d.ts +2 -1
  112. package/dist/detectors/php.d.ts.map +1 -1
  113. package/dist/detectors/php.js +7 -3
  114. package/dist/detectors/php.js.map +1 -1
  115. package/dist/detectors/pkcs11.d.ts +17 -0
  116. package/dist/detectors/pkcs11.d.ts.map +1 -0
  117. package/dist/detectors/pkcs11.js +87 -0
  118. package/dist/detectors/pkcs11.js.map +1 -0
  119. package/dist/detectors/proxy.d.ts +52 -0
  120. package/dist/detectors/proxy.d.ts.map +1 -0
  121. package/dist/detectors/proxy.js +157 -0
  122. package/dist/detectors/proxy.js.map +1 -0
  123. package/dist/detectors/pulumi.d.ts +19 -0
  124. package/dist/detectors/pulumi.d.ts.map +1 -0
  125. package/dist/detectors/pulumi.js +80 -0
  126. package/dist/detectors/pulumi.js.map +1 -0
  127. package/dist/detectors/rust.d.ts.map +1 -1
  128. package/dist/detectors/rust.js +5 -0
  129. package/dist/detectors/rust.js.map +1 -1
  130. package/dist/detectors/secrets.d.ts +4 -1
  131. package/dist/detectors/secrets.d.ts.map +1 -1
  132. package/dist/detectors/secrets.js +5 -21
  133. package/dist/detectors/secrets.js.map +1 -1
  134. package/dist/detectors/solidity.d.ts +50 -0
  135. package/dist/detectors/solidity.d.ts.map +1 -0
  136. package/dist/detectors/solidity.js +108 -0
  137. package/dist/detectors/solidity.js.map +1 -0
  138. package/dist/detectors/source.d.ts.map +1 -1
  139. package/dist/detectors/source.js +105 -6
  140. package/dist/detectors/source.js.map +1 -1
  141. package/dist/detectors/spire.d.ts +49 -0
  142. package/dist/detectors/spire.d.ts.map +1 -0
  143. package/dist/detectors/spire.js +77 -0
  144. package/dist/detectors/spire.js.map +1 -0
  145. package/dist/detectors/ssh-ca.d.ts +72 -0
  146. package/dist/detectors/ssh-ca.d.ts.map +1 -0
  147. package/dist/detectors/ssh-ca.js +119 -0
  148. package/dist/detectors/ssh-ca.js.map +1 -0
  149. package/dist/detectors/supply-chain.d.ts +17 -0
  150. package/dist/detectors/supply-chain.d.ts.map +1 -0
  151. package/dist/detectors/supply-chain.js +89 -0
  152. package/dist/detectors/supply-chain.js.map +1 -0
  153. package/dist/detectors/swift.d.ts +22 -0
  154. package/dist/detectors/swift.d.ts.map +1 -0
  155. package/dist/detectors/swift.js +120 -0
  156. package/dist/detectors/swift.js.map +1 -0
  157. package/dist/detectors/terraform.d.ts.map +1 -1
  158. package/dist/detectors/terraform.js +35 -8
  159. package/dist/detectors/terraform.js.map +1 -1
  160. package/dist/detectors/vault.d.ts +15 -0
  161. package/dist/detectors/vault.d.ts.map +1 -0
  162. package/dist/detectors/vault.js +97 -0
  163. package/dist/detectors/vault.js.map +1 -0
  164. package/dist/detectors/vpn.d.ts +8 -8
  165. package/dist/detectors/vpn.d.ts.map +1 -1
  166. package/dist/detectors/vpn.js +12 -38
  167. package/dist/detectors/vpn.js.map +1 -1
  168. package/dist/detectors/weak-hash.d.ts +71 -0
  169. package/dist/detectors/weak-hash.d.ts.map +1 -0
  170. package/dist/detectors/weak-hash.js +116 -0
  171. package/dist/detectors/weak-hash.js.map +1 -0
  172. package/dist/detectors/webauthn.d.ts +61 -0
  173. package/dist/detectors/webauthn.d.ts.map +1 -0
  174. package/dist/detectors/webauthn.js +109 -0
  175. package/dist/detectors/webauthn.js.map +1 -0
  176. package/dist/detectors/xmldsig.d.ts +23 -0
  177. package/dist/detectors/xmldsig.d.ts.map +1 -0
  178. package/dist/detectors/xmldsig.js +84 -0
  179. package/dist/detectors/xmldsig.js.map +1 -0
  180. package/dist/evidence.d.ts +74 -4
  181. package/dist/evidence.d.ts.map +1 -1
  182. package/dist/evidence.js +71 -0
  183. package/dist/evidence.js.map +1 -1
  184. package/dist/hndl.d.ts +241 -0
  185. package/dist/hndl.d.ts.map +1 -0
  186. package/dist/hndl.js +752 -0
  187. package/dist/hndl.js.map +1 -0
  188. package/dist/index.d.ts +18 -11
  189. package/dist/index.d.ts.map +1 -1
  190. package/dist/index.js +21 -11
  191. package/dist/index.js.map +1 -1
  192. package/dist/inventory.d.ts +0 -2
  193. package/dist/inventory.d.ts.map +1 -1
  194. package/dist/inventory.js +15 -6
  195. package/dist/inventory.js.map +1 -1
  196. package/dist/parallel.d.ts.map +1 -1
  197. package/dist/parallel.js +22 -23
  198. package/dist/parallel.js.map +1 -1
  199. package/dist/registry.d.ts +9 -4
  200. package/dist/registry.d.ts.map +1 -1
  201. package/dist/registry.js +51 -4
  202. package/dist/registry.js.map +1 -1
  203. package/dist/remediate-pipeline.d.ts +0 -3
  204. package/dist/remediate-pipeline.d.ts.map +1 -1
  205. package/dist/remediate-pipeline.js +1 -1
  206. package/dist/remediate-pipeline.js.map +1 -1
  207. package/dist/remediation.d.ts +10 -0
  208. package/dist/remediation.d.ts.map +1 -1
  209. package/dist/remediation.js +32 -0
  210. package/dist/remediation.js.map +1 -1
  211. package/dist/report.d.ts +17 -0
  212. package/dist/report.d.ts.map +1 -1
  213. package/dist/report.js +106 -20
  214. package/dist/report.js.map +1 -1
  215. package/dist/scan-worker.js +5 -3
  216. package/dist/scan-worker.js.map +1 -1
  217. package/dist/scan.d.ts.map +1 -1
  218. package/dist/scan.js +35 -6
  219. package/dist/scan.js.map +1 -1
  220. package/dist/standards-profiles.d.ts +58 -0
  221. package/dist/standards-profiles.d.ts.map +1 -0
  222. package/dist/standards-profiles.js +100 -0
  223. package/dist/standards-profiles.js.map +1 -0
  224. package/dist/types.d.ts +7 -6
  225. package/dist/types.d.ts.map +1 -1
  226. package/dist/types.js.map +1 -1
  227. package/dist/version.d.ts +1 -1
  228. package/dist/version.js +1 -1
  229. package/dist/version.js.map +1 -1
  230. package/dist/vex.d.ts +39 -0
  231. package/dist/vex.d.ts.map +1 -0
  232. package/dist/vex.js +87 -0
  233. package/dist/vex.js.map +1 -0
  234. package/dist/walk.d.ts +39 -4
  235. package/dist/walk.d.ts.map +1 -1
  236. package/dist/walk.js +62 -10
  237. package/dist/walk.js.map +1 -1
  238. package/package.json +1 -1
  239. package/src/cbom-merge.ts +38 -8
  240. package/src/cbom.ts +153 -39
  241. package/src/comments.ts +25 -6
  242. package/src/crypto-agility.ts +407 -0
  243. package/src/dependencies.ts +182 -16
  244. package/src/detect-utils.ts +133 -11
  245. package/src/detectors/age.ts +60 -0
  246. package/src/detectors/ansible.ts +140 -0
  247. package/src/detectors/bicep.ts +107 -0
  248. package/src/detectors/c.ts +31 -3
  249. package/src/detectors/cicd.ts +18 -5
  250. package/src/detectors/cloud-kms.ts +79 -25
  251. package/src/detectors/cloudformation.ts +45 -10
  252. package/src/detectors/codesign.ts +214 -0
  253. package/src/detectors/csharp.ts +13 -3
  254. package/src/detectors/dart.ts +237 -0
  255. package/src/detectors/database.ts +64 -11
  256. package/src/detectors/dkim.ts +172 -0
  257. package/src/detectors/dnssec.ts +19 -10
  258. package/src/detectors/elixir.ts +33 -2
  259. package/src/detectors/java.ts +37 -3
  260. package/src/detectors/jose.ts +19 -3
  261. package/src/detectors/jwk.ts +59 -17
  262. package/src/detectors/k8s.ts +5 -2
  263. package/src/detectors/keystore.ts +109 -0
  264. package/src/detectors/mesh.ts +21 -45
  265. package/src/detectors/messaging.ts +22 -14
  266. package/src/detectors/objc.ts +209 -0
  267. package/src/detectors/openpgp.ts +194 -0
  268. package/src/detectors/pem.ts +30 -0
  269. package/src/detectors/php.ts +9 -4
  270. package/src/detectors/pkcs11.ts +113 -0
  271. package/src/detectors/proxy.ts +236 -0
  272. package/src/detectors/pulumi.ts +106 -0
  273. package/src/detectors/rust.ts +5 -0
  274. package/src/detectors/secrets.ts +15 -26
  275. package/src/detectors/solidity.ts +176 -0
  276. package/src/detectors/source.ts +110 -5
  277. package/src/detectors/spire.ts +143 -0
  278. package/src/detectors/ssh-ca.ts +215 -0
  279. package/src/detectors/supply-chain.ts +117 -0
  280. package/src/detectors/swift.ts +149 -0
  281. package/src/detectors/terraform.ts +42 -8
  282. package/src/detectors/vault.ts +120 -0
  283. package/src/detectors/vpn.ts +20 -48
  284. package/src/detectors/weak-hash.ts +217 -0
  285. package/src/detectors/webauthn.ts +205 -0
  286. package/src/detectors/xmldsig.ts +115 -0
  287. package/src/evidence.ts +127 -4
  288. package/src/hndl.ts +1012 -0
  289. package/src/index.ts +93 -13
  290. package/src/inventory.ts +15 -7
  291. package/src/parallel.ts +21 -20
  292. package/src/registry.ts +51 -4
  293. package/src/remediate-pipeline.ts +1 -1
  294. package/src/remediation.ts +39 -0
  295. package/src/report.ts +120 -20
  296. package/src/scan-worker.ts +5 -3
  297. package/src/scan.ts +41 -6
  298. package/src/standards-profiles.ts +136 -0
  299. package/src/types.ts +18 -5
  300. package/src/version.ts +1 -1
  301. package/src/vex.ts +122 -0
  302. package/src/walk.ts +80 -12
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hndl.js","sourceRoot":"","sources":["../src/hndl.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * HNDL (\"harvest now, decrypt later\") data-risk quantifier - roadmap initiative 2.\n *\n * A crypto finding on its own answers \"what is broken\"; it does not answer \"how\n * much does it matter\". This module joins the crypto finding to the DATA it\n * protects and makes Mosca's inequality concrete, so a migration backlog can be\n * ranked by real exposure instead of by finding counts.\n *\n * Exposure per finding = crypto-vulnerability (V) x data-sensitivity (S) x\n * Mosca-factor (M), each normalised to 0..1, reported as an integer 0..100:\n *\n * - V: how breakable + how confidently detected the crypto is, discounted hard\n * when the finding is not HNDL-exposed (a signature cannot be broken\n * retroactively to reveal harvested ciphertext).\n * - S: the declared sensitivity class of the data the finding sits next to.\n * - M: the fraction of the data's protection horizon (retention / secrecy\n * lifetime + migration time) that extends BEYOND the quantum-threat\n * horizon. Mosca: concern exists when X + Y > Z.\n *\n * The data map is a declared `hndl.yml` (assets, classification, retention +\n * secrecy lifetime, path/scope bindings). Parsing is hand-rolled and\n * zero-dependency, consistent with the rest of core (ADR-0001): no YAML library\n * is pulled in. The full model is documented in docs/HNDL.md so the score is\n * contestable rather than magic.\n */\nimport { readFile } from \"node:fs/promises\";\nimport * as path from \"node:path\";\n\nimport type { Confidence, Finding, Severity } from \"./types.js\";\nimport { fingerprintFinding } from \"./baseline.js\";\nimport { defaultRegistry, detectorScope } from \"./registry.js\";\n\n/* -------------------------------------------------------------------------- */\n/* Model constants (exported so the score is contestable, not magic) */\n/* -------------------------------------------------------------------------- */\n\n/** Version of the exposure model. Bump on any weight / formula change. */\nexport const HNDL_MODEL_VERSION = \"1\" as const;\n\n/** Canonical `hndl.yml` file name discovered at a scan root. */\nexport const HNDL_FILENAME = \"hndl.yml\";\n\n/** Data sensitivity classes, least → most sensitive. Vocabulary aligned with the\n * readiness DPE (data-protection) practice. */\nexport type DataClassification = \"public\" | \"internal\" | \"confidential\" | \"regulated\";\n\nconst CLASSIFICATIONS: readonly DataClassification[] = [\n \"public\",\n \"internal\",\n \"confidential\",\n \"regulated\",\n];\n\n/**\n * Logical scope a finding belongs to, used for optional scope-bound assets. The\n * two detector scopes (\"source\" / \"config\") plus \"dependency\" (manifest\n * findings, which are not produced by a Detector).\n */\nexport type HndlScope = \"source\" | \"config\" | \"dependency\";\n\nconst HNDL_SCOPES: readonly HndlScope[] = [\"source\", \"config\", \"dependency\"];\n\n/** Crypto-vulnerability weight (V) contributed by a finding's severity. */\nexport const SEVERITY_VULNERABILITY: Record<Severity, number> = {\n critical: 1.0,\n high: 0.8,\n medium: 0.5,\n low: 0.25,\n info: 0.1,\n};\n\n/** Crypto-vulnerability weight (V) scaled by detector confidence. */\nexport const CONFIDENCE_WEIGHT: Record<Confidence, number> = {\n high: 1.0,\n medium: 0.85,\n low: 0.6,\n};\n\n/** Data-sensitivity weight (S) per classification. */\nexport const CLASSIFICATION_SENSITIVITY: Record<DataClassification, number> = {\n public: 0.1,\n internal: 0.4,\n confidential: 0.7,\n regulated: 1.0,\n};\n\n/**\n * Discount applied to V when a finding is NOT harvest-now-decrypt-later exposed\n * (e.g. a pure signature). A forged signature is a future-integrity problem, not\n * a retroactive-confidentiality one, so it barely moves the HNDL needle.\n */\nexport const NON_HNDL_DISCOUNT = 0.15;\n\n/**\n * Default years until a cryptographically-relevant quantum computer is assumed\n * to exist (Z in Mosca's inequality). 15 years is a defensible mid-point of the\n * commonly-cited Mosca / NIST window; override per-org in `hndl.yml`.\n */\nexport const DEFAULT_QUANTUM_THREAT_YEARS = 15;\n\n/**\n * Default years to complete the org's PQC migration (Y in Mosca's inequality).\n * Override per-org in `hndl.yml`.\n */\nexport const DEFAULT_MIGRATION_HORIZON_YEARS = 5;\n\n/** Classification assumed for findings that bind to no declared asset. */\nexport const DEFAULT_UNBOUND_CLASSIFICATION: DataClassification = \"internal\";\n\n/* -------------------------------------------------------------------------- */\n/* Declared data map (hndl.yml) */\n/* -------------------------------------------------------------------------- */\n\n/** A single declared data asset from `hndl.yml`. */\nexport interface HndlDataAsset {\n /** Stable id (referenced by finding exposures + the website's `data_asset.key`). */\n key: string;\n /** Human name. */\n name: string;\n classification: DataClassification;\n /** How long the data is retained, in years. */\n retentionYears: number;\n /** How long the data must remain confidential once captured, in years. */\n secrecyLifetimeYears: number;\n /** Path globs (POSIX, relative to scan root) whose findings bind to this asset. */\n paths: string[];\n /** Optional detector-scope filter: only findings of these scopes bind here. */\n scopes?: HndlScope[];\n}\n\n/** The Mosca horizons that gate the exposure model. */\nexport interface HndlHorizon {\n /** Z: years until a cryptographically-relevant quantum computer is assumed. */\n quantumThreatYears: number;\n /** Y: years to complete the org's PQC migration. */\n migrationHorizonYears: number;\n}\n\n/** Defaults applied to findings that bind to no declared asset. */\nexport interface HndlDefaults {\n classification: DataClassification;\n}\n\n/** A fully-parsed, validated `hndl.yml`. */\nexport interface HndlMap {\n version: number;\n horizon: HndlHorizon;\n defaults: HndlDefaults;\n assets: HndlDataAsset[];\n}\n\n/** Thrown when `hndl.yml` is malformed (structure or a bad known value). */\nexport class HndlError extends Error {\n override readonly name = \"HndlError\";\n /** The `hndl.yml` path the error relates to, when known. */\n readonly path: string | undefined;\n constructor(message: string, hndlPath?: string) {\n super(message);\n this.path = hndlPath;\n }\n}\n\n/* -------------------------------------------------------------------------- */\n/* Exposure results */\n/* -------------------------------------------------------------------------- */\n\n/** Full, auditable breakdown of one finding's exposure score. */\nexport interface ExposureRationale {\n /** V - crypto-vulnerability factor (0..1). */\n vulnerability: number;\n /** S - data-sensitivity factor (0..1). */\n sensitivity: number;\n /** M - Mosca factor (0..1): fraction of the protection horizon past the threat. */\n mosca: number;\n classification: DataClassification;\n retentionYears: number;\n secrecyLifetimeYears: number;\n /** X = max(retention, secrecy lifetime): the data's protection requirement. */\n secrecyHorizonYears: number;\n /** Z - quantum-threat horizon (years). */\n quantumThreatYears: number;\n /** Y - migration horizon (years). */\n migrationHorizonYears: number;\n /** (X + Y) - Z; positive means Mosca's inequality is breached. */\n moscaMarginYears: number;\n /** True when (X + Y) > Z (data captured today is exposed while still secret). */\n moscaBreach: boolean;\n /** Whether the finding is HNDL-exposed (drives {@link NON_HNDL_DISCOUNT}). */\n hndl: boolean;\n severity: Severity;\n confidence: Confidence;\n scope: HndlScope;\n /** True when the finding matched a declared asset (false = defaults applied). */\n bound: boolean;\n}\n\n/** A finding's computed exposure, keyed by fingerprint for website ingest. */\nexport interface FindingExposure {\n /** Finding identity: `finding.fingerprint` when present, else the canonical\n * `fingerprintFinding()` hash. This is the join key the website stores. */\n fingerprint: string;\n ruleId: string;\n file: string;\n /** The bound data asset's stable key, or null when unbound. */\n dataAsset: string | null;\n /** 0..100 exposure score. */\n exposureScore: number;\n rationale: ExposureRationale;\n}\n\n/** Per-asset rollup for the repo summary. */\nexport interface AssetExposure {\n key: string;\n name: string;\n classification: DataClassification;\n retentionYears: number;\n secrecyLifetimeYears: number;\n /** Number of findings bound to this asset. */\n findings: number;\n /** Highest exposure among this asset's findings. */\n maxExposure: number;\n /** True when the data's secrecy horizon outlives the quantum threat (X > Z). */\n outlivesThreat: boolean;\n}\n\n/** Repo-level HNDL summary. */\nexport interface HndlSummary {\n findingsScored: number;\n assetsDeclared: number;\n /** Declared assets that bound at least one finding. */\n assetsWithFindings: number;\n /** Declared assets whose secrecy horizon outlives the quantum threat (X > Z). */\n assetsOutlivingHorizon: number;\n /** Findings whose Mosca inequality is breached ((X + Y) > Z). */\n moscaBreaches: number;\n maxExposure: number;\n /** Rounded mean exposure across scored findings. */\n meanExposure: number;\n /** The worst findings, most-exposed first (capped). */\n topExposures: FindingExposure[];\n}\n\n/** The complete HNDL analysis of a scan. */\nexport interface HndlReport {\n modelVersion: string;\n horizon: HndlHorizon;\n /** Per-finding exposures, in input order. */\n exposures: FindingExposure[];\n /** Fingerprint → exposure, for reporters to annotate each finding. */\n byFingerprint: Map<string, FindingExposure>;\n /** Per-asset rollups. */\n assets: AssetExposure[];\n summary: HndlSummary;\n}\n\n/** How many findings the summary's `topExposures` lists. */\nconst TOP_EXPOSURES = 5;\n\n/* -------------------------------------------------------------------------- */\n/* Fingerprint + scope resolution */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Identity key for a finding's exposure. Prefers a `finding.fingerprint` field\n * when a build supplies one (another workstream is adding it to core's Finding\n * type + reporters); falls back to the canonical `fingerprintFinding()` hash\n * (`sha256(ruleId|file|normalizedSnippet)`) otherwise. INTEGRATION POINT: once\n * `Finding.fingerprint` lands, this transparently switches to it - no caller\n * change needed.\n */\nexport function findingFingerprint(f: Finding): string {\n const declared = (f as { fingerprint?: unknown }).fingerprint;\n if (typeof declared === \"string\" && declared.length > 0) return declared;\n return fingerprintFinding(f);\n}\n\n/** ruleId → detector scope, built once from the default registry. */\nlet scopeIndex: Map<string, HndlScope> | undefined;\n\nfunction ruleScopeIndex(): Map<string, HndlScope> {\n if (scopeIndex) return scopeIndex;\n const index = new Map<string, HndlScope>();\n for (const det of defaultRegistry.all()) {\n const scope = detectorScope(det) as HndlScope;\n for (const rule of det.rules ?? []) index.set(rule.id, scope);\n }\n scopeIndex = index;\n return index;\n}\n\n/**\n * The scope a finding belongs to. Dependency findings (from the manifest\n * scanner, category \"dependency\") are \"dependency\"; everything else is looked up\n * by ruleId in the detector registry, defaulting to \"source\".\n */\nexport function findingScope(f: Finding): HndlScope {\n if (f.category === \"dependency\") return \"dependency\";\n return ruleScopeIndex().get(f.ruleId) ?? \"source\";\n}\n\n/* -------------------------------------------------------------------------- */\n/* Glob matching (hand-rolled, zero-dependency) */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Match a POSIX path against a glob supporting `**` (any path segments incl.\n * `/`), `*` (any run of non-`/` chars), and `?` (a single non-`/` char). A\n * trailing `/**` also matches the directory itself. Everything else is literal.\n */\nexport function globMatch(glob: string, filePath: string): boolean {\n return globToRegExp(glob).test(filePath);\n}\n\nconst globCache = new Map<string, RegExp>();\n\nfunction globToRegExp(glob: string): RegExp {\n const cached = globCache.get(glob);\n if (cached) return cached;\n let re = \"^\";\n for (let i = 0; i < glob.length; i++) {\n const ch = glob[i] as string;\n if (ch === \"*\") {\n if (glob[i + 1] === \"*\") {\n // `**` - any number of characters including path separators. Consume a\n // following `/` so `a/**/b` matches `a/b` (zero segments) too.\n i++;\n if (glob[i + 1] === \"/\") i++;\n re += \".*\";\n } else {\n re += \"[^/]*\";\n }\n } else if (ch === \"?\") {\n re += \"[^/]\";\n } else if (\"\\\\^$.|+()[]{}\".includes(ch)) {\n re += `\\\\${ch}`;\n } else {\n re += ch;\n }\n }\n re += \"$\";\n const compiled = new RegExp(re);\n globCache.set(glob, compiled);\n return compiled;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Exposure math */\n/* -------------------------------------------------------------------------- */\n\nfunction clamp01(x: number): number {\n return x < 0 ? 0 : x > 1 ? 1 : x;\n}\n\n/** V - crypto-vulnerability factor for a finding (0..1). */\nexport function vulnerabilityFactor(f: Finding): number {\n const base = SEVERITY_VULNERABILITY[f.severity] * CONFIDENCE_WEIGHT[f.confidence];\n return clamp01(base * (f.hndl ? 1 : NON_HNDL_DISCOUNT));\n}\n\n/**\n * M - the Mosca factor (0..1). `X` is the data's protection horizon\n * (max of retention + secrecy lifetime), `Y` the migration horizon, `Z` the\n * quantum-threat horizon. M is the fraction of `X + Y` that falls after `Z`:\n * 0 when the threat is beyond the whole horizon, 1 when the threat is already\n * here. Mosca's inequality (X + Y > Z) is exactly `M > 0`.\n */\nexport function moscaFactor(secrecyHorizonYears: number, horizon: HndlHorizon): number {\n const span = secrecyHorizonYears + horizon.migrationHorizonYears;\n if (span <= 0) return 0;\n const margin = span - horizon.quantumThreatYears;\n return clamp01(margin / span);\n}\n\ninterface ScoreInput {\n vulnerability: number;\n classification: DataClassification;\n retentionYears: number;\n secrecyLifetimeYears: number;\n bound: boolean;\n}\n\nfunction scoreFinding(f: Finding, input: ScoreInput, horizon: HndlHorizon): FindingExposure {\n const sensitivity = CLASSIFICATION_SENSITIVITY[input.classification];\n const secrecyHorizonYears = Math.max(input.retentionYears, input.secrecyLifetimeYears);\n const mosca = moscaFactor(secrecyHorizonYears, horizon);\n const exposureScore = Math.round(100 * clamp01(input.vulnerability * sensitivity * mosca));\n const moscaMarginYears =\n secrecyHorizonYears + horizon.migrationHorizonYears - horizon.quantumThreatYears;\n const rationale: ExposureRationale = {\n vulnerability: round3(input.vulnerability),\n sensitivity: round3(sensitivity),\n mosca: round3(mosca),\n classification: input.classification,\n retentionYears: input.retentionYears,\n secrecyLifetimeYears: input.secrecyLifetimeYears,\n secrecyHorizonYears,\n quantumThreatYears: horizon.quantumThreatYears,\n migrationHorizonYears: horizon.migrationHorizonYears,\n moscaMarginYears,\n moscaBreach: moscaMarginYears > 0,\n hndl: f.hndl,\n severity: f.severity,\n confidence: f.confidence,\n scope: findingScope(f),\n bound: input.bound,\n };\n return {\n fingerprint: findingFingerprint(f),\n ruleId: f.ruleId,\n file: f.location.file,\n dataAsset: null,\n exposureScore,\n rationale,\n };\n}\n\nfunction round3(x: number): number {\n return Math.round(x * 1000) / 1000;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Binding + top-level compute */\n/* -------------------------------------------------------------------------- */\n\n/** Assets whose path globs + optional scope filter match a finding. */\nfunction matchingAssets(f: Finding, map: HndlMap, scope: HndlScope): HndlDataAsset[] {\n const out: HndlDataAsset[] = [];\n for (const asset of map.assets) {\n if (asset.scopes && !asset.scopes.includes(scope)) continue;\n if (asset.paths.some((g) => globMatch(g, f.location.file))) out.push(asset);\n }\n return out;\n}\n\n/**\n * Compute HNDL exposure for a set of findings against a declared data map.\n *\n * A finding binds to every declared asset whose path glob (and optional scope\n * filter) matches its file; when several match, the WORST-CASE (highest)\n * exposure is chosen and its asset recorded, since risk ranking should not be\n * diluted by an incidental low-sensitivity overlap. A finding that binds to no\n * asset is still scored, using the map's `defaults.classification` and the\n * global horizons, and flagged `bound: false` so it is visibly a fallback. Its\n * secrecy lifetime is assumed to be the quantum-threat horizon Z (the\n * minimum-concern horizon; see {@link scoreFinding} call below and docs/HNDL.md\n * §4), so the fallback classification produces a real, rankable exposure rather\n * than a dead 0.\n *\n * Purely additive: it never mutates findings and never affects a scan's exit\n * code.\n */\nexport function computeHndl(findings: readonly Finding[], map: HndlMap): HndlReport {\n const exposures: FindingExposure[] = [];\n const byFingerprint = new Map<string, FindingExposure>();\n const assetFindings = new Map<string, number>();\n const assetMax = new Map<string, number>();\n\n for (const f of findings) {\n const vulnerability = vulnerabilityFactor(f);\n const scope = findingScope(f);\n const candidates = matchingAssets(f, map, scope);\n\n let best: FindingExposure;\n if (candidates.length === 0) {\n best = scoreFinding(\n f,\n {\n vulnerability,\n classification: map.defaults.classification,\n // Unbound: the data's lifetime is unknown, so we cannot read X off a\n // declared asset. Assuming X = 0 would drive M (hence the score) to a\n // dead 0 for EVERY unbound finding under any sane horizon, making the\n // documented `defaults.classification` fallback unrankable. Instead we\n // assume the MINIMUM-CONCERN horizon: data captured today must stay\n // confidential at least until the quantum threat arrives (X = Z). That\n // yields M = Y / (Y + Z) - a small but non-zero, rankable exposure that\n // never exceeds a declared long-lived asset's and self-adjusts to any\n // per-org horizon override. Retention stays 0 (genuinely unknown); the\n // secrecy lifetime carries the assumption. See docs/HNDL.md §4.\n retentionYears: 0,\n secrecyLifetimeYears: map.horizon.quantumThreatYears,\n bound: false,\n },\n map.horizon,\n );\n } else {\n let bestAsset: HndlDataAsset | undefined;\n best = undefined as unknown as FindingExposure;\n for (const asset of candidates) {\n const scored = scoreFinding(\n f,\n {\n vulnerability,\n classification: asset.classification,\n retentionYears: asset.retentionYears,\n secrecyLifetimeYears: asset.secrecyLifetimeYears,\n bound: true,\n },\n map.horizon,\n );\n if (!bestAsset || scored.exposureScore > best.exposureScore) {\n best = scored;\n bestAsset = asset;\n }\n }\n best.dataAsset = bestAsset!.key;\n assetFindings.set(bestAsset!.key, (assetFindings.get(bestAsset!.key) ?? 0) + 1);\n assetMax.set(bestAsset!.key, Math.max(assetMax.get(bestAsset!.key) ?? 0, best.exposureScore));\n }\n\n exposures.push(best);\n byFingerprint.set(best.fingerprint, best);\n }\n\n const assets: AssetExposure[] = map.assets.map((a) => ({\n key: a.key,\n name: a.name,\n classification: a.classification,\n retentionYears: a.retentionYears,\n secrecyLifetimeYears: a.secrecyLifetimeYears,\n findings: assetFindings.get(a.key) ?? 0,\n maxExposure: assetMax.get(a.key) ?? 0,\n outlivesThreat:\n Math.max(a.retentionYears, a.secrecyLifetimeYears) > map.horizon.quantumThreatYears,\n }));\n\n const scores = exposures.map((e) => e.exposureScore);\n const maxExposure = scores.reduce((m, s) => Math.max(m, s), 0);\n const meanExposure =\n scores.length > 0 ? Math.round(scores.reduce((a, b) => a + b, 0) / scores.length) : 0;\n const topExposures = [...exposures]\n .sort((a, b) => b.exposureScore - a.exposureScore || a.fingerprint.localeCompare(b.fingerprint))\n .slice(0, TOP_EXPOSURES);\n\n const summary: HndlSummary = {\n findingsScored: exposures.length,\n assetsDeclared: map.assets.length,\n assetsWithFindings: assets.filter((a) => a.findings > 0).length,\n assetsOutlivingHorizon: assets.filter((a) => a.outlivesThreat).length,\n moscaBreaches: exposures.filter((e) => e.rationale.moscaBreach).length,\n maxExposure,\n meanExposure,\n topExposures,\n };\n\n return {\n modelVersion: HNDL_MODEL_VERSION,\n horizon: map.horizon,\n exposures,\n byFingerprint,\n assets,\n summary,\n };\n}\n\n/* -------------------------------------------------------------------------- */\n/* hndl.yml parsing (hand-rolled YAML subset) */\n/* -------------------------------------------------------------------------- */\n\ninterface YamlLine {\n indent: number;\n content: string;\n /** 1-based source line number, for error messages. */\n n: number;\n}\n\n/** Strip an inline `# comment` that begins after whitespace, outside quotes. */\nfunction stripInlineComment(text: string): string {\n let quote: string | undefined;\n for (let i = 0; i < text.length; i++) {\n const ch = text[i];\n if (quote) {\n if (ch === quote) quote = undefined;\n continue;\n }\n if (ch === '\"' || ch === \"'\") {\n quote = ch;\n continue;\n }\n if (ch === \"#\" && (i === 0 || /\\s/.test(text[i - 1] as string))) {\n return text.slice(0, i);\n }\n }\n return text;\n}\n\n/** Tokenise text into non-blank, non-comment lines with their indent depth. */\nfunction tokenizeYaml(text: string, file?: string): YamlLine[] {\n const lines: YamlLine[] = [];\n const raw = text.split(/\\r?\\n/);\n for (let i = 0; i < raw.length; i++) {\n const line = raw[i] as string;\n if (line.includes(\"\\t\")) {\n throw new HndlError(`tabs are not allowed for indentation (line ${i + 1})`, file);\n }\n const stripped = stripInlineComment(line).replace(/\\s+$/, \"\");\n if (stripped.trim() === \"\") continue;\n const indent = stripped.length - stripped.trimStart().length;\n lines.push({ indent, content: stripped.trimStart(), n: i + 1 });\n }\n return lines;\n}\n\n/** True when `content` opens a `key:` mapping entry (colon outside quotes). */\nfunction isKeyLine(content: string): boolean {\n return /^[A-Za-z0-9_.-]+\\s*:(\\s|$)/.test(content);\n}\n\nfunction splitKey(content: string, file: string, n: number): { key: string; value: string } {\n const idx = content.indexOf(\":\");\n if (idx < 0) throw new HndlError(`expected \"key: value\" (line ${n})`, file);\n return { key: content.slice(0, idx).trim(), value: content.slice(idx + 1).trim() };\n}\n\n/** Coerce a scalar token: quoted string, boolean, number, or bare string. */\nfunction parseScalar(token: string): string | number | boolean {\n if (token.length >= 2) {\n const q = token[0];\n if ((q === '\"' || q === \"'\") && token[token.length - 1] === q) {\n return token.slice(1, -1);\n }\n }\n if (token === \"true\") return true;\n if (token === \"false\") return false;\n if (/^-?\\d+(\\.\\d+)?$/.test(token)) return Number(token);\n return token;\n}\n\n/**\n * Parse a mapping/sequence VALUE token: either an inline-flow list\n * (`[a, \"b\", c]`, `[]`) or a plain scalar. Only flat flow lists of scalars are\n * supported - enough for `paths: [...]` / `scopes: [...]` without a full YAML\n * flow grammar.\n */\nfunction parseValueToken(token: string, file: string, n: number): YamlValue {\n if (token.startsWith(\"[\")) {\n if (!token.endsWith(\"]\")) {\n throw new HndlError(`unterminated inline list (line ${n})`, file);\n }\n return parseFlowList(token.slice(1, -1), file, n);\n }\n return parseScalar(token);\n}\n\n/** Split a flow-list body on top-level commas (quote-aware) → scalar elements. */\nfunction parseFlowList(body: string, file: string, n: number): YamlValue[] {\n const out: YamlValue[] = [];\n let cur = \"\";\n let quote: string | undefined;\n for (let i = 0; i < body.length; i++) {\n const ch = body[i] as string;\n if (quote) {\n cur += ch;\n if (ch === quote) quote = undefined;\n continue;\n }\n if (ch === '\"' || ch === \"'\") {\n quote = ch;\n cur += ch;\n continue;\n }\n if (ch === \",\") {\n out.push(cur.trim());\n cur = \"\";\n continue;\n }\n cur += ch;\n }\n if (quote) throw new HndlError(`unterminated string in inline list (line ${n})`, file);\n const last = cur.trim();\n // A trailing empty segment only when the list itself is empty (`[]`).\n if (last !== \"\" || out.length > 0) out.push(last);\n return out.filter((t) => t !== \"\").map((t) => parseScalar(t as string));\n}\n\ntype YamlValue = string | number | boolean | null | YamlValue[] | { [k: string]: YamlValue };\n\n/** Recursive-descent parse of the tokenised lines into a generic value. */\nfunction parseYaml(text: string, file: string): YamlValue {\n const lines = tokenizeYaml(text, file);\n if (lines.length === 0) return {};\n\n function parseNode(i: number, indent: number): [YamlValue, number] {\n const first = lines[i] as YamlLine;\n if (first.content === \"-\" || first.content.startsWith(\"- \")) {\n return parseSeq(i, indent);\n }\n return parseMap(i, indent);\n }\n\n function parseSeq(start: number, indent: number): [YamlValue[], number] {\n const arr: YamlValue[] = [];\n let i = start;\n while (\n i < lines.length &&\n (lines[i] as YamlLine).indent === indent &&\n ((lines[i] as YamlLine).content === \"-\" || (lines[i] as YamlLine).content.startsWith(\"- \"))\n ) {\n const line = lines[i] as YamlLine;\n const rest = line.content === \"-\" ? \"\" : line.content.slice(2).trim();\n const itemIndent = indent + 2;\n if (rest === \"\") {\n if (i + 1 < lines.length && (lines[i + 1] as YamlLine).indent > indent) {\n const [val, next] = parseNode(i + 1, (lines[i + 1] as YamlLine).indent);\n arr.push(val);\n i = next;\n } else {\n arr.push(null);\n i++;\n }\n } else if (isKeyLine(rest)) {\n // Map item introduced by the dash: rewrite this line as its first key at\n // the deeper indent, then let parseMap consume it + aligned siblings.\n lines[i] = { indent: itemIndent, content: rest, n: line.n };\n const [val, next] = parseMap(i, itemIndent);\n arr.push(val);\n i = next;\n } else {\n arr.push(parseValueToken(rest, file, line.n));\n i++;\n }\n }\n return [arr, i];\n }\n\n function parseMap(start: number, indent: number): [{ [k: string]: YamlValue }, number] {\n const obj: { [k: string]: YamlValue } = {};\n let i = start;\n while (\n i < lines.length &&\n (lines[i] as YamlLine).indent === indent &&\n !(lines[i] as YamlLine).content.startsWith(\"- \") &&\n (lines[i] as YamlLine).content !== \"-\"\n ) {\n const line = lines[i] as YamlLine;\n const { key, value } = splitKey(line.content, file, line.n);\n if (value !== \"\") {\n obj[key] = parseValueToken(value, file, line.n);\n i++;\n } else if (i + 1 < lines.length && (lines[i + 1] as YamlLine).indent > indent) {\n const [val, next] = parseNode(i + 1, (lines[i + 1] as YamlLine).indent);\n obj[key] = val;\n i = next;\n } else {\n obj[key] = null;\n i++;\n }\n }\n return [obj, i];\n }\n\n const [value] = parseNode(0, (lines[0] as YamlLine).indent);\n return value;\n}\n\n/* -------------------------------------------------------------------------- */\n/* hndl.yml validation → HndlMap */\n/* -------------------------------------------------------------------------- */\n\nfunction isObject(v: YamlValue): v is { [k: string]: YamlValue } {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\nfunction asString(v: YamlValue, what: string, file: string): string {\n if (typeof v !== \"string\" || v.length === 0) {\n throw new HndlError(`${what} must be a non-empty string`, file);\n }\n return v;\n}\n\nfunction asNonNegNumber(v: YamlValue, what: string, file: string): number {\n if (typeof v !== \"number\" || !Number.isFinite(v) || v < 0) {\n throw new HndlError(`${what} must be a non-negative number`, file);\n }\n return v;\n}\n\nfunction asClassification(v: YamlValue, what: string, file: string): DataClassification {\n if (typeof v !== \"string\" || !(CLASSIFICATIONS as readonly string[]).includes(v)) {\n throw new HndlError(`${what} must be one of: ${CLASSIFICATIONS.join(\", \")}`, file);\n }\n return v as DataClassification;\n}\n\nfunction asStringList(v: YamlValue, what: string, file: string): string[] {\n if (!Array.isArray(v) || v.some((x) => typeof x !== \"string\" || x.length === 0)) {\n throw new HndlError(`${what} must be a list of non-empty strings`, file);\n }\n return v as string[];\n}\n\n/**\n * Validate a parsed `hndl.yml` object into a typed {@link HndlMap}. Applies\n * defaults for `version`, `horizon`, and `defaults`; requires each asset to have\n * a unique `key`, a `name`, a valid `classification`, non-negative retention +\n * secrecy lifetime, and at least one path glob.\n */\nexport function parseHndlMap(text: string, file = HNDL_FILENAME): HndlMap {\n const root = parseYaml(text, file);\n if (!isObject(root)) {\n throw new HndlError(`hndl.yml must be a mapping at the top level`, file);\n }\n\n let version = 1;\n if (\"version\" in root) {\n const v = root[\"version\"];\n if (typeof v !== \"number\" || !Number.isInteger(v)) {\n throw new HndlError(`\"version\" must be an integer`, file);\n }\n version = v;\n }\n\n const horizon: HndlHorizon = {\n quantumThreatYears: DEFAULT_QUANTUM_THREAT_YEARS,\n migrationHorizonYears: DEFAULT_MIGRATION_HORIZON_YEARS,\n };\n if (\"horizon\" in root && root[\"horizon\"] !== null) {\n const h = root[\"horizon\"];\n if (!isObject(h)) throw new HndlError(`\"horizon\" must be a mapping`, file);\n if (\"quantum_threat_years\" in h) {\n horizon.quantumThreatYears = asNonNegNumber(\n h[\"quantum_threat_years\"],\n `\"horizon.quantum_threat_years\"`,\n file,\n );\n }\n if (\"migration_horizon_years\" in h) {\n horizon.migrationHorizonYears = asNonNegNumber(\n h[\"migration_horizon_years\"],\n `\"horizon.migration_horizon_years\"`,\n file,\n );\n }\n }\n\n const defaults: HndlDefaults = { classification: DEFAULT_UNBOUND_CLASSIFICATION };\n if (\"defaults\" in root && root[\"defaults\"] !== null) {\n const d = root[\"defaults\"];\n if (!isObject(d)) throw new HndlError(`\"defaults\" must be a mapping`, file);\n if (\"classification\" in d) {\n defaults.classification = asClassification(\n d[\"classification\"],\n `\"defaults.classification\"`,\n file,\n );\n }\n }\n\n const rawAssets = \"assets\" in root ? root[\"assets\"] : [];\n if (!Array.isArray(rawAssets)) {\n throw new HndlError(`\"assets\" must be a list`, file);\n }\n const assets: HndlDataAsset[] = [];\n const seenKeys = new Set<string>();\n for (let idx = 0; idx < rawAssets.length; idx++) {\n const a = rawAssets[idx];\n if (!isObject(a)) throw new HndlError(`assets[${idx}] must be a mapping`, file);\n const key = asString(a[\"key\"], `assets[${idx}].key`, file);\n if (seenKeys.has(key)) throw new HndlError(`duplicate asset key \"${key}\"`, file);\n seenKeys.add(key);\n const asset: HndlDataAsset = {\n key,\n name: asString(a[\"name\"], `assets[${idx}].name`, file),\n classification: asClassification(a[\"classification\"], `assets[${idx}].classification`, file),\n retentionYears: asNonNegNumber(a[\"retention_years\"], `assets[${idx}].retention_years`, file),\n secrecyLifetimeYears: asNonNegNumber(\n a[\"secrecy_lifetime_years\"],\n `assets[${idx}].secrecy_lifetime_years`,\n file,\n ),\n paths: asStringList(a[\"paths\"], `assets[${idx}].paths`, file),\n };\n if (asset.paths.length === 0) {\n throw new HndlError(`assets[${idx}].paths must list at least one glob`, file);\n }\n if (\"scopes\" in a && a[\"scopes\"] !== null) {\n const scopes = asStringList(a[\"scopes\"], `assets[${idx}].scopes`, file);\n for (const s of scopes) {\n if (!(HNDL_SCOPES as readonly string[]).includes(s)) {\n throw new HndlError(\n `assets[${idx}].scopes: \"${s}\" must be one of: ${HNDL_SCOPES.join(\", \")}`,\n file,\n );\n }\n }\n asset.scopes = scopes as HndlScope[];\n }\n assets.push(asset);\n }\n\n return { version, horizon, defaults, assets };\n}\n\n/**\n * Load and validate the `hndl.yml` for a scan. By default reads\n * `<root>/hndl.yml`; pass an explicit `*.yml` path to read a named file. A\n * missing file is always an error here (the caller opted into `--hndl`).\n *\n * @throws {HndlError} On a missing file, unreadable file, or malformed content.\n */\nexport async function loadHndlMap(root: string): Promise<{ map: HndlMap; path: string }> {\n const base = path.basename(root);\n const file =\n base === HNDL_FILENAME || base.endsWith(\".yml\") || base.endsWith(\".yaml\")\n ? path.resolve(root)\n : path.resolve(root, HNDL_FILENAME);\n let text: string;\n try {\n text = await readFile(file, \"utf8\");\n } catch {\n throw new HndlError(\n `hndl.yml not found: ${file} (run \"qscan hndl init\" to scaffold one)`,\n file,\n );\n }\n return { map: parseHndlMap(text, file), path: file };\n}\n\n/* -------------------------------------------------------------------------- */\n/* hndl.yml scaffolding (`qscan hndl init`) */\n/* -------------------------------------------------------------------------- */\n\n/** First path segment of a POSIX file path, or \".\" for a root-level file. */\nfunction topDir(file: string): string {\n const slash = file.indexOf(\"/\");\n return slash < 0 ? \".\" : file.slice(0, slash);\n}\n\n/** A URL/key-safe slug for a directory name. */\nfunction slugify(dir: string): string {\n const slug = dir\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n return slug.length > 0 ? slug : \"root\";\n}\n\n/**\n * Scaffold an `hndl.yml` document seeded from a scan's findings. Config-scope,\n * HNDL-exposed findings are the crypto-to-data join points (KMS, secrets-at-rest,\n * database TDE, brokers, JOSE/JWE), so each directory that contains one becomes a\n * proposed asset stub the user fills in. The returned string is valid `hndl.yml`\n * (it round-trips through {@link parseHndlMap}); the classification / retention /\n * secrecy values are conservative placeholders the user is expected to correct.\n */\nexport function scaffoldHndlYaml(findings: readonly Finding[]): string {\n // Group data-adjacent findings by their top-level directory.\n const byDir = new Map<string, Set<string>>();\n for (const f of findings) {\n if (findingScope(f) !== \"config\" || !f.hndl) continue;\n const dir = topDir(f.location.file);\n let rules = byDir.get(dir);\n if (!rules) {\n rules = new Set<string>();\n byDir.set(dir, rules);\n }\n rules.add(f.ruleId);\n }\n\n const lines: string[] = [\n \"# hndl.yml - HNDL (harvest-now-decrypt-later) data map for this repo.\",\n \"#\",\n \"# qScan joins each crypto finding to the data it protects and scores exposure as\",\n \"# crypto-vulnerability x data-sensitivity x Mosca-factor (retention + secrecy\",\n \"# lifetime vs the quantum-threat horizon). See docs/HNDL.md for the model.\",\n \"#\",\n \"# Fill in the assets below: correct the classification, the retention_years and\",\n \"# secrecy_lifetime_years, and the path globs. Delete stubs that do not apply.\",\n \"version: 1\",\n \"\",\n \"horizon:\",\n ` quantum_threat_years: ${DEFAULT_QUANTUM_THREAT_YEARS} # Z: years until a CRQC is assumed`,\n ` migration_horizon_years: ${DEFAULT_MIGRATION_HORIZON_YEARS} # Y: years to finish your PQC migration`,\n \"\",\n \"defaults:\",\n ` classification: ${DEFAULT_UNBOUND_CLASSIFICATION} # applied to findings that match no asset below`,\n \"\",\n \"assets:\",\n ];\n\n if (byDir.size === 0) {\n lines.push(\n \" # No data-adjacent (config-scope, HNDL) findings were detected to seed from.\",\n \" # Declare your data assets manually, for example:\",\n \" - key: customer-pii\",\n \" name: Customer PII\",\n \" classification: regulated\",\n \" retention_years: 7\",\n \" secrecy_lifetime_years: 25\",\n \" paths:\",\n ' - \"src/**\"',\n );\n } else {\n const dirs = [...byDir.keys()].sort();\n for (const dir of dirs) {\n const rules = [...(byDir.get(dir) as Set<string>)].sort();\n const glob = dir === \".\" ? \"*\" : `${dir}/**`;\n lines.push(\n ` # detected data-adjacent crypto here: ${rules.join(\", \")}`,\n ` - key: ${slugify(dir)}`,\n ` name: ${dir === \".\" ? \"Repository root\" : dir}`,\n \" classification: confidential # TODO: public | internal | confidential | regulated\",\n \" retention_years: 7 # TODO: how long the data is kept\",\n \" secrecy_lifetime_years: 10 # TODO: how long it must stay confidential\",\n \" paths:\",\n ` - \"${glob}\"`,\n );\n }\n }\n\n return `${lines.join(\"\\n\")}\\n`;\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -28,32 +28,39 @@ export { configToggleCodemod } from "./codemods/config-toggle.js";
28
28
  export { remediateFindings } from "./remediate-pipeline.js";
29
29
  export type { RemediateOptions, RemediationResult, VerifiedPatch, RejectedPatch, } from "./remediate-pipeline.js";
30
30
  export { AbortError, BudgetExceededError } from "./errors.js";
31
- export { scanParallel, mergeChunkResults, chunkByBytes } from "./parallel.js";
32
- export type { ScanChunk, ChunkResult, SizedFile } from "./parallel.js";
33
- export { DetectorRegistry, defaultRegistry, detectorScope } from "./registry.js";
34
- export type { RuleCatalogEntry } from "./registry.js";
31
+ export { scanParallel } from "./parallel.js";
32
+ export type { ScanChunk } from "./parallel.js";
33
+ export { DetectorRegistry, defaultRegistry } from "./registry.js";
35
34
  export { fingerprintFinding, baselineFromFindings, applyBaseline, loadBaseline, saveBaseline, BASELINE_VERSION, } from "./baseline.js";
36
35
  export type { Baseline } from "./baseline.js";
37
36
  export { changedFiles } from "./changed.js";
38
37
  export { loadConfig, ConfigError, CONFIG_FILENAME } from "./config.js";
39
38
  export type { QuantakryptoFileConfig, LoadConfigResult } from "./config.js";
40
- export { walkFiles, isBinaryPath, isGeneratedPath, looksMinified } from "./walk.js";
39
+ export { HNDL_MODEL_VERSION, HNDL_FILENAME, SEVERITY_VULNERABILITY, CONFIDENCE_WEIGHT, CLASSIFICATION_SENSITIVITY, NON_HNDL_DISCOUNT, DEFAULT_QUANTUM_THREAT_YEARS, DEFAULT_MIGRATION_HORIZON_YEARS, DEFAULT_UNBOUND_CLASSIFICATION, HndlError, computeHndl, vulnerabilityFactor, moscaFactor, globMatch, findingFingerprint, findingScope, parseHndlMap, loadHndlMap, scaffoldHndlYaml, } from "./hndl.js";
40
+ export type { DataClassification, HndlScope, HndlDataAsset, HndlHorizon, HndlDefaults, HndlMap, ExposureRationale, FindingExposure, AssetExposure, HndlSummary, HndlReport, } from "./hndl.js";
41
+ export { walkFiles, isBinaryPath, looksMinified } from "./walk.js";
41
42
  export { isAnalyzableSource, ANALYZABLE_SOURCE_EXTENSIONS, ANALYZABLE_LANGUAGES_LABEL, } from "./detect-utils.js";
42
43
  export { buildInventory } from "./inventory.js";
43
44
  export { vulnerableDependencies, DEP_VULNERABLE_RULE, isManifestFile } from "./dependencies.js";
44
45
  export { SEVERITY_ORDER, severityRank, meetsThreshold, sarifLevel } from "./severity.js";
45
- export { toSarif, toJson, formatSummary, formatTierGuidance } from "./report.js";
46
+ export { toSarif, toJson, formatSummary, formatTierGuidance, formatProfileGuidance, } from "./report.js";
46
47
  export type { ReportOptions } from "./report.js";
47
48
  export { toCbom } from "./cbom.js";
48
49
  export type { CycloneDxBom, CbomComponent } from "./cbom.js";
49
50
  export { mergeCboms } from "./cbom-merge.js";
50
- export { buildReadinessReport } from "./evidence.js";
51
- export type { ReadinessReport, EvidenceFinding, ReadinessReportOptions } from "./evidence.js";
52
- export { buildPolicyMapping, parseCryptoPolicy, verdictForAlgorithm } from "./policy.js";
51
+ export { toOpenVex } from "./vex.js";
52
+ export type { OpenVexDocument, OpenVexStatement, OpenVexOptions } from "./vex.js";
53
+ export { buildCryptoAgilityManifest, validateCryptoAgilityManifest, CRYPTO_AGILITY_MANIFEST_VERSION, CRYPTO_AGILITY_WELL_KNOWN_PATH, } from "./crypto-agility.js";
54
+ export type { CryptoAgilityManifest, CryptoAgilityManifestOptions, CryptoAgilityPosture, CryptoAgilityCbomSummary, CryptoAgilityFamily, CryptoAgilityPolicy, ManifestValidation, } from "./crypto-agility.js";
55
+ export { buildReadinessReport, signReadinessReport, verifyReadinessReport } from "./evidence.js";
56
+ export type { ReadinessReport, EvidenceFinding, ReadinessReportOptions, EvidenceSigner, SignEvidenceOptions, VerifyReadinessResult, } from "./evidence.js";
57
+ export { buildPolicyMapping, parseCryptoPolicy } from "./policy.js";
53
58
  export type { CryptoPolicy, PolicyVerdict, PolicyMapping, PolicyFindingVerdict } from "./policy.js";
54
- export { remediationFor, remediationForTier, TIER_PARAMS, STATEFUL_HBS_NOTE, PQC_TRANSITION_NOTE, statefulHbsApplies, } from "./remediation.js";
59
+ export { remediationFor, remediationForTier, remediationForProfile, TIER_PARAMS, STATEFUL_HBS_NOTE, PQC_TRANSITION_NOTE, statefulHbsApplies, } from "./remediation.js";
55
60
  export type { SecurityTier } from "./remediation.js";
56
- export { PQC_STANDARDS, standardsReviewStatus } from "./standards.js";
61
+ export { PQC_STANDARDS } from "./standards.js";
57
62
  export type { PqcStandards, StandardsCitation, StandardsReviewStatus } from "./standards.js";
63
+ export { STANDARDS_PROFILES, DEFAULT_PROFILE_ID, standardsProfileIds, getStandardsProfile, defaultStandardsProfile, } from "./standards-profiles.js";
64
+ export type { StandardsProfile, HybridStance } from "./standards-profiles.js";
58
65
  export { CWE_BROKEN_CRYPTO, CWE_WEAK_STRENGTH, CWE_CERT_VALIDATION, CWE_HARDCODED_KEY, CWE_RISKY_PRIMITIVE, } from "./cwe.js";
59
66
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,cAAc,YAAY,CAAC;AAG3B,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG5C,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAGzE,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC7D,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,YAAY,EACV,YAAY,EACZ,eAAe,EACf,aAAa,EACb,KAAK,EACL,WAAW,GACZ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACvF,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACrE,YAAY,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,YAAY,EACV,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,aAAa,GACd,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAG9D,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC9E,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAGvE,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACjF,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGtD,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,gBAAgB,GACjB,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAG9C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAG5C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACvE,YAAY,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAG5E,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAGpF,OAAO,EACL,kBAAkB,EAClB,4BAA4B,EAC5B,0BAA0B,GAC3B,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAKhD,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGhG,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGzF,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjF,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE7D,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAG9F,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACzF,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAGpG,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,WAAW,EACX,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGrD,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACtE,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAG7F,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -24,18 +24,22 @@ export { configToggleCodemod } from "./codemods/config-toggle.js";
24
24
  export { remediateFindings } from "./remediate-pipeline.js";
25
25
  // Scan cancellation / work-budget errors.
26
26
  export { AbortError, BudgetExceededError } from "./errors.js";
27
- // Parallel scanning (worker_threads pool) + pure merge/chunk helpers.
28
- export { scanParallel, mergeChunkResults, chunkByBytes } from "./parallel.js";
29
- // Detector registry (plugin point) + helpers + the rule catalog.
30
- export { DetectorRegistry, defaultRegistry, detectorScope } from "./registry.js";
27
+ // Parallel scanning (worker_threads pool). The chunk/merge helpers and their
28
+ // SizedFile/ChunkResult types are internal plumbing (not part of the public API).
29
+ export { scanParallel } from "./parallel.js";
30
+ // Detector registry (plugin point). `detectorScope` and the rule-catalog type are
31
+ // internal.
32
+ export { DetectorRegistry, defaultRegistry } from "./registry.js";
31
33
  // Canonical baseline (shared by qScan + the Action).
32
34
  export { fingerprintFinding, baselineFromFindings, applyBaseline, loadBaseline, saveBaseline, BASELINE_VERSION, } from "./baseline.js";
33
35
  // Incremental scanning: changed-files helper (git-aware, tolerant).
34
36
  export { changedFiles } from "./changed.js";
35
37
  // Optional `quantakrypto.config.json` loader (P2-9; see docs/CONFIG.md).
36
38
  export { loadConfig, ConfigError, CONFIG_FILENAME } from "./config.js";
39
+ // HNDL (harvest-now-decrypt-later) data-risk quantifier (see docs/HNDL.md).
40
+ export { HNDL_MODEL_VERSION, HNDL_FILENAME, SEVERITY_VULNERABILITY, CONFIDENCE_WEIGHT, CLASSIFICATION_SENSITIVITY, NON_HNDL_DISCOUNT, DEFAULT_QUANTUM_THREAT_YEARS, DEFAULT_MIGRATION_HORIZON_YEARS, DEFAULT_UNBOUND_CLASSIFICATION, HndlError, computeHndl, vulnerabilityFactor, moscaFactor, globMatch, findingFingerprint, findingScope, parseHndlMap, loadHndlMap, scaffoldHndlYaml, } from "./hndl.js";
37
41
  // Filesystem walker (relative POSIX paths, default ignores, size/binary filters).
38
- export { walkFiles, isBinaryPath, isGeneratedPath, looksMinified } from "./walk.js";
42
+ export { walkFiles, isBinaryPath, looksMinified } from "./walk.js";
39
43
  // Analyzable-language coverage (which source languages the scanner inspects).
40
44
  export { isAnalyzableSource, ANALYZABLE_SOURCE_EXTENSIONS, ANALYZABLE_LANGUAGES_LABEL, } from "./detect-utils.js";
41
45
  // Inventory + readiness score.
@@ -47,19 +51,25 @@ export { vulnerableDependencies, DEP_VULNERABLE_RULE, isManifestFile } from "./d
47
51
  // Severity utilities (ordering, threshold, SARIF level) — shared across tools.
48
52
  export { SEVERITY_ORDER, severityRank, meetsThreshold, sarifLevel } from "./severity.js";
49
53
  // Reporters.
50
- export { toSarif, toJson, formatSummary, formatTierGuidance } from "./report.js";
54
+ export { toSarif, toJson, formatSummary, formatTierGuidance, formatProfileGuidance, } from "./report.js";
51
55
  // CycloneDX 1.6 cryptographic bill of materials (CBOM) export.
52
56
  export { toCbom } from "./cbom.js";
53
57
  // Merge multiple CBOMs (code + infra + live endpoints) into one combined BOM.
54
58
  export { mergeCboms } from "./cbom-merge.js";
59
+ // OpenVEX 0.2.0 export — quantum-readiness posture as VEX statements.
60
+ export { toOpenVex } from "./vex.js";
61
+ // Crypto-agility manifest: agent-consumable crypto-posture document.
62
+ export { buildCryptoAgilityManifest, validateCryptoAgilityManifest, CRYPTO_AGILITY_MANIFEST_VERSION, CRYPTO_AGILITY_WELL_KNOWN_PATH, } from "./crypto-agility.js";
55
63
  // ISO/IEC 27001 A.8.24 evidence-chain readiness report.
56
- export { buildReadinessReport } from "./evidence.js";
64
+ export { buildReadinessReport, signReadinessReport, verifyReadinessReport } from "./evidence.js";
57
65
  // Cryptography policy → per-finding verdicts (A.8.24 evidence §4).
58
- export { buildPolicyMapping, parseCryptoPolicy, verdictForAlgorithm } from "./policy.js";
59
- // Remediation lookup (family + tier-aware) and stateful-HBS guidance.
60
- export { remediationFor, remediationForTier, TIER_PARAMS, STATEFUL_HBS_NOTE, PQC_TRANSITION_NOTE, statefulHbsApplies, } from "./remediation.js";
66
+ export { buildPolicyMapping, parseCryptoPolicy } from "./policy.js";
67
+ // Remediation lookup (family + tier-aware + profile-aware) and stateful-HBS guidance.
68
+ export { remediationFor, remediationForTier, remediationForProfile, TIER_PARAMS, STATEFUL_HBS_NOTE, PQC_TRANSITION_NOTE, statefulHbsApplies, } from "./remediation.js";
61
69
  // Post-quantum standards source of truth + review cadence.
62
- export { PQC_STANDARDS, standardsReviewStatus } from "./standards.js";
70
+ export { PQC_STANDARDS } from "./standards.js";
71
+ // Selectable standards regime profiles (NIST / CNSA / BSI / ANSSI / NCSC).
72
+ export { STANDARDS_PROFILES, DEFAULT_PROFILE_ID, standardsProfileIds, getStandardsProfile, defaultStandardsProfile, } from "./standards-profiles.js";
63
73
  // CWE identifier constants.
64
74
  export { CWE_BROKEN_CRYPTO, CWE_WEAK_STRENGTH, CWE_CERT_VALIDATION, CWE_HARDCODED_KEY, CWE_RISKY_PRIMITIVE, } from "./cwe.js";
65
75
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @quantakrypto/core — public API (LOCKED CONTRACT).\n *\n * The exported NAMES and SIGNATURES below are the stable contract that\n * @quantakrypto/qscan, @quantakrypto/mcp and the GitHub Action depend on — do not change\n * them without updating all consumers. The implementations live in focused\n * modules under src/ and are re-exported here; the public surface is identical\n * to the original stub file.\n */\nexport * from \"./types.js\";\n\n// Tool version, surfaced in reports. Keep in sync with package.json.\nexport { VERSION } from \"./version.js\";\n\n// Minimal SARIF 2.1.0 log shape, defined alongside the reporters.\nexport type { SarifLog } from \"./report.js\";\n\n// Core orchestration + built-in detector set.\nexport { scan, detectors, detectFile, compareFindings } from \"./scan.js\";\n\n// Snippet-level fix verification (shared by MCP verify_fix + remediation).\nexport { verifyFix, languageToExtension } from \"./verify.js\";\nexport type { VerifyResult } from \"./verify.js\";\n\n// Agent-plane shared types + the context redactor (offline; reused by MCP).\nexport type {\n ContextLevel,\n RedactedContext,\n TriageVerdict,\n Patch,\n FixProposal,\n} from \"./agent-types.js\";\nexport { buildContext, renderPreflight } from \"./redact.js\";\nexport { TRIAGE_RUBRIC, TRIAGE_VERDICT_SCHEMA, buildTriageRequest } from \"./triage.js\";\nexport type { TriageRequest } from \"./triage.js\";\nexport {\n REMEDIATE_RUBRIC,\n FIX_REQUEST_SCHEMA,\n buildRemediateRequest,\n} from \"./remediate-request.js\";\nexport type { RemediateRequest } from \"./remediate-request.js\";\nexport { checkPatchPolicy } from \"./patch-policy.js\";\nexport type { PolicyContext, PolicyDecision } from \"./patch-policy.js\";\nexport { withWorktree } from \"./worktree.js\";\nexport { codemodRegistry, codemodFor } from \"./codemods/registry.js\";\nexport type { Codemod } from \"./codemods/registry.js\";\nexport { configToggleCodemod } from \"./codemods/config-toggle.js\";\nexport { remediateFindings } from \"./remediate-pipeline.js\";\nexport type {\n RemediateOptions,\n RemediationResult,\n VerifiedPatch,\n RejectedPatch,\n} from \"./remediate-pipeline.js\";\n\n// Scan cancellation / work-budget errors.\nexport { AbortError, BudgetExceededError } from \"./errors.js\";\n\n// Parallel scanning (worker_threads pool) + pure merge/chunk helpers.\nexport { scanParallel, mergeChunkResults, chunkByBytes } from \"./parallel.js\";\nexport type { ScanChunk, ChunkResult, SizedFile } from \"./parallel.js\";\n\n// Detector registry (plugin point) + helpers + the rule catalog.\nexport { DetectorRegistry, defaultRegistry, detectorScope } from \"./registry.js\";\nexport type { RuleCatalogEntry } from \"./registry.js\";\n\n// Canonical baseline (shared by qScan + the Action).\nexport {\n fingerprintFinding,\n baselineFromFindings,\n applyBaseline,\n loadBaseline,\n saveBaseline,\n BASELINE_VERSION,\n} from \"./baseline.js\";\nexport type { Baseline } from \"./baseline.js\";\n\n// Incremental scanning: changed-files helper (git-aware, tolerant).\nexport { changedFiles } from \"./changed.js\";\n\n// Optional `quantakrypto.config.json` loader (P2-9; see docs/CONFIG.md).\nexport { loadConfig, ConfigError, CONFIG_FILENAME } from \"./config.js\";\nexport type { QuantakryptoFileConfig, LoadConfigResult } from \"./config.js\";\n\n// Filesystem walker (relative POSIX paths, default ignores, size/binary filters).\nexport { walkFiles, isBinaryPath, isGeneratedPath, looksMinified } from \"./walk.js\";\n\n// Analyzable-language coverage (which source languages the scanner inspects).\nexport {\n isAnalyzableSource,\n ANALYZABLE_SOURCE_EXTENSIONS,\n ANALYZABLE_LANGUAGES_LABEL,\n} from \"./detect-utils.js\";\n\n// Inventory + readiness score.\nexport { buildInventory } from \"./inventory.js\";\n\n// Vulnerable-dependency database (the manifest scanner is used internally by scan()).\n// `DEP_VULNERABLE_RULE` is the generic catalog entry for dependency findings\n// (which don't come from a Detector, so aren't in the registry's rule catalog).\nexport { vulnerableDependencies, DEP_VULNERABLE_RULE, isManifestFile } from \"./dependencies.js\";\n\n// Severity utilities (ordering, threshold, SARIF level) — shared across tools.\nexport { SEVERITY_ORDER, severityRank, meetsThreshold, sarifLevel } from \"./severity.js\";\n\n// Reporters.\nexport { toSarif, toJson, formatSummary, formatTierGuidance } from \"./report.js\";\nexport type { ReportOptions } from \"./report.js\";\n\n// CycloneDX 1.6 cryptographic bill of materials (CBOM) export.\nexport { toCbom } from \"./cbom.js\";\nexport type { CycloneDxBom, CbomComponent } from \"./cbom.js\";\n// Merge multiple CBOMs (code + infra + live endpoints) into one combined BOM.\nexport { mergeCboms } from \"./cbom-merge.js\";\n// ISO/IEC 27001 A.8.24 evidence-chain readiness report.\nexport { buildReadinessReport } from \"./evidence.js\";\nexport type { ReadinessReport, EvidenceFinding, ReadinessReportOptions } from \"./evidence.js\";\n\n// Cryptography policy → per-finding verdicts (A.8.24 evidence §4).\nexport { buildPolicyMapping, parseCryptoPolicy, verdictForAlgorithm } from \"./policy.js\";\nexport type { CryptoPolicy, PolicyVerdict, PolicyMapping, PolicyFindingVerdict } from \"./policy.js\";\n\n// Remediation lookup (family + tier-aware) and stateful-HBS guidance.\nexport {\n remediationFor,\n remediationForTier,\n TIER_PARAMS,\n STATEFUL_HBS_NOTE,\n PQC_TRANSITION_NOTE,\n statefulHbsApplies,\n} from \"./remediation.js\";\nexport type { SecurityTier } from \"./remediation.js\";\n\n// Post-quantum standards source of truth + review cadence.\nexport { PQC_STANDARDS, standardsReviewStatus } from \"./standards.js\";\nexport type { PqcStandards, StandardsCitation, StandardsReviewStatus } from \"./standards.js\";\n\n// CWE identifier constants.\nexport {\n CWE_BROKEN_CRYPTO,\n CWE_WEAK_STRENGTH,\n CWE_CERT_VALIDATION,\n CWE_HARDCODED_KEY,\n CWE_RISKY_PRIMITIVE,\n} from \"./cwe.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @quantakrypto/core — public API (LOCKED CONTRACT).\n *\n * The exported NAMES and SIGNATURES below are the stable contract that\n * @quantakrypto/qscan, @quantakrypto/mcp and the GitHub Action depend on — do not change\n * them without updating all consumers. The implementations live in focused\n * modules under src/ and are re-exported here; the public surface is identical\n * to the original stub file.\n */\nexport * from \"./types.js\";\n\n// Tool version, surfaced in reports. Keep in sync with package.json.\nexport { VERSION } from \"./version.js\";\n\n// Minimal SARIF 2.1.0 log shape, defined alongside the reporters.\nexport type { SarifLog } from \"./report.js\";\n\n// Core orchestration + built-in detector set.\nexport { scan, detectors, detectFile, compareFindings } from \"./scan.js\";\n\n// Snippet-level fix verification (shared by MCP verify_fix + remediation).\nexport { verifyFix, languageToExtension } from \"./verify.js\";\nexport type { VerifyResult } from \"./verify.js\";\n\n// Agent-plane shared types + the context redactor (offline; reused by MCP).\nexport type {\n ContextLevel,\n RedactedContext,\n TriageVerdict,\n Patch,\n FixProposal,\n} from \"./agent-types.js\";\nexport { buildContext, renderPreflight } from \"./redact.js\";\nexport { TRIAGE_RUBRIC, TRIAGE_VERDICT_SCHEMA, buildTriageRequest } from \"./triage.js\";\nexport type { TriageRequest } from \"./triage.js\";\nexport {\n REMEDIATE_RUBRIC,\n FIX_REQUEST_SCHEMA,\n buildRemediateRequest,\n} from \"./remediate-request.js\";\nexport type { RemediateRequest } from \"./remediate-request.js\";\nexport { checkPatchPolicy } from \"./patch-policy.js\";\nexport type { PolicyContext, PolicyDecision } from \"./patch-policy.js\";\nexport { withWorktree } from \"./worktree.js\";\nexport { codemodRegistry, codemodFor } from \"./codemods/registry.js\";\nexport type { Codemod } from \"./codemods/registry.js\";\nexport { configToggleCodemod } from \"./codemods/config-toggle.js\";\nexport { remediateFindings } from \"./remediate-pipeline.js\";\nexport type {\n RemediateOptions,\n RemediationResult,\n VerifiedPatch,\n RejectedPatch,\n} from \"./remediate-pipeline.js\";\n\n// Scan cancellation / work-budget errors.\nexport { AbortError, BudgetExceededError } from \"./errors.js\";\n\n// Parallel scanning (worker_threads pool). The chunk/merge helpers and their\n// SizedFile/ChunkResult types are internal plumbing (not part of the public API).\nexport { scanParallel } from \"./parallel.js\";\nexport type { ScanChunk } from \"./parallel.js\";\n\n// Detector registry (plugin point). `detectorScope` and the rule-catalog type are\n// internal.\nexport { DetectorRegistry, defaultRegistry } from \"./registry.js\";\n\n// Canonical baseline (shared by qScan + the Action).\nexport {\n fingerprintFinding,\n baselineFromFindings,\n applyBaseline,\n loadBaseline,\n saveBaseline,\n BASELINE_VERSION,\n} from \"./baseline.js\";\nexport type { Baseline } from \"./baseline.js\";\n\n// Incremental scanning: changed-files helper (git-aware, tolerant).\nexport { changedFiles } from \"./changed.js\";\n\n// Optional `quantakrypto.config.json` loader (P2-9; see docs/CONFIG.md).\nexport { loadConfig, ConfigError, CONFIG_FILENAME } from \"./config.js\";\nexport type { QuantakryptoFileConfig, LoadConfigResult } from \"./config.js\";\n\n// HNDL (harvest-now-decrypt-later) data-risk quantifier (see docs/HNDL.md).\nexport {\n HNDL_MODEL_VERSION,\n HNDL_FILENAME,\n SEVERITY_VULNERABILITY,\n CONFIDENCE_WEIGHT,\n CLASSIFICATION_SENSITIVITY,\n NON_HNDL_DISCOUNT,\n DEFAULT_QUANTUM_THREAT_YEARS,\n DEFAULT_MIGRATION_HORIZON_YEARS,\n DEFAULT_UNBOUND_CLASSIFICATION,\n HndlError,\n computeHndl,\n vulnerabilityFactor,\n moscaFactor,\n globMatch,\n findingFingerprint,\n findingScope,\n parseHndlMap,\n loadHndlMap,\n scaffoldHndlYaml,\n} from \"./hndl.js\";\nexport type {\n DataClassification,\n HndlScope,\n HndlDataAsset,\n HndlHorizon,\n HndlDefaults,\n HndlMap,\n ExposureRationale,\n FindingExposure,\n AssetExposure,\n HndlSummary,\n HndlReport,\n} from \"./hndl.js\";\n\n// Filesystem walker (relative POSIX paths, default ignores, size/binary filters).\nexport { walkFiles, isBinaryPath, looksMinified } from \"./walk.js\";\n\n// Analyzable-language coverage (which source languages the scanner inspects).\nexport {\n isAnalyzableSource,\n ANALYZABLE_SOURCE_EXTENSIONS,\n ANALYZABLE_LANGUAGES_LABEL,\n} from \"./detect-utils.js\";\n\n// Inventory + readiness score.\nexport { buildInventory } from \"./inventory.js\";\n\n// Vulnerable-dependency database (the manifest scanner is used internally by scan()).\n// `DEP_VULNERABLE_RULE` is the generic catalog entry for dependency findings\n// (which don't come from a Detector, so aren't in the registry's rule catalog).\nexport { vulnerableDependencies, DEP_VULNERABLE_RULE, isManifestFile } from \"./dependencies.js\";\n\n// Severity utilities (ordering, threshold, SARIF level) — shared across tools.\nexport { SEVERITY_ORDER, severityRank, meetsThreshold, sarifLevel } from \"./severity.js\";\n\n// Reporters.\nexport {\n toSarif,\n toJson,\n formatSummary,\n formatTierGuidance,\n formatProfileGuidance,\n} from \"./report.js\";\nexport type { ReportOptions } from \"./report.js\";\n\n// CycloneDX 1.6 cryptographic bill of materials (CBOM) export.\nexport { toCbom } from \"./cbom.js\";\nexport type { CycloneDxBom, CbomComponent } from \"./cbom.js\";\n// Merge multiple CBOMs (code + infra + live endpoints) into one combined BOM.\nexport { mergeCboms } from \"./cbom-merge.js\";\n// OpenVEX 0.2.0 export — quantum-readiness posture as VEX statements.\nexport { toOpenVex } from \"./vex.js\";\nexport type { OpenVexDocument, OpenVexStatement, OpenVexOptions } from \"./vex.js\";\n// Crypto-agility manifest: agent-consumable crypto-posture document.\nexport {\n buildCryptoAgilityManifest,\n validateCryptoAgilityManifest,\n CRYPTO_AGILITY_MANIFEST_VERSION,\n CRYPTO_AGILITY_WELL_KNOWN_PATH,\n} from \"./crypto-agility.js\";\nexport type {\n CryptoAgilityManifest,\n CryptoAgilityManifestOptions,\n CryptoAgilityPosture,\n CryptoAgilityCbomSummary,\n CryptoAgilityFamily,\n CryptoAgilityPolicy,\n ManifestValidation,\n} from \"./crypto-agility.js\";\n// ISO/IEC 27001 A.8.24 evidence-chain readiness report.\nexport { buildReadinessReport, signReadinessReport, verifyReadinessReport } from \"./evidence.js\";\nexport type {\n ReadinessReport,\n EvidenceFinding,\n ReadinessReportOptions,\n EvidenceSigner,\n SignEvidenceOptions,\n VerifyReadinessResult,\n} from \"./evidence.js\";\n\n// Cryptography policy → per-finding verdicts (A.8.24 evidence §4).\nexport { buildPolicyMapping, parseCryptoPolicy } from \"./policy.js\";\nexport type { CryptoPolicy, PolicyVerdict, PolicyMapping, PolicyFindingVerdict } from \"./policy.js\";\n\n// Remediation lookup (family + tier-aware + profile-aware) and stateful-HBS guidance.\nexport {\n remediationFor,\n remediationForTier,\n remediationForProfile,\n TIER_PARAMS,\n STATEFUL_HBS_NOTE,\n PQC_TRANSITION_NOTE,\n statefulHbsApplies,\n} from \"./remediation.js\";\nexport type { SecurityTier } from \"./remediation.js\";\n\n// Post-quantum standards source of truth + review cadence.\nexport { PQC_STANDARDS } from \"./standards.js\";\nexport type { PqcStandards, StandardsCitation, StandardsReviewStatus } from \"./standards.js\";\n\n// Selectable standards regime profiles (NIST / CNSA / BSI / ANSSI / NCSC).\nexport {\n STANDARDS_PROFILES,\n DEFAULT_PROFILE_ID,\n standardsProfileIds,\n getStandardsProfile,\n defaultStandardsProfile,\n} from \"./standards-profiles.js\";\nexport type { StandardsProfile, HybridStance } from \"./standards-profiles.js\";\n\n// CWE identifier constants.\nexport {\n CWE_BROKEN_CRYPTO,\n CWE_WEAK_STRENGTH,\n CWE_CERT_VALIDATION,\n CWE_HARDCODED_KEY,\n CWE_RISKY_PRIMITIVE,\n} from \"./cwe.js\";\n"]}
@@ -4,8 +4,6 @@
4
4
  * and a 0–100 readiness score.
5
5
  */
6
6
  import type { CryptoInventory, Finding } from "./types.js";
7
- /** True when a finding's file path is test / fixture / example / documentation. */
8
- export declare function isTestOrFixturePath(file: string): boolean;
9
7
  /**
10
8
  * Compute a 0–100 readiness score. 100 means no classical asymmetric crypto was
11
9
  * found. Findings accrue a severity-weighted penalty (with per-bucket diminishing
@@ -1 +1 @@
1
- {"version":3,"file":"inventory.d.ts","sourceRoot":"","sources":["../src/inventory.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAEV,eAAe,EACf,OAAO,EAGR,MAAM,YAAY,CAAC;AAsCpB,mFAAmF;AACnF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAczD;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,CAoB1D;AAED,+EAA+E;AAC/E,wBAAgB,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,eAAe,CAgCnE"}
1
+ {"version":3,"file":"inventory.d.ts","sourceRoot":"","sources":["../src/inventory.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAEV,eAAe,EACf,OAAO,EAGR,MAAM,YAAY,CAAC;AAuDpB;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,CA4B1D;AAED,+EAA+E;AAC/E,wBAAgB,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,eAAe,CAgCnE"}
package/dist/inventory.js CHANGED
@@ -30,7 +30,7 @@ const SCORE_SCALE = 100;
30
30
  */
31
31
  const TEST_PATH_WEIGHT = 0.15;
32
32
  /** True when a finding's file path is test / fixture / example / documentation. */
33
- export function isTestOrFixturePath(file) {
33
+ function isTestOrFixturePath(file) {
34
34
  const f = file.toLowerCase().replace(/\\/g, "/");
35
35
  if (/(?:^|\/)(?:tests?|__tests__|testdata|test-data|fixtures?|examples?|demos?|samples?|specs?|mocks?|docs?|benchmarks?|e2e)\//.test(f)) {
36
36
  return true;
@@ -55,18 +55,27 @@ export function isTestOrFixturePath(file) {
55
55
  export function readinessScore(findings) {
56
56
  if (findings.length === 0)
57
57
  return 100;
58
- const seen = {
58
+ // Diminishing-returns occurrence counters, kept SEPARATE for full-weight vs
59
+ // test-path findings. Sharing one counter per severity let whichever finding came
60
+ // first in the (path-sorted) list claim the `1/√1` slot, so a directory rename — or
61
+ // a test finding sorting ahead of a real one — changed the score. Bucketing makes
62
+ // the penalty independent of file order and of test/real interleaving.
63
+ const zero = () => ({
59
64
  critical: 0,
60
65
  high: 0,
61
66
  medium: 0,
62
67
  low: 0,
63
68
  info: 0,
64
- };
69
+ });
70
+ const seenReal = zero();
71
+ const seenTest = zero();
65
72
  let penalty = 0;
66
73
  for (const f of findings) {
67
- seen[f.severity] += 1;
68
- const weight = SEVERITY_WEIGHT[f.severity] * (isTestOrFixturePath(f.location.file) ? TEST_PATH_WEIGHT : 1);
69
- penalty += penaltyFor(weight, seen[f.severity]);
74
+ const isTest = isTestOrFixturePath(f.location.file);
75
+ const bucket = isTest ? seenTest : seenReal;
76
+ bucket[f.severity] += 1;
77
+ const weight = SEVERITY_WEIGHT[f.severity] * (isTest ? TEST_PATH_WEIGHT : 1);
78
+ penalty += penaltyFor(weight, bucket[f.severity]);
70
79
  }
71
80
  return Math.max(0, Math.min(100, Math.round(100 * Math.exp(-penalty / SCORE_SCALE))));
72
81
  }
@@ -1 +1 @@
1
- {"version":3,"file":"inventory.js","sourceRoot":"","sources":["../src/inventory.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Aggregates findings into a {@link CryptoInventory}: per-algorithm,\n * per-category and per-severity counts, the harvest-now-decrypt-later count,\n * and a 0–100 readiness score.\n */\nimport type {\n AlgorithmFamily,\n CryptoInventory,\n Finding,\n FindingCategory,\n Severity,\n} from \"./types.js\";\n\n/** All severities, most → least severe (used to seed the counts record). */\nconst SEVERITIES: Severity[] = [\"critical\", \"high\", \"medium\", \"low\", \"info\"];\n\n/** Base penalty applied to the readiness score for the first finding of a severity. */\nconst SEVERITY_WEIGHT: Record<Severity, number> = {\n critical: 30,\n high: 18,\n medium: 8,\n low: 3,\n info: 1,\n};\n\n/**\n * Apply diminishing returns to repeated findings of the same severity: the Nth\n * finding contributes `weight / sqrt(N)`. This keeps a single critical hit very\n * impactful while a codebase with hundreds of medium findings doesn't underflow\n * past zero on the first few — the score still saturates toward 0 sensibly.\n */\nfunction penaltyFor(weight: number, occurrence: number): number {\n return weight / Math.sqrt(occurrence);\n}\n\n/** Decay constant for the readiness score (larger = more forgiving). */\nconst SCORE_SCALE = 100;\n\n/**\n * Fraction of the normal penalty a finding in test/fixture/example/doc code\n * contributes to the readiness score. Such findings are almost always test\n * vectors, sample keys, or the library's own algorithm enumerations — accurate\n * detections, but not the deployed crypto whose migration the score is meant to\n * track. Real-repo runs showed 60–77% of findings live in these paths, which\n * dragged the score of no-real-crypto codebases down unfairly. They still appear\n * in the inventory counts in full; only their *score* weight is reduced.\n */\nconst TEST_PATH_WEIGHT = 0.15;\n\n/** True when a finding's file path is test / fixture / example / documentation. */\nexport function isTestOrFixturePath(file: string): boolean {\n const f = file.toLowerCase().replace(/\\\\/g, \"/\");\n if (\n /(?:^|\\/)(?:tests?|__tests__|testdata|test-data|fixtures?|examples?|demos?|samples?|specs?|mocks?|docs?|benchmarks?|e2e)\\//.test(\n f,\n )\n ) {\n return true;\n }\n const base = f.slice(f.lastIndexOf(\"/\") + 1);\n if (/(?:^|[_.-])(?:test|spec)\\.[a-z0-9]+$/.test(base)) return true; // test.go, foo_test.go, foo.test.ts\n if (/^test_[^/]+\\.py$/.test(base)) return true; // python test_foo.py\n if (/^changelog/.test(base) || /\\.(?:md|markdown|rst|adoc|asciidoc)$/.test(base)) return true;\n return false;\n}\n\n/**\n * Compute a 0–100 readiness score. 100 means no classical asymmetric crypto was\n * found. Findings accrue a severity-weighted penalty (with per-bucket diminishing\n * returns), then the score is `100 * e^(-penalty/scale)`. Exponential decay keeps\n * the score responsive across the whole range — fixing findings always raises it,\n * and a large legacy repo lands low without pinning flat at 0 (which made progress\n * invisible under the old linear model). Tuned so one low ~97, one critical ~74.\n */\nexport function readinessScore(findings: Finding[]): number {\n if (findings.length === 0) return 100;\n\n const seen: Record<Severity, number> = {\n critical: 0,\n high: 0,\n medium: 0,\n low: 0,\n info: 0,\n };\n\n let penalty = 0;\n for (const f of findings) {\n seen[f.severity] += 1;\n const weight =\n SEVERITY_WEIGHT[f.severity] * (isTestOrFixturePath(f.location.file) ? TEST_PATH_WEIGHT : 1);\n penalty += penaltyFor(weight, seen[f.severity]);\n }\n\n return Math.max(0, Math.min(100, Math.round(100 * Math.exp(-penalty / SCORE_SCALE))));\n}\n\n/** Build the full inventory (counts + HNDL + score) from a set of findings. */\nexport function buildInventory(findings: Finding[]): CryptoInventory {\n const byAlgorithm: Partial<Record<AlgorithmFamily, number>> = {};\n const byCategory: Partial<Record<FindingCategory, number>> = {};\n const bySeverity: Record<Severity, number> = {\n critical: 0,\n high: 0,\n medium: 0,\n low: 0,\n info: 0,\n };\n let hndlCount = 0;\n\n for (const f of findings) {\n if (f.algorithm) {\n byAlgorithm[f.algorithm] = (byAlgorithm[f.algorithm] ?? 0) + 1;\n }\n byCategory[f.category] = (byCategory[f.category] ?? 0) + 1;\n bySeverity[f.severity] += 1;\n if (f.hndl) hndlCount += 1;\n }\n\n // Ensure all severities are present (seeded above to 0). SEVERITIES is the\n // canonical ordering and guards against missing keys if the type changes.\n void SEVERITIES;\n\n return {\n byAlgorithm,\n byCategory,\n bySeverity,\n hndlCount,\n readinessScore: readinessScore(findings),\n };\n}\n"]}
1
+ {"version":3,"file":"inventory.js","sourceRoot":"","sources":["../src/inventory.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Aggregates findings into a {@link CryptoInventory}: per-algorithm,\n * per-category and per-severity counts, the harvest-now-decrypt-later count,\n * and a 0–100 readiness score.\n */\nimport type {\n AlgorithmFamily,\n CryptoInventory,\n Finding,\n FindingCategory,\n Severity,\n} from \"./types.js\";\n\n/** All severities, most → least severe (used to seed the counts record). */\nconst SEVERITIES: Severity[] = [\"critical\", \"high\", \"medium\", \"low\", \"info\"];\n\n/** Base penalty applied to the readiness score for the first finding of a severity. */\nconst SEVERITY_WEIGHT: Record<Severity, number> = {\n critical: 30,\n high: 18,\n medium: 8,\n low: 3,\n info: 1,\n};\n\n/**\n * Apply diminishing returns to repeated findings of the same severity: the Nth\n * finding contributes `weight / sqrt(N)`. This keeps a single critical hit very\n * impactful while a codebase with hundreds of medium findings doesn't underflow\n * past zero on the first few — the score still saturates toward 0 sensibly.\n */\nfunction penaltyFor(weight: number, occurrence: number): number {\n return weight / Math.sqrt(occurrence);\n}\n\n/** Decay constant for the readiness score (larger = more forgiving). */\nconst SCORE_SCALE = 100;\n\n/**\n * Fraction of the normal penalty a finding in test/fixture/example/doc code\n * contributes to the readiness score. Such findings are almost always test\n * vectors, sample keys, or the library's own algorithm enumerations — accurate\n * detections, but not the deployed crypto whose migration the score is meant to\n * track. Real-repo runs showed 60–77% of findings live in these paths, which\n * dragged the score of no-real-crypto codebases down unfairly. They still appear\n * in the inventory counts in full; only their *score* weight is reduced.\n */\nconst TEST_PATH_WEIGHT = 0.15;\n\n/** True when a finding's file path is test / fixture / example / documentation. */\nfunction isTestOrFixturePath(file: string): boolean {\n const f = file.toLowerCase().replace(/\\\\/g, \"/\");\n if (\n /(?:^|\\/)(?:tests?|__tests__|testdata|test-data|fixtures?|examples?|demos?|samples?|specs?|mocks?|docs?|benchmarks?|e2e)\\//.test(\n f,\n )\n ) {\n return true;\n }\n const base = f.slice(f.lastIndexOf(\"/\") + 1);\n if (/(?:^|[_.-])(?:test|spec)\\.[a-z0-9]+$/.test(base)) return true; // test.go, foo_test.go, foo.test.ts\n if (/^test_[^/]+\\.py$/.test(base)) return true; // python test_foo.py\n if (/^changelog/.test(base) || /\\.(?:md|markdown|rst|adoc|asciidoc)$/.test(base)) return true;\n return false;\n}\n\n/**\n * Compute a 0–100 readiness score. 100 means no classical asymmetric crypto was\n * found. Findings accrue a severity-weighted penalty (with per-bucket diminishing\n * returns), then the score is `100 * e^(-penalty/scale)`. Exponential decay keeps\n * the score responsive across the whole range — fixing findings always raises it,\n * and a large legacy repo lands low without pinning flat at 0 (which made progress\n * invisible under the old linear model). Tuned so one low ~97, one critical ~74.\n */\nexport function readinessScore(findings: Finding[]): number {\n if (findings.length === 0) return 100;\n\n // Diminishing-returns occurrence counters, kept SEPARATE for full-weight vs\n // test-path findings. Sharing one counter per severity let whichever finding came\n // first in the (path-sorted) list claim the `1/√1` slot, so a directory rename — or\n // a test finding sorting ahead of a real one — changed the score. Bucketing makes\n // the penalty independent of file order and of test/real interleaving.\n const zero = (): Record<Severity, number> => ({\n critical: 0,\n high: 0,\n medium: 0,\n low: 0,\n info: 0,\n });\n const seenReal = zero();\n const seenTest = zero();\n\n let penalty = 0;\n for (const f of findings) {\n const isTest = isTestOrFixturePath(f.location.file);\n const bucket = isTest ? seenTest : seenReal;\n bucket[f.severity] += 1;\n const weight = SEVERITY_WEIGHT[f.severity] * (isTest ? TEST_PATH_WEIGHT : 1);\n penalty += penaltyFor(weight, bucket[f.severity]);\n }\n\n return Math.max(0, Math.min(100, Math.round(100 * Math.exp(-penalty / SCORE_SCALE))));\n}\n\n/** Build the full inventory (counts + HNDL + score) from a set of findings. */\nexport function buildInventory(findings: Finding[]): CryptoInventory {\n const byAlgorithm: Partial<Record<AlgorithmFamily, number>> = {};\n const byCategory: Partial<Record<FindingCategory, number>> = {};\n const bySeverity: Record<Severity, number> = {\n critical: 0,\n high: 0,\n medium: 0,\n low: 0,\n info: 0,\n };\n let hndlCount = 0;\n\n for (const f of findings) {\n if (f.algorithm) {\n byAlgorithm[f.algorithm] = (byAlgorithm[f.algorithm] ?? 0) + 1;\n }\n byCategory[f.category] = (byCategory[f.category] ?? 0) + 1;\n bySeverity[f.severity] += 1;\n if (f.hndl) hndlCount += 1;\n }\n\n // Ensure all severities are present (seeded above to 0). SEVERITIES is the\n // canonical ordering and guards against missing keys if the type changes.\n void SEVERITIES;\n\n return {\n byAlgorithm,\n byCategory,\n bySeverity,\n hndlCount,\n readinessScore: readinessScore(findings),\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"parallel.d.ts","sourceRoot":"","sources":["../src/parallel.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAQ3E,+CAA+C;AAC/C,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,yCAAyC;AACzC,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,mFAAmF;IACnF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iFAAiF;IACjF,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAMD,kEAAkE;AAClE,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,CAgBzF;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,GAAG,WAAW,CAa9E;AAuED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC,CAkGpF"}
1
+ {"version":3,"file":"parallel.d.ts","sourceRoot":"","sources":["../src/parallel.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAQ3E,+CAA+C;AAC/C,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,yCAAyC;AACzC,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,mFAAmF;IACnF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iFAAiF;IACjF,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAMD,kEAAkE;AAClE,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,CAgBzF;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,GAAG,WAAW,CAa9E;AAwED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC,CAkGpF"}
package/dist/parallel.js CHANGED
@@ -13,7 +13,7 @@ import { existsSync } from "node:fs";
13
13
  import * as os from "node:os";
14
14
  import * as path from "node:path";
15
15
  import { fileURLToPath } from "node:url";
16
- import { walkFiles } from "./walk.js";
16
+ import { walkFilesSized } from "./walk.js";
17
17
  import { isAnalyzableSource } from "./detect-utils.js";
18
18
  import { buildInventory } from "./inventory.js";
19
19
  import { compareFindings, filterExplicitFileList, scan } from "./scan.js";
@@ -87,32 +87,31 @@ function shouldParallelize(options, files) {
87
87
  * explicit `files` list or the walker. Sizes power byte-balanced chunking.
88
88
  */
89
89
  async function enumerateFiles(options, baseDir) {
90
- const rels = [];
90
+ const sized = [];
91
91
  if (options.files) {
92
+ // Explicit file list: the walker isn't involved, so stat each once here.
92
93
  // Apply the SAME include/exclude/binary filtering the serial path uses via
93
- // `filterExplicitFiles`, so `--parallel` is byte-for-byte identical to serial.
94
- for (const rel of filterExplicitFileList(options.files, options))
95
- rels.push(rel);
96
- }
97
- else {
98
- for await (const rel of walkFiles(options.root, {
99
- include: options.include,
100
- exclude: options.exclude,
101
- noDefaultIgnores: options.noDefaultIgnores,
102
- maxFileSize: options.maxFileSize,
103
- })) {
104
- rels.push(rel);
94
+ // `filterExplicitFileList`, so `--parallel` is byte-for-byte identical to serial.
95
+ for (const rel of filterExplicitFileList(options.files, options)) {
96
+ let size = 0;
97
+ try {
98
+ size = (await stat(path.join(baseDir, ...rel.split("/")))).size;
99
+ }
100
+ catch {
101
+ // Unreadable now; keep with size 0 (the worker read will skip if it's gone).
102
+ }
103
+ sized.push({ rel, size });
105
104
  }
105
+ return sized;
106
106
  }
107
- const sized = [];
108
- for (const rel of rels) {
109
- let size = 0;
110
- try {
111
- size = (await stat(path.join(baseDir, ...rel.split("/")))).size;
112
- }
113
- catch {
114
- // Unreadable now; keep with size 0 — worker read will skip if it's gone.
115
- }
107
+ // Directory walk: reuse the size the walker already stat'd while enforcing the
108
+ // size limit, so files are not stat'd a second time here (double-stat fix).
109
+ for await (const { rel, size } of walkFilesSized(options.root, {
110
+ include: options.include,
111
+ exclude: options.exclude,
112
+ noDefaultIgnores: options.noDefaultIgnores,
113
+ maxFileSize: options.maxFileSize,
114
+ })) {
116
115
  sized.push({ rel, size });
117
116
  }
118
117
  return sized;