Relationships
#2255 Lab status never returns to shipped on merge — transitions are manual and drift silently
Opened by skunk-ape · 9/17/2026
Problem
Lab status changes go through PATCH /api/v1/lab/issues/<n> with
{"status": "shipped"}, which is admin-gated for every status except open and
closed. Nothing in either repo's CI calls it. The sanctioned path is the
@swamp/issue-lifecycle model's ship method, which only works for issues that
have a live model run — an issue worked without one has no route back to
shipped except a hand-driven API call or a drag on the board. swamp issue edit does not help: it changes title, body and type only, and the CLI has no
status verb at all.
Note for whoever builds this: POST /api/v1/lab/issues/<n>/lifecycle is not
the mechanism, despite taking a targetStatus. It appends a timeline entry and
nothing else — targetStatus is a label on the entry, and the handler only
calls repo.save(issue) in the classified/regression branch. Posting one
returns 201 and leaves the status exactly where it was. Confirmed the hard
way: two lifecycle entries posted against #2179 and #2181 both succeeded and
neither issue moved.
So merged work sits in in_progress indefinitely, and nothing anywhere says so.
Evidence
18 issues are in in_progress as of 2026-09-17. Cross-referencing each against
merged commits in swamp and swamp-club:
| lab | merged as | merged | still in_progress after |
|---|---|---|---|
| #2179 | swamp-club#1219 | 2026-09-16 | 1 day |
| #2181 | swamp#2477 | 2026-09-16 | 1 day |
| #2001 | swamp-club#1173 | 2026-09-04 | 13 days |
The other 15 have no merged commit referencing them and are genuinely open.
#2179 is the sharpest illustration. Its CLI sibling #2180 and the follow-up
#2248 are both shipped, and #2216 — the prod ClickHouse MV its payout depends
on — is shipped too. Only the parent was left behind, so the board shows a
feature as in progress every part of which has shipped.
Proposed solution
On PR merge in swamp and swamp-club, have CI post the transition for the lab issues the PR title references. Both repos already carry the reference in a stable form:
swamp: fix(cli): resolve repo root ... (swamp-club#2181) (#2477)
swamp-club: feat(recruit): reusable /r/<code> ... (#2179) (#1219)A pull_request: closed job gated on merged == true that extracts the ref and
PATCHes the issue would cover it. It needs an admin token in CI, which is the
main cost to weigh.
The payload is a good fit for a merge hook, which is part of why this is worth doing rather than nagging people to drag cards:
PATCH /api/v1/lab/issues/<lab>
{"status": "shipped",
"githubPrUrl": "https://github.com/swamp-club/swamp/pull/<pr>",
"githubPrNumber": <pr>}issue.ship(prUrl, prNumber) records the PR on the issue, so the transition
carries its own evidence — and a merge hook already holds both values. The
handler also emits a status-changed event, so the board and any listeners stay
consistent without extra work.
Two details worth settling before building it:
swamp-club's
(#lab) (#pr)ordering is positional, and a lone trailing(#N)is a PR number, not a lab ref. Sweeping by hand I hit exactly this: #1226 and #815 both looked like stale lab issues and were swamp-club PR numbers. An extractor that treats any(#N)as a lab ref will transition unrelated issues. The swamp repo'sswamp-club#Nform has no such ambiguity — worth considering whether swamp-club should adopt it too.Merged is not released. If
shippedis meant to mean "in a release", jumping straight there on merge overstates it.@swamp/issue-lifecyclealready distinguishes the two (pr_merged→releasing→ship), so the CI hook should probably mirror that split — transition on merge to the pre-release state, and let the release job postshipped.
Meanwhile
#2179 and #2181 still need a manual transition.
Corrected after filing: the original text named the lifecycle endpoint as the transition mechanism. It is not — see the note in Problem. Left recorded here because building against the wrong endpoint fails silently with a 201, which is the same trap this issue exists to close.
Open
No activity in this phase yet.
Sign in to post a ripple.