Pin the agent Git attribution interpreter off the pyenv shim #823

Closed
opened 2026-08-14 05:04:13 +00:00 by coilyco-ops · 0 comments
Owner

🤖 Filed by Claude Code on Kai's behalf.

Problem

agent_git_attribution.py is deployed to ~/.local/share/agent-git-attribution/ and symlinked as git on PATH, then executed directly. Its shebang is therefore the interpreter selection, and it runs once per agent Git call.

The shebang is #!/usr/bin/env python3, which on a host with pyenv resolves to ~/.pyenv/shims/python3. Shim resolution dominates the run.

Measured on kais-macbook-pro, ten runs each:

shebang per call
/usr/bin/env python3 258ms
/usr/bin/python3 67ms

Roughly 190ms of pure overhead on every agent Git call, paid to resolve an interpreter the fleet has already standardized on elsewhere.

History

This was diagnosed on 2026-08-12 on branch aos/claude/git-attribution-pin-interpreter and left as an uncommitted git stash entry. The branch carries no commits and is now 13 behind main, so the stash is the entire body of work. There is no issue for it. This issue adopts that work so it stops living in a stash.

Change

Take the stashed shebang pin, plus a guard the original did not have.

The role assumes /usr/bin/python3 exists but never states it. That assumption holds today because ansible/inventory/fleet.yml and ansible/inventory/local.yml both pin ansible_python_interpreter: /usr/bin/python3, so Ansible itself runs under that interpreter on every host this role reaches. The assumption breaks if a host overrides the interpreter, and the failure mode is bad out of proportion to the cause: the shim is git, so a missing interpreter breaks Git for agents on that host.

Add an assertion before the script is installed, so a host that cannot satisfy the pin fails the converge loudly and keeps its existing working Git rather than receiving a shim that cannot execute.

A silent fallback to env python3 was considered and rejected. It would restore the 190ms with no signal that the pin had not applied. A converge-time failure is the safer shape for something on the Git hot path.

Resolving the shebang from ansible_python_interpreter at converge time was also considered. It is the cleaner design, but it requires converting files/agent_git_attribution.py into a template, and scripts/agent_git_attribution_test.py imports that exact path through importlib. That is a larger change to adjacent code and is left for a follow-up.

Scope

The role reaches non-server hosts only, through the claude-hooks and codex-hooks dependencies gated on hostclass_server not in group_names. That is the Mac and the WSL towers. kai-server and ser8 are excluded. Native Windows is not converged yet and stays blocked on #356.

Verification

  • Compiles clean under Apple's /usr/bin/python3, which is 3.9.6.
  • Imports are stdlib only, from __future__ import annotations is present, and nothing evaluates annotations at runtime.
  • Identical CLI behavior under 3.9.6 and pyenv 3.13.2.
  • ward exec ansible-lint and ward exec pre-commit.

Known gap: scripts/agent_git_attribution_test.py does not complete under either 3.9.6 or 3.13.2 in an agent session, hanging past 45 seconds in both. That predates this change and is interpreter-independent, so it is not evidence about the pin, but it does mean the suite did not gate this work.

Note

Apple's /usr/bin/python3 is 3.9.6, which is end of life upstream. It runs this script correctly today. Moving the pin to a maintained interpreter is a separate question from getting off the pyenv shim.

🤖 Filed by Claude Code on Kai's behalf.

> 🤖 Filed by Claude Code on Kai's behalf. ## Problem `agent_git_attribution.py` is deployed to `~/.local/share/agent-git-attribution/` and symlinked as `git` on PATH, then executed directly. Its shebang is therefore the interpreter selection, and it runs once per agent Git call. The shebang is `#!/usr/bin/env python3`, which on a host with pyenv resolves to `~/.pyenv/shims/python3`. Shim resolution dominates the run. Measured on kais-macbook-pro, ten runs each: | shebang | per call | | --- | --- | | `/usr/bin/env python3` | 258ms | | `/usr/bin/python3` | 67ms | Roughly 190ms of pure overhead on every agent Git call, paid to resolve an interpreter the fleet has already standardized on elsewhere. ## History This was diagnosed on 2026-08-12 on branch `aos/claude/git-attribution-pin-interpreter` and left as an uncommitted `git stash` entry. The branch carries no commits and is now 13 behind `main`, so the stash is the entire body of work. There is no issue for it. This issue adopts that work so it stops living in a stash. ## Change Take the stashed shebang pin, plus a guard the original did not have. The role assumes `/usr/bin/python3` exists but never states it. That assumption holds today because `ansible/inventory/fleet.yml` and `ansible/inventory/local.yml` both pin `ansible_python_interpreter: /usr/bin/python3`, so Ansible itself runs under that interpreter on every host this role reaches. The assumption breaks if a host overrides the interpreter, and the failure mode is bad out of proportion to the cause: the shim is `git`, so a missing interpreter breaks Git for agents on that host. Add an assertion before the script is installed, so a host that cannot satisfy the pin fails the converge loudly and keeps its existing working Git rather than receiving a shim that cannot execute. A silent fallback to `env python3` was considered and rejected. It would restore the 190ms with no signal that the pin had not applied. A converge-time failure is the safer shape for something on the Git hot path. Resolving the shebang from `ansible_python_interpreter` at converge time was also considered. It is the cleaner design, but it requires converting `files/agent_git_attribution.py` into a template, and `scripts/agent_git_attribution_test.py` imports that exact path through `importlib`. That is a larger change to adjacent code and is left for a follow-up. ## Scope The role reaches non-server hosts only, through the `claude-hooks` and `codex-hooks` dependencies gated on `hostclass_server not in group_names`. That is the Mac and the WSL towers. `kai-server` and `ser8` are excluded. Native Windows is not converged yet and stays blocked on #356. ## Verification * Compiles clean under Apple's `/usr/bin/python3`, which is 3.9.6. * Imports are stdlib only, `from __future__ import annotations` is present, and nothing evaluates annotations at runtime. * Identical CLI behavior under 3.9.6 and pyenv 3.13.2. * `ward exec ansible-lint` and `ward exec pre-commit`. Known gap: `scripts/agent_git_attribution_test.py` does not complete under either 3.9.6 or 3.13.2 in an agent session, hanging past 45 seconds in both. That predates this change and is interpreter-independent, so it is not evidence about the pin, but it does mean the suite did not gate this work. ## Note Apple's `/usr/bin/python3` is 3.9.6, which is end of life upstream. It runs this script correctly today. Moving the pin to a maintained interpreter is a separate question from getting off the pyenv shim. > 🤖 Filed by Claude Code on Kai's behalf.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
coilyco-flight-deck/infrastructure#823
No description provided.