feat(adapters): codex T2 — AGENTS.md fenced snippet - #393
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Pull request overview
Adds Codex adapter T2 guidance via an AGENTS.md fenced snippet (kept in lockstep with Cursor’s snippet), and improves the installer so fenced snippets can be refreshed in-place when their fence body has drifted. The PR also introduces toml_merge support for Codex’s .codex/config.toml so existing user config is deep-merged rather than silently skipped.
Changes:
- Add
adapters/codex/AGENTS.md.snippetand wire it into Codexinstall.yamlas a T2fenced_appendinstall. - Update
_install_fencedto refresh a drifted fenced body in-place (and report viaInstallResult.merged). - Add
toml_mergesupport + TOML serializer/merge logic, and expand installer tests to cover Codex T2 and TOML merge behaviors.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| tests/test_install_adapter.py | Adds coverage for Codex T2 fenced snippet install/refresh and Codex TOML merge behavior. |
| src/vouch/install_adapter.py | Implements fenced-body refresh behavior and adds toml_merge support (merge + serialize + install). |
| adapters/codex/install.yaml | Defines fence markers, enables toml_merge for T1, and adds T2 fenced snippet entry. |
| adapters/codex/AGENTS.md.snippet | New Codex AGENTS snippet (intended to stay cursor-lockstep modulo host name). |
| existing = dst.read_text(encoding="utf-8") | ||
| if manifest.fence_begin in existing: | ||
| result.skipped.append(rel_dst) | ||
| begin = existing.index(manifest.fence_begin) | ||
| end = existing.find(manifest.fence_end, begin) | ||
| if end == -1: |
vouchdev#361 inserted `_log = logging.getLogger(...)` between two import groups in jsonl_server.py. that statement-among-imports trips ruff's E402 on every import that follows it, so `ruff check src tests` — the lint gate in ci — now fails on the whole repo. move the logger definition below the imports (where storage.py already keeps its own module logger); no behaviour change.
.codex/config.toml is codex's primary config file, so the plain-copy path silently skipped any project where codex was already configured and vouch never got wired. add a toml_merge entry flag mirroring json_merge: parse the existing destination with tomllib, deep-merge the template's tables into it (existing user values always win on conflict), and write back. flip the codex T1 entry to toml_merge. writing uses a minimal hand-rolled serializer (tables, arrays, inline tables in arrays, scalars, datetimes) so the dependency set stays unchanged; the output must survive a tomllib round-trip back to the merged data, and anything the serializer can't faithfully re-emit degrades to skipped rather than risking the user's config. closes vouchdev#384
codex reads AGENTS.md for project instructions the way cursor does, but the codex adapter stopped at T1, so a codex session got the kb tools with no standing guidance on recall-first or the review gate. ship adapters/codex/AGENTS.md.snippet as a T2 tier with the standard fence markers, kept in lockstep with cursor's snippet modulo the host name (enforced by a sync test). also close the edited-fence gap in _install_fenced per the ticket's acceptance criteria: a fence body that drifted from the shipped snippet is replaced within the markers (reported as merged) instead of being skipped forever, while user content outside the fence stays untouched. a begin marker without an end marker is treated as corrupt and left alone. closes vouchdev#385
8ace918 to
628c733
Compare
|
addressed the copilot review: |
codex reads
AGENTS.mdfor project instructions the same way cursor does, and the cursor adapter already ships this exact tier. without it, a codex session gets the kb tools but no standing instructions on when to recall or how to propose through the review gate. this addsadapters/codex/AGENTS.md.snippetas a T2 tier with the standard fence markers.the snippet carries the same invariants as cursor's (what vouch is, all writes via proposals, review stays human) and is phrased host-neutrally: the only difference is the
VOUCH_AGENT=codexidentity line, and a sync test assertscodex_snippet == cursor_snippet.replace("cursor", "codex")so the two can't drift apart silently.the ticket's acceptance criteria also call for "an edited fence body is replaced within the markers", which
_install_fenceddidn't do — it skipped whenever the fence existed, so a hand-edited or stale snippet stayed stale forever. the fenced writer now recognizes its own fence and brings a drifted body back in sync in place (reported through themergedchannel), touching nothing outside the markers. an up-to-date fence still reports skipped, so re-runs stay flat-noop and the existing claude-code/cursor/openclaw behavior is preserved; a begin marker without an end marker is treated as corrupt and left alone. this benefits every fenced adapter, not just codex.tests cover: append to an existing AGENTS.md, create when absent, idempotent re-run, T1 not touching AGENTS.md, the cursor lockstep check, edited-fence refresh (user content above and below the fence survives), and the unclosed-fence guard. full suite, mypy, and ruff green.
stacks on #392 (both touch
adapters/codex/install.yaml) — merge after it; once #392 lands this diff reduces to the T2 change.closes #385