You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[structural-drift-reviewer-codex-ladder] Delegate the client reviewer effort ladder to the server's codex model gate #6817
Slice audited: client-side hand mirrors of server sources of truth (client/src/lib, client/src/utils, client/src/components/*) — structural-drift audit, 2026-09-10.
Problem
client/src/lib/reviewerPins.js:113-126 inlines a copy of codexEffortLevelsForModel (server/lib/providerModels.js:155-162) with its own regex and a hardcoded ultra-model list ['gpt-5.6', 'gpt-5.6-sol', 'gpt-5.6-terra', 'gpt-6-astra'] (the server's CODEX_ULTRA_MODELS, line 137). The copy landed in 255032a (Reviewer effort pins still offer codex 'minimal' for gpt-6 models that reject it #6447) after the server list had already moved twice without the client (e8efea4 introduced three ultra ids; f4df117 added gpt-6-astra).
The copy is wrong today, not merely at risk. Running both sides on the same inputs (server reviewerEffortLevels('codex', model) from reviewerConfig.js:595 vs the client function):
model
server
client
gpt-5.6, gpt-5.6-sol, gpt-5.6-terra
minimal … max, ultra
minimal … max
gpt-6-astra
low … max, ultra
low … max, ultra
gpt-6, gpt-5.5, o3, null
equal
equal
The client consults its ultra list only inside the gpt-6+ branch, so the gpt-5.6 family never gets ultra.
The drift gate cannot see it: server/lib/reviewerConfig.test.js:396-405 ("client mirror of the reviewer vocabulary") compares reviewerEffortLevels(reviewer) with no model, so the model-gated branch is never exercised. The client file's header (reviewerPins.js:19) cites a "client mirror of the reviewer effort ladders" test that no longer exists (it went with providerModels.mirror.test.js in c82dcdf).
Impact
A codex reviewer pinned to a gpt-5.6 model cannot be given the ultra effort in ReviewerPicker although the server (and the CLI) accept it — the exact "hide a tier their CLI accepts" failure the drift test's own comment describes. The next change to CODEX_ULTRA_MODELS or CODEX_NO_MINIMAL_MODEL_RE repeats #6447 in the other direction (offering minimal to a model that answers HTTP 400).
client/src/lib/reviewerPins.js#reviewerEffortLevels: replace the inline branch with if (slug === 'codex' && model) return codexEffortLevelsForModel(model);, imported from '../../../server/lib/providerModels.js' (the leaf client/src/utils/providerModels.js already imports from; reviewerPins.js stays dependency-free so the server suite can keep loading it). Delete the local ultra list and regex. Fix the header comment to name the real test.
Extend "matches server reviewerEffortLevels for every reviewer" in reviewerConfig.test.js with a codex model matrix — gpt-5.6, gpt-5.6-sol, gpt-6-astra, gpt-6, gpt-5.5, o3 — asserting toEqual against the server for each. Confirm the test is red against the current client file before applying steps 1-2.
reviewerConfig.test.js compares codex ladders for at least the six model ids above and fails on the pre-fix client file.
In ReviewerPicker a codex reviewer with model gpt-5.6 offers ultra.
Server and client suites green.
Scope: small
Dispatch:model:light — a well-specified two-file edit plus a test matrix. effort:medium — the parity matrix has to cover both ladder gates (ultra list and no-minimal regex) and be proven red first.
Slice audited: client-side hand mirrors of server sources of truth (
client/src/lib,client/src/utils,client/src/components/*) — structural-drift audit, 2026-09-10.Problem
client/src/lib/reviewerPins.js:113-126inlines a copy ofcodexEffortLevelsForModel(server/lib/providerModels.js:155-162) with its own regex and a hardcoded ultra-model list['gpt-5.6', 'gpt-5.6-sol', 'gpt-5.6-terra', 'gpt-6-astra'](the server'sCODEX_ULTRA_MODELS, line 137). The copy landed in 255032a (Reviewer effort pins still offer codex 'minimal' for gpt-6 models that reject it #6447) after the server list had already moved twice without the client (e8efea4 introduced three ultra ids; f4df117 addedgpt-6-astra).The copy is wrong today, not merely at risk. Running both sides on the same inputs (server
reviewerEffortLevels('codex', model)fromreviewerConfig.js:595vs the client function):gpt-5.6,gpt-5.6-sol,gpt-5.6-terragpt-6-astragpt-6,gpt-5.5,o3,nullThe client consults its ultra list only inside the gpt-6+ branch, so the gpt-5.6 family never gets
ultra.The drift gate cannot see it:
server/lib/reviewerConfig.test.js:396-405("client mirror of the reviewer vocabulary") comparesreviewerEffortLevels(reviewer)with no model, so the model-gated branch is never exercised. The client file's header (reviewerPins.js:19) cites a "client mirror of the reviewer effort ladders" test that no longer exists (it went withproviderModels.mirror.test.jsin c82dcdf).Impact
A codex reviewer pinned to a gpt-5.6 model cannot be given the
ultraeffort in ReviewerPicker although the server (and the CLI) accept it — the exact "hide a tier their CLI accepts" failure the drift test's own comment describes. The next change toCODEX_ULTRA_MODELSorCODEX_NO_MINIMAL_MODEL_RErepeats #6447 in the other direction (offeringminimalto a model that answers HTTP 400).Fix (decided)
server/lib/providerModels.js: exportcodexEffortLevelsForModel.client/src/lib/reviewerPins.js#reviewerEffortLevels: replace the inline branch withif (slug === 'codex' && model) return codexEffortLevelsForModel(model);, imported from'../../../server/lib/providerModels.js'(the leafclient/src/utils/providerModels.jsalready imports from;reviewerPins.jsstays dependency-free so the server suite can keep loading it). Delete the local ultra list and regex. Fix the header comment to name the real test.reviewerConfig.test.jswith a codex model matrix —gpt-5.6,gpt-5.6-sol,gpt-6-astra,gpt-6,gpt-5.5,o3— assertingtoEqualagainst the server for each. Confirm the test is red against the current client file before applying steps 1-2.Acceptance criteria
grep -n "gpt-5.6\|gpt-\[6-9\]" client/src/lib/reviewerPins.jsreturns nothing.reviewerConfig.test.jscompares codex ladders for at least the six model ids above and fails on the pre-fix client file.gpt-5.6offersultra.Scope: small
Dispatch:
model:light— a well-specified two-file edit plus a test matrix.effort:medium— the parity matrix has to cover both ladder gates (ultra list and no-minimal regex) and be proven red first.