fix(respecify): skip stale spec enforcement for in-progress/in-review/done tasks
Background stale spec checks now skip tasks that are already in an active work state (in-progress, in-review, done, merging, merging-pr) to avoid interrupting work that is underway or complete. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -13,7 +13,7 @@ import * as nodeFs from "node:fs";
|
||||
import * as nodeChildProcess from "node:child_process";
|
||||
import { promisify } from "node:util";
|
||||
import type { TaskStore, Column, MergeResult, ScheduleType, ActivityEventType, ModelPreset, AutomationStep, MessageType, ParticipantType, MessageCreateInput, Routine, RoutineCreateInput, RoutineUpdateInput, RoutineExecutionResult, RoutineTriggerType } from "@fusion/core";
|
||||
import { COLUMNS, VALID_TRANSITIONS, GLOBAL_SETTINGS_KEYS, type BatchStatusEntry, type BatchStatusResponse, type BatchStatusResult, type IssueInfo, type PrInfo, type Task, getCurrentRepo, isGhAuthenticated, AUTOMATION_PRESETS, AutomationStore, validateBackupSchedule, validateBackupRetention, validateBackupDir, syncBackupAutomation, exportSettings, importSettings, validateImportData, MessageStore, MEMORY_FILE_PATH, RoutineStore, isWebhookTrigger, resolveMemoryBackend, getMemoryBackendCapabilities, listMemoryBackendTypes, type MemoryBackendCapabilities } from "@fusion/core";
|
||||
import { COLUMNS, VALID_TRANSITIONS, GLOBAL_SETTINGS_KEYS, type BatchStatusEntry, type BatchStatusResponse, type BatchStatusResult, type IssueInfo, type PrInfo, type Task, getCurrentRepo, isGhAuthenticated, AutomationStore, validateBackupSchedule, validateBackupRetention, validateBackupDir, syncBackupAutomation, exportSettings, importSettings, validateImportData, MessageStore, MEMORY_FILE_PATH, RoutineStore, isWebhookTrigger, resolveMemoryBackend, getMemoryBackendCapabilities, listMemoryBackendTypes, type MemoryBackendCapabilities } from "@fusion/core";
|
||||
import type { ChatStore, ChatSessionCreateInput, ChatSessionUpdateInput } from "@fusion/core";
|
||||
import type { ServerOptions } from "./server.js";
|
||||
import { GitHubClient, parseBadgeUrl } from "./github.js";
|
||||
|
||||
@@ -896,16 +896,23 @@ export class TaskExecutor {
|
||||
// execute() to prevent stale tasks from entering worktree creation or agent sessions.
|
||||
// If timestamp evaluation is skipped (missing/unreadable file), continue with execution
|
||||
// so existing filesystem validation paths remain authoritative.
|
||||
const tasksDir = join(this.store.getFusionDir(), "tasks");
|
||||
const promptPath = getPromptPath(tasksDir, task.id);
|
||||
const staleness = await evaluateSpecStaleness({ settings, promptPath });
|
||||
if (staleness.isStale) {
|
||||
executorLog.warn(`Task ${task.id} specification is stale — ${staleness.reason}`);
|
||||
// Move to triage first, then set status so the task enters triage with needs-respecify
|
||||
await this.store.moveTask(task.id, "triage");
|
||||
await this.store.updateTask(task.id, { status: "needs-respecify" });
|
||||
await this.store.logEntry(task.id, staleness.reason, undefined, this.currentRunContext);
|
||||
return;
|
||||
// Skip for tasks that are already in-progress, in-review, merging, or done —
|
||||
// these should not be interrupted and sent back to triage for respecification.
|
||||
const activeColumns = new Set(["in-progress", "in-review", "done"]);
|
||||
const activeMergeStatuses = new Set(["merging", "merging-pr"]);
|
||||
const isActiveTask = activeColumns.has(task.column) || activeMergeStatuses.has(task.status ?? "");
|
||||
if (!isActiveTask) {
|
||||
const tasksDir = join(this.store.getFusionDir(), "tasks");
|
||||
const promptPath = getPromptPath(tasksDir, task.id);
|
||||
const staleness = await evaluateSpecStaleness({ settings, promptPath });
|
||||
if (staleness.isStale) {
|
||||
executorLog.warn(`Task ${task.id} specification is stale — ${staleness.reason}`);
|
||||
// Move to triage first, then set status so the task enters triage with needs-respecify
|
||||
await this.store.moveTask(task.id, "triage");
|
||||
await this.store.updateTask(task.id, { status: "needs-respecify" });
|
||||
await this.store.logEntry(task.id, staleness.reason, undefined, this.currentRunContext);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Hoist worktreePath so it's accessible in the catch block for dep-abort cleanup
|
||||
|
||||
Reference in New Issue
Block a user