Skip to content

docs(api): add operation-level summaries to all OpenAPI routes - #6111

Merged
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
cleanjunc:feat/openapi-operation-summaries
Jul 15, 2026
Merged

docs(api): add operation-level summaries to all OpenAPI routes#6111
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
cleanjunc:feat/openapi-operation-summaries

Conversation

@cleanjunc

Copy link
Copy Markdown
Contributor

Summary

  • src/openapi/spec.ts set response-level description on all 78 registry.registerPath({...}) calls but never the operation-level summary — so every operation in the generated openapi.json and the rendered API browser showed a bare GET /health with no title. grep -c "summary:" src/openapi/spec.ts0.
  • This adds a concise, accurate summary to every one of the 102 operations the spec builds, and a regression test that fails loudly when a future route lands without one. apps/loopover-ui/public/openapi.json is regenerated via npm run ui:openapi and committed.

102 operations, not 78 — worth flagging, because it changes what "all routes" means here. The issue counts the 78 registerPath call sites, but 5 of them sit inside for (const path of [...]) loops that each register several paths (4 + 5 + 9 + 2 + 9 = 29 paths from 5 calls). So 73 literal calls + 29 looped paths = 102 operations. A single hardcoded summary inside a loop would have stamped the same title onto all 9 of its paths, which is exactly the "duplicating a description verbatim" outcome the issue asks to avoid. Instead each loop now iterates [path, summary] tuples:

for (const [path, summary] of [
  ["/v1/app/roles", "App roles granted to the current session"],
  ["/v1/app/miner-dashboard", "Miner dashboard data"],
  // …
] as const) {
  registry.registerPath({ method: "get", path, summary, responses: { /* unchanged */ } });
}

Each summary describes the operation's purpose rather than restating a response description — e.g. GET /health"Service liveness probe" (not the existing 200 description "Service health"), and DELETE /v1/app/selfhost/queue/dead"Purge all dead-letter queue jobs". All 102 summaries are unique; no response-level description, schema, security, or route behavior is touched.

Closes #5810

