Repository navigation
Move saved Opus 5.5 settings to Sonnet 5.5 (data migration, after #164) - #180
Conversation
New Pro accounts start on Sonnet 5.5. Auto Pro routes between Sonnet 5.5 and GPT-6.1 Sol and falls back to Sonnet, so it never picks Opus. Opus runs only when someone selects it. Retired Opus IDs still move to Opus 5.5, since those were explicit picks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Opus 5.5 was the Pro default, and a saved setting can't tell the default from a pick. This data migration moves every saved Opus 5.5 tool setting to Sonnet 5.5, backs the original rows up in private.opus_default_backup, and skips users it has already migrated. A rollback script restores Opus wherever the migrated Sonnet is still saved. A database test runs both twice against seeded rows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Review limit reachedEnable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. Next included review available in 29 minutes. View limit details
Note 🎁 Summarized by CodeRabbit Free
Comment |
|
The GitHub Actions failures on 220b367 never ran the code. Each job stopped within 2 to 3 seconds with "The job was not started because recent account payments have failed or your spending limit needs to be increased", which is the repo-wide billing block. Local results at 220b367: |
The test now seeds a tool already on Sonnet before the migration, which the rollback must keep, and an old updated_at, so it fails if the migration stops bumping it. Clients only save their settings cleanup while updated_at is unchanged, so the bump keeps an older client from writing Opus back. agent-stack.sh test now runs the script too, like npm run test:db. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Deployment failed for project debatelab-staging with the following error: Learn More: https://vercel.com/adam-gaborjanis-projects?upgradeToPro=build-rate-limit |
|
Review-only Opus pass on 220b367 found no high or medium defects. Four low findings, all checked against the code:
|
|
Checks on 8ca1e46: the GitHub Actions jobs stopped after 2 to 3 seconds because of the same billing block, so none of them ran the code. |
# Conflicts: # .claude/skills/verify-debatelab/features/model-defaults.md # supabase/functions/_shared/model-catalog.ts
|
Deployment failed for project debate-navigator with the following error: Learn More: https://vercel.com/adam-gaborjanis-projects?upgradeToPro=build-rate-limit |
#180 added 20261022120000_opus_default_to_sonnet.sql, so the refund migration's identical version failed to apply after the merge from main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Codex review (gpt-6.1-sol, xhigh) of 9565d73 compared the code with
Current status: staging-sync applied this migration to staging at bf4c34e. Production has not had it applied. Vercel rate-limited every production frontend deploy since #164, so production still serves the frontend from before #164, and the migration has to wait for it (step 1). |
…185) * Run Claude only on the Anthropic BYOK key, with no fallback provider. Every anthropic/* call now asks OpenRouter for the anthropic provider only, with fallbacks off, so Bedrock, Vertex and other providers are never tried. Other models keep balanced routing. A refused Claude call returns a 503 outage message the client already translates, logs claude_unavailable, and gives the reserved daily request back through a new refund_daily_quota RPC. A Claude response whose usage shows is_byok false or a cost above zero logs a claude_not_byok warning. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Refund a failed Claude request only when nothing was written yet. A stream that fails after the model wrote text, or a repair retry after a completed attempt, already spent tokens on the key, so the request stays counted. The student still sees the outage message. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep paid research out of Claude refunds and stop the Ask double attempt. From the Opus review of #185: - A request whose research steps already ran on Claude keeps its quota. - Ask no longer resends a provider_unavailable stream failure through the plain endpoint, which tried Claude a second time on a failing key. - ai-stream refunds before it sends the error, so an immediate retry sees it. - Sparring shows the translated provider message instead of the raw one. - Tests cover no refund on success, on a non-Claude failure, after a completed repair attempt, and after research. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Let a quota refund give back more than one unit. refund_daily_quota takes p_units (default 1, the reservation every AI request makes today) and never goes below zero. Once the weighted quota in #178 lands, the refund can return what consume_ai_quota reserved for the model. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Give the refund migration its own version. #180 added 20261022120000_opus_default_to_sonnet.sql, so the refund migration's identical version failed to apply after the merge from main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Refund the weighted units consume_ai_quota reserved, and keep refunds out of the weekly cap. #178 reserves each request's weight (Opus 5, Sonnet 2, others 1; Auto Pro 5) through consume_ai_quota. A refunded Claude failure now gives back the same units checkRateLimit reserved, taken from its RateLimitResult, and logs cap_cost_usd 0 so it does not count toward the weekly $2 either. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Never refund a Claude failure OpenRouter already charged credits for. Zeroing cap_cost_usd on such a row would hide real spend from the weekly cap, so a request with a charge against the cap now keeps both its quota and its cap cost. Only free failures are refunded and logged with cap cost 0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Refund research tools in a Claude outage too. Research steps run on Haiku, so in an outage they are refused along with the main call. Such a refusal did no paid work and no longer blocks the refund; a research step that finished or was charged still does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Bill usage on a stream's error frame, and never refund a cancelled request. From Codex review round 2 of #185: - Both stream readers threw on an error frame before reading its usage, so a charge reported only there was dropped, and the failure could then be refunded with cap cost 0. Usage is now kept before the error is thrown. - ai/index.ts refunded a Claude refusal that raced a client abort. ai-stream already refused that; the plain handler now does too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
|
Status: the migration was applied to production on 2026-10-22 at 16:38:59 Budapest (14:38:59 UTC) and is live. Production's Edge Functions are already newer than this PR's commit. The apply steps in the description are now marked done and kept as a record. Don't re-apply the migration or redeploy anything for this PR. |
Follow-up to #164. Opus 5.5 was the Pro default, so most Pro accounts still have it saved for every tool. A saved setting can't tell the old default from a deliberate pick, so this data migration moves every saved Opus 5.5 tool setting to Sonnet 5.5. Opus stays in the picker, and anyone can choose it again.
Do not merge before #164. This PR targets
cost/sonnet-pro-default. Once #164 is merged, retarget it tomain.What the migration does
supabase/migrations/20261022120000_opus_default_to_sonnet.sql:user_settingsrow, it changes every tool entry infeature_configswhosemodelis exactlyanthropic/claude-opus-5.5toanthropic/claude-sonnet-5.5. Other fields (reasoning effort, provider) and other tools stay as they are.feature_configsinto a new server-only table,private.opus_default_backup, before the update. The table has RLS on and no client grants, and its rows are deleted with the account.anthropic/claude-opus-5, which the client maps to Opus 5.5 as an explicit pick), empty settings, or malformed values.It covers every account with Opus 5.5 saved, not only accounts that are Pro right now. Pro access depends on the clock and on Stripe rows, so SQL can't check it reliably. For a Basic or lapsed account the change has no visible effect, because the client already shows Haiku for any Pro-only model. If that account becomes Pro again, it starts on Sonnet rather than Opus.
Rollback
supabase/rollbacks/20261022120000_opus_default_to_sonnet.down.sql. It isn't insupabase/migrations, sodb pushnever runs it. It sets a tool back to Opus 5.5 only where the migration changed that tool from Opus to Sonnet and the tool still holds Sonnet. Changes a user made after the migration stay. It then empties the backup table, so a second run does nothing. It contains noDROP. The rollback needsprivate.opus_default_backup, so keep that table until it's clear no rollback will be needed; dropping it is a separate decision.To roll back: copy the file into
supabase/migrations/under a new timestamp, open a PR, and apply it like any other migration. This follows the forward-corrective approach indocs/operations.md.Order and apply steps
Done. Do not re-apply or redeploy. The migration was applied to production on 2026-10-22 at 16:38:59 Budapest (14:38:59 UTC) and is live. Production's Edge Functions are already newer than this PR's commit. The staging-sync timer applied it to staging earlier, at bf4c34e. A second run would change nothing, but don't run it again.
The steps below are kept as a record of how it was meant to go out.
main, never from this PR's merge commit, which lacks later migrations. Before pushing, read the fullbackend:statuspending list. Use--include-allfor both the dry run and the push only when production already has a migration newer than20261022120000.private.opus_default_backupholds one row per account that was moved, and no saved tool setting holdsanthropic/claude-opus-5.5.Edge Functions are a separate step from this migration and come only from the newest reviewed
main. Never deploy them from #164's or this PR's commit, because later PRs changed them.Known limitation
The client writes all six tool settings at once, without checking
updated_at, whenever someone changes a setting or the theme. It can therefore write Opus back for the other tools when its in-memory settings are older than the migration:The client's own one-off settings cleanup does check
updated_at, and the migration bumpsupdated_at, so that path can't write Opus back. The rollback leaves rows written back this way alone, because those tools no longer hold the migrated Sonnet. Closing the gap would need a client change; this PR doesn't make one.Verification (local; GitHub Actions is down repo-wide)
./.superset/db-gate.sh --db-only: all pgTAP tests passed (including account deletion and server-only table grants), plus the database scripts.scripts/test-opus-default-migration.sh, now part ofnpm run test:db, seeds six accounts: all Opus, mixed tools, retired Opus ID, never saved, Basic with Opus, and a malformed value. It runs the migration, runs it again after one user picks Opus again, changes settings, then runs the rollback twice. It checks every row after each step, and everything runs in one transaction that is rolled back.updated_at. Two more deliberate breaks now fail it: a rollback without the "was Opus before" check fails "a tool already on Sonnet before it is kept", and a migration without theupdated_atbump fails "migrated rows get a new updated_at". At 8ca1e46 the full database set (pgTAP plus all database scripts) passed on a privatescripts/agent-stack.shstack, which now also runs this test.npm run docs:checkandnpm run lint(including the repo rules) passed.🤖 Generated with Claude Code