Work Closeout
Apply task scope and authorization when
using this workflow; it defines how existing approval and task boundaries apply.
Use this skill to leave a workstream tidy and understandable. It is about
cleanup and handoff, not proving readiness; use repo-readiness when the main
question is whether checks pass or a PR can ship.
For task cleanup, a bulk audit, or repository retirement, read repository
cleanup and preservation, which owns shared
evidence, disposition, preservation, and reporting. Its helper remains read-only.
When the user asks whether work is done, ready to hand off, or safe to exit,
compose the skills in order: use repo-readiness first for gates and evidence,
then use this skill for final hygiene, cleanup, and parking state. Do not force
a single skill when both readiness and closeout are required. This skill owns
the final safe-to-exit answer, and that final answer must include both
Love Gate and Safe to exit. Do not reduce Love Gate to passed, ready,
or a generic approval sentence; write the two entries explicitly as Love: and
Do not love:.
Outcome
Closeout succeeds when the owning durable surface is current or explicitly not
applicable, readiness evidence is preserved, safe cleanup is complete or
clearly deferred, remaining work has a blocker and next action, and the final
answer gives a truthful Safe to exit: yes, conditional, or no verdict.
The result must also say what changed, what remains, and what was removed,
preserved, or intentionally left in place.
Workflow
Identify the repo, branch, active task, and whether a PR/issue/plan is in
play. Before saying "safe to exit," name the owning durable surface in the
closeout answer: the PR, issue, GitHub plan, saved local plan, or explicit
"none" when no owning surface exists. Also state whether that surface was
closed, updated, left open or parked with the current blocker and next action,
or confirmed not applicable, with evidence.
If release, runtime, deploy, browser, or device evidence is decisive, ensure
the owning PR, issue, plan, or doc names the exact environment checked, or
names the substitute environment and the remaining gap.
If .github/github.json exists, read it and check metadata
freshness. Compare the current work with
metadataFreshness.updateWhen and
with common triggers: docs routing, validation gates, primary commands,
important workflows, health endpoints, repo relationships, JetBrains
expectations, cleanup policy, and ownership boundaries. If metadata should
change, update it only with approval, including approval already given for
that metadata change and scope; otherwise record a concrete remaining item
before saying it is safe to exit.
Also read cleanup. During closeout, run or report repo-configured commands
with when: "routine" as closeout evidence. Commands marked explicit,
cold, aggressive, or any unrecognized value are report-only unless the
user explicitly asks for that cleanup. Never run a cleanup command whose
effect is unclear; record the not-run reason instead.
Inspect local state:
git status --short --branch
git worktree list
Apply refresh gates in this order: a runtime-bound checkout uses only the
landed reconciler and stops; any tracked dirt or active Git operation is
report-only and stops; only then may the explicitly requested untracked-only
exception be considered.
First determine whether the active checkout is bound into the active local
runtime for merged work. If it is, do not update it with generic git pull;
use github and its landed repo-local runtime reconciler as the idempotent
closeout backstop. Pass the confirmed final landing SHA; do not substitute a PR
head, candidate, or pre-merge base SHA. Keep remote merge success separate
from local reconciliation. A blocked or failed reconciliation prevents a
claim that installed runtime behavior or provenance-sensitive evidence is
current, but it does not reclassify or retry the confirmed merge.
For a checkout that is not runtime-bound, if the active branch is clean and
behind its configured upstream, fetch and resolve the fetched upstream to an
immutable upstream_sha and record the current tip as head_sha. Fail closed
on an active Git operation and prove the branch is strictly behind that commit
without divergence. Immediately before the merge, re-check that HEAD still
equals head_sha, the tracked checkout is still clean, no Git operation is
active, and head_sha remains an ancestor of upstream_sha. Fast-forward
with git -c core.hooksPath=/dev/null merge --ff-only --no-autostash --no-overwrite-ignore "$upstream_sha". Never pass a moving upstream-tracking
ref directly as the merge operand; use only the pinned commit ID. Then prove
HEAD equals the pinned commit and status remains clean. If the branch is
dirty, ahead, diverged, lacks an upstream, or any proof or fast-forward fails,
do not mutate it; report the state and next safe action.
Do not broaden automatic closeout mutation for a dirty checkout. When the
user explicitly requests this specific fast-forward, a non-runtime default
checkout that is dirty only because of untracked, non-ignored files may use a
bounded exception. The exception relaxes only untracked-file dirtiness. Every
other surrounding precondition still applies: the checkout must remain the
already-identified repository on its configured default branch with a
configured upstream and must not be runtime-bound. When the target is a
separate default worktree, it must share the source repository's Git common
directory and expected GitHub identity. Evaluate runtime binding before this
exception and treat it as absolute: explicit user intent and untracked-only
dirt never make a runtime-bound checkout eligible. First fetch and resolve the
fetched upstream to an immutable upstream_sha, record the current tip as
head_sha, and prove the branch is
strictly behind without divergence. The general closeout refresh has no
landing SHA to prove and must not invent one; when this exception is used by
the post-merge default-checkout backstop below, require the confirmed final
landing SHA on upstream_sha's first-parent history. Prove the tracked index
and worktree are clean and fail closed if git -C <path> status reports an
operation or if any path returned by git -C <path> rev-parse --git-path for
MERGE_HEAD,
CHERRY_PICK_HEAD, REVERT_HEAD, REBASE_HEAD, rebase-merge,
rebase-apply, sequencer, BISECT_LOG, or BISECT_START exists. Enumerate
every untracked entry with git -C <path> ls-files --others --exclude-standard -z, consume the NUL-separated output without shell globbing or pathspecs, and
snapshot each path's file type and content or symlink-target hash. An entry
ending in /, or any entry that cannot be fingerprinted as a regular file or
symlink without descending into another repository, is ambiguous and must
abort report-only. Never pass a moving upstream-tracking ref directly as the
merge operand; use only upstream_sha. Do not implement a separate
path-collision predictor; Git's merge checks plus --no-overwrite-ignore must
reject an incoming tracked path that would overwrite preserved work.
Immediately before the merge, re-resolve HEAD, repeat the tracked-clean and
operation-state checks, and abort report-only unless HEAD still equals
head_sha and head_sha remains an ancestor of upstream_sha. Fast-forward
with hooks and autostash disabled using git -C <path> -c core.hooksPath=/dev/null merge --ff-only --no-autostash --no-overwrite-ignore "$upstream_sha". Re-check that HEAD equals
upstream_sha, git -C <path> status still has no tracked changes, and every
untracked fingerprint matches its preflight value. Any nonzero merge, failed
proof, ambiguous result, runtime binding, or changed fingerprint remains
report-only.
After merged work performed from a task branch, also inspect the repository's
unique local default-branch worktree as a closeout backstop. If it is
runtime-bound, route it through the landed runtime reconciler. Otherwise,
fast-forward it only when it is clean, still on the default branch, shares the
merged worktree's Git common directory and expected GitHub identity, and is
strictly behind its configured upstream. Fetch and resolve the fetched
upstream to an immutable upstream_sha, record the current tip as head_sha,
and use that same commit for the ancestry check and the confirmed final landing
SHA first-parent proof. Immediately before the merge, re-check that HEAD
still equals head_sha, the tracked checkout remains clean, no Git operation
is active, and head_sha remains an ancestor of upstream_sha. Run git -C <path> -c core.hooksPath=/dev/null merge --ff-only --no-autostash --no-overwrite-ignore "$upstream_sha". Never pass a moving upstream-tracking
ref directly as the merge operand; use only the pinned commit ID. Verify
HEAD equals upstream_sha and contains that landing SHA. Leave unsafe,
ambiguous, or unverified state untouched and report: Local default checkout remains stale; fast-forward it before default-branch work or audits. The
active task worktree remains the authoritative agent source; do not replace it
with the refreshed default checkout when handing off or resuming work. If the
active checkout is already that unique default worktree, the preceding active
branch check is sufficient; do not pull it twice.
If the shared Launchplane context helper is present and configured, call it
once as optional closeout context for the repo/workstream:
uv run <skill-dir>/../launchplane/scripts/launchplane-context.py --repo OWNER/REPO
Use available context to notice pending Every Code work, preview readiness,
deploy/product evidence, or source-of-truth links that should be reflected in
the closeout. Treat no_context, unavailable, unauthorized, invalid,
or helper failure as normal absence. Do not block safe-to-exit only because
Launchplane context is unavailable, and do not copy raw helper payloads into
issues, PRs, or final summaries.
If GitHub state matters for closeout, use github for PR,
Actions, labels, merge state, post-merge verification, GitHub
security/quality signals, and safe branch/worktree cleanup.
Use github-plan for planning issue indexes, Project state, blocker graphs,
and planning issue closure. This skill owns closeout judgment and hygiene;
the GitHub skills own helper-backed GitHub writes and planning mutations.
Before declaring an owning GitHub issue or PR settled, run
uv run ../github-work-rollup/scripts/github_unanswered_comments.py --thread OWNER/REPO#NUMBER.
Any attention result
or degraded coverage requires a response or explicit handoff before an
all-clear; a bot response never proves owner acknowledgement.
When an open PR still needs ongoing CI, review, mergeability, or
merged/closed follow-through, transfer that loop to babysit-pr before
declaring the work parked or safe to exit. For an already merged or closed PR,
a babysit-pr --once snapshot can be closeout evidence.
Use github-plan for durable plan state, blockers, stale/duplicate plan
cleanup, and Project planning state. Use legacy plan only for explicit
local/offline plan files that already exist or that the user asks to keep.
If source-of-truth docs, runbooks, deployment notes, or another durable record
contain the decisive completion or blocker evidence, compare that state with
the owning issue/plan before saying safe to exit. If they disagree, reconcile
the issue/plan/docs state or report safe-to-exit as conditional/no with the
mismatch named.
If design collaboration was part of the work, make sure accepted direction,
browser QA evidence, tradeoffs, and remaining design work are captured in the
relevant GitHub planning issue or PR.
Classify this task's artifacts under the shared repository cleanup policy.
Clean only task-owned disposable output whose purpose is complete: transient logs,
screenshots, temp scripts, generated scratch files, generated caches, stopped
test containers, or other consumed temporary files.
If the repo still has legacy handoff*.md files or files matching
cleanup.handoffArtifacts.temporaryGlobs, delete or migrate them once their
content is captured in the owning GitHub issue or PR comment unless they are
intentionally preserved as committed docs.
IDE paths follow ../references/ide-configuration-policy.md: preserve ignored
IDE state in retained checkouts; inspect mixed tracked files hunk by hunk and
retain the canonical shared form plus safe hunks. Never blanket-revert, clean,
stash, or overwrite unrelated IDE changes. Whole-worktree retirement requires
the shared cleanup policy's protected-file, preservation, ownership, and
authorization evidence.
Do not remove user artifacts, broad system caches, unrelated untracked files,
or remote resources without explicit approval.
Report final state concisely.
Consuming Readiness Evidence
When repo-readiness has just run, consume its handoff instead of rerunning the
same gate discovery by default. Verify the evidence is fresh for the current
branch, PR, and commit, then use it to decide whether closeout can proceed:
- Status: ready, not ready, partially ready, or blocked.
- Required gates: checks inferred from
.github/github.json, repo docs, CI, and
the changed surface.
- Passed, failed, pending, and not-run evidence with concrete reasons.
- Metadata/docs impact: whether
.github/github.json or docs changed, were
checked, are stale, or were intentionally not updated.
- Background review: consume the target, observation time or head SHA, and the
canonical point-in-time state from the readiness handoff without re-inferring
a terminal outcome from absence.
- Next action: the smallest step that would change readiness.
If the readiness handoff is missing, stale, tied to a different commit/PR, or
does not cover the current closeout question, run repo-readiness first or
record the gap as a conditional/no safe-to-exit reason. Do not treat closeout
cleanup as proof that gates passed.
Both this skill and repo-readiness read .github/github.json with the same
schema expectations: qualityGate, docs, metadataFreshness, cleanup,
importantWorkflows, repo relationships, health signals, and ownership or
Launchplane routing when present. Readiness uses those fields to decide what
must be verified; closeout uses the same fields to decide what final evidence,
metadata updates, and cleanup remain.
Background Review State
Use ../references/background-review-reporting.md for target matching,
point-in-time vocabulary, and durable wording. Never infer skipped, not emitted, did not run, or another terminal state merely because no lifecycle
evidence is visible before the final response.
Take a point-in-time read when available, but do not poll or delay the final
response solely for a review that can only start after that response. Not yet observable is non-terminal and does not block Safe to exit: yes when every
other gate is satisfied. A matching review that is already in flight remains
pending evidence and keeps the verdict conditional. Preserve positive terminal
evidence exactly, including cancellation, supersession, failure, skip reason,
and completed findings or no-findings results. Observation unavailable keeps
the verdict conditional unless the owning policy explicitly says that review
surface is not required for the current task.
Never wait indefinitely for a matching review. Use a bounded observation when
it is useful; if the review remains in flight, report the verdict as
conditional. Cancellation and supersession are terminal but are not clean
reviews. The never-started exception applies only when a later observation can
read the lifecycle surface and still finds no matching evidence because no
review ever started; then no corrective follow-up is required. If matching
terminal evidence appears after an earlier not yet observable summary, always
preserve that original point-in-time statement and add a follow-up; the
never-started exception cannot apply.
When writing final summaries, closeout comments, or migrated handoff content,
follow ../references/every-code-formatting.md: cite point-in-time evidence,
keep recovery-critical facts in GitHub for GitHub-backed work, and avoid
boilerplate that does not help the next session resume.
Safe To Exit
Treat "safe to exit" as strict hygiene, not merely context preservation. Safe
to exit means work is ready and hygiene is complete, or unfinished work is
intentionally parked with durable state.
Any final answer to a safe-to-exit, wrap-up, closeout, pause, or handoff prompt
is incomplete unless it includes a Love Gate section.
Safe to exit: yes
- Work is complete or explicitly out of scope.
- Gates, inspections, docs checks, metadata checks, and post-merge checks are
done or explicitly not applicable.
- The owning durable surface was named as closed/updated with evidence, or no
owning PR, issue, GitHub plan, or saved local plan was in play.
- Background review state follows the point-in-time contract above.
Current-target findings are resolved, non-blocking, explicitly tracked, or
declined with a recorded reason under
../references/model-review.md;
no matching review is in flight. Not yet observable is permitted when a
post-turn trigger may still occur and the answer says so explicitly. Activity
in detached auto-review-<hex> worktrees for older targets is not a gate.
- PR, issue, GitHub plan, and any explicit local plan state is current.
- The branches and worktrees this task created or adopted are accounted for:
eligible completed ones are removed under the shared cleanup policy, and each
one that stays is named with its reason and what will remove it. Work from the
task's own record of what it created, checked against
git worktree list; a
path or branch name that looks like this task's is not evidence. A merged task
checkout left unaccounted for is unfinished closeout; one retained for a
stated reason is not.
- No important untracked artifacts, transient processes, or hidden follow-up
remain.
Safe to exit: conditional
- Work is unfinished but intentionally parked.
- Blockers and next steps are recorded in a PR, issue, GitHub plan, or explicit
local/offline saved plan.
- The owning durable surface is named, current, and contains the blocker or next
action needed to resume.
- Failing and not-run checks are recorded with reasons.
- Current auto-review blockers, if any, are recorded in the PR, issue, or plan
that owns the unfinished work.
- Remaining docs, metadata, security, or quality follow-up is tracked durably.
- No transient local state is required to resume.
Safe to exit: no
- Uncommitted or unexplained work remains.
- Expected gates/readiness checks have not been run and no reason is recorded.
- An owning issue, PR, GitHub plan, or saved local plan remains stale, incorrectly
blocked, or missing the completed/remaining work state.
- Source-of-truth docs or runbooks disagree with the owning issue/plan and that
disagreement has not been reconciled or explicitly parked.
- Failing checks, docs/metadata/security follow-up, PR/CI/review state, or
cleanup work is unresolved and untracked.
- Temporary artifacts or processes could confuse the next session.
For code changes, broad practical lint/static analysis and jetbrains-inspection
state must be included in closeout, or there must be a documented not-run reason
or intentional parking decision. When .github/github.json defines
qualityGate.inspection, missing JetBrains evidence for code changes prevents
Safe to exit: yes; use conditional/no until the inspection is clean, findings
are fixed or tracked, or the not-run reason is explicit. If the inspection
config is blank or feels wrong, ask the user before changing durable policy or
trusting a suspicious value; for a one-off local check, prefer the helper's safe
inferred route with changed_files scope and report the assumption.
Parking Work and Handoff Surfaces
Before parking unfinished work or migrating a local handoff, read
parking and handoff procedures. Preserve
one current durable owner with its blocker, next action, and verification state.
Use an authorized owning issue or PR when available; valuable local work may use
a known, approved, reconstructable durable location. Apply the plan hygiene
checks below as relevant.
Plan Hygiene
- Use
github-plan plus the sibling github helpers to update the active
issue's Current Status, finish line, blockers, and Project fields before
parking work.
- For issue-backed work that is resolved without a merged PR, close the owning
issue with a concise evidence-backed comment, or leave it open with the current
blocker and next action. Do not rely on a local summary as the only record.
- Before parking or closing a workstream, run a Plan Direction Checkpoint:
identify the next action, how it fits the current plan, whether the plan or
issue graph changed, and where that durable state was updated.
- If the work revealed a new blocker, dependency, sub-workstream, or stale
assumption, update the GitHub issue graph before relying on a handoff summary.
- Treat an accurate issue graph as closeout evidence. A handoff that describes
work not represented in the owning issue, PR, or related issue graph is
incomplete unless the user explicitly asked for private/offline parking.
- After a PR merges, sweep issues referenced by the canonical merged PR body and
comments.
Refs #... is intentionally non-closing; close only issues whose
acceptance criteria were conclusively satisfied by the merge. Otherwise,
update Current Status or leave a comment with what remains.
- Mark completed checklist items, record blockers, and remove or rewrite stale
assumptions in the GitHub plan issue.
- Before declaring safe to exit after closing or merging implementation work,
inspect the remaining open GitHub issues labeled
plan and verify their
labels and Project status/focus fields match their Current Status:
plan:active, plan:blocked, plan:waiting, plan:stale, or plan:done.
Re-read the issue or Project item after updating because labels and board
fields can drift independently. The main LLM owns the final label/status
decision and any mutations. For large issue sets, a read-only agent may
summarize likely mismatches, but the main LLM must make and verify the final
updates.
- If workflow metadata changes are deferred, record the exact
.github/github.json
follow-up in the GitHub plan or closeout remaining items.
- Delete or migrate finished local working plans once useful planning context
has been captured in GitHub, or once implemented behavior has been reflected
in repo docs when docs are actually stale.
- Migrate stale local plans into active GitHub plans instead of leaving archive
clutter.
Git And Worktree Hygiene
- Preserve unrelated user changes.
- Do not use destructive Git commands to bypass required evidence or authorization.
- For task cleanup, bulk audits, or repository retirement, apply the shared
repository cleanup and preservation. Preserve
unique or ambiguous state while investigating; reuse same-action/scope
authorization and ask only for a missing choice or expanded scope.
- If
git status --short --branch shows a clean non-runtime-bound branch behind
its upstream, use the pinned fetched-upstream flow above before saying the
checkout is tidy. Runtime-bound checkouts must use the landed repo-local
reconciler instead. Treat dirty, ahead, diverged, missing-upstream, or failed
fast-forward states as report-only by default. An explicit user request permits
only the bounded untracked-only exception above; it is not blanket approval to
overwrite, stash, clean, or include unrelated files.
- When asked to remove a worktree, establish uncommitted changes' disposition
under the shared policy and retain unresolved or unpreserved state.
Removing a worktree is not approval to lose its branch or local edits.
- Use
github for PR-backed branch/worktree cleanup and GitHub
state.
- Removing an eligible completed checkout this task created needs no new
question. Eligible still means the shared policy's ownership, live-use, and
contents checks; dirty or unpreserved state is retained. This covers the
worktree and its merged local branch, not a remote branch. When the task's
record does not show that it created a registered worktree, the owner is
unknown: leave it, and mention it when it bears on this closeout. Detached
auto-review worktrees stay excluded as described below.
- After merged PRs, include relevant post-merge Actions and GitHub
security/quality signal outcomes when GitHub data is available. Report signals
as clean, findings, unavailable, or not enabled; do not treat unavailable or
not-enabled signals as clean.
- Concrete reproducible broad-gate findings that are not fixed now should be
tracked after a duplicate search. Group speculative or huge-baseline findings
into a cleanup plan/report instead of opening many issues.
- If cleanup safety remains ambiguous after the available investigation,
preserve the candidate and name the exact missing evidence or choice.
Auto Review Worktrees
Codex Desktop and Every Code auto-review flows may create detached review
worktrees under paths like:
~/.code/working/<repo>/branches/auto-review*
Treat these as external review context, not the active workstream.
- Ignore them for normal safe-to-exit and dirty-worktree decisions.
- Do not treat their files as blocking the current repo closeout.
- Exclude them from ordinary cleanup. In an authorized bulk or retirement scope,
preserve them unless the shared policy establishes owner/job completion, lock
and runtime state, valuable contents, and exact disposition.
- Mention them only when relevant, for example: "Ignored detached auto-review
worktrees."
- If the user asks about a review result or review worktree specifically, switch
context deliberately and inspect that worktree as the task target.
Required Love Gate
Before finalizing the closeout, perform a "Love Gate" check. This is an
emotional and qualitative alignment step where the agent evaluates the session's
output against the user's ultimate satisfaction and the agent's own engineering
standards.
- Check if you "love" the work: Does the implementation feel clean, idiomatic,
and complete? Is the solution robust, or does it feel like a "just-in-case"
patch?
- Identify what you do not love: Are there any compromises, technical debt,
missing edge cases, or "smells" that remain? Be honest about shortcuts taken
due to context limits or task complexity.
- Report findings: Always include a brief "Love Gate" section in closeout
and safe-to-exit final answers. The section must include two explicit labels:
Love: for what you love about the result, and Do not love: for concerns,
compromises, or "nothing material" when no meaningful concern remains.
This gate ensures that the session ends not just with technical passing, but
with a shared understanding of the work's quality and "soul."
If you think the user's name is Justin, end with one short dad joke about the
session after the safe-to-exit answer.
Output Format
Use a compact closeout report:
- Done: what changed or was handled.
- Remaining: concrete blockers or follow-up work, including how the next action
fits the active plan.
- Checks: gates, inspections, docs, metadata, CI/Actions, and GitHub
security/quality signals that passed, failed, were pending, or were not run.
- Background review: target, point-in-time state, observation time or head SHA,
and terminal evidence when one was positively observed.
- Love Gate: include
Love: and Do not love: entries. Use Do not love: nothing material when no meaningful concern remains.
- Cleanup: artifacts, plans, handoffs, branches, or worktrees removed or left
intentionally.
- State: dirty files, PR status, CI status, or plan status when relevant.
- Owning surface: PR, issue, GitHub plan, saved local plan, or none; say whether
it was closed, updated, left open or parked with current blocker and next
action, or not applicable.
- Safe to exit: yes/no/conditional, with the condition if needed.
If there are no remaining items, say so plainly. Do not over-explain command
output unless the user asks for it.
1---2name: work-closeout3description: Use when the user asks to wrap up, clean up, close out, pause, park, hand off, determine what remains before stopping, preserve plan direction for the next session, update or remove stale plans/handoffs, reconcile issue graph state, remove transient artifacts, or asks whether they can exit. Coordinates GitHub plan cleanup, safe git/worktree hygiene, artifact cleanup, and final state summaries. Safe-to-exit and closeout final answers must include a Love Gate section with explicit `Love:` and `Do not love:` entries before the safe-to-exit verdict.4---56# Work Closeout78Apply [task scope and authorization](../references/execution-scope.md) when9using this workflow; it defines how existing approval and task boundaries apply.1011Use this skill to leave a workstream tidy and understandable. It is about12cleanup and handoff, not proving readiness; use `repo-readiness` when the main13question is whether checks pass or a PR can ship.1415For task cleanup, a bulk audit, or repository retirement, read [repository16cleanup and preservation](../references/repo-cleanup.md), which owns shared17evidence, disposition, preservation, and reporting. Its helper remains read-only.1819When the user asks whether work is done, ready to hand off, or safe to exit,20compose the skills in order: use `repo-readiness` first for gates and evidence,21then use this skill for final hygiene, cleanup, and parking state. Do not force22a single skill when both readiness and closeout are required. This skill owns23the final safe-to-exit answer, and that final answer must include both24`Love Gate` and `Safe to exit`. Do not reduce Love Gate to `passed`, `ready`,25or a generic approval sentence; write the two entries explicitly as `Love:` and26`Do not love:`.2728## Outcome2930Closeout succeeds when the owning durable surface is current or explicitly not31applicable, readiness evidence is preserved, safe cleanup is complete or32clearly deferred, remaining work has a blocker and next action, and the final33answer gives a truthful `Safe to exit: yes`, `conditional`, or `no` verdict.34The result must also say what changed, what remains, and what was removed,35preserved, or intentionally left in place.3637## Workflow38391. Identify the repo, branch, active task, and whether a PR/issue/plan is in40 play. Before saying "safe to exit," name the owning durable surface in the41 closeout answer: the PR, issue, GitHub plan, saved local plan, or explicit42 "none" when no owning surface exists. Also state whether that surface was43 closed, updated, left open or parked with the current blocker and next action,44 or confirmed not applicable, with evidence.45 If release, runtime, deploy, browser, or device evidence is decisive, ensure46 the owning PR, issue, plan, or doc names the exact environment checked, or47 names the substitute environment and the remaining gap.482. If `.github/github.json` exists, read it and check metadata49 freshness. Compare the current work with50 `metadataFreshness.updateWhen` and51 with common triggers: docs routing, validation gates, primary commands,52 important workflows, health endpoints, repo relationships, JetBrains53 expectations, cleanup policy, and ownership boundaries. If metadata should54 change, update it only with approval, including approval already given for55 that metadata change and scope; otherwise record a concrete remaining item56 before saying it is safe to exit.5758 Also read `cleanup`. During closeout, run or report repo-configured commands59 with `when: "routine"` as closeout evidence. Commands marked `explicit`,60 `cold`, `aggressive`, or any unrecognized value are report-only unless the61 user explicitly asks for that cleanup. Never run a cleanup command whose62 effect is unclear; record the not-run reason instead.63643. Inspect local state:6566 ```bash67 git status --short --branch68 git worktree list69 ```7071 Apply refresh gates in this order: a runtime-bound checkout uses only the72 landed reconciler and stops; any tracked dirt or active Git operation is73 report-only and stops; only then may the explicitly requested untracked-only74 exception be considered.7576 First determine whether the active checkout is bound into the active local77 runtime for merged work. If it is, do not update it with generic `git pull`;78 use `github` and its landed repo-local runtime reconciler as the idempotent79 closeout backstop. Pass the confirmed final landing SHA; do not substitute a PR80 head, candidate, or pre-merge base SHA. Keep remote merge success separate81 from local reconciliation. A blocked or failed reconciliation prevents a82 claim that installed runtime behavior or provenance-sensitive evidence is83 current, but it does not reclassify or retry the confirmed merge.8485 For a checkout that is not runtime-bound, if the active branch is clean and86 behind its configured upstream, fetch and resolve the fetched upstream to an87 immutable `upstream_sha` and record the current tip as `head_sha`. Fail closed88 on an active Git operation and prove the branch is strictly behind that commit89 without divergence. Immediately before the merge, re-check that `HEAD` still90 equals `head_sha`, the tracked checkout is still clean, no Git operation is91 active, and `head_sha` remains an ancestor of `upstream_sha`. Fast-forward92 with `git -c core.hooksPath=/dev/null merge --ff-only --no-autostash93 --no-overwrite-ignore "$upstream_sha"`. Never pass a moving upstream-tracking94 ref directly as the merge operand; use only the pinned commit ID. Then prove95 `HEAD` equals the pinned commit and status remains clean. If the branch is96 dirty, ahead, diverged, lacks an upstream, or any proof or fast-forward fails,97 do not mutate it; report the state and next safe action.9899 Do not broaden automatic closeout mutation for a dirty checkout. When the100 user explicitly requests this specific fast-forward, a non-runtime default101 checkout that is dirty only because of untracked, non-ignored files may use a102 bounded exception. The exception relaxes only untracked-file dirtiness. Every103 other surrounding precondition still applies: the checkout must remain the104 already-identified repository on its configured default branch with a105 configured upstream and must not be runtime-bound. When the target is a106 separate default worktree, it must share the source repository's Git common107 directory and expected GitHub identity. Evaluate runtime binding before this108 exception and treat it as absolute: explicit user intent and untracked-only109 dirt never make a runtime-bound checkout eligible. First fetch and resolve the110 fetched upstream to an immutable `upstream_sha`, record the current tip as111 `head_sha`, and prove the branch is112 strictly behind without divergence. The general closeout refresh has no113 landing SHA to prove and must not invent one; when this exception is used by114 the post-merge default-checkout backstop below, require the confirmed final115 landing SHA on `upstream_sha`'s first-parent history. Prove the tracked index116 and worktree are clean and fail closed if `git -C <path> status` reports an117 operation or if any path returned by `git -C <path> rev-parse --git-path` for118 `MERGE_HEAD`,119 `CHERRY_PICK_HEAD`, `REVERT_HEAD`, `REBASE_HEAD`, `rebase-merge`,120 `rebase-apply`, `sequencer`, `BISECT_LOG`, or `BISECT_START` exists. Enumerate121 every untracked entry with `git -C <path> ls-files --others --exclude-standard122 -z`, consume the NUL-separated output without shell globbing or pathspecs, and123 snapshot each path's file type and content or symlink-target hash. An entry124 ending in `/`, or any entry that cannot be fingerprinted as a regular file or125 symlink without descending into another repository, is ambiguous and must126 abort report-only. Never pass a moving upstream-tracking ref directly as the127 merge operand; use only `upstream_sha`. Do not implement a separate128 path-collision predictor; Git's merge checks plus `--no-overwrite-ignore` must129 reject an incoming tracked path that would overwrite preserved work.130 Immediately before the merge, re-resolve `HEAD`, repeat the tracked-clean and131 operation-state checks, and abort report-only unless `HEAD` still equals132 `head_sha` and `head_sha` remains an ancestor of `upstream_sha`. Fast-forward133 with hooks and autostash disabled using `git -C <path> -c134 core.hooksPath=/dev/null merge --ff-only --no-autostash135 --no-overwrite-ignore "$upstream_sha"`. Re-check that `HEAD` equals136 `upstream_sha`, `git -C <path> status` still has no tracked changes, and every137 untracked fingerprint matches its preflight value. Any nonzero merge, failed138 proof, ambiguous result, runtime binding, or changed fingerprint remains139 report-only.140141 After merged work performed from a task branch, also inspect the repository's142 unique local default-branch worktree as a closeout backstop. If it is143 runtime-bound, route it through the landed runtime reconciler. Otherwise,144 fast-forward it only when it is clean, still on the default branch, shares the145 merged worktree's Git common directory and expected GitHub identity, and is146 strictly behind its configured upstream. Fetch and resolve the fetched147 upstream to an immutable `upstream_sha`, record the current tip as `head_sha`,148 and use that same commit for the ancestry check and the confirmed final landing149 SHA first-parent proof. Immediately before the merge, re-check that `HEAD`150 still equals `head_sha`, the tracked checkout remains clean, no Git operation151 is active, and `head_sha` remains an ancestor of `upstream_sha`. Run `git -C152 <path> -c core.hooksPath=/dev/null merge --ff-only --no-autostash153 --no-overwrite-ignore "$upstream_sha"`. Never pass a moving upstream-tracking154 ref directly as the merge operand; use only the pinned commit ID. Verify155 `HEAD` equals `upstream_sha` and contains that landing SHA. Leave unsafe,156 ambiguous, or unverified state untouched and report: `Local default checkout157 remains stale; fast-forward it before default-branch work or audits.` The158 active task worktree remains the authoritative agent source; do not replace it159 with the refreshed default checkout when handing off or resuming work. If the160 active checkout is already that unique default worktree, the preceding active161 branch check is sufficient; do not pull it twice.162163 If the shared Launchplane context helper is present and configured, call it164 once as optional closeout context for the repo/workstream:165166 ```bash167 uv run <skill-dir>/../launchplane/scripts/launchplane-context.py --repo OWNER/REPO168 ```169170 Use `available` context to notice pending Every Code work, preview readiness,171 deploy/product evidence, or source-of-truth links that should be reflected in172 the closeout. Treat `no_context`, `unavailable`, `unauthorized`, `invalid`,173 or helper failure as normal absence. Do not block safe-to-exit only because174 Launchplane context is unavailable, and do not copy raw helper payloads into175 issues, PRs, or final summaries.1761774. If GitHub state matters for closeout, use `github` for PR,178 Actions, labels, merge state, post-merge verification, GitHub179 security/quality signals, and safe branch/worktree cleanup.180 Use `github-plan` for planning issue indexes, Project state, blocker graphs,181 and planning issue closure. This skill owns closeout judgment and hygiene;182 the GitHub skills own helper-backed GitHub writes and planning mutations.183 Before declaring an owning GitHub issue or PR settled, run184 `uv run ../github-work-rollup/scripts/github_unanswered_comments.py --thread OWNER/REPO#NUMBER`.185 Any attention result186 or degraded coverage requires a response or explicit handoff before an187 all-clear; a bot response never proves owner acknowledgement.188 When an open PR still needs ongoing CI, review, mergeability, or189 merged/closed follow-through, transfer that loop to `babysit-pr` before190 declaring the work parked or safe to exit. For an already merged or closed PR,191 a `babysit-pr --once` snapshot can be closeout evidence.1925. Use `github-plan` for durable plan state, blockers, stale/duplicate plan193 cleanup, and Project planning state. Use legacy `plan` only for explicit194 local/offline plan files that already exist or that the user asks to keep.195 If source-of-truth docs, runbooks, deployment notes, or another durable record196 contain the decisive completion or blocker evidence, compare that state with197 the owning issue/plan before saying safe to exit. If they disagree, reconcile198 the issue/plan/docs state or report safe-to-exit as conditional/no with the199 mismatch named.2006. If design collaboration was part of the work, make sure accepted direction,201 browser QA evidence, tradeoffs, and remaining design work are captured in the202 relevant GitHub planning issue or PR.2037. Classify this task's artifacts under the shared repository cleanup policy.204 Clean only task-owned disposable output whose purpose is complete: transient logs,205 screenshots, temp scripts, generated scratch files, generated caches, stopped206 test containers, or other consumed temporary files.207 If the repo still has legacy `handoff*.md` files or files matching208 `cleanup.handoffArtifacts.temporaryGlobs`, delete or migrate them once their209 content is captured in the owning GitHub issue or PR comment unless they are210 intentionally preserved as committed docs.211 IDE paths follow `../references/ide-configuration-policy.md`: preserve ignored212 IDE state in retained checkouts; inspect mixed tracked files hunk by hunk and213 retain the canonical shared form plus safe hunks. Never blanket-revert, clean,214 stash, or overwrite unrelated IDE changes. Whole-worktree retirement requires215 the shared cleanup policy's protected-file, preservation, ownership, and216 authorization evidence.2178. Do not remove user artifacts, broad system caches, unrelated untracked files,218 or remote resources without explicit approval.2199. Report final state concisely.220221## Consuming Readiness Evidence222223When `repo-readiness` has just run, consume its handoff instead of rerunning the224same gate discovery by default. Verify the evidence is fresh for the current225branch, PR, and commit, then use it to decide whether closeout can proceed:226227- Status: ready, not ready, partially ready, or blocked.228- Required gates: checks inferred from `.github/github.json`, repo docs, CI, and229 the changed surface.230- Passed, failed, pending, and not-run evidence with concrete reasons.231- Metadata/docs impact: whether `.github/github.json` or docs changed, were232 checked, are stale, or were intentionally not updated.233- Background review: consume the target, observation time or head SHA, and the234 canonical point-in-time state from the readiness handoff without re-inferring235 a terminal outcome from absence.236- Next action: the smallest step that would change readiness.237238If the readiness handoff is missing, stale, tied to a different commit/PR, or239does not cover the current closeout question, run `repo-readiness` first or240record the gap as a conditional/no safe-to-exit reason. Do not treat closeout241cleanup as proof that gates passed.242243Both this skill and `repo-readiness` read `.github/github.json` with the same244schema expectations: `qualityGate`, `docs`, `metadataFreshness`, `cleanup`,245`importantWorkflows`, repo relationships, health signals, and ownership or246Launchplane routing when present. Readiness uses those fields to decide what247must be verified; closeout uses the same fields to decide what final evidence,248metadata updates, and cleanup remain.249250## Background Review State251252Use `../references/background-review-reporting.md` for target matching,253point-in-time vocabulary, and durable wording. Never infer `skipped`, `not254emitted`, `did not run`, or another terminal state merely because no lifecycle255evidence is visible before the final response.256257Take a point-in-time read when available, but do not poll or delay the final258response solely for a review that can only start after that response. `Not yet259observable` is non-terminal and does not block `Safe to exit: yes` when every260other gate is satisfied. A matching review that is already `in flight` remains261pending evidence and keeps the verdict conditional. Preserve positive terminal262evidence exactly, including cancellation, supersession, failure, skip reason,263and completed findings or no-findings results. `Observation unavailable` keeps264the verdict conditional unless the owning policy explicitly says that review265surface is not required for the current task.266267Never wait indefinitely for a matching review. Use a bounded observation when268it is useful; if the review remains `in flight`, report the verdict as269conditional. Cancellation and supersession are terminal but are not clean270reviews. The never-started exception applies only when a later observation can271read the lifecycle surface and still finds no matching evidence because no272review ever started; then no corrective follow-up is required. If matching273terminal evidence appears after an earlier `not yet observable` summary, always274preserve that original point-in-time statement and add a follow-up; the275never-started exception cannot apply.276277When writing final summaries, closeout comments, or migrated handoff content,278follow `../references/every-code-formatting.md`: cite point-in-time evidence,279keep recovery-critical facts in GitHub for GitHub-backed work, and avoid280boilerplate that does not help the next session resume.281282## Safe To Exit283284Treat "safe to exit" as strict hygiene, not merely context preservation. Safe285to exit means work is ready and hygiene is complete, or unfinished work is286intentionally parked with durable state.287288Any final answer to a safe-to-exit, wrap-up, closeout, pause, or handoff prompt289is incomplete unless it includes a `Love Gate` section.290291Safe to exit: yes292293- Work is complete or explicitly out of scope.294- Gates, inspections, docs checks, metadata checks, and post-merge checks are295 done or explicitly not applicable.296- The owning durable surface was named as closed/updated with evidence, or no297 owning PR, issue, GitHub plan, or saved local plan was in play.298- Background review state follows the point-in-time contract above.299 Current-target findings are resolved, non-blocking, explicitly tracked, or300 declined with a recorded reason under `../references/model-review.md`;301 no matching review is `in flight`. `Not yet observable` is permitted when a302 post-turn trigger may still occur and the answer says so explicitly. Activity303 in detached `auto-review-<hex>` worktrees for older targets is not a gate.304- PR, issue, GitHub plan, and any explicit local plan state is current.305- The branches and worktrees this task created or adopted are accounted for:306 eligible completed ones are removed under the shared cleanup policy, and each307 one that stays is named with its reason and what will remove it. Work from the308 task's own record of what it created, checked against `git worktree list`; a309 path or branch name that looks like this task's is not evidence. A merged task310 checkout left unaccounted for is unfinished closeout; one retained for a311 stated reason is not.312- No important untracked artifacts, transient processes, or hidden follow-up313 remain.314315Safe to exit: conditional316317- Work is unfinished but intentionally parked.318- Blockers and next steps are recorded in a PR, issue, GitHub plan, or explicit319 local/offline saved plan.320- The owning durable surface is named, current, and contains the blocker or next321 action needed to resume.322- Failing and not-run checks are recorded with reasons.323- Current auto-review blockers, if any, are recorded in the PR, issue, or plan324 that owns the unfinished work.325- Remaining docs, metadata, security, or quality follow-up is tracked durably.326- No transient local state is required to resume.327328Safe to exit: no329330- Uncommitted or unexplained work remains.331- Expected gates/readiness checks have not been run and no reason is recorded.332- An owning issue, PR, GitHub plan, or saved local plan remains stale, incorrectly333 blocked, or missing the completed/remaining work state.334- Source-of-truth docs or runbooks disagree with the owning issue/plan and that335 disagreement has not been reconciled or explicitly parked.336- Failing checks, docs/metadata/security follow-up, PR/CI/review state, or337 cleanup work is unresolved and untracked.338- Temporary artifacts or processes could confuse the next session.339340For code changes, broad practical lint/static analysis and `jetbrains-inspection`341state must be included in closeout, or there must be a documented not-run reason342or intentional parking decision. When `.github/github.json` defines343`qualityGate.inspection`, missing JetBrains evidence for code changes prevents344`Safe to exit: yes`; use conditional/no until the inspection is clean, findings345are fixed or tracked, or the not-run reason is explicit. If the inspection346config is blank or feels wrong, ask the user before changing durable policy or347trusting a suspicious value; for a one-off local check, prefer the helper's safe348inferred route with `changed_files` scope and report the assumption.349350## Parking Work and Handoff Surfaces351352Before parking unfinished work or migrating a local handoff, read353[parking and handoff procedures](references/parking-and-handoff.md). Preserve354one current durable owner with its blocker, next action, and verification state.355Use an authorized owning issue or PR when available; valuable local work may use356a known, approved, reconstructable durable location. Apply the plan hygiene357checks below as relevant.358359## Plan Hygiene360361- Use `github-plan` plus the sibling `github` helpers to update the active362 issue's `Current Status`, finish line, blockers, and Project fields before363 parking work.364- For issue-backed work that is resolved without a merged PR, close the owning365 issue with a concise evidence-backed comment, or leave it open with the current366 blocker and next action. Do not rely on a local summary as the only record.367- Before parking or closing a workstream, run a Plan Direction Checkpoint:368 identify the next action, how it fits the current plan, whether the plan or369 issue graph changed, and where that durable state was updated.370- If the work revealed a new blocker, dependency, sub-workstream, or stale371 assumption, update the GitHub issue graph before relying on a handoff summary.372- Treat an accurate issue graph as closeout evidence. A handoff that describes373 work not represented in the owning issue, PR, or related issue graph is374 incomplete unless the user explicitly asked for private/offline parking.375- After a PR merges, sweep issues referenced by the canonical merged PR body and376 comments. `Refs #...` is intentionally non-closing; close only issues whose377 acceptance criteria were conclusively satisfied by the merge. Otherwise,378 update `Current Status` or leave a comment with what remains.379- Mark completed checklist items, record blockers, and remove or rewrite stale380 assumptions in the GitHub plan issue.381- Before declaring safe to exit after closing or merging implementation work,382 inspect the remaining open GitHub issues labeled `plan` and verify their383 labels and Project status/focus fields match their `Current Status`:384 `plan:active`, `plan:blocked`, `plan:waiting`, `plan:stale`, or `plan:done`.385 Re-read the issue or Project item after updating because labels and board386 fields can drift independently. The main LLM owns the final label/status387 decision and any mutations. For large issue sets, a read-only agent may388 summarize likely mismatches, but the main LLM must make and verify the final389 updates.390- If workflow metadata changes are deferred, record the exact `.github/github.json`391 follow-up in the GitHub plan or closeout remaining items.392- Delete or migrate finished local working plans once useful planning context393 has been captured in GitHub, or once implemented behavior has been reflected394 in repo docs when docs are actually stale.395- Migrate stale local plans into active GitHub plans instead of leaving archive396 clutter.397398## Git And Worktree Hygiene399400- Preserve unrelated user changes.401- Do not use destructive Git commands to bypass required evidence or authorization.402- For task cleanup, bulk audits, or repository retirement, apply the shared403 [repository cleanup and preservation](../references/repo-cleanup.md). Preserve404 unique or ambiguous state while investigating; reuse same-action/scope405 authorization and ask only for a missing choice or expanded scope.406- If `git status --short --branch` shows a clean non-runtime-bound branch behind407 its upstream, use the pinned fetched-upstream flow above before saying the408 checkout is tidy. Runtime-bound checkouts must use the landed repo-local409 reconciler instead. Treat dirty, ahead, diverged, missing-upstream, or failed410 fast-forward states as report-only by default. An explicit user request permits411 only the bounded untracked-only exception above; it is not blanket approval to412 overwrite, stash, clean, or include unrelated files.413- When asked to remove a worktree, establish uncommitted changes' disposition414 under the shared policy and retain unresolved or unpreserved state.415 Removing a worktree is not approval to lose its branch or local edits.416- Use `github` for PR-backed branch/worktree cleanup and GitHub417 state.418- Removing an eligible completed checkout this task created needs no new419 question. Eligible still means the shared policy's ownership, live-use, and420 contents checks; dirty or unpreserved state is retained. This covers the421 worktree and its merged local branch, not a remote branch. When the task's422 record does not show that it created a registered worktree, the owner is423 unknown: leave it, and mention it when it bears on this closeout. Detached424 auto-review worktrees stay excluded as described below.425- After merged PRs, include relevant post-merge Actions and GitHub426 security/quality signal outcomes when GitHub data is available. Report signals427 as clean, findings, unavailable, or not enabled; do not treat unavailable or428 not-enabled signals as clean.429- Concrete reproducible broad-gate findings that are not fixed now should be430 tracked after a duplicate search. Group speculative or huge-baseline findings431 into a cleanup plan/report instead of opening many issues.432- If cleanup safety remains ambiguous after the available investigation,433 preserve the candidate and name the exact missing evidence or choice.434435## Auto Review Worktrees436437Codex Desktop and Every Code auto-review flows may create detached review438worktrees under paths like:439440```text441~/.code/working/<repo>/branches/auto-review*442```443444Treat these as external review context, not the active workstream.445446- Ignore them for normal safe-to-exit and dirty-worktree decisions.447- Do not treat their files as blocking the current repo closeout.448- Exclude them from ordinary cleanup. In an authorized bulk or retirement scope,449 preserve them unless the shared policy establishes owner/job completion, lock450 and runtime state, valuable contents, and exact disposition.451- Mention them only when relevant, for example: "Ignored detached auto-review452 worktrees."453- If the user asks about a review result or review worktree specifically, switch454 context deliberately and inspect that worktree as the task target.455456## Required Love Gate457458Before finalizing the closeout, perform a "Love Gate" check. This is an459emotional and qualitative alignment step where the agent evaluates the session's460output against the user's ultimate satisfaction and the agent's own engineering461standards.462463- **Check if you "love" the work**: Does the implementation feel clean, idiomatic,464 and complete? Is the solution robust, or does it feel like a "just-in-case"465 patch?466- **Identify what you do not love**: Are there any compromises, technical debt,467 missing edge cases, or "smells" that remain? Be honest about shortcuts taken468 due to context limits or task complexity.469- **Report findings**: Always include a brief "Love Gate" section in closeout470 and safe-to-exit final answers. The section must include two explicit labels:471 `Love:` for what you love about the result, and `Do not love:` for concerns,472 compromises, or "nothing material" when no meaningful concern remains.473474This gate ensures that the session ends not just with technical passing, but475with a shared understanding of the work's quality and "soul."476477If you think the user's name is Justin, end with one short dad joke about the478session after the safe-to-exit answer.479480## Output Format481482Use a compact closeout report:483484- Done: what changed or was handled.485- Remaining: concrete blockers or follow-up work, including how the next action486 fits the active plan.487- Checks: gates, inspections, docs, metadata, CI/Actions, and GitHub488 security/quality signals that passed, failed, were pending, or were not run.489- Background review: target, point-in-time state, observation time or head SHA,490 and terminal evidence when one was positively observed.491- Love Gate: include `Love:` and `Do not love:` entries. Use `Do not love:492 nothing material` when no meaningful concern remains.493- Cleanup: artifacts, plans, handoffs, branches, or worktrees removed or left494 intentionally.495- State: dirty files, PR status, CI status, or plan status when relevant.496- Owning surface: PR, issue, GitHub plan, saved local plan, or none; say whether497 it was closed, updated, left open or parked with current blocker and next498 action, or not applicable.499- Safe to exit: yes/no/conditional, with the condition if needed.500501If there are no remaining items, say so plainly. Do not over-explain command502output unless the user asks for it.