From api-dev
Validate and sign off a PR in core-web-api: squash commits, run bin/ci (rspec + rubocop + brakeman + signoff), verify undercover diff coverage, and update the Notion task status.
How this skill is triggered — by the user, by Claude, or both
Slash command
/api-dev:pr-signoffsonnetThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Validates and completes the signoff workflow for a Pull Request before it goes to review. Squashes commits, runs `bin/ci`, verifies diff coverage with `undercover`, and updates the task status in Notion.
Validates and completes the signoff workflow for a Pull Request before it goes to review. Squashes commits, runs bin/ci, verifies diff coverage with undercover, and updates the task status in Notion.
Input: optional $ARGUMENTS — Notion URL or page ID. If omitted, the skill tries to infer the ticket from the branch name.
Run in parallel:
git branch --show-current
gh pr view --json url,title,state
git status --porcelain
git rev-list --count main..HEAD
Validate:
<prefix>/<slug>-<TICKET> where prefix ∈ feature/, bugfix/, improvement/, hotfix/, chore/.main → abort.gh pr view).gh pr create --base main".Parse the branch name for the ticket ID:
/(KODIM-\d+|SC-\d+|[A-Z]+-\d+)/$ARGUMENTS is a Notion URL/ID → use it.COMMIT_COUNT=$(git rev-list --count main..HEAD)
If COMMIT_COUNT > 1:
Fetch task details from Notion (if ticket ID detected):
mcp__notion__API-retrieve-a-page with the page_id.Determine TYPE from the branch prefix:
feature/* → FEATbugfix/* or hotfix/* → FIXimprovement/* → REFACTORchore/* → CHOREBuild the squash commit message:
[<TYPE>] <Notion title or branch slug> - <TICKET>
Co-Authored-By: Claude <[email protected]>
Execute the squash:
git reset --soft $(git merge-base main HEAD)
git commit -m "$(cat <<'EOF'
[<TYPE>] <title> - <TICKET>
Co-Authored-By: Claude <[email protected]>
EOF
)"
git push --force-with-lease
Use --force-with-lease, never --force — protects against overwriting remote changes someone else pushed.
If COMMIT_COUNT == 1:
[<TYPE>] <desc> - <TICKET> format.git commit --amend with a corrected message (+ git push --force-with-lease).Call mcp__notion__API-retrieve-a-page with the ticket's page_id and inspect the Status property.
Valid states for PR phase:
In Progress → OK, will transition to Code Review after successful CI.Code Review → already there, no transition needed.To Do / Backlog → warn: "Task isn't in progress — consider moving it to In Progress first."bin/ci
This executes: setup + rubocop + brakeman + rspec + auto-signoff (via gh signoff).
Capture exit code.
After bin/ci passes, run the additional coverage check:
doppler run --config test -- COVERAGE=true bundle exec rspec
doppler run --config test -- bundle exec undercover --compare origin/main
If undercover reports uncovered lines in the diff → do NOT transition the task to Code Review. Report to the user:
❌ Undercover found N uncovered lines in the diff:
- path/to/file.rb:42
- path/to/other.rb:17
Fix before requesting review:
1. Add specs covering these lines, OR
2. Wrap in `# :nocov:` with a comment justifying why (rare — prefer specs).
Confirm success to the user:
✅ bin/ci passed
- Tests: ✅
- RuboCop: ✅
- Brakeman: ✅
- Signoff: ✅
- Undercover (diff coverage): ✅ clean
Get the PR URL:
gh pr view --json url -q .url
If task is in In Progress, ask:
Task is in "In Progress". Move it to "Code Review"? (y/n)
If yes, update Notion:
mcp__notion__API-patch-page with the ticket's page_id.Status property to Code Review (the exact option name must match the Notion database schema — verify via mcp__notion__API-retrieve-a-database on first run).Analyze output to identify the failing stage:
RuboCop failed:
❌ RuboCop found style issues.
Auto-fix with `bundle exec rubocop -A`? (y/n)
If yes: run autofix, stage, commit [CHORE] Auto-fix rubocop - <TICKET>, push, re-run bin/ci.
Tests failed:
❌ Tests failed.
Fix manually:
1. Review output above
2. doppler run --config test -- bundle exec rspec <failing_spec>
3. Fix code
4. Commit + push
5. Re-run /api-dev:pr-signoff
Do NOT auto-fix tests — that's the human's job.
Brakeman failed:
❌ Brakeman found security warnings.
Fix manually:
1. Review output above
2. Fix unsafe code
3. Commit + push
4. Re-run /api-dev:pr-signoff
NEVER move the task to Code Review if bin/ci or undercover failed.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📊 PR Signoff Summary
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Task: <TICKET> — <title>
Notion: <previous status> → <new status>
PR: <PR URL>
Preparation:
Squash: <✅ N commits → 1 commit | ⏭️ already 1 commit>
Validations:
bin/ci (rspec + rubocop + brakeman + signoff): ✅ / ❌
Undercover diff coverage: ✅ clean / ❌ N uncovered
Next action:
<e.g., "PR ready for review, pinged reviewers in Slack" | "Fix failing tests and re-run">
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
bin/ci — fail fast.bin/ci — one commit per PR.--force-with-lease, never --force.bin/ci OR undercover failed.main directly.Provides behavioral guidelines to reduce common LLM coding mistakes, focusing on simplicity, surgical changes, assumption surfacing, and verifiable success criteria.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub kodimtech/claude-code-plugins --plugin api-dev