Skip to content

WP10: Rulebook.Levels with New-RulebookOffLevel and the generated level pages, the off-level script and the authoring guide - #80

Merged
Arthurvdv merged 26 commits into
mainfrom
wp10/levels
Oct 9, 2026
Merged

Arthurvdv merged 26 commits into
mainfrom
wp10/levels

Conversation

@Arthurvdv

Copy link
Copy Markdown
Member

Summary

  • Rulebook.Levels (new module): Get-RulebookOffLevelEntry and New-RulebookOffLevel write the everything-off root level an organization adds itself (D25: none is shipped); Get-RulebookLevelSummary is the model of one level page (rows with From, To and a lowered flag against the chain below, grouped by analyzer, counts per stage over every catalog id); ConvertTo-LevelDocsMarkdown, ConvertTo-LevelDocsIndexMarkdown and New-RulebookLevelDocs write the Markdown pages and their index for any repository.
  • scripts/New-RulebookOffLevel.ps1: the self-contained download-and-run copy, run in a clone of the organization repository. It writes the same bytes as the module (pinned by a parity test on the fixture catalog, the shipped catalog and a synthetic one per sort-key prefix), never edits the settings, and prints the entry to paste and the next steps.
  • tools/rulebook/Build-Template.ps1: a sixth step, New-RulebookLevelDocs from template/ into the engine's docs/levels/ (-LevelDocsDir), with the generated README.md and the four pages committed. The drift test regenerates them outside its template scratch copy and compares bytes; a new test ties each page's counts to the V14 table in docs/rulebook/README.md.
  • Rulebook.Template: Sync-GeneratedFolder exported with SupportsShouldProcess (no behaviour change for the generators).
  • Docs: docs/authoring-levels.md (maintainer guide: placement changes, how they reach organizations, the level pages, the organization recipes, reference, live run), ADR D49 (the shipped level pages live in the engine's docs/levels/), ARCHITECTURE 5.1 recipes (add a stage, remove a level or stage, the branch route), a new 5.9 for the module, section 8 and the naming table; README, CONTRIBUTING, template-content.md and docs/rulebook/README.md updated.

Interview decisions (2026-10-09)

  1. Pages are generated as Markdown from repository inputs (New-RulebookLevelDocs), the shipped set by Build-Template.ps1 into the engine's docs/levels/ with a drift test; per-organization pages come with the WP14 site from the same model (D49).
  2. The off level is a self-contained script modelled on Get-RulebookSkeletons.ps1: writes base/off.ruleset.json, refuses a differing file without -Force, prints the settings entry and the next steps.
  3. Acceptance criterion 5 proven with a throwaway placement change on this branch, reverted before merge (cards (a) and (a2)).
  4. ConvertTo-UpdateSummary renders System.String[] instead of the effective-diff tables #75 folded in first (Update: the job summary renders the effective diff tables instead of System.String[] #79, merged).
  5. Scratch repos Arthurvdv/rulebook-e2e-template and Arthurvdv/rulebook-e2e-levels.
  6. Live cards: rule change, everything off, custom level plus alias, remove Complete, add stage Nightly plus a scan.
  7. Level pages only; stage pages are a WP14 spin-off.
  8. Page rows: id, title, from, to, a lowered marker, justification, docs link, grouped by analyzer with counts.

Deviations from the issue text

  1. Level pages live in the engine's docs/levels/, not in template/docs/levels/ and not "regenerated by Publish" (D49); per-organization pages come with WP14.
  2. New-RulebookOffLevel -RepositoryRoot [-Name] instead of -CatalogPath -OutputPath, and delivered as a self-contained script as well.
  3. Pages are computed from repository inputs and the catalog, not from matrix/resolved.json; a test proves the shipped counts equal the matrix table.
  4. Issue step 3 (Build-RulebookBase/Build-RulebookStages separately) and step 4 ("release notes line") are outdated: the guide states Build-Template.ps1 and D38 (pull request title plus label).
  5. No docs/design/ folder: design notes are in ARCHITECTURE.md and docs/authoring-levels.md.
  6. Documented without a check: C8 noise when Off is the only published level; scan housekeeping versus root levels (spin-off); large off endpoints in update bodies.

Found in the live run and decided on the way:

  1. Branch route for level and stage changes. A pull request that adds, aliases or removes a level or a stage fails Validate (C11, C12) until the endpoints and skeletons exist, so with Validate as a required check it cannot be merged. The recipe is now: change on a branch, run Update Rulebook System Files from that branch with "Resolve the latest commit" off; with "Push to this branch" on it commits to the branch (card (c)), with it off it opens a pull request into the branch (card (d)); Validate turns green, merge. Merging first stays the alternative. The script's next steps, the guide and the architecture recipe say so; no code change was needed (the action clones and pushes github.ref_name).
  2. CRLF working copies. In a clone with core.autocrlf true, a checkout gives base/off.ruleset.json CRLF endings and the byte comparison reported it as differing. The script and the module now treat content equal apart from line endings (and a missing final newline) as current and leave the file alone.
  3. Alias and scoped overrides. An alias does not inherit overrides scoped to the slug of its basedOn level (overrides name slugs); documented in the guide.
  4. Template repo recreated. The earlier scratch template had been deleted, so Arthurvdv/rulebook-e2e-template was recreated (not re-seeded) from this branch's template/ with the actions pinned to @wp10/levels.

Live run

Scratch repositories Arthurvdv/rulebook-e2e-template and Arthurvdv/rulebook-e2e-levels; details in docs/authoring-levels.md section 7.

Card Result Links
(a) placement change Throwaway OV-09 (AA0021 Info at Recommended) on this branch; the update PR changed the three level files and the three recommended endpoints, effective diff level:recommended, the job summary showed the tables (#75 fixed) 5465f74, #1, run 37935385702
(a2) revert Reverted (ded07c5); the second update PR restored the shipped content #2, run 37940087159
(b) everything off Script wrote 605 ids; file alone is a C9 warning; with the entry C11 x3 + C12 x3; update PR created the off endpoints (605 each), skeletons and the 'off' choice; base/off.ruleset.json untouched #3, #4, run 37946114904
(c) House and Baseline C11 x9 + C12 x15 as predicted; update from the branch with a direct commit; baseline endpoints identical to essential in their rule lines, strict and complete AA0021 via level:house; init script refuses essential, Baseline works #5, run 37955298904, 8ec4f5b
(d) remove Complete C11 x3 + C12 x3; update from the branch as a pull request into it deleted the file, endpoints, skeletons and the choice #6, #7, run 37957039839
(e) stage Nightly and scan C11 x5 + C12 x5; update from the branch as a pull request into it added the five .nightly endpoints (off.nightly equals off) and skeletons and the nightly choice; the first scan recorded tools 18.0.43.1464, tools 30.0.42.60748-beta and alcops 1.3.1 with no new id, so no quarantine file changed (D46); merged as 9bab05f (Validate green; no Publish run, the workflow's path filter leaves catalog/ out), second scan "No new package version ...; nothing to do" #8, #9, run 37957704591, scan 37960398807, #11, second scan 37960790966

Both branch-route variants were observed: a direct commit (card (c)) and a pull request into the branch (cards (d), (e)). Card (a)'s throwaway commit 5465f74 is reverted on this branch by ded07c5; the net diff touches neither docs/rulebook/ nor template/.

Review

Three Sonnet code-review rounds at effort high (approve with fixes each; no must-fix bugs in any round) plus a targeted pass on the three post-round-3 code commits (approve, notes only). Round 1: settings read before the write, catalog parity, a guarded page folder, the readme slug, cell and URL encoding. Round 2: the revert of card (a) as merge gate, link-label escaping, the -WhatIf scope. Round 3: the script's published-level warning, Confirm forwarding, HTML-safe cells, the Listed sentence. After round 3, from the live run: the CRLF handling (bd7f192, module, script and tests) and the branch-route wording (2cc9220, script text and docs); the targeted pass added a data-driven test set pinning the line-ending decisions. Every other later commit is docs only.

Spin-offs (to file at close-out)

  • Update: the effective diff says "No effective change" when the update only adds or removes endpoints that the base commit already declares (cards (b), (d)), and the job summary repeats the pull request line and omits the section for an empty diff (WP07).
  • Publish: deploy-pages race on a fresh artifact and duplicate artifacts on a job re-run (backlog, low priority).
  • Scan PR: list released ids that leave an organization root level at its analyzer default (housekeeping versus root levels).
  • Stage pages for the WP14 site.
  • scripts/New-RulebookOffLevel.ps1 added to the places that hard-code main URLs (comment on WP13: move the init script and al-project.md URLs from main to v1 in one place; merge the duplicated rulebook.json rows in ARCHITECTURE 13 #63).

Closes #12

🤖 Generated with Claude Code

Arthurvdv and others added 25 commits October 9, 2026 14:28
…l pages

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…okLevelDocs in a Rulebook.Levels module

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…verything-off root level

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…vels/ with a drift test

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… and the architecture recipes for stages and removals

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… its basedOn level

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…d page folder and encoded links

- the script and New-RulebookOffLevel read the settings before writing and only warn when they cannot
- both refuse a catalog entry without a boolean enabledByDefault, with the same message
- New-RulebookLevelDocs refuses a folder with a Markdown file that is not a generated page, and a level slug readme
- table cells fold any CR or LF; docs URLs encode parentheses and whitespace
- the module writes through <file>.tmp like the script; a synthetic catalog pins the script's sort key

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
OV-09 / DR-022: AA0021 None/Info/Warning/Warning, for the WP10 live run.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ded off-level names and the -WhatIf scope

- link labels escape pipes and brackets; docs URLs also encode | < > ]
- an unknown action names its id; a catalog entry without an id is left to the catalog reader
- New-RulebookOffLevel warns before replacing a published level's file and refuses the slug readme (script too)
- Build-Template help and the authoring guide say -WhatIf is a drift check for a committed state
- sort-key parity covers a seven-digit id and an id outside the pattern

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This reverts commit 5465f74 (OV-09 / DR-022, AA0021 at Info in Recommended) after card (a) of the WP10 live run.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…nfirm only when asked, HTML-safe cells and the Listed sentence

- the script warns like the module before replacing a published level's file; the module help says it does not require the settings
- New-RulebookLevelDocs forwards -Confirm only when the caller bound it
- table cells escape & < > as entities, also for id, analyzer, from and to; pages regenerated (AA0462 title)
- the Listed sentence names the endpoints through Get-EndpointFileName and counts ids outside the catalog

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…s entry

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… a direct push, then merge

The pull request that adds a level fails Validate (C11, C12) until the endpoints and skeletons exist; with Validate as a
required check it cannot be merged. The script's next steps, the authoring guide and the architecture recipe now name
the branch route; merging first stays the alternative. Card (b) of the live run records the finding.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…script and the module

A clone with core.autocrlf true checks base/off.ruleset.json out with CRLF line endings; the byte comparison then
reported it as differing and asked for -Force. Content equal apart from CRLF and a missing final newline is now
current and the file is not rewritten. Cards (b) to (d) of the live run recorded.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…he branch route

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…guide

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…vel, in the module and the script

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Comment-based help only; docs/authoring-levels.md section 6 already lists the property.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@Arthurvdv

Copy link
Copy Markdown
Member Author

137973e adds CatalogCount to the comment-based help of Get-RulebookLevelSummary (a finding of the docs review of ALCops/rulebook wp10/levels-docs). It is a help-text line only, no code or test change, so no further review round; docs/authoring-levels.md section 6 already listed the property.

@Arthurvdv
Arthurvdv merged commit b91de88 into main Oct 9, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

WP10: Levels and starting points

1 participant