Skip to content

Commit cfc180f

Browse files
committed
docs(openapi): document the five repo maintainer-report routes in the spec
The maintainer-noise, ams-miner-cohort, gate-precision, outcome-calibration, and activation-preview GET routes are all live and maintainer-authenticated with an MCP tool counterpart, but none appeared in the generated OpenAPI spec. MaintainerNoiseReport and AmsMinerCohortComparison were even registered as components yet never attached to a path. Add registerPath entries for all five, define GatePrecisionResponse, OutcomeCalibrationResponse, and ActivationPreviewResponse schemas mirroring their MCP tools' output shapes field-for-field, and regenerate the committed openapi.json. A regression test asserts each path is documented with a 200 response referencing a component whose keys match its MCP tool shape.
1 parent be99f3c commit cfc180f

5 files changed

Lines changed: 538 additions & 6 deletions

File tree

apps/loopover-ui/public/openapi.json

Lines changed: 367 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14856,6 +14856,108 @@
1485614856
"recommendation",
1485714857
"summary"
1485814858
]
14859+
},
14860+
"GatePrecisionResponse": {
14861+
"type": "object",
14862+
"properties": {
14863+
"repoFullName": {
14864+
"type": "string"
14865+
},
14866+
"generatedAt": {
14867+
"type": "string"
14868+
},
14869+
"windowDays": {
14870+
"type": "number",
14871+
"nullable": true
14872+
},
14873+
"perGateType": {
14874+
"type": "array",
14875+
"items": {
14876+
"nullable": true
14877+
}
14878+
},
14879+
"overall": {
14880+
"nullable": true
14881+
},
14882+
"signals": {
14883+
"type": "array",
14884+
"items": {
14885+
"type": "string"
14886+
}
14887+
}
14888+
}
14889+
},
14890+
"OutcomeCalibrationResponse": {
14891+
"type": "object",
14892+
"properties": {
14893+
"repoFullName": {
14894+
"type": "string"
14895+
},
14896+
"generatedAt": {
14897+
"type": "string"
14898+
},
14899+
"windowDays": {
14900+
"type": "number",
14901+
"nullable": true
14902+
},
14903+
"slop": {
14904+
"nullable": true
14905+
},
14906+
"recommendations": {
14907+
"nullable": true
14908+
},
14909+
"signals": {
14910+
"type": "array",
14911+
"items": {
14912+
"type": "string"
14913+
}
14914+
},
14915+
"status": {
14916+
"type": "string"
14917+
}
14918+
}
14919+
},
14920+
"ActivationPreviewResponse": {
14921+
"type": "object",
14922+
"properties": {
14923+
"repoFullName": {
14924+
"type": "string"
14925+
},
14926+
"generatedAt": {
14927+
"type": "string"
14928+
},
14929+
"currentReviewCheckMode": {
14930+
"type": "string"
14931+
},
14932+
"aiReviewConfigured": {
14933+
"type": "boolean"
14934+
},
14935+
"evaluatedCount": {
14936+
"type": "number"
14937+
},
14938+
"withFindingsCount": {
14939+
"type": "number"
14940+
},
14941+
"findingCodeCounts": {
14942+
"type": "array",
14943+
"items": {
14944+
"nullable": true
14945+
}
14946+
},
14947+
"samples": {
14948+
"type": "array",
14949+
"items": {
14950+
"nullable": true
14951+
}
14952+
},
14953+
"recommendedAction": {
14954+
"type": "string",
14955+
"nullable": true
14956+
},
14957+
"summary": {
14958+
"type": "string"
14959+
}
14960+
}
1485914961
}
1486014962
},
1486114963
"parameters": {},
@@ -19370,6 +19472,271 @@
1937019472
}
1937119473
]
1937219474
}
19475+
},
19476+
"/v1/repos/{owner}/{repo}/maintainer-noise": {
19477+
"get": {
19478+
"summary": "Maintainer queue-noise triage report for a repo (#2228)",
19479+
"parameters": [
19480+
{
19481+
"schema": {
19482+
"type": "string"
19483+
},
19484+
"required": true,
19485+
"name": "owner",
19486+
"in": "path"
19487+
},
19488+
{
19489+
"schema": {
19490+
"type": "string"
19491+
},
19492+
"required": true,
19493+
"name": "repo",
19494+
"in": "path"
19495+
}
19496+
],
19497+
"responses": {
19498+
"200": {
19499+
"description": "Read-only queue-noise triage report — noise score/level, sources, recommended maintainer actions, and queue health (mirrors loopover_get_maintainer_noise)",
19500+
"content": {
19501+
"application/json": {
19502+
"schema": {
19503+
"$ref": "#/components/schemas/MaintainerNoiseReport"
19504+
}
19505+
}
19506+
}
19507+
},
19508+
"401": {
19509+
"description": "Missing or invalid credential"
19510+
},
19511+
"403": {
19512+
"description": "Caller is not a maintainer of this repo"
19513+
}
19514+
},
19515+
"security": [
19516+
{
19517+
"LoopOverBearer": []
19518+
},
19519+
{
19520+
"LoopOverSessionCookie": []
19521+
}
19522+
]
19523+
}
19524+
},
19525+
"/v1/repos/{owner}/{repo}/ams-miner-cohort": {
19526+
"get": {
19527+
"summary": "AMS-vs-human contributor-mix cohort comparison for a repo (#6488)",
19528+
"parameters": [
19529+
{
19530+
"schema": {
19531+
"type": "string"
19532+
},
19533+
"required": true,
19534+
"name": "owner",
19535+
"in": "path"
19536+
},
19537+
{
19538+
"schema": {
19539+
"type": "string"
19540+
},
19541+
"required": true,
19542+
"name": "repo",
19543+
"in": "path"
19544+
}
19545+
],
19546+
"responses": {
19547+
"200": {
19548+
"description": "AMS-miner vs human cohort metrics over the comparison window; `present: false` (never a 404) when the AMS reputation bridge is off or the repo has no submitter activity (mirrors loopover_get_ams_miner_cohort)",
19549+
"content": {
19550+
"application/json": {
19551+
"schema": {
19552+
"$ref": "#/components/schemas/AmsMinerCohortComparison"
19553+
}
19554+
}
19555+
}
19556+
},
19557+
"401": {
19558+
"description": "Missing or invalid credential"
19559+
},
19560+
"403": {
19561+
"description": "Caller is not a maintainer of this repo"
19562+
}
19563+
},
19564+
"security": [
19565+
{
19566+
"LoopOverBearer": []
19567+
},
19568+
{
19569+
"LoopOverSessionCookie": []
19570+
}
19571+
]
19572+
}
19573+
},
19574+
"/v1/repos/{owner}/{repo}/gate-precision": {
19575+
"get": {
19576+
"summary": "Per-gate-type false-positive precision report for a repo (#554)",
19577+
"parameters": [
19578+
{
19579+
"schema": {
19580+
"type": "string"
19581+
},
19582+
"required": true,
19583+
"name": "owner",
19584+
"in": "path"
19585+
},
19586+
{
19587+
"schema": {
19588+
"type": "string"
19589+
},
19590+
"required": true,
19591+
"name": "repo",
19592+
"in": "path"
19593+
},
19594+
{
19595+
"schema": {
19596+
"type": "integer",
19597+
"minimum": 0,
19598+
"exclusiveMinimum": true
19599+
},
19600+
"required": false,
19601+
"name": "windowDays",
19602+
"in": "query"
19603+
}
19604+
],
19605+
"responses": {
19606+
"200": {
19607+
"description": "Read-only per-gate-type precision measurement — blocked / blocked-then-merged / overridden counts and false-positive rates with low-sample guards; never adjusts a gate (mirrors loopover_get_gate_precision)",
19608+
"content": {
19609+
"application/json": {
19610+
"schema": {
19611+
"$ref": "#/components/schemas/GatePrecisionResponse"
19612+
}
19613+
}
19614+
}
19615+
},
19616+
"401": {
19617+
"description": "Missing or invalid credential"
19618+
},
19619+
"403": {
19620+
"description": "Caller is not a maintainer of this repo"
19621+
}
19622+
},
19623+
"security": [
19624+
{
19625+
"LoopOverBearer": []
19626+
},
19627+
{
19628+
"LoopOverSessionCookie": []
19629+
}
19630+
]
19631+
}
19632+
},
19633+
"/v1/repos/{owner}/{repo}/outcome-calibration": {
19634+
"get": {
19635+
"summary": "Slop-band and recommendation outcome calibration for a repo (#543)",
19636+
"parameters": [
19637+
{
19638+
"schema": {
19639+
"type": "string"
19640+
},
19641+
"required": true,
19642+
"name": "owner",
19643+
"in": "path"
19644+
},
19645+
{
19646+
"schema": {
19647+
"type": "string"
19648+
},
19649+
"required": true,
19650+
"name": "repo",
19651+
"in": "path"
19652+
},
19653+
{
19654+
"schema": {
19655+
"type": "integer",
19656+
"minimum": 0,
19657+
"exclusiveMinimum": true
19658+
},
19659+
"required": false,
19660+
"name": "windowDays",
19661+
"in": "query"
19662+
}
19663+
],
19664+
"responses": {
19665+
"200": {
19666+
"description": "Read-only measurement of whether higher slop bands merge less often and how agent recommendations are panning out over the optional window (mirrors loopover_get_outcome_calibration)",
19667+
"content": {
19668+
"application/json": {
19669+
"schema": {
19670+
"$ref": "#/components/schemas/OutcomeCalibrationResponse"
19671+
}
19672+
}
19673+
}
19674+
},
19675+
"401": {
19676+
"description": "Missing or invalid credential"
19677+
},
19678+
"403": {
19679+
"description": "Caller is not a maintainer of this repo"
19680+
}
19681+
},
19682+
"security": [
19683+
{
19684+
"LoopOverBearer": []
19685+
},
19686+
{
19687+
"LoopOverSessionCookie": []
19688+
}
19689+
]
19690+
}
19691+
},
19692+
"/v1/repos/{owner}/{repo}/activation-preview": {
19693+
"get": {
19694+
"summary": "Maintainer activation preview over recent PRs for a repo (#701)",
19695+
"parameters": [
19696+
{
19697+
"schema": {
19698+
"type": "string"
19699+
},
19700+
"required": true,
19701+
"name": "owner",
19702+
"in": "path"
19703+
},
19704+
{
19705+
"schema": {
19706+
"type": "string"
19707+
},
19708+
"required": true,
19709+
"name": "repo",
19710+
"in": "path"
19711+
}
19712+
],
19713+
"responses": {
19714+
"200": {
19715+
"description": "Deterministic \"here's what LoopOver would have surfaced\" preview — evaluated/with-findings counts, distinct finding codes, per-PR samples, current review-check mode, and the single recommended next action (mirrors loopover_get_activation_preview)",
19716+
"content": {
19717+
"application/json": {
19718+
"schema": {
19719+
"$ref": "#/components/schemas/ActivationPreviewResponse"
19720+
}
19721+
}
19722+
}
19723+
},
19724+
"401": {
19725+
"description": "Missing or invalid credential"
19726+
},
19727+
"403": {
19728+
"description": "Caller is not a maintainer of this repo"
19729+
}
19730+
},
19731+
"security": [
19732+
{
19733+
"LoopOverBearer": []
19734+
},
19735+
{
19736+
"LoopOverSessionCookie": []
19737+
}
19738+
]
19739+
}
1937319740
}
1937419741
},
1937519742
"servers": [

0 commit comments

Comments
 (0)