Skip to content

Commit f0e2c19

Browse files
authored
Merge pull request #66 from flightctl/refresh-stack-workflow
Refresh stack workflow
2 parents 9e446d8 + 0419b21 commit f0e2c19

14 files changed

Lines changed: 853 additions & 0 deletions

File tree

‎AGENTS.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ This repository contains reusable AI coding workflows that can be installed glob
1717
- **implement** — Story-to-code workflow (ingest, plan, revise, code, validate, publish, respond)
1818
- **kcs** — KCS Solution article workflow (gather, draft, validate, handoff)
1919
- **prd** — Requirements-to-PRD workflow (ingest, clarify, draft, revise, publish, respond)
20+
- **rebase-stack** — Rebase a stacked-branch chain with conflict guidance, per-branch validation, and push (start, continue, validate, push)
2021
- **sizing** — Pre-cycle Feature sizing with T-shirt sizes and team effort breakdowns (ingest, assess, apply)
2122
- **skill-reviewer** — Meta-workflow that audits AI skill directories
2223
- **triage** — Bulk Jira bug triage with AI-driven categorization and HTML reports
@@ -146,6 +147,7 @@ ai-workflows/
146147
├── implement/
147148
├── kcs/
148149
├── prd/
150+
├── rebase-stack/
149151
├── sizing/
150152
├── skill-reviewer/
151153
│ ├── prompts/

‎README.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ Reusable AI coding workflows a team member can install globally or per-project,
3939
- **KCS** -- KCS Solution article workflow: gather bug context from Jira, draft a KCS article in markdown, validate against the KCS Content Standard, and produce a handoff message for the support engineer.
4040
See [kcs/README.md](kcs/README.md).
4141

42+
- **Rebase Stack** -- Rebase a stacked-branch chain onto an updated base using `gh stack`, guide through conflict resolution, validate each branch, and push all updated branches.
43+
See [rebase-stack/README.md](rebase-stack/README.md).
44+
4245
- **Sizing** -- Pre-cycle Feature sizing: ingest Features from Jira (single or batch by Fix Version), assess against a T-shirt size rubric (XS–XXL) with per-team effort breakdowns (DEV, QE, UX, UI, DOCS), and write results back to Jira.
4346
See [sizing/README.md](sizing/README.md).
4447

‎rebase-stack/README.md‎

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
# Rebase Stack Workflow
2+
3+
Rebases a stacked-branch chain onto an updated base branch using `gh stack`,
4+
guides you through conflict resolution if needed, validates each branch, and
5+
pushes all updated branches. Creates any missing PRs afterwards, with
6+
fork-aware targeting.
7+
8+
## Phase Flow
9+
10+
```
11+
/start ──── success ──────────────────────── /validate ──── /push ──── done
12+
└─── conflict ──── (resolve) ──── /continue ──┐
13+
│
14+
conflict ──── (resolve) ────┘
15+
success ──────────────── /validate ──── /push ──── done
16+
```
17+
18+
## Prerequisites
19+
20+
| Tool | Purpose |
21+
|------|---------|
22+
| `git` | Rebase and push operations |
23+
| `gh` (GitHub CLI) | Stack management, PR creation |
24+
| `gh-stack` extension | `gh extension install github/gh-stack` |
25+
| Remote access (`origin`) | Fetch and push |
26+
27+
`/start` installs the extension automatically if it is not found.
28+
29+
> **Note:** `gh-stack` is in private preview. The CLI extension installs for
30+
> anyone, but the Stacked PRs feature (used by `gh stack submit`) requires
31+
> enablement on the upstream repository. If `gh stack submit` exits with
32+
> code 9, the repo does not have it enabled — the skill falls back to
33+
> `gh pr create` automatically.
34+
35+
## Stack Initialization
36+
37+
`/start` detects whether your branches are already tracked by `gh stack`:
38+
39+
- **Already tracked** (`gh stack view --json` exits 0): proceeds directly to
40+
the rebase.
41+
- **Not yet tracked** (exit code 2): discovers branches from the commit graph
42+
(`git log --reverse --decorate origin/{base}..HEAD`), presents the
43+
bottom-to-top list for your confirmation, then runs:
44+
```bash
45+
gh stack init --base {base} branch-1 branch-2 branch-3 ...
46+
```
47+
`gh stack` adopts the existing branches and detects any open PRs automatically.
48+
49+
You only need to initialize once per stack. Subsequent `/start` runs skip
50+
this step.
51+
52+
## Commands
53+
54+
| Command | When to use |
55+
|---------|-------------|
56+
| `/start` | Begin the rebase. Takes an optional base branch (default: `main`). Installs `gh-stack` if needed, initializes the stack if not yet tracked, then rebases. Local only — does not push. |
57+
| `/continue` | Resume after resolving a conflict mid-rebase. Repeat as needed. Local only — does not push. |
58+
| `/validate` | After rebase completes: re-fetches to check remote currency, runs lint and unit tests on each branch independently, and shows a branch overview table. Does not push. |
59+
| `/push` | After validation: asks for confirmation, pushes all branches atomically with `gh stack push`, then creates any missing PRs with fork-aware targeting. |
60+
61+
## Usage Examples
62+
63+
### Typical: rebase a stack onto updated main
64+
65+
You have three branches stacked: `main → story-1 → story-2 → story-3 (HEAD)`.
66+
Main has moved forward. Run:
67+
68+
```
69+
/start
70+
```
71+
72+
The agent checks for `gh-stack`, detects the stack (or initializes it),
73+
then runs `gh stack rebase --remote origin`. On success it prompts you to
74+
run `/validate`, which checks each branch and shows an overview table. Then
75+
run `/push` to push all branches atomically with `gh stack push` after
76+
confirmation.
77+
78+
### With conflicts
79+
80+
Same scenario, but `story-2` conflicts with a change on main:
81+
82+
1. `/start` — rebase stops at `story-2`, shows the conflicting files
83+
2. Resolve conflicts. For "old version vs evolved version" conflicts (the lower
84+
branch was rebased and this branch has older copies): `git checkout --ours <file> && git add <file>`.
85+
For genuine new-code conflicts: merge manually, then `git add <file>`. Do not `git commit`.
86+
3. `/continue` — rebase resumes; if clean, prompts you to run `/validate`
87+
4. If another conflict appears, repeat steps 2–3
88+
5. `/validate` — shows branch overview table after per-branch lint/test
89+
6. `/push` — pushes after confirmation, creates any missing PRs
90+
91+
### Rebasing onto a branch other than main
92+
93+
```
94+
/start feature/platform-upgrade
95+
```
96+
97+
The agent fetches `origin/feature/platform-upgrade` and rebases onto it.
98+
99+
### Fork-based workflow (no Stacked PRs)
100+
101+
After `/push` completes the push, it tries `gh stack submit --auto`. If the
102+
upstream repo does not have Stacked PRs enabled (exit code 9), it falls back
103+
to `gh pr create` with `--head fork-owner:branch --repo upstream/repo`, setting
104+
`Depends on: #N` in each PR body. All PRs target the upstream default branch.
105+
106+
## Artifacts
107+
108+
Local state written to `.artifacts/rebase-stack/` during the workflow (gitignored):
109+
110+
| File | Written by | Purpose | How to clear |
111+
|------|-----------|---------|--------------|
112+
| `validation-cache` | `/validate` | `branch:sha` pairs for each branch that has passed validation. Persists across runs; stale entries are ignored automatically when SHAs change after a rebase. | `rm .artifacts/rebase-stack/validation-cache` to force full re-validation on the next `/validate` run. |
113+
| `logs/{branch}.log` | `/validate` | Full lint and test output per branch. Kept on failure for inspection; deleted on success. | Inspect directly; deleted automatically on the next successful `/validate` run. |
114+
115+
## Push Safety
116+
117+
- Branches are pushed **atomically**: `gh stack push` uses `--force-with-lease
118+
--atomic`, so if any remote branch was updated since the last fetch, the
119+
entire push is rejected rather than partially applied.
120+
- Protected branches (`main`, `master`, `develop`, PR targets) are never
121+
pushed — only the stack branches above them.

