fix(e2e): purge FakeSAENormal and instantiate real Cognitive Stack #5
Reference in New Issue
Block a user
Delete Branch "fix/e2e-deception-purge"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Replace the old dual-path orchestrator (abstract goals vs legacy desires) with unified GoalDecomposer-driven task routing: 1. GoalDecomposer reads mission.strategy + plugins config 2. Generates weighted Task objects (verb, target_screen, budget) 3. GrowthBrain.select_task() picks one probabilistically 4. Selected Task's target_screen routes through existing nav_graph 5. Feed loops + PluginRegistry handle the actual interactions The abstract goals path (goal_executor.achieve('Nurture community')) that caused infinite scrolling is now eliminated entirely. Legacy desire fallback preserved for configs without plugins. 22/22 tests passing.Bug 1 — VLM Profile Tab Hallucination: - VLM confused 'Profile' nav tab with post author username - Added Author Tab Guard to filter_navigation_conflicts() - Fixed mock LLM to use structural row_feed_photo_profile matching instead of hardcoded username (was the test lie) Bug 2 — Like Button 1-Byte Delta Kill: - Toggle actions (like/save) produce 1-byte XML deltas - GOAP's MIN_UI_CHANGE_BYTES=50 threshold killed them as 'no change' - Split interaction gate: interactions use ANY xml diff, navigations keep the 50-byte threshold Bug 3 — Empty Username Silently Accepted: - PostDataExtraction returned 'Post by @' with no warning - Added 'username_missing' reliability flag to result dict - Downstream consumers can now detect degraded data quality Cleanup: - Removed all debug print() statements from production code - Replaced with structured logger.debug() callsTwo critical test additions: 1. test_system_full_lifecycle.py — Full A-to-Z integration test: Exercises the ENTIRE bot pipeline across 4 screen types (HomeFeed → Explore → Post Detail → Profile) with a real InstagramEmulator state machine. Validates plugin execution, session state accumulation, cognitive stack survival, dopamine session timeout, and post-session serialization. This is the single most important test in the suite. 2. test_system_coverage_gate.py — Critical Path Coverage Enforcement: Reads coverage_e2e.json and enforces minimum coverage thresholds on production-critical modules. Each threshold is tied to a real production incident. If persistent_list.py drops below 20% coverage, the build fails — because that's exactly how the sessions.json corruption bug went undetected. Usage: pytest tests/e2e --cov=GramAddict.core \ --cov-report=json:coverage_e2e.json Critical paths enforced: - session_state.py (>=50%): serialization crash prevention - persistent_list.py (>=20%): persist() path must be tested - dopamine_engine.py (>=40%): session timeout logic - screen_identity.py (>=60%): screen identification - spatial_parser.py (>=70%): UI element parsing - intent_resolver.py (>=50%): click decision logic - q_nav_graph.py (>=25%): navigation integrity - device_facade.py (>=40%): device interfaceValidates the deterministic processing logic around the VLM without needing a real LLM. Five contracts covering the full perception stack: 1. VLM Response Parsing (20 parametrized formats): Tests _parse_yes_no against every response format observed in production: clean YES/NO, JSON variants, explanations, edge cases (now/not/nothing), empty strings, free-form JSON. Documents the startswith('yes') early-exit behavior for ambiguous responses. 2. Box Index Extraction (7 formats): Validates JSON parsing of VLM box selections across all observed key variants: 'box', 'selected_index', 'box_index', 'index', null, and out-of-range values. 3. Structural Guards (11 tests): Tests every hallucination prevention guard in IntentResolver: - Tab intent excludes Back button (bug 2026-04-30) - Back intent preserves Back button - Tab height guard (y > 85% screen) - Author intent excludes nav tabs (bug 2026-05-01) - Structural fast-paths (message input, send, author, comment) - Abstract goals return None - Semantic quoted-target guard 4. Semantic Match Validation (10 tests): Prevents memory poisoning via _intent_matches_node: - Correct matches (follow/like/save + German locale) - Poisoning attempts: Reel thumbnails, photo content, comments - Non-toggle intents always pass through 5. ActionMemory Lifecycle (7 tests): Full track → confirm/reject cycle with FakeUIMemoryDB: - Correct follow stores in memory - Poisoned follow is BLOCKED (production bug reproduction) - Rejected click triggers confidence decay - No-track confirm is noop - Mismatched intent is ignored - Follow/view-post structural verificationCONTRACT 6: extract_json() — LLM Response Sanitizer (9 tests) Previously COMPLETELY untested. Every single LLM response in the entire system passes through this function. Tests: - Clean JSON, markdown fences (json+plain), thinking block purge - Text prefix before JSON, truncated JSON fuzzy recovery - Garbage/empty/None resilience CONTRACT 7: _visual_discovery Pre-Filters (8 tests) The guards INSIDE _visual_discovery() that run BEFORE the VLM ever sees the candidates. If they fail, the VLM gets garbage and hallucinates. Tests: - Area filter: tiny nodes (<200px²) and huge containers (>400000px²) - SystemUI filter: Android system elements, notifications, battery - Strict Button Guard: long text captions excluded for button intents - Grid Item Guard: non-grid elements excluded, fallthrough on no match - Author/Username Guard: nav tabs excluded for author intents CONTRACT 8: verify_success Structural Delta (8 tests) The post-click verification logic that decides if a click actually worked. Tests: - Toggle massive XML shift = navigation error (False) - Toggle small diff = success (True) - Toggle zero diff = inconclusive (None) - Follow success with 'Requested' marker (private accounts) - Follow success with German locale ('Abonniert') - View post with clips_viewer marker (Reels) - View post still on grid = inconclusive (None) - Semantic gate blocks wrong toggle element (caption != like button)Production bug 2026-05-02 22:19: Intent 'post author username text (exclude bottom tabs)' contained the word 'tab' in its parenthetical qualifier. The old check: is_tab_intent = 'tab' in intent_lower matched this intent as a TAB navigation intent, activating the Tab Height Guard which excluded ALL nodes with center_y < 85% of screen. This nuked the actual clips_author_username node at y=2012, leaving only 4 irrelevant items for the VLM → bot stuck in a loop unable to find the author username. Fix: Replace substring match with precise regex patterns that only match real tab navigation intents: - 'tap profile tab', 'tap home tab' (tap + word + tab) - 'profile tab', 'explore tab' (word + tab) - 'tab ...' at start of intent TDD: Red test added first, reproducing exact production state. 81 perception tests + 172 total tests pass.4bc9183901to5fbbe3d273View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.