docs: make release-path script the sole source #260
No reviewers
Labels
No labels
attention
blocked
blocker:ci-red
blocker:conflict
blocker:drill-pending
blocker:unrequested
bug
claimed
documentation
enhancement
epic
merge-next
needs-ruling
needs-triage
offsite
post-merge
ready
release
scope:docs
scope:guards
scope:labels
scope:release-flow
stale
state:addressing
state:bots-reviewing
state:building
state:needs-human
No milestone
No project
No assignees
4 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: heavy-duty/ceremony#260
Loading…
Reference in a new issue
No description provided.
Delete branch "build/251-release-path-doc"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #251
Summary
Make
.github/scripts/release-path.shthe sole release-path enumeration in drill doctrine, and guard against reintroducing a copied list.Worklog
build/251-release-path-docfromorigin/main6 passed, 1 failed; all five forbidden tokens reportedchangelog.d/251.mdgit diff --check, exact-scope, and script byte-identity checksAcceptance criteria
drills/README.mdcontains none ofbin/,lib/version.sh,lib/decide.sh,lib/facts.sh,lib/changelog.sh, and still contains condition 1’s.github/workflows/release.ymland the worked example’slib/ruling.sh..github/scripts/release-path.sh, tells the record author to run it, and limits the contract-test claim to the script’s list.test/release-path.test.shcarries a case that fails on the pre-change README and passes after; both runs are recorded.bash test/run.shis green whole at the PR head;git diff --checkis clean.drills/README.md,test/release-path.test.sh, andchangelog.d/251.md;.github/scripts/release-path.shis byte-identical tomain.Test evidence
RED-first focused run on commit
17b9918:Wrong-fix control: reintroducing any one enumeration-only token, including a seemingly helpful
lib/forge.sh, makes the guard red.Final verification at
1cd8a69:7 passed, 0 failed.lib/forge.shrestored temporarily):6 passed, 1 failed, with the offending token named.31 test files passed, 0 failed.64 tracked scripts, clean.git diff --check: clean..github/scripts/release-path.shbyte-identical toorigin/main.Round log
Round at
1cd8a699Round passed with no written reply.
📣 round answered at head
1cd8a6996fWIP: docs: make release-path script the sole sourceto docs: make release-path script the sole source🔎 reviewing head
1cd8a6996fReviewed in a detached worktree at that head against #251.
drills/README.mdhas 0 occurrences ofbin/,lib/version.sh,lib/decide.sh,lib/facts.sh,lib/changelog.sh; condition 1's.github/workflows/release.yml(L85) and the worked example'slib/ruling.sh(L103, L106) still stand..github/scripts/release-path.sh" claim, adds the run-and-paste instruction and the$(sh …)diff form, and the guarantee sentence now claims only the script's list.17b9918(6 passed, 1 failed; all five tokens named); GREEN ata0ffc4band at the head. Every single-token reintroduction (lib/forge.sh,lib/version.sh,bin/,lib/changelog.sh) turns it red naming that token.git diff --checkclean; repo shellcheck sweep clean over 64 tracked scripts.bash test/run.shlocally: 28 files pass, 3 fail identically atorigin/main(yqabsent in this box) — CItestis green at the head.drills/README.md,test/release-path.test.sh,changelog.d/251.md;release-path.shsha256 identical tomain.Verdict submitted.
🔎 reviewing head
1cd8a6996f1cd8a6996f(verified via submit-verdict.sh)🔎 reviewing head
1cd8a6996fApprove. Reviewed the whole PR at head
1cd8a6996f6e1d4699b6cdd3d7a21ee4675ac843against #251's acceptance criteria in a detached throwaway worktree, verifying by running rather than reading claims.Acceptance criteria — all five verified at the head:
drills/README.mdcontains none of the six enumeration tokens (bin/,lib/version.sh,lib/decide.sh,lib/facts.sh,lib/changelog.sh,lib/forge.sh— 0 grep matches each; the sixth token is the wrong-fix control the issue's test plan demands, made permanent) while condition 1's.github/workflows/release.yml(1 occurrence) and the worked example'slib/ruling.sh(2) remain untouched — the diff's only README hunk is condition 2..github/scripts/release-path.sh"), directs the record author to run the script and paste its output, gives the records' owngit diff <last-rehearsed-tag>..HEAD -- $(sh .github/scripts/release-path.sh)form, and scopes the contract-test sentence to the script's list only. No release-path member is named in prose.main's unedited README —6 passed, 1 failed, all five forbidden tokens named, byte-identical to the builder's recorded RED — and green at the head (7 passed, 0 failed); the wrong-fix control (temporarily reintroducinglib/forge.sh) goes red naming the token. Both runs are recorded in the PR body.bash test/run.shgreen whole at the head: 31 test files, 0 failed.git diff --checkclean.drills/README.md,test/release-path.test.sh,changelog.d/251.md;.github/scripts/release-path.shhas an empty diff againstorigin/main(byte-identical).Also verified: the fragment matches the
groupedsentinel's shape under### Fixedand names #251; the sanctionedshellcheck-all.shsweep passes (64 tracked scripts, clean) andactionlint-all.shpasses at the head; conventions hold (set -utest style, decision logic in the test file where a test can drive it).What I could not verify and relied on instead: the Forgejo per-check payload returned null conclusions for the seven CI contexts, so individual check results were not directly readable — I relied on the combined commit status (
success) for the head and independently re-ran every gate the PR claims locally (focused tests incl. RED and wrong-fix controls, whole suite, shellcheck, actionlint,git diff --check), all green.Non-blocking nit, none blocking: the guard hardcodes its forbidden-token list, an inherent third copy — that is the spec's own design (a guard must name what it forbids), and its contract test now covers both directions.
Approve.
The PR matches issue #251's acceptance criteria:
drills/README.mdcondition 2 now states the release path is exactly.github/scripts/release-path.shoutput, directs the record author to run the script, and no longer duplicates the inline six-path list..github/workflows/release.ymland the worked example'slib/ruling.shmentions are untouched.test/release-path.test.shcarries the new guard case; it fails on main'sdrills/README.md(all five enumeration tokens reported) and passes at this head.drills/README.md,test/release-path.test.sh, andchangelog.d/251.md;.github/scripts/release-path.shis byte-identical tomain.git diff --checkis clean.Verification:
bash test/release-path.test.shpasses (7/7).drills/README.mdin the review tree and re-running the new case; it fails as required.bash test/run.shwhole-suite has the same pre-existing package-json failures asmain(nodeis not installed on this box), so they are environmental and unrelated to this change.Non-blocking nit: the guard checks six tokens (
bin/,lib/version.sh,lib/decide.sh,lib/facts.sh,lib/changelog.sh, pluslib/forge.sh) rather than the five decision 4 names, but this is consistent with the issue's own test-plan example and is defensively correct. It does not affect the stated acceptance criterion.Approve
Reviewed the whole PR at
1cd8a6996f6e1d4699b6cdd3d7a21ee4675ac843in a detached worktree, against #251's acceptance criteria, then the repo's constraints, then the code. Every criterion is met and the guard does what the issue asked it to do.What I ran
RED-first ordering is real, not asserted. I checked out each commit and ran the focused file:
17b9918(guard added, doctrine untouched)6 passed, 1 failed— all five tokens nameda0ffc4b(condition 2 rewritten)7 passed, 0 failed1cd8a69(head)7 passed, 0 failedThe RED output matches the PR body byte-for-byte, including the five reported tokens.
The guard fails on a single reintroduction, not just on the whole list. I appended one stray token at a time to
drills/README.mdand re-ran; each turns the case red and names exactly the offending token:The
lib/forge.shrow is the test plan's named wrong-fix class, and it is only catchable because the builder carried a sixth token beyond the issue's five. That is the right call: decision 4 names five, but the test plan requires "a helpfullib/forge.sh" to turn the case red, which the five alone cannot do.lib/forge.shoccurs zero times in the README today, so the extra token costs no false positive.Independent RED control on
main's doctrine. Withgit show origin/main:drills/README.mdswapped in at the head's test file:6 passed, 1 failed, five tokens reported. The guard is measuring the file, not the commit.Acceptance criteria, each measured:
drills/README.md; condition 1's.github/workflows/release.ymlstands at L85 and the worked example'slib/ruling.shat L103 and L106. Untouched, as decision 3 required..github/scripts/release-path.sh" claim, adds the run-and-paste instruction plusgit diff <last-rehearsed-tag>..HEAD -- $(sh .github/scripts/release-path.sh), and the guarantee sentence now reads "The script's contract test keeps its list…" — coverage claimed only for the script. The sentence that used to tell a reader they need not check the script is gone.git diff --check origin/main...HEADclean;bash .github/scripts/shellcheck-all.shexit 0 over 64 tracked scripts;shellcheck -x test/release-path.test.shclean.git diff origin/main...HEAD --statis exactlychangelog.d/251.md,drills/README.md,test/release-path.test.sh..github/scripts/release-path.shsha2563dfd5c95…07fcon both sides; the diff for that path is empty.Constraints checked beyond the issue.
drills/is already an inventoried forge-delta location anddrills/*.mdalready resolves to this tree in the conflict table (docs/UPSTREAM-SYNC.md), so this edit owes no new inventory row — andtest/upstream-delta.test.shis green.drills/README.mdis not indocs/VENDORED.txt, so no mirror is owed.changelog.d/251.mdcarries the### Fixedheading thegroupedsentinel declares and matches its siblings.drills/**maps toscope:release-flowand nothing else in.github/labeler.yml, which is the single scope label on the PR.Closes #251is the correct keyword: every criterion on that issue is pre-merge, so this is not aRefsshape.sh .github/scripts/release-path.shruns clean here under dash and prints all seven paths, so the documented command form works as written.What I could not verify, and what I relied on instead
bash test/run.shin my box gives 28 test files passed, 3 failed, not the PR's31 passed, 0 failed. The three arelabels-bootstrap,labels-dispatchandlabels-triggers, and the cause isyq: command not found—yqis absent from this box. I ran the same three files atorigin/mainin a second worktree as the control and got byte-identical counts (7/7,7/14,28/4), so the gap is my environment, not this PR, and none of the three reads any file this PR touches.CI / testis green at this head, which is the evidence for those three.actionlintis also absent here; I relied on the greenCIrun for it.Non-blocking nits (yours to take or leave)
readme_has_no_path_enumerationgreps a path directly; I removeddrills/README.mdand re-ran, and the case reportsokwith the suite at7 passed, 0 failed. A rename that carried the enumeration to a new filename would leave the guard green. A one-line[ -f "$ROOT/drills/README.md" ] || return 1closes it. This is the shapetest/upstream-delta.test.shrefuses in its own header ("a guard that goes green when it cannot see its input is the blind-sweep shape this repo keeps writing issues about"), and the same point on that file came from a review round (#200)..github/workflows/release.ymlandlib/ruling.share deliberately excluded because conditions 1 and the worked example own them — lives only in #251. A future editor "completing" the list would turn condition 1 red. Two lines with a bare(#251)would carry it, per CONTRIBUTING's comment convention.Neither gates the merge. The deliverable is exactly what #251 specified, the guard fails where it must, and the release path now has one list.