Test that /mcp authenticates through the production router; close the re-wrap gap in main.go #154
Closed
opened 2026-10-03 14:35:26 +00:00 by mathias
·
3 comments
No Branch/Tag Specified
main
fix/pipeline-writes-158
fix/edit-path-io-192
fix/create-regular-188
fix/guard-special-179
fix/linkcheck-keeps-write-178
fix/write-dir-redirect-173
fix/tunnel-detect-174
fix/pipeline-root-157
w3/154-mcp-auth-wiring
fix/tunnel-traversal
test/in-brain-targets-171
fix/brain-scan-root-157
fix/graph-wiki-root-157
fix/vectorstore-root-157
fix/notes-root-157
fix/search-root-157
fix/brainwide-root-157
fix/raw-symlinks-153
feat/symlink-tripwire-157
fix/rest-auth-149
fix/123-brain-edit-envelope-check
feat/106-page-aware-extraction
fix/105-source-drift-on-main
fix/104-surface-merge-conflicts-on-main
agent/b1-compile-on-ingest
agent/104-surface-merge-conflicts
agent/105-source-drift
agent/107-loud-unconfigured-alerting
feat/brain-read-edit
fix/capture-i1-refusal-names-target
renovate/configure
feat/consolidate-single-harness
icebox/cmd-routing
feat/brain-pending-promote
fix/close-session-classification-refresh
fix/capture-summarywriter
v0.24.0
v0.23.1
v0.23.0
v0.22.0
v0.21.1
v0.21.0
v0.20.1
v0.20.0
v0.19.1
v0.19.0
v0.18.4
v0.18.3
v0.18.2
v0.18.1
v0.18.0
v0.17.0
v0.16.1
v0.16.0
v0.15.0
v0.14.0
v0.13.2
v0.13.1
v0.13.0
v0.12.1
v0.12.0
v0.11.2
icebox/cmd-routing-2026-07-01
v0.11.1
v0.11.0
v0.10.0
v0.9.0
v0.8.0
v0.7.0
v0.6.0
v0.5.0
v0.4.1
v0.4.0
v0.3.0
v0.2.0
v0.1.0
Labels
Clear labels
agent/ready
blocked/client
blocked/supplier
blocked/upstream
risk/high
risk/low
risk/medium
size/l
size/m
size/s
size/xs
status:dispatch
status:dispatched
status:review
status:reviewing
type/chore
type/decision
type/docs
type/feat
type/fix
type/ops
type/research
type/test
Meets the agent-ready contract; authorizes unattended execution
Waiting on the client
Waiting on a supplier
Waiting on an upstream project or vendor
Irreversible, security-relevant, or control plane
Reversible, local, test-covered
Touches shared state, deploys or data
Too big - split it
Under two days
Under half a day
Under an hour
Maintenance, no behaviour change
Human decision required; never agent/ready
Documentation only
New capability
Corrects broken behaviour
Infrastructure, deploy, runtime
Investigate; output is a finding, not code
Test coverage only
Milestone
No items
No Milestone
Projects
Clear projects
No projects
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: mathias/hyperguild#154
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Follow-up from the PR #152 round-2 review, 2026-10-03.
/mcpauth is untested in the production wiring.publicRoutessays each public route "authenticates itself", but the bearer check on/mcpis built inmain.goand the buildMux tests use stubs. This predates #152. Move the/mcphandler construction into a tested function, or build/mcp's bearer inside buildMux the same way the REST auth is, and assert that/mcpwith no token gets 401 through that path.buildMuxreturns anhttp.Handler, so nothing can add routes to its result. But main.go could still wrap that result in a new mux with a publicPOST /querybetweenbuildMuxandListenAndServe, and CI would stay green. One untested line of wiring remains. Either accept it and make the comments inroutes_test.go/main.goclaim only that, or move theListenAndServehandler construction into a tested function.Done when both are tested or the comments are narrowed, with a flip test showing the gap is covered.
Created via git-mcp on behalf of @mathias
Same class, added from the PR #159 review: the symlink tripwire's wiring in
ingestion/cmd/server/main.go(startupSymlinkCheck(brainDir)before any reader starts, andgo symlinkguard.Watch(...)) isn't test-covered. Removing both calls keeps the suite green. Covering it belongs with this issue's fix: move server assembly into a tested function, or assert the startup order.Created via git-mcp on behalf of @mathias
pr-gatekeeper verdict: BLOCK (PR #183, commit
a1e0361only, closes #154)Mode: PR mode. Scope: commit
a1e0361, diffed against474473c. #181 is reviewed separately and is still unmerged.Blocking findings
The code change is correct. The block is on the comments. Part 2 of #154 is closed by narrowing the comments (the "or the comments are narrowed" clause), and the narrowed comments are still wrong, so that done-when clause is not met.
ingestion/cmd/server/main.go:588-591says ListenAndServe "must serve its result unchanged: that one line is the untested part".routes.go:44says the same thing ("What stays untested is main's own line"), and so does #182. That is not the only untested line. All of main'sbuildMux(restAuth{...}, ..., public)call is untested. Checked by running it: I changed main.go'svalidator: jwtValidatortovalidator: nil, andgo vetandgo test ./cmd/server/both exit 0. That change drops JWT acceptance on both /mcp and REST, which breaks the claude.ai OAuth connector. Narrow the comment, or say what is actually untested: the restAuth fields and public map that main passes in, plus the ListenAndServe line. Update #182 to match.ingestion/cmd/server/routes_test.go:25-27: the testMux comment says it builds the router "exactly as main does ... and real bearer config". It passes no JWT validator and no resourceMetadataURL. Because of that, these mutations of /mcp's middleware inside buildMux leave the whole suite green:ingestion/cmd/server/routes_test.go:88-91: the TestBuildMuxDoesNotWrapPublicRoutes comment still lists "bearer on /mcp" and "/metrics" as public routes it covers. Neither is in publicRoutes after this commit, so the test no longer iterates them. The comment is stale.Recommended (not in #154's done-when, but it is the PR's own claim)
The PR says /mcp gets "the same BearerMiddleware and credential as REST". The code supports that: one shared
bearerclosure. The tests do not prove it. Only the static token is asserted on /mcp. Two cheap assertions would make the claim tested:resource_metadatain WWW-AuthenticateBoth failures I found go the fail-closed way (a broken connector, not an open door), so this is a recommendation, not a block.
What I verified by running it
captureappear in tools/list through the router: false before the call, true after. In main, buildMux now runs after WithCapture in any case.Flip tests (routes.go mutations,
go test ./cmd/server/exit code)CI
Run 9400, "CI / Lint / Test / Vet (pull_request)", passed on
a1e0361. CI was green, and none of the findings above are things it checks. Locally,go vetexits 0,golangci-lint run ./cmd/server/...exits 0, and the tests exit 0 with 25 passing.Not checked
474473c.pr-gatekeeper verdict: APPROVE (PR #183 re-review, head b04a348; closes #154)
Mode: PR mode. Scope:
6d44e9dandb04a348, diffed againste05a13a(#181's head). #181 is reviewed separately.git range-diffshows6d44e9dis the same patch asa1e0361. Only context lines from #181 changed.b04a348changes in routes.go. Comments only. So the router comparison from the last round still stands: the old and new wiring gave identical status, WWW-Authenticate, Location and body across 2940 cases. The check thatcaptureappears in tools/list after WithCapture on an already-wrapped server also still stands.Flip tests on
b04a348(go test ./cmd/server/exit code)The realm survivor doesn't block: realm is cosmetic in the challenge, and the credential is unaffected. The main.go survivor is now stated in the comments and tracked in #182.
Gate
go vetexits 0,golangci-lint run ./cmd/server/...exits 0, andgo testexits 0 with 28 passing and 0 failing.b04a348. It is green, but it is not what proved the points above.Not checked
Merge
Not merged. #181 is not yet on main. This should merge only after #181 lands, #183 is rebased onto main so the stacked diff is gone, and CI is green on the resulting head.