From 4c4126d43cbd856583dbc648d4130e95f13e7ecb Mon Sep 17 00:00:00 2001 From: Ed_ Date: Thu, 25 Jun 2026 20:54:36 -0400 Subject: [PATCH] =?UTF-8?q?docs(styleguide):=20strengthen=20type=5Faliases?= =?UTF-8?q?=20=C2=A71=20(Metadata=20is=20boundary=20type,=20not=20escape?= =?UTF-8?q?=20hatch)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- conductor/code_styleguides/type_aliases.md | 23 ++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/conductor/code_styleguides/type_aliases.md b/conductor/code_styleguides/type_aliases.md index b4a6bf5e..9b9d7c2b 100644 --- a/conductor/code_styleguides/type_aliases.md +++ b/conductor/code_styleguides/type_aliases.md @@ -37,17 +37,28 @@ Plus the NamedTuple: ## The 5 Decision Patterns -### 1. Use `Metadata` for any dict-shaped record +### 1. Use `Metadata` ONLY at the wire boundary (TOML/JSON parse) + +**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 -def parse_metadata(raw: str) -> Metadata: - return json.loads(raw) +# CORRECT — at the literal wire boundary: +def _parse_toml_config(raw: str) -> Metadata: + return Metadata.from_dict(tomllib.loads(raw)) -def save_metadata(name: str, data: Metadata) -> None: - ... +# 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 ``` -The alias is `dict[str, Any]` at runtime; the name documents the semantic role. +`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. ### 2. Use the more specific alias when the role is known