Context
Follow-up to #940 ("Multi-checkout daemon collision: two repos share port 8765, wrong-version daemon serves both"). That issue was closed by PR #1006, which added warn_if_daemon_identity_mismatch (crates/fbuild-cli/src/daemon_client/identity.rs:26-68) — but the fix is warn-only, and the PR body says so explicitly: "per-checkout endpoint isolation remains a broader behavior change." So the collision is now visible but still happens: two checkouts still share the fixed per-user port and can serve each other wrong-version builds silently in any script that doesn't surface the warning.
Root cause: the endpoint is a fixed per-user TCP port, not keyed by version or checkout — get_daemon_port() (crates/fbuild-paths/src/lib.rs:228-256: env → port file → cross-mode port file → 8765 prod / 8865 dev), and DaemonCacheIdentity (crates/fbuild-paths/src/running_process.rs:127-158) deliberately excludes the backend version.
Compounding it, kill-and-replace is mtime-based, not version-based: ensure_direct_daemon_running (crates/fbuild-cli/src/daemon_client.rs:786-816) shuts the daemon down whenever the CLI's sibling-binary mtime > the running daemon's source_mtime. A freshly built but older-version binary (newer mtime) can therefore evict a running newer-version daemon — the wrong direction.
Proposal
- Key the default endpoint by cache-identity / checkout so concurrent checkouts get isolated daemons by default: derive the port (or a per-identity port file) from
DaemonCacheIdentity / the spawner scope rather than the fixed constant (fbuild-paths/src/lib.rs:228-256). - Make version arbitration deterministic: replace the mtime comparison (
daemon_client.rs:786-816) with a semver/version comparison so an older-versioned binary can't displace a newer daemon regardless of build mtime.
Acceptance criteria
Decisions
Related
Cross-repo sibling of zccache #1007 and soldr #1493 — the same daemon version-shadow class, filed after a cross-repo daemon-deployment audit. fbuild's daemon deployment (stable-named sibling binary, no self-copy) is clean; only endpoint identity is affected.
Context
Follow-up to #940 ("Multi-checkout daemon collision: two repos share port 8765, wrong-version daemon serves both"). That issue was closed by PR #1006, which added
warn_if_daemon_identity_mismatch(crates/fbuild-cli/src/daemon_client/identity.rs:26-68) — but the fix is warn-only, and the PR body says so explicitly: "per-checkout endpoint isolation remains a broader behavior change." So the collision is now visible but still happens: two checkouts still share the fixed per-user port and can serve each other wrong-version builds silently in any script that doesn't surface the warning.Root cause: the endpoint is a fixed per-user TCP port, not keyed by version or checkout —
get_daemon_port()(crates/fbuild-paths/src/lib.rs:228-256: env → port file → cross-mode port file → 8765 prod / 8865 dev), andDaemonCacheIdentity(crates/fbuild-paths/src/running_process.rs:127-158) deliberately excludes the backend version.Compounding it, kill-and-replace is mtime-based, not version-based:
ensure_direct_daemon_running(crates/fbuild-cli/src/daemon_client.rs:786-816) shuts the daemon down whenever the CLI's sibling-binary mtime > the running daemon'ssource_mtime. A freshly built but older-version binary (newer mtime) can therefore evict a running newer-version daemon — the wrong direction.Proposal
DaemonCacheIdentity/ the spawner scope rather than the fixed constant (fbuild-paths/src/lib.rs:228-256).daemon_client.rs:786-816) with a semver/version comparison so an older-versioned binary can't displace a newer daemon regardless of build mtime.Acceptance criteria
Decisions
Related
Cross-repo sibling of zccache #1007 and soldr #1493 — the same daemon version-shadow class, filed after a cross-repo daemon-deployment audit. fbuild's daemon deployment (stable-named sibling binary, no self-copy) is clean; only endpoint identity is affected.