Skip to content

Commit f28a849

Browse files
authored
fix: make release boundaries deterministic (#39)
1 parent c5eb2f9 commit f28a849

12 files changed

Lines changed: 664 additions & 140 deletions

AGENTS.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,17 @@ Post-stable invariants:
154154
documents must contain no exact CometAPI patch or recovery identity. The
155155
document/version checker must fail before merge or release when this
156156
boundary is violated.
157+
12. Keep `CHANGELOG.md` release-only: do not maintain an unmanaged `Unreleased`
158+
section. Record changes in Conventional Commits and let Release Please own
159+
the newest canonical dated release section after the changelog preamble.
160+
The version gate must reject any `Unreleased` level-two heading before merge
161+
or release.
162+
13. A validated release-evidence block binds one canonical publication workflow
163+
run to its machine-readable identity marker and may contain no other Actions
164+
run URL. Keep preparatory implementation, CI, Release Please, failed-attempt,
165+
and recovery history outside that block. The document gate must reject
166+
non-canonical, wrapped, malformed, or contradictory workflow URLs regardless
167+
of prose or Markdown labeling.
157168

158169
## Repository independence
159170

ARCHITECTURE.md

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,13 @@ uses `node24`. The workflow semantic contract fixes that SHA and runtime
140140
disposition so GitHub does not need to force a deprecated Node 20 action onto a
141141
newer runtime.
142142

143-
The version gate accepts Release Please's native linked, dated changelog heading
144-
as well as the existing legacy dated form. It validates repository, previous
145-
tag, candidate tag, and calendar date rather than rewriting generated history.
143+
The changelog is release-only. Release Please owns the newest canonical dated
144+
section immediately after its preamble; contributors record pending changes in
145+
Conventional Commits and never maintain an `Unreleased` placeholder. The
146+
version gate rejects that structurally incompatible placeholder, accepts Release
147+
Please's native linked form and legacy dated history, and validates repository,
148+
previous tag, candidate tag, and calendar date without rewriting generated
149+
history.
146150

147151
The PyPI publisher remains directly in `publish.yml` and is pinned to its
148152
reviewed Node 24 maintenance release. Pinning its exact SHA prevents a syntactic
@@ -159,9 +163,13 @@ idempotent, while retrying immutable tag or GitHub Release creation could leave
159163
ambiguous external state and is forbidden.
160164

161165
Immutable run, tag, commit, registry, and digest records live only in the
162-
validated release-evidence blocks in `ROADMAP.md` and `RELEASING.md`.
163-
Architecture documents mechanisms and boundaries, not a second historical
164-
ledger.
166+
validated release-evidence blocks in `ROADMAP.md` and `RELEASING.md`. Each
167+
block binds only the canonical publication run through its machine-readable
168+
identity; preparatory implementation, CI, Release Please, failed-attempt, and
169+
recovery history stays outside the block. The checker rejects every other run
170+
identity plus wrapped or malformed Actions URLs, so Markdown wording cannot
171+
disguise a contradictory workflow. Architecture documents mechanisms and
172+
boundaries, not a second historical ledger.
165173

166174
The scheduled/manual default-branch smoke is an operational canary only; it
167175
does not prove the release commit. `COMETAPI_KEY` is exposed only to the

CHANGELOG.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ All notable changes to this project are documented in this file. The project
44
follows Semantic Versioning and uses Conventional Commits for release-PR
55
automation.
66

7-
## [Unreleased]
8-
97
## [0.1.3] - 2026-07-30
108

119
### Fixed

CONTRIBUTING.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@ legacy client aliases to a 0.1 change.
6969

7070
Prefer the smallest complete change. Preserve precise type hints, update
7171
documentation and the compatibility matrix when public behavior changes, and
72-
add a changelog entry for user-visible changes.
72+
describe user-visible changes through Conventional Commits. Do not maintain an
73+
`Unreleased` changelog section; Release Please owns canonical dated release
74+
history.
7375

7476
## Commit and pull-request guidance
7577

RELEASING.md

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,18 @@ branch and missing pull-request permission. Treat that run as isolated
198198
transport-failure evidence; do not rerun it or reinterpret it as an
199199
authorization failure.
200200

201+
`CHANGELOG.md` is release-only: do not maintain an `Unreleased` placeholder.
202+
Conventional Commits carry pending changes, and Release Please owns the newest
203+
canonical dated section immediately after the preamble. The version gate rejects
204+
any unmanaged `Unreleased` level-two heading so the generated layout remains
205+
valid on every patch release.
206+
207+
Each validated release-evidence block contains the immutable release identity
208+
and only its canonical publication workflow. Preparatory implementation CI,
209+
Release Please, failed-publication, and recovery history remains outside the
210+
block. The document gate rejects every different run identity and every wrapped
211+
or malformed Actions URL regardless of prose or Markdown labeling.
212+
201213
Release mode (`check_version.py --require-releasable-docs`) also fails closed
202214
until project authorship, the canonical GitHub repository URL, the copyright
203215
holder, security and support contacts, a publication-neutral README, and a
@@ -471,16 +483,17 @@ authorized.
471483

472484
### Completed first stable release evidence
473485

486+
- Selector-descendant fix [PR #23](https://github.com/cometapi-dev/cometapi-python/pull/23)
487+
passed [pull-request CI run 30358662050](https://github.com/cometapi-dev/cometapi-python/actions/runs/30358662050),
488+
squash-merged as `9cd60419130533d6920083e2f4bf295a3b5a4fd7`, and passed
489+
[default-branch CI run 30358990834](https://github.com/cometapi-dev/cometapi-python/actions/runs/30358990834).
490+
474491
<!-- cometapi-release-evidence:start version=0.1.0 date=2026-07-28 -->
475492
<!-- cometapi-release-identity tag=v0.1.0 commit=6f42981edcc6c252f8db997606671c3da84d1dd8 workflow-run=30359383715 wheel-sha256=8eae758688bb6c98274e48d8d81f882eeae760f69cfd2f5e125004881d60e90f sdist-sha256=e9308b44f6091200b5121e24d1a0e1b9ea3e6bcccc109d6de87554b1ab2a8bca -->
476493

477494
- The immutable non-draft [GitHub release](https://github.com/cometapi-dev/cometapi-python/releases/tag/v0.1.0)
478495
and lightweight tag `v0.1.0` resolve to release commit
479496
`6f42981edcc6c252f8db997606671c3da84d1dd8` on protected `main`.
480-
- Selector-descendant fix [PR #23](https://github.com/cometapi-dev/cometapi-python/pull/23)
481-
passed [pull-request CI run 30358662050](https://github.com/cometapi-dev/cometapi-python/actions/runs/30358662050),
482-
squash-merged as `9cd60419130533d6920083e2f4bf295a3b5a4fd7`, and passed
483-
[default-branch CI run 30358990834](https://github.com/cometapi-dev/cometapi-python/actions/runs/30358990834).
484497
- Fresh first-attempt
485498
[recovery run 30359383715](https://github.com/cometapi-dev/cometapi-python/actions/runs/30359383715)
486499
passed immutable identity verification, the shared selector, an exact rebuild,
@@ -506,9 +519,6 @@ authorized.
506519

507520
### Completed configuration maintenance release evidence
508521

509-
<!-- cometapi-release-evidence:start version=0.1.1 date=2026-07-29 -->
510-
<!-- cometapi-release-identity tag=v0.1.1 commit=576e7503a0a8c1103faca5143e4b8d576f8e8b44 workflow-run=30429821548 wheel-sha256=27e7904542f82fbbcd60e0de23a4a62c042420b6d004d00286d1f37d2ec4c5e5 sdist-sha256=64c7cb87745032703b3374cc562ea00b979416c54908862dbcebd116b2dc44c8 -->
511-
512522
- Configuration fix [PR #25](https://github.com/cometapi-dev/cometapi-python/pull/25)
513523
passed [pull-request CI run 30419881169](https://github.com/cometapi-dev/cometapi-python/actions/runs/30419881169)
514524
and squash-merged as `d02b1dba277ac72229b772d29ea1870b569edd88`.
@@ -528,10 +538,15 @@ authorized.
528538
received human owner approval at that exact head, and squash-merged as
529539
`576e7503a0a8c1103faca5143e4b8d576f8e8b44`. The release commit passed
530540
[default-branch CI run 30429821579](https://github.com/cometapi-dev/cometapi-python/actions/runs/30429821579).
541+
542+
<!-- cometapi-release-evidence:start version=0.1.1 date=2026-07-29 -->
543+
<!-- cometapi-release-identity tag=v0.1.1 commit=576e7503a0a8c1103faca5143e4b8d576f8e8b44 workflow-run=30429821548 wheel-sha256=27e7904542f82fbbcd60e0de23a4a62c042420b6d004d00286d1f37d2ec4c5e5 sdist-sha256=64c7cb87745032703b3374cc562ea00b979416c54908862dbcebd116b2dc44c8 -->
544+
531545
- First-attempt [release run 30429821548](https://github.com/cometapi-dev/cometapi-python/actions/runs/30429821548)
532546
created and verified immutable non-draft release
533547
[v0.1.1](https://github.com/cometapi-dev/cometapi-python/releases/tag/v0.1.1)
534-
at the exact release commit, rebuilt and clean-installed both artifacts,
548+
at release commit `576e7503a0a8c1103faca5143e4b8d576f8e8b44`, rebuilt and
549+
clean-installed both artifacts,
535550
passed the four-request exact-release live suite, received protected `pypi`
536551
approval, published directly from top-level `publish.yml` by OIDC with
537552
attestations, and passed public registry verification.
@@ -555,9 +570,6 @@ authorized.
555570

556571
### Completed release-metadata maintenance evidence
557572

558-
<!-- cometapi-release-evidence:start version=0.1.2 date=2026-07-30 -->
559-
<!-- cometapi-release-identity tag=v0.1.2 commit=710c56491d9ef5f47cccff3ce837ab7e799455b0 workflow-run=30515861246 wheel-sha256=3f12c26ae1ae7a1de5ac19d8ef27a784b2bf592143c716493f1b0f35ec19daca sdist-sha256=21c8edc0586610de1a9a8cd39b54ed23d2b1e20552100f69f53938cb7678da3d -->
560-
561573
- Metadata and runtime [PR #29](https://github.com/cometapi-dev/cometapi-python/pull/29)
562574
made packaged long descriptions release-neutral, added artifact assertions,
563575
pinned Release Please v5 to its Node 24 action commit, passed
@@ -581,11 +593,16 @@ authorized.
581593
received human owner approval at that exact head, and squash-merged as release
582594
commit `710c56491d9ef5f47cccff3ce837ab7e799455b0`. The release commit passed
583595
[default-branch CI run 30515861285](https://github.com/cometapi-dev/cometapi-python/actions/runs/30515861285).
596+
597+
<!-- cometapi-release-evidence:start version=0.1.2 date=2026-07-30 -->
598+
<!-- cometapi-release-identity tag=v0.1.2 commit=710c56491d9ef5f47cccff3ce837ab7e799455b0 workflow-run=30515861246 wheel-sha256=3f12c26ae1ae7a1de5ac19d8ef27a784b2bf592143c716493f1b0f35ec19daca sdist-sha256=21c8edc0586610de1a9a8cd39b54ed23d2b1e20552100f69f53938cb7678da3d -->
599+
584600
- First-attempt
585601
[release run 30515861246](https://github.com/cometapi-dev/cometapi-python/actions/runs/30515861246)
586602
created and independently verified immutable non-draft release
587603
[v0.1.2](https://github.com/cometapi-dev/cometapi-python/releases/tag/v0.1.2)
588-
at the exact release commit, rebuilt and clean-installed both artifacts,
604+
at release commit `710c56491d9ef5f47cccff3ce837ab7e799455b0`, rebuilt and
605+
clean-installed both artifacts,
589606
passed the bounded four-request exact-release live suite, received protected
590607
`pypi` approval, published directly from top-level `publish.yml` by OIDC with
591608
attestations, and passed public registry verification.
@@ -610,9 +627,6 @@ authorized.
610627

611628
### Completed release-claim maintenance evidence
612629

613-
<!-- cometapi-release-evidence:start version=0.1.3 date=2026-07-30 -->
614-
<!-- cometapi-release-identity tag=v0.1.3 commit=45429f373bbd11314ec43ba81904fdbb78db2522 workflow-run=30550536000 wheel-sha256=9ac2f8062a8554943649bffd7ec859fc90491f76bbe2b0165327722201417d6f sdist-sha256=07ded54606d50f44b689dad38cf93a74e1175370efaa33be84a3c01240d48e66 -->
615-
616630
- Mutable-release-claim [PR #34](https://github.com/cometapi-dev/cometapi-python/pull/34)
617631
removed the published patch number from persistent guidance and extended the
618632
existing document/version checker through pull-request CI, release source and
@@ -636,11 +650,16 @@ authorized.
636650
received exact-head human owner approval, and squash-merged as release commit
637651
`45429f373bbd11314ec43ba81904fdbb78db2522`. The release commit passed
638652
[default-branch CI run 30550533622](https://github.com/cometapi-dev/cometapi-python/actions/runs/30550533622).
653+
654+
<!-- cometapi-release-evidence:start version=0.1.3 date=2026-07-30 -->
655+
<!-- cometapi-release-identity tag=v0.1.3 commit=45429f373bbd11314ec43ba81904fdbb78db2522 workflow-run=30550536000 wheel-sha256=9ac2f8062a8554943649bffd7ec859fc90491f76bbe2b0165327722201417d6f sdist-sha256=07ded54606d50f44b689dad38cf93a74e1175370efaa33be84a3c01240d48e66 -->
656+
639657
- First-attempt
640658
[release run 30550536000](https://github.com/cometapi-dev/cometapi-python/actions/runs/30550536000)
641659
created and independently verified immutable non-draft release
642660
[v0.1.3](https://github.com/cometapi-dev/cometapi-python/releases/tag/v0.1.3)
643-
and its lightweight tag at the exact release commit, rebuilt and
661+
and its lightweight tag at release commit
662+
`45429f373bbd11314ec43ba81904fdbb78db2522`, rebuilt and
644663
clean-installed both artifacts, passed the bounded four-request exact-release
645664
live suite, received protected `pypi` approval, published directly from
646665
top-level `publish.yml` by OIDC with attestations, and passed public registry

0 commit comments

Comments
 (0)