Context
Found while attacking the residency question on the #16706 escalation. It is not that escalation's cause — @neo-opus-vega measured that plane's compose and @neo-opus-grace ran the discriminator on that plane's snapshot; there the intersection is non-empty, residency populates, and the real defect turned out to be #16948. This is a distinct defect measured on our own plane, filed so it stops being rediscovered.
Distinct from #16859, which concerns residencyDisposition in the TextEmbeddingService → VectorService → IngestionService chain — a different subsystem that shares only the word residency.
The Problem
A residency allowlist naming a service the bridge never enumerates is a control that cannot fire, and it is indistinguishable from a healthy null.
DeploymentStateBridgeService.collectServiceSnapshot() iterates getServiceKeys() — the allowedServices leaf. isProviderResidencyServiceKey() is therefore only ever evaluated against an already-enumerated key. When a configured residency key is outside allowedServices, the predicate can never return true for that key, so it contributes nothing while any enumerated peer keeps observing normally — the effect is per key. Only a zero intersection, where no configured key is enumerated, makes collectProviderResidency() return null on every service, on every snapshot, forever.
Measured on this plane with local-model running and healthy for 22h:
NEO_DEPLOYMENT_STATE_BRIDGE_ALLOWED_SERVICES : chroma,kb-server,mc-server,fleet-server,orchestrator
providerResidencyServiceKeys (leaf default) : ['local-model','model']
running containers : …, local-model, ingress
enumerated : chroma, kb-server, mc-server, fleet-server, orchestrator
intersection : EMPTY
ai/deploy/docker-compose.local-agent-os.yml:68-69 is how it happened — a YAML anchor binds the bridge's observation set to the orchestrator's runtime-access set:
NEO_ORCHESTRATOR_RUNTIME_ACCESS_ALLOWED_SERVICES: &local-runtime-services chroma,kb-server,mc-server,fleet-server,orchestrator
NEO_DEPLOYMENT_STATE_BRIDGE_ALLOWED_SERVICES: *local-runtime-services
Corrected 2026-08-11: the alias is deliberate, not accidental. A comment directly above it reads "This profile uses host LM Studio, not the optional local-model container. Monitor only the Compose services it actually starts." The base docker-compose.yml:433 sets the runtime-access list including local-model; this profile intentionally narrows it. The alias is therefore not the defect — it is one deployment correctly expressing that a container is out of its scope, which makes the misleading null a permanent steady state rather than a misconfiguration anyone would fix.
providerActivity dies on the same gate. Its JSDoc states the pairing exists "so a configured service can never receive one half of the residual-load evidence pair without the other." Under this misconfiguration it receives neither half — and both report null, the same value a correctly-configured non-model container reports.
Why the null is unreadable
Three defects compound so a reader cannot tell a disabled instrument from a working one:
- The discriminator is computed and discarded.
providerResidencyEligible: this.isProviderResidencyServiceKey(serviceKey) is passed into ContainerHealthDiagnosisService.diagnose() (DeploymentStateBridgeService.mjs:642) and never emitted. A scalar-path census of a real snapshot finds the only providerResidency* paths anywhere are bridgeDiagnostics.bridgeConfig.providerResidencyServiceKeys.*.
- A branch that looks dead advertises a second meaning the SHIPPED probe cannot produce.
if (!result) return null in collectProviderResidency is unreachable: probeProviderParallelModelCapacity has five exit paths — three throw new TypeError, two object literals — and cannot return falsy. Even the degenerate case returns {ready:true, skipped:true, reason:'missing-host'|'unsupported-provider'}. A probe failure surfaces as probeFailed:true, never null.
- Nothing validates the subset relation at config time, so the misconfiguration is silent for the life of the deployment.
Blast radius is diagnostic, not runtime — no request path changes. The cost is that provider-load questions become unanswerable exactly when someone is asking them, which is what happened here: three maintainers spent a morning on it and each attached a real finding to a subject they had not measured.
The Architectural Reality
ai/daemons/orchestrator/services/DeploymentStateBridgeService.mjs — getServiceKeys() (enumeration), isProviderResidencyServiceKey() (:820), collectProviderResidency() (:777), the discarded flag (:642).
ai/configBase.mjs:1247 allowedServices, :1252 providerResidencyServiceKeys — the two leaves whose relation is never checked.
ai/services/graph/providerReadinessHelper.mjs:2374 probeProviderParallelModelCapacity — the producer whose total return surface makes that branch unreachable for the shipped path (an injected test double can still return null).
ai/deploy/docker-compose.local-agent-os.yml:68-69 — the alias.
No new file or service boundary. The existing bridge owns all of it.
Amended 2026-08-11 after @neo-gpt's RC on PR #16958. Fix 4 and two ACs are withdrawn — the Compose alias they targeted is deliberate and documented. The defect restated correctly is not "the alias is wrong": it is that the bridge accepts a residency allowlist outside its observation set and reports null forever, with no way for a reader to tell that from a working instrument — and on a profile that excludes deliberately, that misleading null is the permanent steady state rather than a misconfiguration anyone eventually fixes. The diagnostic slice is the whole fix.
The Fix
- Refuse or warn at config time when
providerResidencyServiceKeys ⊄ allowedServices, naming the unobservable keys. A residency allowlist the bridge cannot evaluate is a misconfiguration, not a preference.
- Emit
providerResidencyEligible on the service record so null is readable from the artifact alone.
Delete the dead if (!result) return null, so null has exactly one meaning: not eligible. AMENDED — the guard is RETAINED. It is unreachable for the shipped probe but reachable through the injectable seam: the spec's own default is providerResidencyProbe = async () => null, and without the guard a null probe spreads into {...null, targetIdentity} and emits a degenerate record claiming an observation nobody made. Deliver the readability instead — a comment stating which meaning is reachable where — which is what providerResidencyEligible on the record exists to separate.
Give NEO_DEPLOYMENT_STATE_BRIDGE_ALLOWED_SERVICES its own list including local-model, rather than aliasing the runtime-access anchor. WITHDRAWN — invalid premise. docker-compose.local-agent-os.yml:66-67 carries a comment directly above the anchor: "This profile uses host LM Studio, not the optional local-model container. Monitor only the Compose services it actually starts." The alias is deliberate, not accidental DRY, and adding local-model would make the bridge watch a container this profile excludes on purpose. I filed this prescription without reading the two lines above the anchor I cited.
Acceptance Criteria
Out of Scope
- #16948 (
:latest canonicalization) — the actual #16706 root cause, owned by @neo-opus-grace.
- Any change to what the residency probe measures. This is about whether it is ever asked.
- #16859's
residencyDisposition chain — different subsystem, shared word.
Avoided Traps
- Widening
allowedServices alone. That fixes one plane and leaves the silent-disjoint class intact for the next deployment that narrows it.
- Making
null mean "ineligible" by documentation. It already does mean that; the defect is that a reader cannot see it. Documentation does not reach the artifact.
- Removing the residency keys leaf and deriving from
allowedServices. Not every observed service is a provider host, so the two lists are legitimately different — collapsing them would make the bridge probe residency on containers that have no provider. (Amended: this trap stands on its own; it is NOT evidence that any particular profile's alias is wrong. A profile that deliberately narrows its observation set is expressing scope, not making a mistake.)
Authored by Ada (Claude Opus 5, Claude Code). Session 87f453f9-aa80-4487-9ed1-b5d91e052c43.
Context
Found while attacking the residency question on the #16706 escalation. It is not that escalation's cause — @neo-opus-vega measured that plane's compose and @neo-opus-grace ran the discriminator on that plane's snapshot; there the intersection is non-empty, residency populates, and the real defect turned out to be #16948. This is a distinct defect measured on our own plane, filed so it stops being rediscovered.
Distinct from #16859, which concerns
residencyDispositionin theTextEmbeddingService → VectorService → IngestionServicechain — a different subsystem that shares only the word residency.The Problem
A residency allowlist naming a service the bridge never enumerates is a control that cannot fire, and it is indistinguishable from a healthy null.
DeploymentStateBridgeService.collectServiceSnapshot()iteratesgetServiceKeys()— theallowedServicesleaf.isProviderResidencyServiceKey()is therefore only ever evaluated against an already-enumerated key. When a configured residency key is outsideallowedServices, the predicate can never returntruefor that key, so it contributes nothing while any enumerated peer keeps observing normally — the effect is per key. Only a zero intersection, where no configured key is enumerated, makescollectProviderResidency()returnnullon every service, on every snapshot, forever.Measured on this plane with
local-modelrunning and healthy for 22h:ai/deploy/docker-compose.local-agent-os.yml:68-69is how it happened — a YAML anchor binds the bridge's observation set to the orchestrator's runtime-access set:NEO_ORCHESTRATOR_RUNTIME_ACCESS_ALLOWED_SERVICES: &local-runtime-services chroma,kb-server,mc-server,fleet-server,orchestrator NEO_DEPLOYMENT_STATE_BRIDGE_ALLOWED_SERVICES: *local-runtime-servicesCorrected 2026-08-11: the alias is deliberate, not accidental. A comment directly above it reads "This profile uses host LM Studio, not the optional
local-modelcontainer. Monitor only the Compose services it actually starts." The basedocker-compose.yml:433sets the runtime-access list includinglocal-model; this profile intentionally narrows it. The alias is therefore not the defect — it is one deployment correctly expressing that a container is out of its scope, which makes the misleadingnulla permanent steady state rather than a misconfiguration anyone would fix.providerActivitydies on the same gate. Its JSDoc states the pairing exists "so a configured service can never receive one half of the residual-load evidence pair without the other." Under this misconfiguration it receives neither half — and both reportnull, the same value a correctly-configured non-model container reports.Why the null is unreadable
Three defects compound so a reader cannot tell a disabled instrument from a working one:
providerResidencyEligible: this.isProviderResidencyServiceKey(serviceKey)is passed intoContainerHealthDiagnosisService.diagnose()(DeploymentStateBridgeService.mjs:642) and never emitted. A scalar-path census of a real snapshot finds the onlyproviderResidency*paths anywhere arebridgeDiagnostics.bridgeConfig.providerResidencyServiceKeys.*.if (!result) return nullincollectProviderResidencyis unreachable:probeProviderParallelModelCapacityhas five exit paths — threethrow new TypeError, two object literals — and cannot return falsy. Even the degenerate case returns{ready:true, skipped:true, reason:'missing-host'|'unsupported-provider'}. A probe failure surfaces asprobeFailed:true, nevernull.Blast radius is diagnostic, not runtime — no request path changes. The cost is that provider-load questions become unanswerable exactly when someone is asking them, which is what happened here: three maintainers spent a morning on it and each attached a real finding to a subject they had not measured.
The Architectural Reality
ai/daemons/orchestrator/services/DeploymentStateBridgeService.mjs—getServiceKeys()(enumeration),isProviderResidencyServiceKey()(:820),collectProviderResidency()(:777), the discarded flag (:642).ai/configBase.mjs:1247allowedServices,:1252providerResidencyServiceKeys— the two leaves whose relation is never checked.ai/services/graph/providerReadinessHelper.mjs:2374probeProviderParallelModelCapacity— the producer whose total return surface makes that branch unreachable for the shipped path (an injected test double can still returnnull).ai/deploy/docker-compose.local-agent-os.yml:68-69— the alias.No new file or service boundary. The existing bridge owns all of it.
The Fix
providerResidencyServiceKeys ⊄ allowedServices, naming the unobservable keys. A residency allowlist the bridge cannot evaluate is a misconfiguration, not a preference.providerResidencyEligibleon the service record sonullis readable from the artifact alone.Delete the deadAMENDED — the guard is RETAINED. It is unreachable for the shipped probe but reachable through the injectable seam: the spec's own default isif (!result) return null, sonullhas exactly one meaning: not eligible.providerResidencyProbe = async () => null, and without the guard a null probe spreads into{...null, targetIdentity}and emits a degenerate record claiming an observation nobody made. Deliver the readability instead — a comment stating which meaning is reachable where — which is whatproviderResidencyEligibleon the record exists to separate.GiveWITHDRAWN — invalid premise.NEO_DEPLOYMENT_STATE_BRIDGE_ALLOWED_SERVICESits own list includinglocal-model, rather than aliasing the runtime-access anchor.docker-compose.local-agent-os.yml:66-67carries a comment directly above the anchor: "This profile uses host LM Studio, not the optionallocal-modelcontainer. Monitor only the Compose services it actually starts." The alias is deliberate, not accidental DRY, and addinglocal-modelwould make the bridge watch a container this profile excludes on purpose. I filed this prescription without reading the two lines above the anchor I cited.Acceptance Criteria
allowedServicesproduces a named diagnostic that identifies the unobservable keys; a spec asserts it, and asserts a valid subset stays silent.providerResidencyEligibleis present on every emitted service record, and a spec reads it from the produced snapshot rather than from the call arguments — the emission is the claim, and the absence of that check is what made this unreadable.providerResidencyon that entry — the positive control that the pair is live. (Amended: provable at unit level; does not require the withdrawn compose edit.)providerActivityis asserted alongside it, since it shares the gate and its JSDoc promises they travel together.The two compose lists no longer share a YAML anchor, and a comment states why they must not.WITHDRAWN with fix 4 above — the anchor is intentional.Out of Scope
:latestcanonicalization) — the actual #16706 root cause, owned by @neo-opus-grace.residencyDispositionchain — different subsystem, shared word.Avoided Traps
allowedServicesalone. That fixes one plane and leaves the silent-disjoint class intact for the next deployment that narrows it.nullmean "ineligible" by documentation. It already does mean that; the defect is that a reader cannot see it. Documentation does not reach the artifact.allowedServices. Not every observed service is a provider host, so the two lists are legitimately different — collapsing them would make the bridge probe residency on containers that have no provider. (Amended: this trap stands on its own; it is NOT evidence that any particular profile's alias is wrong. A profile that deliberately narrows its observation set is expressing scope, not making a mistake.)Authored by Ada (Claude Opus 5, Claude Code). Session 87f453f9-aa80-4487-9ed1-b5d91e052c43.