Rule handbook metadata

Rule
DET.CONTRACT.PATH · lane deterministic
Page status
stale
page_version
6083955e6d8907caed366060a29dc76649afb4426732ba85cdadc89524e30a35
generated_at
2026-05-19T21:30:00.000Z
registry_fingerprint
6773fda516344e110b5a7b1435e655e1264e773825ca8bbe62194189891c42ba

How this rule is fixed

Pilot deterministic fixer: repo_overlay · harness mode repo_overlay · verify expect_rule_clean.

  • Harness: fixture includes a repo overlay tree; remediate_repo_overlay() writes catalog/repo files, then applies After HTML when present.
  • Production: repo_overlay Node adapter patches the website repository (contracts, registry JSON, CSS, Python stubs).

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

Purpose

Kitchen Sink ties every active visual-registry row to a design contract — a Markdown file under docs/design/catalog/**/{HASH}-*.md that records anatomy, states, accessibility, forbidden patterns, and screenshot acceptance. When contract_status is own or family-covered, the registry must list a non-empty contract / contract_path that resolves to a real file in the repo. Without that link, showcase HTML can still render with correct hash / data-ks-hash markers while implementers and auditors have no authoritative spec.

This deterministic rule scans docs/design/catalog/visual-registry.generated.json during the metrics phase (scanContractPaths). It flags empty-path (required status but no path) and missing-file (path set but file absent). Rows with other statuses (for example not-applicable) are out of scope when policy does not require a contract file.

Plan: After adding or renaming a hash, allocate or update the registry row and contract file together. Do: Set contract: to the canonical path (for example docs/design/catalog/layouts/Hbk-layout-handbook.md) and commit the Markdown contract in the same change. Check: node tools/design-catalog/check-visual-catalog.mjs --repo . and confirm contractPathReport.issues is empty. Adjust: Either restore the contract file, fix the registry path, or change contract_status with a justified family rule when a separate contract is not required.

Passing signals

  • Every active registry entry with contract_status: own has contract (or contract_path) set to an existing file such as docs/design/catalog/layouts/Hbk-layout-handbook.md.
  • Family-covered rows reference the family contract on disk (for example a shared Ksc style-family contract) — path is non-empty and fs.existsSync succeeds from repo root.
  • contractPathFromRegistryEntry returns the same path the catalog linter and check-visual-catalog.mjs use (entry.contract ?? entry.contract_path).
  • scanContractPaths returns { skipped: false, issues: [] } after regenerating the registry JSON from visual-registry.yaml.
  • Showcase and consumer builds emit layout chrome (Hbk, Ksr, Ksf, Kbc) that matches the contract named in the registry row for that hash.
  • contract_status: not-applicable rows are not required to carry a contract path unless policy changes — no false positives for intentionally uncovered primitives.

Failing signals

  • empty-path: status: active and contract_status: own (or family-covered) but contract is null, "", or whitespace — message cites contract_status and hash.
  • missing-file: Registry lists docs/design/catalog/layouts/Hbk-layout-handbook-OLD.md (or a typo directory) after a rename; HTML and hashes unchanged but the contract file was deleted or never added.
  • Contract moved under docs/design/catalog/chrome/ without updating visual-registry.yaml / regenerating JSON.
  • New hash allocated in Python (layout_shell_attrs, chrome_region_attrs) while the registry row still has contract_status: own and an empty contract field.
  • Auditor caps at MAX_CONTRACT_PATH_FINDINGS (12) per pass with a trailing “additional issues omitted” finding when many rows break at once.
  • contractPathReport.skipped: true with reason: no-registry — fix registry generation before interpreting pass/fail on consumer sites.

Before example

Before (failing example)

Governed delivery

Long-form reading column with sidebar rail.

Body

Markup matches Hbk anatomy, but registry contract path is broken.

Failing governance: Hbk handbook shell HTML is valid and hash-marked, but the registry row still points at a removed contract path (docs/design/catalog/layouts/Hbk-layout-handbook-OLD.md). DET.CONTRACT.PATH reports missing-file; DET.HASH.MARKERS may still pass on the emitted page.

After example

After (passing example)

Governed delivery

Registry contract_path matches on-disk Hbk-layout-handbook.md.

Body

Implementers can trace anatomy to docs/design/catalog/layouts/Hbk-layout-handbook.md.

Passing governance: same Hbk / Ksr / Ksf handbook shell; registry contract resolves to docs/design/catalog/layouts/Hbk-layout-handbook.md (file present). Chrome contracts (Ksr, Ksf) remain linked in their own registry rows for family or own status.

Evidence and remediation

Evidence: Metrics phase stores contractPathReport with rowCount, issues[] (kind: empty-path | missing-file, hash, contractStatus, optional contract rel path). Findings use area visual-catalog, severity minor, and evidence such as hash=Hbk contract_status=own contract=docs/design/catalog/layouts/Hbk-layout-handbook-OLD.md. Attach the registry row snippet from visual-registry.yaml and git status showing whether the contract file exists.

Remediate (in order):

  1. Restore or create the contract — add docs/design/catalog/**/{HASH}-*.md with identity, anatomy, and verification sections; match the hash slug convention used elsewhere in the catalog.
  2. Fix the registry path — set contract: (and regenerate visual-registry.generated.json) to the real file; run node tools/design-catalog/check-visual-catalog.mjs --repo . --registry docs/design/catalog/visual-registry.yaml --showcase showcase.
  3. Empty path — if the row should not own a contract, set contract_status to not-applicable only with a documented family rule; do not leave own with a blank contract.
  4. Family-covered — point at the family contract file that explicitly covers child hashes (AI.CONTRACT.FAMILY_COVERAGE_JUSTIFIED when variance is high).
  5. Re-audit — run analyze-website-ux.mjs on the KS repo or consumer site; confirm no DET.CONTRACT.PATH findings before relying on AI.CONTRACT.IMPLEMENTATION_USEFULNESS or DET.CATALOG.CONTRACT_SPECIFICITY.