--- name: build-close description: "Land a validated three-stage build and run its release ceremonies. Use /build-close , or /build-close alone inside the workspace, after /build-run, whether the workspace branch has a PR or remains local." --- # build-close Input: `` or nothing, resolved exactly as `/build-run` resolves it (the plan document is `/plan.md`; with no argument, the ACTIVE plan of the workspace you are in). Never edit application code. A code change after build completion requires a new, signed-off repair build with its own slug, allowlist, whole-tree regression phase and detached review. Do not dispatch an ad hoc herdr close round or modify frozen inputs. This skill does not invoke another skill; describe the missing build obligation and preserve the workspace. Merge when authorized by the user's existing instruction or explicit answer. The moment a skill instruction proves wrong, ambiguous, or is deviated from - or the user has to intervene where the skill should have sufficed - append `- workflow: ` to `/ledger.md`. These lines are the retro's input for improving the workflow after the run. Every commit anywhere in this workflow - driver, executor, judge, fix - uses Conventional Commits: `type(scope): description` with type in feat, fix, chore, refactor, docs, test, ci, perf. Branch names follow the same shape: `type/short-description`. No attribution lines or trailers. ## Preflight Run inside the workspace `/build-plan` created. Resolve the checkout with `git rev-parse --git-dir`, `git rev-parse --git-common-dir`, and `git rev-parse --show-superproject-working-tree`. Refuse when git dir equals common dir, the superproject result is non-empty, or HEAD is detached. Resolve the sidecar whose `defaults.doc` equals `/plan.md`. Fall back to `.agents/build/plans/ACTIVE` only when exactly that ACTIVE plan pins the same document. Refuse disagreement. Derive `` and `` from the selected machine plan. Read `/workspace.json`, `/ledger.md`, and `/runs.jsonl` before anything else. Require workspace.json to contain exactly `path`, `branch`, `base`, `base_branch`, and `primary`. Require the current absolute root and checked-out branch to equal `path` and `branch`. Read workflow.jsonl, the native_closed proofs and each phase_accepted receipt. Require build_completed and its exact reviewed tip; a parked build cannot close. Read the immutable scorer/judge artifacts named by those receipts, including refusals and earlier failed attempts. runs.jsonl is an index, not recovery authority. A later successful attempt can resolve a failed attempt only through the journaled workflow; a bare merged task status never proves delivery. Discover what release means. Check CLAUDE.md (or the equivalent project instructions) for release and deploy ceremonies - commonly versioning, changelog, release notes, tags, package publication, migrations, deployment, and smoke checks. If none is documented, ask. Also read `## Release requirements` and every `owner: user` row in the plan document. ## Record before landing BEFORE either merge path: regenerate `report.md` in the plan directory - keep its Traceability, Decisions, Escalations and Restatement sections, and rewrite `## Run` as `## Outcome` with each SPEC 2 outcome marked delivered or not by its witness tests' final state, plus every `owner: user` item and its status. Commit it on the workspace branch so the record lands with the code. ## PR path When a PR exists for the workspace branch: 1. Watch CI until terminal. Do not merge red or pending checks. 2. Read review feedback and unresolved threads. Turn every requested code change into an explicit repair-build obligation; preserve the current build evidence and obtain a freshly validated repair result before continuing. 3. Re-run the affected checks, push executor commits to the existing branch, reply, and resolve threads according to repo convention. 4. Require green checks and all required threads resolved. 5. Ask the user whether to merge. On explicit yes, use the repo's merge method, squash where the repo squashes. Otherwise keep the PR, branch, and worktree. ## Local path When no PR exists, ask the user whether to land the validated branch locally. On explicit yes, operate from the primary checkout recorded in workspace.json: 1. Read its current branch. Require it to equal `base_branch`. If it moved, stop and ask; do not switch or merge. 2. Run `git -C checkout ` only if needed after the check. 3. Run `git -C merge --no-ff `. 4. Run the sidecar's `defaults.gate_cmd` on the merged primary tree. If the merged-tree check is red, stop. Leave the merge, workspace, and branch in place for diagnosis. Require a newly validated repair build; do not hide the failed integration with cleanup. ## Ceremonies After a completed merge, assemble one release list from the discovered repo instructions, the plan document's `## Release requirements`, and all `owner: user` phase rows. Execute only driver-safe, authorized items. Hand every credentialed, infrastructure, destructive, or manual `owner: user` item to the user explicitly. Do not claim a release step that was not measured. ## Evidence and cleanup Before removing anything, preserve evidence: /scripts/preserve-evidence.py --root --run / --dest /.agents/build/runs// The script verifies the workflow chain, native archives and judge/scorer receipts, retains reviewed Git objects in evidence refs and a portable bundle, and verifies every copied file. Native retention cannot substitute for this archive. It allows only the regenerated report.md to differ after the validated tip; code drift refuses cleanup. Do not fall back to an unchecked rsync. Restore and verify the captured hooksPath using this skill's own helper: /scripts/workspace-hooks.py restore --root --run / It restores the original local value (or absence), and refuses to overwrite a setting changed outside this build. Record the result in the handoff's Integration section. After either merge path has completed: 1. Run `git status --porcelain` in the workspace. 2. If dirty, list every path and ask. Keep the worktree and branch. 3. If clean, remove the worktree without `--force` from the primary checkout. 4. Delete the merged branch with `git branch -d `. The build allowlist (in Claude Code: `/.claude/settings.local.json`) stays; tell the user it is there and removable by hand. Keep the worktree while a PR remains open or when the user chooses to keep it. Discard only on the user's explicit request and only after they type `discard`. Confirm exact paths before any discard action. ## Handoff Write `/handoff.md` BEFORE the cleanup above removes anything, in ASCII with these headings exactly and no others: ## Outcome ## Phases ## Defects ## Open ## Integration Under Integration, record what the user chose and every exact command run, including hooksPath restoration and its measured verification. Under Phases, include executor, wall time, files, gate, and judge verdict. Under Defects, separate caught-before-merge from post-run findings with file:line evidence. Under Open, list uncompleted release and `owner: user` items. Then re-run the evidence preservation script so the primary's copy contains this handoff: /scripts/preserve-evidence.py --root --run / --dest /.agents/build/runs//