Files
fusion/scripts/lib
gsxdsm 24c565540e gate: a sync lane handed to a wrapper is still inert — 13 scheduler guards were invisible (#3181)
## The fourth shape: a sync lane handed to a wrapper

#3169 taught `unwrapForSyncCall` to walk await, parenthesized,
conditional and binary expressions. It still stops at the **call
boundary**, so a source call sitting in an *argument* position stays
invisible:

```ts
const parked = mergeParkedColumns(resolveTaskParkedColumnsSync(store, id), lanes);
```

That prefers the event payload and falls back to the sync answer
whenever `lanes` is absent. The callee is `mergeParkedColumns`, not a
source — so the walker never looked inside, and **the entire
`scheduler.ts` file read as clean**.

```
main today:   9   (triage 7, executor 2, scheduler 0)
this PR:     22   (scheduler 13, triage 7, executor 2)
```

Thirteen guards. And `check:inert-sync-lanes` has run in `test:gate`
since #3136, so CI is currently enforcing a ratchet that reports a file
it cannot see into as fully converted. The green is official, which
makes it worse than the version nobody ran.

## Is the fallback still reachable?

Yes, which is why these are not retired. #3135 attached lanes at every
*live* emitter, but absence remains reachable three ways: the two
`lifecycle-ops.ts` emitters on the SQLite-only polling path, any future
emitter added without lanes, and the three forwarders
(`project-manager.ts`, `remote-node-runtime.ts`,
`child-process-runtime.ts`) that reconstruct the event object
field-by-field rather than forwarding it.

A rarely-exercised fallback is still a fallback. Counting it as clean is
how the ledger stops meaning anything.

## The change

One line inside your walker, plus its note:

```js
if (ts.isCallExpression(n)) { for (const a of n.arguments) walk(a); }
```

Every shape #3169 added is preserved. Still a name match, not dataflow —
the limits section still applies.

## Mutation evidence — all three shapes, one tree

| Mutant | Result |
|---|---|
| baseline (22) | exit 0 |
| **argument position** (this PR) | **exit 1**, 13 → 14 |
| conditional (#3169's) | exit 1, 13 → 14 |
| inline (#3062's) | exit 1, 13 → 14 |

`scheduler.ts` restored clean after each run.

## Baseline 9 → 22

**Detection, not regression.** No production file changes in this PR. 22
is the exact union I measured before #3169 merged (13 + 7 + 2) and
posted on both PRs at the time — it landing unchanged is the
confirmation that the two fixes were additive rather than overlapping.

## Census before / after

```
before:  COLUMN guards (the backlog):   12
after:   COLUMN guards (the backlog):   12
```

Unchanged — this converts nothing. It restores 13 guards to a ledger
that had silently dropped them.

## Supersedes #3122

#3122 carried this fix as a standalone rewrite of `syncLaneLocals` and
conflicted with #3169 the moment it landed. This is the six-line version
I offered there; #3122 is closed.

## Verification

`test:gate` exit 0 · `check:inert-sync-lanes` exit 0 at the re-recorded
baseline · plus `fnxc-future-dates`, `lifecycle-columns`,
`quarantine-ledger`, `inert-flag-seams`, `lane-wiring`,
`sql-column-literals` — all exit 0. Gate script + baseline only.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved detection of synchronous operations nested within wrapper
arguments.
* Updated synchronization checks to report all currently identified
findings, including additional scheduler-related cases.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-31 08:56:32 -07:00
..