‎rebase-stack/SKILL.md‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
name: rebase-stack
3+
version: 0.1.0
4+
description: >-
5+
Rebases a stacked-branch chain onto an updated base branch using gh-stack,
6+
guides through conflict resolution if needed, validates each branch, and
7+
pushes all updated branches. Creates PRs for any branch that lacks one,
8+
with fork-aware targeting. Works on repos with or without Stacked PRs enabled.
9+
Use when rebasing stacked stories or PRs onto main or another updated branch.
10+
Activated by commands: /start, /continue, /validate, /push.
11+
---
12+
# Rebase Stack Workflow
13+
14+
## Quick Start
15+
16+
1. If the user invoked `/start`, read `commands/start.md` and follow it.
17+
2. If the user invoked `/continue`, read `commands/continue.md` and follow it.
18+
3. If the user invoked `/validate`, read `commands/validate.md` and follow it.
19+
4. If the user invoked `/push`, read `commands/push.md` and follow it.
20+
5. Otherwise, read `skills/controller.md` and present the available phases to the user.
21+
22+
If a step fails or produces unexpected output, stop and report to the user.
23+
Always wait for the user before advancing to the next phase.
24+
25+
For safety rules, see `guidelines.md`.

‎rebase-stack/commands/continue.md‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
name: rebase-stack:continue
3+
description: Resume a gh stack rebase after conflict resolution.
4+
---
5+
# /continue
6+
7+
Read `../skills/controller.md` and follow it.
8+
9+
Dispatch the **continue** phase. Context:
10+
11+
$ARGUMENTS

‎rebase-stack/commands/push.md‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
name: rebase-stack:push
3+
description: Push all stack branches atomically to origin and create any missing PRs.
4+
---
5+
# /push
6+
7+
Read `../skills/controller.md` and follow it.
8+
9+
Dispatch the **push** phase. Context:
10+
11+
$ARGUMENTS

‎rebase-stack/commands/start.md‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
name: rebase-stack:start
3+
description: Verify gh-stack, detect or initialize the stack, then rebase it onto the updated base.
4+
---
5+
# /start
6+
7+
Read `../skills/controller.md` and follow it.
8+
9+
Dispatch the **start** phase. Context:
10+
11+
$ARGUMENTS

‎rebase-stack/commands/validate.md‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
name: rebase-stack:validate
3+
description: Check remote currency, validate each branch, and show a push overview.
4+
---
5+
# /validate
6+
7+
Read `../skills/controller.md` and follow it.
8+
9+
Dispatch the **validate** phase. Context:
10+
11+
$ARGUMENTS

