Skip to content

fix: reject a worktrees baseBranch inside the managed branch namespace - #52

Merged
xantorres merged 1 commit into
mainfrom
fix/worktree-base-branch-namespace
Aug 22, 2026
Merged

xantorres merged 1 commit into
mainfrom
fix/worktree-base-branch-namespace

Conversation

@xantorres

Copy link
Copy Markdown
Owner

worktrees.baseBranch was validated only as z.string().min(1), so it could name any ref — including one RepoKernel creates and later deletes. Point it at an epic branch and every sprint branch merged into that epic registers as merged into the project's base, so rk worktree sweep --apply force-deletes work that never reached trunk.

Two checks added to WorktreesSchema, both hard errors at config load, matching how branchPrefix is already validated:

  • The value must be a legal Git branch name. It is interpolated into git worktree add -b <branch> <path> <baseRef>, where a leading - is argument injection.
  • The value must sit outside the namespace an epic or sprint branch pattern generates into — the pattern up to its first {epicId}/{sprintId} token. That catches a hand-made rk/epic/legacy alongside a rendered rk/epic/E-001, while leaving a base that merely shares branchPrefix (release/current under prefix release/) accepted, so the arrangement feat: sweep merged worktree branches that outlived their worktree #51 documents as supported keeps working.

Test plan

  • 12 cases in packages/cli/test/worktree.test.ts, next to the existing branch-pattern tests
  • pnpm typecheck clean; core 561 pass, cli 1621 pass — including never sweeps the base branch when the base sits under the prefix

worktrees.baseBranch was validated only as a non-empty string, so it could
name any ref — including one RepoKernel itself creates and later deletes.
Basing worktrees on an epic branch makes every sprint branch merged into that
epic register as merged into the project's base, so branch cleanup removes
work that never reached trunk.

Validate it the way branchPrefix already is: reject illegal Git branch names,
and reject a base that falls inside the namespace an epic or sprint branch
pattern generates into. That namespace is the pattern up to its first id
token, so a hand-made branch there is caught alongside a rendered one, while a
base that merely shares branchPrefix stays accepted.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 05e656fc68

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +347 to +349
const collides = namespace.isPrefix
? value.baseBranch.startsWith(namespace.value)
: refsConflict(value.baseBranch, namespace.value);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Handle patterns whose first component is an ID token

When an otherwise-valid pattern begins with {epicId} or {sprintId}, generatedBranchNamespace returns an empty prefix, so baseBranch.startsWith('') rejects every possible base branch. For example, epicBranchPattern: "{epicId}/epic", sprintBranchPattern: "{epicId}/sprint/{sprintId}", and baseBranch: "main" can no longer load even though the generated E-<number>/... refs cannot collide with main; handle the empty-prefix case using the rendered ID shape rather than treating it as the entire branch space.

Useful? React with 👍 / 👎.

@xantorres
xantorres merged commit 8b420bb into main Aug 22, 2026
3 checks passed
@xantorres
xantorres deleted the fix/worktree-base-branch-namespace branch August 22, 2026 09:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant