Skip to content

A release waits on hand-written docs/changelog/unreleased/ entries; prepare should list the merged pull requests itself #180

Description

@vjovanov

Example

ephor has not been released yet: there is no vX.Y.Z tag and Cargo.toml says 0.1.0-dev. At origin/main 85dfd8a, before the first release can be cut, someone has to write one entry file per change under docs/changelog/unreleased/. That directory holds 251 of them today, for example feat-clean.added.md:

- **`ephor clean` gives back what builds took in every idle branch checkout,
  through each project's own clean verb** ([§FS-017-clean](...)). The verb is bound
  the way a check verb is: ...

release-minor.yml runs scripts/prepare_changelog_release.py stamp and then prepare <version> over those files. When the directory is empty, prepare refuses:

docs/changelog/unreleased/ holds no entry to release; its README.md is not one.
  Write the release section first: one entry per change merged since the last tag, ...

The scheduled auto-bump.yml holds on the same condition, through prepare_changelog_release.py pending:

::notice::Changes since <tag> wait for their release section: docs/changelog/unreleased/ holds no entry — skipping.

After the change, prepare <version> writes the numbered section itself. It reads from the forge the pull requests merged since the previous tag (since the start of history for the first release), lists them newest first, and skips the docs- and CI-only ones the schedule already skips:

## 0.1.0

- [test: wait for a dropped job lock to read released instead of racing a forked child](https://github.com/agent-grounds/ephor/pull/179) (PR #179)
- [fix: a registry the schema refuses is refused whole](https://github.com/agent-grounds/ephor/pull/177) (PR #177)
- [fix: a runner stand-in is settled before the board runs it, so E2E-008's listing no longer flakes](https://github.com/agent-grounds/ephor/pull/176) (PR #176)

Nobody writes anything before a release. docs/changelog/unreleased/, stamp and pending are gone.

What is wanted

A release's notes are the titles of the pull requests merged since the previous tag, each linked to its pull request, newest first, as - [<title>](<url>) (PR #N), and the release writes them. prepare <version> reads them from the forge, notes <version> keeps publishing the section as the GitHub release notes, and the scheduled release runs whenever the substantive-paths gate passes. The fragment store, stamp, pending, the contributor rule that describes the store, and every hook and CI check that reads it go, and the spec says so. A maintainer, or the schedule, could then cut any release without writing a line first. This is the owner's direction for every repository under agent-grounds. rhei 0.6.0 was cut this way by hand (agent-grounds/rhei#437).

Why the contract cannot express it today

Under the spec, the current behaviour is correct. §FS-002-release opens with "a changelog written before each release". §FS-002-release.1 says that what has merged is written down before the release is cut, as one entry file per change under docs/changelog/unreleased/, sorted into Keep-a-Changelog sections. §FS-002-release.2 fixes the script's commands as stamp, prepare, notes and pending, and holds the scheduled release while pending prints 0. §FS-002-release.2.3 says an empty directory "means the write-up has not been done, not that nothing changed". §FS-002-release.1.1, .1.2, .2.1 and .2.2 exist only to serve the store. The store was a deliberate decision, reached through #149 and #156, and #156 explicitly left the write-up tooling out of scope. Removing the hand-written step means reversing those points.

What it would change for existing callers

The changed points are §FS-002-release (the lead, §1, §2 and §2.3), plus docs/changelog.md §1.1–1.3. §1.1, §1.2, §2.1 and §2.2 would be deleted and §6 narrowed. grund refs at 85dfd8a counts about 85 citing sites across 27 files. Most of them are in the store, its scripts (changelog_stamp.py, changelog_unreleased.py, changelog_history.py, changelog_switchover.py) and their tests, which are deleted rather than edited. FS-006-project-interface and FS-012-file-size each cite §1 from outside and need a re-read. The workflows change: auto-bump.yml loses gate_pending and the stamp step, release-minor.yml loses the stamp step, and ci.yml loses the scratch-release check.

Two rules have to be decided rather than inherited. First, prepare now needs the forge. §2.2 says forge failures "never fail a release", but without the forge there are no notes, so an unreachable forge and an empty range each need a stated rule (probably a refusal). Second, §REQ-002-parity.4 says a --json field is renamed or removed "only as a release notes it". Today the write-up keeps that duty by reading git diff <tag>..main -- assets/*.schema.json, and a list of pull request titles does not reliably carry it. The replacement has to name how that change still reaches the notes, for example a line prepare adds from the schema diff. The 251 entries already in docs/changelog/unreleased/ should be released once, in the release that switches over. Contributors lose nothing, because since #156 no pull request writes an entry.

Alternatives

One option is to keep the store and have an agent write the entries before each release. That works, but the same write-up cost an agent about 232k tokens for rhei 0.6.0, and the result was then replaced by the plain list. It also still needs someone to start it, so the scheduled release still cannot run unattended. A second option, the cheapest half-fix, is to write the list by hand into fragment files before dispatching release-minor.yml. The notes come out right, but every release still waits on a person. A third is to generate fragments from pull requests in a pull request at release time and then promote them. That keeps stamp, pending and the hold, and gains nothing.

Why it is worth it

The hand-written step is the only thing that keeps an ephor release, scheduled or manual, from running on its own, and §GOAL-004-handover asks that a mechanical next move be handed to a script wherever an algorithm can finish it. With 251 entries pending and no release yet, it is also what stands between ephor and its first tag. The same request is filed for rhei (agent-grounds/rhei#439), grund (agent-grounds/grund#433) and fissile (agent-grounds/fissile#88). Doing all four keeps the format they share the same.

Filed by grounded-ticket intake from ephor.30 (kind: feature).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesthigh-priorityWrong or misleading verdict a user can still catch, or an adoption blockerpath:plannedA written plan, discussed on the ticket, before the fix

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions