From 782530ba6db505f2218304b41470026199cb1748 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Thu, 2 Jul 2026 23:56:18 -0400 Subject: [PATCH] feat(directives): harvest 6 directives from conductor/edit_workflow.md (Rules 1, 2, 6, 7, 8 contract-change, 8 EOL) --- .../directives/ast_parse_insufficient/meta.md | 7 +++++++ .../directives/ast_parse_insufficient/v1.md | 9 +++++++++ .../directives/contract_change_audit/meta.md | 7 +++++++ .../directives/contract_change_audit/v1.md | 11 +++++++++++ .../decorator_orphan_pitfall/meta.md | 7 +++++++ .../directives/decorator_orphan_pitfall/v1.md | 18 ++++++++++++++++++ .../directives/edit_small_incremental/meta.md | 7 +++++++ .../directives/edit_small_incremental/v1.md | 7 +++++++ .../directives/preserve_line_endings/meta.md | 7 +++++++ .../directives/preserve_line_endings/v1.md | 11 +++++++++++ .../directives/verify_before_editing/meta.md | 7 +++++++ .../directives/verify_before_editing/v1.md | 9 +++++++++ 12 files changed, 107 insertions(+) create mode 100644 conductor/directives/ast_parse_insufficient/meta.md create mode 100644 conductor/directives/ast_parse_insufficient/v1.md create mode 100644 conductor/directives/contract_change_audit/meta.md create mode 100644 conductor/directives/contract_change_audit/v1.md create mode 100644 conductor/directives/decorator_orphan_pitfall/meta.md create mode 100644 conductor/directives/decorator_orphan_pitfall/v1.md create mode 100644 conductor/directives/edit_small_incremental/meta.md create mode 100644 conductor/directives/edit_small_incremental/v1.md create mode 100644 conductor/directives/preserve_line_endings/meta.md create mode 100644 conductor/directives/preserve_line_endings/v1.md create mode 100644 conductor/directives/verify_before_editing/meta.md create mode 100644 conductor/directives/verify_before_editing/v1.md diff --git a/conductor/directives/ast_parse_insufficient/meta.md b/conductor/directives/ast_parse_insufficient/meta.md new file mode 100644 index 00000000..164509dd --- /dev/null +++ b/conductor/directives/ast_parse_insufficient/meta.md @@ -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) diff --git a/conductor/directives/ast_parse_insufficient/v1.md b/conductor/directives/ast_parse_insufficient/v1.md new file mode 100644 index 00000000..4e7e9176 --- /dev/null +++ b/conductor/directives/ast_parse_insufficient/v1.md @@ -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. diff --git a/conductor/directives/contract_change_audit/meta.md b/conductor/directives/contract_change_audit/meta.md new file mode 100644 index 00000000..349beb73 --- /dev/null +++ b/conductor/directives/contract_change_audit/meta.md @@ -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) diff --git a/conductor/directives/contract_change_audit/v1.md b/conductor/directives/contract_change_audit/v1.md new file mode 100644 index 00000000..ff156c00 --- /dev/null +++ b/conductor/directives/contract_change_audit/v1.md @@ -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. diff --git a/conductor/directives/decorator_orphan_pitfall/meta.md b/conductor/directives/decorator_orphan_pitfall/meta.md new file mode 100644 index 00000000..bbfeffac --- /dev/null +++ b/conductor/directives/decorator_orphan_pitfall/meta.md @@ -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) diff --git a/conductor/directives/decorator_orphan_pitfall/v1.md b/conductor/directives/decorator_orphan_pitfall/v1.md new file mode 100644 index 00000000..746abc4b --- /dev/null +++ b/conductor/directives/decorator_orphan_pitfall/v1.md @@ -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. diff --git a/conductor/directives/edit_small_incremental/meta.md b/conductor/directives/edit_small_incremental/meta.md new file mode 100644 index 00000000..d64a5a4f --- /dev/null +++ b/conductor/directives/edit_small_incremental/meta.md @@ -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) diff --git a/conductor/directives/edit_small_incremental/v1.md b/conductor/directives/edit_small_incremental/v1.md new file mode 100644 index 00000000..3a1dedb4 --- /dev/null +++ b/conductor/directives/edit_small_incremental/v1.md @@ -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. diff --git a/conductor/directives/preserve_line_endings/meta.md b/conductor/directives/preserve_line_endings/meta.md new file mode 100644 index 00000000..1d1d6f3d --- /dev/null +++ b/conductor/directives/preserve_line_endings/meta.md @@ -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) diff --git a/conductor/directives/preserve_line_endings/v1.md b/conductor/directives/preserve_line_endings/v1.md new file mode 100644 index 00000000..3fdf7358 --- /dev/null +++ b/conductor/directives/preserve_line_endings/v1.md @@ -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. diff --git a/conductor/directives/verify_before_editing/meta.md b/conductor/directives/verify_before_editing/meta.md new file mode 100644 index 00000000..d8b043a7 --- /dev/null +++ b/conductor/directives/verify_before_editing/meta.md @@ -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) diff --git a/conductor/directives/verify_before_editing/v1.md b/conductor/directives/verify_before_editing/v1.md new file mode 100644 index 00000000..cc81d8ac --- /dev/null +++ b/conductor/directives/verify_before_editing/v1.md @@ -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/.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.