General-purpose coding policy for Baruch's AI agents
74
93%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Low
Low-risk findings worth noting
Reference for Step 4 of the release skill — how the two PR reviewers are wired. Pulled out of SKILL.md so the main flow stays focused on what the operator does.
The policy reviewer reviews the PR diff against the in-tree rules/*.md and posts the verdict as a PR review. It runs one of two ways depending on the repo. Normally exactly one deployment reviews a given PR; a repo mid fleet-migration can transiently carry both, which is why the release scripts resolve the verdict fail-safe across both logins (skills/release/poll-pr-reviews.sh login table).
Both derive the review event from per-finding severity (rules/review-severity.md; .github/codex-review/post-review.sh header) — any blocking finding posts REQUEST_CHANGES; nonblocking results approve with any advisory notes included, falling back to COMMENT only when GitHub forbids approval.
review-codex.ymlThe .github/workflows/review-codex.yml GitHub Actions workflow runs the OpenAI Codex CLI authenticated by a ChatGPT subscription (the CODEX_AUTH_JSON secret — no API key), via codex exec with .github/codex-review/prompt.md and schema.json.
pull_request opened / synchronize / reopened — reviews on open and re-reviews each pushed commit. Fork PRs are skipped (no secret access) — adopt via Skill(skill: "adopt-fork-pr").GITHUB_TOKEN, so the author is github-actions[bot].github-actions[bot] cannot APPROVE (GitHub returns HTTP 422), so a clean pass falls back to COMMENT. A clean or advisory-only re-review after an earlier CHANGES_REQUESTED lands as a COMMENT that does NOT supersede the stale request in GitHub's merge gate, so Step 7 dismisses it via skills/release/dismiss-stale-reviews.sh.CODEX_AUTH_JSON at runtime, never persisted to the runner (rules/no-secrets.md); Codex refreshes the access token in-memory. No per-token API billing. If the refresh token expires the review fails loudly and the operator re-seeds the secret. One-time setup — codex login plus gh secret set CODEX_AUTH_JSON < ~/.codex/auth.json — is in the review-codex.yml header.coding-policy-fleet-reviewer[bot] AppConsumer repos carry no per-repo Codex review workflow (review-codex.yml) and no CODEX_AUTH_JSON — only a thin .github/workflows/review-trigger.yml, one lightweight FLEET_DISPATCH_TOKEN PAT, and a .github/fleet-review-enabled marker that enrolls the repo in the scheduled backstop poll (scaffolded by skills/onboard-repo/scaffold.sh). The central fleet App (coding-policy#202) does the reviewing: the fleet-review run tessl installs jbaruch/coding-policy to a temp path and symlinks its .tessl/ into the PR workspace, so the review runs against coding-policy's rules/*.md (see the policy install/symlink block in .github/codex-review/fleet-review-one.sh main), not a copy the consumer pre-installed.
.github/workflows/review-trigger.yml fires on the same pull_request events and dispatches fleet-review.yml (single-PR workflow_dispatch) in coding-policy via the FLEET_DISPATCH_TOKEN PAT; a scheduled marker-gated cron poll in coding-policy is the backstop for any dispatch that never fired (cadence in the fleet-review.yml header).coding-policy-fleet-reviewer[bot].APPROVE, so a clean re-review supersedes its own earlier CHANGES_REQUESTED natively — no dismissal step is needed on consumer repos. Which reviews are dismissal-eligible is the script's decision (see the skills/release/dismiss-stale-reviews.sh header).Codex checks policy compliance. Claude uses the replacement system prompt in .github/claude-review/system-prompt.md for correctness, bugs, security, reliability, performance and concrete test gaps. Its isolated session loads no policy, agent instructions, memory, plugins, skills, hooks or MCP servers and has only read-only source tools. Authentication uses CLAUDE_CODE_OAUTH_TOKEN from claude setup-token; the token is held only in coding-policy. Its dedicated GitHub App uses CLAUDE_REVIEW_APP_ID and CLAUDE_REVIEW_APP_PRIVATE_KEY, also held only in coding-policy (see .env.example).
Both reviews run on PR events. The central fleet workflow runs them as separate
jobs using distinct reviewer Apps; existing consumer dispatches start both. The quality result posts as a
severity-derived verdict with the exact analyzed commit and the marker owned by
skills/release/review-lanes.sh — CLAUDE_REVIEW_LOGIN and review_lanes_jq. Snapshot and dedup use that classifier and the separate logins. Claude posts as jbaruch-claude-reviewer[bot], independently of the Codex policy identity.
Claude approves nonblocking results, including advisory notes. An App's approval supersedes its earlier change request; a plain comment would leave that request active. The dedicated App can approve on coding-policy and consumer repositories. The policy reviewer retains its existing self-review fallback and cleanup.
Both reviewers emit findings in their review bodies. Reply in a PR comment citing the review and finding; use an inline thread only for an actual inline comment. Claude blocking findings are fixed before merge.
Read both bodies before merge. On failed authentication, renew the subscription token in coding-policy and rerun the failed job. Do not use API-key fallback or request Copilot. The workflow pins the Claude CLI; recheck the model pin when Renovate updates the CLI and at the weekly capability refresh.
Reference for Step 6 — how a marginal blocking finding reaches a weighing and how the ruling clears the gating policy review (rules/review-severity.md Judge-Weighed Finding Carve-Out; rules/ci-safety.md Judge-Ruled-Review Dismissal Carve-Out).
When a verified team policy applies, follow its nomination, report and correction contract. The optional integration and fail-closed verification protocol are in skills/release/references/team-ruling-interface.md. A standalone release requires only the operator ruling below.
Standalone, the operator is the judge and the agent nominates.
Nominate only a finding on lines the previous fix push added, or one you can support with a cited reachability claim — a path from input to the flagged line, with file and line citations. The claim travels in the question itself; no separate report is needed. Ask one question per gate, carrying every nomination:
Weighing request at <head sha>. For each finding answer fix, defer or decline:
1. <source> <path>:<line> <rule> — <finding text> — nominated because <added by the last fix push | reachability claim with citations>
Floors are always fix. I keep fixing meanwhile; no answer means fix.Standalone, the question never blocks. Keep working the fix loop; a finding the operator has not answered stays blocking.
Write the operator's answer into a ruling file with AUTHORITY: operator. Its format, schema_version, required ANSWER: line and writer/reader contract are in the skills/release/dismiss-ruled-review.sh header. A selected team policy may instead supply its independently enrolled ruling through the optional interface. Keep the file for the life of the PR; the dismissal message pins its sha256 digest.
dismiss-ruled-review.sh with --ruling and --followup-issue (Step 6 command block). It posts the ruled findings to the follow-up issue — defer, or decline labelled won't-fix — then dismisses the review. Exit 1 names each unmet condition in .unmet; fix those findings instead.<digest> the 16-hex digest from the script's .message. Policy findings appear in the review body; reply in a PR comment citing the review and finding:
Declining — judge ruling <digest>: <reason from the ruling>Acknowledged — deferred to #<follow-up issue> (judge ruling <digest>)dismiss-stale-reviews.sh (Step 7), then re-run the Step 5 watcher. poll-pr-reviews.sh reads the dismissed review as RULED, which the watcher's ready test accepts.A later push re-runs the policy reviewer. Run the script again with the same ruling: it dismisses the new review when the ruling still covers it, and exits 1 naming each finding it no longer covers otherwise. Those go back to a new question or the fix loop.
.tessl-plugin
rules
skills
migrate-to-plugin
onboard-repo
release
hooks
references