@vyuhlabs/dxkit 2.4.7 → 2.5.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 (309) hide show
  1. package/CHANGELOG.md +456 -30
  2. package/README.md +360 -439
  3. package/dist/analyzers/bom/gather.d.ts +3 -3
  4. package/dist/analyzers/bom/gather.js +3 -3
  5. package/dist/analyzers/bom/index.js +2 -2
  6. package/dist/analyzers/bom/index.js.map +1 -1
  7. package/dist/analyzers/dashboard/index.d.ts.map +1 -1
  8. package/dist/analyzers/dashboard/index.js +4 -3
  9. package/dist/analyzers/dashboard/index.js.map +1 -1
  10. package/dist/analyzers/developer/index.d.ts.map +1 -1
  11. package/dist/analyzers/developer/index.js +2 -1
  12. package/dist/analyzers/developer/index.js.map +1 -1
  13. package/dist/analyzers/dispatcher.d.ts +15 -0
  14. package/dist/analyzers/dispatcher.d.ts.map +1 -1
  15. package/dist/analyzers/dispatcher.js +42 -6
  16. package/dist/analyzers/dispatcher.js.map +1 -1
  17. package/dist/analyzers/health.d.ts.map +1 -1
  18. package/dist/analyzers/health.js +11 -1
  19. package/dist/analyzers/health.js.map +1 -1
  20. package/dist/analyzers/licenses/gather.d.ts +1 -1
  21. package/dist/analyzers/licenses/gather.d.ts.map +1 -1
  22. package/dist/analyzers/licenses/gather.js +18 -2
  23. package/dist/analyzers/licenses/gather.js.map +1 -1
  24. package/dist/analyzers/quality/index.d.ts.map +1 -1
  25. package/dist/analyzers/quality/index.js +10 -2
  26. package/dist/analyzers/quality/index.js.map +1 -1
  27. package/dist/analyzers/security/aggregator.d.ts.map +1 -1
  28. package/dist/analyzers/security/aggregator.js +8 -48
  29. package/dist/analyzers/security/aggregator.js.map +1 -1
  30. package/dist/analyzers/security/gather.d.ts +4 -3
  31. package/dist/analyzers/security/gather.d.ts.map +1 -1
  32. package/dist/analyzers/security/gather.js +23 -5
  33. package/dist/analyzers/security/gather.js.map +1 -1
  34. package/dist/analyzers/security/index.d.ts +1 -1
  35. package/dist/analyzers/security/index.js +2 -2
  36. package/dist/analyzers/security/index.js.map +1 -1
  37. package/dist/analyzers/tools/autogen-header.js +1 -1
  38. package/dist/analyzers/tools/cloc.js +3 -3
  39. package/dist/analyzers/tools/cloc.js.map +1 -1
  40. package/dist/analyzers/tools/deadline.d.ts +67 -0
  41. package/dist/analyzers/tools/deadline.d.ts.map +1 -0
  42. package/dist/analyzers/tools/deadline.js +81 -0
  43. package/dist/analyzers/tools/deadline.js.map +1 -0
  44. package/dist/analyzers/tools/exclusions.d.ts +6 -6
  45. package/dist/analyzers/tools/exclusions.js +6 -6
  46. package/dist/analyzers/tools/fingerprint.d.ts +91 -26
  47. package/dist/analyzers/tools/fingerprint.d.ts.map +1 -1
  48. package/dist/analyzers/tools/fingerprint.js +111 -22
  49. package/dist/analyzers/tools/fingerprint.js.map +1 -1
  50. package/dist/analyzers/tools/generic.d.ts.map +1 -1
  51. package/dist/analyzers/tools/generic.js +7 -2
  52. package/dist/analyzers/tools/generic.js.map +1 -1
  53. package/dist/analyzers/tools/gitleaks.d.ts +24 -1
  54. package/dist/analyzers/tools/gitleaks.d.ts.map +1 -1
  55. package/dist/analyzers/tools/gitleaks.js +21 -12
  56. package/dist/analyzers/tools/gitleaks.js.map +1 -1
  57. package/dist/analyzers/tools/graphify.js +1 -1
  58. package/dist/analyzers/tools/jscpd.js +1 -1
  59. package/dist/analyzers/tools/jscpd.js.map +1 -1
  60. package/dist/analyzers/tools/lint-label.d.ts +29 -0
  61. package/dist/analyzers/tools/lint-label.d.ts.map +1 -0
  62. package/dist/analyzers/tools/lint-label.js +23 -0
  63. package/dist/analyzers/tools/lint-label.js.map +1 -0
  64. package/dist/analyzers/tools/nuget-package-reference.d.ts +6 -4
  65. package/dist/analyzers/tools/nuget-package-reference.d.ts.map +1 -1
  66. package/dist/analyzers/tools/nuget-package-reference.js +7 -5
  67. package/dist/analyzers/tools/nuget-package-reference.js.map +1 -1
  68. package/dist/analyzers/tools/report-date.d.ts +17 -0
  69. package/dist/analyzers/tools/report-date.d.ts.map +1 -0
  70. package/dist/analyzers/tools/report-date.js +26 -0
  71. package/dist/analyzers/tools/report-date.js.map +1 -0
  72. package/dist/analyzers/tools/runner.js +3 -3
  73. package/dist/analyzers/tools/runner.js.map +1 -1
  74. package/dist/analyzers/tools/vendored-advisor.js +1 -1
  75. package/dist/analyzers/tools/walk-paths.d.ts +1 -1
  76. package/dist/analyzers/tools/walk-paths.js +1 -1
  77. package/dist/analyzers/tools/walk-source-files.js +1 -1
  78. package/dist/analyzers/types.d.ts +6 -4
  79. package/dist/analyzers/types.d.ts.map +1 -1
  80. package/dist/baseline/baseline-file.d.ts +104 -0
  81. package/dist/baseline/baseline-file.d.ts.map +1 -0
  82. package/dist/baseline/baseline-file.js +110 -0
  83. package/dist/baseline/baseline-file.js.map +1 -0
  84. package/dist/baseline/check-renderers.d.ts +108 -0
  85. package/dist/baseline/check-renderers.d.ts.map +1 -0
  86. package/dist/baseline/check-renderers.js +379 -0
  87. package/dist/baseline/check-renderers.js.map +1 -0
  88. package/dist/baseline/check.d.ts +127 -0
  89. package/dist/baseline/check.d.ts.map +1 -0
  90. package/dist/baseline/check.js +462 -0
  91. package/dist/baseline/check.js.map +1 -0
  92. package/dist/baseline/content-hash.d.ts +83 -0
  93. package/dist/baseline/content-hash.d.ts.map +1 -0
  94. package/dist/baseline/content-hash.js +131 -0
  95. package/dist/baseline/content-hash.js.map +1 -0
  96. package/dist/baseline/create.d.ts +96 -0
  97. package/dist/baseline/create.d.ts.map +1 -0
  98. package/dist/baseline/create.js +339 -0
  99. package/dist/baseline/create.js.map +1 -0
  100. package/dist/baseline/entry-to-located.d.ts +35 -0
  101. package/dist/baseline/entry-to-located.d.ts.map +1 -0
  102. package/dist/baseline/entry-to-located.js +72 -0
  103. package/dist/baseline/entry-to-located.js.map +1 -0
  104. package/dist/baseline/finding-identity.d.ts +47 -0
  105. package/dist/baseline/finding-identity.d.ts.map +1 -0
  106. package/dist/baseline/finding-identity.js +292 -0
  107. package/dist/baseline/finding-identity.js.map +1 -0
  108. package/dist/baseline/git-aware-match.d.ts +146 -0
  109. package/dist/baseline/git-aware-match.d.ts.map +1 -0
  110. package/dist/baseline/git-aware-match.js +439 -0
  111. package/dist/baseline/git-aware-match.js.map +1 -0
  112. package/dist/baseline/policy.d.ts +171 -0
  113. package/dist/baseline/policy.d.ts.map +1 -0
  114. package/dist/baseline/policy.js +206 -0
  115. package/dist/baseline/policy.js.map +1 -0
  116. package/dist/baseline/producers/health.d.ts +30 -0
  117. package/dist/baseline/producers/health.d.ts.map +1 -0
  118. package/dist/baseline/producers/health.js +42 -0
  119. package/dist/baseline/producers/health.js.map +1 -0
  120. package/dist/baseline/producers/index.d.ts +164 -0
  121. package/dist/baseline/producers/index.d.ts.map +1 -0
  122. package/dist/baseline/producers/index.js +200 -0
  123. package/dist/baseline/producers/index.js.map +1 -0
  124. package/dist/baseline/producers/licenses.d.ts +23 -0
  125. package/dist/baseline/producers/licenses.d.ts.map +1 -0
  126. package/dist/baseline/producers/licenses.js +46 -0
  127. package/dist/baseline/producers/licenses.js.map +1 -0
  128. package/dist/baseline/producers/quality.d.ts +39 -0
  129. package/dist/baseline/producers/quality.d.ts.map +1 -0
  130. package/dist/baseline/producers/quality.js +84 -0
  131. package/dist/baseline/producers/quality.js.map +1 -0
  132. package/dist/baseline/producers/secret-hmac.d.ts +45 -0
  133. package/dist/baseline/producers/secret-hmac.d.ts.map +1 -0
  134. package/dist/baseline/producers/secret-hmac.js +70 -0
  135. package/dist/baseline/producers/secret-hmac.js.map +1 -0
  136. package/dist/baseline/producers/security.d.ts +59 -0
  137. package/dist/baseline/producers/security.d.ts.map +1 -0
  138. package/dist/baseline/producers/security.js +135 -0
  139. package/dist/baseline/producers/security.js.map +1 -0
  140. package/dist/baseline/producers/tests.d.ts +36 -0
  141. package/dist/baseline/producers/tests.d.ts.map +1 -0
  142. package/dist/baseline/producers/tests.js +69 -0
  143. package/dist/baseline/producers/tests.js.map +1 -0
  144. package/dist/baseline/salt.d.ts +45 -0
  145. package/dist/baseline/salt.d.ts.map +1 -0
  146. package/dist/baseline/salt.js +113 -0
  147. package/dist/baseline/salt.js.map +1 -0
  148. package/dist/baseline/show.d.ts +79 -0
  149. package/dist/baseline/show.d.ts.map +1 -0
  150. package/dist/baseline/show.js +233 -0
  151. package/dist/baseline/show.js.map +1 -0
  152. package/dist/baseline/types.d.ts +482 -0
  153. package/dist/baseline/types.d.ts.map +1 -0
  154. package/dist/baseline/types.js +53 -0
  155. package/dist/baseline/types.js.map +1 -0
  156. package/dist/cli.d.ts.map +1 -1
  157. package/dist/cli.js +395 -92
  158. package/dist/cli.js.map +1 -1
  159. package/dist/codebase-scanner.d.ts.map +1 -1
  160. package/dist/codebase-scanner.js +0 -1
  161. package/dist/codebase-scanner.js.map +1 -1
  162. package/dist/constants.d.ts.map +1 -1
  163. package/dist/constants.js +0 -4
  164. package/dist/constants.js.map +1 -1
  165. package/dist/detect.js +3 -3
  166. package/dist/detect.js.map +1 -1
  167. package/dist/doctor.d.ts.map +1 -1
  168. package/dist/doctor.js +22 -25
  169. package/dist/doctor.js.map +1 -1
  170. package/dist/fail-on.d.ts +84 -0
  171. package/dist/fail-on.d.ts.map +1 -0
  172. package/dist/fail-on.js +128 -0
  173. package/dist/fail-on.js.map +1 -0
  174. package/dist/generator.d.ts.map +1 -1
  175. package/dist/generator.js +2 -141
  176. package/dist/generator.js.map +1 -1
  177. package/dist/languages/capabilities/provider.d.ts +4 -4
  178. package/dist/languages/capabilities/types.d.ts +1 -1
  179. package/dist/languages/csharp.d.ts.map +1 -1
  180. package/dist/languages/csharp.js +15 -24
  181. package/dist/languages/csharp.js.map +1 -1
  182. package/dist/languages/go.d.ts.map +1 -1
  183. package/dist/languages/go.js +0 -15
  184. package/dist/languages/go.js.map +1 -1
  185. package/dist/languages/index.d.ts +4 -3
  186. package/dist/languages/index.d.ts.map +1 -1
  187. package/dist/languages/index.js +3 -2
  188. package/dist/languages/index.js.map +1 -1
  189. package/dist/languages/java.d.ts.map +1 -1
  190. package/dist/languages/java.js +0 -6
  191. package/dist/languages/java.js.map +1 -1
  192. package/dist/languages/kotlin.d.ts.map +1 -1
  193. package/dist/languages/kotlin.js +0 -11
  194. package/dist/languages/kotlin.js.map +1 -1
  195. package/dist/languages/python.d.ts.map +1 -1
  196. package/dist/languages/python.js +0 -15
  197. package/dist/languages/python.js.map +1 -1
  198. package/dist/languages/ruby.d.ts.map +1 -1
  199. package/dist/languages/ruby.js +0 -6
  200. package/dist/languages/ruby.js.map +1 -1
  201. package/dist/languages/rust.d.ts.map +1 -1
  202. package/dist/languages/rust.js +0 -4
  203. package/dist/languages/rust.js.map +1 -1
  204. package/dist/languages/types.d.ts +9 -35
  205. package/dist/languages/types.d.ts.map +1 -1
  206. package/dist/languages/typescript.d.ts.map +1 -1
  207. package/dist/languages/typescript.js +26 -4
  208. package/dist/languages/typescript.js.map +1 -1
  209. package/dist/lib.d.ts +2 -3
  210. package/dist/lib.d.ts.map +1 -1
  211. package/dist/lib.js +3 -6
  212. package/dist/lib.js.map +1 -1
  213. package/dist/prompts.d.ts.map +1 -1
  214. package/dist/prompts.js +0 -10
  215. package/dist/prompts.js.map +1 -1
  216. package/dist/report-schema.d.ts +42 -0
  217. package/dist/report-schema.d.ts.map +1 -0
  218. package/dist/report-schema.js +54 -0
  219. package/dist/report-schema.js.map +1 -0
  220. package/dist/ship-installers.d.ts +106 -0
  221. package/dist/ship-installers.d.ts.map +1 -0
  222. package/dist/ship-installers.js +415 -0
  223. package/dist/ship-installers.js.map +1 -0
  224. package/dist/types.d.ts +0 -4
  225. package/dist/types.d.ts.map +1 -1
  226. package/dist/update.d.ts.map +1 -1
  227. package/dist/update.js +0 -4
  228. package/dist/update.js.map +1 -1
  229. package/package.json +17 -11
  230. package/templates/.claude/agents/onboarding.md +5 -4
  231. package/templates/.claude/agents-available/codebase-explorer.md +1 -1
  232. package/templates/.claude/agents-available/debugger.md +2 -2
  233. package/templates/.claude/agents-available/health-auditor.md +2 -2
  234. package/templates/.claude/commands/doctor.md +20 -12
  235. package/templates/.claude/skills/build/SKILL.md.template +22 -30
  236. package/templates/.claude/skills/deploy/SKILL.md.template +5 -25
  237. package/templates/.claude/skills/doctor/SKILL.md +24 -47
  238. package/templates/.claude/skills/gcloud/SKILL.md +5 -5
  239. package/templates/.claude/skills/learned/SKILL.md +1 -1
  240. package/templates/.claude/skills/pulumi/SKILL.md +2 -2
  241. package/templates/.claude/skills/quality/SKILL.md.template +4 -23
  242. package/templates/.claude/skills/review/SKILL.md.template +4 -3
  243. package/templates/.claude/skills/scaffold/SKILL.md.template +5 -15
  244. package/templates/.claude/skills/secrets/SKILL.md +20 -21
  245. package/templates/.claude/skills/session/SKILL.md +20 -31
  246. package/templates/.claude/skills/test/SKILL.md.template +1 -7
  247. package/templates/.devcontainer/devcontainer.json +81 -0
  248. package/templates/.devcontainer/install-agent-clis.sh +42 -0
  249. package/templates/.devcontainer/post-create.sh +67 -0
  250. package/templates/.githooks/pre-commit +55 -0
  251. package/templates/.githooks/pre-push +63 -0
  252. package/templates/.github/workflows/dxkit-baseline-refresh.yml +78 -0
  253. package/templates/.github/workflows/dxkit-guardrails.yml +98 -0
  254. package/templates/CLAUDE.md.template +62 -196
  255. package/dist/project-yaml.d.ts +0 -13
  256. package/dist/project-yaml.d.ts.map +0 -1
  257. package/dist/project-yaml.js +0 -188
  258. package/dist/project-yaml.js.map +0 -1
  259. package/templates/.ai/README.md +0 -117
  260. package/templates/.ai/prompts/execution-prompt.md +0 -9
  261. package/templates/.ai/prompts/planning-prompt.md +0 -18
  262. package/templates/.ai/prompts/session-end-template.md +0 -182
  263. package/templates/.ai/prompts/session-end.md +0 -132
  264. package/templates/.ai/prompts/session-start.md +0 -109
  265. package/templates/.ai/prompts/step-by-step.md +0 -113
  266. package/templates/.ai/sessions/.gitkeep +0 -0
  267. package/templates/.claude/commands/setup-pr-review.md +0 -72
  268. package/templates/.devcontainer/Dockerfile.dev.template +0 -89
  269. package/templates/.devcontainer/devcontainer.json.template +0 -184
  270. package/templates/.devcontainer/docker-compose.yml.template +0 -105
  271. package/templates/.devcontainer/init-scripts/01-init.sql.template +0 -12
  272. package/templates/.devcontainer/post-create.sh.template +0 -298
  273. package/templates/.github/workflows/ci.yml.template +0 -399
  274. package/templates/.github/workflows/quality.yml.template +0 -376
  275. package/templates/.pre-commit-config.yaml.template +0 -106
  276. package/templates/.project/config/edit_config.py +0 -275
  277. package/templates/.project/config/project_config.py +0 -894
  278. package/templates/.project/scripts/codegen/generate-all.sh +0 -20
  279. package/templates/.project/scripts/codegen/validate-all.sh +0 -17
  280. package/templates/.project/scripts/docs/generate-all.sh +0 -30
  281. package/templates/.project/scripts/docs/serve.sh +0 -20
  282. package/templates/.project/scripts/quality/fix-all.sh +0 -138
  283. package/templates/.project/scripts/quality/lint-go.sh +0 -34
  284. package/templates/.project/scripts/quality/lint-python.sh +0 -54
  285. package/templates/.project/scripts/quality/run-all.sh +0 -497
  286. package/templates/.project/scripts/session/commit.sh +0 -70
  287. package/templates/.project/scripts/session/create-pr.sh +0 -165
  288. package/templates/.project/scripts/session/end.sh +0 -207
  289. package/templates/.project/scripts/session/start.sh +0 -233
  290. package/templates/.project/scripts/setup/doctor.sh +0 -404
  291. package/templates/.project/scripts/setup/interactive-setup.sh +0 -585
  292. package/templates/.project/scripts/sync/sync-template.sh +0 -328
  293. package/templates/.project/scripts/test/run-all.sh +0 -179
  294. package/templates/.project/scripts/test/run-quick.sh +0 -25
  295. package/templates/Makefile +0 -514
  296. package/templates/config/versions.yaml +0 -57
  297. package/templates/configs/go/.golangci.yml.template +0 -172
  298. package/templates/configs/go/go.mod.template +0 -15
  299. package/templates/configs/java/README.md +0 -6
  300. package/templates/configs/kotlin/README.md +0 -6
  301. package/templates/configs/node/package.json.template +0 -67
  302. package/templates/configs/node/tsconfig.json.template +0 -53
  303. package/templates/configs/python/pyproject.toml.template +0 -92
  304. package/templates/configs/python/pytest.ini.template +0 -64
  305. package/templates/configs/python/ruff.toml.template +0 -79
  306. package/templates/configs/ruby/README.md +0 -6
  307. package/templates/configs/rust/Cargo.toml.template +0 -51
  308. package/templates/configs/shared/.editorconfig +0 -67
  309. package/templates/scripts/validate-templates.sh +0 -449
package/CHANGELOG.md CHANGED
@@ -7,6 +7,432 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2.5.0] - 2026-05-18
11
+
12
+ ### Summary
13
+
14
+ 2.5.0 introduces **commit-time guardrails** — a per-finding baseline
15
+ captured once on a brownfield repo, then diffed against every
16
+ subsequent scan to detect net-new regressions while grandfathering
17
+ existing debt. Existing issues stay where they are, new ones block.
18
+
19
+ This release also **prunes the legacy task-runner scaffolding** that
20
+ prior versions of `init --full` bundled (Makefile, `.project/` task
21
+ scripts, `.ai/` prompt scaffolding, per-language config templates,
22
+ non-dxkit CI workflows, `.editorconfig`, `.pre-commit-config.yaml`).
23
+ The agent DX surface is now the sole `init --full` output —
24
+ `init --full` lands 73 files (down from 119), every one of them
25
+ focused on equipping AI coding agents to operate safely on the
26
+ codebase. Customers who relied on the legacy scaffolding can use
27
+ `@vyuhlabs/create-devstack` for greenfield project bootstrap.
28
+
29
+ The release ships three coordinated surfaces:
30
+
31
+ 1. **A new `baseline` / `guardrail` CLI** that captures stable
32
+ per-finding identities, diffs current scans against them, and
33
+ classifies each pair (`added` / `relocated` / `tooling_drift` /
34
+ `config_drift` / `persisted` / `removed` / `fixed`) with a
35
+ confidence score and structured reasons. The classifier ships
36
+ with a **scanner-wobble demotion** that converts `added` findings
37
+ on UNCHANGED lines into `uncertain` (warn) for high-wobble kinds
38
+ (`code`, `hygiene`), so semgrep's per-run non-determinism on
39
+ large codebases doesn't trigger false-positive blocks. Findings
40
+ inside the diff's changed lines still block — real regressions
41
+ are caught. Customers can extend or clear the kind list via
42
+ `addedRequiresChangedLines` in `.dxkit/policy.json`.
43
+ 2. **Init-installable templates** for the pre-push guardrail hook,
44
+ a devcontainer with pinned toolchains + Claude Code & Codex
45
+ CLIs, a GitHub Actions PR-gate workflow that posts a markdown
46
+ summary as a PR comment, and a post-merge baseline-refresh
47
+ workflow that keeps the anchor current. Pre-commit + AI-PR-
48
+ review are opt-in via `--with-precommit-hook` and
49
+ `--with-pr-review` respectively (slow on large repos / requires
50
+ API-cost opt-in). Every `init` also seeds `.gitignore` entries
51
+ for the analyzer runtime outputs (`.dxkit/reports/`,
52
+ `.dxkit/dashboard.html`) and writes a starter `.dxkit-ignore`
53
+ template for dxkit-specific scan-exclusion tuning.
54
+ 3. **Aggregate-gate flags** (`--fail-on-score`, `--fail-on-severity`)
55
+ on every analyzer command, plus a stable JSON schema banner on
56
+ every `--json` output so consumers can version-gate.
57
+
58
+ Tests: ~1530 unit + integration cases pass on the integrated branch
59
+ (up from 1265 at the 2.4.8 baseline; +265 across fingerprinting,
60
+ producers, policy, matcher, ship installers, the smart classifier,
61
+ opt-in hook + workflow installers, and the CLI surface).
62
+
63
+ #### New CLI surface
64
+
65
+ ```bash
66
+ vyuh-dxkit baseline create [path] [--name <name>] [--force]
67
+ [--verbose]
68
+ vyuh-dxkit baseline show [path] [--name <name>] [--baseline <p>]
69
+ [--kind <kind>] [--json]
70
+ vyuh-dxkit guardrail check [path] [--name <name>] [--baseline <p>]
71
+ [--changed-only] [--policy <p>]
72
+ [--json | --markdown]
73
+ ```
74
+
75
+ - `baseline create` runs every analyzer, fingerprints each per-
76
+ finding entity through the canonical identity dispatcher
77
+ (`src/baseline/finding-identity.ts`), and writes
78
+ `.dxkit/baselines/<name>.json`. Schema-versioned
79
+ (`dxkit-baseline/v1`); commit it.
80
+ - `baseline show` pretty-prints the on-disk baseline, optionally
81
+ filtered by kind or emitted as a schema-banner-wrapped JSON.
82
+ - `guardrail check` loads the baseline, re-runs the analyzers,
83
+ matches via the git-aware matcher (`-M` renames, ±2 line fuzz,
84
+ content-hash fallback for shallow clones), classifies each pair
85
+ through the brownfield policy, and exits 1 when the policy
86
+ blocks. Output modes: console (default), `--json` (schema
87
+ `dxkit.guardrail-check.v1`), or `--markdown` (used by the PR-
88
+ gate workflow to post a comment).
89
+
90
+ The full read/write/compare triplet flows through a registered
91
+ producer pipeline (`src/baseline/producers/index.ts:PRODUCERS`) —
92
+ adding a new identity kind means registering a producer, not
93
+ editing the orchestrator. Architectural rule documented in
94
+ `CLAUDE.md` Rule 10 with three enforcement gates (arch check +
95
+ contract test + synthetic-producer playbook).
96
+
97
+ #### Aggregate gates + schema banner
98
+
99
+ Every analyzer command (`health`, `test-gaps`, `quality`,
100
+ `vulnerabilities`, `bom`) gains composable exit-code gates:
101
+
102
+ - `--fail-on-score <N>` — exit 1 when the headline score drops
103
+ below N (applies to `health`, `test-gaps`).
104
+ - `--fail-on-severity <tier>` — exit 1 when any finding at `<tier>`
105
+ or higher exists (applies to `vulnerabilities`, `bom`; tier ∈
106
+ critical / high / medium / low).
107
+
108
+ Every `--json` output carries a top-level
109
+ `schema: 'dxkit.<kind>-report.v1'` banner so consumers can version-
110
+ gate against future schema migrations.
111
+
112
+ #### `vyuh-dxkit init` ship flags
113
+
114
+ `init` gains four new flags, all implied by `--full`:
115
+
116
+ - `--with-hooks` writes `.githooks/pre-commit` (fast,
117
+ `--changed-only`) and `.githooks/pre-push` (full).
118
+ - `--with-devcontainer` writes a lightweight `.devcontainer/`
119
+ layering all seven supported language toolchains via devcontainer
120
+ features + a `post-create.sh` that runs `vyuh-dxkit tools install
121
+ --yes` to provision the scanner toolchain pinned in the registry
122
+ + `install-agent-clis.sh` that installs Claude Code + OpenAI
123
+ Codex CLIs (opt out of either with `CLAUDE_CODE_VERSION=skip` /
124
+ `CODEX_VERSION=skip`).
125
+ - `--with-ci` writes `.github/workflows/dxkit-guardrails.yml` (PR-
126
+ gate that posts a markdown summary as a PR comment, updating in
127
+ place across pushes via an HTML marker).
128
+ - `--with-baseline-refresh` writes
129
+ `.github/workflows/dxkit-baseline-refresh.yml` (regenerates the
130
+ baseline on every push to the consumer's default branch and
131
+ auto-commits with `[skip ci]`). The default-branch name is
132
+ detected at install time from the consumer's git state, with
133
+ fallbacks for `main` / `master` / `trunk` / `develop`.
134
+
135
+ Installs are **additive by default**. Existing `.githooks/<hook>`
136
+ or `.husky/<hook>` files trigger a `.dxkit` sidecar + merge note
137
+ instead of an overwrite. An existing `.devcontainer/devcontainer.json`
138
+ stashes the full dxkit set under `.devcontainer/.dxkit-reference/`
139
+ for manual merge. Workflow files are uniquely named so they don't
140
+ collide; if our exact filename already exists, init skips it. The
141
+ `--force` flag overrides every additive fallback and writes in
142
+ place.
143
+
144
+ #### Brownfield policy
145
+
146
+ `.dxkit/policy.json` (auto-discovered at the repo root) tunes which
147
+ classifications block vs warn, per-severity confidence thresholds
148
+ that demote low-quality matches to `uncertain`, and per-finding-kind
149
+ block rules (`newSecret`, `newCriticalSecurity`,
150
+ `newCriticalDependencyVulnerability`, etc.). Compiled-in defaults
151
+ ship a conservative posture: block on `added`, warn on
152
+ `tooling_drift` / `config_drift` / `newly_detected` /
153
+ `probable_existing` / `uncertain`. The `--policy <path>` flag
154
+ overrides auto-discovery; when no policy is found, the defaults
155
+ apply.
156
+
157
+ #### Architectural fixes surfaced by the customer-repo audit
158
+
159
+ A pre-ship audit on three real customer repositories (a 444-source
160
+ TypeScript backend, a 553-source TypeScript frontend, and a
161
+ .NET WinForms project) surfaced four drift classes between the
162
+ report aggregates and the per-finding identity sets the baseline
163
+ captures. All four are closed in 2.5.0:
164
+
165
+ 1. **Large-file producer was capped at top 10.** The gather layer
166
+ pre-sliced `largestFiles` to ten entries for the markdown
167
+ renderer's "Top Files by Size" table; the baseline producer
168
+ inherited the cap and silently dropped per-file identity for
169
+ every oversized file beyond the first ten. A real customer
170
+ brownfield with 47 files over 500 lines saw 10 baseline entries;
171
+ the .NET project with 926 oversized files saw 10. The gather now
172
+ emits every file over the 500-line threshold sorted descending;
173
+ the renderer adds an explicit `.slice(0, 10)` at the table site.
174
+ `HealthMetrics.filesOver500Lines` aggregate now matches the
175
+ per-kind count in the baseline byte for byte. Combined recovery
176
+ across the three audit repos: 1,087 previously-silently-missed
177
+ `large-file` findings now flow into baselines.
178
+
179
+ 2. **Secret-HMAC producer emitted duplicates.** When the same
180
+ secret value appeared at multiple locations — the same token on
181
+ two lines of one file, a leaked key in both `.env` and
182
+ `src/config.ts`, or two overlapping gitleaks rules firing on the
183
+ same line — the producer wrote multiple entries with identical
184
+ `(rule, hmac)` identity. Identity sets aren't supposed to have
185
+ duplicates by definition. Now a per-call `Set<string>` keyed on
186
+ the computed identity collapses repeats; first write wins,
187
+ output order is stable.
188
+
189
+ 3. **Tools-map version probes occasionally cached `'present'`
190
+ under load.** The per-process version cache locks the first
191
+ probe's outcome to keep `toolchainHash` byte-stable across two
192
+ back-to-back gathers (a previously-shipped flake closure). But
193
+ when the first `execSync(<tool> --version)` raced its 5-second
194
+ timeout under heavy CPU load — parallel scanner pools or the
195
+ post-merge workflow doing two scans in series — the cache locked
196
+ the `'present'` fallback for the rest of the process. The tools
197
+ map in the baseline file then read `gitleaks@present` instead of
198
+ a real version, and the next run flagged spurious tooling-drift.
199
+ The fix retries the version probe up to three times before
200
+ falling back; each attempt is fresh. The cache layer is
201
+ unchanged — once a value settles (real version or genuine
202
+ `'present'`), it's locked for the rest of the process.
203
+
204
+ 4. **TypeScript license enrichment could stall the entire licenses
205
+ capability.** `gatherTsLicensesResult` calls `enrichReleaseDates`
206
+ after license-checker returns to populate the optional
207
+ `releaseDate` field from the npm registry. The enrichment runs
208
+ with 20-way concurrency, 10s per request — usually fast — but a
209
+ flaky network or rate-limited registry can push a 700-package
210
+ run past the dispatcher's 720-second deadline. When that
211
+ happens, the entire licenses capability is dropped and the
212
+ baseline silently loses every license entry. On the TypeScript
213
+ frontend audit repo, license-checker itself returned 749KB of
214
+ JSON in under 10 seconds when invoked manually; the enrichment
215
+ stalled the whole capability. Now the enrichment is raced
216
+ against a 60-second wall-clock budget; on timeout, the license
217
+ findings still emit with their static fields and `releaseDate`
218
+ is left unset on the unenriched ones. A previously-zero baseline
219
+ now captures 1,897 license entries on that repo.
220
+
221
+ Together these four fixes recover **~3,000 baseline findings** that
222
+ were being silently dropped on real customer repos pre-2.5.0.
223
+
224
+ #### Migration guidance for 2.4.x users
225
+
226
+ No breaking changes. Existing analyzer commands continue to work
227
+ exactly as before. The new commands and flags are additive.
228
+
229
+ To start using guardrails on an existing repo:
230
+
231
+ ```bash
232
+ vyuh-dxkit init --with-hooks --with-ci --with-baseline-refresh
233
+ git config core.hooksPath .githooks
234
+ vyuh-dxkit baseline create
235
+ git add .dxkit/baselines/main.json .githooks .github/workflows/dxkit-*.yml
236
+ git commit -m "chore: enable dxkit guardrails"
237
+ ```
238
+
239
+ See [`docs/getting-started.md`](docs/getting-started.md),
240
+ [`docs/commands/baseline.md`](docs/commands/baseline.md),
241
+ [`docs/commands/guardrail.md`](docs/commands/guardrail.md), and
242
+ [`docs/configuration/policy.md`](docs/configuration/policy.md) for
243
+ the full walkthrough.
244
+
245
+ ## [2.4.8] - 2026-05-18
246
+
247
+ ### Summary
248
+
249
+ Focused patch release closing the regressions surfaced by a
250
+ post-2.4.7 user-simulation evaluation across the three external
251
+ audit repos. The biggest item is the structural follow-up to
252
+ D134 — the silent-health failure root-caused in 2.4.7 was a
253
+ real abandoned-Promise inside `runDetached`, but the underlying
254
+ class (unbounded await chain at the dispatcher level) had a
255
+ second failure mode that the 2.4.7 fix didn't reach. 2.4.8
256
+ closes it structurally. Plus: a date-rollover false-failure on
257
+ long runs, a Tools-used footer attribution drift, a cascade
258
+ warning when the analysis cache can't be built, and a README
259
+ upgrade-advisory correction. Tests: 1265 / 0 (up from 1241 at
260
+ the 2.4.7 baseline).
261
+
262
+ #### Per-provider deadline closes a second silent-health failure mode (D141)
263
+
264
+ D134 in 2.4.7 added a `settle()` guard plus a safety deadline
265
+ **inside** `runDetached` so that exit / error / safety-deadline
266
+ each force the subprocess Promise to resolve. That closed the
267
+ shape where a `runDetached` Promise itself stayed pending. But
268
+ a post-ship user-simulation reproduced the same silent-rc=0
269
+ behavior on a JS-heavy customer frontend audit — and this time
270
+ the runDetached safety deadline did not fire, because the
271
+ abandoned Promise was not inside `runDetached` at all. It was
272
+ inside the capability dispatcher's `Promise.allSettled` over
273
+ nine providers: one of those providers' `gatherOutcome` chains
274
+ contained a Promise that never settled, `Promise.allSettled`
275
+ cannot collapse an unsettled Promise, the whole
276
+ `gatherCapabilityReport` stayed pending forever, Node's event
277
+ loop emptied and the parent saw a clean rc=0 with no markdown
278
+ written.
279
+
280
+ Fix (commit `611321d`):
281
+
282
+ - New `src/analyzers/tools/deadline.ts` with a
283
+ `withDeadline(promise, deadlineMs)` helper that races any
284
+ Promise against a timer.
285
+ - The dispatcher (`src/analyzers/dispatcher.ts`) wraps every
286
+ provider's `gather` / `gatherOutcome` call in a 720-second
287
+ deadline (`DEFAULT_PROVIDER_DEADLINE_MS`). A stalled provider
288
+ is materialised as a skipped source with reason
289
+ `"stalled at >Ns (deadline)"` that flows through the existing
290
+ availability machinery into the `Tools unavailable` surface.
291
+ A stderr line names the stalled capability + source so the
292
+ abandoned-Promise location is visible in `--verbose` and CI
293
+ logs.
294
+ - The two non-dispatcher gathers
295
+ (`gatherDepVulnsWithAvailability` and
296
+ `gatherLicensesWithAvailability`) iterate active packs
297
+ themselves; both apply the same per-pack deadline pattern.
298
+ - New `DispatcherOptions` fields (`providerDeadlineMs`,
299
+ `onProviderStall`) so tests can wrap deadlines around 50-ms
300
+ stubs without polluting test output. Default `onProviderStall`
301
+ emits the stderr notification.
302
+ - New regression test
303
+ (`test/dispatcher-deadline.test.ts`, 7 cases) exercises the
304
+ helper directly, the dispatcher with one hung + one good
305
+ provider, the all-hung case, the bounded wall-clock claim,
306
+ and confirms thrown-provider rejections still route through
307
+ `onProviderError` (not `onProviderStall`).
308
+
309
+ Verification on the failure repo:
310
+
311
+ - Pre-fix (2.4.7 user-sim): `report` exited 1 after ~1428 s;
312
+ Health step hung in the capabilities Promise.all and never
313
+ wrote `health-audit-*.md`; orchestrator's 2.4.7
314
+ defense-in-depth guard surfaced the ✗ but the underlying
315
+ hang remained.
316
+ - Post-fix: `report` exited 0 in 1264.5 s; all 8 steps wrote
317
+ their reports; one stderr line attributed the stall to the
318
+ typescript-pack licenses provider walking a deep
319
+ `node_modules` tree — the reproducible offender behind the
320
+ intermittent hang. The Licenses report's framing notice
321
+ reads `typescript: stalled at >720s (deadline)` so the
322
+ customer sees what to act on.
323
+
324
+ The class is now closed by construction: a never-settling
325
+ provider can no longer keep `Promise.allSettled` pending
326
+ forever; the worst-case behaviour is one capability surfacing
327
+ as unavailable with the deadline reason visible to the user.
328
+
329
+ #### Orchestrator date snapshot survives UTC-midnight rollover (D140)
330
+
331
+ Long `vyuh-dxkit report` runs that crossed UTC midnight
332
+ produced false failures. Files written before midnight got the
333
+ old date suffix; files written after got the new one; the
334
+ orchestrator's post-step file-existence check compared against
335
+ the date snapshot it captured at startup. Several reports were
336
+ on disk under the new date but the orchestrator reported them
337
+ as missing.
338
+
339
+ Fix (commit `cc1f146`):
340
+
341
+ - New `src/analyzers/tools/report-date.ts` exposes
342
+ `getReportDate()`, which honors the optional
343
+ `DXKIT_REPORT_DATE=YYYY-MM-DD` env var (validated) and falls
344
+ back to today's UTC date.
345
+ - The orchestrator captures the date once at startup and
346
+ threads it to every child subcommand via the env var, so
347
+ every report filename in a single run shares the same date.
348
+ - All 10 internal date-stamping call sites in
349
+ `src/cli.ts` + dashboard + dev-report routed through the
350
+ helper.
351
+ - 6 new tests in `test/report-date.test.ts`, including a
352
+ `Date.now` jump that emulates the orchestrator-snapshot
353
+ surviving a midnight rollover.
354
+
355
+ #### Tools-used footer reads cleanly when one pack's lint skipped (D138 follow-up)
356
+
357
+ The 2.4.7 D138 work landed honesty-prose in the dedicated
358
+ `⚠ Lint coverage gap` row when one active language pack's
359
+ linter didn't run. But the `Tools used:` footer at the bottom
360
+ of every report was still rendering the augmented label
361
+ verbatim — so on a polyglot repo it read
362
+ `..., ruff (not run: typescript — config error), ...`, which
363
+ parses as "ruff did not run because of typescript" (false;
364
+ ruff ran fine on Python files; the parenthetical describes
365
+ eslint's fate, not ruff's). Internal commas inside the
366
+ parenthetical also broke the comma-split that fanned the
367
+ footer string into individual tool names.
368
+
369
+ Fix (commit `98ea153`):
370
+
371
+ - New `src/analyzers/tools/lint-label.ts` centralises the
372
+ parse (regex + `stripNotRunSuffix` helper).
373
+ - `splitToolNames` in `health.ts` and the `toolsUsed` push in
374
+ `quality/index.ts` both strip the `(not run: ...)` suffix
375
+ before emitting into the footer.
376
+ - The dedicated `⚠ Lint coverage gap` row keeps its own
377
+ augmented-label parse — that row is exactly where the
378
+ per-pack skip belongs.
379
+ - 11 tests in `test/lint-label.test.ts` cover single-pack,
380
+ multi-pack with internal commas, and malformed input.
381
+
382
+ #### Cascade warning when health fails before the analysis cache builds (related to D141)
383
+
384
+ When the Health step fails before the cross-process
385
+ `AnalysisResult` cache is built, every downstream report
386
+ (Vulnerabilities, BoM, Licenses, Test gaps, Quality,
387
+ Developer) re-runs detection + Layer 0 + Layer 2 gather from
388
+ scratch — measurably slower than the cache-hit path. On a
389
+ heavy polyglot repo this can add hundreds of seconds across
390
+ the run. The structural fix (build the cache from the
391
+ gather output even when the markdown write fails) is the
392
+ larger piece; this release surfaces the symptom honestly so
393
+ the user understands why the remaining steps feel slower.
394
+
395
+ Fix (commit `fa019f8`):
396
+
397
+ - When Health fails before the cache is built, the
398
+ orchestrator logs:
399
+ `Health failed before the analysis cache could be built.
400
+ The remaining steps will re-detect the stack and re-gather
401
+ shared metrics from scratch (expect each to be measurably
402
+ slower than usual).`
403
+ - No new tests — the warning is exercised end-to-end via
404
+ the orchestrator's existing integration coverage.
405
+
406
+ #### README upgrade advisory now matches the observed behavior of modern npm (related to F3 audit finding)
407
+
408
+ The 2.4.7 README's "Already installed dxkit globally?" callout
409
+ claimed `npx @vyuhlabs/dxkit@<version>` falls through to a
410
+ stale `vyuh-dxkit` global on PATH. Tested under npm 11.6.0
411
+ with a stale 2.4.2 global installed, `npx @vyuhlabs/dxkit@2.4.7
412
+ --version` correctly returned `2.4.7` — modern npm/npx does
413
+ not fall through. A reader following the advisory might
414
+ uninstall a working global install on advice that doesn't
415
+ match their environment.
416
+
417
+ Fix (commit `6d8363b`): rewrites the callout to keep the
418
+ genuinely useful upgrade hint (globals don't auto-update;
419
+ either upgrade them or remove them and rely on `npx`) without
420
+ the inaccurate npx-behaviour assertion. Also drops the
421
+ 2.4.7-specific fix-mention which would have gone stale after
422
+ this release.
423
+
424
+ ### Test posture
425
+
426
+ - `npm run test:run` — **1265 / 0** (up from 1241).
427
+ - `+6` tests for D140 (`test/report-date.test.ts`).
428
+ - `+11` tests for D138 follow-up (`test/lint-label.test.ts`).
429
+ - `+7` tests for D141 (`test/dispatcher-deadline.test.ts`),
430
+ including the D138-class regression that simulates a
431
+ never-settling provider and asserts the dispatcher returns
432
+ within the deadline window with the stalled source in
433
+ `skipped` + `skipReasons`.
434
+ - arch / slop / lint / format / typecheck — all clean.
435
+
10
436
  ## [2.4.7] - 2026-05-17
