Repository navigation
Add a sandbox-test skill for agents testing parser changes - #133
Merged
Merged
Conversation
The sandbox workflow added in apache#127 gives us a way to run a parser change against a real repository, but it does not say what to run. Testing seven open pull requests through it turned up a procedure worth writing down, and three bugs that a naive "does it turn on?" run would have missed. The skill covers choosing a sandbox (your own fork, or the Apache one if you are a committer), the token permissions each feature needs, the preflight a branch must pass before it can be dispatched at all, and a set/update/unset test matrix to build instead of a single happy-path run. It then covers resetting the sandbox, proposing a review comment for a human to approve, and proposing a disposition -- including the conditions under which merging is appropriate. Three things in it were learned the expensive way: A green run is not a result. A directive can print "Setting X", exit 0, and have changed nothing on GitHub; that is what a broken state check looks like from the outside. Every claim has to trace to an API read after the run. `github:` directives only run when the branch being processed is the repository's default branch, so the `test/pr-<NNN>` sandbox branch that docs/testing-a-change.md suggests makes every one of them a silent no-op. The config has to go on the sandbox's main. `previous_yaml` is read from a cache that exists only in production, so any directive branch guarded by "was this key set before?" cannot be exercised in a sandbox or in CI. That same guard shape is also a recurring bug: an explicit `false` that cannot turn off a setting which is currently on. Wired into AGENTS.md and docs/testing-a-change.md so it is discoverable from both the agent and human entry points. Generated-by: Claude Opus 5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds
.claude/skills/sandbox-test/SKILL.md, a procedure for coding agents (and areadable checklist for humans) around the sandbox workflow from #127, plus pointers to
it from
AGENTS.mdanddocs/testing-a-change.md.#127 gave us the machinery to run a parser change against a real repository. It does not
say what to run, and the difference turns out to matter: a single happy-path
"does it turn on?" dispatch passes on code that does nothing at all.
Why now
I put seven open PRs through the workflow this week. The runs found three bugs, and every
one of them would have been missed by a happy-path run:
immutable_releases: truenever enables anything. The state check reads theHTTP status (
200assumed to mean "enabled"), but that endpoint returns200in bothstates with
enabledin the body. The run logs "are currently enabled" against a reporeporting
{"enabled": false}, exits 0, and changes nothing. The same fault makes theabsent-key path issue a
DELETEagainst every repository on every apply.code_scanning: false/creation_cap: {enabled: false}cannotturn off a setting that is on, because of a guard that returns before the API call when
the previous-config cache is cold. Only the unset row of a test matrix finds this;
the enable path works perfectly.
prevent_self_review) and silently strips thecontrol on a fallback path. Visible only by running the same config against patched and
unpatched parsers and diffing the result.
Three findings, all in the edges: unset, update, and "leave alone what you do not manage".
What the skill says
apache/...if you are a committer — and thetoken permission each feature area needs. A 403 here is usually the token's repository
access list, not its permission level, which cost me a round trip to work out.
predates the
--branchflag that Add a workflow for testing parser changes against a sandbox repo #127 added toasfyaml-run, so every one of them dieswith
unrecognized arguments: --branchuntil it is rebased. Worth knowing before youdispatch.
rule that a test whose pass state equals its start state proves nothing.
github:directives only runwhen the processed branch is the repository's default branch, so the
test/pr-<NNN>sandbox branch this repo's own docs suggest turns all of them into no-ops while the run
stays green. And
previous_yamlcomes from a cache that exists only in production, soremoval paths cannot be exercised here at all — better to say so than to imply coverage.
That is how I established that feat(github): add merge_queue convenience syntax for rulesets #119's merge queue rejection is GitHub refusing the rule
type on a user-owned repo, not a bad payload — the same hand-written request fails
identically.
and let the human decide; merge only on explicit approval, with permission, after
confirming the tested SHA is still the PR head.
Testing
Documentation only — no parser code changes.
poetry run pytest(145 passed) andpoetry run pre-commit run --all-filesare green. TheCLAUDE.md/GEMINI.mdsymlinksto
AGENTS.mdare untouched.The procedure itself is the tested artefact: it is the written-down form of the runs
linked from #81, #84, #101, #111, #116, #119, #120 and #122.
Worth a maintainer's view
The
.claude/skills/location is the convention Claude Code looks for. If you wouldrather this lived somewhere tool-neutral —
docs/, with a pointer from.claude/— sayso and I will move it.
🤖 Generated with Claude Code