Researched the sibling project's tooling discipline (tools/README inventory,
tools/tests with stdlib unittest, check_docs gate, clean-worktree rule, paid-API
tools human-triggered) and encoded it for this repository:
AGENTS.md gains two sections.
- 'Python and shell tooling': fix the tool not the artefact; improve over fork;
one script one job; fail loudly; result files for Unreal commandlets; absolute
paths into sandboxes; clean worktree for generators (.blend/.umap are
read-only on checkout); network/paid tools human-triggered with 429 back-off;
measure don't assert; document every tool in the README inventory; test the
pure parts.
- 'Architecture documentation': Docs/Architecture is arc42 in Markdown; a table
mapping each kind of change to the section that must be updated; describe what
exists, ADRs append-only, keep architecture.md in sync, prettier --check.
Made the referenced scaffolding real rather than aspirational:
- Tools/tests/ (README + __init__) with 12 passing unittest tests covering
input_emulation's ioctl/key-code encoding and block_height_report's height
classification.
- requirements-tools.txt (requests).
- Extracted classify_height() out of block_height_report.main() so the roof/
shelter rule is testable — the rule itself came from the v0.1.2 finding.
- Tools/README: tests section, input-injection rows, and the removed TEMP-QA row
replaced by the real cvar/self-test description.
- Docs/Architecture 05 + architecture.md: tools table extended (input injection,
tests) and a link to the tool rules; kept in sync per the new rule.
Geo/tools/ is now every geographic script, with Geo/README.md documenting each
one; the Blender-side builders moved beside their outputs in Art/blender/*/ and
import their helpers from Geo/tools/osm_common.py.
That module gains to_unreal_local() and to_blender_local(): the only place in the
repository that multiplies metres by 100, so a second silent scale cannot be
introduced. block_height_report.py adds height provenance for the block — 3 of
15 buildings have no height data and render at a placeholder 6.4 m.
asset_metadata.py writes and audits <asset>.geo.json sidecars; four now exist
(hero-facade, terrain, street, blockout) and the audit recomputes each centre from
the origin, failing anything that disagrees.