11
437
 
12
438
  ### Summary
@@ -204,7 +630,7 @@ Fix (commit `425d0ef`):
204
630
  | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- |
205
631
  | D124 / D100 / D118 | Vendored-source exclusion class-fix — top-largest-file metric on all 3 customer repos now first-party (or correctly flagged by the per-file advisor). Generic `largest_files` walk routes through canonical exclusions. | `72ec70a` |
206
632
  | D113 / D128 | Per-pack lint-skip reasons plumbed end-to-end. Tools row reads `ruff (not run: typescript — config error)` instead of dropping the skip silently. | `b878553` |
207
- | D118-residue | Graphify enumeration honors file-glob + content-minified exclusions. Webpack-hash bundles no longer rank as the densest file on customer reports (web-client: 4 606 fn artifact → 228 fn real first-party densest). | `0da08bd` |
633
+ | D118-residue | Graphify enumeration honors file-glob + content-minified exclusions. Webpack-hash bundles no longer rank as the densest file on customer reports (the JS-heavy customer frontend: 4 606 fn artifact → 228 fn real first-party densest). | `0da08bd` |
208
634
  | D135 / D136 (interim) | Vendored-advisor token list extended for SAP B1 OData proxy classes, map-library, proto-gen conventions. Customers with heavy-autogen .NET ERP integrations now see actionable `.dxkit-ignore` guidance. | `d9f0c31` |
