Skip to content

fix(autoreview): redact secrets without blocking review - #132

Open
steipete wants to merge 1 commit into
mainfrom
codex/autoreview-review-integrity
Open

fix(autoreview): redact secrets without blocking review#132
steipete wants to merge 1 commit into
mainfrom
codex/autoreview-review-integrity

Conversation

@steipete

Copy link
Copy Markdown
Contributor

Summary

  • make autoreview redact secret-like diff content while preserving executable source for review
  • add dialect-aware literal, interpolation, regex, numeric, comment, call-chain, and fallback parsing
  • preserve stable secret identities across files and hunk headers without leaking original values
  • fail closed on ambiguous source while allowing known credential references and lookup keys

Proof

  • python3 -m unittest skills.autoreview.tests.test_autoreview_hardening -k review_patch (281 passed)
  • python3 -m unittest skills.autoreview.tests.test_autoreview_hardening -k secret_detector (86 passed)
  • PYTHONPATH=/tmp/agent-skills-validate-deps scripts/validate-skills (6 skills validated)
  • git diff --check
  • mandatory two-pass autoreview completed; final reported C# numeric-member finding was disproved by the existing focused regression and direct span output (0, 8)

Local full-suite note

The full 520-test run passed 515 tests and skipped 1. Four JVM-home tests failed only because this Mac has no Java runtime; GitHub CI runs on Java-equipped Ubuntu and Windows images.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal priority bug or improvement with limited blast radius. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. labels Jul 18, 2026
@clawsweeper

clawsweeper Bot commented Jul 18, 2026

Copy link
Copy Markdown

Codex review: needs real behavior proof before merge. Reviewed July 30, 2026, 5:41 PM ET / 21:41 UTC.

ClawSweeper review

What this changes

This PR substantially expands the Autoreview skill’s secret-redaction parser and hardening tests so credential-like diff content is sanitized while executable source remains usable for review.

Merge readiness

Blocked until real behavior proof from a real setup is added - 8 items remain

Keep this PR open: the reported templated-URL regression remains an actionable P1 blocker on the unchanged head, and the PR still lacks after-fix real validator output. The patch also cannot currently merge cleanly, so it needs a focused repair, refreshed merge state, and proof before landing.

Priority: P1
Reviewed head: 8a9facf0726e5dceb258a18b6ec1ef8139dc0598

Review scores

Measure Result What it means
Overall readiness 🧂 unranked krab (1/6) The redaction objective is useful, but an unresolved P1 refusal path plus test-only proof keeps the PR below merge-ready quality.
Proof confidence 🧂 unranked krab (1/6) Needs real behavior proof before merge: The PR body provides unit-test and validator claims but no after-fix live output showing a templated URL is accepted while a real URI password is redacted; add redacted terminal output or logs before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Patch quality 🦪 silver shellfish (2/6) 1 actionable review finding remain.

Verification

Check Result Evidence
Real behavior Needs proof Needs real behavior proof before merge: The PR body provides unit-test and validator claims but no after-fix live output showing a templated URL is accepted while a real URI password is redacted; add redacted terminal output or logs before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed 4 items Repository policy: The checked-in AGENTS.md policy identifies skills/autoreview as a canonical shared skill and requires skill validation after edits; this review treats the large parser and test change as a public shared-skill compatibility surface.
Unresolved current-head regression: The supplied PR discussion gives a concrete head-versus-base probe: templated SSH/HTTPS URL userinfo causes validate_review_patch to refuse the full review because an interpolation slot such as {ssh_user} is added to known-secret fragments. The prior review cycles record the same P1 finding against the unchanged head 8a9facf.
Patch scope and merge state: The PR changes two files with 13,818 additions and 1,927 deletions, and GitHub reports mergeableState as dirty. This is materially broader than a narrow redaction repair and needs a refreshed merge result after the functional blocker is fixed.
Findings 1 actionable finding [P1] Exclude URL interpolation slots from known-secret fragments
Security None None.

How this fits together

Autoreview receives a proposed diff, detects credential-like source fragments, rewrites sensitive values to stable placeholders, then sends the sanitized patch to the review workflow. This change sits at the redaction boundary, where false positives can block a review and false negatives can expose sensitive material.

flowchart LR
  A[Proposed code diff] --> B[Autoreview secret detector]
  B --> C[Language-aware parsing]
  C --> D[Secret redaction and identity mapping]
  D --> E[Patch safety validation]
  E --> F[Sanitized review input]
  F --> G[Automated code review]
Loading

Before merge

  • Add real behavior proof - Needs real behavior proof before merge: The PR body provides unit-test and validator claims but no after-fix live output showing a templated URL is accepted while a real URI password is redacted; add redacted terminal output or logs before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
  • Exclude URL interpolation slots from known-secret fragments (P1) - {ssh_user} and equivalent template slots are not secret values, but this path records them as known fragments and the subsequent whole-patch containment scan exits before review. Preserve password redaction while excluding interpolation syntax from fragment registration; this remains on the unchanged reviewed head.
  • Resolve merge risk (P1) - Existing diffs that construct SSH or HTTPS remotes with interpolation can fail closed and stop the entire review, even though the interpolation slot is not a secret.
  • Resolve merge risk (P1) - This 15,745-line net diff changes a redaction security boundary; without focused live output and a clean merge result, reviewers cannot establish that it preserves both non-leakage and review availability.
  • Complete next step (P2) - A narrow mechanical repair is clear: stop treating URL-template interpolation syntax as a known secret fragment, preserve password masking, and add the supplied focused regressions; contributor-owned live proof remains required before merge.
  • Improve patch quality - Repair the interpolation-slot fragment registration and add focused Python and TypeScript regression coverage.
  • Improve patch quality - Rebase or otherwise resolve the dirty merge state against current main.
  • Improve patch quality - Post redacted live validator output showing an accepted templated URL and a masked password-bearing URI; updating the PR body should trigger re-review, or a maintainer can comment @clawsweeper re-review.

Findings

  • [P1] Exclude URL interpolation slots from known-secret fragments — skills/autoreview/scripts/autoreview:13420
Agent review details

Security

None.

Review metrics

Metric Value Why it matters
Patch size 13,818 added, 1,927 removed across 2 files The redaction implementation and its tests are a large concentrated rewrite of a security-sensitive review boundary.
Observed blocker 1 unresolved P1 regression across 6 completed review cycles The same current-head interpolation refusal has been repeatedly documented and still needs a code repair.

Root-cause cluster

Relationship: canonical
Canonical: #132
Summary: This PR is the current candidate implementation for the URL-userinfo redaction behavior reported by the related issue; the related issue is closed but its concrete reproduction identifies an unresolved defect in this branch.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge-risk options

Maintainer options:

  1. Repair the interpolation-fragment path (recommended)
    Exclude templated URL-userinfo slots from known-secret fragments, preserve actual password masking, add the focused regression cases, and refresh the branch against current main.
  2. Pause this broad parser rewrite
    Close or replace the branch with a narrow, independently validated redaction fix if the wider parser expansion cannot be safely reviewed and rebased.

Technical review

Best possible solution:

Narrow the known-secret-fragment collection so URL userinfo interpolation slots and bare usernames remain reviewable, retain password redaction, add focused regressions, then provide redacted live validator output for both acceptance and masking cases on a freshly rebased branch.

Do we have a high-confidence way to reproduce the issue?

Yes, from the supplied current-head probe: pass a one-line added hunk containing ssh://{ssh_user}@... through validate_review_patch and observe the known-secret-fragment guard refuse the full patch. The report also supplies a password-bearing DSN control case that should remain redacted.

Is this the best way to solve the issue?

No. The intended redaction goal is appropriate, but registering interpolation syntax as a secret fragment turns valid URL templates into a whole-patch refusal; a narrow exclusion with regression coverage is safer than accepting this behavior.

Full review comments:

  • [P1] Exclude URL interpolation slots from known-secret fragments — skills/autoreview/scripts/autoreview:13420
    {ssh_user} and equivalent template slots are not secret values, but this path records them as known fragments and the subsequent whole-patch containment scan exits before review. Preserve password redaction while excluding interpolation syntax from fragment registration; this remains on the unchanged reviewed head.
    Confidence: 0.98

Overall correctness: patch is incorrect
Overall confidence: 0.96

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against fe588b1a6267.

Labels

