Skip to content

pr-shepherd's model-resolution step relies on an undeclared PyYAML in the runner's system python #205

Description

@realmarcin

From the review of #194.

The "Resolve model from the fleet agent-config" step runs bare python3 with an inline script that does import yaml:

model=$(python3 -c "
import yaml, sys
cfg = yaml.safe_load(open('/tmp/agent-config.yaml'))
...
")

Nothing in the workflow installs PyYAML, and nothing pins which python3 this is. It works only if the ubuntu-latest image happens to ship PyYAML in its system Python — which it currently does, but that is an image detail, not a contract, and it changes between runner image releases.

This is the same shape as the matplotlib gap found in #190: a script that imports a package nothing declares, working only because one particular interpreter happened to have it. That one went unnoticed because gen-qc-dashboard was only ever run on a machine where Homebrew's Python had it installed.

Severity: low, and loud

If PyYAML disappears from the image the step fails immediately with an ImportError, and the job stops. That is the good failure mode — nothing silently proceeds with a wrong model, which the step's own comment is careful about:

Fails the job if the config cannot be read. A silent fallback to some default is how a repo ends up quietly running a model nobody chose.

So this is a portability and clarity issue rather than a correctness one.

Options

  1. Drop the Python dependency. The value being extracted is one scalar. yq is on the runner image, or a narrow grep/sed would do, though YAML-by-regex has its own failure modes.
  2. Install it explicitlypip install pyyaml in the step, or use astral-sh/setup-uv + uv run --with pyyaml python, matching how every other workflow in this repo resolves its interpreter (see Adopt the curation-history layer; make justfile recipes CI-portable #190, which moved four recipes off hardcoded/system Pythons for exactly this reason).
  3. Leave it and document the assumption in the step comment, so the next person knows it is a deliberate bet on the image.

(2) is most consistent with the rest of the repo.

Related

The same step fetches agent-config.yaml from culturebotai-claw@main unpinned over the network, so running this agent depends on that file being reachable and on whatever main says at the time. That is a deliberate centralisation choice, and the failure is loud, but it is the same availability coupling described in #197 for vendored-sync. Worth tracking as one pattern rather than three separate surprises.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions