feat(hardening): P1 maintainability metrics baseline + freshness gate (#1561)

Epic P1. Adds maintainability-metrics script (typed-error adoption, createLogger coverage, hotpath console.error, files>400 LOC), merges maintainability block into hardening-inventory report, adds 30-day freshness gate to ci-parity-gate.sh, re-baselines burndown 2026-06-18. Local validate + validate:ci-parity green.
This commit is contained in:
Tam Nhu Tran committed 2026-06-18 18:48:12 -04:00
1 parent 27f4e89ad1
commit 95a2864ef3
7 files changed
+1290 -306

No files matched your search

+34 -2
View File
@@ -1,7 +1,7 @@
# Hardening Debt Burndown Tracker
Last Updated: 2026-02-12
Owner: Stream D (`#542`)
Last Updated: 2026-06-18
Owner: Stream D (`#542`); maintainability epic owner TBD (open Q5)
## Scope
@@ -43,3 +43,35 @@ Baseline captured: `2026-02-12`.
| Date | Area | Change | Safety Notes |
|---|---|---|---|
| 2026-02-12 | `src/web-server/jsonl-parser.ts` | Migrated `parseProjectDirectory()` directory listing from sync `readdirSync` to async `fs.promises.readdir` | Existing behavior kept (same filtering/fallback); covered by `tests/unit/jsonl-parser.test.ts` |
## Maintainability & Traceability Baseline (2026-06-18)
Baseline for the maintainability/traceability epic (`plans/260618-1346-maintainability-traceability-epic`). Sourced from `docs/reports/hardening-inventory.json` -> `maintainability` block after `bun run report:hardening`. Baseline captured: `2026-06-18`.
| Metric | Baseline | Epic target | Owner phase |
|---|---:|---:|---|
| typed-error adoption (typed / total throws) | 0.9% (4 / 431) | >40% in locked subdomains | P4 |
| typed-error adoption (locked: cliproxy/quota, cliproxy/auth, web-server/routes, auth) | 0.0% (0 / 23) | >40% | P4 |
| hotpath `console.error`/`warn` occurrences (non-exempt) | 931 (1091 total, 160 CLI-UX exempt) | < 10 | P3 |
| hotpath `console.error`/`warn` files (non-exempt) | 134 | minimal | P3 |
| files with `createLogger` | 35 / 685 (5.1%) | rise across all subdomains | P2/P3 |
| subdomains with zero `createLogger` | 20 (incl. api, channels, config, delegation, dispatcher, docker, shared) | 0 in the named set | P2 |
| files > 400 LOC | 95 | < 60 after P5+P6 | P5/P6 |
| files > 600 LOC | 45 | drop | P5/P6 |
| ESLint `no-new-throw-error` gate | not enforced | error + allowlist | P7 |
| ESLint `max-lines` gate | not enforced | warn at 400 | P7 |
| hardening report freshness | stale (2026-02-12) | < 30d gate in `validate:ci-parity` | P1 |
### Method
Metrics are grep-based and approximate (not a contract). Comments and string/template/regex literals are stripped before matching (`scripts/hardening-inventory.js#stripComments`). Subdomain granularity is 2-level under `src/cliproxy/` (`cliproxy/quota`, `cliproxy/auth`, ...) and 1-level elsewhere (`auth`, `config`, ...). The hotpath `console.error` count excludes CLI-UX print surfaces (`src/commands/`, `src/management/`, `src/utils/ui/`) which are legitimate user-facing terminal output. The typed-error denominator for the P4 target is LOCKED to the four named subdomains so the >40% goal cannot be gamed by narrowing scope. Re-baseline whenever the schema or method changes.
### Largest hotpath console.error offenders (2026-06-18)
| File | `console.error`/`warn` |
|---|---:|
| `src/utils/error-manager.ts` | 142 |
| `src/cliproxy/accounts/account-safety.ts` | 56 |
| `src/cliproxy/config/model-config.ts` | 32 |
| `src/cliproxy/executor/arg-parser.ts` | 26 |
| `src/dispatcher/flows/settings-flow.ts` | 26 |
File diff suppressed because it is too large. Load diff
+85 -26
View File
@@ -6,43 +6,102 @@ Scope: `src/**/*.{ts,tsx,js,jsx,mjs,cjs}`
| Metric | Value |
|---|---:|
| Sync fs occurrences (all) | 835 |
| Sync fs files affected (all) | 100 |
| Sync fs occurrences (runtime hotpaths) | 724 |
| Sync fs files affected (runtime hotpaths) | 89 |
| Legacy shim markers | 131 |
| Legacy shim files affected | 56 |
| Sync fs occurrences (all) | 2304 |
| Sync fs files affected (all) | 243 |
| Sync fs occurrences (runtime hotpaths) | 1949 |
| Sync fs files affected (runtime hotpaths) | 193 |
| Legacy shim markers | 424 |
| Legacy shim files affected | 163 |
## Top Runtime Hotpath Sync fs Files
| File | Sync Calls | API Names |
|---|---:|---|
| `src/management/shared-manager.ts` | 60 | copyFileSync, cpSync, existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, readlinkSync, rmSync, statSync, symlinkSync, unlinkSync, writeFileSync |
| `src/utils/claude-symlink-manager.ts` | 27 | copyFileSync, existsSync, lstatSync, mkdirSync, readdirSync, readlinkSync, renameSync, rmSync, statSync, symlinkSync, unlinkSync |
| `src/utils/shell-completion.ts` | 23 | appendFileSync, copyFileSync, existsSync, mkdirSync, readFileSync, statSync |
| `src/web-server/routes/settings-routes.ts` | 23 | copyFileSync, existsSync, mkdirSync, readFileSync, renameSync, statSync, writeFileSync |
| `src/utils/claude-dir-installer.ts` | 21 | copyFileSync, cpSync, existsSync, lstatSync, mkdirSync, readdirSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync |
| `src/cliproxy/binary/version-cache.ts` | 20 | existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync |
| `src/management/recovery-manager.ts` | 20 | copyFileSync, existsSync, mkdirSync, renameSync, writeFileSync |
| `src/web-server/routes/cliproxy-stats-routes.ts` | 20 | closeSync, existsSync, fstatSync, mkdirSync, openSync, readdirSync, readFileSync, readSync, renameSync, statSync, writeFileSync |
| `src/web-server/routes/misc-routes.ts` | 20 | copyFileSync, existsSync, mkdirSync, readdirSync, readFileSync, renameSync, statSync, writeFileSync |
| `src/web-server/routes/persist-routes.ts` | 17 | closeSync, copyFileSync, existsSync, lstatSync, openSync, readdirSync, readSync, renameSync, unlinkSync, writeFileSync |
| `src/cliproxy/__tests__/pool-routing-phase3.test.ts` | 96 | existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync |
| `src/cliproxy/config/__tests__/config-generator.test.js` | 88 | existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync |
| `src/management/shared-manager.ts` | 86 | copyFileSync, cpSync, existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, readlinkSync, rmSync, statSync, symlinkSync, unlinkSync, writeFileSync |
| `src/cliproxy/config/__tests__/claude-model-neutral.test.ts` | 63 | existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, statSync, writeFileSync |
| `src/cliproxy/accounts/__tests__/account-safety-quota-exhaustion.test.ts` | 48 | existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync |
| `src/cliproxy/accounts/__tests__/account-registry-integrity.test.ts` | 45 | existsSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync, writeFileSync |
| `src/cliproxy/executor/__tests__/variant-port-integration.test.js` | 36 | existsSync, mkdirSync, readdirSync, readFileSync, rmSync, unlinkSync, writeFileSync |
| `src/cliproxy/executor/__tests__/composite-variant-service.test.ts` | 33 | existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync |
| `src/cliproxy/executor/__tests__/variant-port-edge-cases.test.js` | 33 | existsSync, mkdirSync, readdirSync, rmSync, unlinkSync, writeFileSync |
| `src/utils/browser/mcp-installer.ts` | 32 | chmodSync, copyFileSync, existsSync, mkdirSync, readFileSync, renameSync, statSync, unlinkSync, writeFileSync |
## Top Legacy Shim Marker Files
| File | Marker Count |
|---|---:|
| `src/auth/profile-detector.ts` | 18 |
| `src/utils/config-manager.ts` | 13 |
| `src/auth/profile-detector.ts` | 11 |
| `src/config/unified-config-loader.ts` | 9 |
| `src/commands/setup-command.ts` | 7 |
| `src/management/checks/config-check.ts` | 6 |
| `src/web-server/routes/account-routes.ts` | 6 |
| `src/config/migration-manager.ts` | 5 |
| `src/api/services/profile-writer.ts` | 4 |
| `src/cliproxy/quota-fetcher-gemini-cli.ts` | 4 |
| `src/auth/profile-registry.ts` | 3 |
| `src/cliproxy/__tests__/pool-onboarding-phase5.test.ts` | 12 |
| `src/cliproxy/executor/__tests__/variant-port-allocation.test.js` | 12 |
| `src/config/schemas/websearch.ts` | 10 |
| `src/commands/cursor-command-display.ts` | 9 |
| `src/config/migration-manager.ts` | 9 |
| `src/cliproxy/config/__tests__/env-builder-provider-url.test.ts` | 8 |
| `src/cliproxy/executor/__tests__/variant-port-edge-cases.test.js` | 8 |
| `src/cliproxy/config/__tests__/config-generator.test.js` | 7 |
## Explicit Shim/Re-export Files
- `src/cliproxy/openai-compat-manager.ts`
- `src/cliproxy/__tests__/model-catalog-compat.test.ts`
- `src/cliproxy/ai-providers/__tests__/codex-plan-compatibility.test.ts`
- `src/cliproxy/ai-providers/__tests__/openai-compat-manager.test.js`
- `src/cliproxy/ai-providers/openai-compat-manager.ts`
- `src/cliproxy/types/__tests__/types-backward-compat.test.ts`
- `src/utils/profile-compat.ts`
- `src/web-server/services/compatible-cli-docs-registry.ts`
## Maintainability Metrics
| Metric | Value |
|---|---:|
| typed-error adoption (typed/total throws) | 0.9% (4/431) |
| typed-error adoption (P4 locked subdomains) | 0.0% (0/23), target 40% |
| hotpath console.error/warn occurrences | 931 (1091 total, 160 CLI-UX exempt) |
| hotpath console.error/warn files | 134 |
| files with createLogger | 35/685 |
| subdomains with zero createLogger | 20 (api, bin, channels, cliproxy, cliproxy/accounts, cliproxy/ai-providers, cliproxy/binary, cliproxy/config, cliproxy/executor, cliproxy/management, cliproxy/quota, cliproxy/routing, cliproxy/sync, cliproxy/types, config, delegation, dispatcher, docker, shared, types) |
| files > 400 LOC | 95 |
| files > 600 LOC | 45 |
### Top Hotpath console.error/warn Files
| File | console.error/warn |
|---|---:|
| `src/utils/error-manager.ts` | 142 |
| `src/cliproxy/accounts/account-safety.ts` | 56 |
| `src/cliproxy/config/model-config.ts` | 32 |
| `src/cliproxy/executor/arg-parser.ts` | 26 |
| `src/dispatcher/flows/settings-flow.ts` | 26 |
| `src/copilot/copilot-executor.ts` | 24 |
| `src/delegation/delegation-handler.ts` | 23 |
| `src/dispatcher/cli-argument-parser.ts` | 22 |
| `src/web-server/routes/cliproxy-stats-routes.ts` | 22 |
| `src/cliproxy/executor/lifecycle-manager.ts` | 16 |
| `src/cursor/cursor-profile-executor.ts` | 16 |
| `src/dispatcher/profile-resolver.ts` | 16 |
| `src/cliproxy/auth/antigravity-responsibility.ts` | 15 |
| `src/cliproxy/executor/auth-coordinator.ts` | 14 |
| `src/cliproxy/executor/model-warnings.ts` | 13 |
### Files > 400 LOC (top 15)
| File | LOC |
|---|---:|
| `src/management/shared-manager.ts` | 1631 |
| `src/web-server/routes/cliproxy-auth-routes.ts` | 1502 |
| `src/cliproxy/auth/oauth-handler.ts` | 1453 |
| `src/cursor/cursor-executor.ts` | 1234 |
| `src/cliproxy/quota/quota-fetcher-gemini-cli.ts` | 1130 |
| `src/commands/cliproxy/quota-subcommand.ts` | 1130 |
| `src/web-server/routes/cliproxy-stats-routes.ts` | 1103 |
| `src/cliproxy/quota/quota-fetcher.ts` | 1087 |
| `src/commands/persist-command.ts` | 1071 |
| `src/web-server/model-pricing.ts` | 1070 |
| `src/web-server/routes/settings-routes.ts` | 1040 |
| `src/cliproxy/proxy/tool-sanitization-proxy.ts` | 1039 |
| `src/cliproxy/config/env-builder.ts` | 1037 |
| `src/cliproxy/auth/oauth-process.ts` | 1018 |
| `src/cliproxy/config/generator.ts` | 1012 |