Skip to content

fieldwork: reconnect MCP clients on explicit host config reload - #5

Closed
teamleaderleo wants to merge 7 commits into
mainfrom
fieldwork/31-mcp-config-reload-reconnect
Closed

teamleaderleo wants to merge 7 commits into
mainfrom
fieldwork/31-mcp-config-reload-reconnect

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Jul 29, 2026 •

Copy link
Copy Markdown
Owner

In simple words

This is a compiled, narrow Campaign #84 primitive: an explicit host MCP-config reload requests fresh connections, while ordinary per-turn reconciliation continues reusing an unchanged ready client.

It is not the complete lifecycle repair. Reconnect alone does not prove that the latest generation wins publication, that the advertised catalogue was replaced, or that active calls keep their original authority and operation lineage.

Compiled result

Validated source commit: dbbd2bb0a9981cea8d8dfe231015349af84662a3.

Passing focused checks:

  • Rust formatting;
  • host_mcp_config_refresh_reconnects_ready_clients;
  • reconciliation_reuses_connection_without_relisting_regular_tools.

The app-server target was blocked before the requested behavior test by an unrelated existing fixture that omitted the newly required ItemCompletedEvent.started_at_ms. That is a baseline_compile_blocker, not evidence against this reconnect primitive.

What this proves

  • host CodexThread::refresh_mcp_config can mark the current ready MCP client for reconnection;
  • the next refresh creates another initialization attempt;
  • ordinary reconciliation keeps its existing reuse behavior.

What this does not prove

  • accepted publication belongs to the newest refresh generation;
  • an older late relist cannot replace a newer catalogue;
  • the advertised or bound catalogue actually changed;
  • cached catalogue A and live binding B have equal schema, approval, annotation, visibility, hook, file-input, or authority metadata;
  • a prepared, active, timed-out, or locally cancelled call stays tied to its original runtime and Campaign ci(fieldwork): execute typed mutation identity on a01a2d #83 receipt lineage.

Required integration follow-up

  1. Restack the primitive onto current owned main and the canonical Campaign ci(fieldwork): execute typed mutation identity on a01a2d #83 receipt owner.
  2. Add one refresh-generation ticket shared by host reload, explicit reconnect, auth change, notification, and recovery.
  3. Reject stale publication and prove a late older relist cannot consume a newer reconnect request.
  4. Compare advertised and live catalogue/authority fingerprints before any cached-A/live-B late binding.
  5. Preserve captured runtime identity for prepared and active calls, including an outer timeout whose underlying MCP request continues.
  6. Return typed per-server outcomes for unchanged, replaced, failed, cancelled, superseded, identity mismatch, and catalogue mismatch.

Boundary

  • this draft remains a component of Campaign [SUPERSEDED] Surface append outcome from session writes #84, not an integration-ready lifecycle repair;
  • no credentials, production resources, or consequential external mutations;
  • owned fork only;
  • public upstream remains read-only and no upstream contact is authorized.

Fieldwork: teamleaderleo/fieldwork#84

teamleaderleo commented Jul 29, 2026 •

Copy link
Copy Markdown
Owner Author

Read-only cross-lane review from Fieldwork L01/#84:

CI result

The narrowed workflow now separates the candidate from repository-wide formatter dependencies.

  • Rust formatting passed.
  • host_mcp_config_refresh_reconnects_ready_clients passed.
  • the ordinary-reconciliation reuse control passed.
  • the app-server target did not reach the requested behavior test because an unrelated existing fixture failed to compile: app-server/tests/suite/v2/thread_fork.rs constructs ItemCompletedEvent without the newly required started_at_ms field.

Classify that last result as baseline_compile_blocker, not as a reconnect-candidate failure. The PR still needs either a baseline repair/rebase or a narrower app-server target that compiles independently before it can claim app-server coverage.

Publication findings

Current Codex already contains a useful publication model in codex-mcp for Codex Apps:

  • hard_refresh_codex_apps_tools_cache serializes refresh and increments tool_catalog_revision once per accepted publication;
  • shared tool-cache fetch tickets reject older out-of-order results;
  • McpBinding freezes the advertised catalogue/client;
  • PreparedMcpCall rejects an old revision before irreversible preparation, while an already-started preparation holds the revision read lock so publication waits.

That authority contract is valid for a prepared call which remains bound to its request catalogue.

A separate current-head path needs explicit coverage. PR openai#35590 intentionally advertises cached regular-MCP catalogue A before startup, then waits and resolves the call against live binding B. The existing test proves that an A description can be shown to inference while the same tool name executes on B, and that a tool removed from B fails closed. It does not test same-name schema, approval, annotation, or hook changes.

The focused follow-up is:

capture model tool spec from cached A
→ initialize replacement B with the same tool name but changed schema or authority metadata
→ model calls using A's arguments
→ verify whether execution silently uses B

Require verified catalogue equality, fail-closed mismatch, or an explicit recorded late-rebind policy. Public upstream and the official SDK remained read-only; no upstream contact occurred.

Copy link
Copy Markdown
Owner Author

Re-review against current Campaign #83/#84 ordering

This remains a useful freshness trigger, but it is not yet a safe lifecycle repair on its own.

The current test proves only that host reload increases initialization attempts by one. It does not prove:

  • the accepted publication belongs to the latest refresh generation;
  • the new catalogue actually replaced the advertised/bound catalogue;
  • a late older relist cannot publish afterward;
  • an already prepared call remains on captured A rather than silently rerouting to B;
  • a timed-out but still-running A request is handled before B is published.

That last case is now concrete: the adjacent timeout probe shows an outer Codex timeout can return locally while the underlying legacy MCP request continues and completes its effect. Reconnecting/publishing B during that window must not erase or relabel A's operation lineage.

Recommended disposition:

  1. keep this patch as the narrow host-reload reconnect primitive;
  2. rebase it onto the current canonical session receipt owner;
  3. add refresh-generation acceptance and stale-publication rejection;
  4. add active/prepared/timed-out call controls that consume Campaign ci(fieldwork): execute typed mutation identity on a01a2d #83 receipts;
  5. test catalogue identity, not only initialize-attempt count.

Do not merge this old-base slice as though reconnect alone resolves stale catalogue or authority drift. It should be one component of #84's generation-bound publication contract.

@teamleaderleo teamleaderleo changed the title [Fieldwork] Reconnect MCP clients on host config reload fieldwork: reconnect MCP clients on explicit host config reload Jul 29, 2026

Copy link
Copy Markdown
Owner Author

Canonical source ownership moved to #46 at eb39c46b4bd0e115aa3e0acece50a19e803a37a4, with an exact two-file source boundary and focused reconnect/reuse receipts. This older branch remains useful historical evidence for the primitive and its baseline fixture blocker, but it carries no unique current source residue.

Receipt and lineage are recorded in Fieldwork #84, openai#197, and openai#239. Closing as superseded historical carrier. Public upstream interaction: none.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants