From 0df5b31be7b13f117deb89143b25429924bfe242 Mon Sep 17 00:00:00 2001 From: rohansx Date: Fri, 3 Jul 2026 21:53:06 +0530 Subject: [PATCH 01/11] ci: add Claude Code PR review workflow (OAuth auth) Runs anthropics/claude-code-action@v1 on non-draft PRs, authenticated with a Claude subscription OAuth token (CLAUDE_CODE_OAUTH_TOKEN) rather than an API key. Review prompt is tailored to CloakPipe: PII leak-safety, cryptographic ledger/verifier integrity, Rust correctness, hot-path performance, and the cloakleak/verifier gates. Uses track_progress for a live checklist, concurrency cancellation to review only the latest push, and least-privilege permissions. --- .github/workflows/claude-code-review.yml | 86 ++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 .github/workflows/claude-code-review.yml diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml new file mode 100644 index 0000000..4ab07f8 --- /dev/null +++ b/.github/workflows/claude-code-review.yml @@ -0,0 +1,86 @@ +name: Claude Code Review + +# Automated PR review powered by Claude Code. +# Auth: OAuth token from a Claude subscription (Pro/Max/Team), NOT an API key. +# Generate it locally with `claude setup-token` and store the value as the +# repository secret CLAUDE_CODE_OAUTH_TOKEN +# (Settings -> Secrets and variables -> Actions -> New repository secret). + +on: + pull_request: + types: [opened, synchronize, ready_for_review, reopened] + +# Cancel an in-flight review when new commits are pushed to the same PR, +# so we only pay for a review of the latest state. +concurrency: + group: claude-review-${{ github.event.pull_request.number }} + cancel-in-progress: true + +jobs: + claude-review: + # Skip drafts — review once the PR is marked ready. + if: github.event.pull_request.draft == false + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + id-token: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Claude Code Review + uses: anthropics/claude-code-action@v1 + with: + claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} + + # Post a tracking comment with progress checkboxes as the review runs. + track_progress: true + + prompt: | + REPO: ${{ github.repository }} + PR NUMBER: ${{ github.event.pull_request.number }} + + You are reviewing a pull request for CloakPipe — a Rust-native + privacy proxy that detects, masks, and unmasks PII in LLM traffic, + plus a cryptographic ledger/verifier (chain, signatures, anchors, + proofs). Correctness and privacy guarantees matter more than style. + + Focus your review on: + + 1. **Privacy / leak safety** (highest priority) + - Any code path where PII could pass through unmasked, be logged, + persisted, or emitted in errors, telemetry, or panics. + - Mask/unmask round-trip correctness and placeholder collisions. + - New entity handling that could regress the zero-leak gates. + + 2. **Cryptographic integrity** + - Ledger hashing/chaining, signature verification, anchors, and + Merkle proofs — verify no check is weakened, skipped, or made + to fail open. Constant-time comparisons where relevant. + + 3. **Rust correctness** + - `unwrap`/`expect`/`panic!` on paths reachable from untrusted + input; unhandled `Result`/`Option`; integer/slice panics. + - `unsafe` blocks, incorrect lifetimes, and concurrency hazards + (data races, deadlocks, `.await` while holding a lock). + - Error handling that silently swallows failures. + + 4. **Performance** + - Regressions on the hot masking path (target <5ms); needless + allocations or clones in per-request code. + + 5. **Testing** + - Adequate coverage for new logic; missing edge cases; whether + cloakleak / verifier gates still hold. + + Report concrete issues as inline comments on the exact lines. Use a + top-level comment for the summary and any general observations. Be + specific and cite file:line. Do not flag pure style nits unless they + affect correctness or safety. + + # Read-only repo access plus the ability to post review comments. + claude_args: | + --allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*)" From 36e2bf67f5e485848823cac0abd41fb181f98033 Mon Sep 17 00:00:00 2001 From: rohansx Date: Fri, 3 Jul 2026 22:06:26 +0530 Subject: [PATCH 02/11] ci: add REVIEW.md to focus Claude PR reviews Defines what Important means for CloakPipe (PII leakage, fail-open crypto verification, panics on untrusted input, concurrency hazards), caps nits, skips CI-enforced and intentionally-insecure baseline code, and lists always-check rules for the privacy and verifier invariants. --- REVIEW.md | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 REVIEW.md diff --git a/REVIEW.md b/REVIEW.md new file mode 100644 index 0000000..56c6d46 --- /dev/null +++ b/REVIEW.md @@ -0,0 +1,67 @@ +# Review instructions + +CloakPipe is a Rust-native privacy proxy that detects, masks, and unmasks PII +in LLM traffic, plus a cryptographic ledger and verifier (chain, signatures, +anchors, Merkle proofs). Correctness and privacy guarantees outrank style. + +Open the review summary with a one-line tally (e.g. `3 important, 2 nits`), and +lead with "No blocking issues" when nothing is Important. + +## What Important (🔴) means here + +Reserve 🔴 for findings that would break a privacy guarantee, corrupt the +verifiable ledger, or crash on untrusted input. Specifically: + +- **PII leakage**: any path where raw/unmasked PII can be logged, persisted, + cached, sent to an upstream model, or surfaced in an error, panic message, + span, or metric label. Broken mask/unmask round-trips and placeholder + collisions count here. +- **Weakened crypto verification**: ledger hashing/chaining, signature checks, + anchors, or proof validation that is skipped, made to **fail open**, uses a + non-constant-time comparison for secrets/MACs, or accepts a malformed bundle + that should be rejected. +- **Panic on untrusted input**: `unwrap`/`expect`/`panic!`/`unreachable!`, + slice/index or integer-overflow panics, on a path reachable from request + data or an untrusted bundle. +- **Concurrency hazards**: data races, deadlocks, or holding a lock across an + `.await`. +- **Regressions to the zero-leak gates** (cloakleak) or the verifier e2e checks. + +Style, naming, formatting, and refactor suggestions are 🟡 Nit at most. + +## Cap the nits + +Report at most **five** 🟡 Nits per review. If you found more, add +"plus N similar items" to the summary instead of posting them inline. + +## Do not report + +- Anything CI already enforces: `cargo fmt`, `cargo clippy -- -D warnings`, + and compiler warnings (see `.github/workflows/ci.yml`). +- `Cargo.lock` and any generated or vendored files. +- The intentionally-insecure **baseline** implementations in cloakleak that are + designed to leak 100% (they exist as a reference — do not flag them as leaks). +- Test fixtures and corpora that contain fake/sample PII on purpose. + +## Always check + +- New PII entity detectors / maskers ship with tests, and any change is + reflected in the cloakleak tracks (prose + tool_json) so the zero-leak gate + still passes. +- Log lines, error messages, panics, and telemetry never include raw PII, + secrets, or full request/response bodies. +- Verifier checks (`chain`, `sigs`, `anchors`, `proofs`) fail **closed** — a + missing, malformed, or tampered field must be an error, never a silent pass. +- New dependencies are justified; watch for anything pulling PII or ledger data + off-box. + +## Verification bar + +Behavior claims need a `file:line` citation in the source, not an inference +from a name. If you cannot point to the code that causes the issue, downgrade +to a question in the summary rather than a 🔴 inline comment. + +## Re-review convergence + +After the first review of a PR, suppress new nits and post 🔴 Important +findings only. Don't re-raise items already fixed. From cf8e2f2726122f314b623a55cc5adb84ba1e9401 Mon Sep 17 00:00:00 2001 From: rohansx Date: Fri, 3 Jul 2026 22:18:57 +0530 Subject: [PATCH 03/11] ci: re-trigger Claude review now that OAuth secret is set From ac788ad0c7045a49df8038f6f81dbabd629fbf4b Mon Sep 17 00:00:00 2001 From: rohansx Date: Fri, 3 Jul 2026 22:20:38 +0530 Subject: [PATCH 04/11] ci: use built-in GITHUB_TOKEN for Claude review comments Avoids the 'Claude Code GitHub App not installed' 401 by passing the Actions token instead of falling back to app-token exchange. --- .github/workflows/claude-code-review.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index 4ab07f8..df2b526 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -35,6 +35,12 @@ jobs: uses: anthropics/claude-code-action@v1 with: claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} + # Use the built-in Actions token to post comments, so the Claude + # GitHub App does not need to be installed on the repo. Comments + # appear as github-actions[bot]. (To have them appear as "Claude" + # and re-trigger CI, install https://github.com/apps/claude and + # drop this line.) + github_token: ${{ secrets.GITHUB_TOKEN }} # Post a tracking comment with progress checkboxes as the review runs. track_progress: true From c46ee6520c49ce79c39c1d4d82e6f8ef15614cbc Mon Sep 17 00:00:00 2001 From: rohansx Date: Fri, 3 Jul 2026 22:25:37 +0530 Subject: [PATCH 05/11] ci: temporarily enable --debug to diagnose empty Claude review --- .github/workflows/claude-code-review.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index df2b526..27761c5 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -90,3 +90,4 @@ jobs: # Read-only repo access plus the ability to post review comments. claude_args: | --allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*)" + --debug From bb87d2b74cb839db82d63cd54ad6e4ea1019f7e9 Mon Sep 17 00:00:00 2001 From: rohansx Date: Fri, 3 Jul 2026 22:28:02 +0530 Subject: [PATCH 06/11] ci: remove debug flag from Claude review workflow --- .github/workflows/claude-code-review.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index 27761c5..df2b526 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -90,4 +90,3 @@ jobs: # Read-only repo access plus the ability to post review comments. claude_args: | --allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*)" - --debug From df49ec047970487bb542cc2370f13586441ae08a Mon Sep 17 00:00:00 2001 From: rohansx Date: Fri, 3 Jul 2026 22:34:21 +0530 Subject: [PATCH 07/11] ci: add @claude mention trigger workflow Responds to @claude mentions on issues and PRs via the same OAuth token. Note: comment-triggered workflows only run from the default branch, so this takes effect once merged to main. --- .github/workflows/claude.yml | 49 ++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 .github/workflows/claude.yml diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml new file mode 100644 index 0000000..e1066ab --- /dev/null +++ b/.github/workflows/claude.yml @@ -0,0 +1,49 @@ +name: Claude + +# On-demand assistant: responds when you mention @claude in an issue or PR +# comment (e.g. "@claude review this PR", "@claude why does this test fail?"). +# +# IMPORTANT: issue_comment / pull_request_review_comment / issues triggers only +# run the workflow version on the DEFAULT branch (main). This file must be +# merged to main before @claude mentions do anything — mentions on a PR whose +# base is main use main's copy of this workflow, not the PR branch's. + +on: + issue_comment: + types: [created] + pull_request_review_comment: + types: [created] + pull_request_review: + types: [submitted] + issues: + types: [opened, assigned] + +jobs: + claude: + # Only run when @claude is actually mentioned. + if: | + (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) || + (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) || + (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) || + (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) + runs-on: ubuntu-latest + permissions: + contents: write # allow @claude to apply and push fixes when asked + pull-requests: write + issues: write + id-token: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Claude + uses: anthropics/claude-code-action@v1 + with: + claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} + # Built-in token to post comments (no Claude GitHub App install needed). + github_token: ${{ secrets.GITHUB_TOKEN }} + # No `prompt`: the action replies to whatever you write after @claude. + # Same CloakPipe review focus is available on request, e.g. + # "@claude review this PR for PII leaks and crypto-verification issues". From 5aab34db5ab2e657b2faaf273553265f1650defb Mon Sep 17 00:00:00 2001 From: rohansx Date: Fri, 3 Jul 2026 22:37:06 +0530 Subject: [PATCH 08/11] ci: temp step to dump raw Claude execution output for diagnosis --- .github/workflows/claude-code-review.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index df2b526..be54d10 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -90,3 +90,12 @@ jobs: # Read-only repo access plus the ability to post review comments. claude_args: | --allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*)" + + # TEMPORARY diagnostic: surface the raw API error the action swallows. + - name: Dump Claude execution output + if: always() + run: | + echo "===== claude-execution-output.json =====" + cat "${RUNNER_TEMP}/claude-execution-output.json" 2>/dev/null \ + || cat /home/runner/work/_temp/claude-execution-output.json 2>/dev/null \ + || echo "(execution output file not found)" From 1708b61608e69a8a34cbfd3194f9565a9e177d7e Mon Sep 17 00:00:00 2001 From: rohansx Date: Fri, 3 Jul 2026 22:39:11 +0530 Subject: [PATCH 09/11] ci: remove temporary diagnostic dump step --- .github/workflows/claude-code-review.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index be54d10..df2b526 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -90,12 +90,3 @@ jobs: # Read-only repo access plus the ability to post review comments. claude_args: | --allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*)" - - # TEMPORARY diagnostic: surface the raw API error the action swallows. - - name: Dump Claude execution output - if: always() - run: | - echo "===== claude-execution-output.json =====" - cat "${RUNNER_TEMP}/claude-execution-output.json" 2>/dev/null \ - || cat /home/runner/work/_temp/claude-execution-output.json 2>/dev/null \ - || echo "(execution output file not found)" From b6e8ff0c5f1556b0694efff1bf874c209a70fbc2 Mon Sep 17 00:00:00 2001 From: rohansx Date: Fri, 3 Jul 2026 22:45:29 +0530 Subject: [PATCH 10/11] ci: re-trigger Claude review with corrected sk-ant-oat token From f2d91655460fcbb72a4779491a506f4cf8d4e057 Mon Sep 17 00:00:00 2001 From: rohansx Date: Fri, 3 Jul 2026 22:50:24 +0530 Subject: [PATCH 11/11] =?UTF-8?q?ci:=20address=20Claude=20review=20?= =?UTF-8?q?=E2=80=94=20gate=20@claude=20on=20author=5Fassociation,=20trim?= =?UTF-8?q?=20tools?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - claude.yml: require OWNER/MEMBER/COLLABORATOR to trigger the write-privileged @claude agent (was: anyone could trigger it). - claude-code-review.yml: drop Bash(gh pr comment:*) so track_progress keeps a single tracked comment instead of duplicate freeform ones. --- .github/workflows/claude-code-review.yml | 6 ++++-- .github/workflows/claude.yml | 21 ++++++++++++++++----- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index df2b526..365b614 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -87,6 +87,8 @@ jobs: specific and cite file:line. Do not flag pure style nits unless they affect correctness or safety. - # Read-only repo access plus the ability to post review comments. + # Read-only repo access plus inline review comments. No `gh pr comment`: + # track_progress already owns a single tracked comment for the summary, + # so freeform top-level comments would only create duplicates. claude_args: | - --allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*)" + --allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh pr diff:*),Bash(gh pr view:*)" diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index e1066ab..3084ca0 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -20,12 +20,23 @@ on: jobs: claude: - # Only run when @claude is actually mentioned. + # Only run when @claude is mentioned AND the author is a trusted user + # (repo owner, org member, or collaborator). Without the association check, + # anyone on a public repo could trigger this write-privileged agent with + # arbitrary instructions. if: | - (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) || - (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) || - (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) || - (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) + (github.event_name == 'issue_comment' && + contains(github.event.comment.body, '@claude') && + contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association)) || + (github.event_name == 'pull_request_review_comment' && + contains(github.event.comment.body, '@claude') && + contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association)) || + (github.event_name == 'pull_request_review' && + contains(github.event.review.body, '@claude') && + contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.review.author_association)) || + (github.event_name == 'issues' && + (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')) && + contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.issue.author_association)) runs-on: ubuntu-latest permissions: contents: write # allow @claude to apply and push fixes when asked