You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/audits/AUDIT_2026-06-10.md
+47Lines changed: 47 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -186,6 +186,53 @@ has exactly 2 mock blocks (`auth.js`, `storage.js`) and a single sanctioned
186
186
`as never` fixture. A migration PR would be churn, not deduplication. With
187
187
this, every roadmap item is either delivered or explicitly closed.
188
188
189
+
### 5.2 Direct-coverage wave (added 2026-06-10, after the roadmap merge)
190
+
191
+
The phase-3/phase-4 extractions (§4.1.1) left ~2,500 lines of login machinery,
192
+
health-check, and persistence helpers reachable only through the giant CLI
193
+
suites. Writing direct suites for extracted modules surfaced real bugs twice
194
+
earlier in this cycle (the `isRecord` guard fixed in #544 and the stream-stall
195
+
fix in #546), so the method was applied across the remaining gaps.
196
+
Every PR below is independent and based on `main`. The test PRs
197
+
(#559–#575, plus #580 and #582–#584) each mock only the effectful seams and run the
198
+
real identity-matching / retry / parsing logic; the remaining rows are
199
+
follow-ups from the same wave — the L3 convention doc (#576), a
200
+
version-drift fix the wave's full-suite canary caught (#577), a
201
+
dead-code sweep the coverage scan surfaced (#578, later folded into the
202
+
pre-existing #554), a dedup idempotence
203
+
fix found by a new identity property suite (#579), and an unused
204
+
devDependency removal (#581).
205
+
(The number sequence skips #558 and #562, which are issues — the knip CI
206
+
tracking issue and a maintainer MCP-auth test — not PRs; it also skips
207
+
#568, which is the PR delivering this very section.)
208
+
209
+
| PR | Suite | Pins |
210
+
|----|-------|------|
211
+
|[#559](https://github.com/ndycode/codex-multi-auth/pull/559)|`test/login-oauth-selection.test.ts`| login-oauth `resolveAccountSelection` through the real candidate extraction (only `decodeJWT` mocked): #491/#512 workspaces persistence incl. the explicit `--org` path, org-override precedence, cancellation/abort predicates |
212
+
|[#560](https://github.com/ndycode/codex-multi-auth/pull/560)|`test/login-menu-actions.test.ts`|`handleManageAction` with the real `findMatchingAccountIndex`: delete/toggle re-resolve by identity under concurrent reorder, active-index rebalancing, refresh transports (cancel/manual via stubbed select), non-TTY prompt fallbacks |
213
+
|[#561](https://github.com/ndycode/codex-multi-auth/pull/561)|`test/login-flow.test.ts`|`runAuthLogin` with the real arg parser and cancellation predicate: explicit transports bypass the dashboard and exit on cancel, `--org` threads as an argument (no env mutation), inserted/updated/rebound messaging, MAX_ACCOUNTS cap, forced re-login on add-another |
|[#564](https://github.com/ndycode/codex-multi-auth/pull/564)|`test/persist-selected-account.test.ts`| the shared switch/best/restore persistence helper: family-index bookkeeping, validation refresh (success/graceful failure), pinning, the #474 affinity bump on max(disk, memory), EBUSY retry |
216
+
|[#565](https://github.com/ndycode/codex-multi-auth/pull/565)|`test/health-check.test.ts`|`runHealthCheck` quick + live probe: fresh-session trust, rotated-credential write-back and CLI sync, refresh-then-probe with the rotated token, re-login vs still-works classification, cache-save failure tolerance |
|[#567](https://github.com/ndycode/codex-multi-auth/pull/567)|`test/settings-write-queue.test.ts`|`withQueuedRetry` only (the helper exports are internal surface): retry schedule with injected sleep, 429 retry-after clamping, strict per-path ordering, failed predecessors not blocking, retries staying inside their queue slot |
219
+
|[#569](https://github.com/ndycode/codex-multi-auth/pull/569)|`test/dashboard-settings-data.test.ts`| settings clone/equality contract with the real layout-mode resolver: sparse legacy objects clone to documented defaults, explicit layout mode beats the legacy boolean, equality sweeps every independent field comparison |
220
+
|[#570](https://github.com/ndycode/codex-multi-auth/pull/570)|`test/rotation-account-selection.test.ts`|`chooseAccount` through a real AccountManager: #474 pin discipline (wins without cursor commit, never falls back, full skip-reason taxonomy), affinity tier, hybrid + linear fallback cursor rules, #509 sequential mode never moving the drain-first primary on transient failure |
221
+
|[#571](https://github.com/ndycode/codex-multi-auth/pull/571)|`test/rotation-token-refresh.test.ts`|`ensureFreshAccessToken` with real cooldown bookkeeping: fresh-token short-circuit, rotate-and-commit, concurrent-commit dedup, the #495 invalidation cooldown + monotonic guard, commit-failure degradation |
222
+
|[#572](https://github.com/ndycode/codex-multi-auth/pull/572)|`test/rotation-proxy-state.test.ts`| proxy state init and pool-exhausted stale-state recovery: manager swap with the previous pool kept known, routing-mutex carry-over, 1s reload dedupe incl. concurrent sharing, failed-reload retry |
223
+
|[#573](https://github.com/ndycode/codex-multi-auth/pull/573)|`test/auth-menu-builder.test.ts`| the auth dashboard view-model formatters, asserted with ANSI stripped so both UI palettes hold: identity precedence + ANSI/control-character stripping in row titles, status badges/colors, hint field ordering, focus keys on storage position |
224
+
|[#574](https://github.com/ndycode/codex-multi-auth/pull/574)|`test/property/model-fallback.property.test.ts`| fast-check invariants for the unsupported-model fallback: any returned fallback is a chain member, never the current or an attempted model (under any prefix/suffix/casing spelling), legacy gpt-5.3 edge toggle respected, exhausted chains give up |
225
+
|[#575](https://github.com/ndycode/codex-multi-auth/pull/575)|`test/property/settings-write-queue.property.test.ts`| fast-check invariants for the write queue: per-key invocations stay contiguous and in submission order under any ok/flaky/fatal schedule, fatal tasks never block successors, 429 retry-after hints clamp into 10ms..30s |
226
+
|[#576](https://github.com/ndycode/codex-multi-auth/pull/576)|`lib/AGENTS.md`| closes audit L3: documents the class vs module-state convention (classes for multi-instance/injectable state and the error hierarchy; module-level state only for process-global concerns, always with a test reset helper) |
227
+
|[#577](https://github.com/ndycode/codex-multi-auth/pull/577)|`.codex-plugin/plugin.json`, `docs/README.md`, `AGENTS.md`, `test/documentation.test.ts`| live-regression fix found by a full-suite canary vs the §7 baseline: the 2.3.0-beta.2 bump left three stale beta.1 references (plugin manifest, docs-portal release table, AGENTS.md header); adds a doc-integrity guard pinning the AGENTS.md version to package.json |
228
+
|[#578](https://github.com/ndycode/codex-multi-auth/pull/578) (closed, superseded by [#554](https://github.com/ndycode/codex-multi-auth/pull/554)) | five deleted modules + `lib/AGENTS.md`| dead-code sweep surfaced while verifying coverage convergence; an open-PR sweep then showed #554 already deletes the same five files plus two more (`recovery/index.ts`, `storage/restore.ts`) that this PR's reference search had false-matched as live — #578 was closed and its unique `lib/AGENTS.md` fix moved onto #554|
229
+
|[#579](https://github.com/ndycode/codex-multi-auth/pull/579)|`lib/storage.ts` + `test/property/account-identity.property.test.ts`| third live bug found by the coverage method: fast-check proved `deduplicateAccounts` non-idempotent (a newest-wins merge in one matching tier can install an account that duplicates an earlier survivor through another tier); fixed with a fixpoint loop, pinned by 9 identity-matching properties incl. a deterministic counterexample replay |
230
+
|[#580](https://github.com/ndycode/codex-multi-auth/pull/580)|`test/account-rate-limits.test.ts`| the extracted per-account rate-limit helpers, previously reachable only via the `accounts.ts` facade: reason-code taxonomy incl. the generic-429 unknown bucket, family vs model-scoped quota keys, expiry-boundary semantics (`now >= reset` clears), model-key precedence, and the expired-entry pruning side effect |
231
+
|[#581](https://github.com/ndycode/codex-multi-auth/pull/581)|`package.json`| drops the unused `@fast-check/vitest` devDependency (the property suites deliberately use plain `fast-check`, so the `test.prop` wrapper has no consumers) |
232
+
|[#582](https://github.com/ndycode/codex-multi-auth/pull/582)|`test/usage-redaction.test.ts`| the usage-ledger redaction/normalization contracts (previously reachable only via the `usage/index.js` facade): identifier hashing, account refs storing only hashes, the unknown-outcome -> `failure` fallback (never miscounted as success), token clamping/total recompute, the 100..599 status window, cost fallback to the pricing estimate, and the serialized JSONL line never containing raw account id or email |
233
+
|[#583](https://github.com/ndycode/codex-multi-auth/pull/583)|`test/settings-preview.test.ts`| the preview-first settings renderer (previously reachable only via the interactive settings-hub panels), using the real `resolveMenuLayoutMode`: statusline-field normalization incl. the defensive copy, summary composition with the inverted status-badge dependency and both nothing-visible explanations, badge toggles, and TTY-gated ANSI highlighting asserted by stripped equality |
234
+
|[#584](https://github.com/ndycode/codex-multi-auth/pull/584)|`test/settings-hub-shared.test.ts`| the settings-hub merge/persist layer (only the disk seams mocked; real queued-retry policy): array-clone copy semantics, key-scoped defaults/merge, the load-merge-save transaction preserving concurrent edits to unrelated keys, EBUSY retry without warning, warn + clone-normalized fallback on persistent failure, backend patch save with defensive clone, and `clampBackendNumber`|
235
+
189
236
---
190
237
191
238
## 6. Findings investigated and REJECTED (do not re-report)
0 commit comments