* test(#1995): regression test for agent-<id> branch namespace Add failing-first tests proving that normalizeCleanupManifestEntry and planWorktreeRecordAgent reject Claude Code's current agent-<id> isolation branches (only worktree-agent-<id> is accepted). Boundary tests cover both namespaces plus rejection cases. * fix(#1995): widen worktree branch regex to accept agent-<id> namespace Claude Code's isolation="worktree" branch naming changed from worktree-agent-<id> to agent-<id>. Widen the regex in all 7 locations from ^worktree-agent-[A-Za-z0-9._/-]+$ to ^(worktree-)?agent-[A-Za-z0-9._/-]+$ so both namespaces are accepted. Introduce a shared WORKTREE_AGENT_BRANCH_RE constant in src/worktree-safety.cts to prevent future drift. Closes #1995 * fix(#1995): update workflow guards, test assertions, and baselines Widen the branch-check regex in execute-phase.md and execute-plan.md. Update all test assertions that checked for ^worktree-agent- to expect the widened ^(worktree-)?agent- pattern. Regenerate golden-install-parity fixtures, agent-size-baseline, and workflow-size-baseline. Closes #1995 * fix(#1995): update extractCwdGuardBash sanity check for widened regex The e2e test's sanity check verified the extracted bash block contained 'worktree-agent-'. After widening to '(worktree-)?agent-', update the check to match the new pattern. * fix(#1995): widen missed workflow-guard branch check + changeset + lint fixes - hooks/gsd-workflow-guard.js: widen startsWith('worktree-agent-') to /^(worktree-)?agent-/ regex — same defect class, was missed in prior commit - tests/worktree.test.cjs: fix indentation regression from prior edit - Add .changeset/1995-worktree-agent-branch-namespace.md (pr:0 placeholder) Found by orthogonal code review (Step 4). * fix(#1995): regenerate golden + size baselines for workflow-guard change * docs(#1995): backfill changeset PR number (2548)
This commit is contained in:
@@ -143,11 +143,11 @@ process.stdin.on('end', () => {
|
||||
const command = data.tool_input?.command || '';
|
||||
for (const gitCwd of forceGitAddCwds(command, cwd)) {
|
||||
const branch = currentBranch(gitCwd);
|
||||
if (branch.startsWith('worktree-agent-')) {
|
||||
if (/^(worktree-)?agent-/.test(branch)) {
|
||||
const output = {
|
||||
decision: 'block',
|
||||
code: 'WORKTREE_AGENT_FORCE_ADD_FORBIDDEN',
|
||||
reason: 'worktree-agent branches must not run git add -f or git add --force. Respect the SDK skipped_gitignored/skipped_commit_docs_false contract and leave gitignored files untracked.',
|
||||
reason: 'agent/worktree-agent branches must not run git add -f or git add --force. Respect the SDK skipped_gitignored/skipped_commit_docs_false contract and leave gitignored files untracked.',
|
||||
};
|
||||
process.stdout.write(JSON.stringify(output));
|
||||
// Kimi CLI's exit-2 protocol feeds stderr back to the model (#2304)
|
||||
|
||||
@@ -118,13 +118,14 @@ process.stdin.on('end', () => {
|
||||
}
|
||||
|
||||
// #1342: Only enforce inside a GSD-managed isolated executor worktree. Those
|
||||
// are always on a `worktree-agent-*` branch (the positive allow-list enforced
|
||||
// by worktree-branch-check.md, #2924). A manually-created linked worktree (plain
|
||||
// non-GSD work, e.g. Claude Code plan-mode) is on the user's own branch, so the
|
||||
// guard must be a no-op there. Detached HEAD / error → not GSD-managed → no-op.
|
||||
// are always on an `agent-*` or legacy `worktree-agent-*` branch (the positive
|
||||
// allow-list enforced by worktree-branch-check.md, #2924, #1995). A manually-
|
||||
// created linked worktree (plain non-GSD work, e.g. Claude Code plan-mode) is
|
||||
// on the user's own branch, so the guard must be a no-op there. Detached HEAD
|
||||
// / error → not GSD-managed → no-op.
|
||||
const branchResult = git(['symbolic-ref', '--short', 'HEAD'], cwd);
|
||||
const branch = branchResult.status === 0 && branchResult.stdout ? branchResult.stdout.trim() : '';
|
||||
if (!/^worktree-agent-[A-Za-z0-9._/-]+$/.test(branch)) {
|
||||
if (!/^(worktree-)?agent-[A-Za-z0-9._/-]+$/.test(branch)) {
|
||||
process.exit(0); // not a GSD-managed executor worktree — no-op
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user