Skip to content

polish: resolve doc-only allowlist + marker follow-ups (#44-#46, #48-#50) - #53

Merged
twistedmelonman merged 4 commits into
mainfrom
claude/resolve-followups-20260418
Apr 18, 2026
Merged

polish: resolve doc-only allowlist + marker follow-ups (#44-#46, #48-#50)#53
twistedmelonman merged 4 commits into
mainfrom
claude/resolve-followups-20260418

Conversation

@twistedmelonman

Copy link
Copy Markdown
Member

Summary

Six follow-up issues filed by local reviewers during the three main session PRs (#39, #47, #52). Bundled into one PR because they share the same files (doc-only case block and the marker printf line) and four small atomic commits are easier to read than a rewrite.

Issues resolved

Commit Issue Impact
d42d068 #44 -F id-f id in the minimizeComment mutation. Consistency with surrounding -f for String-typed vars.
8324219 #45, #48, #49 Remove *.txt (matched requirements.txt-class files), remove PULL_REQUEST_TEMPLATE.md (can embed required security checklists), add image extensions (*.png, *.jpg, *.jpeg, *.gif, *.svg, *.webp, *.ico, *.bmp).
81587ef #46 Switch file enumeration from gh pr diff --name-only to the files API, so renamed files contribute both pre-rename and post-rename paths to doc-only classification. A src/foo.pydocs/foo.md rename can no longer hide code removal behind a doc path.
d311d3f #50 Add `

Behavioral impact

Before After
requirements.txt, packages.txt, constraints.txt PRs: doc-only skip Reviewed — dependency changes should not bypass CI
README screenshot update (*.png): reviewed Doc-only skip — cheap wins
PULL_REQUEST_TEMPLATE.md edits: doc-only skip Reviewed — template can contain security checklists
Renamed code→docs: doc-only skip (silent) Reviewed — union-of-paths classification catches it
SHA marker on non-PR triggers Non-empty fallback to github.sha
minimizeComment(ID) typed via -F (auto) -f (explicit string) for consistency with adjacent code

What this PR does NOT change

Test plan

  • Local pre-commit reviewers PASS on all four commits
  • Codebase reviewer PASS (validated rename union-classification, case ordering, SHA expression syntax)
  • Classification test matrix: requirements.txt → non-doc ✓, README.md → doc ✓, *.png → doc ✓, PULL_REQUEST_TEMPLATE.md → non-doc ✓, CODEOWNERS → non-doc ✓
  • Self-review: CI will run under the NEW rename-aware classifier and tightened allowlist
  • Consumer sanity: after merge + v1 retag, watch kebab-tax or similar for regressions

Closes

Closes #44, #45, #46, #48, #49, #50.

Next step after this merges

Cut new v1 tag so consumer repos pick up the full stack (#39 grep, #47 doc-skip + marker + minimize, #52 narrow prompt, plus this one).

🤖 Generated with Claude Code

Claude Code Bot and others added 4 commits April 18, 2026 13:47
Consistency with the preceding query that already uses -f for owner
and name. GitHub Relay node IDs are base64-encoded and always contain
non-digit characters, so the practical risk of -F type-coercing an
ID to an integer is zero today — but the stated rationale in the
comment above (line 262-264) recommends -f for String-typed variables,
and ID values serialize the same way as String. This aligns the code
with the documented pattern.

Closes #44.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three allowlist adjustments in one commit — they share the same case
block and ship together to avoid rewriting it three times.

1. Remove *.txt (resolves #48). Matched dependency manifests like
   requirements.txt, constraints.txt, packages.txt, which are
   code-adjacent and deserve review on change. `.txt` is rarely used
   for prose in modern repos; README/docs are conventionally .md.
   If a consumer genuinely has prose .txt files, they'll get a cheap
   review — the failure mode of skipping a requirements.txt change is
   significantly worse.

2. Remove .github/PULL_REQUEST_TEMPLATE.md (resolves #49). Templates
   can embed required security checklists, reviewer sign-offs, or
   label instructions. A PR that removes a required security checklist
   should not sail through unreviewed. ISSUE_TEMPLATE/* stays in the
   allowlist — those are user-facing forms with lower enforcement
   significance.

   Note: this required reordering the case statement — the explicit
   NON-DOC exclusion for PULL_REQUEST_TEMPLATE.md / CODEOWNERS /
   dependabot.yml now comes FIRST, because they'd otherwise match the
   general *.md / *.yml patterns that follow. The CODEOWNERS and
   dependabot.yml rules were already correct (they don't match *.md
   or the ISSUE_TEMPLATE glob) but collecting them into the same
   explicit exclusion block documents the "security-critical meta
   file" category cleanly.

3. Add image assets (resolves #45). *.png, *.jpg, *.jpeg, *.gif,
   *.svg, *.webp, *.ico, *.bmp. README screenshot updates, docs
   figures, and logo swaps don't need a paid review — they can't
   meet any BLOCK criterion (no runtime behavior). Conservative
   set — excludes *.pdf, *.psd, and other heavier binary formats.

No functional change to the rest of the workflow.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Closes #46. Under the previous implementation, `gh pr diff --name-only`
returned only the destination paths for renamed files, so a rename from
`src/foo.py` → `docs/foo.md` would appear as only `docs/foo.md`,
classify as doc-only, and skip review — even though the diff contains
significant code deletion at the source path.

Switch to the `repos/{owner}/{repo}/pulls/{pr}/files` API and emit the
UNION of `previous_filename` (non-null when renamed or copied) and
`filename` for every entry. The doc-only check then requires every
pre-rename AND post-rename path to match the allowlist — closing the
blind spot.

For non-renamed files `previous_filename` is null and filtered by the
jq `select(. != null)` clause, so non-rename behavior is unchanged.

Verified against PRs #39, #47, #52 (all modified-only) — output is
identical to the prior `--name-only` approach. An actual rename case
wasn't available in recent history to test empirically, but the jq
emits `previous_filename, filename` separately so the case is covered
by construction: if ANY of those paths is non-doc, the final
classification flips to non-doc.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Closes #50. The marker previously interpolated
`github.event.pull_request.head.sha`, which is only populated when the
reusable workflow is called from a `pull_request` caller. A consumer
that invokes it from `workflow_dispatch`, `push`, or another trigger
would produce:

  <!-- claude-blocking-review sha= run=12345 -->

with an empty `sha=` value. Downstream consumers that filter by SHA
(e.g. post-push status scrapers) would then see every review for that
commit as "unknown SHA" and fall through to phantom-finding behavior.

Use the GitHub Actions expression `||` fallback so the marker always
has a non-empty SHA. The operator returns the first truthy operand —
empty strings from unpopulated nested paths like
`github.event.pull_request.head.sha` evaluate falsy, so the fallback
to `github.sha` fires on non-PR triggers.

Behavior by trigger:
- pull_request (this repo's self-review): PR head SHA, unchanged.
- workflow_dispatch / push / schedule: the triggering commit SHA,
  which is the closest analogue to "what this review is reviewing."
- scheduled / manual runs with no associated commit: github.sha is
  still populated with the workflow file's commit SHA, so the marker
  has a value rather than being empty.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@claude

claude Bot commented Apr 18, 2026

Copy link
Copy Markdown

Four changes in the diff:

  1. Files API → doc-only skip (line ~141): gh api with jq correctly emits both previous_filename and filename, filtering JSON null. No shell injection risk — values reach only a case statement via IFS= read -r. Logic is sound.

  2. Case-pattern cleanup: Explicit NON-DOC guards for PULL_REQUEST_TEMPLATE.md, CODEOWNERS, dependabot.yml placed before general patterns that would swallow them. Removal of *.txt avoids false doc-only on requirements.txt. No regression.

  3. -F id → -f id in GraphQL mutation (line ~319): GitHub node IDs are opaque base64 strings; -f (always string) is more correct than -F (auto-coerce). Safe.

  4. || github.sha SHA fallback (line ~427): Used only in the marker printf embedded in Claudes prompt. Fires only in non-PR trigger contexts. Safe.

VERDICT: PASS

@twistedmelonman
twistedmelonman merged commit 988148f into main Apr 18, 2026
3 checks passed
@twistedmelonman
twistedmelonman deleted the claude/resolve-followups-20260418 branch April 18, 2026 20:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Inconsistent -f vs -F usage for GraphQL ID variable

1 participant