go-openapi-spec-vs-mcp-tool-surface-drift-guard
No repo was present on this host, so I reconstructed the guard and verified it end-to-end in a minimal Go reproduction. The solution is saved at ~/solution.md.
Root cause: Tool names (ask_agent) and spec operationIds (askAgent) are disjoint vocabularies by design, so any name-equality drift test is permanently red — it flags the intentional naming boundary, not drift. The correct oracle is an explicit accountability ledger of reviewed coverage.
Fix: A test-only in-package guard (server/drift_guard_test.go) that calls toolDefinitions() and checks four things against a toolCoverage map and an excludedOperations map:
- (a) every advertised tool has an entry
- (b) every entry is advertised
- (c) every referenced operationId exists in the spec
- (d) every spec operationId is covered or excluded
Verified results:
| Check | Result |
|---|---|
Baseline go vet + go test |
PASS |
Rename tool def ask_agent→ask_agent_v2 |
FAIL — names both the uncovered new tool and the stale ledger entry |
Rename spec op askAgent→askAgentV2 |
FAIL — names the dangling reference and the uncovered new op |
| Restore both (sha256 byte-identical) | PASS |
| Rename a dispatch key only | PASS (boundary confirmed: dispatch set is out of scope) |
Toolchain: go1.26.0, gopkg.in/yaml.v3 v3.0.1.
The full, directly usable markdown — including the complete drift_guard_test.go source, integration notes for the real server package, and the captured failure transcripts — is in ~/solution.md. Key ledger shape:
var toolCoverage = map[string][]string{
"ask_agent": {"askAgent"},
"inbox_list": {"inboxList"},
"inbox_ack": {"inboxAck"},
"status_report": {"statusReport"},
}
var excludedOperations = map[string]string{
"healthCheck": "internal liveness probe for the orchestrator; not part of the MCP client surface",
}
Reproduction workspace: /tmp/driftdemo (go test ./... green at HEAD).
# Evidence - Problem class: go-openapi-spec-vs-mcp-tool-surface-drift-guard - Model: openrouter/deepseek/deepseek-v4.1-flash - Solved: 2026-09-25T18:20:25.093Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "Guarding a curated MCP bridge against its OpenAPI spec: tool vocabulary (snake_case verbs like ask_agent) and spec operationId vocabulary (camelCase like inboxDeliver) are DISJOINT by design, so a name-equality drift test is red at HEAD forever. Working guard = accountability ledger: explicit toolCoverage map (tool -> operationId(s) its handler exercises, verified against the code path) plus excludedOperations map (deliberately unexposed spec ops, one grounded justification each). Four assertions: (a) every advertised tool has a table entry, (b) every table entry is advertised, (c) every referenced operationId exists in the spec, (d) every spec operationId is either covered or explicitly excluded - new/renamed/removed tool OR operation fails loudly with named entries. Parse spec with gopkg.in/yaml.v3; in-package test calling server toolDefinitions() directly. Non-vacuity: rename one tool def in the defs source AND one operationId in the spec - both FAIL then pass restored (sha256-verify restore). Boundary: guard covers the ADVERTISED surface (toolDefinitions), not the dispatch-key registration set.", "environment": "", "language": "", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "go-openapi-spec-vs-mcp-tool-surface-drift-guard", "provider": "openrouter", "solved_at": "2026-09-25T18:20:25.093Z", "version": ""}No repo was present on this host, so I reconstructed the guard and verified it end-to-end in a minimal Go reproduction. The solution is saved at ~/solution.md.
Root cause: Tool names (ask_agent) and spec operationIds (askAgent) are disjoint vocabularies by design, so any name-equality drift test is permanently red — it flags the intentional naming boundary, not drift. The correct oracle is an explicit accountability ledger of reviewed coverage.
Fix: A test-only in-package guard (server/drift_guard_test.go) that calls toolDefinitions() and checks four things against a toolCoverage map and an excludedOperations map:
- (a) every advertised tool has an entry
- (b) every entry is advertised
- (c) every referenced operationId exists in the spec
- (d) every spec operationId is covered or excluded
Verified results:
| Check | Result |
|---|---|
Baseline go vet + go test |
PASS |
Rename tool def ask_agent→ask_agent_v2 |
FAIL — names both the uncovered new tool and the stale ledger entry |
Rename spec op askAgent→askAgentV2 |
FAIL — names the dangling reference and the uncovered new op |
| Restore both (sha256 byte-identical) | PASS |
| Rename a dispatch key only | PASS (boundary confirmed: dispatch set is out of scope) |
Toolchain: go1.26.0, gopkg.in/yaml.v3 v3.0.1.
The full, directly usable markdown — including the complete drift_guard_test.go source, integration notes for the real server package, and the captured failure transcripts — is in ~/solution.md. Key ledger shape:
var toolCoverage = map[string][]string{
"ask_agent": {"askAgent"},
"inbox_list": {"inboxList"},
"inbox_ack": {"inboxAck"},
"status_report": {"statusReport"},
}
var excludedOperations = map[string]string{
"healthCheck": "internal liveness probe for the orchestrator; not part of the MCP client surface",
}
Reproduction workspace: /tmp/driftdemo (go test ./... green at HEAD).
# Evidence - Problem class: go-openapi-spec-vs-mcp-tool-surface-drift-guard - Model: openrouter/deepseek/deepseek-v4.1-flash - Solved: 2026-09-25T18:20:25.093Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "Guarding a curated MCP bridge against its OpenAPI spec: tool vocabulary (snake_case verbs like ask_agent) and spec operationId vocabulary (camelCase like inboxDeliver) are DISJOINT by design, so a name-equality drift test is red at HEAD forever. Working guard = accountability ledger: explicit toolCoverage map (tool -> operationId(s) its handler exercises, verified against the code path) plus excludedOperations map (deliberately unexposed spec ops, one grounded justification each). Four assertions: (a) every advertised tool has a table entry, (b) every table entry is advertised, (c) every referenced operationId exists in the spec, (d) every spec operationId is either covered or explicitly excluded - new/renamed/removed tool OR operation fails loudly with named entries. Parse spec with gopkg.in/yaml.v3; in-package test calling server toolDefinitions() directly. Non-vacuity: rename one tool def in the defs source AND one operationId in the spec - both FAIL then pass restored (sha256-verify restore). Boundary: guard covers the ADVERTISED surface (toolDefinitions), not the dispatch-key registration set.", "environment": "", "language": "", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "go-openapi-spec-vs-mcp-tool-surface-drift-guard", "provider": "openrouter", "solved_at": "2026-09-25T18:20:25.093Z", "version": ""}