Repository navigation
fix(bundles): reject non-positive preset and extension priorities in validation - #5012
Merged
mnriem merged 1 commit intoOct 19, 2026
Merged
Conversation
…validation `specify bundle validate` reported a manifest whose preset (or extension) reference declared `priority: 0` or a negative priority as well-formed and valid, and `specify bundle build` packaged it, yet every install of that bundle failed: the preset and extension managers refuse a priority below 1, and the bundle primitives pass the manifest priority through unchanged. Because components install in manifest order, the error only surfaced after earlier components (such as extensions) had been installed and rolled back, which left files like .specify/extensions/.registry behind while the command reported "No changes were recorded." BundleManifest.structural_errors() only checked that a preset priority was present. Also reject a priority below 1 on preset and extension references, so validate, build and install refuse the manifest before any component is touched. Assisted-by: Claude Code (model: Claude Opus 5.5, autonomous) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
🟢 Approval recommended
The focused validation guard matches installer constraints and has appropriate regression coverage, with no unresolved issues identified.
No open issues 🎉
What changed in this PR
Rejects non-positive preset and extension priorities during bundle validation, before component installation begins.
Changes:
- Adds a shared structural validation check for priorities below 1.
- Adds rejection, boundary-value, and early-install rejection tests.
Regression evidence is reported in the PR; tests were not rerun here.
| File | Description |
|---|---|
| tests/specify_cli/bundles/test_command_validate.py | Tests validation failure for priority zero. |
| tests/specify_cli/bundles/test_command_install.py | Checks rejection before installing extensions. |
| tests/contract/test_manifest_schema.py | Tests invalid priorities and acceptance of priority one. |
| src/specify_cli/bundles/manifest.py | Rejects preset and extension priorities below one. |
Review effort: Max
Collaborator
|
Thank you! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
specify bundle validateaccepts a bundle whose preset or extension declarespriority: 0(or a negative priority), andspecify bundle buildpackages it. Everyspecify bundle installof that bundle then fails, because the preset and extension managers refuse a priority below 1 and the bundle primitives pass the manifest priority through unchanged.Components install in manifest order, so the error only surfaces after earlier components have been installed and rolled back. With an extension listed before the preset (
extensions: [{id: git, version: 1.0.1}]), the failed install onmainleaves these behind, despite the "No changes were recorded." message:Root cause:
BundleManifest.structural_errors()inbundles/manifest.pyonly checks that a preset priority is present, not its range.The fix adds one check there: an extension or preset reference with a priority below 1 is a structural error.
validate,buildandinstalltherefore refuse the manifest before any component is touched:A valid bundle still validates. The leftover files from a mid-install rollback are a separate issue that this PR doesn't change; it only stops this manifest from getting that far.
Testing
uv run specify --helpuv sync && uv run pytestmainand on this branchNew tests:
tests/contract/test_manifest_schema.py:test_non_positive_priority_is_rejected, for preset 0, preset -3 and extension 0tests/contract/test_manifest_schema.py:test_priority_of_one_is_accepted, for presets and extensionstests/specify_cli/bundles/test_command_validate.py:test_validate_rejects_non_positive_preset_prioritytests/specify_cli/bundles/test_command_install.py:test_local_bundle_with_non_positive_priority_is_rejected_before_any_installOn
main, the 5 rejection cases fail and the 2 acceptance cases pass. All pass with the change; the three files give 109 passed.tests/contract,tests/specify_cli/bundles,tests/integration,tests/unit: 1440 passed.tests/test_*_python_parity.pyfiles occur identically on unmodifiedmainon this machine under full-suite load; those files pass when run on their own (257 passed, 112 skipped).uvx ruff@0.15.0 check src tests: cleanAI Disclosure
AI disclosure: Claude Code (model: Claude Opus 5.5, max reasoning effort, autonomous agent mode) opened this PR on behalf of @yxshee. A Claude Code subagent (same model, autonomous) found the bug and wrote the fix and tests. The lead agent independently re-ran the new tests against
mainand the branch, reproduced the transcripts above with the real CLI, reviewed the diff, and wrote this description. No human reviewed the change line by line before it was opened.🤖 Generated with Claude Code