fix(gsd): merge enhanced context sections into standard template, clean up stale gate patterns
- Add Architectural Decisions, Error Handling Strategy, Testing Requirements, and Acceptance Criteria sections to context.md so discussion investigation output persists for downstream phases - Remove layer1-4 gate patterns from write-gate.ts (only depth_verification remains — the 4-layer gates were only in the deleted discuss-prepared.md) - Update write-gate tests to use depth_verification fixtures Follows up on #3934
This commit is contained in:
parent
cc5157e534
commit
a9fc396043
3 changed files with 47 additions and 22 deletions
|
|
@ -50,10 +50,6 @@ let pendingGateId: string | null = null;
|
|||
* These appear in discuss.md (depth/requirements/roadmap).
|
||||
*/
|
||||
const GATE_QUESTION_PATTERNS = [
|
||||
"layer1_scope_gate",
|
||||
"layer2_architecture_gate",
|
||||
"layer3_error_gate",
|
||||
"layer4_quality_gate",
|
||||
"depth_verification",
|
||||
] as const;
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,28 @@ To call this milestone complete, we must prove:
|
|||
- {{one real end-to-end scenario}}
|
||||
- {{what cannot be simulated if this milestone is to be considered truly done}}
|
||||
|
||||
## Architectural Decisions
|
||||
|
||||
### {{decisionTitle}}
|
||||
|
||||
**Decision:** {{decisionStatement}}
|
||||
|
||||
**Rationale:** {{rationale}}
|
||||
|
||||
**Alternatives Considered:**
|
||||
- {{alternative}} — {{whyNotChosen}}
|
||||
|
||||
---
|
||||
|
||||
> Add additional decisions as separate `### Decision Title` blocks following the same structure above.
|
||||
> See `.gsd/DECISIONS.md` for the full append-only register of all project decisions.
|
||||
|
||||
## Error Handling Strategy
|
||||
|
||||
{{errorHandlingStrategy}}
|
||||
|
||||
> Describe the approach for handling failures, edge cases, and error propagation. Include retry policies, fallback behaviors, and user-facing error messages where relevant.
|
||||
|
||||
## Risks and Unknowns
|
||||
|
||||
- {{riskOrUnknown}} — {{whyItMatters}}
|
||||
|
|
@ -47,8 +69,6 @@ To call this milestone complete, we must prove:
|
|||
- `{{fileOrModule}}` — {{howItRelates}}
|
||||
- `{{fileOrModule}}` — {{howItRelates}}
|
||||
|
||||
> See `.gsd/DECISIONS.md` for all architectural and pattern decisions — it is an append-only register; read it during planning, append to it during execution.
|
||||
|
||||
## Relevant Requirements
|
||||
|
||||
- {{requirementId}} — {{howThisMilestoneAdvancesIt}}
|
||||
|
|
@ -71,6 +91,18 @@ To call this milestone complete, we must prove:
|
|||
|
||||
- {{systemOrService}} — {{howThisMilestoneInteractsWithIt}}
|
||||
|
||||
## Testing Requirements
|
||||
|
||||
{{testingRequirements}}
|
||||
|
||||
> Specify test types (unit, integration, e2e), coverage expectations, and specific test scenarios that must pass.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
{{acceptanceCriteria}}
|
||||
|
||||
> Per-slice acceptance criteria gathered during discussion. Each slice should have clear, testable criteria.
|
||||
|
||||
## Open Questions
|
||||
|
||||
- {{question}} — {{currentThinking}}
|
||||
|
|
|
|||
|
|
@ -230,16 +230,13 @@ import {
|
|||
// ─── Scenario 19: isGateQuestionId recognizes all gate patterns ──
|
||||
|
||||
test('write-gate: isGateQuestionId recognizes all gate patterns', () => {
|
||||
assert.strictEqual(isGateQuestionId('layer1_scope_gate'), true);
|
||||
assert.strictEqual(isGateQuestionId('layer2_architecture_gate'), true);
|
||||
assert.strictEqual(isGateQuestionId('layer3_error_gate'), true);
|
||||
assert.strictEqual(isGateQuestionId('layer4_quality_gate'), true);
|
||||
assert.strictEqual(isGateQuestionId('depth_verification'), true);
|
||||
assert.strictEqual(isGateQuestionId('depth_verification_M002'), true);
|
||||
assert.strictEqual(isGateQuestionId('my_layer1_scope_gate_question'), true);
|
||||
assert.strictEqual(isGateQuestionId('depth_verification_confirm'), true);
|
||||
// Non-gate question IDs
|
||||
assert.strictEqual(isGateQuestionId('project_intent'), false);
|
||||
assert.strictEqual(isGateQuestionId('feature_priority'), false);
|
||||
assert.strictEqual(isGateQuestionId('layer1_scope_gate'), false);
|
||||
assert.strictEqual(isGateQuestionId(''), false);
|
||||
});
|
||||
|
||||
|
|
@ -249,14 +246,14 @@ test('write-gate: pending gate lifecycle (set, get, clear)', () => {
|
|||
clearDiscussionFlowState();
|
||||
assert.strictEqual(getPendingGate(), null, 'starts null');
|
||||
|
||||
setPendingGate('layer1_scope_gate');
|
||||
assert.strictEqual(getPendingGate(), 'layer1_scope_gate', 'set correctly');
|
||||
setPendingGate('depth_verification');
|
||||
assert.strictEqual(getPendingGate(), 'depth_verification', 'set correctly');
|
||||
|
||||
clearPendingGate();
|
||||
assert.strictEqual(getPendingGate(), null, 'cleared correctly');
|
||||
|
||||
// clearDiscussionFlowState also clears pending gate
|
||||
setPendingGate('layer2_architecture_gate');
|
||||
setPendingGate('depth_verification_M002');
|
||||
clearDiscussionFlowState();
|
||||
assert.strictEqual(getPendingGate(), null, 'clearDiscussionFlowState clears pending gate');
|
||||
});
|
||||
|
|
@ -265,12 +262,12 @@ test('write-gate: pending gate lifecycle (set, get, clear)', () => {
|
|||
|
||||
test('write-gate: shouldBlockPendingGate blocks write/edit during pending gate', () => {
|
||||
clearDiscussionFlowState();
|
||||
setPendingGate('layer1_scope_gate');
|
||||
setPendingGate('depth_verification');
|
||||
|
||||
// write should be blocked during discussion
|
||||
const writeResult = shouldBlockPendingGate('write', 'M001', false);
|
||||
assert.strictEqual(writeResult.block, true, 'write should be blocked');
|
||||
assert.ok(writeResult.reason!.includes('layer1_scope_gate'), 'reason mentions the gate');
|
||||
assert.ok(writeResult.reason!.includes('depth_verification'), 'reason mentions the gate');
|
||||
|
||||
// edit should be blocked
|
||||
const editResult = shouldBlockPendingGate('edit', 'M001', false);
|
||||
|
|
@ -287,7 +284,7 @@ test('write-gate: shouldBlockPendingGate blocks write/edit during pending gate',
|
|||
|
||||
test('write-gate: shouldBlockPendingGate allows read-only and ask_user_questions during pending gate', () => {
|
||||
clearDiscussionFlowState();
|
||||
setPendingGate('layer1_scope_gate');
|
||||
setPendingGate('depth_verification');
|
||||
|
||||
// ask_user_questions is always safe (model needs to re-ask)
|
||||
assert.strictEqual(shouldBlockPendingGate('ask_user_questions', 'M001').block, false);
|
||||
|
|
@ -304,7 +301,7 @@ test('write-gate: shouldBlockPendingGate allows read-only and ask_user_questions
|
|||
|
||||
test('write-gate: shouldBlockPendingGate blocks outside discussion when a gate is pending', () => {
|
||||
clearDiscussionFlowState();
|
||||
setPendingGate('layer1_scope_gate');
|
||||
setPendingGate('depth_verification');
|
||||
|
||||
// No milestoneId and no queue phase — still block because the gate is pending
|
||||
const result = shouldBlockPendingGate('write', null, false);
|
||||
|
|
@ -330,7 +327,7 @@ test('write-gate: shouldBlockPendingGate blocks in queue mode when gate is pendi
|
|||
|
||||
test('write-gate: shouldBlockPendingGateBash allows read-only commands during pending gate', () => {
|
||||
clearDiscussionFlowState();
|
||||
setPendingGate('layer2_architecture_gate');
|
||||
setPendingGate('depth_verification');
|
||||
|
||||
assert.strictEqual(shouldBlockPendingGateBash('cat file.txt', 'M001').block, false);
|
||||
assert.strictEqual(shouldBlockPendingGateBash('git log --oneline', 'M001').block, false);
|
||||
|
|
@ -344,11 +341,11 @@ test('write-gate: shouldBlockPendingGateBash allows read-only commands during pe
|
|||
|
||||
test('write-gate: shouldBlockPendingGateBash blocks mutating commands during pending gate', () => {
|
||||
clearDiscussionFlowState();
|
||||
setPendingGate('layer2_architecture_gate');
|
||||
setPendingGate('depth_verification');
|
||||
|
||||
const result = shouldBlockPendingGateBash('npm run build', 'M001');
|
||||
assert.strictEqual(result.block, true, 'mutating bash should be blocked');
|
||||
assert.ok(result.reason!.includes('layer2_architecture_gate'));
|
||||
assert.ok(result.reason!.includes('depth_verification'));
|
||||
|
||||
clearDiscussionFlowState();
|
||||
});
|
||||
|
|
@ -365,7 +362,7 @@ test('write-gate: no pending gate means no blocking', () => {
|
|||
// ─── Scenario 28: resetWriteGateState clears pending gate ──
|
||||
|
||||
test('write-gate: resetWriteGateState clears pending gate', () => {
|
||||
setPendingGate('layer3_error_gate');
|
||||
setPendingGate('depth_verification');
|
||||
resetWriteGateState();
|
||||
assert.strictEqual(getPendingGate(), null);
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue