refactor(lib): dedupe drifted isRecord guards into the canonical utils helper - #545
Conversation
…s helper Sweep follow-up to the runtime-current-account isRecord fix: of the nine local isRecord definitions in lib/, two had drifted from the canonical array-rejecting contract in lib/utils.ts (both accepted arrays): - lib/codex-manager/commands/rotation.ts (app helper status file parse) - lib/refresh-lease.ts (lease lock/result payload parse) Both local copies are deleted in favor of importing the canonical helper. Unlike the runtime-current-account case, the drift here was latent: downstream per-field validation already yielded all-null/invalid results for array payloads, so there is no observable behavior change. New tests pin the array-rejection contract at both call sites (array lock/result files never become a lease or follower result; an array helper status file reads as "not running"). The six remaining local isRecord copies already match the canonical semantics and are left in place. https://claude.ai/code/session_01XNtnkLbBiXZxfQQYLMpucB
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
|
Warning Review limit reached
More reviews will be available in 3 minutes and 4 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (4)
✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
Sweep follow-up to #544 (which fixed a real bug caused by a drifted local
isRecord). This PR audits all nine localisRecorddefinitions underlib/and dedupes the two that drifted from the canonical array-rejecting contract inlib/utils.ts:lib/codex-manager/commands/rotation.ts— local guard (typeof value === "object" && value !== null) used when parsing the app runtime helper status file; replaced withimport { isRecord } from "../../utils.js".lib/refresh-lease.ts— local guard (value !== null && typeof value === "object") used inparseLeasePayload/parseResultPayload; replaced withimport { isRecord } from "./utils.js".Unlike #544, the drift here was latent: downstream per-field validation already produced all-null/invalid results for array payloads, so there is no observable behavior change — this is dedupe plus hardening against the same silent-drift bug class. The six remaining local copies already match the canonical semantics (reject arrays) and are deliberately left in place.
Changes
isRecorddefinitions; import the canonical helper instead.test/refresh-lease.test.ts: new test pinning that an array result file never makes a caller a follower, and an array lock file is an invalid payload (never owned, never treated stale — acquire times out to bypass without deleting it).test/codex-manager-rotation-command.test.ts: new test pinning that an array helper status file reads as "Codex app helper: not running" rather than a record with all-null fields.Validation
npm run typecheckcleannpx eslinton all four touched files,--max-warnings=0npx vitest run test/refresh-lease.test.ts test/codex-manager-rotation-command.test.ts— 51/51 passed (49 pre-existing + 2 new)Risk / Rollback
Low: zero observable behavior change (array payloads were already rejected by field-level checks); the canonical guard is strictly narrower. Independent of #543/#544 (no overlapping files); based on
main. Rollback = revert the single commit.https://claude.ai/code/session_01XNtnkLbBiXZxfQQYLMpucB
Generated by Claude Code
note: greptile review for oc-chatgpt-multi-auth. cite files like
lib/foo.ts:123. confirm regression tests + windows concurrency/token redaction coverage.Greptile Summary
dedupes two drifted local
isRecordguards inlib/refresh-lease.tsandlib/codex-manager/commands/rotation.tsby importing the canonical array-rejecting helper fromlib/utils.ts, and adds regression tests pinning that array JSON payloads are correctly rejected in both files.lib/refresh-lease.ts: removesvalue !== null && typeof value === \"object\"local guard; canonical guard adds!Array.isArray(value), preventing arrays from being silently parsed as lease/result records with all-null fields.lib/codex-manager/commands/rotation.ts: same removal; array status files now correctly return null fromreadAppRuntimeHelperStatusinstead of a record with every field null.Confidence Score: 4/5
changes to the two targeted files are correct and well-tested; a third drifted guard in runtime-current-account.ts reads the same status file and was not fixed
the audit claimed to cover all nine local copies, but lib/runtime/runtime-current-account.ts line 101 still has the array-accepting form (typeof value === 'object' && value !== null) in its own readAppRuntimeHelperStatus — the same read path the rotation.ts fix covers — leaving the latent drift alive in a parallel code path
lib/runtime/runtime-current-account.ts — local isRecord at line 100 is missing !Array.isArray(value)
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A[JSON file on disk] --> B{JSON.parse} B --> C[isRecord check] C -- "old: typeof obj && !== null\n(arrays pass!)" --> D[field-level validation\nall fields null] C -- "new: canonical utils.isRecord\n(arrays rejected)" --> E[return null\nearly exit] D --> F[caller sees all-null struct\nsilent bad state] E --> G[caller sees null\ncorrect not-running / invalid]Reviews (1): Last reviewed commit: "refactor(lib): dedupe drifted isRecord g..." | Re-trigger Greptile