diff --git a/conductor/directives/ban_getattr_dispatch/v1.md b/conductor/directives/ban_getattr_dispatch/v1.md index 3917a33f..41a0beba 100644 --- a/conductor/directives/ban_getattr_dispatch/v1.md +++ b/conductor/directives/ban_getattr_dispatch/v1.md @@ -1,3 +1,5 @@ +# getattr(x, 'field', default) used for type-dispatch polymorphism is banned + ### 17.5 Banned: `getattr(x, 'field', default)` for type dispatch ```python diff --git a/conductor/directives/ban_hasattr_dispatch/v1.md b/conductor/directives/ban_hasattr_dispatch/v1.md index 2d529c34..4b33b71e 100644 --- a/conductor/directives/ban_hasattr_dispatch/v1.md +++ b/conductor/directives/ban_hasattr_dispatch/v1.md @@ -1,3 +1,5 @@ +# Using hasattr() for entity-type dispatch is banned + ### 17.4 Banned: `hasattr()` for entity type dispatch ```python diff --git a/conductor/directives/ban_local_imports/v1.md b/conductor/directives/ban_local_imports/v1.md index 9c75bf4b..12ee256c 100644 --- a/conductor/directives/ban_local_imports/v1.md +++ b/conductor/directives/ban_local_imports/v1.md @@ -1,3 +1,5 @@ +# Local imports inside function bodies are banned (use module-level imports) + - Local imports inside functions (top-of-module imports only) **The one exception:** the literal wire boundary (TOML/JSON parse functions) may use `dict[str, Any]` + `Metadata.from_dict(...)`. \ No newline at end of file diff --git a/conductor/directives/ban_optional_returns/v1.md b/conductor/directives/ban_optional_returns/v1.md index 26245107..5d3571f7 100644 --- a/conductor/directives/ban_optional_returns/v1.md +++ b/conductor/directives/ban_optional_returns/v1.md @@ -1,3 +1,5 @@ +# The type Optional[T] is banned as a return type — use Result[T] or NIL_T sentinels + ### 17.3 Banned: `Optional[T]` returns ```python diff --git a/conductor/directives/ban_prefix_aliasing/v1.md b/conductor/directives/ban_prefix_aliasing/v1.md index 41b5c01e..ae8bc721 100644 --- a/conductor/directives/ban_prefix_aliasing/v1.md +++ b/conductor/directives/ban_prefix_aliasing/v1.md @@ -1 +1,3 @@ +# `import X as _X` aliasing for naming convenience is banned (use the full type name) + - `import X as _PREFIX` aliasing (use the original name) \ No newline at end of file diff --git a/conductor/directives/ban_repeated_from_dict/v1.md b/conductor/directives/ban_repeated_from_dict/v1.md index cb0e0444..b34e6350 100644 --- a/conductor/directives/ban_repeated_from_dict/v1.md +++ b/conductor/directives/ban_repeated_from_dict/v1.md @@ -1 +1,3 @@ +# Calling .from_dict() repeatedly in the same expression is banned — promote the type at the boundary + - Repeated `.from_dict()` calls in the same expression (cache the result or promote the type) \ No newline at end of file diff --git a/conductor/directives/batch_verification_not_isolation/v1.md b/conductor/directives/batch_verification_not_isolation/v1.md index 10ebc15a..ad7c7541 100644 --- a/conductor/directives/batch_verification_not_isolation/v1.md +++ b/conductor/directives/batch_verification_not_isolation/v1.md @@ -1,3 +1,5 @@ +# For live_gui tests, verification must be batch — not isolated + ### Isolated-Pass Verification Fallacy (Added 2026-06-09) A test that "passes when run after test X but fails in isolation" is a **fragile test, not a fragile fixture**. The flip side is also true: a test that "passes in isolation but fails in batch" is failing — its failure is masked by isolation. The only verification that matters for `live_gui` tests (or any test that depends on shared subprocess state) is the **batch run** in the suite the test will ship in. diff --git a/conductor/directives/boundary_layer_exception/v1.md b/conductor/directives/boundary_layer_exception/v1.md index ab94f6f8..1b7db017 100644 --- a/conductor/directives/boundary_layer_exception/v1.md +++ b/conductor/directives/boundary_layer_exception/v1.md @@ -1,3 +1,5 @@ +# dict[str, Any], Any, Optional[T] returns are allowed only at the literal wire boundary (TOML/JSON parse) + ### 17.7 The one exception: the boundary layer The ONLY place these patterns are allowed is at the literal wire boundary — the function that calls `tomllib.load()`, `json.loads()`, or a vendor SDK's response parser. The boundary is 2-3 functions per file. Every consumer IMMEDIATELY converts to a typed dataclass via `from_dict()`.