name: gt-flow description: > Most sensible Graphite (gt) stacking decision and execution flow. Diagnoses coupling (overlapping file touches across planned slices), honestly recommends "gt is overkill here — use plain branches / split-to-prs / sequential waves / one PR" when gt would add complexity or risk (especially with coupled core files or agent worktree generation). When gt is chosen or the safe path is taken, enforces commit-in-generation-env + explicit two-phase handoff + backup refs + per-slice escape branches + state so generated code is never lost and recovery is trivial. Use on any gt/graphite/stack/submit --stack decision, execute-plan assembly, concurrent agent work, or manual PR planning.
gt-flow — Sensible Graphite stacking with honest "overkill" guard and zero-lost-code contract
Graphite (gt) and Git worktrees are not mutually exclusive. They are compatible (Graphite has provided explicit support since v1.8.4+), but they are not seamless in all cases. This skill gives you the precise mental model, official guardrails, decision criteria (including coupling), and safe execution patterns so you get the benefits of both without losing code or creating unrecoverable state.
This skill is the single source of truth for "should we use gt here, and exactly how (single worktree, multiple worktrees, or hybrid), so nothing gets lost".
It combines official Graphite guidance (learn-to-stack, how-to-structure-your-stacks, ai-ingestion/llms, comparing-git-and-gt, multiple-worktrees, create-stack, squash-fold-split, and the worktree support notes) with the hard-won realities of agentic execution in this repo (execute-plan dual-mode, git-worktrees, split-to-prs, worktree handoff between agent sessions and primary authenticated shell, and frequent concurrent agent lanes).
Quick Mental Model (gt vs worktrees vs plain git)
| Tool | What it solves | Working directory model | Branch relationship tracking |
|---|---|---|---|
| Plain Git | Basic branching + history | Usually 1 working tree | None (you track it mentally) |
Graphite (gt) |
Stacked/dependent PRs + automated restacking + nice stack UX | Designed for 1 tree (strong support for many since 1.8.4+) | Explicit "stack" graph (parent/child) |
| Git worktrees | Multiple physical checkouts from one .git (isolation, parallel processes, no heavy switch cost) |
Many working trees | None (Git doesn't track stacks) |
Graphite adds the stack graph + cross-stack commands (gt sync + restack, gt modify, gt submit --stack, etc.).
Worktrees give physical isolation (separate dirs, separate node_modules/build state/IDE/dev servers) while sharing the object store.
They compose well when you follow the guardrails below. Graphite will actively protect you from mutating a branch checked out in another worktree.
Core decision procedure (always run this first)
Get the change intent / plan
- If from a design doc or
/execute-planor/implementor chat: extract the intended PR slices (titles + "Files/components affected"). - If raw diff or uncommitted work: run
git status --porcelain+git diff --name-only(and staged) to list touched paths.
- If from a design doc or
Diagnose coupling / overlap
- Build the set of files per intended slice.
- Compute overlap: files that appear in 2+ slices.
- Flag "core files": anything under
src-tauri/src/(especially lib.rs, commands, secrets.rs, app_dirs.rs), central React components/state, shared types, AGENTS.md, .agents/ rules or skills, prompt files that multiple slices would edit, build configs. - Score:
- High coupling: heavy overlap on core files, or >40% of slices touch the same 1-3 files.
- Medium: some shared surface but clear boundaries (e.g. one slice only adds a new module).
- Low: clean functional splits (DB/backend vs frontend, refactor vs behavior change, pure addition with no shared edits).
Context check (critical for agents)
- Is the current shell / worktree the user's primary authenticated clone (where
gthas real GitHub auth and the human doesgt submit --stack)? - Are we inside an agent worktree (local
.worktrees/preferred or~/.grok/worktrees/global fallback clone) / subagent isolation? - Is
command -v gt+gt --help | grep -qi graphitetrue here? - Will the human need to do the final land/submit from a different terminal/shell?
- Is the current shell / worktree the user's primary authenticated clone (where
Decide and declare (be honest and explicit) Output one of:
- "gt recommended (clean splits)" — low coupling + clear functional/iterative/refactor/risk boundaries per how-to-structure-your-stacks. Human or agent is in primary checkout. Proceed with gt recipe.
- "gt overkill or makes harder — use safe alternative" — high coupling on core files, or agent generation context (gt state/auth lives elsewhere), or small scope, or high recoverability priority. Explicitly recommend and follow: plain independent PRs (split-to-prs), sequential waves on one branch then
gt split --by-file/--by-commitat end, or single PR. - "hybrid: produce per-slice branches + handoff recipe" — common for execute-plan style. Agents produce committed + pushed per-PR branches (with good names). Human runs
git fetchin primary shell then usesgt(create/track/submit) or plain gh. This is the "flawless + recoverable" default for most agentic work.
State the decision + 1-sentence rationale citing coupling or context. Get confirmation before mutating branches if the user is in the loop.
When gt is genuinely overkill or makes things harder (honest list)
Use this language in reports:
- High file coupling: "Multiple slices touch the same core files (e.g. lib.rs + central reactor + shared types + AGENTS.md). Graphite's parent/child tracking and restack add little value while increasing surface for desync on resume, worktree handoff, or concurrent agents.
gt splitat the end on a linear branch is simpler and still gives stacked PRs." - Agent worktree / shell mismatch: "Implementation happens in isolated worktrees (local
.worktrees/<...>/by default per git-worktrees preference, or fallback global Grok-managed clones under~/.grok/worktrees/) where the gt CLI is either absent or lacks the user's authenticated GitHub session. Per the multiple-worktrees doc and past execute-plan runs, gt commands must be run from the exact worktree that has the branch checked out; crossing shells creates exactly the auth + state problems we have seen. Safer to have agents produce plain pushed branches + per-PR refs; human does gt (or gh) in primary shell afterfetch." - Small / one-concept change or pure generated-code/version-bump style: one PR or one branch +
gt split --by-fileif review size is the only concern. - High recoverability requirement: state file + named
refs/backup/...+ explicit per-slice branches +gt undohistory being per-worktree make plain-git + documented handoff the lower-risk path when the run can be interrupted. - You want the simplest mental model: "just commit and push a branch per reviewable unit."
Graphite shines for interactive human development on clean boundaries in the primary checkout (asynchronous building while waiting for review, nice gt log / gt up / gt restack, gt modify for fixups without rebase hell). It is not magic for coupled changes or cross-shell agent orchestration.
gt + Git worktrees: Official stance, compatibility guardrails, and decision guide
Official Graphite Stance on Worktrees (v1.8.4+)
- Graphite fully supports multiple Git worktrees.
- It respects Git's rule: a branch can only be checked out in one worktree at a time.
- Graphite will not mutate a branch that is checked out in another worktree. It errors out with a clear message instead. Treat this as a safety feature.
gt logshows which worktree each branch is currently checked out in (extremely valuable before any stack operation).gt undois per-worktree.- Strong recommendation: Avoid having more than one worktree on the same stack when possible.
- If a stack is split across worktrees, you must run
gt sync/gt restack(and similar stack-wide commands) from each relevant worktree. - Special case:
gt sync/gt getmay still update the localtrunk(main) even if it is checked out elsewhere. - Use
gt create --onto <branch>when you want to start a new branch on top of a branch that is already checked out in another worktree.
This is a significant improvement over earlier reports of potential data loss — Graphite now actively protects you.
When to Use What (Decision Guide)
1. Plain Git branching is enough when:
- Most PRs are relatively independent or small/atomic.
- You don't frequently have long chains of dependent changes waiting in review.
- Low PR volume, small team, or you prefer minimal tooling and are comfortable with manual rebases or
gt splitat the end. - You value maximum flexibility and "nothing extra."
Trade-off: You do the restacking yourself. This gets painful with deep stacks.
2. gt in a single worktree (the sweet spot for most human interactive work)
Use this when:
- You regularly break work into stacked PRs (dependent changes reviewed separately but landing in order).
- You want to stay unblocked: submit PR #1 while still working on PR #3 (iterative improvement stacks).
- You value automation for the painful parts (
gt sync --restackis excellent). - You mostly work on one feature/stack at a time (or can context-switch with
gt checkout/ stack navigation). - You are in your primary authenticated checkout (or a dedicated worktree where gt has full state and auth).
Why single worktree? Lowest cognitive overhead. All the stack magic just works. gt was primarily designed around this model. Most developers should start here for their daily driver.
3. gt + multiple worktrees
Use this when:
- You frequently work on 2+ independent features/stacks in parallel.
- You hate branch switching in one directory (slow rebuilds, Docker context, IDE state, long-running dev servers, etc.).
- You want true physical isolation (one terminal building/testing while editing in another; parallel AI coding agents in separate "lanes").
- You run long-lived processes or have different environment needs per branch.
How to do it well (critical in this repo):
- Create worktrees with
git worktree add ...(or the project'sconcurrent-cli-agents/ git-worktrees scripts). - Always run
gt logbeforegt sync,gt restack,gt modify,gt submit, or creating on top of something. It tells you exactly where branches live. - If a stack ends up split across worktrees, run the relevant stack commands from each worktree that owns part of it.
- Use
gt create --onto <branch>when the desired parent is checked out in another worktree. - Graphite will refuse (with a clear error) if you try to mutate a branch checked out elsewhere — this protects you.
Caveats for agentic use:
- gt state and authenticated GitHub session usually live in the user's primary shell / primary worktree. Agent worktrees (local
.worktrees/by default, or full clones under~/.grok/worktrees/in fallback/extreme cases) often have gt absent or unauthenticated. - This is why the hybrid pattern (agents produce committed/pushed per-PR branches → human performs gt assembly or submit in the primary authenticated tree after
fetch) is so common and safe here. gt undohistory is per-worktree, so recovery context can be split.
4. Hybrid / advanced patterns (very common in this project)
- Primary worktree on
main(or a stable trunk) + dedicated worktrees (or full clones) for active generation / agent lanes. - One "lane" per concurrent task (review, active dev, experiment, agent sub-plan).
- Agents implement in isolation (worktree or full clone) and push their branches. The human (or orchestrator in the primary tree) then uses
gt create --onto,gt track, or assembles the stack withgt submit --stack. - Some teams use worktrees instead of deep Graphite stacks purely for isolation; many who like stacking use both.
Summary Recommendation (this repo context)
| Your situation | Best choice | Notes for agentic / multi-worktree work |
|---|---|---|
| Mostly independent PRs or high coupling on core files | Plain Git or "do work then gt split" at end |
Coupling diagnosis in this skill often wins here. |
| Regular stacked PRs, mostly one thing at a time, human in primary checkout | gt in single worktree (primary) |
Sweet spot for clean functional/iterative stacks. |
| Parallel independent work + hate switching + agents | gt + multiple worktrees (with discipline) |
Powerful. Use gt log religiously + gt create --onto. |
| Agent generation (execute-plan, subagents, concurrent) + final human gt steps | Hybrid: agents in isolated trees/clones produce per-PR branches + commits; human does gt in primary after fetch |
Default for most ambitious plans here. Per-PR escape hatches + explicit handoff required. |
| Very complex / many concurrent stacks | gt + worktrees (with strict discipline) |
gt log before every stack-wide command. Run sync/restack from owning trees. |
Practical Starting Advice (adapted for this environment)
- Install
gtand try the core flow first in your normal primary clone (single worktree):gt create,gt submit --stack,gt sync,gt modify,gt log/gt ls. - Only add worktrees (or let agents use them) when you feel the pain of switching or need true parallel isolation.
- Before any potentially stack-affecting
gtcommand, rungt logto see current checkout state and worktree ownership. - For agent runs: follow the zero-lost-code contract below. Agents should commit + push inside their environment. The primary authenticated shell is usually where the final
gtassembly / submit happens. - You can always fall back to plain
git— Graphite is additive. The per-slice branches we preserve give you escape hatches.
The "flawless + easily recoverable + code never lost" contract (always)
Regardless of gt vs plain decision, these rules are non-negotiable in this project:
- Commit inside the generation environment. Subagents (or you)
git add -A && git commitin the worktree / shell where the code was written. Never rely on "I'll copy later". - Push the concrete branches (with
--force-with-leasefor safety on resume). The objects must be on the remote (or at least fetchable) before declaring a slice "done". - Record authoritative SHAs (not just branch names).
pr.commit_sha = $(git -C <wt> rev-parse HEAD); verify withgit cat-file -t. - Tear down worktrees before mutating their branch refs (the Subagent Worktree Protocol from execute-plan). Use
grok worktree rm --force(or the scripts) beforegit checkout -Bor gt operations on that branch name. - Worktree ownership discipline for gt (official guardrail). Before any gt command that can affect a stack (
gt sync,gt restack,gt submit,gt modify,gt createon top of something, etc.), rungt log(orgt ls) to see exactly which worktree owns each branch. Graphite will refuse to mutate a branch checked out in another worktree — this is protection, not a bug. Usegt create --onto <branch>when the parent lives in a different worktree. Never assume "my current shell owns the whole stack." - Two-phase handoff is explicit and copy/pasteable.
- Phase 1 (agent / generation shell or worktree): commit + push the per-slice or gt branches. Print exact commands for the user.
- Phase 2 (user's primary authenticated clone / primary worktree):
git fetch origin, then the gt (or gh) commands. Never assume the agent shell or secondary worktree can do the finalgt submit --stack.
- Backup refs before any risky mutation.
- Before gt operations that could surprise:
git stash create+git update-ref refs/backup/pre-gt-$(date +%s) $sha. - Or
git branch backup/pre-gt-... <branch>.
- Before gt operations that could surprise:
- Per-slice escape hatches always exist. Even in "gt mode", keep the
execute-plan/<plan>-pr-N-<slug>style branches (or equivalent) as plain refs the user can fall back to withgt track,gt split, or plain PRs. - State / transcript survives. For long runs use a
/tmp/...-plan.jsonor equivalent + the memory flush patterns. On crash,--resumeor manual reconstruction from pushed branches + chat must be possible. - Hygiene after. After any agent orchestration: prefer
git worktree prune+ local scripts for.worktrees/(the default);grok worktree gc+.agents/skills/git-worktrees/scripts/agent-worktree-clean.sh --pruneif global clones or ghosts are present. Run from the primary shell. See git-worktrees skill. - Never
cpor editor-save from a worktree into the primary checkout for integration. Commit + cherry-pick / merge / gt create + cherry-pick range in the integration shell only.
If any of the above cannot be satisfied, choose the simpler path (plain branches or single branch + split later) and document why.
Recommended flows (chosen after the decision)
When gt recommended — single worktree (primary authenticated checkout)
From how-to-structure-your-stacks + create-stack + comparing-git-and-gt + official worktree support:
This is the classic sweet spot: clean functional component stacks, iterative improvement stacks, refactor-then-change, riskiness stacks, or version-bump/generated-code stacks.
In your primary human checkout (the one with real gt auth and where you normally run gt submit --stack):
# trunk-based, small atomic commits-as-branches
gt trunk
# ... make the first reviewable slice (e.g. DB/model or pure refactor)
gt add -A
gt create -m "part 1: ..."
# continue on next slice while previous is in review (asynchronous development)
gt create -am "part 2: ..."
gt create -am "part 3: ..."
# when ready for review
gt submit --stack
Key patterns:
- Use
gt create --onto <branch>when the desired parent/base is checked out in another worktree. - For feedback on a downstack PR:
gt checkout <that-branch>, make changes,gt modify -a(or-cam "msg"), thengt submit --stack(important for propagating to upstack PRs). - Exploration checkpoints:
gt createliberally, later clean up withgt fold(orgt splitto undo a fold). - When
mainmoves:gt syncthengt restack(run from the worktree that owns the relevant part of the stack). - Always inspect first:
gt log(orgt ls) — it shows the full stack visualization plus which worktree owns each branch. - After submit: use
/pr-babysitor monitor in the Graphite UI / GitHub.
gt log before big commands is non-negotiable once you have multiple worktrees in play.
gt + multiple worktrees (when you need physical isolation)
Use when you have 2+ independent stacks in flight, hate the cost of switching branches (rebuilds, dev servers, IDE, Docker), or are running parallel agents/lanes.
Rules that keep it safe and effective:
- Create worktrees via
git worktree add(or the project's scripts under git-worktrees / concurrent-cli-agents). - Run
gt logfirst beforegt sync,gt restack,gt submit --stack,gt modify, or any create that depends on another branch. This is the single most important habit. - If any part of a stack is checked out in another worktree, run the stack-wide commands from each owning worktree.
- Use
gt create --onto <branch>to extend a branch that lives in a different worktree. - Graphite will error (helpfully) rather than corrupt state when you try to touch a branch owned by another worktree.
gt undoonly affects the current worktree.
In agentic scenarios this often looks like: several agent worktrees (or full clones) each working on their own independent branch or small sub-stack, while the human's primary worktree stays on a stable base or a review lane.
Hybrid / most common agentic case (per-PR or per-lane branches → human gt in primary)
This is the dominant pattern for execute-plan, concurrent-cli-agents, and heavy subagent work in this repo.
Agents / implementers run inside isolated worktrees (local project
.worktrees/strong default per git-worktrees skill;~/.grok/worktrees/full clones only as fallback for extreme isolation/bloat cases).They follow the Subagent Worktree Protocol: implement, commit (including all review-fix rounds), push objects, record the authoritative
commit_sha.At assembly time the orchestrator (or you) in a workspace that has gt may do
gt create+ cherry-pick +gt submit --stack, but only if this workspace is the right authenticated primary one.In the far more common case (gt/auth lives in the user's everyday shell), agents simply ensure every slice branch is committed and pushed. The user then does in their primary authenticated clone:
git fetch origin # Option A (common when coupling was discovered late or you want clean review slices) git checkout -b review/plan-xxx origin/execute-plan/xxx-...-linear # or the integration branch gt track ... # if needed gt split --by-commit # or --by-file / --by-hunk for functional or risk-based splits # Option B (when you already have good per-PR branches) gt create execute-plan/xxx-pr-1-... --onto main # or the correct parent # ... repeat in stack order gt submit --stackAlways leave the individual
execute-plan/...-pr-N-...(or equivalent lane) branches pushed. They are the ultimate recoverable artifacts and work with or without gt.Print a crystal-clear handoff in every agent run.
This pattern gives you the safety of commit-in-generation-env + per-slice escape hatches while still letting you (the human) enjoy the full power of gt in the shell where it actually works.
When we declared "gt overkill"
Follow split-to-prs or git-worktrees patterns (or "work on one linear/sequential branch then split at the end"):
- Save recoverable snapshot (stash create + update-ref backup).
- For each approved slice: branch from correct base, stage only the planned files/hunks for that slice, commit, push, open PR (or print gh command).
- Or: do the whole thing on one branch (or sequential waves), push it, then in primary:
gt split --by-commitor--by-fileor--by-hunkto produce the stacked PRs after the fact. - This still gives the reviewer benefits of small PRs without forcing gt tracking during the risky generation phase or when coupling is high.
Late discovery of coupling
If you started with gt creates and now see the slices are too entangled: use gt fold to collapse, or finish on the linear branch and use gt split (by commit / file / hunk) at the end. gt split is your friend for "I did the work, now make it reviewable". In worktree setups, make sure you are in the worktree that owns the branch you are splitting.
Quick command reference (tailored)
From Graphite llms/cheatsheet + the pages you asked to read (plus worktree guardrails):
- See everything including worktree ownership:
gt log(orgt ls). Run this before any stack-wide command. - Create next in stack (single commit style):
gt create [-a] [-m "msg"] [name] - Create on a base checked out in another worktree:
gt create --onto <branch> - Submit the current stack (push + create/update PRs):
gt submit --stack(orgt ss) - Sync trunk + clean merged + prepare for restack:
gt sync - Restack the current stack onto updated parents:
gt restack(run from each worktree that owns part of the stack) - Amend staged changes into current branch (great for fixups):
gt modify -a(orgt modify -cam "msg", orgt modify --into <downstack-branch>) - Fold current branch into its parent:
gt fold(orgt f) - Split the current branch into multiple (by commit boundaries, hunks, or files):
gt split [--by-commit|-c] [--by-file|-f ...] [--by-hunk|-h] - Undo the most recent Graphite mutation in this worktree:
gt undo - Navigate the stack:
gt up/gt down/gt top/gt bottom/gt checkout <name> - Start tracking an existing (pushed) branch with Graphite:
gt track <branch> - Stop tracking:
gt untrack
Critical worktree rules (memorize):
gt logis your friend — it tells you which worktree owns each branch.- Graphite refuses to mutate a branch checked out in another worktree.
gt undois per-worktree.- For split stacks: run
gt sync/gt restackfrom every relevant worktree. - Use
--ontowhen extending across worktrees.
Integration with other skills in this repo
execute-plan: already implements dual-mode (gt vs plain-git) + the Subagent Worktree Protocol + state + resume + hygiene. Consult gt-flow at Step 0.5 / assembly time (and in the coupling diagnosis step) for honest "gt overkill?" calls and precise handoff recipes. The mental model and worktree guardrails here directly inform when execute-plan should force plain-git mode or produce strong per-PR escape hatches.git-worktrees: the low-level "where the code actually lives", scripts for create/merge/clean (local.worktrees/default + global hygiene), and disk hygiene (local preferred; global~/.grok/worktrees/as documented fallback). gt-flow provides the higher-level decision of whether and how to use gt on top of those isolated environments.split-to-prs: the primary "gt overkill or high coupling" escape hatch. Use it (or lategt split) when the coupling diagnosis fires.agent-orchestrator/ briefs +concurrent-cli-agents: surface coupling + worktree isolation needs early. Prefer disjoint file ownership per lane; document the exact gt handoff the human will run in primary.- After any agent orchestration involving branches or worktrees: run the git-worktrees cleanup scripts +
grok worktree gcfrom the primary shell.
Recovery playbook (when something goes wrong)
- Code only exists in a worktree that is about to be removed: stop. Commit it first. Push the branch. Only then remove.
- gt state / stack is confused across worktrees: run
gt logfrom each relevant worktree first. Thengt sync/gt restackfrom the worktree(s) that own the downstack branches. Graphite will tell you when a branch is checked out elsewhere. - Partial stack after crash or interrupted handoff: use the per-PR / per-lane pushed branches +
git fetch origin. Reconstruct withgt create --onto ...,gt track, or plain git +gt submit --stackin the primary authenticated shell. - Want to abandon the gt tracking but keep the commits: the underlying git branches still exist.
gt untrack(or just stop using gt on them) and open PRs directly, or usegt spliton a linear result. - Lost worktree dir but commits were pushed:
git fetch origin <branch>will bring the objects and branch back. The explicit per-slice branches (execute-plan/...style or your lane names) + backup refs are your ultimate anchors. gt undodidn't do what you expected: remember it is per-worktree. Switch to the worktree where the command was originally run.
After creating / updating this skill
- The TUI should pick it up automatically under
.agents/skills/gt-flow(skills reload on file change). - Consider adding a row to the project AGENTS.md "Project-Specific Skills" table (under X / finder-reactor / tauri-agentic / git-worktrees etc.).
- When in doubt on any stacking, PR planning, execute-plan, or concurrent agent decision involving branches or gt, prefix with "use gt-flow" or just let the description match.
This skill exists so that ambitious agentic plans (and human ones) produce reviewable, stacked, high-quality PRs without ever losing the generated code, while honestly using gt + worktrees only when the coupling, context, and guardrails say it will actually help — and falling back gracefully otherwise.