Label justifications:

  • P1: Templated SSH/HTTPS remote URLs can make the full automated review fail closed for ordinary source code.
  • merge-risk: 🚨 compatibility: The PR changes existing review acceptance behavior and currently rejects valid templated URL constructions that previously remained reviewable.
  • merge-risk: 🚨 security-boundary: The diff materially rewrites the secret-detection and redaction boundary that decides what source is safe to expose to automated review.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🦪 silver shellfish.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR body provides unit-test and validator claims but no after-fix live output showing a templated URL is accepted while a real URI password is redacted; add redacted terminal output or logs before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Evidence

Acceptance criteria:

  • [P1] python3 -m unittest skills.autoreview.tests.test_autoreview_hardening -k review_patch.
  • [P1] python3 -m unittest skills.autoreview.tests.test_autoreview_hardening -k secret_detector.
  • [P1] scripts/validate-skills.
  • [P1] Run validate_review_patch on a templated SSH/HTTPS URL and a password-bearing URI, saving redacted live output for PR proof.

What I checked:

  • Repository policy: The checked-in AGENTS.md policy identifies skills/autoreview as a canonical shared skill and requires skill validation after edits; this review treats the large parser and test change as a public shared-skill compatibility surface. (AGENTS.md:1, fe588b1a6267)
  • Unresolved current-head regression: The supplied PR discussion gives a concrete head-versus-base probe: templated SSH/HTTPS URL userinfo causes validate_review_patch to refuse the full review because an interpolation slot such as {ssh_user} is added to known-secret fragments. The prior review cycles record the same P1 finding against the unchanged head 8a9facf. (skills/autoreview/scripts/autoreview:13420, 8a9facf0726e)
  • Patch scope and merge state: The PR changes two files with 13,818 additions and 1,927 deletions, and GitHub reports mergeableState as dirty. This is materially broader than a narrow redaction repair and needs a refreshed merge result after the functional blocker is fixed. (skills/autoreview/scripts/autoreview:1, 8a9facf0726e)
  • Proof remains test-only: The PR body reports unit tests, validation, and diff checks, but it does not show after-fix live validator output for both required cases: accepting a templated URL userinfo and redacting an actual URI password. The prior ClawSweeper review requested this exact proof. (skills/autoreview/tests/test_autoreview_hardening.py:1, 8a9facf0726e)

Likely related people:

  • Yigtwxx: Provided the concrete branch-history comparison and a focused reproduction for the URL-interpolation refusal path, making them the best available routing contact in the supplied evidence. (role: reproduction reviewer; confidence: medium; files: skills/autoreview/scripts/autoreview)

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

Workflow

  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

History

Review history (6 earlier review cycles)
  • reviewed 2026-07-18T10:27:05.906Z sha 8a9facf :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-29T17:11:15.636Z sha 8a9facf :: needs real behavior proof before merge. :: [P1] Do not register interpolation slots as known secret fragments
  • reviewed 2026-07-30T11:10:43.932Z sha 8a9facf :: needs real behavior proof before merge. :: [P1] Exclude URL interpolation slots from known-secret fragments
  • reviewed 2026-07-30T15:22:06.232Z sha 8a9facf :: needs real behavior proof before merge. :: [P1] Exclude URL interpolation slots from known-secret fragments
  • reviewed 2026-07-30T17:59:01.015Z sha 8a9facf :: needs real behavior proof before merge. :: [P1] Exclude URL interpolation slots from known-secret fragments
  • reviewed 2026-07-30T20:12:58.711Z sha 8a9facf :: needs real behavior proof before merge. :: [P1] Exclude URL interpolation slots from known-secret fragments

@Yigtwxx

Yigtwxx commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

@steipete Measured this branch against the case class from #133 (URL userinfo). Two results worth separating: the four over-masking cases are unchanged, and one of them regresses from masking into a hard refusal, which runs against this PR's stated goal of redacting without blocking review.

To keep main's drift out of it, both columns are this branch's own history — merge-base 2efd5a1 vs head 8a9facf. Each line was passed through validate_review_patch as a one-line added hunk.

