Measured on this repo’s own mint, 2026-09-20.
Parent: rsr-template-repo · parent-pin: 06d8c9f7a8d2 (recorded in
.machine_readable/descriptiles/VARIANT.a2ml) · outcome: mint exit 0,
just verify PASS, all placeholders replaced.
This file exists because a mint is not finished when the script exits 0. It is finished when the repo stops describing itself as something else.
just repo-init is not a pure-shell operation:
| Tool | Why |
|---|---|
|
the task runner; every phase is a recipe |
|
|
|
derives the repo’s UUIDv5 identity ( |
|
not needed to mint, but needed by |
On a machine without them, the mint fails partway through — after substitution has already begun — which is the worst place to stop.
uuid5(NAMESPACE_URL, "github.com/metadatastician/evil-weevil")
= 87120fab-5ff8-57c0-8a5d-2cc9110f93e0Derived independently and by the template’s own uuidgen path; identical. The
derived-not-invented identity model holds, and .machine_readable/descriptiles/CLADE.a2ml
records how to recompute it.
Do not set RSR_NON_INTERACTIVE=1. The template says so itself
(README.adoc, docs/AI_INSTALLATION_GUIDE.adoc) and the reason is in
build/just/repo-init.just:
if [ -n "${RSR_NON_INTERACTIVE:-}" ]; then
read() { return 0; } # intended: silence the prompts
fiThat stub does not silence prompts; it replaces read for every read in the
script, including the file-walking loops (find … | while read -r file; do … done).
Two failures at once: the loop variable is never assigned (so set -u reports
file: unbound variable), and read returns success without consuming stdin, so
the loop never terminates. Measured: the substitution pass never runs and the process
spins until killed. Repro in twelve lines: the same loop behaves correctly the moment
the stub is removed.
Consequence for us: the mint is driven by piping 18 answers to stdin. The recipe’s stale "Non-interactive support" comment promises a mode that does not work, and the honest fix upstream is to make the flag fail loudly or delete it — a flag that silently converts a mint into an infinite loop is worse than no flag.
The substitution pass fills {{TOKEN}}-shaped text. The self-name pass rewrites the
literal rsr-template-repo and the owner literal. Everything else is left as
written — so free-form self-description prose is in neither net, and a freshly minted
repo keeps asserting that it is the template.
| # | What survived | Why it matters / how it was repaired |
|---|---|---|
1 |
|
The repo described the template’s evolution as its own, at 97% complete. Rewritten to evil-weevil’s purpose and the seven-phase route, with an honest completion number. |
2 |
|
Claimed to be scaffolding for every estate repo. Rewritten; |
3 |
|
|
4 |
|
Carried the template’s uuid, clade |
Also done at mint: .machine_readable/ai/PLACEHOLDERS.adoc removed (template cruft), the
placeholder ORCID dropped from CITATION.cff rather than left as
0000-0000-0000-0000, and the clade chosen (gm, with the rationale recorded in
CLADE.a2ml — the template deliberately fails CLADE-003/CLADE-006 until a human picks).
# 1. Mint (never RSR_NON_INTERACTIVE):
just repo-init < answers.txt # 14 identity/description + 3 container + confirm
# 2. Repair descriptiles (STATE, ECOSYSTEM), then choose the clade:
# edit .machine_readable/descriptiles/{STATE,ECOSYSTEM,CLADE}.a2ml
# 3. Initialise git, because the arrival pack wants a repository:
git init -b main && git add -A && git commit -m "chore: mint"
# 4. Regenerate everything derived, in this order:
just claude-md && just coapt && just repo-map
# 5. Gate:
just validateStep 3 before step 4 is not optional: generate.sh calls git rev-parse --show-toplevel
and dies outside a work tree. Step 4’s order matters because validate-claude-md,
validate-coapt and validate-repo-map each fail on a stale artifact — which is the
point of them.
Found while running the Phase 1 gates on a repo that — like every fresh local mint — has no git remote yet:
scripts/check-no-placeholders.sh reads the repo’s identity from GITHUB_REPOSITORY,
falling back to git config --get remote.origin.url. That command exits 1 when the key
is absent, and the script runs under set -euo pipefail, so on a remote-less repo the
gate killed itself silently: status 1, no output, nothing to read. The fallback to
the directory basename on the line after it never ran.
The failure mode is the one this estate has been systematically removing — a check that fails without saying why, where the failure is indistinguishable from a finding. A maintainer sees a red gate and an empty log and starts hunting for a placeholder that does not exist. It is fixed here (capture the remote, then parse it), and the fix is worth carrying upstream with the other two.
Three things are worth carrying upstream to rsr-template-repo:
-
repo-initshould either repair the descriptile self-descriptions or print them as required post-mint actions. A mint that is 97% complete as somebody else’s template is the same class of defect as the 211-repo placeholder drift the estate already paid for. -
CLAUDE.mdshould be regenerated as part of the mint. It is the file agents read first, and it shipped here with the wrong uuid, the wrong clade and the wrong IS-NOT boundary. -
check-no-placeholders.shshould survive a repo with no remote (see §5):|| trueon thegit configcall is the whole fix, and the estate’s gates should be runnable in a bare local checkout, because that is how most of them are run the first time.