ROOT CAUSE: qwen3.5 (reasoning model) returns response='' with thinking
block containing all reasoning. llm_provider.py line 352 silently
substituted the thinking block as the response via:
content = raw_response or raw_thinking or ''
The Brain then extracted random actions from the reasoning text.
FIXES:
1. llm_provider.py: Conditional thinking isolation
- format_json=True (SAE/perception): thinking fallback preserved
- format_json=False (Brain): thinking NEVER substituted
- Added think=false for Ollama free-text calls to force direct response
2. planner.py: No-Op Guard strips tab actions that navigate to
the current screen (e.g. 'tap profile tab' on OWN_PROFILE)
3. test_brain_live.py: Stochastic testing (5 runs, 60% min valid)
to handle non-deterministic LLM behavior reliably
4. tests/integration/test_llm_provider_pipeline.py: NEW test layer
mocking at HTTP level (requests.post) to exercise the FULL
llm_provider → Brain pipeline. This would have caught the
thinking substitution bug from day one.
Suite: 168 passed, 0 failed