Draft PRs went up for review. Matt reviewed and said “done.” Everyone moved on. Two days later we found the release to RippleCore main was broken - a PR had merged but never actually shipped. The current tab shows merge state but not release state, so “merged” read as “shipped” when it wasn't. The redesign makes the gap between merged and live on main a first-class, loud state.
Great at review + merge status. But the story ends at “merged” - there's no built-in “did this actually reach production” state next to the PR.
Batch changes and ship them on a set cadence - exactly Jon's ask. But they're heavy CI machinery, divorced from a simple team PR list.
Show deploy success/fail clearly. But they live in a separate tool from the PRs, so a failed deploy isn't sitting next to the PR that caused it.
Strong issue workflow and cycles. Release/ship state is bolted on with custom fields, and it tracks issues, not the PRs themselves.
| Tier | Capability | Wave 1? | The real blocker |
|---|---|---|---|
| Must | Four release states from PR data | OK Wave 1 | The webhook already delivers opened / review / merge events, and ship.html already renders PR rows. Merge-side states are free. |
| Must | “Merged, not released” surfaced loud | Partial | Needs a release signal - did the merge actually reach RC main? The GitHub webhook gives merge, not deploy-to-main. Source it from GitHub Deployment status events, the RC-main CI result, or a manual “released” mark. |
| Should | Grouped release train (batch by ship day) | Partial | Needs a “which train” grouping: a PR milestone / label / target-date convention, or a small DWR-side batch table (one row per train). Not in the webhook by default. |
| Should | Held / excluded, with the reason | OK Wave 1 | “Changes requested” already comes over the webhook; the reason is the review comments. Just needs to be shown as a first-class state instead of buried. |
| Differentiator | Per-PR release timeline (opened→released) | Partial | The merge-side timeline is free from webhook events; the “released” step needs the release signal above. Assembled timeline can be derived live or cached in a small D1 table. |
| Differentiator | Release-FAILED health & alerting | Gated | Highest value, highest dependency: needs a real RC-main deploy / CI status feed (the DWR doesn't observe that today) plus a “merged but not released after N hours” rule. Once the release signal exists, the alert itself is small. |
node mockups/release-pipeline/_serve.mjs (serves on http://localhost:4310).