Rule handbook metadata

Rule
DET.HASH.REGISTRY_ROW · lane deterministic
Page status
stale
page_version
8b23253fec83e82d81039d13831251f57cd75cb62b86f892e33426a08c8c3ba9
generated_at
2026-05-19T22:45:00.000Z
registry_fingerprint
6773fda516344e110b5a7b1435e655e1264e773825ca8bbe62194189891c42ba

How this rule is fixed

Pilot deterministic fixer: handbook_after · harness mode standalone · verify expect_rule_clean.

  • Harness: apply-harness-fixture-remediation.py copies the After example HTML from this handbook page onto the defect fixture, then invoke-det-ruleset-remediation-verify.sh re-audits and expects zero findings for this rule.
  • Production sites: run-website-ux-remediation-loop.sh runs handbook_html_patch (HTML patches in lib/ux-deterministic-fixers/fixers/patches/) before invoking the Cursor agent when the quality gate still fails.

Detection module: docs/design/ux-audit/deterministic-design-rules.md#det-hash-registry-row. Scroll down for Before / After examples and Evidence and remediation steps.

Purpose

Kitchen Sink registers every governed visual surface in docs/design/catalog/visual-registry.yaml, emitted as docs/design/catalog/visual-registry.generated.json. When HTML ships with hash="XYZ" / data-ks-hash="XYZ", auditors must confirm that XYZ is a real registry row and that optional DOM metadata matches the row's type field (for example layout for Hbk, chrome-region for Ksr).

This deterministic rule runs in the metrics phase (det-hash-registry-row.check.js). It collects hash instances from metrics.ksVisualHashReport or live DOM ([data-ks-hash], [hash]), then crosswalks each three-letter token against the generated registry. DET.HASH.MARKERS only checks marker shape and pairing; DET.HASH.REGISTRY_ROW answers whether the token is catalog-governed and typed correctly. Contract file presence remains DET.CONTRACT.PATH.

Plan: Allocate or reuse a hash in visual-registry.yaml before emitting it from Python (ks_hash_attrs, layout_shell_attrs, chrome_region_attrs) or React helpers. Do: Regenerate JSON after registry edits; keep data-ks-type aligned with the registry type column. Check: node tools/design-catalog/check-visual-catalog.mjs --repo . and analyze-website-ux.mjs on showcase/ or consumer website/. Adjust: Register unknown hashes, migrate deprecated aliases, or fix data-ks-type mismatches before relying on contract or AI usefulness rules.

Passing signals

  • Every rendered hash on a governed visual root (for example Hbk, Ksr, Ksf, Kco) appears in visual-registry.generated.json with status: active (or an allowed non-deprecated state).
  • When data-ks-type is present on the DOM node, it equals the registry row's type after normalization (case-insensitive trim): layout for handbook shell Hbk, chrome-region for aside.forge-sidebar Ksr, chrome-region for Ksf footer region.
  • buildHashRegistryRowReport returns { skipped: false, issues: [] } for the page's hash instance list.
  • hash and data-ks-hash agree on the canonical token (conflicting pairs are skipped by the collector, per DET.HASH.MARKERS).
  • Showcase builds after python3 generator/build-showcase.py emit only registry-known hashes on preview pages such as showcase/preview-handbook.html.
  • No unknown-hash, type-mismatch, or deprecated kinds in hashRegistryRowReport.issues.
  • Generated registry has no duplicate hash keys (registry-duplicate is empty).

Failing signals

  • unknown-hash (warn): HTML emits data-ks-hash="Zzz" (or any three-letter token) with no row in visual-registry.generated.json — common after a local experiment or copy-paste from docs without running allocate-visual-hash.mjs.
  • type-mismatch (minor): Registry lists Ksr as type: chrome-region but DOM has data-ks-type="component" or data-ks-type="layout" on the sidebar root.
  • deprecated (minor): Registry row status: deprecated still emitted on a consumer site; remediation should follow registry aliases to the successor hash.
  • registry-missing (minor): Markers present in HTML but visual-registry.generated.json is absent or unreadable at repo root — fix catalog generation before interpreting other visual-catalog rules.
  • registry-duplicate (warn): Generated JSON lists the same hash twice — repair visual-registry.yaml / generator output so entryByHash is unambiguous.
  • Findings cap at MAX_HASH_REGISTRY_ROW_FINDINGS (12) per pass with a trailing "additional issues omitted" finding when many hashes break at once.
  • Passing DET.HASH.MARKERS does not imply registry membership; a perfectly paired unknown token still fails here.

Before example

Before (failing example)

Unregistered surface

Hash Zzz is not in visual-registry.generated.json.

Registry crosswalk failure

Ksr type does not match catalog; Zzz is unknown.

Body

Inner card has no hash — not evaluated by this rule.

Failing crosswalk: handbook shell Hbk is registered and typed correctly, but Ksr declares data-ks-type="component" while the registry row is chrome-region, and a stray hero block emits unregistered hash Zzz.

After example

After (passing example)

Governed delivery

Hbk and Ksr rows match visual-registry.generated.json.

Passing crosswalk: remove or register experimental surfaces; Ksr uses data-ks-type="chrome-region" per docs/design/catalog/chrome/Ksr-doc-sidebar.md; only registry-known hashes remain on visual roots.

Evidence and remediation

Evidence: Metrics may include hashRegistryRowReport with registryJson, rowCount, issues[] (kind: unknown-hash | type-mismatch | deprecated | registry-missing | registry-duplicate, hash, optional domType / registryType, message). Findings use area visual-catalog, default severity warn for unknown hashes, minor for type mismatches and deprecated rows. Selectors such as [data-ks-hash="Ksr"] anchor remediation to the DOM node. Attach the registry row snippet from visual-registry.yaml and the built HTML fragment showing data-ks-type.

Remediate (in order):

  1. Unknown hash — run node tools/design-catalog/allocate-visual-hash.mjs, add the row to visual-registry.yaml, create or link the design contract, regenerate visual-registry.generated.json, then emit the hash from ks_hash_attrs() / layout helpers. If the surface is not governed, remove the markers instead of inventing a token.
  2. Type mismatch — align data-ks-type with the registry type field (see components/ks_hash_attrs.py and ks_catalog_hashes.py for canonical layout vs chrome-region labels).
  3. Deprecated hash — migrate HTML and contracts to the successor hash listed under registry aliases; stop emitting the deprecated token on new builds.
  4. Missing or duplicate registry JSON — run the design-catalog generator and node tools/design-catalog/check-visual-catalog.mjs --repo . --registry docs/design/catalog/visual-registry.yaml --showcase showcase until the registry report is clean.
  5. Re-audit — run node tools/website-ux-auditor/analyze-website-ux.mjs on the KS repo or consumer site; clear DET.HASH.REGISTRY_ROW before treating DET.CONTRACT.PATH or AI.CONTRACT.IMPLEMENTATION_USEFULNESS as authoritative for that hash.