209
635
 
210
636
  Tests at this phase close: 1241 / 0 (+15 new unit tests for
@@ -283,11 +709,11 @@ consumer.
283
709
  - **platform** (TS / Node backend): test-gap MEDIUM 207;
284
710
  Maintainability prose reads "controllers / components"
285
711
  (typescript wins cloc weight on a 106k-line monorepo).
286
- - **web-client** (React frontend): test-gap MEDIUM 499 → 379
712
+ - **the JS-heavy customer frontend** (React frontend): test-gap MEDIUM 499 → 379
287
713
  (-120) because the vendored-exclusion class-fix in the
288
714
  audit-residue phase above also excludes lexical-playground
289
715
  subtrees from primary-component matching. Honest count.
290
- - **dpl-studio** (.NET WinForms): Maintainability vocabulary
716
+ - **the .NET WinForms benchmark** (.NET WinForms): Maintainability vocabulary
291
717
  reads "Forms / Services"; test-gap classification correctly
292
718
  picks up the WinForms project structure.
293
719
 
@@ -401,11 +827,11 @@ for JSON-consumer migration.
401
827
 
402
828
  Two-phase release. **Phase A** (audit-driven hot-patches, originally
403
829
  shipped 2026-05-13) closed a 17-defect cascade surfaced by a critical
404
- post-shipment audit on dpl-studio (enterprise C# / 1500+ files / 68
830
+ post-shipment audit on the .NET WinForms benchmark (enterprise C# / 1500+ files / 68
405
831
  sub-projects / 1.6M lines of cloc-counted JSON), plus the long-deferred
406
832
  D021 (coverage workflow). **Phase B** (class-fix release, 2026-05-14)
407
833
  pivoted from patch shipping to architectural class-fix shipping after
408
- pre-ship audits on platform and web-client surfaced 12 NEW defects
834
+ pre-ship audits on platform and the JS-heavy customer frontend surfaced 12 NEW defects
409
835
  (D074–D085), 9 of which were repeated instances of the same disease
410
836
  class fixed at different sites.
411
837
 
@@ -430,7 +856,7 @@ scoring-credibility, and prioritization gaps that remained.
430
856
  siblings of `findings`; renderer reads them by name.
431
857
 
432
858
  - **C2.2 / D098 — `SECRETS_PRESENT_CAP = 40`** (commit `243fa86`).
433
- Pre-C2 baseline: web-client scored Security 60/100 "Good" despite
859
+ Pre-C2 baseline: the JS-heavy customer frontend scored Security 60/100 "Good" despite
434
860
  4 hardcoded API keys + 1 .env in git. Credentials in source-control
435
861
  history are presumed compromised even after rotation, and a "Good"
436
862
  score reads as deprioritizable. C2.2 caps the Security dimension at
@@ -438,8 +864,8 @@ scoring-credibility, and prioritization gaps that remained.
438
864
  privateKeyFiles > 0 || envFilesInGit > 0`. Applied as a ceiling
439
865
  AFTER all per-signal penalties and the dep-availability cap, so
440
866
  it composes monotonically with everything else.
441
- - Validated: web-client 60 → 40 "Fair" (✓ cap fires);
442
- platform 45 → 40 "Fair" (✓); dpl-studio 90 → 90 (✓ cap
867
+ - Validated: the JS-heavy customer frontend 60 → 40 "Fair" (✓ cap fires);
868
+ platform 45 → 40 "Fair" (✓); the .NET WinForms benchmark 90 → 90 (✓ cap
443
869
  correctly does NOT fire — no committed credentials).
444
870
 
445
871
  - **C2.3 / D099 — `.env`-in-git callout block** (commit `7f43dfc`).
@@ -466,7 +892,7 @@ scoring-credibility, and prioritization gaps that remained.
466
892
  sections below.
467
893
 
468
894
  - **D108 — Top 5 sparse-tier fallback** (commit `c09ba87`). C2.5
469
- audit surfaced D108: dpl-studio's Top 5 had only 1 entry despite
895
+ audit surfaced D108: the .NET WinForms benchmark's Top 5 had only 1 entry despite
470
896
  2 unpatched dep vulns (MongoDB.Driver risk 19 + SharpCompress
471
897
  risk 15). The original C2.4 dep filter required `riskScore >= 25`
472
898
  which excluded the "watch" tier (10-25 per risk-score.ts), leaving
@@ -478,13 +904,13 @@ scoring-credibility, and prioritization gaps that remained.
478
904
  ### Phase C2 — Verification audit (C2.5)
479
905
 
480
906
  Cross-report parity audit on three customer repos (`platform`,
481
- `dpl-studio`, `web-client`). All vuln-scan + health pairs verified:
907
+ the .NET WinForms benchmark, the JS-heavy customer frontend). All vuln-scan + health pairs verified:
482
908
 
483
909
  - **D086 / D087 / D091 closures from C1 remain intact** across
484
910
  all 3 repos. Cross-report parity holds.
485
- - **D098 secrets-cap fires correctly**: web-client + platform both
486
- drop to 40 "Fair"; dpl-studio (no secrets) stays at 90.
487
- - **D099 .env callout renders correctly on web-client** (the only
911
+ - **D098 secrets-cap fires correctly**: the JS-heavy customer frontend + platform both
912
+ drop to 40 "Fair"; the .NET WinForms benchmark (no secrets) stays at 90.
913
+ - **D099 .env callout renders correctly on the JS-heavy customer frontend** (the only
488
914
  repo with a tracked .env).
489
915
  - **D105 Top 5 surfaces actionable rows on every repo**, post-D108
490
916
  including the sparse-repo case.
@@ -545,7 +971,7 @@ pre-release audit and fixed before ship.
545
971
  ScoreInput fixtures predating the aggregator field).
546
972
 
547
973
  - **D107 — BoM vs vuln-scan disagreement (NEW, surfaced in C1.7
548
- audit)** (commit `4ae69ed`). dpl-studio: vuln-scan reported 2 dep
974
+ audit)** (commit `4ae69ed`). the .NET WinForms benchmark: vuln-scan reported 2 dep
549
975
  advisories (MongoDB.Driver HIGH + SharpCompress MEDIUM via
550
976
  osv-scanner-nuget-direct) while BoM reported 0. Root cause: BoM
551
977
  walks per-sub-root project directories and called `gatherDepVulns`
@@ -555,7 +981,7 @@ pre-release audit and fixed before ship.
555
981
  now gathers dep-vulns ONCE at the repo root and passes the result
556
982
  to every per-sub-root entry builder via a new `depVulnsOverride`
557
983
  option. License-side stays per-sub-root (legitimately
558
- per-project). Post-fix: dpl-studio BoM 2 ≡ vuln-scan 2.
984
+ per-project). Post-fix: the .NET WinForms benchmark BoM 2 ≡ vuln-scan 2.
559
985
 
560
986
  - **G_v4_9 — csharp pack cwd-invariant** (commit `14b02a7`). The
561
987
  pack-contract defect underneath D107: `gatherCsharpDepVulnsResult`
@@ -570,7 +996,7 @@ pre-release audit and fixed before ship.
570
996
  consistency.
571
997
 
572
998
  - **D091 boundary case (NEW, surfaced in C1.7 audit)** (commit
573
- `c7b72e2`). Web-client `DBConfigureForm.js:43` (semgrep MEDIUM
999
+ `c7b72e2`). The JS-heavy customer frontend `SetupConfigForm.js:43` (semgrep MEDIUM
574
1000
  `bypass-tls-verification`) and `:45` (registry HIGH
575
1001
  `tls-validation-disabled`) — same root, 2 lines apart, same
576
1002
  canonical rule — failed to collapse because the
@@ -579,7 +1005,7 @@ pre-release audit and fixed before ship.
579
1005
  edge case in the C1.1 commit; biting in production was the trigger
580
1006
  to fix it. Fix: after the natural-bucket lookup misses, check
581
1007
  neighbor buckets at `(canonicalRule, file, line ± 3)`. Two
582
- MEDIUMs absorbed into HIGHs on web-client, reducing apparent
1008
+ MEDIUMs absorbed into HIGHs on the JS-heavy customer frontend, reducing apparent
583
1009
  code-finding count from 13 → 11 in the right direction.
584
1010
 
585
1011
  - **G_v4_8 architectural gate** (commit `6e89131`) in
@@ -620,12 +1046,12 @@ post-Phase-C1):
620
1046
  **81**" ≡ BoM `totalAdvisories` **81** ✓
621
1047
  - 5 cross-tool TLS-bypass collisions deduped (MEDIUM bucket
622
1048
  14 → 9)
623
- - **dpl-studio** (C#, 3 nested project roots):
1049
+ - **the .NET WinForms benchmark** (C#, 3 nested project roots):
624
1050
  - vuln-scan **2** ≡ BoM **2** ≡ health **2** (dep) ✓
625
1051
  - health code findings **1** ≡ vuln-scan code findings **1** ✓
626
- - **web-client** (JS-heavy, large repo with degraded license info):
1052
+ - **the JS-heavy customer frontend** (JS-heavy, large repo with degraded license info):
627
1053
  - dep advisories **31** ≡ **31** ≡ **31** ✓
628
- - D091-boundary case on `DBConfigureForm.js:43+:45` collapses (the
1054
+ - D091-boundary case on `SetupConfigForm.js:43+:45` collapses (the
629
1055
  C1.10 fix)
630
1056
  - 2 MEDIUMs absorbed into HIGHs via neighbor-bucket lookup
631
1057
 
@@ -657,7 +1083,7 @@ and a permanent gate:
657
1083
 
658
1084
  - **G_v4_7 — `walkSourceFiles` + `countLineMatches`** (new canonical
659
1085
  helpers in `src/analyzers/tools/walk-source-files.ts`). Pure JS,
660
- no shell. The web-client D082/D083 silent-zero cascade was caused
1086
+ no shell. The the JS-heavy customer frontend D082/D083 silent-zero cascade was caused
661
1087
  by `grep -rEf <pat> --include=*.js .` producing 67MB of stdout on
662
1088
  minified files, overflowing `run()`'s 64MB ceiling, and returning
663
1089
  empty. The walker prunes excluded files at the directory boundary,
@@ -699,10 +1125,10 @@ and a permanent gate:
699
1125
  | D078 — BoM Risk `**0.0**` for missing CVSS | MED | `46b0d6e` (`computeRiskScore` returns `null` for `cvssScore=0`) |
700
1126
  | D079 — duplicate grep-count implementations | MED | `82e0e75` + `e7a8821` (shared `gatherDebugStatements`) |
701
1127
  | D080 — lint dispatcher last-wins | MED | `72cd102` (`gatherWithProvenance` exposes attempted+skipped sources; label reads `"ruff (not run: typescript)"`) |
702
- | D082 — web-client `consoleLogCount = 0` silent zero | CRITICAL | `0e71683` + `3275e1e` + `e7a8821` (walker prunes minified files at directory boundary) |
1128
+ | D082 — the JS-heavy customer frontend `consoleLogCount = 0` silent zero | CRITICAL | `0e71683` + `3275e1e` + `e7a8821` (walker prunes minified files at directory boundary) |
703
1129
  | D083 — `run()` maxBuffer overflow on minified-JS | CRITICAL | `0e71683` + `3275e1e` + `099e844` + `32574e0` |
704
1130
  | D084 — D082 cascade (anyType, eval) | HIGH | closes with D082/D083 |
705
- | D085 — web-client dep-count drift | HIGH | `06b0cec` |
1131
+ | D085 — the JS-heavy customer frontend dep-count drift | HIGH | `06b0cec` |
706
1132
 
707
1133
  **Deferred to 2.4.8**:
708
1134
  - D081 (`Dead Imports: 0` suspicious) — investigated; root cause is
@@ -719,7 +1145,7 @@ and a permanent gate:
719
1145
 
720
1146
  Convergence audit on three customer repos:
721
1147
 
722
- - **dpl-studio**: 1537 source files consistent across health,
1148
+ - **the .NET WinForms benchmark**: 1537 source files consistent across health,
723
1149
  test-gaps, maintainability dimension; `consoleLogCount=1`,
724
1150
  `tlsDisabledCount=1` stable.
725
1151
  - **platform** (the audit's most-troubled repo): `sourceFiles`
@@ -727,7 +1153,7 @@ Convergence audit on three customer repos:
727
1153
  `consoleLogCount` cross-report converged 1578/1555 → **698 / 698**;
728
1154
  `tlsDisabledCount` 18 reported / 11 active → **11**; lint label
729
1155
  `"ruff"` → `"ruff (not run: typescript)"`.
730
- - **web-client**: `consoleLogCount` **0 → 1066** (D082/D083 closure;
1156
+ - **the JS-heavy customer frontend**: `consoleLogCount` **0 → 1066** (D082/D083 closure;
731
1157
  catastrophic silent zero eliminated).
732
1158
 
733
1159
  ### Phase A — Audit-driven hot-patches (2026-05-13)
@@ -792,7 +1218,7 @@ Four pieces shipped together:
792
1218
  declares the names cloc emits in its `--json` output. cloc's
793
1219
  per-language summary + `totalLines` aggregation now filter to the
794
1220
  active-pack set, so markup/data formats (JSON / XML / CSV /
795
- Markdown) stop deflating quality metrics. On dpl-studio: Comment
1221
+ Markdown) stop deflating quality metrics. On the .NET WinForms benchmark: Comment
796
1222
  Ratio 4.3% → 27.9% (a 1.6M JSON denominator vs C#'s 568K).
797
1223
 
798
1224
  ### Fixed — Tier 1 (credibility critical)
@@ -800,8 +1226,8 @@ Four pieces shipped together:
800
1226
  The post-shipment audit's master bug + its direct cascade:
801
1227
 
802
1228
  - **D055** — `.dxkit-ignore` multi-segment paths flatten to basenames
803
- in cloc / graphify / grep. `Dev/Addons/DPLAddon/SAPB1/` silently
804
- became `{Dev, Addons, DPLAddon, SAPB1}` — cloc then excluded every
1229
+ in cloc / graphify / grep. `Dev/Addons/VendorAddon/SAPB1/` silently
1230
+ became `{Dev, Addons, VendorAddon, SAPB1}` — cloc then excluded every
805
1231
  directory named `Dev` in the tree, killing 90% of source visibility.
806
1232
  Fix: `getClocExcludeFlags` emits `--exclude-dir` (basenames) PLUS
807
1233
  `--fullpath --not-match-d` (Perl regex on full path).
@@ -822,7 +1248,7 @@ The post-shipment audit's master bug + its direct cascade:
822
1248
  content marker) that `gatherGenericMetrics` uses for `sourceFiles`.
823
1249
  Pre-D072 docCommentFiles counted designer.cs / .g.cs files in the
824
1250
  numerator but not in `sourceFiles`'s denominator, producing 104%
825
- docRatio on dpl-studio even after D055.
1251
+ docRatio on the .NET WinForms benchmark even after D055.
826
1252
  - **D062** closure via **G_v4_4** above.
827
1253
 
828
1254
  ### Fixed — Tier 2 (visible UX bugs)
@@ -832,7 +1258,7 @@ The post-shipment audit's master bug + its direct cascade:
832
1258
  W10 7, W14 1, W16 6, ...` had silent gaps that implied "data
833
1259
  missing" when reality was zero commits.
834
1260
  - **D061** — Hot Files filters auto-generated files via the existing
835
- `autogeneratedSourcePatterns` registry. Pre-fix dpl-studio's hot
1261
+ `autogeneratedSourcePatterns` registry. Pre-fix the .NET WinForms benchmark's hot
836
1262
  list included `*.Designer.cs` files (WinForms designer regeneration
837
1263
  noise).
838
1264
  - **D063** — BoM Risk column rendered to one decimal (`18.5`,