From 819dc7d992e1ef43a0cc9b81d170221b98130b4e Mon Sep 17 00:00:00 2001 From: claude-bot-andresmgsl Date: Fri, 24 Jul 2026 10:19:38 +0000 Subject: [PATCH] feat: convert Unreleased entries to changelog.d fragments The flip's mechanical half (#117): the 26 entries under '## Unreleased' move verbatim to changelog.d/.md, the heading is deleted, the directory gains its marker README (#112 D1) and this PR's own fragment (112.md), CHANGELOG.md's preamble describes fragments, and labeler.yml maps changelog.d/** into scope:release-flow. --- .github/labeler.yml | 1 + CHANGELOG.md | 35 ++++------------------------------- changelog.d/101.md | 1 + changelog.d/104.md | 1 + changelog.d/105.md | 1 + changelog.d/109.md | 1 + changelog.d/112.md | 1 + changelog.d/113.md | 1 + changelog.d/114.md | 1 + changelog.d/115.md | 1 + changelog.d/116.md | 1 + changelog.d/126.md | 1 + changelog.d/51.md | 1 + changelog.d/52.md | 1 + changelog.d/57.md | 1 + changelog.d/58.md | 1 + changelog.d/61.md | 1 + changelog.d/68.md | 1 + changelog.d/69.md | 1 + changelog.d/72.md | 1 + changelog.d/73.md | 1 + changelog.d/74.md | 1 + changelog.d/77.md | 1 + changelog.d/84.md | 1 + changelog.d/85.md | 1 + changelog.d/86.md | 1 + changelog.d/91.md | 1 + changelog.d/93.md | 1 + changelog.d/95.md | 1 + changelog.d/98.md | 1 + changelog.d/README.md | 10 ++++++++++ 31 files changed, 43 insertions(+), 31 deletions(-) create mode 100644 changelog.d/101.md create mode 100644 changelog.d/104.md create mode 100644 changelog.d/105.md create mode 100644 changelog.d/109.md create mode 100644 changelog.d/112.md create mode 100644 changelog.d/113.md create mode 100644 changelog.d/114.md create mode 100644 changelog.d/115.md create mode 100644 changelog.d/116.md create mode 100644 changelog.d/126.md create mode 100644 changelog.d/51.md create mode 100644 changelog.d/52.md create mode 100644 changelog.d/57.md create mode 100644 changelog.d/58.md create mode 100644 changelog.d/61.md create mode 100644 changelog.d/68.md create mode 100644 changelog.d/69.md create mode 100644 changelog.d/72.md create mode 100644 changelog.d/73.md create mode 100644 changelog.d/74.md create mode 100644 changelog.d/77.md create mode 100644 changelog.d/84.md create mode 100644 changelog.d/85.md create mode 100644 changelog.d/86.md create mode 100644 changelog.d/91.md create mode 100644 changelog.d/93.md create mode 100644 changelog.d/95.md create mode 100644 changelog.d/98.md create mode 100644 changelog.d/README.md diff --git a/.github/labeler.yml b/.github/labeler.yml index ea86a49..9271aa4 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -16,6 +16,7 @@ scope:release-flow: - bin/** - VERSION - CHANGELOG.md + - changelog.d/** - drills/** - test/decide.test.sh - test/facts.test.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index ae287da..d297992 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,37 +2,10 @@ The curated history of the ceremony itself. Each release's section is published verbatim as that release's body (lib/changelog.sh extracts it), -so entries say what changed, cite the issue, and stop. - -## Unreleased - -- `test/changelog-assembled.test.sh` — keep the trio interaction aligned with fragment mode: a dropped entry makes armed red too, while a hand-edited section leaves assembled as the sole red (#126). -- `changelog-armed` — treat `changelog.d/` as the arming, validate every development fragment, and require bare releases to consume the directory into their exact publishable section (#115). -- `actions/changelog-assembled` — a release PR's stamped section must be byte-for-byte what the fragments it consumed assemble to, replayed from the merge base; inapplicable trees pass with a NOTICE (#116). -- `lib/changelog.sh` + `bin/changelog-assemble` — read the `changelog.d/` fragments, assemble one release section (canonical group order, one shape per repo), and consume exactly what was published (#114). -- BUILDER.md — the directed hold is the parked claim's fifth shape, its attention demand is acknowledged in the declaration comment, and its board bookkeeping covers in-flight work; TRIAGE.md no longer excludes it (#113). -- BUILDER.md — the handed-off PR is the parked claim's fourth shape, its handoff is its declaration, and shape 2 covers the round awaiting its first verdicts (#109). -- `labels-reconcile` — a degraded mergeability/checks read now logs gh's actual stderr (collapsed, bounded) beside the byte-identical counted line, and the blind-sweep warning leads with the observed reason instead of asserting the permissions cause (#101). -- `LABELS.md` — drop the vendored scope-table enumeration; the per-repo set lives in `.github/labels.conf` and the repo's own CONTRIBUTING (#104). -- Changelog publication — count entries instead of bytes, refuse dangling grouped headings, and seed grouped re-arms with Added/Changed/Fixed (#98). -- `labels-reconcile` — warn once per sweep when a repository lacks labels declared by the pinned core taxonomy (#105). -- `labels-reconcile` — grant callers private-repo check reads and warn when an entire PR sweep is blind (#95). -- `labels-reconcile` — the bootstrap now retires the six GitHub defaults `LABELS.md` publishes as deleted, tolerating both an already-absent label and a refused delete (#93). -- `issueflow-reconcile` — a triage-authored issue arrival stands down with exit 0 instead of killing the run before the sweep (#91). -- FLEET.md — the assignee's `attention` wake: one role-independent trigger ahead of every per-role list, one acked session per demand; a spec on paper until `duty.sh` polls it (#86). -- `attention` doctrine — define its assignee-owned pickup, ack, queue and clock semantics across labels, triage, and builder roles (#85). -- `attention` — add the issue-only, hand-set assignee-demand flag to the core label taxonomy (#84). -- `issueflow-reconcile` — keep cross-repo references out of local dependency decisions and require triage to resolve cross-repo blockers by hand (#61). -- `needs-ruling` — the cross-cutting flag for a pending human decision, excluded from `state:needs-human` and from the staleness sweep (#51). -- Cross-repo doctrine: the panel is the PR's repo's roster, a review request is authorization but not panel membership, and `Part of #N` replaces the `Closes #N` that cannot cross repos (#57). -- `actions/runner-isolated` — a `pull_request`-triggered job may never run on a self-hosted runner (#58). -- The sweep's `needs-ruling` invariants, one implementation for both surfaces: the issue-side staleness exemption, the bare-flag check (comment-only, the label is never removed), and the 7-day nudge to the decider (#52). -- `offsite` — protect claimed issues whose PR lives in another repository from the claim-reclaim clock (#68). -- `issueflow-reconcile` — nudge once when an `offsite` flag outlives every visible cross-referenced PR (#69). -- Ruling doctrine — define every human-owned trigger, the fixed escalation shape, and the 0–24h builder-to-triage ladder (#72). -- The sweep observes the escalation contract: a malformed escalation is named field-by-field, and the ladder's 12h/24h rungs each draw one comment to the flag-setter — comment-only, per-episode, both surfaces (#73). -- FLEET.md — the operator notifier's `needs-ruling` queue (one tracked message per item, edited in place across the rungs) and triage's past-24h wake condition; a spec on paper until an operator updates the box (#74). -- One issue at a time counts build work in flight: the parked claim's three shapes, its declared-never-inferred comment, and triage's duty to name a directed hold as a park (#77). +so entries say what changed, cite the issue, and stop. 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.1.0 — 2026-07-22 diff --git a/changelog.d/101.md b/changelog.d/101.md new file mode 100644 index 0000000..fae50f9 --- /dev/null +++ b/changelog.d/101.md @@ -0,0 +1 @@ +- `labels-reconcile` — a degraded mergeability/checks read now logs gh's actual stderr (collapsed, bounded) beside the byte-identical counted line, and the blind-sweep warning leads with the observed reason instead of asserting the permissions cause (#101). diff --git a/changelog.d/104.md b/changelog.d/104.md new file mode 100644 index 0000000..8428e43 --- /dev/null +++ b/changelog.d/104.md @@ -0,0 +1 @@ +- `LABELS.md` — drop the vendored scope-table enumeration; the per-repo set lives in `.github/labels.conf` and the repo's own CONTRIBUTING (#104). diff --git a/changelog.d/105.md b/changelog.d/105.md new file mode 100644 index 0000000..df8841f --- /dev/null +++ b/changelog.d/105.md @@ -0,0 +1 @@ +- `labels-reconcile` — warn once per sweep when a repository lacks labels declared by the pinned core taxonomy (#105). diff --git a/changelog.d/109.md b/changelog.d/109.md new file mode 100644 index 0000000..326c6f6 --- /dev/null +++ b/changelog.d/109.md @@ -0,0 +1 @@ +- BUILDER.md — the handed-off PR is the parked claim's fourth shape, its handoff is its declaration, and shape 2 covers the round awaiting its first verdicts (#109). diff --git a/changelog.d/112.md b/changelog.d/112.md new file mode 100644 index 0000000..29738cf --- /dev/null +++ b/changelog.d/112.md @@ -0,0 +1 @@ +- Ceremony adopts `changelog.d/` — a PR writes one fragment per issue instead of editing `CHANGELOG.md`, the release PR assembles the section, and `## Unreleased` is gone (#112). diff --git a/changelog.d/113.md b/changelog.d/113.md new file mode 100644 index 0000000..35c5087 --- /dev/null +++ b/changelog.d/113.md @@ -0,0 +1 @@ +- BUILDER.md — the directed hold is the parked claim's fifth shape, its attention demand is acknowledged in the declaration comment, and its board bookkeeping covers in-flight work; TRIAGE.md no longer excludes it (#113). diff --git a/changelog.d/114.md b/changelog.d/114.md new file mode 100644 index 0000000..160da0f --- /dev/null +++ b/changelog.d/114.md @@ -0,0 +1 @@ +- `lib/changelog.sh` + `bin/changelog-assemble` — read the `changelog.d/` fragments, assemble one release section (canonical group order, one shape per repo), and consume exactly what was published (#114). diff --git a/changelog.d/115.md b/changelog.d/115.md new file mode 100644 index 0000000..324eb08 --- /dev/null +++ b/changelog.d/115.md @@ -0,0 +1 @@ +- `changelog-armed` — treat `changelog.d/` as the arming, validate every development fragment, and require bare releases to consume the directory into their exact publishable section (#115). diff --git a/changelog.d/116.md b/changelog.d/116.md new file mode 100644 index 0000000..1acdd6a --- /dev/null +++ b/changelog.d/116.md @@ -0,0 +1 @@ +- `actions/changelog-assembled` — a release PR's stamped section must be byte-for-byte what the fragments it consumed assemble to, replayed from the merge base; inapplicable trees pass with a NOTICE (#116). diff --git a/changelog.d/126.md b/changelog.d/126.md new file mode 100644 index 0000000..e6558e9 --- /dev/null +++ b/changelog.d/126.md @@ -0,0 +1 @@ +- `test/changelog-assembled.test.sh` — keep the trio interaction aligned with fragment mode: a dropped entry makes armed red too, while a hand-edited section leaves assembled as the sole red (#126). diff --git a/changelog.d/51.md b/changelog.d/51.md new file mode 100644 index 0000000..688a2c1 --- /dev/null +++ b/changelog.d/51.md @@ -0,0 +1 @@ +- `needs-ruling` — the cross-cutting flag for a pending human decision, excluded from `state:needs-human` and from the staleness sweep (#51). diff --git a/changelog.d/52.md b/changelog.d/52.md new file mode 100644 index 0000000..cafdc0b --- /dev/null +++ b/changelog.d/52.md @@ -0,0 +1 @@ +- The sweep's `needs-ruling` invariants, one implementation for both surfaces: the issue-side staleness exemption, the bare-flag check (comment-only, the label is never removed), and the 7-day nudge to the decider (#52). diff --git a/changelog.d/57.md b/changelog.d/57.md new file mode 100644 index 0000000..b79fb23 --- /dev/null +++ b/changelog.d/57.md @@ -0,0 +1 @@ +- Cross-repo doctrine: the panel is the PR's repo's roster, a review request is authorization but not panel membership, and `Part of #N` replaces the `Closes #N` that cannot cross repos (#57). diff --git a/changelog.d/58.md b/changelog.d/58.md new file mode 100644 index 0000000..791b399 --- /dev/null +++ b/changelog.d/58.md @@ -0,0 +1 @@ +- `actions/runner-isolated` — a `pull_request`-triggered job may never run on a self-hosted runner (#58). diff --git a/changelog.d/61.md b/changelog.d/61.md new file mode 100644 index 0000000..9edee59 --- /dev/null +++ b/changelog.d/61.md @@ -0,0 +1 @@ +- `issueflow-reconcile` — keep cross-repo references out of local dependency decisions and require triage to resolve cross-repo blockers by hand (#61). diff --git a/changelog.d/68.md b/changelog.d/68.md new file mode 100644 index 0000000..f5ad678 --- /dev/null +++ b/changelog.d/68.md @@ -0,0 +1 @@ +- `offsite` — protect claimed issues whose PR lives in another repository from the claim-reclaim clock (#68). diff --git a/changelog.d/69.md b/changelog.d/69.md new file mode 100644 index 0000000..45a4d80 --- /dev/null +++ b/changelog.d/69.md @@ -0,0 +1 @@ +- `issueflow-reconcile` — nudge once when an `offsite` flag outlives every visible cross-referenced PR (#69). diff --git a/changelog.d/72.md b/changelog.d/72.md new file mode 100644 index 0000000..34824e7 --- /dev/null +++ b/changelog.d/72.md @@ -0,0 +1 @@ +- Ruling doctrine — define every human-owned trigger, the fixed escalation shape, and the 0–24h builder-to-triage ladder (#72). diff --git a/changelog.d/73.md b/changelog.d/73.md new file mode 100644 index 0000000..db95180 --- /dev/null +++ b/changelog.d/73.md @@ -0,0 +1 @@ +- The sweep observes the escalation contract: a malformed escalation is named field-by-field, and the ladder's 12h/24h rungs each draw one comment to the flag-setter — comment-only, per-episode, both surfaces (#73). diff --git a/changelog.d/74.md b/changelog.d/74.md new file mode 100644 index 0000000..0d81292 --- /dev/null +++ b/changelog.d/74.md @@ -0,0 +1 @@ +- FLEET.md — the operator notifier's `needs-ruling` queue (one tracked message per item, edited in place across the rungs) and triage's past-24h wake condition; a spec on paper until an operator updates the box (#74). diff --git a/changelog.d/77.md b/changelog.d/77.md new file mode 100644 index 0000000..956ff97 --- /dev/null +++ b/changelog.d/77.md @@ -0,0 +1 @@ +- One issue at a time counts build work in flight: the parked claim's three shapes, its declared-never-inferred comment, and triage's duty to name a directed hold as a park (#77). diff --git a/changelog.d/84.md b/changelog.d/84.md new file mode 100644 index 0000000..b5e00fe --- /dev/null +++ b/changelog.d/84.md @@ -0,0 +1 @@ +- `attention` — add the issue-only, hand-set assignee-demand flag to the core label taxonomy (#84). diff --git a/changelog.d/85.md b/changelog.d/85.md new file mode 100644 index 0000000..42ef042 --- /dev/null +++ b/changelog.d/85.md @@ -0,0 +1 @@ +- `attention` doctrine — define its assignee-owned pickup, ack, queue and clock semantics across labels, triage, and builder roles (#85). diff --git a/changelog.d/86.md b/changelog.d/86.md new file mode 100644 index 0000000..8b6f008 --- /dev/null +++ b/changelog.d/86.md @@ -0,0 +1 @@ +- FLEET.md — the assignee's `attention` wake: one role-independent trigger ahead of every per-role list, one acked session per demand; a spec on paper until `duty.sh` polls it (#86). diff --git a/changelog.d/91.md b/changelog.d/91.md new file mode 100644 index 0000000..89cd4bc --- /dev/null +++ b/changelog.d/91.md @@ -0,0 +1 @@ +- `issueflow-reconcile` — a triage-authored issue arrival stands down with exit 0 instead of killing the run before the sweep (#91). diff --git a/changelog.d/93.md b/changelog.d/93.md new file mode 100644 index 0000000..7902fac --- /dev/null +++ b/changelog.d/93.md @@ -0,0 +1 @@ +- `labels-reconcile` — the bootstrap now retires the six GitHub defaults `LABELS.md` publishes as deleted, tolerating both an already-absent label and a refused delete (#93). diff --git a/changelog.d/95.md b/changelog.d/95.md new file mode 100644 index 0000000..0c933bc --- /dev/null +++ b/changelog.d/95.md @@ -0,0 +1 @@ +- `labels-reconcile` — grant callers private-repo check reads and warn when an entire PR sweep is blind (#95). diff --git a/changelog.d/98.md b/changelog.d/98.md new file mode 100644 index 0000000..1c200cb --- /dev/null +++ b/changelog.d/98.md @@ -0,0 +1 @@ +- Changelog publication — count entries instead of bytes, refuse dangling grouped headings, and seed grouped re-arms with Added/Changed/Fixed (#98). diff --git a/changelog.d/README.md b/changelog.d/README.md new file mode 100644 index 0000000..1c529b2 --- /dev/null +++ b/changelog.d/README.md @@ -0,0 +1,10 @@ +# changelog.d/ — the next release's section, one fragment per issue + +Machine-assembled by `bin/changelog-assemble` (#112): every PR that changes +behavior writes one file here — `.md`, the exact prose that will be +published, nothing else — and the release PR folds them all into the next +`## X.Y.Z — DATE` section of `CHANGELOG.md`, consuming them. Distinct +filenames never conflict, which is this directory's whole reason to exist. +This README is the marker that keeps the directory tracked when it holds no +fragments (#112 D1) — `changelog-armed` refuses a tree without it; do not +delete it.