Skip to content

fix: three stability fixes for rollout pruning, CDP outages, and new-session binding - #1

Open
tsubasakong wants to merge 4 commits into
SergioChan:mainfrom
tsubasakong:fix/token-meter-stability
Open

fix: three stability fixes for rollout pruning, CDP outages, and new-session binding#1
tsubasakong wants to merge 4 commits into
SergioChan:mainfrom
tsubasakong:fix/token-meter-stability

Conversation

@tsubasakong

Copy link
Copy Markdown

Summary

Three independent stability fixes for the Codex Desktop injector, split into
separate commits so each can be reviewed or reverted on its own.

1. fix: tolerate rollout files removed between discovery and read

  • Problem: Codex prunes old rollout JSONL files. When a file disappeared
    after discovery but before the metadata/appended read, the injector crashed
    with an unhandled ENOENT, killing the meter and leaving a frozen overlay.
  • Fix: missing files are skipped during discovery and both read phases, and
    the underlying range read treats a vanished file as an empty read.
  • Test: added a regression test covering a file removed between polls.

2. fix: survive transient CDP unavailability

  • Problem: a temporary CDP outage (for example a fetch timeout) exited the
    injector, freezing the injected overlay until manual restart.
  • Fix: the poll loop now retries through CDP failures, re-verifies the
    loopback listener when CDP returns, re-attaches to verified renderers, and
    logs errors at most once per minute instead of dying.

3. fix: bind new Codex sessions by real conversation id

  • Problem: Codex Desktop assigns new sessions an optimistic sidebar id
    (local:client-new-thread:<uuid>) until the real session id exists. The
    session probe only accepted plain UUIDs, so brand-new sessions stayed
    UNBOUND even though their rollout data was being written.
  • Fix: when the active sidebar row carries an optimistic id, the probe
    resolves the real conversation id from the main content area
    (data-response-annotation-conversation /
    data-above-composer-conversation-id). Binding still fails closed when no
    real id is available.
  • Tests: added coverage for optimistic-id resolution and the fail-closed
    case.

Testing

  • npm test: 27/27 pass (3 new regression tests).
  • npm run check: pass.
  • Live validation on Codex Desktop 26.730.61309 (macOS 26.3): a new session
    binds to its real conversation id, token totals advance, and the meter
    re-attaches after a transient CDP interruption.

Security implications

  • No new privileges or network surfaces; CDP stays loopback-only behind the
    existing bundle/signature/listener verifier.
  • Unknown or ambiguous sessions still fail closed (UNBOUND) and are never
    guessed from file recency.
  • The collector still retains only numerical usage and timing metadata, never
    prompt, reasoning, tool, or assistant content.

Codex prunes old rollout JSONL files; a file deleted after discovery but before metadata/appended reads crashed the injector with ENOENT. Skip missing files instead of failing.
A temporary CDP outage killed the injector and froze the overlay. Keep polling, re-verify the listener, and re-attach when CDP returns; log errors at most once per minute.
New sessions show an optimistic sidebar id (local:client-new-thread:<uuid>) until Codex assigns the real id. Resolve the real conversation id from the main content area so the meter can bind immediately; fail closed when no real id is available.
A CDP call that never settles (for example after a renderer WebSocket silently dies) could drain the event loop: the call timeout timer was unref'd, so Node exited with code 13 and an unsettled top-level await, freezing the overlay. Keep the timeout timer ref'd, refuse calls on non-open sockets, and exit 130 when stopped by a signal so launchers can distinguish a clean stop from an unexpected crash.
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.

1 participant