Repository navigation
feat(api-wiring): closest-route suggestions + surface removed endpoints hiding in the baseline (#12738) - #12893
Merged
Merged
Conversation
Contributor
✅ SSOT Configuration Compliance: Passing🎉 No hardcoded values detected that have SSOT config equivalents! |
3 tasks
…removed endpoints hiding in the baseline (#12738)
4 tasks
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.
Thinking Path
Gap 1 asked for a closest-match suggestion. The obvious implementation —
difflib.get_close_matchesover the OpenAPI path set — ranks by character overlap, which favours long unrelated routes over the short renamed sibling that is usually the right answer. So the scoring is segment-aware, and weighted toward agreement on the leading segments: a rename almost always changes the last segment and keeps the namespace.That weighting turned out to matter for a second reason. Running against static mode first produced suggestions like
/api/analytics/bug-prediction/cached→/voice/bug-prediction/cached, because static mode's route table combines every registry prefix with every route, so/voice/<x>and/ai-stack/<x>shadow the real/<x>. Positional agreement alone ranks those highly; leading agreement rejects them.Gap 2 needed a sharper definition than the issue's wording. "Baseline entries whose target is absent from the current OpenAPI" describes every entry — that is what being baselined means. The distinction that actually matters is whether a close surviving route exists: if it does, the endpoint was renamed and the call wants rewiring, not suppression. That plus two hygiene buckets (entries that now resolve, entries nobody calls any more) is what the baseline could never tell apart.
To check this against real data rather than static-mode heuristics I built the authoritative route table locally (
--dump-openapi, 2161 paths + 281 websocket). It confirmed the gap 2 hypothesis exactly: 32 of the 35 baselined calls point at endpoints that were renamed, not endpoints that were never built.What Changed
scripts/audit_api_wiring.pysuggest_routes()— segment-aware closest match, scored0.45 · positional + 0.35 · leading + 0.20 · difflib, floored so a weak match prints nothing rather than sending someone to rewire against the wrong route. Requires a shared concrete segment. Scores both the call and its/api-stripped variant, matching whatmatches()already does for static mode.audit_baseline()— classifies baseline entries intorematch(close surviving route → renamed, fix it),resolved(now matches a real route → prune) andabsent(no caller left → prune).BASELINE HEALTHsection reports the classification. The gate itself is unchanged — same exit codes, same failing set.scripts/api_wiring_baseline.txt— pruned the 3 entries the authoritative run proved were dead weight (2 resolved, 1 no longer called). Re-running after the prune reports0 resolved, 0 no-longer-calledand the same 5 gating findings, so the gate did not move.~/.claude/skills/api-wiring-audit/SKILL.md— documents the suggestion output and the three baseline-health classifications, including the warning to trust them only in authoritative mode.Verification
Authoritative run (route table built locally from this branch's source):
The browser endpoints moved under
/mcp/and the baseline absorbed every caller — dead buttons, gate green. That is exactly the escape route gap 2 predicted, now visible.Suggestion quality before/after the leading-segment weighting, on the same static-mode run: 90+ suggestions including nonsense like
/voice/bug-prediction/cached, down to 31 with the noise gone.Black and flake8 clean.
Scope note
Acceptance criterion 3 — rewiring the flagged callers — is not in this PR. It is 32 frontend call sites across composables and repositories, a different risk profile from tooling changes, and several need confirming that the target is genuinely the replacement rather than a same-named neighbour. Filed separately with the full evidence so it is not lost.
Closes #12738 (gaps 1 and 2, plus docs). Gap 3 (reconciling the two detectors) depends on #12853, which cannot be verified without the live instance.
Model Used
claude-opus-5