Files
fusion/packages
gsxdsm 41cdcc741e fix(events): carry resolved lanes on task:moved so listener guards stop being inert (#3109)
Removes the **inert-guard class at its source** instead of one call site
at a time. Independent of my other branches.

## The problem

`task:moved` listeners run synchronously, so a listener needing a lane
answer had to resolve one synchronously — and
`resolveTaskWorkflowIrSync` returns the **default** workflow under
PostgreSQL, the shipped backend. Every such guard behaved exactly as the
literal it replaced, while the census scored it as converted.

**Resolving asynchronously inside the listener is not available**, and
that is measured rather than assumed. The scheduler's
`snapshotManager.invalidate` is asserted to run in the listener's
**synchronous prologue**; putting an await ahead of it produced **3
failures across 21 scheduler suites**.

## The fix

The emitter carries the answer, which removes the dilemma rather than
trading one horn for the other. `moves.ts` is already async and already
post-commit, so it resolves the moving task's lanes **once** and hands
them to every listener. The guard becomes correct **and** the prologue
stays synchronous.

This is the file's own recorded preferred fix — *"having the emitter
carry the resolved lanes on the event payload so no listener resolves at
all"* — now that the audit it was waiting on is done and came back as
**one** prologue-dependent consumer, not a class.

## Design choices

- **`lanes` is optional and fail-soft to `undefined`** — "unknown",
never "legacy". Some emit paths fire from sync contexts or a cached row
mid-teardown. Listeners keep their existing fallback, so those paths are
no better than before but **no worse**, and they become the exception
rather than the rule.
- **`mergeParkedColumns` overlays only fields the emitter actually
resolved**, so a partial payload cannot blank a lane back to a wrong
answer.
- **The sync resolver stays** as that fallback. Deleting it would strand
the emit paths that cannot resolve.

## Verification

- **Revert-proof and it pins the prologue:** the new case asserts
invalidation on a **renamed** hold lane with **no `waitFor`**. Ignoring
the payload gives **0 calls**.
- 21 scheduler suites — **361 green**
- self-healing + notification suites — **491 green**
- core moves + the `sync-workflow-ir-callsite-allowlist` ratchet — green
- **`pnpm test:gate` green** (71)
- Changeset added; `check:changesets` passes

## What it unblocks

`scheduler.ts`'s 10 allow-listed guards now resolve correctly for every
move that goes through `moves.ts` — the path real moves take. Those were
already absent from the backlog, so **the census number does not move**;
what changes is that they now do what the number claimed.
`executor.ts`'s 4 remaining sites can follow the same pattern in a
separate PR.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-31 04:47:09 -07:00
..
2026-07-26 18:11:47 -07:00