Skip to content

History / Component Audit Rubric

Revisions

  • Rubric v1.4: two scoping rules — does this defect have a victim? Added after the Indicator audit produced two findings that graded correctly against the rule text and should never have been recorded. Both failures were mine to catch and I did not; the TL did. 1. MIGRATION RULES BIND RELEASED SURFACE ONLY. Q11, T33, P11, X20 and I7 all demand a [breaking] changeset and a codemod. Every one exists to protect installed consumers, and not one said so. Indicator merged 2026-08-11; core@0.3.0 shipped 2026-08-05 with no ./Indicator subpath, so the whole layer was unreleased for its first week in main -- and P11 was cited against it for omitting props from a type no consumer could install. Both the auditor and I cited the rule accurately and neither asked whether the export had ever shipped. The rules now require establishing that first, with the command. P11 also drops to FIX in modes N/O. Its subject is a CHANGESET, which is consumed and deleted at release, so a BLOCK derived from one evaporates on its own with nobody fixing anything and the next audit sees an unexplained jump. That belongs on the PR, where it can be acted on before merge -- which is what L14 already does, and is the model. 2. A FINDING NEEDS A REACHABLE VICTIM. "Score the failure, not its likelihood" is right and stays. It is about USERS in rare states. It does not license grading a defect nothing can reach. A defect needing code the type rejects, that no call site contains and no doc suggests, is a NIT at most. The worked example is tabIndex on an indicator: axe really does report aria-hidden-focus, measured 0 -> 1 violation, which reads like a solid finding -- but nobody passes it, the type rejects the literal, and no doc mentions it. Recorded as a FIX, it produced a PR carrying a new internal module to strip a prop nobody sets. Corollary added: a finding closable by a type change should say so, instead of leaving the fix shape to whoever picks it up. Minor, not patch: both narrow when a BLOCK may be recorded, so §2, §3, §8 and §9 scores taken under <=1.3 are not comparable where a migration rule was cited. Weights, floors and ceilings unchanged.

    @cixzhang cixzhang committed Aug 13, 2026
  • Rubric: unbreak the §2 and §5 tables A blockquote in the middle of a markdown table ends the table: the rows after it rendered as a paragraph of literal pipe text. The T1-exceptions and T14-scoping notes split §2 into three pieces (T2-T14 and T15-T34 both raw), and the D12 note split §5 (D13-D16 raw). Each table is now contiguous, with the notes moved directly below it — the shape §9 already used. Rows are unchanged apart from T2b's pointer, which now says the T1 note is below rather than above.

    @cixzhang cixzhang committed Aug 12, 2026
  • Rubric v1.3: add X21 — a doc example may not teach a pattern we removed The Indicator audit surfaced a finding with no rule to hold it. #4913 replaced `{children ?? mark}` in all three shipped indicators because it deletes the state mark on a falsy child (#4893), and left the ONLY worked example of writing a replacement indicator teaching exactly that shape. Code fixed, documentation still instructing readers to rebuild the bug -- on a surface X5a's own rationale calls LLM training signal. The auditor who found it filed it under X5. That citation is wrong: X5a is a phantom prop, X5b is a missing prop entry, and this is neither. I overruled the citation and recorded a FIX, which left a BLOCK-severity defect scored as cosmetic. The real defect was in the rubric: no rule covered it, so it had nowhere to go but a rule that did not fit. X21 (§8, BLOCK) closes that gap, scoped so it cannot become a style cudgel: the test is whether following the example re-creates a defect the repo has already paid to remove -- not whether the example is simplified, and not taste. Detection is a grep of the component's .doc.mjs for the shape just removed, run as part of any behavioral fix. Minor bump, not patch: a new check that can BLOCK changes what counts, so §8 scores taken under <=1.2.1 are not comparable. No weight, floor or ceiling moved, and no other section is affected.

    @cixzhang cixzhang committed Aug 11, 2026
  • Component-Audit-Rubric: correct T34 to the indicator convention we shipped The host renders the indicator unconditionally and passes state; an indicator may legitimately draw nothing in a state. The focus ring is the owner's to guarantee -- it is painted onto the indicator's own element, not omitted. Radius is tokenized (--radius-full, not 50%).

    @cixzhang cixzhang committed Aug 11, 2026
  • Rubric v1.2.1 + API Conventions: correct T28 (composition-layer theme targets) and P33 (html prefix) Both from the AlertDialog audit review, PR #4887. T28 read as a blanket ban on themeProps anywhere a composition wrapper wraps themed components. That is not what #672 and #749 established: #672 deliberately ADDED a target to MoreMenu over DropdownMenu so themes could reach it, and #749 skipped Tokenizer, an outer node wrapping several independently themed components. T28 now says that: a layer may name its own concept on the painting element; the ban is on the multi-component wrapper node. P33 led with the html prefix. The prefix is for props that ARE the native attribute (htmlName, htmlFor); a prop that merely reuses the name with a different meaning keeps the semantic name. BaseProps already omits title, so a component's own title prop is not a collision at all. API Conventions §HTML Attribute Collisions rewritten to match, since it owns the rule.

    @cixzhang cixzhang committed Aug 11, 2026
  • Ledger tooling and the scores page are on main; activate T34

    @cixzhang cixzhang committed Aug 11, 2026
  • State visuals: scale(0.98) is the button press treatment; match the archetype before the representation

    @cixzhang cixzhang committed Aug 11, 2026
  • Testing: compare visuals against Design Conventions; missing tooling is not a deduction

    @cixzhang cixzhang committed Aug 11, 2026
  • D12: link the view-transitions tracking issue

    @cixzhang cixzhang committed Aug 11, 2026
  • D12: view transitions are the resolution path, blocked on React stable

    @cixzhang cixzhang committed Aug 11, 2026
  • D12 applies on every render path; only T14's DOM-shape rule is scoped

    @cixzhang cixzhang committed Aug 11, 2026
  • D12: explain what the guard protects; the auto-height exception is permanent

    @cixzhang cixzhang committed Aug 11, 2026
  • T14: scope the style-only-wrapper rule to the main render path

    @cixzhang cixzhang committed Aug 11, 2026
  • D12: scope the layout-animation rule to the main render path; sanction the auto-height disclosure

    @cixzhang cixzhang committed Aug 11, 2026
  • Resolve the issue-filing contradiction: the nightly pass files none, a grading or promotion does

    @cixzhang cixzhang committed Aug 11, 2026
  • Repoint two more pointers at the sections that exist

    @cixzhang cixzhang committed Aug 11, 2026
  • Rubric: a row citing the rubric itself says nothing — name the real source or none

    @cixzhang cixzhang committed Aug 11, 2026
  • Fix every piped wiki link: GitHub treats the text after the pipe as the page name

    @cixzhang cixzhang committed Aug 11, 2026
  • Restore the Layer 3 design review and its form; the rubric still requires the form be archived

    @cixzhang cixzhang committed Aug 11, 2026
  • Delete the superseded hardening and auditor pages; repoint every link at the rubric

    @cixzhang cixzhang committed Aug 11, 2026
  • Ledger: the write path is a hand edit — no score-ledger tool or scores page exists yet

    @cixzhang cixzhang committed Aug 11, 2026
  • Component auditor: one component a night, audit-fix-reaudit, ledger as the only state, no issues

    @cixzhang cixzhang committed Aug 11, 2026
  • Rubric: cite the page that owns each rule, not the auditor's deleted section numbers

    @cixzhang cixzhang committed Aug 11, 2026
  • Wiki-wide: drop the mode-letter shorthand for plain language

    @cixzhang cixzhang committed Aug 11, 2026
  • Ledger: the JSON is the only stored form; delete the generated table Component-Scores.md was a second copy of component-scores.json and went stale the moment the JSON changed without a regeneration. The ledger now has exactly one stored form (the JSON) and exactly one view (the sandbox page), which fetches it at runtime and can therefore never be out of date. Every page that linked [[Component Scores]] now links the sandbox page.

    @cixzhang cixzhang committed Aug 11, 2026
  • Rubric: lead with what you are doing; plain language; act as the hub for the rule pages

    @cixzhang cixzhang committed Aug 11, 2026
  • Ledger: nothing in CI reads it while the rubric is being calibrated

    @cixzhang cixzhang committed Aug 11, 2026
  • Document the ledger write path end to end

    @cixzhang cixzhang committed Aug 11, 2026
  • Mode R: set the bar by change type — bug fix, feature, new component (core vs lab)

    @cixzhang cixzhang committed Aug 11, 2026
  • Mode R: derive a small check set from the diff; depth follows the existing triage

    @cixzhang cixzhang committed Aug 11, 2026