# Bicycles & Parts: research notes

Scope: complete bicycles (road, mountain, hybrid/commuter, kids, BMX/folding) and the core
mechanical and electrical parts that make them go, stop and fit — frames, forks and suspension,
drivetrain (crankset, cassette, derailleurs, chain), brakes, wheels and tires, frame sizing, axle
and bottom-bracket standards, and e-bike motors and batteries. One register for the whole leaf;
the splits (riding type, electric assist, whole-bike-vs-part) do the dividing a second register
would otherwise do.

Overlap with the sibling leaf: `catalog.json` lists `bicycle-accessories`
(`supplies>active>bicycle_accessories`, "Bicycle Accessories") as a separate planned leaf at the
same taxonomy depth. This register does not cover helmets, locks, lights, racks, panniers,
pumps, bottle cages, bike computers or bells — those belong to `bicycle-accessories`. Where a
product could plausibly sit in either (e.g. a kickstand, a mudguard) I left it out of this
register's facets; it is an accessory, not a part that changes how the bike rides, stops or fits.

Taxonomy path: `supplies > active > bicycle_parts`. Date: 2026-10-25.

Quote labels: **verbatim** = the sentence in quotation marks was in text I read myself (curl plus
a Python tag-strip, or `pdftotext` on a downloaded PDF); **fetched excerpt** = the fetch tool
summarised or lightly reworded the page; **search excerpt** = the claim came from a search-engine
summary because the page itself would not load. WebSearch reported its session budget was
already used (0 of 200 remaining) before I ran a single query for this category, so every claim
below came from a direct fetch (curl or WebFetch) of a URL I already knew or found by following
links inside a fetched page, never from a search-result snippet. There are no search-excerpt-only
numbers in this register.

## Seed

Seed script output, recorded verbatim:

```
=== Example entry (from an unrelated category) ===
category: car-tyres
what this shows: a number that is on every listing and still needs a judgement attached, because
experts know it only compares within one manufacturer's range.
<example id="treadwear_grade" ...>

=== Persona ===
A perfumer, who thinks in what you notice first, what lasts, and what fades
```

1. The bicycle-parts equivalent of `treadwear_grade` is **speed count** ("7-speed", "21-speed",
   "1x12"). It is on every listing and box, buyers compare bikes on it, and it needs the same
   kind of judgement attached: Wikipedia's own worked example shows a 3-chainring, 8-cog
   drivetrain advertises 24 gear combinations but has only 16 to 18 genuinely distinct ratios
   (verbatim, `wikipedia_bicycle_gearing`), the same way a 600 treadwear grade only compares
   reliably within one brand's own test. Survived the data check and is in `category.json` as
   `drivetrain_speed_count` plus the judgement about nominal-versus-distinct gears.
2. The perfumer, who thinks in what you notice first, what lasts and what fades, would notice
   that a bicycle's parts fade at wildly different rates: the chain and cassette wear out in a
   season of hard riding regardless of frame quality, while the frame itself barely changes in
   years. That "what fades first" framing is why `groupset_tier`'s `why_experts_care` and its
   trade-off entry are written around replacement frequency, not permanence, and why I did not
   build a universal "expected lifespan" claim (see Dropped, under Seed, below) — the perfumer's
   instinct pushed me to look for a sourced number and I could not find one that generalised
   across bike types without inventing it.

Dropped from the seed: a quantified "expected consumable part lifespan in miles or months"
facet. No two-source numeric figure survived the data check across road, mountain and commuter
use, and a single invented range would have violated the "do not invent ranges" rule, so the
insight stayed as framing in `groupset_tier` and its trade-off instead of becoming its own facet.

## Sources and what each supports

### Regulators and standards bodies

