From 2d484884752a6fd79ca1a891c62450333c15a4fe Mon Sep 17 00:00:00 2001 From: Tam Nhu Tran Date: Thu, 18 Jun 2026 18:48:13 -0400 Subject: [PATCH] docs(hardening): finalize epic metrics + progress log (P1-P7) --- docs/hardening-debt-burndown.md | 23 ++++ docs/reports/hardening-inventory.json | 184 ++++++++++++-------------- docs/reports/hardening-inventory.md | 38 +++--- 3 files changed, 128 insertions(+), 117 deletions(-) diff --git a/docs/hardening-debt-burndown.md b/docs/hardening-debt-burndown.md index 83aa0959..9003a3f2 100644 --- a/docs/hardening-debt-burndown.md +++ b/docs/hardening-debt-burndown.md @@ -82,6 +82,29 @@ Metrics are grep-based and approximate (not a contract). Comments and string/tem |---|---|---|---| | 2026-06-18 | P2 | Express `withRequestContext` wrap; `CCS_REQUEST_ID` daemon forwarding + child re-anchor; logger toe-holds in delegation/docker. | zero-createLogger subdomains 20 -> 18 | | 2026-06-18 | P3 | Redaction gate (token-shape scrubbing in context + `Error.message` + message string). `tool-sanitization-proxy` private log subsystem deleted (13 sites -> existing `createLogger`). ~120 diagnostic `console.error` -> structured `createLogger` across proxy, web-server/routes, glmt, quota-fetchers, executors, delegation. User-facing `console.error` (CLI flows, arg-parser usage, installers, prompts, adapter launch errors, error display) migrated to `process.stderr.write` (preserves stderr output). `error-manager.ts` reclassified CLI-UX-exempt (user-facing display). | hotpath `console.error` 928 -> 267 (71%); createLogger files 35 -> 64 | +| 2026-06-18 | P4 | `throw new Error` -> typed subclasses (ProfileError/AuthError/ConfigError/ProviderError/ValidationError) in cliproxy/auth, web-server/routes, auth. Error taxonomy made erasable (enum -> const, param-props -> fields) so the UI build accepts it. | typed adoption (locked subdomains) 0/23 -> 21/23 (91.3%); overall 0.9% -> 8.6% | +| 2026-06-18 | P5 | Split 4 test-backed god-files into submodule dirs + barrels (shared-manager, cliproxy-stats-routes, persist-command, quota-subcommand). Public API preserved. | files > 400 LOC 95 -> 91 | +| 2026-06-18 | P6 | Split 2 of 6 characterization-first god-files (quota-fetcher, quota-fetcher-gemini-cli; both had strong per-provider test coverage). 4 deferred. | files > 400 LOC 91 -> 89 | +| 2026-06-18 | P7 | ESLint gates: `ccs/no-new-throw-error` (error, baseline-allowlisted) + `max-lines` (warn, 400). code-standards.md + logging-contract.md (error.code table). | gates enforced (0 lint errors on baseline) | + +## Epic outcome (2026-06-18) + +| Metric | Baseline | Final | Target | Status | +|---|---:|---:|---:|---| +| typed-error adoption (locked subdomains) | 0.0% (0/23) | 91.3% (21/23) | >40% | met | +| typed-error adoption (overall) | 0.9% (5/431) | 8.6% (37/431) | rise | met | +| hotpath `console.error`/`warn` | 928 | 267 | <10 (diagnostics) | diagnostics fully structured; residual is user-facing CLI output (see P3 note) | +| files with `createLogger` | 35 | 64 | rise | met | +| files > 400 LOC | 95 | 89 | <60 | partial (P6 deferred 4 targets) | +| hardening report freshness | stale | <30d gate | gate | met (P1) | +| ESLint `no-new-throw-error` | not enforced | error + allowlist | enforced | met (P7) | +| ESLint `max-lines` | not enforced | warn at 400 | enforced | met (P7) | + +### Deferred follow-ups + +- P6 remaining 4 targets (`oauth-handler.ts`, `cursor-executor.ts`, `tool-sanitization-proxy.ts`, +1): need dedicated characterization-test work before splitting (the plan's characterization-first hard gate). Each has a clean seam identified in the epic plan. +- P3 residual ~267 user-facing `console.error` -> `process.stderr.write`: mechanical, no traceability value; continues incrementally. + ### P3 residual note (2026-06-18) diff --git a/docs/reports/hardening-inventory.json b/docs/reports/hardening-inventory.json index 5d6ab00d..e614b57a 100644 --- a/docs/reports/hardening-inventory.json +++ b/docs/reports/hardening-inventory.json @@ -2,9 +2,9 @@ "scope": "src/**/*.{ts,tsx,js,jsx,mjs,cjs}", "syncFs": { "totalOccurrences": 2301, - "filesAffected": 242, + "filesAffected": 247, "hotpathOccurrences": 1946, - "hotpathFilesAffected": 192, + "hotpathFilesAffected": 197, "topHotpathFiles": [ { "file": "src/cliproxy/__tests__/pool-routing-phase3.test.ts", @@ -32,26 +32,6 @@ ], "markers": [] }, - { - "file": "src/management/shared-manager.ts", - "count": 86, - "calls": [ - "copyFileSync", - "cpSync", - "existsSync", - "lstatSync", - "mkdirSync", - "readdirSync", - "readFileSync", - "readlinkSync", - "rmSync", - "statSync", - "symlinkSync", - "unlinkSync", - "writeFileSync" - ], - "markers": [] - }, { "file": "src/cliproxy/config/__tests__/claude-model-neutral.test.ts", "count": 63, @@ -148,6 +128,20 @@ "writeFileSync" ], "markers": [] + }, + { + "file": "src/cliproxy/__tests__/session-tracker-port.test.js", + "count": 31, + "calls": [ + "existsSync", + "mkdirSync", + "readdirSync", + "readFileSync", + "rmSync", + "unlinkSync", + "writeFileSync" + ], + "markers": [] } ], "topFilesOverall": [ @@ -177,26 +171,6 @@ ], "markers": [] }, - { - "file": "src/management/shared-manager.ts", - "count": 86, - "calls": [ - "copyFileSync", - "cpSync", - "existsSync", - "lstatSync", - "mkdirSync", - "readdirSync", - "readFileSync", - "readlinkSync", - "rmSync", - "statSync", - "symlinkSync", - "unlinkSync", - "writeFileSync" - ], - "markers": [] - }, { "file": "src/cliproxy/config/__tests__/claude-model-neutral.test.ts", "count": 63, @@ -293,12 +267,26 @@ "writeFileSync" ], "markers": [] + }, + { + "file": "src/cliproxy/__tests__/session-tracker-port.test.js", + "count": 31, + "calls": [ + "existsSync", + "mkdirSync", + "readdirSync", + "readFileSync", + "rmSync", + "unlinkSync", + "writeFileSync" + ], + "markers": [] } ] }, "legacyShim": { - "totalMarkers": 424, - "filesAffected": 163, + "totalMarkers": 427, + "filesAffected": 164, "topFiles": [ { "file": "src/auth/profile-detector.ts", @@ -481,16 +469,16 @@ "maintainability": { "typedErrors": { "totalThrows": 431, - "typedThrows": 4, - "plainThrows": 369, + "typedThrows": 37, + "plainThrows": 336, "otherThrows": 58, - "adoptionRatio": 0.0093, + "adoptionRatio": 0.0858, "topSubdomainsByThrows": [ { "subdomain": "web-server", "count": 103, - "typed": 4, - "plain": 57 + "typed": 16, + "plain": 45 }, { "subdomain": "proxy", @@ -537,8 +525,8 @@ { "subdomain": "auth", "count": 12, - "typed": 0, - "plain": 12 + "typed": 12, + "plain": 0 }, { "subdomain": "cliproxy/ai-providers", @@ -555,15 +543,15 @@ "web-server/routes", "auth" ], - "numerator": 0, + "numerator": 21, "denominator": 23, - "ratio": 0, + "ratio": 0.913, "targetRatio": 0.4 }, "loggerCoverage": { "filesWithCreateLogger": 64, - "totalSourceFiles": 685, - "coverageRatio": 0.0934, + "totalSourceFiles": 745, + "coverageRatio": 0.0859, "subdomainsWithZeroCreateLogger": [ "api", "bin", @@ -584,18 +572,28 @@ "topSubdomainsByFiles": [ { "subdomain": "web-server", - "count": 103, + "count": 111, "withLogger": 10 }, + { + "subdomain": "commands", + "count": 107, + "withLogger": 2 + }, { "subdomain": "utils", "count": 87, "withLogger": 1 }, { - "subdomain": "commands", - "count": 85, - "withLogger": 2 + "subdomain": "management", + "count": 32, + "withLogger": 1 + }, + { + "subdomain": "cliproxy/quota", + "count": 31, + "withLogger": 5 }, { "subdomain": "cliproxy/auth", @@ -617,20 +615,10 @@ "count": 23, "withLogger": 8 }, - { - "subdomain": "management", - "count": 22, - "withLogger": 1 - }, { "subdomain": "auth", "count": 20, "withLogger": 1 - }, - { - "subdomain": "cliproxy/executor", - "count": 17, - "withLogger": 4 } ] }, @@ -703,52 +691,28 @@ ] }, "largeFiles": { - "countOver400": 95, - "countOver600": 45, + "countOver400": 89, + "countOver600": 39, "topOver400": [ - { - "file": "src/management/shared-manager.ts", - "loc": 1631 - }, { "file": "src/web-server/routes/cliproxy-auth-routes.ts", "loc": 1515 }, { "file": "src/cliproxy/auth/oauth-handler.ts", - "loc": 1453 - }, - { - "file": "src/web-server/routes/cliproxy-stats-routes.ts", - "loc": 1238 + "loc": 1455 }, { "file": "src/cursor/cursor-executor.ts", "loc": 1234 }, - { - "file": "src/cliproxy/quota/quota-fetcher-gemini-cli.ts", - "loc": 1183 - }, - { - "file": "src/commands/cliproxy/quota-subcommand.ts", - "loc": 1130 - }, - { - "file": "src/cliproxy/quota/quota-fetcher.ts", - "loc": 1094 - }, - { - "file": "src/commands/persist-command.ts", - "loc": 1071 - }, { "file": "src/web-server/model-pricing.ts", "loc": 1070 }, { "file": "src/web-server/routes/settings-routes.ts", - "loc": 1040 + "loc": 1041 }, { "file": "src/cliproxy/config/env-builder.ts", @@ -756,7 +720,7 @@ }, { "file": "src/cliproxy/proxy/tool-sanitization-proxy.ts", - "loc": 1022 + "loc": 1020 }, { "file": "src/cliproxy/auth/oauth-process.ts", @@ -765,6 +729,30 @@ { "file": "src/cliproxy/config/generator.ts", "loc": 1012 + }, + { + "file": "src/commands/cliproxy/variant-subcommand.ts", + "loc": 978 + }, + { + "file": "src/cliproxy/quota/quota-manager.ts", + "loc": 954 + }, + { + "file": "src/web-server/services/codex-dashboard-service.ts", + "loc": 940 + }, + { + "file": "src/glmt/glmt-proxy.ts", + "loc": 939 + }, + { + "file": "src/cliproxy/accounts/registry.ts", + "loc": 871 + }, + { + "file": "src/channels/official-channels-runtime.ts", + "loc": 867 } ] } diff --git a/docs/reports/hardening-inventory.md b/docs/reports/hardening-inventory.md index 22b7cfae..e3f129b8 100644 --- a/docs/reports/hardening-inventory.md +++ b/docs/reports/hardening-inventory.md @@ -7,11 +7,11 @@ Scope: `src/**/*.{ts,tsx,js,jsx,mjs,cjs}` | Metric | Value | |---|---:| | Sync fs occurrences (all) | 2301 | -| Sync fs files affected (all) | 242 | +| Sync fs files affected (all) | 247 | | Sync fs occurrences (runtime hotpaths) | 1946 | -| Sync fs files affected (runtime hotpaths) | 192 | -| Legacy shim markers | 424 | -| Legacy shim files affected | 163 | +| Sync fs files affected (runtime hotpaths) | 197 | +| Legacy shim markers | 427 | +| Legacy shim files affected | 164 | ## Top Runtime Hotpath Sync fs Files @@ -19,7 +19,6 @@ Scope: `src/**/*.{ts,tsx,js,jsx,mjs,cjs}` |---|---:|---| | `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 | @@ -27,6 +26,7 @@ Scope: `src/**/*.{ts,tsx,js,jsx,mjs,cjs}` | `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 | +| `src/cliproxy/__tests__/session-tracker-port.test.js` | 31 | existsSync, mkdirSync, readdirSync, readFileSync, rmSync, unlinkSync, writeFileSync | ## Top Legacy Shim Marker Files @@ -56,14 +56,14 @@ Scope: `src/**/*.{ts,tsx,js,jsx,mjs,cjs}` | Metric | Value | |---|---:| -| typed-error adoption (typed/total throws) | 0.9% (4/431) | -| typed-error adoption (P4 locked subdomains) | 0.0% (0/23), target 40% | +| typed-error adoption (typed/total throws) | 8.6% (37/431) | +| typed-error adoption (P4 locked subdomains) | 91.3% (21/23), target 40% | | hotpath console.error/warn occurrences | 267 (569 total, 302 CLI-UX exempt) | | hotpath console.error/warn files | 82 | -| files with createLogger | 64/685 | +| files with createLogger | 64/745 | | subdomains with zero createLogger | 15 (api, bin, channels, cliproxy, cliproxy/accounts, cliproxy/ai-providers, cliproxy/binary, cliproxy/config, cliproxy/management, cliproxy/sync, cliproxy/types, config, dispatcher, shared, types) | -| files > 400 LOC | 95 | -| files > 600 LOC | 45 | +| files > 400 LOC | 89 | +| files > 600 LOC | 39 | ### Top Hotpath console.error/warn Files @@ -89,19 +89,19 @@ Scope: `src/**/*.{ts,tsx,js,jsx,mjs,cjs}` | File | LOC | |---|---:| -| `src/management/shared-manager.ts` | 1631 | | `src/web-server/routes/cliproxy-auth-routes.ts` | 1515 | -| `src/cliproxy/auth/oauth-handler.ts` | 1453 | -| `src/web-server/routes/cliproxy-stats-routes.ts` | 1238 | +| `src/cliproxy/auth/oauth-handler.ts` | 1455 | | `src/cursor/cursor-executor.ts` | 1234 | -| `src/cliproxy/quota/quota-fetcher-gemini-cli.ts` | 1183 | -| `src/commands/cliproxy/quota-subcommand.ts` | 1130 | -| `src/cliproxy/quota/quota-fetcher.ts` | 1094 | -| `src/commands/persist-command.ts` | 1071 | | `src/web-server/model-pricing.ts` | 1070 | -| `src/web-server/routes/settings-routes.ts` | 1040 | +| `src/web-server/routes/settings-routes.ts` | 1041 | | `src/cliproxy/config/env-builder.ts` | 1037 | -| `src/cliproxy/proxy/tool-sanitization-proxy.ts` | 1022 | +| `src/cliproxy/proxy/tool-sanitization-proxy.ts` | 1020 | | `src/cliproxy/auth/oauth-process.ts` | 1018 | | `src/cliproxy/config/generator.ts` | 1012 | +| `src/commands/cliproxy/variant-subcommand.ts` | 978 | +| `src/cliproxy/quota/quota-manager.ts` | 954 | +| `src/web-server/services/codex-dashboard-service.ts` | 940 | +| `src/glmt/glmt-proxy.ts` | 939 | +| `src/cliproxy/accounts/registry.ts` | 871 | +| `src/channels/official-channels-runtime.ts` | 867 |