TL;DR: Five-phase procedure for deciding whether component-spec changes should
roll into the real shared component library, and for surfacing new shared/reusable components:
gate check → inventory → classify →
update living docs → commit/PR. This is a different
question from the Figma sync procedure: that one asks
"do the spec docs match Figma?" — this one asks "does the real code in
ALPAMobile.Presentation/Components/Library/ match the specs, and
does anything new belong in the shared library?" Run this after a Figma sync's doc
roll-up lands, or whenever the implementation gate status might have changed.
A Figma sync keeps the spec docs (docs/component-specifications/) faithful
to Figma. It does not check whether the real shared component library — the code other
features actually import — reflects what's specced, or whether new patterns that showed up across
multiple specs deserve to be promoted into a shared atom/primitive rather than re-implemented per screen.
That's this procedure's job.
As of 2026-07-13 this reconciliation exists only as dated, one-off snapshot artifacts
(scaffold-component-reconciliation.html, component-library-plan.html) that
explicitly call themselves "backlog artifacts, not a work order." This doc formalizes the repeatable
procedure so those stop going stale between runs — update them in place each run rather
than creating a new dated snapshot every time (that's how the AB#2087 gate-language staleness happened:
the artifacts said "gated" for 12 days after the gate actually cleared, because nothing re-checked them).
Verify live, don't trust doc text. Reconciliation artifacts reference a specific Azure Boards work item as the implementation gate (currently WI-2087, "Presentation Extraction," under Epic AB#2081). Doc text lags reality — it only updates when someone runs this procedure.
az boards work-item show --id <gate-WI> --query "{state:fields.\"System.State\"}" -o json
If the gate is now resolved but the doc still says "gated," that mismatch alone is a finding — update the gate language (see Phase 4) even if you do nothing else this pass. Do not assume a resolved gate WI means the specific migration/track it was blocking is complete — verify against real code (Phase 2) before changing a track's status from "not started" to "done."
Compare what the specs describe against what actually exists in code:
ALPAMobile.Presentation/Components/Library/
(the RCL home per D20, executed 2026-07-15 WI-2254/D61; the legacy MAUI-head
ALPAMobile/Components/Library/ location is empty since the migration). A component appearing
anywhere else is a migration gap, not a missing-component gap.docs/component-specifications/<name>/<name>-component.html),
confirm: does a matching .razor renderer + ViewModel exist? If yes, is it in the target
location? If no, is it built at all?alpa-* CSS patterns that duplicate an existing spec — that's a
consume-don't-rebuild gap, not a new-component gap.For each gap found in Phase 2, classify using the existing opt-in criterion (D40): the shared library is for recurring, data-driven controls; one-off static/informational content is exempt and may stay plain markup. The shared layer is atoms + tokens, not a base class — domain controls compose shared atoms rather than inheriting a shared base.
| Gap type | Action |
|---|---|
| Specced, not built, target location | Add to the "ready to build" list — no further decision needed, just scheduling. |
| Built, but in the wrong location (legacy head vs. RCL) | Migration gap — track separately from new-component gaps; don't conflate "needs to move" with "needs to be built." |
| Hand-rolled pattern duplicates an existing spec | Consume-don't-rebuild — flag the screen/page for a rebuild pass, not a new spec. |
| Recurring pattern, no spec, meets D40's opt-in bar | New shared component candidate — needs a spec page and a decision (D-number) before it's build-ready. |
| Recurring pattern, no spec, one-off/static per D40 | Exempt — record the exemption reasoning so it isn't re-flagged next pass. |
Edit in place. Do not create a new dated snapshot doc each run — that's what let the last one go stale. Update:
| File | What to update |
|---|---|
docs/component-specifications/scaffold-component-reconciliation.html | Table A (consume-don't-rebuild) and Table B (new controls needed) rows; gate language in the Recommendation section; Updated: stamp. |
docs/ui-refresh-1821/component-library-plan.html | Track A/B/C status badges; Work Items to Update table; Updated: stamp. |
naming-decisions-record.html | New D-number for any new shared-component candidate classified in Phase 3, following the standard decision-recording steps. |
Same verification and branch conventions as the Figma sync procedure: tag-balance check on changed HTML,
stage specific files (never git add -A), commit message format
"docs: component library reconciliation (<what changed>)". Check how far behind the
target branch your base commit is before pushing (see the Figma sync procedure's
Gotchas — the same branch-staleness risk applies here).
| File | Purpose |
|---|---|
docs/component-specifications/scaffold-component-reconciliation.html | Consume-don't-rebuild list + new-controls backlog |
docs/ui-refresh-1821/component-library-plan.html | Track A/B/C build status against the real RCL |
docs/component-specifications/naming-decisions-record.html#d40 | The opt-in criterion for shared-library membership |
docs/component-specifications/foundations-reconciliation.html | Sibling reconciliation, scoped to design-system foundations (color/type/spacing) rather than components — not this procedure's concern |
component-library-plan.html's Track C was gated on it specifically for the renderer move.ALPAMobile/Components/Library/ until the 2026-07-15 WI-2254/D61 migration into
ALPAMobile.Presentation. That's a migration item, not a build item.