Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix(runtime): reject array helper-status files; dedupe isRecord - #544

Merged
ndycode merged 5 commits into
mainfrom
claude/audit-26-isrecord-fix
Jun 10, 2026
Merged

ndycode merged 5 commits into
mainfrom
claude/audit-26-isrecord-fix

Conversation

@ndycode

@ndycode ndycode commented Jun 10, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes the bug surfaced by #543's coverage work: the local isRecord copy in lib/runtime/runtime-current-account.ts had drifted from the canonical lib/utils.ts guard and accepted JSON arrays, so an [] helper-status file produced an all-null status object instead of null. Harmless today only because the downstream kind check happened to reject the all-null object — but it's exactly the class of silent drift the canonical guard exists to prevent.

Stacked on #543 (which pinned the buggy behavior with a test) — merge that first; this PR then shows only the fix commit.

Changes

  • Deletes the drifted local isRecord duplicate; imports the canonical isRecord from lib/utils.js (which already does !Array.isArray(value)). No cycle risk — utils is a leaf.
  • Flips test(lib): cover the highest-value gaps in four logic modules #543's behavior-pinning test to the corrected contract: an [] helper-status file now reads as null (malformed content), not an all-null record.

Note for a future sweep: four more files carry local isRecord copies (commands/rotation.ts, codex-cli/writer.ts, codex-cli/state.ts, plus one in recovery) — each needs its own semantics check before deduping, so they're deliberately out of scope here.

Validation

  • npm run typecheck; eslint --max-warnings=0
  • runtime-current-account suite 17/17 with the corrected expectation; proxy safe-equal + issue-474 + app-router canaries pass

Risk / Rollback

One guard tightened to match the canonical implementation; revert the single commit. Behavior change is strictly: malformed array status files are now rejected at read time instead of one step later.

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

replaces the drifted local isRecord copy in runtime-current-account.ts with the canonical import from lib/utils.ts, which correctly excludes arrays via !Array.isArray(value). this closes the silent gap where a [] status file produced an all-null object instead of null.

  • core fix: one-line import swap in runtime-current-account.ts — the local duplicate is deleted and the canonical guard takes over, so array-shaped status files are now rejected at the isRecord boundary rather than one step later by the kind check.
  • test coverage: test/runtime-current-account.test.ts gets a full readAppRuntimeHelperStatus suite including the array-rejection regression case; test/snapshot-inspectors.test.ts is a new file that uses the canonical isRecord import in createDeps (addressing the previous review comment), and two other test files gain additional command-level coverage.
  • windows safety: all new test cleanup paths use removeWithRetry, consistent with the project convention.

Confidence Score: 5/5

safe to merge — a one-import swap tightening a guard on an untrusted filesystem read, with a direct regression test covering the corrected behavior

the change is minimal and targeted: the local isRecord copy is deleted, the canonical version (which adds !Array.isArray) is imported, and the new test explicitly asserts that an array status file now returns null. no logic paths beyond the guard change are touched, and downstream consumers of readAppRuntimeHelperStatus are unaffected because the stricter guard only rejects already-malformed input.

no files require special attention — all changed files are straightforward

Important Files Changed

Filename Overview
lib/runtime/runtime-current-account.ts removes drifted local isRecord; imports canonical guard from lib/utils.ts — fix is correct and targeted
test/runtime-current-account.test.ts adds readAppRuntimeHelperStatus suite including the array-rejection regression test; removeWithRetry used correctly for Windows-safe cleanup
test/snapshot-inspectors.test.ts new test file; createDeps now imports canonical isRecord from lib/utils.ts — addresses previous review comment about drifted guard in test helper
test/codex-manager-usage-command.test.ts adds --since parsing, atomic file write, EBUSY retry, and ENOSPC failure tests; all use removeWithRetry for cleanup
test/codex-manager-models-command.test.ts adds --help, --model validation, per-account availability, and quota-cache-failure coverage tests

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[readAppRuntimeHelperStatus] --> B{file exists?}
    B -- no --> Z1[return null]
    B -- yes --> C{size > 1 MB?}
    C -- yes --> Z2[return null]
    C -- no --> D[JSON.parse file]
    D --> E{isRecord check}
    E -- before fix: typeof===object && !==null\naccepts arrays --> F_OLD[array → all-null status object]
    E -- after fix: canonical isRecord\n!Array.isArray added --> F_NEW[array → return null]
    F_OLD --> G[downstream kind check rejects]
    F_NEW --> Z3[return null early]
    E -- plain object --> H[build AppRuntimeHelperAccountStatus]
    H --> I[return normalized status]
