Two decisions taken before the 160-file move, because both change what the
move produces.
The Makefile has 84 targets and is today's front door, so "one CLI for all
repo tooling" was not yet true. The split is by what a target DOES: make keeps
genuine build and test orchestration, and targets that are really tooling
wrappers are retired in favour of reach verbs — retired, not wrapped. A
wrapper leaves two ways to invoke every tool, and then reach --help stops
being the answer to "what tooling exists" because the Makefile is still a
competing index. Two doors is the condition this record exists to end, so
keeping both would defeat it while looking like caution.
Streaming becomes a decorator rather than an API commands call. @command
already wraps every invocation, and that is exactly the seam where job
identity, progress correlation and detach belong: the decorator assigns the
job id, tags the events, and forks on --detach. A command must not know that
jobs exist. The alternative — each command opening a job and remembering to
close it — is call-site discipline wearing a different hat, and it fails the
same way the fortieth command into a porting session, with the failure
vanishing from the log and nothing to indicate anything is missing. Logging
and error handling are decorators for this reason; streaming is the third
cross-cutting concern, not a special case.
Consequent resequencing: T-1264 lands before the T-1250 move, so every ported
command arrives already streaming. Old scripts now retire per domain as each
port passes its parity test, rather than in one sweep at the end — a
continuous shrink, instead of months where every tool exists twice and an edit
can land in the dead copy.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>