fix: auto-correct prefix conflicts in create-new-feature scripts#1829
fix: auto-correct prefix conflicts in create-new-feature scripts#1829daniel-graham wants to merge 1 commit intogithub:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Updates the feature creation Bash script to prevent duplicate spec-directory prefixes when --number is provided and conflicts with an existing specs/NNN-* directory, by auto-correcting to the next available global number.
Changes:
- Added a guardrail that detects existing
specs/${FEATURE_NUM}-*directories and recomputes the feature number from the global maximum across specs and git branches. - Emits a warning to stderr when auto-correction occurs.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
mnriem
left a comment
There was a problem hiding this comment.
Thanks for tackling this — the problem is real and the guardrail idea is the right direction. Before we can merge, there are a few things we need to address: the --number flag's contract changes from a hard override to a suggestion, which is a silent breaking change for any automation relying on deterministic output; the recalculation path skips git fetch so the corrected number could still collide with unfetched remote branches; the check only covers spec directories but not existing branches, leaving an inconsistent experience; the help text still says "overrides auto-detection"; and the PowerShell script doesn't get the same guardrail, breaking cross-platform parity. Could you scope the guardrail to only fire when --number was explicitly passed, add a fetch before recalculating, extend the collision check to branches, update the help text, and port it to the PowerShell side as well?
There was a problem hiding this comment.
Pull request overview
Adds a guardrail to feature creation scripts so an explicitly requested feature number (--number / -Number) is treated as a validated suggestion and auto-corrected when its NNN- prefix already exists, preventing duplicate spec directories/branch prefixes that break downstream workflows.
Changes:
- Add “explicit number” tracking and a conflict check that recalculates the next available number when a requested prefix already exists.
- Update help text to clarify that
--number/-Numberis preferred and may be auto-corrected.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| scripts/bash/create-new-feature.sh | Adds an explicit---number guardrail that detects existing NNN- prefixes and recalculates from global max. |
| scripts/powershell/create-new-feature.ps1 | Mirrors the guardrail behavior in PowerShell and updates CLI help text accordingly. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Changes made in response to reviewThanks for the thorough review @mnriem! All feedback addressed across 3 follow-up commits: @mnriem review (requested changes)
@copilot review (suggestions)
Also fixed
All changes validated on macOS with both Bash and PowerShell (
|
There was a problem hiding this comment.
Pull request overview
Adds guardrails to the “create new feature” scripts so an explicitly suggested feature number won’t silently collide with existing specs/NNN-* directories or existing branch prefixes, preventing downstream prefix-ambiguity errors.
Changes:
- Add prefix-conflict detection and auto-correction when
--number/-Numberis explicitly provided. - Update CLI help text to describe
--number/-Numberas a preferred (validated) number rather than a hard override. - Fix/adjust the
specify.mdcommand template validation step reference (proceed to step 7).
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| templates/commands/specify.md | Updates the command template’s instructions/step reference and removes an unused header. |
| scripts/powershell/create-new-feature.ps1 | Adds -Number explicit-tracking and a guardrail to auto-correct number conflicts; updates help text. |
| scripts/bash/create-new-feature.sh | Adds --number explicit-tracking and a guardrail to auto-correct number conflicts; updates help text. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
scripts/bash/create-new-feature.sh
Outdated
| # Check for conflict in spec directories | ||
| SPEC_CONFLICT=false | ||
| if compgen -G "$SPECS_DIR/${FEATURE_NUM}-*" > /dev/null 2>&1; then | ||
| SPEC_CONFLICT=true | ||
| fi |
|
|
||
| - **If all items pass**: Mark checklist complete and proceed to step 6 | ||
| - **If all items pass**: Mark checklist complete and proceed to step 7 | ||
|
|
mnriem
left a comment
There was a problem hiding this comment.
Please pull in latest from main and address Copilot feedback. If not applicable, please explain why.
ebbfc54 to
f6dbbe2
Compare
Follow-up: rebased on main + addressed remaining feedbackWhat changed
Final PR diffOnly 2 files changed (82 additions, 2 deletions):
No other files are modified. |
There was a problem hiding this comment.
Pull request overview
Updates the “create new feature” scripts to prevent duplicate numeric prefixes (e.g., 001-*) when a caller explicitly suggests a feature number, aligning behavior with downstream tooling that expects unique 3-digit prefixes.
Changes:
- Treat
--number/-Numberas a validated “preferred” value and auto-correct it when the prefix already exists inspecs/or git branches. - Track whether the number was explicitly provided to preserve existing auto-detection behavior.
- Update help text to reflect the new auto-correction semantics.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| scripts/bash/create-new-feature.sh | Adds an explicit-number guardrail to detect prefix conflicts in specs/ and branches and auto-correct to the next available number. |
| scripts/powershell/create-new-feature.ps1 | Mirrors the guardrail behavior in PowerShell and updates CLI help text accordingly. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if [ "$HAS_GIT" = true ]; then | ||
| # Fetch remotes so we don't miss branches that exist only on remotes | ||
| git fetch --all --prune >/dev/null 2>&1 || true | ||
| if git branch -a 2>/dev/null | grep -qE "(^|[[:space:]])(remotes/[^/]+/)?${FEATURE_NUM}-"; then | ||
| BRANCH_CONFLICT=true | ||
| fi | ||
| fi | ||
|
|
||
| if [ "$SPEC_CONFLICT" = true ] || [ "$BRANCH_CONFLICT" = true ]; then | ||
| REQUESTED_NUM="$FEATURE_NUM" | ||
| # Delegate to check_existing_branches, which fetches and computes | ||
| # max(all specs, all branches) + 1 — same logic used by auto-detection. | ||
| if [ "$HAS_GIT" = true ]; then | ||
| BRANCH_NUMBER=$(check_existing_branches "$SPECS_DIR") | ||
| else |
| # Track whether the caller explicitly passed -Number so the guardrail below | ||
| # only fires for explicit overrides, not for auto-detected numbers. | ||
| $numberExplicit = $PSBoundParameters.ContainsKey('Number') |
| if ($hasGit) { | ||
| # Fetch remotes so we don't miss branches that exist only on remotes | ||
| try { git fetch --all --prune 2>$null | Out-Null } catch { } | ||
| $allBranches = git branch -a 2>$null | ||
| if ($LASTEXITCODE -eq 0) { | ||
| $branchConflict = ($allBranches | Where-Object { $_ -match "(^|\s)(remotes/[^/]+/)?$featureNum-" }).Count -gt 0 | ||
| } | ||
| } | ||
|
|
||
| if ($specConflict -or $branchConflict) { | ||
| # Delegate to Get-NextBranchNumber, which fetches and computes | ||
| # max(all specs, all branches) + 1 — same logic used by auto-detection. | ||
| if ($hasGit) { | ||
| $Number = Get-NextBranchNumber -SpecsDir $specsDir | ||
| } else { |
| @@ -39,14 +40,15 @@ while [ $i -le $# ]; do | |||
| exit 1 | |||
| fi | |||
mnriem
left a comment
There was a problem hiding this comment.
Please address the additional Copilot comments. Thank for staying with it!
When --number (Bash) or -Number (PowerShell) is explicitly passed and
the requested prefix already exists as a spec directory or git branch,
auto-correct to the global max + 1 rather than failing or creating
duplicate numbering.
Changes:
- Guard fires only on explicit --number/-Number (Bash: NUMBER_EXPLICIT
flag; PowerShell: $PSBoundParameters.ContainsKey('Number') -and $Number
-ne 0), leaving the auto-detection contract unchanged
- Bash: validates --number is an integer in [1,999]; values outside this
range are rejected with a clear error message since downstream tooling
expects a 3-digit prefix
- Conflict detection checks both specs/NNN-* directories (directories
only) and all local/remote git branches
- Single fetch: Bash fetches once before conflict detection and inlines
max-finding from local branch data to avoid a second network call;
PowerShell defers the fetch to Get-NextBranchNumber, which runs only
when a conflict is actually found
- Emits a warning to stderr when auto-correction occurs
- Help text updated: --number/-Number is now "Preferred branch number
(auto-corrected if prefix already exists in specs or branches)"
- Full parity between Bash and PowerShell implementations
f6dbbe2 to
4fae020
Compare
Latest update (rebased + squashed to 1 commit)Addressed the remaining Copilot feedback and cleaned up from internal review:
Note for @mnriem on range validationWe added If there's an intentional reason to allow values outside Final diff stat |
There was a problem hiding this comment.
Pull request overview
Improves the “create new feature” scripts (bash + PowerShell) so an explicitly provided feature number is treated as a validated suggestion and auto-corrected when the numeric prefix already exists in specs/ or in git branches, preventing duplicate NNN-* spec directories.
Changes:
- Add explicit-number tracking and a conflict guardrail that recomputes the next available global feature number on collision.
- Update CLI help text to clarify
--number/-Numberis auto-corrected on conflicts. - Add input validation for
--number/-Number(but see blocking issues in review comments).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| scripts/powershell/create-new-feature.ps1 | Adds -Number conflict guardrail + help text update; introduces a parameter validation issue with the default sentinel. |
| scripts/bash/create-new-feature.sh | Adds --number validation and a conflict guardrail to auto-correct prefix collisions after number resolution. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| $Number = Get-NextBranchNumber -SpecsDir $specsDir | ||
| } else { | ||
| $Number = (Get-HighestNumberFromSpecs -SpecsDir $specsDir) + 1 | ||
| } |
| [ValidateRange(1, 999)] | ||
| [int]$Number = 0, | ||
| [switch]$Help, |
| >&2 echo 'Error: --number must be an integer between 1 and 999' | ||
| exit 1 | ||
| fi | ||
| if (( next_arg < 1 || next_arg > 999 )); then |
| >&2 echo "⚠️ [specify] --number $REQUESTED_NUM conflicts with an existing spec dir or branch. Auto-corrected to $FEATURE_NUM." | ||
| fi | ||
| fi | ||
|
|
There was a problem hiding this comment.
I would prefer the range to allow for 5 digits so it takes a longer time to run out. Now that we are using AI we probably will go through number more quickly so 3 digits seems a bit small. And please address Copilot feedback. if not applicable please explain why.
Agreed, I imagine we may want to either add some padding 00NNN to existing directories, or leave that up to the user, and have the script simply progress naturally to 5 digits from 999 -> 01000? |
|
Probably should keep the prepending for the current scheme and once it overflows no more prepending as that will keep it backwards compatible |
Problem
When
--numberis passed tocreate-new-feature.shwith a prefix that already exists inspecs/(e.g., an AI agent passes--number 1butspecs/001-*already exists), the script silently creates a duplicate directory. This causes downstream errors incheck-prerequisites.sh:Root cause
AI agents sometimes compute an incorrect feature number (e.g., matching only branches with the same short-name instead of globally), bypassing the script's own global-max logic via
--number.Fix
After
FEATURE_NUMis determined, the script now checks if aspecs/NNN-*directory already exists. If so, it recalculates from the true global maximum across all spec directories and git branches, then warns on stderr:The
--numberflag becomes a validated suggestion rather than a hard override. The workflow never fails due to numbering — it self-heals.Changes
scripts/bash/create-new-feature.sh: Added a prefix-conflict guardrail after the feature number is computed (24 lines added, 0 removed).Testing
Tested with an existing
specs/001-*directory: