Skip to content

v0.1.0 is a movable tag in an unprotected repo, and four repos pin it #15

Description

@mairas

Found independently by the adversarial and security reviewers on hatlabs/halpi2#49, and reproduced by both.

Four repositories now pin halos-docs-tools @ git+https://github.com/halos-org/docs-tools@v0.1.0. That names an ordinary annotated tag in a repository with no branch protection and no rulesets (gh api repos/halos-org/docs-tools/rulesets[]), so nothing stops the tag being force-moved or deleted. By contrast halos-org/shared-workflows already carries a "Protect main branch" ruleset with enforce_admins.

uv sync --locked holds — reproduced on a cold cache with a git package tagged v0.1.0 at commit A, the tag then force-moved to commit B: --locked still installed A. The lock is doing that work, not the tag.

Two ways it stops holding:

  • Re-resolution. uv lock --upgrade, a pin bump, or a dependency bot re-reads the tag and adopts whatever it points at. Reproduced: the lock changed to ?rev=v0.1.0#<commit B> — same rev string, different content, no other diff. The entire visible evidence of a checker behaviour change is 40 hex characters in a lock fragment, and these checkers decide whether merges are allowed in four repositories.
  • Deletion. If the tag goes and the commit is orphaned, uv sync --locked fails in all four consumers at once, plus every developer clone.

Fix: add a tag-protection ruleset covering v* — block deletion and non-fast-forward — matching what shared-workflows has on its default branch. Then re-cut v0.1.1 for any fix rather than moving v0.1.0, and say so next to the release instructions in AGENTS.md.

Optionally also name the commit in each consumer's pyproject.toml (...docs-tools@7f09d05...) so the reviewed artifact and the lock agree without depending on tag discipline. The tag then serves as documentation.

Related: #14 covers the other half of the version story — the shared workflow floats on @main while the CLI it calls is pinned, and neither side records which versions are compatible.

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