Private
Public Access
0
0
Files
manual_slop/docs/superpowers/plans/2026-06-05-undo-redo-lifecycle-fix.md

5.3 KiB

undo_redo_lifecycle_fix_20260605 Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Resolve the test_undo_redo_lifecycle failure. Phase 1: verify state-sync fix is sufficient. Phase 2: investigate snapshot mechanism if needed. Phase 3: flake-fix with polling if needed.

Architecture: Sequential investigation. Cheapest fix first.

Tech Stack: Python 3.11+, pytest 9.0.


File Structure

File Change Purpose
(Phase 1) None
(Phase 2) src/history.py, src/gui_2.py, tests/test_undo_redo_ai_input_snapshot.py Possibly modify Fix snapshot if it doesn't include ai_input
(Phase 3) tests/test_undo_redo_sim.py Possibly modify Replace time.sleep with polling

Task 1: Phase 1 — Run the test, see if it passes after the state-sync fix

Files: (no changes; verification)

  • Step 1.1: Run the test in isolation
cd C:\projects\manual_slop; uv run pytest tests/test_undo_redo_sim.py::test_undo_redo_lifecycle -v --timeout=60

Expected outcomes:

  • A) PASSES → Done. The state-sync fix is sufficient. Skip to Task 4 (documentation).

  • B) FAILS → Proceed to Task 2 (Phase 2: investigate snapshot).

  • Step 1.2: Document the outcome

If passes: commit a doc-only note confirming state-sync fixed it.

cd C:\projects\manual_slop; git -c core.autocrlf=false commit --allow-empty -m "verify: undo_redo_lifecycle passes after state-sync fix"
$h = git -C C:\projects\manual_slop log -1 --format='%H'
git -C C:\projects\manual_slop notes add -m "Confirmed: the ui_ai_input property delegation in live_gui_state_sync_20260605 fixes test_undo_redo_lifecycle. The snapshot reads app.ui_ai_input (now delegated to controller.ui_ai_input where the value lives) and captures the right value. Undo restores correctly." $h

If fails: proceed to Task 2.


Task 2: Phase 2 — Check the snapshot mechanism for ai_input

Files: (read-only; possibly modify later)

  • Step 2.1: Read UISnapshot definition

Read src/history.py to find the UISnapshot dataclass. List its fields.

cd C:\projects\manual_slop; uv run python -c "
import re
with open('src/history.py', 'r', encoding='utf-8') as f:
    content = f.read()
m = re.search(r'class UISnapshot', content)
if m:
    print(content[m.start():m.start()+500])
"
  • Step 2.2: Check if ai_input is a field

  • A) ai_input is a field → Task 3: check _apply_snapshot for restore line.

  • B) ai_input is NOT a field → Add it. See Step 2.3.

  • Step 2.3: If ai_input is missing from UISnapshot, add it

Add ai_input: str = "" to the UISnapshot dataclass.

In src/gui_2.py:_take_snapshot (line 551), add ai_input=self.ui_ai_input,.

In src/gui_2.py:_apply_snapshot (line 569), add self.ui_ai_input = snapshot.ai_input.

Commit:

cd C:\projects\manual_slop; git add src/history.py src/gui_2.py
git -C C:\projects\manual_slop commit -m "fix(gui_2): add ai_input to UISnapshot for undo/redo round-trip"
$h = git -C C:\projects\manual_slop log -1 --format='%H'
git -C C:\projects\manual_slop notes add -m "Add ai_input field to UISnapshot (src/history.py), capture in _take_snapshot, restore in _apply_snapshot. The undo/redo system was silently dropping ai_input changes; this fixes test_undo_redo_lifecycle." $h
  • Step 2.4: Run the test
cd C:\projects\manual_slop; uv run pytest tests/test_undo_redo_sim.py::test_undo_redo_lifecycle -v --timeout=60

Expected: 1 passed.

If still fails → proceed to Task 3 (Phase 3: flake-fix with polling).


Task 3: Phase 3 — Test-ordering / flake investigation

Files:

  • Modify: tests/test_undo_redo_sim.py (replace time.sleep with polling)

  • Step 3.1: Add the polling helpers (or import from wait_for_ready track)

import time

def wait_for_value(client, item, expected, timeout=5.0):
    deadline = time.time() + timeout
    while time.time() < deadline:
        if client.get_value(item) == expected:
            return
        time.sleep(0.1)
    raise TimeoutError(f"Item '{item}' did not become {expected!r} within {timeout}s")
  • Step 3.2: Replace the time.sleep calls

  • Step 3.3: Run the test

  • Step 3.4: Commit

cd C:\projects\manual_slop; git add tests/test_undo_redo_sim.py
git -C C:\projects\manual_slop commit -m "test(undo_redo): replace time.sleep with wait_for_value polling"

Task 4: Update tracks.md

Files:

  • Modify: conductor/tracks.md

  • Step 4.1: Add a note about the outcome

cd C:\projects\manual_slop; git add conductor/tracks.md
git -C C:\projects\manual_slop commit -m "conductor: undo_redo_lifecycle sub-track complete"

Self-Review

  • Spec coverage: 3-phase sequential investigation. State-sync fix may resolve it (Phase 1). If not, snapshot investigation (Phase 2). If not, flake-fix (Phase 3).
  • Placeholders: None.
  • Type consistency: ai_input: str matches the existing type.
  • Risk: Low — only investigation + minimal source change.

Execution Handoff

Inline execution. Up to 4 tasks; some may be skipped depending on the outcome of Phase 1.