Skip to content

Bucket the backlog and refresh the divergence ledger - #535

Merged
ptr727 merged 5 commits into
developfrom
todo-buckets-and-ledger-refresh
Aug 3, 2026
Merged

Bucket the backlog and refresh the divergence ledger#535
ptr727 merged 5 commits into
developfrom
todo-buckets-and-ledger-refresh

Conversation

@ptr727

@ptr727 ptr727 commented Aug 3, 2026

Copy link
Copy Markdown
Owner

Two files, one session's findings.

TODO.md

A flat list of twenty entries had grown past the point where the next action was visible in it. It is now grouped by the surface each entry changes, since an entry's cost is mostly set by what it touches, and every open issue is named on the entry covering the same ground so the two are read together rather than worked twice.

A new opening section records five issues verified complete against the tree, each with the commit that fixed it, so closing them cites evidence rather than assertion. Those five are #509, #490, #489, #379 and #353, and each was re-checked line by line rather than taken at its filed state.

Three new entries:

  • The prose_lint.py scope floor, promoted to lead its bucket, because every verdict below it is only worth reading once the gate can prove it read something.
  • An agent never assumes a Docker image is still present locally, since a background prune can remove one between two commands of the same session. The entry states the honest limit, that docker run re-pulls an absent registry tag by itself, so the cases that actually break are a locally built tag and any command that branches on the image being present.
  • The gh-write-guard newline defect found while running this sweep. _git_subcommand_arglists ends a git push argument list at && but not at a newline, so a push followed by any later line resolves that line's tokens as refspecs. Measured: one branch alone, five with a following gh pr create whose base is develop. It over-blocks rather than under-blocks, so it is not a safety hole, but the denial tells the agent it is bypassing a branch rule with admin power when it is pushing an ordinary feature branch, and a safety hook that cries wolf stops being read.

reports/divergences.md

Regenerated. The committed copy was dated 2026-07-22 and predated the router split, so it still filed "Repository Boundaries and Write Safety", "Git and Commit Rules" and "Verification Discipline" under AGENTS.md when all three now live in GOVERNANCE.md. It was handing out a work list measured against a tree that no longer exists.

The refresh corrected the propagation picture materially: only two repos carry GOVERNANCE.md at all, verified against the live repos rather than inferred. The router split never reached the fleet, so what reads as a section re-vendor is, for seventeen repos, adopting the split itself. That is #305's problem rather than a sweep, and the entry says so.

TODO.md was a flat list of twenty entries that had grown past the point
where the next action was visible in it. It is now grouped by the surface
each entry changes, since an entry's cost is mostly set by what it touches,
and every open issue is named on the entry that covers the same ground.

Five issues were verified complete against the tree and are recorded with
the commits that fixed them, so closing them cites evidence rather than
assertion. Three new entries: the prose_lint scope floor, the rule that an
agent never assumes a Docker image is still present locally, and the
gh-write-guard newline defect.

reports/divergences.md is regenerated. The committed copy predated the
router split and still filed three sections under AGENTS.md that now live
in GOVERNANCE.md, so it was handing out a work list measured against a tree
that no longer exists. The refresh corrected the propagation picture: only
two repos carry GOVERNANCE.md at all, so the split never reached the fleet.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 3, 2026 16:58

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the repo’s operational tracking docs by reorganizing the backlog into clearer “buckets” and regenerating the fleet divergence ledger to reflect the current governance/router split.

Changes:

  • Restructures TODO.md into grouped sections (e.g., verified-complete items, gate-honesty work, carried-content propagation).
  • Adds an explicit “Verified Complete, Awaiting Close” section with evidence-style notes tied to specific issues/commits.
  • Regenerates reports/divergences.md to align with the post-split GOVERNANCE.md section layout and updated re-vendor targets.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
TODO.md Re-buckets and annotates the repo backlog, adding a verified-complete section and regrouping work by affected surface area.
reports/divergences.md Regenerated divergence ledger reflecting the updated governance section ownership and current re-vendor targets.

Comment thread reports/divergences.md Outdated
The disposition read "in these three" while the report rendered two names,
because PhotoCleaner resolved and the generated line drops a resolved repo
while the reason text stayed as written. Correcting the number to two would
go stale the same way the next time a repo converges, so the count is gone
rather than fixed.

