Summary
CLAUDE.md, docs/TESTING.md and .github/workflows/ci.yml all name one
command as this repo's test anchor:
PYTHONPATH=. python3 -m unittest discover -s tests -v
Inside a gardener tend dispatch against this repo, that exact command is
refused with This command requires approval and never executes. The
refusal is reproducible and appears to key on the leading
environment-variable assignment rather than on the program being run —
observed during the dispatch that produced PR #111:
| Command |
Result |
PYTHONPATH=. python3 -m unittest discover -s tests -v |
denied — requires approval |
PYTHONPATH=. python3 -m compileall -q gardener tests |
denied — requires approval |
python3 -m unittest discover -s tests -t . -v |
ran |
python3 with an inline -c script |
ran |
python3 --version |
ran |
python3.10 --version |
denied — requires approval |
So python3 itself is permitted; prefixing an invocation with a
VAR=value assignment is what is refused, and a non-default interpreter
name is refused separately.
Why it matters
A headless dispatch has no human to approve anything, so a denial here is
not a prompt — it is the anchor silently becoming unavailable for the whole
run. The dev-loop skill's Phase 4 requires the anchor to be green before a
PR may be reviewed or merged, and its documented fallback for an unrunnable
anchor is to mark the PR UNVERIFIED and hand it to a human. The
practical effect is that every tend of this repo is one step away from
reporting correct, tested work as unvalidated.
It is also self-affecting in a way worth stating plainly: gardener is the
tool dispatching the run, this repo is a member of its own garden, and the
command being refused is the one gardener's own contributor documentation
instructs a contributor to run.
The workaround used in PR #111 was an inline script that inserts . into
sys.path and drives unittest through importlib. That works, but it is
not the documented command, it does not exercise unittest discover, and
nothing about it is discoverable from the docs — a future run has to
rediscover it.
Notes on scope
Whether the right fix belongs in dispatch.py's tend_mode_spec()
allowed-tools scoping, or in how a Bash command string is matched against
that scope, has not been established here — the observation above is what
was actually seen, and CLAUDE.md is explicit that claims about the
claude CLI's behaviour must be confirmed against a real invocation rather
than assumed. Confirming the mechanism before changing anything is the
suggested first step.
Two adjacent questions worth answering in the same investigation:
- Whether other prefixed forms in common use across the garden (
CI=1,
NODE_ENV=test, MAVEN_OPTS=...) are refused the same way, which would
make this a garden-wide dispatch limitation rather than a Python-specific
one.
- Whether a denial of this kind is visible in the run's recorded
permission_denials, since CLAUDE.md's manual-verification steps ask
for that field to be checked after a tend.
This issue was filed during a Gardener session (https://github.com/Stephenson-Software/gardener).
drafted by Claude on behalf of Daniel Stephenson
Summary
CLAUDE.md,docs/TESTING.mdand.github/workflows/ci.ymlall name onecommand as this repo's test anchor:
Inside a
gardener tenddispatch against this repo, that exact command isrefused with
This command requires approvaland never executes. Therefusal is reproducible and appears to key on the leading
environment-variable assignment rather than on the program being run —
observed during the dispatch that produced PR #111:
PYTHONPATH=. python3 -m unittest discover -s tests -vPYTHONPATH=. python3 -m compileall -q gardener testspython3 -m unittest discover -s tests -t . -vpython3with an inline-cscriptpython3 --versionpython3.10 --versionSo
python3itself is permitted; prefixing an invocation with aVAR=valueassignment is what is refused, and a non-default interpretername is refused separately.
Why it matters
A headless dispatch has no human to approve anything, so a denial here is
not a prompt — it is the anchor silently becoming unavailable for the whole
run. The dev-loop skill's Phase 4 requires the anchor to be green before a
PR may be reviewed or merged, and its documented fallback for an unrunnable
anchor is to mark the PR UNVERIFIED and hand it to a human. The
practical effect is that every
tendof this repo is one step away fromreporting correct, tested work as unvalidated.
It is also self-affecting in a way worth stating plainly: gardener is the
tool dispatching the run, this repo is a member of its own garden, and the
command being refused is the one gardener's own contributor documentation
instructs a contributor to run.
The workaround used in PR #111 was an inline script that inserts
.intosys.pathand drivesunittestthroughimportlib. That works, but it isnot the documented command, it does not exercise
unittest discover, andnothing about it is discoverable from the docs — a future run has to
rediscover it.
Notes on scope
Whether the right fix belongs in
dispatch.py'stend_mode_spec()allowed-tools scoping, or in how a
Bashcommand string is matched againstthat scope, has not been established here — the observation above is what
was actually seen, and
CLAUDE.mdis explicit that claims about theclaudeCLI's behaviour must be confirmed against a real invocation ratherthan assumed. Confirming the mechanism before changing anything is the
suggested first step.
Two adjacent questions worth answering in the same investigation:
CI=1,NODE_ENV=test,MAVEN_OPTS=...) are refused the same way, which wouldmake this a garden-wide dispatch limitation rather than a Python-specific
one.
permission_denials, sinceCLAUDE.md's manual-verification steps askfor that field to be checked after a
tend.This issue was filed during a Gardener session (https://github.com/Stephenson-Software/gardener).
drafted by Claude on behalf of Daniel Stephenson