Skip to content

feat(factory): two-level navigation and first-party chart parity - #1023

Closed
castrojo wants to merge 14 commits into
projectbluefin:mainfrom
castrojo:feat/factory-two-level-nav
Closed

feat(factory): two-level navigation and first-party chart parity#1023
castrojo wants to merge 14 commits into
projectbluefin:mainfrom
castrojo:feat/factory-two-level-nav

Conversation

@castrojo

@castrojo castrojo commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Implements adr/0003-factory-two-level-navigation.md.

What changed

/factory was one 5,364-line component with two tabs behind ?tab=. It is now eight code-split routes under a two-level tab bar:

Live /factory · /factory/community
Factory /factory/images · /builds · /tests · /applications · /metrics · /userspace

?tab=live and ?tab=health are rewritten to their routes, guarded to /factory so a stale query string cannot hijack navigation from another view.

The tabs were measurably hidden. They were 0.78rem uppercase #8b949e with no background fill, a 2px underline, a sub-44px target, ~400px down a 1080p viewport — readers reached content before navigation. They are now 1rem/700, filled when active, sticky, with a roving tabindex so passing the nav costs two Tab presses instead of nine.

Seven new pipelines, zero lab resources

Every dataset is regenerated from its original public source. Nothing reads the lab site or the lab cluster.

Fedora countme · Homebrew analytics · Flathub · OpenSSF Scorecard · GitHub Releases, Actions and Packages APIs.

The countme CSV is 618 MB, so fetch-countme.js range-reads a bounded 12 MB tail of a file sorted ascending by week and merges into a tracked seed — history accrues without the size ever being paid. Scorecard has no history endpoint, so its seed accumulates the same way.

What is deliberately absent

  • Container pull counts. GHCR publishes no download counter and Bluefin publishes to GHCR only. Countme, Flathub and Homebrew are the adoption signals instead.
  • Homebrew third-party tap installs. Not tracked by Homebrew. Its os-version analytics is substituted — and it is a better metric: Bluefin ranks chore(ci): turn on merge queue, workflow dispatch, PR checks #11 worldwide out of 9,734 operating systems, at 0.48% of all Homebrew installs.
  • Per-image CVE counts. Refused with reasons in adr/research/cve-feasibility.md: the SBOM seed carries 11 curated package versions, not an inventory. Scanning 0.5% of a 2,000-package surface and calling it a CVE count would be a confident-looking false claim next to true ones.
  • Everything measuring the lab cluster — BuildStream caches, the Thunderbolt link, contributor hardware, KubeVirt, ArgoCD. Dropped, not approximated.

Defects fixed along the way

Found by a design audit of the shipped page:

  • An all-zero sparkline series vanished instead of drawing a flat line.
  • Six small multiples in HistoryTrends autoscaled independently, so every cell looked identical regardless of value.
  • Severity was encoded by hue, including a red/green pair, in advisories, CI badges and the formation bar.
  • Three colour pairs failed WCAG AA — the worst at 2.7:1. Every text grey now clears AA on all three surfaces.
  • Two infinite animations had no prefers-reduced-motion guard.
  • 136 KB of static JSON was fetched client-side in four effects on every tab; routes now declare what they need and navigation does not refetch.
  • Panels returned null while loading, so they disappeared. scripts/panel-unavailability.test.js now fails on a component-level return null in any panel, present or future.

Assumptions ratified by ADR 0003

Applications means the applications Bluefin ships, not lab's ArgoCD state. Userspace means Bluefin's userspace stack. Tests is reconstructed from GitHub Actions at repo × workflow granularity rather than lab's suite × variant.

Verification

  • Clean build with a token and without one: both exit 0. Also builds green with every dataset forced to unavailable.
  • All eight routes emitted; no lab hostname and no IP address anywhere in build/factory/.
  • ECharts is isolated in lazy chunks, out of the initial route bundle.
  • npm test 318 pass / 0 fail · npm run typecheck clean · npm run lint 0 errors.

Jorge Castro and others added 14 commits August 7, 2026 21:17
Supersedes in part ADR 0002: the two-tab structure, the content split with
lab, and the hand-rolled-SVG-only rule.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…defects

Implements adr/0003-factory-two-level-navigation.md.

