Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
npx skills add w2ur/claude-code-setup --skill ci-and-branch-protectiongit clone --depth 1 https://github.com/w2ur/claude-code-setupWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/skills/w2ur/claude-code-setup/ci-and-branch-protection)<a href="https://agentmods.dev/skills/w2ur/claude-code-setup/ci-and-branch-protection"><img src="https://agentmods.dev/badge/skills/w2ur/claude-code-setup/ci-and-branch-protection.svg" alt="Measured on agentmods" height="20"></a>What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5.1 | $0.00075 | $0.01184 |
| Opus 5 | $0.00037 | $0.00592 |
| Sonnet 5 | $0.00015 | $0.00237 |
| Haiku 4.5 | $0.00007 | $0.00118 |
Grade A, and why
ci-and-branch-protection scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 2d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 98 lines — stays where its author put it; the contents beside it link to each section on GitHub.
CI gates and branch protection — the reasons
The rules live in ~/.claude/CLAUDE.md. This skill holds the measurements.
A check that did not run must never look like a check that passed
GitHub Actions does not give you this for free:
- a job excluded by
if:reportsskipped - a job dropped from a
needs:list reports nothing at all jq 'all(.[]; .result=="success")'over an empty set returnstrue
So the obvious aggregating job reports success on zero coverage. Measured, not assumed.
Therefore: an aggregate gate must assert a named list of expected checks computed up front, and must refuse an empty list. Never "did anything fail?".
That aggregate gate is the only check a branch protection rule should require. Requiring the individual jobs reintroduces the hole, because a protection rule can only require a name it already knows.
This is the same family as the falsifiable-control rule in the global CLAUDE.md, one layer out.
Where the implementation lives
{github-username}/.github's reusablepr-gate.yml— stack detected from the tree, same signals asdev-scanner.sh.my-trading-appkeeps its owntests.ymland carries the same gate inline.
Callers are chosen on measured PR traffic, not coverage for its own sake
A gate on a repo that never sees a PR is decoration. Derive the traffic before
adding a caller — gh search prs --owner <user> enumerates every repo in one call.
A hand-picked loop silently omits repos.
Branch protection needs a public repo on this account
gh api .../branches/main/protection and .../rulesets both return
403 Upgrade to GitHub Pro or make this repository public on a private repo.
Consequence: every gate on a private repo here is advisory — a red X, not a blocked merge. Never write docs claiming enforcement. Do not "fix" it by upgrading to Pro; the zero-cost policy stands.
The control you must run when checking whether a repo is protected
[] from a rulesets query is equally the answer from a protectable-but-unprotected
repo. Run a known-unprotected control alongside, or the empty result tells you
nothing.
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 2d ago Changed · +11 lines d0248d866e20
- 7d ago First seen · 87 lines · 75 tokens per session scan A 5aeda9aab15c
ci-and-branch-protection is a skill published in the GitHub repository w2ur/claude-code-setup (2 stars, last pushed 3d ago), licensed MIT. It adds 75 tokens to every session and 1,184 once invoked, about $0.0004 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.
Other skills, from other repositories
land-and-deploy
Merge PR, wait for CI, verify deploy, run canary. The complete landing pipeline.
ci-pipeline
Push current branch and return the pipeline tracking URL (GitLab or GitHub Actions).
ci-status
Show current pipeline status for the active branch (GitLab CI or GitHub Actions).
deployment-patterns
Deployment workflows, CI/CD pipeline patterns, Docker containerization, health checks, rollback strategies, and production readiness checklists for web applications. Use when setting up deployment infrastructure or planning releases.
ship
Verify and publish by pushing, opening a PR, and watching CI; land mode merges then cleans branches. Triggers "ship it", "create PR", "/ship", "watch the PR", "babysit CI"; land mode "land it", "/ship land", "fix CI and merge".
pr-triage
4-phase PR backlog management with audit, deep code review, validated comments, and optional worktree setup. Use when triaging pull requests, catching up on pending code reviews, or managing a backlog of open PRs. Args: 'all' to review all, PR numbers to focus (e.g. '42 57'), 'en'/'fr' for language, no arg = audit…