Rule handbook metadata
- Rule
AI.PY.HTML_AUTHORING_QUALITY· laneai- 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.shrunsdesign-rules/ai/run-design-ai-rule.shon the Before fixture and expects findings with matchingprincipleId. - Remediation: Cursor agent plans from
forge-ux-remediation.plan.mdafter 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="…">, optionalsection-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 ath3/h4/h5(forge-card h5), noth1→h4jumps inside the same article. - Visual roots carry
hash/data-ks-hashviaks_hash_attrsorchrome_region_attrswhere 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 inlinemargin-top. - Optional regions (
render_card_railwith empty items, optional sidebars) return""or omit the section—no emptyh2or 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 inlinestylefor spacing. - Heading jumps: page-level
h1followed by cardh4/h5with no intervening sectionh2, or multipleh1elements in one article. - Redundant wrappers duplicating what
render_sectionalready provides (extra<section>inside<section>with duplicate titles). - Ghost structure: optional lists render empty rails, blank
forge-cardshells, orsection-labelabove missing body copy. - Ad-hoc semantics: breadcrumbs, alerts, or CTAs hand-rolled with generic classes while
render_breadcrumbs/render_alert/render_nav_buttonsexist. - 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.
Outcomes
Traceable
Evidence on every change.
Reviewable
Gates before release.
Bounded
Clear execution limits.
Failing KS markup: anonymous wrapper stack, heading jump (h1 → h4), 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)
Outcomes
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):
- Replace anonymous wrapper stacks with
render_section(or layout slot contracts) so each major block has oneid, oneh2, and optionalsection-label. - Normalize heading levels inside sections (
h3/h5on cards under sectionh2); fix page-levelh1policy per layout contract. - Route cards, rails, and callouts through
forge-card,render_card_rail,render_alert, or other shared helpers—do not fork markup strings. - Emit
ks_hash_attrs/chrome_region_attrson visual roots required by the registry; align withDET.PY.KS_HASH_ATTRS. - Guard optional slots so empty inputs omit the region entirely (
DET.PY.OPTIONAL_REGIONS). - 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. - 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.