Skip to content

fix(setup): make isolated-setup-verify checks catch false passes - #1808

Open
shahar1 wants to merge 3 commits into
apache:mainfrom
shahar1:fix/verify-skill-accuracy
Open

shahar1 wants to merge 3 commits into
apache:mainfrom
shahar1:fix/verify-skill-accuracy

Conversation

@shahar1

@shahar1 shahar1 commented Oct 25, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

A setup-isolated-setup-verify run on a Linux host (Claude Code started from the VS Code extension, adopter settings only in .claude/settings.local.json) reported several checks as passing that proved nothing. This PR closes those false passes:

  • Check 1 evaluates the merged settings (managed, user, project, project-local) instead of only the committed project file, names the file each key came from, and requires sandbox.filesystem.denyRead to cover ~/. Without that entry, bubblewrap reads are deny-only and credential files stay readable from the sandbox.
  • Check 7a probes common credential paths with test -r / stat (never cat). When denyRead covers ~/, a sentinel file known to exist on the host proves the denial. It reports inconclusive only when no sentinel is available. Before, a missing ~/.aws/credentials produced the same output as a working denial.
  • Check 7b lists environment variable names only and flags credential-shaped ones. It reports CLAUDE_CODE_ENTRYPOINT and gives ⚠ for IDE-launched sessions, which never pass through claude-iso. The old probe (echo $AWS_ACCESS_KEY_ID) passed regardless, because sandbox.credentials already unsets that variable. The clean-env wrapper doc gains a paragraph on IDE launches.
  • Check 5 / 10a / 13c first locate the framework checkout (the current repo, an .apache-magpie/ snapshot, or the directory the shell rc sources agent-iso.sh from), and report unchecked rather than ✗ or ⚠ when there is none. A marketplace-only install has no tools/ directory, and the running claude-code version is still reported.
  • Check 10 runs the touch-overlay sub-checks only for a hardware key (an sk- public key, or a card that gpg --card-status finds). 10c still applies to every ssh-format key.
  • The verify and doctor skills explain sandbox placeholders: write-protected paths that do not exist show up as character devices 1,3, so git status lists them as untracked.
  • The verification prompts in docs/setup/secure-agent-setup.md (including "Keeping the setup updated") are kept in sync, and never print a credential.

Type of change

  • Skill change (.claude/skills/<name>/) — eval fixtures updated below
  • Documentation (docs/, README.md, CONTRIBUTING.md)

Test plan

  • prek run --all-files --skip workspace-pytest passes
  • prek run workspace-pytest --from-ref upstream/main --to-ref HEAD passes
  • Eval suite for the affected skill, skill-eval --cli "claude -p" tools/skill-evals/evals/setup-isolated-setup-verify/: 29/34 pass. All 7 new cases pass. Of the 5 failures, 4 also fail on unmodified upstream/main (step-1 case-7; step-2 case-3, case-5, case-6; the baseline run was 20/27). The fifth, step-1 case-14, passed on two re-runs and is not touched by this PR.
  • New eval cases: step-1 case-17-deny-read-missing, case-18-local-settings-only, case-19-ide-entrypoint-env, case-20-plain-ssh-signing-key, case-21-7a-inconclusive, case-22-no-framework-checkout; step-2 case-7-unchecked-no-checkout. The step-1 status enum gains inconclusive and unchecked.
  • Reviewed by an independent agent. Its requested changes are in the second commit.

RFC-AI-0004 compliance

  • Sandbox — the verify checks now detect a missing home denyRead and stop printing credential contents
  • Vendor neutrality — placeholders only (check-placeholders passes)

Notes for reviewers (optional)

  • Companion PR fix(agent-isolation): guard Linux allowAllUnixSockets with denyRead #1809 covers the Linux allowAllUnixSockets exposure (verify check 12) and the sandbox-lint rules. Both PRs add step-1 eval cases and touch the same README case counts, so whichever merges second needs a trivial rebase.
  • Not included: a clean-env wrapper mode for the VS Code extension's claudeCode.claudeProcessWrapper. agent-iso.sh's env -i allowlist would drop the CLAUDE_CODE_* variables the extension needs, so that needs its own design and will be raised as a separate issue.

Generative AI: drafted with Claude Code (Claude Opus 5.5) and checked by an independent Claude Opus review agent; opened as a draft for the author's line-by-line review before it is marked ready.

🤖 Generated with Claude Code

@github-actions github-actions Bot added family:setup setup-* skills family:tools tools/* family:docs Docs, MISSION.md, READMEs capability:reassess Re-run historical issues against current code capability:platform Framework / agent substrate skills (install, verify, doctor, override, status, setup bootstrap) substrate:framework-dev Tool substrate: build / validate / eval the framework itself labels Oct 25, 2026
@shahar1
shahar1 requested a review from potiuk October 25, 2026 06:44
@shahar1
shahar1 marked this pull request as ready for review October 25, 2026 06:53

@potiuk potiuk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks, this is a clear improvement over the old cat/echo probes. A few of the new rules still let a false pass or false fail through; details inline. The first is the one that matters most.

Comment thread plugins/magpie-setup/skills/isolated-setup-verify/SKILL.md Outdated
Comment thread plugins/magpie-setup/skills/isolated-setup-verify/SKILL.md Outdated
Comment thread plugins/magpie-setup/skills/isolated-setup-verify/conditional-checks.md Outdated
Comment thread docs/setup/secure-agent-setup.md Outdated
Comment thread docs/setup/secure-agent-setup.md Outdated
Comment thread plugins/magpie-setup/skills/isolated-setup-verify/SKILL.md Outdated
Comment thread plugins/magpie-setup/skills/isolated-setup-verify/SKILL.md
@shahar1
shahar1 force-pushed the fix/verify-skill-accuracy branch from 20df286 to 457e09f Compare October 26, 2026 03:57
A verify run on a Linux host launched from an IDE extension, with the
project settings only in settings.local.json, reported several checks
as passing that proved nothing:

- Check 1 read only the committed project file and never asked for
  sandbox.filesystem.denyRead. Without "~/" there, bubblewrap reads
  are deny-only and credential files stay readable. Check 1 now
  evaluates the merged project, project-local and user settings,
  requires the home denyRead entry, and names the file each key came
  from.
- Check 7a treated bubblewrap's "No such file or directory" as a pass,
  which a missing file also prints. It now probes common credential
  paths with test -r and stat, never cat, and reports inconclusive
  until the user confirms from a terminal that one exists.
- Check 7b echoed AWS_ACCESS_KEY_ID, which the reference
  sandbox.credentials already unsets, wrapper or not. It now lists
  variable names only, flags credential-shaped ones, and reports an
  IDE CLAUDE_CODE_ENTRYPOINT as a warning, since such a session never
  went through claude-iso. The clean-env wrapper doc says so too.
- Checks 5, 10a and 13c compare against a framework checkout the skill
  never located. A pre-flight now finds it, and reports those
  comparisons as unchecked when there is none.
- Check 10 ran the touch-overlay sub-checks for any signed commit.
  They now apply only to a hardware key; 10c still applies to every
  ssh-format key.
- Sandbox /dev/null placeholders (character special 1,3) looked like
  empty untracked files. The verify and doctor skills now say how to
  recognise them and to take host state from git or the user.

The mirrored prompt in secure-agent-setup.md is kept in sync, and the
step-1-classify eval suite gains four cases for these verdicts.

Generated-by: Claude Code (Claude Opus 5.5)
Check 10 counted a key as hardware only for an sk- public key or an
OpenPGP-format card. ssh-format signing through gpg-agent uses the
card's aut slot and shows a plain ssh-ed25519 or ssh-rsa key, so a card
gpg --card-status finds now counts whatever gpg.format is.

Check 7a was inconclusive on every correctly secured host, because with
denyRead covering ~/ every path under it looks missing. It now proves
the denial with a sentinel: a file known to exist on the host, such as
the shell rc, that the sandbox cannot see. Inconclusive is left for the
case with no sentinel.

The step-1 output spec gains the inconclusive and unchecked verdicts
the skill now emits, with cases for both and a step-2 case for the
unchecked routing. The rest is review follow-up: managed settings in
check 1's merge, the opt-in question for flagged variable names, the
running claude-code version beside an unchecked check 5, the
credential-shaped wording of the no-print rule, the update prompt's
denial probes, and probe output attributed to stat in the fixtures.

Generated-by: Claude Code (Claude Opus 5.5)
With no framework checkout, the claude-code min_version floor could
not be compared and was reported unchecked, so a marketplace-only
install below the minimum passed. Report that floor as warn instead,
and route the re-run accordingly.

Under zsh on macOS, test -e on a denied sentinel still returns 0, so
the 7a sentinel uses test -r with the /dev/null placeholder exception.
A sentinel that stays readable and is not a placeholder now means
denyRead is not in effect (fail). A one-call test -r ~/.ssh/id_*
misreads as "not readable" with two or more matches (a key plus its
.pub is enough), and zsh errors out on no match, so keys are listed
with find -H (follows a symlinked ~/.ssh), which behaves the same in
bash and zsh.

A plugged-in smart card that does not hold the signing key made the
touch-overlay checks mandatory for software-key users. A card now
counts only when it holds the ssh-format signing key, an OpenPGP
signing-capable key (looked up by user.signingkey, else the committer
email), or the key a gpg-agent ssh remote authenticates with. A new
eval case covers a software signing key with an unrelated card.

7b gains more credential-name patterns, and the docs prompt matches
the skill.

Generated-by: Claude Code (Opus 5.5, Sonnet 5.5)
@shahar1
shahar1 force-pushed the fix/verify-skill-accuracy branch from 457e09f to f065e53 Compare October 26, 2026 05:47
@shahar1
shahar1 requested a review from potiuk October 26, 2026 16:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

capability:platform Framework / agent substrate skills (install, verify, doctor, override, status, setup bootstrap) capability:reassess Re-run historical issues against current code family:docs Docs, MISSION.md, READMEs family:setup setup-* skills family:tools tools/* substrate:framework-dev Tool substrate: build / validate / eval the framework itself

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants