docs(governance): D-263 — half the tooling is bash, and it gets rewritten
Found on starting the first port: 17 of the 33 tooling executables are bash, about 900 lines. Both this record and the domain map had assumed a Python tree, so those are rewrites rather than moves — a materially larger epic than T-1250 was written for. Decided: rewrite them, do not wrap them. Wrapping would achieve one door while leaving half the CLI surface outside the contract — no @command, no remedy on failure, no streaming, no testable service. reach --help would then list verbs that behave differently from the ones beside them, which is worse than two doors, because the inconsistency is invisible until something fails. The cost lands unevenly and the record says where. The grep-pipeline scripts compute verdicts and gain most from becoming services. The environment scripts — install-godot, install-rust, worktree-setup — gain least and carry the most regression risk, because downloading a specific Godot build or driving rustup is awkward to exercise in a gate. For those, port the decision logic into a testable service and keep the irreducible external calls behind core/process: a rewrite that cannot be tested has to be trusted instead, and trusting an installer is how a working environment becomes an unreproducible one. The domain map gains the inventory by shape, and a rule that every per-domain ticket states which of its sources are bash — since that is what turns a port from mechanical into a rewrite needing its own parity evidence. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2619,6 +2619,12 @@ tooling/
|
||||
- **Failures that name the fix are the highest-value requirement in this record.** The reader of an error message is usually an agent deciding what to run next. A message that says only "no" costs a whole exploratory turn; one that names the command costs none.
|
||||
- **Machine-readable output is the default path, not the exception.** stderr is a pipe far more often than a terminal, so JSONL-when-not-a-TTY matches reality rather than accommodating an edge case.
|
||||
|
||||
**The bash scripts are rewritten in Python, not wrapped** *(settled 2026-08-31, after a survey found the tree is half shell)*. **17 of the 33 tooling executables are bash, ~900 lines** — the record and the domain map had both assumed a Python tree, so porting them is a rewrite rather than a move. They are rewritten anyway.
|
||||
|
||||
- **Why not wrap them.** Wrapping achieves one door while leaving half the surface outside the contract: no `@command`, no remedy on failure, no streaming, no testable service. `reach --help` would then list verbs that behave differently from the ones beside them, which is worse than two doors because the inconsistency is invisible until a failure.
|
||||
- **The cost is real and lands unevenly.** The grep-pipeline scripts (`check-fact-ids`, `validate-ron`, `godot-cold-parse`) compute verdicts and gain the most from becoming services — testable, with failures that teach. The environment scripts (`install-godot`, `install-rust`, `worktree-setup`) gain least and carry the most regression risk, because what they do — download and unzip a specific build, drive `rustup`, manipulate git worktrees — is awkward to exercise in a gate.
|
||||
- **So the risk is named rather than absorbed:** for those three, port the *decision* logic (which version, is it already installed, what does the tree look like) into a testable service and keep the irreducible external calls behind `core/process`. A rewrite that cannot be tested is a rewrite that has to be trusted, and trusting an installer is how a working environment becomes an unreproducible one.
|
||||
|
||||
**`make` and `reach` split by kind, not by preference** *(settled 2026-08-31)*. The Makefile has 84 targets and is today's front door, so "one CLI for all repo tooling" is not true until that relationship is stated. The boundary is **what the target actually does**, not who calls it:
|
||||
|
||||
- **`make` keeps genuine build and test orchestration** — cargo, Godot, the test gate, anything that sequences a build. That is what make is for, and `reach` would be a worse version of it.
|
||||
|
||||
Reference in New Issue
Block a user