Linear issue → shipped feature
Take a Linear issue all the way to PR open, CI green, review comments addressed, and
Linear updated. There is exactly one explicit checkpoint — plan approval — and
even that is conditional: routine changes run straight through.
The phases below gather the Linear context and prepare git. The actual work — grilling
you on the open design decisions, exploring, planning, reviewing, implementing,
gating, shipping — lives in the shared build loop.
Read references/build-loop.md now. It is the body of this skill, not optional
background. This file supplies the Linear bindings it asks for.
Philosophy (hold these throughout)
- A ticket is a pointer, not a specification. Requirements get negotiated in comments as
often as they are written in the description. Read those first, then grill the user on what is
still open — a wrong assumption costs one question here and an implementation at Step F.
- Never invent a requirement. An issue that fails to fetch, a description that is empty, an
attachment nobody attached — name it and ask. An issue key is not a specification either.
- The repository is the system of record. A Linear status, a label, a blocker marked done —
none of those are evidence. Confirm a dependency against
git log and the code.
- No architecture is assumed. Read what this repo actually does and follow it. Never plan
against a pattern it does not use, and never propose adopting one; that is a separate
conversation, not a side effect of a ticket.
- Evidence beats claims. You run the gates yourself and paste their real output — a subagent
reporting "tests pass" is a claim, the gate's own output is evidence. Same for CI: a run that
never registered is not a green run, and an absent CI is not a green CI.
- One checkpoint, and it has to be earned. Step E stops the run only when the change's shape
demands it. Stopping on a routine fix teaches the user to skim your plans; not stopping on a
schema migration is how you lose them.
- Autonomy ends at the PR. Push it, open it, babysit it to green — never merge, never enable
auto-complete, never deploy.
- A silent run is a run nobody trusts. Say which step you are on, what you just changed, and
what you are waiting for — in plain sentences the person who wrote the ticket can follow, not in
raw tool output. See § Say what you are doing in
references/build-loop.md.
- A finished subissue is marked finished. Each child that is implemented, gated and pushed
moves to the team's completed state as it closes. The parent is what waits on the PR.
- Keep the tracker footprint minimal. Status and comments on the issue you are building, and
nothing else in Linear, ever.
Autonomy contract
- Act and self-verify by default. No option menus, no "should I proceed?" on green.
- Linear writes on this issue are pre-authorized — the status and comments of
TICKET and of any subissue you actively work. Never ask permission for those, and
never write anything else in Linear.
- This skill pushes branches and opens pull requests without asking. It never
merges a PR, never enables auto-complete, and never deploys.
- Escalate only for the cases listed in
references/build-loop.md § Escalation.
Otherwise keep going.
Arguments
Parse $ARGUMENTS:
- Issue identifier — a Linear key like
ABC-123, or a
linear.app/<workspace>/issue/ABC-123/<slug> URL (extract the key). If absent, list
the caller's assigned, unstarted-or-in-progress issues with list_issues and ask
which one via AskUserQuestion.
skip-checkpoint — or freeform "skip the plan checkpoint" / "run straight to
PR". The user's opt-in for routine issues: force the Step E skip. Honor it only when
explicitly given, and never over a user who asked to see a plan.
There is no brief-file or inline-description path. This skill starts from a Linear
issue; if you don't have one, ask for one.
Phase 0 — Resolve the bindings and check the tooling
Two things have to hold before Phase 1. Both are cheap to check here and expensive to
discover later.
0a. The Linear binding
The Linear MCP server is registered under different names in different setups, so the
tool prefix varies: mcp__linear__* in some sessions, mcp__linear-server__* in
others. Determine which prefix this session actually exposes and use it consistently.
If neither is available, stop and say so — point the user at the Linear MCP server
setup. Never infer an issue's content from its key.
Everything below names operations bare (get_issue, save_issue); prepend the prefix
you resolved.
0b. The GitHub path — prerequisites
Steps H and I push a branch, open the PR and read CI through gh. Check it now: an
unauthenticated gh discovered at Step H costs a full implementation before it
surfaces. Report what is missing and install nothing yourself.
| Tool |
Check |
macOS |
Windows |
Linux |
gh CLI |
gh --version |
brew install gh |
winget install GitHub.cli |
the distro's gh package, or cli.github.com |
gh authentication |
gh auth status |
gh auth login |
gh auth login |
gh auth login |
a GitHub origin |
git remote get-url origin |
— |
— |
— |
If gh is missing or unauthenticated, say so and ask whether to continue anyway:
everything through Step G still runs, and the work would stop at the push with the
branch intact. If origin is not a GitHub remote, name the host and stop — this
skill's OPEN-PR and CI bindings are GitHub-only, and ado-plan-build is the
sibling for Azure Repos.
Phase 1 — Gather Linear context
Run these in parallel:
get_issue for the key — include relations (parent, blocking, related). Note the
team ID and project ID.
list_issues with parentId = the issue ID — the subissues.
list_comments — prior discussion and decisions. Requirements are frequently
negotiated in comments rather than written in the description; read them before
concluding anything is unspecified.
get_project, if the issue belongs to one — goals and scope.
list_cycles for the team with type: "current" — what else is in flight.
Resolve the team's real workflow states with list_issue_statuses before any status
write. "In Progress", "In Review" and "Done" are conventions, not guarantees — teams
rename and reorder them. Resolve three states by type, not by name: the
started one for in-progress, the team's review state (typically the last started
or unstarted state before completion) for in-review, and the completed one that
subissues land in when they close. Say which state you picked for each. If nothing
plausibly matches, pick the closest by type, name it, and continue — a status write is
never worth blocking the work.
Phase 2 — Prepare the git environment
- Default branch:
git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@'.
git fetch origin.
- If the working tree is dirty, stop and report. Do not stash, do not discard.
git checkout <default-branch> && git pull --ff-only origin <default-branch>.
- Create the feature branch. Prefer the
branchName Linear itself suggests on the
issue; otherwise feature/<ISSUE-KEY>-<short-slug>. The branch name must
contain the Linear key. If you are already on that branch with prior work on it,
stay on it and continue rather than recreating it.
Phase 3 — Present the issue summary
Print a concise summary: title, status, priority, assignee, project, current cycle,
branch name, subissues (key / title / status), blocking and related issues, and the
decisions buried in the comments.
Print the subissues even when there is only one — that list is what Step A asks the
user to choose from, and it is the work list for the rest of the run.
Linear status is not authoritative. Flag every blocker that isn't done, and before
treating a dependency as met, confirm it against git log and the code rather than
against a green label.
Phase 4 — Run the build loop
Follow references/build-loop.md, Steps A → J, with these bindings.
| Binding |
Linear / GitHub |
TICKET |
the Linear issue — the parent |
SUB-TICKETS |
its subissues — list_issues with parentId to list, save_comment / save_issue against the child's id |
STATUS→IN-PROGRESS |
save_issue with the team's started-type state (Phase 1) |
STATUS→IN-REVIEW |
save_issue with the team's review state (Phase 1) — used on the parent, which waits on the PR |
STATUS→DONE |
save_issue with the team's completed-type state (Phase 1) — used on a subissue once it is implemented, gated and pushed |
COMMENT |
save_comment on the issue |
BRANCH |
the Phase 2 branch |
LINK-TOKEN |
the issue key (ABC-123) — this is what Linear's GitHub integration matches on. Each Step F.6 commit carries the sub-issue's own key; the PR title carries the parent's. With no subissues the work list is TICKET itself, so its key is the one in every commit as well |
OPEN-PR |
gh pr create --title "<key>: <title>" --body "<body>" |
CI |
gh pr checks <pr> --watch to wait; gh run view <run-id> --log-failed for logs; gh run rerun <run-id> --failed to retry a flaky job |
PR-COMMENTS |
gh pr view <pr> --comments for the conversation; gh api repos/{owner}/{repo}/pulls/{n}/comments for inline threads; reply with gh pr comment or the API |
gh pr checks --watch blocks until the checks settle, which is the right way to wait —
it beats polling. If the repo has no CI configured at all, say so and skip straight to
the review-comment half of Step I; an absent CI is not a green CI.
Notes
- What this skill is pre-approved to do. Read and write files in the repo, run the
repo's own build/test commands, write to this Linear issue, push its branch, and
open a PR. It will not merge, deploy, or touch anything else in Linear. If that is
more autonomy than you want on a given ticket, run it without
skip-checkpoint and
stop it at the Step E checkpoint.
- The plan file. Step C writes
.claude/plans/<TICKET>.md and keeps it current
while the work runs — a working notebook, never staged and never committed on the
skill's initiative. Step J asks what to do with it.
- Keep secrets out of the shell and the commit. Don't stage
.env files, keys, or
tokens, and don't echo secret values into commands, commit messages, or PR bodies.
- Deleting the plan file is the one step that asks.
allowed-tools is static and
<TICKET> is not, so no grant can say "this ticket's plan and no other" — a
Bash(rm .claude/plans/*) would authorise deleting every other ticket's plan too. The
grant is therefore absent on purpose: Step J's "Delete it" runs
rm .claude/plans/<TICKET>.md, exactly that path, and costs one permission prompt.
One prompt for the only destructive step in the run, right after the user chose it, is
the correct trade.
- The Bash allowlist is narrowed to the subcommands this run actually uses, so a
package publish, an arbitrary GitHub API mutation or an unrelated tool prompts instead
of running silently.
gh api is scoped to the inline-review-comment path — the one
place the skill needs it. Two grants stay wide on purpose and are worth knowing about:
git add/git push and npx. A glob cannot express "not -A" or "not --force",
and the gate a repo defines may legitimately be npx <anything>; the controls there
are the textual rules in references/build-loop.md (stage only what the item touched,
never git add -A, never force-push, never merge). A team that wants a hard boundary
rather than an instruction should add permissions.deny rules in settings.json —
deny wins over any allowlist, including this one.
- Gate commands. The mainstream runners (
make, npm/pnpm/yarn, pytest,
go, cargo, dotnet, mvn/gradle, bundle, composer) are pre-approved. If
your repo's gate isn't among them, run it and approve the prompt — never skip or
fake a gate to avoid a permission dialog.
References
| Reference |
Used by |
What it covers |
build-loop.md |
Phase 4 |
The body of the skill: Steps A → J — grilling the user, exploring, drafting the plan, the three-lens adversarial review, the conditional approval checkpoint, test-first implementation, the repo's gates, commit/push/PR, the CI-and-review-comments watch loop, and the complete Escalation list |
Troubleshooting
| Symptom |
Almost always |
Confirm with |
Neither mcp__linear__* nor mcp__linear-server__* is exposed |
The Linear MCP server is not registered, or the workspace is not trusted so a project-scoped server never loaded |
/mcp. A pending-approval server behaves exactly like an absent one |
gh fails to authenticate at Step H, after the whole build |
Phase 0b was skipped |
gh auth status before Phase 1 — that is what 0b is for. Recover with gh auth login and resume from Step H; the branch and commits survive |
gh pr checks --watch returns instantly with no checks |
Either the repo has no CI, or the first run has not registered yet on a just-pushed branch |
gh run list --branch <branch>. If there genuinely is no CI, say so and skip to the review-comment half of Step I — an absent CI is not a green CI, and Step J must name it as a skipped gate |
| The status write lands in the wrong column |
The state was matched by name. Teams rename and reorder states, so "In Progress" is a convention, not a guarantee |
list_issue_statuses and match by state type (started, the team's review state, completed). Name the state you picked |
| Subissues sit in progress after their work shipped |
Step F.6.4 was skipped, or the completed state was never resolved in Phase 1 |
Each child closes into STATUS→DONE as Step F.6 finishes it; only the parent stays in review, waiting on the PR |
| Linear never links the commit or the PR to the issue |
A key is missing, or the wrong one is used. Branch and PR title carry the PARENT key; each Step F.6 commit carries its own sub-issue's key — one key in all three is impossible once a run covers several sub-issues, and a commit under the parent key leaves the child with nothing attached |
Branch name and PR title: parent key. Each commit: the key of the sub-issue it closes. Linear's GitHub integration matches on whichever key it finds |
| Phase 2 stops on a dirty working tree |
By design. Stashing someone's uncommitted work is not this skill's call |
git status. Commit or stash it yourself, then re-run |
| Two subagents overwrite each other's edits in Step F |
Steps that converge on the same file were dispatched in parallel |
Step F.2: converging steps stay serial in one agent. Parallelize the thinking (subagents return diffs, you apply them), not the writes |
EnterPlanMode errors, or the plan is presented twice |
The session was already in plan mode |
Step E: when already in plan mode, go straight to ExitPlanMode |
| The same gate fails three times in a row |
Not a reason to keep iterating — classify it: test, code, environment, or plan drift |
Step F.5, and § Escalation in build-loop.md. An ambiguous failure is an escalation, never a guess |
1---2name: linear-plan-build3description: Take a Linear issue from "read it" to "PR open, CI green, review comments addressed, Linear updated" with maximum autonomy. Reads the issue, its subissues and its discussion; grills you on the design decisions the ticket left open; explores the repo; drafts a plan and puts it through a three-lens adversarial review; asks for your approval through plan mode when the change warrants it and skips it when it doesn't; then implements test-first, runs your repo's gates, opens the PR, and babysits it to green. Stack-agnostic — assumes no particular architecture. Invoke with `/arkandia:linear-plan-build [ABC-123 | issue URL] [skip-checkpoint]`.4---56# Linear issue → shipped feature78Take a Linear issue all the way to **PR open, CI green, review comments addressed, and9Linear updated**. There is exactly **one** explicit checkpoint — plan approval — and10even that is conditional: routine changes run straight through.1112The phases below gather the Linear context and prepare git. The actual work — grilling13you on the open design decisions, exploring, planning, reviewing, implementing,14gating, shipping — lives in the shared build loop.1516**Read `references/build-loop.md` now.** It is the body of this skill, not optional17background. This file supplies the Linear bindings it asks for.1819## Philosophy (hold these throughout)2021- **A ticket is a pointer, not a specification.** Requirements get negotiated in comments as22 often as they are written in the description. Read those first, then grill the user on what is23 still open — a wrong assumption costs one question here and an implementation at Step F.24- **Never invent a requirement.** An issue that fails to fetch, a description that is empty, an25 attachment nobody attached — name it and ask. An issue key is not a specification either.26- **The repository is the system of record.** A Linear status, a label, a blocker marked done —27 none of those are evidence. Confirm a dependency against `git log` and the code.28- **No architecture is assumed.** Read what this repo actually does and follow it. Never plan29 against a pattern it does not use, and never propose adopting one; that is a separate30 conversation, not a side effect of a ticket.31- **Evidence beats claims.** You run the gates yourself and paste their real output — a subagent32 reporting "tests pass" is a claim, the gate's own output is evidence. Same for CI: a run that33 never registered is not a green run, and an absent CI is not a green CI.34- **One checkpoint, and it has to be earned.** Step E stops the run only when the change's shape35 demands it. Stopping on a routine fix teaches the user to skim your plans; not stopping on a36 schema migration is how you lose them.37- **Autonomy ends at the PR.** Push it, open it, babysit it to green — never merge, never enable38 auto-complete, never deploy.39- **A silent run is a run nobody trusts.** Say which step you are on, what you just changed, and40 what you are waiting for — in plain sentences the person who wrote the ticket can follow, not in41 raw tool output. See § *Say what you are doing* in `references/build-loop.md`.42- **A finished subissue is marked finished.** Each child that is implemented, gated and pushed43 moves to the team's completed state as it closes. The **parent** is what waits on the PR.44- **Keep the tracker footprint minimal.** Status and comments on the issue you are building, and45 nothing else in Linear, ever.4647## Autonomy contract4849- **Act and self-verify by default.** No option menus, no "should I proceed?" on green.50- **Linear writes on this issue are pre-authorized** — the status and comments of51 `TICKET` and of any subissue you actively work. Never ask permission for those, and52 never write anything else in Linear.53- **This skill pushes branches and opens pull requests without asking.** It never54 merges a PR, never enables auto-complete, and never deploys.55- **Escalate only** for the cases listed in `references/build-loop.md` § Escalation.56 Otherwise keep going.5758## Arguments5960Parse `$ARGUMENTS`:6162- **Issue identifier** — a Linear key like `ABC-123`, or a63 `linear.app/<workspace>/issue/ABC-123/<slug>` URL (extract the key). If absent, list64 the caller's assigned, unstarted-or-in-progress issues with `list_issues` and ask65 which one via `AskUserQuestion`.66- **`skip-checkpoint`** — or freeform "skip the plan checkpoint" / "run straight to67 PR". The user's opt-in for routine issues: force the Step E skip. Honor it only when68 explicitly given, and never over a user who asked to see a plan.6970There is no brief-file or inline-description path. This skill starts from a Linear71issue; if you don't have one, ask for one.7273## Phase 0 — Resolve the bindings and check the tooling7475Two things have to hold before Phase 1. Both are cheap to check here and expensive to76discover later.7778### 0a. The Linear binding7980The Linear MCP server is registered under different names in different setups, so the81tool prefix varies: `mcp__linear__*` in some sessions, `mcp__linear-server__*` in82others. Determine which prefix this session actually exposes and use it consistently.83If **neither** is available, stop and say so — point the user at the Linear MCP server84setup. Never infer an issue's content from its key.8586Everything below names operations bare (`get_issue`, `save_issue`); prepend the prefix87you resolved.8889### 0b. The GitHub path — prerequisites9091Steps H and I push a branch, open the PR and read CI through `gh`. Check it **now**: an92unauthenticated `gh` discovered at Step H costs a full implementation before it93surfaces. Report what is missing and **install nothing yourself**.9495| Tool | Check | macOS | Windows | Linux |96|---|---|---|---|---|97| `gh` CLI | `gh --version` | `brew install gh` | `winget install GitHub.cli` | the distro's `gh` package, or `cli.github.com` |98| `gh` authentication | `gh auth status` | `gh auth login` | `gh auth login` | `gh auth login` |99| a GitHub `origin` | `git remote get-url origin` | — | — | — |100101If `gh` is missing or unauthenticated, say so and ask whether to continue anyway:102everything through Step G still runs, and the work would stop at the push with the103branch intact. If `origin` is not a GitHub remote, name the host and stop — this104skill's `OPEN-PR` and `CI` bindings are GitHub-only, and `ado-plan-build` is the105sibling for Azure Repos.106107## Phase 1 — Gather Linear context108109Run these in parallel:1101111. `get_issue` for the key — include relations (parent, blocking, related). Note the112 team ID and project ID.1132. `list_issues` with `parentId` = the issue ID — the subissues.1143. `list_comments` — prior discussion and decisions. **Requirements are frequently115 negotiated in comments rather than written in the description**; read them before116 concluding anything is unspecified.1174. `get_project`, if the issue belongs to one — goals and scope.1185. `list_cycles` for the team with `type: "current"` — what else is in flight.119120**Resolve the team's real workflow states with `list_issue_statuses` before any status121write.** "In Progress", "In Review" and "Done" are conventions, not guarantees — teams122rename and reorder them. Resolve **three** states by *type*, not by name: the123`started` one for in-progress, the team's review state (typically the last `started`124or `unstarted` state before completion) for in-review, and the `completed` one that125subissues land in when they close. Say which state you picked for each. If nothing126plausibly matches, pick the closest by type, name it, and continue — a status write is127never worth blocking the work.128129## Phase 2 — Prepare the git environment1301311. Default branch: `git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@'`.1322. `git fetch origin`.1333. **If the working tree is dirty, stop and report.** Do not stash, do not discard.1344. `git checkout <default-branch> && git pull --ff-only origin <default-branch>`.1355. Create the feature branch. Prefer the `branchName` Linear itself suggests on the136 issue; otherwise `feature/<ISSUE-KEY>-<short-slug>`. The branch name **must**137 contain the Linear key. If you are already on that branch with prior work on it,138 stay on it and continue rather than recreating it.139140## Phase 3 — Present the issue summary141142Print a concise summary: title, status, priority, assignee, project, current cycle,143branch name, subissues (key / title / status), blocking and related issues, and the144decisions buried in the comments.145146**Print the subissues even when there is only one** — that list is what Step A asks the147user to choose from, and it is the work list for the rest of the run.148149**Linear status is not authoritative.** Flag every blocker that isn't done, and before150treating a dependency as met, confirm it against `git log` and the code rather than151against a green label.152153## Phase 4 — Run the build loop154155Follow `references/build-loop.md`, Steps A → J, with these bindings.156157| Binding | Linear / GitHub |158|---|---|159| `TICKET` | the Linear issue — the parent |160| `SUB-TICKETS` | its subissues — `list_issues` with `parentId` to list, `save_comment` / `save_issue` against the child's id |161| `STATUS→IN-PROGRESS` | `save_issue` with the team's `started`-type state (Phase 1) |162| `STATUS→IN-REVIEW` | `save_issue` with the team's review state (Phase 1) — used on the **parent**, which waits on the PR |163| `STATUS→DONE` | `save_issue` with the team's `completed`-type state (Phase 1) — used on a **subissue** once it is implemented, gated and pushed |164| `COMMENT` | `save_comment` on the issue |165| `BRANCH` | the Phase 2 branch |166| `LINK-TOKEN` | the issue key (`ABC-123`) — this is what Linear's GitHub integration matches on. Each Step F.6 commit carries **the sub-issue's own key**; the PR title carries the parent's. **With no subissues the work list is `TICKET` itself, so its key is the one in every commit as well** |167| `OPEN-PR` | `gh pr create --title "<key>: <title>" --body "<body>"` |168| `CI` | `gh pr checks <pr> --watch` to wait; `gh run view <run-id> --log-failed` for logs; `gh run rerun <run-id> --failed` to retry a flaky job |169| `PR-COMMENTS` | `gh pr view <pr> --comments` for the conversation; `gh api repos/{owner}/{repo}/pulls/{n}/comments` for inline threads; reply with `gh pr comment` or the API |170171`gh pr checks --watch` blocks until the checks settle, which is the right way to wait —172it beats polling. If the repo has no CI configured at all, say so and skip straight to173the review-comment half of Step I; an absent CI is not a green CI.174175## Notes176177- **What this skill is pre-approved to do.** Read and write files in the repo, run the178 repo's own build/test commands, write to this Linear issue, push its branch, and179 open a PR. It will not merge, deploy, or touch anything else in Linear. If that is180 more autonomy than you want on a given ticket, run it without `skip-checkpoint` and181 stop it at the Step E checkpoint.182- **The plan file.** Step C writes `.claude/plans/<TICKET>.md` and keeps it current183 while the work runs — a working notebook, never staged and never committed on the184 skill's initiative. Step J asks what to do with it.185- **Keep secrets out of the shell and the commit.** Don't stage `.env` files, keys, or186 tokens, and don't echo secret values into commands, commit messages, or PR bodies.187- **Deleting the plan file is the one step that asks.** `allowed-tools` is static and188 `<TICKET>` is not, so no grant can say "this ticket's plan and no other" — a189 `Bash(rm .claude/plans/*)` would authorise deleting every other ticket's plan too. The190 grant is therefore absent on purpose: Step J's "Delete it" runs191 `rm .claude/plans/<TICKET>.md`, exactly that path, and costs one permission prompt.192 One prompt for the only destructive step in the run, right after the user chose it, is193 the correct trade.194- **The Bash allowlist is narrowed to the subcommands this run actually uses**, so a195 package publish, an arbitrary GitHub API mutation or an unrelated tool prompts instead196 of running silently. `gh api` is scoped to the inline-review-comment path — the one197 place the skill needs it. Two grants stay wide on purpose and are worth knowing about:198 `git add`/`git push` and `npx`. A glob cannot express "not `-A`" or "not `--force`",199 and the gate a repo defines may legitimately be `npx <anything>`; the controls there200 are the textual rules in `references/build-loop.md` (stage only what the item touched,201 never `git add -A`, never force-push, never merge). A team that wants a hard boundary202 rather than an instruction should add `permissions.deny` rules in `settings.json` —203 deny wins over any allowlist, including this one.204- **Gate commands.** The mainstream runners (`make`, `npm`/`pnpm`/`yarn`, `pytest`,205 `go`, `cargo`, `dotnet`, `mvn`/`gradle`, `bundle`, `composer`) are pre-approved. If206 your repo's gate isn't among them, run it and approve the prompt — never skip or207 fake a gate to avoid a permission dialog.208209## References210211| Reference | Used by | What it covers |212|---|---|---|213| `build-loop.md` | Phase 4 | The body of the skill: Steps A → J — grilling the user, exploring, drafting the plan, the three-lens adversarial review, the conditional approval checkpoint, test-first implementation, the repo's gates, commit/push/PR, the CI-and-review-comments watch loop, and the complete Escalation list |214215## Troubleshooting216217| Symptom | Almost always | Confirm with |218|---|---|---|219| Neither `mcp__linear__*` nor `mcp__linear-server__*` is exposed | The Linear MCP server is not registered, or the workspace is not trusted so a project-scoped server never loaded | `/mcp`. A pending-approval server behaves exactly like an absent one |220| `gh` fails to authenticate at Step H, after the whole build | Phase 0b was skipped | `gh auth status` before Phase 1 — that is what 0b is for. Recover with `gh auth login` and resume from Step H; the branch and commits survive |221| `gh pr checks --watch` returns instantly with no checks | Either the repo has no CI, or the first run has not registered yet on a just-pushed branch | `gh run list --branch <branch>`. If there genuinely is no CI, say so and skip to the review-comment half of Step I — an absent CI is **not** a green CI, and Step J must name it as a skipped gate |222| The status write lands in the wrong column | The state was matched by name. Teams rename and reorder states, so "In Progress" is a convention, not a guarantee | `list_issue_statuses` and match by state *type* (`started`, the team's review state, `completed`). Name the state you picked |223| Subissues sit in progress after their work shipped | Step F.6.4 was skipped, or the `completed` state was never resolved in Phase 1 | Each child closes into `STATUS→DONE` as Step F.6 finishes it; only the parent stays in review, waiting on the PR |224| Linear never links the commit or the PR to the issue | A key is missing, or the wrong one is used. **Branch and PR title carry the PARENT key; each Step F.6 commit carries its own sub-issue's key** — one key in all three is impossible once a run covers several sub-issues, and a commit under the parent key leaves the child with nothing attached | Branch name and PR title: parent key. Each commit: the key of the sub-issue it closes. Linear's GitHub integration matches on whichever key it finds |225| Phase 2 stops on a dirty working tree | By design. Stashing someone's uncommitted work is not this skill's call | `git status`. Commit or stash it yourself, then re-run |226| Two subagents overwrite each other's edits in Step F | Steps that converge on the same file were dispatched in parallel | Step F.2: converging steps stay **serial** in one agent. Parallelize the thinking (subagents return diffs, you apply them), not the writes |227| `EnterPlanMode` errors, or the plan is presented twice | The session was already in plan mode | Step E: when already in plan mode, go straight to `ExitPlanMode` |228| The same gate fails three times in a row | Not a reason to keep iterating — classify it: test, code, environment, or plan drift | Step F.5, and § Escalation in `build-loop.md`. An ambiguous failure is an escalation, never a guess |