fix(openapi): one endpoint documented twice disabled the contract gate - #62
Merged
LMPrado-DZ23 merged 2 commits intoSep 20, 2026
Merged
Conversation
The [3.8.55] section stopped at #47 while eight more PRs landed. A release note written at tag time from memory is how work goes unrecorded, so this catches the section up while the PRs are still fresh: #48 contract tests — governance debt 150 → 53 untested routes #50 Add API Key links to the page that issues the key #51 phantom operations zeroed; the policy CLI stops overclaiming #52 workspace → project → API key hierarchy with rolled-up budgets #55 dark theme meets AA without repainting the brand #57 11 more CLIs pointable at the gateway (catalog 36 → 47) #58 the key URL moved to the field the product actually reads #59 the new-code gates run on Windows again Mirrored into the 41 localized changelogs by `scripts/release/sync-changelog-i18n.mjs`. [changelog-integrity] OK — no base bullets lost [doc-links] PASS — 172 docs, 1044 internal links prettier --check CHANGELOG.md — clean Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
docs/openapi.yaml carried both spellings of the same two endpoints:
/api/tools/agent-bridge/agents/{agentId}/dns hand-written, full schemas
/api/tools/agent-bridge/agents/{id}/dns generated stub
…and the same pair for /mappings
OpenAPI 3.x is explicit that templated paths differing only in the variable
name are the same endpoint and must not coexist. The consequence was not
cosmetic: oasdiff refuses the whole document with
Error: diff failed: duplicate endpoint
(GET /api/tools/agent-bridge/agents/{id}/mappings)
so check:openapi-breaking could not diff anything and fell through to its
graceful skip. The gate meant to catch contract regressions has been
reporting a green that measured nothing.
Merged into the route's real parameter name — the folder is `[id]` — keeping
the hand-written schemas and carrying over the `x-loopback-only: true` the
stubs were holding for check-openapi-security-tiers. Spec paths 720 → 718,
operations 1048 → 1045; the three removed are the stub duplicates, and every
operation is still documented under the surviving path.
check-openapi-routes was blind to this by construction: it compares
param-insensitively, so both spellings matched the one real route and both
passed. It now reports paths that collapse to the same endpoint — proven red
on the spec before the fix.
[openapi-routes] 2 endpoint(s) documentado(s) mais de uma vez exit=1
[openapi-routes] OK — 718 paths na spec, todos com rota real (after)
[openapi-security-tiers] PASS [openapi-coverage] PASS 100.0% (718/718)
[api-governance] PASS — 718 routes, 1045 operations
tests 3 / pass 3 / fail 0
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Found while reading why #53's Fast Quality Gates run was red. It is not #53's defect — it is on the base, and it has been quietly costing us the contract gate.
The defect
docs/openapi.yamlcarried both spellings of the same two endpoints:/api/tools/agent-bridge/agents/{agentId}/dns/api/tools/agent-bridge/agents/{id}/dnssummary: "POST tools › agent bridge › agents › <id> › dns",200 OK, nothing else…and the same pair for
/mappings. The generator emitted stubs for routes that were already documented by hand, because it matched the folder name[id]while the hand-written entries used{agentId}.OpenAPI 3.x is explicit: templated paths differing only in the variable name are the same endpoint and must not coexist. The document was invalid.
Why it matters
The consequence is not cosmetic.
oasdiffrefuses the whole document:check:openapi-breakingcannot diff anything, so it falls through to its graceful skip and exits 0. The gate meant to catch contract regressions has been reporting a green that measured nothing — on every PR, not just this one.The fix
Merged into the route's real parameter name (the folder is
[id]), keeping the hand-written schemas and carrying over thex-loopback-only: truethe stubs were holding —check-openapi-security-tiersrequires it on these prefixes, so dropping the stubs without it would have traded one silent hole for another.Spec paths 720 → 718, operations 1048 → 1045. The three removed are the stub duplicates; every operation is still documented, under the surviving path.
Keeping it fixed
check-openapi-routeswas blind to this by construction: it compares param-insensitively, so both spellings matched the one real route and both passed. That is the right comparison for its own job, so the detector is additive — it now also reports paths that collapse to the same endpoint.Proven red on the spec before the fix:
tests/unit/openapi-duplicate-templated-paths.test.tscovers the detector on a synthetic collision, checks that genuinely distinct paths are not flagged (a false positive here would make the gate unusable), and pins the shipped spec.Gates
check:openapi-routescheck:openapi-security-tierscheck:openapi-coveragecheck:api-governancetests/unit/openapi-duplicate-templated-paths.test.tsprettier --checkdocs/openapi.yamlis not prettier-clean on the base either, so it is left as it is rather than reformatted in a fix PR.Note for whoever reads the breaking-change baseline next:
metrics.openapiBreakinginconfig/quality/quality-baseline.jsonwas frozen while the gate could not run. Once oasdiff diffs a valid document again, that number should be re-measured rather than trusted.🤖 Generated with Claude Code