Systematic DevOps tooling organization: a researched taxonomy (kind, packaging weight, fixture placement, discoverability) for tools/, not an ad hoc layout
Context
User feedback: tools/ (tools/decisions/ as a Gleam package, tools/browser_check.ts and tools/check_warnings.ts as flat Deno scripts, tools/expected_warnings.json as a flat data fixture) looked like DevOps tools 'randomly thrown' together, with no visible rule for what goes where or how it scales. Asked for the same cross-referenced, researched rigor already applied to the Core/Shell split and modularization thresholds, applied to tools/ specifically, documented in the standard place (ARCHITECTURE.md).
Options considered
Decision
Added a 'DevOps tooling organization' section to ARCHITECTURE.md (positioned before 'Compiler warnings', which it now cross-references and vice versa): the three-kind taxonomy, a packaging-weight table with concrete trigger conditions (own dependency manifest needed, or own dedicated test suite -- either promotes a flat script to a self-contained package), the testdata/ fixture rule, and the deno task discoverability rule. Applied immediately: moved tools/expected_warnings.json to tools/testdata/expected_warnings.json, updated check_warnings.ts's BASELINE_PATH and all its own doc-comment/output-string references (including one that had been easy to miss -- a hardcoded path string in the PASS console.log, not just the BASELINE_PATH constant). Added a tasks field to the root deno.json (browser-check, check-warnings) with the exact permission flags each script already documented, so both are now invoked as deno task <name> rather than requiring the full flag incantation to be copied out of a header comment. Updated every cross-reference across CLAUDE.md, ARCHITECTURE.md, and docs/development-plan.md to the new task-based invocation and the new fixture path -- swept the whole repo afterward (not just the files touched) to confirm no stale reference to the old flat path or the old raw command remained.
Verification
Both new deno tasks (deno task check-warnings, deno task browser-check) run successfully end-to-end after the move, including a real headless-Chromium session for browser-check (zero page errors) and the warnings gate correctly reading the relocated baseline (49/49 matching, PASS message itself now correctly printing the new tools/testdata/ path -- confirmed the hardcoded-string bug was actually fixed, not just the path constant). 164 Erlang / 187 JavaScript gleam test cases still passing on both targets, unaffected (this change touches only tooling, no game source). A repo-wide sweep (every .md/.gleam/.ts/.mjs file, not just the ones directly edited) confirmed zero remaining references to the old tools/expected_warnings.json path or the old raw deno run invocation as the primary documented command.
Consequences
tools/ now has an explicit, cross-referenced rule for where a new dev-tool belongs, at what packaging weight, and how its own fixtures/baselines are kept separate from its code -- the exact 'why does this look random' question this decision answers directly rather than leaving implicit. The three-kind taxonomy and the packaging-weight table are the concrete reference for the next tool this project adds, the same way the Core/Shell split and modularization thresholds already are for game code.