Rule handbook metadata
- Rule
DET.HASH.MARKERS· lanedeterministic- Page status
- current
- page_version
f1ae381bf7bcb852bfd9003985c12a0b91c9d4fd8e075dcb96dbec2b98015c14- generated_at
- 2026-05-19T22:20:00.000Z
- registry_fingerprint
aef1de6082cf0f50d463783c843dee0ffb9132fbd5ed4ea6e5bb3f031f359c72
How this rule is fixed
Pilot deterministic fixer: handbook_after · harness mode standalone · verify expect_rule_clean.
- Harness:
apply-harness-fixture-remediation.pycopies the After example HTML from this handbook page onto the defect fixture, theninvoke-det-ruleset-remediation-verify.shre-audits and expects zero findings for this rule. - Production sites:
run-website-ux-remediation-loop.shrunshandbook_html_patch(HTML patches inlib/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-markers. Scroll down for Before / After examples and Evidence and remediation steps.
Purpose
Kitchen Sink assigns every reusable visual root (layout shell, chrome region, page, section, component, diagram block, React primitive root) a three-letter hash registered in docs/design/catalog/visual-registry.yaml. Emitted HTML must expose that hash twice on the same element: hash="XYZ" and data-ks-hash="XYZ", plus data-ks-type and data-ks-name where the catalog defines them. The pair lets crawlers, auditors, and remediation plans locate governed surfaces in raw HTML without relying on class names alone.
This deterministic rule evaluates metrics.ksVisualHashReport from the UX auditor crawl (lib/dom-metrics.js). It flags invalid token shapes, attribute mismatches, one-sided markers, and (as a warning) repeated hashes on multiple nodes. Registry membership is DET.HASH.REGISTRY_ROW; contract file presence is DET.CONTRACT.PATH. Python source should use ks_hash_attrs() (components/ks_hash_attrs.py) so builds fail before shipping one-sided markers.
Plan: Allocate or reuse a hash when adding a visual surface. Do: Emit both attributes from ks_hash_attrs, layout_shell_attrs, chrome_region_attrs, or React ksVisualAttrs / ksReactPrimitiveAttrs. Check: node tools/website-ux-auditor/analyze-website-ux.mjs on built website/ or showcase/, or grep HTML for [data-ks-hash] and confirm each node has a matching hash=. Adjust: Fix pairing before chasing registry or contract issues — a page can pass DET.HASH.MARKERS while DET.CONTRACT.PATH still fails.
Passing signals
- Every element with
[data-ks-hash]or[hash]that represents a governed visual root has both attributes set to the same three-letter value (for examplehash="Hbk"anddata-ks-hash="Hbk"). - Marker values match
/^[A-Za-z]{3}$/(exactly three ASCII letters). Pythonks_hash_attrs()also requires three distinct letters at build time. - Companion metadata is present where KS emits it:
data-ks-type="layout",data-ks-name="layout-handbook",data-ks-type="chrome-region",data-ks-name="doc-sidebar", and similar pairs on showcase pages such asshowcase/preview-handbook.html. ksVisualHashReport.validUniquelists discovered hashes;invalidRaw,mismatches, andincompleteMarkersare empty for the page.instanceCountByHashshows at most one instance per hash on a page, or duplicates are intentional and documented in the catalog contract.- Consumer sites that submodule KS reproduce the same marker pattern on handbook shells (Hbk, Ksr, Kco, Ksf) and doc pages (Ctr, Fag) after
build-showcase.py/ site generators run.
Failing signals
invalidRaw(minor): Value is not exactly three ASCII letters — for exampledata-ks-hash="abcd",hash="12", or placeholder tokens copied from docs.mismatches(minor):hash="Hbk"anddata-ks-hash="Xyz"on the same node — often a partial edit or manual HTML paste.incompleteMarkers(warn): Onlydata-ks-hashwithouthash=, or onlyhash=withoutdata-ks-hashon a governed root.instanceCountByHash> 1 (warn): Same hash on multiple elements (for example twodata-ks-hash="Ksr"sidebars) — may be valid for reusable chrome but needs catalog justification.- Stray
hash=on non-visual nodes pollutes the scan; remove or align with registry policy. - Findings cap at
MAX_HASH_MARKER_FINDINGS(10) per page with a trailing “additional issues omitted” message when many nodes break at once. - Passing this rule does not imply the hash is registered (
DET.HASH.REGISTRY_ROW) or that contracts exist (DET.CONTRACT.PATH).
Before example
Before (failing example)
Handbook
Governed delivery
Layout root missing hash=; sidebar missing data-ks-hash.
Body
Inner card is not a catalog visual root.
Failing handbook shell: layout root carries data-ks-hash and type metadata but omits the paired hash= attribute. Sidebar has hash= but omits data-ks-hash. Crawl reports incompleteMarkers.
After example
After (passing example)
Handbook
Handbook sample page
Markers pair on every governed root.
Footer hash paired.
Passing handbook shell (aligned with showcase/preview-handbook.html): layout and chrome roots emit matching pairs and type metadata from ks_hash_attrs() / chrome_region_attrs().
Evidence and remediation
Capture: Save the audited URL, raw HTML snippet around each flagged selector ([data-ks-hash="…"]), and the ksVisualHashReport slice from analyze output (invalidRaw, mismatches, incompleteMarkers, instanceCountByHash). For KS repo work, grep showcase/ or rebuilt website/ after python3 generator/build-showcase.py.
Remediation (PDCA):
- Plan — Identify the visual root in
visual-registry.yaml(hash,type,name). Do not invent ad hoc tokens. - Do — In Python renderers, use
ks_hash_attrs(hash_id, visual_type, name)or layout/chrome helpers; in React, useksReactPrimitiveAttrs()/ksVisualAttrs(). Never set only one ofhashordata-ks-hash. - Check — Re-run
analyze-website-ux.mjson the built tree; confirmDET.HASH.MARKERSis clean, then runDET.HASH.REGISTRY_ROWandnode tools/design-catalog/check-visual-catalog.mjs --repo .. - Adjust — For intentional duplicate instances, document repetition in the design contract; for consumer sites, bump the
kitchensinksubmodule after fixing emitters in forgesdlc-kitchensink.
Module: design-rules/deterministic/generated/det-hash-markers.check.js (auditor package). Default severity minor; incomplete pairs and duplicate-instance warnings use warn.
Related rules
DET.HASH.REGISTRY_ROW— hash exists in generated registry with expectedtype(orthogonal DOM pairing check).DET.INVENTORY.CROSSWALK— showcase-emitted hashes are a subset of registry; no stray tokens.DET.CONTRACT.PATH— registry row resolves to an on-disk design contract (may fail while markers pass).DET.PY.KS_HASH_ATTRS— Python sources callks_hash_attrs()at emit sites (build-time complement).DET.REACT.KS_ATTRS— React primitives emit governeddata-ks-type/data-ks-name/ hash trio.AI.CONTRACT.IMPLEMENTATION_USEFULNESS— contracts should citeDET.HASH.MARKERSin verification sections for implementers.