Skip to content

mcpx: initialize sends rootUri/workspaceFolders for scope-resolved instances #959

Closed

Description

@dezren39

Slice 3 of decision record 0004 (pkgs/mcpx/docs/decisions/0004-scope-resolved-roots.md, PR #957). Design source: dezren39/darwin-nix#819 — this issue carries its acceptance criteria. Depends on slice 1 (ResolvedScope plumbing).

What to build (spec §5)

  • mcpclient.Options gains the instance root; when non-empty, initialize for that instance includes rootUri (file:// URI of the root), workspaceFolders ([{uri, name = base name of root}]), and declares the workspace.workspaceFolders client capability true.
  • Both fields are sent for every era (legacy and modern) — initialize params are extensible and non-consuming servers ignore them. When the root is empty, initialize is byte-for-byte what it is today.

Acceptance criteria (from nix#819, verbatim intent)

  • For an instance with a scope-resolved root, the initialize request includes rootUri/workspaceFolders naming that root (demonstrated by a captured handshake or a test-double server recording initialize params).
  • Servers that don't negotiate workspace support initialize exactly as before.
  • global-scoped instances send no rootUri/workspaceFolders — no fabricated daemon-cwd root.
  • Tests cover: root present for repo/worktree scopes, absent for global scope.

(The live gopls go_package_api proof is slice 4's acceptance.)

Activity

  1. added
    kind/featureNew feature or capability request
    source/humanFiled directly by a human
    status/blockedQueue or user escalation state
    priority/normalOrdinary priority (the default)
    effort/sSmall: expected under 2 hours of work
    meta/enrichedIntake review done: acceptance criteria, links, and normalized labels added
    on Oct 26, 2026
  2. dezren39 commented on Oct 26, 2026

    @dezren39
    MemberAuthor

    Intake review

    Still live (verified this run): nothing on main sends rootUri/workspaceFolders for scope-resolved instances — the prerequisite ResolvedScope plumbing (#958) does not exist on main yet, and its design record is still in open PR #957. No merged PR addresses this.

    Related: #958 (slice 1, prerequisite) · PR #957 (decision 0004, open) · #961 (slice 4 consumes this for the live gopls proof) · design origin dezren39/darwin-nix#819.

    Notes / risks: Marked status/blocked at intake because it cannot be implemented before slice 1 lands. The byte-for-byte-unchanged requirement for empty-root instances is the key regression guard — a captured-handshake comparison for a global-scoped server is the cleanest proof. Sending both fields for every era is deliberate (extensible initialize params); do not era-gate it.

    Suggested approach: After #958 merges, thread the instance root into mcpclient.Options, add the fields + capability declaration behind "root non-empty", and cover repo/worktree-present vs global-absent with a test-double server recording initialize params.

    — Fleet monitor intake enrichment (acceptance criteria were already in the body; labels normalized, meta/enriched added).

  3. dezren39 commented on Oct 29, 2026

    @dezren39
    MemberAuthor

    Relocated copy of this work arrived (from dezren39/darwin-nix#819) and was closed as a duplicate — two deltas folded in

    developing-today/code#1993 was the placement-audit relocation of dezren39/darwin-nix#819 (this issue's design source). Triaged today (queue task 2899, worker repo-worker-code, origin openchamber-scheduled-lane) against main @ 4d157755: duplicate of this issue, closed with the pointer — it carries no acceptance criterion that is missing here.

    Two things from the relocated copy worth keeping:

    1. Era gate (a real divergence, needs a decision before implementation). This issue's spec says rootUri/workspaceFolders are sent "for every era (legacy and modern)". The relocated copy said the opposite — send only what the negotiated revision and capabilities allow. The modern era 2026-07-28 dropped the roots feature and mcpx already declares roots: {} there (internal/mcpclient/modern.go:64-65,80), so sending workspace fields inside a 2026-07-28 initialize is spec-questionable and untested. The stricter, negotiate-gated wording is the safer default until someone verifies the modern path; worth settling when mcpx: ResolvedScope plumbing + spawn cwd = resolved scope root #958 lands rather than assuming it in the diff.
    2. Live-proof dependency. The gopls go_package_api proof also needs the child-cwd half. That is mcpx: spawn repo/worktree-scoped instances with the child cwd set to the resolved scope root #1989 (open, nix#817). Note mcpx: ResolvedScope plumbing + spawn cwd = resolved scope root #958's title — "ResolvedScope plumbing + spawn cwd = resolved scope root" — appears to claim the same spawn-cwd work, so mcpx: ResolvedScope plumbing + spawn cwd = resolved scope root #958 and mcpx: spawn repo/worktree-scoped instances with the child cwd set to the resolved scope root #1989 look like duplicates of each other for the cwd half; flagged for whoever owns them, not resolved here.

    State re-checked today, still as the intake review says: Client.initializeParams() (internal/mcpclient/client.go:422-429) sends only protocolVersion, capabilities, clientInfo; SetRoots (client.go:921), the roots capability declaration (modern.go:80-83) and the roots/list relay (modern.go:287-303) exist, so the missing piece is precisely "put the resolved root in the initialize request"; and ResolvedScope plumbing (#958) is still absent from pkgs/mcpx/internal, so this stays blocked on slice 1.

  4. dezren39 commented on Nov 1, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note — triage verdict: CONFIRMED, still blocked on slice 1 (queue task 2294, lane D, 2026-11-01T02:2xZ)

    Fresh verification against current main:

    • Nothing on main sends rootUri/workspaceFolders for scope-resolved instances: code search finds ResolvedScope and rootUri only in pkgs/mcpx/docs/decisions/0004-scope-resolved-roots.md — the design doc, not code.
    • The dependency is real and unmet: slice 1, mcpx: ResolvedScope plumbing + spawn cwd = resolved scope root #958 (ResolvedScope plumbing + spawn cwd), is still OPEN, and mcpclient.Options has no instance root to send. This issue's spec (§5) is buildable only on top of that plumbing.
    • The chain is moving: mcpx: ResolvedScope plumbing + spawn cwd = resolved scope root #958's own triage (queue task 2292) is claimed by another lane as of this check, so the unblock path is active rather than stalled.

    status/blocked stays — the blocker is #958 landing. Once #958 merges, this slice is a small, fully-specced fix (Options root + initialize params + capability declaration + scope tests) and can be enqueued directly against the acceptance criteria above.

  5. added
    queue/queuedHas a queued task in the Supabase agent queue
    task/triageQueue packet kind: verify, reproduce, and route this item
    on Nov 3, 2026
  6. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    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 30 (priority/normal). Issue carries status/blocked; the covering triage must re-derive and name the current blocker. 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

  7. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · triaged — confirmed live, blocker cleared, fix packet enqueued

  8. added
    task/small-fixQueue packet kind: bounded fix with reproduction and targeted tests
    work/assignedQueue worker lifecycle state
    queue/claimedQueue worker lifecycle state
    and removed
    task/triageQueue packet kind: verify, reproduce, and route this item
    status/blockedQueue or user escalation state
    queue/queuedHas a queued task in the Supabase agent queue
    on Nov 3, 2026
  9. added a commit that references this issue on Nov 3, 2026
  10. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    Done: slice 3 merged in #4992

    mcpclient.Options now carries the instance root, and initialize names it when it is non-empty:

    • rootUri: file:// URI of the scope-resolved root.
    • workspaceFolders: [{uri: <same>, name: <base name of root>}].
    • capabilities.workspace.workspaceFolders: true.
    • Both eras send the same fields; a rootless instance (global scope, degraded resolution) sends exactly what it sent before, so no daemon-cwd root is fabricated.
    • pool.startLane passes ResolvedScope.Root (slice 1, mcpx: ResolvedScope plumbing + spawn cwd = resolved scope root (#958) #3925).

    Verified: go build ./... clean, gofmt -l clean, and the new test-double test records the initialize params — present with a root (uri + base name + capability), absent without one. Targeted run: go test ./internal/mcpx... → ok internal/mcpclient 0.040s, ok internal/pool 0.930s. PR checks: basic: production line limit pass. Merged as 62344683de67512ddb4f50e2795af1e9eca525be.

    Slice 4 — flipping gopls to worktree scope plus the live go_package_api proof — is #961, as this issue's own AC says.

    🤖 Agent note · done

  11. removed
    task/small-fixQueue packet kind: bounded fix with reproduction and targeted tests
    queue/claimedQueue worker lifecycle state
    work/assignedQueue worker lifecycle state
    on Nov 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

effort/sSmall: expected under 2 hours of workkind/featureNew feature or capability requestmeta/enrichedIntake review done: acceptance criteria, links, and normalized labels addedpriority/normalOrdinary priority (the default)source/humanFiled directly by a human

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions