feat(directives): harvest 3 type/data-structure directives + update boundary_layer_exception

This commit is contained in:
ed
2026-07-02 21:57:36 -04:00
parent 5ba69aaa6c
commit 62fc04b172
3 changed files with 163 additions and 5 deletions
@@ -1,13 +1,58 @@
# boundary_layer_exception — v1
**Why this iteration:** Lifted verbatim from `conductor/code_styleguides/python.md` §17.7 (lines 352-354).
This is the baseline encoding — the imperative-ban style currently in production.
Future variants will test alternative encodings (rationale-first, before/after, tabular) against this baseline.
**Why this iteration:** Cross-referenced lift combining `conductor/code_styleguides/python.md` §17.7 + §17.8 (lines 352-359) + `data_oriented_design.md` §8.5 boundary-exception + §8.6 (lines 193-202) + `type_aliases.md` §1 (lines 54-72). This is the boundary-layer rule from three canonical sources, all lifted verbatim. The plan updated the v1 in t1_4 to cross-reference the §17.7 exception, §17.8 enforcement, §8.6 boundary definition, and the type_aliases.md Metadata-as-boundary-type rule.
Future variants will test alternative encodings (rationale-first, tabular, single-source) against this baseline.
**Source:** `conductor/code_styleguides/python.md:352-354`
**Source:** `conductor/code_styleguides/python.md:352-359 + data_oriented_design.md:193-202 + type_aliases.md:54-72`
---
### 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()`.
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()`.
### 17.8 Enforcement
- `scripts/audit_weak_types.py --strict` — flags `dict[str, Any]`, `Any`, anonymous tuple returns
- `scripts/audit_optional_in_3_files.py --strict` — flags `Optional[T]` return types in the baseline 4 files (`src/mcp_client.py`, `src/ai_client.py`, `src/rag_engine.py`, plus one more). An all-`src/*.py` successor (`audit_optional_returns.py`) is referenced in older planning docs but is NOT yet built — the live script today is `audit_optional_in_3_files.py`.
---
**The one exception (the boundary layer) — from `data_oriented_design.md` §8.5:**
at the literal wire boundary (TOML parsing, JSON parsing, vendor SDK response parsing), the data is open-ended for the 100ns between parsing and `from_dict()` conversion. At that boundary:
- The function that calls `tomllib.load()` or `json.loads()` may return `Metadata` (the typed fat struct — see §8.6).
- Every consumer of that function IMMEDIATELY calls `SomeTypedDataclass.from_dict(metadata)` and uses the typed result.
- The boundary is 2-3 functions per file (one per wire entry point).
**No other code uses `Metadata` or `dict[str, Any]` or `Any`.** This is enforced by `scripts/audit_weak_types.py --strict` (existing) + the boundary-layer audit (planned in `conductor/tracks/cruft_elimination_20260627/spec.md`).
### 8.6 The Boundary Layer (the wire schema)
The codebase has ONE typed fat struct at the boundary: `Metadata` in `src/type_aliases.py`. It is `@dataclass(frozen=True, slots=True)` with explicit fields covering the TOML/JSON wire schema (paths, project, discussion, role, content, ts, source_tier, model, depends_on, document, script, args, etc.). It is used in exactly 2 places:
---
### 1. Use `Metadata` ONLY at the wire boundary (TOML/JSON parse) — from `type_aliases.md`
**UPDATED 2026-06-25 (the C11/Odin/Jai-in-Python mandate).** `Metadata` is the typed fat struct at the wire boundary. It is `@dataclass(frozen=True, slots=True)` with explicit fields covering the TOML/JSON wire schema (paths, project, discussion, role, content, ts, source_tier, model, depends_on, document, script, args, etc.).
```python
# CORRECT — at the literal wire boundary:
def _parse_toml_config(raw: str) -> Metadata:
return Metadata.from_dict(tomllib.loads(raw))
# CORRECT — consumer at the boundary, converts immediately:
def _load_project_context(raw_toml: Metadata) -> ProjectContext:
return ProjectContext.from_dict(raw_toml)
# WRONG — using Metadata as a lazy-typing escape hatch:
def process_event(self, event: Metadata) -> None:
if hasattr(event, 'tool_calls'):
... # ← BAD: this is the laziest possible typing
```
`Metadata` is **NOT** `TypeAlias = dict[str, Any]`. It is a typed fat struct. The boundary is 2-3 functions per file. Every consumer IMMEDIATELY converts to a componentized dataclass via `from_dict()`.
**Anti-pattern (banned):** `Metadata: TypeAlias = dict[str, Any]` (the lazy-typing escape hatch). LLMs default to this because it's idiomatic Python. This codebase does NOT do idiomatic Python. See `data_oriented_design.md` §8.5.