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
.or(z.string().transform(...))handles the case where the LLM returns plain strings instead of objects — a real compliance failure we actually hit. Without this, those tasks would fail every run; with it, they degrade gracefully..default('P3')on the priority field means a missing field produces a sensible default rather than a validation error.parseDecompositionas a pure exported function means the validation logic is independently testable without mocking axe or Todoist.
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
None significant. Zod does exactly what it claims.