The fix belongs in spec/divergences.json rather than in the report, since
reports/divergences.md is generated and a hand edit there is undone by the
next regeneration.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 3, 2026 17:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

Suppressed comments (1)

spec/divergences.json:7

  • The PR description says this change is "Two files", but this PR also updates the divergence ledger source (spec/divergences.json) that drives the regenerated reports/divergences.md. Please update the PR description to mention this file explicitly so reviewers know the report change is sourced and intentional.
        { "path": ".editorconfig-checker.json", "repos": ["HomeAutomation-Config", "HolidayLights"], "disposition": "accepted", "reason": "Both carry a legitimate repo-specific Exclude list (HomeAutomation-Config excludes a Vantage/ subtree, HolidayLights excludes .fseq sequence files). The uniform Disable block is carried intent-equivalent. Exclude is inherently repo-local, which is why the unit is intent, not verbatim.", "tracking": null },
        { "path": ".markdownlint-cli2.jsonc", "repos": ["aiopurpleair", "PhotoCleaner", "AudioCleaner"], "disposition": "re-vendor", "reason": "Verbatim config held as a hand-modified copy rather than a past hub revision. Restore the current canonical.", "tracking": null },
        { "path": "repo-config/configure.sh", "repos": ["NxWitness", "aiopurpleair", "homeassistant-purpleair", "ESPHome-NonRoot", "VSCode-Server-DotNetCore", "LanguageTags"], "disposition": "re-vendor", "reason": "The hub adopted the fleet check mode into the configure.sh canonical (apply plus a payload-driven check). These carry an older design that predates it (five an older check-mode fork with ruleset-*.json filenames and no registry, LanguageTags an older apply-only copy). Re-vendor the new canonical to converge them. The stale copies re-vendor mechanically. NxWitness may keep a thin repo-specific wrapper for its hardcoded Docker Hub secret checks, which the repo-agnostic canonical leaves as a manual-verify note.", "tracking": null }

AUDIT.md section 8 governs a note's end of life, saying it records a current
deviation and is deleted once resolved, and says nothing about its content at
the moment an agent authors one. PhotoCleaner is the worked example: asked to
self-audit and reconcile, the agent wrote a completion record, the date a past
version published, and a description of the repo conforming to spec. None is a
current deviation, and nothing it was given forbids any of the three, so this
is an incomplete instruction rather than an agent ignoring one.

The detector has the matching gap. It flags a stale note by matching words
that assert outstanding work, which is the opposite polarity to all three of
those notes, and it only runs when the repo audits clean, which is the state
where the problem has already gone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 3, 2026 18:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

The re-bucketing rewrote the whole file rather than editing it in place, and
the write emitted LF into a repo whose editorconfig sets crlf as the default
for every file with no override. editorconfig-checker caught it in CI, which
is the check working, but the cause is worth naming: a whole-file rewrite
discards the line endings an in-place edit would have preserved, so the risk
scales with how much of a file is replaced rather than with how much of it
changed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

Suppressed comments (1)

reports/divergences.md:27

  • reports/divergences.md reports "GOVERNANCE.md > Representative Data in Agent-Authored Text" as "hand-modified" for Financial-Modeling/PhotoCleaner, but spec/fidelity_honesty.py currently puts a downstream missing verbatim section into the same differs bucket as a true hand-edit (region is None -> spread["differs"], then rendered as "hand-modified"). For newly introduced verbatim sections, any downstream repo that simply hasn't received the section yet will always show up as "hand-modified" (not "stale") because absent sections are skipped when building history. Consider splitting this case out (e.g., missing_section) and rendering it as "missing section" (or treating it as stale) so the report doesn't imply manual edits when the section is merely absent.
- **AGENTS.md > Context and Delegation Discipline** - hand-modified in AudioCleaner, DevKitCIoT, ESPHome-Config, ESPHome-NonRoot, HolidayLights, HomeAssistant-Config, HomeAutomation-Config, KiCadLibrary, LanguageTags, MediaTools, NxWitness, PlexCleaner, Utilities, VSCode-Server-DotNetCore, Vantage-Config, aiopurpleair, homeassistant-purpleair (verbatim canonical)
- **AGENTS.md > Where the Rules Live** - hand-modified in AudioCleaner, DevKitCIoT, ESPHome-Config, ESPHome-NonRoot, HolidayLights, HomeAssistant-Config, HomeAutomation-Config, KiCadLibrary, LanguageTags, MediaTools, NxWitness, PlexCleaner, Utilities, VSCode-Server-DotNetCore, Vantage-Config, aiopurpleair, homeassistant-purpleair (verbatim canonical)
- **GOVERNANCE.md > Representative Data in Agent-Authored Text** - hand-modified in Financial-Modeling, PhotoCleaner (verbatim canonical)

