diff --git a/.github/workflows/labels-sweep.yml b/.github/workflows/labels-sweep.yml index ffa2d61..707b871 100644 --- a/.github/workflows/labels-sweep.yml +++ b/.github/workflows/labels-sweep.yml @@ -49,7 +49,7 @@ on: env: # A called workflow arrives without its repository. Keep this literal pin # aligned with the ceremony release consumed by callers (issue #9 D3). - CEREMONY_SELF_REF: "0.5.0" + CEREMONY_SELF_REF: "0.6.0" jobs: reconcile: diff --git a/.github/workflows/labels.yml b/.github/workflows/labels.yml index 46234d1..f787729 100644 --- a/.github/workflows/labels.yml +++ b/.github/workflows/labels.yml @@ -48,7 +48,7 @@ on: env: # A called workflow arrives without its repository. Keep this literal pin # aligned with the ceremony release consumed by callers (issue #9 D3). - CEREMONY_SELF_REF: "0.5.0" + CEREMONY_SELF_REF: "0.6.0" jobs: scope: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 62e8928..4941d7f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -129,7 +129,7 @@ env: # `ref:` accepts ${{ env }}; `uses:` strings do not — which is why the # shared logic arrives as script files via checkout, not as inner `uses:` # references. - CEREMONY_SELF_REF: "0.5.0" + CEREMONY_SELF_REF: "0.6.0" VERSION_SOURCE: ${{ inputs.version-source }} jobs: diff --git a/CHANGELOG.md b/CHANGELOG.md index 491b733..6f9675b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,201 @@ Entries arrive as fragments — one `changelog.d/.md` per PR, never an edit to this file — and the release PR assembles them into the next section here (`bin/changelog-assemble`, #112). +## 0.6.0 — 2026-08-05 + +### Added + +- The issue-flow sweep's `claimed`-branch ruling pre-read is pinned: an + unassigned claim under `needs-ruling` must draw its board diagnostic and + its ruling nudge in one sweep, so a read that drifts below the diagnostic + reds instead of silently costing the escalation 7 days (#284, #307). +- The issue-flow sweep now flags a collision the board never declared: two + open, unblocked issues whose titles name one deliverable draw a comment + naming the newer's owed `Blocked by` edge. Keys normalize, so + `actions/x` and `x` are one deliverable (#288). +- The sweep now flags an unblocked non-member during a standing release + window, naming the window's invariant. `claimed` counts, PR in flight or + not. The gate is read from the release issue's own `Blocked by` + declarations, and an emptied gate leaves it dormant (#292). +- Both flags are advisory: comments only, no label write and no state + change, deduped against each family's last word on the thread so a + standing state re-sweeps silently (#293). +- The fragment guard now requires each entry to end with its issue + citation: one `(#N)` group — local, `repo#N` or `owner/repo#N` + references separated by `, ` — then the final `.` and nothing after it + (#262). +- The refusal distinguishes an entry carrying no reference at all from one + whose reference is present but not terminal, and names the shape to + write in both (#262). +- The 300-character bound still outranks the citation across the whole + fragment, and the outranked problem stays out of the message it lost + to: one fragment, one diagnosis, wherever in the file it sits (#262). +- BUILDER.md now describes a fix round that rides a draft: the draft phase + stays the builder's, ready-for-review is the builder's own act, and where a + draft suppressed the checks green is proven at the flip (#258). +- REVIEWER.md now reads a draft carrying `state:addressing` as a fix round in + progress rather than abandonment (#258). +- A `post-merge` item with no comment for 7 days now draws one nudge from the + issue sweep: the wake evidence is owed. A starving criterion used to be + found only when someone happened to run the right read (#254). +- Label churn does not reset that clock, and neither does an assignment: on + `post-merge` an assignee is an invalid composition, not activity, and it + must not buy the item another 7 days of silence (#254). +- The nudge names the triage actor from `triage-actors=`, not the human + reviewer: `post-merge` is triage's completion queue, so the starved wake + condition is triage's to answer (#254). +- It links the item and parses nothing from the body — which criterion + starved is prose, and the machine never judges prose (#254). +- Like the ruling nudge it carries no idempotency marker on purpose: the + comment is itself activity, so the rule self-rate-limits to one nudge per 7 + quiet days. Comment-only — no path here writes a label (#254). +- Release epics now announce release initialization when their declared dependency gates clear (#253). +- The issue sweep now echoes an issue's parsed `Blocked by` set as a comment + whenever that set changes, so a readable-but-wrong declaration is visible in + one sweep instead of days later, when a human happens to run the parser by + hand (#252). +- The echo's marker carries the parsed set itself: an unchanged parse never + re-posts on a 15-minute cron, and a changed one always speaks. Comment-only + — no path here writes a label (#252). +- CI now refuses a root `*.md` declared in neither `docs/VENDORED.txt` nor the + guard's short exemption list, so a new doctrine file can no longer reach a + tag undeclared and stay invisible to every consumer's `docs-sync` (#251). +- The same guard reads the manifest the other way: every entry must resolve to + a regular, non-empty, tracked file — no symlink, no directory, no `../` + escape (#251). +- Document the optional, operator-ruled release-epic flow for governed repositories. (#248). +- Guard documentation availability markers against missing issue citations + and release candidates that already ship the cited work (#238). +- The label and issue-flow sweeps now comment once per episode when + `attention` targets a pull request or an unassigned issue, without + retargeting the demand or changing labels or assignees (#232). +- Pull requests that promise `Refs #N` now fail a read-only, body-edit-aware + guard if GitHub would close N through a keyword or sidebar link (#218). + +### Changed + +- `README.md` is rewritten whole from the current tree: the front page names + the governance repo ceremony now is, routes to `docs/CONSUMERS.md`, + `AGENTS.md`, `LABELS.md` and `RELEASES.md` rather than restating them, and + keeps the operator's release runbook as its core, re-measured (#311). +- Standing release windows are dependency DAGs: every mint is placed in the window or behind it, and only current sources are `ready` (#292). +- TRIAGE.md now requires unconditional collision-edge chains when open issues + carry the same deliverable, keeping the ready queue concurrently claimable + (#288). +- TRIAGE.md now states its rules with bare record cites: the label-race and + lifted-hold incident narratives leave the normative text while their + operational rules remain complete (#282). +- `BUILDER.md` states its rules and cites their record bare: the incident + narratives, the links into issue comments and the cross-repo issue cites + leave the normative text, which no rule leaves with them (#281). +- CONTRIBUTING.md now keeps vendored doctrine self-contained: state the rule, + retain at most one sentence of why, cite the local record bare, and leave the + incident narrative in that record (#280). +- BUILDER.md's green ruled term now says which entry to read before it says + what an entry means: a check's word at a head is its newest entry by start + time, and a cancelled entry is not that word while the same check carries a + non-cancelled one at that head (#276). +- A check whose every entry at the head is cancelled is unchanged — nothing + survived to be its word, so it never reported and is not green — and the + collapse mirrors `checks_state`'s carve-out rather than adding a class + (#276). +- BUILDER.md's step 1 now rules the checkless head: no checks configured is + nothing to wait for, and the request goes out straight away — stated once, + in the ruled-term paragraph, with the draft-round restatement removed + (#272). +- `README.md` and `RELEASES.md` derive `scope:docs`, and the + `changelog-assembled`, `docs-sync` and `runner-isolated` actions and tests + derive `scope:guards`; all five were mapped nowhere. The docs block matched + a literal `README`, which this tree does not carry (#267). +- `lib/read.sh` and `lib/ruling.sh` derive `scope:labels` beside + `scope:release-flow`. Both reconcilers share them, and a mixed file wears + both labels rather than `lib/**` being re-carved into a row per file (#267). +- TRIAGE.md now tells every epic author to put its progress checklist under + the literal `## Task list` heading, because any other heading is silently + invisible to the completion sweep (#266). +- TRIAGE.md now scopes the no-assignee board bug to flagging an unassigned + issue, while still directing triage to repair ownership instead (#264). +- `BUILDER.md` and `CHANGELOG.md` state the citation as guard-enforced + rather than as house style, beside the 300-character bound it now sits + next to (#262). +- Four fragments in flight gained a terminal citation; published sections + are untouched, so no shipped prose is re-opened (#262). +- BUILDER.md's green ruled term now names its field: greenness is read from + each check's `conclusion`, never its `status`, and *stale* means a check + of a superseded head — not a same-head node whose `status` lags its own + conclusion (#260). +- Consumer guidance: re-vendor tooling reads the pin's `docs/VENDORED.txt`, + never a hardcoded list, so a new doctrine file propagates at the next + ordinary pin bump with zero list edits (#251). +- Define the doors-unchanged drill record and an executable release-path list, + so a release may reuse live evidence only when its door bytes are unchanged + since the last rehearsed tag (#237). + +### Fixed + +- A roster edit no longer reds the whole suite: the labels-reconcile + state-machine fixtures name their own panel instead of binding + `.github/labels.conf` by slot (#304). +- Shrinking `panel=` to three had left that binding's third slot unbound, and + `set -u` aborted the file before its first assertion — 217 assertions + became 0, on `main` and on every branch cut from it (#304). +- The one case still reading the shipped roster asserts a property, not a + size: it parses, and each member is recused from its own panel. Any + `panel=` of one or more members leaves `test/run.sh` green (#304). +- `lib/attention.sh` locates as label machinery beside its two shelf-mates — + `[scope:release-flow]` alone was a wrong answer of the class #267 measured + — and the map learns the sweep workflow pair, the shared-lib tests, and + seven enumerated test/guard surfaces (#302). +- Claiming a `needs-ruling` issue no longer buys its escalation another 7 + quiet days: the issue-side ruling clock reads comments alone — an + assignment is the claim clock's fact — and LABELS.md now names what each + surface's clock reads (#284). +- `scope:release-flow` no longer rides every pull request: `changelog.d/**` + is out of its path map. Doctrine makes every behavior change write a + fragment, so the glob labelled 20 of the last 20 PRs while 3 touched a + release surface. `CHANGELOG.md` stays, as only the release PR edits it + (#267). +- The issue-flow reconciler and its test now derive `scope:labels`, the scope + that already names the taxonomy they reconcile (#267). +- Abort issue-flow reconciliation when the board read fails instead of reporting a complete pass over an empty or partial result (#257). +- The issue sweep no longer derives label writes from a read that failed. An + HTTP 504 whose body is GitHub's JSON error object passed every guard and + emptied the label set, so a healthy epic was written `needs-triage` and the + pass reported success (#247). +- A failed comments read no longer reclaims a live claim. Swallowed, it dated + the issue by `created_at` and unassigned the builder under a comment + asserting 48 hours of silence about an issue commented on seconds earlier + (#247). +- A failed comments read no longer reads as "no marker", which re-posted the + comment the marker exists to suppress (#247). +- Every read inside the per-issue subshell is checked explicitly, on its + status and on its payload shape; the issue is left exactly as it is and the + sweep continues. A partial pass names its skipped issues after + `reconciled.` (#247). +- A per-issue pass is now atomic: its writes and its log lines commit only + once the pass completes. A skip could previously land after an earlier + mutation, reporting an issue as untouched when a label had already been + written or removed (#247). +- The issue-flow sweep now reads an issue's deliverable as the `Refs` PR that + merged last, not the one numbered highest — merge order is not number order, + and the old rule spent the transition marker on the wrong PR (#242). +- Preserve active claims when an open local pull request links them with `Refs #N`. (#241). +- `blocker:unrequested` no longer fires while a head's checks are pending or + red: the review round forbids requesting there, so the one blocker that + demanded an act flagged builders for complying. Pending is CI's move, red is + `blocker:ci-red`'s (#236). +- `blocker:unrequested` now waits for the round to settle — the head and the + newest verdict must have stood for `RECONCILE_UNREQUESTED_GRACE` (default + 300s) — so a sweep landing between a push and its re-request no longer flags + a round in motion (#236). +- LABELS.md no longer claims nothing in `actions/` clears or reads + `attention`: the reconciler has done both since the derived `claimed` → + `post-merge` transition shipped. The amended text keeps the hand-set rule + and admits the one clear and the diagnostic read (#231). +- Triage now puts `attention` on the assigned issue that owns a claim, never + on its pull request, and treats an unassigned issue as a board bug rather + than a demand (#230). + ## 0.5.0 — 2026-08-03 ### Added diff --git a/VERSION b/VERSION index 53978e5..a918a2a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.5.1-dev +0.6.0 diff --git a/changelog.d/218.md b/changelog.d/218.md deleted file mode 100644 index cdbdc46..0000000 --- a/changelog.d/218.md +++ /dev/null @@ -1,4 +0,0 @@ -### Added - -- Pull requests that promise `Refs #N` now fail a read-only, body-edit-aware - guard if GitHub would close N through a keyword or sidebar link (#218). diff --git a/changelog.d/230.md b/changelog.d/230.md deleted file mode 100644 index 159ce2b..0000000 --- a/changelog.d/230.md +++ /dev/null @@ -1,5 +0,0 @@ -### Fixed - -- Triage now puts `attention` on the assigned issue that owns a claim, never - on its pull request, and treats an unassigned issue as a board bug rather - than a demand (#230). diff --git a/changelog.d/231.md b/changelog.d/231.md deleted file mode 100644 index df32aeb..0000000 --- a/changelog.d/231.md +++ /dev/null @@ -1,6 +0,0 @@ -### Fixed - -- LABELS.md no longer claims nothing in `actions/` clears or reads - `attention`: the reconciler has done both since the derived `claimed` → - `post-merge` transition shipped. The amended text keeps the hand-set rule - and admits the one clear and the diagnostic read (#231). diff --git a/changelog.d/232.md b/changelog.d/232.md deleted file mode 100644 index 6785136..0000000 --- a/changelog.d/232.md +++ /dev/null @@ -1,5 +0,0 @@ -### Added - -- The label and issue-flow sweeps now comment once per episode when - `attention` targets a pull request or an unassigned issue, without - retargeting the demand or changing labels or assignees (#232). diff --git a/changelog.d/236.md b/changelog.d/236.md deleted file mode 100644 index 2d76876..0000000 --- a/changelog.d/236.md +++ /dev/null @@ -1,10 +0,0 @@ -### Fixed - -- `blocker:unrequested` no longer fires while a head's checks are pending or - red: the review round forbids requesting there, so the one blocker that - demanded an act flagged builders for complying. Pending is CI's move, red is - `blocker:ci-red`'s (#236). -- `blocker:unrequested` now waits for the round to settle — the head and the - newest verdict must have stood for `RECONCILE_UNREQUESTED_GRACE` (default - 300s) — so a sweep landing between a push and its re-request no longer flags - a round in motion (#236). diff --git a/changelog.d/237.md b/changelog.d/237.md deleted file mode 100644 index 59a0d4f..0000000 --- a/changelog.d/237.md +++ /dev/null @@ -1,5 +0,0 @@ -### Changed - -- Define the doors-unchanged drill record and an executable release-path list, - so a release may reuse live evidence only when its door bytes are unchanged - since the last rehearsed tag (#237). diff --git a/changelog.d/238.md b/changelog.d/238.md deleted file mode 100644 index 6805c0b..0000000 --- a/changelog.d/238.md +++ /dev/null @@ -1,4 +0,0 @@ -### Added - -- Guard documentation availability markers against missing issue citations - and release candidates that already ship the cited work (#238). diff --git a/changelog.d/241.md b/changelog.d/241.md deleted file mode 100644 index a095226..0000000 --- a/changelog.d/241.md +++ /dev/null @@ -1,3 +0,0 @@ -### Fixed - -- Preserve active claims when an open local pull request links them with `Refs #N`. (#241). diff --git a/changelog.d/242.md b/changelog.d/242.md deleted file mode 100644 index 73e8d48..0000000 --- a/changelog.d/242.md +++ /dev/null @@ -1,5 +0,0 @@ -### Fixed - -- The issue-flow sweep now reads an issue's deliverable as the `Refs` PR that - merged last, not the one numbered highest — merge order is not number order, - and the old rule spent the transition marker on the wrong PR (#242). diff --git a/changelog.d/247.md b/changelog.d/247.md deleted file mode 100644 index a2243dd..0000000 --- a/changelog.d/247.md +++ /dev/null @@ -1,20 +0,0 @@ -### Fixed - -- The issue sweep no longer derives label writes from a read that failed. An - HTTP 504 whose body is GitHub's JSON error object passed every guard and - emptied the label set, so a healthy epic was written `needs-triage` and the - pass reported success (#247). -- A failed comments read no longer reclaims a live claim. Swallowed, it dated - the issue by `created_at` and unassigned the builder under a comment - asserting 48 hours of silence about an issue commented on seconds earlier - (#247). -- A failed comments read no longer reads as "no marker", which re-posted the - comment the marker exists to suppress (#247). -- Every read inside the per-issue subshell is checked explicitly, on its - status and on its payload shape; the issue is left exactly as it is and the - sweep continues. A partial pass names its skipped issues after - `reconciled.` (#247). -- A per-issue pass is now atomic: its writes and its log lines commit only - once the pass completes. A skip could previously land after an earlier - mutation, reporting an issue as untouched when a label had already been - written or removed (#247). diff --git a/changelog.d/248.md b/changelog.d/248.md deleted file mode 100644 index baa2137..0000000 --- a/changelog.d/248.md +++ /dev/null @@ -1,3 +0,0 @@ -### Added - -- Document the optional, operator-ruled release-epic flow for governed repositories. (#248). diff --git a/changelog.d/251.md b/changelog.d/251.md deleted file mode 100644 index 7853b80..0000000 --- a/changelog.d/251.md +++ /dev/null @@ -1,14 +0,0 @@ -### Added - -- CI now refuses a root `*.md` declared in neither `docs/VENDORED.txt` nor the - guard's short exemption list, so a new doctrine file can no longer reach a - tag undeclared and stay invisible to every consumer's `docs-sync` (#251). -- The same guard reads the manifest the other way: every entry must resolve to - a regular, non-empty, tracked file — no symlink, no directory, no `../` - escape (#251). - -### Changed - -- Consumer guidance: re-vendor tooling reads the pin's `docs/VENDORED.txt`, - never a hardcoded list, so a new doctrine file propagates at the next - ordinary pin bump with zero list edits (#251). diff --git a/changelog.d/252.md b/changelog.d/252.md deleted file mode 100644 index 3b47994..0000000 --- a/changelog.d/252.md +++ /dev/null @@ -1,9 +0,0 @@ -### Added - -- The issue sweep now echoes an issue's parsed `Blocked by` set as a comment - whenever that set changes, so a readable-but-wrong declaration is visible in - one sweep instead of days later, when a human happens to run the parser by - hand (#252). -- The echo's marker carries the parsed set itself: an unchanged parse never - re-posts on a 15-minute cron, and a changed one always speaks. Comment-only - — no path here writes a label (#252). diff --git a/changelog.d/253.md b/changelog.d/253.md deleted file mode 100644 index 25cb78d..0000000 --- a/changelog.d/253.md +++ /dev/null @@ -1,3 +0,0 @@ -### Added - -- Release epics now announce release initialization when their declared dependency gates clear (#253). diff --git a/changelog.d/254.md b/changelog.d/254.md deleted file mode 100644 index 92ca2d5..0000000 --- a/changelog.d/254.md +++ /dev/null @@ -1,16 +0,0 @@ -### Added - -- A `post-merge` item with no comment for 7 days now draws one nudge from the - issue sweep: the wake evidence is owed. A starving criterion used to be - found only when someone happened to run the right read (#254). -- Label churn does not reset that clock, and neither does an assignment: on - `post-merge` an assignee is an invalid composition, not activity, and it - must not buy the item another 7 days of silence (#254). -- The nudge names the triage actor from `triage-actors=`, not the human - reviewer: `post-merge` is triage's completion queue, so the starved wake - condition is triage's to answer (#254). -- It links the item and parses nothing from the body — which criterion - starved is prose, and the machine never judges prose (#254). -- Like the ruling nudge it carries no idempotency marker on purpose: the - comment is itself activity, so the rule self-rate-limits to one nudge per 7 - quiet days. Comment-only — no path here writes a label (#254). diff --git a/changelog.d/257.md b/changelog.d/257.md deleted file mode 100644 index b49ecfa..0000000 --- a/changelog.d/257.md +++ /dev/null @@ -1,3 +0,0 @@ -### Fixed - -- Abort issue-flow reconciliation when the board read fails instead of reporting a complete pass over an empty or partial result (#257). diff --git a/changelog.d/258.md b/changelog.d/258.md deleted file mode 100644 index b03d4a0..0000000 --- a/changelog.d/258.md +++ /dev/null @@ -1,7 +0,0 @@ -### Added - -- BUILDER.md now describes a fix round that rides a draft: the draft phase - stays the builder's, ready-for-review is the builder's own act, and where a - draft suppressed the checks green is proven at the flip (#258). -- REVIEWER.md now reads a draft carrying `state:addressing` as a fix round in - progress rather than abandonment (#258). diff --git a/changelog.d/260.md b/changelog.d/260.md deleted file mode 100644 index d32662f..0000000 --- a/changelog.d/260.md +++ /dev/null @@ -1,6 +0,0 @@ -### Changed - -- BUILDER.md's green ruled term now names its field: greenness is read from - each check's `conclusion`, never its `status`, and *stale* means a check - of a superseded head — not a same-head node whose `status` lags its own - conclusion (#260). diff --git a/changelog.d/262.md b/changelog.d/262.md deleted file mode 100644 index 89e90fa..0000000 --- a/changelog.d/262.md +++ /dev/null @@ -1,20 +0,0 @@ -### Added - -- The fragment guard now requires each entry to end with its issue - citation: one `(#N)` group — local, `repo#N` or `owner/repo#N` - references separated by `, ` — then the final `.` and nothing after it - (#262). -- The refusal distinguishes an entry carrying no reference at all from one - whose reference is present but not terminal, and names the shape to - write in both (#262). -- The 300-character bound still outranks the citation across the whole - fragment, and the outranked problem stays out of the message it lost - to: one fragment, one diagnosis, wherever in the file it sits (#262). - -### Changed - -- `BUILDER.md` and `CHANGELOG.md` state the citation as guard-enforced - rather than as house style, beside the 300-character bound it now sits - next to (#262). -- Four fragments in flight gained a terminal citation; published sections - are untouched, so no shipped prose is re-opened (#262). diff --git a/changelog.d/264.md b/changelog.d/264.md deleted file mode 100644 index fa70c7c..0000000 --- a/changelog.d/264.md +++ /dev/null @@ -1,4 +0,0 @@ -### Changed - -- TRIAGE.md now scopes the no-assignee board bug to flagging an unassigned - issue, while still directing triage to repair ownership instead (#264). diff --git a/changelog.d/266.md b/changelog.d/266.md deleted file mode 100644 index 9d6bd0b..0000000 --- a/changelog.d/266.md +++ /dev/null @@ -1,5 +0,0 @@ -### Changed - -- TRIAGE.md now tells every epic author to put its progress checklist under - the literal `## Task list` heading, because any other heading is silently - invisible to the completion sweep (#266). diff --git a/changelog.d/267.md b/changelog.d/267.md deleted file mode 100644 index 2fb77a0..0000000 --- a/changelog.d/267.md +++ /dev/null @@ -1,19 +0,0 @@ -### Fixed - -- `scope:release-flow` no longer rides every pull request: `changelog.d/**` - is out of its path map. Doctrine makes every behavior change write a - fragment, so the glob labelled 20 of the last 20 PRs while 3 touched a - release surface. `CHANGELOG.md` stays, as only the release PR edits it - (#267). -- The issue-flow reconciler and its test now derive `scope:labels`, the scope - that already names the taxonomy they reconcile (#267). - -### Changed - -- `README.md` and `RELEASES.md` derive `scope:docs`, and the - `changelog-assembled`, `docs-sync` and `runner-isolated` actions and tests - derive `scope:guards`; all five were mapped nowhere. The docs block matched - a literal `README`, which this tree does not carry (#267). -- `lib/read.sh` and `lib/ruling.sh` derive `scope:labels` beside - `scope:release-flow`. Both reconcilers share them, and a mixed file wears - both labels rather than `lib/**` being re-carved into a row per file (#267). diff --git a/changelog.d/272.md b/changelog.d/272.md deleted file mode 100644 index adf20be..0000000 --- a/changelog.d/272.md +++ /dev/null @@ -1,6 +0,0 @@ -### Changed - -- BUILDER.md's step 1 now rules the checkless head: no checks configured is - nothing to wait for, and the request goes out straight away — stated once, - in the ruled-term paragraph, with the draft-round restatement removed - (#272). diff --git a/changelog.d/276.md b/changelog.d/276.md deleted file mode 100644 index 7d2dcdc..0000000 --- a/changelog.d/276.md +++ /dev/null @@ -1,10 +0,0 @@ -### Changed - -- BUILDER.md's green ruled term now says which entry to read before it says - what an entry means: a check's word at a head is its newest entry by start - time, and a cancelled entry is not that word while the same check carries a - non-cancelled one at that head (#276). -- A check whose every entry at the head is cancelled is unchanged — nothing - survived to be its word, so it never reported and is not green — and the - collapse mirrors `checks_state`'s carve-out rather than adding a class - (#276). diff --git a/changelog.d/280.md b/changelog.d/280.md deleted file mode 100644 index a3c0ca2..0000000 --- a/changelog.d/280.md +++ /dev/null @@ -1,5 +0,0 @@ -### Changed - -- CONTRIBUTING.md now keeps vendored doctrine self-contained: state the rule, - retain at most one sentence of why, cite the local record bare, and leave the - incident narrative in that record (#280). diff --git a/changelog.d/281.md b/changelog.d/281.md deleted file mode 100644 index f53fca6..0000000 --- a/changelog.d/281.md +++ /dev/null @@ -1,5 +0,0 @@ -### Changed - -- `BUILDER.md` states its rules and cites their record bare: the incident - narratives, the links into issue comments and the cross-repo issue cites - leave the normative text, which no rule leaves with them (#281). diff --git a/changelog.d/282.md b/changelog.d/282.md deleted file mode 100644 index 90d412d..0000000 --- a/changelog.d/282.md +++ /dev/null @@ -1,5 +0,0 @@ -### Changed - -- TRIAGE.md now states its rules with bare record cites: the label-race and - lifted-hold incident narratives leave the normative text while their - operational rules remain complete (#282). diff --git a/changelog.d/284.md b/changelog.d/284.md deleted file mode 100644 index ad98894..0000000 --- a/changelog.d/284.md +++ /dev/null @@ -1,6 +0,0 @@ -### Fixed - -- Claiming a `needs-ruling` issue no longer buys its escalation another 7 - quiet days: the issue-side ruling clock reads comments alone — an - assignment is the claim clock's fact — and LABELS.md now names what each - surface's clock reads (#284). diff --git a/changelog.d/288.md b/changelog.d/288.md deleted file mode 100644 index 245e524..0000000 --- a/changelog.d/288.md +++ /dev/null @@ -1,5 +0,0 @@ -### Changed - -- TRIAGE.md now requires unconditional collision-edge chains when open issues - carry the same deliverable, keeping the ready queue concurrently claimable - (#288). diff --git a/changelog.d/292.md b/changelog.d/292.md deleted file mode 100644 index 0fbafcb..0000000 --- a/changelog.d/292.md +++ /dev/null @@ -1,3 +0,0 @@ -### Changed - -- Standing release windows are dependency DAGs: every mint is placed in the window or behind it, and only current sources are `ready` (#292). diff --git a/changelog.d/293.md b/changelog.d/293.md deleted file mode 100644 index 40a6d63..0000000 --- a/changelog.d/293.md +++ /dev/null @@ -1,13 +0,0 @@ -### Added - -- The issue-flow sweep now flags a collision the board never declared: two - open, unblocked issues whose titles name one deliverable draw a comment - naming the newer's owed `Blocked by` edge. Keys normalize, so - `actions/x` and `x` are one deliverable (#288). -- The sweep now flags an unblocked non-member during a standing release - window, naming the window's invariant. `claimed` counts, PR in flight or - not. The gate is read from the release issue's own `Blocked by` - declarations, and an emptied gate leaves it dormant (#292). -- Both flags are advisory: comments only, no label write and no state - change, deduped against each family's last word on the thread so a - standing state re-sweeps silently (#293). diff --git a/changelog.d/302.md b/changelog.d/302.md deleted file mode 100644 index c0a759a..0000000 --- a/changelog.d/302.md +++ /dev/null @@ -1,6 +0,0 @@ -### Fixed - -- `lib/attention.sh` locates as label machinery beside its two shelf-mates — - `[scope:release-flow]` alone was a wrong answer of the class #267 measured - — and the map learns the sweep workflow pair, the shared-lib tests, and - seven enumerated test/guard surfaces (#302). diff --git a/changelog.d/304.md b/changelog.d/304.md deleted file mode 100644 index 0b57d16..0000000 --- a/changelog.d/304.md +++ /dev/null @@ -1,11 +0,0 @@ -### Fixed - -- A roster edit no longer reds the whole suite: the labels-reconcile - state-machine fixtures name their own panel instead of binding - `.github/labels.conf` by slot (#304). -- Shrinking `panel=` to three had left that binding's third slot unbound, and - `set -u` aborted the file before its first assertion — 217 assertions - became 0, on `main` and on every branch cut from it (#304). -- The one case still reading the shipped roster asserts a property, not a - size: it parses, and each member is recused from its own panel. Any - `panel=` of one or more members leaves `test/run.sh` green (#304). diff --git a/changelog.d/307.md b/changelog.d/307.md deleted file mode 100644 index 5c59de4..0000000 --- a/changelog.d/307.md +++ /dev/null @@ -1,6 +0,0 @@ -### Added - -- The issue-flow sweep's `claimed`-branch ruling pre-read is pinned: an - unassigned claim under `needs-ruling` must draw its board diagnostic and - its ruling nudge in one sweep, so a read that drifts below the diagnostic - reds instead of silently costing the escalation 7 days (#284, #307). diff --git a/changelog.d/311.md b/changelog.d/311.md deleted file mode 100644 index 4c8dd26..0000000 --- a/changelog.d/311.md +++ /dev/null @@ -1,6 +0,0 @@ -### Changed - -- `README.md` is rewritten whole from the current tree: the front page names - the governance repo ceremony now is, routes to `docs/CONSUMERS.md`, - `AGENTS.md`, `LABELS.md` and `RELEASES.md` rather than restating them, and - keeps the operator's release runbook as its core, re-measured (#311). diff --git a/docs/CONSUMERS.md b/docs/CONSUMERS.md index bd68963..bbb43e3 100644 --- a/docs/CONSUMERS.md +++ b/docs/CONSUMERS.md @@ -155,9 +155,9 @@ the machinery at all: - uses: heavy-duty/ceremony/actions/refs-not-closing@ ``` - `refs-not-closing` is **unreleased** (#218) until the first tag carrying it. - Adopt this caller with that ordinary pin bump; never point only this file - at a moving or newer ref. + `refs-not-closing` is available at `0.6.0` and later (#218). Adopt this + caller with that ordinary pin bump; never point only this file at a + moving or newer ref. 7. **Labels automation** (optional but recommended): the two callers from [Labels automation](#labels-automation) — the event-facing labels caller and the sweep caller (#209) — plus `.github/labels.conf` @@ -593,10 +593,10 @@ marking the directory machine-managed. `actions/docs-sync` owns the copy: mirror), `--check` re-diffs it in CI on every PR, so a hand edit or a stale pin goes red instead of quietly governing. -`RELEASES.md` joins that mirror with the first tag carrying ceremony#248. -It is **unreleased** (#248) until that tag exists: consumers add -`.ceremony/RELEASES.md` only with the ordinary pin bump and re-sync, never by -copying it ahead of their pinned doctrine set. +`RELEASES.md` joins that mirror with the first tag carrying ceremony#248, +and is available at `0.6.0` and later: consumers add `.ceremony/RELEASES.md` +only with the ordinary pin bump and re-sync, never by copying it ahead of +their pinned doctrine set. ### Read the manifest, never a copy of it @@ -625,10 +625,9 @@ What makes reading the manifest *sufficient* — rather than merely better than a copy — is that ceremony's CI now refuses a root doctrine file that is declared in neither the manifest nor a short in-script exemption list (`.github/scripts/vendored-check.sh`), so the manifest at a tag is the -complete set as of that tag. That guarantee is **unreleased** (#251) until -the first tag carrying it exists; the manifest is worth reading at every -earlier pin regardless, since it is what `actions/docs-sync` has always -mirrored. +complete set as of that tag. That guarantee holds at `0.6.0` and later +(#251); the manifest is worth reading at every earlier pin regardless, since +it is what `actions/docs-sync` has always mirrored. The consumer's ci.yml gains the guard alongside the others: diff --git a/drills/0.6.0.md b/drills/0.6.0.md new file mode 100644 index 0000000..753c02c --- /dev/null +++ b/drills/0.6.0.md @@ -0,0 +1,68 @@ +# 0.6.0 — drill record + +**IN PROGRESS — this record is being written as the rehearsal runs.** It is +committed early so the candidate carries evidence at every head rather than +appearing at the end; the release PR is a draft until it is complete, and no +probe row below is written before its run exists. + +Run 2026-08-05 by `cndgrr` against the 0.6.0 release PR (Refs #249), +candidate branch `build/249-release-0-6-0`. + +## Scope ruling — a full rehearsal is owed, and doors-unchanged is refused + +This record's shape was measured, not chosen. `drills/README.md` allows the +doors-unchanged shape only when all three of its conditions hold at the +candidate head; the first one does not. + +The baseline is the last **rehearsed** tag, never the previous tag: +`drills/0.4.1.md` and `drills/0.5.0.md` are both doors-unchanged records, so +the anchor is **`0.4.0`**, whose record is a full disposable-repo rehearsal, +whose release is published, and after which `main` was re-armed to +`0.4.1-dev` (`84bb1a4`). Condition 3 holds. + +The release path is exactly the output of `.github/scripts/release-path.sh` +at this head — `.github/workflows/release.yml`, `bin/`, `lib/version.sh`, +`lib/decide.sh`, `lib/facts.sh`, `lib/changelog.sh`. Condition 2 holds. + +Condition 1 fails. Measured at this candidate: + +```console +$ git diff 0.4.0..HEAD -- $(.github/scripts/release-path.sh) + .github/workflows/release.yml | 2 +- + lib/changelog.sh | 83 ++++++++++++++++++++++++++++++++++++++--- +``` + +`release.yml`'s two lines are the `CEREMONY_SELF_REF` pin, which the +condition exempts. **`lib/changelog.sh` is not exempt and is not empty**: it +carries `72fa3e0` (the terminal issue-citation rule joining the fragment +guard, #262) and `75a5b68` (one fragment, one diagnosis, #262). That file is +on the release path because the merge door sources it to assemble and read +the release section — this is a door byte, not a neighbouring library, and +the last-rehearsed anchor exists precisely so an accumulated change like +this forces a new rehearsal rather than chaining a third doors-unchanged +assertion off the second. + +So this release owes the disposable-repo rehearsal, and this record is it. + +## Where + +_Pending — the scratch repo's full `owner/name` and its disposal state as +observed by this record's author are written here when the rehearsal runs._ + +## Candidate-ref deviation + +_Pending — the fork ref carrying the candidate tree and the canonical +candidate SHA its `CEREMONY_SELF_REF` carriers are rewritten to._ + +## Probes + +_Pending — one row per probe, written from its run, never before it._ + +| # | probe | run | result | +|---|---|---|---| +| 1 | merge-door ceremony | — | — | +| 2 | mislabeled ordinary PR | — | — | +| 3 | bare-version PR without `release` | — | — | +| 4 | re-run completed ceremony | — | — | +| 5 | manual matching tag | — | — | +| 6 | mismatched tag | — | — |