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
{{ message }}
Repository navigation
fix: contain persisted feature paths and protect plan creation - #5178
Constrain feature paths loaded from .specify/feature.json to the project after resolving symbolic links and parent-directory components. External feature directories remain supported through an explicit SPECIFY_FEATURE_DIRECTORY override on every invocation.
Apply the same policy across Python, Bash, and PowerShell. Plan setup rejects symbolic-link destinations and creates new plans exclusively while preserving existing regular files. Update the shared reference and add cross-port regression coverage.
Testing
Tested locally with uv run specify --help
Ran existing tests with uv sync && uv run pytest
Tested with a sample project (if applicable)
The full suite used this worktree's own interpreter, as recommended by CONTRIBUTING.md, instead of the literal generic uv run pytest command above.
Sample-project coverage is automated through temporary project fixtures for Python, Bash, and the available PowerShell runtime. Windows PowerShell 5.1 cases are explicitly included but skipped on this macOS host; Windows PowerShell 5.1 runtime verification remains outstanding. No manual agent-driven process test is claimed.
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), autonomously generated the implementation, tests, documentation, commit, and PR body on behalf of @mnriem, following the user's approved path policy. Work occurred in an interactive session; reasoning effort was not explicitly specified. The initial read-only assessment used a security-review subagent whose model was not reported. Validation was automated; no human line-by-line review or manual testing is claimed.
Require stored feature directories to resolve within the project while retaining explicit external overrides. Reject linked plan destinations and create new plans exclusively across all three script ports.
Assisted-by: GitHub Copilot (model: GPT-6.1 Sol, autonomous)
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
A Windows parity assertion fails when directory symlink creation succeeds, while FIFO handling and PowerShell link-resolution defects can block execution or misdirect paths.
Hardens Spec Kit’s shared feature-path resolution and plan setup across Python, Bash, and PowerShell.
Changes:
Restricts persisted feature paths to the project after resolving symbolic links and parent components; external paths require an explicit override on each invocation.
Adds plan-destination link checks and exclusive-create handling while preserving existing regular plans.
Documents the policy and expands cross-port regression coverage.
File
Description
tests/test_setup_plan_python_parity.py
Adds containment, symlink, override, and Windows PowerShell cases.
scripts/python/setup_plan.py
Rejects plan symlinks and uses exclusive file creation.
scripts/python/common.py
Resolves and validates persisted feature-path containment.
scripts/powershell/setup-plan.ps1
Checks destination links and creates plans with CreateNew.
scripts/powershell/common.ps1
Adds component-wise path resolution and containment checks.
scripts/bash/setup-plan.sh
Adds symlink rejection and noclobber-based creation.
scripts/bash/common.sh
Resolves persisted paths and checks the project boundary.
docs/reference/core.md
Documents containment, external overrides, and plan protection.
Publish Bash plans without opening existing destinations. Bound total PowerShell link traversals, preserve non-link reparse directories, and use platform-correct name matching. Correct Windows path assertions and propagate strict Python resolution failures with regression coverage.
Assisted-by: GitHub Copilot (model: GPT-6.1 Sol, autonomous)
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Fixed in 10b557989ca821d0794e87b21e4cec24feaa4938: Bash now publishes completed plans atomically without opening existing destinations; PowerShell shares one 40-traversal budget, uses platform-correct name matching, and permits non-redirecting reparse directories while still validating links. The Windows-specific path assertion is corrected, and Python now propagates strict-resolution errors to fix the additional Windows link-loop failure. Added before-and-after regressions, including FIFO handling, exact traversal limits, and reparse-directory classification. The affected local suites passed (370 passed, 79 skipped), and all upstream checks passed, including all six full-suite matrix jobs and the Windows PowerShell 5.1 cases. On behalf of @mnriem, GitHub Copilot using GPT-6.1 Sol (gpt-6.1-sol) autonomously generated these code, test, documentation, and comment changes in an interactive session; reasoning effort was not explicitly specified. No human line-by-line review or manual testing is claimed.
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
A critical mixed-separator path handling flaw can bypass PowerShell containment checks, allowing plan setup to write outside the project without an override.
Both readlink here and dirname at line 175 lose trailing newlines through command substitution. A valid path under a directory named feature\n then resolves to feature, causing setup to write the plan in a different directory. Preserve the target bytes when capturing readlink and remove parent components with parameter expansion.
AI-generated review for the requester: GitHub Copilot; model/reasoning settings unavailable; autonomous analysis and suggested fixes.
Allow non-redirecting cloud-backed plan files
scripts/powershell/setup-plan.ps1:47
An existing OneDrive/Cloud Files plan.md can have the ReparsePoint attribute without being a symbolic link. This blanket check rejects those regular plans instead of preserving them, even though the new directory resolver explicitly accommodates non-redirecting cloud placeholders. Distinguish redirecting links from cloud-backed files here too, and cover an existing cloud-backed plan in the preservation tests.
AI-generated review for the requester: GitHub Copilot; model/reasoning settings unavailable; autonomous analysis and suggested fixes.
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
Constrain feature paths loaded from
.specify/feature.jsonto the project after resolving symbolic links and parent-directory components. External feature directories remain supported through an explicitSPECIFY_FEATURE_DIRECTORYoverride on every invocation.Apply the same policy across Python, Bash, and PowerShell. Plan setup rejects symbolic-link destinations and creates new plans exclusively while preserving existing regular files. Update the shared reference and add cross-port regression coverage.
Testing
uv run specify --helpuv sync && uv run pytestThe full suite used this worktree's own interpreter, as recommended by CONTRIBUTING.md, instead of the literal generic
uv run pytestcommand above.LC_ALL=en_US.UTF-8 .venv/bin/python -m pytest tests -q -n 4- passed: 13,712 passed, 167 skipped, 63 warnings.uvx ruff@0.15.0 check src tests- passed.uv run specify --help- passed.git diff --check- passed.Sample-project coverage is automated through temporary project fixtures for Python, Bash, and the available PowerShell runtime. Windows PowerShell 5.1 cases are explicitly included but skipped on this macOS host; Windows PowerShell 5.1 runtime verification remains outstanding. No manual agent-driven process test is claimed.
AI Disclosure
AI disclosure: GitHub Copilot, powered by GPT-6.1 Sol (
gpt-6.1-sol), autonomously generated the implementation, tests, documentation, commit, and PR body on behalf of @mnriem, following the user's approved path policy. Work occurred in an interactive session; reasoning effort was not explicitly specified. The initial read-only assessment used a security-review subagent whose model was not reported. Validation was automated; no human line-by-line review or manual testing is claimed.