Skip to content

[CRITICAL] providers.json + spawn-target: one shared resolver, kill the config-drift class #197

Closed

Description

@jobordu

Problem

Two primitives are re-implemented across ~14 call sites with divergent semantics — this is the structural root of config-drift (fixed 6×: #150 #148 #162 #163 #165 #186) and null-CLI (fixed 4×: #161 #164 #180 #193).

Spawn target: call-quorum-slot.cjs:387 & probe-quorum-slots.cjs use resolvedCli||cli||mainTool; quorum-preflight.cjs:311 uses raw p.cli (see #urgent).

Config location (9 resolvers): unified-mcp-server.mjs:37, call-quorum-slot.cjs:284, probe-quorum-slots.cjs:28, quorum-preflight.cjs:55, provider-status.cjs:41, quorum-consensus-gate.cjs:343, check-provider-health.cjs:146, four inline reads in quorum-slot-dispatch.cjs, manage-agents-core.cjs:29, update-agents.cjs:34, migrate-plaintext-tokens.cjs:24. They disagree on order and on empty-file skipping. The authoritative UNIFIED_PROVIDERS_CONFIG pointer (written by install.js into every mcpServers env) is read only by unified-mcp-server.mjs. Five physical copies exist on a dev machine; which loads depends on cwd/__dirname.

Scope

  • New bin/resolve-providers.cjs: order = UNIFIED_PROVIDERS_CONFIG env → pointer from a unified-mcp-server entry in ~/.claude.json → __dirname (non-empty only) → ~/.claude/nf-bin → legacy nf/bin (non-empty only); log chosen path to stderr.
  • New bin/resolve-spawn-target.cjs (or extend resolve-cli.cjs): resolvedCli||cli||mainTool.
  • Wire all sites to these two modules (supersedes the localized preflight fix; rebase after that merges).

Regression gate

  • lint:isolation rule: fail CI on any inline providers.json path construction or require('./providers.json') outside the resolver module.
  • Hermetic resolution-order test (temp HOME + NF_CLAUDE_JSON): every entry point loads the same file.

Found in the 2026-06 quorum deep-review (8 areas mapped, 80 findings adversarially verified, 26 confirmed). Full plan: .planning/quorum-hardening-plan.md.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions