Skip to content

A tend dispatch cannot run gardener's own documented test command: the PYTHONPATH= prefix form is denied #112

Description

@dmccoystephenson

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions