Skip to content

test(review): add revert eval cases and resolve reverts named by PR number - #13097

Closed
kyle-sexton wants to merge 6 commits into
mainfrom
test/12939-revert-cases
Closed

kyle-sexton wants to merge 6 commits into
mainfrom
test/12939-revert-cases

Conversation

@kyle-sexton

@kyle-sexton kyle-sexton commented Nov 4, 2026 •

Copy link
Copy Markdown
Member

Closes #12939

Summary

Adds the first 16 revert cases for review:code-review and their first run: the lane caught 11 of 16 on Opus at effort high. revert-cases.sh list could not find any pair on this repository's history before this PR, because reverts here name the original by pull request number.

Fix

Verification

claude plugin eval on a copy outside git, --case 'revert-*' --scaffold --ablation none --runs 1 -j 2, claude-opus-5-5, effort high (the pr-review profile in docs/conventions/pr-pipeline.yaml), Claude Code 2.1.318. run-validity.py --runs 1 --scaffolded at 3e711ca460: VALID, no denied tool call in 16 traces. Its warning is only that no case has a skill-fired grader.

revert-cases.sh report, pair count 16:

case result
revert-12114-curate-language-description missed
revert-12121-kindle-dedrm-concise missed
revert-12162-dometrain-sync-body missed
revert-12186-name-it-better-description missed
revert-12201-ai-slop-audit-body caught
revert-1835-cursor-manifests caught
revert-4899-park-ledger-a caught
revert-4903-park-ledger-b caught
revert-4923-park-ledger-c caught
revert-4960-park-ledger-d caught
revert-4961-park-ledger-e caught
revert-4963-park-ledger-f missed
revert-4964-park-ledger-g caught
revert-6500-coverage-check-docs-lookup caught
revert-8254-clean-first-pr-merge caught
revert-8791-docs-only-review-evidence caught
total caught 11 of 16

Read the total with these limits:

  • A hit means the reply cited a reverted line, not that it found the reason for the revert. The seven park-ledger cases and revert-1835 revert whole files or large parts of a change, so almost any citation counts. Comparing two totals is sounder than reading one.
  • One run per case, as the README's run command sets.
  • The grader matches a file's basename, so with repeated basenames (revert-6500's seven copies, revert-1835's plugin.json files) a citation of a sibling file can count.
  • The verifier read revert diffs by eye for six cases and the code files of two more. The rest rest on git blame from each listed line to its pull request, which matched every line. No line was dropped from the 16.

The eval ran before the fixtures were packed; I scaffolded one case from its archive afterward, and it rebuilt the change.

Left out: revert-cases.test.sh is the only local test run, since CI runs the suites; no second run for a before-and-after comparison, because no review-lane change is in this PR.

Related

🤖 Generated with Claude Code

kyle-sexton and others added 3 commits November 4, 2026 00:23
…umber

revert-cases.sh list found 0 pairs in this repository's full history:
every revert names its original by pull request number, not by the
reverted subject or a "This reverts commit" line. List now tries each
merged non-revert pull request a revert's message names, which finds 16
pairs. Adds the 16 cases a verifier agent confirmed; a 17th pairing was
dropped because that revert names the pull request without undoing it.

Closes #12939

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
They are byte copies of history, which the markdown, typos and exec-bit checks must not judge.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kyle-sexton
kyle-sexton marked this pull request as ready for review November 4, 2026 05:31
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-04T05:33:22.038220Z 2e1d555 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions

github-actions Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

claude-security-review partial review of 969f5112eec08676e9e83ac58cb73bc6a7d84c7d: read 68 of 84 changed file(s). 0 finding(s) in what was read, 0 as inline comments. This head is not reviewed.

Chunk 1 of 3 (40 files)

Security review: chunk 1 of 3 (PR #13097). Partial review: 32 of 40 files read

No security issues found in this chunk.

What this chunk changes

  • .changes/review/test-12939-revert-cases-b5e2f4e0.md: a changeset with bump: none.
  • plugins/review/README.md: the "Revert cases" text now covers the PR-number lookup and the fixtures.tar.gz archives.
  • Eight revert-* eval cases. Each has a comment-only case.yaml, a regex grader in graders/caught.md, a prompt.md, a two-line scaffold.sh and a fixtures.tar.gz.
    • Every scaffold.sh is the same one-liner: exec bash "$(dirname "${BASH_SOURCE[0]}")/../revert-cases.sh" scaffold <fixed case name>. No input from outside the repository reaches it.
    • Every prompt.md runs /review:code-review with allowed_tools: [Read, Glob, Grep, Skill, Agent] and no Bash. It tells the run that it has no GitHub access and must post nothing.

Checks

  • Trusted paths and controls. No file in this chunk matches a TRUSTED PATHS glob. Nothing here touches a trust control, a merge hold, the token broker, the kill switch or a plugin manifest. CLAUDE.md and the plugin.json / hooks.json files show up only as names inside case comments, graders and prompts. They are not files this PR changes.
  • Identical copies. revert-12186-name-it-better-description/graders/caught.md is a copy of the 12114 grader. Both are regex grader files, so the copy's path does not change what its content does.
  • Archive handling. These are the fixtures that revert-cases.sh scaffold unpacks (that script is in chunk 3, read here for context only).
    • It runs tar -xzf "$archive" -C "$fixtures" into a fresh mktemp -d directory: revert-cases.sh.
    • It refuses to scaffold into a directory that already holds .git.
    • It refuses a case still marked confirmed-by: pending.
    • The archives are committed to the repository by the owner's own agent. Under the owner threat model the only actors are the owner, its bots, its agents and its GitHub Apps. So no untrusted actor reaches the extraction, and nothing reaches a credentialed lane.
  • Instruction surfaces. The README change removes no guardrail. It adds that the verifier rejects a pair whose message names a PR it did not undo.

Not reviewed

I did not inspect the 8 fixtures.tar.gz files. The diff carries them as raw gzip bytes, which cannot be read as a diff:

  • revert-12114-curate-language-description
  • revert-12121-kindle-dedrm-concise
  • revert-12162-dometrain-sync-body
  • revert-12186-name-it-better-description
  • revert-12201-ai-slop-audit-body
  • revert-1835-cursor-manifests
  • revert-4899-park-ledger-a
  • revert-4903-park-ledger-b

files_read is therefore 32, not 40. I cannot confirm from the diff that each archive holds only the files its case.yaml lists.

One case for whoever runs the evals: the archives hide their contents from every review lane, and scaffold copies each <path>.txt to <path> in the eval workspace. A future archive could therefore add a workspace .claude/ settings file or a CLAUDE.md that the eval session on the host would load, and no review would see it. No case.yaml in this chunk lists a .claude/ path, and the PR description says a verifier scanned the unpacked files for home paths and token shapes. Since only the owner and its agents author these archives, I did not count this as a finding.

Spend

Sixteen added on-demand eval cases (max 40 turns, 900 s timeout, one run each) spend prepaid API credit when someone runs them. They are not a required check and cause no billable charge.

critical-findings: 0

Chunk 2 of 3 (40 files)

Security review, chunk 2 of 3 (PR #13097, head 969f511): partial

I found no security issues in the text files of this chunk. The review is partial: I read every text file whole (32 of 40), but I could not see what the 8 fixtures.tar.gz archives contain.

critical-findings: 0

What I read

  • Text files, read whole (32):
    • scaffold.sh for 4903-b, 4923-c, 4960-d, 4961-e, 4963-f, 4964-g, 6500, 8254. Each is a two-line exec bash .../revert-cases.sh scaffold <fixed case name>, with no input from outside.
    • case.yaml, prompt.md and graders/caught.md for 4923-c through 4964-g, 6500, 8254 and 8791.
    • Each prompt.md runs /review:code-review with allowed_tools: [Read, Glob, Grep, Skill, Agent] and tells the run it has no GitHub access.
    • The graders are anchored regex alternations of fixed line numbers. I saw nothing in them that could backtrack badly.
  • Fixture archives (8), contents not checked: 4923-c, 4960-d, 4961-e, 4963-f, 4964-g, 6500, 8254, 8791.
    • In the patch they are gzip bytes. This lane has no shell, and the review:lane-verifier I asked to list them had no Bash either, so it could not run tar -tzvf (no Bash in this run).
    • So I could not confirm that each archive holds only pr-context.md plus base//head/ copies of the paths on its case.yaml # lines: comment, as the # rebuilt: only the files above line claims.
    • I also could not check them for symlinks, executable bits, token-shaped strings or text aimed at the reviewer. The PR text says a verifier scanned them; I did not rely on that.
  • Prior findings: none (0 rounds, cap 3, not past the cap). No settled-threads file. No embedded instructions in the PR context.

Why the archive contents matter (context from chunk 3, not a finding here)

  • scaffold extracts the archive into a temp directory with tar -xzf (revert-cases.sh#L283).
  • place then copies every regular *.txt member to its own path, minus .txt, and never checks that path (revert-cases.sh#L262-L271). This happens after git init, and git commit runs right after (#L285-L296).
  • So a member such as base/.git/hooks/pre-commit.txt or head/.claude/settings.json.txt would run code on the host that scaffolds the case, or become live settings for the eval session.
  • I do not rate this here, for two reasons:
    • Fixtures are built only from git-history blobs of the paths a revert touched (#L193-L200).
    • The archives' author is this PR's author, one of the owner's agents, who is a trusted actor under the owner threat model. No outside attacker reaches them.
  • The missing path check in place belongs to the chunk-3 review of revert-cases.sh.
  • Recommended follow-up: someone with a shell should run tar -tzvf on each archive in this chunk and compare the members with its case.yaml path list before merge.

Other notes

  • Archives 8254 and 8791 carry byte copies of .github/workflows/pr-merge.yml and babysit_review_evidence.py, which are names on the trusted-path list. They sit inside archives, not at live paths, and scaffold places them in a scratch repository. No live control changes.
  • No trusted-path files, plugin manifests, workflows or token, merge-hold or kill-switch controls are in this chunk.
  • Spend: the cases use prepaid credit only when someone runs claude plugin eval (max_turns 40, timeout 900s per case). No CI job runs them and nothing bills.

Chunk 3 of 3 (3 files)

Security review: chunk 3 of 3 (PR #13097)

No security issues found in this chunk. I read every hunk of all 3 files: plugins/review/evals/revert-8791-docs-only-review-evidence/scaffold.sh, plugins/review/evals/revert-cases.sh and plugins/review/evals/revert-cases.test.sh. I also read the whole revert-cases.sh at head for context. None of the 3 files matches a trusted-path glob, and none is a copy listed in identical.txt.

What I checked:

  • Shell injection in the new named_originals. Only digits reach $ref, because grep -oE '#[0-9]+' is followed by tr -d '#'. It is passed to git log -F --grep=" (#$ref)" as one quoted argument (revert-cases.sh#L66-L67). Commit text cannot inject anything there.
  • Unpacking the archive in scaffold. tar -xzf unpacks into a fresh mktemp -d directory (L282-L283). GNU tar already refuses absolute paths and .. entries. place copies only regular files (find -type f, L270). The archives come from this repository: build writes them with a fixed owner and time, and only a merged pull request can change them. The repository's threat model counts only the owner, its bots and its agents as actors, so nobody outside reaches this path.
  • The archived fixtures are opaque binaries, which is not a finding. Neither a reviewer nor this lane can read them in the diff. Their text reaches only an eval workspace, as .claude-lane/pr-context.md (labelled untrusted data) and pr.diff. Each case's prompt.md limits the run to allowed_tools: [Read, Glob, Grep, Skill, Agent] (L242): no Bash and no credentials. So text planted in a fixture has no route to a leak, a takeover or a charge.
  • scaffold is safer than before. It now refuses to run in a directory that is already a repository (L277), so git rm -rqf . cannot wipe a real checkout. Both temporary directories are removed with the ${fixtures:?} guard.
  • No standing instruction, trust control, merge hold, token scope, workflow or plugin manifest changes in this chunk.

Spend: the 16 new eval cases use prepaid model usage only when someone runs claude plugin eval on demand. They are not a required check and start no billed resource, so there is no cost hold.

No prior findings apply: 0 rounds before this one, and the cap of 3 does not apply.

critical-findings: 0

…ectory

Under evals/fixtures/ the orphaned-fixtures check requires a grader or test to name each file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

claude-review partial review of 969f5112eec08676e9e83ac58cb73bc6a7d84c7d: read 73 of 84 changed file(s). 2 finding(s) in what was read, 2 as inline comments. This head is not reviewed.

Chunk 1 of 3 (40 files)

Code review, chunk 1 of 3: PR #13097 at 969f5112

I found nothing to block or flag in this chunk. The review is partial: I read every hunk of 34 of the chunk's 40 files.

The other 6 files are fixtures.tar.gz archives whose content I did not review: 12121, 12162, 12186, 12201, 1835 and 4903. I read the hunks of the 12114 and 4899 archives, but compressed gzip bytes can't be reviewed as text. Their contents can only be checked against the commits each case.yaml names. I did not unpack or run anything; the PR says a verifier scanned the unpacked files, and I have not confirmed that.

What I checked

  • Changelog fragment (.changes/review/test-12939-revert-cases-b5e2f4e0.md): bump: none fits a test-only change. No plugin manifest changes in this chunk.
  • plugins/review/README.md: the updated text for list (it now tries the merged pull requests a revert's message names by number) and for build (it writes fixtures.tar.gz) matches revert-cases.sh:
    • build packs the archive with deterministic tar and gzip -n, at revert-cases.sh L257.
    • scaffold unpacks it and refuses a case whose confirmed-by: is still pending, at L275–L300.
  • The 8 cases in this chunk (12114, 12121, 12162, 12186, 12201, 1835, 4899, 4903):
    • Each case.yaml records the original pull request, its merge commit, the base, the revert, the listed lines and a filled-in confirmed-by: line.
    • Each prompt.md runs /review:code-review only.
    • Each scaffold.sh is mode 755 and hands off to revert-cases.sh scaffold <case>.
    • Each grader's line list matches its case.yaml and the expected_outcome in prompt.md.
    • The (?!\d) lookahead stops partial-number hits, so SKILL.md:2 does not match :20.
  • Duplicate grader: revert-12186-name-it-better-description/graders/caught.md is a byte copy of 12114's. That's correct: both cases grade SKILL.md line 2, and the path is an ordinary eval path, so where the copy sits doesn't change what it does.

Closing issue #12939

In this chunk, the criterion "The suite's revert- cases each record the original PR, the revert and a verifier-agent confirmation in case.yaml" is met for all 8 cases. A test can catch a regression: revert-cases.test.sh L81 and L92 check the pending marker and the confirmation step that scaffold enforces. The criteria for the lister, the report and "not a required check" are covered by chunk 3 (revert-cases.sh and its test).

Grader limits (the PR body already discloses these; not findings)

  • The graders match a file's basename, not its full path.
  • In revert-1835-cursor-manifests, the root README.md and scripts/cursor-export/README.md both feed the README.md alternation, so a citation of nearly any README.md line from 1 to 57 counts. marketplace.json lines 1–981 also match .claude-plugin/marketplace.json.
  • A range citation that starts before the first listed line, such as SKILL.md lines 95-100 for 12201, is graded as missed.

The PR body states these limits, and I read them as known caveats on the 11-of-16 total.

Spend

Running the 16 cases (40 turns and 900 s max each, one run per case) draws only prepaid API credit. They run on demand, not as a required check, so this is not a hold.

Other notes

  • No prior findings from this lane (0 rounds, cap 3), and no settled-threads file was given.
  • No embedded instructions in the PR context.

Chunk 2 of 3 (40 files)

Code review: chunk 2 of 3 (PR #13097, head 969f511)

Result: no findings in this chunk.

Scope. This chunk covers 40 added files across 9 revert cases: revert-4903-park-ledger-b/scaffold.sh, revert-4923-park-ledger-c, -4960-park-ledger-d, -4961-park-ledger-e, -4963-park-ledger-f, -4964-park-ledger-g, revert-6500-coverage-check-docs-lookup, revert-8254-clean-first-pr-merge, and revert-8791-docs-only-review-evidence up to its prompt.md. None of these files match a trusted-path glob.

This review is partial: 35 of 40 files read. I read every text hunk: each case.yaml, graders/caught.md, prompt.md and scaffold.sh. I also saw the full diff bytes of the fixtures.tar.gz archives for 4923-c, 4960-d and 4961-e. I did not page through the gzip bytes of the archives for 4963-f, 4964-g, 6500, 8254 and 8791, so they are not counted. Gzip data in a diff cannot be reviewed line by line anyway. Those archives' contents were not inspected; the PR body says they are byte copies of history.

What I checked

  • Generated files match the generator. I compared each file against build() in plugins/review/evals/revert-cases.sh (lines 171–260). The case.yaml header, prompt.md and the one-line scaffold.sh match what build writes.
  • The diff prepares each case to run. Every case has a filled confirmed-by: line, so scaffold (line 278) will not refuse it. Every scaffold.sh is added with mode 100755.
  • Line lists agree. For all eight cases with graders here, I expanded the lines: ranges in each case.yaml and compared them with the line numbers in its caught.md regex. They match exactly, including the long lists in 8254 and 8791.
  • Grader regex. The trailing (?!\d) stops a cited line such as :12 from matching listed line 1. Single quotes are escaped correctly for YAML.
  • Revert IDs are consistent. All seven park-ledger cases name revert revert: remove seven merged out-of-scope park ledgers #5044 7e3a5c3d. Each prompt.md description quotes the same revert PR number and short SHA as its case.yaml.

Known limitations, already stated in the PR body (not findings)

  • Shared basename in revert-6500. The revert-6500 grader matches on basename, and all seven files share the name docs-lookup-procedure.md. So:

    • The six 64–67 alternatives are identical.
    • A citation of lines 61–63 in any plugin copy, or 65–67 in lib/, counts as caught even though the revert did not touch those lines.

    This is the PR body's third limitation ("a citation of a sibling file can count").

  • Whole-file ledgers. The park-ledger cases each add a whole ledger file that the revert deletes, so almost any citation counts. The PR body states this too.

Closing issue #12939. The relevant criterion is: "The suite's revert- cases each record the original PR, the revert and a verifier-agent confirmation in case.yaml". Every case in this chunk meets it on its pr:, revert: and confirmed-by: lines. The test coverage for list/build/scaffold is in revert-cases.test.sh, which is in chunk 3 and was not reviewed here.

Verification. The eval run and the 11-of-16 result are the author's claims; I have not verified them. I ran nothing: this lane has no shell.

Spend. These cases run only on demand through claude plugin eval: 16 cases, 1 run each, max_turns: 40, timeout 900s. That draws on prepaid API or subscription usage only, and the cases are not a required check. This is not a hold.

Embedded text. No directive aimed at this lane was found in the PR context or the prior-findings file. The prior-findings file lists 0 rounds with findings and a cap of 3, so the round cap does not apply.

Chunk 3 of 3 (3 files)

I found 2 advisory problems in chunk 3 and nothing that should block the merge

I read every hunk of the three files in this chunk:

  • plugins/review/evals/revert-8791-docs-only-review-evidence/scaffold.sh (new)
  • plugins/review/evals/revert-cases.sh (changed)
  • plugins/review/evals/revert-cases.test.sh (changed)

I read both scripts in full at the head commit for context.

What changed

  • list gains a third way to find a revert's original: through named_originals, it tries each merged non-revert pull request whose number the revert's message names. It does this only when neither the subject form nor a This reverts commit line resolves the original. It skips the revert's own number and any named pull request that is itself a revert.
  • build no longer writes fixtures under fixtures/. It writes them to a temporary directory and packs them into <case>/fixtures.tar.gz. scaffold unpacks that archive.
  • scaffold now refuses to run in a directory that already holds .git.

Tracing the new tests by hand (not run)

The PR body says revert-cases.test.sh passed locally. That claim is the author's; I did not run it.

Closing issue #12939
This chunk covers the lister criterion. The script prints each pair and the pair count, and its new resolution path has tests. The other criteria (case.yaml contents, the run, the report) sit in chunks 1 and 2 and the PR body.

Findings (both advisory, inline)

  1. In the new pull-request-number path, every outcome with no pair is reported as its original commit is not in this history. That includes a named original that removes no line or no longer reverses cleanly, where the original is in history, so the skip reason is wrong for those two cases.
  2. build never checks the status of its tar | gzip pipeline. Its tar flags are GNU-only, and macOS bsdtar rejects --sort. If tar fails, build writes an empty archive, deletes the temporary fixtures and still exits 0.

Other notes

  • This chunk has no plugin manifest changes and no path-scoped rule that applies. eval-case-transcripts.md covers these paths, but none of the three files holds a transcript.
  • I found no embedded instructions in the PR context or the prior-findings file. This is the lane's first round, so nothing was already posted and the round cap does not apply.
  • No change here can cause a billed charge, so there is no hold.

kyle-sexton and others added 2 commits November 4, 2026 00:41
…tory

Scaffold runs git add -A, so in a real checkout it would commit stray untracked files.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…read them

They are line numbers at the historic merge, not citations of the current tree.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

claude-review: 2 inline finding(s) on 969f5112eec08676e9e83ac58cb73bc6a7d84c7d; the summary is in this lane's pull request comment.

claude-lane: claude-review

Comment on lines +144 to 145
if [[ "$found" == 0 ]]; then
printf 'skip\t%s\tits original commit is not in this history\n' "$sha" >&2

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Advisory: wrong skip reason when a named pull request is found but fails a check.

In the new pull-request-number path, found stays 0 in three cases:

  1. The message names no merged non-revert pull request.
  2. It names one, but the revert removes no line that pull request added (pair_lines is empty).
  3. It names one, but that change no longer reverses cleanly.

All three print its original commit is not in this history. That is false for cases 2 and 3, where the original was resolved and is in history. The header promises skip<TAB><sha><TAB><why>, and the subject and body paths keep the two failure reasons apart (removes no line #<n> added, #<n> does not reverse cleanly onto its parent).

How to see it: commit feat: add q (#20) adding q=1, then commit revert: undo it (#21) with body Undoes #20. that edits an unrelated line of the same file. list resolves #20, pair_lines is empty, and stderr says the original is not in history. Someone sorting skipped reverts to recover pairs (as with the #9438/#9456 pairing in the PR body) is pointed at a history problem that does not exist.

Fix: record the last failure per candidate, for example removes no line #<n> added or #<n> does not reverse cleanly. Print not in this history only when named_originals yields nothing. Add a test case for a named pull request that fails pair_lines.

claude-lane: claude-review

MD

printf -- "---\ntype: regex\npattern: '%s'\nflags: i\n---\n" "${alt//$q/$q$q}" >"$case_dir/graders/caught.md"
tar --sort=name --mtime=@0 --owner=0 --group=0 --numeric-owner -C "$fixtures" -c . | gzip -n >"$case_dir/fixtures.tar.gz"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Advisory: build reports success even when the archive step fails.

The script runs without set -e (line 2's shellcheck note says each caller checks the status it needs), but nothing checks this pipeline's status. If tar fails, gzip -n still writes a valid but empty gzip stream to fixtures.tar.gz. Then rm -rf deletes the only copy of the fixtures, and build prints $case_dir and exits 0.

The failure is easy to hit: --sort=name, --mtime=@0 and --owner/--group/--numeric-owner are GNU tar options. bsdtar, the default tar on macOS, rejects --sort.

The broken case only surfaces later, when scaffold runs tar -xzf under set -e. By then the case directory exists, so a rerun of build dies with already exists until it is deleted by hand.

Fix: check the status and clean up on failure:

if ! tar --sort=name --mtime=@0 --owner=0 --group=0 --numeric-owner -C "$fixtures" -c . | gzip -n >"$case_dir/fixtures.tar.gz"; then
  rm -rf "${fixtures:?}" "${case_dir:?}"
  die "could not archive the fixtures for $name (GNU tar is required)"
fi

claude-lane: claude-review

@kyle-sexton

Copy link
Copy Markdown
Member Author

Superseded by #13223 (text files) and a held archive-only PR, per hub H25: every file these reviews could not read was a gzip archive. The two advisory threads are fixed in #13223.

@kyle-sexton kyle-sexton closed this Nov 4, 2026
@github-actions
github-actions Bot deleted the test/12939-revert-cases branch November 5, 2026 13:24
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.

Revert eval set for review:code-review

1 participant