Symptom
codex-clean seat status refuses to run while any codex-clean run holds the lock:
Error: a codex-clean run is in progress (holding ~/.config/codex-clean/codex.lock);
use `codex-clean seat list` for the cached snapshot and retry later
During a long session this means there is no way to get a fresh usage reading at all — only the cached one via seat list. In the session that produced #37 this blocked every attempt for over an hour.
Why it is more annoying than it needs to be
The usage fetch itself needs no exclusivity. It already runs each seat in its own per-seat, per-pid scratch CODEX_HOME and never touches the global auth file (src/usage.rs:332-345):
let scratch = ScratchCodexHome::create_for(&seat.name, "status")?;
seat::atomic_write(&scratch.auth_path(), &bytes)?;
seat::seed_file_store_config(scratch.path())?;
let result = call(scratch.path());
seat::refresh_back_from_guarded(&scratch.auth_path(), &seat.name, &expected)?;
The lock at src/seat_cmd.rs:460 is there for the other things seat status does: refresh-back into ~/.codex/auth.json, active-slot syncing, and the state.json write.
Suggested direction
A read-only mode — seat status --no-sync, or automatic fallback when the lock is held — that:
- fetches usage in scratch homes as it already does,
- skips refresh-back and active-slot syncing,
- either skips the
state.json write or takes the lock only for that brief window,
- prints the table with a note that nothing was persisted.
This is independent of the wider locking redesign in the concurrency issue and could ship on its own.
Symptom
codex-clean seat statusrefuses to run while any codex-clean run holds the lock:During a long session this means there is no way to get a fresh usage reading at all — only the cached one via
seat list. In the session that produced #37 this blocked every attempt for over an hour.Why it is more annoying than it needs to be
The usage fetch itself needs no exclusivity. It already runs each seat in its own per-seat, per-pid scratch
CODEX_HOMEand never touches the global auth file (src/usage.rs:332-345):The lock at
src/seat_cmd.rs:460is there for the other thingsseat statusdoes: refresh-back into~/.codex/auth.json, active-slot syncing, and thestate.jsonwrite.Suggested direction
A read-only mode —
seat status --no-sync, or automatic fallback when the lock is held — that:state.jsonwrite or takes the lock only for that brief window,This is independent of the wider locking redesign in the concurrency issue and could ship on its own.