From d1ea33ee79a03baa8d6ea2159d981f1daffdda41 Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Thu, 30 Jul 2026 17:52:56 -0700 Subject: [PATCH] =?UTF-8?q?docs(lanes):=20three=20measured=20claims=20of?= =?UTF-8?q?=20mine=20had=20gone=20stale=20=E2=80=94=20date=20them=20or=20d?= =?UTF-8?q?elete=20them=20(#2904)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Comment-only. No source change, no behaviour change. #2903 corrected a note that named a caller which had since been converted. This applies the same check to my own notes, and all three measured claims I wrote are now wrong: | claim | where | actual | |---|---|---| | "`self-healing.ts` alone issues **49** such reads" | `project-lane-vocabulary.ts` + its test | **37** | | "**51** such destinations exist in production" | `workflow-lifecycle-traits.ts` | ~34 | | "**22** deliberately pass `recoveryRehome: true`" | same | ~18 | All were accurate when measured. The shq fleet has been converting `self-healing.ts` since, and this program has been converting `moveTask` destinations all day. The repo-wide read-shaped total is now 37 *in total*, so "49 in one file" could not have remained true regardless. ## Two different repairs, because the claims differ in one way that matters **The self-healing figure has a reproduction.** `node scripts/lifecycle-column-census.mjs --json` reports `queryByFile` and `queryRoles`. So the number is kept, marked explicitly as a dated measurement, and the reader is pointed at the command rather than asked to trust the figure. **The `moveTask` counts have none.** Nothing regenerates them — the census cannot see call arguments, which is the very point the note is making. So they are **deleted** rather than refreshed, with the grep that approximates them inlined and labelled approximate. Refreshing an un-reproducible number just resets the clock on the same failure. The shape of the finding is what the note is for; the count was decoration that decays. ## Two process notes worth recording **Notes that assert facts about other files are a decay class with no detector.** The census counts literals; the unwired-lane guard counts declarations; neither reads prose. Two of these corrections in a row (#2903 and this) came from *reading a note and checking its claim*, which is not something the toolchain will ever do for us. The durable form is: cite a command, or state the shape without the number. **I nearly published a wrong replacement figure.** My first probe against the census AST returned `0` because I wired `summarize()` incorrectly — the third time this session a probe has been wrong before the product was. That is why the corrected note cites `--json` output rather than another hand count. ## Verification - `pnpm test:gate` — 161 / 487 / 13 / 71 passed - `pnpm lint` — clean - `tsc --noEmit` (`@fusion/core`) — clean - `project-lane-vocabulary.test.ts` — 9 passed - census `--strict` — exit 0, counts unchanged 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5 (1M context) --- .../__tests__/project-lane-vocabulary.test.ts | 6 +++++- packages/core/src/project-lane-vocabulary.ts | 8 ++++++- .../core/src/workflow-lifecycle-traits.ts | 21 +++++++++++++++---- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/packages/core/src/__tests__/project-lane-vocabulary.test.ts b/packages/core/src/__tests__/project-lane-vocabulary.test.ts index 6d7200ef90..63a0ef8b6b 100644 --- a/packages/core/src/__tests__/project-lane-vocabulary.test.ts +++ b/packages/core/src/__tests__/project-lane-vocabulary.test.ts @@ -9,11 +9,15 @@ impossible one for a read: await store.listTasks({ column: "in-review" }) // there is no task to resolve from yet -#2800 measured the consequence: `self-healing.ts` alone issues 49 such reads, and on a renamed board +#2800 measured the consequence: `self-healing.ts` alone issued 49 such reads, and on a renamed board every one returns an EMPTY array, so the sweep never executes. The census scores the comparison INSIDE the loop, not the query above it — so converting those comparisons drops a count while the loop body stays unreachable. In that file the census total is not a floor; it is misleading. +The 49 is dated, not fixed: 37 as of this writing, and falling as the fleet converts them. Regenerate +with `node scripts/lifecycle-column-census.mjs --json` (`queryByFile`, `queryRoles`) rather than +trusting the figure — an un-reproducible count is how a comment starts lying about another file. + WHAT THIS MODULE IS FOR. It gives the query class one shared answer instead of each site inventing its own. I wrote this logic once inline for the legacy auto-merge stamp backfill; a second copy is how two readers of the same fact begin to disagree. diff --git a/packages/core/src/project-lane-vocabulary.ts b/packages/core/src/project-lane-vocabulary.ts index 2c8f58cf43..2a720f892c 100644 --- a/packages/core/src/project-lane-vocabulary.ts +++ b/packages/core/src/project-lane-vocabulary.ts @@ -8,11 +8,17 @@ and the wrong shape for a QUERY, because a query runs before any task is in hand await store.listTasks({ column: "in-review" }) // ← nothing to resolve from -`#2800` measured the cost: `self-healing.ts` alone issues 49 such reads, and on a board whose lanes +`#2800` measured the cost: `self-healing.ts` alone issued 49 such reads, and on a board whose lanes are renamed every one returns an EMPTY array, so the sweep it feeds never executes. The census scores the comparison inside the loop, not the query above it, so converting those comparisons drops a count and changes nothing an operator can observe — the loop body was already unreachable. +That 49 is a MEASUREMENT WITH A DATE, not a constant: it was 37 at the time of writing and falls as +the fleet converts them. Reproduce rather than trust it — +`node scripts/lifecycle-column-census.mjs --json` reports `queryByFile` and `queryRoles`. Quoting a +hand-counted figure with no way to regenerate it is how a note starts lying about another file, which +this program has now corrected twice in comments that were true when written. + Fixing a query needs a different answer: not "this task's lane" but "every column ANY workflow in this project declares for this role". That is what this module returns, and it is deliberately shared rather than re-derived per call site — I wrote this logic once inline for the legacy auto-merge stamp diff --git a/packages/core/src/workflow-lifecycle-traits.ts b/packages/core/src/workflow-lifecycle-traits.ts index 2298f3c282..369c9c4616 100644 --- a/packages/core/src/workflow-lifecycle-traits.ts +++ b/packages/core/src/workflow-lifecycle-traits.ts @@ -395,12 +395,25 @@ MOVE-TARGET resolvers, kept beside `resolveTaskLifecycleColumns` because they an for the other half of a conversion. The lifecycle-column census is an AST scan for COMPARISONS, so a `moveTask` DESTINATION — a call -argument — is invisible to it. 51 such destinations exist in production; 22 deliberately pass -`recoveryRehome: true` (the #1411 legacy safe-landing escape, which must not be converted), and the rest -are rejected outright on a board that does not declare the target now that U12 hoisted the -`workflowHasColumn` check out of its dead flag-gated branch. See +argument — is invisible to it. A share of those deliberately pass `recoveryRehome: true` (the #1411 +legacy safe-landing escape, which must not be converted); the rest are rejected outright on a board +that does not declare the target, now that U12 hoisted the `workflowHasColumn` check out of its dead +flag-gated branch. See `docs/solutions/architecture-patterns/hardcoded-movetask-destinations-are-census-invisible.md`. +THE COUNTS THAT USED TO BE HERE ARE GONE ON PURPOSE. This note read "51 such destinations exist in +production; 22 deliberately pass `recoveryRehome: true`". Both were true when measured and neither is +now — the program has been converting them since — and unlike the census totals there is no command +that regenerates these, so the figures could only rot. A comment that states an un-reproducible count +about other files is a comment that will eventually lie; the shape is what matters here, and the +current numbers are one grep away: + + grep -rnE 'moveTask\([^,]+, *"(todo|in-progress|in-review|done|archived|triage)"' packages \ + --include='*.ts' | grep -v __tests__ + +(approximate — it sees single-line call sites only, which is precisely why it was never a total worth +pinning in prose). + Both fall back to the legacy id: `resolveWorkflowIrForTask` degrades to the BUILT-IN IR rather than throwing, so a board whose workflow cannot be read behaves exactly as before.