Skip to content
xiv

xiv stack

The stacked-PR feature lifecycle: init, plan, build, status, triage, preview, push, review, and amend.

xiv stack takes a whole Linear feature — a project, or a parent issue with sub-issues — and builds it as a stack of locally-committed branches: one reviewable branch per issue, each stacked on the one below it. You publish them to GitHub a few PRs at a time, and when a change lands low in the stack, Jujutsu (jj) — the rebase engine underneath the whole stack lifecycle — re-flows it up through every descendant automatically.

Everything is keyed by --feature <slug>, which names the stack map — the source of truth linking each issue to its branch, position, status, and PR. The map lives at <SMITHERS_HOME>/stacks/<feature>.json.

cd /path/to/target-repo
xiv stack init                                   # one-time per repo: colocate jj
xiv stack plan ENG-400 --feature checkout        # Linear parent/project -> ordered stack map
xiv stack build   --feature checkout             # build every entry locally; resumable
xiv stack status  --feature checkout             # positions, statuses, branches, PRs
xiv stack preview --feature checkout             # checkout the tip = try the whole feature
xiv stack push    --feature checkout --count 5   # publish the lowest 5 as stacked PRs
xiv stack review  --feature checkout             # settle open PRs against CI + human comments
xiv stack amend   --feature checkout -m "rename the column" --target ENG-401

The operating loop

You don't have to memorize the sequence — xiv stack triage tells you the next action every time:

  1. Run xiv stack triage --feature <slug> --json.
  2. Read the action field: plan → run plan; build → run build (a crashed run also shows build — re-running resumes); push → run push; wait → all published, nothing to do until humans review and merge; done → every entry merged.
  3. Run the matching command, then go back to step 1.

xiv how-to prints the authoritative runbook for this loop, and the xiv-operator skill automates it for long or overnight builds. See Stack Map & Triage for the state model behind it.

xiv stack init

One-time per repo: switch on jj in the current repo.

xiv stack init

Runs jj git init --colocate, creating .jj/ next to .git/. Reversible with rm -rf .jj; GitHub, CI, and reviewers only ever see a normal git repo. Requires jj on PATH (brew install jj).

It refuses, with a specific error, when: jj isn't installed; the current directory isn't a git repo (never run it in a parent directory holding multiple repos); or a stray jj workspace in a parent directory shadows this repo. Already-colocated repos are reported as ready. For multi-repo features, run it in each repo before building.

xiv stack plan

Plan a stack: fetch a Linear project or parent issue and order its issues into a stack map — or persist a resolved plan file.

xiv stack plan <source> --feature <slug> [--base <branch>] [--repo key=path]... [--skip-acceptance-review]
xiv stack plan --feature <slug> --plan <file> [--repo key=path]...
 
# examples
xiv stack plan ENG-400 --feature checkout
xiv stack plan PROJ-42 --feature payments \
  --repo api=/code/api --repo ledger=/code/ledger-rs
xiv stack plan --feature payments --plan /tmp/payments-plan.json --repo api=/code/api

source is a Linear project ID or a parent issue key whose sub-issues become the stack. It's required unless you pass --plan.

FlagDefaultWhat it does
--feature <slug>requiredNames the stack map file and identifies the stack across commands.
--base <branch>mainTrunk branch every repo's substack is based on.
--repo key=pathcurrent directoryAssign a repo (repeatable) for multi-repo features. Omit for a single-repo stack rooted here.
--plan <file>Persist a resolved plan file (from the stack-plan skill) instead of running the planner. Deterministic — no agent runs.
--skip-acceptance-reviewoffRecord in the map that every build of this feature skips the local acceptance-review step (the feature-wide default).

Without --plan, it launches the stack-plan workflow, which reads Linear and writes the ordered map. This step deliberately runs the most capable planning model regardless of tier — the ordering it writes is inherited by every later command, so a wrong order is a rebuild (see Model Tiers).

For interactive planning — auto-assign the obvious issues, confirm the unclear ones, exclude non-code work like "set GCP secrets" — use the stack-plan skill, which writes the resolved plan and persists it via --plan. Excluded issues are recorded in the map and shown by status, never built, never lost.

plan runs from anywhere — jj readiness is checked per repo at build/amend/push time, not here.

xiv stack build

Build entries locally, bottom to top. Resumable.

xiv stack build --feature <slug> [--repo <key> | --all-repos] [--detach] \
  [--skip-acceptance-review] [--max-iterations <n>]
FlagDefaultWhat it does
--feature <slug>requiredWhich stack to build.
--repo <key>sole repoBuild only this repo's substack (a key from the stack map). Required on multi-repo stacks unless --all-repos.
--all-reposoffFan out across every repo in the stack — one pinned run per repo, in parallel (each run is detached).
--detachoffStart the run in the background (smithers up -d) and return immediately, so you can poll with xiv stack triage.
--skip-acceptance-reviewoffBuild without the local review step, this run only. ORs with the map's plan-time default — it can force skipping on, never re-enable review a plan opted out of. Validation still gates every entry.
--max-iterations <n>3Forwarded to every entry's implement subflow: passes allowed per issue. Clamped to 1–10.

Each entry runs through the same implement loop as xiv implement — plan, implement, validate, locally review — on a branch stacked on the previous entry's branch (or the trunk, for the first). Everything stays local; nothing is pushed.

