fix: honor workflow guard opt-in for Bash blocks
This commit is contained in:
@@ -26,23 +26,36 @@ function makeRepo(branch) {
|
||||
return dir;
|
||||
}
|
||||
|
||||
function runHook(cwd, command) {
|
||||
function setWorkflowGuard(dir, enabled) {
|
||||
const planningDir = path.join(dir, '.planning');
|
||||
fs.mkdirSync(planningDir, { recursive: true });
|
||||
fs.writeFileSync(
|
||||
path.join(planningDir, 'config.json'),
|
||||
JSON.stringify({ hooks: { workflow_guard: enabled } }, null, 2)
|
||||
);
|
||||
}
|
||||
|
||||
function runHookInput(cwd, input) {
|
||||
return spawnSync(process.execPath, [HOOK_PATH], {
|
||||
cwd,
|
||||
encoding: 'utf8',
|
||||
input: JSON.stringify({
|
||||
cwd,
|
||||
tool_name: 'Bash',
|
||||
tool_input: { command },
|
||||
}),
|
||||
input: JSON.stringify({ cwd, ...input }),
|
||||
});
|
||||
}
|
||||
|
||||
function runBashHook(cwd, command) {
|
||||
return runHookInput(cwd, {
|
||||
tool_name: 'Bash',
|
||||
tool_input: { command },
|
||||
});
|
||||
}
|
||||
|
||||
describe('bug #261: workflow guard blocks forced git add on worktree-agent branches', () => {
|
||||
test('blocks git add -f on worktree-agent branch before it can stage gitignored files', () => {
|
||||
test('blocks git add -f on worktree-agent branch when workflow guard is enabled', () => {
|
||||
const dir = makeRepo('worktree-agent-a1');
|
||||
try {
|
||||
const result = runHook(dir, 'git add -f .planning/phases/01/01-01-SUMMARY.md');
|
||||
setWorkflowGuard(dir, true);
|
||||
const result = runBashHook(dir, 'git add -f .planning/phases/01/01-01-SUMMARY.md');
|
||||
assert.strictEqual(result.status, 2);
|
||||
const envelope = JSON.parse(result.stdout);
|
||||
assert.strictEqual(envelope.decision, 'block');
|
||||
@@ -55,7 +68,8 @@ describe('bug #261: workflow guard blocks forced git add on worktree-agent branc
|
||||
test('blocks git add --force with git global options on worktree-agent branch', () => {
|
||||
const dir = makeRepo('worktree-agent-b2');
|
||||
try {
|
||||
const result = runHook(path.dirname(dir), `git -C "${dir}" add --force .planning/SUMMARY.md`);
|
||||
setWorkflowGuard(dir, true);
|
||||
const result = runBashHook(dir, `git -C "${dir}" add --force .planning/SUMMARY.md`);
|
||||
assert.strictEqual(result.status, 2);
|
||||
assert.strictEqual(JSON.parse(result.stdout).code, 'WORKTREE_AGENT_FORCE_ADD_FORBIDDEN');
|
||||
} finally {
|
||||
@@ -66,7 +80,8 @@ describe('bug #261: workflow guard blocks forced git add on worktree-agent branc
|
||||
test('allows ordinary git add on worktree-agent branch', () => {
|
||||
const dir = makeRepo('worktree-agent-c3');
|
||||
try {
|
||||
const result = runHook(dir, 'git add .planning/SUMMARY.md');
|
||||
setWorkflowGuard(dir, true);
|
||||
const result = runBashHook(dir, 'git add .planning/SUMMARY.md');
|
||||
assert.strictEqual(result.status, 0);
|
||||
assert.strictEqual(result.stdout, '');
|
||||
} finally {
|
||||
@@ -77,11 +92,57 @@ describe('bug #261: workflow guard blocks forced git add on worktree-agent branc
|
||||
test('allows git add -f outside worktree-agent branches', () => {
|
||||
const dir = makeRepo('feature-docs');
|
||||
try {
|
||||
const result = runHook(dir, 'git add -f .planning/SUMMARY.md');
|
||||
setWorkflowGuard(dir, true);
|
||||
const result = runBashHook(dir, 'git add -f .planning/SUMMARY.md');
|
||||
assert.strictEqual(result.status, 0);
|
||||
assert.strictEqual(result.stdout, '');
|
||||
} finally {
|
||||
fs.rmSync(dir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
test('allows git add -f on worktree-agent branch when workflow guard is disabled', () => {
|
||||
const dir = makeRepo('worktree-agent-d4');
|
||||
try {
|
||||
setWorkflowGuard(dir, false);
|
||||
const result = runBashHook(dir, 'git add -f .planning/SUMMARY.md');
|
||||
assert.strictEqual(result.status, 0);
|
||||
assert.strictEqual(result.stdout, '');
|
||||
} finally {
|
||||
fs.rmSync(dir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
test('allows git add -f on worktree-agent branch when no GSD config exists', () => {
|
||||
const dir = makeRepo('worktree-agent-e5');
|
||||
try {
|
||||
const result = runBashHook(dir, 'git add -f .planning/SUMMARY.md');
|
||||
assert.strictEqual(result.status, 0);
|
||||
assert.strictEqual(result.stdout, '');
|
||||
} finally {
|
||||
fs.rmSync(dir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
test('applies the advisory path to MultiEdit when workflow guard is enabled', () => {
|
||||
const dir = makeRepo('feature-multiedit');
|
||||
try {
|
||||
setWorkflowGuard(dir, true);
|
||||
const result = runHookInput(dir, {
|
||||
tool_name: 'MultiEdit',
|
||||
tool_input: {
|
||||
file_path: path.join(dir, 'src.js'),
|
||||
edits: [],
|
||||
},
|
||||
});
|
||||
assert.strictEqual(result.status, 0);
|
||||
const envelope = JSON.parse(result.stdout);
|
||||
assert.match(
|
||||
envelope.hookSpecificOutput.additionalContext,
|
||||
/WORKFLOW ADVISORY/
|
||||
);
|
||||
} finally {
|
||||
fs.rmSync(dir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user