- **CPSC, 16 CFR Part 1512** (`cpsc_1512`). Fetched the full XML of the current part from
  govinfo.gov and stripped tags myself (verbatim text, 66,000 characters). Key quotes:
  - "(2) A two- or three-wheeled vehicle with fully operable pedals and an electric motor of less
    than 750 watts (1 h.p.), whose maximum speed on a paved level surface, when powered solely by
    such a motor while ridden by an operator who weighs 170 pounds, is less than 20 mph." —
    verbatim, § 1512.2(a). Supports the 750 W / 20 mph "still a bicycle" threshold in
    `electric_assist`, `motor_power_w` and the e-bike judgement.
  - "Sidewalk bicycle means a bicycle with a seat height of no more than 635 mm (25.0 in)...
    Recumbent bicycles are not included." — verbatim, § 1512.2(b). Used as the regulatory anchor
    for treating kids' bikes as a distinct, simpler class in the `riding_type` branch.
  - "shall have a stopping distance of no greater than 4.57 m (15 ft) from the actual test speed"
    — verbatim, § 1512.5(b)(1). Supports the "every bicycle must pass the same stopping-distance
    test regardless of brake type" line in `brake_type`.
  - "The tensile strength of the drive chain shall be no less than 8010 N (1,800 lbf)" — verbatim,
    § 1512.8. Kept as background only; not a facet, since no listing states chain tensile
    strength and it does not discriminate between products buyers actually compare.
  - Chain guard geometry (§ 1512.9: covers at least 90° of the sprocket, extends 8 cm forward of
    the rear axle centreline) — verbatim. Dropped as a facet: it is a pass/fail construction
    requirement on single-chainring, single-cog bikes, not something that varies across the
    catalog in a way a buyer chooses.

- **PeopleForBikes, Model Electric Bicycle Legislation, Jan 2020 PDF** (`pfb_model_ebike`).
  Downloaded the PDF and ran `pdftotext` myself (verbatim). Key quotes:
  - "(a) 'Class 1 electric bicycle' shall mean an electric bicycle equipped with a motor that
    provides assistance only when the rider is pedaling, and that ceases to provide assistance
    when the bicycle reaches the speed of 20 miles per hour." — verbatim, Section 1(a).
  - "(b) 'Class 2 electric bicycle'... a motor that may be used exclusively to propel the
    bicycle... not capable of providing assistance when the bicycle reaches... 20 miles per
    hour." — verbatim, Section 1(b).
  - "(c) 'Class 3 electric bicycle'... ceases to provide assistance when the bicycle reaches the
    speed of 28 miles per hour." — verbatim, Section 1(c).
  - "A municipality... may prohibit the operation of a class 3 electric bicycle on that path." —
    verbatim, path-access section. Supports the Class 3 trail-access trade-off.
  - Age 16 minimum and helmet requirement for Class 3 — verbatim, Chapter 3. Kept as context for
    `ebike_class`'s `why_experts_care`; not broken into its own facet because it is a direct
    consequence of the class value, not an independent spec.
  These three definitions directly gave `ebike_class`'s three values and its definition text.

- **PeopleForBikes, Electric Bicycle FAQ, Aug 2023 PDF** (`pfb_ebike_faq`). `pdftotext`, verbatim.
  - "As of August 2023, 48 states that define an e-bike as a bike, 41 of which use the
    three-class system." — verbatim. Supports `ebike_class`'s backfill note.
  - "Why is the top speed for Class 3 electric bicycles 28 MPH? In Europe, the classification
    that is equivalent to a class 3 electric bicycle is 'speed pedelec.'... limited to a top
    assisted speed of 45 KPH, which is equivalent to 28 MPH." — verbatim. Confirms the US/EU
    cross-reference used in `ebike_class`'s definition.
  - "For Class 1 and Class 3 electric bicycles, the rider must be pedaling for the motor to be
    engaged. For Class 2 electric bicycles, the motor can propel the electric bicycle without the
    rider pedaling." — verbatim. This is the throttle-vs-pedelec distinction in the facet
    definition.

### E-bike mechanism and classes (second sources, cross-checking PeopleForBikes and CPSC)

- **Wikipedia, Electric bicycle** (`wikipedia_electric_bicycle`). Curled and tag-stripped myself
  (verbatim, 70,000 characters). Key quotes:
  - "the motor produces maximum continuous rated power of not more than 250 W (0.34 hp)... An
    e-bike conforming to these conditions is considered to be a pedelec in the EU." — verbatim.
    Second source (independent of PeopleForBikes/CPSC) for the EU 250 W figure in `motor_power_w`.
  - "many states have adopted S-Pedelecs into the Class 3 category, limited to 750 W (1.01 hp) of
    power and 45 km/h (28 mph) speed." — verbatim. Third confirmation of the US 750 W / 28 mph
    Class 3 figures already sourced to CPSC and the PeopleForBikes model law.
  - "Most manufacturers will provide a spread, claiming for example, 20km of continuous strong
    assist with steep hills, and 140km of intermittent gentle assist with slight hills." —
    verbatim. Supports the `battery_capacity_wh` judgement that Wh alone does not predict range.
    Single source; flagged in the judgement itself (confidence medium, "one source only").

- **Wikipedia, Pedelec** (`wikipedia_pedelec`). Curled, verbatim.
  - "The European Union passed a similar directive with maximum 250 W motor power and a cut-out
    of 25 km/h (15.6 mph), but with the important difference that it applied only to pedelecs." —
    verbatim. Second, independently-written source for the EU 250 W / 25 km/h figures, matching
    `wikipedia_electric_bicycle`.
  - "This is 25 km/h or 15.5 mph in many countries, notably EU and UK... or 45 km/h (28 mph) for
    S-pedelecs." — verbatim.

### Wheel and tire sizing (two independent sources, both read as raw text)

- **Wikipedia, ISO 5775** (`wikipedia_iso5775`). Curled, verbatim, including the full size table.
  - "622 28-622 28 x 1+5/8 x 1+1/8 700 x 28 C" and "700 C Carrera" rows in the conversion table —
    verbatim. Confirms 622 mm BSD = 700C.
  - "584 26 x 1+3/8 x 1+1/2 650 B" and "'27 five' (meaning 27.5) 584 mm" rows — verbatim. Confirms
    584 mm BSD = 650B / 27.5.
  - "559 47-559 26 x 1.75 x 2" and "26 x 1.00 through 5.0 559 mm Most Mountain bikes, cruisers,
    fatbikes" — verbatim. Confirms 559 mm BSD as the common mountain-bike "26 inch."
  - "at least 6 different '26 inch' sizes exist (just by American notation)" — verbatim. Supports
    the "ambiguous 26-inch" line in `wheel_tire_standard`.
- **Sheldon Brown, Tire Sizing Systems** (`sheldonbrown_tiresizing`). Curled, verbatim (enthusiast
  community, the most-cited bike-mechanic reference site).
  - "a 700 x 20 C road tire would be a 20-622... any rim that could fit one of them would work
    after a fashion with the other" — verbatim.
  - "29 inch 622 mm This is a marketing term for wide 622 mm ('700C') tires." — verbatim. Backs
    the judgement that 29ers and 700C wheels share one rim diameter.
  - "26 x 1.00 through 5.0 559 mm Most Mountain bikes, cruisers, fatbikes etc." and "'27 five'...
    584 mm Marketing term for wide, knobby 584 mm tires. Some Mountain bikes" — verbatim. Agrees
    with the ISO 5775 Wikipedia table; used together as the two sources for `wheel_tire_standard`.
  - "406 32-406 20 x 1+1/4" — verbatim. Confirms 406 mm BSD as the common small/BMX/kids wheel,
    used for the `20in_or_smaller_406mm` value.

### Frame sizing and materials

- **Sheldon Brown, Revisionist Theory of Bicycle Sizing** (`sheldonbrown_framesizing`). Curled,
  verbatim.
  - "The old standard system was to measure from the center of the bottom bracket to the very top
    of the seat tube. Some manufacturers have decided that this is too easy, so now many bikes
    are measured instead to the intersection of the centerline of the top tube with the centerline
    of the seat tube... Anarchy reigns; I know of one bicycle line that made a running change in
    the middle of the year. You could have two bikes of the same make, model, year and nominal
    size, but one was 2 cm larger than the other!" — verbatim. This is the direct source for the
    judgement that cm-labelled frame sizes are not standardised across brands, and the reason
    `frame_size`'s split question asks rider height rather than treating cm as comparable.
- **Wikipedia, Bicycle frame** (`wikipedia_bicycle_frame`). Curled, verbatim.
  - "Typical 'medium' sizes are 54 or 56 cm... for a European men's racing bicycle or 46 cm...for
    a men's mountain bike." — verbatim. Background for `frame_size`; not asserted as a hard range
    in the JSON because it is only "typical," not a standard.
  - "Aluminum alloys have a lower density and lower strength compared with steel alloys; however,
    they possess a better strength-to-weight ratio" — verbatim.
  - "Early aluminum structures have shown to be more vulnerable to fatigue... This contrasts with
    some steel and titanium alloys, which have clear fatigue limits" — verbatim. Source for the
    `frame_material` fatigue claim; the JSON originally said aluminium has "a lower fatigue
    limit," which the source does not say — corrected 2026-10-26 to "more vulnerable to fatigue,
    lacking the clear fatigue limit" steel/titanium have.
  - "Steel frames... are strong, easy to work, and relatively inexpensive. However, they are
    denser (and thus generally heavier)" — verbatim.
  - "Carbon fiber composite... is light-weight, corrosion-resistant and strong... can be formed
    into almost any shape desired. The result is a frame that can be fine-tuned for specific
    strength where it is needed... while allowing flexibility in other frame sections" — verbatim.
  - "Steel frames are often built using various types of steel alloys including chromoly" —
    verbatim. Clarifies that chromoly is a steel sub-type, noted in the vocabulary and in the
    "against the add-on schema" section below (the add-on schema lists `steel` and `chromoly` as
    separate enum values, which this source says is a family/sub-type relationship, not two
    unrelated materials).
  Single source for the material trade-off claims; these are qualitative material-science
  descriptions rather than disputed numeric thresholds, so I treated one encyclopedic source as
  enough rather than inventing a second citation for the same uncontested physics.

### Drivetrain, gearing and groupsets

- **Wikipedia, Bicycle gearing** (`wikipedia_bicycle_gearing`). Curled, verbatim.
  - "Consider a derailleur-equipped bicycle with 3 chainrings and an 8-sprocket cogset: the number
    of possible gear ratios is 24 (=3x8, this is the number usually quoted in advertisements);
    the number of usable gear ratios is 22; the number of distinct gear ratios is typically 16 to
    18." — verbatim. This is the single most important quote in the register: it is the source for
    `drivetrain_speed_count`'s `why_experts_care`, the nominal-vs-distinct judgement, and the
    `nominal_gear_combinations` derived metric's framing. I did not turn the 24-to-16/18 ratio
    into a general formula or coefficient (e.g. "distinct gears = 0.7 x nominal") because the
    source gives one worked example, not a general rule; inventing a coefficient from one example
    would have violated the "do not invent ranges" instruction.
  - "modern crankset chainrings... 1x10 and 1x11" and cogsets "typically between 5 and 12
    sprockets" — verbatim. Background for `chainring_config` and `drivetrain_speed_count`.
- **Wikipedia, Groupset** (`wikipedia_groupset`). Curled, verbatim.
  - "Dura-Ace, Super Record and Red are the top-of-the-line road racing groupsets for Shimano,
    Campagnolo and SRAM respectively while Claris, Veloce and Apex are their entry level road
    racing groupsets" — verbatim. Direct source for `groupset_tier`'s brand-name examples.
- **Wikipedia, List of Shimano groupsets** (`wikipedia_shimano_groupsets_list`). Curled, verbatim.
  - "road bike groupsets in order of descending tiers: Dura-Ace Ultegra 105 Tiagra CUES (new
    standard that replaces Sora and Claris) Sora... Claris... Essa" — verbatim. Confirms the full
    hierarchy order, used as the second source alongside the Groupset page (both Wikipedia, but
    separate articles with separate edit histories; flagged as same-platform in the numbers
    table below).

### Mountain bikes, suspension and tires

- **Wikipedia, Mountain bike** (`wikipedia_mountain_bike`). Curled, verbatim.
  - "MTB development has led to an increase in suspension travel, now often up to 8 inches (200
    mm), and gearing up to 13 speed" — verbatim. Supports the suspension-travel judgement and
    `fork_travel_mm`'s range.
  - "Hardtail: A mountain bike equipped with a suspension fork for the front wheel, but otherwise
    a rigid frame... Full suspension (or dual suspension): A mountain bike equipped with both
    front and rear suspension." — verbatim. Direct source for `suspension_type`'s three values.
  - "incorporate... a suspension fork, large knobby tires, more durable wheels, more powerful
    brakes" — verbatim. Used, together with the road-bicycle efficiency language on the Bicycle
    frame page, to support the `riding_type` branch that makes suspension irrelevant on
    road/hybrid/kids bikes (an inference from what mountain bikes add, not a direct statement that
    other bikes never have it; flagged below under Branches).
- **Wikipedia, Bicycle suspension** (`wikipedia_bicycle_suspension`). Curled, verbatim.
  - "When suspension forks were introduced, 80-100 mm of travel was deemed sufficient for a
    downhill mountain bike. This amount of travel is now common for cross-country disciplines,
    whereas downhill forks typically offer 200 mm or more of travel." — verbatim. Second source,
    confirming the Mountain bike page's 200 mm figure and giving the 80-100 mm cross-country
    anchor used in `fork_travel_mm`'s range and the suspension-travel judgement.
