feat(api): add REST mirrors for the finding-taxonomy and enrichment-analyzers MCP resources - #6706
Conversation
…nalyzers MCP resources buildFindingTaxonomyDocument() and buildEnrichmentAnalyzersTaxonomyDocument() were reachable only as MCP resources (loopover://finding-taxonomy, gittensory://enrichment-analyzers). A caller without MCP access -- a plain HTTP client, a dashboard, a non-MCP integration -- had no way to fetch either, even though routes.ts otherwise exposes essentially every other piece of review/registry/scoring data over /v1/*. Adds GET /v1/finding-taxonomy and GET /v1/enrichment-analyzers, each delegating to its existing pure, argument-free builder with the same plain-c.json() handler shape as the /v1/scoring/model route they sit beside. Both are additive: the MCP resource registrations are untouched, and the URIs stay MCP-only identifiers. Registers both paths in src/openapi/spec.ts with response schemas, and regenerates apps/loopover-ui/public/openapi.json so ui:openapi:check stays green. The two schemas are deliberately permissive on member strings -- the taxonomies are open-ended (FINDING_CATEGORIES, the committed analyzer-metadata.json), so the shape is the contract, not the enum membership. Tests assert each route returns its builder's document byte-identically, that neither leaks PR/user/private data, and that both are gated exactly like the sibling /v1/scoring/model route -- pinned against that sibling rather than a hard-coded status, so the assertion stays honest if the shared middleware changes. Extends openapi.test.ts's path list with both new paths. Closes JSONbored#6593
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #6706 +/- ##
=======================================
Coverage 93.65% 93.65%
=======================================
Files 681 682 +1
Lines 68098 68124 +26
Branches 18695 18702 +7
=======================================
+ Hits 63775 63800 +25
Misses 3347 3347
- Partials 976 977 +1
Flags with carried forward coverage won't be shown. Click here to find out more.
|
|
Tip ✅ LoopOver review result - approve/merge recommendedReview updated: 2026-07-16 20:14:29 UTC
Review summary Nits — 5 non-blocking
Decision drivers
Context & advisory signals — never blocks the verdict
Review context
Contributor next steps
Signal definitions
🧪 Chat with LoopOverAsk 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.
Full command reference: https://loopover.ai/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.
|
What & why
buildFindingTaxonomyDocument()andbuildEnrichmentAnalyzersTaxonomyDocument()were reachable only as MCP resources (loopover://finding-taxonomy,gittensory://enrichment-analyzers). A caller without MCP access — a plain HTTP client, a dashboard, a non-MCP integration — had no way to fetch either, even thoughroutes.tsotherwise exposes essentially every other piece of review/registry/scoring data over/v1/*.Changes
GET /v1/finding-taxonomyandGET /v1/enrichment-analyzers, each delegating to its existing pure, argument-free builder with the same plain-c.json()handler shape as the/v1/scoring/modelroute they sit beside.src/mcp/server.tsare untouched, and the URIs stay MCP-only identifiers.src/openapi/spec.tswith response schemas, andapps/loopover-ui/public/openapi.jsonregenerated soui:openapi:check/ui:openapi:settings-paritystay green.The two schemas are deliberately permissive on member strings: the taxonomies are open-ended (
FINDING_CATEGORIES, the committedanalyzer-metadata.json), so the shape is the contract — adding a category or analyzer must never break the spec.One correction worth flagging
The issue describes these as "unauthenticated GET routes consistent with the other public static-data routes (
/v1/registry/snapshot,/v1/upstream/ruleset,/v1/scoring/model)". Those siblings aren't actually public — I verifiedGET /v1/scoring/modelreturns 401 unauthenticated. So I followed the requirement as written where it counts (no new auth middleware added), and the new routes inherit exactly the same gating as the siblings they mirror. The auth test pins them against/v1/scoring/model's own behavior rather than a hard-coded status, so it stays honest if that shared middleware ever changes — and can never silently open a public hole.Tests
Each route returns its builder's document byte-identically; neither leaks PR/user/private data; both match the sibling's gating; and
openapi.test.ts's path list is extended with both new paths (as the issue requires). Zero uncovered lines and branches across all three changedsrc/files, measured against the changed-line set.Closes #6593