specgen learns MCP: a third transport dialect, with a locked tool surface #337
No reviewers
Labels
No labels
burndown-2026-06
burndown-2026-08
sunday-sprint
autonomy
async-consult
autonomy
epic
autonomy
headless
autonomy
live-collab
coherence-core
priority
P0
priority
P1
priority
P2
priority
P3
priority
P4
qa-fixture
role/advocate
role/director
role/exec
role/frontend
role/gamedev
role/human
role/platform
role/qa
role/science
role/sysadmin
state
ambient
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
coilyco-flight-deck/umbra!337
Loading…
Reference in a new issue
No description provided.
Delete branch "mcp-dialect"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Implements coilyco-flight-deck/umbra#336: specgen learns MCP as a third transport dialect.
Landed as a pull request rather than straight to
main(the repo'smerge-remote-mainlane) because the direct push tomainwas refused by the harness permission layer, not by policy. The branch is the only thing carrying the work until this merges.What this is
MCP is a third transport at a seam that already existed, not a new subsystem.
codegen.Transportwasspec | exec; it is nowspec | exec | mcp.sniffTransportgains a third answer,membera third guardfile, and the generatedmain.goamountMCParm.The design and its reasoning are on the issue. What changed while building it is at the bottom.
Why this beats wrapping an MCP client
Every guard umbra has sits above transport.
opcore.Operation.Executegrows a third branch, next to thesqlgrant and the raw response: an mcp leaf leaves before the HTTP floor and rejoins atcheckResponse. Sorestrict,fail-when, the destructive marking, the audit row, and the exit-code taxonomy all bind to atools/callunchanged, because none of them ever touched HTTP.mcporter callhas no policy, no audit row, no postcondition, and no deny-by-absence.The lock is the headline
specgen lockconnects, runstools/list, prunes to the granted tools, and freezes them through the same gzip encoder the spec dialect uses.specgen skewprunes live upstream the same way and diffs, exit 3 on drift.Nothing else locks MCP tool schemas. A client can print today's schema; only a lock can say it moved.
_metais part of the compared value, so an MCP Apps widget address that silently repoints is drift rather than a swap nobody sees. That closes the gate coilysiren/inbox#505 named.Commits
feat(mcpclient)- the client, inpkg/because it expresses no permission. A stdio spawn passespkg/policy's argv gate: it does not get a weaker check for arriving through the request surface.feat(mcpverb)- the dialect, the guards, and theExecutebranch.feat(specgen)- the driver,lock, andskew.docs(mcpverb)-docs/mcpverb.md, the trifecta updates, and a runnable example.style(mcpverb)- held to the repo's 2-line comment cap.Two decisions that changed against the issue
mcp/, on the reasoning thathttp/mcpverbwould have to reach intocli/execverbto spawn a stdio child. Readingpkg/policyshowed the spawn needs core, notcli/, so the cross-surface import never arises and umbra stays two surfaces.docs/architecture.mdstates the wrinkle rather than leaving it to be found.Verification
go build,go vet,go test ./...,golangci-lint run ./..., andpre-commit run --all-filesall pass.Tests run against a real MCP server over HTTP rather than a mock, so the protocol, flag binding, guards, and drift detection are exercised end to end.
TestLockAndSkew_MCPMemberlocks a live server, asserts a clean skew, moves the server's schema mid-test, and assertsErrSkew.One unrelated fix carried along
_typos.tomllearnsser8. That hook fails onmaintoday, before this branch: typos reads theserinside the real hostname as a misspeltset. Fixed here because this change has to pass the same gate.Not in scope, per the issue
The keep-alive daemon (waiting on a cold-start measurement), the OAuth browser flow, editor config import,
serve, andemit-ts.brew uninstall mcporteris not the end of this phase.