feat(sdk): empty phase dir surfaces NO_UAT_FILES reason (#3184)

Cycle 4 of ~15: phase dir present but no *-HUMAN-UAT.md files
now returns a typed NO_UAT_FILES reason instead of an empty
reasons array (which prior cycles used as a 'shouldn't happen'
fallback).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Tom Boucher
2026-05-18 22:41:57 -04:00
parent c1664e52ae
commit 1a27780443
2 changed files with 28 additions and 0 deletions

View File

@@ -43,6 +43,24 @@ describe('isPhaseUatPassed', () => {
expect(result.reasons.length).toBe(0);
});
it('returns passed=false with NO_UAT_FILES reason when phase dir has no UAT files', async () => {
const localTmp = await mkdtemp(join(tmpdir(), 'gsd-uat-c4-'));
try {
const phaseDir = join(localTmp, '.planning', 'phases', '05-empty');
await mkdir(phaseDir, { recursive: true });
// Write a non-UAT file to ensure the dir exists but has no *-HUMAN-UAT.md
await writeFile(join(phaseDir, '05-PLAN.md'), '# Plan\nNothing here.\n');
const result = await isPhaseUatPassed(localTmp, '5');
expect(result.passed).toBe(false);
expect(result.items.length).toBe(0);
expect(result.reasons.length).toBe(1);
expect(result.reasons[0].code).toBe(REASON_CODE.NO_UAT_FILES);
} finally {
await rm(localTmp, { recursive: true, force: true });
}
});
it('returns passed=false with NO_PHASE_DIR reason when phase has no directory', async () => {
const localTmp = await mkdtemp(join(tmpdir(), 'gsd-uat-c3-'));
try {