Skip to main content
guard generate splits each kept doc into sections and, per section:
1

Classify

Decides whether the section makes a claim a driver can assert. Two drivers today: cli invokes your project’s binary, api drives your HTTP service; web/tui drivers are planned. A non-testable verdict carries a one-sentence reason and surfaces as a visible coverage gap; nothing is silently skipped.
2

Author

Writes one or more declarative YAML scenarios from the section’s claim plus the code. Authoring is grounded in an analysis of the app’s own source (its route surface, the fields each handler actually requires, and the upstream requests it sends), which is what prevents scenarios against routes that don’t exist or bodies missing required fields. (This grounding is JS/TS only today.)
3

Birth-validate

Runs each new scenario immediately; the outcome becomes the test’s status. Every authored test is committed, so a test that fails at birth (the spec and the code already disagree) lands as a failing test you can open, re-run, and resolve, not a separate species of report entry.
truecourse guard setup is a prerequisite: generate refuses to run until the repo has been prepared (recipe proved, external APIs declared, seed drafted).

Authoring guarantees

  • Worked examples are byte-for-byte. A section’s own worked example (a fenced block) is seeded into its test verbatim, never paraphrased, and the engine byte-checks the committed scenario against the doc’s bytes.
  • Two-sided promises get both halves. “Valid X is accepted, invalid X is rejected” gets steps for both directions, so exclusion logic that silently breaks can’t stay green.
  • An inert corpus aborts the run. When a large sample of birth steps is overwhelmingly inert (a CLI entry answering everything instantly with nothing, or a server answering every route with the same empty status), generate aborts as a recipe failure and writes nothing, instead of committing a green corpus that proves nothing.

Output

All committable, so the whole team runs the same tests: A gitignored guard/result.json records the last generate’s summary (written/settled counts, per-section gap reasons, detected external services, call+token+cost totals); truecourse guard status and the dashboard render it.

Incremental re-generates

Section fingerprints in the manifest mean a re-generate only touches sections whose spec text actually changed; unchanged sections keep their scenarios and cost nothing. Like spec scan, generate prints a cache-aware cost estimate up front and asks for confirmation (-y / --yes skips it); when nothing changed, there’s nothing to confirm.

Flows

Generate synthesizes flows (the user-visible journeys the spec describes) and binds tests to them. They’re inspectable and curatable without an LLM:
Every committed test can be read in plain words. A test’s YAML carries the flow’s promise, and one shared renderer turns the whole file into sentences: the world it’s placed in, what each step does, what it remembers, and what must be true. The dashboard’s test detail offers View · Story · YAML; --story prints the same words in the terminal.

Findings: whose fault is it?

A generate produces two very different results, and only one of them is work for you:
The dashboard draws the same line: a tool defect is a muted marker beside the flow’s status, never a red one, and each failing test carries its triage verdict (code drift, doc drift, our defect) with the concrete unblock beside it.

Next steps

Guard run

Run the committed scenarios deterministically, in CI.

Dashboard

Coverage, flows, stories, and findings, visually.