You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Reject symlinked extension registry storage by routing registry reads and writes through a deny-mode FileHelper rooted at the project, or its nearest existing ancestor for a new project. Validate the destination before file-change observers run, while retaining registry recovery, write semantics, and preset-resolution diagnostics.
Add regression coverage for linked registry files and parent directories, including dangling links, and document the registry filesystem boundary.
For the existing-tests checklist item, dependencies were installed with uv sync --extra test, and pytest used this worktree's interpreter as required by the contribution guidance rather than bare uv run pytest. No separate manual sample-project run was performed.
AI Disclosure
I did not use AI assistance for this contribution
I did use AI assistance (fill in the disclosure below)
AI disclosure: GitHub Copilot, powered by GPT-6.1 Sol (gpt-6.1-sol), performed the investigation, code and test generation, documentation changes, automated validation, and PR preparation in autonomous agent mode at the contributor's request. The reasoning-effort setting is not exposed to the agent; no human line-by-line review is claimed.
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
Registry policy failures can still allow disabled extension commands to run, while linked parent paths can bypass validation and several callers mishandle the new errors.
This PR hardens Specify CLI’s extension registry storage by moving registry I/O to a project-rooted, deny-mode FileHelper.
Changes:
Route registry reads and writes through the helper, validating destinations before file-change observers run.
Translate registry policy errors into preset-resolution diagnostics.
Add regression coverage for linked and missing storage, and document the filesystem boundary.
Full project tests were not rerun during this review.
AI review assistance: GitHub Copilot performed automated inspection and comment editing for the requesting contributor; contributor identity and model/settings were unavailable.
File
Description
tests/test_extensions.py
Tests linked-storage rejection, missing-storage creation, and observer sequencing.
tests/specify_cli/presets/test_resolver.py
Updates expectations for dangling registry links.
src/specify_cli/presets/_resolver.py
Wraps helper failures in preset-validation diagnostics.
src/specify_cli/extensions/__init__.py
Adds scoped registry I/O and write-destination preflight.
design/file-helper.md
Documents the registry’s always-deny boundary and preserved write semantics.
Updated in e42d18e: registry hierarchy validation now precedes missing-directory and leaf recovery; event resolution stops on forbidden registry state; artifact CLI/MCP and extension commands preserve their error formats; and dependency/configuration probes retain their non-fatal behavior. Regression coverage and the filesystem-boundary documentation were updated. Posted on behalf of @mnriem by GitHub Copilot (GPT-6.1 Sol, autonomous agent mode; reasoning-effort setting not exposed), which implemented the code, tests, and documentation and generated this reply.
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
The dispatcher can still execute extension handlers with live or dangling registry symlinks, and extension update leaves the new symlink-policy exception uncaught.
Updated in c671cc9: generated event dispatchers now reject linked registry storage and unsupported reparse points before importing an installed resolver or entering the inline fallback, with a diagnostic and exit status 2. Extension update now uses the shared CLI policy-error handler. Added coverage for no-package and stale-package execution, live and dangling links, reparse points, and both update invocation forms. Posted on behalf of @mnriem by GitHub Copilot (GPT-6.1 Sol, autonomous agent mode; reasoning-effort setting not exposed), which implemented the code, tests, and documentation and generated this reply.
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
With events enabled and only built-in integrations installed, linked extension storage can cause integration switching to fail after removing the old integration’s files and metadata, without rollback.
Validate registry before removing the current integration
src/specify_cli/extensions/__init__.py:777
For a project with only built-in integrations and events enabled, a linked extensions directory or .registry now makes integration switch fail after it has removed the old integration's files and metadata. resolve_events() runs before the handler's rollback block (integrations/command_switch.py:295-303), and the outer lifecycle skips its transaction when no external packages are recorded (integrations/_lifecycle.py:468-469), leaving the old integration removed. Validate registry storage before Phase 1 and add a switch regression test that checks files and metadata remain unchanged on rejection.
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
triage-must-haveVerdict: high-value, important work for Spec Kit — do first
2 participants
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
Reject symlinked extension registry storage by routing registry reads and writes through a deny-mode FileHelper rooted at the project, or its nearest existing ancestor for a new project. Validate the destination before file-change observers run, while retaining registry recovery, write semantics, and preset-resolution diagnostics.
Add regression coverage for linked registry files and parent directories, including dangling links, and document the registry filesystem boundary.
Testing
Tested locally with
uv run specify --helpRan existing tests with
uv sync && uv run pytestTested with a sample project (if applicable)
uv sync --extra test— passed.uv run specify --help— passed.LC_ALL=en_US.UTF-8 .venv/bin/python -m pytest tests -q— passed: 13,677 passed, 130 skipped.For the existing-tests checklist item, dependencies were installed with
uv sync --extra test, and pytest used this worktree's interpreter as required by the contribution guidance rather than bareuv run pytest. No separate manual sample-project run was performed.AI Disclosure
AI disclosure: GitHub Copilot, powered by GPT-6.1 Sol (
gpt-6.1-sol), performed the investigation, code and test generation, documentation changes, automated validation, and PR preparation in autonomous agent mode at the contributor's request. The reasoning-effort setting is not exposed to the agent; no human line-by-line review is claimed.