From bf632b6996076d0c347cf4da7ec924d8a4a4aa44 Mon Sep 17 00:00:00 2001 From: garrytan Date: Mon, 26 Oct 2026 05:36:15 +0000 Subject: [PATCH] docs(design-lint): CHANGELOG entry, NOTICE and MIT-hallmark licence, module-size ratchet entries Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --- CHANGELOG.md | 18 ++++++++++++++++++ NOTICE.md | 18 ++++++++++++++++++ licenses/MIT-hallmark.txt | 21 +++++++++++++++++++++ test/fixtures/module-size-ratchet.json | 11 +++++++++++ 4 files changed, 68 insertions(+) create mode 100644 licenses/MIT-hallmark.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index dc2778549..9d44b963a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,23 @@ # Changelog +## [Unreleased] + +**A free, deterministic design lint ships with gstack: `bin/gstack-design-lint` checks a page's HTML, CSS and components for the tells that make it read as machine-made, in under a second, and with `--render` measures what only a browser can.** Until now gstack's only mechanical design check was the opt-in impeccable engine most users never install, plus `gstack-design-craft`'s seventeen copy and ship-floor regexes; everything else in the Slop Gate was prose the model judged itself. The lint ports the roughly fifty-five machine-checkable gates of [Nutlope/hallmark](https://github.com/Nutlope/hallmark)'s `sloplint` (MIT; see NOTICE.md) into TypeScript under `lib/design-lint/`, rewritten in gstack's voice and mapped onto gstack's severity words. This release is the tool alone (Phase 1 of plans/absorb-hallmark.md, approved by Garry on 2026-10-26); /design-html and /design-review start calling it in Phase 2, so no skill prose changes here. + +### Added +- **`bin/gstack-design-lint [--render] [--url] [--scope page|component] [--job ] [--json] [--rules]`**: reads `.html`, `.css`, `.jsx`, `.tsx`, `.vue`, `.svelte` and `.astro` (Tailwind class strings included, `cn()`/`clsx()`/`cva()` calls too), links each page to the stylesheets it reaches through `` and `@import`, resolves CSS variables, converts colours to OKLCH and computes contrast, and prints one line per finding: `LINT: : | fix: `, then `LINT_SUMMARY: blocks=N ask=N waived=N polish=N render=`. Exit 2 on blocks, 1 on an unanswered ask, 0 otherwise. `docs/design-lint.md` is the contract and lists every rule. +- **Three tiers in gstack's words, no fourth scale.** `blocks` (hallmark's Floor: contrast, focus rings, reduced motion, a card in a card, a purple-blue gradient, content hidden until JavaScript runs; never waivable), `ask` (hallmark's Reflex: three equal cards, Inter as the display, the centred-stack hero; waivable on the record) and `polish` (hallmark's Finish: straight quotes, a lonely last grid item; never blocks). Blocking and waived counts are never summed, so `blocks=0` is always a true sentence about the Floor. Three house rules hallmark holds at Floor stay at ask here: the eyebrow above a heading, the 80-word screen and the dash. +- **Waivers on the record.** `` (or the `/* */` and `//` comment forms; `impeccable-disable : ` is an alias) answers an ask or polish finding when the reason is about this page: 24 characters or more, not boilerplate, not reused on another waiver, sharing a word with the page's own text. A waiver of a blocking rule is refused and the rule still fires; more than three waivers on one page is reported as a house style that belongs in DESIGN.md. +- **The render tier** (`--render`, or `--url` for a dev server) runs on the same engine `gstack-render` picks, Aside first and gstack's own headless browser otherwise, with nothing to install: the hero fits at 1280x800 (headline, sentence, action and visual), about 80 words per 900px window, contrast against the painted pixels, focus rings found by focusing every control, headings crowded against the section above, text painted under another element, horizontal scroll between 320 and 1920, wrapping button labels, thin sections, dead bands, drawn illustrations, empty picture slots, counting marks and photographs covering more than a third of the page. Without a browser the summary says `render=skipped: ` and the static tier still runs. +- **The copy tier**: `gstack-design-craft`'s content-realism and ship-floor tells (placeholder names, lorem, buzzwords, round numbers, `[Needs proof]`, dead links, images without alt, the missing title, description, skip link and `aria-current`) report under the same contract and ids, so one command prints one list. `bin/gstack-design-craft` itself is unchanged until Phase 2 swaps the call. +- Fixtures under `test/fixtures/design-lint/` (hallmark's `slopped.html`, eyebrow and Tailwind pass/fail pairs and the waiver page, MIT-attributed, plus a clean page every rule family must leave alone); `licenses/MIT-hallmark.txt`; a NOTICE.md entry. + +### Tests +- `test/design-lint.test.ts`: the parsers (nested CSS, tokens, var() fallbacks, colour spaces, JSX pseudo-HTML), the rule table against `docs/design-lint.md`, the output lines and exit codes, waiver acceptance and every refusal reason, the waiver fixture. One test per rule family (`test/design-lint-.test.ts`) holds a negative control and a planted positive for every rule id. `test/design-lint-render.test.ts` drives the browse daemon when it is built and skips with a named reason otherwise. + +### Gate integrity +- No threshold, budget, timeout, trial count or assertion was weakened. New code only; no template, catalog or eval changed. + ## [1.91.229.0] - 2026-10-26 **The OpenSSF Scorecard workflow uploads its results with `github/codeql-action/upload-sarif` 4.39.0 (from 4.38.3), recreated from Dependabot's #3307.** Dependabot's branch can't take a version stamp at merge time, so the same one-line change ships from a crew branch. The new pin `6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee` is the commit that the annotated tag `v4.39.0` points to in github/codeql-action, and GitHub shows that commit as verified. 4.39.0's one breaking change raises the minimum CodeQL bundle to 2.20.7, which applies to `init` and `analyze`. This workflow uses only `upload-sarif` with Scorecard's own SARIF file. diff --git a/NOTICE.md b/NOTICE.md index 831e0162a..2c9acedc8 100644 --- a/NOTICE.md +++ b/NOTICE.md @@ -50,6 +50,24 @@ signature components are not carried over): ship-floor tells, turned into a free check. - `design-shotgun/SKILL.md.tmpl`: page archetypes as a variant axis. +## hallmark — Copyright (c) 2026 Hallmark contributors — MIT License + +https://github.com/Nutlope/hallmark (`skills/hallmark/scripts/sloplint.mjs`, +`sloplint-render.mjs`, `references/gates.md`, `scripts/fixtures/`, at 7ec8682). +License text: `licenses/MIT-hallmark.txt`. + +Derived, modified (every gate rewritten in TypeScript and in gstack's voice, +mapped onto gstack's severity words; hallmark's theme stamp, genres, posture +guards, photo index and judged gates are not carried over): + +- `lib/design-lint/` and `bin/gstack-design-lint`: the static tier's parsers + (CSS rules and tokens, HTML and component pseudo-HTML, Tailwind class + strings), the colour maths, the waiver record, and the rule families under + `lib/design-lint/rules/`; the render tier in `lib/design-lint/render*.ts`, + driving gstack's own browser instead of puppeteer. +- `test/fixtures/design-lint/{slopped.html,eyebrow-pass,eyebrow-fail,tailwind-pass,tailwind-fail,waiver}`: + the fixtures, with their waiver comments rewritten to the lint's form. + ## DESIGN.md specification — Copyright Google LLC — Apache License 2.0 https://github.com/google-labs-code/design.md diff --git a/licenses/MIT-hallmark.txt b/licenses/MIT-hallmark.txt new file mode 100644 index 000000000..f4bfc53d8 --- /dev/null +++ b/licenses/MIT-hallmark.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Hallmark contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/test/fixtures/module-size-ratchet.json b/test/fixtures/module-size-ratchet.json index 6077ef67e..401dd210c 100644 --- a/test/fixtures/module-size-ratchet.json +++ b/test/fixtures/module-size-ratchet.json @@ -1,5 +1,16 @@ { "newModules": [ + { "file": "lib/design-lint/css.ts", "movedFrom": "(new: the bundled design lint, GSTA-105; ported from hallmark sloplint.mjs)" }, + { "file": "lib/design-lint/color.ts", "movedFrom": "(new: the bundled design lint, GSTA-105; ported from hallmark sloplint.mjs)" }, + { "file": "lib/design-lint/html.ts", "movedFrom": "(new: the bundled design lint, GSTA-105; ported from hallmark sloplint.mjs)" }, + { "file": "lib/design-lint/context.ts", "movedFrom": "(new: the bundled design lint, GSTA-105; ported from hallmark sloplint.mjs)" }, + { "file": "lib/design-lint/report.ts", "movedFrom": "(new: the bundled design lint, GSTA-105; ported from hallmark sloplint.mjs)" }, + { "file": "lib/design-lint/waivers.ts", "movedFrom": "(new: the bundled design lint, GSTA-105; ported from hallmark sloplint.mjs)" }, + { "file": "lib/design-lint/static.ts", "movedFrom": "(new: the bundled design lint, GSTA-105; ported from hallmark sloplint.mjs)" }, + { "file": "lib/design-lint/index.ts", "movedFrom": "(new: the bundled design lint, GSTA-105; ported from hallmark sloplint.mjs)" }, + { "file": "lib/design-lint/rules/ids.ts", "movedFrom": "(new: the bundled design lint, GSTA-105; ported from hallmark sloplint.mjs)" }, + { "file": "lib/design-lint/rules/index.ts", "movedFrom": "(new: the bundled design lint, GSTA-105; ported from hallmark sloplint.mjs)" }, + { "file": "lib/design-lint/rules/copy.ts", "movedFrom": "(new: the bundled design lint, GSTA-105; ported from hallmark sloplint.mjs)" }, { "file": "lib/pricing.ts", "movedFrom": "test/helpers/pricing.ts (PRICING, estimateCostUsd; plan E1 moved the table under lib/ so bin/gstack-eval-plan can price arms)" }, { "file": "lib/eval-plan.ts", "movedFrom": "(new: preregistration check, priced arms, $0 dry run, priced pilot ledger behind bin/gstack-eval-plan, plan E1)" }, { "file": "lib/lane-ownership.ts", "movedFrom": "(new: lane ownership check behind bin/gstack-lane-check, plan E2)" },