Building is resumable: Smithers persists each completed step, so a crash mid-stack resumes by skipping already-built entries. Re-running build is the standard recovery — don't restart from scratch, and don't push to "fix" a build problem. For long or overnight builds, hand supervision to the xiv-operator skill rather than watching it yourself.

Findings the local review raised that the loop shipped anyway are recorded on the entry at build time — they become the "Known gaps" section of the PR description at push.

xiv stack status

Print the stack map, grouped by repo: positions, statuses, branches, and PRs.

xiv stack status --feature <slug>

Each entry shows its position, status (pending, implementing, implemented, pushed, pr-open, merged), issue key, branch, and PR number if one exists. Each repo section ends with its tip — the branch to git checkout to see that repo's full substack. Excluded issues are listed at the bottom with their reasons.

xiv stack triage

Print a compact, structured next-action report for operating the stack. Start here whenever you're unsure what to do.

xiv stack triage --feature <slug> [--json]
FlagDefaultWhat it does
--jsonoffEmit the report as JSON for an operator agent to parse.

The report is derived deterministically from the stack map alone — the same map always produces the same report — so a low-cost operator agent can match action against a fixed decision table. It contains:

  • action — the overall next step: plan, build, push, wait, or done (most urgent across repos wins).
  • A per-repo breakdown: phase (building, built-unpublished, has-stale, publishing, complete), the entry currently in flight, and any stale branches (open PRs an amend re-flowed that need re-syncing — those surface as push).
  • A hint with the exact command to run next.
  • A dump of active Smithers runs (smithers ps --all), so you can tell "needs building" apart from "already building".

xiv stack preview

Check out every repo at its stack tip to preview the whole feature locally.

xiv stack preview --feature <slug>

Runs git checkout <tip> in each repo of the stack (skipping repos not built yet; errors if nothing is built at all). For a multi-repo feature this puts every service at feature-complete simultaneously — the way to integration-test the feature before publishing.

xiv stack push

Publish the next N built entries as stacked PRs, and re-sync re-flowed open PRs.

xiv stack push --feature <slug> [--count <n>] [--repo <key> | --all-repos] [--no-draft]
FlagDefaultWhat it does
--count <n>5How many built-but-unpublished entries to publish this batch.
--repo <key>sole repoPublish only this repo's substack.
--all-reposoffPublish across every repo in the stack.
--draftonOpen each PR as a draft. Pass --no-draft to open ready-for-review PRs.

push is the only stack command that touches GitHub. For each entry it pushes the branch, opens a PR against the entry below it (or the trunk), and force-pushes any already-open PR that a later amend re-flowed (the "stale" branches triage reports).

Each PR gets a real description: an agent reads that entry's own diff (base...branch, exactly its contribution) and writes Summary, Test Plan, and Known gaps — the last fed by the unfixed review findings recorded at build time. The issue link and stack position are appended from the map, not written by the agent, so they're always correct. A failed description never blocks the PR; it opens with the plain footer.

xiv stack review

Settle the open stacked PRs against CI and human review comments. Never merges.

xiv stack review --feature <slug> [--repo <key> | --all-repos] [--detach]
FlagDefaultWhat it does
--repo <key>sole repoSettle only this repo's substack.
--all-reposoffFan out one pinned run per repo, in parallel (each detached).
--detachoffRun in the background.

For each open stacked PR it reads the CI checks and human review comments, fixes what they raise in the branch that owns the code via jj — so the fix cascades up through the descendants — and pushes. Code review already happened locally during build, so nothing here waits on a review bot; this is the stacked-PR counterpart of xiv pr refine.

xiv stack amend

Apply a change to one stack entry and re-flow it through its repo's descendants.

xiv stack amend --feature <slug> -m "<change>" [--target <issue|branch>] [--repo <key>]
 
# examples
xiv stack amend --feature checkout -m "rename the column to created_at"
xiv stack amend --feature payments -m "guard the null case" --target ENG-402
FlagDefaultWhat it does
-m, --message <text>requiredThe change to apply to the located stack entry.
--target <issue|branch>located from the messageExplicit entry to amend (issue key or branch name).
--repo <key>inferredThe repo whose substack is amended. Resolved from --target's entry when omitted; required on a multi-repo stack when neither locates it.

The workflow locates the entry (from --target, or from the message itself), applies the change there, lets jj auto-rebase every descendant branch, and re-validates. It's local-only — the re-flowed branches don't reach GitHub until the next push, which re-syncs any affected open PRs.

The jj rule: read with git, edit through the stack

The stacking is powered by jj colocated with git — underneath it's a normal git repo, and reading it any way you like (git checkout, git diff, git log, your IDE) is fine and encouraged. But:

  • Edit and restack only through xiv stack amend (or jj directly, if you know what you're doing).
  • Never hand-edit a pushed stacked branch with git — no git rebase, git commit --amend, or git push --force on a stack branch. That bypasses jj's cascade and desyncs the stack map from the actual branches.
  • A jj rebase/restack conflict during build or amend is a stop-and-escalate situation; the xiv-operator skill owns the playbook.

Guardrails

  • Never merge a stacked PR — merging is always the human's call.
  • Prefer resuming (build again) over restarting; prefer triage over guessing.
  • push and amend change real state — run them deliberately, not speculatively.