mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-03 23:37:53 +01:00
changelog: wave PRs fragment covers release, stacked-PR refusal and settle checks
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
501ff46f50
commit
7fa0c5e6c7
1 file changed
+4
-4
@@ -2,10 +2,10 @@
|
||||
|
||||
### Added
|
||||
- **`gstack-ship-queue wave plan`** (read-only) counts the live READY PRs (open, head equal to their READY receipt). Over 6, it prints `WAVE_ADVISED` and suggested groups of 3 to 6. PRs that change a common file always share a group. Each group takes its largest PR's area (a skill directory, the first word of a `lib/`, `bin/` or `test/` module name, or `docs`), and its integrator is the PR with the most changed lines. `train build` prints the same `WAVE_ADVISED` line when handed more than 6 pins. It is advice, never a refusal.
|
||||
- **`wave build --prs <n>@<sha>,...`** makes the integrator branch `wave/<nonce>`. It merges each constituent's pinned head onto main with the train's merge rules, as a merge commit whose second parent is the pin, so no constituent is rebased or squashed. It writes the wave record to `refs/notes/gstack-trains` before pushing and leaves one "frozen in wave" comment on each constituent. A conflict stops with `QUEUE_WAVE_CONFLICT` and leaves the merge in a worktree under the state root. `--continue` takes the integrator's committed resolution only when that commit merges exactly that pin. `--drop <pr>` rebuilds the wave without one PR on a new branch (never a force-push), and refuses with `QUEUE_WAVE_DEPENDENT` when another pin contains the dropped one.
|
||||
- **`ready` and `train build` check a wave PR before it gets a slot.** They walk the wave branch back to its recorded base: every pin must be merged unchanged and in order, any other merge is refused, and every constituent must still be open at its pin. Otherwise they refuse with `QUEUE_WAVE_MOVED`. They refuse with `QUEUE_WAVE_UNKNOWN` when a `wave/` branch has no record, and with `QUEUE_WAVE_DUPLICATE` when a PR is pinned both on its own and inside a wave. READY gains `WAVE:` and `CONSTITUENTS:` lines. After that the wave PR is an ordinary slot: `train land`, `verify`, the stamp and the backstop are unchanged.
|
||||
- **`wave settle --wave <nonce>`** runs after the wave PR merges. It checks that main's merge carries the wave head's tree. Each constituent still at its pin gets a "Landed in wave #W as vX" comment, naming any integrator commits that touched its files, and is closed. A constituent whose head moved stays open with a comment saying its newer work did not land. Reruns post nothing twice, and `--dry-run` shows what it would do.
|
||||
- **`wave build --prs <n>@<sha>,...`** makes the integrator branch `wave/<nonce>`. It merges each constituent's pinned head onto main with the train's merge rules, as a merge commit whose second parent is the pin, so no constituent is rebased or squashed. It writes the wave record to `refs/notes/gstack-trains` before pushing and leaves one "frozen in wave" comment on each constituent. A conflict stops with `QUEUE_WAVE_CONFLICT` and leaves the merge in a worktree under the state root. `--continue` takes the integrator's committed resolution only when that commit merges exactly that pin. `--drop <pr>` rebuilds the wave without one PR on a new branch (never a force-push), and refuses with `QUEUE_WAVE_DEPENDENT` when another pin contains the dropped one. A drop that would leave fewer than 3 PRs, or `--release`, ends the wave so its PRs ride alone. Both wait until the wave PR is closed, because a train that already admitted it would still land it. Stacked PRs (whose base is another branch) cannot join a wave.
|
||||
- **`ready` and `train build` check a wave PR before it gets a slot.** They walk the wave branch back to its recorded base: every pin must be merged unchanged and in order, any other merge is refused, and every constituent must still be open at its pin. Otherwise they refuse with `QUEUE_WAVE_MOVED`. Train land's stamp commits after the last constituent are allowed, so a stamped wave is re-READY'd like any stamped PR. They refuse with `QUEUE_WAVE_UNKNOWN` when a `wave/` branch has no record, and with `QUEUE_WAVE_DUPLICATE` when a constituent of a live wave is READY'd or trained on its own, so it cannot land twice. READY gains `WAVE:` and `CONSTITUENTS:` lines. After that the wave PR is an ordinary slot: `train land`, `verify`, the stamp and the backstop are unchanged.
|
||||
- **`wave settle --wave <nonce>`** runs after the wave PR merges. It takes only a wave PR merged into the base branch, and checks that the merge commit is on that branch and carries the wave head's tree. Each constituent still at its pin gets a "Landed in wave #W as vX" comment, naming any integrator commits or hand-resolved merges that touched its files, and is closed if its head has not moved since. A constituent whose head moved stays open with a comment saying its newer work did not land. Reruns post nothing twice, and `--dry-run` shows what it would do.
|
||||
- `docs/ship-policy.md#wave-prs`, the merge-train section of `docs/captain.md`, the `/captain` skill, the READY template's `WAVE` lines and a `WAVE_TRIGGER` crew parameter. Seven new result codes, each with a troubleshooting entry.
|
||||
|
||||
### Tests
|
||||
- `test/ship-queue-wave.test.ts` runs the real bin against the train fixture. It covers area and grouping rules; a wave build's merge chain, record, push and notices; size and moved refusals; a conflict, an early `--continue` refused, then a resolution; `--drop` as a new wave, and its dependent refusal; `ready` and `train build` reading a wave from a record rebuilt from notes, with moved, duplicate and unknown refusals; `WAVE_ADVISED` and `wave plan`; and `wave settle` closing, leaving open and staying idempotent.
|
||||
- `test/ship-queue-wave.test.ts` runs the real bin against the train fixture. It covers area and grouping rules; a wave build's merge chain, record, push and notices; size and moved refusals; a conflict, an early `--continue` refused, then a resolution; `--drop` as a new wave, its dry run, its dependent refusal and a drop under the minimum releasing the wave; a stacked constituent refused; `ready` and `train build` reading a wave from a record rebuilt from notes, with moved, duplicate (a constituent alone included) and unknown refusals; a wave head carrying train stamps; `WAVE_ADVISED` and `wave plan`; and `wave settle` refusing a merge into another branch, walking two stacked stamps, naming a hand-resolved merge, closing, leaving open and staying idempotent.
|
||||
Reference in new issue
Block a user