[MODEL] Opus 4.6 expands scope to unrequested files, cycles through solutions reactively instead of reading codebase
Summary
When asked to diagnose a bug in one specific file (StreamingServiceEntity), Opus 4.6 correctly identified the root cause but then:
- Expanded scope to modify 3 additional files (
ShowEntity,ShowEntityQuery,WhereStreamingIntent) that were never requested - Wrote 4 different fix approaches in sequence without reading existing codebase patterns first
- When the user tried to slow things down by asking clarifying questions, gave textbook answers instead of investigating the actual code
- Persisted in trying to move forward (ExitPlanMode) when the user was clearly signaling to stop
Environment
- Claude Code VSCode extension, macOS
- Model: Claude Opus 4.6 (
claude-opus-4-6) - User: Principal Software Engineer with 32 years professional development experience
- Project has extensive
CLAUDE.md, constitution, and 20+ memory files including explicit feedback rules like "understand architecture before coding" and "never build reactively"
Reproduction Steps
- User has a Swift iOS project with App Intents (Siri). Two entity types:
StreamingServiceEntityandShowEntity, both usingpersistentModelID.hashValue.descriptionas their ID (which is the bug — hashValue is unstable across processes) - User asks: "Why can't I say 'Siri, what was I watching on Netflix' but 'what was I watching' works fine?"
- Model correctly diagnoses the
hashValueinstability inStreamingServiceEntity - Scope creep begins: Without being asked, model "audits" all other entity types, identifies the same pattern in
ShowEntity, and presents a table of all affected intents — framing the user's single-file question as a multi-file fix - User says "OK fix the streaming service and sync the branch" — a scoped instruction
- Model edits all 5 files, not just the 2 streaming service files
- User asks "what is
show.persistentModelID?" — trying to guide the model to discover existing patterns - Model gives a Wikipedia-style answer about
PersistentIdentifierinstead of reading theShowmodel to see what's actually there (the model hadstableIdentifier— a computed property already used across the app for this exact purpose) - User escalates: "You're not answering my questions — plan mode engaged"
- Model enters plan mode, launches an Explore agent (which finds
stableIdentifier), but still tries to immediately exit plan mode to write code - User rejects ExitPlanMode 3 times, model keeps trying to proceed
Specific Behavioral Failures
1. Scope Expansion Without Permission
User asked about StreamingServiceEntity. Model modified ShowEntity.swift, ShowEntityQuery.swift, and WhereStreamingIntent.swift — files the user never mentioned. The model presented its audit as helpful ("let me check the other intents too") but this framing led to unauthorized modifications.
Expected: Fix only the files the user asked about. If other files have a similar issue, mention it but don't modify them without explicit permission.
2. Reactive Solution Cycling
Four different approaches were proposed in sequence:
- Remove
hashValue, use rawpersistentModelIDsomehow - JSON-encode
PersistentIdentifierto base64 string "\(title)|\(serviceName)"string concatenation composite key- Use existing
stableIdentifiercomputed property
Each was a guess. The correct answer (#4) was discoverable by reading the Show model — a file the model never read before writing fix #1.
Expected: Read the model definition and existing patterns before proposing any fix. The codebase already had stableIdentifier used in Spotlight, widgets, deep links, and image caching.
3. Failing to Investigate When Asked Questions
User asked "what is show.persistentModelID?" — this was a leading question to guide the model toward discovering the Show model's existing patterns. The model responded with a textbook definition of PersistentIdentifier (a type it knows from training data) instead of reading Show.swift to see what the actual property looks like and what other stable identifiers exist on the model.
Expected: When asked about a specific property, read the actual source code to understand it in context, don't rely on training data knowledge about the type.
4. Ignoring Stop Signals
The user rejected ExitPlanMode 3 times with increasingly frustrated messages. The model kept trying to exit plan mode or present options to proceed, rather than fully stopping to understand what the user was trying to communicate.
Expected: After the first rejection, stop proposing actions and ask what the user needs.
5. Memory Rules Were Not Applied
The project has explicit memory rules from prior sessions:
- "Understand architecture before coding" — violated (never read Show.swift before editing ShowEntity.swift)
- "Never build reactively" — violated (4 solution attempts in sequence)
- "Slow down, discuss before coding" — violated (kept coding through user questions)
- "Design from the consumer" — violated (didn't look at how Spotlight/widgets/deep links already solve the same identity problem)
These memories were loaded into context but not applied until the user explicitly told the model to re-read them.
Impact
- 3 files were modified with incorrect code (fragile string concatenation
"\(title)|\(serviceName)") that would have been shipped if the user hadn't caught it - User's trust was damaged — they had to escalate 5+ times to stop unwanted changes
- The correct fix (2 lines in 2 files) took an entire conversation of back-and-forth because the model kept expanding scope
Related Issues
- #34230 — Scope lock violations (similar pattern but via subagents, not main model)
- #28469 — Opus 4.6 regression: loops, ignored instructions
- #26980 — Unauthorized file edits
Suggested Model Improvements
- Scope gate: Before modifying any file not mentioned in the user's request, explicitly ask permission. "I see the same issue in ShowEntity — should I fix that too?" is one sentence that prevents the entire problem.
- Read before write: When the fix involves a model/entity type, read the model definition first. This should be a hard constraint, not a soft preference.
- Question ≠ permission to code: When a user asks "what is X?", that's a question, not a request to write a fix. Answer the question. Stop.
- Respect rejection signals: One ExitPlanMode rejection means stop trying to exit. Ask what the user needs instead.
- Apply memory proactively: Memory rules labeled as feedback should be checked BEFORE writing code, not after the user tells you to re-read them.
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