Redact StageOptions error payloads and summarize debug launch args.
Propagate request IDs through Cursor daemon and dashboard completion logs.
Mark remaining P2/P3 maintainability targets as partial instead of overclaiming.
Epic P6 (partial: 2 of 6 targets). These two files have strong existing
per-provider test coverage, so the characterization-first requirement is met
by the safety net; both are split test-backed.
- src/cliproxy/quota/quota-fetcher.ts (1106 -> barrel 29 + 9 submodules, max
254 LOC): status-classifier (the clean extract), http-client, auth-file-reader,
project-lookup, available-models-fetcher, account-quota-fetcher,
all-accounts-fetcher, types, constants.
- src/cliproxy/quota/quota-fetcher-gemini-cli.ts (1179 -> barrel 27 + 11
submodules, max 334 LOC): token-parsing, auth-file-discovery,
supplementary-metadata, error-parsing, bucket-building, managed-request,
shared-utils, types, constants, index.
Public API preserved verbatim (incl. __testExports). All P3 structured logging
preserved through the splits. Regenerated eslint-rules/throw-error-baseline.json
(throws moved to new module paths).
Remaining P6 targets (characterization-first, deferred): oauth-handler.ts,
cursor-executor.ts, tool-sanitization-proxy.ts, + 1. Each needs dedicated
characterization-test work before splitting; tracked in the epic plan.
Metric: files > 400 LOC 91 -> 89. validate + validate:ci-parity green.
Epic P7. Locks in the epic's gains with ESLint gates so the adoption work
does not regress.
- ccs/no-new-throw-error (error): custom flat-config rule that flags NEW
throw new Error(...) outside a generated baseline allowlist. Forces the
typed-error taxonomy (src/errors/error-types.ts). Existing 338 sites are
grandfathered in eslint-rules/throw-error-baseline.json; only NEW violations
error. Rule normalizes the filename to repo-root-relative to match baseline
keys regardless of how ESLint reports paths.
- max-lines (warn, 400, skipBlankLines/skipComments): warns on files over
400 LOC (goal of P5/P6 god-file splits). Currently 51 warnings on the
not-yet-split god-files (P6 territory).
- scripts/generate-throw-error-baseline.js: emits the allowlist from raw
source (superset of real throws; never undercounts). Run after intentionally
grandfathering a site, or quarterly to prune.
- tests/unit/eslint-rules/no-throw-new-error.test.ts: rule logic (flags
off-allowlist, passes on-allowlist/typed/rethrow, line-sensitivity).
- docs/code-standards.md: Lint Enforcement Gates section.
- docs/logging-contract.md: error.code -> ExitCode table (from P4).
validate + validate:ci-parity green.
Epic P4. Migrates plain throw new Error to the typed-error classes in the four
locked subdomains, and makes the taxonomy erasable-syntax-compatible so it can
be adopted across UI-reachable code.
Migration (cliproxy/auth, web-server/routes, auth):
- 21 of 23 throws in the locked subdomains now use typed subclasses
(ProfileError, AuthError, ConfigError, ValidationError, ProviderError).
- Typed adoption in locked subdomains: 0/23 -> 21/23 (91.3%), > 40% target.
- Overall typed adoption: 0.9% -> 8.6%.
- Messages preserved exactly (message-based tests stable). Exit codes now
differentiate via handleError (ProfileError=7, AuthError=4, ConfigError=2,
ProviderError=6). ccs doctor 0/1 contract untouched (outside scope).
Erasable-syntax fix (unblocks the migration in the UI build graph):
- exit-codes.ts: enum ExitCode -> const object + union type (value and type
usage both preserved; no Object.values(ExitCode) consumers).
- error-types.ts: constructor parameter properties -> explicit readonly field
declarations + body assignment.
- The web UI build enforces erasableSyntaxOnly (ui/tsconfig.app.json) and
reaches src/errors via the @shared -> src/auth graph; pre-erasable
error-types blocked the build once profile-registry adopted typed errors.
Compat audit: docs/reports/typed-error-exit-code-compat-audit.md (Q1 resolved:
migrate freely; only documented contract is ccs doctor, which is untouched).
Behavior-lock: src/errors/__tests__/typed-error-migration-exit-codes.test.ts
(taxonomy -> exit-code mapping, instanceof chains, context fields).
validate + validate:ci-parity green (incl. UI build).
Epic P2. Closes the three real traceability gaps so every diagnostic log can
carry a requestId from origin (ccs.ts main) through HTTP edges and spawned
daemons.
- log-context: add REQUEST_ID_HEADER/ENV/PATTERN, resolveRequestIdFromEnv,
forwardRequestIdEnv. runWithRequestId now reuses a forwarded CCS_REQUEST_ID
when well-formed (child re-anchor), else mints fresh.
- request-logging-middleware: wrap the Express dashboard handler chain in
withRequestContext so downstream route-handler logs carry requestId (mirrors
src/proxy/server/proxy-server.ts, which is untouched prior art).
- forward CCS_REQUEST_ID at the 4 child-daemon spawn sites: delegation
headless-executor, cursor-daemon, cursor-profile-executor, copilot-executor.
- cursor-daemon-entry: re-anchor via runWithRequestId so daemon startup logs
correlate with the spawning CLI invocation (ALS does not cross spawn).
- logger adoption toe-hold: delegation/session-manager (load/save failures) and
docker/supervisord-lifecycle (restart failure) now use createLogger.
api/channels/shared have no touchable diagnostic console.error (CLI-UX only or
pure data); dispatcher's only diagnostic is in pre-dispatch.ts, owned by plan
#1165. Those defer to P3's full per-site sweep.
Tests: request-context-middleware (handler log requestId === header),
request-id-forwarding (env resolve/reject, re-anchor, forwardRequestIdEnv).
validate + validate:ci-parity green.
Built-in Claude provider now uses the CLIProxy root URL instead of /api/provider/claude (which 404'd since base CLIProxy registers /v1/messages at root). Repairs stale local Claude settings, keeps non-Claude providers on their scoped routes, and applies the same root-URL rule to the ccs api create --cliproxy-provider claude bridge path via a shared buildCliproxyProviderPath helper. Closes#1545.
* test(bar): cover socket-level 401/403 auth detection and liveness-poll rogue rejection
Add two new describe blocks to bar-command.test.ts:
1. `defaultFindRunningServer: socket-level 401/403 classifies authRequired=true`
Drives `net.connect` via mock.module('net') to verify that status lines
401 and 403 off the wire set authRequired=true. A correct-token 200 must
not set authRequired. Prior tests bypassed the real status-line parser by
injecting authRequired via deps; these tests couple to the actual branch.
2. `defaultWaitForServerLive: rogue 200 without matching token is rejected`
Uses the same net mock pattern to verify that a 200 carrying a wrong
x-ccs-bar-token never causes the liveness poll to resolve (rogue reflector
cannot pass). Correct token resolves immediately.
Export `defaultWaitForServerLive` from launch-subcommand.ts so the direct
unit test can import it without forcing a full handleBarLaunch invocation.
Both test groups are behavior-coupled: removing the relevant branch in
production causes the tests to fail (verified under mutation).
* refactor(bar): drop dead ensureLoopbackNoProxy proxy shim
The probe now uses raw net.connect() which never consults proxy env vars
(undici was fully removed in an earlier PR). ensureLoopbackNoProxy()
permanently mutated process-wide NO_PROXY/no_proxy on every discovery call
with no effect on the actual network path.
Verified zero remaining references to ensureLoopbackNoProxy outside the
declaration and call site that are now removed.
Closes a spoofed-loopback-200 bar.json poisoning vector with a per-user 0600 capability token. The real bar server echoes its file-derived token on /bar/* responses; the launch probe verifies the echoed token against the locally-read file (fail-closed) before reusing a server, so a rogue loopback process that cannot read the token file is rejected.
Raw-socket probe detects auth-protected (401/403) bar servers, reuses them, and kills the orphaned detached server on auth timeout. Integrated with the non-blocking priority probe.
Preserves the Gatekeeper quarantine attribute on the installed CCS Bar app so the user makes the right-click to Open trust decision, instead of silently clearing it.
Hardens the macOS bar launch.json descriptor against untrusted/foreign-owned files and constrains the decoded descriptor; blocks dashboard file writes to the launch descriptor.