* 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:
@@ -18,6 +18,9 @@ import { execGit as execGitSeam, posixNormalize } from './shell-command-projecti
|
||||
// remote, stalled NFS mount, etc.). Callers can override via deps.timeout.
|
||||
const DEFAULT_GIT_TIMEOUT_MS = 10000;
|
||||
|
||||
const WORKTREE_AGENT_BRANCH_RE = /^(worktree-)?agent-[A-Za-z0-9._/-]+$/;
|
||||
const WORKTREE_AGENT_BRANCH_PATTERN = WORKTREE_AGENT_BRANCH_RE.source;
|
||||
|
||||
interface GitResult {
|
||||
exitCode: number;
|
||||
stdout: string;
|
||||
@@ -428,7 +431,7 @@ function normalizeCleanupManifestEntry(entry: unknown): CleanupManifestEntry | n
|
||||
const branch = typeof e.branch === 'string' ? e.branch : '';
|
||||
const expectedBase = typeof e.expected_base === 'string' ? e.expected_base : '';
|
||||
if (!worktreePath || !branch || !expectedBase) return null;
|
||||
if (!/^worktree-agent-[A-Za-z0-9._/-]+$/.test(branch)) return null;
|
||||
if (!WORKTREE_AGENT_BRANCH_RE.test(branch)) return null;
|
||||
const rawAllowedBases = Array.isArray(e.allowed_bases) ? e.allowed_bases : [];
|
||||
const allowedBases = Array.from(new Set(
|
||||
[expectedBase, ...rawAllowedBases.filter((base): base is string => typeof base === 'string' && base.length > 0)]
|
||||
@@ -939,7 +942,7 @@ function planWorktreeRecordAgent(manifestRaw: string, fields: RecordAgentFields)
|
||||
return {
|
||||
ok: false,
|
||||
reason: 'invalid_entry',
|
||||
hint: `Entry failed cleanup-manifest validation: --path/--branch/--base must be non-empty and --branch must match ^worktree-agent-[A-Za-z0-9._/-]+$ (got branch="${branch}"). Fix the field and re-run.`,
|
||||
hint: `Entry failed cleanup-manifest validation: --path/--branch/--base must be non-empty and --branch must match ${WORKTREE_AGENT_BRANCH_PATTERN} (accepts both agent-<id> and worktree-agent-<id> namespaces; got branch="${branch}"). Fix the field and re-run.`,
|
||||
entry: null,
|
||||
manifest: null,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user