## Description
Headroom currently treats missing `auth.json` as “not ChatGPT auth” for
Codex, which breaks keyring-backed ChatGPT sessions on Codex CLI 0.144.6
because those sessions intentionally may not store credentials in the
file. This updates the Codex auth detector to keep the existing
file-backed fast path and fall back to Codex-owned auth metadata when
the session is keyring-backed or auto-backed, so `requires_openai_auth =
true` is emitted only for real ChatGPT logins.
Closes#2474
## Type of Change
- [x] Bug fix (non-breaking change that fixes an issue)
- [ ] New feature (non-breaking change that adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
- [ ] Performance improvement
- [ ] Code refactoring (no functional changes)
## Changes Made
- extend Codex auth detection so keyring-backed and auto-backed sessions
can be classified from Codex-owned auth metadata when `auth.json` is
absent
- preserve the current file-backed ChatGPT, API-key, malformed-file, and
fail-closed behaviors
- add focused install-layer regression coverage for the new keyring path
and adjacent negative space
## Testing
- [x] Unit tests pass (`uv run pytest
tests/test_install/test_codex_install.py -q`)
- [x] Linting passes (`uv run ruff check
headroom/providers/codex/install.py
tests/test_install/test_codex_install.py`)
- [ ] Type checking passes (`uv run mypy headroom`)
- [x] New tests added for new functionality when applicable
- [x] Manual testing performed
### Test Output
```text
uv run pytest tests/test_install/test_codex_install.py -q
============================= test session starts =============================
platform win32 -- Python 3.12.13, pytest-9.0.3, pluggy-1.6.0
collected 9 items
tests\test_install\test_codex_install.py ......... [100%]
============================== 9 passed in 0.24s ==============================
uv run ruff check headroom/providers/codex/install.py tests/test_install/test_codex_install.py
All checks passed!
```
## Real Behavior Proof
- Environment: Windows, Codex CLI 0.144.6 available locally, Python
3.12.13 via `uv`
- Exact command / steps: `codex login status`; `Measure-Command { codex
login status > $null }`; focused pytest and Ruff commands above
- Observed result: `codex login status` returns `stdout=''` and
`stderr='Logged in using ChatGPT\n'`; the status probe measured `71.40`
ms; pytest reports `9 passed in 0.24s`; keyring ChatGPT emits
`requires_openai_auth = true`, non-ChatGPT and failed probes omit it,
and file-backed ChatGPT/API-key cases remain true/false
- Not tested: live local keyring-backed Codex login
## Review Readiness
- [x] I have performed a self-review
- [x] This PR is ready for human review
## Checklist
- [x] My code follows the project's style guidelines
- [x] I have performed a self-review of my code
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] I have updated the CHANGELOG.md if applicable
## Additional Notes
`CHANGELOG.md` stays untouched because Headroom generates release notes
from conventional commits. The PR should only claim the Codex-owned
detection path and focused local regression coverage; the live keyring
session proof remains a follow-up owner check.