Every text grey now clears WCAG AA on all three surfaces. #484f58 measured
2.7:1 and #6e7681 measured 3.5-4.1:1; both are replaced by #808893, the
darkest grey in the same hue that still reaches 4.5:1, so the muted/faint
hierarchy survives. Both infinite animations are now guarded.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Implements adr/0003-factory-two-level-navigation.md.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Implements adr/0003-factory-two-level-navigation.md.

Replaces a 0.78rem uppercase tab bar with no background fill and a sub-44px
target. Active tabs are now filled rather than underlined, the primary row is
sticky, and only the selected tab in each row sits in the tab order.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…state

Implements adr/0003-factory-two-level-navigation.md.

Charts are gap-safe, animation-free and always accompanied by a data table.
Init and setOption are separate effects so an inline option literal cannot
drive a dispose/reimport loop.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Implements adr/0003-factory-two-level-navigation.md.

Routes declare the datasets they need; navigation no longer refetches. Each
fetch signals on its own completion, so a superseded effect cannot strand a
dataset at loading forever.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Implements adr/0003-factory-two-level-navigation.md.

Extracts useFactoryState() from the former 5,364-line single component so the
eight routes share one set of hive fetches instead of each mounting its own,
and splits the JSX into per-destination sections. ?tab=live and ?tab=health
are rewritten to their routes, guarded to /factory so a query string cannot
hijack navigation from another view.

Also replaces the formation red/green/amber triple with the severity intensity
scale plus a glyph, per ADR 0002 rule 3.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Implements adr/0003-factory-two-level-navigation.md.

Zero lab resources. Every dataset is regenerated from its original public
source: Fedora countme, Homebrew analytics, Flathub, OpenSSF Scorecard, and
the GitHub Releases, Actions and Packages APIs.

The countme CSV is 618 MB, so fetch-countme reads a bounded 12 MB tail of a
file sorted ascending by week and merges it into a tracked seed; history
accrues without the size ever being paid. Scorecard has no history endpoint,
so its seed accumulates the same way.

Every script degrades visibly: without a token each writes an explicit
unavailable payload and exits 0.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… buckets

The seed predated the weekly-bucket support already present in
fetch-hive-history.js, so the leaderboard sparklines had two points to draw
from. It now carries 52 weekly buckets for 275 contributors.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…eaderboard

Two leaderboards with unexplained different numbers side by side was flagged
in the design audit as a comprehension problem.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The SBOM seed carries 11 curated package versions per release, not a package
inventory. OSV answers fast and unauthenticated, but scanning 0.5% of a
2,000-package surface and labelling it a CVE count would be a confident-looking
false claim next to true ones.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Those metrics now live on their own route rather than in a tab.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Implements adr/0003-factory-two-level-navigation.md.

Images: lane freshness with awaiting summarised in one honest line rather than
a grid of dashes, release timeline, freshness brackets, availability by family.
Builds: adds per-lane duration trends on one shared y-domain with a p25-p95
band, plus a terminal-runs table with in-flight counted separately.
Tests: triage list, pass-rate trends, repo-by-suite heatmap, flake sparklines
on a shared domain.
Applications: the apps Bluefin ships, with Flathub downloads attributed to
Bluefin on a labelled log scale against peer distributions.
Metrics: countme active devices with a range toggle, ecosystem share, Homebrew
rank, delivery frequency, and the OpenSSF score published as-is at 4.5.
Userspace: the FSDK image inventory and the Flatpak runtime distribution on
Bluefin, with lab-cluster internals explicitly not reproduced.

Every chart goes through EChart and gapSafe, every series states its current
value, small multiples share a domain, and an in-flight run is never drawn as
a failure.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…hing

Code review found panels returning null while their data loaded, which is the
exact failure the visible-unavailability rule exists to prevent: a panel that
disappears is indistinguishable from one that has nothing to report.

Also repoints the lab reference at projectbluefin/lab, because
lab.projectbluefin.io still returns 404 — ADR 0002 moves that hostname by a
Cloudflare change outside this repository, and shipping is not atomic.

Adds scripts/panel-unavailability.test.js so the hazard cannot return: it
fails on a component-level 'return null' in any panel, present or future.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@castrojo

castrojo commented Aug 8, 2026

Copy link
Copy Markdown
Contributor Author

Closing — this was opened from a personal fork by mistake. Reopening from a branch on projectbluefin/documentation for pure upstream development.

@castrojo castrojo closed this Aug 8, 2026
@castrojo
castrojo deleted the feat/factory-two-level-nav branch August 8, 2026 14:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant