snap-resolve ยท diff

git:20260927.7808db4 to git:20261015.053a170

121 added, 34 removed. Audit A to A.

---
name: snap-resolve
description: >
- Use when a GitHub PR has reviewer feedback, requested changes, failing checks,
- unanswered comments, or unresolved review threads that must be fixed, replied
- to, and resolved.
+ Use when the user asks to resolve PR review feedback, failing checks, or unresolved threads
---
- ## Invocation
+ Take every open review item and failing check on the PR to done: fix or explain, reply, resolve:
- Syntax: `/skill:snap-resolve [ask]`
+ ```
+ pr = owner, repo, number from branch or session # ask only when none
- Parse shell-style arguments; bare keys mean `true`. `help` prints usage and stops. Unsafe unknown arguments stop with usage.
+ if this session reviewed this PR and the reviewed head SHA == PR head: # warm handoff
+ reuse its evidence, findings, and posted review
+ refresh only: local status and HEAD, PR head SHA, checks, feedback newer than the review, thread state
+ # everything else is cached; fetch a source only to fill a specific gap
+ else: # cold start
+ gather body, comments, reviews, threads and replies, commits, checks, failed logs, linked artifacts that affect intent or acceptance
+ # a changed head, other target, failed review post, or conflicting evidence invalidates only the affected evidence; refresh that
+ threads = capture query
+ ci = ci items
- ## Args
+ items = dedupe(findings and feedback + ci) # merge a CI failure with feedback on the same defect; keep that feedback's ids
+ classify each:
+ FIX # code, docs, or test change
+ EXPLAIN # reply only
+ CI # check failure
+ Already addressed # current evidence proves it
+ Unsure # evidence missing, conflicting, or inaccessible
- | Key | Values | Default | Effect |
- | --- | --- | --- | --- |
- | `help` | bool | false | print usage; do not execute |
- | `ask` | bool | false | wait for approval before changing anything |
+ if the user asked to approve first: show the worklist; run only approved items; Unsure needs clarification first
+ else: run FIX, EXPLAIN, CI; skip Already addressed; hold Unsure
- ## Routes
+ for item in selected:
+ if trivial: # typo, import, mechanical rename
+ edit; verify; commit
+ else:
+ red(item) # extend the existing test owner; add one public-interface regression only when existing coverage misses the former failure; fails on pre-fix code for the reported reason; asserts behavior, not implementation; coverage alone never justifies it
+ green(item) # smallest change that passes; no unrelated refactoring
+ run targeted test, lint, type, build; fix every local failure
+ commit # fix(scope): address <issue>; keep the full SHA for the reply
+ refactor while green when fixes exposed duplication, brittle seams, or an awkward interface # refactor(scope): <improvement>, separate commit
- | Selector | Behavior |
- | --- | --- |
- | default | execute clear `[FIX]`, `[EXPLAIN]`, and `CI` items automatically; hold `Unsure` |
- | `ask` | present the full worklist; execute only explicitly approved items |
+ push once
+ plain(replies) # everyday words; one idea per sentence; cut each sentence the reviewer would not miss
+ for item in FIX and EXPLAIN: reply through its channel; resolve its thread after the reply succeeds
+ rerun the capture query # every unexpected unresolved thread is a missed reply, failed resolution, or reported blocker
- ## Workflow
+ report commits, local checks, replies, pending CI, held Unsure, blockers # pending CI is reported, not awaited
+ done = every item completed, skipped with evidence, held, or blocked with a reason; every failed check mapped to an item or a blocker
+ ```
- 1. **Target.** Identify the PR from branch or session context and record its `owner`, `repo`, and `pr` number. Ask only when neither provides one.
+ ## CI items
- 2. **Evidence.** Choose the narrowest route that proves the current worklist:
- - **Warm handoff:** when the current session contains a completed review of the same PR and its reviewed head SHA still matches the PR head, reuse its gathered evidence, conclusions, and posted review as the starting record. Refresh only mutable execution state: local status and HEAD, the PR head SHA, current checks, feedback created after the review, and identifiers or resolution state needed for selected replies. Treat the PR body, reviewed diff, commits, repository instructions, linked artifacts, and established findings as cached; fetch one only to fill a specific gap.
- - **Cold start:** otherwise gather the PR body, comments, reviews, threads and replies, commits, current checks, failed logs, and linked artifacts that affect intent or acceptance.
+ ```
+ gh pr checks "$pr" --repo "$owner/$repo" --json name,state,bucket,link,workflow
+ # keep bucket "fail", newest run per workflow; record pending checks for the report
- A changed head, different target, failed review post, conflicting evidence, or missing action-critical detail invalidates only the affected cached evidence; refresh that evidence rather than restarting discovery. Follow [`references/ci-checks.md`](references/ci-checks.md) for current failed checks. Complete when every reused fact is tied to the current PR head and every candidate item has enough current evidence to classify.
+ gh run view "$run_id" --repo "$owner/$repo" --log-failed # run_id from /actions/runs/<run-id>
+ # per job, the first root failure: assertion or compiler output, error code, test name, file:line
+ # inaccessible log -> blocker
- 3. **Worklist.** On a warm handoff, start from the review's established findings and unresolved feedback, add only newer feedback and current CI failures, then deduplicate. On a cold start, build the worklist from gathered evidence. Classify each item:
- - `[FIX]`: code, documentation, or test change
- - `[EXPLAIN]`: reply only
- - `CI`: current check failure
- - `Already addressed`: current evidence proves completion
- - `Unsure`: evidence is missing, conflicting, or inaccessible
+ item = CI | <check name> | <specific error> | <files> # one per independent root cause; CI-only items get no reply
+ ```
- 4. **Gate.** On the default route, run every clear actionable item, skip `Already addressed`, and hold `Unsure`. On `ask`, show the full worklist and wait; clarification is required before selecting `Unsure`.
+ ## Threads
- 5. **Resolve.** Process selected items vertically and commit each fix atomically:
- - Substantive: follow [`references/tdd-cycle.md`](references/tdd-cycle.md).
- - Trivial: edit, verify, and commit directly.
- - After local checks pass: push once, then follow [`references/thread-resolution.md`](references/thread-resolution.md). Report pending GitHub CI without waiting.
+ Capture query, paginated past 100 threads. Keep each thread's `id`, `isResolved`, and its root comment `databaseId` (`replyTo: null`) and `url`. Replies target the root; the REST endpoint rejects replies to replies.
- 6. **Report.** List commits, local checks, replies, pending CI, held `Unsure`, and unresolved items. Every work item must end as completed, skipped with evidence, held for a decision, or blocked with a concrete reason.
+ ```bash
+ gh api graphql --paginate -f query='
+ query($owner: String!, $repo: String!, $pr: Int!, $endCursor: String) {
+ repository(owner: $owner, name: $repo) {
+ pullRequest(number: $pr) {
+ reviewThreads(first: 100, after: $endCursor) {
+ nodes {
+ id
+ isResolved
+ path
+ comments(first: 50) {
+ nodes {
+ databaseId
+ body
+ url
+ author { login }
+ replyTo { databaseId }
+ }
+ }
+ }
+ pageInfo { hasNextPage endCursor }
+ }
+ }
+ }
+ }
+ ' -F owner="$owner" -F repo="$repo" -F pr="$pr"
+ ```
+
+ ```
+ channel(item):
+ review thread or line comment -> gh api --method POST "repos/$owner/$repo/pulls/$pr/comments/$comment_id/replies" -f body="$body"
+ top-level PR comment -> gh pr comment "$pr" --repo "$owner/$repo" --body "$body" # wrapped in the quote template
+ CI only -> no reply # a merged CI item uses its feedback's channel
+ # inline reply fails: report it; fall back to a quote reply only when it still helps the reviewer
+
+ resolve(thread): # only after its reply succeeds; Unsure, skipped, already addressed, already resolved, and failed-reply threads stay as they are
+ gh api graphql -f query='mutation($threadId: ID!) { resolveReviewThread(input: { threadId: $threadId }) { thread { id isResolved } } }' -F threadId="$thread_id"
+ # permission failure: report and continue
+ ```
+
+ ## Reply templates
+
+ FIX:
+
+ ```markdown
+ ## FIXED
+
+ - Fixed [concern] in [commit](https://github.com/OWNER/REPO/commit/SHA).
+ - [Observable result or regression coverage.]
+
+ Verified:
+ - `[command that ran]`
+ ```
+
+ EXPLAIN:
+
+ ```markdown
+ ## EXPLANATION
+
+ - [Behavior, scope, or decision.]
+ - [Issue, PR, or spec link; drop when none.]
+ ```
+
+ Top-level quote wrapper:
+
+ ```markdown
+ > [Feedback excerpt.]
+ >
+ > Source: ORIGINAL_COMMENT_URL
+
+ [FIXED or EXPLANATION body]
+ ```