You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@magpie.apache.org by "shahar1 (via GitHub)" <gi...@apache.org> on 2026/10/04 07:30:29 UTC
[PR] fix(agent-guard): re-exec under Python 3.11+ when python3 is older [magpie]
shahar1 opened a new pull request, #1507:
URL: https://github.com/apache/magpie/pull/1507
## 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
- [x] Python package (`tools/*/` with `pyproject.toml`) — `tools/agent-guard`
- [x] Documentation (`docs/`, `README.md`, `CONTRIBUTING.md`) — `tools/agent-guard/README.md`, `tools/spec-loop/specs/agent-isolation-sandbox.md`
- [x] Other: `isolated_fingerprint.py` regenerated by the `isolated-setup-fingerprint` prek hook (expected whenever `tools/agent-guard/src` changes)
## Test plan
- [x] `prek run --all-files` passes (including lychee, ruff, mypy, pytest, isolated-setup-fingerprint)
- [x] 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)
- [x] 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
- [x] **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.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@magpie.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] fix(agent-guard): re-exec under Python 3.11+ when python3 is older [magpie]
Posted by "potiuk (via GitHub)" <gi...@apache.org>.
potiuk merged PR #1507:
URL: https://github.com/apache/magpie/pull/1507
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@magpie.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] fix(agent-guard): re-exec under Python 3.11+ when python3 is older [magpie]
Posted by "potiuk (via GitHub)" <gi...@apache.org>.
potiuk commented on code in PR #1507:
URL: https://github.com/apache/magpie/pull/1507#discussion_r4179976215
##########
tools/agent-guard/src/agent_guard/__init__.py:
##########
@@ -1064,5 +1067,39 @@ def cli(argv: list[str] | None = None) -> int:
return main()
+_MIN_PYTHON = (3, 11)
+_REEXEC_VAR = "_AGENT_GUARD_REEXEC"
+
+
+def _reexec_under_supported_python() -> None:
+ """Re-run this script under a 3.11+ interpreter when ``python3`` is older.
+
+ Hooks invoke the engine as a bare ``python3``, which resolves through the
+ user's ``PATH`` — often an activated project virtualenv pinned to an older
+ Python. Look for a versioned ``python3.N`` instead of failing; when there is
+ none, exit 1 with an actionable message rather than an ImportError
+ traceback on every shell call.
+ """
+ if sys.version_info[:2] >= _MIN_PYTHON:
+ return
+ import shutil
+
+ if not os.environ.get(_REEXEC_VAR):
+ # ponytail: probes up to python3.20; raise the bound when that ships.
+ for minor in range(20, _MIN_PYTHON[1] - 1, -1):
+ interpreter = shutil.which(f"python3.{minor}")
+ if interpreter:
+ os.environ[_REEXEC_VAR] = "1"
Review Comment:
**minor** — The marker is set in `os.environ` before the `execv` and never cleared once the 3.11+ interpreter takes over, so it is inherited by everything the guard starts afterwards — most visibly the command `--exec` runs via `os.execvp`. Any nested guard run from that command under the old `python3` sees the marker, skips the interpreter search, and exits 1 with "no python3.11+ is on PATH", which isn't true. Reproduced at this head with `/usr/bin/python3` (3.9.6) and `python3.14` on `PATH`:
```
python3 agent_guard/__init__.py --exec bash -c 'python3 agent_guard/__init__.py --check ls'
# -> agent-guard: needs Python 3.11+ ... no python3.11+ is on PATH ... ; exit 1
```
This hits the documented `git` wrapper pattern whenever git re-invokes `git` (e.g. from a pre-commit hook). Clearing the marker once the re-exec succeeded fixes it:
```python
if sys.version_info[:2] >= _MIN_PYTHON:
os.environ.pop(_REEXEC_VAR, None)
return
```
Please add a test that sets the marker, runs `_reexec_under_supported_python()` on 3.11+, and asserts it is gone. Separately, the "already re-exec'd" branch should not print the "no python3.11+ is on PATH" text — there the re-exec'd interpreter was itself too old, and a distinct message would point users at the real cause.
##########
tools/agent-guard/src/agent_guard/__init__.py:
##########
@@ -1064,5 +1067,39 @@ def cli(argv: list[str] | None = None) -> int:
return main()
+_MIN_PYTHON = (3, 11)
+_REEXEC_VAR = "_AGENT_GUARD_REEXEC"
+
+
+def _reexec_under_supported_python() -> None:
+ """Re-run this script under a 3.11+ interpreter when ``python3`` is older.
+
+ Hooks invoke the engine as a bare ``python3``, which resolves through the
+ user's ``PATH`` — often an activated project virtualenv pinned to an older
+ Python. Look for a versioned ``python3.N`` instead of failing; when there is
+ none, exit 1 with an actionable message rather than an ImportError
+ traceback on every shell call.
+ """
+ if sys.version_info[:2] >= _MIN_PYTHON:
+ return
+ import shutil
+
+ if not os.environ.get(_REEXEC_VAR):
+ # ponytail: probes up to python3.20; raise the bound when that ships.
Review Comment:
**nit** — `ponytail:` isn't a comment tag used anywhere else in the repo, so readers won't know what it means. A plain `# Probes python3.20 down to python3.11; raise the upper bound when 3.21 ships.` says the same thing.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@magpie.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org