fix(hooks): process depth verification in queue mode (#1823)
The tool_result handler early-returned when getDiscussionMilestoneId() was null, which is always the case in queue mode. This prevented markDepthVerified() from being called, permanently blocking CONTEXT.md writes when queuePhaseActive was true. The handler now also checks isQueuePhaseActive() before returning early, allowing depth verification to complete in queue mode. A second guard after depth verification processing ensures the discussion log write still requires a valid milestoneId. Fixes #1812 Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
d2be9f34ce
commit
1a70f9daea
2 changed files with 76 additions and 2 deletions
|
|
@ -136,7 +136,8 @@ export function registerHooks(pi: ExtensionAPI): void {
|
|||
pi.on("tool_result", async (event) => {
|
||||
if (event.toolName !== "ask_user_questions") return;
|
||||
const milestoneId = getDiscussionMilestoneId();
|
||||
if (!milestoneId) return;
|
||||
const queueActive = isQueuePhaseActive();
|
||||
if (!milestoneId && !queueActive) return;
|
||||
|
||||
const details = event.details as any;
|
||||
if (details?.cancelled || !details?.response) return;
|
||||
|
|
@ -149,6 +150,8 @@ export function registerHooks(pi: ExtensionAPI): void {
|
|||
}
|
||||
}
|
||||
|
||||
if (!milestoneId) return;
|
||||
|
||||
const basePath = process.cwd();
|
||||
const milestoneDir = resolveMilestonePath(basePath, milestoneId);
|
||||
if (!milestoneDir) return;
|
||||
|
|
|
|||
|
|
@ -11,7 +11,17 @@
|
|||
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { shouldBlockContextWrite } from '../index.ts';
|
||||
import {
|
||||
shouldBlockContextWrite,
|
||||
isDepthVerified,
|
||||
isQueuePhaseActive,
|
||||
setQueuePhaseActive,
|
||||
} from '../index.ts';
|
||||
import {
|
||||
markDepthVerified,
|
||||
clearDiscussionFlowState,
|
||||
resetWriteGateState,
|
||||
} from '../bootstrap/write-gate.ts';
|
||||
|
||||
// ─── Scenario 1: Blocks CONTEXT.md write during discussion without depth verification (absolute path) ──
|
||||
|
||||
|
|
@ -120,3 +130,64 @@ test('write-gate: blocked reason contains depth_verification keyword', () => {
|
|||
assert.ok(result.reason!.includes('depth_verification'), 'reason should mention depth_verification question id');
|
||||
assert.ok(result.reason!.includes('ask_user_questions'), 'reason should mention ask_user_questions tool');
|
||||
});
|
||||
|
||||
// ─── Scenario 8: Queue mode blocks CONTEXT.md write without depth verification ──
|
||||
|
||||
test('write-gate: blocks CONTEXT.md write in queue mode without depth verification', () => {
|
||||
const result = shouldBlockContextWrite(
|
||||
'write',
|
||||
'.gsd/milestones/M001/M001-CONTEXT.md',
|
||||
null, // no milestoneId in queue mode
|
||||
false, // not depth-verified
|
||||
true, // queue phase active
|
||||
);
|
||||
assert.strictEqual(result.block, true, 'should block in queue mode without depth verification');
|
||||
assert.ok(result.reason, 'should provide a reason');
|
||||
});
|
||||
|
||||
// ─── Scenario 9: Queue mode allows CONTEXT.md write after depth verification ──
|
||||
|
||||
test('write-gate: allows CONTEXT.md write in queue mode after depth verification', () => {
|
||||
const result = shouldBlockContextWrite(
|
||||
'write',
|
||||
'.gsd/milestones/M001/M001-CONTEXT.md',
|
||||
null, // no milestoneId in queue mode
|
||||
true, // depth-verified
|
||||
true, // queue phase active
|
||||
);
|
||||
assert.strictEqual(result.block, false, 'should not block in queue mode after depth verification');
|
||||
});
|
||||
|
||||
// ─── Scenario 10: markDepthVerified works in queue-only mode (no milestoneId) ──
|
||||
// This is the core regression for #1812: in queue mode, the tool_result handler
|
||||
// must call markDepthVerified() even when getDiscussionMilestoneId() is null.
|
||||
|
||||
test('write-gate: markDepthVerified unblocks queue-mode writes when milestoneId is null', () => {
|
||||
clearDiscussionFlowState();
|
||||
setQueuePhaseActive(true);
|
||||
|
||||
// Before marking: should block
|
||||
const blocked = shouldBlockContextWrite(
|
||||
'write',
|
||||
'.gsd/milestones/M001/M001-CONTEXT.md',
|
||||
null,
|
||||
isDepthVerified(),
|
||||
isQueuePhaseActive(),
|
||||
);
|
||||
assert.strictEqual(blocked.block, true, 'should block before markDepthVerified');
|
||||
|
||||
// Simulate what the fixed tool_result handler does
|
||||
markDepthVerified();
|
||||
|
||||
// After marking: should pass
|
||||
const allowed = shouldBlockContextWrite(
|
||||
'write',
|
||||
'.gsd/milestones/M001/M001-CONTEXT.md',
|
||||
null,
|
||||
isDepthVerified(),
|
||||
isQueuePhaseActive(),
|
||||
);
|
||||
assert.strictEqual(allowed.block, false, 'should allow after markDepthVerified in queue mode');
|
||||
|
||||
clearDiscussionFlowState();
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue