diff --git a/packages/cli/src/commands/task.ts b/packages/cli/src/commands/task.ts index 6c3c16693f..cccc69f719 100644 --- a/packages/cli/src/commands/task.ts +++ b/packages/cli/src/commands/task.ts @@ -1604,7 +1604,10 @@ export async function runTaskImportGitHubInteractive( const task = await retryBoardCall(context, "import", "create task", () => store.createTask({ title: title || undefined, description, - column: "triage", + /* FNXC:WorkflowLifecycleColumns 2026-07-29-20:15 (U11): no explicit column — + `createTaskImpl` resolves the WORKFLOW'S intake column, and `input.column` would + override it. Hard-coding `"triage"` created the card in a column the default + lineage no longer declares (#2515), i.e. straight into the stranded state. */ dependencies: [], sourceIssue: source.sourceIssue, source: { @@ -1777,7 +1780,10 @@ export async function runTaskImportFromGitHub( const task = await retryBoardCall(context, "import", "create task", () => store.createTask({ title: title || undefined, description, - column: "triage", + /* FNXC:WorkflowLifecycleColumns 2026-07-29-20:15 (U11): no explicit column — + `createTaskImpl` resolves the WORKFLOW'S intake column, and `input.column` would + override it. Hard-coding `"triage"` created the card in a column the default + lineage no longer declares (#2515), i.e. straight into the stranded state. */ dependencies: [], sourceIssue: source.sourceIssue, source: { @@ -1852,7 +1858,10 @@ export async function runTaskImportFromGitLab( const task = await retryBoardCall(context, "import", "create task", () => store.createTask({ title: title || undefined, description: dashboard.buildGitLabTaskDescription(item), - column: "triage", + /* FNXC:WorkflowLifecycleColumns 2026-07-29-20:15 (U11): no explicit column — + `createTaskImpl` resolves the WORKFLOW'S intake column, and `input.column` would + override it. Hard-coding `"triage"` created the card in a column the default + lineage no longer declares (#2515), i.e. straight into the stranded state. */ dependencies: [], sourceIssue: provenance.sourceIssue, gitlabTracking: provenance.gitlabTracking, diff --git a/packages/cli/src/extension.ts b/packages/cli/src/extension.ts index 4515447f80..c6053172b3 100644 --- a/packages/cli/src/extension.ts +++ b/packages/cli/src/extension.ts @@ -2298,7 +2298,10 @@ export default function kbExtension(pi: ExtensionAPI) { const task = await store.createTask({ title: title || undefined, description, - column: "triage", + /* FNXC:WorkflowLifecycleColumns 2026-07-29-20:15 (U11): no explicit column — + `createTaskImpl` resolves the WORKFLOW'S intake column, and `input.column` would + override it. Hard-coding `"triage"` created the card in a column the default + lineage no longer declares (#2515), i.e. straight into the stranded state. */ dependencies: [], sourceIssue: source.sourceIssue, source: { @@ -2393,7 +2396,10 @@ export default function kbExtension(pi: ExtensionAPI) { const task = await store.createTask({ title: title || undefined, description, - column: "triage", + /* FNXC:WorkflowLifecycleColumns 2026-07-29-20:15 (U11): no explicit column — + `createTaskImpl` resolves the WORKFLOW'S intake column, and `input.column` would + override it. Hard-coding `"triage"` created the card in a column the default + lineage no longer declares (#2515), i.e. straight into the stranded state. */ dependencies: [], sourceIssue: source.sourceIssue, source: { @@ -2530,7 +2536,7 @@ export default function kbExtension(pi: ExtensionAPI) { const provenance = dashboard.buildGitLabTaskProvenance({ auth: client.auth, resourceType, item, projectInput: resourceType !== "group_issue" ? target : undefined, groupInput: resourceType === "group_issue" ? target : undefined }); if (existingTasks.some((task) => dashboard.isGitLabAlreadyImported(task, provenance))) continue; const title = resourceType === "merge_request" ? `Review MR !${item.iid}: ${item.title.slice(0, 180)}` : item.title.slice(0, 200); - const task = await store.createTask({ title: title || undefined, description: dashboard.buildGitLabTaskDescription(item), column: "triage", dependencies: [], sourceIssue: provenance.sourceIssue, gitlabTracking: provenance.gitlabTracking, source: { sourceType: "gitlab_import", sourceMetadata: provenance.sourceMetadata } }); + const task = await store.createTask({ title: title || undefined, description: dashboard.buildGitLabTaskDescription(item), dependencies: [], sourceIssue: provenance.sourceIssue, gitlabTracking: provenance.gitlabTracking, source: { sourceType: "gitlab_import", sourceMetadata: provenance.sourceMetadata } }); await store.logEntry(task.id, resourceType === "merge_request" ? "Imported merge request from GitLab" : "Imported from GitLab", item.webUrl); existingTasks.push(task); createdTasks.push({ id: task.id, title: task.title || item.title }); diff --git a/packages/engine/src/__tests__/pr-comment-handler.test.ts b/packages/engine/src/__tests__/pr-comment-handler.test.ts index 863fe9c9c8..f87c2ea0f4 100644 --- a/packages/engine/src/__tests__/pr-comment-handler.test.ts +++ b/packages/engine/src/__tests__/pr-comment-handler.test.ts @@ -245,10 +245,20 @@ describe("PrCommentHandler", () => { }, ]); + /* + FNXC:WorkflowLifecycleColumns 2026-07-29-20:40 (U11): + This asserted `column: "triage"` and so PINNED the defect. `createTaskImpl` + resolves the column as `input.column || resolvedEntryColumn || fallbackIntake + || "triage"`, so an explicit column OVERRIDES the workflow's intake — and + after #2515 `triage` is not a column the default lineage declares, so the + follow-up was created straight into the stranded state. + + Now asserts the invariant instead of the id: the caller passes NO column, so + whatever intake the task's workflow declares is what wins. + */ expect(mockStore.createTask).toHaveBeenCalledWith({ title: "Follow-up: Address PR #42 feedback", description: expect.stringContaining("FN-001"), - column: "triage", dependencies: ["FN-001"], source: { sourceType: "api", @@ -259,6 +269,8 @@ describe("PrCommentHandler", () => { }, }, }); + const [createArg] = (mockStore.createTask as unknown as { mock: { calls: [Record][] } }).mock.calls[0]; + expect(Object.hasOwn(createArg, "column")).toBe(false); }); it("does nothing when no unaddressed comments", async () => { diff --git a/packages/engine/src/eval-followups.ts b/packages/engine/src/eval-followups.ts index 7e9e0fdf91..8183823218 100644 --- a/packages/engine/src/eval-followups.ts +++ b/packages/engine/src/eval-followups.ts @@ -230,7 +230,10 @@ export async function materializeEvalFollowUps(input: MaterializeEvalFollowUpsIn `Rationale: ${followUp.rationale}`, `Evidence refs: ${followUp.evidenceRefs.map((ref) => ref.evidenceId).join(", ") || "none"}`, ].join("\n"), - column: "triage", + /* FNXC:WorkflowLifecycleColumns 2026-07-29-20:15 (U11): no explicit column — + `createTaskImpl` resolves the WORKFLOW'S intake column, and `input.column` would + override it. Hard-coding `"triage"` created the card in a column the default + lineage no longer declares (#2515), i.e. straight into the stranded state. */ priority: followUp.priority, source: { sourceType: "automation", diff --git a/packages/engine/src/pr-comment-handler.ts b/packages/engine/src/pr-comment-handler.ts index d8cd398dda..e0436db413 100644 --- a/packages/engine/src/pr-comment-handler.ts +++ b/packages/engine/src/pr-comment-handler.ts @@ -251,7 +251,10 @@ Please review the PR comments and address any remaining issues.`; const task = await this.store.createTask({ title: `Follow-up: Address PR #${prInfo.number} feedback`, description, - column: "triage", + /* FNXC:WorkflowLifecycleColumns 2026-07-29-20:15 (U11): no explicit column — + `createTaskImpl` resolves the WORKFLOW'S intake column, and `input.column` would + override it. Hard-coding `"triage"` created the card in a column the default + lineage no longer declares (#2515), i.e. straight into the stranded state. */ dependencies: [originalTaskId], source: { sourceType: "api", diff --git a/packages/engine/src/triage.ts b/packages/engine/src/triage.ts index 4144ac2bcb..73e4a0e452 100644 --- a/packages/engine/src/triage.ts +++ b/packages/engine/src/triage.ts @@ -3278,7 +3278,10 @@ export class TriageProcessor { title: params.title, description: params.description, dependencies: validDeps, - column: "triage", + /* FNXC:WorkflowLifecycleColumns 2026-07-29-20:15 (U11): no explicit column — + `createTaskImpl` resolves the WORKFLOW'S intake column, and `input.column` would + override it. Hard-coding `"triage"` created the card in a column the default + lineage no longer declares (#2515), i.e. straight into the stranded state. */ priority: params.priority, workflowId: params.workflow_id, noCommitsExpected: params.noCommitsExpected,