input line 2efd5a1 (merge-base) 8a9facf (head)
url = f"ssh://{ssh_user}@git.example.invalid/org/repo.git" masked → redacted@ refused — review blocked
url = f"https://{user}@example.com/repo" masked → redacted@ refused — review blocked
const url = `ssh://${sshUser}@git.example.invalid/org/repo.git`; masked → redacted@ refused — review blocked
u = "https://alice@github.com/example/repo" masked masked (unchanged)
u = "https://username:@host/repo" masked masked (unchanged)
remote = "ssh://git@github.com/org/repo.git" refused refused (unchanged)
dsn = "postgres://user:hunter2pass@db.example/app" user:redacted@ user:redacted@

Password redaction is intact on both sides — the last row is the control, and it is the one case in the set that should be redacted.

Mechanism

The refusal is not a new pattern match. require_no_known_secret_fragments is called from the same site on both sides (:13420 head / :6987 base); what changed is what lands in known_secret_fragments. Instrumenting the fragment set on the first row:

head  8a9facf   fragments flagged: ['{ssh_user}']  -> SystemExit
base  2efd5a1   fragments flagged: []              -> passes (masked)

So the interpolation slot text itself{ssh_user}, a variable name — is registered as a known secret value, and the whole-patch containment check then trips on it.

Blast radius

Because that check is a substring scan over the entire patch, one scheme-bearing f-string poisons every other occurrence of the same slot in the diff:

url = f"ssh://{ssh_user}@git.example.invalid/org/repo.git"
log.info(f"connecting as {ssh_user}")
base  2efd5a1   both lines emitted (over-masked to `redacted`, but reviewable)
head  8a9facf   refused — the whole review stops

The second line has no userinfo position at all; it is collateral from the first.

Scope of the claim

The boundary is specifically scheme-URL userinfo. A bare f"{account}@mail.example.invalid" is left untouched on both sides, so this is not "any interpolation before @". I have not evaluated the rest of this PR — the dialect-aware literal/regex/comment parsing is a large surface and I only exercised the URL-userinfo path.

Reproduction, if useful:

probe script
import importlib.util, importlib.machinery, sys, pathlib

mod_path = pathlib.Path(sys.argv[1])  # skills/autoreview/scripts/autoreview
spec = importlib.util.spec_from_loader(
    "ar", importlib.machinery.SourceFileLoader("ar", str(mod_path))
)
ar = importlib.util.module_from_spec(spec)
sys.modules["ar"] = ar
spec.loader.exec_module(ar)

CASES = [
    ("fixture.py", 'url = f"ssh://{ssh_user}@git.example.invalid/org/repo.git"'),
    ("fixture.py", 'url = f"https://{user}@example.com/repo"'),
    ("fixture.py", 'target = f"{account}@mail.example.invalid"'),
    ("fixture.ts", "const url = `ssh://${sshUser}@git.example.invalid/org/repo.git`;"),
    ("fixture.py", 'u = "https://alice@github.com/example/repo"'),
    ("fixture.py", 'dsn = "postgres://user:hunter2pass@db.example/app"'),
]

for name, line in CASES:
    patch = (
        f"diff --git a/{name} b/{name}\n--- a/{name}\n+++ b/{name}\n"
        f"@@ -0,0 +1 @@\n+{line}\n"
    )
    try:
        out = ar.validate_review_patch("diff", [name], patch)
        got = next(
            l[1:] for l in out.splitlines()
            if l.startswith("+") and not l.startswith("+++")
        )
        status = "same" if got == line else "masked"
    except SystemExit as error:
        got, status = str(error).splitlines()[0], "REFUSED"
    print(f"[{status}] {line}\n      -> {got}")

Run against each checkout:

git checkout 2efd5a1 && python probe.py skills/autoreview/scripts/autoreview
git checkout 8a9facf && python probe.py skills/autoreview/scripts/autoreview

Not opening a competing fix — this branch owns the subsystem. Flagging it here because the refusal path is the one failure mode that costs more than a false positive: a contributor whose diff contains a templated remote URL cannot run autoreview at all, and the error text points at "move or remove the ambiguous occurrence" for source that has no secret in it.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. P1 Urgent regression or broken agent/channel workflow affecting real users now. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. P2 Normal priority bug or improvement with limited blast radius. labels Jul 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. P1 Urgent regression or broken agent/channel workflow affecting real users now. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants