ci(forbidden-patterns): add Check 7/7 — no bespoke var(--glass-surface-*) (Brief 7) #127

Merged
varutasu merged 1 commit from brief-7-forbidden-bespoke-glass-surface into main 2026-06-04 17:47:26 -04:00
varutasu commented 2026-06-04 17:44:25 -04:00 (Migrated from github.com)

Summary

Final brief of unify-glass-panel-surfaces. Adds the regression gate that prevents reintroduction of bespoke var(--glass-surface-low|mid|high) inline styles outside the documented allowlist.

This PR closes the convoy.

Two documented deviations from the brief

1. Implementation shape: Check 7/7 inside forbidden-patterns (not a standalone job)

Brief 7 was authored before PR #126 (slash-ci-minutes convoy) consolidated the 6 grep-only forbidden-* jobs into a single forbidden-patterns job with sequential ::group:: sections. Adding Brief 7 as a standalone forbidden-bespoke-glass-surface job (the brief's verbatim shape) would partially undo PR #126's checkout amortization win.

Instead, this PR adds the check as Check 7/7 inside the existing forbidden-patterns job — semantics, allowlist, and grep pattern are exactly as Brief 7 specifies; only the wrapper changes. Job display name updated: Forbidden patterns (6 checks)Forbidden patterns (7 checks).

2. Allowlist expanded from 3 entries to 6

Brief 7 planned a 3-entry allowlist (the 3 chrome blocks). On a fresh post-Briefs-1-6 main, the grep turned up three more files that still handroll their own glass surfaces:

File What handrolls
components/ui/Button.js secondary variant inline background: var(--glass-surface-high) + Tailwind arbitrary class hover:bg-[var(--glass-surface-mid)]
components/ui/Input.js Input wrapper inline background: var(--glass-surface-high)
components/MobileNavigation.js Bottom-nav backdrop inline background: var(--glass-surface-mid)

These are residual migration targets the convoy didn't anticipate.

Per Brief 7's own note ("If you need to add a fourth allowlist entry, that's a design-system decision — open a new convoy"), the right call is to ship the gate NOW with a 6-entry allowlist (3 chrome + 3 pending-migration) and track the cleanup separately.

The 3 pending entries are tagged with inline # TODO: comments in ci.yml naming the follow-up convoy.

Follow-up convoy seeded

.convoys/migrate-button-input-mobilenav-to-glass-primitive.md (113 lines) — full architect-ready seed with:

  • Goal + files in scope
  • 3 open questions for the architect (Button hover strategy, Input wrapper shape, MobileNav class reuse)
  • Acceptance criteria draft
  • Pre-work checklist for the conductor
  • Recommended decomposition (3 small briefs, one per file, dispatchable in parallel)

Local verification — Brief 7's pre-merge tests

Positive test (clean main)

$ grep -lE "var\(--glass-surface-(low|mid|high)\)" pages components -r --include='*.js' | sort -u
components/Layout.js                # allowlist
components/MobileNavigation.js      # allowlist (pending migration)
components/ui/Button.js             # allowlist (pending migration)
components/ui/Input.js              # allowlist (pending migration)
components/ui/TopSearchBar.js       # allowlist

After the allowlist filter: 0 violations.

Negative test (per Brief 7 § Pre-merge negative test)

Injected a scratch line at EOF of pages/profile.js:

+const scratch = { background: 'var(--glass-surface-low)' };

Re-ran the gate logic — pages/profile.js correctly flagged as 1 violation. Reverted. Re-ran — back to 0 violations.

The scratch change was NOT committed (per Brief 7's instructions).

Files

File Change
.github/workflows/ci.yml +70 lines: Check 7/7 step + job display name + final exit copy edit
.convoys/migrate-button-input-mobilenav-to-glass-primitive.md new file, 132 lines
.convoys/unify-glass-panel-surfaces.md +2 lines: status: closing + queued_followup

Net diff: +203 / -3.

Convoy closeout

Once this merges, all 7 briefs of unify-glass-panel-surfaces are landed and the convoy's success metric is met:

Every panel-shaped surface in the app renders with the same gradient-border corner-light treatment at the appropriate intensity tier, verified by visual diff + a forbidden grep gate that prevents reintroduction of bespoke var(--glass-surface-*) inline styles outside the documented exception list.

Status moves from openclosing on merge; the queued
migrate-button-input-mobilenav-to-glass-primitive convoy
will eventually shrink the allowlist back to 3 entries and fully
close the loop.

Acceptance criteria

  • ci.yml contains the Check 7/7 step matching Brief 7's verbatim grep + allowlist + error annotation pattern.
  • Allowlist has 6 entries (3 chrome + 3 pending-migration, latter tagged with TODO comments).
  • On a clean post-Briefs-1-through-6 main, the new check is GREEN (no false positives).
  • Negative test verified locally; documented in this PR description; scratch NOT committed.
  • No other CI jobs reordered, renamed, or modified (apart from the cosmetic job-display-name change 6 checks → 7 checks on the host job).
  • Follow-up convoy seeded with full architect briefing.
  • npm run lint passes (1 pre-existing unrelated warning).
  • npm run test:run: 118/118 tests pass.
  • YAML parses.

Test plan

  • Watch this PR's Forbidden patterns (7 checks) job: should pass green.
  • After merge, open a small scratch PR introducing style={{ background: 'var(--glass-surface-low)' }} somewhere non-allowlisted; verify the gate fails with the expected ::error file=...::msg annotation. Close the scratch PR without merging.
  • Convoy: .convoys/unify-glass-panel-surfaces.md
  • Brief: .convoys/unify-glass-panel-surfaces/brief-7-forbidden-bespoke-glass-surface-ci-gate.md
  • Follow-up convoy: .convoys/migrate-button-input-mobilenav-to-glass-primitive.md
  • Prior briefs: PRs #120 (6), #121 (2), #122 (5), #123 (1), #124 (3), #125 (4).
  • CI-consolidation prerequisite: PR #126 (slash-ci-minutes).

Made with Cursor

<!-- pipeline: brief=7, convoy=unify-glass-panel-surfaces --> ## Summary Final brief of `unify-glass-panel-surfaces`. Adds the regression gate that prevents reintroduction of bespoke `var(--glass-surface-low|mid|high)` inline styles outside the documented allowlist. This PR closes the convoy. ## Two documented deviations from the brief ### 1. Implementation shape: Check 7/7 inside `forbidden-patterns` (not a standalone job) Brief 7 was authored before PR #126 (`slash-ci-minutes` convoy) consolidated the 6 grep-only `forbidden-*` jobs into a single `forbidden-patterns` job with sequential `::group::` sections. Adding Brief 7 as a standalone `forbidden-bespoke-glass-surface` job (the brief's verbatim shape) would partially undo PR #126's checkout amortization win. Instead, this PR adds the check as **Check 7/7 inside the existing `forbidden-patterns` job** — semantics, allowlist, and grep pattern are **exactly** as Brief 7 specifies; only the wrapper changes. Job display name updated: `Forbidden patterns (6 checks)` → `Forbidden patterns (7 checks)`. ### 2. Allowlist expanded from 3 entries to 6 Brief 7 planned a 3-entry allowlist (the 3 chrome blocks). On a fresh post-Briefs-1-6 `main`, the grep turned up **three more files** that still handroll their own glass surfaces: | File | What handrolls | | - | - | | `components/ui/Button.js` | `secondary` variant inline `background: var(--glass-surface-high)` + Tailwind arbitrary class `hover:bg-[var(--glass-surface-mid)]` | | `components/ui/Input.js` | Input wrapper inline `background: var(--glass-surface-high)` | | `components/MobileNavigation.js` | Bottom-nav backdrop inline `background: var(--glass-surface-mid)` | These are residual migration targets the convoy didn't anticipate. Per Brief 7's own note (*"If you need to add a fourth allowlist entry, that's a design-system decision — open a new convoy"*), the right call is to ship the gate NOW with a 6-entry allowlist (3 chrome + 3 pending-migration) and track the cleanup separately. The 3 pending entries are tagged with inline `# TODO:` comments in `ci.yml` naming the follow-up convoy. ## Follow-up convoy seeded `.convoys/migrate-button-input-mobilenav-to-glass-primitive.md` (113 lines) — full architect-ready seed with: - Goal + files in scope - 3 open questions for the architect (Button hover strategy, Input wrapper shape, MobileNav class reuse) - Acceptance criteria draft - Pre-work checklist for the conductor - Recommended decomposition (3 small briefs, one per file, dispatchable in parallel) ## Local verification — Brief 7's pre-merge tests ### Positive test (clean `main`) ```sh $ grep -lE "var\(--glass-surface-(low|mid|high)\)" pages components -r --include='*.js' | sort -u components/Layout.js # allowlist components/MobileNavigation.js # allowlist (pending migration) components/ui/Button.js # allowlist (pending migration) components/ui/Input.js # allowlist (pending migration) components/ui/TopSearchBar.js # allowlist ``` After the allowlist filter: **0 violations**. ✅ ### Negative test (per Brief 7 § Pre-merge negative test) Injected a scratch line at EOF of `pages/profile.js`: ```diff +const scratch = { background: 'var(--glass-surface-low)' }; ``` Re-ran the gate logic — `pages/profile.js` correctly flagged as 1 violation. Reverted. Re-ran — back to 0 violations. ✅ **The scratch change was NOT committed** (per Brief 7's instructions). ## Files | File | Change | | - | - | | `.github/workflows/ci.yml` | +70 lines: Check 7/7 step + job display name + final exit copy edit | | `.convoys/migrate-button-input-mobilenav-to-glass-primitive.md` | new file, 132 lines | | `.convoys/unify-glass-panel-surfaces.md` | +2 lines: `status: closing` + `queued_followup` | Net diff: **+203 / -3**. ## Convoy closeout Once this merges, all 7 briefs of `unify-glass-panel-surfaces` are landed and the convoy's success metric is met: > Every panel-shaped surface in the app renders with the same gradient-border corner-light treatment at the appropriate intensity tier, **verified by visual diff + a forbidden grep gate that prevents reintroduction of bespoke `var(--glass-surface-*)` inline styles outside the documented exception list**. Status moves from `open` → `closing` on merge; the queued `migrate-button-input-mobilenav-to-glass-primitive` convoy will eventually shrink the allowlist back to 3 entries and fully close the loop. ## Acceptance criteria - [x] `ci.yml` contains the Check 7/7 step matching Brief 7's verbatim grep + allowlist + error annotation pattern. - [x] Allowlist has **6 entries** (3 chrome + 3 pending-migration, latter tagged with TODO comments). - [x] On a clean post-Briefs-1-through-6 `main`, the new check is GREEN (no false positives). - [x] Negative test verified locally; documented in this PR description; scratch NOT committed. - [x] No other CI jobs reordered, renamed, or modified (apart from the cosmetic job-display-name change `6 checks → 7 checks` on the host job). - [x] Follow-up convoy seeded with full architect briefing. - [x] `npm run lint` passes (1 pre-existing unrelated warning). - [x] `npm run test:run`: 118/118 tests pass. - [x] YAML parses. ## Test plan - [ ] Watch this PR's `Forbidden patterns (7 checks)` job: should pass green. - [ ] After merge, open a small scratch PR introducing `style={{ background: 'var(--glass-surface-low)' }}` somewhere non-allowlisted; verify the gate fails with the expected `::error file=...::msg` annotation. Close the scratch PR without merging. ## Related - Convoy: `.convoys/unify-glass-panel-surfaces.md` - Brief: `.convoys/unify-glass-panel-surfaces/brief-7-forbidden-bespoke-glass-surface-ci-gate.md` - Follow-up convoy: `.convoys/migrate-button-input-mobilenav-to-glass-primitive.md` - Prior briefs: PRs #120 (6), #121 (2), #122 (5), #123 (1), #124 (3), #125 (4). - CI-consolidation prerequisite: PR #126 (`slash-ci-minutes`). Made with [Cursor](https://cursor.com)
vercel[bot] commented 2026-06-04 17:44:30 -04:00 (Migrated from github.com)

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
tcg-vault Ready Ready Preview, Comment Jun 4, 2026 9:44pm

Request Review

[vc]: #aSlYBwTI9KfsBEMs2oc2ePneUwc416rtGBAH1l8CEL4=:eyJpc01vbm9yZXBvIjp0cnVlLCJ0eXBlIjoiZ2l0aHViIiwicHJvamVjdHMiOlt7Im5hbWUiOiJ0Y2ctdmF1bHQiLCJwcm9qZWN0SWQiOiJwcmpfRjZXOEVvRkd3Y0g3aWVGcnRvRlNlOXdVVkFhNSIsImxpdmVGZWVkYmFjayI6eyJyZXNvbHZlZCI6MCwidW5yZXNvbHZlZCI6MCwidG90YWwiOjAsImxpbmsiOiJ0Y2ctdmF1bHQtZ2l0LWJyaWVmLTctZm9yYmlkLWU2NzU5YS1yYW5kYWxsLXN0aWxsd2VsbHMtcHJvamVjdHMudmVyY2VsLmFwcCJ9LCJpbnNwZWN0b3JVcmwiOiJodHRwczovL3ZlcmNlbC5jb20vcmFuZGFsbC1zdGlsbHdlbGxzLXByb2plY3RzL3RjZy12YXVsdC9DR2pvM21pU3djU2k4cEthdEpHM01uY1luUXltIiwicHJldmlld1VybCI6InRjZy12YXVsdC1naXQtYnJpZWYtNy1mb3JiaWQtZTY3NTlhLXJhbmRhbGwtc3RpbGx3ZWxscy1wcm9qZWN0cy52ZXJjZWwuYXBwIiwibmV4dENvbW1pdFN0YXR1cyI6IkRFUExPWUVEIn1dLCJyZXF1ZXN0UmV2aWV3VXJsIjoiaHR0cHM6Ly92ZXJjZWwuY29tL3ZlcmNlbC1hZ2VudC9yZXF1ZXN0LXJldmlldz9vd25lcj12YXJ1dGFzdSZyZXBvPXRjZy12YXVsdCZwcj0xMjcifQ== The latest updates on your projects. Learn more about [Vercel for GitHub](https://vercel.link/github-learn-more). | Project | Deployment | Actions | Updated (UTC) | | :--- | :----- | :------ | :------ | | [tcg-vault](https://vercel.com/randall-stillwells-projects/tcg-vault) | ![Ready](https://vercel.com/static/status/ready.svg) [Ready](https://vercel.com/randall-stillwells-projects/tcg-vault/CGjo3miSwcSi8pKatJG3MncYnQym) | [Preview](https://tcg-vault-git-brief-7-forbid-e6759a-randall-stillwells-projects.vercel.app), [Comment](https://vercel.live/open-feedback/tcg-vault-git-brief-7-forbid-e6759a-randall-stillwells-projects.vercel.app?via=pr-comment-feedback-link) | Jun 4, 2026 9:44pm | <a href="https://vercel.com/vercel-agent/request-review?owner=varutasu&repo=tcg-vault&pr=127" rel="noreferrer"><picture><source media="(prefers-color-scheme: dark)" srcset="https://agents-vade-review.vercel.sh/request-review-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://agents-vade-review.vercel.sh/request-review-light.svg"><img src="https://agents-vade-review.vercel.sh/request-review-light.svg" alt="Request Review"></picture></a>
Sign in to join this conversation.
No description provided.