fix(chatgpt): target Max tier, Ultra policy, stale-slider fall-through, model_used overwrite (yz-7p3) - #440
Merged
Merged
Conversation
…h, model_used overwrite, account-max rename Lead ruling (yoetz/chatgpt-max-tier, 2026-08-25): target the literal Max effort tier on the personal/Pro picker; Extra High is acceptable proof only when Max is absent from the opened Effort submenu ladder. Enterprise Pro unchanged. Ultra is recognized but never clicked/selected; a preset Ultra is accepted as at-or-above-Max proof with a diagnostic. - chatgpt-dom.js: ladder-aware effortIsMaxTier (Max target, Extra High only when Max absent or no Effort row); six-tier ladder (Light/Medium/High/Extra High/Max/Ultra); Advanced -> Effort row -> opened ladder -> select Max fall-through for stale slider ceilings; Ultra preset accepted via the opened submenu (never clicked); findMainModelMenu matches the six-tier ladder. - moveEffortSliderToMaxTier: root-cause hardening (attemptKey ?? state) + final_fresh_recheck guard; the guard only rescues a verified Max/Pro/ Max-absent tier, never an unknown label. - service-worker.js: backend model_slug no longer overwrites the picker-proven model_used when selection was verified; slug captured as model_slug. - CDP/dev-browser (chatgpt_web.rs): accepts Sol Max tier (parity with native). - Rename gpt-5-6-sol-extra-high -> gpt-5-6-sol-account-max across Rust mirrors. - CLI: model_slug added to ChatgptRecipeDiagnostics + parse_recipe_result + JSON output, so 7p3.2 observability holds end-to-end. - CLAUDE.md Browser Architecture first bullet rewritten per the ruling. - Fixtures: six-tier ladder (from the live dump verbatim), stale-Extra-High fall-through selects Max, Max-unverifiable fail-closed, preset-Ultra accepted, negative stale-ceiling test, slider unknown-ceiling not rescued by final_fresh_recheck, plus the 7p3.4 stale-snapshot regressions. Tests: 651 Rust (cargo test), 402 extension (node --test), fmt + clippy clean. Beads: yz-7p3.1/.2/.4/.5/.6/.7/.9 under epic yz-7p3.
…cognition (A), directional pill corroboration (B)
yz-7p3.3 review-gate findings from Claude (wave-2 re-review, CHANGES REQUIRED):
Finding D (BLOCKING — ruling violation on the CDP transport): chatgpt_web.rs
effortVerified accepted a checked "extra high" unconditionally (verified a
preset Extra High with Max present without selecting Max) and did not
recognize "ultra", so a preset Ultra fell through to the maxTier click path
and was DOWNGRADED to Max. Fix: rewrite effortVerified to be ladder-aware —
checked max/pro verifies; checked ultra verifies (never clicked, diagnostic
warning); checked extra-high verifies ONLY when no "max" item exists. Result
envelope now carries ultraPreset + an Ultra diagnostic warning. The
maxTier fallback click path never includes ultra. is_verified_sol_extra_high_
selection now trusts "GPT-5.6 Sol Ultra". Tests: preset-ultra never
downgraded; extra-high gated on max-present; verified set includes ultra.
Finding A (should-fix): findEffortSubmenu required labels.includes("max"),
so a legacy five-tier Effort submenu (Max genuinely absent) was unreachable
except via the structural aria-controls fallback — a visible-but-unlinked
five-tier submenu failed closed where the ruling says accept Extra High, and
the maxAbsent branch was unreachable through findEffortSubmenu proper. Fix:
recognize the ladder by >=2 known ladder labels; maxAbsent is decided AFTER,
from the labels. Re-stamp ladder_max_absent across the closeEffortSubmenu
fresh re-read (same flag-preservation fix as the Ultra branch). Test:
five-tier submenu with Max genuinely absent accepts Extra High with
ladder_max_absent.
Finding B (should-fix): pillConfirmsEffortLabel used the loose
CHATGPT_MAX_EFFORT_LABELS set — a closed pill reading "Extra High"
corroborated a selected "Max", gutting the closed-pill corroboration exactly
in the stale-pill scenario. Fix: corroboration is now directional (pill tier
>= verified picker tier). A stale Extra High pill cannot confirm a Max when
the ladder had Max; going up (picker Extra High, pill Max/Pro) still passes.
Flipped the two personal-picker tests encoding the old loose behavior to the
correct fail-closed expectation.
MINOR: aligned the effortMaxTierDecision comment — the effort_row_label path
accepts a preset Max/Pro row before the submenu fall-through (corroborated
downstream by the tightened pill), only Ultra requires submenu verification.
Wave-1 leftover: added a regression guard test that would have caught the
unawaited waitForEffortSubmenu Promise (an unawaited menu would make
effortSubmenuLadderLabels(Promise) return [] and mis-classify the ladder).
Tests: 653 Rust (cargo test), 404 extension (node --test), fmt + clippy clean.
Beads: yz-7p3.5 reopened for this gate; closes again only after re-review.
…ix two-word tier suffix match
yz-7p3.3 re-review non-blocking cleanups (approved, folded into release PR):
1. The options param ({ladderMaxAbsent, ultraPreset}) was threaded by both
callers but never read in the function body — the directional rank logic
already handles those cases directly. Dropped from signature + both callers.
2. pillToken = foldedPill.split(' ').pop() turned 'extra high' into 'high'
(rank 2, not 3). Coincidentally correct today (the earlier endsWith check
caught the exact-tier case and the misrank gave the right verdict everywhere
reachable), but a latent trap for any future two-word tier. Now extracts the
pill tier by matching a known ladder label as a suffix (longest-first order
so 'extra high' is matched before 'high').
Tests: 404/404 extension (node --test). No Rust change.
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.
Summary
Lead ruling from Claude (AMQ thread
yoetz/chatgpt-max-tier, 2026-08-25): target the literal Max effort tier on the personal/Pro ChatGPT picker; Extra High is acceptable proof only when Max is absent from the opened Effort submenu ladder. Enterprise Pro unchanged. Ultra is recognized but never clicked/selected; a preset Ultra is accepted as at-or-above-Max proof with a diagnostic.This closes the drift between the native extension's picker contract and the CDP/dev-browser path, and stops the backend
model_slugfrom clobbering the picker-provenmodel_usedlabel.Review trail
a78be41.a78be41— APPROVED. yz-7p3.3 gate passes.a9634ea— two non-blocking cleanups (deadoptionsparam dropped; two-word tier suffix match) folded in per Claude.PR diff =
7c29b20+a78be41+a9634ea(exactly as Claude expects).Changes
chatgpt-dom.js— ladder-awareeffortMaxTierDecision(six-tier ladder Light/Medium/High/Extra High/Max/Ultra; Max is the target; Extra High only when Max absent or no Effort row; Ultra preset accepted via the opened submenu, never clicked).selectMaxFromEffortSubmenu: Advanced -> Effort row -> opened ladder -> select Max -> re-verify.moveEffortSliderToMaxTier: root-cause?? statehardening +final_fresh_recheckguard (only rescues verified Max/Pro/Max-absent, never an unknown label).findEffortSubmenurecognizes by >=2 known ladder labels (nomaxrequirement).pillConfirmsEffortLabelis directional (pill tier >= verified picker tier).service-worker.js— backendmodel_slugno longer overwrites the picker-provenmodel_usedwhen selection was verified; slug captured asmodel_slug.chatgpt_web.rs(CDP) —effortVerifiedladder-aware (Ultra verifies, never downgraded; Extra High gated on Max-absent);is_verified_sol_extra_high_selectiontrusts"GPT-5.6 Sol Ultra".Rename
gpt-5-6-sol-extra-high->gpt-5-6-sol-account-maxacross Rust + JS.CLI —
model_slugadded toChatgptRecipeDiagnostics+parse_recipe_result+ JSON output (7p3.2 observability end-to-end).CLAUDE.md— Browser Architecture first bullet rewritten per ruling.Tests
cargo test -p yoetz --bin yoetz-> 653 passed, 0 failed, 2 ignored (require Chrome)node --test tests/*.test.js-> 404 passed, 0 failedcargo fmt --checkcleancargo clippy -p yoetz --bin yoetzclean (no warnings)New fixtures: six-tier ladder (from the live failure dump verbatim), stale-Extra-High -> selects Max, Max-unverifiable fail-closed, preset-Ultra accepted, five-tier-submenu Max-absent accepts Extra High, slider unknown-ceiling not rescued by
final_fresh_recheck, unawaited-waitForEffortSubmenuregression guard, directional pill-corroboration negatives.After merge
Release via
./scripts/release.shfrommain(CHANGELOG## [Unreleased]already populated). The managed extension re-syncs viayoetz browser extension update --chatgptafter release.