docs(governance): D-263 — the primary user is an agent, and that changes things
Stated plainly because the record was quietly assuming otherwise: Jeroen runs make and plays the game; the caller typing reach all day is Claude. It resolves several arguments in the opposite direction from human-CLI instinct. --help is a discovery mechanism rather than documentation, since it is how the tool gets relearned from nothing every session — which makes the domain list and closed-set enumeration load-bearing rather than polish. Output volume is a context cost, so quiet-by-default is right for a better reason than not spamming a hook. Latency matters less than legibility: nobody drums their fingers at 300 ms, but a multi-minute silence is expensive because a wedge is indistinguishable from work. And errors that name the next command are the highest-value requirement here, because the reader is usually deciding what to run next — "no" costs a whole exploratory turn. One correction follows directly. D-263 had scoped streaming to "callers with no escape — a human terminal, a Makefile, a git hook", reasoning that Claude Code's background mode already solved the timeout for agents. That got the audience backwards. Background mode solves the timeout and nothing else: it returns when the process exits, so a nine-minute wedge still looks exactly like nine minutes of work. Streaming is what makes a long run legible while it runs, and reattach is worth most to the caller whose attention is not continuous. Both are primary-user features, not fallbacks. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2611,6 +2611,14 @@ tooling/
|
||||
- **Never literally interactive by default.** Any prompt is TTY-gated and suppressible with `--no-input`, which hooks pass unconditionally. `tea`'s interactive prompts *"crash in Claude Code (no TTY)"*; a helpful prompt that hangs a hook is worse than a terse exit code.
|
||||
- **This is enforced by a conformance test, not by discipline** — every registered command must have help at its own level, and every declared failure path must name a next command. A contract nothing checks is a style guide.
|
||||
|
||||
**The primary user is an agent, not a human** *(stated 2026-08-31, and it settles arguments the rest of this record was having with itself)*. Jeroen runs `make` and plays the game; the caller typing `reach` all day is Claude. Design consequences, each of which contradicts an instinct applied earlier in this record:
|
||||
|
||||
- **`--help` is the discovery mechanism, not documentation.** An agent reads it instead of grepping the tree. That is why the domain list and the closed-set enumeration are load-bearing rather than polish — they are how the tool is *learned*, every session, from nothing.
|
||||
- **Output volume is a real cost, not an aesthetic one.** Every emitted line spends the primary consumer's context window. "Quiet by default" is right for a better reason than not spamming the push hook: verbosity bills the caller who can least afford it. The `--verbose` gate on the invocation record stands.
|
||||
- **Latency matters less than legibility.** An agent does not drum its fingers at 300 ms. The ~500 ms ceiling is therefore a sanity bound, not a target worth optimising toward — but a command that runs for minutes in silence is genuinely expensive, because the caller cannot tell a wedge from work.
|
||||
- **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.
|
||||
|
||||
**`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.
|
||||
@@ -2628,7 +2636,7 @@ tooling/
|
||||
- **Streaming is additive to the failure contract, never a replacement for it.** A stream has no single moment of truth: a remedy emitted at line 400 of 900 is technically printed and practically invisible. **The verdict — outcome, exit code, and the command that fixes it — is still printed once, last, where it cannot be missed.** A stream that dissolved the summary would quietly undo the requirement this record cares most about.
|
||||
- **The split follows the `core/` bound, and this is its first real test.** The primitives — emit, spawn, detach, redirect, record — are substrate and live in `core/`. The verbs `list`, `status`, `log`, `wait` have logic and state of their own, so they are a **domain**: `reach jobs …`. A job store in `core/` would be exactly the drift this record warns about.
|
||||
- **Non-negotiable: a detached job's exit code must survive.** A runner that reports "started" and loses the failure is the exit-0 trap from the top of this record, relocated somewhere nothing is watching — which is worse. `reach jobs wait` exits with the job's code, and an unwaited failed job is visible in `reach jobs list`.
|
||||
- **Where this overlaps the harness, prefer the harness.** Claude Code's `Bash` tool already has a background mode that solves the timeout *for agents*. What `reach` adds is for the callers with no such escape — a human terminal, a Makefile, a git hook — plus durable logs and job history. Scope it there rather than rebuilding what one caller already provides.
|
||||
- **The harness overlaps but does not cover it** *(corrected 2026-08-31 — see the primary-user note below; the original text here scoped streaming to "callers with no escape, a human terminal, a Makefile, a git hook" on the reasoning that Claude Code's `Bash` background mode already solved the timeout for agents. That got the audience backwards.)* Background mode solves **the timeout** and nothing else: it returns when the process exits, so a nine-minute wedge still looks exactly like nine minutes of work. **Streaming is what makes a long run legible while it runs**, and the reattach path — `reach jobs log <id>` after a turn has moved on — is worth most to the caller whose attention is not continuous. Both are primary-user features, not fallbacks for callers who lack a better option.
|
||||
|
||||
**Constraints on execution (these are why the work is sequenced, not why it is hard):**
|
||||
|
||||
|
||||
Reference in New Issue
Block a user