fix(events): the last two live task:moved emitters carry the resolved lanes (#3135)
## The last two live emitters #3109 attached lanes at `moves.ts`. #3120 attached them at the archive and completion emits. Two live emitters were still sending `lanes: undefined`: ``` task-update.ts:962 todo -> triage update-task-deps.ts:502 emits to: task.column — the row's ACTUAL lane ``` A listener reads absence as "unknown" and falls back to `resolveTaskParkedColumnsSync`, which returns the **default board** for every task under PostgreSQL. So these two paths kept the pre-#3109 behaviour while the listener code reads as resolved at every site. `update-task-deps.ts` is the sharper of the two: it emits `to: task.column`, the row's real lane, so on a renamed board it sends e.g. `"shipped"` to a listener comparing against `"done"`. The emitter had already resolved the board and threw the answer away. Nothing errors; the branch stops firing. ## Emitter coverage after this ``` LANES moves.ts:1450 (#3109) LANES archive-lifecycle-2.ts:385 (#3120) LANES task-artifacts-ops.ts:578 (#3120) LANES task-update.ts:970 (this PR) LANES update-task-deps.ts:504 (this PR) MISSING lifecycle-ops.ts:668 deliberate — see below MISSING lifecycle-ops.ts:715 deliberate — see below ``` **Every emitter that can execute under the shipped backend now carries lanes.** ## Flagged — the two I did NOT convert `lifecycle-ops.ts:668` and `:715` stay lane-less on purpose. Both sit on the polling-replica path that file already documents as legacy-SQLite-only — it reaches `store.db`, which throws under PostgreSQL — and the same note argues against spending a signature change on dead code. I agreed rather than overrode it. If that path is ever revived they must be attached, because absence resolves to the default board rather than to nothing. ## Supersedes my own earlier PR This replaces **#3119**, which carried four emitters. #3120 landed two of them first, so I rebuilt against current `main` with only the remainder rather than resolving a conflict into a half-redundant diff. #3119 is closed with nothing lost. ## Census before / after ``` before: COLUMN guards (the backlog): 17 after: COLUMN guards (the backlog): 17 ``` Unchanged — this converts no guards. It makes the resolved answer *reach* guards that were already converted, which is the half that was missing. ## Verification Full `@fusion/core` suite **462 files / 4906 passed, 0 failed** · `test:gate` exit 0 · typecheck exit 0 · lifecycle-column census exit 0 · `pnpm lint` clean. ## Still open `main` is **red on `check:inert-sync-lanes`** and nothing in CI runs it — **#3127** fixes both halves. **#3122** restores 13 guards laundered through `mergeParkedColumns`. **#3131** corrects a 44% under-report in `--triage`.
This commit is contained in:
@@ -7,6 +7,8 @@
|
||||
* instance as its first parameter and performs byte-identical work.
|
||||
*/
|
||||
import {type TaskStore, storeLog} from "../store.js";
|
||||
import {toTaskMoveLanes} from "../workflow-lifecycle-traits.js";
|
||||
import {resolveWorkflowIrForTask} from "../workflow-ir-resolver.js";
|
||||
import {resolveTaskLifecycleColumns} from "../workflow-lifecycle-traits.js";
|
||||
import {InvalidFileScopeError} from "./errors.js";
|
||||
import {mkdir, readFile, writeFile} from "node:fs/promises";
|
||||
@@ -959,7 +961,14 @@ export async function updateTaskUnlockedImpl(store: TaskStore, id: string, updat
|
||||
}
|
||||
|
||||
if (movedToTriage) {
|
||||
store.emit("task:moved", { task, from: "todo" as Column, to: "triage" as Column, source: "engine" });
|
||||
/* FNXC:WorkflowEvents 2026-08-01-05:10 (fleet — the last two emitters):
|
||||
#3109 attached lanes at moves.ts and #3120 at the archive/completion emits. This one and
|
||||
`update-task-deps.ts` were still sending `lanes: undefined`, and a listener reads absence as
|
||||
"unknown" and falls back to `resolveTaskParkedColumnsSync` — the DEFAULT board under
|
||||
PostgreSQL. So these two paths kept the pre-#3109 behaviour while the listeners read as
|
||||
resolved. */
|
||||
const lanes = toTaskMoveLanes(await resolveWorkflowIrForTask(store, id).catch(() => undefined));
|
||||
store.emit("task:moved", { task, from: "todo" as Column, to: "triage" as Column, source: "engine", lanes });
|
||||
}
|
||||
store.emitTaskLifecycleEventSafely("task:updated", [task]);
|
||||
return task;
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
* instance as its first parameter and performs byte-identical work.
|
||||
*/
|
||||
import {TaskStore, storeLog, type TaskDependencyMutation} from "../store.js";
|
||||
import {toTaskMoveLanes} from "../workflow-lifecycle-traits.js";
|
||||
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";
|
||||
@@ -504,6 +506,7 @@ export async function updateTaskDependenciesImpl(store: TaskStore, id: string, m
|
||||
from: respecifyFromColumn as Column,
|
||||
to: task.column as Column,
|
||||
source: "engine",
|
||||
lanes: toTaskMoveLanes(await resolveWorkflowIrForTask(store, task.id).catch(() => undefined)),
|
||||
});
|
||||
}
|
||||
store.emitTaskLifecycleEventSafely("task:updated", [task]);
|
||||
|
||||
Reference in New Issue
Block a user