diff --git a/src/resources/extensions/gsd/tests/auto-loop.test.ts b/src/resources/extensions/gsd/tests/auto-loop.test.ts index 3ecb5a667..c77fb44df 100644 --- a/src/resources/extensions/gsd/tests/auto-loop.test.ts +++ b/src/resources/extensions/gsd/tests/auto-loop.test.ts @@ -367,9 +367,6 @@ function makeMockDeps( getPriorSliceCompletionBlocker: () => null, getMainBranch: () => "main", closeoutUnit: async () => {}, - verifyExpectedArtifact: () => true, - clearUnitRuntimeRecord: () => {}, - writeUnitRuntimeRecord: () => {}, recordOutcome: () => {}, writeLock: () => {}, captureAvailableSkills: () => {}, @@ -1990,7 +1987,6 @@ test("autoLoop does NOT reject non-execute-task units with 0 tool calls (#1833)" }); }, getLedger: () => mockLedger, - verifyExpectedArtifact: () => true, postUnitPostVerification: async () => { deps.callLog.push("postUnitPostVerification"); s.active = false; diff --git a/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts b/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts index d02ba7bc4..29e82ac59 100644 --- a/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +++ b/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts @@ -195,9 +195,6 @@ function makeMockDeps(overrides?: Partial): LoopDeps & { callLog: stri getPriorSliceCompletionBlocker: () => null, getMainBranch: () => "main", closeoutUnit: async () => {}, - verifyExpectedArtifact: () => true, - clearUnitRuntimeRecord: () => {}, - writeUnitRuntimeRecord: () => {}, recordOutcome: () => {}, writeLock: () => {}, captureAvailableSkills: () => {}, diff --git a/src/resources/extensions/gsd/tests/idle-recovery.test.ts b/src/resources/extensions/gsd/tests/idle-recovery.test.ts index f13b3a32e..664d1480a 100644 --- a/src/resources/extensions/gsd/tests/idle-recovery.test.ts +++ b/src/resources/extensions/gsd/tests/idle-recovery.test.ts @@ -7,7 +7,7 @@ import { writeBlockerPlaceholder, verifyExpectedArtifact, buildLoopRemediationSteps, -} from "../auto.ts"; +} from "../auto-recovery.ts"; import { describe, test, beforeEach, afterEach } from 'node:test'; import assert from 'node:assert/strict'; diff --git a/src/resources/extensions/gsd/tests/journal-integration.test.ts b/src/resources/extensions/gsd/tests/journal-integration.test.ts index c6e637392..ddbc096e5 100644 --- a/src/resources/extensions/gsd/tests/journal-integration.test.ts +++ b/src/resources/extensions/gsd/tests/journal-integration.test.ts @@ -92,9 +92,6 @@ function makeMockDeps( getPriorSliceCompletionBlocker: () => null, getMainBranch: () => "main", closeoutUnit: async () => {}, - verifyExpectedArtifact: () => true, - clearUnitRuntimeRecord: () => {}, - writeUnitRuntimeRecord: () => {}, recordOutcome: () => {}, writeLock: () => {}, captureAvailableSkills: () => {}, diff --git a/src/resources/extensions/gsd/tests/parallel-budget-atomicity.test.ts b/src/resources/extensions/gsd/tests/parallel-budget-atomicity.test.ts index 461beb245..cf2bd048e 100644 --- a/src/resources/extensions/gsd/tests/parallel-budget-atomicity.test.ts +++ b/src/resources/extensions/gsd/tests/parallel-budget-atomicity.test.ts @@ -322,7 +322,6 @@ test("budget — refreshWorkerStatuses updates worker state from disk", async () const workers = getWorkerStatuses(); assert.equal(workers.length, 1); assert.equal(workers[0]!.state, "paused", "worker state should be updated from disk"); - assert.equal(workers[0]!.completedUnits, 5, "completedUnits should be updated from disk"); assert.equal(workers[0]!.cost, 2.5, "cost should be updated from disk"); } finally { resetOrchestrator(); diff --git a/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts b/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts index 9e1564e9e..b4a1bed08 100644 --- a/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +++ b/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts @@ -71,7 +71,6 @@ test('Test 1: persistState writes valid JSON', () => { worktreePath: "/tmp/wt-M001", startedAt: Date.now(), state: "running", - completedUnits: 3, cost: 0.15, }, ], @@ -114,7 +113,6 @@ test('Test 3: restoreState filters dead PIDs', () => { worktreePath: "/tmp/wt-M001", startedAt: Date.now(), state: "running", - completedUnits: 0, cost: 0, }, { @@ -124,7 +122,6 @@ test('Test 3: restoreState filters dead PIDs', () => { worktreePath: "/tmp/wt-M002", startedAt: Date.now(), state: "running", - completedUnits: 0, cost: 0, }, ], @@ -153,7 +150,6 @@ test('Test 4: restoreState keeps alive PIDs', () => { worktreePath: "/tmp/wt-M001", startedAt: Date.now(), state: "running", - completedUnits: 5, cost: 0.25, }, { @@ -163,7 +159,6 @@ test('Test 4: restoreState keeps alive PIDs', () => { worktreePath: "/tmp/wt-M002", startedAt: Date.now(), state: "running", - completedUnits: 0, cost: 0, }, ], @@ -176,7 +171,6 @@ test('Test 4: restoreState keeps alive PIDs', () => { assert.deepStrictEqual(result!.workers.length, 1, "restoreState: filters out dead PID"); assert.deepStrictEqual(result!.workers[0].milestoneId, "M001", "restoreState: keeps alive worker"); assert.deepStrictEqual(result!.workers[0].pid, process.pid, "restoreState: preserves PID"); - assert.deepStrictEqual(result!.workers[0].completedUnits, 5, "restoreState: preserves progress"); } finally { rmSync(basePath, { recursive: true, force: true }); } @@ -194,7 +188,6 @@ test('Test 5: restoreState skips stopped/error workers even with alive PIDs', () worktreePath: "/tmp/wt-M001", startedAt: Date.now(), state: "stopped", - completedUnits: 10, cost: 0.50, }, ], diff --git a/src/resources/extensions/gsd/tests/parallel-merge.test.ts b/src/resources/extensions/gsd/tests/parallel-merge.test.ts index 0e8ddcfd3..9b46cae6e 100644 --- a/src/resources/extensions/gsd/tests/parallel-merge.test.ts +++ b/src/resources/extensions/gsd/tests/parallel-merge.test.ts @@ -70,7 +70,6 @@ function makeWorker(overrides: Partial = {}): WorkerInfo { worktreePath: "/tmp/test", startedAt: Date.now(), state: "stopped", - completedUnits: 3, cost: 1.5, ...overrides, }; @@ -132,16 +131,16 @@ test("determineMergeOrder — by-completion sorts by startedAt (earliest first)" assert.deepEqual(order, ["M003", "M002", "M001"]); }); -test("determineMergeOrder — only includes stopped workers with completedUnits > 0", () => { +test("determineMergeOrder — only includes stopped workers", () => { const workers = [ - makeWorker({ milestoneId: "M001", state: "stopped", completedUnits: 3 }), - makeWorker({ milestoneId: "M002", state: "running", completedUnits: 2 }), - makeWorker({ milestoneId: "M003", state: "stopped", completedUnits: 0 }), - makeWorker({ milestoneId: "M004", state: "error", completedUnits: 5 }), - makeWorker({ milestoneId: "M005", state: "paused", completedUnits: 1 }), + makeWorker({ milestoneId: "M001", state: "stopped" }), + makeWorker({ milestoneId: "M002", state: "running" }), + makeWorker({ milestoneId: "M003", state: "stopped" }), + makeWorker({ milestoneId: "M004", state: "error" }), + makeWorker({ milestoneId: "M005", state: "paused" }), ]; const order = determineMergeOrder(workers, "sequential"); - assert.deepEqual(order, ["M001"]); + assert.deepEqual(order, ["M001", "M003"]); }); test("determineMergeOrder — empty workers returns empty array", () => { diff --git a/src/resources/extensions/gsd/tests/parallel-orchestration.test.ts b/src/resources/extensions/gsd/tests/parallel-orchestration.test.ts index aabd9736c..ab541faaa 100644 --- a/src/resources/extensions/gsd/tests/parallel-orchestration.test.ts +++ b/src/resources/extensions/gsd/tests/parallel-orchestration.test.ts @@ -297,7 +297,6 @@ describe("parallel-orchestrator: lifecycle", () => { worktreePath: "/tmp/wt-M001", startedAt: Date.now(), state: "running", - completedUnits: 2, cost: 0.25, }, ], @@ -309,7 +308,6 @@ describe("parallel-orchestrator: lifecycle", () => { const workers = getWorkerStatuses(base); assert.equal(workers.length, 1); assert.equal(workers[0].milestoneId, "M001"); - assert.equal(workers[0].completedUnits, 2); assert.equal(isParallelActive(), true); } finally { resetOrchestrator(); @@ -416,7 +414,6 @@ describe("parallel-orchestrator: lifecycle", () => { const workers = getWorkerStatuses(); assert.equal(workers.length, 1); assert.equal(workers[0].state, "running"); - assert.equal(workers[0].completedUnits, 4); } finally { resetOrchestrator(); rmSync(base, { recursive: true, force: true }); @@ -552,7 +549,6 @@ function makeWorker(overrides: Partial = {}): WorkerInfo { worktreePath: "/tmp/test-worktree", startedAt: Date.now() - 60_000, state: "stopped", - completedUnits: 5, cost: 2.50, ...overrides, }; @@ -563,9 +559,9 @@ function makeWorker(overrides: Partial = {}): WorkerInfo { describe("parallel-merge: determineMergeOrder sequential", () => { it("returns milestone IDs sorted alphabetically by default", () => { const workers = [ - makeWorker({ milestoneId: "M003", state: "stopped", completedUnits: 1 }), - makeWorker({ milestoneId: "M001", state: "stopped", completedUnits: 2 }), - makeWorker({ milestoneId: "M002", state: "stopped", completedUnits: 3 }), + makeWorker({ milestoneId: "M003", state: "stopped" }), + makeWorker({ milestoneId: "M001", state: "stopped" }), + makeWorker({ milestoneId: "M002", state: "stopped" }), ]; const order = determineMergeOrder(workers, "sequential"); assert.deepEqual(order, ["M001", "M002", "M003"]); @@ -573,27 +569,27 @@ describe("parallel-merge: determineMergeOrder sequential", () => { it("excludes workers that are still running", () => { const workers = [ - makeWorker({ milestoneId: "M001", state: "stopped", completedUnits: 5 }), - makeWorker({ milestoneId: "M002", state: "running", completedUnits: 0 }), - makeWorker({ milestoneId: "M003", state: "stopped", completedUnits: 2 }), + makeWorker({ milestoneId: "M001", state: "stopped" }), + makeWorker({ milestoneId: "M002", state: "running" }), + makeWorker({ milestoneId: "M003", state: "stopped" }), ]; const order = determineMergeOrder(workers, "sequential"); assert.deepEqual(order, ["M001", "M003"]); }); - it("excludes workers with zero completedUnits even if stopped", () => { + it("includes all stopped workers", () => { const workers = [ - makeWorker({ milestoneId: "M001", state: "stopped", completedUnits: 0 }), - makeWorker({ milestoneId: "M002", state: "stopped", completedUnits: 3 }), + makeWorker({ milestoneId: "M001", state: "stopped" }), + makeWorker({ milestoneId: "M002", state: "stopped" }), ]; const order = determineMergeOrder(workers, "sequential"); - assert.deepEqual(order, ["M002"]); + assert.deepEqual(order, ["M001", "M002"]); }); it("returns empty array when no workers are completed", () => { const workers = [ - makeWorker({ milestoneId: "M001", state: "running", completedUnits: 0 }), - makeWorker({ milestoneId: "M002", state: "paused", completedUnits: 0 }), + makeWorker({ milestoneId: "M001", state: "running" }), + makeWorker({ milestoneId: "M002", state: "paused" }), ]; const order = determineMergeOrder(workers); assert.deepEqual(order, []); @@ -601,8 +597,8 @@ describe("parallel-merge: determineMergeOrder sequential", () => { it("uses sequential order as the default when no order arg provided", () => { const workers = [ - makeWorker({ milestoneId: "M002", state: "stopped", completedUnits: 1 }), - makeWorker({ milestoneId: "M001", state: "stopped", completedUnits: 1 }), + makeWorker({ milestoneId: "M002", state: "stopped" }), + makeWorker({ milestoneId: "M001", state: "stopped" }), ]; // Call with no second argument — should default to "sequential" const order = determineMergeOrder(workers); @@ -614,9 +610,9 @@ describe("parallel-merge: determineMergeOrder by-completion", () => { it("returns milestones sorted by startedAt (earliest first)", () => { const now = Date.now(); const workers = [ - makeWorker({ milestoneId: "M003", state: "stopped", completedUnits: 1, startedAt: now - 30_000 }), - makeWorker({ milestoneId: "M001", state: "stopped", completedUnits: 1, startedAt: now - 90_000 }), - makeWorker({ milestoneId: "M002", state: "stopped", completedUnits: 1, startedAt: now - 60_000 }), + makeWorker({ milestoneId: "M003", state: "stopped", startedAt: now - 30_000 }), + makeWorker({ milestoneId: "M001", state: "stopped", startedAt: now - 90_000 }), + makeWorker({ milestoneId: "M002", state: "stopped", startedAt: now - 60_000 }), ]; const order = determineMergeOrder(workers, "by-completion"); assert.deepEqual(order, ["M001", "M002", "M003"]); @@ -625,9 +621,9 @@ describe("parallel-merge: determineMergeOrder by-completion", () => { it("excludes paused workers from by-completion order", () => { const now = Date.now(); const workers = [ - makeWorker({ milestoneId: "M001", state: "stopped", completedUnits: 2, startedAt: now - 90_000 }), - makeWorker({ milestoneId: "M002", state: "paused", completedUnits: 1, startedAt: now - 60_000 }), - makeWorker({ milestoneId: "M003", state: "stopped", completedUnits: 3, startedAt: now - 30_000 }), + makeWorker({ milestoneId: "M001", state: "stopped", startedAt: now - 90_000 }), + makeWorker({ milestoneId: "M002", state: "paused", startedAt: now - 60_000 }), + makeWorker({ milestoneId: "M003", state: "stopped", startedAt: now - 30_000 }), ]; const order = determineMergeOrder(workers, "by-completion"); assert.deepEqual(order, ["M001", "M003"]); diff --git a/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts b/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts index 227abc565..227a3c90a 100644 --- a/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +++ b/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts @@ -155,7 +155,6 @@ describe("parallel-worker-monitoring", () => { worktreePath: "/tmp/wt-M001", startedAt: Date.now(), state: "running", - completedUnits: 1, cost: 0.1, }, ], @@ -191,7 +190,6 @@ describe("parallel-worker-monitoring", () => { refreshWorkerStatuses(base, { restoreIfNeeded: true }); const workers = getWorkerStatuses(); assert.deepStrictEqual(workers[0].state, "running", "live session status restored"); - assert.deepStrictEqual(workers[0].completedUnits, 3, "completed units restored from status file"); } finally { resetOrchestrator(); rmSync(base, { recursive: true, force: true }); diff --git a/src/resources/extensions/gsd/tests/projection-regression.test.ts b/src/resources/extensions/gsd/tests/projection-regression.test.ts index f7bf2c5c4..90a06e7b9 100644 --- a/src/resources/extensions/gsd/tests/projection-regression.test.ts +++ b/src/resources/extensions/gsd/tests/projection-regression.test.ts @@ -52,6 +52,7 @@ function makeTaskRow(overrides?: Partial): TaskRow { key_files: [], key_decisions: [], full_summary_md: '', + full_plan_md: '', description: 'Test description', estimate: '30m', files: ['src/test.ts'], diff --git a/src/resources/extensions/gsd/tests/session-lock-regression.test.ts b/src/resources/extensions/gsd/tests/session-lock-regression.test.ts index dd763640a..86631e525 100644 --- a/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +++ b/src/resources/extensions/gsd/tests/session-lock-regression.test.ts @@ -103,7 +103,7 @@ describe('session-lock-regression', async () => { try { acquireSessionLock(base); - updateSessionLock(base, 'execute-task', 'M001/S01/T01', 5, '/tmp/session.json'); + updateSessionLock(base, 'execute-task', 'M001/S01/T01', '/tmp/session.json'); const data = readSessionLockData(base); assert.ok(data !== null, 'lock data readable after update'); @@ -111,7 +111,6 @@ describe('session-lock-regression', async () => { assert.deepStrictEqual(data.pid, process.pid, 'lock data has correct PID'); assert.deepStrictEqual(data.unitType, 'execute-task', 'lock data has correct unit type'); assert.deepStrictEqual(data.unitId, 'M001/S01/T01', 'lock data has correct unit ID'); - assert.deepStrictEqual(data.completedUnits, 5, 'lock data has correct completed count'); assert.deepStrictEqual(data.sessionFile, '/tmp/session.json', 'lock data has session file'); } @@ -136,7 +135,6 @@ describe('session-lock-regression', async () => { unitType: 'execute-task', unitId: 'M001/S01/T01', unitStartedAt: new Date(Date.now() - 3600000).toISOString(), - completedUnits: 3, }; writeFileSync(lockFile, JSON.stringify(staleLock, null, 2)); @@ -233,7 +231,6 @@ describe('session-lock-regression', async () => { unitType: 'execute-task', unitId: 'M001/S01/T01', unitStartedAt: new Date().toISOString(), - completedUnits: 0, }, null, 2)); const status = getSessionLockStatus(base); diff --git a/src/resources/extensions/gsd/tests/stop-auto-remote.test.ts b/src/resources/extensions/gsd/tests/stop-auto-remote.test.ts index 082827e0c..3fb025241 100644 --- a/src/resources/extensions/gsd/tests/stop-auto-remote.test.ts +++ b/src/resources/extensions/gsd/tests/stop-auto-remote.test.ts @@ -64,7 +64,7 @@ test("stopAutoRemote cleans up stale lock (dead PID) and returns found:false", ( const base = makeTmpBase(); try { // Write a lock with a PID that doesn't exist - writeLock(base, "execute-task", "M001/S01/T01", 3); + writeLock(base, "execute-task", "M001/S01/T01"); // Overwrite PID to a dead one const lock = readCrashLock(base)!; const staleData = { ...lock, pid: 999999999 }; @@ -111,7 +111,6 @@ test("stopAutoRemote sends SIGTERM to a live process and returns found:true", { unitType: "execute-task", unitId: "M001/S01/T01", unitStartedAt: new Date().toISOString(), - completedUnits: 0, }; writeFileSync(join(base, ".gsd", "auto.lock"), JSON.stringify(lockData, null, 2), "utf-8"); @@ -143,7 +142,7 @@ test("lock file should be discoverable at project root, not worktree path", () = try { // Simulate: auto-mode writes lock to project root (the fix) - writeLock(projectRoot, "execute-task", "M001/S01/T01", 0); + writeLock(projectRoot, "execute-task", "M001/S01/T01"); // Second terminal checks project root — should find the lock const lock = readCrashLock(projectRoot); diff --git a/src/resources/extensions/gsd/tests/workflow-events.test.ts b/src/resources/extensions/gsd/tests/workflow-events.test.ts index ee3f7f9ec..ffad719be 100644 --- a/src/resources/extensions/gsd/tests/workflow-events.test.ts +++ b/src/resources/extensions/gsd/tests/workflow-events.test.ts @@ -22,7 +22,7 @@ function cleanupDir(dirPath: string): void { try { fs.rmSync(dirPath, { recursive: true, force: true }); } catch { /* best effort */ } } -function makeEvent(cmd: string, params: Record = {}): Omit { +function makeEvent(cmd: string, params: Record = {}): Omit { return { cmd, params, ts: new Date().toISOString(), actor: 'agent' }; } diff --git a/src/resources/extensions/gsd/tests/workflow-projections.test.ts b/src/resources/extensions/gsd/tests/workflow-projections.test.ts index 764079155..cf21052e2 100644 --- a/src/resources/extensions/gsd/tests/workflow-projections.test.ts +++ b/src/resources/extensions/gsd/tests/workflow-projections.test.ts @@ -54,6 +54,7 @@ function makeTask(overrides: Partial = {}): TaskRow { key_files: [], key_decisions: [], full_summary_md: '', + full_plan_md: '', inputs: [], expected_output: [], observability_impact: '',