LearnNewsExamplesServices
Frontmatter
id17278
title`explore_lane_landscape` reports an empty backlog instead of "I could not look"
stateClosed
labels
bugaiarchitectureagent-os
assigneesneo-opus-ada
createdAtAug 17, 2026, 9:57 AM
updatedAtAug 17, 2026, 10:47 AM
githubUrlhttps://github.com/neomjs/neo/issues/17278
authorneo-opus-ada
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtAug 17, 2026, 10:47 AM

explore_lane_landscape reports an empty backlog instead of "I could not look"

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

explore_lane_landscape reports an empty backlog instead of "I could not look"

Scope amendment, 2026-08-17 (review-time, @neo-opus-grace on PR #17280). This ticket originally bundled two things: the payload defect below, and the reason the census fails — no container in the plane holds a GitHub credential. A Resolves #N closes its target on merge regardless of a PR body saying otherwise, so the undelivered half is now its own leaf: #17283. This ticket is scoped to the payload half, which PR #17280 fully delivers.

Context

Found 2026-08-17 while using explore_lane_landscape for next-lane selection at session start. It is the fleet's next-lane awareness engine, and every seat that boots and asks "what should I pick up" reads it.

The Problem

The live return, from a seat picking its first lane:

{"coverage":{"totalOpenItems":0,"edgeCount":3,"degraded":true,
  "degradedReasons":["open issues: page 1 failed (Could not authenticate with GitHub…)",
                     "open pull requests: page 1 failed (…)"]},
 "authorityCoverage":{"assignedCount":0,"unassignedCount":0,"unassignedIds":[]},
 "goalTrajectory":[],"dependencyPath":[],"citations":[],
 "synthesis":{"available":false,"unavailableReason":"coverage-degraded"}}

Nothing there is a lie. degraded is true, the reasons are specific and correct, and the narrative is honestly suppressed. But every count is 0 and every list empty — the same shape a genuinely empty backlog produces. A caller reading totalOpenItems, unassignedIds or goalTrajectory without first branching on degraded gets "there is no work" from a tool whose actual answer is "I could not look".

Suppressing synthesis was the right instinct and shows the shape was considered — but only the narrative half was covered. The census fields stayed confidently populated with zeros.

For a next-lane engine the direction of that error is the bad one: it does not misroute a seat toward the wrong lane, it reports that there are no lanes.

The contract channel carries the same defect. ai/mcp/server/memory-core/openapi.yaml declares totalOpenItems / assignedCount / unassignedCount as type: integer and required. The schema is what a consuming agent reads instead of the payload, so an author who trusts it writes if (coverage.totalOpenItems > 0) — and null > 0 is false. Fixing the payload without the schema reintroduces the defect through the documentation channel.

Contract Ledger

# Surface (live anchor) Delta Source of authority Fallback / degraded Docs Evidence
1 coverage.totalOpenItems (/lanes/landscape response) integerinteger, nullable this ticket null whenever degraded openapi description degraded-path spec
2 coverage.observedOpenItems Additive, always present this ticket n/a — always a number openapi description partial-read spec
3 authorityCoverage.assignedCount / unassignedCount integerinteger, nullable this ticket null whenever degraded openapi description degraded-path spec
4 authorityCoverage.unassignedIds Unchanged — observed evidence, not a completeness claim prior contract stays a list existing description existing spec
5 coverage.edgeCount Unchanged — not a claim about the open-item census prior contract stays a number existing description existing spec
6 buildLaneLandscapeSynthesisPrompt count rendering ?? 0 → explicit unknown this ticket unreachable while the caller gates on degraded JSDoc at the helper prompt spec

Acceptance Criteria

  • A degraded census is not representable as an empty one: totalOpenItems / assignedCount / unassignedCount are null rather than 0.
  • A consumer that ignores degraded entirely cannot conclude "no open work" — asserted as a property (no count in a degraded landscape is a number), not only as three field assertions.
  • Partial reads keep their value: an always-numeric observedOpenItems floor, so a clipped-but-successful walk is not flattened away with the completeness claim it cannot make.
  • The published response schema matches, with the null case explained in the description fields agents actually read — a payload that stopped lying beside a contract that still does is the same defect one channel over.
  • No prompt-facing coercion turns the unknown back into a number before it reaches a model.

Out of Scope

  • The credential cause → #17283. Whether the containerized plane should hold a GitHub credential at all is an architectural fork about the plane's outbound posture, and it is not this ticket's to presume. This ticket's fix is correct under either answer, because a transient GitHub outage produces the same degraded path even with a credential wired.
  • A mechanical implementation↔openapi response-schema link. Nothing failed when the payload's types diverged from the declared ones, and no response validator exists under ai/mcp/** — recorded by @neo-opus-grace as a [TOOLING_GAP] on PR #17280; it is larger than this leaf.

Avoided Traps

  • Fixing the payload and leaving the schema. The schema is the artifact consuming agents read; honesty in one and not the other just moves the lie.
  • Nulling every count. edgeCount is not a completeness claim about the open-item census, and unassignedIds is observed evidence — nulling those would be overreach that discards the usable half of a partial read.
  • Treating the honest degradedReasons as sufficient. The reasons were always correct and present; the defect is that the other fields stayed confidently populated beside them.

Related

#17283 (the credential cause, split out) · PR #17280 · ai/services/graph/laneLandscapeProjection.mjs · ai/services/graph/laneLandscapeSynthesis.mjs · ai/mcp/server/memory-core/openapi.yaml

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

Retrieval Hint: query_raw_memories("explore_lane_landscape degraded totalOpenItems null observedOpenItems empty backlog")

tobiu referenced in commit 2adb25d - "fix(ai): a degraded lane-landscape census reports unknown counts, never zero ones (#17280) on Aug 17, 2026, 10:47 AM
tobiu closed this issue on Aug 17, 2026, 10:47 AM