- **Wikipedia, Bicycle tire** (`wikipedia_bicycle_tire`). Curled, verbatim.
  - "pinch flats are less common in a tubeless setup because they require a hole through the tire
    carcass, not just the inner tube... Liquid sealants are often injected into tubeless tires to
    improve sealing and to stop leaks caused by punctures... air can escape if the bead [is not
    properly seated]" — verbatim (last clause paraphrased by me from the surrounding sentence).
    Single source for `tubeless_ready`; kept qualitative (no PSI numbers asserted) since no second
    source was fetched for a specific pressure figure.

### Compatibility standards (axle, bottom bracket)

- **Wikipedia, Thru-axle** (`wikipedia_thru_axle`). Curled, verbatim.
  - "Three M12 through-axles... Quick releases are sometimes recommended against with the use of
    disc brakes because of the need for the axle attachment to withstand braking forces... the
    introduction of disc brakes has caused increased vulnerability of the front axle and skewer,
    due to the disc brake applying an ejection force that tends to pull the axle out of the fork."
    — verbatim. Single source for `axle_standard`; I did not put the specific 12 mm / 15 mm
    front-vs-rear diameter split into the JSON because I could not confirm it from a second
    source in the time available, so `axle_standard`'s values stay at the quick_release /
    thru_axle level without asserting exact diameters.
