docs(design): m-mcp-exact-tool-surface Lane B — embeddable session-owned protocol surface (#498) - #582
Merged
Conversation
…ned protocol surface (#498) Lane B of #498, filed by the Ailang World mission and its sole clause-6 external blocker. Adds a narrow public `serveapi` package exporting AILANG's MCP-HTTP and A2A handlers behind host-owned callbacks: caller-owned mux, principal/session resolved BEFORE discovery and invocation, caller-supplied exact descriptors, MCP tools and A2A skills projected from ONE set, and no built-in tool unless the caller supplies it. AILANG stays the protocol owner; the host owns session, capability and state. Standalone CLI defaults are structurally unchanged (cmd/ailang stays on apiserver.New/Server.Start). Central premise, controller-verified: the MCP Go SDK already hands AILANG a per-request `getServer(*http.Request)` callback, which mcp.go:303 currently calls while discarding the request. Requirements 2-3 therefore need no new transport work. Quorum: designer codex:gpt-5.6-sol; reviewers gpt5-6-sol + gemini-3-1-pro, both present in both rounds (no N-1 degrade). R1 BLOCKED x2 -> revision. R2 BLOCKED x2 -> narrow-refinement carve-out (both objections carried concrete reviewer-authored fixes and neither disputed the design direction); reviewers' verbatim fixes applied and recorded in the doc's Quorum Verification Log. Metered $0.1910. Two reviewer claims were MEASURED by the controller rather than forwarded: - SSE breakage from per-request servers: REFUTED on this path. Stateless mode answers GET/DELETE with 405 Allow: POST, so no cross-request stream exists. The real adjacent landmine it surfaced is closed: Stateless:true is frozen, stateful/resumable MCP is an explicit non-goal, and acceptance asserts GET=>405. - A2A timeout wire format: a2a.go:304 already writes HTTP 200 with a JSON-RPC envelope, so the design's mandate preserves the surface rather than corrupting it (V27); -32603 is new to the file, with a known-positive control (V28). Co-Authored-By: codex <gpt-5.6-sol>
|
sunholo-voight-kampff
deleted the
sprint/m-mcp-exact-tool-surface-lane-b
branch
August 4, 2026 02:17
sunholo-voight-kampff
pushed a commit
that referenced
this pull request
Aug 4, 2026
…uorum-cleared STATUS stamp for iteration 137, iter-134 rotated to the archive (invariant asserted: 1731 -> 1731, 3 stamps, queue rows control-checked post-edit), log entry 142, and the Lane B queue row retagged DOC LANDED + QUORUM-CLEARED with "route to sprint-planner" as its next step. Iteration 137 landed PR #582 (squash 2629ad8, dev CI green SHA-addressed: 20 checks, 0 non-success, plus per-workflow confirm) and closed iteration 136's owed evaluator gap (sonnet PASS 84/100 r1, zero blocking, 5/5 mutations caught, follow-ups filed as #581). Notable: the STATUS rotation itself failed destructively on first attempt because zsh arrays are 1-indexed -- ${S[2]} selected iteration 135 as "oldest" and ${S[0]} was empty. The iter-127 line-count assertion caught it, both files were restored from git and re-verified, and the rotation was redone without any array indexing. Same zsh family as the ${PIPESTATUS[0]} lesson already recorded.
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.



Design doc for Lane B of #498, filed by the Ailang World mission and recorded as its sole clause-6 external blocker (
w-mcp-projectionis BLOCKED on it). Docs-only — no code changes.What it designs
A narrow public
github.com/sunholo-data/ailang/serveapipackage exporting AILANG's existing MCP-HTTP and A2A serving machinery behind host-owned callbacks, covering all seven of #498's requested behaviours: caller-owned mux, principal/session resolved before discovery and invocation, caller-supplied exact descriptors, invocation returned with the same resolved session, MCP tools and A2A skills projected from one descriptor set, no built-in tool unless the caller supplies it, and upstream MCP/A2A conformance + SSE framing preserved.AILANG stays the protocol owner; the host keeps session, capability and state. No World persistence, store, or scheduler comes upstream. The standalone CLI's defaults are unchanged structurally —
cmd/ailangstays onapiserver.New/Server.Startrather than depending on callback defaults.The premise that shrank the work
The MCP Go SDK already hands AILANG a per-request server-selection callback, and
internal/apiserver/mcp.go:303calls it while discarding the request:So requirements 2–3 are supported by the dependency already in use — this is a wiring and authority problem, not a transport problem.
Quorum
Designer
codex:gpt-5.6-sol. Reviewersgpt5-6-sol+gemini-3-1-pro, both present in both rounds (no N−1 degrade). Metered $0.1910.proposed_fixand neither disputed the design direction, so the reviewers' verbatim fixes were applied and recorded in the doc's Quorum Verification Log. Not a force-pass; no contested direction overridden.Two reviewer claims were measured rather than forwarded (the controller runs the check instead of buying another round):
Statelessmode the SDK answers GET/DELETE with 405Allow: POST, so there is no long-lived stream to correlate, andgetServer(req)is called per POST. But the reviewer surfaced a genuine adjacent landmine, now closed:Stateless: trueis a frozen requirement, stateful/resumable MCP is an explicit non-goal with the empty-registry failure mode written out, a Conflict Surface row forces any future stateful change to revisit the decision, and acceptance asserts GET⇒405.a2a.go:304isw.WriteHeader(http.StatusOK) // JSON-RPC always returns 200.and all existing task errors are JSON-RPC codes — so the design's mandate preserves the surface (V27).-32603is new to the file, recorded with a known-positive control so the zero is a measurement (V28).Bounded waits and bounded concurrency
R2's other catch was sharp: a deadline bounds the wait, not the resource. A context-ignoring callback still leaks a goroutine per request. Applied verbatim:
Config.MaxConcurrentCallbacks, a capacity token held until the goroutine actually exits, a frozen overload envelope on exhaustion, and the plain statement that in-process Go callbacks cannot be forcibly terminated — so the guarantee is narrowed to bounded latency and bounded callback starts, never enforced completion. The test is discriminating in both directions.Notes
make check-boundariesandmake check-file-sizes(server.gois 764/800 — the design adds nothing to it).**Planner-Lane**: opus-required;derive-planner-lane.shreturnsopus declared:opus-required, exercising the iteration-136 lane end-to-end on a brand-new doc.🤖 Generated with Claude Code