Project-Template/docs/TOOLS.md

96 lines
4.6 KiB
Markdown

# Tools — where the scripts are, and which ones can stop you
```
Status: Current
Owner: <who maintains this>
Last reviewed: <YYYY-MM-DD>
Governs: docs/architecture/scripts/**, docs/architecture/githooks/**
Review trigger: Any script added to, removed from or repurposed in
docs/architecture/scripts/; any change to which of them gates
```
> A signpost, deliberately. Every project that adopts this template has a
> `docs/TOOLS.md`, so "read `docs/TOOLS.md` first" is an instruction that works
> without knowing anything about the project — which is the whole reason this
> file exists at a fixed path.
## The list is not here
**[`architecture/README.md`](architecture/README.md)** holds the table of what
ships and what each script is. That is the one copy.
A second table here would be two records of one fact, and the other one would
never hear that a script was renamed — the failure `DOC_TRUST_MAP.md` exists to
prevent, applied to the tooling instead of the documents. So this file answers
the questions that table does not, and points at it for everything else.
## If this project has fewer scripts than that table lists
That is the intended state, not a broken copy. `scaffold.sh` writes the
documents and deliberately leaves the scripts behind — *"an unconfigured
`release.sh` landing in every new repository is a loaded gun, not a head
start"* — so they are taken from the template one at a time, having been read.
Which makes the table a menu rather than an inventory here: it says what exists
to be copied. Once a script is in this project, it is this project's, and its
row in `architecture/README.md` should say what it does **here** if that has
drifted from the template's version.
## Which ones can stop you
Not in a table, because the honest answer lives in each script's own header and
would go stale here. The rule that matters:
**Exit code `2` is never a pass.** These scripts distinguish "the check ran and
found nothing" from "the check did not run", because those look identical from
the outside and only one of them is evidence. A CI step or a hook that treats a
`2` as success has quietly turned the check off. Each script states its codes at
the top; read them there.
The hooks are the other place work gets stopped:
[`architecture/githooks/`](architecture/githooks/README.md) has the one install
command and the table of what each hook runs.
**And a third place, which stops something the other two cannot: the claim.**
`scripts/verify-before-done.sh` is a Claude Code `TaskCompleted` hook that runs
`verify.sh` and refuses to let a task be reported as finished when it fails.
Every other gate here fires on an **artifact** — a commit, a build, a tag — so
an agent that says "done" without committing trips none of them, which is the
gap `WORK_CYCLE.md` is describing when it says *"Done" is not a close*.
Two things to know before installing it, both in the script's header at length:
- **It exits `2` to block, and `1` fails open.** Claude Code reads a `1` from a
hook as "the hook broke" and continues, so a gate written the ordinary way
lets through precisely what it was installed to catch, and looks identical
doing it. This is the exit-code rule above with the numbers swapped, and it is
the one place in this template where that is true.
- **It gates Claude Code and nothing else.** A Codex session, a human, or any
other agent in the same checkout writes past it without knowing it is there.
It is a second layer; `.githooks/pre-commit` is the layer, because git runs
that whoever is driving. If this project's real suite is not wired into that
hook, wiring it there is worth more than installing this.
## Where to start in a fresh clone
1. `bash docs/architecture/scripts/check-env.sh` — what is configured and what
is missing, before anything reads it.
2. `bash docs/architecture/scripts/secrets.sh --tracked` — the one-time audit of
what is already committed. The staged-diff mode is for the hook; this mode is
for the day you adopt the template.
3. [`architecture/GUARDS.md`](architecture/GUARDS.md) — how to write a check that
can actually fail, before you write one. `scripts/prove-guard.sh` performs its
first rule.
## Adding one
Put it in `scripts/`, give it a header saying what it does and
**which incident motivated it**, state its exit codes, and add a row to
`architecture/README.md`'s table — this file's `Review trigger` fires on exactly
that.
The bar, from the scripts that are already here: **done by hand three times, or
once with a consequence.** A script written before either of those has no failure
to describe in its header, which is the part that stops the next person deleting
it.