Exempt a verbatim section from the coordination-reference scan - #572
Merged
Conversation
Found by the Blog re-audit in #571 and recorded there as escalation 1. The rule bans a reference to the template repo in any carried file, on the reasoning that the coordination flow is machinery a consumer should not see. `AGENTS.md` "Fleet Bootstrap" is byte-locked fleet-wide and its first sentence names the hub by path, because saying where the canonical rules live is that section's entire function: it is what an agent reads in a repository whose carried copies are stale, partial, or absent, which is exactly when nothing else present can say it. So the two rules contradicted each other. A repository carrying the current canonical was flagged for holding a section the hub requires it to hold, byte for byte, and the only way to clear the finding was to edit that section and fail the verbatim check instead. The finding was unclearable by construction, and it was going to spread rather than stay a curiosity, since every repository picks it up as the carry propagates. ## Three surfaces stated the rule, so three change - `spec/audit.py` excises a file's verbatim sections before looking for the name, via a new `template_ref_outside_verbatim` helper. Deriving the exemption from the declared verbatim list rather than hardcoding one heading means a future verbatim section that must name the hub is covered without a second fix. - `GOVERNANCE.md` "Documentation Style Conventions" carries the exception, its reason, and its boundary. - `recurring.norepoxref` in `spec/project-types.json` carries the same, since that is the check an auditor judges by hand and a tool fix that leaves the written rule contradicting it has fixed nothing. The exception stops at the region boundary. A repository naming the destination in prose it owns is still flagged, which is the point. A reference that reaches a verbatim section is a defect in the canonical, fixed once at the source rather than reported against every repository carrying it. ## Verification Six offline cases in `--selftest`, covering the exempt and non-exempt positions, a document with nothing declared verbatim, a re-cased heading, and a CRLF document, since `extract_section` normalizes EOLs while carried files are CRLF on this fleet and excision has to survive that. Old versus new predicate run across all 21 non-hub cataloged repositories: it clears exactly two findings, both `AGENTS.md` on the two repositories that carry the current Fleet Bootstrap, and keeps the other eleven. Live runs agree, with Blog losing the false positive and its seven genuine verbatim drifts unchanged, and Utilities keeping its genuine one. The scan also moved into the file loop, so it reads content already fetched for the section checks instead of re-fetching all three files, and reads the same selector-resolved verbatim list those checks used. The conformance matrix note claiming the check has no exemption is updated in the same pass rather than left to contradict the code. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR resolves a contradiction between the “no coordination references in carried files” rule and the byte-locked AGENTS.md “Fleet Bootstrap” verbatim section by exempting verbatim regions from the template-repo reference scan.
Changes:
- Updates
spec/audit.pyto scan for the hub name only outside selector-resolved verbatim sections (and adds--selftestcoverage for the new behavior). - Documents the exemption and its boundary in
GOVERNANCE.mdand therecurring.norepoxrefcheck text inspec/project-types.json. - Updates
reports/conformance-matrix.mdto reflect that the contradiction is fixed and where.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| spec/audit.py | Implements verbatim-section excision for the coordination-reference scan and adds self-tests. |
| spec/project-types.json | Updates the human-audited check text to match the new exception and boundary. |
| GOVERNANCE.md | Records the exemption rationale and explicitly scopes it to the verbatim region. |
| reports/conformance-matrix.md | Updates the matrix note to reflect the scan/rule updates and outcomes. |
From the Copilot review on #572. The scan removed each verbatim section by deleting the extracted text with str.replace, which removes every occurrence rather than the one region it came from. The review flagged it as imprecise. It is worse than imprecise: it fails open. A copy of the section inside a fenced code block is not a heading, so it is prose the repository owns and a hub reference in it must be flagged. extract_section correctly skips the fence and returns the real region, but deleting that text then removes the fenced copy as well, and the reference disappears from the scan. Demonstrated on the fixture now in the self-test: the old expression returns False where the new one returns True. That is the one arrangement a repository could have used to carry the reference anywhere in a document it owns. strip_sections replaces the extract-then-delete pass and removes the named regions positionally in a single walk, using the same fence and sibling-H2 rules extract_section uses, so the two agree on where a section starts and stops. Two cases added, eight in total. The other new one records that a heading appearing twice excises both regions, which is correct rather than a hole, since both are that section by name. It is written down because it looks like the same bug and is not. Fleet verdicts are unchanged: the same two findings clear and the same eleven are kept. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ptr727
added a commit
that referenced
this pull request
Aug 6, 2026
…574) Promotes the nine commits `develop` has carried since the previous promotion (#555) to `main`. Merge commit only, no squash, and `develop` is not deleted. ## What lands - **#560** Standardize the static-site-deploy repo type and its destination, including the deploy-verification guarantee and a retention rule that records which side owns the prune. - **#561** Ask for a blocked decision instead of reporting it, and scope the clickable-link rule to a surface that renders markdown. - **#564** Read a suppressed section nested inside the review-details wrapper, so `scripts/pr_review.py` stops reporting a clean round over findings that reach no thread. - **#566** Settle Markdown capitalization in `CODESTYLE.md`, and fix the two `TODO.md` prose defects the digest defect had hidden. - **#568** Check a `driftNote` on every run rather than only on an otherwise clean audit, and state what the audit does not evaluate. - **#569** Name who trips the production ref gate, and state that a harness refusal is a different thing from the maintainer's permission and is not lifted by it. - **#571** Re-audit `ptr727/Blog` against the hugo type and bump the conformance matrix. - **#573** Scope the semicolon exemption to the sentence its list lives in, with the 44 newly reported occurrences recorded on #519 rather than swept here. - **#572** Exempt a verbatim section from the coordination-reference scan. ## Issues closed Fixes #562. Closes #565. The closing keywords sit on this promotion rather than on the feature pull requests, because GitHub fires them only on a merge into the default branch. #456, #558, #563, #567, and #570 are already closed against their merged fixes. ## Verification `git merge-tree` reports no conflict between `origin/main` and `origin/develop`, so this promotion needs no throwaway resolution branch. Every constituent pull request merged green with its review loop closed.
This was referenced Aug 6, 2026
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Found by the Blog re-audit in #571 and recorded there as escalation 1.
The contradiction
The rule bans a reference to the template repo in any carried file, because the coordination flow is machinery a consumer should not see.
AGENTS.md"Fleet Bootstrap" is byte-locked fleet-wide and its first sentence names the hub by path, because saying where the canonical rules live is that section's entire function. It is what an agent reads in a repository whose carried copies are stale, partial, or absent, which is precisely when nothing else present can say it.The two rules therefore contradicted each other. A repository carrying the current canonical was flagged for holding a section the hub requires it to hold, byte for byte, and the only way to clear the finding was to edit that section and fail the verbatim check instead.
The finding was unclearable by construction, and it was going to spread rather than stay a curiosity, since every repository picks it up as the carry propagates. Two repositories had reached it already.
Three surfaces stated the rule, so three change
spec/audit.pytemplate_ref_outside_verbatimhelper excises a file's verbatim sections before looking for the nameGOVERNANCE.md"Documentation Style Conventions"recurring.norepoxrefinspec/project-types.jsonA tool fix that left the written rule contradicting it would have fixed nothing, which is why all three move together.
The exemption is derived from the declared verbatim list rather than hardcoded to one heading, so a future verbatim section that must name the hub is covered without a second fix.
The exception stops at the region boundary. A repository naming the destination in prose it owns is still flagged, which is the point. A reference that reaches a verbatim section is a defect in the canonical, fixed once at the source rather than reported against every repository carrying it.
Verification
Six offline cases in
--selftest, covering the exempt and non-exempt positions, a document with nothing declared verbatim, a re-cased heading, and a CRLF document. The last matters becauseextract_sectionnormalizes EOLs while carried files are CRLF on this fleet, so excision has to survive that.Old versus new predicate across all 21 non-hub cataloged repositories. It clears exactly two findings, both
AGENTS.md, on the two repositories carrying the current Fleet Bootstrap, and keeps the other eleven:Live runs agree. Blog loses the false positive with its seven genuine verbatim drifts unchanged, and Utilities keeps its genuine one.
Incidental
The scan moved into the file loop, so it reads content already fetched for the section checks instead of re-fetching all three files per repository, and reads the same selector-resolved verbatim list those checks were judged against.
The conformance matrix note claiming the check has no exemption is updated in the same pass rather than left to contradict the code. The Blog report is deliberately not edited: it is a point-in-time run snapshot, and the run-stamp discipline in AUDIT.md section 8 says a later run supersedes the file rather than an edit revising it.
Note that
GOVERNANCE.md"Documentation Style Conventions" is verbatim fleet law, so every downstream repository's copy goes stale on merge and is due a re-vendor.🤖 Generated with Claude Code