Skip to content

SleepPSG: sync RecipeConfig.shipped with #987's awake row (main is red) - #997

Merged
ryanbr merged 1 commit into
mainfrom
fix/sleeppsg-port-awake-row
Jul 31, 2026
Merged

SleepPSG: sync RecipeConfig.shipped with #987's awake row (main is red)#997
ryanbr merged 1 commit into
mainfrom
fix/sleeppsg-port-awake-row

Conversation

@ryanbr

@ryanbr ryanbr commented Jul 31, 2026

Copy link
Copy Markdown
Owner

main is failing Swift Packages CI / tools (SleepPSG) after #987. This is the one-line fix.

What happened

#987 changed SleepStagerV2's awake transition row. #991's port-equivalence guard — merged before it — caught the divergence immediately:

RecipeConfig.shipped no longer reproduces SleepStagerV2 — 195 of 12377 epoch labels differ.
Update RecipeConfig.shipped to match the shipped file.

This is the guard doing precisely what it was built for, on its first real occasion, and it named both the cause and the file to fix. Without it the tool would have gone on printing confident numbers about a recipe that no longer existed — which is the failure mode #991's description called out.

Why it slipped through

#991 merged after #987 was opened, so #987's branch predates the tool and its 13/13 green never included a tools (SleepPSG) job. MERGEABLE CLEAN only ever meant no textual conflict, and there genuinely was none — the two files never touch. The coupling is semantic, which is exactly the kind review does not catch and a test does.

Worth noting for future merges: a green PR check plus a clean merge state does not imply main stays green when a guard has landed in between.

The fix

One line, and RecipePort.swift's own comment predicted it:

THE AWAKE ROW IS THE ONE LINE THAT LEGITIMATELY DIFFERS BETWEEN BRANCHES … RecipeConfig.shipped must always describe SleepStagerV2 AS COMPILED on this branch — PortValidation is what enforces that, and it will fail loudly on the wrong value.

Variants.pr987 needs no edit. It reads the shipped row and offers whichever one is absent:

let shippedRow = RecipeConfig.shipped.transition["awake"] ?? awakeRowPre987
let alreadyHas987 = shippedRow == awakeRowPR987

so the #987 ablation keeps working from the other side, comparing post-#987 against pre-#987 instead of the reverse.

Verification

Port row and SleepStagerV2.swift:205 now agree character-for-character: ["deep": 0.0, "rem": 0.0, "light": 0.10, "awake": 0.90]. swiftc -parse clean. The real check is tools (SleepPSG) on this PR — it replays all 55 corpus nights against the compiled stager, so it passes only if the port genuinely reproduces it again.

#987 changed SleepStagerV2's awake transition row; #991's port-equivalence
guard landed before it and correctly failed on main:

  RecipeConfig.shipped no longer reproduces SleepStagerV2 —
  195 of 12377 epoch labels differ.

This is the guard working, not a defect in it. #991 merged AFTER #987 was
opened, so #987's own green CI never ran the SleepPSG job — its branch predates
the tool. MERGEABLE CLEAN only ever meant no textual conflict, and there was
none: the two files never touch. The coupling is semantic, which is exactly the
kind a test has to catch because review will not.

RecipePort's own comment already called this out — the awake row "is the one
line that legitimately differs between branches" and RecipeConfig.shipped "must
always describe SleepStagerV2 AS COMPILED on this branch". So the fix is the
single line it predicted, and Variants.pr987 needs no edit: it reads the shipped
row and offers whichever one is not there, so the #987 ablation keeps working
from the other side.
@ryanbr
ryanbr merged commit 109b17c into main Jul 31, 2026
13 checks passed
@ryanbr
ryanbr deleted the fix/sleeppsg-port-awake-row branch July 31, 2026 06:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant