Send It
Use this skill for an end-to-end "get this branch into a clean PR" workflow. By default, stop before merge.
Workflow
Inspect the worktree with
git status --short --branchandgit diff --stat. Identify intended PR files and leave unrelated dirty or untracked files alone. Determine the PR base branch before changing branches.Confirm the target branch if ambiguous. Do not infer merge intent from phrases like "send it", "ship it", "get this through", or "open the PR"; treat those as PR creation, CI monitoring, and review-comment handling only. Merge is in scope only when the user explicitly asks to merge, enable auto-merge, or merge after checks pass.
Create or switch to the intended topic branch before reviews, screenshots, or cleanup. Preserve unrelated dirty and untracked files exactly as found. Run
git fetch origin <base>and compute the merge base againstorigin/<base>(not local<base>, which may be stale) so every diff in this workflow matches what the actual PR diff will be. Do not merge or rebase the base branch into the topic branch; only diff against fresh remote state.- Pre-flight check: verify everything this workflow needs is installed and authenticated before starting —
git,gh(authenticated), the reviewer CLIs (codex,opencode,coderabbit),trufflehog(the autoreview helper runs it as a secret preflight over the changed content and fail-closes when the binary is missing), and anything the repo's hooks or validation scripts require. Install or fix missing dependencies now, never mid-loop. - On macOS, keep the machine awake for the whole run so long review rounds and UI validation never hit a sleeping or locked screen: start
caffeinate -di &at the beginning, record its PID, and kill it at close-out (step 10).
- Pre-flight check: verify everything this workflow needs is installed and authenticated before starting —
Commit the intended changes before any cleanup or review:
- Secret-scan the intended files first: run the repo's scanner if it has one (e.g.
pnpm secretlint), otherwise skim the files for keys, tokens,.envmaterial, and dumps. Never commit secrets. - Commit only the intended PR files, including intended untracked files — never
git add -A. Leave unrelated dirty and untracked files exactly as found. - Then do a diff-minimization cleanup pass against the base branch:
- Review the full intended PR diff with commands such as
git diff --stat <merge-base>,git diff --numstat <merge-base>, andgit diff <merge-base> -- <intended files>, where<merge-base>is the merge base between the topic branch andorigin/<base>. - Look for safe ways to reduce added lines, total diff size, and review noise while preserving the same functionality and tests. Good targets include dead code, duplicated logic, overly broad abstractions, unused helpers, debug scaffolding, generated or accidental files, unnecessary renames, and style-only churn mixed into feature work.
- Apply cleanup only when it keeps behavior equivalent or clearer. Do not remove meaningful tests, important edge-case handling, accessibility, security checks, or code clarity just to shrink the diff.
- Review the full intended PR diff with commands such as
- After cleanup, rerun targeted validation for the touched area, commit the cleanup, then continue. Repeat the cleanup pass at most once more (2 passes total, each followed by a commit) if more safe cleanup is obvious, then continue automatically with the remaining workflow.
- Secret-scan the intended files first: run the repo's scanner if it has one (e.g.
Before creating the PR, run the review round loop (also reused in step 8, but with a different diff target there):
- The Codex-engine and opencode-engine reviewers both run through the autoreview helper bundled with this skill at
scripts/autoreview(resolve relative to this SKILL.md). If the bundled copy is missing, stop and report — do not substitute a copy from another skill; divergent copies have caused mid-run behavior changes in the past. It runs each engine in an isolated workspace with project config, skills, and plugins disabled. Always pass--repo-access: it gives the reviewer read-only repo access (read/grep/glob; gitignored files excluded from search) so it can verify callers and surrounding code — findings still must target files in the diff. - Pre-flight secret scan (once per run, before the first reviewer round): the autoreview script first runs TruffleHog over temporary snapshots of the exact changed content (fail-closes with an install link when the binary is missing — a TruffleHog hit means a likely real credential: remove or rotate it, never suppress it), then fail-closes with
refusing to include secret-like content in review bundlewhen its built-in scanner flags secret-like assignments in the diff, and it runs both scans before any engine starts — so probe cheaply first by running<skill>/scripts/autoreview --mode branch --base <round-base> --repo-accesson its own. If it refuses, locate the flagged file/lines and verify each is a false positive with concrete evidence (in-memory variable copies, decoder/model assignments, identifiers merely namedtoken/accessToken— never a literal credential). For confirmed false positives, add an inlineautoreview:allow-secretcomment on the flagged line (e.g.// autoreview:allow-secret), commit, and re-probe until the scan passes; note: Swift and other non-JS/TS files get no source-code leniency from the scanner, so OAuth/device-flow code trips this often. NEVER add the marker to a genuine secret — real secrets must be removed or rotated; if one is found, stop the workflow and report. Only then proceed with the parallel reviewer round. - Round start: run the four reviewers once each, in parallel when possible, against the round's diff target (see phases below) using
--base <round-base>:<skill>/scripts/autoreview --mode branch --base <round-base> --repo-access --stream-engine-output. Do NOT usecodex review— it loads user-installed skills and has recursively spawned the whole send-it harness in practice.<skill>/scripts/autoreview --mode branch --base <round-base> --engine opencode --model kimi-for-coding/k3 --repo-access --stream-engine-output(if opencode is installed). If the run fails because the model is unavailable, retry once without--modelto use opencode's default configured model.<skill>/scripts/autoreview --mode branch --base <round-base> --engine opencode --model xai/grok-4.5 --repo-access --stream-engine-output(if opencode is installed). If the run fails because the model is unavailable, skip this reviewer for that round and disclose the skip in the final report — do not fall back to a different model, since that would duplicate the kimi reviewer.coderabbit review --agent -t all --base <round-base>(if CodeRabbit CLI is installed and authenticated)
- Suppression prompt: reviewers have no memory between rounds, so feed the rejection ledger (see below) back to them. When
/tmp/send-it-findings-<repo>-<branch>.mdexists and is non-empty, append this to all three autoreview invocations (the flag injects extra instructions into the review prompt; it never replaces it):--prompt "The following findings were already triaged as wont-fix or false-positive with concrete evidence; do not re-report them unless the current diff materially changes the cited code: $(cat /tmp/send-it-findings-<repo>-<branch>.md)". Skip the flag when the ledger is missing or empty. CodeRabbit cannot take this context, so rely on the triage-time ledger check for its re-raised findings. - Diff targets by phase: Phase A — round 1 uses the full branch diff (
<round-base>=origin/<base>, matching the future PR diff); every later round uses only the delta since the last reviewed head (<round-base>= the head SHA reviewed in the previous round), keeping rounds fast. Record the reviewed head SHA at the end of every round. If a delta round's valid findings touch more than 3 files, jump straight to a full-diff round instead. Phase B — once a delta round reports no new actionable findings from all four reviewers, switch to full-diff rounds vsorigin/<base>. The loop normally terminates on an all-clean full-diff round, but full-diff rounds are the most expensive step in this workflow and reviewers keep finding marginal issues on large diffs indefinitely — so cap them at 3: if the third full-diff round produces no new fix-worthy findings (only ledgered rejections or accepted risks, see triage below), the loop terminates as well. - Reviewer failure handling: for the autoreview reviewers, exit 0 means clean and exit 2 means findings — both are valid review outcomes. Exit 1 (abort/error), getting killed (e.g. exit 143), timing out, or producing empty or unparseable output counts as errored — never as clean. For CodeRabbit, any non-zero exit or rate-limit error counts as errored. Rate limits are a skip, not a blocker: if any reviewer reports a rate limit, do not retry it — skip it for that round, continue the loop with the remaining reviewers, and disclose the skip in the final report. Retry other errored reviewers one at a time (not in the parallel batch), at most 2 retries. If a reviewer is still unavailable after that, record it as unavailable and disclose that in the final report. When the CLI is rate-limited, count a completed hosted review on the PR as satisfying the CodeRabbit requirement for those rounds.
- Collect all findings, dedupe them, and treat every finding as a hypothesis. Verify each against the current code. Mark false positives and intentional behavior as wont-fix; do not fix them. Reject a finding only with concrete evidence (command output, line-numbered reads, typecheck, live API probes, official docs for library/API behavior claims), never on intuition.
- There is also a third, cheaper triage outcome for findings that are TRUE but not worth fixing: mark them accepted risk when the severity is low, the trigger is pathological, or the fix cost is disproportionate to the impact (e.g. a model-wide refactor for a label nuance). No disproof is required for accepted risk — but the ledger entry must state plainly what the finding is and why it is being skipped, and every accepted-risk finding MUST be presented to the user in chat as a list (what it was, why it was skipped) when the loop converges, before PR creation, and again in the final report, so the user can review and veto each one.
- Track rejected findings in a per-run ledger at
/tmp/send-it-findings-<repo>-<branch>.md(outside the repo, never committed). Truncate it when the loop starts; append every rejected finding with its title, priority, the claim, the concrete evidence that disproved it, and the round number. Append accepted-risk findings the same way, taggedaccepted-risk, with the skip rationale instead of disproof. Keep entries compact — the ledger is also fed back to the autoreview reviewers as a suppression prompt each round. - Reviewers have no memory between rounds and regularly re-raise the same finding reworded. Before verifying a finding, check the ledger: if it matches an earlier rejection, dismiss it by citing the existing evidence instead of re-investigating. Investigate fresh only when the report adds a genuinely different angle.
- Fix all valid findings of a round with ONE fix subagent that receives the full triaged findings list and addresses them together — never one subagent per finding, since parallel fixers fight over the same files. The subagent prompt includes an instruction to check official docs before fixing when library or API behavior is involved. Run targeted checks after fixes.
- Anti-whack-a-mole guard: if two consecutive fix rounds touch the same component or function, do not apply another point patch — have the fix subagent re-read and holistically restructure that component's logic or state machine instead. Repeated micro-fixes to the same spot reliably introduce the next regression, which the next round then has to catch.
- Serialize rounds: never run reviewers while a fix subagent is editing the tree (reviewers working from a mutating tree produce stale results and wasted rounds). Each round is strictly: reviewers in parallel → triage → single fix subagent → targeted checks → commit the round's fixes → next round.
- Freeze check: record
HEADat round start. IfHEADmoved or the tree is dirty when all reviewers have finished, discard every result from that round and re-run it. - Re-run all four reviewers on the new state and repeat the loop per the phases above — meaning each round has zero findings, or only findings already triaged as wont-fix or accepted-risk, terminating on an all-clean full-diff round or on the Phase B full-diff cap.
- Soft round budget: after round 8, if three consecutive rounds produced no new fix-worthy findings (only ledgered re-raises or accepted risks), stop and decide whether to ship or continue — tell the user your reasoning (e.g. "last N rounds yielded no meaningful findings, converging") instead of grinding more rounds by default.
- The Codex-engine and opencode-engine reviewers both run through the autoreview helper bundled with this skill at
For UI-visible changes, capture "after" screenshots of the changed views when trivial — only after the review loop in step 5 has converged and validation is green, immediately before creating the PR; add before/after comparison shots only if cheap to get:
- Any UI-visible change made after capture (CI fixes, review feedback) invalidates the screenshots: recapture, re-upload, and replace the PR links before merge.
- Use a browser tool to capture comparable views, such as Playwright CLI, @Browser, the Chrome plugin, or the repo's existing visual QA command.
- If the UI is gated, auth-walled, or otherwise nontrivial to capture, skip screenshots entirely — do not fight for them.
- Store screenshots as temporary local artifacts only; do not commit them.
- Upload screenshots to catbox.moe (permanent links, no API key needed):
curl -F "reqtype=fileupload" -F "fileToUpload=@screenshot.png" https://catbox.moe/user/api.php - Verify each returned
https://files.catbox.moe/...URL is a direct image link with animage/*content type before embedding it in the PR description. If verification hangs, retry with HTTP/1.1, for example:curl --http1.1 --max-time 20 -I https://files.catbox.moe/example.png - If the catbox upload or verification fails, skip screenshot links and note that the upload failed.
Run repo-appropriate validation from
AGENTS.md, package scripts, and CI config. Commit only intended files, push the topic branch, and create a PR with a concise summary, validation notes, and UI screenshot links when applicable.- Check for a pre-push hook (e.g.
.husky/pre-push) before running the full validation suite manually. If the hook runs the full gate (lint, typecheck, tests, build), run only quick targeted checks locally and let the hook be the full gate — do not run the entire suite twice. - When committing, wait for the commit command to finish completely — pre-commit hooks may run lint, tests, and builds for several minutes. Never abandon a still-running commit and never start a concurrent build in the same worktree. If the tool call times out, keep polling that same session until the hook exits, then verify with
git log/git statuswhether the commit was created. Retry the commit only after confirming no hook processes are still running.
- Check for a pre-push hook (e.g.
Monitor the PR until it is clean:
- Watch CI with
gh pr checks <number> --repo <owner>/<repo> --watch --interval 20 2>&1 | tail -15instead of blind sleep loops — it blocks until checks settle and exits non-zero on failure. Check latest head SHA, merge state, reviews, comments, and review threads once the watch returns. - When checks flip green, still wait ~30 seconds and then re-audit review threads (e.g.
gh api graphqlreviewThreads) before treating the PR as clean — review bots, especially CodeRabbit, often publish inline threads only after their check turns green. - A green check whose output says it did not actually review (e.g. CodeRabbit's "Review rate limited") counts as NOT reviewed. Do not treat it as a review pass; rely on the local review round loop for that head and note the gap in the final report.
- If CI fails: implement fixes and commit them locally (only intended files; secret-scan any newly added files). Then run the review round loop from step 5 scoped to the fix commits — diff against the pushed head instead of
origin/<base>:<skill>/scripts/autoreview --mode branch --base origin/<topic-branch> --repo-access --stream-engine-output,<skill>/scripts/autoreview --mode branch --base origin/<topic-branch> --engine opencode --model kimi-for-coding/k3 --repo-access --stream-engine-output(same no---modelfallback as step 5),<skill>/scripts/autoreview --mode branch --base origin/<topic-branch> --engine opencode --model xai/grok-4.5 --repo-access --stream-engine-output(same skip-on-unavailable rule as step 5), andcoderabbit review --agent -t committed --base origin/<topic-branch>, with the same ledger suppression--prompton the autoreview invocations and a single fix subagent per round as in step 5, until no new actionable findings remain. Then push and resume CI polling from the new head SHA. - If a feedback round touched more than 3 files or more than ~50 lines, run one final full-branch-diff review round (step 5 reviewers against
origin/<base>) before treating the new head as ready. Small fixes skip this. - Fix valid review comments, resolve fixed, outdated, or false-positive threads, commit, push, and resume polling from the new head SHA.
- Loop until CI is green and no unresolved actionable comments remain.
- Watch CI with
If and only if the user explicitly requested a merge, merge only when the latest PR head satisfies all gates:
- merge state is clean
- required checks are green
- review bots are success or skipped, not pending
- all review threads are resolved or outdated
- no unresolved actionable comments remain
- local worktree has no unintended tracked changes
Merge with the verified latest head SHA. Never enable auto-merge or merge manually as part of the default workflow.
Report the PR URL, final head SHA, checks passed, review/comment status, merge readiness, UI screenshot links when applicable, and any remaining local untracked files. Include the merge commit SHA only if a user-requested merge was completed. Always include the accepted-risk list from step 5 (each finding and why it was skipped), and stop the
caffeinateprocess started in step 3.