Public: anyone can read this; the crew can change it.

A release whose tree covers the page is refused before the swap, and the tick names the rule #11921

opened this

Check · Review · Land · Live — Its check is running. Next: reviewer, no review yet.

Ready to land

Before a release is swapped in, `preflightRelease` (in `src/release/checkout.ts`) now runs the covered-page rule from #11831 over the new tree's `src/web`. If the rule fails, preflight returns `{ok:false}` with one line naming the rule, the file and the selector, for example `preflight refused: covered-page rule (#11831): src/web/style/layer.ts:2 .sheet { display: block }`. The swap never starts,…

4 files · +167 −82

working checking now deploy 983ae0e

Check running · 11 min · 3549 passed, 0 failedCheck of 983ae0echecked against main at 9c9f483fast tier: running · full gate runs on land

Website spec: 23 findings (report only)
opened this

Before a release is swapped in, preflightRelease (in src/release/checkout.ts) now runs the covered-page rule from #11831 over the new tree's src/web. If the rule fails, preflight returns {ok:false} with one line naming the rule, the file and the selector, for example preflight refused: covered-page rule (#11831): src/web/style/layer.ts:2 .sheet { display: block }. The swap never starts, and neither does the tree's own --preflight.

  • Rule moved: the overlay rule and its two helpers, sourceFiles and cssBlocksAt, now live in src/design/overlay.ts instead of scripts/design-lint.ts. That way the running forge calls the same function in its own process, with no shelling out and no import from scripts/. The lint imports and re-exports them, so the lint and its tests behave as before.
  • New function: coveredPage(dir) is the check on its own. If the tree has no src/web it passes, so a tree without a web folder is not refused.
  • Test: test/release-preflight-covered.test.ts covers three cases:

- A stand-in tree whose stylesheet adds an always-on .sheet { display: block; position: fixed; inset: 0 } inside a phone media query is refused with the rule and the file, and the tree's own preflight never runs. - The same layer written as .sheet[open] passes, and the tree's own preflight does run. - Today's tree passes.

Without the change the test fails, because coveredPage doesn't exist.

Look at: the rule only flags selectors that can match a closed dialog, popover or [hidden] element. A plain fixed full-screen class is allowed, as it already is in the lint; today's .space { position: fixed; inset: 0 } in src/web/space_client.ts is one. I did not widen the rule. The release workflow and the chart are untouched.

Checks run: bun x tsc --noEmit, bun scripts/gate.ts and bun scripts/design-lint.ts pass. scripts/fast.ts said the diff was too broad to pick tests because it touches scripts/design-lint.ts. So I ran the 17 test files that import the lint, src/release/checkout.ts or the scan map: 171 pass, 0 fail.

🤖 Generated with Claude Code

Closes #11916

commented

Before a release is swapped in, preflightRelease (in src/release/checkout.ts) now runs the covered-page rule from #11831 over the new tree's src/web. If the rule fails, preflight returns {ok:false} with one line naming the rule, the file and the selector, for example preflight refused: covered-page rule (#11831): src/web/style/layer.ts:2 .sheet { display: block }. The swap never starts, and neither does the tree's own --preflight.

  • Rule moved: the overlay rule and its two helpers, sourceFiles and cssBlocksAt, now live in src/design/overlay.ts instead of scripts/design-lint.ts. That way the running forge calls the same function in its own process, with no shelling out and no import from scripts/. The lint imports and re-exports them, so the lint and its tests behave as before.
  • New function: coveredPage(dir) is the check on its own. If the tree has no src/web it passes, so a tree without a web folder is not refused.
  • Test: test/release-preflight-covered.test.ts covers three cases:

- A stand-in tree whose stylesheet adds an always-on .sheet { display: block; position: fixed; inset: 0 } inside a phone media query is refused with the rule and the file, and the tree's own preflight never runs. - The same layer written as .sheet[open] passes, and the tree's own preflight does run. - Today's tree passes.

Without the change the test fails, because coveredPage doesn't exist.

Look at: the rule only flags selectors that can match a closed dialog, popover or [hidden] element. A plain fixed full-screen class is allowed, as it already is in the lint; today's .space { position: fixed; inset: 0 } in src/web/space_client.ts is one. I did not widen the rule. The release workflow and the chart are untouched.

Checks run: bun x tsc --noEmit, bun scripts/gate.ts and bun scripts/design-lint.ts pass. scripts/fast.ts said the diff was too broad to pick tests because it touches scripts/design-lint.ts. So I ran the 17 test files that import the lint, src/release/checkout.ts or the scan map: 171 pass, 0 fail.

🤖 Generated with Claude Code

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs