Repository navigation
fix(cross-model): attest the omp serving family from the session's recorded model - #2043
Merged
Merged
Conversation
Real omp sessions record role=temporary model_change entries that the worker jq skipped, so a temporary switch to another family left the host family at the earlier default and could mark a peer independent against the wrong host. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Codex Review Summary: ✅ CompletedThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6ebce11de3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
A Codex, Claude Code, or Grok session started inside omp inherits OMPCODE and PI_SESSION_FILE, so the workers read the parent's recorded model and attested the wrong family, letting same-family agreement be promoted as independent. The workers now read the session file only when no other harness's marker is present, and fail closed otherwise. Also map omp's first-party subscription providers (openai-codex -> codex, xai-oauth -> grok), which omp records for ChatGPT and xAI logins, and drop two Coverage lines that existing conditions already decide.
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #2042
Summary
Follow-up to #1825 / #1867. Under oh-my-pi (omp) the host-attestation snippet leaves the serving family
unknown, which is correct because omp setsCLAUDECODE=1whatever model serves it. The cross-model worker then refuses an unknown family before any egress, so the cross-model pass is skipped under omp unless the orchestrator sets the family by hand. In one real session a six-lens review shipped without its independent lens.omp records the serving model:
PI_SESSION_FILEpoints at a session JSONL whosemodel_changeentries carryprovider/id. Thece-code-reviewandce-doc-reviewworkers now read it when the harness is omp and the family arrives asunknown.anthropic/claude-*-> claude,openai/gpt-*|codex-*|o<digit>*-> codex,xai/grok-*-> grok,google/gemini-*-> gemini. Everything else staysunknown, so the pass is skipped instead of mis-attested (gateway-served Claude, local models, missing or empty session file, nomodel_change).smol,subagent:*) are ignored. If the latest relevant entry is afallbackortemporaryswitch, the serving model can't be known and the family staysunknown.jqparse failure (for example a torn trailing line) also fails closed tounknown.ce-code-reviewandce-doc-reviewreferences now says to passunknownand still start the job under omp, and to report a worker skip ofhost serving family unattestedplainly in Coverage instead of as a routine not-run.Not done:
ce-pov. Its orchestrator excludes automatic oracle candidates while the family isunknown, before the worker runs, so worker-side resolution cannot reach it. An attempted edit was reverted in this PR's history. It needs the family resolved before candidate discovery without breaking the snippet parity test.Validation
Base:
8e5d1c87.bun run test --changed-since=8e5d1c87,bun run test:skill-guards,bun run release:validate,bun run plugin:validateandbun run typecheckpass, apart fromtests/omp-native-install.test.ts. That test fails on omp 18.18.x becauseomp install --dry-run --jsonno longer printsnameandmanifest; the test does not depend on this change.tests/skills/ce-code-review-cross-model-routes.test.tsandtests/skills/ce-doc-review-cross-model-routes.test.tscover first-party mappings, ignored non-default roles, later default entries, and the fail-closed cases.anthropic/claude-sonnet-5-5):ce-code-reviewandce-doc-revieweach passed on Claude, Codex and OpenCode. Every cell declared harnessomp, familyunknown, targetcodex. Grok did not run: the eval driver's grok flags (--prompt-file,--verbatim,--cwd,--always-approve) do not exist in the grok CLI I have (1.1.7), and it has no credentials configured here. The pre-change arm was run once force-doc-reviewonly: Codex skipped, and Claude declared familyclaudefrom its own model id.anthropic/claude-sonnet-5-5(real npm/acpx/Codex execution, synthetic fixture diffs only): the worker run directly loggedhost claude excluded, ran thecodexroute ongpt-6.1-terraand publishedindependence_verified=true; the same worker launched throughpeer-job-runner.py start/wait/resultreacheddonewith the same receipt; and a fullce-code-reviewrun (mode:agent, staged payment-handling fixture, depthfull) started the peer with harnessompand familyunknownwithout the orchestrator setting the family, and foldedadversarial-codexinto the review.jqfilter on a random sample of 60 files. Most turns come from entries that record noruntime.version, so this does not establish the rule for every omp release.Open: verification on omp versions beyond 18.18.x, and
ce-pov.Security Disclosure
Shell is changed in the two cross-model worker scripts (
cross-model-adversarial-review.sh,cross-model-doc-review.sh): they now runjqover the file named byPI_SESSION_FILE, read-only, and only when the harness is omp and the family isunknown. The path comes from the host's environment and is passed as an argument, not interpolated into a command. The extracted model id is only pattern-matched against a fixed list of first-party prefixes to pick a family name; it is never executed; any parse error, unreadable file or unrecognized id leaves the familyunknown, which skips the pass before any egress. Residual risk: a session file that falsely records a first-party model would attest that family. The file is written by the host runtime, which is the same trust boundary as the existingCLAUDECODE/OMPCODEmarkers.Agent Disclosure
🤖 Generated with Claude Code
Maintainer follow-up (0a1b47c)
OMPCODEandPI_SESSION_FILE, so the worker read the parent's model and attested the wrong family. Same-family agreement could then be promoted as independent. The workers now read the session file only when no other harness's marker is present (CLAUDE_CODE_ENTRYPOINT/CLAUDE_CODE_SESSION_ID,CODEX_*,GROK_*,CURSOR_*,OPENCODE_TERMINAL), and otherwise skip as unattested. omp itself sets none of these. The new route tests failed on the previous head and pass now.openai-codex/<model>for ChatGPT logins andxai-oauth/<model>for xAI logins, and both previously stayedunknown. omp pins them tochatgpt.comandx.ai/grok.com, so they now map tocodexandgrok.ce-code-review, the "never started" bullet described a job that did start, and the recovery branch already owns that case. Ince-doc-review, the existing clean-skip condition ("host un-attestable") already decides it.Validation:
release:validateandplugin:validatepass.bun run test --changed-since=8e5d1c87: 5001 pass, 1 fail. The failure istests/omp-native-install.test.ts: omp 18.18.5's dry-run JSON droppednameandmanifest. It predates this PR and is skipped in CI.anthropic/claude-sonnet-5-5attestedclaudeand ran the real Codex peer (gpt-6.1-terra) withindependence_verified: true.openai-codex/gpt-6.1-terraandxai-oauth/grok-4.20-0309-reasoningsessions attestedcodexandgrok(dry run).Agent disclosure for this follow-up: Claude Code · claude-opus-5-5.