From 68bf425606d59d2b6a0fd7db69540cebb555a27f Mon Sep 17 00:00:00 2001 From: deseltrus Date: Tue, 14 Apr 2026 06:11:42 +0200 Subject: [PATCH] test: update assertions for blocked-phase behavior change Tests now expect: - pauseAuto instead of stopAuto for blocked state (resumable) - phase:"planning" instead of "blocked" when partial-dep fallback picks a slice (slice-level only; milestone-level blocked unchanged) - activeSlice set via fallback instead of null --- src/resources/extensions/gsd/tests/auto-loop.test.ts | 4 ++-- .../gsd/tests/derive-state-crossval.test.ts | 5 +++-- .../extensions/gsd/tests/derive-state-db.test.ts | 5 +++-- .../extensions/gsd/tests/derive-state.test.ts | 6 +++--- .../integration/state-machine-edge-cases.test.ts | 6 ++++-- .../gsd/tests/state-machine-full-walkthrough.test.ts | 12 +++++------- 6 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/resources/extensions/gsd/tests/auto-loop.test.ts b/src/resources/extensions/gsd/tests/auto-loop.test.ts index 6fd5eb0e6..2d506c815 100644 --- a/src/resources/extensions/gsd/tests/auto-loop.test.ts +++ b/src/resources/extensions/gsd/tests/auto-loop.test.ts @@ -688,8 +688,8 @@ test("autoLoop exits on terminal blocked state", async (t) => { assert.ok(deps.callLog.includes("deriveState"), "should have derived state"); assert.ok( - deps.callLog.includes("stopAuto"), - "should have called stopAuto for blocked state", + deps.callLog.includes("pauseAuto"), + "should have called pauseAuto for blocked state", ); assert.ok( !deps.callLog.includes("resolveDispatch"), diff --git a/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts b/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts index a349e2c81..599bfa17a 100644 --- a/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +++ b/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts @@ -351,8 +351,9 @@ skills_used: [] const dbState = await deriveStateFromDb(base); assertStatesEqual(dbState, fileState, 'E-blocked'); - assert.deepStrictEqual(dbState.phase, 'blocked', 'E-blocked: phase is blocked'); - assert.ok(dbState.blockers.length > 0, 'E-blocked: has blockers'); + // With partial-dep fallback, circular deps no longer block — fallback picks first eligible slice + assert.deepStrictEqual(dbState.phase, 'planning', 'E-blocked: phase is planning (fallback picks a slice)'); + assert.ok(dbState.activeSlice !== null, 'E-blocked: activeSlice is set via fallback'); closeDatabase(); } finally { diff --git a/src/resources/extensions/gsd/tests/derive-state-db.test.ts b/src/resources/extensions/gsd/tests/derive-state-db.test.ts index 08ea28f8a..2eaa0f01f 100644 --- a/src/resources/extensions/gsd/tests/derive-state-db.test.ts +++ b/src/resources/extensions/gsd/tests/derive-state-db.test.ts @@ -616,9 +616,10 @@ describe('derive-state-db', async () => { invalidateStateCache(); const dbState = await deriveStateFromDb(base); - assert.deepStrictEqual(dbState.phase, 'blocked', 'blocked-db: phase is blocked'); + // With partial-dep fallback, circular deps no longer block — fallback picks first eligible slice + assert.deepStrictEqual(dbState.phase, 'planning', 'blocked-db: phase is planning (fallback picks a slice)'); assert.deepStrictEqual(dbState.phase, fileState.phase, 'blocked-db: phase matches filesystem'); - assert.ok(dbState.blockers.length > 0, 'blocked-db: has blockers'); + assert.ok(dbState.activeSlice !== null, 'blocked-db: activeSlice is set via fallback'); closeDatabase(); } finally { diff --git a/src/resources/extensions/gsd/tests/derive-state.test.ts b/src/resources/extensions/gsd/tests/derive-state.test.ts index ce93f7ffa..8aa5bd9f2 100644 --- a/src/resources/extensions/gsd/tests/derive-state.test.ts +++ b/src/resources/extensions/gsd/tests/derive-state.test.ts @@ -446,9 +446,9 @@ Continue from step 2. const state2 = await deriveState(base2); - assert.deepStrictEqual(state2.phase, 'blocked', 'blocked-B: phase is blocked'); - assert.deepStrictEqual(state2.activeSlice, null, 'blocked-B: activeSlice is null'); - assert.ok(state2.blockers.length > 0, 'blocked-B: blockers array is non-empty'); + // With partial-dep fallback, S01 is picked despite unmet dep on S99 + assert.deepStrictEqual(state2.phase, 'planning', 'blocked-B: phase is planning (fallback picks S01)'); + assert.deepStrictEqual(state2.activeSlice?.id, 'S01', 'blocked-B: activeSlice is S01 via fallback'); } finally { cleanup(base2); } diff --git a/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts b/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts index db7b992c8..51e3eae06 100644 --- a/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +++ b/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts @@ -691,7 +691,7 @@ describe("transition boundary failures", () => { ); }); - test("blocked state: all slices have unmet deps → blocked phase", async () => { + test("blocked state: all slices have unmet deps → fallback picks slice", async () => { base = makeTempDir(); const mDir = join(base, ".gsd", "milestones", "M001"); mkdirSync(join(mDir, "slices", "S01", "tasks"), { recursive: true }); @@ -736,7 +736,9 @@ describe("transition boundary failures", () => { invalidateAllCaches(); const state = await deriveStateFromDb(base); - assert.equal(state.phase, "blocked", "circular deps should produce blocked phase"); + // With partial-dep fallback, circular deps no longer block — fallback picks first eligible slice + assert.equal(state.phase, "planning", "circular deps: fallback picks a slice instead of blocking"); + assert.ok(state.activeSlice !== null, "activeSlice set via fallback"); }); }); diff --git a/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts b/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts index f1b66acb9..22fa60fbd 100644 --- a/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +++ b/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts @@ -811,9 +811,9 @@ describe("state-machine-full-walkthrough", () => { assert.ok(state.blockers.length > 0, "should have blockers"); }); - test("no eligible slice (all deps unmet) → blocked at slice level", async () => { + test("no eligible slice (all deps unmet) → fallback picks slice with most deps satisfied", async () => { const base = createFixtureBase(); - // S01 depends on S00 which doesn't exist + // S01 depends on S00 which doesn't exist — fallback picks S01 anyway writeRoadmap(base, "M001", [ "# M001: Test Milestone", "", @@ -827,11 +827,9 @@ describe("state-machine-full-walkthrough", () => { invalidateStateCache(); const state = await deriveState(base); - assert.equal(state.phase, "blocked"); - assert.ok( - state.blockers.some(b => b.includes("dependency") || b.includes("eligible")), - "blockers should mention dependency or eligibility", - ); + // With partial-dep fallback, S01 is picked despite unmet dep on S00 + assert.equal(state.phase, "planning"); + assert.equal(state.activeSlice?.id, "S01"); }); });