Zod

TypeScript-first schema validation.

Goals

Validate the raw JSON output from axe agents (specifically inertia-decomposer) at the boundary between the LLM and the domain logic — catching malformed or non-compliant responses before they can corrupt task data.

Effectiveness

Excellent. Zod is exactly the right tool for this boundary. The schema is expressive enough to describe what the LLM should produce, coercive enough to handle what it actually produces, and integrates cleanly with TypeScript's type system so validated data flows through the rest of the code as typed values.

What made it effective

Bonus utility

The ZodError thrown on schema violations is structured enough to log the specific field that failed — useful for diagnosing which LLM output pattern is non-compliant.

Friction / pain points / surprises

Schema constraints drift from LLM agent prompts with no enforcement. Zod validates what the LLM produces; the LLM is constrained by the agent TOML. When the TOML was updated (essay-outliner: 5→7 min sections, 400→600 min word_quota) but the Zod schema wasn't (still max(7) sections, max(550) words), the pipeline entered a silent retry loop: axe exited 0, Zod threw, the checkpoint never advanced. The fix is mechanical (update both together) but there's no tooling that enforces the pairing. The TOML and the schema are a two-sided contract with no shared source of truth.