Files
settled-reach/docs/sprints/sprint-9/ci.md
T
jpmschweitzerandClaude Opus 4.6 bccdcfcdcb docs(docs): add frontmatter to all sprint briefings
Standardized YAML frontmatter on all 115 sprint briefing files across
sprints 1-26 with title, description, type, status, sprint number, and
team fields.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 00:15:45 +01:00

7.9 KiB

title, description, type, status, sprint, team
title description type status sprint team
Sprint 9 — CI Briefing make pre-pr target, content cross-reference validation, fixture staleness check sprint archived 9 ci

Sprint 9: Gauntlet — CI Tasks

Goal: Build the test infrastructure backbone — test client binary, Gauntlet rooms 1-3, golden file suite, and client QA harness — so every future sprint can be validated end-to-end.

Branch: ci Agents: Justine (build/deploy)

Carry-over from Sprint 8

# Title Status Notes
#460 make pre-pr target backlog Critical — did not start in Sprint 8. Linchpin for the pre-PR validation chain. Blocks #465.
#464 Content cross-reference validation (9 checks) backlog Critical — extends tooling/validate-content. Standalone from #460.
#465 Fixture staleness check in make pre-pr backlog Blocked by #460.
#475 make fixtures-client target (GDScript-generated fixtures for Rust) backlog #474 completed Sprint 8 — now unblocked.

New Tickets

# Title Blocked by
#475 make fixtures-client target (GDScript-generated fixtures for Rust) — (#474 done Sprint 8)
#486 make golden-diff + make golden-update targets #485 (server)
#497 Checklist YAML schema + make checklist generation #487 (server)

Key Decisions

  • decisions/architecture.md — D-030 (testability architecture: pre-PR chain, fixture staleness, Layer 3 integration tests; total runtime <3min for pre-PR target)
  • decisions/architecture.md — D-020 (server binary is a standalone Rust binary; make pre-pr must build it as part of the chain)

Notes

#460 — make pre-pr target

What exists: The top-level Makefile has validate-content (wraps tooling/validate-content) and individual ci-server, ci-client targets (see docs/DEVOPS.md). The make pre-pr target does not yet exist.

What to deliver: make pre-pr in the top-level Makefile as an ordered chain:

  1. lint-server (Clippy)
  2. build-server (cargo build)
  3. test-server (cargo nextest)
  4. lint-client (GDScript linter if any)
  5. build-client
  6. test-client (gdUnit4 headless)
  7. validate-content (schema validation)
  8. Fixture staleness check (stub hook for #465)

Total runtime target: <3 minutes on a clean build. Branch-specific variants: make pre-pr-server (steps 1-3 only), make pre-pr-client (steps 4-6 only), make pre-pr-content (step 7 only). These let individual teams run their own slice.

Gotcha: Server binary must be built before Layer 3 tests (which spawn it as a subprocess per D-030). Ensure build-server precedes test-server in the chain. Use $(MAKE) for sub-targets to get proper error propagation.

#464 — Content cross-reference validation (9 checks)

What exists: tooling/validate-content is an executable script that runs YAML schema validation. Extend it with a cross-reference pass.

What to deliver: 9 cross-reference checks in tooling/validate-content (or a companion script it calls):

  1. canonical_id uniqueness — no two content items share an ID
  2. Relationship target resolution — every target_id in a relationship block resolves to a known entity
  3. Location slug resolution — every location_slug references a known location
  4. Dialogue location resolution — every dialogue location field resolves
  5. Fact tag validity — every fact tag is in the registered tag vocabulary
  6. Line pool tag coverage — every monologue line's trigger tags exist in content
  7. Archetype consistency — every NPC archetype value is a known enum variant
  8. Routine phase validity — every routine phase field is a valid DayPhase value
  9. (Check 9 is Bidirectional relationship consistency — advisory warning, non-blocking, see #515 for full impl; stub it here as a TODO comment)

Exit 0 if all checks pass (warnings OK for check 9). Exit 1 on any blocking failure. Output: per-check pass/fail with file+line reference for failures.

#465 — Fixture staleness check in make pre-pr

What exists: server/tests/gen_fixtures.rs generates .msgpack files at client/tests/fixtures/msgpack/. The fixtures committed to git are the source of truth. If code changes alter fixture output without regenerating, client tests will fail with misleading errors.

What to deliver: A script (or Makefile target check-fixture-staleness) that:

  1. Runs cargo test gen_fixtures to regenerate fixtures into a temp location
  2. git diff the output against client/tests/fixtures/msgpack/
  3. Exit 1 if any fixture differs (stale fixtures = false positive in client tests)
  4. Print a clear message: "Fixtures stale — run make fixtures-regen to update"

Integrate as step 8 in make pre-pr (blocked by #460 providing the chain structure). Also expose as a standalone make check-fixtures target.

#475 — make fixtures-client target (GDScript-generated fixtures for Rust)

What exists: #474 was completed in Sprint 8 — GDScript encoding asymmetry tests are done and validated. This target is now unblocked. It exercises the reverse direction: GDScript encoder → Rust decoder.

What to deliver: make fixtures-client Makefile target that:

  1. Runs the Godot headless GDScript test that generates .msgpack files at server/tests/fixtures/gdscript/
  2. The Rust integration test in server/tests/serialization.rs (or a new file) then verifies it can decode those files

This validates the full bidirectional protocol: Rust encodes → GDScript decodes (#474), GDScript encodes → Rust decodes (#475). Together they close the cross-encoder compatibility loop.

#486 — make golden-diff + make golden-update targets

What exists: Blocked by #485 (server golden file suite). The golden file lives at tests/golden/gauntlet_tick_10.json (created by #485).

What to deliver: Two Makefile targets:

  • make golden-diff: runs the golden file test, shows a diff if the output has changed (use diff --color or jq for pretty output). Exits 1 if changed.
  • make golden-update: regenerates tests/golden/gauntlet_tick_10.json from a fresh run and stages it with git add. Does NOT commit — leaves the diff for developer review.

These are developer workflow targets, not CI gates. Document in make help output.

#497 — Checklist YAML schema + make checklist generation

What exists: Blocked by #487 (server Gauntlet rooms — provides room IDs for checklist scope). Checklists live at content/gauntlet/rooms/{room_id}/checklist.yaml (per-room) and content/gauntlet/cross_room_checks.yaml.

What to deliver:

  • YAML schema definition (JSON Schema or serde-compatible struct): 7 condition types: player_near, player_facing, entity_present, entity_absent, expected_monologue, expected_dialogue, expected_interaction_verb. Each condition has id, description, condition_type, and type-specific fields.
  • make checklist-generate Makefile target: validates all checklist YAML against the schema, outputs a summary of condition counts per room
  • make checklist-validate target: runs the schema check standalone (useful in pre-PR chain)

The checklist format feeds into #503 (client auto-checklist progress tracking) in Sprint 10. Design the schema with that consumer in mind — conditions should be evaluable from an ObserverSnapshot.

Dependency Chain

#460 (make pre-pr) — start immediately, no blockers
    -> #465 (fixture staleness check)

#464 (content cross-reference validation) — standalone, parallel to #460

#474 (done Sprint 8) -> #475 (make fixtures-client, unblocked)

#485 (server, golden suite) -> #486 (make golden-diff + golden-update)

#487 (server, Gauntlet rooms) -> #497 (checklist YAML schema)

PR Workflow

When ready to submit, create a PR with tea CLI. All flags are required to avoid TTY prompts (see CLAUDE.md "Gitea access" section):

tea pr create --repo jpmschweitzer/settled-reach --login schweitz --title "feat(ci): sprint 9 gauntlet — pre-pr chain, content validation, golden targets" --description "body" --base main --head ci