# Work Plan: Sprint 8a — Fix Bundle (trace_flow Local Calls + Visual Verification Prompt)

**Created**: 2026-03-06
**Status**: Not Started
**Scope**: Small (~50 lines Python, ~30 lines prompt, 1 fixture, 5 new tests)
**Strategy**: Implementation-First (Strategy B) — no test design information provided

---

## Overview

Two independent fixes bundled into one sprint:

1. **Fix 1**: `trace_flow` misses intra-file (local) function calls. Only signal emissions and autoload method calls are followed. Direct `self.func()` / `func()` calls within the same script are invisible.
2. **Fix 2**: After 3D placement/move operations, the agent has no prompt instruction to visually verify results. A mandatory visual verification workflow section is needed in the system prompt.

---

## Phase Structure Diagram

```mermaid
graph TD
    subgraph "Phase 1: Fixture & Prompt (parallel, no deps)"
        T1["Task 1: Create chained_manager.gd fixture"]
        T4["Task 4: Add visual verification to prompt"]
    end

    subgraph "Phase 2: Core Implementation"
        T2["Task 2: Add _find_local_calls + integrate into _trace_from_function"]
    end

    subgraph "Phase 3: Tests & Quality Assurance"
        T3["Task 3: Add 5 local call tracking tests"]
    end

    T1 --> T2
    T2 --> T3
    T4 -.-> T3

    style T1 fill:#e8f5e9
    style T4 fill:#e8f5e9
    style T2 fill:#fff3e0
    style T3 fill:#e3f2fd
```

## Task Dependency Diagram

```mermaid
graph LR
    T1["Task 1: Fixture"] --> T2["Task 2: Implementation"]
    T2 --> T3["Task 3: Tests + Quality Gate"]
    T4["Task 4: Prompt"] --> T3

    T1 -.- T4

    linkStyle 3 stroke-dasharray:5
```

**Legend**: Solid arrows = hard dependency. Dashed line = can run in parallel (no dependency).

---

## Phase 1: Foundation (Fixture + Prompt)

> Tasks 1 and 4 have no dependencies and can be executed in parallel.

### Task 1: Create fixture file `chained_manager.gd`

- [ ] **Confirm skill constraints**
- [ ] Create `tests/fixtures/trace_flow/chained_manager.gd` with:
  - `class_name ChainedManagerClass` extending `Node`
  - `signal task_completed(task_id: String)`
  - `accept_item(item_id)` calls `_process_item(item_id)`
  - `_process_item(item_id)` calls `_create_task(item_id)`
  - `_create_task(item_id)` emits `task_completed`
- [ ] Verify fixture loads in a `GodotIQSession` (parsed without errors)
- [ ] **Verify skill fidelity**

**Completion Criteria**:
- File exists at `tests/fixtures/trace_flow/chained_manager.gd`
- GdScript parser extracts 3 functions (`accept_item`, `_process_item`, `_create_task`)
- GdScript parser extracts 1 signal (`task_completed`)
- GdScript parser extracts 1 signal emission (`task_completed` in `_create_task`)
- Existing 835+ tests still pass

**Files**:
| File | Action |
|------|--------|
| `tests/fixtures/trace_flow/chained_manager.gd` | CREATE |

---

### Task 4: Add mandatory visual verification to prompt

- [ ] **Confirm skill constraints**
- [ ] Add "MANDATORY: Visual Verification After 3D Changes" section to `src/godotiq/prompts/godot_development.md` after the tool list (after line ~12, before "Mandatory Workflows")
  - 5-step verification loop: focus_node, screenshot, evaluate, adjust, save
  - List of triggering operations (move, scale, add_child, reparent, placement)
- [ ] Add "Spatial Operations Workflow (ALWAYS follow this)" section with 6-step workflow
- [ ] Review: new sections are prominent and come before other workflows
- [ ] **Verify skill fidelity**

**Completion Criteria**:
- `godot_development.md` contains "MANDATORY: Visual Verification After 3D Changes" section
- `godot_development.md` contains "Spatial Operations Workflow" section
- Sections appear near the top of the file (before or at the start of the Mandatory Workflows block)
- No existing content deleted or broken
- Existing 835+ tests still pass

**Files**:
| File | Action |
|------|--------|
| `src/godotiq/prompts/godot_development.md` | MODIFY |

---

## Phase 2: Core Implementation

### Task 2: Add `_find_local_calls()` helper and integrate into `_trace_from_function()`

- [ ] **Confirm skill constraints**
- [ ] Add `_find_local_calls()` helper function to `src/godotiq/tools/flow/__init__.py`:
  - Signature: `_find_local_calls(script: GdScript, func: GdFunction, file_path: str, project_root: Path, file_lines_cache: dict[str, list[str]]) -> list[str]`
  - Collects all function names in the script: `{f.name for f in script.functions}`
  - Gets source lines for function body via `_get_file_lines()` (between `func.line` and `func.end_line`)
  - Regex pattern `(?:self\.)?(\w+)\s*\(` to find function calls
  - Only matches names that exist in `all_func_names` and are not the current function
  - Skips comment lines (lines starting with `#` after strip)
  - Returns deduplicated list
