Repository navigation
WP07: Update Rulebook System Files: the CheckForUpdates action, the update workflow, GHTOKENWORKFLOW (D44) and unusedRulebookFiles as paths - #66
Merged
Conversation
…elative paths, C9 path-only (#49) unusedRulebookFiles entries get a pattern (repository-relative paths with /, at least one folder), the new update object carries schedule (five-field cron or null), and templateSha says the update writes it. C9 matches an entry by its path only, so an entry that silences C9 is the entry the update honours. The template settings and the template-default fixture gain "update": { "schedule": null }. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…l requests, clone and push Invoke-GitHubApi is the one REST call (non-2xx returned, pagination over Link, -OutFile), the single mock point of the suites. Get-GitHubAccessToken passes a personal access token through and exchanges GitHub App JSON (AL-Go format) for an installation token limited to the repository; New-GitHubAppJwt signs the RS256 JWT and accepts a PEM whose lines were joined. New-GitHubClone gives git the token as an extra header through GIT_CONFIG_COUNT in the process environment only; Publish-GitHubChange commits, pushes a branch or a direct commit and falls back to a branch when the push is refused. Tests against bare repositories, with a pre-receive hook as branch protection. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The update workflow of an organization repository: dispatch inputs templateUrl, downloadLatest and directCommit, a read-only GITHUB_TOKEN, a settings step that reads ghTokenWorkflowSecretName (default GHTOKENWORKFLOW) and, on a schedule, takes directCommit from commitOptions.createPullRequest, then the CheckForUpdates action with update 'Y' and the secret by name. No schedule: in the template; the update writes it from update.schedule. The Template suite counts it among the 10 hand-written files. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…on gate, update pull request
ConvertTo-TemplateUrl normalises the template URL AL-Go style;
Get-RulebookTemplate downloads the template zipball (and the installed one when
the site comparison or a removed listed file needs it), retrying a private
template with the exchanged write token, or takes local folders.
Get-RulebookUpdatePlan copies the working tree, writes the managed files the
template ships by class (overwrite, settings, customizable with the D35
three-way decision, unusedRulebookFiles as paths), regenerates skeletons/ and
rulesets/, runs Test-Rulebook on the candidate and lists the changes, with the
sha-only case for a repository whose only difference is templateSha.
Update-RulebookSettingsText edits $schema, templateUrl and templateSha in place;
ConvertTo-UpdatedWorkflowText replaces {TEMPLATEURL}, rewrites the ChangeRule
choice lists from the settings (D30) and adds or removes the schedule with a
line editor ported from AL-Go's yamlclass. Publish-RulebookUpdate guards
against a duplicate pull request by title, clones, commits, pushes and opens
the labelled pull request with the effective diff in its body.
Fixtures: tests/fixtures/templates/v1 and v2 and tests/fixtures/repos/update-org,
generated parts written by the engine functions, derivation in
tests/fixtures/templates/README.md.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
action.yaml takes templateUrl (empty uses the setting), templatePath, installedTemplatePath and templateSha (local templates for tests and CI), the GHTOKENWORKFLOW token, update, downloadLatest, directCommit, updateBranch, repositoryRoot and actor, and writes updatesAvailable, pullRequestUrl, templateSha and failure. CheckForUpdates.ps1 never fails check mode: an unreachable template or a candidate that would not validate is one warning "update check skipped". Update mode needs the token before any request, fails on a candidate that does not validate with its findings and pushes nothing, masks the exchanged token and reports an open pull request with the same title. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With checkForUpdates the Validate action downloads the template of the
settings with GITHUB_TOKEN (now passed to the step, read-only) or takes local
folders (-TemplatePath, -InstalledTemplatePath), builds the update plan and
adds one notice (no updates; templateSha not recorded) or warning (updates
available; check skipped) and the section "## Template update check" to the
summary. Neither counts towards warnings= or failOnWarning, and the check
never fails the step. The result carries UpdateCheck { Status, Reason, Plan }.
A first run's bookkeeping (templateSha and the {TEMPLATEURL} placeholder) now
counts as sha-only, so a repository fresh from the template gets the notice.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The new job runs ./actions/CheckForUpdates in check mode on update-org against the local templates v1 (no updates) and v2 (updates available), and in update mode without a token (must fail with failure 'token'); a guard step fails the job on any other outcome. The three Validate steps of validate-action pass checkForUpdates 'false', so the fixtures are not compared with ALCops/rulebook. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…kFiles as paths docs/reference/update-mechanics.md describes the file classes and the include-list rule, the candidate tree, the customizable decision table, the settings edit, the workflow rewrite, the token exchange and secret lookup, check mode, update mode, the pull request body, the action and the engine proof. D44 records the reuse of GHTOKENWORKFLOW in AL-Go's format with ghTokenWorkflowSecretName and closes O4 (#28). ARCHITECTURE sections 4, 5.3, 5.5, 7.3, 8, 11 and 13, naming.md, template-content.md, dashboard.md section 9, al-go-template-mechanics.md section 9.1, CONTRIBUTING (layout, the update-action job, the ruleset) and the template README follow: skeletons are generated from the settings, C9 matches unusedRulebookFiles by path (#49), update.schedule is a setting, Validate runs the update check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The repository, branch and commit of a template URL may hold '?', '#' or '%'. Join-ApiPath escapes each segment with EscapeDataString and keeps the slashes between them, for the installation, branch, zipball, pull request and label calls and the manual tree link of a refused pull request. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… a caller's work folder stays Validate imports Rulebook.GitHub and Rulebook.Update and names its work folder inside the try, so any failure of the check becomes "update check skipped". Both entry scripts remove only the temporary work folder they name themselves; a -WorkPath or -UpdateWorkPath the caller passes is left in place. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ed release notes, one removal rule - A file is binary by a longer extension list or a NUL byte in its first 8 KB (Test-BinaryFile), in the comparison, the copy and the content sha. - The pull request body is built from separate sections, without searching its own Markdown. Above the limit it drops the release notes, then endpoint tables of the effective diff from the end, each with an italic note, and only then cuts at a line boundary. - The release-notes heading shift leaves lines inside ``` and ~~~ fences alone. - Compare-CustomizableFile decides only the site files the template ships; removal goes through unusedRulebookFiles alone (the dead -Listed switch and the remove and vanished outcomes are gone). - update-mechanics.md: the binary rule, the body limit, the decision table, and the duplicate guard limitation stated plainly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…error kept, pull request stage, tokens masked - Get-RulebookTemplate downloads the installed commit whenever it differs from the new one, so every dropped managed file gets its note; -UpdateMode and -UnusedFiles are gone. - A failed exchange in the private-template retry rethrows the original error (its status kept, so a missing installed commit stays a note) and adds the exchange error as a note. -OnToken runs with every exchanged token first. - Publish-RulebookUpdate: the duplicate guard, the body and the opening are the pull-request stage; after the push a failure names the pushed branch and its tree link. Results carry DiffNote, which the summary renders, with the new release notes. - The sha-only check reads text only for the settings and workflow kinds; Get-TreeFile prunes .git, site/data and node_modules while walking. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…mmary capped The write token is exchanged and masked right after the token guard, before the template download and the plan; tokens exchanged for a private template are masked through -OnToken. In check mode any failure of the template or the plan is the warning "update check skipped" with exit 0; update mode still fails. The job summary is capped at 900 KiB at a line boundary, as Validate's is. Validate passes the new Get-RulebookTemplate parameters. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ontent, check limits update-mechanics.md and ARCHITECTURE 7.3 follow the code: the installed template is downloaded whenever it differs, a personal access token is used as it is while GitHub App JSON is exchanged, every token is masked when obtained, the push and pull-request stages, what the job summary holds and its cap, and that Validate's check is skipped for a template GITHUB_TOKEN cannot read. The template README links docs/updating.md and docs/ghtokenworkflow.md plainly and says when Validate reports an update. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e failures as notes, direct commit without the guard - Get-TreeFile skips directory symlinks and junctions. - A failed exchange for the new template adds its message to the original error (status kept). The installed zipball is read with the token the new template needed, without a second exchange; any failure there is a note. - Publish-RulebookUpdate runs the duplicate guard only for a pull request; a direct commit takes <sha7> from the cloned head and builds no body. - Limit-SummaryText cuts a summary at a line boundary, closes an open code fence and adds a footer. - New-GitHubClone takes extra GIT_CONFIG_* pairs as a test seam; the suite clones an https remote through url.<bare>.insteadOf and checks that the token is in neither the remote, the config nor any file under .git. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…reads with GITHUB_TOKEN only Both job summaries go through Limit-SummaryText with a footer that says where the full lists are (the pull request body, or the job log); Validate cuts its update-check section to what the cap leaves instead of dropping it. Check mode of CheckForUpdates passes no write token, as Validate. -SummaryLimit and -PublishCommand are test seams; the suite covers the push and pull-request failures, the failing plan's failure kind and a cut inside a fence. Docs: direct commits have no duplicate guard, the exchange order in ARCHITECTURE 7.3, the installed template read with the same token. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Group-Object sorts its groups by name, so the effective-diff tables of the update pull request and of the Validate summary came out in endpoint-name order (complete before recommended). Both now keep the order of the diff, which is the settings order. update-mechanics.md section 12 records the live run of 2026-10-07. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Member
Author
Live run (2026-10-07, C1 steps 5 to 8)Template Arthurvdv/rulebook-e2e-template, organization repository Arthurvdv/rulebook-e2e-update, a GitHub App as
|
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Member
Author
|
AC9 (2026-10-07): with GHTOKENWORKFLOW deleted, run 37645738825 failed in the action step with "The GHTOKENWORKFLOW secret is needed to update system files. Read https://github.com/ALCops/rulebook/blob/main/docs/ghtokenworkflow.md", before any request. Recorded in update-mechanics.md section 12 ( |
GitHub forbids secret names that start with GITHUB_ (any case). The settings schema pattern and the settings step of UpdateRulebookSystemFiles.yaml now reject them too, with fixtures on both sides. CheckForUpdates no longer falls back to GHTOKENWORKFLOW when the setting is present but invalid: update mode fails with failure=token and names the configured value. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… branch When the pull request cannot be opened after the push, the message now always starts with "Branch <name> was pushed." followed by the API message, which carries the tree link; the link is added only when it is missing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 7, 2026
Closed
Arthurvdv
added a commit
to ALCops/rulebook
that referenced
this pull request
Oct 7, 2026
User pages for the Update Rulebook System Files workflow, the user side of WP07 (engine side: ALCops/rulebook-engine#66, merged). - docs/updating.md (new): what an update changes (replaced, kept, regenerated, never touched, site files), running it, how Validate reports an update and when the check is skipped, the pull request (title, branch, labels, body sections, when a second one appears), unusedRulebookFiles as paths, update.schedule, direct commit and its fallback, troubleshooting with the messages as observed or taken from the code. - docs/ghtokenworkflow.md (new): why GITHUB_TOKEN is not enough, a GitHub App step by step with the one-liner for the compressed JSON, personal access tokens, repository and organization secrets, reuse with AL-Go, ghTokenWorkflowSecretName and its name rule, a private template, the failure messages. - docs/README.md: both pages listed; al-go.md and troubleshooting.md rows point at ghtokenworkflow.md for the secret. - README.md: section 1 links both pages. Review: three Sonnet code-review rounds at effort high, 29 findings, all fixed; two led to engine changes on ALCops/rulebook-engine#66. Part of ALCops/rulebook-engine#9 🤖 Generated with [Claude Code](https://claude.com/claude-code)
This was referenced Oct 7, 2026
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 #9, #28, #49 (WP07, engine side). The user pages
docs/updating.mdanddocs/ghtokenworkflow.mdfollow in a pull request to ALCops/rulebook right after this one.Summary
actions/CheckForUpdates(new): check mode (updateother than'Y') and update mode. InputstemplateUrl(empty uses the setting),templatePath/installedTemplatePath/templateSha(local templates for tests and CI),token,update,downloadLatest,directCommit,updateBranch,repositoryRoot,actor; outputsupdatesAvailable,pullRequestUrl,templateSha,failure(token,template,validation,push,pull-request,error). Check mode never fails: anything that goes wrong is one warningupdate check skipped: <reason>.modules/Rulebook.Update(new): file classes with AL-Go's include-list rule (overwrite, settings, generated, customizable, org-owned), the candidate tree, regeneration ofskeletons/andrulesets/,Test-Rulebookon the candidate as the gate before any push, the change list and the sha-only case, the D35 three-way decision forsite/**, the in-place settings edit of$schema,templateUrl,templateSha, the workflow rewrite ({TEMPLATEURL}, the ChangeRulelevels/stageschoice lists from the settings (D30),schedule:fromupdate.schedule) with a line editor ported from AL-Go'syamlclass, release notes newer than the installed copy, the pull request body with the effective diff, andPublish-RulebookUpdate(duplicate title guard, clone, commit, push, labelled pull request, direct commit with fallback to a pull request).modules/Rulebook.GitHub(new): one REST wrapper, theGHTOKENWORKFLOWexchange (personal access token as it is; GitHub App JSON in AL-Go's format exchanged for an installation token limited to the repository, RS256 JWT), zipball download, pull request helpers, and clone and push with the token only in the git process environment (http.<server>/.extraheaderthroughGIT_CONFIG_COUNT), never in a URL or git config.template/.github/workflows/UpdateRulebookSystemFiles.yaml(new): dispatch inputstemplateUrl,downloadLatest,directCommit; read-onlyGITHUB_TOKEN; a settings step resolves the secret name fromghTokenWorkflowSecretName; the update writesschedule:fromupdate.schedule.checkForUpdatesis wired: one notice or warning and a## Template update checksummary section, read withGITHUB_TOKEN, never counted towardswarnings=orfailOnWarning.unusedRulebookFilesentries are repository-relative paths with/(schema pattern); C9 matches them by path only, as the update does. Newupdate.schedule(five-field cron ornull).tests/fixtures/templates/v1andv2andtests/fixtures/repos/update-org, generated parts written by the engine functions, derivation and the exact v1 -> v2 difference list intests/fixtures/templates/README.md(asserted by a test).Rulebook.GitHub.Tests.ps1,Rulebook.Update.Tests.ps1(includingPublish-RulebookUpdateagainst a bare git repository with apre-receivehook as branch protection),CheckForUpdates.Action.Tests.ps1, and additions to the Validate, Validate action, Template and Schemas suites. 1196 tests, green on Windows and on Linux.update-action(check mode onupdate-orgagainst v1 and v2, update mode without a token must fail withfailuretoken); the Validate fixture steps passcheckForUpdates: 'false'.docs/reference/update-mechanics.md(new); ADR D44 closes O4 (O4: Name of the write token secret (reuse GHTOKENWORKFLOW or a Rulebook-specific name) #28); ARCHITECTURE 4, 5.3, 5.5, 7.3, 8, 11, 13; naming.md; template-content.md (42 files, 10 hand-written); dashboard.md 9; al-go-template-mechanics.md 9.1; CONTRIBUTING (layout, CI, ruleset); the template README.Interview decisions (2026-10-07)
GHTOKENWORKFLOW.GHTOKENWORKFLOW, AL-Go format,ghTokenWorkflowSecretName);unusedRulebookFilesas repository-relative paths.secrets[steps.settings.outputs.secretName]; the action does the exchange and masks the token.update.schedulein v1, written into the workflow by the update.update-action.update-mechanics.md, ARCHITECTURE touch-ups, D44; user docs in ALCops/rulebook.skeletons/*.ruleset.jsonare generated from the settings.Review
Three Sonnet code-review rounds on the engine at effort high: 31 findings, 29 fixed, 1 accepted (the duplicate guard embeds the base head sha, AL-Go behaviour), 2 deferred to #58 (helper duplication, comment on #58). Fixed among others: binary detection by content, a sectioned PR body with truncation by whole parts, fence-aware release-note headings, escaped REST path segments, caller work folders kept, check mode never failing, the installed template downloaded on every differing run with every failure there a note, the original error kept when an exchange fails, tokens masked the moment they are obtained, the push and pull-request failure stages, no duplicate guard for direct commits, summaries cut at a line boundary with fences closed, link loops not followed, and a real https clone test for the token-free git config. The docs review of ALCops/rulebook#4 (three rounds, 29 findings) led to two more engine changes here:
ghTokenWorkflowSecretNamerejects theGITHUB_prefix with no silent fallback, and a failed pull request step always says "Branch was pushed.".Known limitations
<sha7>in the title, so the next run opens a second update pull request (AL-Go behaviour).docs/updating.mdanddocs/ghtokenworkflow.mdland with the ALCops/rulebook pull request that follows; the links return 404 until then.GITHUB_TOKENonly: a private template, or a pull request from a fork, gives "update check skipped".Deviations from the issue text
skeletons/*.ruleset.jsonare generated from the organization's settings on every update, not overwrite; onlyskeletons/README.mdis overwrite.update.schedule(the open question answered: in v1).templatePathandinstalledTemplatePathfor local templates (tests and CI).unusedRulebookFilesentries need at least one/(every managed path has a folder); a bare file name is rejected by the schema.{TEMPLATEURL}placeholder, so a repository fresh from the template gets the "not recorded" notice rather than "updates available".Spin-offs
checkForUpdates: 'false'in Validate.yaml, is reverted by the next update).Live run (2026-10-07)
AC1 to AC10 met on Arthurvdv/rulebook-e2e-template and Arthurvdv/rulebook-e2e-update with a GitHub App as
GHTOKENWORKFLOW: the first run's PR withtemplateShaand{TEMPLATEURL}only, then "No updates available"; "Updates available" in Validate after the template moved; a level change regenerating the chained endpoints withessential.*untouched; "Pull request already exists"; a stage change regenerating only*.ci; an override winning; org files untouched;update.scheduleadded and removed;directCommitfalling back to a PR under a ruleset; and without the secret "The GHTOKENWORKFLOW secret is needed ...". Thesecrets[steps.settings.outputs.secretName]lookup works, and no token appears in the logs. Runs, PRs and observations:docs/reference/update-mechanics.mdsection 12 and the comments below. One engine fix came from the run (endpoint order in the effective-diff tables).Docs
ALCops/rulebook#4 (
docs/updating.md,docs/ghtokenworkflow.md); merge this PR first.🤖 Generated with Claude Code