docs: Phase 7 — language tags, pagelint --fix, and the acceptance pass (spec 011 complete) - #76
Merged
Merged
Conversation
…11, Task 7.2) The backfill and the rule that stops it recurring, in one commit. Tagging without enforcing leaves the tags to decay like every other unenforced convention here, which is what the audit measured in the first place. Not one of the 34 was code: 1 bash block (two `dotnet add package` lines) and 33 `text` — ASCII flow diagrams, directory trees, validation-message dumps and trace output. That is the explanation for the debt rather than a curiosity. An author writing C# reaches for ```csharp because they want the highlighting; an author drawing a box-and-arrow diagram has no language in mind and types a bare fence. The untagged population was never latent code debt; it was the absence of a name for "not code". Corroborated by a number that did not move: the using-directive debt is 802 blocks across 93 pages before and after. Tagging any of the 34 `csharp` would have added it to rule 6's population. pagelint.py goes 836 warnings to 802, and 802 is the using debt entire — the split recorded before this change holds exactly. Rule 4 was proved red before it was trusted green: retagging Telemetry.md:207 back to a bare fence gives 1 error and exit 1, printed without the (warning) label. --changed origin/master is green and non-vacuous at 15 files / 38 hunks. Rule 4 needs no --changed softening, unlike rule 6: it has no standing debt, so an untagged fence today is one added today. CLAUDE.md's ledger row moves to `error` in both columns, keeping the two-way parity AC5 checks. The 149 space-separated fences (``` csharp) are left alone. They render as C# and rule 4 has never flagged them; normalising them would touch 40-odd pages to change nothing visible and bury a diff whose whole claim is that it is nothing but tags. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012tcdwxVb8NmKaX2S6fvyFg
… 011, Task 7.3) A version bump is 110 banners. Retyping one segment across 110 pages gets abandoned half-done, and a half-bumped corpus is worse than an un-bumped one: some pages assert the new version, some the old, and nothing distinguishes a page that was considered from one that was missed. Rehearsed end to end rather than assumed. With APPLIES_TO temporarily moved to V11/V5: 110 stale, 110 fixed, 0 left for a human — 100 Brighter, 5 Darker, 5 both, reconciling with the 10 Darker-touching pages already in pagetypes.tsv. Page types survived exactly (50/33/27). All five Prerequisites segments survived, checked first because that is the failure apply_banners.py actually shipped in 5498cd6. One line changed per page, 110 files at 1 insertion 1 deletion. The 17 files with no trailing newline still have none, byte-compared against HEAD. Second run is a no-op. No migration map exists. A stale value names a set of products and the fix is whichever APPLIES_TO entry names exactly that set, so one edit to the tuple is the whole bump. Two entries claiming one set is a restructure, not a bump, and it refuses. It never decides a page type. Given `**Guide** · Applies to **Brighter V9**` it fixes the version, leaves the type, and the page still fails rule 2 — --fix cannot launder a bad page type into a green build. Only the version segment is substituted, so the type and Prerequisites are out of reach by construction. The language-tag half had ground truth: the 34 fences Task 7.2 tagged by hand. Replayed against that tree it tags 26 and holds 8, and all 26 match the hand verdict. No wrong tag; the only failure mode is doing nothing and saying so. One of the 8 is exactly right — AsyncAPISupport's `dotnet add package`, the one block that took bash. The rest are over-caution, mostly `key: value` firing on labelled output. `text` is the only inferable tag because all 34 untagged fences were prose; picking between csharp, bash, json and yaml belongs to the author. Kept out on purpose: apply_banners.py's TSV lookup (one-off migration logic keyed to a file recording years-old decisions), rule 6 (writing `// ...` for a reader converts a debt into a declaration nobody made), and --fix --changed, which is rejected with exit 2 because --changed only varies the strictness of a rule --fix does not repair. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012tcdwxVb8NmKaX2S6fvyFg
Eight criteria walked, each verified by running something rather than by recalling what an earlier session reported. Seven passed; AC5 failed and is fixed. AC5 asks for CLAUDE.md <-> linter parity in both directions. pagelint.py can emit eight rule labels and the ledger listed seven: NO H1, returned by check_banner when a page has no title to hang a banner below, was never written down. It is rule 1's precondition rather than a rule of its own, which is presumably why — but the ledger's own claim is that every rule maps back, and this one did not. Nothing was broken by it, because every page has an H1 and the rule has never fired, which is exactly why it survived four sessions of the ledger being read and edited. A rule that never fires is invisible to everything but an enumeration. A second drift of the same shape, found while checking AC6: docs.yml's comment still said untagged fences stay warnings on the repo-wide step. Task 7.2 made them an error two commits ago and updated CLAUDE.md and the docstring, but not the workflow comment — changed where it was enforced, not everywhere it was described. Two checks that had never been run, both of which could have been false silently: every page's banner type matches its reviewed verdict in pagetypes.tsv (110/110), and every page's Applies to matches the TSV's applies column (110/110, tallying 100/5/5), so the 10 Darker-touching pages really are the set that column names and the next Darker release is the one-edit bump it was positioned to be. AC4 re-derived without the linter: an independent fence-aware pass finds 688 distinct non-navigation ## slugs and 0 on more than one page. Confirming rule 3a with the tool that enforces rule 3a would only have proved self-consistency. AC1's baseline for whoever shrinks it: 802 C# blocks across 93 pages with no using directives, left standing deliberately. AC7's redirects stated plainly rather than ticked — no URL moved, so there is nothing to redirect from; the 28 anchor links the splits broke were repointed directly in Phase 6, because GitBook redirects operate on pages, not fragments. 43 of 43 tasks. Spec 011 is complete and Spec 010 has been unblocked since 7.1. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012tcdwxVb8NmKaX2S6fvyFg
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.
Closes out Spec 011. Three commits, one per task; 43 of 43 tasks done.
Task 7.2 — language tags on the last 34 fences, rule 4 to a repo-wide error
The backfill and the rule that stops it recurring, in one commit — tagging without
enforcing leaves the tags to decay like every other unenforced convention here, which
is what the audit measured in the first place.
Not one of the 34 was code: 1
bashblock (twodotnet add packagelines) and 33text— ASCII flow diagrams, directory trees, validation-message dumps, trace output.That is the explanation for the debt rather than a curiosity. An author writing C#
reaches for
```csharpbecause they want the highlighting; an author drawing abox-and-arrow diagram has no language in mind and types a bare fence. The untagged
population was never latent code debt — it was the absence of a name for "not code".
Corroborated by a number that did not move: the using-directive debt is 802 blocks
across 93 pages before and after. Tagging any of the 34
csharpwould have added it torule 6's population.
pagelint.pygoes 836 warnings → 802, and 802 is the using debt entire. Rule 4 wasproved red before it was trusted green: retagging a fence back to bare gives
1 errorsand exit 1.Task 7.3 —
pagelint.py --fixA version bump is 110 banners, and retyping one segment 110 times gets abandoned
half-done. Rehearsed end to end with
APPLIES_TOtemporarily at V11/V5: 110 stale,110 fixed, 0 left for a human. Page types survived exactly (50/33/27), all five
Prerequisites segments survived — checked first, because that is the failure
apply_banners.pyactually shipped — one line changed per page, and the 17 fileswithout a trailing newline still have none. Second run is a no-op.
There is no migration map. A stale value names a set of products and the fix is
whichever
APPLIES_TOentry names exactly that set, so one edit to the tuple is thewhole bump.
It never decides a page type. Given
**Guide** · Applies to **Brighter V9**itfixes the version, leaves the type, and the page still fails rule 2 —
--fixcannotlaunder a bad page type into a green build.
The language-tag half had ground truth: the 34 fences 7.2 tagged by hand. Replayed
against that tree it tags 26 and holds 8, and all 26 match the hand verdict. No
wrong tag; the only failure mode is doing nothing and saying so.
Task 7.4 — acceptance pass, AC1–AC8
Seven passed as they stood. AC5 failed and is fixed: the linter can emit eight rule
labels and the ledger listed seven —
NO H1was never written down. Nothing was brokenby it, because every page has an H1 and the rule has never fired, which is exactly why
it survived four sessions of the ledger being read and edited. A rule that never fires
is invisible to everything but an enumeration.
A second drift of the same shape turned up while checking AC6:
docs.yml's commentstill said untagged fences stay warnings.
Two checks that had never been run, both of which could have been false silently: every
page's banner type matches its reviewed verdict in
pagetypes.tsv(110/110), and everypage's Applies to matches the TSV's
appliescolumn (110/110, 100/5/5). AC4 wasre-derived without the linter — 688 distinct non-navigation
##slugs, 0 repeated.State
pagelint.py0 errors / 802 warnings across 110 pages;linkcheck.pyclean at 112files;
--changed origin/mastergreen and non-vacuous. The remaining 802-blockusing-directive debt is deliberate and is AC1's baseline to shrink.
🤖 Generated with Claude Code
https://claude.ai/code/session_012tcdwxVb8NmKaX2S6fvyFg