The disposition said NxWitness may keep a thin repo-specific wrapper for its
hardcoded secret checks. Measured rather than left open: the fork asserts four
secret names, and spec/audit.py checks the spec/secrets.json baseline plus
that repo's registry requiredSecrets, which is a strict superset of the four
and additionally covers CODECOV_TOKEN that the fork misses. Re-vendoring loses
no coverage and gains some, so no wrapper is owed.

The disposition also now records what actually blocks these repos, which the
sweep found the hard way. Five of the six carry ruleset-develop.json and
ruleset-main.json against the canonical's develop.json and main.json, so each
needs the payload migration before it can take the script at all, and a
re-vendor without it leaves apply and check aborting on payloads that do not
exist. NxWitness is the fifth, missed at first because its configure.sh was
never in its pull request so its payload names went unchecked.

Report regenerated so it matches its source.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 3, 2026 18:26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

@ptr727

ptr727 commented Aug 3, 2026

Copy link
Copy Markdown
Owner Author

Answering the suppressed finding on reports/divergences.md:27, which carries no thread. Quoting it, since there is nowhere to reply in-line:

spec/fidelity_honesty.py currently puts a downstream missing verbatim section into the same differs bucket as a true hand-edit (region is None -> spread["differs"], then rendered as "hand-modified") ... Consider splitting this case out (e.g., missing_section) and rendering it as "missing section".

Correct, and it matters more than a label. The report currently says "hand-modified in AudioCleaner, DevKitCIoT, ESPHome-Config, ..." for AGENTS.md > Context and Delegation Discipline across seventeen repos, and those repos have not hand-edited anything. They simply do not carry the section, because they still hold the pre-split monolithic AGENTS.md. The two states call for opposite responses: a hand-edit is drift to reconcile against a local decision, and an absent section is a baseline that never arrived.

Independently confirmed while this pull request was being prepared, by a direct read rather than from the report: GOVERNANCE.md is absent from PlexCleaner, Utilities, MediaTools, NxWitness, AudioCleaner, LanguageTags, HomeAssistant-Config and aiopurpleair, and present only in PhotoCleaner and Financial-Modeling. So the conclusion drawn from the report was right and the word it was drawn from was wrong, which is the more dangerous shape of the two.

Fixing it is a generator change rather than a data change, so it is not folded in here. This pull request regenerates the report faithfully from the current code, and the mislabel lives in spec/fidelity_honesty.py where region is None falls into differs. Splitting a missing_section bucket changes every row that renders it, which wants its own diff and its own review rather than riding inside a backlog-and-ledger change.

Queued as a follow-up, and worth stating in the entry: a newly introduced verbatim section will report as "hand-modified" in every repo on the day it lands, which is precisely the case the new GOVERNANCE.md > Representative Data in Agent-Authored Text row shows today.

@ptr727
ptr727 merged commit bf746aa into develop Aug 3, 2026
7 checks passed
@ptr727
ptr727 deleted the todo-buckets-and-ledger-refresh branch August 3, 2026 18:41
ptr727 added a commit that referenced this pull request Aug 3, 2026
…541)

Follow-up to the suppressed finding on #535, which is now merged. That
finding was correct and pointed at a defect with a measurable cost.

## The defect

`spec/fidelity_honesty.py` put a verbatim section whose heading is
missing downstream into the same `differs` bucket as a genuine local
edit (`region is None` -> `spread["differs"]`), and the report rendered
both as **"hand-modified"**.

The two states want opposite responses. A hand-edit is drift to
reconcile against a local decision someone made. An absence is a section
that never arrived, which is carried. Calling the second one the first
sends a reader looking for decisions that were never taken.

## What it actually produced

Seventeen repos were reported as having hand-modified `AGENTS.md >
Context and Delegation Discipline` and `Where the Rules Live`. None of
them edited anything: they still hold the pre-split monolithic
`AGENTS.md`, so the sections are simply not there.

**That claim was quoted as evidence in this repo's own backlog work
before a reviewer caught it.** The conclusion drawn from it happened to
be right, because absence was separately confirmed by direct reads
against the live repos, but the word it was drawn from was wrong, which
is the more dangerous shape.

There is a second-order effect the finding also named: an absent section
contributes nothing to the `history` set, so it can never be classified
`stale`. That means **every newly added verbatim section reports as
hand-modified across the whole fleet on the day it lands**. The new
`GOVERNANCE.md > Representative Data in Agent-Authored Text` row was
showing exactly that.

## The change

A new `absent` bucket, with three consequences handled beyond the label
itself:

- **It no longer disqualifies an `intent` unit from promotion.** A
missing section is not evidence of a local decision, so it should not
block a unit from being promoted to `verbatim`.
- **It still counts as a live divergence for burn-down**, because the
section is genuinely owed to that repo.
- **The untriaged section reports the two kinds separately**, since one
is fixed by reconciling and the other by carrying.

## Result

```diff
-- **AGENTS.md > Where the Rules Live** - hand-modified in AudioCleaner, DevKitCIoT, ...
+- **AGENTS.md > Where the Rules Live** - **not carried** by AudioCleaner, DevKitCIoT, ..., so the section never arrived rather than being edited
```

Three rows change, covering nineteen repo-section pairs.

## Verification