- [ ] Integrate into `_trace_from_function()` after existing signal and autoload recursion (after line 270):
  - Call `_find_local_calls(script, func, file_path, project_root, file_lines_cache)`
  - For each local call found, recursively call `_trace_from_function()` with same `file_path` and the called function name
  - Append `self.<name>` entries to `step.calls` for visibility in the output
  - Extend `all_steps` and `all_failures` with sub-results
- [ ] Verify manually: `_find_local_calls` on `chained_manager.gd`'s `accept_item` returns `["_process_item"]`
- [ ] Verify: existing 835+ tests still pass (no regressions)
- [ ] **Verify skill fidelity**

**Completion Criteria**:
- `_find_local_calls()` function exists and is correctly implemented
- `_trace_from_function()` recurses into local calls after signal and autoload recursion
- Local calls appear in `step.calls` as `self.<name>` entries
- Cycle prevention works (existing `visited` set handles recursive local calls)
- Built-in calls (print, push_error, etc.) are not followed (not in `all_func_names`)
- All existing 835+ tests pass without modification

**Files**:
| File | Action |
|------|--------|
| `src/godotiq/tools/flow/__init__.py` | MODIFY |

**Dependencies**: Task 1 (fixture must exist for manual verification)

---

## Phase 3: Tests and Quality Assurance

### Task 3: Add 5 local call tracking tests and run full quality gate

- [ ] **Confirm skill constraints**
- [ ] Add `_find_local_calls` to the import block in `tests/test_tools/test_trace_flow.py`
- [ ] Add `TestLocalCallTracking` test class with 5 tests:
  - [ ] `test_follows_local_function` — `accept_item()` calls `_process_item()` -> trace includes `_process_item` step
  - [ ] `test_local_call_recursive_chain` — `accept_item()` -> `_process_item()` -> `_create_task()` -> all three in trace
  - [ ] `test_local_plus_signal` — `accept_item()` chain reaches `_create_task()` which emits `task_completed` -> both local calls and signal emission appear
  - [ ] `test_ignores_builtin_calls` — `print()`, `push_error()` not followed (not in trace steps beyond the calling function)
  - [ ] `test_cycle_in_local_calls` — If A() -> B() -> A(), the visited set prevents infinite recursion (trace completes, no error)
- [ ] Run `pytest tests/ -v` — all 835+ existing tests pass
- [ ] Run `pytest tests/ -v` — all 5 new tests pass
- [ ] Verify prompt file renders correctly (no broken markdown)
- [ ] **Verify skill fidelity**

**Completion Criteria**:
- 5 new tests exist in `TestLocalCallTracking` class
- All 5 new tests pass
- All 835+ existing tests pass (zero regressions)
- Test case resolution: 5/5 items
- Unresolved tests: 0

**Files**:
| File | Action |
|------|--------|
| `tests/test_tools/test_trace_flow.py` | MODIFY |

**Dependencies**: Task 1 (fixture), Task 2 (implementation), Task 4 (prompt — for final quality gate)

---

## Complete File Change Summary

| File | Action | Task | Change Description |
|------|--------|------|--------------------|
| `tests/fixtures/trace_flow/chained_manager.gd` | CREATE | T1 | GDScript fixture with 3-function call chain + signal |
| `src/godotiq/tools/flow/__init__.py` | MODIFY | T2 | Add `_find_local_calls()` + integrate local call recursion |
| `tests/test_tools/test_trace_flow.py` | MODIFY | T3 | Add 5 new tests in `TestLocalCallTracking` class |
| `src/godotiq/prompts/godot_development.md` | MODIFY | T4 | Add visual verification + spatial workflow sections |

---

## Risk Assessment

| Risk | Likelihood | Impact | Mitigation |
|------|-----------|--------|------------|
| Regex false positives (matching non-call patterns) | Low | Medium | Filter against `all_func_names`; only local function names matched |
| Infinite recursion in local call chains | Low | High | Existing `visited` set already prevents cycles; test explicitly |
| Regex misses valid call patterns | Medium | Low | Pattern `(?:self\.)?(\w+)\s*\(` covers `func()` and `self.func()` forms |
| Existing test regression | Low | High | Run full `pytest tests/ -v` after each task |
| Comment lines matched as calls | Low | Low | Skip lines starting with `#` after strip |

---

## DO NOT TOUCH

- `godot-addon/` — no GDScript addon changes
- `src/godotiq/parsers/` — parsers are not modified
- Any existing test file that already passes (no modifications to existing tests)

---

## Verification Procedures

### Per-Task Verification
- **Task 1**: `python -c "from godotiq.session import GodotIQSession; from pathlib import Path; s = GodotIQSession(Path('tests/fixtures/trace_flow')); s.load(); print([f.name for f in s._gd_scripts['res://chained_manager.gd'].functions])"`
- **Task 2**: Run `pytest tests/test_tools/test_trace_flow.py -v` — all existing tests pass
- **Task 3**: Run `pytest tests/test_tools/test_trace_flow.py -v` — all tests pass including 5 new ones
- **Task 4**: Visual inspection of `godot_development.md` for correct markdown rendering

### Final Quality Gate
- [ ] `pytest tests/ -v` — ALL 835+ tests pass plus 5 new tests
- [ ] New trace_flow local call tracking tests pass (5/5)
- [ ] Prompt review: visual verification section is prominent and well-formatted
- [ ] No files outside the 4 listed files were modified
claude --dangerously-skip-permissions