Files
fusion/scripts
gsxdsm 0b30eb4146 fix(gate): detect ternary move-target literals, which #3246's ratchet could not see (#3250)
## What

#3246 landed a gate holding `moveTask` legacy-literal destinations at
zero, printing **"POPULATION EMPTY … keep it empty."** I probed that
claim the way #3247 probed the census. It held for two spellings and not
a third.

| form | before | after |
|---|---|---|
| `moveTask(id, "done")` | ✅ | ✅ |
| `` moveTask(id, `todo`) `` | ✅ | ✅ |
| `moveTask(id, ok ? "done" : "in-review")` | ❌ **invisible** | ✅ |

The check required `arguments[1]` to *be* a literal. A ternary over two
lanes is a natural way to write exactly the destination this gate exists
to prevent — and per the gate's own header, a wrong target **throws** at
runtime rather than no-opping.

## Measured

```
real repo, before and after:  0 targets, --strict passes   (no false positives)
ternary probe:                0 on HEAD~1  ->  1 after
direct + backtick forms:      unchanged
DELIBERATE-LITERAL marker:    still suppresses (canonical placement)
lint clean; fnxc-future-dates: none added
```

## Two scoping decisions, both probed rather than assumed

**Not descending into `??` / `||`.** `moveTask(id, lanes.complete ??
"done")` is the documented degraded arm this program writes deliberately
— the shape the lifecycle census classifies as `traitFallback` rather
than backlog. Counting it would report correct code as debt. Measured at
0 both before and after.

**`const t = "archived"; moveTask(id, t)` is still undetected**, and the
comment says so at the site. Resolving it needs symbol/dataflow analysis
rather than a shape test, which is a different tool than this file is.
Flagged so the next person extends deliberately instead of assuming
coverage.

## No unit test, and why

The script has no export seam and executes at import, so testing it
means extracting one — a refactor of a one-commit-old file, which
belongs in its own change rather than folded into a behaviour fix. The
revert-proof is the measurement above: the ternary probe reads 0 against
`HEAD~1` and 1 against this commit.

## Note to #3246's author

I raised these gaps on your PR first and offered to send this rather
than assume. Two traps that cost me time on the census extension, in
case you take it further:

- **A count-unless-excluded rule backfires on this vocabulary.** My
first census extension counted `switch (x)` unless the receiver looked
like a role/status and reported 7 guards — 6 were `switch (eventName)` /
`switch (state)` / `switch (event)`, since event enums routinely carry
`case "done"`. Requiring a *positive* column signal was the fix.
- **Verify the probe file is git-tracked.** My first probe measured
nothing because the scanner enumerates tracked files; the scanned-file
count stayed flat and I nearly read that as "no gap."
2026-07-31 15:19:11 -07:00
..