fix(skills): design-handoff review-finding fixes (CodeRabbit on ponderous-site#31 + lawnomator-site#14) - #86
Merged
Conversation
CodeRabbit review of the vendored copy (ponderousdev/ponderous-site#31) flagged ingest:design as a critical shell-interpolation hole: BUNDLE/DEST were spliced unquoted into shell source, so a value like 'x.tar.gz; rm -rf ~' executed and paths with spaces broke — and the tar/unzip fallback chain extracted untrusted archives with no entry validation (zip-slip). - new assets/ingest-design.sh: takes BUNDLE/DEST from the environment (no interpolation), selects tar vs unzip by validated extension, and refuses archives containing absolute paths, .. traversal, or link entries before extracting - Taskfile.design.yml ingest:design now passes BUNDLE/DEST via env: and delegates to the script (keeps cmds: trivial per repo convention) - ingesting-the-bundle.md: treat the archive as untrusted — validate entries before extraction (manual grep equivalent documented); identify the coding handoff by content shape (README + chats/), not extension, since exports have shipped as both .tar.gz and .zip Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…orted grounds Two fail-open holes in the dual contrast gate (CodeRabbit on ponderous-site#31 / lawnomator-site#14): - check-contrast.mjs dropped alpha when parsing oklch/rgb/hex, so a translucent foreground token could PASS AA on its opaque value. Alpha is now preserved end-to-end: translucent foregrounds are composited over the audited background (gamma sRGB, as browsers blend) before scoring, and a translucent background — impossible to composite statically — is reported as unsupported for the rendered check instead of passing. - measure-rendered-contrast.mjs composited ancestor background-colors only, reporting fictional AA ratios for text over gradients, images, or painted pseudo-elements. Those samples are now detected and fail as UNSUPPORTED until measured manually; undetectable overlay siblings are documented as manual-only (accessibility-verification.md). - measure-rendered-contrast.mjs also re-added its theme init script to a shared page each pass (init scripts persist and run in undefined order); each theme now gets a fresh page/context. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…n bad root
CodeRabbit (ponderous-site#31 / lawnomator-site#14) showed the attribute
pattern only matched a color literal immediately after the property name, so
style={{ background: "linear-gradient(#111, #222)" }} passed; rgba()/hsla()
and modern color functions also slipped through, and a typo'd target dir
reported a false 'clean' because grep's stderr is suppressed.
- scan the whole style value (bounded at quote/semicolon), catching literals
buried in gradients; var(--token)-only values still pass
- flag rgba/hsla/hwb/lab/lch/color() in both patterns; add
background-image/outline-color/caret-color properties
- exit 2 when the target dir doesn't exist instead of falling through to the
success message
Regression-run against fixtures: 10 bypass cases flagged, 6 token-safe
negatives clean, missing dir fails.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…theme overflow guard - pages taller than the browser capture cap were silently truncated to the top slice; they are now captured as stacked -part1/-part2/… clips covering through the document bottom (single fullPage file kept within the cap) - the horizontal-overflow guard ran light-theme-only; it now asserts per route x theme via the existing setTheme helper, catching dark-only overflow - align the spec header and responsive-and-cross-browser.md with the production build-and-preview rule (one stray line still said to point baseURL/webServer at the dev server) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…dance Doc-level CodeRabbit findings from ponderous-site#31: - assets-fonts-favicons.md: the manual @font-face example placed the block above @import "tailwindcss", which per the CSS spec silently kills the import; example reordered and the '@font-face can go anywhere' claim corrected (any rule before an @import invalidates it) - brand-page.md: Tier 3 Email no longer mandates React Email — the zero-dependency table-HTML pattern is the documented workflow (React Email only if the repo already carries it); Tier 3 Print and the collateral recipe now label CSS-generated PDFs as digital proofs, with true print-ready output (CMYK/300dpi/crop marks) requiring a production export and vendor validation - greenfield-bootstrap.md: the shadcn-init safety rule created an EMPTY globals.css even when one existed, deleting app CSS; now create-only-if- absent, preserve existing contents; script-copy lists include ingest-design.sh - token-reconciliation.md: shadcn sidebar-* defaults DIFFER between :root and .dark (they are not authored identical by convention) — constant chrome requires deleting/aligning the .dark overrides or minting dedicated fixed-chrome tokens - SKILL.md: identify the handoff by content shape (README + chats/), not archive extension — the raw-assets .zip export is not the coding handoff; bundled-assets list updated for ingest-design.sh and the hardened gates Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Updates the canonical ai/skills/frontend/design-handoff/ skill to address downstream CodeRabbit review findings in vendored copies, primarily tightening safety/accuracy of the bundled “design gate” assets and aligning the written guidance with current export/tool behavior.
Changes:
- Hardened and clarified design-bundle ingestion (new
ingest-design.sh, Taskfile wiring, and docs aligned to “content shape” vs extension). - Improved correctness of design QA assets (alpha-aware static contrast, fail-closed rendered contrast over painted grounds, broader off-palette detection).
- Refined Playwright cross-browser sweep guidance (production preview server requirement, tall-page capture chunking, per-theme overflow checks).
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| ai/skills/frontend/design-handoff/SKILL.md | Updates skill contract/docs for bundle identification and asset inventory. |
| ai/skills/frontend/design-handoff/references/token-reconciliation.md | Corrects guidance on sidebar-* tokens and theme behavior. |
| ai/skills/frontend/design-handoff/references/responsive-and-cross-browser.md | Aligns browser verification guidance to production preview server usage. |
| ai/skills/frontend/design-handoff/references/ingesting-the-bundle.md | Documents format drift and emphasizes safe extraction / untrusted archive handling. |
| ai/skills/frontend/design-handoff/references/greenfield-bootstrap.md | Updates bootstrap steps to preserve existing CSS and include new scripts. |
| ai/skills/frontend/design-handoff/references/brand-page.md | Clarifies email/print deliverable expectations (zero-dep email, “digital proof” PDFs). |
| ai/skills/frontend/design-handoff/references/assets-fonts-favicons.md | Fixes and clarifies @import ordering rules relative to @font-face. |
| ai/skills/frontend/design-handoff/references/accessibility-verification.md | Documents rendered-contrast limitations and required manual measurement cases. |
| ai/skills/frontend/design-handoff/assets/Taskfile.design.yml | Routes ingest:design through env-passed vars and the new extraction script. |
| ai/skills/frontend/design-handoff/assets/measure-rendered-contrast.mjs | Uses per-theme fresh pages and fail-closed UNSUPPORTED detection for painted grounds. |
| ai/skills/frontend/design-handoff/assets/ingest-design.sh | Adds safe extraction with entry validation and extension-based extractor selection. |
| ai/skills/frontend/design-handoff/assets/check-off-palette.sh | Broadens detection for modern color functions and improves failure behavior. |
| ai/skills/frontend/design-handoff/assets/check-contrast.mjs | Preserves/composites alpha for foregrounds and fail-closed behavior for translucent backgrounds. |
| ai/skills/frontend/design-handoff/assets/brand-screenshots.spec.ts | Improves screenshot coverage across themes and tall-page chunk capture. |
…t() API - ingest-design.sh: the tar link guard grepped ' -> ', which only matches symlinks; GNU/bsd tar render hardlinks as 'name link to target' (no arrow), so they slipped through. Match the mode-string type column (^[hl]) to reject both symlinks and hardlinks portably. - brand-screenshots.spec.ts: import expect from @playwright/test and call expect(...) instead of test.expect(...), which is not the documented API and throws at runtime (expect was never imported). Both from Copilot review on PR #86. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Jul 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes the CodeRabbit review findings raised against the vendored copy of this skill in
ponderousdev/ponderous-site#31 (plus 3 from
ponderousdev/lawnomator-site#14). Downstream
copies are drift-checked and never edited, so every accepted finding is fixed here in the canonical
source (
ai/skills/frontend/design-handoff/); consumers pick it up on the next skill sync.Verdicts — ponderous-site#31
assets/brand-screenshots.spec.ts-part1/-part2/…clips (fullPage+ document-relativeclip) covering through the bottom; in-cap pages keep the single fullPage file.assets/brand-screenshots.spec.tssetThemehelper.assets/check-contrast.mjsmuted-foregroundthat passed before now FAILs).assets/check-off-palette.shcolor();background-image/outline-color/caret-coloradded. Regression-run: 10 bypass cases flagged, 6var(--token)negatives clean. (No asset-test harness exists in this repo; cases documented in the commit.)assets/measure-rendered-contrast.mjsbackground-imageor painted::before/::afteranywhere in the ancestor chain now fail asUNSUPPORTED(fail-closed) with a manual-measurement instruction; overlay siblings are documented as undetectable/manual-only.ingest:design(3566278397)assets/Taskfile.design.ymlBUNDLE/DESTnow pass via Taskenv:(never spliced into shell source) to a newassets/ingest-design.sh, which picks tar vs unzip by validated extension. Tested:BUNDLE='x.tar.gz; touch PWNED'does not execute; paths with spaces work.references/accessibility-verification.md@font-facebefore@import "tailwindcss"kills the import (3566278404)references/assets-fonts-favicons.md@font-faceblocks can go anywhere" claim rewritten — any rule before an@importinvalidates it.references/brand-page.mdreferences/brand-page.mdreferences/greenfield-bootstrap.mdglobals.csscontents are preserved, with a recoverability note for untracked files.references/ingesting-the-bundle.mdingest-design.shrejects absolute paths,..traversal, and link entries before extracting (tested against crafted tar/zip archives); manual grep equivalent documented.references/responsive-and-cross-browser.mdbuild && preview, matching the config and the spec header.sidebar-*claimed theme-constant by convention (3566278418)references/token-reconciliation.md:rootvs.dark; constant chrome requires deleting/aligning the.darkoverrides — or dedicated fixed-chrome tokens when a real themed sidebar coexists..ziphandoff contract mismatch (3566278420)SKILL.md+references/ingesting-the-bundle.mdchats/+ project), never extension; the raw-assets "Download as .zip" export lacks that shape and is rejected. Extraction flow (ingest:design) accepts both.tar.gzand.zipafter entry validation.Verdicts — lawnomator-site#14
attributeregex missesrgba(/hsla((3566249742)assets/check-off-palette.shrgba?\(/hsla?\(color-function alternation used by both patterns.2>/dev/nullmasks a bad$rootas "clean" (3566249745)assets/check-off-palette.shaddInitScriptstacking across themes (3566249747)assets/measure-rendered-contrast.mjsRejected: none — every finding reproduced against the canonical source.
Notes
assets/ingest-design.sh(env-passed args, extension-validated tar/unzip, entryvalidation).
SKILL.md/greenfield-bootstrap.mdcopy-lists updated;Taskfile.design.ymlingest:designdelegates to it, keepingcmds:trivial per repo convention.check-off-palette.shcan false-positive on anSVG
url(#id)whose id is 3+ hex chars; flagged lines are human-reviewed by design.to/resolved here — a separate agent handles those, citing this PR.
Gates
task verify— green (lint incl. shellcheck/shfmt on the new/changed.sh, markdown/yaml/hygiene,skills validation, 63 tooling tests)
ingest-design against good tar/zip,
..-traversal tar, symlink tar, crafted evil zip, injectionfilename, and paths with spaces;
ingest:designexercised end-to-end via go-tasknode --checkon both.mjs;tscparse of the spec template (module-resolution errors only, expected —@playwright/testis a target-repo dependency)🤖 Generated with Claude Code