conductor(workflow): add Indentation-Driven Class Method Visibility pitfall (2026-06-05)
This commit is contained in:
@@ -425,3 +425,22 @@ In particular, watch for:
|
||||
### Live_gui Test Fragility (Authoring-Side)
|
||||
|
||||
`live_gui` is a session-scoped fixture. All tests in a session share the same `sloppy.py` subprocess. A test that "passes when run after test X but fails in isolation" is a **fragile test, not a fragile fixture**. The fixture is session-scoped by design; the test must explicitly wait-for-ready, reset state via Hook API, and verify preconditions via `get_value`/`wait_for_event` rather than assuming a "clean" ImGui state from a prior test. See [../docs/guide_testing.md](../docs/guide_testing.md#authoring-robust-live_gui-tests-dont-assume-clean-state) for the 5-rule authoring contract with anti-pattern vs pattern code examples. Bisect failures by running the test both in the full suite and in isolation to distinguish "test needs work" from "real app bug".
|
||||
|
||||
|
||||
### Indentation-Driven Class Method Visibility (CRITICAL)
|
||||
|
||||
**The bug:** A class method defined with the right intent (2-space indent) may be parsed as **nested inside the previous function** if indentation is off by even one space. The file "passes" syntactically (imports OK) but the method is **not** on the class. `hasattr(App, 'method_name')` returns `False`. Any production code that calls `app.method_name` falls through to `__getattr__`, which delegates to the Controller (which also doesn't have the method), and a cryptic `AttributeError` is raised at runtime.
|
||||
|
||||
**This bit the project in 2026-06-05** during a cleanup commit. `_capture_workspace_profile` was indented with 3 spaces instead of 2 (drift from re-organizing method placement). The Python parser saw the method as a nested function inside `_apply_snapshot` (the previous method). The App class had 59 methods but no `_capture_workspace_profile`. 3 live_gui tests (test_auto_switch_sim, test_workspace_profiles_restoration, test_undo_redo_lifecycle) failed with cryptic `AttributeError: 'AppController' object has no attribute '_capture_workspace_profile'` deep in the test subprocess.
|
||||
|
||||
**How to detect during TDD:**
|
||||
- After modifying a class body, walk the AST and verify all expected methods are class-level:
|
||||
```bash
|
||||
uv run python -c "import ast; tree = ast.parse(open('src/gui_2.py').read()); [print(item.name) for n in ast.walk(tree) if isinstance(n, ast.ClassDef) and n.name == 'App' for item in n.body if isinstance(item, ast.FunctionDef)]"
|
||||
```
|
||||
- The skeleton via `manual-slop_py_get_skeleton` should show the method as a class member. If it's missing, it's nested.
|
||||
|
||||
**How to fix:** Re-indent the affected method to exactly 2-space class level. Use the file_slice tool or PyCharm-style auto-format to verify. Run the failing test to confirm.
|
||||
|
||||
**Prevention:** When reorganizing a class body, run the AST check above immediately after the edit. This catches the issue in <1 second vs. finding it via failing live_gui tests minutes later.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user