Relationships
#1025 Scorecard: beta/rc-only extensions show "not scored" despite successful scoring (GET /score resolves only latestVersion)
Opened by swamp_lord · 7/7/2026· Shipped 7/7/2026
Summary
Extensions whose only published release is on a pre-release channel (beta / rc) display "not scored" on swamp-club.com even though the scorecard pipeline scored the version successfully. The score is computed and persisted, but the public GET /score read short-circuits before it looks the score up.
Root cause
The scorecard read resolves the target version from the stable channel only:
routes/api/v1/extensions/[...path].ts (handleGetScore, ~line 264):
const targetVersion = version ?? ext.latestVersion; // latestVersion is null for a beta-only extension
if (!targetVersion) {
return Response.json({ status: "not_scored" }); // ← returns here, never reads the meta
}For a beta-only extension, ext.latestVersion (stable) is null while ext.latestBeta holds the version, so targetVersion is null and the handler returns bare {"status":"not_scored"} without ever calling extensionVersionMetaRepo.findByExtensionIdAndVersion(...) — even though a scored meta row exists.
This is asymmetric with the rescore path. POST /score (handleScoreExtension, ~line 569) resolves the version via extensionRepo.getLatestNonYankedVersion(existing.id), which does find the beta version. So the owner's "rescore" button enqueues + scores the beta version successfully and writes the meta — but the GET read still refuses to surface it. The result is a frustrating loop: rescore succeeds → refresh → still "not scored".
Reproduction
- Publish an extension with its only release on the beta channel (so the extension record has
latestBetaset andlatestVersion = null). - Wait for background scoring to complete (
watcher.extension-scoring.tick→app.extension-scoring.process.batch; log line"Extension version scored"withrubricVersion: 3). - Load the extension page / call
GET /api/v1/extensions/<name>/score. - Expected: the computed scorecard (
{"available":true, "percentage":…}). - Actual:
{"status":"not_scored"}.
Observed in production (2026-07-07)
Extension @magistr/stripe-mpp@2026.07.03.1:
- Scored successfully 3× today (21:39, 21:40, 21:47) — each logged
Extension version scored,rubricVersion: 3,dependencyTrustPassed: false(2 blockers inmppx),percentageDocumentedSymbols: 1, etc. So the meta row exists. - Extension record:
latestVersion: null,latestBeta: "2026.07.03.1",latestRc: null,score: null. GET /api/v1/extensions/@magistr/stripe-mpp/score→{"status":"not_scored"}(the bare line-266 shape, i.e.targetVersionwas falsy — not the{available:false, reason:…}shape used when a version is known but meta is missing).- Contrast
@webframp/twitch(stable release):latestVersion: "2026.07.03.1"→GET /score→{"available":true, "percentage":100, …}.
Suggested fix
Make GET /score resolve the target version the same way the rescore path does — fall back to getLatestNonYankedVersion() (or consider latestBeta / latestRc) instead of relying solely on ext.latestVersion. Any beta-only or rc-only extension is currently mis-shown as "not scored." Separately, consider whether the UI should distinguish "beta — no stable release yet" from a genuine "not scored" state.
Impact
All extensions whose only release is on a pre-release channel are silently unscored on the site despite scoring succeeding. Worth auditing how many extensions are currently beta/rc-only.
Shipped
Click a lifecycle step above to view its details.
Sign in to post a ripple.