Scope

  • The PR title follows type(scope): short summary Conventional Commit format, for example fix(api): restore profile access checks.
  • This PR is focused and does not mix unrelated backend, UI, MCP, docs, dependency, and deploy changes.
  • This follows CONTRIBUTING.md and does not reintroduce GitHub Pages, VitePress, site/, or CNAME.
  • I linked a currently open issue this PR resolves (e.g. Closes #123) — a linked open issue is required for every contributor PR.

Validation

  • git diff --check
  • npm run actionlint
  • npm run typecheck
  • npm run test:coverage locally; codecov/patch requires ≥99% coverage of the lines AND branches you changed (aim for 100% on your diff so CI variance does not fail near the threshold). Global coverage is a non-blocking trend with a loose 90% backstop, not the gate.
  • npm run test:workers
  • npm run build:mcp
  • npm run test:mcp-pack
  • npm run ui:openapi:check
  • npm run ui:lint
  • npm run ui:typecheck
  • npm run ui:build
  • npm audit --audit-level=moderate
  • New or changed behavior has unit/integration tests for new branches, fallback paths, and sanitizer boundaries

If any required check was skipped, explain why:

  • Nothing was skipped: the full npm run test:ci chain (every box above except npm audit, run separately) passed end-to-end, and npm audit --audit-level=moderatefound 0 vulnerabilities.
  • Patch coverage measured empirically, not inferred. src/openapi/spec.ts is inside coverage.include, so this diff is Codecov-gated. Scoped run → 100% statements, 100% lines, 100% functions on the file; the single uncovered branch the report shows is line 1217 (...(document.components ?? {})), a pre-existing nullish fallback that is not in this diff (confirmed by intersecting the report against git diff -U0's new-side hunks). The changed lines add no branches at all — they are static string properties plus a tuple destructure — and the new test builds the whole spec, so every changed line is executed by construction. Patch = 100% lines and branches.
  • The regression test is proven, not asserted. Against upstream/main's src/openapi/spec.ts it fails with GET /health is missing an operation-level summary: expected 'undefined' to be 'string'; against this branch all 3 tests in the file pass. Both directions were run.

Safety

  • No secrets, wallet details, hotkeys, coldkeys, user PATs, private keys, raw trust scores, private rankings, or private maintainer evidence are exposed.
  • Public GitHub text stays sanitized, low-noise, and does not imply compensation guarantees or optimization tactics.
  • Auth, cookie, CORS, GitHub App, Cloudflare, or session changes include negative-path tests.
  • API/OpenAPI/MCP behavior is updated and tested where needed.
  • UI changes use live API data or real empty/error/loading states, not production mock/demo fallbacks.
  • Visible UI changes include a UI Evidence section below with JPG/JPEG or PNG screenshots arranged as organized, captioned, clickable thumbnails. SVG screenshots are not used as review evidence. Review-only screenshots or recordings are not committed to the repository.
  • Public docs/changelogs are updated where needed; changelogs are only edited for release-prep PRs.

Unchecked boxes above, and why — all N/A rather than skipped:

  • Auth/cookie/CORS/session: no auth, session, CORS, GitHub App, or Cloudflare behavior changes. The auth routes only gain documentation titles; their security blocks and the isProtectedPath logic are untouched, and the existing openapi.test.ts assertions that pin each route's security shape still pass unchanged.
  • UI / UI Evidence: no UI source is touched. apps/loopover-ui/public/openapi.json changes only because it is the generated artifact npm run ui:openapi writes (Phase 4 requires committing it, and ui:openapi:check fails if it drifts). The API browser that renders it will now show a title per operation, but there is no frontend code change to screenshot, and review-only screenshots are not committed.

Notes

  • Diff shape: src/openapi/spec.ts (+summaries, 5 loops converted to [path, summary] tuples), test/unit/openapi.test.ts (+1 regression test), apps/loopover-ui/public/openapi.json (regenerated, not hand-edited).
  • The test iterates the built document, not the source. Counting summary: lines in spec.ts would have missed the 29 looped paths entirely; buildOpenApiSpec().paths → every method is the only shape that actually covers all 102. It mirrors the sibling in: path parameter test directly above it, including the per-operation failure label so a future miss names the exact route.
  • Verified there are no gaps or collisions: all 102 operations have a non-empty summary, and all 102 are distinct — checked by building the spec and diffing the summary set, so no route silently inherited a neighbor's title.

@cleanjunc
cleanjunc requested a review from JSONbored as a code owner July 15, 2026 09:55
@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:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. label Jul 15, 2026
@loopover-orb

loopover-orb Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Tip

🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩

✅ LoopOver review result - approve/merge recommended

Review updated: 2026-07-15 10:04:48 UTC

3 files · 1 AI reviewer · no blockers · readiness 100/100 · CI green · clean

✅ Suggested Action - Approve/Merge

  • safe to merge

Review summary
This PR adds operation-level `summary` fields to all 102 OpenAPI operations in src/openapi/spec.ts, correctly converting loop-based route registrations from bare path arrays to `[path, summary]` tuples so each looped path gets a distinct, meaningful summary rather than a duplicated one. It includes a regression test that iterates the built spec document (not just source grep) so it also catches loop-registered paths and future routes lacking a summary, and regenerates/commits the derived openapi.json. The diff is well-scoped, closes #5810, touches no response schemas/security/behavior, and the sampled summaries are accurate and non-generic.

Nits — 4 non-blocking
  • test/unit/openapi.test.ts:139 casts `methods` to `Record<string, { summary?: string }>` losing type safety on the actual generated spec type — a type-level assertion (e.g. narrowing via the real OpenAPIV3 type) would catch drift better than a hand-rolled interface.
  • The regenerated apps/loopover-ui/public/openapi.json is a large generated-artifact diff bundled with the source change — worth confirming CI actually verifies the checked-in JSON matches `npm run ui:openapi` output so the two don't silently drift again.
  • Consider asserting summary uniqueness in the new test (the PR description claims all 102 are unique) so a future copy-paste duplicate is also caught, not just missing ones.
  • If not already done elsewhere, verify the CI pipeline runs `ui:openapi` generation and diffs it against the committed file to prevent future staleness.
Signal Result Evidence
Code review ✅ No blockers 1 reviewer
Linked issue ✅ Linked #5810
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 ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 55 registered-repo PR(s), 21 merged, 30 issue(s).
Contributor context ✅ Confirmed Gittensor contributor cleanjunc; Gittensor profile; 55 PR(s), 30 issue(s).
Gate result ✅ Passing No configured blocker found.
Improvement ✅ Minor risk: clean · value: minor · LLM: moderate
Linked issue satisfaction

Addressed
The diff adds operation-level `summary` fields to all 78 registerPath call sites (including the 5 loop-based ones expanded via [path, summary] tuples covering 102 total operations), adds a regression test iterating buildOpenApiSpec().paths asserting non-empty summary strings, and regenerates apps/loopover-ui/public/openapi.json.

Review context
  • Author: cleanjunc
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: Python, TypeScript, Cuda, JavaScript, Scala
  • Official Gittensor activity: 55 PR(s), 30 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Keep the PR focused and include validation evidence before maintainer review.
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 &lt;question&gt; answers contribution-quality Q&A with source citations and freshness.
  • @loopover chat &lt;question&gt; 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://gittensory.aethereal.dev/docs/loopover-commands

🧪 Experimental — new and may change.

🟩 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

@loopover-orb loopover-orb Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LoopOver approves — the gate is satisfied and CI is green.

@loopover-orb
loopover-orb Bot merged commit 70d46de into JSONbored:main Jul 15, 2026
14 checks passed
@codecov

codecov Bot commented Jul 15, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.31%. Comparing base (0ad33b7) to head (11647d9).
⚠️ Report is 13 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6111      +/-   ##
==========================================
+ Coverage   95.24%   95.31%   +0.06%     
==========================================
  Files         595      595              
  Lines       47069    47097      +28     
  Branches    15020    15030      +10     
==========================================
+ Hits        44831    44890      +59     
+ Misses       1493     1476      -17     
+ Partials      745      731      -14     
Flag Coverage Δ
shard-1 43.97% <100.00%> (-0.05%) ⬇️
shard-2 36.64% <0.00%> (+0.01%) ⬆️
shard-3 32.13% <100.00%> (+0.06%) ⬆️
shard-4 33.26% <100.00%> (-0.48%) ⬇️
shard-5 31.47% <0.00%> (-0.19%) ⬇️
shard-6 44.87% <100.00%> (+0.33%) ⬆️

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

Files with missing lines Coverage Δ
src/openapi/spec.ts 99.42% <100.00%> (ø)

... and 1 file with indirect coverage changes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docs(api): add operation-level summary/description to all 78 OpenAPI routes

1 participant