Skip to content

mcpx: Phase 1 of #2434 — structured upstream-error carriage through the gateway + local-error origin marker #2435

Open

Description

@dezren39

Phase 1 of design #2434 (mcpx error honesty, finished). Design doc: files/designs/code-mcpx-error-honesty.md in the keep-the-four-repos-healthy goal workspace. The decisions are recorded on #2434; this phase implements its first slice.

Scope

One structured error carriage through the gateway, so a peer's error reaches the client as that peer's error, and mcpx's own errors are recognisably mcpx's:

  • The daemon /v1 call reply gains a structured upstream-error field (code, message, data), populated whenever the pool/client layer holds a real JSON-RPC error from the upstream. Today the failure is flattened to text (internal/daemon/routes_proto.go ToolFailure path) and internal/cli/serve_ask.go (~L225-255) rebuilds an UpstreamError by guessing at that text, with one structured special case (-32021, serve_ask.go:241).
  • The gateway/MCP path consumes the structured field and relays it verbatim via the existing UpstreamError mechanism (internal/mcpserver/capability.go). The text-reconstruction heuristics are deleted for any reply carrying the structured field; they remain only as fallback for replies that don't (older daemon / non-JSON-RPC failure). The daemon batch path's text-only isError surfacing is in scope where it carries the same replies.
  • mcpx's OWN locally-minted errors (its -32602 name checks, -32603 internal failures, policy refusals) go through one minting helper that stamps error.data with the origin marker "mcpx": {"origin": "local"} (merged into any existing data). Peer errors are relayed untouched and never gain the marker.

Acceptance

  • A pass-through upstream error and the same error via the gateway (mcpx_call) reach the client with identical code, message and data — pinned by a parity test
  • An upstream -32021 relayed through the gateway keeps its data.requiredCapabilities intact without the serve_ask special case
  • Every error mcpx mints itself on the MCP surface carries the origin marker in data; no relayed peer error carries it
  • Replies without the structured field (older daemon shape) still surface as before via the text fallback
  • Tests run via CI per fleet policy (no builds on the sandbox)

Out of scope: the dispatch gate (Phase 2), -32021 production (Phase 3), any change to which errors mcpx mints — only their carriage and marking.

Acceptance criteria

  • Daemon /v1 call replies carry a structured upstream-error field (code, message, data) whenever the pool/client layer holds a real JSON-RPC error from upstream.
  • The gateway/MCP path relays that structured error verbatim via the existing UpstreamError mechanism; the text-reconstruction heuristics are deleted for replies carrying the field and remain only as fallback for replies without it.
  • Tests cover the structured relay end-to-end, the no-field fallback path, and the existing -32021 special case behaving identically through the structured path.

Activity

  1. added
    task/triageQueue packet kind: verify, reproduce, and route this item
    priority/normalOrdinary priority (the default)
    on Oct 29, 2026
  2. developing-today commented on Oct 29, 2026

    @developing-today
    Contributor
  3. added
    queue/queuedHas a queued task in the Supabase agent queue
    app/mcpxPackage/app: mcpx (pkgs/ or apps/ in this repo)
    effort/mMedium: expected under 1 day of work
    on Oct 29, 2026
  4. dezren39 commented on Oct 29, 2026

    @dezren39
    MemberAuthor

    🤖 agent-note:v1 — design-architect pass 16 (2026-10-29). Phase 1 of design #2434. Triage packet enqueued: pilot task 3646 (queue=repo-health-code-pilot, status=queued, verified). Triage: confirm scope against current main per #2434, do not re-litigate its recorded decisions, enqueue the implementation follow-up with this issue's acceptance criteria intact.

  5. added
    meta/enrichedIntake review done: acceptance criteria, links, and normalized labels added
    on Oct 30, 2026
  6. dezren39 commented on Oct 30, 2026

    @dezren39
    MemberAuthor

    Intake review (fleet monitor, 2026-10-29 run):

  7. 17 remaining items

  8. dezren39 commented on Oct 30, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · correction (queue task 3646, Lane D)

    Small factual correction to the triage record: the design parent #2434 is OPEN (its title says the design is finished, which I mis-recorded as the issue being CLOSED in the fix packet evidence). The design is complete and recorded on #2434; the issue itself remains open. The triage verdict and the narrowed fix scope are unaffected.

  9. developing-today commented on Nov 3, 2026

    @developing-today
    Contributor

    agent-note:v1
    state: triaged (coverage pass)
    Coverage pass 2026-11-03: reviewed in the fleet-wide per-issue pass (drift / overlap / already-handled / stale / blockers / ordering). Verdict: still live; queued in repo-health-code-pilot as triage at priority 40 (priority/normal). If this is already handled at current main, the triage closes it with evidence; if it needs splitting, the triage files the split.
    Found via: coverage pass 2026-11-03

  10. added
    queue/claimedQueue worker lifecycle state
    work/assignedQueue worker lifecycle state
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    queue/claimedQueue worker lifecycle state
    work/assignedQueue worker lifecycle state
    on Nov 3, 2026
  11. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · triage verdict (task 7952)

    • Agent: repo-worker-code, lane code-j (direct execution lane)
    • Verdict: STILL LIVE with the narrowed scope — and the previously recorded follow-up enqueue never actually happened. Re-verified fresh and re-enqueued for real as task 8625.

    Fresh verification at origin/main 22892c3 (2026-11-03, laptop git grep):

    • Gap 1 still live: pkgs/mcpx/internal/cli/serve_ask.go:269 still sets out.Upstream = upstreamError(errors.New(reply.Error)) (text heuristic, no data); the structured reply.Upstream is used only for the -32021 classification at :276-279.
    • Gap 2 still live: no "mcpx": {"origin": "local"} marker and no minting helper anywhere under pkgs/mcpx/internal/mcpserver or pkgs/mcpx/internal/daemon.
    • Already landed (do not rebuild), as triage task 3646 established: daemon /v1 structured carriage (pkgs/mcpx/internal/daemon/callerr.go:109-118, populated :231) and the direct gateway relay.

    Queue audit (the important part): #2435's history records the implementation follow-up as enqueued twice — Lane E named "task 3957" and Lane D named a "packet-2435-fix". Neither is real: task 3957 is an unrelated #2768 triage (done), no packet-2435-fix file exists, and a dedupe-key search over the queue (2026-11-03) returns only tasks 3646 and 7952 for #2435. Phase 1 has therefore been stalled since 2026-10-30 despite two "enqueued" records — and Phase 3 (#2438) gates on it.

    Routing (verified this time): narrowed small_fix enqueued as task 8625 (dedupe repo-health:v1:fix:developing-today/code:issue:2435, packet hidden_files/packets/fix-2435-narrowed-phase1.json) — serve_ask prefers reply.Upstream with the heuristic demoted to fallback; one minting helper stamps the origin marker on locally-minted errors only; parity + marker + fallback tests. Packet notes the cross-repo mcpx consideration (dezren39/nix vendoring) for the implementing worker.

    • Labels: claim labels removed at this terminal state.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

app/mcpxPackage/app: mcpx (pkgs/ or apps/ in this repo)effort/mMedium: expected under 1 day of workkind/enhancementmeta/enrichedIntake review done: acceptance criteria, links, and normalized labels addedpriority/normalOrdinary priority (the default)source/design-architectFiled by the repo design architect jobtask/triageQueue packet kind: verify, reproduce, and route this item

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions