Fix stale auto-fallback origin model selection#92819
Conversation
|
Codex review: needs maintainer review before merge. Reviewed July 1, 2026, 1:05 AM ET / 05:05 UTC. Summary PR surface: Source +366, Tests +527. Total +893 across 11 files. Reproducibility: yes. at source level. Current main rejects auto-fallback rows whose stored origin differs from the active primary, and the linked production report plus PR proof cover the runtime stale-origin shape. Review metrics: 1 noteworthy metric.
Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Land this guarded stale-origin cleanup, or an equivalent maintainer-approved fix, and let the linked issue close after merge while keeping broader fallback policy work separate. Do we have a high-confidence way to reproduce the issue? Yes, at source level. Current main rejects auto-fallback rows whose stored origin differs from the active primary, and the linked production report plus PR proof cover the runtime stale-origin shape. Is this the best way to solve the issue? Yes. The shared predicate plus deferred/exact-row cleanup covers both reply and direct command surfaces without a broad migration or a second source of truth. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against d68ba5edc598. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +366, Tests +527. Total +893 across 11 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
30bd429 to
a439e64
Compare
a439e64 to
ebe706b
Compare
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
ebe706b to
519c178
Compare
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
519c178 to
bc3d129
Compare
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
6b7803e to
239ae36
Compare
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
Updated the PR body with redacted runtime/session proof from an isolated @clawsweeper re-review |
|
🦞👀 Command router queued. I will update this comment with the next step. |
239ae36 to
844c625
Compare
|
Rebased onto current Proof update:
Validation:
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
This pull request has been automatically marked as stale due to inactivity. |
|
Closing due to inactivity. |
Summary
/model ...directives and concurrent row updates are not overwritten.Maintainer feedback addressed
What Problem This Solves
Stale auto-fallback model pins whose recorded fallback origin no longer matches the current primary were being treated as active stored overrides. That could make the next real agent run continue using an old
fallback-modeland stale auto auth instead of the currentprimary-model.This patch prepares the primary selection for the next real run and defers durable cleanup until the run boundary without overwriting user-owned, newer auto-owned, or exhausted-run model/auth state.
Evidence
origin/maind68ba5edc59, PR head844c625a8a0e99bc7de934c286fbdd105d5cec39.oxfmt --check,pnpm tsgo:prod,pnpm check:test-types, extension package boundary compile for 116 plugins,pnpm build, andgit diff --check origin/main...HEADpassed.Redacted runtime/session proof
I also ran a real
openclaw agent --localturn on this rebased PR head using a throwawayOPENCLAW_STATE_DIR, a synthetic session row, and a local OpenAI-compatible test endpoint. No production config, production session store, production auth profile, or external provider was used.The seeded session row contained a stale auto fallback pin:
{ "providerOverride": "proof-local", "modelOverride": "fallback-model", "modelOverrideSource": "auto", "modelOverrideFallbackOriginProvider": "proof-local", "modelOverrideFallbackOriginModel": "old-primary-model", "authProfileOverride": "proof-local:auto-fallback", "authProfileOverrideSource": "auto" }The real CLI run completed successfully and sent exactly one streamed model request to the local endpoint:
{ "head": "844c625a8a0e99bc7de934c286fbdd105d5cec39", "isolatedStateDir": "<temp OPENCLAW_STATE_DIR>", "localEndpoint": "<127.0.0.1 OpenAI-compatible test server>", "cliExit": 0, "stdoutContainsProofToken": true, "requests": [ { "method": "POST", "url": "/v1/chat/completions", "model": "primary-model", "stream": true, "messageCount": 2, "toolCount": 39 } ], "after": { "modelProvider": "proof-local", "model": "primary-model" }, "assertions": { "requestedPrimaryModel": true, "neverRequestedFallbackModel": true, "staleModelOverrideCleared": true, "staleAutoAuthCleared": true, "replyObserved": true } }That proves the stale fallback row was not reused for the next real run: the request went to
primary-model, no request went tofallback-model, and the persisted session row no longer contains the stale model/auth override fields.Verification
node scripts/run-vitest.mjs src/agents/agent-command.live-model-switch.test.ts src/auto-reply/reply/model-selection.test.ts(passed: 2 shards, 133 tests)node scripts/run-vitest.mjs src/auto-reply/reply/get-reply-directives-apply.test.ts(passed: 3 tests)pnpm exec oxfmt --check --threads=1 src/agents/agent-command.ts src/agents/agent-command.live-model-switch.test.ts src/agents/auto-fallback-stale-origin.ts src/auto-reply/reply/model-selection.ts src/auto-reply/reply/model-selection.test.ts src/auto-reply/reply/get-reply-directives-apply.ts src/auto-reply/reply/get-reply-directives-apply.test.ts src/auto-reply/reply/get-reply-directives.ts src/auto-reply/reply/get-reply.test-fixtures.ts src/auto-reply/reply/get-reply.ts src/commands/agent-command.test-mocks.tspnpm tsgo:prodpnpm check:test-typespnpm run test:extensions:package-boundary:compilepnpm buildgit diff --check origin/main...HEADFixes #92776
Supersedes #92790