‎rebase-stack/guidelines.md‎

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Rebase Stack Guidelines
2+
3+
## Principles
4+
5+
- Work branch-by-branch and confirm state at each step before proceeding.
6+
- Prefer explicit commands over assumptions — always check exit codes and capture output.
7+
- Preserve the user's intent: rebasing reorganizes history but must not silently drop commits.
8+
- Keep the user informed at every decision point that requires their input.
9+
10+
## Hard Limits
11+
12+
- Never push directly to `main`, `master`, `develop`, or any branch designated as a PR target.
13+
- Never run a destructive git operation (force push, branch deletion) without presenting the
14+
scope to the user first.
15+
- Never resolve a conflict without the user's explicit choice (fix-for-me vs. manual).
16+
- Never skip validation for a branch unless the cache holds a matching `branch:sha` entry
17+
from a previous passing run. Any branch whose SHA has changed must be re-validated.
18+
19+
## Safety Rules
20+
21+
- **Push with `gh stack push --remote origin`.** It uses `--force-with-lease --atomic`
22+
internally, so if the remote was updated since your last fetch the entire push is
23+
rejected rather than partially applied.
24+
- **Never push protected branches.** Do not push to `main`, `master`, `develop`, or any
25+
branch that is the PR target — only push the stack branches above it.
26+
- **Confirm before pushing.** Always present the full list of branches to be pushed and
27+
wait for explicit user confirmation.
28+
- **Stop on unexpected state.** If git or `gh stack` output is ambiguous or unexpected,
29+
stop and report rather than guess.
30+
31+
## Conflict Handling
32+
33+
- When a conflict occurs, show the user the commit that caused it and the conflicting files,
34+
then ask whether they want the agent to fix it or prefer to fix it themselves. Do not
35+
attempt resolution before the user answers.
36+
- **Conflict strategy:** When the conflict is "old version vs evolved version" (a lower
37+
branch was rebased and this branch carries older copies of the same commits), take
38+
`--ours`. In a rebase, `--ours` is the onto-branch (the lower branch's updated tip),
39+
so it keeps the evolved version and discards the stale copy:
40+
```bash
41+
git checkout --ours <file>
42+
git add <file>
43+
```
44+
For conflicts involving genuinely new code unique to this branch, manually merge both sides.
45+
- Instruct the user to resolve, `git add` the resolved files (do NOT `git commit`),
46+
then run `/continue`.
47+
- `gh stack rebase --continue` resumes from where the rebase paused — do not restart
48+
from scratch.
49+
50+
## Quality
51+
52+
- Every branch must pass its project's lint and test suite before being pushed.
53+
- The validation cache (`branch:sha`) ensures previously validated branches are not
54+
re-run unless their tip SHA changed — do not skip cache checks.
55+
- Report validation failures with the log file path; do not dump the full log to chat.
56+
- A clean `git status` (no uncommitted changes) is required before starting a rebase.
57+
58+
## Escalation
59+
60+
- If `gh stack` output is ambiguous or exits with an unexpected code, stop and report
61+
the full output before taking any further action.
62+
- If a conflict cannot be cleanly resolved with `--ours`, show the conflict markers to
63+
the user and wait for their decision.
64+
- If a push is rejected despite `--force-with-lease`, report the rejection and ask the
65+
user how to proceed — do not retry automatically.
66+
67+
## PR Creation
68+
69+
- After pushing, check which branches lack an open PR (use `gh stack view --json`).
70+
- For repos with Stacked PRs enabled: try `gh stack submit --auto`. If it succeeds, done.
71+
- For forks or repos where Stacked PRs are not enabled (exit code 9): create PRs manually
72+
with `gh pr create`, setting `--head owner:branch` and `--repo upstream` for forks.
73+
- All PRs in a fork-based workflow target the upstream default branch (PR Target), not
74+
each other's branches. Use `Depends on: #N` in the PR body to express ordering.

‎rebase-stack/skills/continue.md‎

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
---
2+
name: continue
3+
description: Resume a gh stack rebase after conflict resolution.
4+
---
5+
6+
# Continue Rebase Stack
7+
8+
## Process
9+
10+
### Step 1: Verify Conflicts Are Resolved
11+
12+
```bash
13+
git diff --name-only --diff-filter=U
14+
```
15+
16+
If any files are listed, conflicts are still unresolved. Tell the user to
17+
resolve them and `git add` each file before running `/continue` again.
18+
19+
### Step 2: Continue the Rebase
20+
21+
```bash
22+
gh stack rebase --continue --remote origin
23+
```
24+
25+
Capture the full output. Three outcomes:
26+
27+
---
28+
29+
**On conflict** — another commit in the stack conflicted. Show the user:
30+
31+
1. The commit that caused the conflict:
32+
```bash
33+
git rebase --show-current-patch 2>/dev/null | head -10
34+
```
35+
2. The conflicting files:
36+
```bash
37+
git diff --name-only --diff-filter=U
38+
```
39+
40+
Then ask:
41+
42+
> A conflict was detected. How would you like to proceed?
43+
> - **Fix it for me** — I'll attempt to resolve the conflicts and continue.
44+
> - **I'll fix it** — Pause here; I'll resolve the conflicts manually and run `/continue` when ready.
45+
46+
**Stop here.** Wait for the user's choice before doing anything.
47+
48+
If the user asks you to fix it: examine each conflicting file. For files where
49+
the conflict is "old version vs evolved version" (this branch carries a stale
50+
copy of a commit that the lower branch already updated), apply `--ours` — in a
51+
rebase, `--ours` is the onto-branch (the lower branch's updated tip):
52+
53+
```bash
54+
git checkout --ours <file>
55+
git add <file>
56+
```
57+
58+
For files with genuinely new code on both sides, show the conflict markers and
59+
ask the user which version to keep before proceeding.
60+
61+
Once all files are resolved and staged, run `gh stack rebase --continue --remote origin` automatically.
62+
63+
If the user wants to fix it themselves: instruct them to resolve the conflicts,
64+
then `git add <resolved files>` (do **not** `git commit`), then run `/continue` again.
65+
66+
---
67+
68+
**On unexpected non-zero exit (not a conflict)** — stop and report the full output to
69+
the user. Do not attempt to continue the rebase. Common causes: no rebase is in progress,
70+
network failure, or an unexpected git state. The user must diagnose and resolve before
71+
retrying.
72+
73+
---
74+
75+
**On success** — proceed to Step 3.
76+
77+
---
78+
79+
### Step 3: Report and Hand Off
80+
81+
Tell the user:
82+
83+
> Rebase complete. Run `/validate` to validate each branch before pushing.

0 commit comments

Comments
 (0)