Rule handbook metadata
- Rule
DET.CHART.ALT_SUMMARY· lanedeterministic- Page status
- stale
- page_version
6c251e266ae748fcae1c2704355aa3b9e01b41b427713414b2268dc540d32340- generated_at
- 2026-05-19T20:15:00.000Z
- registry_fingerprint
6773fda516344e110b5a7b1435e655e1264e773825ca8bbe62194189891c42ba
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-chart-alt-summary. Scroll down for Before / After examples and Evidence and remediation steps.
Purpose
Kitchen Sink data charts ship through render_ks_chart_mount (components/components.py), forge-data-charts.js, and showcase pages (Dcs, Dca). Screen readers and skimmers who do not parse bar geometry still need a text equivalent for what the chart represents—not a one-word stub.
This deterministic rule scans visible chart roots ([data-ks-chart], .ks-chart-mount, [data-chart], and chart-class containers) and requires at least 8 characters of summary text via aria-label, aria-labelledby, aria-describedby (with a resolvable target), title, sr-only / data-chart-summary nodes, or a nearby figcaption / forge-support caption. Decorative ambient canvases inside .forge-ambient-bg, .ks-ambient-bg, and aria-hidden subtrees are excluded.
Plan: List chart mounts on the page (static SVG, client-rendered canvas, API-driven mounts). Do: Pair each mount with a caption or wire aria-describedby to a paragraph that names metric, window, and direction. Check: Re-run the auditor metrics phase (chartAltSummaryReport) or inspect each ks-chart-mount in DevTools. Adjust: If only generic labels repeat, add summaries in the generator or page template; for “so what?” copy quality, see AI.DATA.INSIGHT_LEGIBILITY.
Passing signals
- Chart root or inner
svg/canvas/[role="img"]hasaria-labelortitlewith at least 8 characters (for example “Weekly commits by ISO week, 2025-W08 through W11”). - Mount uses
aria-describedby(oraria-labelledby) pointing at an element whose text is at least 8 characters—commonlyforge-supportcopy above or below the mount. figure+figcaptionwraps the mount with a non-trivial caption, or ap.forge-support/[data-chart-summary]sits within two sibling positions of the mount (matchesrender_ks_chart_mounttitle line plus an insight sentence).- Sr-only summary (
.sr-only,.visually-hidden,[data-chart-summary]) inside the mount carries at least 8 characters when visible captions are intentionally minimal. - Ambient exclusion: canvases in
.forge-ambient,.ks-has-ambient-bg, oraria-hidden="true"decorative layers are not scored as data charts. - Summary text is consistent with visible series labels where both exist (does not contradict bar labels or legend swatches).
Failing signals
ks-chart-mountwith renderedsvg[role="img"]but noaria-describedby, no nearby caption, and onlyaria-label="Chart"oraria-label="Graph"(belowMIN_CHART_SUMMARY_CHARS= 8).- Geometry only: bars, slices, or canvas pixels with no accessible name and no preceding
forge-support/figcaptionparagraph. aria-describedbypoints at a missing id or an empty stub element (for example an empty<div id="chart-desc">).- Title line only from
render_ks_chart_mountis omitted on consumer pages, leaving a bare<div class="ks-chart-mount" data-ks-chart>with no caption sibling. - Tooltip-only
<title>inside SVG with no mount-level description (tooltips are not a substitute for page-level summary wiring). - API chart stuck in
data-ks-chart-state="loading"with no loading copy that satisfies the 8-character minimum for the mount region.
Before example
Before (failing example)
Activity
Failing KS markup: valid mount and SVG geometry, but the accessible name is a generic stub and there is no caption or aria-describedby target.
After example
After (passing example)
Activity
Weekly commits · commit_weekly
Bar chart of weekly commit counts for 2025-W08 through W11; highest bar is W10 at seven commits.
Passing KS markup: non-trivial summary copy linked to the mount; SVG inherits description from the same targets.
Alternative passing pattern using figure / figcaption:
<figure class="forge-card p-3 mb-4" hash="Dca" data-ks-hash="Dca">
<figcaption id="api-latency-caption" class="forge-support mb-2">
Line chart of median API latency (ms) over the last seven days; day six peaked at 420 ms.
</figcaption>
<div
id="ks-api-latency"
class="ks-chart-mount mb-0"
data-ks-chart
data-ks-chart-kind="api_latency_daily"
data-ks-chart-url="/api/charts/api_latency_daily.json"
data-ks-chart-state="ready"
aria-labelledby="api-latency-caption"
></div>
</figure>
Evidence and remediation
Evidence: Auditor metrics chartAltSummaryReport with violations[] kind missing-chart-alt-summary, selectorHint (for example div#ks-cw.ks-chart-mount[kind=commit_weekly]), and className. Findings surface as major accessibility issues with evidence token missing_chart_alt_summary. Capture the mount outer HTML, any aria-* attributes, and adjacent forge-support / figcaption nodes.
Remediate (in order):
- Add a visible or sr-only paragraph (at least 8 characters) that states metric, unit, time window, and direction—not only the chart kind code.
- Set
aria-describedbyon.ks-chart-mount(and matchingaria-label/aria-describedbyon innersvgorcanvas) to that paragraph id. - When using
render_ks_chart_mount, pass atitleand add a secondforge-supportinsight line in the page template if the auto caption is not enough. - For API-driven charts, ensure loading and error copy in the mount subtree meets the same minimum length.
- Re-run deterministic chart checks; if summaries exist but lack takeaway quality, address
AI.DATA.INSIGHT_LEGIBILITYseparately.