LearnNewsExamplesServices
Frontmatter
id17283
titleThe containerized census reports "degraded" where it should report "unavailable on this plane" — GitHub reads are host-edge by design
stateClosed
labels
bugaiarchitectureagent-os
assignees[]
createdAtAug 17, 2026, 10:16 AM
updatedAtAug 24, 2026, 7:05 AM
githubUrlhttps://github.com/neomjs/neo/issues/17283
authorneo-opus-ada
commentsCount3
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtAug 24, 2026, 7:05 AM

The containerized census reports "degraded" where it should report "unavailable on this plane" — GitHub reads are host-edge by design

Closed Backlog/active-chunk-17 bugaiarchitectureagent-os
neo-opus-ada
neo-opus-ada commented on Aug 17, 2026, 10:16 AM

Context

Split out of #17278 at review time. #17278 bundled two things: a payload that reported an empty backlog when it meant "I could not look" (delivered by PR #17280), and the reason the census failed in the first place — this ticket. @neo-opus-grace flagged the bundling on PR #17280: a Resolves #17278 closes the ticket on merge regardless of a PR body saying it stays open, so the undelivered half needs its own leaf.

The Problem

GraphqlService.#getAuthToken() (ai/services/github-workflow/GraphqlService.mjs:127-149) resolves in three branches: an explicit override → GH_TOKEN / GITHUB_TOKENgh auth token via subprocess. Measured inside the running plane, every branch fails by construction:

container GH_TOKEN GITHUB_TOKEN gh binary
mc-server unset unset absent
orchestrator unset unset
kb-server unset unset
fleet-server unset unset

A container has no gh binary and no keychain to hold a login, so the third branch is not a fallback there — it is dead code. The host is unaffected (gh auth token exits 0), which is exactly why this stayed invisible: every diagnosis run from a shell succeeds.

Observed symptom: explore_lane_landscape degrades on every call, its census reading zero items. That symptom's reporting is fixed by PR #17280; the cause is here.

The Fork — this ticket exists to decide it, not to presume it

Both readings are defensible and the choice belongs to whoever owns the plane's outbound stance:

  1. The plane SHOULD read GitHub. Then a credential is wired into the compose environment for the services that need it, scoped to those services, and the gh auth token branch is documented as host-only so the next reader does not treat it as a container fallback.
  2. The plane should NOT read GitHub. Then a container-side census is the wrong architecture: explore_lane_landscape either moves to a host-side reader or declares the capability unavailable on this plane rather than attempting a call that cannot succeed. Note this reading also means the current code is asking for a credential it is not supposed to have, which is its own smell.

Deliberately not decided by the filer. Wiring a PAT into four containers to quiet one tool would be widening a security boundary to silence a symptom, and the plane may be credential-free on purpose.

Acceptance Criteria

  • The fork is decided and the decision is recorded where a reader of the deployment will find it — not only in this ticket.
  • If (1): a probe from inside a container proves the census returns a non-zero count; the credential is scoped to the services that need it rather than the whole plane; and GraphqlService's third branch names its host-only nature at the point a reader meets it.
  • If (2): no container-side code path attempts a GitHub read that cannot succeed — the capability reports unavailable rather than degraded, since "degraded" implies it could have worked.
  • Either way, the sweep question is answered: which other containerized consumers silently degrade without GitHub? orchestrator sync tasks are the obvious candidate and were not measured beyond their env.

Out of Scope

  • The payload-honesty half — delivered by PR #17280 on #17278. That fix is correct under either answer here, because a transient GitHub outage produces the same degraded path even with a credential wired.
  • Broadening any container's outbound network posture beyond what the fork decides.

Avoided Traps

  • Wiring a token because it makes the error stop. That is the symptom-silencing path, and it widens a boundary by default.
  • Assuming the gh auth token branch is a fallback everywhere. It is host-only by construction; treating it as universal is what let this survive.

Related

#17278 (the symptom's reporting — the payload half) · PR #17280 · ai/services/github-workflow/GraphqlService.mjs:127-149 · ai/deploy/docker-compose.local-agent-os.yml · ai/services/graph/laneLandscapeCensusSource.mjs

Live latest-open sweep: open queue checked 2026-08-17T08:0xZ; the only adjacent item is #17278, which this splits from by reviewer request.

Origin Session ID: 80b326bf-b37a-4efd-8313-1a9eae09e9c4

tobiu referenced in commit 9932ccf - "fix(ai): the lane-landscape census refuses on this plane instead of reaching across it (#17285) (#17324) on Aug 18, 2026, 11:32 AM