From 0f59c01238d982e319331c1ee4504f6d3d48c163 Mon Sep 17 00:00:00 2001 From: garrytan Date: Mon, 26 Oct 2026 10:27:46 +0000 Subject: [PATCH] fix: craft audit files failed Persuade checks as deferred High, judges source tells by eye; stderr pin (GSTA-92) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --- CHANGELOG.md | 2 +- design-review/sections/craft-audit.md | 4 ++-- design-review/sections/craft-audit.md.tmpl | 4 ++-- test/design-craft.test.ts | 1 + test/helpers/carve-guards.ts | 4 ++-- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 39cbe57d7..d7cf9c48d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ## [Unreleased] ### Changed -- **/design-review audits a Persuade page or a redesign for craft, or on request** (`sections/craft-audit.md`, read in Phases 1-6; design-review is now carved on every host, so the audit is one lazy section, not inlined text). It runs `bin/gstack-design-craft` on each page's served HTML (or the repo file when no app runs) and files each `CRAFT_CHECK` line as a category 9 finding (no `CRAFT_RESULT` line means the check was unavailable, and a framework mount-node shell is judged by eye too; the saved page holds only inline CSS and JS, so tells in linked files are judged by eye; it also holds session data, so it is deleted in the block that checks it, whatever the exit code, and never copied to the report; `--accepted` takes that screen's finalized.json, only for a page /design-html finalized, and never covers `needs-proof` or `lorem`; a claim without proof is filed and asked about, never marked or cut); checks what the tool cannot see (claims only from the user, realistic sample content, the ship floor, a designed 404, cookie consent where required, the motion rules); files a failed Persuade check (one primary action, named objections, proof beside each claim, a real risk reversal, an index/noindex decision) as High impact; and in Phase 8 breaks impact ties with Elaya's fix order and reads the installed Tailwind major version before touching its config. The audit's rules render from /design-html's craft section, so the build and the audit cannot drift. +- **/design-review audits a Persuade page or a redesign for craft, or on request** (`sections/craft-audit.md`, read in Phases 1-6; design-review is now carved on every host, so the audit is one lazy section, not inlined text). It runs `bin/gstack-design-craft` on each page's served HTML (or the repo file when no app runs) and files each `CRAFT_CHECK` line as a category 9 finding (no `CRAFT_RESULT` line means the check was unavailable, and a framework mount-node shell is judged by eye too; the saved page holds only inline CSS and JS, so `100vh`, `transition: all`, scroll listeners and `alert()` are also judged by eye; it also holds session data, so it is deleted in the block that checks it, whatever the exit code, and never copied to the report; `--accepted` takes that screen's finalized.json, only for a page /design-html finalized, and never covers `needs-proof` or `lorem`; a claim without proof is filed and asked about, never marked or cut); checks what the tool cannot see (claims only from the user, realistic sample content, the ship floor, a designed 404, cookie consent where required, the motion rules); files a failed Persuade check (one primary action, named objections, proof beside each claim, a real risk reversal, an index/noindex decision) as a deferred High finding, since its fix needs the team's copy or indexing call; and in Phase 8 breaks impact ties with Elaya's fix order and reads the installed Tailwind major version before touching its config. The audit's rules render from /design-html's craft section, so the build and the audit cannot drift. - **/plan-design-review**: a Persuade plan gets the same five checks in Pass 1, Pass 4 rejects unsourced proof, and the runner checklist names them. - **The craft tells are catalog entries.** Placeholder people and brands, lorem, round sample numbers, `[Needs proof:` markers, "Oops" errors, scroll-listener reveals, dead `href="#"`, `alert()`, images without alt, `100vh`, and a missing title, description, favicon, skip link or `aria-current` live in `lib/design-catalog.ts` as `checkerOnly` entries: one id, one short line and the fix, reported by the craft check and kept out of Methodology category 9, `review/design-checklist.md` and the consultation bullets, so no skill carries their prose. `lib/design-craft.ts` prints only catalog ids, with each entry's `fix` text; `transition: all` now reports under the existing `layout-transition` id instead of `transition-all`. diff --git a/design-review/sections/craft-audit.md b/design-review/sections/craft-audit.md index c35813bc0..516e4d24b 100644 --- a/design-review/sections/craft-audit.md +++ b/design-review/sections/craft-audit.md @@ -12,7 +12,7 @@ With a URL, save the page in the script that opens it. Aside: add `await fs.writ ~/.claude/skills/gstack/bin/gstack-design-craft ``` -Each `CRAFT_CHECK: ` line is one category 9 finding under that id; `CRAFT_RESULT: clean` adds none; no `CRAFT_RESULT` line (framework source or an empty or unreadable file) or a mount-node shell: say the check was unavailable for that page and judge the tells below by eye. A saved page holds only inline CSS and JS: judge `100vh`, `transition: all`, scroll listeners and `alert()` in linked files by eye. For a page /design-html finalized, add `--accepted` with that screen's finalized.json (under `$GSTACK_STATE_ROOT/projects/$SLUG/designs/`; unsure: omit it): a `CRAFT_ACCEPTED` line is a finding the user accepted, listed with its reason, not filed again, except `needs-proof` and `lorem`, which a live page cannot carry. After a `cannot use exceptions` warning, file every line. A hit real user content explains (a customer named Nexus) is noted, not filed. Never mark or cut a claim as the rules below say: file it and ask for the proof. +Each `CRAFT_CHECK: ` line is one category 9 finding under that id; `CRAFT_RESULT: clean` adds none; no `CRAFT_RESULT` line (framework source or an empty or unreadable file) or a mount-node shell: say the check was unavailable for that page and judge the tells below by eye. A saved page holds only inline CSS and JS: judge `100vh`, `transition: all`, scroll listeners and `alert()` by eye. For a page /design-html finalized, add `--accepted` with that screen's finalized.json (under `$GSTACK_STATE_ROOT/projects/$SLUG/designs/`; unsure: omit it): a `CRAFT_ACCEPTED` line is a finding the user accepted, listed with its reason, not filed again, except `needs-proof` and `lorem`, which a live page cannot carry. After a `cannot use exceptions` warning, file every line. A hit real user content explains (a customer named Nexus) is noted, not filed. Never mark or cut a claim as the rules below say: file it and ask for the proof. ### 2. What the check cannot see @@ -39,7 +39,7 @@ Beyond the document: a made-up path returns a designed 404 with a way back, ever ### 3. Persuade pages -File a failed check as High impact. +File a failed check as a deferred High. 1. **One primary action**, named; nothing competes with it above the fold, and the closing CTA repeats it. 2. **Named objections**: the visitor's top objections, each answered where it arises (FAQ of real questions, comparison, guarantee). diff --git a/design-review/sections/craft-audit.md.tmpl b/design-review/sections/craft-audit.md.tmpl index 6d49d0df3..8d52d0df0 100644 --- a/design-review/sections/craft-audit.md.tmpl +++ b/design-review/sections/craft-audit.md.tmpl @@ -10,7 +10,7 @@ With a URL, save the page in the script that opens it. Aside: add `await fs.writ {{BIN_DIR}}/gstack-design-craft ``` -Each `CRAFT_CHECK: ` line is one category 9 finding under that id; `CRAFT_RESULT: clean` adds none; no `CRAFT_RESULT` line (framework source or an empty or unreadable file) or a mount-node shell: say the check was unavailable for that page and judge the tells below by eye. A saved page holds only inline CSS and JS: judge `100vh`, `transition: all`, scroll listeners and `alert()` in linked files by eye. For a page /design-html finalized, add `--accepted` with that screen's finalized.json (under `$GSTACK_STATE_ROOT/projects/$SLUG/designs/`; unsure: omit it): a `CRAFT_ACCEPTED` line is a finding the user accepted, listed with its reason, not filed again, except `needs-proof` and `lorem`, which a live page cannot carry. After a `cannot use exceptions` warning, file every line. A hit real user content explains (a customer named Nexus) is noted, not filed. Never mark or cut a claim as the rules below say: file it and ask for the proof. +Each `CRAFT_CHECK: ` line is one category 9 finding under that id; `CRAFT_RESULT: clean` adds none; no `CRAFT_RESULT` line (framework source or an empty or unreadable file) or a mount-node shell: say the check was unavailable for that page and judge the tells below by eye. A saved page holds only inline CSS and JS: judge `100vh`, `transition: all`, scroll listeners and `alert()` by eye. For a page /design-html finalized, add `--accepted` with that screen's finalized.json (under `$GSTACK_STATE_ROOT/projects/$SLUG/designs/`; unsure: omit it): a `CRAFT_ACCEPTED` line is a finding the user accepted, listed with its reason, not filed again, except `needs-proof` and `lorem`, which a live page cannot carry. After a `cannot use exceptions` warning, file every line. A hit real user content explains (a customer named Nexus) is noted, not filed. Never mark or cut a claim as the rules below say: file it and ask for the proof. ### 2. What the check cannot see @@ -26,7 +26,7 @@ Beyond the document: a made-up path returns a designed 404 with a way back, ever ### 3. Persuade pages -File a failed check as High impact. +File a failed check as a deferred High. {{DESIGN_PERSUADE_CHECKS}} diff --git a/test/design-craft.test.ts b/test/design-craft.test.ts index 77c4c09d9..ee3309f7e 100644 --- a/test/design-craft.test.ts +++ b/test/design-craft.test.ts @@ -205,6 +205,7 @@ describe('accepted craft exceptions (finalized.json craft_exceptions)', () => { const bad = run(page, '--accepted', path.join(dir, name)); expect(bad).toMatchObject({ code: 2, out: run(page).out }); expect(bad.err).toContain('checked with none accepted'); + expect(bad.err).toContain('cannot use exceptions'); } fs.writeFileSync(page, CLEAN); expect(run(page, '--accepted', path.join(dir, 'broken.json'))).toMatchObject({ code: 2, out: 'CRAFT_RESULT: clean\n' }); diff --git a/test/helpers/carve-guards.ts b/test/helpers/carve-guards.ts index 2597dac28..05b453b14 100644 --- a/test/helpers/carve-guards.ts +++ b/test/helpers/carve-guards.ts @@ -752,9 +752,9 @@ do not launch the downstream skill or open a browser.`, // periodic census past its 38-slice cap (test/paid-retry-supervision.test.ts). behavioral: 'none', maxSkeletonBytes: 137_767, // measured 137767 (2026-10-26; 137773 on 2026-10-25 before the shorter craft-audit trigger): the Section index the external-host carve test requires, its craft-audit row, and the STOP pointer (GSTA-92; Garry 2026-10-25 'Do it' (GSTA-92)). - minUnionBytes: 143_300, // measured union 145049 (2026-10-26) + minUnionBytes: 143_300, // measured union 145037 (2026-10-26) mustContain: ['AI Slop Detection', 'Fix Loop', 'gstack-design-craft', 'Proof beside each claim', 'holds session data'], - maxSizeRatio: 1.3705, // first parity guard for design-review: measured 145082 / 105,842 = 1.3708 (2026-10-25; 145077 after the /ship review fixes, 145068 = 1.3707 after the line-13 reword, 145049 = 1.3705 after the post-merge /ship review, 2026-10-26), the skeleton's growth since v1.64.1.0 plus the craft audit (Garry 2026-10-25 'Do it' (GSTA-92)). + maxSizeRatio: 1.3704, // first parity guard for design-review: measured 145082 / 105,842 = 1.3708 (2026-10-25; 145077 after the /ship review fixes, 145068 = 1.3707 after the line-13 reword, 145049 = 1.3705 after the post-merge /ship review, 145037 = 1.3704 after its second pass, 2026-10-26), the skeleton's growth since v1.64.1.0 plus the craft audit (Garry 2026-10-25 'Do it' (GSTA-92)). }, // ── Token-reduction Phase 4 wave 4 (v1.69.x branch): design doctrine carve ──