active/fin/SKILL.md
Finalize completed PR or local checkout work.
npx skillsauth add kevinslin/skills finInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Use this skill at the end of a task before the final user-facing report.
Run fin [context] [target].
gh: finalize from a GitHub PR context. Use this when the task should land by merging the current remote PR or when the matching PR already merged and only cleanup/final verification remains. The original fin workflow maps to this context.local: finalize from a local checkout. Use this when the task should land directly from local git state without depending on GitHub PR state.[target]: optional for gh only. Accept a PR number, PR URL, or branch name. Examples: fin gh 85117, fin gh https://github.com/owner/repo/pull/85117.HEAD, treat that as a preflight issue, not a valid finalization state. Create a short-lived local branch from the current commit before auto-detecting context, checking mergeability, or attempting worktree cleanup.gh or local, respect it throughout the flow. Do not silently switch later just because repo state would make the other path easier.gh has an explicit [target], lock that PR target before current-branch detection. Use the target PR as the source of truth for state, mergeability, comments, checks, spec matching, merge, and automation cleanup.[target] but the immediately preceding active heartbeat or delayed-merge instruction names exactly one PR and the user asks to merge, finalize, ignore a waiting period, or ignore a proof gate, treat that PR as an explicit gh target after one live PR-state check. Report the target source as heartbeat automation.gh target does not match the current branch, do not silently fall back to the current branch's PR. Either run the remote-PR finalization path for that explicit target, or stop with a target mismatch before any spec archival, branch cleanup, or merge.gh when the current branch has an open or already-merged PR that corresponds to the branch being finalized.local when the current branch has no matching PR and the work should land directly from local git state.gh / local, stop and ask the user which context to use.Target: PR #<number>, branch <headRefName>, source=<current checkout|explicit user PR|heartbeat automation>. When multiple PRs have been mentioned in the session, prefix every PR-specific state claim with the PR number.main checkout lives.~/.fin.yaml for repo-specific finalization instructions before landing or cleanup. If the file exists, parse entries shaped as workspace: [{path: ..., instructions: ...}].~/.fin.yaml exists but cannot be parsed, do not treat the parse failure as "no hooks". Report the parser error separately and inspect the raw file. Continue only when the raw content is clearly non-executable, unambiguous context; if it might contain commands, hooks, destructive instructions, or ambiguous cleanup requirements, stop before spec archival, landing cleanup, or linked-worktree removal and report the malformed config as the blocker.workspace[].path against the normalized non-worktree checkout root for the branch's repository, not against a transient linked worktree path. Resolve symlinks and trailing slashes before comparing.~/.fin.yaml workspace entry exists, record its instructions and apply them after the PR merge / already-merged confirmation or local landing succeeds, but before removing any linked worktree. This preserves ignored or untracked files that may need to be copied out of the soon-to-be-removed worktree.~/.fin.yaml instructions as routing context for active spec discovery. If the instructions mention a $specy, $mem, or .mem artifact root, derive candidate docs roots from that instruction before falling back to the default docs root.~/.fin.yaml is missing or no workspace entry matches the non-worktree checkout root, state that no repo-specific final hooks applied and continue.HEAD, create a temporary local branch from the current commit first. Prefer the repo's normal task-branch prefix when one exists, otherwise use a short codex/ branch name derived from the task.HEAD into a named branch, lock that branch identity for the rest of the run. Do not continue finalization from anonymous detached state.gh, do not fall back to local-only landing. If the user requested local, do not silently land via PR merge just because a PR exists.gh without an explicit target, identify the current PR and check its state before testing mergeability or attempting any merge command.gh with an explicit target, identify that target PR directly with GitHub before consulting current-branch PR state. If the current checkout points at another PR, report the mismatch in the target identity line and ignore the other PR unless it blocks local cleanup.gh, identify any active PR babysit/watch automation for the target PR or branch when automation state is visible. Record its id so it can be updated or deleted after the PR lands.main refresh, and retrospective.gh, when the target PR is still open, confirm it is mergeable against main or its base branch.
gh pr view reports UNKNOWN/indeterminate mergeability while checks and reviews otherwise look green, poll the REST pull-request endpoint once or twice for mergeable and mergeable_state before invoking conflict repair. Treat REST mergeable: true with mergeable_state: clean as the mergeability confirmation; treat repeated null/unknown as indeterminate and wait or report it.local, confirm the current branch is mergeable into local main.gh flow is blocked only by base-branch conflicts, run trigger:fix-pr-conflict against the locked target PR and let it try to restore a clean merge state.gh flow is blocked by broader PR issues, or conflict repair needs a fuller pass, run trigger:fix-pr against the locked target PR.local flow is blocked only by trunk drift, run trigger:sync-branch or otherwise rebase the current branch onto the merge target before retrying the check.DOCS_ROOT when it is configured.~/.fin.yaml instructions mention an absolute .mem artifact root for $specy, $mem, or notes, add <that-root>/main when the instruction points at .mem, or the path itself when it already points at .mem/main../docs.specy's layout rule for each candidate root: active specs live directly under $DOCS_ROOT/specs/.$DOCS_ROOT/specs/ as active specs. Ignore files already under $DOCS_ROOT/specs/.archive/.ag-dir-v2: an active spec folder lives directly under a candidate $DOCS_ROOT/specs/<spec-slug>/ and contains spec.md, with optional sidecars such as checklist.md or data/. Treat the folder as the active spec unit, not only spec.md.spec.md..archive/
until the whole folder spec is complete.$DOCS_ROOT/specs/.archive/, creating the directory if needed. For folder specs, move the whole folder so sidecars such as checklist.md and data/ stay with the completed spec.specy's convention exactly: when a single-file spec is complete, move it to $DOCS_ROOT/specs/.archive/ and keep the same filename.gh Context WorkflowMERGED, do not run trigger:merge-pr; record the merge commit or merged-at details when available and proceed as an already-landed PR.trigger:merge-pr immediately after the matching spec has been marked complete and archived.gh pr merge <target>, after the matching spec has been marked complete and archived. Do not use current-branch merge shortcuts for a different PR.main, delete matching automation, and report that no local target checkout cleanup was applicable.~/.fin.yaml. Treat these hooks as part of finalization; if they fail, stop before deleting the worktree and report the exact blockage.git -C <worktree> reset --hard and git -C <worktree> clean -fdx. This is intentionally destructive because the worktree is being deleted; do not run it against the non-worktree main checkout or any worktree that is not being removed.gh pr merge --delete-branch already deleted the remote branch but failed local deletion because the branch was still attached to the worktree, finish the cleanup explicitly instead of retrying the merge.git worktree prune.HEAD, do not use ancestry alone as the safety check. For squash or rebase merges, verify the GitHub PR is MERGED, record the PR head SHA and merge commit, refresh local main, confirm local main contains the merge commit, and only then delete the local branch when no worktree checks it out.main cannot be refreshed because the non-worktree checkout has unrelated dirty changes, treat the remote PR landing and linked-worktree removal as complete but defer local branch deletion. Report the dirty-main refresh blocker exactly, keep the local branch until local main can safely contain the merge commit, and do not force-delete it from GitHub state alone.main checkoutmain if needed.main to origin/main.main HEAD includes the merge commit for the landed PR before continuing.git branch -d rejected ancestry, finish that branch deletion now after local main contains the PR merge commit and the branch is no longer checked out anywhere.main refresh fails because the non-worktree checkout has unrelated dirty changes, stop local-main refresh and report a partial terminal state instead of overwriting or stashing user work: PR landed, any linked worktree cleanup completed, automation cleanup completed if it was safe to do, local main not refreshed, and local branch deletion deferred when squash/rebase containment proof is unavailable.main refresh fails for any other reason, stop and report the exact git error instead of claiming the task is fully finalized.local Context Workflowtrigger:commit-code first.main checkout when possible, not from an attached feature worktree.main before merging when the repo has a remote, but do not discard the completed work while doing so.main. Use a non-fast-forward merge unless the user explicitly requested a different merge style.main, do not fabricate a merge commit; instead verify that main already contains the intended change set and continue.main is appropriate for the repo, push the updated main after the local merge. If the flow is intentionally local-only, state that explicitly in the report.~/.fin.yaml. Treat these hooks as part of finalization; if they fail, stop before deleting the worktree and report the exact blockage.git -C <worktree> reset --hard and git -C <worktree> clean -fdx. This is intentionally destructive because the worktree is being deleted; do not run it against the non-worktree main checkout or any worktree that is not being removed.git worktree prune.main.main checkoutmain if needed.main HEAD includes the merge commit or direct commit that landed the completed work.main, confirm the pushed remote ref contains the landed commit too.main verification fails, stop and report the exact git error or verification gap instead of claiming the task is fully finalized.$ag-learn after the task lands in the requested context, after any matching spec has been archived, and after any matching repo-specific final hooks from ~/.fin.yaml have completed.gh, run it after the PR merge or already-merged confirmation, repo-specific final hooks, and local main refresh complete.local, run it after the local merge, repo-specific final hooks, and local main verification complete.ag-learn finds no meaningful improvement opportunities, say that explicitly.gh or local.gh, state the target identity line with PR number, branch, and source before reporting mergeability, checks, blockers, merge, or cleanup. If another PR was also present in the current checkout, explicitly state that it was not the finalization target.fix-pr-conflict / fix-pr / sync-branch / manual repair.gh, state whether the PR was already merged and merge-pr was skipped, or whether merge-pr ran successfully, including whether the remote merge succeeded directly or required separate post-merge worktree cleanup because local branch deletion failed.local, state whether the branch landed via local merge, was already on main, or was blocked before landing.gh, state whether any PR babysit/watch automation was found and whether it was deleted, already absent, or blocked.main containment check used as the cleanup proof.main checkout was updated or verified successfully and identify the resulting main tip when relevant.main refresh was blocked by unrelated dirty changes, call that out as partial local cleanup: include the merge commit, the dirty-main error, which cleanup steps did complete, and which local branch or verification step was intentionally deferred.~/.fin.yaml was checked, whether it parsed successfully, whether a workspace entry matched the non-worktree checkout root, and whether the matched repo-specific final hooks completed or were skipped.local pushed main, state whether the push succeeded. If it intentionally remained local-only, say that explicitly.ag-learn saved the learning note.main, completed retrospective..archive unless the task is actually complete.HEAD; create a named branch first.gh to local or from local to gh.gh vs local when the argument is omitted and branch PR state clearly determines the context.gh from a no-argument invocation unless the PR belongs to the current branch being finalized.trigger:merge-pr when GitHub reports the matching PR is already MERGED; use the existing merged state and continue finalization from there.gh repair via fix-pr-conflict or fix-pr cannot restore a mergeable state, stop and report the blockage instead of continuing the finalization flow.local repair via branch sync or rebase cannot restore a mergeable state, stop and report the blockage instead of continuing the finalization flow.merge-pr in gh mode before the matching spec is marked complete and archived.local mode.gh pr merge --delete-branch local branch-deletion failures caused only by linked worktree attachment as a failed merge when the remote PR already landed.gh mode, when it is a detached temporary PR review worktree tied to the finalized PR by PR number/path or recorded head SHA.main contains the PR merge commit first, and verify no worktree still checks out the branch.main cannot be refreshed because it has unrelated dirty changes, do not use that dirty checkout as a reason to delete a squash/rebase-merged local branch. Leave the branch, report the dirty-main blocker, and let cleanup resume after local main can be safely fast-forwarded.~/.fin.yaml.git worktree remove cannot be blocked by disposable local changes.main checkout or any checkout that will remain after finalization.~/.fin.yaml workspace paths against temporary linked worktree roots; match the non-worktree checkout root for the branch's repository.~/.fin.yaml workspace entry. If the additional instructions are ambiguous, destructive, or cannot be verified, stop and report the blocker before cleanup.~/.fin.yaml; a parse failure is a finalization preflight issue unless raw content is clearly non-executable and unambiguous. Never delete a linked worktree while malformed fin config might contain unrun hooks or cleanup instructions.main still points behind the landed result unless the user explicitly says not to refresh or verify it.specy convention already present in the workspace.spec.md when the active spec uses a folder schema. Move the entire spec folder so checklist, data, and other sidecars remain attached.ag-learn output just because the task was straightforward; run it and report either the proposals or the explicit no-learning result.fin was run with either an explicit gh / local argument or no argument and a context auto-detected from current-branch PR state.gh mode, any explicit PR number, PR URL, branch target, or heartbeat-derived PR target was locked before current-branch PR detection and reused for every PR-state, mergeability, merge, automation, and cleanup decision.HEAD, it was converted into a named branch before context detection and landing.main or its base branch before spec archival, unless the matching PR was already merged; any detected conflicts were handled with trigger:fix-pr-conflict, trigger:fix-pr, trigger:sync-branch, or an equivalent local repair flow.$DOCS_ROOT/specs/.archive/; folder specs were moved as whole folders only
when the parent spec was complete, and milestone or sidecar completions inside
still-active parent specs were recorded without archiving the parent.~/.fin.yaml was checked, parsed or explicitly handled as malformed, and any workspace entry matching the non-worktree checkout root was applied before linked-worktree removal.gh mode, the matching PR was checked for an existing MERGED state before attempting merge; trigger:merge-pr has been run after archival only when the PR was not already merged, or the missing-PR condition was reported explicitly.local mode, the completed branch has been merged into local main or verified as already landed there.git reset --hard and git clean -fdx after final hooks ran and before git worktree remove.git worktree prune was run, and the merged local branch was deleted when it was no longer checked out anywhere; unrelated named worktrees and branches were left untouched.main containing the PR merge commit, not branch ancestry alone.main checkout was refreshed or verified to include the landed work before the task was reported complete.$ag-learn has been run.main refresh or verification result.development
Resolve explicit shortcut triggers and usage. Always read this file at the start of a thread or when user mentions `trigger`.
testing
Improve skills from observed agent friction in sessions, PRs, or audits.
development
Generate incremental Slack digests for channels, topics, and categories.
testing
Audit an OpenClaw maturity-scorecard surface into an evidence-backed component score report. Use when given a surface from an OpenClaw maturity-scorecard.md and asked to score coverage, quality, readiness, or generate a detailed surface report plus per-component subreports.