[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6JK3R0K4JJV8NF3D9X4DVE2":3,"skill-same:01M6JK3R0K4JJV8NF3D9X4DVE2":95},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":40,"linkOnly":41,"markdownContent":42,"markdownBody":43,"frontMatter":44,"refName":28,"commitSha":60,"skillDirectory":61,"forksCount":62,"repositoryHtmlUrl":63,"repositoryHomepageUrl":6,"ownerHtmlUrl":64,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":65,"install":66,"resources":78},"01M6JK3R0K4JJV8NF3D9X4DVE2","box-it-up",null,"Box the pie and hand it across the counter - per slice, commit + push only (no PR, CI stays quiet); at the pie boundary, open one PR, watch CI once (auto-fix on red), merge on approval preserving every slice commit, sync main, delete the branch, remove the pie worktree. Opt-in merge-per-slice mode (--merge-slice, run internally by the conductor) opens, CI-checks and merges one PR per slice with a merge commit instead. Opt-in ship-once delivery (set by \u002Fpizza-party) uses --pie-local at each pie boundary (full local check, local --no-ff merge into the ship branch, no PR) and --ship once after the last pie (one PR ship branch to main, CI once, merge on green).","steve-piece\u002Fbytheslice","steve-piece","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F190656564?v=4","01M6JK3M1VYSHFKN1PW540DV5H","Steven Light","01M6JK3MDHEWS5WHC4H0RNKTD9",0,"MIT","https:\u002F\u002Fgithub.com\u002Fsteve-piece\u002Fbytheslice\u002Fblob\u002Fmain\u002Fskills\u002Fbox-it-up\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39],"box it up","box","it","up","auto-fix","across","hand","commit","auto","main","only","open","local","ci","fix","mode","remove","submit","green","branch","SET","2026-11-10 10:12:30",false,"---\nname: box-it-up\ndescription: \"Box the pie and hand it across the counter - per slice, commit + push only (no PR, CI stays quiet); at the pie boundary, open one PR, watch CI once (auto-fix on red), merge on approval preserving every slice commit, sync main, delete the branch, remove the pie worktree. Opt-in merge-per-slice mode (--merge-slice, run internally by the conductor) opens, CI-checks and merges one PR per slice with a merge commit instead. Opt-in ship-once delivery (set by \u002Fpizza-party) uses --pie-local at each pie boundary (full local check, local --no-ff merge into the ship branch, no PR) and --ship once after the last pie (one PR ship branch to main, CI once, merge on green).\"\nuser-invocable: true\ntriggers: [\"\u002Fbytheslice:box-it-up\", \"\u002Fbox-it-up\", \"box up the pie\", \"box up the slice\", \"hand it over\", \"close out the pie\", \"\u002Fbytheslice:ship-pr\", \"\u002Fship-pr\", \"ship the pr\", \"submit the pr\", \"open and merge the pr\", \"ship this branch\", \"ship this pie\"]\n---\n\u003C!-- skills\u002Fbox-it-up\u002FSKILL.md -->\n\u003C!-- Standalone closeout skill, re-scoped pie-level for v5 (spec §1.10). Pizza-shop framing: the pie cooled slice by slice - box it and hand it over. TWO call shapes: (1) per-slice, invoked repeatedly by \u002Fsell-pie's loop after each slice → commit + push only, no PR opened so CI does not fire; (2) pie-completion, invoked once when every slice in the active Pie is [x] → open one PR \"Pie N\", CI runs once, HITL review, merge PRESERVING per-slice commits (rebase\u002Fmerge-commit, never squash), sync main --ff-only, delete branch, remove the pie worktree. Universal closeout safety preserved: a hand-rolled branch with no checklist still ships through the pie-completion path (no pie-status flip, project-default merge strategy). Decoupled from \u002Fsell-pie and \u002Fsell-slice so the operator can review \u002F UAT before the boundary PR. Ship-once delivery adds --pie-local (local check + local --no-ff merge of the pie into the ship branch) and --ship (the one ship PR to main, merged on green with no human gate). -->\n\n# \u002Fbox-it-up\n\nIn v5 a **Pie** (a coherent chapter, usually 3 to 8 slices; a small app's pie may hold 1 or 2) is the unit of PR, CI, and review. `\u002Fbox-it-up` carries both halves of the pie's git lifecycle:\n\n- **Per slice** - `\u002Fsell-pie`'s loop calls `\u002Fbox-it-up --slice` after each slice clears its gates. The skill commits the slice on the pie branch and pushes. **No PR is opened, so CI does not fire** - per-slice pushes stay cheap.\n- **At the pie boundary** - when every slice in the active Pie is `[x]`, `\u002Fbox-it-up` opens **one** PR `Pie N: \u003Cname>`, lets CI run **once**, gets your merge approval, merges **preserving every per-slice commit** (rebase or merge-commit, never squash), syncs `main` fast-forward-only, deletes the branch, and **removes the pie worktree**.\n- **Merge per slice (opt-in)** - when `delivery.mode` resolves to `merge-per-slice` (an explicit autonomous-delivery run instruction, or the config), the conductor runs `\u002Fbox-it-up --merge-slice` internally after each slice: one PR `Slice N.M: \u003Cname>`, CI, up to 3 fix rounds, merge on green with a merge commit, cleanup from the primary checkout. No per-slice merge approval; the operator gets one notice when the pie finishes. The two bullets above describe the default (`pie-pr`) mode.\n- **Ship once (opt-in)** - when `delivery.mode` resolves to `ship-once` (`\u002Fpizza-party` sets it), per-slice commits stay local (no push). At each pie boundary the conductor runs `\u002Fbox-it-up --pie-local`: confirm every slice was verified, re-run the full local check once, merge the pie branch into the long-lived local ship branch with `git merge --no-ff`, remove the pie worktree and branch. After the last pie, `\u002Fbox-it-up --ship` pushes the ship branch, opens **one** PR to `main`, watches CI once and merges on green with a merge commit. Neither step has a human merge gate: choosing ship-once authorized it.\n\nIt is intentionally a **separate** skill so you can review the whole pie locally, run a manual visual UAT, or rebase against fresh main before deciding to ship the boundary PR. The closeout path is **universal** - safe to run on a hand-rolled branch that never touched the ByTheSlice delivery loop. Pre-flight checks and the merge\u002Fcleanup pattern do not assume a checklist or a pie.\n\n---\n\n## Mode detection\n\n`\u002Fbox-it-up` is **always standalone** and operates on whatever feature branch is currently checked out (in `slice-merge` mode, the slice branch in the slice worktree the conductor names). It resolves one of six modes before doing anything:\n\n| Mode | How it's detected | What it does |\n|------|-------------------|--------------|\n| **per-slice** | Invoked with `--slice` (how `\u002Fsell-pie`'s loop calls it), or the operator explicitly asks to \"box up the slice\" mid-pie. | **Phase 1 only** - commit the slice on the pie branch + push. **No PR, no CI watch, no merge, no cleanup.** Returns immediately so the loop continues to the next slice. |\n| **pie-completion** | Default. A master checklist exists, the current branch matches a `pie-\u003Cn>-\u003Cscope>` row, and **every** `### Slice N.M` under that `## Pie N` is `[x]`. Also the shape `\u002Fsell-pie` hands off at the boundary. | **Full closeout** - Phases 0 → 6: open one PR `Pie N`, CI once, HITL merge gate, merge preserving slice commits, sync main, delete branch, remove worktree, flip the pie's checklist status. |\n| **universal** (hand-rolled) | No master checklist, or the branch doesn't map to a pie row (a feedback round, a fix on a delivered slice). | **Same closeout as pie-completion** (Phases 0 → 6) minus the pie-status flip, and merge strategy falls back to the project default. The universal-closeout safety net - never assumes ByTheSlice ran. |\n| **slice-merge** (merge per slice) | Invoked with `--merge-slice` by the `\u002Fsell-pie` or `\u002Fsell-slice` conductor when `delivery.mode` resolves to `merge-per-slice` and the pie is not `review: continuous`. Always an **internal** invocation: the conductor sits on `main` between slices by design and follows this skill's phases itself rather than typing the command, so the on-`main` precondition question below does not apply to it. | **One slice, one PR** - see \"Merge-per-slice closeout\" below: PR `Slice N.M: \u003Cname>`, CI, up to 3 `ci-fix-attempter` rounds, merge on green with a merge commit (no human merge gate), cleanup from the primary checkout. |\n| **pie-local** (ship-once boundary) | Invoked with `--pie-local` by the `\u002Fsell-pie` conductor at the pie boundary when `delivery.mode` resolves to `ship-once`. Internal, like `--merge-slice`. | **No PR, no push, no CI** - see \"Pie-local closeout\" below: verified-slice check, the full local check once (up to 3 `fix-attempter` rounds), `git merge --no-ff` of the pie branch into the ship branch in the primary checkout, worktree and branch removal. |\n| **ship** (ship-once finish) | Invoked with `--ship` after the last pie of a ship-once build: by `\u002Fsell-pie` in an interactive run, or by the `\u002Fpizza-party` conductor in an unattended one. Runs from the primary checkout on the ship branch. | **One ship PR** - see \"Ship closeout\" below: push the ship branch, PR `Ship \u003Capp>: \u003Cpies> pies, \u003Cslices> slices` with every pie's evidence, CI once, up to 3 `ci-fix-attempter` rounds, merge on green with a merge commit (no human gate), sync `main`, delete the ship branch. |\n\n**Refusal guards:**\n- In **per-slice** mode, if the active Pie still has unfinished slices the skill must NOT try to open a PR - that is correct, expected mid-pie behavior, not an error.\n- In **pie-completion** mode, if the master checklist shows the active Pie still has unchecked slices (`### Slice N.M` is `[ ]`), STOP and surface as `needs_human: true` with `hitl_category: prd_ambiguity`: *\"Pie N still has unfinished slices - finish them via \u002Fsell-pie before boxing the pie, or confirm you want to ship a partial pie.\"* Never silently ship an incomplete pie. In **pie-local** mode the same guard applies, except that an unattended run (`run.unattended: true`) treats a slice whose status reads `deferred: \u003Creason>` as finished for this merge (its commits already left the pie branch), and a slice `waiting until \u003CYYYY-MM-DD>` as finished too (its commits passed `slice-verifier` and merge with the pie; the row stays `[ ]`), and lists both in `blocked`. A slice whose `**Status:**` reads `waiting until \u003CYYYY-MM-DD>: \u003Ccriterion>` is unfinished too: refuse with *\"Pie N is waiting on Slice N.M until \u003CYYYY-MM-DD> (\u003Ccriterion>). Re-run \u002Fsell-pie on or after that date; the boundary PR opens once it closes.\"* No HITL is needed for a waiting slice, since the date is the only blocker; set `status: needs_human` only if the operator asked to ship anyway.\n\nIf a master checklist exists and the branch maps to a pie row, `\u002Fbox-it-up` flips that **Pie's** status from `In Progress` to `Completed` and commits the flip **on the pie branch before the PR opens** (Phase 1 step 4), so the status reaches `main` with the merge and never as an uncommitted edit on `main`. That is the only sequential-flavored behavior - best-effort enhancement, never a precondition.\n\n## Subagent Roster\n\n| Phase | Agent file | Model | Effort | Mode |\n|-------|-----------|-------|--------|------|\n| 3 (on CI fail, pie-completion \u002F slice-merge \u002F ship) | [agents\u002Fci-fix-attempter.md](agents\u002Fci-fix-attempter.md) | sonnet | high | write |\n| pie-local check (on red, pie-local only) | [..\u002Fsell-slice\u002Fagents\u002Ffix-attempter.md](..\u002Fsell-slice\u002Fagents\u002Ffix-attempter.md) | sonnet | high | write |\n\nCI watching itself is inline (`gh pr checks \u003Cpr> --watch` blocks until checks settle). No separate watcher subagent. **Per-slice mode dispatches no subagents** - there is no PR and therefore no CI to fix.\n\n---\n\n## Inputs and Preconditions\n\n> This skill checks its own preconditions inline at the start, via tools (current branch, `gh auth status` when the mode needs PR work). If one fails, raise the problem to the operator as a question with a recommended next step, never a refusal. On `main` \u002F `master`, say so and ask how to proceed (usually: switch to the pie branch or its worktree); the merge-per-slice closeout (`--merge-slice`) runs from `main` by design, so this check is skipped there. Never narrate passing checks in chat. No ByTheSlice hook blocks a prompt.\n\n- Working tree on a feature branch (not `main` \u002F `master`) - for a v5 pie this is `pie-\u003Cn>-\u003Cscope>`.\n- **Per-slice mode:** the slice's changes are committed locally OR present as uncommitted changes the skill should commit. `gh` is **not** required (no PR work).\n- **Pie-completion \u002F universal mode:** `gh` CLI installed and authenticated (`gh auth status` returns \"Logged in\"); the repository has a remote (`git remote -v` returns at least `origin`).\n- One **worktree per pie** (default mode) - created upstream by `\u002Fsell-pie` when the pie branch is cut, removed here at the boundary. In `slice-merge` mode it is one worktree per slice, created by the conductor and removed here after that slice merges. `\u002Fbox-it-up` never *creates* a worktree; it only removes one.\n- **Slice-merge mode:** `gh` authenticated, and the repo allows merge commits (`gh repo view --json mergeCommitAllowed`).\n- **Pie-local mode:** the primary checkout is clean and on the ship branch; the pie worktree is clean. `gh` is **not** required (no PR work), and nothing is pushed.\n- **Ship mode:** the primary checkout is clean and on the ship branch; `gh` authenticated (the only ship-once step that needs it); an `origin` remote; the repo allows merge commits.\n\n---\n\n## Workflow\n\nAt every phase boundary, if the `bts_status` tool is available call it instead of re-reading the checklist; if it is not, read the checklist as before.\n\n> **Per-slice mode runs Phase 1 only, then returns.** Phases 0 and 2-6 are pie-completion \u002F universal closeout. `slice-merge` mode runs Phases 0 → 6 with the overrides in \"Merge-per-slice closeout\" below. The phase numbering is shared so the commit logic is defined once.\n\n### Phase 0 - Pre-flight Safety Checks *(pie-completion \u002F universal)*\n\nThe skill refuses to proceed past Phase 0 if any check fails. The point is to avoid a destructive accident on `main` or an accidental push to a stale branch.\n\n1. `git rev-parse --abbrev-ref HEAD` - capture current branch as `BRANCH`.\n2. **If `BRANCH` is `main` or `master`, STOP.** Surface as `needs_human: true` with `hitl_category: destructive_operation` and message: *\"Refusing to ship from main. Switch to a pie \u002F feature branch first.\"* Do not push, do not commit.\n3. `git worktree list` - capture worktree state as `WORKTREE_PATH` (the path matching the current working directory) and `IS_WORKTREE` (`true` if cwd is not the main worktree). For a v5 pie this is the pie worktree slated for removal in Phase 5.\n4. `gh pr list --state merged --limit 1 --base main --json headRefName,number,mergedAt` - capture the most recently merged PR. If `BRANCH` matches its `headRefName` (an already-shipped pie branch reused without renaming), STOP and surface as `needs_human: true` with `hitl_category: destructive_operation`. Ask whether to rename or proceed.\n5. `gh pr list --state open --head \"$BRANCH\" --json number,url --jq '.[0]'` - check whether an open PR for this branch already exists. If yes, capture its number and URL as `EXISTING_PR_NUMBER` \u002F `EXISTING_PR_URL`. The skill reuses it (watch CI on the existing PR) rather than create a duplicate. Because per-slice pushes never open a PR, the first boundary run normally finds none.\n6. `gh auth status` - confirm gh is authenticated. If not, surface as `external_credentials` HITL and stop.\n7. **Pie-completeness check (pie-completion mode only):** confirm every `### Slice N.M` under the active `## Pie N` in `docs\u002Fplans\u002F00_master_checklist.md` is `[x]`. If any is `[ ]`, STOP per the Mode-detection refusal guard (`prd_ambiguity`, or the waiting-slice refusal when its status reads `waiting until \u003Cdate>`).\n\n### Phase 1 - Commit + Push *(both modes; the per-slice entry point)*\n\n1. `git status --short` - if there are uncommitted changes, handle them per the **batched-approvals** rule: when a conductor invoked this skill (`--slice`, `--merge-slice`, or the `\u002Fsell-pie` boundary handoff) and every changed path came from agents' `files_changed` or the checklist, commit without asking (the conductor already owns those paths). Ask only when something is unexpected, and then put this question in **one batch** with every other approval already known at this point (for example a squash-only repo from the Phase 4 strategy check, run early), one decision per question, each with a recommended answer. The Phase 4 merge gate needs CI's result, so it is its own later batch. The commit question:\n   - \"Stage and commit these changes? (yes \u002F let me write the message \u002F cancel)\"\n   - **Always provide a recommended answer in the available options.** Default recommendation: yes if the diff looks like the in-scope slice; \"let me write\" if it includes unexpected files.\n   - On `yes`: stage selectively, never `git add -A` or `git add .`. Stage only the paths the conductor recorded from agents' `files_changed` and the checklist; anything else is an unexpected file, so recommend \"let me write\" and list it. Then derive the commit message **by mode**:\n     - **Per-slice mode** - the slice's task commits (`feat(pie-N): N.M task K \u003Ctask name>`) are already pushed. This is the slice's **final commit**, using the v5 slice commit convention: **`feat(pie-N): N.M \u003Cslice name>`** (swap `feat` for `fix`\u002F`chore`\u002F`docs` when the diff is purely a fix \u002F infra-config \u002F docs). One-line subject; short body listing touched files grouped by package\u002Fapp. **If the slice touched UI** and `\u002Fsell-slice`\u002F`\u002Fsell-pie` produced a closing-narrative paragraph (one paragraph: what was built · why this shape · what was left out · what reviewers should pay attention to), include it verbatim in the commit body before the file list. These task and slice commit messages are what the boundary PR preserves - they become the PR's commit-by-commit story, so keep each one self-describing. When nothing is left to stage (the checklist is gitignored, as it is by default, and no fix patch or state file is pending), make the final commit with `git commit --allow-empty`: its subject is the slice's record in the history, and Phase 4 merges a branch holding an empty commit with a merge commit so it survives. After the push, `git status --short` must be empty: the slice may not leave an untracked or modified file it created.\n     - **Pie-completion \u002F universal mode** - only reached here when the boundary run finds straggler uncommitted changes (most slices are already committed by the per-slice runs). Derive a conventional type from the diff (`feat:`\u002F`fix:`\u002F`chore:`\u002F`docs:`) with a one-line subject and a file-list body.\n   - On `let me write`: prompt for the message.\n   - On `cancel`: stop here. Working tree unchanged.\n2. `git push origin \"$BRANCH\"` - push to the pie branch. If the remote rejects (non-fast-forward, etc.), STOP and surface as `destructive_operation` HITL - never auto force-push. **Ship-once:** skip the push; the pie branch stays local until `--pie-local` merges it into the ship branch, and only `--ship` pushes anything.\n3. **Per-slice mode ends here.** Return the per-slice contract (`status: complete`, the commit SHA + branch). **Do not open a PR, do not watch CI, do not merge.** The `\u002Fsell-pie` loop advances to the next slice; CI fires only at the pie boundary.\n4. **Flip the Pie's checklist status (pie-completion mode only), before the PR opens.** In `docs\u002Fplans\u002F00_master_checklist.md`, set the active `## Pie N` status from `In Progress` to `Completed`, commit it on the pie branch as `chore(pie-N): mark Pie N completed`, and push. The flip rides into `main` with the merge, so `main` never carries an uncommitted checklist edit (the pre-commit guard blocks commits on `main`, and Phase 5 requires a clean tree). If the operator holds or cancels the PR, the flip stays on the unmerged branch only. When the checklist is gitignored (`git check-ignore -q docs\u002Fplans\u002F00_master_checklist.md`, the default), flip the primary checkout's copy (`$PLANS\u002F00_master_checklist.md`, per [`git-worktree-standard.md`, \"Where the plans live\"](..\u002Fcook-pizzas\u002Freferences\u002Fgit-worktree-standard.md); a worktree has no copy) and make no commit. Skip silently in universal mode (no checklist \u002F no pie row).\n5. **Reconcile the checklist before any PR opens (every mode that opens one: pie-completion, universal, slice-merge and ship).** Before Phase 2 runs `gh pr create`, read `docs\u002Fplans\u002F00_master_checklist.md` (the primary checkout's `$PLANS` copy when it is gitignored) against the branch diff, `git diff --name-only origin\u002Fmain...HEAD`. Every slice the branch delivers or changes, including a feedback round, a review follow-up or a CI fix made outside `\u002Fsell-slice` and `\u002Fsell-pie`, gets its `**Status:**` line set to what the branch leaves it at (`Completed`, `In Progress`, or `Partial: \u003Cwhat is owed>`), and its pie heading reads `Completed` once every slice in it does. Commit that on the branch as `docs(pie-N): update the checklist for \u003Cscope>` and push; with gitignored plans, edit the primary checkout's copy and commit nothing. In universal mode a project that has a master checklist is no exception: map the changed files to slices through the slice plans that name them. A branch that touches no slice leaves the checklist alone. Use only the status words the parsers read (Completed, In Progress, Not Started, Partial, `waiting until \u003Cdate>: \u003Ccriterion>`); the checklist edit hook reports any line they cannot read. If this step is skipped, the `gh pr create` hook (`hooks\u002Fchecklist-check.sh pr`) adds a warning; it never blocks.\n\n### Phase 2 - Open the Pie PR (or Reuse Existing) *(pie-completion \u002F universal)*\n\n1. **If `EXISTING_PR_NUMBER` from Phase 0 is set**, skip to Phase 3 - the existing PR already tracks this branch.\n2. **Otherwise**, open one PR for the whole pie:\n   - **Title:** for a pie, `Pie N: \u003Cname>` (lift `N` and the name from the `## Pie N - \u003Cname>` checklist header). For a hand-rolled branch, fall back to `gh pr create --fill` (latest commit subject).\n   - `gh pr create --base main --head \"$BRANCH\" --fill` - the `--fill` body lifts the accumulated slice commit subjects\u002Fbodies, so the per-slice closing-narrative paragraphs carry the design story into the PR description without a separate step. For a named pie, set the title explicitly (`--title \"Pie N: \u003Cname>\"`) and keep `--fill` for the body.\n   - **Evidence section (the Pass ledger):** when `bts_pr_body` is available, write its output into the PR body under `## Evidence` after the `--fill` content; the section is generated, do not edit it by hand. Call it once with `{ \"pie\": N }` before `gh pr create`. A `--body` or `--body-file` overwrites what `--fill` would write, so build the body file yourself: the `--fill` content (`git log --reverse --format='%s%n%n%b' origin\u002Fmain..HEAD`), then a blank line and `## Evidence`, then the tool's output verbatim; pass it with `--body-file` and keep `--title`. When the tool is absent, or answers its one-line `bts_pr_body:` message (no ledger, no `node`), open the PR with `--fill` alone and leave the section out. It warns and never blocks: a missing section is not a reason to stop.\n   - Capture the returned URL as `PR_URL` and the number as `PR_NUMBER`.\n3. Output the PR URL to the user immediately so they can open it in a browser if they want to skim the pie.\n4. **No failing gate rides in the body as an open item.** Every enabled gate passed before the pie reached this phase ([`quality-gates.md`](..\u002Fsell-slice\u002Freferences\u002Fquality-gates.md)), so the body never lists one as a follow-up, \"for your decision\" or out of scope. Advisory-class findings (`gates.advisory`) may be listed, labeled advisory.\n\n### Phase 3 - Watch CI *(pie-completion \u002F universal - CI's single run for the pie)*\n\nIn the default `pie-pr` mode this is the **one** time CI fires for the entire pie - per-slice pushes opened no PR. In `slice-merge` mode it is the slice PR's CI run. `gh pr checks \"$PR_NUMBER\" --watch` blocks until every check finishes. Capture the exit code:\n\n- **Exit 0** → all checks passed. Continue to Phase 4.\n- **Non-zero** → at least one check failed. Capture the output (`gh pr checks \"$PR_NUMBER\" --json name,state,bucket,workflow`) and the required set (`gh pr checks \"$PR_NUMBER\" --required --json name`), then **classify each failed check.** It is *advisory* when its gate class is in `gates.advisory` ([`quality-gates.md`](..\u002Fsell-slice\u002Freferences\u002Fquality-gates.md); the class comes from the job name: `lint`, `typecheck`, `build`, unit or integration tests are `tests`, any e2e job `e2e`, `visual` `visual`, `design-system-compliance` `design-system`, an accessibility job `accessibility`, anything else `ci`) **and** it is not a required check. Every other failure is binding, and a failed required check is always binding, whatever `gates.advisory` says.\n  - Any binding failure → Phase 3a, the auto-fix loop, with the binding failures only.\n  - Only advisory failures left → CI counts as green: continue to Phase 4, listing each advisory failure by name, labeled advisory, in the merge prompt and the PR body. Never fix one.\n\nThe skill caps total CI watch time at **30 minutes per attempt**. If `--watch` does not return within 30 minutes (e.g. self-hosted runner hung), surface as `external_credentials` HITL.\n\n#### Phase 3a - CI Fix Loop (on red)\n\nLoop counter starts at 1. Cap at **3 attempts**.\n\n**Every red check is a binding gate.** Dispatch the fix without asking the operator first, and never offer \"merge anyway\", \"fix in a follow-up\" or \"the cause is outside this pie\" as an answer: `ci-fix-attempter` fixes the root cause where it lives, a shared design token or a file the pie only consumes included. A non-required check in a class listed in `gates.advisory` is the one exception (Phase 3 classified it): report it, labeled advisory, and do not fix it; it never enters this loop or counts against its cap. The operator hears about a red required check only at the cap-exhaustion HITL below, or when its fix is destructive or needs a secret.\n\n1. Capture the failed-check rollup: `gh pr checks \"$PR_NUMBER\" --json name,state,link,workflow`, keeping the binding failures only (Phase 3's classification; re-run it after each round).\n2. For each failed check, retrieve logs:\n   - `gh run view \u003Crun-id> --log-failed` for workflow runs, OR\n   - `gh pr view \"$PR_NUMBER\" --comments` for non-Actions checks (e.g. external services posting back).\n3. Dispatch `bytheslice:ci-fix-attempter` ([definition](agents\u002Fci-fix-attempter.md); fallback on hosts without plugin agents: Read the file and dispatch it per [`loop-workflow-fallback-pattern.md`](..\u002Fcook-pizzas\u002Freferences\u002Floop-workflow-fallback-pattern.md) \"Agent shape on the fallback path\": its frontmatter goes first as a header (model tier and effort, the normalized tool allowlist, the read-only line for an agent without write tools, the no-git-writes line), then its body, then the inputs; log one self-check line per dispatch in the run log). Pass:\n   - `PR_NUMBER`, `PR_URL`, `BRANCH`\n   - The failed-check rollup\n   - Truncated log excerpts (last 200 lines per failed job) - let the agent ask for more on demand\n   - The pie diff (`git diff origin\u002Fmain...HEAD`)\n   - The attempt number\n   - `previous_signature`: the `signature` the previous round returned, or `null` on attempt 1\n4. The agent makes no git writes: it returns `files_changed` and a proposed commit subject and body. **This skill** stages exactly those paths (`git add -- \u003Cpaths>`), commits with the proposed message, and pushes to `origin \"$BRANCH\"` (never forced; a rejected push is a `destructive_operation` HITL). Do not call `--watch` from inside the dispatch - the skill returns to Phase 3 (top) after its push lands and re-invokes `gh pr checks --watch` against the new head SHA.\n   When a round's fix changes what a slice delivers, update that slice's `**Status:**` line in the same commit (Phase 1 step 5). If the agent returns `bail_reason: repeated_signature`, it patched nothing because the identical failure survived the last round: stop the loop now, commit and push nothing, and surface the `creative_direction` HITL below. The bail counts as that round and never extends the 3.\n5. Increment the counter. If it would exceed 3, STOP. Surface as `creative_direction` HITL with the full failure history, naming each check still failing, so the user can decide whether to grant more rounds, debug manually, retry CI, or close the PR. This cap-exhaustion HITL is the only place a failing gate is put to the user.\n\nThe 3-attempt cap is a hard rule and is **not overridable by the run instruction**: \"continue until CI is green\", \"never stop\", \"fully automated\" or an autonomous-delivery instruction do not add rounds. Only the operator's explicit reply at this HITL can grant more. The CI counter is per PR and separate from the conductor's 3 local fix loops per slice; neither borrows from the other. One identical repeat already signals a structural problem (flaky test, missing secret, infra outage) that needs human judgment, so the loop stops at the first repeated signature (`normalize(first_error_line) + \" | \" + file + \" | \" + job_name`, a plain string compared by equality and never persisted) instead of counting to three.\n\n### Phase 4 - Merge Authorization Gate *(pie-completion \u002F universal - the kept pie-boundary HITL)*\n\nCI is green, or only advisory, non-required checks are red (Phase 3). **Stop and prompt the user** (this is the §1.8 pie-boundary checkpoint - in the default `pie-pr` mode, the one HITL the loop never auto-approves; `slice-merge` mode has no per-slice merge gate, see \"Merge-per-slice closeout\"):\n\n> \"CI is green on PR `\u003CPR_URL>` (Pie N)\u003C; advisory checks red, not fixed: \u003Cnames>, when any>. Approve merge?\"\n>\n> Options (always include a recommended answer):\n> 1. **Approve and merge now** (recommended if you've already reviewed the pie) - the skill merges **preserving every per-slice commit** (see strategy below) and proceeds to Phase 5.\n> 2. **Hold - keep the PR open for manual review** - the skill exits, leaving the PR open. You merge via the GitHub UI when ready (with the strategy the helper picked: \"Create a merge commit\" when the pie holds empty commits), then re-run `\u002Fbox-it-up --resume` to do cleanup.\n> 3. **Cancel - leave the PR open and stop** - the skill exits without merging.\n\n**Merge strategy - preserve per-slice commits (never squash).** The whole point of the per-slice commits is that they survive the merge as the pie's history. These rules - merge preserving per-slice commits (never squash), `--ff-only` sync, `git worktree remove`\u002F`prune` cleanup, and the boundary-PR body shape - come from [`..\u002Fcook-pizzas\u002Freferences\u002Fgit-worktree-standard.md`](..\u002Fcook-pizzas\u002Freferences\u002Fgit-worktree-standard.md) (Phase 3 + Invariants §5 + the PR template §6). Resolve the strategy with the helper, from the pie branch: `gh repo view --json rebaseMergeAllowed,mergeCommitAllowed,squashMergeAllowed | node \"\u003Cthis-skill-directory>\u002Fpick-merge-strategy.js\" --base origin\u002Fmain` (after `git fetch origin`), and capture the branch's commit subjects for Phase 5 with `SUBJECTS=$(git log --format=%s origin\u002Fmain..HEAD)`. The helper prints one JSON line, `{ strategy, reason, emptyCommits }`, by these rules (with `--mode slice-merge` or `--mode ship` it skips them and always answers a merge commit, `reason: merge-commit-required`, or `strategy: none`, `reason: merge-commits-disallowed`):\n\n1. **Empty commits force a merge commit.** GitHub's rebase-merge drops a commit whose tree equals its parent's, so a slice-close commit made with `--allow-empty` would vanish from `main`. When the branch holds one (`reason: empty-commits`), use a **merge commit** (`gh pr merge \"$PR_NUMBER\" --merge`). If merge commits are disallowed (`strategy: none`, `reason: empty-commits-need-merge-commit`), STOP and surface `prd_ambiguity`: *\"This pie has N empty slice-close commits that a rebase-merge would drop. Enable merge commits, or confirm you accept losing them.\"*\n2. **Otherwise prefer rebase-merge** for a pie PR (`gh pr merge \"$PR_NUMBER\" --rebase`; a slice PR in `slice-merge` mode always uses a merge commit instead) - replays each slice commit onto main, linear history, every `feat(pie-N): N.M` preserved.\n3. If rebase is disallowed (`reason: rebase-disallowed`), use a **merge commit** (`gh pr merge \"$PR_NUMBER\" --merge`) - also preserves the individual commits under a merge node.\n4. **Never `--squash`** for a pie - squashing collapses the per-slice commits into one and destroys the boundary contract. If a project's settings allow *only* squash (the helper's `reason: squash-only`), STOP and surface as `needs_human: true` with `hitl_category: prd_ambiguity`: *\"This repo only permits squash merges, which would collapse the pie's per-slice commits. Enable rebase or merge-commit merges, or confirm you accept a squash for this pie.\"* For a **hand-rolled** branch with no per-slice contract, the project default (including squash) is acceptable - the preserve-commits rule binds pies, not arbitrary branches.\n\nNever force-merge a PR with non-required failing checks unless the user explicitly authorizes via the HITL prompt.\n\n### Phase 5 - Post-merge Cleanup *(pie-completion \u002F universal)*\n\nOnly runs after the PR is merged (by this skill in Phase 4 option 1, or by the user manually before `\u002Fbox-it-up --resume`).\n\n1. `gh pr view \"$PR_NUMBER\" --json state,number,mergedAt` - confirm state is `MERGED`. If not, STOP. Don't pull or delete branches on a falsely-assumed merge.\n   - **Pie-completion mode only, before cleanup:** record the confirmed merge for the local kitchen. Pipe a fresh successful `gh pr view \"$PR_NUMBER\" --json state,number,mergedAt` response to `node \"\u003Cthis-skill-directory>\u002Frecord-kitchen-merge.js\" --mode pie --pie \"\u003Cactive-pie-number>\" --project \"${CLAUDE_PROJECT_DIR:-$PWD}\"`. The helper validates `MERGED`, a PR number and a merge timestamp, then atomically replaces the single bounded `.claude\u002F.bytheslice-state\u002Fkitchen\u002Fmerged-pie.json` record with only version, pie, PR number and merge time. Use this skill's installed absolute directory for the helper path. If the read or write fails, report missing kitchen evidence; do not invent success.\n   - **Slice-merge mode:** run the same writer exactly once per pie, after the pie's **last** slice PR merges, piping that PR's `gh pr view` response with `--mode pie --pie \"\u003Cactive-pie-number>\"`. Never per slice.\n   - Never run this writer in `--slice` or universal mode, for any slice-merge slice but the pie's last, before merge confirmation, or from skill\u002FStop log events. A skill finish cannot prove a PR merged. The kitchen reader makes no network calls and ignores malformed, stale, future or wrong-pie records.\n**Every step after the merge check runs from the primary checkout, never from the pie worktree.** `main` is checked out in the primary checkout, so `git checkout main` inside the pie worktree fails, and git refuses to delete a branch a worktree still holds. Resolve the primary checkout once: `PRIMARY=$(git worktree list --porcelain | sed -n '1s\u002F^worktree \u002F\u002Fp')` (the first entry is always the main working tree). The Pie's checklist flip is already committed on the branch (Phase 1 step 4), so nothing here edits a tracked file.\n\n2. `cd \"$PRIMARY\"` so the shell is not inside the worktree about to be removed. If `IS_WORKTREE` was false (the branch was checked out in the primary checkout itself), run `git -C \"$PRIMARY\" checkout main`; if that would overwrite uncommitted changes, STOP and surface as `destructive_operation` HITL. Then confirm `git -C \"$PRIMARY\" rev-parse --abbrev-ref HEAD` is `main` and `git -C \"$PRIMARY\" status --short` is empty. If the primary checkout sits on another branch or is dirty, STOP (`destructive_operation`): never switch, stash or overwrite a checkout the operator may be using.\n3. `git -C \"$PRIMARY\" pull --ff-only origin main` - fast-forward only. If this fails (history diverged), STOP and surface as `destructive_operation` HITL.\n4. Confirm the PR's merge result is now in local main: `git -C \"$PRIMARY\" log --oneline | grep -q \"$PR_NUMBER\\|\u003Cmerge sha>\"`, then confirm every branch commit subject captured in Phase 4 (`SUBJECTS`) appears in `git -C \"$PRIMARY\" log --format=%s`. If any is absent, STOP and surface - something's odd.\n5. **Remove the pie worktree first (if `IS_WORKTREE` from Phase 0 was true):** `git -C \"$PRIMARY\" worktree remove \"$WORKTREE_PATH\"` (never `rm -rf`). This must precede the branch delete: git refuses to delete a branch that a worktree still has checked out.\n6. `git -C \"$PRIMARY\" branch -d \"$BRANCH\"` - delete the local pie branch (safe delete; refuses if unmerged commits exist, which is what we want). After a rebase-merge the commits on `main` carry new SHAs, so `-d` passes only while the branch's upstream ref still exists; if it refuses, confirm step 4 found every slice commit subject on `main` and surface `destructive_operation` before any `-D`.\n7. `git push origin --delete \"$BRANCH\"` - delete the remote branch. If GitHub auto-deleted it on merge (or `gh pr merge --delete-branch` did), this returns \"remote ref does not exist\" - fine; record it but don't fail. From a worktree, run `gh pr merge` without `--delete-branch`: that flag also tries to switch the local checkout to `main`, which the primary checkout holds.\n8. `git -C \"$PRIMARY\" worktree prune` - clear stale worktree metadata.\n9. `git -C \"$PRIMARY\" status --short` - must be empty. `git -C \"$PRIMARY\" rev-parse --abbrev-ref HEAD` - must be `main`. `git -C \"$PRIMARY\" status -uno` - confirm fully synced with remote. The pie is closed; the next pie starts in a fresh chat with a fresh worktree.\n\n### Phase 6 - Final Report *(pie-completion \u002F universal)*\n\nSurface to the user:\n- PR URL + merge commit SHA (+ note the merge strategy used: rebase \u002F merge-commit, and why when the helper picked a merge commit for empty commits)\n- Pie name + branch name (now deleted) + worktree path (now removed)\n- Slice and task commit count preserved on main\n- Total CI attempts (1 if green on first run; up to 3 if the fix loop ran) + ci-fix-attempter dispatch count \u002F per-attempt summary if applicable\n- Final state: \"On main, clean tree, fully synced with origin\u002Fmain. Pie N closed - start the next pie in a fresh chat.\"\n\n### Merge-per-slice closeout *(slice-merge mode, `--merge-slice`)*\n\nRuns once per slice when `delivery.mode` resolves to `merge-per-slice`. The conductor (`\u002Fsell-pie` or `\u002Fsell-slice`) invokes it internally and passes `BRANCH` (`pie-N-sN.M-\u003Cscope>`), `WORKTREE_PATH` (the slice worktree), the slice id and name, and whether this is the pie's last slice. Phases 0 → 6 apply with these overrides:\n\n- **Phase 0.** Run steps 1-6 against the slice worktree (`git -C \"$WORKTREE_PATH\" ...`). Skip step 7 (pie completeness). Add: `gh repo view --json mergeCommitAllowed --jq .mergeCommitAllowed` must print `true`. If it does not, STOP the loop with `needs_human: true`, `hitl_category: prd_ambiguity`: *\"This repo disallows merge commits, which merge-per-slice delivery requires. Enable merge commits, or rerun this pie in the default one-PR-per-pie mode?\"* Never fall back to squash or rebase on its own.\n- **Phase 1.** The slice's work is already committed and pushed on `BRANCH`. On the pie's last slice, Phase 1 step 4 applies: flip `## Pie N` to `Completed`, commit, push, so the flip reaches `main` with this slice's merge. With a gitignored checklist (the default) there is nothing to commit: flip `$PLANS\u002F00_master_checklist.md` in the primary checkout only after the Phase 4 merge, so a slice that stays red never marks its pie done. If any slice of the pie is still `waiting until \u003CYYYY-MM-DD>` (calendar-gated), this is not the last slice: do not flip the pie and do not write the kitchen merge record; the slice PR that later closes the waiting slice is the pie's last.\n- **Phase 2.** Title the PR `Slice N.M: \u003Cname>`: `gh pr create --base main --head \"$BRANCH\" --title \"Slice N.M: \u003Cname>\" --fill`.\n- **Phase 3 \u002F 3a.** Watch CI as usual, classifying failed checks as Phase 3 does. On a binding failure, up to **3** `ci-fix-attempter` rounds (the CI fix counter is per slice); advisory, non-required failures alone count as green and are listed in the slice notice. Still red after the 3rd round, or a round that bails on a repeated signature: **halt the loop** with a `creative_direction` HITL carrying the failure history. Never skip the slice, never merge it red, never start the next slice.\n- **Phase 4.** No human merge gate: the run instruction or `delivery.mode` already authorized autonomous delivery. On green, merge with a **merge commit**: `gh pr merge \"$PR_NUMBER\" --merge` (never `--squash`, never `--rebase`, never `--delete-branch` from the worktree).\n- **Phase 5.** Identical cleanup from the primary checkout: `git -C \"$PRIMARY\" pull --ff-only origin main`, `git -C \"$PRIMARY\" worktree remove \"$WORKTREE_PATH\"`, `git -C \"$PRIMARY\" branch -d \"$BRANCH\"`, `git push origin --delete \"$BRANCH\"`, `git -C \"$PRIMARY\" worktree prune`. Write the kitchen merge record only after the pie's last slice (see Phase 5 step 1). Append one line to the run log `.claude\u002F.bytheslice-state\u002Frun-log.md` (gitignored): slice id, PR URL, merge commit SHA, merge time.\n- **Phase 6.** Return a short per-slice result to the conductor (PR URL, merge SHA, CI rounds). The conductor cuts the next slice from the freshly synced `main`; on the pie's last slice it sends the operator **one** notice listing every slice PR from the run log.\n\n### Pie-local closeout *(pie-local mode, `--pie-local`)*\n\nRuns once per pie when `delivery.mode` resolves to `ship-once`. The `\u002Fsell-pie` conductor invokes it internally and passes `BRANCH` (`pie-\u003Cn>-\u003Cscope>`), `WORKTREE_PATH` (the pie worktree), `SHIP` (the ship branch), the pie number and name, `run.unattended`, and any slices it deferred. Phases 2-4 do not run: there is no PR, no push and no CI. All gates are local.\n\n1. **Pre-flight.** Resolve `PRIMARY=$(git worktree list --porcelain | sed -n '1s\u002F^worktree \u002F\u002Fp')` and `$PLANS` per [`git-worktree-standard.md`, \"Where the plans live\"](..\u002Fcook-pizzas\u002Freferences\u002Fgit-worktree-standard.md). Confirm `git -C \"$PRIMARY\" rev-parse --abbrev-ref HEAD` is `SHIP`, `git -C \"$PRIMARY\" status --short` is empty, `git -C \"$WORKTREE_PATH\" status --short` is empty, and `BRANCH` is neither `main` nor `SHIP`. A failure is a `destructive_operation` HITL (never switch, stash or overwrite the primary checkout).\n2. **Verified-slice check.** Every `### Slice N.M` under `## Pie N` in `$PLANS\u002F00_master_checklist.md` must be `[x]` **and** have a `slice-verifier` pass in the Pass ledger (`bts_status` shows each slice's last verdicts; without the tool, look for the slice's `slice-verifier` pass in `$PRIMARY\u002F.bytheslice\u002Fledger.jsonl`). With no ledger at all, trust the checklist and say so in the report. A `deferred:` slice (unattended only) must have no commit on the branch: no subject in `git -C \"$PRIMARY\" log --format=%s \"$SHIP\"..\"$BRANCH\"` names `N.M`. A slice that fails this check means the merge would carry unverified work into the ship PR.\n3. **Full local check, once, on the pie branch.** In `WORKTREE_PATH`, run the same commands `slice-verifier` runs on its first pass under ship-once ([definition](..\u002Fsell-slice\u002Fagents\u002Fslice-verifier.md), \"Which commands run\"): the **CI command list** parsed from the project's generated `.github\u002Fworkflows\u002Fci.yml` and then, when it exists, `.github\u002Fworkflows\u002Fe2e.yml` (every `run:` step, jobs in `needs:` order, environment setup skipped, a literal `origin\u002Fmain...HEAD` replaced with `\"$SHIP\"...HEAD`), so this check and the ship PR's CI run the same commands, every one of them, never a subset. Read `quality.tier` from `bytheslice.config.json` (`auto` resolves as `\u002Ffinal-quality-check` \"Quality tier\" documents). Under `lean` that list is lint, typecheck, unit tests, build, `check:design-system` only when a design system exists, and `test:e2e:smoke`; never run `test:e2e:feature`, `test:e2e:regression` or `test:e2e:visual` under lean, since lean CI does not. Under `standard`, that list includes every e2e suite `e2e.yml` runs (`@feature`, `@regression-core` and `@visual`), in full: `verification.e2e.*` does not narrow it, because CI does not read those thresholds. With no `ci.yml` yet, fall back to `\u003Cpm> lint`, `\u003Cpm> typecheck`, `\u003Cpm> build`, `\u003Cpm> test`, `\u003Cpm> check:design-system` when it exists and the tier's e2e gate, with the package manager from the lockfile (`pnpm-lock.yaml`, `package-lock.json`, `yarn.lock`, `bun.lock` \u002F `bun.lockb`) and the actual script names from `package.json` (they may be non-standard, e.g. `check-types`), and say so. Skip a script the project does not define and say so. Run each once and continue past a failure so the full picture is known. All green: go to step 5. Every other generated workflow that runs on pull requests (`e2e-coverage.yml`, `db-schema-drift.yml`, `design-system-compliance.yml`, when present) runs too, so nothing can fail only in CI on the ship PR.\n4. **Fix rounds (on red).** First classify each failed command as Phase 3 classifies a check, by the job it came from: one whose gate class is in `gates.advisory` is advisory (listed, labeled advisory, in the ship PR body, never fixed, outside this cap) unless branch protection on `main` requires that job (`gh api repos\u002F{owner}\u002F{repo}\u002Fbranches\u002Fmain\u002Fprotection --jq '.required_status_checks.contexts'`, when readable), which keeps it binding. Only advisory failures left: the check counts as green, go to step 5. Counter starts at 1, cap **3**, separate from every slice's local fix loops and from the CI rounds. Dispatch `bytheslice:fix-attempter` ([definition](..\u002Fsell-slice\u002Fagents\u002Ffix-attempter.md); fallback per [`loop-workflow-fallback-pattern.md`](..\u002Fcook-pizzas\u002Freferences\u002Floop-workflow-fallback-pattern.md) \"Agent shape on the fallback path\") with the failing checks as its verdict (check, command, exit code, last ~50 lines of output), the pie diff (`git -C \"$WORKTREE_PATH\" diff \"$SHIP\"...HEAD`), the round number and `previous_signature` (`normalize(first_error_line) + \" | \" + file + \" | \" + check`, never persisted). It returns `files_changed`; this skill stages exactly those paths, commits them on `BRANCH` as `fix(pie-N): pie-local check round K \u003Ccheck>` (no push), and re-runs the full local check (a round is one fix plus one full check, like a CI round). A `repeated_signature` bail ends the loop at once and counts as that round. Still red after round 3:\n   - **Interactive:** `creative_direction` HITL with the failure history; the pie is not merged.\n   - **Unattended (`run.unattended: true`):** do not ask. Leave the pie branch and worktree in place, unmerged, record the blocker `{pie: \"N\", reason: \"pie-local check red after 3 rounds: \u003Cchecks>\", attempts: 3}` with one `bts_note`, and return `status: complete_with_deferrals`.\n5. **Flip the pie status.** Tracked plans: set `## Pie N` to `Completed` on `BRANCH`, commit `chore(pie-N): mark Pie N completed`. Gitignored plans (the default): flip `$PLANS\u002F00_master_checklist.md` after step 6 succeeds, no commit. With deferred slices (unattended) the status reads `Completed (deferred: N.M, N.K)`.\n6. **Merge into the ship branch, preserving every slice commit.** Capture `SUBJECTS=$(git -C \"$PRIMARY\" log --format=%s \"$SHIP\"..\"$BRANCH\")`, then from the primary checkout: `git -C \"$PRIMARY\" merge --no-ff -m \"merge(pie-N): Pie N \u003Cname> into $SHIP\" \"$BRANCH\"`. Never squash, never rebase, never fast-forward. The subject names no slice id, so the PR evidence does not read the merge commit as an unverified slice. Confirm every line of `SUBJECTS` appears in `git -C \"$PRIMARY\" log --format=%s \"$SHIP\"`. A conflict (unexpected: the ship branch moves only through these merges, and the pie was cut from its tip) is `git -C \"$PRIMARY\" merge --abort`, then a `destructive_operation` HITL (interactive) or a pie blocker (unattended); never auto-resolve.\n7. **Cleanup from the primary checkout.** `git -C \"$PRIMARY\" worktree remove \"$WORKTREE_PATH\"`, then `git -C \"$PRIMARY\" branch -d \"$BRANCH\"` (safe: it is merged into the checked-out ship branch), then `git -C \"$PRIMARY\" worktree prune`. No remote delete: the pie branch was never pushed. Leave any `deferred\u002Fpie-N-sN.M` branch in place for the conductor. Append one line to the run log `.claude\u002F.bytheslice-state\u002Frun-log.md`: pie, ship-branch merge SHA, check rounds, deferred slices. No kitchen merge record here (no PR merged); `--ship` writes it.\n8. **Return** a short result to the conductor: merge SHA, check rounds, deferred slices and blockers, and whether this was the checklist's last pie.\n\n### Ship closeout *(ship mode, `--ship`)*\n\nRuns once, after the last pie of a ship-once build has merged into the ship branch. An interactive `\u002Fsell-pie` invokes it after its last `--pie-local`; in an unattended run the `\u002Fpizza-party` conductor invokes it after its replan. The caller passes `SHIP`, the app name (default: `SHIP` without its `ship\u002F` prefix), `run.unattended`, and the `blocked` list collected across the build. Phases 0 → 6 apply from the primary checkout with these overrides:\n\n- **Phase 0.** `BRANCH` is `SHIP`; confirm the primary checkout is on it and clean. Skip step 7 (pie completeness); instead confirm every `## Pie N` in `$PLANS\u002F00_master_checklist.md` is `Completed` (interactive: an unmerged pie is a `prd_ambiguity` HITL, \"ship without Pie N?\"; unattended: proceed and list it as a blocker). Run steps 4-6 as written (`gh auth status` is the one ship-once `gh` check). Resolve the merge strategy now: `gh repo view --json rebaseMergeAllowed,mergeCommitAllowed,squashMergeAllowed | node \"\u003Cthis-skill-directory>\u002Fpick-merge-strategy.js\" --base origin\u002Fmain --mode ship` (after `git fetch origin`) always picks a merge commit; `reason: merge-commits-disallowed` is a `prd_ambiguity` HITL (interactive) or a blocker returned before anything is pushed (unattended).\n- **Phase 1.** Nothing to commit. `git -C \"$PRIMARY\" push -u origin \"$SHIP\"`; a rejected push is a `destructive_operation` HITL (interactive) or a blocker (unattended), never a force-push.\n- **Phase 2.** Title `Ship \u003Capp>: \u003Cpies> pies, \u003Cslices> slices`, counting the pies merged into the ship branch (`merge(pie-N)` merge commits in `origin\u002Fmain..$SHIP`) and the slices `[x]`. Build the body file: the commit story (`git log --reverse --no-merges --format='%s%n%n%b' origin\u002Fmain..\"$SHIP\"`), a blank line, `## Evidence`, then for **every** merged pie a `### Pie N` heading and `bts_pr_body({ \"pie\": N })` output verbatim (omit the section when the tool is absent), then `## Deferred` listing every `blocked` entry and the design-critique findings recorded as deferred (omit when empty). `gh pr create --base main --head \"$SHIP\" --title \"\u003Ctitle>\" --body-file \u003Cfile>`. Every slice named on the branch must carry a `slice-verifier` pass in the ledger, which deferral guarantees (it keeps unverified commits off the branch). If one does not, surface its slice list (`prd_ambiguity`, interactive) or return it as a blocker (unattended) instead of opening the PR.\n- **Phase 3 \u002F 3a.** Watch CI once (30-minute cap per attempt), classifying failed checks as Phase 3 does; on a binding failure, up to **3** `ci-fix-attempter` rounds committed and pushed on `SHIP` from the primary checkout (advisory, non-required failures alone count as green and are listed in the ship PR body). Still red after round 3, or a `repeated_signature` bail: interactive, the `creative_direction` HITL as usual; **unattended, leave the PR open**, record the blocker `{pie: \"ship\", reason: \"ship PR CI red after 3 rounds: \u003Cchecks>\", attempts: 3, pr: \"\u003CPR_URL>\"}` and return `status: complete_with_deferrals` without merging. A PR GitHub reports as conflicting with `main` (`gh pr view --json mergeable` is `CONFLICTING`) is handled the same way, as a `destructive_operation` HITL or a blocker; never auto-resolve.\n- **Phase 4.** No human merge gate: choosing ship-once authorized the merge. On green, `gh pr merge \"$PR_NUMBER\" --merge` (the strategy from Phase 0; never `--squash`, never `--rebase`, which would drop the pie merge commits; never `--delete-branch`, since the primary checkout holds `SHIP`).\n- **Phase 5.** Capture `SUBJECTS=$(git -C \"$PRIMARY\" log --format=%s origin\u002Fmain..\"$SHIP\")` before the merge. After `gh pr view` confirms `MERGED`, write the kitchen merge record once with `--mode pie --pie \"\u003Clast pie number>\"`. Then, from the clean primary checkout: `git -C \"$PRIMARY\" switch main`, `git -C \"$PRIMARY\" pull --ff-only origin main`, confirm every `SUBJECTS` line is in `git -C \"$PRIMARY\" log --format=%s`, `git -C \"$PRIMARY\" branch -d \"$SHIP\"`, `git push origin --delete \"$SHIP\"`, `git -C \"$PRIMARY\" worktree prune`. Pie worktrees are already gone; any pie left unmerged by an unattended blocker keeps its worktree and is listed in the report. `deferred\u002F*` branches stay for the conductor.\n- **Phase 6.** Report the ship PR URL, the merge SHA and strategy, pies and slices shipped, CI rounds, and every blocker; return `status: complete`, or `complete_with_deferrals` when `blocked` is not empty.\n\n---\n\n## HITL Handling\n\n**Agents and this skill never call `ask_user_input_v0`.** At every elicitation point - the Phase 1 commit prompt and the Phase 4 merge-authorization gate - the skill **sets `needs_human: true` plus the `hitl_*` fields in its return contract** and lets the invoking orchestrator (`\u002Fsell-pie`'s loop, or the operator's session) surface the prompt. The phase descriptions above show the question text; the skill emits it as `hitl_question`, not as a direct tool call.\n\nFor sub-agent failures (e.g. `ci-fix-attempter` returns `needs_human: true`), the skill bubbles the structured fields up via its own return contract - it does not retry indefinitely.\n\n**Unattended ship-once runs never ask.** In `pie-local` and `ship` mode with `run.unattended: true`, every point below that would set `needs_human` instead records a blocker in `blocked` (`{slice | pie, reason, attempts}`, plus `pr` when a ship PR is left open), leaves the git state as it is (an unmerged pie keeps its branch and worktree; a red ship PR stays open), and returns `status: complete_with_deferrals` to the conductor. Fix caps never rise. Interactive runs behave exactly as described below.\n\nHITL categories the skill produces:\n- `destructive_operation` - about to push from main, force-push detected, merge-conflict pull, branch-reuse without rename, would-overwrite uncommitted changes on checkout.\n- `external_credentials` - `gh` not authenticated, CI watch timeout (likely runner \u002F secrets issue).\n- `creative_direction` - ci-fix-attempter exhausted 3 attempts or bailed on a repeated signature; user decides whether to debug, retry, or close the PR. In `slice-merge` mode this halts the delivery loop. In `pie-local` mode, the full local check still red after 3 `fix-attempter` rounds.\n- `prd_ambiguity` - boxing a pie with unfinished slices; a squash-only repo that would collapse per-slice commits; a repo that disallows merge commits in `slice-merge` mode; a precondition that needs the user to tell the skill how to interpret state.\n\n---\n\n## Hard Constraints\n\n- **Per-slice mode opens no PR and watches no CI.** Commit + push only, then return. In the default `pie-pr` mode CI fires exactly **once per pie**, at the boundary, and no PR opens mid-pie. **Exception:** `slice-merge` mode (`delivery.mode: merge-per-slice`) opens, CI-checks and merges one PR per slice.\n- **Preserve per-slice commits on a pie merge - never `--squash`.** Default mode: rebase-merge for the pie PR, merge-commit as fallback, and always a merge commit when the branch holds an empty commit (rebase-merge drops it; `pick-merge-strategy.js` decides). `slice-merge` mode: always a merge commit; a repo that disallows merge commits is a `prd_ambiguity` HITL. A squash-only repo is a `prd_ambiguity` HITL, not a silent squash.\n- **Ship-once: no human merge gate, local gates per pie, CI once at the end.** `pie-local` merges the pie into the ship branch only after every non-deferred slice has a `slice-verifier` pass and the full local check is green (at most 3 `fix-attempter` rounds), with `git merge --no-ff` (never squash, rebase or fast-forward), and never pushes. `ship` pushes the ship branch, opens one PR, merges it with a merge commit only on green CI (at most 3 `ci-fix-attempter` rounds), then syncs `main` and deletes the ship branch. Unattended runs return blockers instead of asking, and leave a red ship PR open.\n- **No per-slice merge approval in `slice-merge` mode; never merge red.** The slice merges only on green CI, after at most 3 `ci-fix-attempter` rounds; still red halts the loop. There is never an integration branch.\n- **One worktree per pie (default and ship-once) or per slice (`slice-merge`); `\u002Fbox-it-up` only removes it.** The worktree is created upstream by the conductor. This skill removes it after the merge (via `git worktree remove` + `prune`, never `rm -rf`) and never creates one. The merge\u002Fcleanup rules here are the standard's - see [`..\u002Fcook-pizzas\u002Freferences\u002Fgit-worktree-standard.md`](..\u002Fcook-pizzas\u002Freferences\u002Fgit-worktree-standard.md) (Phase 3 + Invariants §5).\n- **Never ship from `main` \u002F `master`.** Phase 0 step 2 is a stop-everything check. `--ship` ships from the ship branch; `--pie-local` writes only the pie merge commit on it.\n- **Never force-push.** If `git push` is rejected for non-fast-forward, STOP. The user resolves on a fresh branch.\n- **Only the conductor makes git writes, `git add` included.** `ci-fix-attempter` returns `files_changed`; this skill stages those paths selectively, commits and pushes, on the registered and fallback paths alike. Never `git add -A`.\n- **Never auto-merge a PR with failing required checks.** Phase 4 only runs when CI is green on the latest head SHA.\n- **Never box an incomplete pie.** If any slice under the active Pie is still `[ ]`, STOP (`prd_ambiguity`).\n- **Never `git stash` on the user's behalf.** If `git checkout main` would overwrite uncommitted changes, STOP.\n- **Clean up from the primary checkout, in order.** Sync `main` with `git -C \"$PRIMARY\" pull --ff-only`, then `worktree remove`, then `branch -d`, then the remote delete, then `worktree prune`. Never check out `main` inside a worktree, and never delete a branch a worktree still holds.\n- **Never edit a tracked file on `main`.** The Pie's checklist flip is committed on the pie branch before the PR opens.\n- **Never auto-resolve merge conflicts during cleanup pull.** `--ff-only` fails fast; the user resolves.\n- **Red checks are binding gates.** Fix them through Phase 3a without asking, root cause fixed where it lives; never merge red, never park a failing check as a follow-up or \"out of scope\". Only a class in `gates.advisory` is reported instead of fixed.\n- **Cap the CI fix loop at 3 attempts.** Beyond that → HITL `creative_direction`. No \"one more try.\" No run instruction raises the cap; only the operator's explicit reply at the HITL does. Separate from the 3 local fix loops per slice. The `pie-local` check rounds are their own counter with the same cap of 3 and the same rule.\n- **Cap CI watch at 30 minutes per attempt.** Beyond that → HITL `external_credentials`.\n- **Reuse existing PRs.** If an open PR already tracks the branch, watch its CI; never create a duplicate.\n- **Never call `ask_user_input_v0`.** Set `needs_human` + `hitl_*` and let the orchestrator prompt.\n- **Subagent prompts live in `.\u002Fagents\u002F*.md`.** This SKILL.md is workflow only - never inline subagent prompts here.\n- **Always provide a recommended answer in available options** at every elicitation point.\n\n---\n\n## Triggers\n\nFollow this skill whenever the user (or `\u002Fsell-pie`'s loop):\n\n- runs `\u002Fbox-it-up` (pie-completion \u002F universal closeout) or `\u002Fbox-it-up --slice` (per-slice commit + push)\n- is a ship-once conductor at a pie boundary (`--pie-local`) or after the last pie (`--ship`)\n- says \"box up the pie\", \"close out the pie\", \"ship the pr\", \"submit the pr\", \"open and merge the pr\", \"ship this branch\", \"ship this pie\"\n- has finished every slice of a Pie under `\u002Fsell-pie` and reached the pie boundary\n- has a hand-rolled feature branch ready to ship (universal closeout)\n\nIf the working tree is on `main` with no feature branch in sight, redirect to `\u002Fsell-pie` (autonomous, whole pie) or `\u002Fsell-slice` (one careful slice) first.\n\nIf the user wants to open the boundary PR but pause before merging for code review, they should pick option 2 (Hold) at the Phase 4 gate.\n\n---\n\n## Completion Checklist\n\nWalk the checklist that matches the mode. Do not report done until every applicable box is `[x]`.\n\n### Per-slice mode\n\n- [ ] Current branch confirmed not `main` \u002F `master` (it is the pie branch).\n- [ ] Slice closed with a `feat(pie-N): N.M \u003Cname>` (or fix\u002Fchore\u002Fdocs) final commit on top of its pushed task commits; tree clean.\n- [ ] Branch pushed to `origin`.\n- [ ] No PR opened, no CI watched - returned cleanly so the loop continues.\n\n### Slice-merge mode\n\n- [ ] Repo allows merge commits (`mergeCommitAllowed` true), or the loop halted and asked.\n- [ ] Checklist reconciled before the PR opened (Phase 1 step 5): the slice reads `Completed`.\n- [ ] PR `Slice N.M: \u003Cname>` opened against `main`.\n- [ ] CI green on the latest head SHA (at most 3 `ci-fix-attempter` rounds; still red halted the loop).\n- [ ] Merged with a merge commit, no squash, no rebase.\n- [ ] Cleanup ran from the primary checkout: `pull --ff-only`, `worktree remove`, `branch -d`, remote delete, `worktree prune`.\n- [ ] Run-log line appended; kitchen merge record written only after the pie's last slice.\n\n### Pie-local mode (ship-once)\n\n- [ ] Primary checkout clean and on the ship branch; pie worktree clean.\n- [ ] Every slice `[x]` with a `slice-verifier` pass (or, unattended, `deferred:` with no commit on the branch).\n- [ ] Full local check ran once on the pie branch (every command `ci.yml` and, under standard, `e2e.yml` run, in full; lean: smoke spec only, never `@feature` \u002F `@regression-core` \u002F `@visual`) and is green (at most 3 `fix-attempter` rounds), or the pie was left unmerged with a HITL (interactive) or a blocker (unattended).\n- [ ] Pie merged into the ship branch with `git merge --no-ff`; every pie commit subject found on the ship branch; nothing pushed.\n- [ ] Pie worktree removed, pie branch deleted with `-d`, `worktree prune` ran; pie status flipped; run-log line appended.\n\n### Ship mode (ship-once)\n\n- [ ] Every pie `Completed` on the ship branch (or, unattended, listed as a blocker), and the checklist reconciled before the PR opened (Phase 1 step 5).\n- [ ] Repo allows merge commits (`pick-merge-strategy.js --mode ship` picked `merge`).\n- [ ] Ship branch pushed; one PR `Ship \u003Capp>: \u003Cpies> pies, \u003Cslices> slices` opened against `main` with a `### Pie N` evidence block per pie and a `## Deferred` section when anything was deferred.\n- [ ] CI green (at most 3 `ci-fix-attempter` rounds) and merged with a merge commit, no human gate; or, unattended and still red, the PR left open and reported as a blocker.\n- [ ] Kitchen merge record written once; `main` synced `--ff-only` in the primary checkout; ship branch deleted local and remote; `worktree prune` ran.\n\n### Pie-completion \u002F universal mode\n\n#### 1. Pre-flight passed\n\n- [ ] Current branch confirmed not `main` \u002F `master`.\n- [ ] Worktree state captured (path + IS_WORKTREE flag).\n- [ ] No accidental reuse of a recently-merged branch.\n- [ ] `gh` authenticated.\n- [ ] (pie mode) Every slice under the active Pie is `[x]`.\n\n#### 2. Pie PR open\n\n- [ ] Checklist reconciled before the PR opened (Phase 1 step 5): every slice the diff delivers or changes carries its true `**Status:**`, also in universal mode when a checklist exists.\n- [ ] Any straggler changes committed; branch pushed to `origin`.\n- [ ] (pie mode) Pie status flipped `In Progress` → `Completed` and committed on the pie branch before the PR opened.\n- [ ] One PR open against `main` - titled `Pie N: \u003Cname>` for a pie (or reused existing).\n- [ ] PR URL surfaced to the user.\n\n#### 3. CI green on the merged head SHA\n\n- [ ] `gh pr checks \u003Cpr> --watch` returned exit 0 (CI's single run for the pie).\n- [ ] If the auto-fix loop ran, the final attempt cleared green; ci-fix-attempter dispatch history captured.\n- [ ] No required check skipped or pending.\n\n#### 4. Merge authorized + completed (preserving slice commits)\n\n- [ ] Phase 4 user prompt surfaced (via `needs_human`\u002F`hitl_*`) and answered.\n- [ ] Merge used rebase or merge-commit - **not** squash for a pie; per-slice commits preserved on main.\n- [ ] PR state is `MERGED` per `gh pr view`.\n\n#### 5. Branch + worktree cleanup\n\n- [ ] Cleanup ran from the primary checkout (`git -C \"$PRIMARY\" ...`), which is on `main`.\n- [ ] `git -C \"$PRIMARY\" pull --ff-only origin main` succeeded.\n- [ ] Pie worktree removed via `git worktree remove` (if a worktree was used), before the branch delete.\n- [ ] Local pie branch deleted (`git branch -d`).\n- [ ] Remote pie branch deleted (or already auto-deleted by GitHub).\n- [ ] `git worktree prune` ran.\n- [ ] `git status --short` empty in the primary checkout; `git status -uno` confirms fully synced with `origin\u002Fmain`.\n\n#### 6. Final report emitted\n\n- [ ] User received the report (PR URL, merge SHA + strategy, slice-commit count, attempt counts, \"Pie N closed - next pie in a fresh chat\").\n\n---\n\n## Sub-agent return contract\n\n`\u002Fbox-it-up` returns structured fields whether it ran per-slice or boxed the whole pie (e.g. when `\u002Fsell-pie`'s loop invokes it). It never prompts the user directly - the orchestrator reads `needs_human` + `hitl_*` and surfaces any question.\n\n```yaml\nstatus: complete | complete_with_deferrals | failed | needs_human   # complete_with_deferrals: unattended pie-local \u002F ship recorded a blocker instead of asking\nmode: slice | slice-merge | pie | universal | pie-local | ship\nsummary: \u003Cone paragraph - mode; for slice: commit sha + branch; for slice-merge: slice PR URL + number, CI rounds, merge commit SHA, cleanup state; for pie: pie name, PR URL + number, CI attempt count, merge strategy + SHA, per-slice-commit count preserved, cleanup state; for pie-local: pie name, local check rounds, ship-branch merge SHA, deferred slices, cleanup state; for ship: ship PR URL + number, pies and slices shipped, CI rounds, merge SHA, cleanup state>\nartifacts:\n  - \u003Ccommit sha (slice mode)>\n  - \u003Cpr url (slice-merge\u002Fpie\u002Funiversal\u002Fship mode)>\n  - \u003Cmerge commit sha (slice-merge\u002Fpie\u002Funiversal\u002Fpie-local\u002Fship mode)>\nlocal_check_rounds: null | \u003Cint>    # pie-local only: fix rounds used (0 when green on the first run)\nlast_pie: null | false | true       # pie-local only: every pie in the checklist is now merged into the ship branch (or deferred, unattended)\nblocked: [] | [{slice: \"\u003CN.M>\", reason: \"\u003Cone line>\", attempts: \u003Cint>} | {pie: \"\u003CN>\" | \"ship\", reason: \"\u003Cone line>\", attempts: \u003Cint>, pr: \"\u003Curl, ship only>\"}]   # unattended pie-local \u002F ship only\nneeds_human: false | true\nhitl_category: null | \"prd_ambiguity\" | \"external_credentials\" | \"destructive_operation\" | \"creative_direction\"\nhitl_question: null | \"\u003Cplain-language question>\"\nhitl_context: null | \"\u003Cwhat triggered this>\"\n```\n","\u003C!-- skills\u002Fbox-it-up\u002FSKILL.md -->\n\u003C!-- Standalone closeout skill, re-scoped pie-level for v5 (spec §1.10). Pizza-shop framing: the pie cooled slice by slice - box it and hand it over. TWO call shapes: (1) per-slice, invoked repeatedly by \u002Fsell-pie's loop after each slice → commit + push only, no PR opened so CI does not fire; (2) pie-completion, invoked once when every slice in the active Pie is [x] → open one PR \"Pie N\", CI runs once, HITL review, merge PRESERVING per-slice commits (rebase\u002Fmerge-commit, never squash), sync main --ff-only, delete branch, remove the pie worktree. Universal closeout safety preserved: a hand-rolled branch with no checklist still ships through the pie-completion path (no pie-status flip, project-default merge strategy). Decoupled from \u002Fsell-pie and \u002Fsell-slice so the operator can review \u002F UAT before the boundary PR. Ship-once delivery adds --pie-local (local check + local --no-ff merge of the pie into the ship branch) and --ship (the one ship PR to main, merged on green with no human gate). -->\n\n# \u002Fbox-it-up\n\nIn v5 a **Pie** (a coherent chapter, usually 3 to 8 slices; a small app's pie may hold 1 or 2) is the unit of PR, CI, and review. `\u002Fbox-it-up` carries both halves of the pie's git lifecycle:\n\n- **Per slice** - `\u002Fsell-pie`'s loop calls `\u002Fbox-it-up --slice` after each slice clears its gates. The skill commits the slice on the pie branch and pushes. **No PR is opened, so CI does not fire** - per-slice pushes stay cheap.\n- **At the pie boundary** - when every slice in the active Pie is `[x]`, `\u002Fbox-it-up` opens **one** PR `Pie N: \u003Cname>`, lets CI run **once**, gets your merge approval, merges **preserving every per-slice commit** (rebase or merge-commit, never squash), syncs `main` fast-forward-only, deletes the branch, and **removes the pie worktree**.\n- **Merge per slice (opt-in)** - when `delivery.mode` resolves to `merge-per-slice` (an explicit autonomous-delivery run instruction, or the config), the conductor runs `\u002Fbox-it-up --merge-slice` internally after each slice: one PR `Slice N.M: \u003Cname>`, CI, up to 3 fix rounds, merge on green with a merge commit, cleanup from the primary checkout. No per-slice merge approval; the operator gets one notice when the pie finishes. The two bullets above describe the default (`pie-pr`) mode.\n- **Ship once (opt-in)** - when `delivery.mode` resolves to `ship-once` (`\u002Fpizza-party` sets it), per-slice commits stay local (no push). At each pie boundary the conductor runs `\u002Fbox-it-up --pie-local`: confirm every slice was verified, re-run the full local check once, merge the pie branch into the long-lived local ship branch with `git merge --no-ff`, remove the pie worktree and branch. After the last pie, `\u002Fbox-it-up --ship` pushes the ship branch, opens **one** PR to `main`, watches CI once and merges on green with a merge commit. Neither step has a human merge gate: choosing ship-once authorized it.\n\nIt is intentionally a **separate** skill so you can review the whole pie locally, run a manual visual UAT, or rebase against fresh main before deciding to ship the boundary PR. The closeout path is **universal** - safe to run on a hand-rolled branch that never touched the ByTheSlice delivery loop. Pre-flight checks and the merge\u002Fcleanup pattern do not assume a checklist or a pie.\n\n---\n\n## Mode detection\n\n`\u002Fbox-it-up` is **always standalone** and operates on whatever feature branch is currently checked out (in `slice-merge` mode, the slice branch in the slice worktree the conductor names). It resolves one of six modes before doing anything:\n\n| Mode | How it's detected | What it does |\n|------|-------------------|--------------|\n| **per-slice** | Invoked with `--slice` (how `\u002Fsell-pie`'s loop calls it), or the operator explicitly asks to \"box up the slice\" mid-pie. | **Phase 1 only** - commit the slice on the pie branch + push. **No PR, no CI watch, no merge, no cleanup.** Returns immediately so the loop continues to the next slice. |\n| **pie-completion** | Default. A master checklist exists, the current branch matches a `pie-\u003Cn>-\u003Cscope>` row, and **every** `### Slice N.M` under that `## Pie N` is `[x]`. Also the shape `\u002Fsell-pie` hands off at the boundary. | **Full closeout** - Phases 0 → 6: open one PR `Pie N`, CI once, HITL merge gate, merge preserving slice commits, sync main, delete branch, remove worktree, flip the pie's checklist status. |\n| **universal** (hand-rolled) | No master checklist, or the branch doesn't map to a pie row (a feedback round, a fix on a delivered slice). | **Same closeout as pie-completion** (Phases 0 → 6) minus the pie-status flip, and merge strategy falls back to the project default. The universal-closeout safety net - never assumes ByTheSlice ran. |\n| **slice-merge** (merge per slice) | Invoked with `--merge-slice` by the `\u002Fsell-pie` or `\u002Fsell-slice` conductor when `delivery.mode` resolves to `merge-per-slice` and the pie is not `review: continuous`. Always an **internal** invocation: the conductor sits on `main` between slices by design and follows this skill's phases itself rather than typing the command, so the on-`main` precondition question below does not apply to it. | **One slice, one PR** - see \"Merge-per-slice closeout\" below: PR `Slice N.M: \u003Cname>`, CI, up to 3 `ci-fix-attempter` rounds, merge on green with a merge commit (no human merge gate), cleanup from the primary checkout. |\n| **pie-local** (ship-once boundary) | Invoked with `--pie-local` by the `\u002Fsell-pie` conductor at the pie boundary when `delivery.mode` resolves to `ship-once`. Internal, like `--merge-slice`. | **No PR, no push, no CI** - see \"Pie-local closeout\" below: verified-slice check, the full local check once (up to 3 `fix-attempter` rounds), `git merge --no-ff` of the pie branch into the ship branch in the primary checkout, worktree and branch removal. |\n| **ship** (ship-once finish) | Invoked with `--ship` after the last pie of a ship-once build: by `\u002Fsell-pie` in an interactive run, or by the `\u002Fpizza-party` conductor in an unattended one. Runs from the primary checkout on the ship branch. | **One ship PR** - see \"Ship closeout\" below: push the ship branch, PR `Ship \u003Capp>: \u003Cpies> pies, \u003Cslices> slices` with every pie's evidence, CI once, up to 3 `ci-fix-attempter` rounds, merge on green with a merge commit (no human gate), sync `main`, delete the ship branch. |\n\n**Refusal guards:**\n- In **per-slice** mode, if the active Pie still has unfinished slices the skill must NOT try to open a PR - that is correct, expected mid-pie behavior, not an error.\n- In **pie-completion** mode, if the master checklist shows the active Pie still has unchecked slices (`### Slice N.M` is `[ ]`), STOP and surface as `needs_human: true` with `hitl_category: prd_ambiguity`: *\"Pie N still has unfinished slices - finish them via \u002Fsell-pie before boxing the pie, or confirm you want to ship a partial pie.\"* Never silently ship an incomplete pie. In **pie-local** mode the same guard applies, except that an unattended run (`run.unattended: true`) treats a slice whose status reads `deferred: \u003Creason>` as finished for this merge (its commits already left the pie branch), and a slice `waiting until \u003CYYYY-MM-DD>` as finished too (its commits passed `slice-verifier` and merge with the pie; the row stays `[ ]`), and lists both in `blocked`. A slice whose `**Status:**` reads `waiting until \u003CYYYY-MM-DD>: \u003Ccriterion>` is unfinished too: refuse with *\"Pie N is waiting on Slice N.M until \u003CYYYY-MM-DD> (\u003Ccriterion>). Re-run \u002Fsell-pie on or after that date; the boundary PR opens once it closes.\"* No HITL is needed for a waiting slice, since the date is the only blocker; set `status: needs_human` only if the operator asked to ship anyway.\n\nIf a master checklist exists and the branch maps to a pie row, `\u002Fbox-it-up` flips that **Pie's** status from `In Progress` to `Completed` and commits the flip **on the pie branch before the PR opens** (Phase 1 step 4), so the status reaches `main` with the merge and never as an uncommitted edit on `main`. That is the only sequential-flavored behavior - best-effort enhancement, never a precondition.\n\n## Subagent Roster\n\n| Phase | Agent file | Model | Effort | Mode |\n|-------|-----------|-------|--------|------|\n| 3 (on CI fail, pie-completion \u002F slice-merge \u002F ship) | [agents\u002Fci-fix-attempter.md](agents\u002Fci-fix-attempter.md) | sonnet | high | write |\n| pie-local check (on red, pie-local only) | [..\u002Fsell-slice\u002Fagents\u002Ffix-attempter.md](..\u002Fsell-slice\u002Fagents\u002Ffix-attempter.md) | sonnet | high | write |\n\nCI watching itself is inline (`gh pr checks \u003Cpr> --watch` blocks until checks settle). No separate watcher subagent. **Per-slice mode dispatches no subagents** - there is no PR and therefore no CI to fix.\n\n---\n\n## Inputs and Preconditions\n\n> This skill checks its own preconditions inline at the start, via tools (current branch, `gh auth status` when the mode needs PR work). If one fails, raise the problem to the operator as a question with a recommended next step, never a refusal. On `main` \u002F `master`, say so and ask how to proceed (usually: switch to the pie branch or its worktree); the merge-per-slice closeout (`--merge-slice`) runs from `main` by design, so this check is skipped there. Never narrate passing checks in chat. No ByTheSlice hook blocks a prompt.\n\n- Working tree on a feature branch (not `main` \u002F `master`) - for a v5 pie this is `pie-\u003Cn>-\u003Cscope>`.\n- **Per-slice mode:** the slice's changes are committed locally OR present as uncommitted changes the skill should commit. `gh` is **not** required (no PR work).\n- **Pie-completion \u002F universal mode:** `gh` CLI installed and authenticated (`gh auth status` returns \"Logged in\"); the repository has a remote (`git remote -v` returns at least `origin`).\n- One **worktree per pie** (default mode) - created upstream by `\u002Fsell-pie` when the pie branch is cut, removed here at the boundary. In `slice-merge` mode it is one worktree per slice, created by the conductor and removed here after that slice merges. `\u002Fbox-it-up` never *creates* a worktree; it only removes one.\n- **Slice-merge mode:** `gh` authenticated, and the repo allows merge commits (`gh repo view --json mergeCommitAllowed`).\n- **Pie-local mode:** the primary checkout is clean and on the ship branch; the pie worktree is clean. `gh` is **not** required (no PR work), and nothing is pushed.\n- **Ship mode:** the primary checkout is clean and on the ship branch; `gh` authenticated (the only ship-once step that needs it); an `origin` remote; the repo allows merge commits.\n\n---\n\n## Workflow\n\nAt every phase boundary, if the `bts_status` tool is available call it instead of re-reading the checklist; if it is not, read the checklist as before.\n\n> **Per-slice mode runs Phase 1 only, then returns.** Phases 0 and 2-6 are pie-completion \u002F universal closeout. `slice-merge` mode runs Phases 0 → 6 with the overrides in \"Merge-per-slice closeout\" below. The phase numbering is shared so the commit logic is defined once.\n\n### Phase 0 - Pre-flight Safety Checks *(pie-completion \u002F universal)*\n\nThe skill refuses to proceed past Phase 0 if any check fails. The point is to avoid a destructive accident on `main` or an accidental push to a stale branch.\n\n1. `git rev-parse --abbrev-ref HEAD` - capture current branch as `BRANCH`.\n2. **If `BRANCH` is `main` or `master`, STOP.** Surface as `needs_human: true` with `hitl_category: destructive_operation` and message: *\"Refusing to ship from main. Switch to a pie \u002F feature branch first.\"* Do not push, do not commit.\n3. `git worktree list` - capture worktree state as `WORKTREE_PATH` (the path matching the current working directory) and `IS_WORKTREE` (`true` if cwd is not the main worktree). For a v5 pie this is the pie worktree slated for removal in Phase 5.\n4. `gh pr list --state merged --limit 1 --base main --json headRefName,number,mergedAt` - capture the most recently merged PR. If `BRANCH` matches its `headRefName` (an already-shipped pie branch reused without renaming), STOP and surface as `needs_human: true` with `hitl_category: destructive_operation`. Ask whether to rename or proceed.\n5. `gh pr list --state open --head \"$BRANCH\" --json number,url --jq '.[0]'` - check whether an open PR for this branch already exists. If yes, capture its number and URL as `EXISTING_PR_NUMBER` \u002F `EXISTING_PR_URL`. The skill reuses it (watch CI on the existing PR) rather than create a duplicate. Because per-slice pushes never open a PR, the first boundary run normally finds none.\n6. `gh auth status` - confirm gh is authenticated. If not, surface as `external_credentials` HITL and stop.\n7. **Pie-completeness check (pie-completion mode only):** confirm every `### Slice N.M` under the active `## Pie N` in `docs\u002Fplans\u002F00_master_checklist.md` is `[x]`. If any is `[ ]`, STOP per the Mode-detection refusal guard (`prd_ambiguity`, or the waiting-slice refusal when its status reads `waiting until \u003Cdate>`).\n\n### Phase 1 - Commit + Push *(both modes; the per-slice entry point)*\n\n1. `git status --short` - if there are uncommitted changes, handle them per the **batched-approvals** rule: when a conductor invoked this skill (`--slice`, `--merge-slice`, or the `\u002Fsell-pie` boundary handoff) and every changed path came from agents' `files_changed` or the checklist, commit without asking (the conductor already owns those paths). Ask only when something is unexpected, and then put this question in **one batch** with every other approval already known at this point (for example a squash-only repo from the Phase 4 strategy check, run early), one decision per question, each with a recommended answer. The Phase 4 merge gate needs CI's result, so it is its own later batch. The commit question:\n   - \"Stage and commit these changes? (yes \u002F let me write the message \u002F cancel)\"\n   - **Always provide a recommended answer in the available options.** Default recommendation: yes if the diff looks like the in-scope slice; \"let me write\" if it includes unexpected files.\n   - On `yes`: stage selectively, never `git add -A` or `git add .`. Stage only the paths the conductor recorded from agents' `files_changed` and the checklist; anything else is an unexpected file, so recommend \"let me write\" and list it. Then derive the commit message **by mode**:\n     - **Per-slice mode** - the slice's task commits (`feat(pie-N): N.M task K \u003Ctask name>`) are already pushed. This is the slice's **final commit**, using the v5 slice commit convention: **`feat(pie-N): N.M \u003Cslice name>`** (swap `feat` for `fix`\u002F`chore`\u002F`docs` when the diff is purely a fix \u002F infra-config \u002F docs). One-line subject; short body listing touched files grouped by package\u002Fapp. **If the slice touched UI** and `\u002Fsell-slice`\u002F`\u002Fsell-pie` produced a closing-narrative paragraph (one paragraph: what was built · why this shape · what was left out · what reviewers should pay attention to), include it verbatim in the commit body before the file list. These task and slice commit messages are what the boundary PR preserves - they become the PR's commit-by-commit story, so keep each one self-describing. When nothing is left to stage (the checklist is gitignored, as it is by default, and no fix patch or state file is pending), make the final commit with `git commit --allow-empty`: its subject is the slice's record in the history, and Phase 4 merges a branch holding an empty commit with a merge commit so it survives. After the push, `git status --short` must be empty: the slice may not leave an untracked or modified file it created.\n     - **Pie-completion \u002F universal mode** - only reached here when the boundary run finds straggler uncommitted changes (most slices are already committed by the per-slice runs). Derive a conventional type from the diff (`feat:`\u002F`fix:`\u002F`chore:`\u002F`docs:`) with a one-line subject and a file-list body.\n   - On `let me write`: prompt for the message.\n   - On `cancel`: stop here. Working tree unchanged.\n2. `git push origin \"$BRANCH\"` - push to the pie branch. If the remote rejects (non-fast-forward, etc.), STOP and surface as `destructive_operation` HITL - never auto force-push. **Ship-once:** skip the push; the pie branch stays local until `--pie-local` merges it into the ship branch, and only `--ship` pushes anything.\n3. **Per-slice mode ends here.** Return the per-slice contract (`status: complete`, the commit SHA + branch). **Do not open a PR, do not watch CI, do not merge.** The `\u002Fsell-pie` loop advances to the next slice; CI fires only at the pie boundary.\n4. **Flip the Pie's checklist status (pie-completion mode only), before the PR opens.** In `docs\u002Fplans\u002F00_master_checklist.md`, set the active `## Pie N` status from `In Progress` to `Completed`, commit it on the pie branch as `chore(pie-N): mark Pie N completed`, and push. The flip rides into `main` with the merge, so `main` never carries an uncommitted checklist edit (the pre-commit guard blocks commits on `main`, and Phase 5 requires a clean tree). If the operator holds or cancels the PR, the flip stays on the unmerged branch only. When the checklist is gitignored (`git check-ignore -q docs\u002Fplans\u002F00_master_checklist.md`, the default), flip the primary checkout's copy (`$PLANS\u002F00_master_checklist.md`, per [`git-worktree-standard.md`, \"Where the plans live\"](..\u002Fcook-pizzas\u002Freferences\u002Fgit-worktree-standard.md); a worktree has no copy) and make no commit. Skip silently in universal mode (no checklist \u002F no pie row).\n5. **Reconcile the checklist before any PR opens (every mode that opens one: pie-completion, universal, slice-merge and ship).** Before Phase 2 runs `gh pr create`, read `docs\u002Fplans\u002F00_master_checklist.md` (the primary checkout's `$PLANS` copy when it is gitignored) against the branch diff, `git diff --name-only origin\u002Fmain...HEAD`. Every slice the branch delivers or changes, including a feedback round, a review follow-up or a CI fix made outside `\u002Fsell-slice` and `\u002Fsell-pie`, gets its `**Status:**` line set to what the branch leaves it at (`Completed`, `In Progress`, or `Partial: \u003Cwhat is owed>`), and its pie heading reads `Completed` once every slice in it does. Commit that on the branch as `docs(pie-N): update the checklist for \u003Cscope>` and push; with gitignored plans, edit the primary checkout's copy and commit nothing. In universal mode a project that has a master checklist is no exception: map the changed files to slices through the slice plans that name them. A branch that touches no slice leaves the checklist alone. Use only the status words the parsers read (Completed, In Progress, Not Started, Partial, `waiting until \u003Cdate>: \u003Ccriterion>`); the checklist edit hook reports any line they cannot read. If this step is skipped, the `gh pr create` hook (`hooks\u002Fchecklist-check.sh pr`) adds a warning; it never blocks.\n\n### Phase 2 - Open the Pie PR (or Reuse Existing) *(pie-completion \u002F universal)*\n\n1. **If `EXISTING_PR_NUMBER` from Phase 0 is set**, skip to Phase 3 - the existing PR already tracks this branch.\n2. **Otherwise**, open one PR for the whole pie:\n   - **Title:** for a pie, `Pie N: \u003Cname>` (lift `N` and the name from the `## Pie N - \u003Cname>` checklist header). For a hand-rolled branch, fall back to `gh pr create --fill` (latest commit subject).\n   - `gh pr create --base main --head \"$BRANCH\" --fill` - the `--fill` body lifts the accumulated slice commit subjects\u002Fbodies, so the per-slice closing-narrative paragraphs carry the design story into the PR description without a separate step. For a named pie, set the title explicitly (`--title \"Pie N: \u003Cname>\"`) and keep `--fill` for the body.\n   - **Evidence section (the Pass ledger):** when `bts_pr_body` is available, write its output into the PR body under `## Evidence` after the `--fill` content; the section is generated, do not edit it by hand. Call it once with `{ \"pie\": N }` before `gh pr create`. A `--body` or `--body-file` overwrites what `--fill` would write, so build the body file yourself: the `--fill` content (`git log --reverse --format='%s%n%n%b' origin\u002Fmain..HEAD`), then a blank line and `## Evidence`, then the tool's output verbatim; pass it with `--body-file` and keep `--title`. When the tool is absent, or answers its one-line `bts_pr_body:` message (no ledger, no `node`), open the PR with `--fill` alone and leave the section out. It warns and never blocks: a missing section is not a reason to stop.\n   - Capture the returned URL as `PR_URL` and the number as `PR_NUMBER`.\n3. Output the PR URL to the user immediately so they can open it in a browser if they want to skim the pie.\n4. **No failing gate rides in the body as an open item.** Every enabled gate passed before the pie reached this phase ([`quality-gates.md`](..\u002Fsell-slice\u002Freferences\u002Fquality-gates.md)), so the body never lists one as a follow-up, \"for your decision\" or out of scope. Advisory-class findings (`gates.advisory`) may be listed, labeled advisory.\n\n### Phase 3 - Watch CI *(pie-completion \u002F universal - CI's single run for the pie)*\n\nIn the default `pie-pr` mode this is the **one** time CI fires for the entire pie - per-slice pushes opened no PR. In `slice-merge` mode it is the slice PR's CI run. `gh pr checks \"$PR_NUMBER\" --watch` blocks until every check finishes. Capture the exit code:\n\n- **Exit 0** → all checks passed. Continue to Phase 4.\n- **Non-zero** → at least one check failed. Capture the output (`gh pr checks \"$PR_NUMBER\" --json name,state,bucket,workflow`) and the required set (`gh pr checks \"$PR_NUMBER\" --required --json name`), then **classify each failed check.** It is *advisory* when its gate class is in `gates.advisory` ([`quality-gates.md`](..\u002Fsell-slice\u002Freferences\u002Fquality-gates.md); the class comes from the job name: `lint`, `typecheck`, `build`, unit or integration tests are `tests`, any e2e job `e2e`, `visual` `visual`, `design-system-compliance` `design-system`, an accessibility job `accessibility`, anything else `ci`) **and** it is not a required check. Every other failure is binding, and a failed required check is always binding, whatever `gates.advisory` says.\n  - Any binding failure → Phase 3a, the auto-fix loop, with the binding failures only.\n  - Only advisory failures left → CI counts as green: continue to Phase 4, listing each advisory failure by name, labeled advisory, in the merge prompt and the PR body. Never fix one.\n\nThe skill caps total CI watch time at **30 minutes per attempt**. If `--watch` does not return within 30 minutes (e.g. self-hosted runner hung), surface as `external_credentials` HITL.\n\n#### Phase 3a - CI Fix Loop (on red)\n\nLoop counter starts at 1. Cap at **3 attempts**.\n\n**Every red check is a binding gate.** Dispatch the fix without asking the operator first, and never offer \"merge anyway\", \"fix in a follow-up\" or \"the cause is outside this pie\" as an answer: `ci-fix-attempter` fixes the root cause where it lives, a shared design token or a file the pie only consumes included. A non-required check in a class listed in `gates.advisory` is the one exception (Phase 3 classified it): report it, labeled advisory, and do not fix it; it never enters this loop or counts against its cap. The operator hears about a red required check only at the cap-exhaustion HITL below, or when its fix is destructive or needs a secret.\n\n1. Capture the failed-check rollup: `gh pr checks \"$PR_NUMBER\" --json name,state,link,workflow`, keeping the binding failures only (Phase 3's classification; re-run it after each round).\n2. For each failed check, retrieve logs:\n   - `gh run view \u003Crun-id> --log-failed` for workflow runs, OR\n   - `gh pr view \"$PR_NUMBER\" --comments` for non-Actions checks (e.g. external services posting back).\n3. Dispatch `bytheslice:ci-fix-attempter` ([definition](agents\u002Fci-fix-attempter.md); fallback on hosts without plugin agents: Read the file and dispatch it per [`loop-workflow-fallback-pattern.md`](..\u002Fcook-pizzas\u002Freferences\u002Floop-workflow-fallback-pattern.md) \"Agent shape on the fallback path\": its frontmatter goes first as a header (model tier and effort, the normalized tool allowlist, the read-only line for an agent without write tools, the no-git-writes line), then its body, then the inputs; log one self-check line per dispatch in the run log). Pass:\n   - `PR_NUMBER`, `PR_URL`, `BRANCH`\n   - The failed-check rollup\n   - Truncated log excerpts (last 200 lines per failed job) - let the agent ask for more on demand\n   - The pie diff (`git diff origin\u002Fmain...HEAD`)\n   - The attempt number\n   - `previous_signature`: the `signature` the previous round returned, or `null` on attempt 1\n4. The agent makes no git writes: it returns `files_changed` and a proposed commit subject and body. **This skill** stages exactly those paths (`git add -- \u003Cpaths>`), commits with the proposed message, and pushes to `origin \"$BRANCH\"` (never forced; a rejected push is a `destructive_operation` HITL). Do not call `--watch` from inside the dispatch - the skill returns to Phase 3 (top) after its push lands and re-invokes `gh pr checks --watch` against the new head SHA.\n   When a round's fix changes what a slice delivers, update that slice's `**Status:**` line in the same commit (Phase 1 step 5). If the agent returns `bail_reason: repeated_signature`, it patched nothing because the identical failure survived the last round: stop the loop now, commit and push nothing, and surface the `creative_direction` HITL below. The bail counts as that round and never extends the 3.\n5. Increment the counter. If it would exceed 3, STOP. Surface as `creative_direction` HITL with the full failure history, naming each check still failing, so the user can decide whether to grant more rounds, debug manually, retry CI, or close the PR. This cap-exhaustion HITL is the only place a failing gate is put to the user.\n\nThe 3-attempt cap is a hard rule and is **not overridable by the run instruction**: \"continue until CI is green\", \"never stop\", \"fully automated\" or an autonomous-delivery instruction do not add rounds. Only the operator's explicit reply at this HITL can grant more. The CI counter is per PR and separate from the conductor's 3 local fix loops per slice; neither borrows from the other. One identical repeat already signals a structural problem (flaky test, missing secret, infra outage) that needs human judgment, so the loop stops at the first repeated signature (`normalize(first_error_line) + \" | \" + file + \" | \" + job_name`, a plain string compared by equality and never persisted) instead of counting to three.\n\n### Phase 4 - Merge Authorization Gate *(pie-completion \u002F universal - the kept pie-boundary HITL)*\n\nCI is green, or only advisory, non-required checks are red (Phase 3). **Stop and prompt the user** (this is the §1.8 pie-boundary checkpoint - in the default `pie-pr` mode, the one HITL the loop never auto-approves; `slice-merge` mode has no per-slice merge gate, see \"Merge-per-slice closeout\"):\n\n> \"CI is green on PR `\u003CPR_URL>` (Pie N)\u003C; advisory checks red, not fixed: \u003Cnames>, when any>. Approve merge?\"\n>\n> Options (always include a recommended answer):\n> 1. **Approve and merge now** (recommended if you've already reviewed the pie) - the skill merges **preserving every per-slice commit** (see strategy below) and proceeds to Phase 5.\n> 2. **Hold - keep the PR open for manual review** - the skill exits, leaving the PR open. You merge via the GitHub UI when ready (with the strategy the helper picked: \"Create a merge commit\" when the pie holds empty commits), then re-run `\u002Fbox-it-up --resume` to do cleanup.\n> 3. **Cancel - leave the PR open and stop** - the skill exits without merging.\n\n**Merge strategy - preserve per-slice commits (never squash).** The whole point of the per-slice commits is that they survive the merge as the pie's history. These rules - merge preserving per-slice commits (never squash), `--ff-only` sync, `git worktree remove`\u002F`prune` cleanup, and the boundary-PR body shape - come from [`..\u002Fcook-pizzas\u002Freferences\u002Fgit-worktree-standard.md`](..\u002Fcook-pizzas\u002Freferences\u002Fgit-worktree-standard.md) (Phase 3 + Invariants §5 + the PR template §6). Resolve the strategy with the helper, from the pie branch: `gh repo view --json rebaseMergeAllowed,mergeCommitAllowed,squashMergeAllowed | node \"\u003Cthis-skill-directory>\u002Fpick-merge-strategy.js\" --base origin\u002Fmain` (after `git fetch origin`), and capture the branch's commit subjects for Phase 5 with `SUBJECTS=$(git log --format=%s origin\u002Fmain..HEAD)`. The helper prints one JSON line, `{ strategy, reason, emptyCommits }`, by these rules (with `--mode slice-merge` or `--mode ship` it skips them and always answers a merge commit, `reason: merge-commit-required`, or `strategy: none`, `reason: merge-commits-disallowed`):\n\n1. **Empty commits force a merge commit.** GitHub's rebase-merge drops a commit whose tree equals its parent's, so a slice-close commit made with `--allow-empty` would vanish from `main`. When the branch holds one (`reason: empty-commits`), use a **merge commit** (`gh pr merge \"$PR_NUMBER\" --merge`). If merge commits are disallowed (`strategy: none`, `reason: empty-commits-need-merge-commit`), STOP and surface `prd_ambiguity`: *\"This pie has N empty slice-close commits that a rebase-merge would drop. Enable merge commits, or confirm you accept losing them.\"*\n2. **Otherwise prefer rebase-merge** for a pie PR (`gh pr merge \"$PR_NUMBER\" --rebase`; a slice PR in `slice-merge` mode always uses a merge commit instead) - replays each slice commit onto main, linear history, every `feat(pie-N): N.M` preserved.\n3. If rebase is disallowed (`reason: rebase-disallowed`), use a **merge commit** (`gh pr merge \"$PR_NUMBER\" --merge`) - also preserves the individual commits under a merge node.\n4. **Never `--squash`** for a pie - squashing collapses the per-slice commits into one and destroys the boundary contract. If a project's settings allow *only* squash (the helper's `reason: squash-only`), STOP and surface as `needs_human: true` with `hitl_category: prd_ambiguity`: *\"This repo only permits squash merges, which would collapse the pie's per-slice commits. Enable rebase or merge-commit merges, or confirm you accept a squash for this pie.\"* For a **hand-rolled** branch with no per-slice contract, the project default (including squash) is acceptable - the preserve-commits rule binds pies, not arbitrary branches.\n\nNever force-merge a PR with non-required failing checks unless the user explicitly authorizes via the HITL prompt.\n\n### Phase 5 - Post-merge Cleanup *(pie-completion \u002F universal)*\n\nOnly runs after the PR is merged (by this skill in Phase 4 option 1, or by the user manually before `\u002Fbox-it-up --resume`).\n\n1. `gh pr view \"$PR_NUMBER\" --json state,number,mergedAt` - confirm state is `MERGED`. If not, STOP. Don't pull or delete branches on a falsely-assumed merge.\n   - **Pie-completion mode only, before cleanup:** record the confirmed merge for the local kitchen. Pipe a fresh successful `gh pr view \"$PR_NUMBER\" --json state,number,mergedAt` response to `node \"\u003Cthis-skill-directory>\u002Frecord-kitchen-merge.js\" --mode pie --pie \"\u003Cactive-pie-number>\" --project \"${CLAUDE_PROJECT_DIR:-$PWD}\"`. The helper validates `MERGED`, a PR number and a merge timestamp, then atomically replaces the single bounded `.claude\u002F.bytheslice-state\u002Fkitchen\u002Fmerged-pie.json` record with only version, pie, PR number and merge time. Use this skill's installed absolute directory for the helper path. If the read or write fails, report missing kitchen evidence; do not invent success.\n   - **Slice-merge mode:** run the same writer exactly once per pie, after the pie's **last** slice PR merges, piping that PR's `gh pr view` response with `--mode pie --pie \"\u003Cactive-pie-number>\"`. Never per slice.\n   - Never run this writer in `--slice` or universal mode, for any slice-merge slice but the pie's last, before merge confirmation, or from skill\u002FStop log events. A skill finish cannot prove a PR merged. The kitchen reader makes no network calls and ignores malformed, stale, future or wrong-pie records.\n**Every step after the merge check runs from the primary checkout, never from the pie worktree.** `main` is checked out in the primary checkout, so `git checkout main` inside the pie worktree fails, and git refuses to delete a branch a worktree still holds. Resolve the primary checkout once: `PRIMARY=$(git worktree list --porcelain | sed -n '1s\u002F^worktree \u002F\u002Fp')` (the first entry is always the main working tree). The Pie's checklist flip is already committed on the branch (Phase 1 step 4), so nothing here edits a tracked file.\n\n2. `cd \"$PRIMARY\"` so the shell is not inside the worktree about to be removed. If `IS_WORKTREE` was false (the branch was checked out in the primary checkout itself), run `git -C \"$PRIMARY\" checkout main`; if that would overwrite uncommitted changes, STOP and surface as `destructive_operation` HITL. Then confirm `git -C \"$PRIMARY\" rev-parse --abbrev-ref HEAD` is `main` and `git -C \"$PRIMARY\" status --short` is empty. If the primary checkout sits on another branch or is dirty, STOP (`destructive_operation`): never switch, stash or overwrite a checkout the operator may be using.\n3. `git -C \"$PRIMARY\" pull --ff-only origin main` - fast-forward only. If this fails (history diverged), STOP and surface as `destructive_operation` HITL.\n4. Confirm the PR's merge result is now in local main: `git -C \"$PRIMARY\" log --oneline | grep -q \"$PR_NUMBER\\|\u003Cmerge sha>\"`, then confirm every branch commit subject captured in Phase 4 (`SUBJECTS`) appears in `git -C \"$PRIMARY\" log --format=%s`. If any is absent, STOP and surface - something's odd.\n5. **Remove the pie worktree first (if `IS_WORKTREE` from Phase 0 was true):** `git -C \"$PRIMARY\" worktree remove \"$WORKTREE_PATH\"` (never `rm -rf`). This must precede the branch delete: git refuses to delete a branch that a worktree still has checked out.\n6. `git -C \"$PRIMARY\" branch -d \"$BRANCH\"` - delete the local pie branch (safe delete; refuses if unmerged commits exist, which is what we want). After a rebase-merge the commits on `main` carry new SHAs, so `-d` passes only while the branch's upstream ref still exists; if it refuses, confirm step 4 found every slice commit subject on `main` and surface `destructive_operation` before any `-D`.\n7. `git push origin --delete \"$BRANCH\"` - delete the remote branch. If GitHub auto-deleted it on merge (or `gh pr merge --delete-branch` did), this returns \"remote ref does not exist\" - fine; record it but don't fail. From a worktree, run `gh pr merge` without `--delete-branch`: that flag also tries to switch the local checkout to `main`, which the primary checkout holds.\n8. `git -C \"$PRIMARY\" worktree prune` - clear stale worktree metadata.\n9. `git -C \"$PRIMARY\" status --short` - must be empty. `git -C \"$PRIMARY\" rev-parse --abbrev-ref HEAD` - must be `main`. `git -C \"$PRIMARY\" status -uno` - confirm fully synced with remote. The pie is closed; the next pie starts in a fresh chat with a fresh worktree.\n\n### Phase 6 - Final Report *(pie-completion \u002F universal)*\n\nSurface to the user:\n- PR URL + merge commit SHA (+ note the merge strategy used: rebase \u002F merge-commit, and why when the helper picked a merge commit for empty commits)\n- Pie name + branch name (now deleted) + worktree path (now removed)\n- Slice and task commit count preserved on main\n- Total CI attempts (1 if green on first run; up to 3 if the fix loop ran) + ci-fix-attempter dispatch count \u002F per-attempt summary if applicable\n- Final state: \"On main, clean tree, fully synced with origin\u002Fmain. Pie N closed - start the next pie in a fresh chat.\"\n\n### Merge-per-slice closeout *(slice-merge mode, `--merge-slice`)*\n\nRuns once per slice when `delivery.mode` resolves to `merge-per-slice`. The conductor (`\u002Fsell-pie` or `\u002Fsell-slice`) invokes it internally and passes `BRANCH` (`pie-N-sN.M-\u003Cscope>`), `WORKTREE_PATH` (the slice worktree), the slice id and name, and whether this is the pie's last slice. Phases 0 → 6 apply with these overrides:\n\n- **Phase 0.** Run steps 1-6 against the slice worktree (`git -C \"$WORKTREE_PATH\" ...`). Skip step 7 (pie completeness). Add: `gh repo view --json mergeCommitAllowed --jq .mergeCommitAllowed` must print `true`. If it does not, STOP the loop with `needs_human: true`, `hitl_category: prd_ambiguity`: *\"This repo disallows merge commits, which merge-per-slice delivery requires. Enable merge commits, or rerun this pie in the default one-PR-per-pie mode?\"* Never fall back to squash or rebase on its own.\n- **Phase 1.** The slice's work is already committed and pushed on `BRANCH`. On the pie's last slice, Phase 1 step 4 applies: flip `## Pie N` to `Completed`, commit, push, so the flip reaches `main` with this slice's merge. With a gitignored checklist (the default) there is nothing to commit: flip `$PLANS\u002F00_master_checklist.md` in the primary checkout only after the Phase 4 merge, so a slice that stays red never marks its pie done. If any slice of the pie is still `waiting until \u003CYYYY-MM-DD>` (calendar-gated), this is not the last slice: do not flip the pie and do not write the kitchen merge record; the slice PR that later closes the waiting slice is the pie's last.\n- **Phase 2.** Title the PR `Slice N.M: \u003Cname>`: `gh pr create --base main --head \"$BRANCH\" --title \"Slice N.M: \u003Cname>\" --fill`.\n- **Phase 3 \u002F 3a.** Watch CI as usual, classifying failed checks as Phase 3 does. On a binding failure, up to **3** `ci-fix-attempter` rounds (the CI fix counter is per slice); advisory, non-required failures alone count as green and are listed in the slice notice. Still red after the 3rd round, or a round that bails on a repeated signature: **halt the loop** with a `creative_direction` HITL carrying the failure history. Never skip the slice, never merge it red, never start the next slice.\n- **Phase 4.** No human merge gate: the run instruction or `delivery.mode` already authorized autonomous delivery. On green, merge with a **merge commit**: `gh pr merge \"$PR_NUMBER\" --merge` (never `--squash`, never `--rebase`, never `--delete-branch` from the worktree).\n- **Phase 5.** Identical cleanup from the primary checkout: `git -C \"$PRIMARY\" pull --ff-only origin main`, `git -C \"$PRIMARY\" worktree remove \"$WORKTREE_PATH\"`, `git -C \"$PRIMARY\" branch -d \"$BRANCH\"`, `git push origin --delete \"$BRANCH\"`, `git -C \"$PRIMARY\" worktree prune`. Write the kitchen merge record only after the pie's last slice (see Phase 5 step 1). Append one line to the run log `.claude\u002F.bytheslice-state\u002Frun-log.md` (gitignored): slice id, PR URL, merge commit SHA, merge time.\n- **Phase 6.** Return a short per-slice result to the conductor (PR URL, merge SHA, CI rounds). The conductor cuts the next slice from the freshly synced `main`; on the pie's last slice it sends the operator **one** notice listing every slice PR from the run log.\n\n### Pie-local closeout *(pie-local mode, `--pie-local`)*\n\nRuns once per pie when `delivery.mode` resolves to `ship-once`. The `\u002Fsell-pie` conductor invokes it internally and passes `BRANCH` (`pie-\u003Cn>-\u003Cscope>`), `WORKTREE_PATH` (the pie worktree), `SHIP` (the ship branch), the pie number and name, `run.unattended`, and any slices it deferred. Phases 2-4 do not run: there is no PR, no push and no CI. All gates are local.\n\n1. **Pre-flight.** Resolve `PRIMARY=$(git worktree list --porcelain | sed -n '1s\u002F^worktree \u002F\u002Fp')` and `$PLANS` per [`git-worktree-standard.md`, \"Where the plans live\"](..\u002Fcook-pizzas\u002Freferences\u002Fgit-worktree-standard.md). Confirm `git -C \"$PRIMARY\" rev-parse --abbrev-ref HEAD` is `SHIP`, `git -C \"$PRIMARY\" status --short` is empty, `git -C \"$WORKTREE_PATH\" status --short` is empty, and `BRANCH` is neither `main` nor `SHIP`. A failure is a `destructive_operation` HITL (never switch, stash or overwrite the primary checkout).\n2. **Verified-slice check.** Every `### Slice N.M` under `## Pie N` in `$PLANS\u002F00_master_checklist.md` must be `[x]` **and** have a `slice-verifier` pass in the Pass ledger (`bts_status` shows each slice's last verdicts; without the tool, look for the slice's `slice-verifier` pass in `$PRIMARY\u002F.bytheslice\u002Fledger.jsonl`). With no ledger at all, trust the checklist and say so in the report. A `deferred:` slice (unattended only) must have no commit on the branch: no subject in `git -C \"$PRIMARY\" log --format=%s \"$SHIP\"..\"$BRANCH\"` names `N.M`. A slice that fails this check means the merge would carry unverified work into the ship PR.\n3. **Full local check, once, on the pie branch.** In `WORKTREE_PATH`, run the same commands `slice-verifier` runs on its first pass under ship-once ([definition](..\u002Fsell-slice\u002Fagents\u002Fslice-verifier.md), \"Which commands run\"): the **CI command list** parsed from the project's generated `.github\u002Fworkflows\u002Fci.yml` and then, when it exists, `.github\u002Fworkflows\u002Fe2e.yml` (every `run:` step, jobs in `needs:` order, environment setup skipped, a literal `origin\u002Fmain...HEAD` replaced with `\"$SHIP\"...HEAD`), so this check and the ship PR's CI run the same commands, every one of them, never a subset. Read `quality.tier` from `bytheslice.config.json` (`auto` resolves as `\u002Ffinal-quality-check` \"Quality tier\" documents). Under `lean` that list is lint, typecheck, unit tests, build, `check:design-system` only when a design system exists, and `test:e2e:smoke`; never run `test:e2e:feature`, `test:e2e:regression` or `test:e2e:visual` under lean, since lean CI does not. Under `standard`, that list includes every e2e suite `e2e.yml` runs (`@feature`, `@regression-core` and `@visual`), in full: `verification.e2e.*` does not narrow it, because CI does not read those thresholds. With no `ci.yml` yet, fall back to `\u003Cpm> lint`, `\u003Cpm> typecheck`, `\u003Cpm> build`, `\u003Cpm> test`, `\u003Cpm> check:design-system` when it exists and the tier's e2e gate, with the package manager from the lockfile (`pnpm-lock.yaml`, `package-lock.json`, `yarn.lock`, `bun.lock` \u002F `bun.lockb`) and the actual script names from `package.json` (they may be non-standard, e.g. `check-types`), and say so. Skip a script the project does not define and say so. Run each once and continue past a failure so the full picture is known. All green: go to step 5. Every other generated workflow that runs on pull requests (`e2e-coverage.yml`, `db-schema-drift.yml`, `design-system-compliance.yml`, when present) runs too, so nothing can fail only in CI on the ship PR.\n4. **Fix rounds (on red).** First classify each failed command as Phase 3 classifies a check, by the job it came from: one whose gate class is in `gates.advisory` is advisory (listed, labeled advisory, in the ship PR body, never fixed, outside this cap) unless branch protection on `main` requires that job (`gh api repos\u002F{owner}\u002F{repo}\u002Fbranches\u002Fmain\u002Fprotection --jq '.required_status_checks.contexts'`, when readable), which keeps it binding. Only advisory failures left: the check counts as green, go to step 5. Counter starts at 1, cap **3**, separate from every slice's local fix loops and from the CI rounds. Dispatch `bytheslice:fix-attempter` ([definition](..\u002Fsell-slice\u002Fagents\u002Ffix-attempter.md); fallback per [`loop-workflow-fallback-pattern.md`](..\u002Fcook-pizzas\u002Freferences\u002Floop-workflow-fallback-pattern.md) \"Agent shape on the fallback path\") with the failing checks as its verdict (check, command, exit code, last ~50 lines of output), the pie diff (`git -C \"$WORKTREE_PATH\" diff \"$SHIP\"...HEAD`), the round number and `previous_signature` (`normalize(first_error_line) + \" | \" + file + \" | \" + check`, never persisted). It returns `files_changed`; this skill stages exactly those paths, commits them on `BRANCH` as `fix(pie-N): pie-local check round K \u003Ccheck>` (no push), and re-runs the full local check (a round is one fix plus one full check, like a CI round). A `repeated_signature` bail ends the loop at once and counts as that round. Still red after round 3:\n   - **Interactive:** `creative_direction` HITL with the failure history; the pie is not merged.\n   - **Unattended (`run.unattended: true`):** do not ask. Leave the pie branch and worktree in place, unmerged, record the blocker `{pie: \"N\", reason: \"pie-local check red after 3 rounds: \u003Cchecks>\", attempts: 3}` with one `bts_note`, and return `status: complete_with_deferrals`.\n5. **Flip the pie status.** Tracked plans: set `## Pie N` to `Completed` on `BRANCH`, commit `chore(pie-N): mark Pie N completed`. Gitignored plans (the default): flip `$PLANS\u002F00_master_checklist.md` after step 6 succeeds, no commit. With deferred slices (unattended) the status reads `Completed (deferred: N.M, N.K)`.\n6. **Merge into the ship branch, preserving every slice commit.** Capture `SUBJECTS=$(git -C \"$PRIMARY\" log --format=%s \"$SHIP\"..\"$BRANCH\")`, then from the primary checkout: `git -C \"$PRIMARY\" merge --no-ff -m \"merge(pie-N): Pie N \u003Cname> into $SHIP\" \"$BRANCH\"`. Never squash, never rebase, never fast-forward. The subject names no slice id, so the PR evidence does not read the merge commit as an unverified slice. Confirm every line of `SUBJECTS` appears in `git -C \"$PRIMARY\" log --format=%s \"$SHIP\"`. A conflict (unexpected: the ship branch moves only through these merges, and the pie was cut from its tip) is `git -C \"$PRIMARY\" merge --abort`, then a `destructive_operation` HITL (interactive) or a pie blocker (unattended); never auto-resolve.\n7. **Cleanup from the primary checkout.** `git -C \"$PRIMARY\" worktree remove \"$WORKTREE_PATH\"`, then `git -C \"$PRIMARY\" branch -d \"$BRANCH\"` (safe: it is merged into the checked-out ship branch), then `git -C \"$PRIMARY\" worktree prune`. No remote delete: the pie branch was never pushed. Leave any `deferred\u002Fpie-N-sN.M` branch in place for the conductor. Append one line to the run log `.claude\u002F.bytheslice-state\u002Frun-log.md`: pie, ship-branch merge SHA, check rounds, deferred slices. No kitchen merge record here (no PR merged); `--ship` writes it.\n8. **Return** a short result to the conductor: merge SHA, check rounds, deferred slices and blockers, and whether this was the checklist's last pie.\n\n### Ship closeout *(ship mode, `--ship`)*\n\nRuns once, after the last pie of a ship-once build has merged into the ship branch. An interactive `\u002Fsell-pie` invokes it after its last `--pie-local`; in an unattended run the `\u002Fpizza-party` conductor invokes it after its replan. The caller passes `SHIP`, the app name (default: `SHIP` without its `ship\u002F` prefix), `run.unattended`, and the `blocked` list collected across the build. Phases 0 → 6 apply from the primary checkout with these overrides:\n\n- **Phase 0.** `BRANCH` is `SHIP`; confirm the primary checkout is on it and clean. Skip step 7 (pie completeness); instead confirm every `## Pie N` in `$PLANS\u002F00_master_checklist.md` is `Completed` (interactive: an unmerged pie is a `prd_ambiguity` HITL, \"ship without Pie N?\"; unattended: proceed and list it as a blocker). Run steps 4-6 as written (`gh auth status` is the one ship-once `gh` check). Resolve the merge strategy now: `gh repo view --json rebaseMergeAllowed,mergeCommitAllowed,squashMergeAllowed | node \"\u003Cthis-skill-directory>\u002Fpick-merge-strategy.js\" --base origin\u002Fmain --mode ship` (after `git fetch origin`) always picks a merge commit; `reason: merge-commits-disallowed` is a `prd_ambiguity` HITL (interactive) or a blocker returned before anything is pushed (unattended).\n- **Phase 1.** Nothing to commit. `git -C \"$PRIMARY\" push -u origin \"$SHIP\"`; a rejected push is a `destructive_operation` HITL (interactive) or a blocker (unattended), never a force-push.\n- **Phase 2.** Title `Ship \u003Capp>: \u003Cpies> pies, \u003Cslices> slices`, counting the pies merged into the ship branch (`merge(pie-N)` merge commits in `origin\u002Fmain..$SHIP`) and the slices `[x]`. Build the body file: the commit story (`git log --reverse --no-merges --format='%s%n%n%b' origin\u002Fmain..\"$SHIP\"`), a blank line, `## Evidence`, then for **every** merged pie a `### Pie N` heading and `bts_pr_body({ \"pie\": N })` output verbatim (omit the section when the tool is absent), then `## Deferred` listing every `blocked` entry and the design-critique findings recorded as deferred (omit when empty). `gh pr create --base main --head \"$SHIP\" --title \"\u003Ctitle>\" --body-file \u003Cfile>`. Every slice named on the branch must carry a `slice-verifier` pass in the ledger, which deferral guarantees (it keeps unverified commits off the branch). If one does not, surface its slice list (`prd_ambiguity`, interactive) or return it as a blocker (unattended) instead of opening the PR.\n- **Phase 3 \u002F 3a.** Watch CI once (30-minute cap per attempt), classifying failed checks as Phase 3 does; on a binding failure, up to **3** `ci-fix-attempter` rounds committed and pushed on `SHIP` from the primary checkout (advisory, non-required failures alone count as green and are listed in the ship PR body). Still red after round 3, or a `repeated_signature` bail: interactive, the `creative_direction` HITL as usual; **unattended, leave the PR open**, record the blocker `{pie: \"ship\", reason: \"ship PR CI red after 3 rounds: \u003Cchecks>\", attempts: 3, pr: \"\u003CPR_URL>\"}` and return `status: complete_with_deferrals` without merging. A PR GitHub reports as conflicting with `main` (`gh pr view --json mergeable` is `CONFLICTING`) is handled the same way, as a `destructive_operation` HITL or a blocker; never auto-resolve.\n- **Phase 4.** No human merge gate: choosing ship-once authorized the merge. On green, `gh pr merge \"$PR_NUMBER\" --merge` (the strategy from Phase 0; never `--squash`, never `--rebase`, which would drop the pie merge commits; never `--delete-branch`, since the primary checkout holds `SHIP`).\n- **Phase 5.** Capture `SUBJECTS=$(git -C \"$PRIMARY\" log --format=%s origin\u002Fmain..\"$SHIP\")` before the merge. After `gh pr view` confirms `MERGED`, write the kitchen merge record once with `--mode pie --pie \"\u003Clast pie number>\"`. Then, from the clean primary checkout: `git -C \"$PRIMARY\" switch main`, `git -C \"$PRIMARY\" pull --ff-only origin main`, confirm every `SUBJECTS` line is in `git -C \"$PRIMARY\" log --format=%s`, `git -C \"$PRIMARY\" branch -d \"$SHIP\"`, `git push origin --delete \"$SHIP\"`, `git -C \"$PRIMARY\" worktree prune`. Pie worktrees are already gone; any pie left unmerged by an unattended blocker keeps its worktree and is listed in the report. `deferred\u002F*` branches stay for the conductor.\n- **Phase 6.** Report the ship PR URL, the merge SHA and strategy, pies and slices shipped, CI rounds, and every blocker; return `status: complete`, or `complete_with_deferrals` when `blocked` is not empty.\n\n---\n\n## HITL Handling\n\n**Agents and this skill never call `ask_user_input_v0`.** At every elicitation point - the Phase 1 commit prompt and the Phase 4 merge-authorization gate - the skill **sets `needs_human: true` plus the `hitl_*` fields in its return contract** and lets the invoking orchestrator (`\u002Fsell-pie`'s loop, or the operator's session) surface the prompt. The phase descriptions above show the question text; the skill emits it as `hitl_question`, not as a direct tool call.\n\nFor sub-agent failures (e.g. `ci-fix-attempter` returns `needs_human: true`), the skill bubbles the structured fields up via its own return contract - it does not retry indefinitely.\n\n**Unattended ship-once runs never ask.** In `pie-local` and `ship` mode with `run.unattended: true`, every point below that would set `needs_human` instead records a blocker in `blocked` (`{slice | pie, reason, attempts}`, plus `pr` when a ship PR is left open), leaves the git state as it is (an unmerged pie keeps its branch and worktree; a red ship PR stays open), and returns `status: complete_with_deferrals` to the conductor. Fix caps never rise. Interactive runs behave exactly as described below.\n\nHITL categories the skill produces:\n- `destructive_operation` - about to push from main, force-push detected, merge-conflict pull, branch-reuse without rename, would-overwrite uncommitted changes on checkout.\n- `external_credentials` - `gh` not authenticated, CI watch timeout (likely runner \u002F secrets issue).\n- `creative_direction` - ci-fix-attempter exhausted 3 attempts or bailed on a repeated signature; user decides whether to debug, retry, or close the PR. In `slice-merge` mode this halts the delivery loop. In `pie-local` mode, the full local check still red after 3 `fix-attempter` rounds.\n- `prd_ambiguity` - boxing a pie with unfinished slices; a squash-only repo that would collapse per-slice commits; a repo that disallows merge commits in `slice-merge` mode; a precondition that needs the user to tell the skill how to interpret state.\n\n---\n\n## Hard Constraints\n\n- **Per-slice mode opens no PR and watches no CI.** Commit + push only, then return. In the default `pie-pr` mode CI fires exactly **once per pie**, at the boundary, and no PR opens mid-pie. **Exception:** `slice-merge` mode (`delivery.mode: merge-per-slice`) opens, CI-checks and merges one PR per slice.\n- **Preserve per-slice commits on a pie merge - never `--squash`.** Default mode: rebase-merge for the pie PR, merge-commit as fallback, and always a merge commit when the branch holds an empty commit (rebase-merge drops it; `pick-merge-strategy.js` decides). `slice-merge` mode: always a merge commit; a repo that disallows merge commits is a `prd_ambiguity` HITL. A squash-only repo is a `prd_ambiguity` HITL, not a silent squash.\n- **Ship-once: no human merge gate, local gates per pie, CI once at the end.** `pie-local` merges the pie into the ship branch only after every non-deferred slice has a `slice-verifier` pass and the full local check is green (at most 3 `fix-attempter` rounds), with `git merge --no-ff` (never squash, rebase or fast-forward), and never pushes. `ship` pushes the ship branch, opens one PR, merges it with a merge commit only on green CI (at most 3 `ci-fix-attempter` rounds), then syncs `main` and deletes the ship branch. Unattended runs return blockers instead of asking, and leave a red ship PR open.\n- **No per-slice merge approval in `slice-merge` mode; never merge red.** The slice merges only on green CI, after at most 3 `ci-fix-attempter` rounds; still red halts the loop. There is never an integration branch.\n- **One worktree per pie (default and ship-once) or per slice (`slice-merge`); `\u002Fbox-it-up` only removes it.** The worktree is created upstream by the conductor. This skill removes it after the merge (via `git worktree remove` + `prune`, never `rm -rf`) and never creates one. The merge\u002Fcleanup rules here are the standard's - see [`..\u002Fcook-pizzas\u002Freferences\u002Fgit-worktree-standard.md`](..\u002Fcook-pizzas\u002Freferences\u002Fgit-worktree-standard.md) (Phase 3 + Invariants §5).\n- **Never ship from `main` \u002F `master`.** Phase 0 step 2 is a stop-everything check. `--ship` ships from the ship branch; `--pie-local` writes only the pie merge commit on it.\n- **Never force-push.** If `git push` is rejected for non-fast-forward, STOP. The user resolves on a fresh branch.\n- **Only the conductor makes git writes, `git add` included.** `ci-fix-attempter` returns `files_changed`; this skill stages those paths selectively, commits and pushes, on the registered and fallback paths alike. Never `git add -A`.\n- **Never auto-merge a PR with failing required checks.** Phase 4 only runs when CI is green on the latest head SHA.\n- **Never box an incomplete pie.** If any slice under the active Pie is still `[ ]`, STOP (`prd_ambiguity`).\n- **Never `git stash` on the user's behalf.** If `git checkout main` would overwrite uncommitted changes, STOP.\n- **Clean up from the primary checkout, in order.** Sync `main` with `git -C \"$PRIMARY\" pull --ff-only`, then `worktree remove`, then `branch -d`, then the remote delete, then `worktree prune`. Never check out `main` inside a worktree, and never delete a branch a worktree still holds.\n- **Never edit a tracked file on `main`.** The Pie's checklist flip is committed on the pie branch before the PR opens.\n- **Never auto-resolve merge conflicts during cleanup pull.** `--ff-only` fails fast; the user resolves.\n- **Red checks are binding gates.** Fix them through Phase 3a without asking, root cause fixed where it lives; never merge red, never park a failing check as a follow-up or \"out of scope\". Only a class in `gates.advisory` is reported instead of fixed.\n- **Cap the CI fix loop at 3 attempts.** Beyond that → HITL `creative_direction`. No \"one more try.\" No run instruction raises the cap; only the operator's explicit reply at the HITL does. Separate from the 3 local fix loops per slice. The `pie-local` check rounds are their own counter with the same cap of 3 and the same rule.\n- **Cap CI watch at 30 minutes per attempt.** Beyond that → HITL `external_credentials`.\n- **Reuse existing PRs.** If an open PR already tracks the branch, watch its CI; never create a duplicate.\n- **Never call `ask_user_input_v0`.** Set `needs_human` + `hitl_*` and let the orchestrator prompt.\n- **Subagent prompts live in `.\u002Fagents\u002F*.md`.** This SKILL.md is workflow only - never inline subagent prompts here.\n- **Always provide a recommended answer in available options** at every elicitation point.\n\n---\n\n## Triggers\n\nFollow this skill whenever the user (or `\u002Fsell-pie`'s loop):\n\n- runs `\u002Fbox-it-up` (pie-completion \u002F universal closeout) or `\u002Fbox-it-up --slice` (per-slice commit + push)\n- is a ship-once conductor at a pie boundary (`--pie-local`) or after the last pie (`--ship`)\n- says \"box up the pie\", \"close out the pie\", \"ship the pr\", \"submit the pr\", \"open and merge the pr\", \"ship this branch\", \"ship this pie\"\n- has finished every slice of a Pie under `\u002Fsell-pie` and reached the pie boundary\n- has a hand-rolled feature branch ready to ship (universal closeout)\n\nIf the working tree is on `main` with no feature branch in sight, redirect to `\u002Fsell-pie` (autonomous, whole pie) or `\u002Fsell-slice` (one careful slice) first.\n\nIf the user wants to open the boundary PR but pause before merging for code review, they should pick option 2 (Hold) at the Phase 4 gate.\n\n---\n\n## Completion Checklist\n\nWalk the checklist that matches the mode. Do not report done until every applicable box is `[x]`.\n\n### Per-slice mode\n\n- [ ] Current branch confirmed not `main` \u002F `master` (it is the pie branch).\n- [ ] Slice closed with a `feat(pie-N): N.M \u003Cname>` (or fix\u002Fchore\u002Fdocs) final commit on top of its pushed task commits; tree clean.\n- [ ] Branch pushed to `origin`.\n- [ ] No PR opened, no CI watched - returned cleanly so the loop continues.\n\n### Slice-merge mode\n\n- [ ] Repo allows merge commits (`mergeCommitAllowed` true), or the loop halted and asked.\n- [ ] Checklist reconciled before the PR opened (Phase 1 step 5): the slice reads `Completed`.\n- [ ] PR `Slice N.M: \u003Cname>` opened against `main`.\n- [ ] CI green on the latest head SHA (at most 3 `ci-fix-attempter` rounds; still red halted the loop).\n- [ ] Merged with a merge commit, no squash, no rebase.\n- [ ] Cleanup ran from the primary checkout: `pull --ff-only`, `worktree remove`, `branch -d`, remote delete, `worktree prune`.\n- [ ] Run-log line appended; kitchen merge record written only after the pie's last slice.\n\n### Pie-local mode (ship-once)\n\n- [ ] Primary checkout clean and on the ship branch; pie worktree clean.\n- [ ] Every slice `[x]` with a `slice-verifier` pass (or, unattended, `deferred:` with no commit on the branch).\n- [ ] Full local check ran once on the pie branch (every command `ci.yml` and, under standard, `e2e.yml` run, in full; lean: smoke spec only, never `@feature` \u002F `@regression-core` \u002F `@visual`) and is green (at most 3 `fix-attempter` rounds), or the pie was left unmerged with a HITL (interactive) or a blocker (unattended).\n- [ ] Pie merged into the ship branch with `git merge --no-ff`; every pie commit subject found on the ship branch; nothing pushed.\n- [ ] Pie worktree removed, pie branch deleted with `-d`, `worktree prune` ran; pie status flipped; run-log line appended.\n\n### Ship mode (ship-once)\n\n- [ ] Every pie `Completed` on the ship branch (or, unattended, listed as a blocker), and the checklist reconciled before the PR opened (Phase 1 step 5).\n- [ ] Repo allows merge commits (`pick-merge-strategy.js --mode ship` picked `merge`).\n- [ ] Ship branch pushed; one PR `Ship \u003Capp>: \u003Cpies> pies, \u003Cslices> slices` opened against `main` with a `### Pie N` evidence block per pie and a `## Deferred` section when anything was deferred.\n- [ ] CI green (at most 3 `ci-fix-attempter` rounds) and merged with a merge commit, no human gate; or, unattended and still red, the PR left open and reported as a blocker.\n- [ ] Kitchen merge record written once; `main` synced `--ff-only` in the primary checkout; ship branch deleted local and remote; `worktree prune` ran.\n\n### Pie-completion \u002F universal mode\n\n#### 1. Pre-flight passed\n\n- [ ] Current branch confirmed not `main` \u002F `master`.\n- [ ] Worktree state captured (path + IS_WORKTREE flag).\n- [ ] No accidental reuse of a recently-merged branch.\n- [ ] `gh` authenticated.\n- [ ] (pie mode) Every slice under the active Pie is `[x]`.\n\n#### 2. Pie PR open\n\n- [ ] Checklist reconciled before the PR opened (Phase 1 step 5): every slice the diff delivers or changes carries its true `**Status:**`, also in universal mode when a checklist exists.\n- [ ] Any straggler changes committed; branch pushed to `origin`.\n- [ ] (pie mode) Pie status flipped `In Progress` → `Completed` and committed on the pie branch before the PR opened.\n- [ ] One PR open against `main` - titled `Pie N: \u003Cname>` for a pie (or reused existing).\n- [ ] PR URL surfaced to the user.\n\n#### 3. CI green on the merged head SHA\n\n- [ ] `gh pr checks \u003Cpr> --watch` returned exit 0 (CI's single run for the pie).\n- [ ] If the auto-fix loop ran, the final attempt cleared green; ci-fix-attempter dispatch history captured.\n- [ ] No required check skipped or pending.\n\n#### 4. Merge authorized + completed (preserving slice commits)\n\n- [ ] Phase 4 user prompt surfaced (via `needs_human`\u002F`hitl_*`) and answered.\n- [ ] Merge used rebase or merge-commit - **not** squash for a pie; per-slice commits preserved on main.\n- [ ] PR state is `MERGED` per `gh pr view`.\n\n#### 5. Branch + worktree cleanup\n\n- [ ] Cleanup ran from the primary checkout (`git -C \"$PRIMARY\" ...`), which is on `main`.\n- [ ] `git -C \"$PRIMARY\" pull --ff-only origin main` succeeded.\n- [ ] Pie worktree removed via `git worktree remove` (if a worktree was used), before the branch delete.\n- [ ] Local pie branch deleted (`git branch -d`).\n- [ ] Remote pie branch deleted (or already auto-deleted by GitHub).\n- [ ] `git worktree prune` ran.\n- [ ] `git status --short` empty in the primary checkout; `git status -uno` confirms fully synced with `origin\u002Fmain`.\n\n#### 6. Final report emitted\n\n- [ ] User received the report (PR URL, merge SHA + strategy, slice-commit count, attempt counts, \"Pie N closed - next pie in a fresh chat\").\n\n---\n\n## Sub-agent return contract\n\n`\u002Fbox-it-up` returns structured fields whether it ran per-slice or boxed the whole pie (e.g. when `\u002Fsell-pie`'s loop invokes it). It never prompts the user directly - the orchestrator reads `needs_human` + `hitl_*` and surfaces any question.\n\n```yaml\nstatus: complete | complete_with_deferrals | failed | needs_human   # complete_with_deferrals: unattended pie-local \u002F ship recorded a blocker instead of asking\nmode: slice | slice-merge | pie | universal | pie-local | ship\nsummary: \u003Cone paragraph - mode; for slice: commit sha + branch; for slice-merge: slice PR URL + number, CI rounds, merge commit SHA, cleanup state; for pie: pie name, PR URL + number, CI attempt count, merge strategy + SHA, per-slice-commit count preserved, cleanup state; for pie-local: pie name, local check rounds, ship-branch merge SHA, deferred slices, cleanup state; for ship: ship PR URL + number, pies and slices shipped, CI rounds, merge SHA, cleanup state>\nartifacts:\n  - \u003Ccommit sha (slice mode)>\n  - \u003Cpr url (slice-merge\u002Fpie\u002Funiversal\u002Fship mode)>\n  - \u003Cmerge commit sha (slice-merge\u002Fpie\u002Funiversal\u002Fpie-local\u002Fship mode)>\nlocal_check_rounds: null | \u003Cint>    # pie-local only: fix rounds used (0 when green on the first run)\nlast_pie: null | false | true       # pie-local only: every pie in the checklist is now merged into the ship branch (or deferred, unattended)\nblocked: [] | [{slice: \"\u003CN.M>\", reason: \"\u003Cone line>\", attempts: \u003Cint>} | {pie: \"\u003CN>\" | \"ship\", reason: \"\u003Cone line>\", attempts: \u003Cint>, pr: \"\u003Curl, ship only>\"}]   # unattended pie-local \u002F ship only\nneeds_human: false | true\nhitl_category: null | \"prd_ambiguity\" | \"external_credentials\" | \"destructive_operation\" | \"creative_direction\"\nhitl_question: null | \"\u003Cplain-language question>\"\nhitl_context: null | \"\u003Cwhat triggered this>\"\n```\n",{"name":5,"triggers":45,"description":7,"user-invocable":59},[46,47,48,49,50,51,52,53,54,55,56,57,58],"\u002Fbytheslice:box-it-up","\u002Fbox-it-up","box up the pie","box up the slice","hand it over","close out the pie","\u002Fbytheslice:ship-pr","\u002Fship-pr","ship the pr","submit the pr","open and merge the pr","ship this branch","ship this pie",true,"a877abb24b61dfec2e931454e4590081dfbdbcfc","skills\u002Fbox-it-up",1,"https:\u002F\u002Fgithub.com\u002Fsteve-piece\u002Fbytheslice","https:\u002F\u002Fgithub.com\u002Fsteve-piece","2026-11-12 16:05:34",{"source":8,"skillName":5,"commands":67,"prompt":77,"zipAvailable":59},[68,71,74],{"tool":69,"command":70},"npx","npx skills add steve-piece\u002Fbytheslice --skill box-it-up",{"tool":72,"command":73},"bunx","bunx skills add steve-piece\u002Fbytheslice --skill box-it-up",{"tool":75,"command":76},"pnpm","pnpm dlx skills add steve-piece\u002Fbytheslice --skill box-it-up","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fsteve-piece\u002Fbytheslice\u002Fblob\u002Fmain\u002Fskills\u002Fbox-it-up\u002FSKILL.md",[79,85,91],{"path":80,"resourceType":81,"resourceTypeDesc":82,"sizeBytes":83,"sourceHtmlUrl":84},"agents\u002Fci-fix-attempter.md","REFERENCE","参考文档",10328,"https:\u002F\u002Fgithub.com\u002Fsteve-piece\u002Fbytheslice\u002Fblob\u002Fmain\u002Fskills\u002Fbox-it-up\u002Fagents\u002Fci-fix-attempter.md",{"path":86,"resourceType":87,"resourceTypeDesc":88,"sizeBytes":89,"sourceHtmlUrl":90},"pick-merge-strategy.js","SCRIPT","脚本",3029,"https:\u002F\u002Fgithub.com\u002Fsteve-piece\u002Fbytheslice\u002Fblob\u002Fmain\u002Fskills\u002Fbox-it-up\u002Fpick-merge-strategy.js",{"path":92,"resourceType":87,"resourceTypeDesc":88,"sizeBytes":93,"sourceHtmlUrl":94},"record-kitchen-merge.js",2452,"https:\u002F\u002Fgithub.com\u002Fsteve-piece\u002Fbytheslice\u002Fblob\u002Fmain\u002Fskills\u002Fbox-it-up\u002Frecord-kitchen-merge.js",[96,126,151,180,207,228],{"skillNo":97,"name":98,"nameZh":6,"description":99,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":100,"categories":101,"keywords":102,"publishedAt":40},"01M6JK6TG7HJ54TN5XYD8N3QE8","special-order","Cook a slice with the customer's specifications on the spot: add new features mid-flight to an existing project. Auto-detects project type and extends the master checklist with new stages.","https:\u002F\u002Fgithub.com\u002Fsteve-piece\u002Fbytheslice\u002Fblob\u002Fmain\u002Fskills\u002Fspecial-order\u002FSKILL.md",[],[103,104,105,27,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125],"special order","app","project","bolt","customer","features","master","add","opus","feature","custom","true","Existing","type","with","high","spot","specifications","about","new","request","extend","slice",{"skillNo":127,"name":128,"nameZh":6,"description":129,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":130,"categories":131,"keywords":137,"publishedAt":40},"01M6JK6K6SH4N8Q597D3ABRRMR","setup-shop","Start the oven, check ingredients, prep the shop. Bootstrap a new project or configure ByTheSlice in an existing one. First-time install, system-wide config, or per-project setup.","https:\u002F\u002Fgithub.com\u002Fsteve-piece\u002Fbytheslice\u002Fblob\u002Fmain\u002Fskills\u002Fsetup-shop\u002FSKILL.md",[132],{"categoryNo":133,"categoryName":134,"taxonomyType":135,"taxonomyTypeDesc":136},"01JBSEEDCAT000000000000031","产品经理","PROFESSION","适用职业",[138,139,140,39,104,141,105,142,22,30,143,144,145,146,147,111,148,149,150,114,122],"shop","setup shop","setup","monorepo","time","configure","create","config","install","start","new project","for","system",{"skillNo":152,"name":153,"nameZh":6,"description":154,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":155,"categories":156,"keywords":165,"publishedAt":40},"01M6JK6CX6DNV9EE9VH6H3YRD0","set-display-case","Build the display case the pies will sit in, bootstrap your design system: tokens, Tailwind config, design rules, and the operator-only \u002Flibrary preview route. Run once before \u002Fsell-slice; also invocable standalone on any project.","https:\u002F\u002Fgithub.com\u002Fsteve-piece\u002Fbytheslice\u002Fblob\u002Fmain\u002Fskills\u002Fset-display-case\u002FSKILL.md",[157,162],{"categoryNo":158,"categoryName":159,"taxonomyType":160,"taxonomyTypeDesc":161},"01JBSEEDCAT000000000000015","视觉设计","SCENARIO","使用场景",{"categoryNo":163,"categoryName":164,"taxonomyType":135,"taxonomyTypeDesc":136},"01JBSEEDCAT000000000000032","设计师",[39,166,167,168,169,105,170,22,171,172,29,173,174,175,145,146,176,177,178,179],"display","case","set display case","standalone","Tailwind","init","design","preview","route","run","operator","design-system","library","design system",{"skillNo":181,"name":182,"nameZh":6,"description":183,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":184,"categories":185,"keywords":190,"publishedAt":40},"01M6JK629AYG2B1NSSDYQAPWP2","sell-slice","Sell a customer their slice - the high-touch single-slice delivery loop. Execute one slice from your master checklist as an interactive spine (prep gate · recon · build-plan auth · \u002Fgoal · branch) + Workflow A (produce) + library gate + Workflow B (verify-once). Run me repeatedly, one fresh chat per slice. For autonomous whole-pie baking use \u002Fsell-pie.","https:\u002F\u002Fgithub.com\u002Fsteve-piece\u002Fbytheslice\u002Fblob\u002Fmain\u002Fskills\u002Fsell-slice\u002FSKILL.md",[186,189],{"categoryNo":187,"categoryName":188,"taxonomyType":160,"taxonomyTypeDesc":161},"01JBSEEDCAT000000000000023","Skill与智能体开发",{"categoryNo":163,"categoryName":164,"taxonomyType":135,"taxonomyTypeDesc":136},[191,192,125,38,193,194,195,196,175,109,178,197,198,149,199,200,201,202,118,203,204,205,206],"sell slice","sell","loop","fresh","plan","spine","ship","as","touch","use","interactive","chat","build","checklist","deliver","baking",{"skillNo":208,"name":209,"nameZh":6,"description":210,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":211,"categories":212,"keywords":214,"publishedAt":40},"01M6JK5RGMT1ZDVNG9CEHQF61Q","sell-pie","Bake a whole Pie autonomously - the v5 forefront delivery loop. A \u002Floop-driven baker that drives ONE Pie (a coherent chapter, usually 3 to 8 slices) to \"ready for review\" without per-slice prompting; each slice runs the context-separated build→test→verify→fix Workflow, commits + pushes (no PR), and advances; when every slice is [x] it stops at the pie boundary and opens one PR via \u002Fbox-it-up. Refuses flat v4 checklists (points you at \u002Fcook-pizzas --repie). For a continuous-review pie (review=continuous) it runs in high-touch \u002Fsell-slice mode. Opt-in merge-per-slice delivery (delivery.mode, or an explicit autonomous-delivery run instruction) instead gives each slice its own branch, PR and green-CI merge; opt-in ship-once delivery (delivery.mode, set by \u002Fpizza-party) merges each pie into one local ship branch on local gates only and ships one PR at the end. The four blocking HITL categories halt the loop instead of rescheduling (an unattended ship-once run defers the slice instead). Use when the user runs \u002Fsell-pie, says \"sell a pie\", \"bake the pie\", \"run the next pie\", \"loop the pie\", or wants one whole chapter delivered hands-off. For a single careful slice use \u002Fsell-slice; for the whole app end to end use \u002Fpizza-party.","https:\u002F\u002Fgithub.com\u002Fsteve-piece\u002Fbytheslice\u002Fblob\u002Fmain\u002Fskills\u002Fsell-pie\u002FSKILL.md",[213],{"categoryNo":187,"categoryName":188,"taxonomyType":160,"taxonomyTypeDesc":161},[215,192,39,216,104,217,38,37,34,218,22,33,32,31,29,219,193,220,221,222,205,175,223,224,197,225,226,227],"sell pie","categories","ready","end","autonomous","workflow","you","review","at","coherent","context","prompting","commits",{"skillNo":229,"name":230,"nameZh":6,"description":231,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":232,"categories":233,"keywords":238,"publishedAt":40},"01M6JK5GSHAXR9EAVBJBACPVGF","pizza-party","Cater a whole app, start to finish: from a short brief to a finished, deployed app with a URL. One interview up front (AskUserQuestion), then no human stops: \u002Fsetup-shop, \u002Fcreate-menu, \u002Fcook-pizzas, the Prep pie, every pie through \u002Fsell-pie in ship-once delivery (all gates local), one PR that ships the app, a deploy to whatever host the operator has authorized (or an artifact or localhost link), and a run record for comparing runs over time. Every decision a sub-skill would normally ask about is decided, recorded in the order ticket, and the run continues. Use when the user runs \u002Fpizza-party, sets a \u002Fgoal to build an app end to end, or says \"build me this app end to end\", \"from scratch to production\", \"pizza party\", \"bake the whole roadmap\" or \"run all pies\".","https:\u002F\u002Fgithub.com\u002Fsteve-piece\u002Fbytheslice\u002Fblob\u002Fmain\u002Fskills\u002Fpizza-party\u002FSKILL.md",[234,237],{"categoryNo":235,"categoryName":236,"taxonomyType":160,"taxonomyTypeDesc":161},"01JBSEEDCAT000000000000011","运维与部署",{"categoryNo":133,"categoryName":134,"taxonomyType":135,"taxonomyTypeDesc":136},[239,240,104,241,142,218,242,243,22,244,31,219,245,246,247,248,144,249,250,251,252],"pizza party","party","brief","short","ticket","decision","host","roadmap","URL","ask","me","artifact","human","when"]