Loading

Reviews (2): Last reviewed commit: "Merge branch 'claude/audit-25-coverage-g..." | Re-trigger Greptile

claude added 2 commits June 10, 2026 10:33
…me-current-account, usage and models commands

Per-file line coverage (same metric as the full-suite baseline run):
- lib/storage/snapshot-inspectors.ts: 34.7% -> 100% (66 uncovered lines -> 0);
  describeAccountsWalSnapshot was fully untested
- lib/runtime/runtime-current-account.ts: 77.6% -> 99.0% (43 -> 2)
- lib/codex-manager/commands/usage.ts: 86.1% -> 100% (45 -> 0)
- lib/codex-manager/commands/models.ts: 72.2% -> 100% (20 -> 0)

Behaviors pinned:
- WAL snapshot inspection: missing-file short-circuit, malformed/forged
  journal entries (checksum mismatch never reaches the normalizer),
  schema-valid fast path, raw-JSON legacy fallback with schemaErrors
  surfaced and non-numeric storedVersion dropped, EACCES read failures
  reported as existing-but-invalid.
- Runtime current-account resolution: index fallback (truncation,
  negative/out-of-range/NaN rejection) and contradiction checks where a
  signal's id/email disagrees with the indexed account; helper status
  file parsing (1 MB cap, type normalization, malformed JSON). Pinned
  quirk: isRecord() accepts JSON arrays, so an "[]" status file yields an
  all-null status object instead of null (downstream kind check still
  rejects it) - suspected oversight, behavior pinned, not fixed.
- usage --since parsing (relative 30m/24h/7d/2W against the clock via
  fake timers, epoch passthrough as number, date strings as strings) and
  the default atomic report writer (nested mkdir, .tmp consumed on
  success, EBUSY rename retry, non-retryable failure cleans the staged
  temp file that briefly exists next to the destination).
- models command: --help short-circuits before account loading, --model
  value validation (missing/empty/flag-like), text-mode availability
  lines incl. disabled-account reasons, quota cache load failures
  swallowed.

https://claude.ai/code/session_01XNtnkLbBiXZxfQQYLMpucB
The local isRecord copy in runtime-current-account.ts had drifted from
the canonical lib/utils.ts guard and accepted JSON arrays, so an []
helper-status file produced an all-null status object instead of null
(harmless today only because the downstream kind check rejected it).
Deletes the drifted duplicate in favor of the canonical import and flips
the behavior-pinning test from PR #543 to the corrected contract.

https://claude.ai/code/session_01XNtnkLbBiXZxfQQYLMpucB
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@ndycode, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 10 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 @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: f96df4f0-e688-4707-b11a-4da7228e5d9a

📥 Commits

Reviewing files that changed from the base of the PR and between 98d9819 and 63f8b75.

📒 Files selected for processing (5)
  • lib/runtime/runtime-current-account.ts
  • test/codex-manager-models-command.test.ts
  • test/codex-manager-usage-command.test.ts
  • test/runtime-current-account.test.ts
  • test/snapshot-inspectors.test.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/audit-26-isrecord-fix
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch claude/audit-26-isrecord-fix

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Comment thread test/snapshot-inspectors.test.ts
The createDeps helper inlined the exact drifted array-accepting guard
this PR removes from runtime-current-account.ts. Import the canonical
helper from lib/utils.js instead so the test deps cannot silently
diverge from the production contract.

https://claude.ai/code/session_01XNtnkLbBiXZxfQQYLMpucB
claude added 2 commits June 10, 2026 10:46
…g it

Use APP_RUNTIME_HELPER_STATUS_FILE from lib/runtime-constants.js so a
rename of the status file cannot silently turn the readAppRuntimeHelperStatus
tests into file-not-found nulls.

https://claude.ai/code/session_01XNtnkLbBiXZxfQQYLMpucB
@ndycode
ndycode merged commit 1930d73 into main Jun 10, 2026
1 of 2 checks passed
ndycode pushed a commit that referenced this pull request Jun 10, 2026
Inline the #544 isRecord and #546 stream-stall references so the
'surfaced real bugs twice' claim is verifiable without scrolling to
section 5.1.

https://claude.ai/code/session_01XNtnkLbBiXZxfQQYLMpucB
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants