Skip to content

Latest commit

 

History

History
71 lines (54 loc) · 4.22 KB

File metadata and controls

71 lines (54 loc) · 4.22 KB

github-workflows

Central repository for organization-wide GitHub Actions workflows enforced across all hotdata-dev repos via org rulesets.

Workflows

Claude PR Review

Automated code review on every pull request using claude-code-action. Reviews are severity-based:

  • P0/P1 issues — requests changes with inline comments
  • P2/P3 issues — approves with non-blocking suggestions
  • No issues — silent approve

The review prompt lives in docs/claude-pr-review-prompt.md.

Frontloaded review context

The workflow gathers the PR into the prompt before the reviewer starts: title and description, commits, changed files with per-file line counts, CI check status with log excerpts from failing jobs, the diff since the reviewer's own last review, the full diff, and the PR conversation.

This is not a convenience. The reviewer's allowlist is four gh pr commands plus rg, Read, Grep, and Glob, and the checkout is fetch-depth: 1 — so the reviewer cannot reach git history, cannot run tests, and cannot pipe or redirect even the commands it is allowed. Before this, it spent 19.5 Bash calls and 5.2 permission denials per run trying anyway; 86% of runs hit at least one denial, and one review approved a PR with the words "reviewed statically (test suite not run in this environment)" while CI had already run those tests. Runs with no denials averaged 14 turns and 98 seconds against 37 turns and 270 seconds for runs with five or more.

Each block degrades to a sentence saying what is missing rather than to silence, because a reviewer handed an empty CI block will state that CI is clean. Two reads get a stronger treatment: a failed /reviews or /pulls/{n}/comments would otherwise render as REVIEW CYCLE: 1 and "no prior review comments", which are claims rather than gaps, so those failures are disclosed to the reviewer in a ## Context warnings block at the top of the context. The step is continue-on-error: a failure there once skipped the review step and the notify step with it, leaving the PR with no review and no explanation.

Both step outputs are byte-bounded (100 KB of comment threads, 200 KB of context), with per-block caps beneath that — 3,000 diff lines, 40 KB per CI log excerpt, 3,000 characters per comment. The caps are deliberately far below any plausible runner limit: 400 inline comments rendered 1.1 MB of threads before they existed, and the runner accounts for output size in UTF-16, so a byte count here is not the number it checks against. Blocks are ordered so that truncation sacrifices the PR conversation before the diff or the CI status.

Everything reaching the prompt is attacker-controlled — title, body, diff, CI logs, comments — so the block delimiters are neutralised by shape rather than by exact string: </pr_context >, </PR_CONTEXT> and < / pr_context foo="1"> all read as the same delimiter to a model, and any of them would otherwise end the data block early and land the rest where it reads as instructions.

Tool usage artifact

Each run attaches a claude-tool-usage-pr-<number> artifact (14-day retention): tool call counts, Bash command labels with a compound flag, the denied subset of both, and the run's turn count and cost. It exists to diagnose permission denials against the workflow's --allowedTools list, since the job log records only the number of denials, never what was refused. Tool names alone proved insufficient — 520 of 567 denials in the first week were Bash, which is every command there is.

The artifact is a projection of the action's execution log, never the log itself — that file is the full conversation, and the runner holds a git credential the reviewer can read, which artifacts (unlike job logs) would not mask. Command labels come from the fixed vocabulary in CMD_JQ, never from the transcript, so no path, search pattern, or credential can ride along in a "command prefix". tests/tool-usage-test.sh asserts that containment directly. Both the projection and the upload are non-fatal.

Setup

Requires:

  • ANTHROPIC_API_KEY org secret
  • Claude Code GitHub App installed on the org
  • Org ruleset pointing to this repo's workflow