2026-08-11-admin-cleanup
2026-08-11 · project workspace · path prompts/2026-08-11-admin-cleanup
Prompt prompts/2026-08-11-admin-cleanup/PROMPT.md
ADMIN CLEANUP ROUND
Extends the governance architecture; AGENTS.md rules apply. Read from the public repo at b7207e9, plus the unmerged patch/priorities-and-slop. Dispatch after that branch merges. Confirm current state yourself; pointers are not a spec.
Housekeeping only. Nothing here changes what the repository claims.
A. Close the dispatch-provenance gaps
Three round directories lack their dispatch: 2026-08-11-scrub-round-2, 2026-08-11-contributor-checkers, and — check — 2026-08-11-public-flip-and-scrub, whose dispatch was reconstructed from inline instructions. The maintainer holds the originals and will supply what he has. For each supplied prompt, replace the recorded gap with the verbatim dispatch and drop the not-recoverable note; where nothing is supplied, leave the gap as recorded. Do not paraphrase a dispatch into existence.
B. Delete merged branches
Five branches remain on the remote — feat/contributor-checkers, patch/attribution-provenance-names, rename/alignment-workspace, scrub/round-2, and patch/priorities-and-slop once merged. Confirm each is merged into main, then delete it on the remote. Do not delete anything unmerged; list any that is.
C. Settle the ledger's mutability
DECISIONS.md says settled decisions "are not re-litigated," but the rename round edited a settled entry in place, as no negative ontologies required. The ledger is therefore neither append-only nor freely editable, and the previous round's report recorded both readings without picking one. Settle it in the header:
Settled entries are append-only in substance. Identifiers within them — a renamed path, file, or namespace — are updated in place so the record keeps resolving; anything else that changes lands as a new dated entry.
State it in the terms above unless you find a case it mishandles, in which case say so and propose the fix rather than improvising the wording. Record the clarification as its own dated entry.
D. A failure case for every gate
Two gates have now shipped and passed while checking nothing: the DCO gate counted GitHub's synthetic merge commit and would have failed every pull request, and the attribution gate's first parse accepted the pristine template. Both were caught, and the attribution gate now carries a self-test.
Make it general. In AGENTS.md, under the checker and gate rules: every gate ships a case proving it fails on the null input — the untouched template, the absent field, the empty match — wired into the same self-test the gate already runs, not performed once at review. Then audit the existing gates against it: path_gate, dco, attribution, name_lint, contrib_hygiene, conservativity, check_frozen, audit_axioms, and the registry checker. For each, either point at the existing null-input case or add one. Report the table: gate, null case, where it lives.
This is the most valuable item in this round. A gate that reports green while matching nothing is indistinguishable from a gate that works, and this repository has produced two in a week.
E. Stubs awaiting the author
DECISIONS.md lists three. Do not decide them; make them decidable. For each, state in one or two lines what the choice actually costs now — what changes, what breaks, what it forecloses:
- Whether further leverage frozen trees are registered now or later.
- The name of the leverage forward tree (
forward/). - Which deference documents are canonical.
Report these as a short list the maintainer can answer in a sitting.
F. Consistency sweep
After the priorities round, confirm: no live document, script, or config outside prompts/ and frozen/ refers to OPEN_PROBLEMS.md except the two deliberate pointers into frozen/consolidation_aug9/; the eight required check names in the protection payload still match the CI job names exactly; and tests/run.py invokes every gate script present in tests/. Report each as checked, with the command.
Report
ROUND_REPORT.md per convention, with Outstanding maintainer actions listed first. Section D's table is the report's substance; the rest is a list of what was closed.
Prompt author: Claude Fable 5 (Anthropic), 2026-08-11, in a maintainer-directed session. Dispatched by the maintainer.
Report prompts/2026-08-11-admin-cleanup/REPORT.md
Admin cleanup — report
Dispatch: PROMPT.md beside this file, verbatim.
Outstanding maintainer actions
- Merge this pull request to recover the priorities round. PR #7 was merged into
patch/attribution-provenance-namesat 04:43, after that branch had already squash-merged tomainat 04:40. GitHub marks #7 merged; its content never reachedmain. This branch carries it. Details in §B. - **Then delete
patch/attribution-provenance-namesandpatch/priorities-and-slop.** Held back deliberately — until this merges they are the only remote copies of the priorities round. - Supply the two missing dispatches —
2026-08-11-scrub-round-2and2026-08-11-contributor-checkers. Nothing was supplied with this round, so the gaps stand as recorded. - Answer the three stubs. Each now states what deciding it costs; the deference one is the only one that blocks anything (§E).
- **Consider whether
--recordshould exist.**tests/conservativity.py --recordis the deliberate way to re-baseline the spec shape, replacing the silent auto-write. It is a specification-layer escape hatch; if you would rather have no such flag and edittests/spec_shape.jsonby hand, say so.
D. A failure case for every gate
The round's substance. AGENTS.md gains a standard — Every gate fails on its null input — and each of the nine gates now carries a --self-test run in the same CI job as the gate, and in tests/run.py locally.
| gate | null input | case | where |
|---|---|---|---|
path_gate | empty changed-file list inside a pull request | 8 cases incl. "an unknown path is in neither layer" and "no specification pattern is empty" | tests/path_gate.py --self-test, job path-gate |
dco | no non-merge commits inside a pull request | 5 cases incl. "an empty message is rejected", "a sign-off without an address is rejected" | tests/dco.py --self-test, job dco |
attribution | the untouched pull-request template | 7 cases; "pristine template asserts nothing" is the one that already caught a live defect | tests/attribution.py --self-test, job dco |
name_lint | no Markdown in scope; a name it cannot see | 8 cases incl. "an empty file list fails rather than passing" and three pinning the backtick exemption | tests/name_lint.py --self-test, job python |
contrib_hygiene | zero contributor checkers — the current live state | 5 cases on synthetic modules: missing docstring, third-party import, missing check, nested check | tests/contrib_hygiene.py --self-test, job checkers |
conservativity | missing spec_shape.json; empty spec-file set | 7 cases incl. "the recorded shape exists" and "the word axiom inside an identifier is not matched" | tests/conservativity.py --self-test, job conservativity |
check_frozen | a registry with no entries | 6 cases incl. "a content change moves the digest" and "the live registry is non-empty" | tests/check_frozen.py --self-test, job frozen-integrity |
audit_axioms | no Lean sources; #print axioms naming declarations that do not exist | 7 cases incl. "silence is not a pass" and "an empty source list is a failure, not a skip" | tests/audit_axioms.py --self-test, job lean |
| registry checker | missing PRIORITIES.md; an unfiled item | "missing PRIORITIES.md fails rather than skipping the check", added last round | python3 -m checkers.run --self-test, job checkers |
Four gates had real holes, not just missing tests
The audit was not a formality. Half the gates could pass while checking nothing:
- **
path_gateanddcopassed on an empty input inside a pull request.** Both printed "no pull-request context" and returned 0 when their diff came back empty. On a real pull request an empty diff means the fetch failed, not that the branch is clean — so a broken base fetch silently disabled the layer gate and the sign-off gate together. Both now fail whenGITHUB_BASE_REFis set and the list is empty. - **
conservativityre-baselined itself.** A missingtests/spec_shape.jsoncaused it to write the current shape and return 0 — so deleting the baseline silently re-froze the shape the gate exists to freeze, and reported green doing it. Now a failure, with--recordas the deliberate way to set a baseline. - **
check_frozenverified an empty registry.** Zero entries producedFROZEN DIGESTS VERIFIED: 0 registered inputsand passed, which is what a wiped checksums file looks like from outside. Now a failure.
The two the dispatch cites were caught by a person reading code. These four were caught by looking for the same shape deliberately, which is the argument for the rule.
**The audit of audit_axioms runs on captured output, not on Lean.** Its parsing cases feed recorded lake env lean lines to the regexes rather than invoking a toolchain, so the self-test can run in every job rather than only the one with elan installed. What that exercises is recognition, not elaboration — the live run still re-elaborates every file.
B. Branches — and the priorities round that never landed
Confirming "merged" by branch name was the wrong test, twice. git branch -r --merged reports nothing under squash merges, and both git diff main..branch and the three-dot form report differences for every branch regardless. The test that works is whether each pull request's own merge commit is an ancestor of main:
gh pr view N --json mergeCommit --jq .mergeCommit.oid
git merge-base --is-ancestor <oid> origin/main
| PR | branch | base | merge commit in main? |
|---|---|---|---|
| 1 | flip/public-and-protection | main | yes |
| 2 | scrub/round-2 | main | yes |
| 3 | feat/contributor-checkers | main | yes |
| 4 | rename/alignment-workspace | main | yes |
| 6 | patch/attribution-provenance-names | main | yes |
| 7 | patch/priorities-and-slop | patch/attribution-provenance-names | no |
PR #7 merged into a branch that had already been squash-merged and was a dead end. #6 landed on main at 04:40:21; #7 landed on #6's branch at 04:43:06. GitHub retargets a stacked pull request when its base merges while it is open, and #7 was merged directly against the stale base instead. main still had OPEN_PROBLEMS.md and no PRIORITIES.md.
Recovered by cherry-picking ccf229e onto main; the resulting tree is byte-identical to patch/priorities-and-slop's (003d2c3…), so nothing was lost or re-derived.
This is the stacking trap I set up, and it is worth not repeating. I stacked two rounds on open branches to avoid conflicts, which worked, and then the merge order that the stack required was not the one that happened. A stacked pull request must be merged before its base, or retargeted to main after.
Deleted, with tips recorded so they remain reachable by SHA:
feat/contributor-checkers 2e3dba29c34513eda50a1b225f4e5db13faf3fc1
rename/alignment-workspace c41e6725560769ff028e44457093f3bbf1e9824c
scrub/round-2 996cf925e483a67c5f9c8fb1354c3fcd736fa59b
Not deleted: patch/attribution-provenance-names and patch/priorities-and-slop. Until this pull request merges they hold the only remote copies of the priorities round.
A. Dispatch-provenance gaps
Nothing was supplied with this round, so nothing was replaced. The two gaps stand as recorded, and neither was paraphrased.
The third directory the dispatch flagged for checking, 2026-08-11-public-flip-and-scrub, is not a gap of the same kind. Its PROMPT.md quotes the maintainer's three inline instructions verbatim — the dispatch for that round was those instructions, and there is no separate document that went missing. It already says so. Nothing to replace.
C. The ledger's mutability
Adopted in the dispatch's terms, in the header rather than as an entry so it is read before the entries are, with a sentence on why: a pointer that no longer resolves is not history, it is a dead link, while a decision that turned out wrong is corrected by the entry superseding it and not by editing the record of having made it. Recorded as its own dated entry.
One case the wording does not cover, reported rather than improvised. Removing something from a settled entry for privacy — a name, a personal detail — is neither an identifier update nor something a later entry can fix by appending: you cannot un-publish by adding text. It has not arisen, and this ledger is deliberately exempt from the name lint, which is why it has not. If it does, the header needs a third clause. Proposed shape, not applied:
A passage removed for privacy is removed in place, and the removal is recorded as a dated entry that does not restate what was removed.
E. The three stubs, with what deciding them costs
Rewritten in DECISIONS.md so each can be answered without reconstructing context. Only the third blocks anything.
- Further leverage frozen trees — register now or later. Registering costs a digest pass and makes the material citable and immutable from that moment. Waiting costs nothing today and risks the material drifting on your machine, so that what eventually gets frozen is a later version than the one the current work was done against. Nothing is blocked either way.
- **The name
forward/.** Confirming costs nothing. Changing it is onegit mv, one file rename, and six prose references today — and the cost rises with every round that lands work in the tree or cites a path into it. The next leverage round is the first that would. - Which deference documents are canonical. This one forecloses.
projects/deference/kernel/is reserved and empty andnotes/holds a pointer and no documents, so a round dispatched against the deference line has nothing in-repo to work from — it would have to be handed its inputs in the dispatch, which is the provenance gap the convention exists to close.
F. Consistency sweep
**F1 — OPEN_PROBLEMS.md references.** Not clean in the terms the dispatch expected, and correctly so:
git grep -In "OPEN_PROBLEMS" -- . ':!prompts' ':!frozen'
Six hits, not two. Two are the deliberate pointers into frozen/consolidation_aug9/ — PRIORITIES.md:32 and projects/leverage/README.md:40. The other four are under projects/leverage/forward/attic/, which the priorities dispatch explicitly excluded as retired material. Correct as they stand; the dispatch's "except the two" undercounted by not accounting for its own exclusion.
F2 — required checks against job names. Exact match, both against the payload and against live protection:
python3 -c "…json.loads(.github/branch-protection.json) vs ^ name: in ci.yml"
gh api repos/A-M-Berns/alignment-workspace/branches/main/protection \
--jq '.required_status_checks.contexts[]'
8 required contexts, 8 CI job names, none required-but-absent, none job-but-not-required, and the live protection list matches the payload string-for-string.
**F3 — tests/run.py invokes every gate script.** It did not. tests/conservativity.py was never invoked locally at all, and tests/audit_axioms.py was not invoked even under WORKSPACE_LEAN. Both wired in — conservativity unconditionally, the axiom audit after a successful build.
Rather than assert this stays true, it is now checked: coverage() in tests/run.py fails if any tests/*.py is neither invoked nor listed in PULL_REQUEST_ONLY, which names the three gates whose real form needs a pull request. Output:
GATE COVERAGE: 8 gate scripts, all invoked (3 self-test only — no local form)
Gates
python3 tests/run.py green, now including nine self-tests, gate coverage, conservativity, the name lint and contrib hygiene. Lean is unaffected — this round touches no Lean — and runs in CI.
Attribution
| prompt author | Claude Fable 5 (Anthropic) |
| executor | Claude Opus 5 (Anthropic) |
| date | 2026-08-11 |
Claims it registered
None.
Items it filed or answered
None recorded in the index.
Nodes pointing at it
None.