Validate in CI

Goal: a repo where a broken story fails the build — dangling references, unwinnable quests, and regressed playthroughs all caught by CI. ~10 minutes.

1. Run the validator headless

From your project directory:

parlance ci-check .

Same validator the editor runs on every save — headless. It prints a project summary (dialogue/node/choice/word counts) and every issue grouped by family, then exits:

Exit code Meaning
0 clean
1 validation errors (with --strict: errors or warnings)
2 not a Parlance project

Start CI with plain ci-check (errors only) so in-progress warnings don't block the team; graduate to --strict when the backlog is clean — the demo project stays --strict-clean permanently, and it's a good standard to covet.

2. Turn a playthrough into a test

Validation proves the story is well-formed; route fixtures prove specific playthroughs still work. A route is a scripted walk — which choices to take, with check outcomes forced so the walk is dice-independent — plus assertions about where you end up:

{
  "id": "rt_talk_past",
  "description": "Talking past the gatekeeper marks you as known at the gate.",
  "dialogueId": "dlg_gate_first",
  "steps": [{ "choiceId": "c_talk", "forced": "pass" }],
  "assertEnd": { "flags": { "talked_past_gate": true } }
}

Drop it at tests/routes/rt_talk_past.json and run:

parlance route --all --strict

Because play is deterministic, the replay is exact every run. When next month's edit accidentally gates your only route to node_pass, this fixture fails with the step where the walk diverged. The demo ships four of these, including one asserting the failure branch still works.

Routes live in tests/, not data/, deliberately: a shipping game never loads them (layout reference).

3. Wire it into GitHub Actions

name: narrative
on: [push, pull_request]
jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: 22 }
      - run: npx parlance ci-check . --strict
      - run: npx parlance route --all --strict

Now a pull request that breaks the story shows a red ✗ like any other broken build — which changes the social contract: narrative edits get the same review-and-green-check flow as code, and "it validates" stops being a claim anyone has to take on faith. (Why that matters.)

No Node in your pipeline? The independent Python validator (reference) reports the same issues, enforced by a parity test.

4. Read failures fast

When CI goes red, the validation checks reference is the decoder ring — every family, what it scans, and how to fix it. In the editor, the same issues are clickable rows that navigate straight to the offending entity.

Where next

That's the full loop — author → validate → playtest → review → CI → engine. The remaining depth lives in the editor guide and the reference pages.