Rule handbook metadata

Rule
AI.PY.HTML_AUTHORING_QUALITY · lane ai
Page status
stale
page_version
9612773abc083bc074cce0ff2d407a12d9c644290bb098f2c79f335ea54c80f8
generated_at
2026-05-19T19:15:00.000Z
registry_fingerprint
6773fda516344e110b5a7b1435e655e1264e773825ca8bbe62194189891c42ba

How this rule is fixed

This is an AI-enabled rule. Pass/fail requires model judgment; there is no deterministic fixer in the pilot registry.

  • Harness: invoke-ai-ruleset-harness.sh runs design-rules/ai/run-design-ai-rule.sh on the Before fixture and expects findings with matching principleId.
  • Remediation: Cursor agent plans from forge-ux-remediation.plan.md after sitewide audit — not handbook After copy.

Detection module: docs/design/ux-audit/ai-enabled-design-principles.md#ai-py-html-authoring-quality. Scroll down for Before / After examples and Evidence and remediation steps.

Purpose

Kitchen Sink ships most public surfaces through Python HTML modules (components/components.py, components/layouts.py, components/presentation.py, generator page composers). Deterministic gates prove hash markers and heading order exist; this AI rule judges whether the emitted HTML reads as authored on purpose—a reviewer can infer section jobs, scan headings, and map DOM to render_* entrypoints without mentally unwrapping accidental nesting.

Plan: Open showcase or consumer HTML for a page type, trace each major block to its renderer, and note heading jumps, anonymous wrapper stacks, and spacing hacks that bypass KS helpers. Do: Refactor toward render_section, render_alert, chrome_region_attrs / ks_hash_attrs, and registry-backed roots. Check: Outline order matches h2 then h3/h4/h5 inside sections; optional slots omit ghost headings (DET.PY.OPTIONAL_REGIONS). Adjust: When the same anti-pattern repeats (for example triple-wrapped card grids), propose a DET.* candidate or tighten the contract anatomy field.

Passing signals

  • Major content blocks use render_section (or layout equivalents): <section class="mb-5" id="…">, optional section-label, one <h2 class="font-display">, then body—not a chain of unlabeled <div> shells.
  • Heading ladder stays coherent under each section h2: card titles at h3/h4/h5 (forge-card h5), not h1h4 jumps inside the same article.
  • Visual roots carry hash / data-ks-hash via ks_hash_attrs or chrome_region_attrs where the registry defines a hash (DET.PY.KS_HASH_ATTRS, DET.HASH.MARKERS).
  • Spacing and rhythm use KS tokens (forge-divider, mb-5, forge-support, forge-card, row/col-*) instead of anonymous wrappers with inline margin-top.
  • Optional regions (render_card_rail with empty items, optional sidebars) return "" or omit the section—no empty h2 or placeholder shells.
  • Card rails and callouts use shared helpers (render_card_rail, render_alert, _rail_card_cell) so structure matches showcase “For agents” documentation.
  • A maintainer can point from DOM to implementation notes in the design contract without guessing which Python function produced a subtree.

Failing signals

  • Nesting soup: three or more consecutive wrapper <div>s with no KS class, landmark, or hash—only inline style for spacing.
  • Heading jumps: page-level h1 followed by card h4/h5 with no intervening section h2, or multiple h1 elements in one article.
  • Redundant wrappers duplicating what render_section already provides (extra <section> inside <section> with duplicate titles).
  • Ghost structure: optional lists render empty rails, blank forge-card shells, or section-label above missing body copy.
  • Ad-hoc semantics: breadcrumbs, alerts, or CTAs hand-rolled with generic classes while render_breadcrumbs / render_alert / render_nav_buttons exist.
  • Hash afterthought: visual chrome invented in raw strings while registry rows expect ks-doc-breadcrumb, ks-section, or catalog hashes.
  • Copy-pasted markup blocks across pages with drifting class lists—signals the renderer should be centralized in components/.

Before example

Before (failing example)

Governed delivery

Human-owned intent with agent execution.

Traceable

Evidence on every change.

Reviewable

Gates before release.

Bounded

Clear execution limits.

Failing KS markup: anonymous wrapper stack, heading jump (h1h4), spacing via nested unclassed <div>s instead of render_section / forge-divider, and outcome cells without forge-card or section shell.

After example

After (passing example)


What teams gain

Traceable

Evidence on every change

Reviewers can follow intent to work to proof without opening source maps.

Reviewable

Gates before release

Human checkpoints stay visible in the delivery spine.

Bounded

Clear execution limits

Agents and automation run inside declared boundaries.

Passing KS markup: render_section shell with forge-divider, coherent h2 section title, section-label, and forge-card outcome cells—structure tied to components/components.py and presentation._rail_card_cell.

Evidence and remediation

Capture: generator module path (for example generator/pages/*.py, components/components.py), function name (render_section, render_card_rail), built HTML snippet or DOM snapshot, design contract render_entrypoints / anatomy, and screenshot when the page is registry-backed. Note heading order (h1 count, first h2, card heading levels) and wrapper depth.

Remediate (in order):

  1. Replace anonymous wrapper stacks with render_section (or layout slot contracts) so each major block has one id, one h2, and optional section-label.
  2. Normalize heading levels inside sections (h3/h5 on cards under section h2); fix page-level h1 policy per layout contract.
  3. Route cards, rails, and callouts through forge-card, render_card_rail, render_alert, or other shared helpers—do not fork markup strings.
  4. Emit ks_hash_attrs / chrome_region_attrs on visual roots required by the registry; align with DET.PY.KS_HASH_ATTRS.
  5. Guard optional slots so empty inputs omit the region entirely (DET.PY.OPTIONAL_REGIONS).
  6. Update the element contract anatomy and forbidden_patterns when structure changes; rebuild showcase (python3 generator/build-showcase.py) and re-run AI batch on the affected URLs.
  7. If the same nesting or heading jump appears across multiple renderers, propose a deterministic DET.* (for example max anonymous wrapper depth) in the remediation plan.