Private
Public Access
0
0

feat(directives): harvest 6 directives from conductor/edit_workflow.md (Rules 1, 2, 6, 7, 8 contract-change, 8 EOL)

This commit is contained in:
2026-07-02 23:56:18 -04:00
parent 8407742a14
commit 782530ba6d
12 changed files with 107 additions and 0 deletions
@@ -0,0 +1,7 @@
# ast_parse_insufficient
## v1
**Why this iteration:** Lifted verbatim from `conductor/edit_workflow.md:70-76 (Rule 7)`.
**Source:** `conductor/edit_workflow.md:70-76 (Rule 7)`
**Lifted:** 2026-07-02 (Phase A expansion harvest; user directive 2026-07-02)
@@ -0,0 +1,9 @@
### Rule 7. ast.parse() Is Not Enough
`py_check_syntax` only confirms `ast.parse()` succeeds. Semantic errors (wrong decorator targets, wrong base class, wrong attribute, missing `self`) are NOT caught. After any multi-line edit, ALWAYS:
1. Import the module: `python -c "from src.app_controller import AppController"`
2. Instantiate the class
3. Call the new method in the way it's expected to be called (`ctrl.foo_ts` for a property, `ctrl.foo_ts()` for a method)
If you skip this step, the file passes `py_check_syntax` but blows up at import time or when the new method is called. The 2026-06-05 `_capture_workspace_profile` regression (3-space indent vs 2-space class level) is the canonical example.
@@ -0,0 +1,7 @@
# contract_change_audit
## v1
**Why this iteration:** Lifted verbatim from `conductor/edit_workflow.md:90-99 (Rule 8 contract-change check)`.
**Source:** `conductor/edit_workflow.md:90-99 (Rule 8 contract-change check)`
**Lifted:** 2026-07-02 (Phase A expansion harvest; user directive 2026-07-02)
@@ -0,0 +1,11 @@
### The contract-change check (mandatory for any edit that changes a public interface)
Before any edit, search the codebase for callers of the function/symbol/yield shape you're changing. If your edit changes:
- A function signature (add/remove/rename a parameter)
- A return type or yield shape (e.g. `yield process, gui_script` -> `yield process, gui_script, workspace_path`)
- A class hierarchy (add/remove a base class, change a method's name)
- A module-level function name (rename)
- A public attribute name
...you MUST update ALL callers in the same atomic commit. Use `py_find_usages` to locate them. If you change a contract and don't update callers, you have broken the codebase.
@@ -0,0 +1,7 @@
# decorator_orphan_pitfall
## v1
**Why this iteration:** Lifted verbatim from `conductor/edit_workflow.md:51-68 (Rule 6)`.
**Source:** `conductor/edit_workflow.md:51-68 (Rule 6)`
**Lifted:** 2026-07-02 (Phase A expansion harvest; user directive 2026-07-02)
@@ -0,0 +1,18 @@
### Rule 6. The Decorator-Orphan Pitfall
When inserting new methods **before an existing `@property` def**:
```python
@property
def perf_profiling_enabled(self) -> bool:
...
```
If you anchor on `def perf_profiling_enabled` and insert before it, the `@property` decorator on the line above is left orphaned on the line right before YOUR new method. Now `@property` decorates your method (which is no longer a property), and the original setter `@perf_profiling_enabled.setter` blows up at import with `'function' object has no attribute 'setter'`.
**Fix:** Anchor on a non-decorated landmark, or include the decorator in the replacement:
- `old_string` = ` self._init_actions()\n\n @property\n def perf_profiling_enabled`
- `new_string` = ` self._init_actions()\n\n def your_new(...)\n ...\n\n @property\n def perf_profiling_enabled`
This keeps the `@property` attached to its original method.
@@ -0,0 +1,7 @@
# edit_small_incremental
## v1
**Why this iteration:** Lifted verbatim from `conductor/edit_workflow.md:9-12 (Rule 1)`.
**Source:** `conductor/edit_workflow.md:9-12 (Rule 1)`
**Lifted:** 2026-07-02 (Phase A expansion harvest; user directive 2026-07-02)
@@ -0,0 +1,7 @@
### Rule 1. ALWAYS Use Small, Incremental Edits
**WRONG:** Replace large blocks (50+ lines)
**RIGHT:** Replace 3-10 lines at a time, verify, repeat
Rationale: `manual-slop_edit_file` requires exact string matches. The `set_file_slice` tool requires exact line ranges. A single 50+ line edit can fail on whitespace drift and lose the working tree's state silently. Small edits let you verify after each, isolate failures, and roll back atomically.
@@ -0,0 +1,7 @@
# preserve_line_endings
## v1
**Why this iteration:** Lifted verbatim from `conductor/edit_workflow.md:101-108 (Rule 8 whitespace/EOL)`.
**Source:** `conductor/edit_workflow.md:101-108 (Rule 8 whitespace/EOL)`
**Lifted:** 2026-07-02 (Phase A expansion harvest; user directive 2026-07-02)
@@ -0,0 +1,11 @@
### The whitespace-and-EOL rule (mandatory for set_file_slice)
The `new_content` must preserve:
- The file's line ending convention (CRLF on Windows, LF on Linux — pick from the surrounding file, not from your text editor's default)
- The indentation of the surrounding code (1 space per level, per `conductor/code_styleguides/python.md` §1)
- The number of lines replaced (`start_line`..`end_line` must equal `len(new_content.splitlines())`)
If you mismatch any of these, the file will fail to parse. Run `py_check_syntax` and a real `import` after every `set_file_slice`.
**Do NOT normalize line endings via git smudge.** This repo has a mix of CRLF and LF; repo-wide LF standardization is a future track. For now, preserve existing line endings on edit.
@@ -0,0 +1,7 @@
# verify_before_editing
## v1
**Why this iteration:** Lifted verbatim from `conductor/edit_workflow.md:14-24 (Rule 2)`.
**Source:** `conductor/edit_workflow.md:14-24 (Rule 2)`
**Lifted:** 2026-07-02 (Phase A expansion harvest; user directive 2026-07-02)
@@ -0,0 +1,9 @@
### Rule 2. Verify Before Editing
Before ANY edit to a function you haven't touched recently:
1. Run: `py_check_syntax` on `src/<file>.py`
2. Get current state with `get_file_slice` (the exact lines you're about to touch)
3. Read the contract: does this function/field/method's signature, yield shape, or return type have callers I need to update?
DO NOT use `git checkout` or `git restore` to revert your way to a clean state. That destroys in-progress work. If a previous edit left the file in a broken state, ask the user.