Stop Claude Code turns whenever the serving model changes - #458
Merged
Merged
Conversation
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.
Claude Code's model guard recognized only selected family transitions and inspected completed assistant messages. Make the enabled guard stop a turn whenever the serving model differs from the selected model, including Fable 5.1 → Opus 5 / Opus 4.8, other families, and version changes. Detect the change at streamed message start as well as in completed messages and explicit fallback notices.
Reuse the existing context-suffix normalizer: case and supported
[1m]/[2m]suffix differences remain equivalent. Synthetic error messages and native subagent messages do not trigger the parent guard. Keep existing settings and event names compatible.The Claude mapper owns the shared model observation; runtime shutdown now records and broadcasts an interrupted completion so clients stop showing a running turn. Update both locales and the design contract to describe general model changes without asserting a classifier cause, and offer an explicit retry on the reported model when no classifier category is available.
Regression coverage replaces the retired family whitelist test with production-mapper cases, preserves per-turn deduplication, and covers both Opus targets at stream start, subagent isolation, suffix filtering, and interrupted completion delivery to clients. The generalized mismatch, stream-start, suffix-notice, and missing-completion regressions were observed failing before their respective fixes.
Validation performed locally on macOS:
cargo fmt --all --checkcargo clippy --workspace --all-targets --locked -- -D warningscargo build --workspace --lockedcargo test --workspace --locked— 1197 passed, 6 intentionally ignored across reported test groupscargo macheteRUSTFLAGS='-D warnings' IPHONEOS_DEPLOYMENT_TARGET=26.0 cargo check -p tcode-ios --target aarch64-apple-ios-sim --lockedRUSTFLAGS='-D warnings' cargo check -p tcode-web --target wasm32-unknown-unknown --lockedRUSTFLAGS='-D warnings' CARGO_NDK_PLATFORM=26 cargo ndk -t arm64-v8a check -p tcode-android --lockedwith NDK 27.1.12297006Validation gaps: no live-provider reproduction of the original report; narrow-window visual verification was not completed. Linux and Windows execution is left to CI. The local build reports the existing large debug unwind-table linker warning and the dependency
blockfuture-compatibility notice.