From 9a5155c71aed1293c1790b9905db13b6b82005d8 Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Thu, 30 Jul 2026 13:14:36 -0700 Subject: [PATCH] =?UTF-8?q?fix(tests):=20main=20red=20=E2=80=94=20a=20cens?= =?UTF-8?q?us=20source=20guard=20that=20a=20COMMENT=20could=20invert=20(#2?= =?UTF-8?q?825)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Red on main ``` lifecycle-column-census > the baseline can always be re-recorded > writes the baseline BEFORE the rise check can exit AssertionError: expected 19345 to be greater than 26374 ``` Read literally, that says the CLI now runs its rise check *before* the `--update-baseline` write — which would break the one command whose entire job is re-recording, and would be a genuine bug worth stopping for. **It does not.** The order in code is correct and unchanged: | | line | |---|---| | `if (updateBaseline) { … writeBaseline() … process.exit(0)` | `scripts/lifecycle-column-census.mjs:487` | | `"column-guard count ROSE"` + `process.exit(1)` | `:510` | ## What actually moved was a comment Line **359** explains this exact failure mode and quotes the marker verbatim: > …`"column-guard count ROSE"`, which is the opposite of what happened and sends the reader looking for… So `cli.indexOf("column-guard count ROSE")` found the **prose**, 7000 characters before the branch it was meant to locate. A guard that a comment can invert is not measuring control flow. And the honest-looking fix — reword the comment — silently re-arms the same trap for whoever explains this next. `cliSource()` now strips comments before indexing. The same defence is already used by `archived-column-gate-parity.test.ts`, for the same reason: notes documenting *why* a literal is dangerous have to mention the literal. ## Kept, not deleted The end-to-end block below these does cover the contract — it drives the real CLI and asserts exit code, baseline content and printed output, and its own comment names the ordering bug. It would have been defensible to delete the two source-text cases as redundant. I kept them because two guards at different levels is the point: **e2e proves the behaviour, these locate the branch that provides it.** They only needed to stop being defeated by prose. ## Evidence The real ordering bug — make a rise exit before the update branch writes — fires **all three**: | guard | failure | |---|---| | source order | `expected 9454 to be greater than 9505` | | slice / uniqueness | `expected 10433 to be -1` | | end-to-end | `expected 1 to be +0` (exit code) | **My first mutation attempt was invalid** and I nearly reported it as evidence: it moved the block by line range, mangled the file, and both markers disappeared — the resulting `-1`s look like a firing guard but prove nothing. A mutation that corrupts its target is not evidence that a guard works. Engine **10991 passed / 0 failed** · gate **732 green** · lint clean. Test-only; the CLI is restored clean. ## Note on duplicated effort #2811 and my #2814 both re-recorded the census baseline for #2783's rise, concurrently. No harm done — but this file is now a fleet-wide contention point, and the per-file baseline shape exists precisely to avoid that. Worth one owner for census/ratchet fixes rather than whoever notices first. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5 (1M context) --- .../__tests__/lifecycle-column-census.test.ts | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/packages/engine/src/__tests__/lifecycle-column-census.test.ts b/packages/engine/src/__tests__/lifecycle-column-census.test.ts index bb2d6ac609..650665dd28 100644 --- a/packages/engine/src/__tests__/lifecycle-column-census.test.ts +++ b/packages/engine/src/__tests__/lifecycle-column-census.test.ts @@ -368,9 +368,32 @@ repeated marker is the magic-number problem wearing a name. describe("the baseline can always be re-recorded", () => { const cliPath = new URL("../../../../scripts/lifecycle-column-census.mjs", import.meta.url).pathname; + /* + FNXC:LifecycleColumnCensus 2026-07-31-06:30: + STRIP COMMENTS — the assertions below index on marker strings, and the CLI's own prose names them. + + These two cases went red on main claiming the ORDER was inverted: `updateAt` 26374, `riseAt` 19345. + The order in CODE is unchanged and correct (`if (updateBaseline) {` at line 487, the rise message at + 510). What moved was a COMMENT: line 359 explains the failure mode and quotes + "column-guard count ROSE" verbatim, so `indexOf` found the prose 7000 characters before the branch + it was meant to locate. + + A guard that a comment can invert is not measuring control flow. Worse, the honest-looking fix is to + reword the comment, which silently re-arms the same trap for whoever explains this next. + + The same defence is already used by `archived-column-gate-parity.test.ts` for the same reason: the + notes documenting WHY a literal is dangerous have to mention the literal. + + Deliberately NOT deleting these in favour of the end-to-end block below, even though that block does + cover this contract (it drives the real CLI and asserts exit code, baseline content and output — and + its own comment names the ordering bug). Two guards at different levels is the point: the e2e one + proves the behaviour, these locate the branch that provides it. They only needed to stop being + defeated by prose. + */ function cliSource(): string { // eslint-disable-next-line @typescript-eslint/no-require-imports - return require("node:fs").readFileSync(cliPath, "utf8") as string; + const raw = require("node:fs").readFileSync(cliPath, "utf8") as string; + return raw.replace(/\/\*[\s\S]*?\*\//g, "").replace(/^\s*\/\/.*$/gm, ""); } function sliceBetween(cli: string, from: string, to: string): string {