Skip to content

test(harness-ops): move the plugins-audit evals to native cases with fleet fixtures - #13442

Merged
kyle-sexton merged 2 commits into
mainfrom
test/8206-plugins-audit-native-cases
Nov 5, 2026
Merged

kyle-sexton merged 2 commits into
mainfrom
test/8206-plugins-audit-native-cases

Conversation

@kyle-sexton

Copy link
Copy Markdown
Member

Refs: #9966

Summary

The four /harness-ops:plugins-audit eval cases are now claude plugin eval cases under plugins/harness-ops/evals/, and three of them carry a fleet fixture. These are the files the #8206 output arm ran on (result on #9966). They were in a scratch copy only; this PR keeps them, as the hub asked (H48 (b)).

Fix

  • Converted skills/plugins-audit/evals/evals.json with convert-evals-json.py and removed the legacy file. The four case directories match a fresh conversion of main's file, apart from the run settings below.
  • audit-issues-zero-mutating-calls, divergence-report-collapses-bulk-names-conflicts and model-starts-audit-not-sync each get a scaffold.sh and context.scaffold_script. The scaffold writes the run's home with known_marketplaces.json, a catalog, installed_plugins.json, settings and a harness-ops install record, so the default marketplace resolves. The divergence case gets the fleet its prompt names: 29 plugins whose scopes differ, 2 same-version multi-scope, and 1 settings-only delisted id.
  • All four cases list Bash in allowed_tools. The three scaffolded cases say in their description that they need --scaffold --allow-tools Bash with the real node first on PATH.

Verification

  • validate-cases.py plugins/harness-ops/evals exits 0 with no FAIL. Its warnings are the converter's: judge-only graders, and samples that need judge calibration.
  • diff -r of a fresh convert-evals-json.py run against these directories shows only the scaffold.sh files, the scaffold_script lines and Bash in allowed_tools.
  • Run record, Sonnet 5.5, judge Opus, 3 runs per arm: with the plugin, three of the four cases scored at least 0.8; the noise report gave +0.45, interval +0.26 to +0.65.
  • Left out: a re-run on this exact tree. The case files are the ones measured, with only a description line added to three prompts' frontmatter.

Remaining

Related

🤖 Generated with Claude Code

…fleet fixtures

Convert the skill's four legacy evals.json cases with convert-evals-json.py
and retire the legacy file. Three cases get a scaffold that seeds the run's
home with a marketplace, its catalog, install records and settings, so the
default marketplace resolves and the cases measure the skill rather than
the empty sandbox. These are the cases the #8206 output arm ran on.

Refs: #9966

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

chatgpt-codex-connector Bot commented Nov 5, 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-05T05:43:20.556010Z 7acfb23 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 5, 2026 •

Copy link
Copy Markdown
Contributor

claude-security-review reviewed 13b4af188b031b551ec58f9f6ad5d427819144d0: read 30 of 30 changed file(s); 0 finding(s), 0 as inline comments.

Security review: no security issues found

This pull request moves the four /harness-ops:plugins-audit eval cases from the skill's old evals.json into native claude plugin eval case directories. It also adds a fixture scaffold.sh to three of them. Every changed file is eval data, a test fixture or a change note. The diff changes no workflow, trust control, merge hold, manifest, hook or standing instruction.

What I checked

  • The three scaffold.sh files. They write the fixture fleet under $HOME. Each one first resolves the account's real home with getent passwd or dscl and refuses to run when HOME points there. It refuses when it can't look the real home up, and refuses to overwrite any file it would write (the refuse checks on lines 13–23 and 31/33 of each script). The divergence scaffold uses one base directory, $PWD, throughout and adds $HOME/other-project to its no-overwrite check.
    • Every interpolated value is a fixed fixture name or a path built from $HOME, $PWD or the script's own directory. No pull request, issue or comment text reaches them, so I found no injection path.
    • The harness-ops install record's installPath points at the checkout's own plugins/harness-ops directory. That is the code under test, not an outside source.
  • allowed_tools now includes Bash in all four prompt.md files. This only affects eval runs of fixed prompts that live in the repository. It gives untrusted text no new way into a credentialed lane and grows no token scope.
  • Deleted skills/plugins-audit/evals/evals.json. It holds eval definitions, not standing instructions. The same cases are recreated under evals/, so no guardrail is removed.
  • Manifests. The diff changes no plugin.json or marketplace.json. The .changes entry is bump: none.
  • Trusted paths. No changed file matches a TRUSTED PATHS glob.

Settled thread. My earlier finding on plugins-audit-audit-issues-zero-mutating-calls/scaffold.sh (the fixture home was guessed with no guard against the real home) was resolved in 13b4af1, marked lines changed since resolution: no. I confirmed the head code matches the owner's description of the fix, in all three scaffolds. I am not raising it again.

Identical files. I read the first file of each identical-copy group and skipped the rest. None of the copies sits at a path that would change what its content does. plugins-audit-model-starts-audit-not-sync/scaffold.sh has the same blob as the zero-mutating-calls scaffold but is not on the identical list, so I read it separately.

Spend. Adding Bash to the eval cases and adding scaffolds may lengthen eval runs a little. That uses only prepaid API or subscription usage, and there is no billable change.

critical-findings: 0

@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: 1 inline finding(s) on 7acfb2368e8903438a6d575f1abf8500c11b847b; the summary is in this lane's pull request comment.

claude-lane: claude-review

@github-actions

github-actions Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

claude-review reviewed 13b4af188b031b551ec58f9f6ad5d427819144d0: read 3 of 3 changed file(s); 0 finding(s), 0 as inline comments.

Code review: PR #13442, incremental (7acfb23 → 13b4af1)

No new findings in this push. This review was blocking only, because this lane already reviewed an earlier head. I read every hunk of all 3 files in scope, which are the three plugins-audit-* scaffold.sh files.

The earlier finding is fixed. That finding said the scaffolds guessed the fixture home as $(cd .. && pwd), had no guard against the real home and overwrote files without checking. The owner resolved it, and this push carries the fix. Each scaffold now:

  • writes only under $HOME.
  • refuses when HOME is unset or not a directory.
  • refuses when HOME resolves (pwd -P) to the account's real home from getent passwd or dscl, and refuses when neither lookup tool exists.
  • refuses when any target already exists, before writing anything.

The targets checked are the two plugin-state JSON files, the user and workspace settings*.json files, the marketplace directory, and in the divergence scaffold also other-project.

In the divergence scaffold, EVAL_FIXTURE_CWD is gone and the script uses $PWD throughout, so the two-directory split is fixed as well. A grep of the three scaffolds finds no remaining use of the old home or cwd variables, which would have aborted under set -u.

Edge cases I checked:

  • If getent fails, pipefail plus set -e stop the script before any write.
  • If the real-home directory does not exist, its cd yields an empty string, the comparison passes, and that is correct because HOME cannot be that directory.
  • The final printf '{}\n' >"$f" loop now overwrites without the old -s check. That is safe, because the existence guard has already refused any of those paths that existed.

Not checked by me. The owner says they ran these by hand: a fresh temporary home passes, a rerun refuses, HOME=<real home> refuses, and the fixtures are byte-identical after normalising paths. They also say the runner's HOME has no .claude yet, so the runner itself trips no refusal. These are author claims, and I did not run anything.

Spend (not a finding, not a hold). Running these eval cases uses prepaid API credit only. This push does not change that.

Other checks. There is no closing issue, so there are no acceptance criteria to check. No plugin manifest changed.

… a real-home guard

The three scaffolds took the fixture home as the parent of the working
directory and overwrote plugin state there. Run by hand from a project
under ~, that is the real home. They now write under $HOME, which the
runner sets to the run's temporary home, refuse the account's real home
and any existing target, as the context-guard scaffolds do, and drop the
unused EVAL_FIXTURE_CWD. The fixture each writes is unchanged.

Refs: #9966

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kyle-sexton
kyle-sexton added this pull request to the merge queue Nov 5, 2026
Merged via the queue into main with commit b77c250 Nov 5, 2026
44 checks passed
@kyle-sexton
kyle-sexton deleted the test/8206-plugins-audit-native-cases branch November 5, 2026 05: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.

1 participant