- **Wikipedia, Bottom bracket** (`wikipedia_bottom_bracket`). Curled, verbatim.
  - "shell widths (68, 70, 73, 83, or 100 mm)... Road bikes usually use 68 mm; Italian road bikes
    use 70 mm; Early model mountain bikes use 73 mm." — verbatim.
  - "BB30 requires special frames which have a 42 mm diameter unthreaded bottom bracket shell...
    current pressed-bearing standards... are: BB30 (Cannondale) PF30 (SRAM) BB90 and BB95 (Trek)
    BB86 and BB92 (Shimano) BB79 (Cervelo's BBRight) BB386EVO (FSA and BH Bicycles)." — verbatim.
    Single source. I deliberately kept the exact mm figures out of `bottom_bracket_standard`'s
    JSON prose (the facet's values are just `threaded` / `press_fit` / `other`) and said so in
    the facet's `backfill_note`, rather than asserting un-cross-checked numbers as a `range`.

### Could not reach

- REI's bike-sizing and bike-tire buying guides (`rei.com/learn/...`): direct fetch returned
  HTTP 000 (connection failure) every time, and the Wayback Machine blocked the same URL as
  "suspected abusive bot traffic." Never read; no REI claims are in this register.
- Specialized, Giant and Trek's own size-chart pages: all 404'd on direct fetch (the URLs I tried
  no longer exist on those sites). Cannondale's size-chart page returned 200 but is a JavaScript
  app with no chart data in the static HTML I could curl.
- Park Tool's repair-help pages for bottom brackets and disc rotors: both URLs I tried 404'd;
  I did not find the correct current slugs in the time available, so Park Tool is not cited.
- Schwalbe's own tire-size chart page 404'd.
- WheelsManufacturing's bottom-bracket tech page returned a JavaScript shell with no static data.
- bikegremlin.com returned an HTTP 511 (requires portal authentication) and was not read.
- Shimano's own bike.shimano.com pages returned HTTP 403 on every attempt.
All of the above were spec-sheet or retail-listing style sources; their absence is why
`axle_standard` and `bottom_bracket_standard` stayed single-sourced on Wikipedia and why I did not
add exact front/rear axle diameters or exact BB shell widths as JSON-level numeric claims.

## Data points used for derived metrics

- `nominal_gear_combinations = chainring_count * drivetrain_speed_count`. Both inputs are listing
  fields (the facets `chainring_config` and `drivetrain_speed_count`); the formula itself and its
  "this overstates distinct gears" framing come from the worked example in
  `wikipedia_bicycle_gearing` (3 chainrings x 8 cogs = 24 nominal, 16-18 distinct).

I looked for a second derived metric (an estimated e-bike range in miles from `battery_capacity_wh`
and `motor_power_w`) and dropped it: the one source I have for e-bike range
(`wikipedia_electric_bicycle`) explicitly says the same battery capacity yields anywhere from
20 km to 140 km depending on assist level and terrain, which is itself evidence that there is no
clean Wh-per-mile constant to divide by. Turning that into a formula would have meant inventing
the missing constant, so it stayed a judgement instead of a derived metric.

## Against the existing add-on schema

`zamana-expertise/data/schema-parts/supplies/active/add-ons/bicycles_part.jsonc` has:
`frame_material` (enum aluminum/carbon_fiber/steel/titanium/chromoly/na/unspecified),
`fork_travel_mm`, `groupset` (free string), `gear_count`, `brake_type` (enum rim/disc_mechanical/
disc_hydraulic/coaster/drum/na/unspecified), `part_compatibility` (free string), and
`sizing.frame_size_label` / `sizing.frame_size_cm` / `sizing.wheel_size`. Proposals only; nothing
in `zamana-expertise` was edited.

- **Keep as is**: `frame_material` and `brake_type`'s enums match this register's
  `frame_material` and `brake_type` facets closely; no change proposed beyond noting (per
  `wikipedia_bicycle_frame`) that `chromoly` is a sub-type of `steel`, not a separate family, so
  the two enum values should stay distinct only if the pipeline can reliably tell them apart from
  listing text (most listings that say "chromoly" or "4130" are more specific than ones that just
  say "steel").
- **`fork_travel_mm` kept, but currently has no companion `suspension_type`.** A rigid fork and a
  "0" or null `fork_travel_mm` are not distinguishable in the current add-on; this register's
  `suspension_type` (rigid/hardtail/full_suspension) is a kind: categorical field worth adding so
  the pipeline doesn't have to infer "rigid" from a missing number.
- **`groupset` (free string) is noise as a filter or sort key.** It is good for display ("Shimano
  105") but cannot be filtered, sorted or compared across brands as text. This register's
  `groupset_tier` (ordinal: entry/mid/performance/race_pro) is a kind: ordinal field that could sit
  alongside the free string, built from a brand-name lookup table (Shimano Claris through
  Dura-Ace, SRAM Apex through Red, Campagnolo Veloce through Super Record), so a shopper could
  sort or filter by tier while the free string still displays the exact name.
  `wikipedia_shimano_groupsets_list`'s hierarchy and `wikipedia_groupset`'s cross-brand mapping
  are the source for that lookup table.
- **`gear_count` is ambiguous.** It is not documented as nominal (chainrings x cogs) or as the
  cassette's own cog count, and `wikipedia_bicycle_gearing`'s worked example shows those two
  readings differ (24 nominal vs an 8-cog cassette). This register splits that into
  `drivetrain_speed_count` (the cassette/hub cog count, a kind: numeric filter/sort_key) and
  `chainring_config` (1x/2x/3x, a kind: categorical filter), which composes back into the add-on's
  single `gear_count` only if its documentation says explicitly which of the two it means.
- **`part_compatibility` (free string) is noise as a filter.** Nothing can match on free text
  reliably. This register proposes replacing or supplementing it with the specific compatibility
  facts a parts buyer actually needs: `wheel_tire_standard` (kind: categorical hard filter, the
  BSD/common-name standard), `axle_standard` (kind: categorical hard filter, quick_release vs
  thru_axle) and `bottom_bracket_standard` (kind: categorical hard filter, threaded vs press_fit).
  These are exactly the three things that have to match between a frame/fork and a wheel, or
  between a frame and a crankset, per the sources above.
- **`sizing.frame_size_label` and `sizing.frame_size_cm` stay, with a judgement attached.** Per
  the `sheldonbrown_framesizing` quote above, `frame_size_cm` is not comparable across brands
  without knowing which reference point that brand measures to; this register's `frame_size`
  facet recommends treating `frame_size_label` plus the brand's own height chart as more reliable
  than ranking products by raw `frame_size_cm` alone. No schema change proposed here, just a
  caution for how the pipeline or UI uses the existing field.
- **`sizing.wheel_size` stays, but its free-text values ("700c", "29\"", "26\"") are exactly the
  marketing names this register's `wheel_tire_standard` maps to a BSD.** Proposal: normalise
  `wheel_size` against the ISO 5775 BSD table (700c/650b/26in/20in-or-smaller) rather than keeping
  it free text, since "26 inch" alone is ambiguous across at least six historical sizes per
  `wikipedia_iso5775`.
- **Noise the add-on does not have and this register does not propose adding as top-level add-on
  fields**: chain tensile strength, chain-guard geometry, and exact axle/BB millimetre diameters.
  These are either pass/fail construction facts with no buyer-facing variation (chain strength,
  chain guard) or single-sourced numbers I could not confirm well enough to assert as filterable
  fields (exact axle/BB mm); they stay as context in this register's facet notes rather than as
  schema proposals.
- `max_user_weight` (in `active-standard.jsonc`) already covers rider/cargo weight limits; this
  register does not duplicate it as a facet.

## Branches

- `riding_type = mountain` -> ask `suspension_type`, `fork_travel_mm`, `wheel_tire_standard`.
  Chain: mountain bikes "incorporate... a suspension fork, large knobby tires" (verbatim,
  `wikipedia_mountain_bike`); mountain-bike wheel sizes are specifically 26-inch/559mm, 27.5/584mm
  and 29-inch/622mm per the Sheldon Brown quotes above ("Most Mountain bikes," "'27 five'...Some
  Mountain bikes," "'29 inch'...marketing term for wide 622 mm tires"). SUPPORTED.
- `riding_type` in `{road, hybrid_commuter, kids}` -> `suspension_type`, `fork_travel_mm` become
  irrelevant. Chain: suspension forks are introduced specifically as a mountain-bike feature
  (`wikipedia_mountain_bike`), and road bikes are described as built "for efficient power transfer
  at minimum weight and drag" (`wikipedia_bicycle_frame`), which is the stated reason road bikes
  do not carry the weight of a suspension fork. This is an inference from what mountain bikes add
  and what road bikes optimise for, not a direct "road bikes never have suspension" sentence;
  flagged as SUPPORTED (inference from a stated design goal) rather than verbatim-stated.
- `riding_type = road` -> ask `wheel_tire_standard`, `chainring_config`, `groupset_tier`,
  `brake_type`. Chain: "road bike groupsets" is literally how Shimano's own hierarchy page
  describes Dura-Ace/Ultegra/105/Tiagra (`wikipedia_shimano_groupsets_list`), i.e. groupset tier
  is explicitly a road-bike-framed spec; wheel/tire standard and brake type are the compatibility
  and stopping facts every bike has, asked once riding type narrows the likely wheel size.
  SUPPORTED.
- `riding_type = hybrid_commuter` -> ask `brake_type`, `wheel_tire_standard`. LOW CONFIDENCE: no
  direct source says "hybrid bikes ask brake type first"; kept because these two facets are asked for
  every non-mountain, non-kids riding type and hybrid/commuter has no additional facets of its
  own in this register, so the branch is really "ask the two generic ones." Logged as the weakest
  branch in this register; it could be dropped without losing a real distinction, but it mirrors
  the "road" branch's shared facets rather than inventing a new rule.
- `riding_type = kids` -> ask `wheel_tire_standard`, `brake_type`; make `groupset_tier`,
  `chainring_config`, `ebike_class`, `motor_power_w`, `battery_capacity_wh`, `tubeless_ready`,
  `bottom_bracket_standard` irrelevant. LOW CONFIDENCE on the `makes_irrelevant` list: CPSC's
  "sidewalk bicycle" definition (seat height
  <= 635 mm) marks kids/sidewalk bikes as a distinct, simpler regulatory class with reduced
  requirements (e.g. § 1512.16(e), pedals on sidewalk bicycles are not required to have
  reflectors) — verbatim. The specific claim that kids bikes never carry a multi-speed groupset,
  suspension, or an e-bike motor is domain knowledge about the mainstream kids'-bike catalog
  rather than a sentence I can quote; flagged as SUPPORTED BY INFERENCE from the sidewalk-bicycle
  distinction plus ordinary catalog knowledge, not verbatim-sourced for every listed facet.
- `electric_assist = yes` -> ask `ebike_class`, `motor_power_w`, `battery_capacity_wh`. Chain:
  CPSC's own "bicycle" definition turns on motor wattage and speed cutoff (verbatim, § 1512.2(a)
  (2)), and the PeopleForBikes model law's Class 1/2/3 definitions are built from exactly those
  two facts plus throttle presence (verbatim, Section 1(a)-(c)). SUPPORTED, strongly.
- `electric_assist = no` -> the same three facets become irrelevant. Direct consequence of the
  same chain; a pedal-only bike has no motor or battery to ask about. SUPPORTED (trivial).
- `buying_scope = whole_bike` -> ask `frame_size`, `frame_material`; `replacement_part` -> ask
  `wheel_tire_standard`, `axle_standard`, `brake_type`, `bottom_bracket_standard`, and
  `frame_size` becomes irrelevant. Chain: the add-on schema itself has no "rider height" field at
  all, only `part_compatibility` plus `sizing.wheel_size`, which is the schema's own evidence that
  compatibility facts (wheel size, and by the same logic axle and bottom-bracket standard), not
  fit facts, are what a parts purchase actually needs; frame sizing by height
  (`sheldonbrown_framesizing`, `wikipedia_bicycle_frame`) is specifically discussed as a
  whole-bike concern. SUPPORTED.

## Trimmed detail

- The CPSC regulation's handlebar-stem loading test, pedal reflector geometry, and the full
  reflector candlepower tables (Tables 1-3 of Part 1512) were read but not used: they are
  pass/fail construction tests with no buyer-facing variation, not specs a shopper compares
  products on.
- The PeopleForBikes FAQ's e-bike market-size figures (about 525,000 e-bikes sold annually in the
  US, average price about $2,000) were read but dropped: price is explicitly excluded as a facet,
  and sales volume does not help a shopper choose between two bikes.
- The full ISO 5775 and Sheldon Brown wheel-size tables list dozens of historical sizes (12-inch
  unicycle wheels, antique roadster sizes, etc.); only the four values that cover the modern
  catalog (700C/622, 650B/584, 26in/559, 20in-or-smaller/406) made it into `wheel_tire_standard`.
- Wikipedia's Bicycle gearing page also covers gear-inches, gain ratio and metres-of-development
  as ways to compare gearing across wheel sizes; none of these made it into a facet because they
  need chainring and cog tooth counts, which are not collected as facets here (too granular for a
  listing-level spec, and the add-on schema does not carry them either).
- Mountain-bike sub-disciplines (cross-country, trail, all-mountain, enduro, freeride, downhill)
  are named in `wikipedia_mountain_bike` but not turned into a facet of their own; they are not a
  standard, just marketing names layered over `suspension_type` and `fork_travel_mm`, which is why
  the register has a judgement about this rather than a sub-discipline facet.

## Corrections

None. This is the first pass on this category; no blind check has run yet.

## Script notes

`validate.py`, `render.py` and `viewer.py` all ran clean on the first attempt after one fix: the
validator initially flagged three facets whose `visual.grammar` string did not exactly match the
corresponding `visual_grammars[].name` ("wheel size scale" vs "Wheel size scale," etc. — a casing
mismatch on my part, not a script bug). After matching the casing exactly, validate/render/viewer
all completed without errors or warnings. One cosmetic observation for `render.py`, not changed
per instructions: the visual-grammars section renders each entry's `origin` field inside the
fixed template `f" Used today by {origin}."` (`scripts/render.py` line 149). When `origin` is
itself written as a full sentence ending in a period (as both this register's and the existing
`lamps` register's `origin` fields are), the rendered line ends in a double period and reads as
"Used today by <subject> <verb-phrase ending the origin's own sentence>.." rather than a clean
noun phrase. This is a pre-existing template quirk, reproducible in the already-delivered
`lamps/category.md` (grep "Used today by" there shows the same double-period pattern on all six
of its visual grammars), not something introduced by this run. I left my `origin` fields as full
sentences to match that existing house convention rather than diverging from it, and I'm
reporting the template behaviour as requested rather than editing `render.py`.

## Corrections (2026-10-26)

- Fix 1: `frame_size` split/facet asked rider height, not its own letter-size value (house-rule
  violation). Changed the question/`cold_start_question` to ask the size label directly (`XS`–
  `XXL`) and added a `backfill_note` keeping height-plus-brand-chart as the fallback.
- Fix 2: `brake_type`'s `coaster`/`drum` values were undefined and its question offered only
  rim-vs-disc. Extended the definition to cover all five values, widened the `cold_start_question`
  to name all five, and added `Coaster brake`/`Drum brake` vocabulary entries.
- Fix 3: `hybrid_commuter`/`kids` legs of `riding_type` rest on inference, already self-flagged.
  No new citation found; marked both legs "LOW CONFIDENCE" explicitly in notes.md rather than
  escalating a chain the checker rated low severity.
- Fix 4: `nominal_gear_combinations.formula` used `chainring_count`, not matching `depends_on`'s
  `chainring_config`. Renamed the formula variable to `chainring_config_count` and documented the
  1x/2x/3x -> 1/2/3 parse in `why`.
- Fix 5: `frame_material.why_experts_care` said aluminium has "a lower fatigue limit," but
  `wikipedia_bicycle_frame` says it is "more vulnerable to fatigue" and lacks the "clear fatigue
  limit" some steel/titanium alloys have. Reworded to match, and added the verbatim quote to the
  Sources section (it was missing there, confirmed by fetching the page fresh).
