Rule handbook metadata
- Rule
DET.PAGE.TITLE· lanedeterministic- Page status
- current
- page_version
4040ca340c20e070ac3646e7875cf98f539cdb90d66b4145dd5874f55ad35dfd- generated_at
- 2026-05-25T16:45:00.000Z
- registry_fingerprint
2ce40848effce579d3e4879f6ca85535183a14db201870a6c007da424624550c
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-page-title. Scroll down for Before / After examples and Evidence and remediation steps.
Purpose
The <title> element is the primary document label for browser chrome, history, bookmarks, search results, and screen-reader page summaries. A missing or placeholder title forces users to infer context from the URL or first heading — especially painful when many handbook tabs are open.
Kitchen Sink layouts set titles from Python parameters:
handbook_page—<title>{handbook_name} — {browser_title}</title>(e.g.Forge SDLC — Governed delivery handbook). The visible<h1 class="font-display">usespage_title, which may differ frombrowser_titlewhen the tab label should stay shorter.chapter_page/ JS-driven handbook shells —{handbook_name} — {browser_title}in<title>.product_page,landing_page, showcase shells —doc_titleorbrowser_titletied to the page's primary job.
This deterministic rule runs in the metrics phase. The crawler reads document.title (whitespace-normalized into metrics.title). A page passes when the title is non-empty and not a known generic placeholder (index, home, document, page, case-insensitive). A page fails when the title is missing or empty (major) or matches a generic placeholder (minor).
Plan: Define a title pattern per layout (handbook name + chapter, product name + section). Do: Pass browser_title / doc_title into layout calls and verify <title> in generated HTML. Check: metrics.title in crawl JSON is descriptive; DET.PAGE.TITLE produces no findings. Adjust: Replace scaffold defaults (Home, index) in generators, SPA shells, and static export stubs.
Passing signals
<title>in<head>is non-empty after trim — auditmetrics.titleis truthy.- Title follows a site-specific pattern: handbook pages use
{handbook_name} — {browser_title}; product pages use the visible primary topic, not a filename stem. handbook_pageoutput matches{handbook_name} — {browser_title}fromcomponents/layouts.py.- Title aligns with the primary
<h1>or breadcrumb leaf — users see the same words in the tab and on the page where practical. - Generic placeholders are avoided: not
Home,Index,Document, orPagealone (seeGENERIC_TITLESintitle.check.js). - Audit produces no
DET.PAGE.TITLEfindings.
Failing signals
- Missing or empty title: no
<title>element,<title></title>, or whitespace-only content — major finding: "Page title is missing." - Generic placeholder:
<title>Home</title>,<title>index</title>,<title>Document</title>, or<title>Page</title>— minor finding: "Page title is too generic." - Scaffold drift: generator leaves Vite/React default
indexor a bare directory name while body copy and<h1>are fully authored. - Title/body mismatch: tab reads
Homebut<h1 class="font-display">shows a specific chapter — hurts wayfinding and SEO snippets. - Wrong source: title copied from a layout partial but post-processing strips
<head>during static export. - Auditor evidence includes
Title: "Home"or<title> is empty or absent.
Before example
Before (failing example)
Methodology
Governed human + agent delivery
Body copy is specific, but the browser tab still says Home.
Outcome
Tabs, bookmarks, and search snippets cannot distinguish this page.
Failing KS markup: handbook-style shell mirrors handbook_page anatomy (forge-aurora, forge-sidebar, main#main, doc-content, font-display heading) but leaves the scaffold placeholder Home in <title> instead of a descriptive handbook + chapter label.
After example
After (passing example)
Methodology
Governed human + agent delivery
Tab title matches the handbook name and page topic.
Outcome
Browser chrome and assistive tech announce a specific document label.
Passing KS markup: same handbook shell with a descriptive <title> as emitted by handbook_page when handbook_name="Forge SDLC" and browser_title="Governed delivery handbook".
Evidence and remediation
| Evidence | Meaning | Remediation |
|---|---|---|
metrics.title empty in crawl JSON |
<title> missing or blank |
Add <title> in layout <head>; pass browser_title / doc_title into handbook_page, chapter_page, or product_page |
| Finding: Page title is missing | title.check.js major failure |
Ensure generator emits <title> before ship; fix SPA shells that render body without updating document.title |
Finding: Page title is too generic with Title: "Home" |
Placeholder in {index, home, document, page} set |
Replace scaffold default with {handbook_name} — {browser_title} or product-specific label |
Raw HTML <title>Home</title> on authored pages |
Layout default not overridden | Set browser_title in content map / generator call; rebuild website/ |
Kitchen Sink: Pass meaningful browser_title and handbook_name into handbook_page(...). Confirm generator/build-showcase.py and consumer builds emit <title> in the first <head> block. Match the visible <h1 class="font-display"> topic (page_title) where practical.
Consumer sites: After layout fixes, run python3 generator/build-site.py (or handbook build), then re-audit. Spot-check: curl -s … | grep -i '<title>' should show a descriptive string, not Home or index.
Harness: generator/build_rule_defect_fixtures.py and auditor-tests/invoke-det-ruleset-harness.sh --only-rule DET.PAGE.TITLE for regression. Implementation: tools/website-ux-auditor/design-rules/deterministic/page/title.check.js. Deterministic fixer adapter: page_title in lib/ux-deterministic-fixers/.