Repository navigation
Pin the Validator's uvx ruff to a Dependabot-Managed Manifest - #3640
Conversation
The lint-only Python branch of validate-task.yml ran `uvx ruff@latest`, so a ruff release turned carriers red with no change of their own. A new python-tool-pins composite action reads the ruff version from the requirements.txt beside it, and the hub's dependabot.yml gains a pip pair watching that directory on main and develop. The action resolves through `$/` at the reusable workflow's own commit, so a carrier runs the version its hub pin carries rather than anything in its own tree. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The adoption doc and the python-codestyle skill still said the validator's uvx fallback, and the commands it backstops, ran ruff@latest. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The hub's pre-commit hook and OPERATIONS.md local block now run the ruff version the validator pins, so a local run still matches CI. The pins step reads its manifest without mapfile, which macOS's stock bash 3.2 lacks, and its test reuses step_script. The skill names the caller's hub pin as what ends the version skew. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars.
|
|
A recorded local strict-review pass covers head |
There was a problem hiding this comment.
🟡 Changes recommended
An active cross-platform test issue remains because the test uses a redundant bash check that can accept a non-runnable shim instead of the repository’s shared capability probe.
1 open issue
What changed in this PR
This pull request makes the validator’s fallback Ruff version reproducible through a Dependabot-managed composite-action manifest, while preserving project-local Ruff versions where applicable.
Changes:
- Adds the
python-tool-pinsaction withruff==0.17.3. - Updates validator workflows, local hooks, operations guidance, specifications, and documentation to use the managed pin.
- Adds Dependabot tracking and tests for manifest parsing, workflow behavior, and hook fixtures.
- Regenerates the relevant Python codestyle skill distributions.
- Review note:
tests/test_release_guards.pyhas a[P2]nit for a redundantshutil.which("bash")decorator; the test already uses the sharedbash_or_skip()probe.
| File | Summary |
|---|---|
tests/test_release_guards.py |
Tests Ruff pin resolution, manifest validation, Dependabot coverage, and validator command selection. |
tests/test_pre_commit_hook.py |
Includes the Ruff pin manifest in hook test fixtures. |
spec/project-types.json |
Updates the Python lint-only profile contract. |
OPERATIONS.md |
Uses the shared Ruff pin for local validation. |
docs/reusable-workflows.md |
Documents the validator’s pinned Ruff behavior. |
.husky/pre-commit |
Runs Ruff using the manifest pin. |
.github/workflows/validate-task.yml |
Reads the pin action output and applies it to fallback Ruff calls. |
.github/skills/python-codestyle/SKILL.md |
Documents CI pinning and local/CI Ruff version skew. |
.github/skills/python-codestyle/references/profiles.md |
Updates Python profile toolchain guidance. |
.github/dependabot.yml |
Tracks the pin manifest on main and develop. |
.github/actions/python-tool-pins/requirements.txt |
Defines the Dependabot-managed Ruff version. |
.github/actions/python-tool-pins/action.yml |
Validates and exports exactly one Ruff pin. |
.claude-plugin/fleet-skills/skills/python-codestyle/SKILL.md |
Regenerated Claude skill documentation. |
.claude-plugin/fleet-skills/skills/python-codestyle/references/profiles.md |
Regenerated Claude profile reference. |
.claude-plugin/fleet-skills/.source-digests/python-codestyle |
Updates the generated skill source digest. |
.agents/skills/python-codestyle/SKILL.md |
Updates the authored Python style guidance. |
.agents/skills/python-codestyle/references/profiles.md |
Updates the authored Python profile guidance. |
Review effort: Lite
run_tool_pins_step already calls bash_or_skip, the probe that is correct on Windows, so the shutil.which decorator only checked the wrong thing first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #3640 +/- ##
========================================
Coverage 81.69% 81.69%
========================================
Files 26 26
Lines 9111 9111
========================================
Hits 7443 7443
Misses 1668 1668
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
The hub's hook now runs the pinned ruff, so its Ruff Format and Ruff Check tasks resolve ruff with the pin manifest as a requirement to stay in step. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The hook and OPERATIONS.md block now pass the manifest to uvx with --with-requirements, as the VS Code tasks do, so only the action parses it. The spec and profile text scope the unpinned-latest local tools to carriers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
A recorded local strict-review pass covers head |
…Session Prompt Rules (#3667) Promotes the changes merged into `develop` since promotion #3636 to `main`. - [#3640](#3640) Pins the validator's `uvx ruff` to a Dependabot-managed manifest. - [#3642](#3642) Counts Copilot findings under the unresolved bullet and the file table. - [#3644](#3644) Aligns the split comment copies and drops the stale counts. - [#3646](#3646) Sends a command meant for the session's input line in a plain message, never in a blocking prompt. - [#3648](#3648) Opens the attended session by cloning a hub checkout of the session's own. - [#3650](#3650) Reads a held package as installed in both Linux host scripts. - [#3652](#3652) States the PowerShell `-Help` and `-h` form in the command-line argument rules. - [#3654](#3654) Counts sentences in Markdown table cells for the sentence-length check. - [#3658](#3658) Splits a table row only at an unescaped pipe in the semicolon rule. - [#3660](#3660) Finds table cell boundaries before blanking code spans and quotations. - [#3662](#3662) Names a stale job record on a completed run in `pr_review.py`. - [#3665](#3665) Keeps a line holding code after a block comment's closer out of `comment-added`. Its squash commit on `develop` carries the pull request's original title, which names a heredoc reading. That reading was withdrawn before the merge on decision #3666, so a workflow `run:` heredoc body still reads as code. - [#3669](#3669) Counts each `[Pn]` marker in a Copilot Findings cell, so a second finding in one cell is no longer dropped from triage. It answers one of the two findings Copilot raised on this promotion. The other is declined with a parser probe in its thread. Closes #3616 Closes #3610 Closes #3622 Closes #3638 Closes #3604 Closes #3511 Closes #3602 Closes #3456 Closes #3655 Closes #3657 Closes #3362 Closes #1664 🤖 Generated with [Claude Code](https://claude.com/claude-code)

Summary
Implements #3616 as the maintainer decided on it: a Dependabot-managed ruff pin with no fleet canary.
python-tool-pinscomposite action carriesrequirements.txtwithruff==0.17.3, the current PyPI release and the version the hub's own code already passes. Its one step reads that pin from$GITHUB_ACTION_PATHand fails, naming the file, unless exactly oneruff==<version>line is there. It does so withoutmapfile, so the test also runs under macOS's stock bash 3.2.validate-task.ymlreaches the action as$/.github/actions/python-tool-pins, so it resolves at the reusable workflow's own commit. A carrier calling the workflow at a hub pin therefore runs that pin's ruff rather than anything in its own tree. Both lint-onlyuvxcalls,ruff checkandruff format --check, now runuvx "ruff@$RUFF_VERSION". A declared pip directory whose venv installs ruff, and a uv directory, keep their own versions as before..github/dependabot.ymlgains apippair, main and develop, on/.github/actions/python-tool-pins, so the next ruff release opens a hub pull request. The hub's own CI calls the workflow locally, so that bump is linted against the hub's code before it merges. It then reaches carriers at a named hub release..husky/pre-commit, theOPERATIONS.mdlocal block, and its own.vscode/tasks.jsonruff tasks runuvx --with-requirements .github/actions/python-tool-pins/requirements.txt ruff .... That constrains ruff to the pin, so a local run here still matches CI. A probe with a manifest pinningruff==0.15.22resolved 0.15.22 that way.spec/project-types.jsonpython.scripts.uvx, the python-codestyle skill (SKILL.mdandreferences/profiles.md), anddocs/reusable-workflows.mdnow say CI's uvx ruff runs the hub's pin. mypy, pyright, and coverage still run@latest. A carrier's local tools (the catalog's VS Code and pre-commit snippets, the skill's local commands) still run ruff@latest, since ruff@latest in the Lint-Only Validator Turns Carriers Red on a Ruff Release With No Change of Their Own #3616 covers the validator only. The skill now names the skew that leaves, and says it ends when the caller's hub pin moves to a release carrying the new version.The change adds comment lines, so it carries the
commentslabel.Closes on promotion: #3616
Verification
tests/test_release_guards.pygainstest_tool_pins_read_exactly_one_ruff_pin. It runs the action's step against the hub's own manifest and against constructed manifests: one with a comment, no pin, a range, and two pins. It also gainstest_tool_pins_manifest_is_dependabot_tracked_on_both_branches. The existingtest_ruff_prefers_a_declared_pip_directory_venvnow expectsuvx ruff@<pin>.uvx ruff@0.17.3 check .andformat --check .are clean on the hub. mypy,repo_gate.py(composite-actions included),spec/validate.py,build_dist.py --check, actionlint, and the prose gate with--allow-commentsare clean too.local-strict-reviewpasses ran before each push.introducedfindings:docs/reusable-workflows.mdand the python-codestyleSKILL.mdstill described the fallback asruff@latest. Both are fixed in ee4ed5b.mapfileread under bash 3.2, a hand-rolledstep_script, the hub's hook andOPERATIONS.mdclaiming to match CI while running@latest, and the skill naming the wrong release as the end of the skew.skipUnless(shutil.which("bash"))decorator, which Copilot raised too. It is fixed in 853ba38.@latest, fixed in b248df8. The other was the spec and profile text then misdescribing the hub, plus the hook's andOPERATIONS.md's separate sed readers, fixed in 633642c.Declined findings
.github/actions/python-tool-pins/action.ymlread step,introduced, design: the finding says the multi-line half of the one-pin check guards a failure that is already loud, since a second unkeyed line in$GITHUB_OUTPUTfails the step. Declined. It is one more condition in theifthe empty-pin check needs anyway, and the finding itself says that check stays. Its error names the manifest and the expectedruff==<version>shape, which a runner refusal of a malformed output line does not. Thetwo pinssubtest oftest_tool_pins_read_exactly_one_ruff_pinpins that message. The finding's alternative,uvx --with-requirementsin the validator, would float silently to latest if the manifest lost its ruff line. So it would need the same presence check.🤖 Generated with Claude Code