feat(config): T-1282 — the validate domain, and a move that broke a root

reach validate content / checklist / ron / name-collisions. The three old
scripts are retired, their make targets with them.

Print statements go through the logging sink rather than a collector. The
validators emit their findings as console events as they run, so a long content
validation streams instead of going quiet and dumping at the end — the message
strings and their order are unchanged, only the destination. That also
satisfies the conformance rule forbidding print() in the package, which is what
forced the question.

validate-ron was three languages deep: bash dispatching on a flag, a Python
heredoc doing collision detection, cargo run for schema validation. Logic
embedded in a shell string cannot be imported, tested, or found by anything
that indexes Python, so it became Python; the cargo call became a guarded exec.
It also split into two verbs, because --check-name-collisions answered a
different question from the default path: whether the SET of cultures is
coherent, versus whether ONE file is well-formed.

The move broke something, quietly, which is the point of doing these one at a
time. validate-checklist computed ROOT as Path(__file__).parent.parent — the
repo root while it lived at tooling/validate-checklist, and tooling/domains
once moved. Both its schema and gauntlet paths silently repointed at nothing,
the gauntlet directory "did not exist", and it reported success having checked
zero files. Caught by running it beside the original: old exit 1, new exit 0.
Now config.repo_root(), and load_schema raises ReachError instead of calling
sys.exit, which a service must not do.

Parity on the live tree: content reproduces the original byte for byte
including its counts, name-collisions likewise. Tests pin what those runs
cannot reach — the detection path, since the repo currently has no collisions,
and the argument errors.

Two things found and left alone: validate-content FAILS on the live tree with
13 missing schemas, pre-existing and unrelated to this port; and the ticket's
claim that validate-content sits in the pre-commit hook is wrong — that hook
runs only check-fact-ids and pql decisions validate, so there was no shared
edit to coordinate.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-02 12:48:56 +02:00
co-authored by Claude Opus 5
parent cb5d3f1335
commit 7f20bd303b
15 changed files with 798 additions and 252 deletions
+11 -16
View File
@@ -3,12 +3,12 @@ GODOT := $(shell command -v godot4 2>/dev/null || command -v godot 2>/dev/null)
.PHONY: help setup build client server game atlas stop test test-tooling lint lint-python setup-venv ci ci-client ci-server clean \
install-reach reach-repoint \
decisions-sync decisions-active decisions-validate \
validate-content setup-hooks install-hooks \
setup-hooks install-hooks \
audit deny atlas-verify economy-db regen-db \
pre-pr pre-pr-lint pre-pr-build pre-pr-test pre-pr-validate pre-pr-fixtures \
pre-pr-server pre-pr-client pre-pr-content \
fixtures-client fixtures-gauntlet golden-diff golden-update \
checklist-validate checklist-generate check-star-map star-map-data \
check-star-map star-map-data \
build-sr-voice run-sr-voice test-voice-mock test-voice-real \
perf-baseline debug-schedule \
test-ipc-fixtures test-ipc-protocol test-ipc-integration test-ipc-benchmark \
@@ -55,7 +55,6 @@ help:
@echo " make decisions-validate Validate decision records — malformed-record gate (pql)"
@echo " make audit Run cargo audit (security advisory check)"
@echo " make deny Run cargo deny check (license/ban policy)"
@echo " make validate-content Validate content YAML against schemas"
@echo " make atlas-verify Verify atlas proposal JSONs (all in docs/atlas/proposals/)"
@echo " make star-map-data Regenerate client/data/star_map_data.json from systems.db + wiki"
@echo " make check-star-map Assert star_map_data.json is up to date (part of pre-pr-client)"
@@ -65,8 +64,6 @@ help:
@echo " make fixtures-client Generate GDScript->Rust cross-encoder fixtures (#475)"
@echo " make golden-diff Show diff if golden file output has changed"
@echo " make golden-update Regenerate golden file and stage for commit"
@echo " make checklist-validate Validate checklist YAML against schema"
@echo " make checklist-generate Validate checklists + print condition summary"
@echo " make perf-baseline Run performance benchmarks and save baseline"
@echo ""
@echo " make screenshot Ad-hoc visual capture (SCENARIO=name, default: atlas_GJ820Bc_Global)"
@@ -315,6 +312,10 @@ test-tooling:
@mkdir -p .cache
@$(VENV_PY) tooling/test_conformance.py 2> .cache/test-tooling-conformance.log || \
{ echo " FAIL: reach conformance — log follows:"; cat .cache/test-tooling-conformance.log; exit 1; }
@echo " [test-tooling] reach validate verbs — behaviour (T-1282)..."
@mkdir -p .cache
@$(VENV_PY) tooling/test_validate.py 2> .cache/test-tooling-validate.log || \
{ echo " FAIL: validate verbs — log follows:"; cat .cache/test-tooling-validate.log; exit 1; }
@echo " [test-tooling] reach check gates — behaviour (T-1281)..."
@mkdir -p .cache
@$(VENV_PY) tooling/test_check.py 2> .cache/test-tooling-check.log || \
@@ -378,7 +379,7 @@ pre-pr-build: build-server build-client
pre-pr-test: test-server test-client
@echo "--- Tests: PASS ---"
pre-pr-validate: validate-content check-star-map
pre-pr-validate: check-star-map
@echo "--- Content validation: PASS ---"
pre-pr-fixtures:
@@ -423,7 +424,7 @@ pre-pr-server: lint-server build-server test-server pre-pr-fixtures audit deny
pre-pr-client: lint-client build-client test-client check-star-map
@echo "=== Client pre-PR: PASSED ==="
pre-pr-content: validate-content checklist-validate atlas-verify
pre-pr-content: atlas-verify
@echo "=== Content pre-PR: PASSED ==="
# --- CI (run locally) ---
@@ -468,6 +469,9 @@ regen-db: ## Regenerate systems.db from all sources and stamp meta table (#855,
# make check-canvas-version -> reach check canvas-version
# make check-fact-ids -> reach check fact-ids
# make check-dataflow-graph -> reach check dataflow-graph
# make validate-content -> reach validate content
# make checklist-validate -> reach validate checklist --check
# make checklist-generate -> reach validate checklist
#
# Wrapping them would leave two ways to invoke each, and `reach --help` would
# stop being the answer to "what tooling exists" because the Makefile would
@@ -501,9 +505,6 @@ decisions-validate:
# --- Content Validation ---
validate-content:
@tooling/validate-content
atlas-verify:
@tooling/atlas-verify docs/atlas/proposals/*.json
@@ -513,12 +514,6 @@ audit:
deny:
cd server && cargo deny check
checklist-validate:
@tooling/validate-checklist --check
checklist-generate:
@tooling/validate-checklist
check-star-map:
@python3 tooling/generate-star-map-data.py --check