skills/code-review-gate/SKILL.md
--- name: code-review-gate description: Wire the Council-of-LLMs code review into a repo's pre-push hook, gated per-project by a config file with a first-run prompt. When enabled, every push triggers /ro:council-review on the pushed commits and blocks the push if the council finds critical issues; the report can then be looped back to a dev agent. Opt-in per repo: a committed .ro-code-review.json (shareable with the team) or a gitignored .ro-code-review.local.json (personal) records whether the
npx skillsauth add RonanCodes/ronan-skills skills/code-review-gateInstall 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.
Make the [[council-of-llms|Council of LLMs]] run automatically before a push, and decide per-repo whether it runs at all. This is the "code review is the new bottleneck" idea from Farhan Thawar's talk turned into a real gate: the local pre-push hook is already the CI gate in these repos (see /ro:ship), so the review belongs right there.
Two design rules, both from the user:
ro ci)Resolution order, later wins:
{ prePushReview: "ask", blockOn: "critical", level: "strict", lenses: ["all"] }~/.claude/code-review-policy.json (global personal default).ro-code-review.json (committed: the team-shared decision).ro-code-review.local.json (gitignored: personal override for this checkout)// .ro-code-review.json
{
"prePushReview": "on", // "on" = run + block; "ask" = first-run prompt then notice-only; "off" = no-op
"blockOn": "critical", // "critical" | "critical+major" | "none" (none = report only, never block)
"level": "standard", // "critical" | "standard" | "strict" (default strict: full council incl. nitpicks)
"lenses": ["all"], // or ["security","architecture",...]; an explicit list overrides the level's set
"ignore": ["comment-style"], // finding classes never reported in this repo (suppression stays visible in the report)
"scopes": { // per-class surface limits instead of full on/off
"em-dash": "user-facing" // enforced on release notes / site copy / docs; ignored in comments, commits, PR bodies
},
"checklist": [ // repo-specific checks every council run verifies
"Every new MCP tool ships with an HTTP shim, a docs-registry section, and a Bruno entry in the same PR"
],
"models": { // optional: different model per lens (the ensemble-table idea)
"security-reviewer": "opus",
"simplicity-reviewer": "haiku"
}
}
level, ignore, scopes, and checklist are read by the council, not the hook; their semantics (which lenses each level runs, the class tiers, the user-facing scope, the suppression footer) live in /ro:council-review under "Levels (how hard the council bites)". The gate just resolves and passes them through: the hook's claude -p call inherits the repo's resolved level, so a level: "critical" repo gets a showstopper-only pre-push review automatically.
prePushReview values:
on — run the council on the pushed range; block the push when the verdict crosses blockOn.ask — the unconfigured state. The hook does NOT block; it prints a one-time notice telling the user to run /ro:code-review-gate to choose on/off. This is the "first-run check".off — the hook is a no-op (exits 0 immediately).install (default).husky/pre-push (the convention in these repos); fall back to .git/hooks/pre-push..ro-code-review*.json exists:
"Run the code-review council automatically before every push in this repo?"
- On, block on critical (recommended) — full gate.
- On, report only — runs the council, writes a report, never blocks (
blockOn: none).- Ask me later — write
prePushReview: "ask"(notice-only until decided).- Off — don't run on push. Also ask: commit the decision (
.ro-code-review.json, shared) or keep it personal (.ro-code-review.local.json, gitignored)?
.ro-code-review.local.json is in .gitignore.# --- ro code-review gate (managed by /ro:code-review-gate) ---
bash "$(git rev-parse --show-toplevel)/.ro/pre-push-review.sh" "$@" </dev/null || exit 1
scripts/pre-push-review.sh into the repo at .ro/pre-push-review.sh (gitignore .ro/ if not already) and chmod +x. Pinning a copy in-repo keeps the hook working without the plugin on PATH for the script itself; it still needs the claude CLI to run the council./ro:code-review-gate disable).statusShow the resolved config (which file won), whether the hook is installed, and the last report under .code-review/.
enable / disableFlip prePushReview to on / off in the nearest config file (create .ro-code-review.local.json if none). --block-on and --scope set the other keys.
runRun the gate logic now against the working tree (a dry run of what the hook would do), without pushing. Useful to test the setup.
scripts/pre-push-review.sh (installed at .ro/pre-push-review.sh):
prePushReview is off → exit 0. If ask → print the one-time notice and exit 0 (never block an undecided repo).<local ref> <local sha> <remote ref> <remote sha>) and compute the range: remote_sha..local_sha, or main...local_sha for a brand-new branch (all-zero remote sha).claude CLI is not on PATH, print a notice and exit 0 (never hard-fail a push over missing tooling; the gate is best-effort, the human still owns the push).claude -p "/ro:council-review --pre-push --block-on <blockOn> <range>"
The council writes .code-review/council-<ts>.md and signals the verdict via exit code (0 = clean / below threshold, 1 = blocked).Council requested changes (N critical). Report: .code-review/council-<ts>.md Fix and re-push, or run
/ro:council-review --fixto dispatch a dev agent, then push again.
The report → dev-agent loop is deliberately NOT run from inside the git hook (a hook is a blocking, non-interactive git operation, and the agent that wrote the code is usually not alive at push time). Instead:
/ro:council-review --fix routes the report to the author agent if it is still live in the session, otherwise spawns a fresh dev agent, fixes, and re-reviews./ro:ralph, /ro:planner-worker, /ro:night-shift), the loop already owns the worker, so it feeds the council report straight back to that worker and re-runs the council before opening the PR.This keeps the honest boundary: the hook gates; the fix loop routes.
blockOn: critical by default. A pre-push council can take minutes; blocking on every minor finding makes pushes painful and trains people to --no-verify (which the way-of-working lens flags anyway)./ro:ship: local CI gate first (build/lint/types/test), then the council, then push./ro:council-review directly.testing
--- name: linear-pipeline description: The Fable orchestrator for a single dispatched Linear ticket. Holds almost no context itself; it receives `--issue <ID> --detached`, decides the stage sequence, and fans out a sub-agent per stage, passing forward only each stage's artifact (never re-derived, never inlined into its own context). Step zero, before any planning or stage routing, is a boundary triage against `canon/security-boundary.md` (#199): a match tags Ronan Connolly and stops the run, no
development
--- name: in-your-face description: Capture a chat-only answer into a durable artifact (markdown + HTML, PDF when cheap) and launch it automatically so the user cannot miss it. Use when user says "in your face", "don't let me lose this", "save that answer", "make that durable", or right after answering a substantive side question (a recipe, comparison, how-to, or generated prompt) that would otherwise die with the context. category: workflow argument-hint: [--no-open] [--vault <short>] [hint of
tools
One-shot headless OpenAI Codex CLI calls for background/admin AI tasks — summaries, classification, extraction, admin glue. The default engine for anything that runs AI constantly in the background (daemon-driven, per-event), because it bills the flat ChatGPT subscription instead of Claude usage or per-token API spend, and it keeps working while Claude is rate-limited. NEVER for coding — coding stays Claude. Use when a skill or daemon needs a cheap always-on AI call, when the user says "use codex", "ask codex", "codex as backup", or when building a background summarizer/classifier into a listener or loop. Reads auth from ~/.codex/auth.json (ChatGPT account, no API key).
research
Turn a warranty rejection, repair quote, or RMA email into a cited decision brief — legal read (NL/EU consumer law), is the part user-serviceable, live part and new-unit prices, repair-vs-DIY-vs-new economics, before-you-send-it checklist, deadlines. Use when the user pastes or screenshots a repair quote, warranty rejection, "not covered" email, onderzoekskosten fee, or asks "should I repair or replace this".