The ecosystem dashboard, and rankings that say what they rank on - #13
Merged
Merged
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
…ares of Spec §9's ecosystem dashboard and rankings, both computed from measured data and neither able to say the thing a directory is usually asked for. Shares, never totals. §15.7 withholds the absolute "how many people play MU*" figure because a ratio over the games we reached survives the ones we cannot and the ones nobody claimed, and a headcount survives neither — so EcosystemDashboard has nowhere to put one, and a test sums the fixture's counts and requires the number never to appear. A share carries its denominator as a field, not as a caption. MeasuredShare holds the count and the set it was counted in, and Fraction can be computed from nothing else, so a percentage cannot travel to a renderer without the set it is a fraction of. Protocols carry two denominators because they are two sets: games whose handshake we completed, and games whose MSSP report we hold. Three things the data could not honestly support, said on the page rather than filled in: - There is no adoption curve. game_field holds a current value with transitions beside it, so a curve has to be reconstructed and there are not yet enough transitions to plot. The available alternative — plotting each observation's first sighting — would draw a confident rising line measuring the crawl reaching more games and nothing about anybody adopting anything. The transition count is on the page instead, which is the number that says when the curve becomes real. - TLS is unmeasured, and says so rather than reading 0%. The probe dials plain telnet and TLS is not a telnet option, so no capability.tls.measured row can exist; "0% of games offer TLS" would be a limit of our crawler published as a fact about the hobby. The rule is derived from the tally rather than compiled in, so the column starts reporting a share the day the first measurement lands. - The measured column is a floor and is labelled one. The crawler writes a capability down when it observes it and otherwise writes nothing, because it requests MSSP alone and declines MCCP outright — MSSP is the one protocol whose silence is an answer, and it is the only one whose absence is counted as a no. The protocol denominator is read off availability rather than off capability rows: a reachable interval is a session of ours that completed, which is what a measured capability is a capability of. Counting games that have capability rows instead would define the denominator out of the numerator and quietly raise every share. Rankings are busiest-by-median over a stated week among games with enough samples to have a median, and the current unbroken reachable spell, which carries the date it began because a spell cannot be longer than we have been watching. Archived games are out of both and of nothing else. An uncountable probe is not a zero in either, and a measured zero is a count and ranks. The §5.1 ladder is resolved in SQL for the first time, because the dashboard reads every game at once. It is passed as a parameter generated from the enum's declared order, so the ladder still has exactly one spelling. Also: the fixture's demo week is scaled to each game's own count, so a demo ranking is a ranking rather than five ties; and the test container's client limit is lifted, because a database per test met Postgres's default hundred on the run that took the suite past a hundred and thirty tests and reported it as a flake in twenty unrelated places.
HarryCordewener
changed the base branch from
chore/park-the-importer
to
feat/about-page
July 31, 2026 15:21
HarryCordewener
force-pushed
the
feat/ecosystem-dashboard
branch
from
July 31, 2026 15:21
5a4a6ac to
3cb6618
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Spec §9's ecosystem dashboard and rankings, both in §14's v1 boundary and neither previously
existing.
Stacks on #11 (
chore/park-the-importer), which ismainplus #9 and #11. Those two rewrote howthe site gets its data, and building on
mainwould have meant writing against the fixture and stalewording. Review after #11 lands, or read the diff against that branch.
What is here
Two pages,
/ecosystemand/rankings, both static SSR with no script, both surviving?plain=1whole. Aggregates live in
NpgsqlGameQueriesbehindIGameQueries;MUI.Catalogreferences nothingnew.
Shares, never totals. §15.7 withholds the absolute "how many people play MU*" figure because a
ratio over the games we reached survives the ones we cannot reach and the ones nobody claimed, and a
headcount survives neither.
EcosystemDashboardhas nowhere to put one — it has no access topresence at all — and
NoAbsolutePlayerFigureIsEmittedByEitherSurfacesums the fixture's measuredcounts and requires the number never to appear on either surface.
A share carries its denominator as a field.
MeasuredShare(Label, Count, Denominator), withFractioncomputable from nothing else, so a percentage cannot travel to a renderer without the setit is a fraction of. Protocols carry two denominators, because they are two sets: games whose
handshake we completed, and games whose MSSP report we hold.
The protocol denominator is read off availability, not off capability rows. A
reachableinterval is a session of ours that completed, which is exactly what a measured capability is a
capability of. Counting "games that have capability rows" would define the denominator out of the
numerator — a game whose handshake completed and offered nothing measurable would drop out of the
bottom of every fraction and quietly raise every share on the page.
What the stored data could not honestly support, and what the page says instead
game_fieldholds a current value with transitions beside it infield_change, so a curve has to be reconstructed from transitions and there are not yet enough toplot. The available alternative — plotting each observation's
first_seen_at— would draw aconfident rising line measuring our crawler reaching more games and nothing whatever about anybody
adopting anything. The page says so and prints the transition count, which is the number that says
when the curve becomes real.
a telnet option, and nothing writes a
tlsendpoint — so nocapability.tls.measuredrow canexist today.
ProtocolAdoption.Offeredis nullable for exactly this, and the null is derived fromthe tally rather than compiled in, so the column starts reporting a share on its own the day the
first measurement lands. TLS still shows a declared share, over its own denominator.
FieldObservationswrites a capabilitywhen it observes one and otherwise writes nothing, because the crawler requests MSSP alone and
declines MCCP outright. MSSP is the one protocol whose silence is an answer — we ask by name — so
it is the only one whose absence is counted as a
no. Everything else lands in neither offerednor asked.
Rankings
Two tables, each stating its basis on the page: busiest by the median of measured concurrent
counts over a named week among games that produced at least 24 counted samples (
percentile_disc, sothe median is a number some probe actually read), and the current unbroken reachable spell, which
carries the date it began because a spell cannot be longer than we have been watching. Archived games
are out of both and of nothing else. An uncountable probe is not a zero in either; a measured zero is
a count and ranks. There is no voting affordance and the page says there never will be.
Tests
670 across the five suites, all green and warning-free. Worth naming:
NoAbsolutePlayerFigureIsEmittedByEitherSurfaceEveryPercentageOnTheDashboardArrivesWithItsDenominatorAGameWeHaveNeverHandshakedIsOutOfTheDenominatorRatherThanInItAsANoAHandshakeThatOfferedNothingIsStillInTheDenominatorAProtocolNothingHasOfferedIsUnmeasuredRatherThanNoughtPerCentOnlyAProtocolWeAskedForCountsSilenceAsANoAnUncountableProbeIsNotAZeroInARankingTwo things outside the feature
regardless of the count that game reports, which made the demo ranking five ties.
on the run that took the suite past 130 tests, failing whichever tests happened to be starting and
reading as a flake in twenty unrelated places.
Deliberately not here
No
/api/ecosystem— §10 is a separate surface and this adds no endpoint. No recency window on theprotocol denominator: a listed game we handshaked six weeks ago is in it, and the page states how old
the stalest handshake in the picture is rather than silently trimming the set.
🤖 Generated with Claude Code
https://claude.ai/code/session_01NrGKmKcRCGktyhRTFbQDMk