code-gt-restack-resolve
Restack the current Graphite stack with conflict resolution — downstack by default, full stack on explicit request. Auto-merge mechanically-safe conflicts (verified with project checks), escalate ambiguous ones. Use for 'restack and resolve conflicts', 'intelligent/auto restack', 'full restack', 'whole-stack restack', 'downstack restack', or a restack expected to conflict.
- License 许可
- MIT
- 所属仓库
- nseng-ai/ns
- 最近更新
- 2026-10-02
- Stars
- ★ 2
- Forks
- 0
01 前言 Front Matter
- name
- code-gt-restack-resolve
- description
- Restack the current Graphite stack with conflict resolution — downstack by default, full stack on explicit request. Auto-merge mechanically-safe conflicts (verified with project checks), escalate ambiguous ones. Use for 'restack and resolve conflicts', 'intelligent/auto restack', 'full restack', 'whole-stack restack', 'downstack restack', or a restack expected to conflict.
- disable-model-invocation
- true
02 资源文件 1
- 参考文档agents/openai.yaml43 B
03 SKILL.md 正文
code-gt-restack-resolve
Drive a Graphite restack semi-autonomously with an explicit scope: downstack (ancestors + current) by default, or full stack when the user explicitly asks for the whole stack.
This skill is a parent-session driver: the main agent session owns the
restack workflow — preflight, scope, slot consolidation, starting or resuming
the loop, interpreting subagent reports, user-facing escalation, final
validation, and gt-specific bail-outs. Each individual conflict stop is
delegated to one fresh, same-worktree subagent that follows the engine skill,
code-resolve-merge-conflicts
(skills/incubating/code/code-resolve-merge-conflicts/SKILL.md), with the Engine parameters
below. Do not restate or improvise per-file resolution policy here.
It also defers to code-graphite for the gt mental model, stack navigation,
and the "Recovering from Interrupted Rebase" section.
Harness entry points
- Pi users:
/code:gt-restack-resolveis the single command entry point. The Pi command is a thin deterministic wrapper: it checks for an interrupted rebase, runs plaingt restackwhen safe, and invokes this skill only when conflict resolution is needed. - Claude Code, Codex, and other harnesses: invoke this skill directly. Do not depend on the Pi wrapper. Follow the workflow below from the current repository state: if no rebase is in progress, start the selected restack; if a restack/rebase is already interrupted, resume from that state.
Engine parameters
The driver facts the engine consumes — continue command, extra bail-out
condition (any conflict in a branch outside the selected scope, e.g. an
upstack branch during downstack scope or a sibling/unrelated stack during any
scope), escalation channel (return-to-parent; an escalating subagent leaves
the rebase stopped, returns the engine's structured payload, and does not run
gt continue) — travel in the Agent prompt template below, which is their
single source. Model selection lives in Subagent model routing.
Parent-facing post-completion checks: git status is clean;
ns slot gt exec stack-branches --format json answers structured topology;
gt log / gt ls may be used only as visual confirmation.
<!-- TEMPORARY (TS toolchain rollout) — remove once the oxlint/oxfmt/native-tsc toolchain commits have fully landed and no longer sit unrebased under active stacks. -->
TEMPORARY: TS toolchain-rollout conflicts
While the TypeScript toolchain rollout (pnpm 11 / oxlint / oxfmt / native-tsc) is still propagating through stacks, restacks hit a recurring conflict shape: a formatting-only oxfmt reflow of the old code replays onto a base that gained real feature logic on the same statements. The operative resolution rule lives in the TEMPORARY block of the Agent prompt template below and travels verbatim in every conflict subagent's prompt; it is the only auto-resolution the driver may apply without escalating.
Scope and non-goals
- Scope must be explicit. Default to downstack for generic restack requests; use full only when the user explicitly asks for the whole stack or confirms a prompt.
- A single-PR (or tip) stack has no scope decision — see the single-PR rule in Choose scope.
- Full scope: operate on the current Graphite stack as
gt restackdoes (ancestors + current + descendants) — not every stack in the repo. It may rewrite upstack descendants, which is why it requires explicit intent. - Downstack scope: operate on the chain trunk → current (ancestors + current). Upstack is not touched.
- Never
gt submit/ push / land. - Never touch sibling stacks. Upstack descendants are in scope only for a full restack.
- Never
gt abortwithout explicit confirmation (engine abort policy).
Workflow
0. Verify inherited interruption context
The Pi wrapper may invoke this skill with one of two authoritative context
statements: structured full-scope preflight already reported
rebaseInProgress=true, or full-scope preflight passed and the wrapper then ran
gt restack without completing cleanly. Treat either statement as inherited
evidence that must be refreshed, not as permission to assume repository state.
Before normal preflight, run git status as the code-graphite skill's interrupted
rebase context reset requires. Skip preflight only when that fresh status
confirms a rebase is still in progress (including a rebase stopped at unmerged
conflicts). In that confirmed wrapper path:
- set
RESTACK_SCOPE=full, because the wrapper always requests full semantics; - do not run
ns slot gt exec restack-preflightagain; - do not start another
gt restack; - jump directly to the Loop and continue from the observed state.
If fresh status does not confirm an interrupted rebase, the wrapper context is
stale or the failed command did not stop a rebase. Fall back to Preflight and
scope facts. Never start another gt restack solely because the handoff says
the fast path failed; only the normal preflight and scope workflow may authorize
a new start.
Direct skill invocations without either wrapper context always begin with normal preflight. User prose that merely speculates about a conflict is not wrapper context and does not bypass preflight.
1. Preflight and scope facts
Unless step 0 confirmed a wrapper-originated interrupted rebase, first map the
request to REQUESTED_SCOPE: generic or ambiguous restack intent is
downstack; explicit whole-stack intent is full. Gather all cleanliness,
tracking, interrupted-rebase, topology, and Slot occupancy facts in one call:
ns slot gt exec restack-preflight --scope <full|downstack> --format json
Always replace the placeholder explicitly: generic requests pass
--scope downstack; explicit whole-stack requests pass --scope full. Pass
the scope even when it matches the command's own default.
Interpret the Clinkr envelope before acting:
status: "ok"carries usable preflightdata, including the expected resume staterebaseInProgress: true: an in-progress rebase in the current worktree is an ok/exit-0 answer, not a blocked result, even though the tree is dirty and the rebase appears inslotConflicts.- A nonzero
status: "negative"is an expected blocked/precondition result (untracked branch, dirty tree without a current rebase, foreign Slot conflicts, on-trunk) and still carries usabledata; inspect it rather than treating the exit code alone as a command failure. status: "failure", missing/unparseable JSON, or malformed/missing required fields is not usable preflight evidence. Stop and report the envelope/error; do not restack or free slots.
The stable data fields are:
clean: whether the current worktree has no uncommitted changes;tracked: whether the current branch is present in Graphite metadata;rebaseInProgress: whether the current worktree is already in a rebase;hasUpstackChildren: whether full scope differs from downstack scope;requestedScopeandeffectiveScope: the explicit request and the scope the helper could inspect (fullcollapses todownstackat a tip);branches: all in-scope branches, bottom-to-top, including current;slotConflicts: in-scope occupancy/rebase conflicts; each entry identifies its branch and type and gives the conflicting path inworktreePath(plus operation/Slot details when applicable);warnings: non-fatal topology/metadata warnings to surface and account for.
If rebaseInProgress is true, do not start a new restack or free stack
slots. Jump straight to the Loop at the resolve step, following the
code-graphite skill's "Recovering from Interrupted Rebase (Context Reset)"
section. Otherwise, if tracked is false, stop with the helper's gt track
guidance. If clean is false, stop and ask the user to commit or stash first.
Review all warnings before continuing.
2. Choose scope
Set RESTACK_SCOPE from the explicit request and the returned scope facts before
running any restack command.
| User intent | Scope | Slot consolidation command | Restack command |
|---|---|---|---|
| Generic "restack and resolve", "restack", "intelligent/auto restack", or ambiguous request | downstack (default) |
ns slot gt free-stack --downstack |
gt restack --downstack |
| Explicit "full restack", "whole-stack restack", "restack everything", or confirmed prompt | full |
ns slot gt free-stack |
gt restack |
Rules:
- Single-PR / tip stacks: never ask about scope. When
hasUpstackChildrenis false, full and downstack are the same operation: skip the scope question entirely and run plaingt restack(no--downstackneeded — the result is identical). There are no upstack slots to free either, so skip the consolidation prompt too unlessslotConflictsreports an in-scope ancestor in another worktree. - When in doubt, ask — but only when scope actually changes the outcome (i.e., the current branch has upstack descendants).
- Do not auto-checkout to the tip. Run the command from the user's current branch unless they explicitly ask to move first.
3. Multi-slot consolidation
In this repo a stack's branches can be checked out across multiple worktree slots, which locks them against rebasing. A restack can fail when another slot has a branch in the selected scope checked out, so run the slot consolidation command from the Choose scope table before looping.
Use slotConflicts from preflight to identify the worktree path and branch that
must be released. In the single-PR / tip case, skip this step per the single-PR
rule in Choose scope, unless an in-scope ancestor conflict is reported.
The ns slot gt free-stack command is mutating: it releases matching slots by
detaching them at trunk — --format json is a machine-readable record of what
was freed, not a dry-run. If the user has not already authorized freeing stack
slots, ask before running it.
4. Loop
If no rebase is currently in progress, start the restack with the command chosen in Choose scope. If a rebase is already interrupted, skip the start command and continue from the current conflict state.
After starting or resuming, run git status in the parent session to identify
the current state. In the happy path, the count invariant is: one conflict
stop = one engine run = one gt continue = one subagent. Escalation adds a
parent user round-trip and a follow-up subagent for that same stop.
While the restack is stopped at conflicts:
- Launch exactly one fresh, same-worktree subagent for the current conflict
stop using the Agent prompt template below and the Subagent model
routing policy below. Do not launch conflict subagents in parallel; the
current
gt continuedetermines whether another conflict stop exists. - Await that subagent completely before launching any other subagent.
- Inspect the subagent's final text/status, then re-run
git statusin the parent session. Do not blindly trust the final text. - Do not propagate an unverified behavior diagnosis or pre-existing failure
claim as fact. If a subagent reports
behavior_evidence: unverifiedorpreexisting_failure_evidence: unverified, either independently verify the claim before using it as context/whitelist, or preserve theunverifiedlabel when asking the user, launching the next subagent, or summarizing. Unverified claims cannot become failure whitelists. - Branch on the observed outcome:
- advanced:
gt continuesucceeded but the restack stopped again on a later conflict. Loop and launch a new subagent for that next stop. - completed: the restack completed. Proceed to Done.
- escalation: ask the user in the parent conversation using the returned
payload. Then launch a fresh follow-up subagent for the same stop, seeded
with the user's decision, to apply the resolution, stage files, run
gt continue, and report back. Re-rungit statusagain afterward. - bail: stop and summarize what was resolved, what remains, and the exact command/state stopped at.
- advanced:
If git status shows no rebase in progress and no conflicts after the initial
restack command returns successfully, proceed directly to Done.
Subagent model routing
Conflict-resolution subagents edit code in an interrupted rebase and decide whether a merge is mechanically safe. They are implementation subagents, not bounded classification or review helpers, so do not route them to the cheap/fast model tier.
When the harness supports per-dispatch model selection, request the model below for these restack conflict subagents. Concrete examples:
- Claude Code: launch the
Agentconflict-resolution subagent on Opus (use the Claude Codeopusselector available in the current installation). - OpenAI Codex-backed Pi: call
subagentwithagent: "task"and setmodeltoopenai-codex/gpt-5.6-sol:high(or the local equivalent Sol model pattern). - Anthropic-backed Pi: call
subagentwithagent: "task"and setmodelto the currentclaude-opusmodel (or the local equivalent Opus model pattern).
If per-dispatch model selection is unavailable, continue with the session's current model but mention that no explicit smart model could be requested.
Agent prompt template
Use this structure for each sequential conflict-resolution subagent. Fill in
RESTACK_SCOPE from Choose scope and include any user decision when this is
a follow-up subagent after escalation.
You are resolving one conflict stop for a Graphite restack that is already in
progress in this same worktree.
Orchestrator-decided facts:
- RESTACK_SCOPE: <full|downstack>
- Continue command: gt continue
- Extra bail-out condition: any conflict in a branch outside RESTACK_SCOPE
- Escalation channel: return-to-parent
Follow skills/incubating/code/code-resolve-merge-conflicts/SKILL.md as the conflict-resolution
engine with those driver parameters.
TEMPORARY (TS toolchain rollout): if a conflict is purely a formatting-only
oxfmt/toolchain reflow of the OLD code shape replaying onto a base that gained
real feature logic on the same statements, resolve it deterministically by
KEEPING the base (HEAD) logic verbatim, discarding the reverted incoming code,
then re-applying formatting by running `just ts-format-fix` (not by
hand-wrapping). This is the only "keep + reformat" auto-resolution allowed; any
conflict where the incoming side carries genuine logic still escalates.
Agent-decided work:
- Inspect git status and identify the current stopped commit and conflicted
files.
- Classify conflict regions using only the engine's safe categories.
- Edit only conflict regions, except generated files as allowed by the engine.
- Run the engine verification gate and conflict-marker sweep.
- Stage resolved files.
- Run gt continue if and only if verification passes and no escalation or
bail-out condition blocks it.
- After gt continue, inspect git status only enough to classify the outcome.
Hard constraints:
- Do not prompt the user.
- Do not abort the rebase/restack.
- Do not resolve conflicts outside the current conflict stop.
- Run gt continue at most once. This is an audit boundary: if that continue
reaches a new conflict stop, do not resolve it; return outcome=advanced with
the new repository state.
- Do not use whole-file checkout except for generated files as allowed by the
engine.
Output contract: end with this delimited result block, filling every line for
all outcomes:
--- CONFLICT SUBAGENT RESULT ---
outcome: advanced | completed | escalation | bail
files_resolved: <paths or none>
safe_categories_used: <categories or none>
verification: <commands and pass/fail results>
gt_continue_ran: yes | no
traceability_check: <base|incoming|intent-diff|mechanical-propagation|mixed; note "no novel logic" or describe any novel logic>
behavior_evidence: <not_applicable | observed: <command + concise output> | unverified: <reason>>
preexisting_failure_evidence: <not_applicable | observed: <base_sha + command + concise output> | unverified: <reason>>
summary: <concise summary>
For outcome=escalation, also include:
affected_file: <path>
both_sides: <concise conflict-region summary or quoted snippets>
intent_diff_summary: <what the incoming commit intended>
proposed_resolution: <proposal and reasoning>
why_outside_safe_set: <reason>
current_repository_state: <git status summary>
--- END CONFLICT SUBAGENT RESULT ---
5. Done
When the selected restack command reports there is nothing left to restack:
- Run a final
git status(clean) andns slot gt exec stack-branches --format jsonfor structured topology confirmation.gt log/gt lsmay be shown as human visual confirmation only. - Regenerate any auto-generated files that were touched (per
code-resolve-merge-conflictsstep 7) and stage/commit them as appropriate. - For a full-scope restack, the final-verification rule is binary: if any
conflict was resolved anywhere in the restack, run a final scoped
verification from the stack tip after the restack completes; if the whole
restack replayed conflict-free, skip it. This covers upstack branches that
replayed without conflicts but now sit atop resolved code. Use the engine's
step-4 check rule
(
code-resolve-merge-conflicts, "Verify before continuing"), scoped by the file types conflicted across the whole restack.
6. Bail-out
The engine's bail-out policy applies, plus this driver's extra condition from Engine parameters (a conflict outside the selected scope). Summarize per the engine: what was resolved, what remains, and the exact command/state you stopped at.
04 同仓库更多 Skills
pr-make-accountable
Interview a PR author to establish shared understanding of intent and design decisions, then co-author the What / Why / Changes PR body with opt-in Requested reviewer focus.
typescript-style
Opinionated style guide for strict, portable TypeScript. Use when writing, designing, or reviewing TypeScript: type design, boundary validation, error handling, module architecture, and review discipline.
typescript-fake-driven-testing
TypeScript fake-driven testing architecture. Use when writing or reviewing TS code with external dependencies, gateway interfaces, real adapters, in-memory fakes, or CLI scenario tests.
ns-typescript
TypeScript overlay for ns-style projects. Use when editing or reviewing TS in this repo: tsconfig baseline, pnpm/Vitest/oxlint/oxfmt/native tsc commands, relative .ts imports, workspace subpath exports, and the exactOptionalPropertyTypes spread idiom. Repo-specific enforcement (test lanes, time seams, style guard) lives in the host repo's AGENTS.md.
ns-typescript-style-tripwire
Invoke the ns TypeScript style Tripwire against a supplied diff or current branch.
skill-management
Manage skills with `npx skills`: add, edit, remove, rename, update, or list skills (local or GitHub), and the nested `skills/<disposition>/.../<name>/` / flat `.agents/skills/` layout conventions.