feat(provider): Codex CLI adapter behind AgentProvider — device-code auth, rollout chat surface, conformance to the #80 bar (ADR-0037) #91
No reviewers
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Cloonar/coding-lab!91
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "afk/87"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The second
AgentProvider(idcodex,internal/provider/codex), implementing issue #87's research-pinned spec — the issue body plus both amendments — to ADR-0036's two-tier conformance bar. Every fragile coupling is live-pinned against codex-cli 0.133.0: the Tier-2 spike sweep in the issue's Amendment 2 plus fresh probes from this branch (device-auth stdout,codex debug models,login statusshapes, a live TUI slash-popup scrape, and a live validation that the trust config-append suppresses the first-run prompt).The adapter
codex --ask-for-approval never --sandbox danger-full-access -c project_doc_fallback_filenames=["AGENTS.local.md"] [--model M] -c model_reasoning_effort=E [prompt]. Effort is always explicit (codex execdefaults to none); no-c commit_attribution=""(unknown key on 0.133, hard error under--strict-config; attribution is absent at source). Full access is evidence-based: workspace-write's three live-verified traps (network off, cwd-confined writes,.gitmounted read-only) each break a lab session.LoginStartdrivescodex login --device-authin thelab-login-codexsession (ADR-0034), scrapes the verification URL + one-time code from the pane, and a single background poller forcescodex login statusuntil the login lands, then publishesprovider.auth.changed.LoginSubmitCodereturns the new typedErrLoginCodeUnsupported; logout is status-decided with anauth.jsonremoval escalation.SeedWorkspacewrites nothing in-tree: a guarded, append-only[projects."<worktree>"] trust_level = "trusted"table inconfig.toml(the argv trust route is dead on 0.133 — live-refuted; the append validated live on a real spawn) and a marker-guardedAGENTS.local.mdbridge block in the global$CODEX_HOME/AGENTS.md(a repo-trackedAGENTS.mdsilently skips the fallback-filenames leg — the trap ADR-0035 predicted).NativeSkillDiscovery: false(0.133 discovers skills globally only) so the ADR-0035 skills index applies. Incogni is a no-op by ground truth; defensiveScrubPatternsjoin the ADR-0033 union.$CODEX_HOME/sessions/YYYY/MM/DD/, located newest-first bysession_meta.cwd(local-time filenames, UTC payloads;/newrotates natively so clear/epoch identity is free).event_msgrecords drive prose and state (turn_aborted(reason=interrupted)→ interrupted lifecycle); tool chips resolve bycall_id; encrypted reasoning renders from summaries only. Reply = bracketed paste + paced Enter (queue-with-steer mid-turn); interrupt = single Esc, never Ctrl-C (immediate quit — worst case confirmed live). A curated 40-command catalog scraped verbatim from the live TUI popup.DeepLinker(no per-session web surface; rows fall back to tmux attach), noLiveSignalsin v1 (0.133's stable hooks vocabulary is recorded in the compat record as the follow-up substrate), noConnectingReporter.Seam + SPA (generic, additive)
New
AuthFlowDeviceCodekind, optionalLoginCodeReportercapability, andErrLoginCodeUnsupportedsentinel ininternal/provider; httpapi returnsuser_codefrom login/start for providers asserting the capability and maps the sentinel to 409; the SPA auth card gains a descriptor-driven device-code branch (verification link + prominent one-time code + SSE completion). Existing adapters and fakes compile untouched.Conformance evidence
TestConformance/codex— all ten obligations pass via the #80 registration table.internal/compat/codex/compat.md(§1–§10, provenance-tagged, version-tagged fixtures undertestdata/), 13 hermetic pin tests plusLAB_COMPAT_LIVE=1probes — both live probes pass against the real authenticated binary on this host.neutrality_test.goextended with the codex package exactly as claudecode; no codex coupling outside the adapter and thecmd/lab/main.gocomposition root.go build ./...(+-tags ui),go test ./...green (the only failures areinternal/tmuxxlive-integration tests, untouched by this branch and environmental — the sandbox cannot start real tmux servers; CI provides them), golangci-lint 2.12.2 (CI's version): 0 issues, SPA eslint/prettier/vitest: 563/563.ADR-0037 records the decisions and the rejected alternatives.
Closes #87
🤖 Generated with Claude Code
https://claude.ai/code/session_016NZQDuabyKgLnhqZWPQJWK