Clear the comment half of the prose backlog, exemption first - #604
Conversation
Takes the `The Prose Content Backlog` cluster from `TODO.md`. Its `Checked` anchor was re-verified against `develop` at `c64e3e0` before anything was written: `prose_lint.py --summary` reported the same 373 violations across 26 files, `catalog/snippets` the same 0, and the three largest files the same 99, 52 and 41. ## The exemption came first, and it was wrong `RUN_ON` read the closing dot of an ellipsis as a sentence terminator, so `scripts/repo_gate.py:204` was reported as two sentences: ```text # .editorconfig: [glob] ... end_of_line = lf ``` That is one schematic line, and the split the rule asked for would have broken the fragment the comment exists to show. Fixing the prose first would have damaged a correct comment on the checker's say-so, which is the failure this repository has now recorded six times. The guard is that a dot preceded by a dot never terminates, it carries two tests, and the verdict diff was run in both directions: exactly one finding disappeared and none appeared. ## The batch is the comment surface, all of it The backlog splits by surface rather than by file. `comment-wrap` and `comment-case` lived entirely in non-Markdown comments, `dash` and `semicolon` live entirely in Markdown prose, so the comment half is one reviewable change that owes no re-vendor: of the eleven files, four are workflows carried at `interface` fidelity, where the contract is job keys and tokens rather than comments, and the rest are hub-only. 241 findings are cleared by restructuring, never by widening an exemption. A sentence per comment line, and a comment that opened on a lowercase identifier reworded to open on a word, which is what the rule asks for and what the snippets sweep established. The tree goes from 373 across 26 files to 131 across 15, all of them `dash` and `semicolon` in Markdown. Six of those files are carried, so the next batch splits again at that line: the carried half rewrites byte-locked sections and owes a re-vendor, the hub-only half owes nothing. ## Both rules now gate A rule swept clean but left warn-only regresses on the next edit with nothing reporting it, so `comment-wrap` and `comment-case` move to the gating CI step and out of the warn-only one. Every claim about which rules gate moved with them, in `OPERATIONS.md`, `scripts/README.md` and the two workflow comments, including the one in `scripts/README.md` saying gating still needs `--diff` because the tree carries several hundred of them. ## One gap found while counting, not fixed here `home-path` is in `DEFAULT_RULES` and is named by neither CI list, so the pattern-detectable half of the representative-data rule runs on every bare local run and gates nothing in CI. It is clean tree-wide, so it is a hole rather than a backlog. It is recorded in `OPERATIONS.md` beside the two gaps already named there and in `TODO.md`, rather than closed here, because gating a third rule is its own decision. The write guard and both installer wrappers are among the eleven files, so every installed copy is now behind the hub by that much. The divergence is comment-only, the self-test passes unchanged, and `TODO.md` carries it under the host rollout as a re-run at the next visit. Verified with the full `OPERATIONS.md` local list: five self-tests, the repo gate, both prose invocations, `jq`, `spec/validate.py`, editorconfig-checker, markdownlint and actionlint. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR reduces the prose-lint backlog by rewriting non-Markdown comment prose to satisfy comment-wrap and comment-case, and then updates the documentation and CI wiring so those comment rules are enforced as gates going forward. It also adjusts the run-on sentence detector to treat ellipses correctly and adds regression tests.
Changes:
- Update
scripts/prose_lint.pyrun-on detection to avoid treating an ellipsis' closing dot as a sentence terminator, with added unit tests. - Reflow and rephrase comments across spec, safety tooling, and workflow files to clear
comment-wrapandcomment-casefindings. - Move
comment-wrapandcomment-casefrom warn-only reporting into the gating prose step, and update operational documentation to match.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| TODO.md | Refresh prose backlog tracking notes and add missing link references. |
| spec/validate.py | Comment rewording to satisfy comment prose rules. |
| spec/fidelity_honesty.py | Comment rewording to satisfy comment prose rules. |
| spec/audit.py | Comment rewording to satisfy comment prose rules. |
| scripts/test_prose_lint.py | Add regression tests for ellipsis handling in run-on detection. |
| scripts/README.md | Update prose-lint gating vs warn-only documentation. |
| scripts/prose_lint.py | Adjust RUN_ON detection for ellipsis and document intent. |
| OPERATIONS.md | Update local verification runbook and describe CI check coverage gaps. |
| host-setup/agent-safety/install.sh | Comment reflow for comment prose compliance. |
| host-setup/agent-safety/install.ps1 | Comment reflow for comment prose compliance. |
| host-setup/agent-safety/gh-write-guard.py | Comment reflow for comment prose compliance. |
| .github/workflows/validate-task.yml | Gate comment-wrap and comment-case, trim warn-only list. |
| .github/workflows/test-pull-request.yml | Comment reflow for comment prose compliance. |
| .github/workflows/publish-release.yml | Comment reflow for comment prose compliance. |
| .github/workflows/merge-bot-pull-request.yml | Comment reflow for comment prose compliance. |
| .github/dependabot.yml | Comment reflow for comment prose compliance. |
The guard sat in front of the whole `[.!?]` class, so it suppressed a terminator that happens to follow an ellipsis. `Really...? Yes it does.` read as one sentence, because the `?` is preceded by the ellipsis' closing dot, and that is a genuine run-on the rule exists to catch. Only a dot can end an ellipsis, so the guard belongs on the dot alternative alone: `(?:(?<!\.)\.|[!?])`. A test covers both `...?` and `...!`. No verdict changes on this tree, since it carries no such line, which is what makes this a correctness fix to the rule rather than a change to the sweep. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 16 out of 16 changed files in this pull request and generated no new comments.
Suppressed comments (2)
TODO.md:34
- This
Checkedbullet anchors the measurement todevelopatc64e3e0but then reports an "after the comment batch" number that would be on this PR branch, not on that develop commit. Clarify which ref the post-batch measurement comes from to avoid misattributing the figures.
- **Checked** - `develop` at `c64e3e0` on 2026-08-07, where `python3 scripts/prose_lint.py --summary` reported 373 violations across 26 files before the comment batch and 131 across 15 after it, and `catalog/snippets` reports 0. The snippets sweep took the tree from 557 across 45, of which 184 across 19 were snippets.
scripts/README.md:75
- This sentence lists which rules are clean tree-wide and gate CI, but it omits
spelling, which is still gated in the workflow/ops invocations. That makes the doc inconsistent with the actual gating set.
`charset`, `dupword`, `comment-wrap`, and `comment-case` are clean tree-wide and gate CI. `charset-unknown`, `semicolon`, and `dash` run as one warn-only CI step, so the remaining backlog is visible without blocking and is corrected as each file is next edited, or cleared in a deliberate batch.
…to the gate list Two findings the review suppressed rather than threaded, both correct. The `Checked` bullet anchored to `develop` at `c64e3e0` and then quoted a post-batch figure that exists only on this branch, which reads as though the anchor commit carries it. `Checked` is the freshness anchor, so a number under it that was measured somewhere else is the one thing it must not do. Each figure now names the ref it came from, and says the branch figure becomes the anchor's own on merge. `scripts/README.md` listed the gating rules twice and omitted `spelling` from the second list. The omission predates this change, and adding the two comment rules around it left the same file stating five gating rules in one place and four in another. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Answering the two suppressed findings from the round on
Correct, and it is the specific thing a
Correct. Worth recording that the omission predates this pull request: the line already read " |
) Takes the next batch of the `The Prose Content Backlog` cluster from [`TODO.md`](./TODO.md), following [#600](#600) (snippets) and [#604](#604) (comments). Part of [#519](#519). ## The anchor was re-verified first `develop` at `c9c92dd`, where `python3 scripts/prose_lint.py --summary` reports **131 violations across 15 files**. That is the figure the comment batch left, and merging that batch made it the anchor's own rather than a branch's, exactly as the cluster entry predicted. ## Scope, and a correction to it The batch is the **hub-only Markdown files**: `docs/`, `spec/*.md` and `catalog/README.md`. That is **90 findings across 9 files** (79 `dash`, 11 `semicolon`), not the ~104 the batch was scoped at. The carried six hold 41, and 90 + 41 = 131. The 6 carried files are left for a later batch, since they rewrite byte-locked sections and owe a fleet re-vendor while these owe nothing. Every `dash` finding in the tree turned out to be hub-only, so what the carried half now holds is **41 semicolons and no dash at all**. | File | Findings | | --- | ---: | | `docs/devcontainer.md` | 22 | | `docs/ssh-signing.md` | 17 | | `spec/type-model.md` | 17 | | `spec/fidelity-model.md` | 8 | | `docs/repo-config-carry.md` | 7 | | `spec/scope-model.md` | 7 | | `catalog/README.md` | 6 | | `docs/token-cost.md` | 5 | | `spec/readme-structure.md` | 1 | ## The exemption came first, and this time it was right `LABEL_DASH` exempts `- **Label** - text` as a definition separator that is structurally a colon. It reaches neither a code-span label nor a paragraph-leading one, and both shapes flagged here. Widening it was the obvious move, and the corpus rejected it twice. **A code-span definition list** is already spelled with a colon in five files, against four dash-spelled lines in one (`catalog/README.md`): ```text STANDUP.md:91 - `ARCHITECTURE.md`: how a code repo is built spec/section-model.md:68 - `ARCHITECTURE.md`: how a code repo is built scripts/README.md:81 - `sha-pin`: every workflow `uses:` naming repo-config/README.md:6 - `operational/develop.json`: the `develop` CODESTYLE.md:79 - `.NET Build`: Build with diagnostic ``` **A paragraph-leading label** is already spelled `**Label.** Sentence`, against nine dash-spelled lines confined to two troubleshooting sections. So both were a file that had not adopted the tree's own convention rather than a construct the rule fails to describe. **The checker is unchanged by this batch.** That is the same verdict the comment batch reached on a comment opening on a lowercase identifier. A bulleted list terminating its items with semicolons appeared in exactly one place tree-wide, `spec/type-model.md:24-25`, and its own last item already ended in a period. It was punctuation to make consistent rather than the list construction the semicolon exemption protects, which a line-based checker could not see across bullets in any case. ## One adjacent fix, flagged because it widens scope Rewriting `docs/devcontainer.md` and `docs/ssh-signing.md` with a script rather than an editor took both from CRLF to LF wholesale. Every prose and Markdown gate stayed green, and `editorconfig-checker` was the only one that reported it. `OPERATIONS.md` scoped that instruction to a *new* file, so it is widened here to a scripted rewrite of an existing one. Hub-only, `presence` fidelity, no re-vendor owed. Happy to split it out if it does not belong in this batch. ## Verification Run from the repository root: ```text prose_lint.py gating list exit 0 prose_lint.py backlog list 131/15 -> 41/6, the carried six exactly test_prose_lint.py 198 tests OK test_repo_gate.py, test_pr_review.py OK audit.py --selftest, gh-write-guard SELFTEST PASS repo_gate.py, validate.py, jq clean markdownlint-cli2 (44 files) 0 issues editorconfig-checker 0 errors ``` Every prose file changed line for line, with no line-count change in any of the 9, and the full word-diff was read for meaning drift. `TODO.md` carries the updated `Checked` anchor and four new `Settled` lines: the batch figures, the two rejected exemptions, the one-off bullet list, and the CRLF gap. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…606) Takes the last batch of the `The Prose Content Backlog` cluster from [`TODO.md`](./TODO.md), following [#600](#600) (snippets), [#604](#604) (comments) and [#605](#605) (hub-only Markdown). Closes [#519](#519) on the prose, subject to the sweep below. ## The anchor was re-verified first `develop` at `d791930`, where `python3 scripts/prose_lint.py --summary` reports **41 violations across 6 files**, all `semicolon`. That is the figure #605 predicted, and merging it made the figure develop's own rather than a branch's. | File | Findings | Fidelity | | --- | ---: | --- | | `GOVERNANCE.md` | 14 | `intent`, 5 sections `verbatim` | | `WORKFLOW.md` | 14 | `intent`, whole | | `CODESTYLE.md` | 6 | `intent`, whole | | `.github/copilot-instructions.md` | 4 | `intent`, whole | | `repo-config/README.md` | 2 | `intent`, whole | | `HISTORY.md` | 1 | `presence` | **The tree is now at 0 across 0**, from 557 across 45 when the backlog opened. ## The exemption came first, and left the checker alone again Two candidates, both rejected by the corpus. That is the third batch running where the pass ends in "do not touch the checker". **The `*Prevents: a; b.*` tail.** Flagged on 4 lines because the list exemption requires the items to carry commas. The tree already spells the same construct with a comma on **5** lines against **6** semicolon-spelled, so it is a convention half-adopted rather than a construct the rule fails to describe. Two of the six (`D1.6`, `D5.6`) keep their semicolons untouched, because their items *do* carry commas — the rule working, not an exception to it. **A two-example parenthetical**, `(A does X; B does Y)`. The tree already spells this with a comma where the items carry none, `GOVERNANCE.md` "No-op republish guarantee" being the case in point. ## Only 14 of the 41 are actually byte-locked The cluster entry said the carried half "rewrites byte-locked sections". That is true of `GOVERNANCE.md` and of nothing else, which changes what the sweep owes: - **`verbatim`, hash-detected.** All 14 `GOVERNANCE.md` findings sit in five `verbatim` sections: Branching Model, Release Model, Documentation Style Conventions, PR Review Etiquette, Workflow YAML Conventions. Every downstream copy is now byte-mismatched and `spec/audit.py` classifies it **stale** (matches a past hub revision), which is the correct disposition and reaches the fleet without anyone filing anything. - **`intent`, detected by nothing.** `WORKFLOW.md`, `CODESTYLE.md`, `.github/copilot-instructions.md` and `repo-config/README.md` are judged by meaning, so a punctuation-only edit produces no hash and therefore no audit finding at all. These are the half that would be silently missed, which is why they are written down rather than left to the run. - **`presence`.** `HISTORY.md` is each repo's own changelog. Its one fix owes nothing downstream. No rule changed meaning anywhere, so the re-vendor is a **hash refresh rather than a propagation**. A repo still holding the old copy is correct on the rule and wrong on the bytes. The Fleet Sweeps entry "Re-vendor the changed `verbatim` content" grows from **five files to seven** and carries both halves as `Detail` lines. It does not trigger a dedicated sweep — Blog remains the pilot. ## What #519 got wrong, and why it is worth recording The issue states that the governance files were clean and that this was "not a carry problem". That was true of the checker of the day and false of the tree: | Content | Checker | Result | | --- | --- | ---: | | the six files at `69688ec` | that commit's own `prose_lint.py` | **0** | | the six files at `69688ec` | today's `prose_lint.py` | **38** | `semicolon` was in `DEFAULT_RULES` the whole time. What changed is the **unit** the list exemption is judged over: scoping it to a sentence rather than a whole bullet accounts for **37 of the 38**, because a colon anywhere ahead of the first semicolon had been exempting every semicolon after it, however plainly one joined two clauses. So the carry problem was real from the start and invisible — the stale-exemption hazard running in the loose direction, on the most-carried files in the fleet. ## One fix beyond the 41 `GOVERNANCE.md` "Orchestration vs. build" carried a splice the exemption excused only because the **bold label** on that sentence happened to contain a comma (`...globs it; do not switch a single-target repo...`). Same line as a flagged finding, so it is fixed inline rather than stepped around. That is 42 semicolons removed, not 41. ## Verification Run from the repository root: ```text prose_lint.py --summary 41/6 -> 0/0 scripts/ unittest (375 tests) OK spec/audit.py --selftest SELFTEST PASS spec/validate.py 22 cataloged, 0 backlog scripts/repo_gate.py eol 0, sha-pin 0 markdownlint-cli2 (44 files) 0 issues cspell (README.md, HISTORY.md) 0 issues editorconfig-checker 0 on tracked files ``` Every edit is a **within-line** replacement, so all seven CRLF files stayed CRLF — verified by an `\n` versus `\r\n` count per file, not by `file`. The full word-diff was read for meaning drift; the change is 31 lines, 31 insertions and 31 deletions. `editorconfig-checker` reports 221 errors, every one of them under `.artifacts/` or `Tests/obj/` — untracked pre-repurpose build leftovers in the working tree, not tracked files. Pre-existing and untouched here. ## `TODO.md` - The `The Prose Content Backlog` cluster is deleted, per selection rule 9. - [#519](#519) moves to "Verified Complete, Awaiting Close" with both of its questions answered and the checker-versus-tree finding as closing evidence. - The Fleet Sweeps re-vendor entry grows to seven files and gains the two `Detail` lines above. - Four link reference definitions orphaned by the cluster deletion are dropped. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Closes #607. ## What was wrong A Copilot review body states how many of the pull request's changed files it read, and nothing parsed that line. A round that read part of the diff carries the correct `commit.oid`, raises no inline threads, and reports "generated no comments", so it is the clean pass byte for byte in everything the loop checks, and `status` printed `review_on_head=yes` over it and exited `0`. Measured over **332 Copilot review bodies** on this repository, five rounds across three pull requests reported reading fewer files than were changed, and all three merged. #592 is the sharpest: three changed files, one never read, across *both* rounds, both reporting no comments. ## What changed, and why it is wider than the issue asked Partial coverage is the third instance of a shape this script already answers twice, and the generalization is the point. Every reader here keys on a structural marker, so a marker that changes spelling is a section the reader stops finding and reports as absent. All three failures on record have that shape: | Drift | Result | | --- | --- | | Suppressed heading reworded | `suppressed=0` over a body carrying findings | | Suppressed section moved inside another wrapper | `suppressed=0` again | | Coverage line never parsed | a partial round reported as a covered head | Each was found by the maintainer after it had landed, rather than by the gate. So the digest now vets the reviewer's output as a whole and **fails closed**: - `coverage=full` / `PARTIAL` / `unstated`, with exit **42** on a partial round. - `shapes=ok` / `UNRECOGNIZED`, with exit **43** on any heading, `<summary>`, metadata label, coverage wording or reviewer login the script has no vetted spelling for. It outranks 42, because a reader that does not understand the output cannot be believed about what it read of the diff. The `43` message states the remedy in two parts: **file an issue on the repository hosting the reader**, quoting the body the shape came from, and **the merge decision is the maintainer's**. An unrecognized shape does not say the pull request is bad, only that nothing here can vouch for the review of it. ## The inventory is measured, not imagined With fenced blocks dropped and text reduced to ASCII, all 332 bodies reduce to **7 headings, 6 `<summary>` texts and 3 metadata labels**, and every body carries at least one. Counts normalize to `(N)` and the verdict headings' colored circle is dropped before comparing, since both change on every review without the section changing, and dropping the emoji is also what keeps the source inside the charset rule. Two exemptions, both required by the corpus: - **A body stating no coverage** reads as `unstated`, never as pass or failure. 28 of the 332 are an overview and a change list, that shape is current and interleaves with the counted one, and one pull request carries both across its two rounds. Failing on it would cry wolf on about one review in twelve. - **A refusal** is exempt, being a bare paragraph by design and already classified. The exemption is the pattern rather than a carve-out, so a refusal reworded stops being exempt and blocks, which is the refusal check's own failure mode caught one rewording later. The quietest reading is the reviewer **login**: a rename leaves every filter here matching nothing, so a review that landed reads as `rounds=0` and a wait polls out its timeout against it. ## Evidence Both readers were swept over the full corpus before this was written, and over it again after: - Shape inventory: **0** items raised across all 332 bodies, and **0** across every review and comment author on those 120 pull requests (`copilot-pull-request-reviewer` and `ptr727`). - Coverage: `full 299 / unstated 28 / partial 5`, the five being exactly #476 (x2), #479 and #592 (x2). - Live: #592 reports `coverage=PARTIAL shapes=ok` and exits `42`. #595, #604 and #606 report `shapes=ok` and exit `0`. 166 tests pass, up from 132. The two fixtures the issue named as unasserted filler are promoted to assertions, and a case reads the vetted coverage spellings out of the runbook and hands them to the script's own parser, so the pair fails in both directions on drift. The old fixtures crafted review bodies with no heading, which no real body has, so they were made realistic rather than the check loosened. ## Also carried - `.github/copilot-instructions.md` - the verify step checked `commit.oid` only, which is what this shows to be insufficient, plus a new section stating that an unrecognized shape blocks and earns an issue. - `GOVERNANCE.md` - merge-gate precondition 4, and the "all four preconditions" restatement swept to five. - `scripts/README.md` - both readings. - `TODO.md` - a `measure` cluster to survey whether GitHub publishes anything structured about a Copilot review, since this whole design rests on prose being the only surface. Introspection says it is: `PullRequestReview` exposes `body`, `bodyText` and `bodyHTML` and no field naming a finding or a file count, and the only Copilot-named GraphQL types configure review-on-push in a ruleset. ## The accepted cost The shape scan reads every round rather than the head's, so once Copilot changes format, every open pull request blocks at once until the inventory is updated. That is deliberate and the maintainer's call: it is well balanced against a reviewer silently missing a raised finding. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
… that blocks on what it cannot read (#609) Promotes 14 commits from `develop`. Merge with a **merge commit** (`gh pr merge --merge`), never a squash, and **without `--delete-branch`**, since this pull request's head is `develop` itself. Closes #607 through the closing keyword already carried in `530cf71`, which is why it is not repeated here. ## The prose backlog, cleared end to end `#600`, `#604`, `#605`, `#606` took the tree from **557 findings across 45 files to 0 across 0**, in four batches ordered by surface: snippets, comments, hub-only Markdown, then the carried files. Each batch measured the checker's own exemption against the live corpus *before* sweeping, and twice the measured answer was **"do not change the checker"**, which is a result of that pass rather than a skipped one. `#594` added the floor that makes those numbers trustworthy: a diff-scoped run now asserts what it actually scanned, since a check whose scan matches nothing reports zero findings and reads exactly like a pass. One finding from that work is worth carrying up: an exemption that is too **loose** produces silence rather than false positives. #519 recorded the governance files as clean; today's checker reports 38 findings against those same files as they stood at the commit that measured them. ## A review loop that fails closed `#599`, `#601`, `#602`, `#603` and `#608` are one arc on `scripts/pr_review.py`, each removing a shape in which the loop reported a clean pass over a review it had misread: - **`#599`** removed the shape a reply kept failing in, by taking the thread's *words* rather than an id, so there is no argument a hand-typed `PRRT_...` fits in. - **`#602`** made `claims` resolve what a description points at rather than what it looks like. - **`#603`** gave a disproved claim a home the next round reads. - **`#608`** reads the file-coverage line, and then generalizes: every reader keys on a structural marker, so a marker that changes spelling is a section the reader stops finding and reports as absent. The digest now vets headings, `<summary>` texts, metadata labels, coverage wordings and the reviewer login against an inventory measured from **332 review bodies**, and **blocks on anything outside it**, exit `43`, with the remedy stated as filing an issue on the hub. Whether to merge regardless is the maintainer's decision. `GOVERNANCE.md` merge gate went from four preconditions to **five** accordingly. ## Governance and tooling - **`#593`** states which checkout an agent works in and what the hub is, which is the host-wide routing the repositories that most need it cannot carry. - **`#596`** gates the pattern-detectable half of the representative-data rule, honest that no pattern closes the name-shaped case. - **`#598`** declares where a repository states what CI cannot verify. - **`#592`** regrouped `TODO.md` by what ships rather than by what it touches, so a `###` heading is one pull request. - **`#601`** ended a `gh push` argument list at a newline rather than only at `&&`, fixing a write-guard over-block. ## Verification Run on `develop` at `530cf71` immediately before opening this: `test_pr_review.py` (174), `test_prose_lint.py`, `test_repo_gate.py`, `spec/audit.py --selftest`, `gh-write-guard.py --selftest`, `spec/validate.py`, `repo_gate.py`, the prose gate in both CI invocations, markdownlint and editorconfig-checker. All clean. ## Not carried by this promotion - **#519 is complete and still open.** `TODO.md` holds its closing evidence under "Verified Complete, Awaiting Close". Closing it is the maintainer's call, so no keyword for it appears here. - **The re-vendor debt is now nine files.** `#606` queued seven, and `#608` changed `GOVERNANCE.md` "PR Review Etiquette" (`verbatim`) and `.github/copilot-instructions.md` (`intent`) on top. The `intent` half produces no hash and therefore no audit finding, which is why the Fleet Sweeps entry names those files by hand. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Takes the
The Prose Content Backlogcluster fromTODO.md. ItsCheckedanchor was re-verified against
developatc64e3e0before anything waswritten:
prose_lint.py --summaryreported the same 373 violations across 26files,
catalog/snippetsthe same 0, and the three largest files the same99, 52 and 41.
The exemption came first, and it was wrong
RUN_ONread the closing dot of an ellipsis as a sentence terminator, soscripts/repo_gate.py:204was reported as two sentences:That is one schematic line, and the split the rule asked for would have broken
the fragment the comment exists to show. Fixing the prose first would have
damaged a correct comment on the checker's say-so, which is the failure this
repository has now recorded six times. The guard is that a dot preceded by a
dot never terminates, it carries two tests, and the verdict diff was run in
both directions: exactly one finding disappeared and none appeared.
The batch is the comment surface, all of it
The backlog splits by surface rather than by file.
comment-wrapandcomment-caselived entirely in non-Markdown comments,dashandsemicolonlive entirely in Markdown prose, so the comment half is one reviewable change
that owes no re-vendor: of the eleven files, four are workflows carried at
interfacefidelity, where the contract is job keys and tokens rather thancomments, and the rest are hub-only.
241 findings are cleared by restructuring, never by widening an exemption. A
sentence per comment line, and a comment that opened on a lowercase identifier
reworded to open on a word, which is what the rule asks for and what the
snippets sweep established.
The tree goes from 373 across 26 files to 131 across 15, all of them
dashand
semicolonin Markdown. Six of those files are carried, so the next batchsplits again at that line: the carried half rewrites byte-locked sections and
owes a re-vendor, the hub-only half owes nothing.
Both rules now gate
A rule swept clean but left warn-only regresses on the next edit with nothing
reporting it, so
comment-wrapandcomment-casemove to the gating CI stepand out of the warn-only one. Every claim about which rules gate moved with
them, in
OPERATIONS.md,scripts/README.mdand the two workflow comments,including the one in
scripts/README.mdsaying gating still needs--diffbecause the tree carries several hundred of them.
One gap found while counting, not fixed here
home-pathis inDEFAULT_RULESand is named by neither CI list, so thepattern-detectable half of the representative-data rule runs on every bare
local run and gates nothing in CI. It is clean tree-wide, so it is a hole
rather than a backlog. It is recorded in
OPERATIONS.mdbeside the two gapsalready named there and in
TODO.md, rather than closed here, because gatinga third rule is its own decision.
The write guard and both installer wrappers are among the eleven files, so
every installed copy is now behind the hub by that much. The divergence is
comment-only, the self-test passes unchanged, and
TODO.mdcarries it underthe host rollout as a re-run at the next visit.
Verified with the full
OPERATIONS.mdlocal list: five self-tests, the repogate, both prose invocations,
jq,spec/validate.py, editorconfig-checker,markdownlint and actionlint.