- `spec/validate.py`: OK, 21 cataloged
- `prose_lint --diff`: clean
- editorconfig: clean, CRLF preserved on the regenerated report
- Report regenerated from a live fleet pass so it matches its source

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
ptr727 added a commit that referenced this pull request Aug 3, 2026
…ndor groundwork (#542)

Six commits, all from one session. Merged as a **merge commit**, never
squashed, per the branching model.

| Commit | PR | What it does |
| --- | --- | --- |
| `1ab9b32` | #537 | Deletes three stale PhotoCleaner `driftNotes` that
described finished work |
| `bf746aa` | #535 | Buckets `TODO.md` by the surface each entry
changes, records five issues verified complete, refreshes the divergence
ledger |
| `69276d1` | #536 | Adds the byte-locked `AGENTS.md` "Fleet Bootstrap"
section, the host-wide `fleet-bootstrap` block, and the `AUDIT.md`
routing that sends an un-stood-up repo to `STANDUP.md` first |
| `530dc0d` | #539 | Records two `gh-write-guard` limits found by
running it: a write inside a script is unseen, and a push followed by a
newline over-blocks |
| `5f4c17f` | #540 | Makes `configure.sh check` verify what the payloads
declare, closing a false clean where a `jq` failure left every setting
reported as passing while nothing was compared |
| `a549572` | #541 | Reports a verbatim section that never arrived as
**absent** rather than as hand-modified |

## Why this promotion matters more than most

Two of these change what the fleet is measured against, so until they
reach `main` every downstream audit compares against ground truth that
predates them.

**#536 is the one with reach.** A downstream agent had no way to
discover this repository. `AGENTS.md` is carried at `intent`, and the
hub's only self-reference described *the hub*, which is false about a
downstream repo, so an agent adapting the file correctly deleted it.
Four repos now hold no hub reference at all and one holds no `AGENTS.md`
either. The replacement is `verbatim` so adaptation cannot remove it,
declared in `spec/files.json` and classified in `spec/section-model.md`
so the audit reports its absence as drift rather than losing it
silently.

**#540 closes a false clean.** `check_settings` streamed its payload
from a process substitution, and a `jq` failure there leaves the loop
body unexecuted without tripping `set -e`. Every static setting reported
as checked and passing while nothing was compared. Verified by negative
test rather than by a clean pass: a malformed `settings.json` now fails
with exit 1, an extra live rule fails the rule-set assertion, and a
changed `copilot_code_review` parameter fails the parameters assertion.

**#541 corrects a report that was actively misleading.** It accused
seventeen repos of hand-editing `AGENTS.md` sections they had never been
given. They still hold the pre-split monolithic file, so the sections
are simply absent. A hand-edit is reconciled against a local decision,
an absence is carried, and the report was naming the wrong one.

## Fleet state behind this

Seventeen downstream re-vendor pull requests merged alongside this work,
each gate-checked at merge time and each verified after. Four repos had
`configure.sh` withdrawn from their re-vendor when review found they
carry `ruleset-*.json` payload names the canonical does not resolve,
which would have left `apply` and `check` aborting on files that do not
exist. That payload migration is still owed and is tracked in `TODO.md`.

## Expected immediately after this merges

The divergence ledger currently reports the hub itself as not carrying
"Fleet Bootstrap" and as owing a `configure.sh` re-vendor. That is the
ledger reading each repo's `main`, honestly, before this promotion.
Regenerating after the merge is what makes the report meaningful again,
and the `configure.sh` re-vendor list will collapse as repos take the
corrected script.

## Verification

`spec/validate.py` OK (21 cataloged), diff-scoped `prose_lint` clean,
`markdownlint-cli2` clean, editorconfig clean, `gh-write-guard
--selftest` PASS, 157 `prose_lint` unit tests pass.
ptr727 added a commit that referenced this pull request Aug 7, 2026
## Why

Selecting the next work item meant re-deriving the grouping every
session. Entries were grouped by the surface they change, which is
#535's convention and answers what a change costs, while the working
question is what fits one pull request. That analysis is what the file
should carry forward and did not.

Three defects made it unsafe to select from, each verified against
`develop` at `3d1a0b1`:

- **Three open issues appeared nowhere in it.** A pass reading only this
file could not see #538, #550 or #557.
- **Two open issues were already fixed.** Both are now closed with their
evidence quoted, see below.
- **Two research artifacts contradicted the tree.** The re-vendor entry
called `repo-config/configure.sh` carried `verbatim` with `appliesTo:
"*"`, while `spec/files.json` no longer declares it and
`spec/divergences.json` dispositions it `retire`.
`reports/divergences.md` still rendered it under `re-vendor` across six
repos, so the committed report disagreed with its own ledger.

## What changed

A `###` heading under `Work Clusters` is one pull request. 20 clusters,
28 entries, after the follow-up commit retired one. The #535 rationale
is not discarded, it moves from an organizing axis to a per-cluster
`Touches` and `Cost` field, which states more than the old heading
implied: a cluster confined to one surface says so in a clause and a
cluster spanning two states both.

An entry carries `Blocked by`, `Issue` and `Checked` exactly once each,
in that order, and never omits one, because an omitted field reads as
unknown rather than as none. `Checked` is a per-entry freshness anchor
naming the branch, commit and date a claim was last read against the
tree, replacing a file-level anchor that already carried two commits for
two passes and could not carry a third. `Open` states a decision a
future session makes, `Settled` states a finding it does not re-derive,
and a `Settled` bullet carries a number, a proper name, or a rejected
alternative.

Two structural slots are new:

- **`Fleet Sweeps`** holds work landing on a downstream visit. It had no
home, which left #353, #379 and #489 under a heading promising a close
they explicitly could not take. Each item carries `Hub state`,
`Outstanding` and `Rides with`, so six repetitions of naming the same
visit become one manifest. It records the batching preference outright,
that the fleet is caught up periodically rather than after every hub
change, and names Blog as the pilot.
- **`Recorded for the Maintainer`** holds issue actions that are the
maintainer's to take, each carrying the evidence so it is one action
rather than a re-derivation.

`How to Select the Next Item` states the procedure. Step 1 is confirming
every open issue has an entry, which is the honest maximum a
hand-maintained file gives and the reason it comes first.

## Two overlaps folded in

- **#577 and the registry-description entry are one decision.**
Declaring the description in `registry/repos.json` makes every mirror
read a field rather than parse a paragraph, so taking #577 first means
writing an extraction rule the registry change then deletes. They are
now one cluster with the sequencing stated.
- **#365 and #483 are one host visit.** The rollout needs the tooling
matrix to be repeatable and the matrix is only worth filling if the
rollout uses it.

## A generated ledger was considered and rejected

`spec/divergences.json` earns its generator by joining a curated ledger
against live fleet reality and rendering `UNTRIAGED` for anything live
the ledger missed. A backlog has no such reality to join against, and
the only mechanizable join is issue open or closed state, which is step
1 of the procedure. What is given up is stated in the file rather than
glossed: no enum enforcement, and no automatic surfacing of an open
issue with no entry, which is exactly the #538, #550 and #557 failure.
The bold-label template stays parseable, so a later checker asserting
every `Checked` commit resolves is buildable without re-shaping the
file.

## Sweep obligations

`spec/readme-structure.md` said a `TODO.md` "opens with a `# TODO`
heading and one line saying what it holds, then a flat bullet list".
#535 already contradicted both clauses. It now states the minimum rather
than the shape, and says this repo's file is a worked example rather
than a template every repo adopts, since a five-line downstream backlog
needs no selection procedure. That file is not in `spec/files.json`, so
the edit costs no re-vendor.

`spec/section-model.md`, `STANDUP.md` and `README.md` describe the
file's purpose without asserting its shape, verified clean and recorded
here so the sweep is done rather than skipped.
`host-setup/agent-safety/README.md` ends the write-guard note with
"Tracked in `TODO.md`", still true.

## Ledger regenerated

`reports/divergences.md` now renders `repo-config/configure.sh` under
`retire` rather than `re-vendor`, resolving the contradiction.
Regenerating it also **disproved a claim written during this pass**:
Blog is one of two repos carrying `AGENTS.md` "Fleet Bootstrap", not the
only one. HomeAutomation-Config carries it too, and being `operational`
it exercises the direct-to-`develop` path rather than the pull request
one, which the pilot note now records as the second visit worth making
rather than the first.

A second correction, to #521's own claim: three merge-bot jobs carry
both `contents: write` and `pull-requests: write` and the fourth carries
`pull-requests: write` alone, so the issue's "all four" is one job wide.
The entry records this rather than repeating the issue.

## Issues closed

- **#552** closed. #572 landed `template_ref_outside_verbatim` in
`spec/audit.py`, excising verbatim regions by position before the
coordination-reference scan, with eight self-test cases. Positional
excision rather than content removal is required by the fenced-copy
case, since removing extracted text would delete a fenced copy along
with the real region and the scan would fail open.
- **#538** closed. Complete on all three points, checked one at a time:
the whole `parameters` object of every parameterized rule is compared
with keys and set-like arrays sorted on both sides, the rule-type set is
compared in both directions, and the header states what check verifies
and names what stays unaudited.

## Follow-up: the file's own procedure applied to itself

`6bed2d9` is the first exercise of step 9, and it is also what gave this
pull request the CI run it never had, since the whole thing opened
during the Actions outage and a rollup does not re-fire on its own.

`9d85941` merged "Reaching the Hub in Your Own Checkout" whole, so the
cluster is deleted rather than annotated and nothing moves out of it.
Each of its four entries was re-read against `develop` before the
deletion rather than trusted to the merge: the checkout-isolation rule
and the stale-clone read rule in `GOVERNANCE.md`, the hub definition in
`AGENTS.md` "Fleet Bootstrap", the six terms in `README.md`, and the
hub-script pointers in `.github/copilot-instructions.md`.

#557 and #579 take its place under "Verified Complete, Awaiting Close"
citing that commit, since both close on the `develop` to `main`
promotion rather than on the merge that completed them. The two
"Recorded for the Maintainer" comments they subsume go with them,
because a recorded action saying an issue stays open until a cluster
lands is a stale instruction once the cluster has landed. That section
now holds two items rather than four.

Two entries left the same section for the opposite reason. #509 and #490
were closed on 2026-08-03, three days before the clustering commit, so a
section whose entire subject is what still awaits a close was carrying
two entries that had already had one. Their link definitions stay, since
other clusters still cite both issues.

Four definitions the deletions orphaned go too, `issue-552`, `pr-572`,
`pr-588` and `workflow`, along with the pull request block left holding
none. MD053 is enabled by default, so an unused definition is a lint
failure rather than a spare, and the reference-and-definition audit in
the verification list above was re-run rather than assumed to still
hold.

## Verification

- `python3 scripts/prose_lint.py . --diff origin/develop` clean, and
`TODO.md` holds 0 violations under the default rules as it did before.
- `python3 spec/validate.py` reports 22 cataloged, 0 backlog.
- markdownlint-cli2 and editorconfig-checker clean on all three files,
CRLF preserved, and both re-run on `TODO.md` after `6bed2d9`.
- Every link reference is defined and every definition is cited, with
each block sorted by reference name.
- All 28 cluster entries carry the three mandatory fields in order,
checked mechanically.
- The selection procedure was walked end to end against the file, and
names a cluster from 5 KB of headings and `State` lines without opening
any research.

Note the file grew, 61 KB to 73 KB, rather than compressing. Three
issues that had no entry were added along with the procedure and the
per-entry anchors. The metric that moved is the one selection depends
on, which is the 5 KB a re-select actually reads.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants