diff --git a/CHANGELOG.md b/CHANGELOG.md index 71c490dd4..e9bb85bbb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ ### Changed - **The archetype the user picks on the /design-shotgun board now reaches /design-html.** Captions name the archetype id (`classic-hero`, `long-form-story`, `minimal-conversion`, `comparison`). On approval, approved.json also gets the chosen `archetype` and its `sections` outline, added with the Edit tool so no free text reaches a shell command. /design-html reads both in Case A, and the craft section uses them as given instead of choosing again or asking. - **Accepted craft exceptions persist.** /design-html's finalized.json records each accepted `CRAFT_CHECK` finding in `craft_exceptions` (`id`, `count`, `reason`) and carries forward earlier ones. A later run passes that file with `--accepted`, so a finding the user already accepted is reported as accepted instead of flagged again. A higher count is still flagged as a new issue. -- **/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 textless 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`; on a live page 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 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`; on a live page 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. - **/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 1cf7bda7d..4a4d2365a 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 textless 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. On a live page, 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()` 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. On a live page, never mark or cut a claim as the rules below say: file it and ask for the proof. ### 2. What the check cannot see diff --git a/design-review/sections/craft-audit.md.tmpl b/design-review/sections/craft-audit.md.tmpl index 741196cdb..219537aaa 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 textless 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. On a live page, 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()` 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. On a live page, never mark or cut a claim as the rules below say: file it and ask for the proof. ### 2. What the check cannot see diff --git a/test/design-craft-resolvers.test.ts b/test/design-craft-resolvers.test.ts index 55066f328..8671bb95e 100644 --- a/test/design-craft-resolvers.test.ts +++ b/test/design-craft-resolvers.test.ts @@ -42,6 +42,7 @@ describe('craft resolvers', () => { const audit = read('design-review', 'sections', 'craft-audit.md'); expect(audit).toContain('line is one category 9 finding under that id'); expect(audit).toContain('no `CRAFT_RESULT` line (framework source'); + expect(audit).toContain('or a mount-node shell: say the check was unavailable for that page and judge the tells below by eye'); expect(audit).toContain('add `--accepted` with that screen\'s finalized.json'); expect(audit).toContain('a `CRAFT_ACCEPTED` line is a finding the user accepted, listed with its reason, not filed again, except `needs-proof` and `lorem`'); expect(audit).toContain('After a `cannot use exceptions` warning, file every line.'); diff --git a/test/helpers/carve-guards.ts b/test/helpers/carve-guards.ts index 5ddf28371..381c64a28 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 145077 (2026-10-26) + minUnionBytes: 143_300, // measured union 145068 (2026-10-26) mustContain: ['AI Slop Detection', 'Fix Loop', 'gstack-design-craft', 'Proof beside each claim', 'holds session data'], - maxSizeRatio: 1.3708, // first parity guard for design-review: measured 145082 / 105,842 = 1.3708 (2026-10-25; 145077 after the /ship review fixes, 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.3707, // 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, 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 ──