Files
fusion/packages/core/src
gsxdsm b752f9014d fix(core): a hold-only column vanished from the SDLC funnel (+ un-red the census on main) (#2674)
Two things, both small, one urgent.

## 1. Hold-only columns disappeared from the funnel

`hold` was absent from `TRAIT_TO_STAGE`, so a column whose only
pre-implementation trait is `hold` — a renamed board's wait-for-capacity
lane — resolved to `OTHER` and vanished from the SDLC funnel.

Measured before the fix:

```
stageForTraits(["hold"]) === "other"
```

The default lineage hid it: its Planning column also carries `intake`
and `reset-on-entry`, so it always matched something. Only a board that
names its wait lane separately was affected — **exactly the custom shape
this trait mapping exists to support**.

Revert check: removing the entry gives `expected 'other' to be 'todo'`.

## What I deliberately did NOT fix, and why

The merged default Planning column carries
`["intake","hold","reset-on-entry"]`, and `stageForTraits` prefers the
earliest stage in flow order — so `intake` wins and it still resolves to
`triage`. The `todo` stage therefore stays empty on every default board
since U11, and the funnel shows a **phantom 100% drop between Triage and
Todo**.

That is a real defect. It is also not a reversible call: changing which
stage Planning reports would retroactively alter how historical
analytics read. Flagged on #2669 for a product decision.

Adding `hold` does not touch it — `intake` still outranks — and a second
test **pins the current behaviour** so the larger question gets answered
deliberately rather than drifted into by a future edit to this map.

## 2. `check:lifecycle-columns` is RED on pristine `origin/main` — again

```
census exit on pristine main = 1
  packages/engine/src/executor.ts: allows 87, tree has 85
```

`executor.ts` is a file this PR does not touch, so a merge lowered the
count without re-recording and the blocking PR check is failing for
**every open PR**. The re-record is mechanical and is included here to
unblock it — called out explicitly because it is unrelated to the funnel
fix and should not ride along unexplained.

This is the second time the baseline has gone stale on main this way.
The rule works (`--strict` caught it immediately); what is missing is
that it caught it *after* the merge. Worth considering whether the
census should run on the merge queue rather than only on PR head —
otherwise a PR that is green when opened can still land a stale
baseline.

## Verification

`pnpm test:gate` green (10 / 158 / 487 / 71). `pnpm
check:lifecycle-columns` exits 0 after the re-record. `tsc -p
packages/core/tsconfig.json` clean. `pnpm lint` clean.
`sdlc-funnel-default-columns.test.ts` 8/8.

No changeset: the funnel entry is a correctness fix with no user-facing
API change, and the baseline re-record is internal.

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

## Summary by CodeRabbit

* **Bug Fixes**
* Improved SDLC funnel classification for hold-only columns, placing
them in the Todo stage instead of Other.
* Preserved correct Planning column behavior when hold-related traits
are combined.

* **Tests**
* Added coverage for hold-related funnel stage mapping and trait
ordering.
* Updated lifecycle column census baselines to reflect current results.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 02:08:26 -07:00
..
…