Twinned from https://github.com/cfsh/ninefold/issues/1093 by tools/beads/import_github.py's reconcile pass.
Aedan's ask, verbatim (PR #1092 inline thread, 2026-08-18, on .claude/commands/prototype.md's tier1_authority mention): "where does tier1_authority come from? We are trying to kill all references to tier xyz"
tier1_authority() (tools/nflib/authority.py:226) is the function that
answers "may this PR merge WITHOUT a human approval?" — what the reviewer
verdicts and PR labels now call approval:auto/approval:human. It was
introduced in #704 ("merge authority as a required status check, and one
implementation of the question"), part of the original Tier-1
merge-authority work.
Two rounds of "tier" cleanup have already shipped:
- #971 (design 009 T3, closed/shipped): the reviewer's advisory
tier:1/2/3 labels → risk:{routine,infra,feel}.
- #1077 (closed/shipped, just landed as of this issue): "Tier 0"
wording describing the reviewer bot's own comment-only stage, dropped
across CHARTER.md, DESIGN.md, README.md, notes/reviewer.md,
DEVEL.md, CLAUDE.md, notes/merging.md.
**Both explicitly carved out tier1_authority and "Tier 1"/"Tier 2" prose
as a Non-goal.** #1077's Non-goals section, verbatim:
> The perimeter's "Tier 1"/"Tier 2" merge-authority naming
> (tools/nflib/authority.py's tier1_authority(), "ordinary Tier 1" in
> CLAUDE.md and notes/merging.md, design 009's own "Tier 2
> (tools/nflib/)" reference to the philosophy's hardened tier). Design 009
> deliberately kept this vocabulary — it isn't the leftover this issue is
> about, and renaming it would reopen a decision design 009 already made. A
> future round can revisit it if it ever causes real confusion; this issue
> doesn't argue that case.
That's design_docs/009-the-games-audit-lane.md §5's own ruling: "The word
tier is freed to mean only NINEFOLD_PHILOSOPHY.md's hacky vs hardened
— prose vocabulary, never a label" — but 009 chose to keep "Tier 1"/"Tier 2"
itself as the perimeter's own name for the two merge-authority paths,
alongside that same freed sense. **This issue is Aedan reopening that
decision** — the coexistence is exactly the confusion #1077 fixed for "Tier
0", now recurring for "Tier 1".
Live (non-historical) references, grep -n "tier1_authority\|[Tt]ier[ -]1\b\|[Tt]ier[ -]2\b":
- tools/nflib/authority.py — the function itself (:226, exported at
:69) and ~15 docstring/comment mentions of "Tier 1" (`:18, 242, 245,
282, 292, 345, 352, 401, 445, 474, 629, 636, 675`).
- tools/nflib/perimeter.py — module docstring title (:1: "The Tier-1
merge perimeter…"), and ~7 more prose mentions (`:100-101, 105, 190, 298,
431-432, 634`).
- tools/pr/merge_pr.py — ~20 mentions across the module docstring and
inline comments (`:28, 32, 34, 51, 132, 602, 627, 702-703, 769-770, 808,
830, 833, 1102, 1106, 1131-1132, 1147, 1216, 1235`).
- notes/merging.md:29 — "tier1_authority".
- tools/reviewer/CHARTER.md:226 — "Tier-1 authority".
Rename tier1_authority() to a name built from the live vocabulary
(approval:auto/approval:human) rather than a tier number — e.g.
approval_auto_authority() or unattended_merge_authority() (pick one;
§ Open questions). Update every call site
(tools/pr/merge_pr.py:132,808,1147) and every docstring/comment above to
match, same "drop the number, keep the sense" pattern #1077 used for "Tier
0" — most sites already gloss "Tier 1" as "no human approval"/"approval:auto"
right next to the tier wording, so this is mostly deletion, not new prose.
notes/merging.md and tools/reviewer/CHARTER.md get the same treatment at
their one site each.
Follow #1077's own Non-goals precedent for what NOT to touch:
- design_docs/009-the-games-audit-lane.md and other accepted design docs —
frozen prose, amendments only, never rewritten after acceptance.
- notes/history.md — case law, quotes real history verbatim.
- Any tier=N/tier:N legacy-grammar parsing or its test fixtures
(tools/nflib/verdict.py, tools/nflib/test_data/pr_sample.json,
engine_test.py's LEGACY_TIER_LABELS cases) — unrelated to this
function, must keep parsing old verdicts forever per design 009 T3.
- NINEFOLD_PHILOSOPHY.md's own "tier" usage (hacky-vs-hardened) — the
sense every prior round has explicitly preserved.
Pure rename — no behavior change. grep -n "tier1_authority" tools/ notes/
returns nothing outside test files exercising the renamed symbol under its
new name; ./presubmit.py --all green (particularly
tools/nflib/authority_test.py, tools/pr/merge_pr_test.py,
tools/pr/perimeter_check_test.py, tools/pr/review_now_test.py,
tools/pr/digest_test.py — all currently reference tier1_authority by
name or assert on "Tier 1" strings per the grep above).
One PR — mechanical rename at one cognitive level (E3), same shape as #1077.
Touches tools/nflib/* (governed) so it waits for Aedan's approval
regardless of how it's split; no benefit to splitting further.
Everything under "Follow #1077's own Non-goals precedent" above.
1. Replacement name for tier1_authority(). Candidates:
approval_auto_authority(), unattended_merge_authority(),
no_human_needed(). Default: approval_auto_authority() — matches the
label it decides (approval:auto) most directly. Not worth a review
cycle to pre-negotiate; ships with the dev's best call if unanswered.
2. Whether the module docstring title of perimeter.py ("The Tier-1
merge perimeter…") should also drop "Tier-1" or keep it as a proper
noun now that #1077 established the pattern of dropping tier numbers
entirely. Default: drop it, same as every other site — "The
approval:auto merge perimeter" or equivalent.
None.
No comments.