|
| 1 | +# Landing workflow follow-ups |
| 2 | + |
| 3 | +This document captures the next layer of work that became obvious while using |
| 4 | +`stack` to turn a pile of existing PRs into one verified landing PR in |
| 5 | +`TeamSidewinder/event-agent`. |
| 6 | + |
| 7 | +The current tool is already useful for: |
| 8 | + |
| 9 | +- adopting existing branches into an explicit parent graph |
| 10 | +- keeping parent/child intent legible |
| 11 | +- restacking after lower branches move |
| 12 | +- syncing PR base drift back to GitHub |
| 13 | + |
| 14 | +What it does not yet handle well is the operator workflow after the graph is |
| 15 | +known: |
| 16 | + |
| 17 | +- grouping already-open PRs into one strict landing batch |
| 18 | +- excluding later follow-up commits from that landing batch |
| 19 | +- marking original PRs as superseded by the landing PR |
| 20 | +- carrying verification evidence alongside the stack |
| 21 | +- telling the operator which tickets and original PRs are safe to close after |
| 22 | + merge and deploy |
| 23 | + |
| 24 | +Those are not side concerns. For a team that produces many runner PRs in |
| 25 | +parallel, they are the difference between a stack tool and a landing workflow. |
| 26 | + |
| 27 | +## What we learned from a real workflow |
| 28 | + |
| 29 | +The `event-agent` discovery batch looked like this: |
| 30 | + |
| 31 | +- original PRs: `#353`, `#354`, `#363`, `#364` |
| 32 | +- intended outcome: one combined landing PR with the verified set |
| 33 | +- complication: the working composed branch later picked up an extra follow-up |
| 34 | + commit that we did not want to include in the first merge |
| 35 | + |
| 36 | +`stack` was still useful: |
| 37 | + |
| 38 | +- it helped make the intended grouping explicit |
| 39 | +- it helped us reason about parent order and adoption |
| 40 | + |
| 41 | +But the final landing workflow was manual: |
| 42 | + |
| 43 | +1. identify the exact commit that represented the strict verified scope |
| 44 | +2. cut a fresh landing branch at that commit |
| 45 | +3. push it manually |
| 46 | +4. open a combined PR manually |
| 47 | +5. comment on the original PRs manually |
| 48 | +6. manually decide which Linear tickets were safe to close after deploy |
| 49 | + |
| 50 | +That is the gap this document is about. |
| 51 | + |
| 52 | +## Recommendation |
| 53 | + |
| 54 | +Keep `stack` and keep using it. |
| 55 | + |
| 56 | +Do not turn it into a hosted system or a merge queue reimplementation. |
| 57 | + |
| 58 | +Do extend it from: |
| 59 | + |
| 60 | +- branch graph management |
| 61 | + |
| 62 | +to: |
| 63 | + |
| 64 | +- branch graph management plus landing orchestration |
| 65 | + |
| 66 | +The shape should stay explicit, local-first, and Git/GitHub-native. |
| 67 | + |
| 68 | +## Priority follow-ups |
| 69 | + |
| 70 | +### 1. First-class landing branch composition |
| 71 | + |
| 72 | +The tool should help create a strict landing branch from a selected portion of |
| 73 | +the stack. |
| 74 | + |
| 75 | +Example operator need: |
| 76 | + |
| 77 | +```bash |
| 78 | +stack compose discovery-core \ |
| 79 | + --branches hack-agent/lnhack-66-... \ |
| 80 | + --branches hack-agent/lnhack-74-... \ |
| 81 | + --branches hack-agent/lnhack-68-... \ |
| 82 | + --branches hack-agent/lnhack-69-... |
| 83 | +``` |
| 84 | + |
| 85 | +Or, when the stack already exists: |
| 86 | + |
| 87 | +```bash |
| 88 | +stack compose discovery-core --from <bottom-branch> --to <top-branch> |
| 89 | +``` |
| 90 | + |
| 91 | +Expected behavior: |
| 92 | + |
| 93 | +- create a new ordinary branch, for example `stack/discovery-core` |
| 94 | +- base it on trunk |
| 95 | +- replay only the selected stack commits in order |
| 96 | +- exclude later unrelated or follow-up commits unless explicitly requested |
| 97 | +- show the exact commit set before mutating anything |
| 98 | + |
| 99 | +This is the biggest missing piece from the real workflow. |
| 100 | + |
| 101 | +### 2. Superseded PR support |
| 102 | + |
| 103 | +Once a composed landing PR exists, the original PRs should not remain ambiguous. |
| 104 | + |
| 105 | +Example: |
| 106 | + |
| 107 | +```bash |
| 108 | +stack supersede --landing stack/discovery-core --prs 353,354,363,364 |
| 109 | +``` |
| 110 | + |
| 111 | +Expected behavior: |
| 112 | + |
| 113 | +- add a comment to each original PR saying it is superseded by the landing PR |
| 114 | +- optionally add a local metadata link from original PRs to the landing PR |
| 115 | +- optionally close the originals after the landing PR merges |
| 116 | +- refuse to guess if more than one open PR appears to own the same branch |
| 117 | + |
| 118 | +This should be explicit and reversible. |
| 119 | + |
| 120 | +### 3. Verification metadata |
| 121 | + |
| 122 | +Right now verification lives in the PR body or in chat. |
| 123 | + |
| 124 | +That is too fragile for a stack tool that is supposed to support landing order |
| 125 | +and closeout decisions. |
| 126 | + |
| 127 | +Add a lightweight verification record per branch or landing branch. |
| 128 | + |
| 129 | +Example: |
| 130 | + |
| 131 | +```bash |
| 132 | +stack verify add stack/discovery-core \ |
| 133 | + --note "AA General Festival Discovery Deeplink" \ |
| 134 | + --run-id b2f34b20-... \ |
| 135 | + --score 100 \ |
| 136 | + --passed |
| 137 | +``` |
| 138 | + |
| 139 | +Expected stored fields: |
| 140 | + |
| 141 | +- branch or landing branch |
| 142 | +- check type: sim, unit, integration, manual, deploy, smoke |
| 143 | +- identifier: run id, check URL, commit SHA |
| 144 | +- pass/fail |
| 145 | +- optional score |
| 146 | +- optional note |
| 147 | +- timestamp |
| 148 | + |
| 149 | +This should feed status and closeout views. |
| 150 | + |
| 151 | +### 4. Closeout planning |
| 152 | + |
| 153 | +After merge, the operator needs one command that answers: |
| 154 | + |
| 155 | +- which original PRs should now be closed as superseded |
| 156 | +- which tickets are safe to close immediately |
| 157 | +- which tickets remain pending post-deploy checks |
| 158 | +- what post-deploy checks are still outstanding |
| 159 | + |
| 160 | +Example: |
| 161 | + |
| 162 | +```bash |
| 163 | +stack closeout stack/discovery-core |
| 164 | +``` |
| 165 | + |
| 166 | +Expected output: |
| 167 | + |
| 168 | +- landing PR |
| 169 | +- superseded PRs |
| 170 | +- tickets safe to close now |
| 171 | +- tickets blocked on deploy verification |
| 172 | +- required follow-up checks |
| 173 | + |
| 174 | +This should be read-only by default and optionally able to post comments or |
| 175 | +write local notes. |
| 176 | + |
| 177 | +### 5. Better status for operators |
| 178 | + |
| 179 | +`stack status` should grow from “stack health” into “what should I do next”. |
| 180 | + |
| 181 | +Useful additions: |
| 182 | + |
| 183 | +- landing branch detection |
| 184 | +- original PR to landing PR relationships |
| 185 | +- verification summary |
| 186 | +- unresolved post-deploy work |
| 187 | +- clear ready/blocking reasons |
| 188 | + |
| 189 | +Example questions it should answer directly: |
| 190 | + |
| 191 | +- which branch is the real merge target? |
| 192 | +- which original PRs are now traceability-only? |
| 193 | +- which stack item is blocked, and on what? |
| 194 | +- is this safe to queue? |
| 195 | + |
| 196 | +### 6. Better adoption ergonomics for existing PR piles |
| 197 | + |
| 198 | +The adoption fix for stale branches was necessary, but the operator experience |
| 199 | +is still too manual for a large pile of existing PRs. |
| 200 | + |
| 201 | +Improvements worth adding: |
| 202 | + |
| 203 | +- `stack adopt pr 353 --parent main` |
| 204 | +- `stack adopt pr 354 --parent pr/353` |
| 205 | +- optional helpers to fetch the PR head locally if missing |
| 206 | +- clearer warnings when a branch has drift that suggests “compose instead of |
| 207 | + direct stack submit” |
| 208 | + |
| 209 | +The tool should not infer the whole dependency graph. It should make the |
| 210 | +adoption path faster and safer once the operator already knows the shape. |
| 211 | + |
| 212 | +## Commands worth adding |
| 213 | + |
| 214 | +Suggested command surface: |
| 215 | + |
| 216 | +- `stack compose` |
| 217 | +- `stack supersede` |
| 218 | +- `stack verify add` |
| 219 | +- `stack verify list` |
| 220 | +- `stack closeout` |
| 221 | +- `stack adopt pr` |
| 222 | + |
| 223 | +Commands that probably should not exist yet: |
| 224 | + |
| 225 | +- automatic ticket closure |
| 226 | +- automatic deployment polling |
| 227 | +- merge queue orchestration beyond normal `stack queue` handoff |
| 228 | + |
| 229 | +Those belong later, if at all. |
| 230 | + |
| 231 | +## Recommended v1 order |
| 232 | + |
| 233 | +1. `stack compose` |
| 234 | +2. `stack supersede` |
| 235 | +3. `stack verify add` and `stack verify list` |
| 236 | +4. `stack closeout` |
| 237 | +5. `stack status` improvements |
| 238 | +6. `stack adopt pr` |
| 239 | + |
| 240 | +This order matches the highest-friction steps from the real discovery landing. |
| 241 | + |
| 242 | +## Design constraints |
| 243 | + |
| 244 | +Keep the following properties: |
| 245 | + |
| 246 | +- ordinary local branches |
| 247 | +- ordinary GitHub PRs |
| 248 | +- explicit operator choices |
| 249 | +- deterministic repair flows |
| 250 | +- no hidden hosted state |
| 251 | +- no attempt to replace GitHub merge queue |
| 252 | + |
| 253 | +The tool should help an operator say: |
| 254 | + |
| 255 | +- “these are the changes I want to land together” |
| 256 | +- “these are the original PRs this replaces” |
| 257 | +- “this is the evidence that the landing branch is good” |
| 258 | +- “these are the tickets safe to close after deploy” |
| 259 | + |
| 260 | +without requiring a separate spreadsheet or a memory-heavy manual ritual. |
| 261 | + |
0 commit comments