Repository navigation
Description
Context
The managed zccache sidecar is installed lazily from the build path:
crates/fbuild-build/src/zccache.rsresolves zccache throughfind_zccache().find_zccache()uses a process-localOnceLock<Option<PathBuf>>, so within a single daemon process only one thread runsmanaged_zccache::ensure()and other same-process callers block on that initialization.crates/fbuild-build/src/managed_zccache.rs::ensure()checks for the final binary, then downloadsSHA256SUMSplus the release archive, verifies it, extracts into a unique staging dir, and finally renames into~/.fbuild/<mode>/bin/zccache-<version>/.- The final rename handles a lost race: if another installer already placed the final binary, the loser deletes its staging dir and succeeds.
That final atomic rename prevents a half-installed zccache from being observed, but it does not prevent duplicate work before the rename. Multiple fbuild daemons/processes that hit first-run zccache setup at the same time can each download and extract the same archive. The daemon also does not expose a distinct "managed zccache download/install in progress" state; blocked clients just see a generic build/install wait.
Current daemon behavior:
POST /api/buildandPOST /api/install-depsserialize per project throughctx.project_lock(project_dir).- Streaming builds return the NDJSON response immediately and can wait up to the CLI's 1800s request timeout.
- Non-streaming operations also use the generic 1800s daemon POST timeout.
/ws/statusand daemon status snapshots exposeoperation_in_progressandcurrent_operation, but not a structured dependency-install phase or wait reason.OperationGuardupdates in-memory daemon state but does not currently broadcast a status update when operation text changes.
The desired behavior is that the daemon owns first-run sidecar install coordination: one installer performs the download, other clients block intentionally, and blocked clients receive a clear status/progress signal instead of appearing hung or timing out.
Proposal
Add a daemon/process-shared managed dependency install gate for the zccache sidecar.
Suggested shape:
- Add a cross-process lock around managed zccache installation before network fetch begins, not only at final rename.
- Lock scope should be the final managed version dir or a sibling lock file under
~/.fbuild/<mode>/bin/. - Within the lock, re-check
managed_zccache_exe().is_file()before downloading. - Other processes should wait on the lock instead of starting duplicate downloads.
- Lock scope should be the final managed version dir or a sibling lock file under
- Add daemon-visible install state for managed sidecar setup.
- At minimum:
dependency_install_in_progress,dependency_name = "zccache",dependency_version,phase(waiting_for_lock,downloading,verifying,extracting,installed), and a human message. - This should update
/health//api/daemon/infoor a dedicated status endpoint, and/ws/statusshould broadcast phase changes.
- At minimum:
- Ensure clients do not time out while intentionally blocked behind a sidecar install.
- Streaming clients should receive periodic NDJSON/status events while waiting.
- Non-streaming clients should either use the existing 1800s timeout safely or get a clear long-running operation response contract if the wait exceeds a threshold.
- The status should distinguish "waiting for another fbuild process to install zccache" from "compiling".
- Keep failure behavior explicit.
- If the installer fails, waiters should observe the failure and either retry once or fall back to ambient zccache discovery according to the existing
find_zccache()policy. - Do not leave stale lock state that blocks future clients forever.
- If the installer fails, waiters should observe the failure and either retry once or fall back to ambient zccache discovery according to the existing
Acceptance criteria
- Two concurrent fbuild clients starting with no managed zccache installed result in exactly one network download/extract attempt for the managed zccache version.
- Other clients block on the daemon/process-shared install gate and do not start duplicate downloads.
- While blocked, clients can observe a clear status such as "waiting for managed zccache 1.12.7 install" rather than only "building".
- Streaming build clients receive periodic status/log events during long sidecar install waits so the connection stays alive and looks intentional.
- Non-streaming build/install-deps clients do not hit a request timeout solely because another client is installing zccache.
- A failed or interrupted installer does not leave a permanent stale lock; a later fbuild invocation can recover.
- Tests cover same-process contention, cross-process/file-lock contention, and stale/interrupted install recovery.
Open questions
- Should this gate live in
fbuild-build::managed_zccacheas a generic sidecar-install lock, or infbuild-daemonso it can update daemon status directly? - Should zccache install status be represented as a new daemon state, or as structured fields alongside the existing
Buildingstate? - Should the same mechanism become a generic managed-dependency install gate for future sidecars, not just zccache?
Related issues
- chore: remove zccache crate linkage and use the managed sidecar for cache APIs #600 removes compile-time zccache crate linkage. This issue is separate: it covers runtime sidecar install coordination and client-visible blocking behavior.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsTriage
Activity
zackees commentedon Jun 16, 2026
Additional investigation: broker/cache strategy risk
There is a broader broker-design issue here beyond the zccache install lock.
fbuild has very large, shared artifacts: toolchains, framework/platform packages, downloaded archives, managed sidecars, and compile/cache data. Those need to behave like a per-user/global repository (
~/.fbuild/<mode>/cache, or an explicitFBUILD_CACHE_DIR) with stable package identity. We should not let broker adoption accidentally turn these into private stores scoped to whichever fbuild daemon/backend version the broker negotiated.Current broker-facing code records fbuild cache roots through
CacheManifestincrates/fbuild-daemon/src/broker/service.rs:CacheData=get_cache_root()CacheIndex=<cache>/indexCacheTmp=<fbuild_root>/tmpCacheLogs/CacheLocks= daemon dirCacheRuntime= daemon binary dirCacheConfig=get_fbuild_root()That is directionally good because it points at fbuild's real cache roots, not a broker-created private backend cache. The risk is policy: if the broker starts resolving multiple fbuild backend versions as separate runnable backends, clients could observe different daemon versions while sharing or publishing cache manifests inconsistently. For fbuild, the artifact repository has to be authoritative and shared, while daemon version negotiation should not imply per-version artifact ownership.
This points to a strategy decision before deeper broker migration:
EXPLICIT_INSTANCE.Suggested follow-up acceptance criteria for the broker side:
FBUILD_CACHE_DIR/dev-mode inputs.zackees commentedon Jun 16, 2026
Broker/global cache investigation split
Breaking the concern in the broker/cache strategy comment into sub-issues for focused investigation:
Sub-issue A: daemon identity and broker resolution
Sub-issue B: global artifact repository ownership
Sub-issue C: large download/install concurrency and client blocking
Sub-issue D: compatibility, migration, and recovery policy
I?m going to append separate repo-backed findings for each sub-issue.
zackees commentedon Jun 16, 2026
Sub-issue B findings: global artifact repository ownership
Findings from the current tree:
crates/fbuild-paths/src/lib.rs:get_fbuild_root()is~/.fbuild/{dev|prod}(FBUILD_DEV_MODEsplit) andget_cache_root()isFBUILD_CACHE_DIRor<fbuild_root>/cache(crates/fbuild-paths/src/lib.rs:19,crates/fbuild-paths/src/lib.rs:61). This is independent of the fbuild daemon/backend version.Cachefacade buildspackages/,toolchains/,platforms/,libraries/, andcore/belowcache_root(crates/fbuild-packages/src/cache.rs:51,:55,:59,:63,:67), andPackageBase::new()usesCache::new(project_dir)plusDiskCache::open()(crates/fbuild-packages/src/lib.rs:211,:212).PackageBase::staged_install()commits into the resolved cache path and writes.install_complete(crates/fbuild-packages/src/lib.rs:314,:369,:376). No daemon-version segment is part of these paths.DiskCachealso opens atfbuild_paths::get_cache_root()(crates/fbuild-packages/src/disk_cache/mod.rs:41) and definesarchives/,installed/, andindex.sqliteunder the same root (crates/fbuild-packages/src/disk_cache/paths.rs:118,:123,:128).Kindcovers packages, toolchains, platforms, libraries, frameworks, and lnk blobs (crates/fbuild-packages/src/disk_cache/paths.rs:18). This is the right ownership model for large archives and cache data, but there is still a mixed layout: the legacy package installer records installs into the DiskCache index only if the install path is underdc.cache_root()(crates/fbuild-packages/src/lib.rs:289,:291), while the physical install path can be the legacy<cache>/toolchains/.../<cache>/platforms/...shape rather than<cache>/installed/....get_cache_root(): fbuild installs the pinned binary under~/.fbuild/<mode>/bin/zccache-<MANAGED_ZCCACHE_VERSION>/viamanaged_dir()(crates/fbuild-build/src/managed_zccache.rs:23,:47,:48).find_zccache()intentionally prefersFBUILD_ZCCACHE_BINand otherwise this managed binary (crates/fbuild-build/src/zccache.rs:31,:34,:55,:70). This is stable per user/mode and versioned by zccache, not by fbuild daemon version, but it will not followFBUILD_CACHE_DIR.CacheManifestis directionally correct for artifacts:CacheDataisget_cache_root(),CacheIndexis<cache>/index, and config/temp/log/lock come fromget_fbuild_root()/daemon dirs (crates/fbuild-daemon/src/broker/service.rs:44,:53,:59;crates/fbuild-paths/src/running_process.rs:117,:134,:138,:139,:140,:143,:144). The inventory doc says the same and explicitly treats local dev asSHARED_BROKER, with CI usingEXPLICIT_INSTANCE ci-trusted(docs/running-process/inventory.md:19,:20).Where broker adoption could accidentally create private/versioned stores:
CacheRuntime, relocated daemon binary dirs, broker instance id, or backend version instead offbuild_paths::get_cache_root(), they could forkpackages/toolchains/frameworksinto private per-version stores.CacheRuntimeis explicitly the daemon binary directory (crates/fbuild-daemon/src/broker/service.rs:49,:58). That is useful runtime metadata, but it should not become the owner for artifact sidecars. The managed zccache sidecar already lives underget_fbuild_root()/bin; if broker relocation adds another per-version bin root, zccache installs could split by backend runtime path.FBUILD_CACHE_DIRand not~/.fbuild/*/daemon/(docs/CI_CACHE.md:15,:19;docs/CI_CACHING.md:92,:93,:94,:97,:99). Broker adoption should keep CIEXPLICIT_INSTANCEisolation as a trust-domain exception, not as the local default.Actionable recommendations:
FBUILD_DEV_MODE,FBUILD_CACHE_DIR,HOME/USERPROFILE), two fbuild backend versions must publish identicalCacheData/artifact roots and must not include service version, broker instance, or daemon runtime path in package/toolchain/framework/cache roots.CacheRuntimeas executable provenance only. Do not use it to root package archives, extracted installs, zccache sidecars, lnk blobs, or cache indexes.get_fbuild_root()/binpermanently or should move/report as a sidecar root. Either way, make the contract explicit because it is stable per user/mode but outsideFBUILD_CACHE_DIR.<cache>/archives,<cache>/installed, andindex.sqlite, while current package installs can still land in legacy<cache>/toolchains/<cache>/platforms. That is not a broker-versioning bug, but it is the main place future cache-root changes could accidentally fork ownership.zackees commentedon Jun 16, 2026
Sub-issue C findings: download/install concurrency and client blocking
Findings from the current Rust daemon/package paths:
crates/fbuild-daemon/src/context.rskeeps per-project locks asDashMap<PathBuf, Arc<tokio::sync::Mutex<()>>>andproject_lock()keys them by the exactPathBuf.crates/fbuild-daemon/src/handlers/operations/build.rstakes that lock for both streaming and non-streaming builds, andcrates/fbuild-daemon/src/handlers/operations/install_deps.rstakes the same lock beforeinstall_platform_deps(). This serializes concurrent requests for the same project inside one daemon, but it does not protect shared package/toolchain/framework installs across different projects or across separate daemon processes.The generic package installer in
crates/fbuild-packages/src/lib.rsis staged but not package-locked.PackageBase::staged_install()checksinstall_path.exists(), uses a deterministic sibling{final}_staging, deletes any existing staging dir, downloads withdownloader::download_file(), extracts, validates, then renames staging to final and writes.install_complete. Two fbuild clients installing the same uncached package can delete or reuse each other's staging dir; if they are different projects/daemons, the project lock will not prevent this. Most toolchains and framework packages call this shared path viaensure_installed()(crates/fbuild-packages/src/toolchain/*.rs,crates/fbuild-packages/src/library/*.rs).crates/fbuild-build/src/managed_zccache.rsalready has the safer pattern: unique per-process staging dirs under~/.fbuild/<mode>/bin, atomic rename to final, and an explicit "lost race with concurrent installer" success path if the final binary exists. This should be the model for package/framework/toolchain installs.Download progress plumbing exists but is not wired into package installs.
crates/fbuild-packages/src/downloader.rshasDownloadProgressanddownload_file_with_progress(), butPackageBase::staged_install()andlibrary_downloader.rscall buffereddownload_file(), which loads the whole response into memory and emits no client-visible progress. That is especially rough for ESP32/toolchain/framework downloads.Blocked streaming clients currently get an open NDJSON response but no queued/progress event while waiting for the project lock.
build.rslogswaiting for project lockand warns after 10s, then waits indefinitely, but it does not send a stream event until build log lines start. Non-streaming clients just hold the HTTP request.crates/fbuild-cli/src/daemon_client.rshas 1800s request timeouts for build/post paths, 100ms connect timeout, and returnsstream ended without a result eventonly if the stream closes without a terminal result.Status surfaces are too coarse for this case.
/api/locks/statusincrates/fbuild-daemon/src/handlers/locks.rsreports project locks as{ project_dir, is_held }only, with no holder request/client, waiters, wait duration, phase, package URL/name, or package install state./ws/statusincrates/fbuild-daemon/src/handlers/websockets.rsreportsstate,current_operation,operation_in_progress, andprogress_percent: null; I did not find build/package paths broadcasting status updates throughBroadcastHub.Actionable recommendations:
(kind, cache_key, version)beforePackageBase::staged_install(): at minimum unique staging dirs plus race-aware final commit likemanaged_zccache; preferably also a cross-process lock/lease so only one daemon downloads/extracts a given package while others wait and re-check final/sentinel state.install_path.exists()alone as insufficient completion. Gate cache hits on the.install_completesentinel or validation, and handle stale_staging/partial directories without deleting another active installer's work.download_file_with_progress()into toolchain/framework/library installs and propagate structured events:queued_for_project_lock,waiting_for_package_install,download_started,download_progress,extracting,install_complete. Streaming/api/buildcan emit these as NDJSON before compile logs;/ws/statusand/api/locks/statusshould expose the same phase for blocked clients.zackees commentedon Jun 16, 2026
Sub-issue A findings: daemon identity and broker resolution
Findings from the current tree:
docs/running-process/inventory.md:12says local fbuild is a single persistent per-user daemon, withFBUILD_DEV_MODE=1using~/.fbuild/dev/+ port 8865 and prod using~/.fbuild/prod/+ port 8765.docs/running-process/inventory.md:20sets the target local broker isolation toSHARED_BROKER, with CI as theEXPLICIT_INSTANCE "ci-trusted"exception.crates/fbuild-daemon/src/broker/service.rs:63builds the defaultSHARED_BROKERservice definition for servicefbuild, andcrates/fbuild-daemon/src/broker/service.rs:95usesServiceDefinitionBuilder::shared_broker(SERVICE_NAME, daemon_binary). The manifest hard-codes broker instance"shared"atcrates/fbuild-daemon/src/broker/service.rs:148, so it does not distinguish cache roots or dev/prod roots in the broker instance id.~/.fbuild/{dev|prod}/daemon, not the artifact cache root.crates/fbuild-paths/src/lib.rs:19definesget_fbuild_root()as~/.fbuild/{dev|prod};crates/fbuild-paths/src/lib.rs:31,:36, and:41derive daemon dir/PID/port files from that root.FBUILD_CACHE_DIRaffects onlyget_cache_root()atcrates/fbuild-paths/src/lib.rs:61, so two invocations with differentFBUILD_CACHE_DIRvalues but the same dev/prod mode still share the same daemon PID/port identity.get_daemon_port()first honorsFBUILD_DAEMON_PORT, then current-modedaemon.port, then the other mode'sdaemon.port, then the mode default (crates/fbuild-paths/src/lib.rs:171). That cross-mode fallback is useful for legacy discovery, but it means a prod client can route to a dev daemon if its own current-mode port file is absent.crates/fbuild-cli/src/daemon_client.rs:897callstry_acquire_broker_daemon()before direct fallback; on success,crates/fbuild-cli/src/daemon_client.rs:927records the negotiated broker endpoint/version, butcrates/fbuild-cli/src/daemon_client.rs:936immediately creates a normalDaemonClientand waits onclient.health()fromget_daemon_url(). That means the broker-selected backend endpoint and the HTTP port-file endpoint can diverge.crates/fbuild-daemon/src/main.rs:155,:161,:164) and installs the running-process service definition afterward (crates/fbuild-daemon/src/main.rs:168,:180). I did not find a startup call that publishes theCacheManifest; the helper exists incrates/fbuild-daemon/src/broker/service.rs:127, but current startup appears to install only the service definition. If the broker later relies on manifests for cache-root identity, this needs to be made explicit.docs/running-process/README.md:11says broker-spawned daemons answer broker health/daemon-info diagnostics, while CLI/PyO3 continue using HTTP for operations.crates/fbuild-daemon/src/broker/backend.rs:117serves onlyHealthandDaemonInfo; other ops return an error telling callers to use HTTP fallback. So inconsistent routing is currently most likely at acquisition/health/diagnostic time, but it will become a build/deploy correctness issue once operations move onto broker frames.Conclusion: local fbuild should enforce exactly one active daemon per effective local daemon domain, but the domain needs to be defined deliberately. Today the implementation is effectively one daemon per user + dev/prod root + HTTP port, not one daemon per
FBUILD_CACHE_DIR. If the desired policy is truly one daemon per user/cache root, the current path model does not implement it. If the desired policy is one daemon per user/mode with optional sharedFBUILD_CACHE_DIR, then broker resolution should key and document that explicitly so cache-root changes cannot silently route to the wrong long-lived daemon.Actionable recommendations:
{user, mode/dev-prod root, effective artifact cache root, broker isolation/trust domain}. IfFBUILD_CACHE_DIRis intentionally not part of identity, document that and reject/diagnose cache-root changes against an already-running daemon.client.health_full()returns the same PID/version/cache_dir/daemon_dir as the negotiated backend before returning success.SHARED_BROKER, either replace/upgrade the active daemon when a newer binary is requested, or require the broker resolver to select by daemon identity/cache-root compatibility, not only service name/version. CIEXPLICIT_INSTANCE "ci-trusted"should remain the exception.daemon running-process/daemon status) so users can see when prod is talking to a dev daemon via the other mode's port file.CacheManifestduring daemon startup if broker cache-root identity is part of routing policy. Add a test that two same-domain daemons cannot advertise differentCacheData/CacheLocksroots under the sameSHARED_BROKERinstance.zackees commentedon Jun 16, 2026
Sub-issue D findings: compatibility, migration, and recovery policy
Scope checked: broker docs/session/service, cache roots/manifest, disk-cache schema + GC, package staging, managed_zccache, daemon PID/status/lock handling, CLI/Python acquisition paths.
Findings:
crates/fbuild-paths/src/running_process.rs:42-88still reports broker mode asbroker-requested-direct-fallback, while CLI/Python both try broker adoption and then continue using the HTTP health/endpoint path (crates/fbuild-cli/src/daemon_client.rs:894-947,crates/fbuild-python/src/daemon.rs:84-124). This is a reasonable migration bridge, but the policy should be explicit: direct HTTP remains the compatibility fallback until broker request routing is complete, and typed brokerVersionUnsupported/VersionBlockedrefusals should stay fatal rather than spawning a second incompatible daemon (crates/fbuild-cli/src/daemon_client.rs:955-963,crates/fbuild-python/src/daemon.rs:160-168).SHARED_BROKER; CI has an explicitEXPLICIT_INSTANCE "ci-trusted"builder (crates/fbuild-daemon/src/broker/service.rs:63-117) and the diagnostic exposes the distinction (crates/fbuild-cli/src/cli/daemon_cmd.rs:147-188). One gap:manifest_builder()always advertises broker instance"shared"(crates/fbuild-daemon/src/broker/service.rs:144-155), so a future CI manifest path needs either a CI-specific manifest builder or a test proving cache manifests are intentionally shared even when service isolation is explicit.schema_migrationsis authoritative,cache_meta.schema_versionis mirrored only for legacy tooling (crates/fbuild-packages/src/disk_cache/index/mod.rs:6-17,:127-176), andm002_add_leases_refcountfixes oldleasesrows (crates/fbuild-packages/src/disk_cache/index/migrations.rs:18-36,:86-103). Existing regression coverage seeds a pre-migration DB and verifies lease acquisition (crates/fbuild-packages/tests/disk_cache_schema_migration.rs:21-102). Add a guard that fails if existing migration IDs are reordered/renamed and a compatibility test opening a DB with all known old objects plus unknown futurecache_metakeys..partialstaging and.install_completesentinels (crates/fbuild-packages/src/disk_cache/paths.rs:147-183);reconcile()removes missing rows, incomplete installs, and.partialdirectories (crates/fbuild-packages/src/disk_cache/gc.rs:137-197,:236-249); daemon startup runs reconciliation in the background (crates/fbuild-daemon/src/main.rs:302-320). PackageBase still uses a legacy<version>_stagingsibling and final-path existence check (crates/fbuild-packages/src/lib.rs:307-382), so add tests for crash points before rename, after rename before sentinel, and stale_stagingcleanup; also consider aligning PackageBase staging names with disk_cache.partialso one recovery rule covers both.DaemonContext.project_locksand are cleared when unlocked by/api/locks/clearor periodic cleanup (crates/fbuild-daemon/src/context.rs:151-156,crates/fbuild-daemon/src/handlers/locks.rs:46-74,crates/fbuild-daemon/src/main.rs:277-297). Disk-cache leases use PID+nonce refcounts and reap dead PIDs during GC (crates/fbuild-packages/src/disk_cache/lease.rs:1-15,crates/fbuild-packages/src/disk_cache/index/queries.rs:131-174,:264-290). Add an explicit test that a dead-PID lease is reaped and unpins entries, plus a daemon lock-status test documenting thatstale_locksis currently always empty (crates/fbuild-daemon/src/handlers/locks.rs:38-43) unless that field is made meaningful.crates/fbuild-daemon/src/main.rs:136-151,:406-423), binds with platform-specific reuse/exclusive-address policy and retry (crates/fbuild-daemon/src/main.rs:465-490), writes PID/port files (crates/fbuild-daemon/src/main.rs:155-166), and writesdaemon_status.jsonatomically with a Windows fallback (crates/fbuild-daemon/src/status_manager.rs:194-225). Add integration tests around stale PID file cleanup, live PID refusal/no cleanup, and status temp-file interruption leaving either old-valid or new-valid JSON.crates/fbuild-build/src/managed_zccache.rs:59-85,:109-157). Add tests for concurrentensure()races and a startup/ensure cleanup policy for stale.zccache-*.tmpdirs from interrupted downloads.Recommended policy text for this sub-issue:
cache_meta.schema_versionis compatibility-only.EXPLICIT_INSTANCE "ci-trusted"should be tested as a deliberate exception, including whether its cache manifest instance should beci-trustedor intentionallyshared.zackees commentedon Jun 16, 2026
Broker/global cache investigation synthesis
The four sub-issue passes are posted:
Main conclusion: the safe local policy should be one active fbuild daemon identity per shared artifact repository, not one private repository per broker-selected daemon/backend version. Today fbuild mostly behaves like one daemon per dev/prod root and legacy port file, but that is not the same thing as one daemon per
FBUILD_CACHE_DIR, and the broker path can introduce a second routing identity unless we define and enforce the tuple explicitly.Recommended follow-up shape:
(user, dev/prod mode, canonical FBUILD_CACHE_DIR or default cache root, trust domain), and document that backend version is not a cache-owner dimension.SHARED_BROKERresolution converge on that identity. If a different fbuild version is requested, either reuse/upgrade/replace the daemon for that cache root, or refuse with a clear compatibility message; do not silently create a private versioned artifact store.CacheRuntimeroot as daemon provenance only.CacheData/package/toolchain/framework archives remain owned by fbuild's global repository.FBUILD_CACHE_DIRacross broker-negotiated versions publishes the sameCacheData; CIEXPLICIT_INSTANCEremains isolated; stale_staging/partial sidecar installs recover; migration IDs remain immutable; dead-PID leases do not block forever.Open policy question to settle before implementation: should local fbuild strictly refuse parallel daemon versions for the same cache root, or allow them only when a declared cache schema compatibility check passes?
zackees commentedon Jun 16, 2026
Created parent/meta burndown issue for this broker/global-artifact work:
That tracker consolidates the four sub-issue findings from this thread into implementation workstreams and acceptance criteria. This issue can remain focused on the original managed zccache install gate and detailed investigation history.
zackees commentedon Jul 8, 2026
Validated against current main for the #1004 burn-down.
Current state:
crates/fbuild-build/src/zccache.rsis embedded-only;compile_backend.rsinstalls the daemon-owned embeddedFbuildZccacheService.Local validation on this machine:
soldr --no-cache cargo test -p fbuild-build --test zccache_embedded_smoke-> 1 passed.soldr --no-cache cargo test -p fbuild-packages install_lock::tests-> 5 passed.soldr --no-cache cargo test -p fbuild-core install_status --lib-> 3 passed.soldr --no-cache cargo test -p fbuild-daemon dependency_install --lib-> 3 passed.Closing this as completed/stale: the specific managed-zccache sidecar install gate no longer exists, and the remaining shared install/status requirements were implemented and closed through #603.