Skip to content

fix(agent-guard): re-exec under Python 3.11+ when python3 is older - #1507

Open
shahar1 wants to merge 1 commit into
apache:mainfrom
shahar1:fix-agent-guard-python-interpreter
Open

shahar1 wants to merge 1 commit into
apache:mainfrom
shahar1:fix-agent-guard-python-interpreter

Conversation

@shahar1

@shahar1 shahar1 commented Oct 4, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • The magpie-agent-guard PreToolUse hook runs the engine as a bare python3. When that resolves to a pre-3.11 interpreter — typically an activated project virtualenv, e.g. Apache Airflow's .venv on 3.10 — the module-level import tomllib fails with ModuleNotFoundError on every Bash call: a traceback in the UI each time, and the guard silently never runs.
  • The engine now imports on 3.10 (tomllib is imported where it is used) and, when running under <3.11, re-execs itself under the newest python3.N (3.11+) found on PATH. When none exists it exits 1 with one actionable line instead of a traceback. The check runs before cli() dispatches, so every harness adapter (Claude Code, OpenCode, Gemini, Kiro, --check, --exec) benefits.
  • Kept within the engine's design constraints: stdlib-only, bare python3, never uv run.

Type of change

  • Python package (tools/*/ with pyproject.toml) — tools/agent-guard
  • Documentation (docs/, README.md, CONTRIBUTING.md) — tools/agent-guard/README.md, tools/spec-loop/specs/agent-isolation-sandbox.md
  • Other: isolated_fingerprint.py regenerated by the isolated-setup-fingerprint prek hook (expected whenever tools/agent-guard/src changes)

Test plan

  • prek run --all-files passes (including lychee, ruff, mypy, pytest, isolated-setup-fingerprint)
  • For Python packages touched: uv run pytest / ruff check / mypy passes — 4 new tests in tests/test_python_version.py (no-op on 3.11+, re-exec picks the newest interpreter, no interpreter found, re-exec marker already set)
  • Other: reproduced end-to-end with a Python 3.10 python3: with python3.13 on PATH the Co-Authored-By deny fires and --check still exits 2; with no newer interpreter on PATH it prints agent-guard: needs Python 3.11+ ... and exits 1

RFC-AI-0004 compliance

  • Sandbox — no new host access; the only new system call is os.execv of an interpreter already on PATH

Linked issues

None found — the symptom was observed on an Apache Airflow adopter machine (53 sessions since the plugin was installed on 2026-09-28).

Notes for reviewers (optional)

  • Considered and rejected: changing the hook command to uv run --python '>=3.11' — the engine's documented contract is stdlib-only and never via uv, so the hook stays fast and needs no environment.
  • The re-exec probes python3.20 down to python3.11; the upper bound is a ponytail: comment to raise when needed.
  • .last-sync was not bumped: it is 27 commits behind main and this PR only updates the one spec paragraph it touches.

Generated-by: Claude Code (Fable 5.1). AI-assisted; reviewed and submitted by a human.

Hooks invoke the guard engine as a bare `python3`, which resolves through
the user's PATH. With an activated project virtualenv on Python 3.10 (a
common adopter setup, e.g. Apache Airflow) the module-level
`import tomllib` raised ModuleNotFoundError on every Bash call: a
traceback in the UI each time, and the guard silently never ran.

The engine now imports on 3.10 (tomllib is imported where it is used)
and, when the interpreter is older than 3.11, re-runs itself under the
newest `python3.N` (3.11+) on PATH. When none exists it exits 1 with one
actionable line instead of a traceback. Every harness adapter benefits,
since the check runs before `cli()` dispatches.

Generated-by: Claude Code (Fable 5.1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

substrate:action-guard Tool substrate: deterministic pre-tool-use command guards

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant