Skip to content

fix(api): declare 404 and 503 for the public README badge routes - #9748

Merged
JSONbored merged 1 commit into
JSONbored:mainfrom
shin-core:fix/badge-openapi-404-503-9710
Jul 29, 2026
Merged

fix(api): declare 404 and 503 for the public README badge routes#9748
JSONbored merged 1 commit into
JSONbored:mainfrom
shin-core:fix/badge-openapi-404-503-9710

Conversation

@shin-core

Copy link
Copy Markdown
Contributor

What & why

Closes #9710.

#8377 gave GET /v1/public/repos/:owner/:repo/badge.svg and .../badge.json a deliberate
three-outcome split — 404 (this repo has no public badge), 503 (the badge data could not be
loaded, short-cached), 200 otherwise — so a monitor can tell "no badge" apart from a transient
backend failure. But the spec entries added in #9531 declared only 200, so the published contract
these README-embedded routes are read against was missing exactly the two statuses the handler comment
says a monitor must distinguish.

Change

Add 404 and 503 to both getRepoBadgeSvg and getRepoBadgeJson in
internal-and-public-route-specs.ts (descriptions matching the handler's own distinction), and
regenerate openapi.json. No handler behaviour, status, or cache header changes.

Validation

  • Tests pin which branch produces which status: the no-badge 404 and the loader-failure 503 each
    carry Cache-Control: public, max-age=300 and render the exact renderUnavailableBadgeSvg() body
    (svg) / unavailable shields payload (json).
  • A buildOpenApiSpec() assertion that both operations declare 200/404/503.
  • Bug-catch verified: removing the statuses from the spec fails the openapi assertion.
  • ui:openapi:check drift-check clean.

JSONbored#8377 gave GET /v1/public/repos/:owner/:repo/badge.svg and .../badge.json a
deliberate three-outcome split -- 404 (no public badge for this repo), 503 (the
badge data could not be loaded, short-cached), 200 otherwise -- so a monitor can
tell a repo with no badge apart from a transient backend failure. But the spec
entries added in JSONbored#9531 declared only 200, so the published contract these
README-embedded routes are read against was missing exactly the two statuses the
handler comment says a monitor must distinguish.

Add 404 and 503 to both getRepoBadgeSvg and getRepoBadgeJson (their descriptions
matching the handler's own distinction) and regenerate openapi.json. No handler
behaviour, status, or cache header changes.

Adds tests pinning which branch produces which status: the no-badge 404 and the
loader-failure 503 each carry Cache-Control: public, max-age=300 and render the
exact renderUnavailableBadgeSvg() body (svg) / unavailable shields payload (json),
plus a buildOpenApiSpec() assertion that both operations declare 200/404/503.

Closes JSONbored#9710
@shin-core
shin-core requested a review from JSONbored as a code owner July 29, 2026 05:48
@superagent-security superagent-security Bot added the contributor:flagged Contributor flagged for review by trust analysis. label Jul 29, 2026
@superagent-security

Copy link
Copy Markdown
Contributor

🚨 Contributor flagged. Click here for more info: Superagent Dashboard

@loopover-orb

loopover-orb Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Warning

⏸️ LoopOver review result - manual review recommended

Review updated: 2026-07-29 05:58:51 UTC

4 files · 1 AI reviewer · no blockers · CI green · unstable

⏸️ Suggested Action - Manual Review

Review summary
This PR adds 404 and 503 response entries to the badge.svg and badge.json OpenAPI spec entries in internal-and-public-route-specs.ts, regenerates openapi.json to match, and updates tests to pin the exact status/cache-header/body behavior on both branches plus a new spec assertion. The change is narrow, correctly scoped to the documented gap from #9710 (the handler already produces 404/503 per #8377, but the spec only declared 200), and includes both a regression test on the openapi builder and integration tests exercising the real routes. No handler logic changes, and the openapi.json diff matches the spec-file diff exactly.

Nits — 3 non-blocking
  • The magic-number flags on 200/404/503 in internal-and-public-route-specs.ts are noise — these are literal HTTP status codes used as object keys throughout this file's existing pattern (see INTERNAL_AUTH, QUEUED, RAN), not unexplained constants needing naming.
  • test/integration/api.test.ts:328-333 adds a badge.json 404 check but doesn't assert its body equals renderUnavailableBadgeSvg()-equivalent JSON shape the way the svg check does, so the json branch's exact payload shape isn't pinned as tightly as the svg branch.
  • Consider asserting the badge.json unavailable body shape (e.g. the 'unavailable' shields.io payload) with a toEqual/toMatchObject the way test/unit likely does elsewhere, to match the svg branch's exact-body rigor mentioned in the PR description.

Decision drivers

  • ✅ Code review — No blockers (1 reviewer)
  • ✅ Gate result — Passing (No configured blocker found.)
Context & advisory signals — never blocks the verdict
Signal Result Evidence
Linked issue ✅ Linked #9710
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Change scope ✅ 20/20 Low review scope from cached public metadata (1 linked issue).
Validation posture ❌ 5/25 Preflight is holding this PR: the review lane is unavailable, so it is not ready for automated review.
Contributor workload ✅ 10/10 Author activity: 38 registered-repo PR(s), 26 merged, 0 issue(s).
Contributor context ✅ Confirmed Gittensor contributor shin-core; Gittensor profile; 38 PR(s), 0 issue(s).
Improvement ✅ Minor risk: clean · value: minor
Linked issue satisfaction

Addressed
The PR adds 404/503 response entries with the required distinguishing descriptions to both getRepoBadgeSvg and getRepoBadgeJson in the spec file, regenerates openapi.json, and adds tests pinning the 404-vs-503 cache-control and body behavior for badge.svg plus a buildOpenApiSpec() assertion checking both statuses on both routes, matching the issue's core ask.

Review context
  • Author: shin-core
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository is registered but has no active allocation in the current snapshot.
  • Public profile languages: TypeScript, JavaScript, Solidity, Dart, Python, CSS, PHP, Rust
  • Official Gittensor activity: 38 PR(s), 0 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Start here: Await review-lane availability.
  • Then work through the remaining 2 steps in the Signals table above.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.
🧪 Chat with LoopOver

Ask LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.

  • @loopover ask <question> answers contribution-quality Q&A with source citations and freshness.
  • @loopover chat <question> answers in natural prose from cached decision-pack facts via local inference (maintainer/collaborator; read-only).
  • A plain-language @loopover mention with a real question is routed to the closest matching read-only command automatically — no exact syntax required.

Full command reference: https://loopover.ai/docs/loopover-commands

🧪 Experimental — new and may change.

Decision record
  • action: hold · clause: success
  • config: 09cb8c1d88374b21e7e8671ab1680b0f52ac298c8a9a3104630024e638354cde · pack: oss-anti-slop · ci: passed
  • record: ba7a6b2bb0c632ea8c41b5f3df60a2ab689cbbab799d78b60f6f8e57f664b923 (schema v5, head 4511caa)
Visual preview
Route Viewport Before (production) After (this PR's preview) Diff
/ desktop before /
before /
after /
after /
/ mobile before / (mobile)
before / (mobile)
after / (mobile)
after / (mobile)

Click any thumbnail to open the full-size screenshot. Before = production · After = this PR's preview deploy.

Scroll preview
Route Before (production) After (this PR's preview)
/ before / (scroll)
before / (scroll)
after / (scroll)
after / (scroll)

A short scroll-through clip (desktop) — click either thumbnail to open the full animation. Evidence for scroll-linked behavior a single screenshot can't show.

🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed


💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →.

Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.

  • Re-run LoopOver review

@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@loopover-orb loopover-orb Bot added the gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. label Jul 29, 2026
@codecov

codecov Bot commented Jul 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 76.59%. Comparing base (0f4276d) to head (4511caa).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #9748   +/-   ##
=======================================
  Coverage   76.58%   76.59%           
=======================================
  Files         282      283    +1     
  Lines       59419    59441   +22     
  Branches     6553     6553           
=======================================
+ Hits        45508    45530   +22     
  Misses      13629    13629           
  Partials      282      282           
Flag Coverage Δ
backend 100.00% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/openapi/internal-and-public-route-specs.ts 100.00% <ø> (ø)

@loopover-orb loopover-orb Bot added the manual-review Gittensor contributor context label Jul 29, 2026
@loopover-orb

loopover-orb Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Held for manual review: the gate and required CI are green, but GitHub reports this pull request's mergeable state as unstable because a non-required check or status is not passing, so LoopOver will not auto-merge. A maintainer can resolve the failing check or review and merge manually. This is an automated maintenance action.

@JSONbored
JSONbored merged commit ef6d580 into JSONbored:main Jul 29, 2026
9 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contributor:flagged Contributor flagged for review by trust analysis. gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. manual-review Gittensor contributor context

Projects

None yet

Development

Successfully merging this pull request may close these issues.

api(badge): the README badge routes publish only 200 despite a documented 404 and 503

2 participants