From a20ddf6ed65c98aa71c2d11209cf94d0e38cb545 Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Fri, 31 Jul 2026 15:08:20 -0700 Subject: [PATCH] fix(core): refine + duplicate create into the resolved intake lane, not the deleted triage column Co-Authored-By: Claude Fable 5 --- .changeset/refine-duplicate-intake-lane.md | 7 +++++++ .../postgres/refine-duplicate-task.pg.test.ts | 4 +++- packages/core/src/task-store/project-store-ops.ts | 8 +++++++- packages/core/src/task-store/task-creation.ts | 12 +++++++++++- packages/core/src/task-store/update-task-deps.ts | 12 +++++++++++- 5 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 .changeset/refine-duplicate-intake-lane.md diff --git a/.changeset/refine-duplicate-intake-lane.md b/.changeset/refine-duplicate-intake-lane.md new file mode 100644 index 0000000000..6145768d2b --- /dev/null +++ b/.changeset/refine-duplicate-intake-lane.md @@ -0,0 +1,7 @@ +--- +"@runfusion/fusion": patch +--- + +summary: Refined and duplicated tasks land in the workflow's Planning column instead of a deleted legacy column. +category: fix +dev: task_refine (update-task-deps.ts) and task_duplicate (project-store-ops.ts) hardcoded column "triage"; both now resolve resolveWorkflowIntakeFacts().intake with the literal as last resort. Symptom: amber PLANNING badge (badge color keys off raw column id) on cards in an undeclared column. diff --git a/packages/core/src/__tests__/postgres/refine-duplicate-task.pg.test.ts b/packages/core/src/__tests__/postgres/refine-duplicate-task.pg.test.ts index 3549fdaf8d..b6f641850f 100644 --- a/packages/core/src/__tests__/postgres/refine-duplicate-task.pg.test.ts +++ b/packages/core/src/__tests__/postgres/refine-duplicate-task.pg.test.ts @@ -43,7 +43,9 @@ pgDescribe("refineTask / duplicateTask backend mode (PostgreSQL)", () => { expect(refined.id).not.toBe(source.id); expect(refined.sourceType).toBe("task_refine"); expect(refined.sourceParentTaskId).toBe(source.id); - expect(refined.column).toBe("triage"); + // FNXC:MergedPlanningColumn 2026-07-31-22:40: refine resolves the workflow intake lane; the + // default coding workflow's intake is the merged `todo` Planning column ("triage" is deleted). + expect(refined.column).toBe("todo"); expect(refined.dependencies).toEqual([source.id]); expect(refined.description).toContain("Please tighten the empty-state copy"); diff --git a/packages/core/src/task-store/project-store-ops.ts b/packages/core/src/task-store/project-store-ops.ts index 620b40afa5..d7397c79b1 100644 --- a/packages/core/src/task-store/project-store-ops.ts +++ b/packages/core/src/task-store/project-store-ops.ts @@ -10,6 +10,7 @@ */ import {TaskStore, storeLog, WORKFLOW_COMPILED_STEP_TEMPLATE_PREFIX, WORKFLOW_MOVE_POLICY_TIMEOUT_MS} from "../store.js"; import { resolveCapacityPoolId } from "../workflow-capacity.js"; +import {resolveWorkflowIntakeFacts} from "./task-creation.js"; import {TransitionRejectionError} from "./errors.js"; import * as schema from "../postgres/schema/index.js"; import {and, eq, isNull, ne, or, sql} from "drizzle-orm"; @@ -208,7 +209,12 @@ export async function duplicateTaskImpl(store: TaskStore, id: string): Promise { diff --git a/packages/core/src/task-store/update-task-deps.ts b/packages/core/src/task-store/update-task-deps.ts index b3bdfc8ea8..35c9ae4b04 100644 --- a/packages/core/src/task-store/update-task-deps.ts +++ b/packages/core/src/task-store/update-task-deps.ts @@ -12,6 +12,7 @@ import {resolveWorkflowIrForTask} from "../workflow-ir-resolver.js"; import {buildRefinementSeedPrompt} from "../mesh-task-replication.js"; import {SelfDefeatingDependencyError, detectSelfDefeatingDependency} from "./errors.js"; import {resolveTaskLifecycleColumns} from "../workflow-lifecycle-traits.js"; +import {resolveWorkflowIntakeFacts} from "./task-creation.js"; import type {WorkflowIr} from "../workflow-ir-types.js"; import {mkdir, readFile, writeFile} from "node:fs/promises"; import {join} from "node:path"; @@ -111,6 +112,15 @@ export async function refineTaskImpl(store: TaskStore, id: string, feedback: str }); } + /* + FNXC:MergedPlanningColumn 2026-07-31-22:35 (missed creation surface — refine): + Resolve the inherited workflow's intake lane instead of the legacy `"triage"` literal. The + hardcoded id landed refinements in a column the merged coding workflow no longer declares — + surfaced on the live board as an amber PLANNING badge (badge color keys off the raw column id) + on a card invisible to trait-driven sweeps until the undeclared-column re-home. Literal survives + only as the last resort for a store that cannot resolve any workflow, matching createTask. + */ + const refineIntakeColumn = (await resolveWorkflowIntakeFacts(store, pendingWorkflowSelection?.workflowId)).intake ?? "triage"; const newTask = await store.createTaskWithDistributedReservation({ description: feedback.trim() }, { createTaskWithId: async (newId) => { // FN-5077: keep deterministic "Refinement" fallback when normalized refinement label is unusable (null). @@ -138,7 +148,7 @@ export async function refineTaskImpl(store: TaskStore, id: string, feedback: str title: normalizedTitle.title ?? "Refinement", description: `${feedback.trim()}\n\nRefines: ${id}`, priority: normalizeTaskPriority(sourceTask.priority), - column: "triage", + column: refineIntakeColumn as Task["column"], dependencies: [id], sourceType: "task_refine", sourceParentTaskId: id,