Context
PR #13986 resolved #13984, so #13984 must remain closed. This ticket owns the follow-up defect instead of reopening a resolved ticket.
Follow-up evidence from 2026-06-25 shows two separate runtime observability failures in the REM/topology path:
- The LMS developer console showed topology-conflict chat requests reaching prompt processing completion and finishing streamed responses, but it did not expose the streamed chat response bodies. Neo-side topology result logging therefore has to be the source of truth.
- The LMS developer console is also being spammed by diagnostic daemon / health cache debug logs roughly every 20s, including repeated health-cache churn such as
[HealthService] Cache cleared, next health check will be fresh. Diagnostics still need durable logs, but not by burying meaningful user-facing model lifecycle entries.
Live latest-open sweep: checked the latest 30 open issues at 2026-06-25T09:29:11Z. #13994 covers the separate 400k token counter/provider-context contamination investigation, but no open ticket covers topology result observability plus diagnostic log-channel hygiene.
A2A in-flight sweep: checked the latest 30 all-status A2A messages immediately before filing. The only overlapping claim was my stale #13984 follow-up claim, which this ticket supersedes because #13984 is closed and must stay closed.
KB sweep: queried TopologyInferenceEngine topologyConflicts LMS developer console diagnostic health log spam maxCompletionTokens HealthService Cache cleared; results surfaced general health/log observability prior art but no equivalent ticket for this failure mode.
Release classification: boardless live Agent OS reliability / developer-experience bug. It should only be project-attached if the operator explicitly marks this release-gating.
The Problem
Operators cannot currently tell what topology REM calls returned when the provider accepts and processes the request:
- LMS developer logs expose request/model lifecycle data, not the streamed chat completion body.
TopologyInferenceEngine logs extraction start and conflict persistence, but successful zero-conflict responses are silent.
- Non-empty but unparseable topology responses can collapse into the same practical outcome as zero conflicts, which hides parser/schema drift.
- The topology provider options do not pass an output cap, so the graph-output budget is not enforced at the provider boundary.
- The diagnostic daemon / health path emits high-frequency cache/debug noise into a user-facing log stream, making meaningful LMS model lifecycle lines hard to find.
The combined effect is bad: the model can process several topology prompts to completion, yet the operator sees neither the actual parsed outcome nor a clean log channel where the meaningful evidence is visible.
The Architectural Reality
ai/services/graph/TopologyInferenceEngine.mjs:getTopologyProviderOptions() currently prepares topology provider options without a maxCompletionTokens cap.
ai/services/graph/TopologyInferenceEngine.mjs:extractTopology() dispatches the provider call and parses Json.extract(result.content), then treats empty/zero-conflict outcomes as successful no-op returns.
ai/provider/OpenAiCompatible.mjs already maps maxCompletionTokens to payload.max_tokens when supplied, so the topology path should use the existing provider boundary rather than inventing a new mechanism.
ai/services/memory-core/HealthService.mjs:clearCache() emits [HealthService] Cache cleared, next health check will be fresh; runtime diagnostic activity can repeat this frequently enough to pollute developer-facing logs.
learn/agentos/incidents/sandman-silent-failure-forensics.md already identifies topology extraction as a silent-failure surface; this ticket narrows that into concrete provider-budget and logging ACs.
The Fix
- Pass a bounded topology output cap through existing provider options, using the AiConfig local-model chat graph output setting as the source of authority. Do not add env rereads, hidden defaults, optional-config fallbacks, or config pass-through that violates ADR 0019.
- Reserve output budget before topology prompt dispatch so graph chunking cannot spend the entire context window on input and leave unbounded output behavior to the provider.
- Add per-call topology outcome diagnostics that are useful without dumping full session/model content: session id, chunk index/count when available, estimated input tokens, output cap, finish reason if available, response character count, parsed conflict count, and parse-failure state.
- Treat non-empty but unparseable topology output as explicit parse failure / ConsumerFriction, not as
conflictCount: 0.
- Add a concise success outcome for valid zero-conflict topology responses so
no outcome log stops being a diagnostic blind spot.
- Route high-frequency diagnostic health/cache churn away from user-facing/LMS-visible logs while still preserving durable diagnostic logs for forensic use.
- Add focused unit coverage for the provider cap, zero-conflict logging, parse-failure logging, and health-cache log demotion/routing.
Contract Ledger Matrix
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback |
Docs |
Evidence |
| Topology provider options |
TopologyInferenceEngine.getTopologyProviderOptions() + ADR 0019 AiConfig SSOT |
Include bounded output cap via existing provider option contract |
Fail loud if required AiConfig leaf is invalid; no hidden defaults |
Existing AiConfig / ADR 0019 docs |
Unit test asserts OpenAI-compatible payload includes bounded output |
| Topology result diagnostics |
TopologyInferenceEngine.extractTopology() |
Emit bounded outcome metadata for zero, parsed, and parse-failed results |
ConsumerFriction / typed diagnostic for parse failure |
Incident note plus test names |
Unit tests cover zero-conflict and invalid JSON-like output |
| Diagnostic health/cache logging |
HealthService.clearCache() and diagnostic daemon log routing |
Preserve durable diagnostics without spamming developer-facing/LMS-visible logs |
Route to durable diagnostic file/log channel at lower console severity |
Existing logging patterns |
Test/log assertion covers repeated cache clear behavior |
| LMS developer console signal hygiene |
Operator-visible model lifecycle stream |
Meaningful model lifecycle entries remain visible; diagnostic churn is not mixed into the same high-volume channel |
Durable diagnostics remain searchable elsewhere |
Ticket body |
Manual runtime check or focused log-channel test |
Decision Record impact
Aligned with ADR 0019. This ticket must use AiConfig as the reactive Provider SSOT and must not introduce env rereads, hidden defaults, defensive optional leaves, or local config type-casts.
Acceptance Criteria
Out of Scope
- Reopening #13984.
- Reworking the merged #13986 ticket lifecycle.
- Duplicating #13994's provider-context / 400k token contamination investigation.
- Adding a new public MCP tool for this bug.
- Logging full model responses, full session payloads, or private user transcript content.
- Changing LMS itself.
Avoided Traps
- A new MCP diagnostic tool is not warranted for this bug; the failure is in existing provider-budgeting and log-channel behavior.
- Logging everything to the console would make the operator symptom worse. Diagnostics need durable persistence plus channel separation, not more user-facing spam.
- Treating zero-conflict and parse-failed topology responses as the same no-op would preserve the silent failure mode.
Related
#13984
#13986
#13994
#12073
#12768
Origin Session ID: 1583113d-4deb-455a-bee4-16521e9d1479
Handoff Retrieval Hint: TopologyInferenceEngine topologyConflicts LMS developer console HealthService Cache cleared log spam maxCompletionTokens parse failure zero conflicts
Context
PR #13986 resolved #13984, so #13984 must remain closed. This ticket owns the follow-up defect instead of reopening a resolved ticket.
Follow-up evidence from 2026-06-25 shows two separate runtime observability failures in the REM/topology path:
[HealthService] Cache cleared, next health check will be fresh. Diagnostics still need durable logs, but not by burying meaningful user-facing model lifecycle entries.Live latest-open sweep: checked the latest 30 open issues at 2026-06-25T09:29:11Z. #13994 covers the separate 400k token counter/provider-context contamination investigation, but no open ticket covers topology result observability plus diagnostic log-channel hygiene.
A2A in-flight sweep: checked the latest 30 all-status A2A messages immediately before filing. The only overlapping claim was my stale #13984 follow-up claim, which this ticket supersedes because #13984 is closed and must stay closed.
KB sweep: queried
TopologyInferenceEngine topologyConflicts LMS developer console diagnostic health log spam maxCompletionTokens HealthService Cache cleared; results surfaced general health/log observability prior art but no equivalent ticket for this failure mode.Release classification: boardless live Agent OS reliability / developer-experience bug. It should only be project-attached if the operator explicitly marks this release-gating.
The Problem
Operators cannot currently tell what topology REM calls returned when the provider accepts and processes the request:
TopologyInferenceEnginelogs extraction start and conflict persistence, but successful zero-conflict responses are silent.The combined effect is bad: the model can process several topology prompts to completion, yet the operator sees neither the actual parsed outcome nor a clean log channel where the meaningful evidence is visible.
The Architectural Reality
ai/services/graph/TopologyInferenceEngine.mjs:getTopologyProviderOptions()currently prepares topology provider options without amaxCompletionTokenscap.ai/services/graph/TopologyInferenceEngine.mjs:extractTopology()dispatches the provider call and parsesJson.extract(result.content), then treats empty/zero-conflict outcomes as successful no-op returns.ai/provider/OpenAiCompatible.mjsalready mapsmaxCompletionTokenstopayload.max_tokenswhen supplied, so the topology path should use the existing provider boundary rather than inventing a new mechanism.ai/services/memory-core/HealthService.mjs:clearCache()emits[HealthService] Cache cleared, next health check will be fresh; runtime diagnostic activity can repeat this frequently enough to pollute developer-facing logs.learn/agentos/incidents/sandman-silent-failure-forensics.mdalready identifies topology extraction as a silent-failure surface; this ticket narrows that into concrete provider-budget and logging ACs.The Fix
conflictCount: 0.no outcome logstops being a diagnostic blind spot.Contract Ledger Matrix
TopologyInferenceEngine.getTopologyProviderOptions()+ ADR 0019 AiConfig SSOTTopologyInferenceEngine.extractTopology()HealthService.clearCache()and diagnostic daemon log routingDecision Record impact
Aligned with ADR 0019. This ticket must use AiConfig as the reactive Provider SSOT and must not introduce env rereads, hidden defaults, defensive optional leaves, or local config type-casts.
Acceptance Criteria
max_tokenswhen topology extraction runs.{"conflicts":[]}topology responses produce a bounded Neo-side outcome log/state entry.conflictCount: 0.Out of Scope
Avoided Traps
Related
#13984 #13986 #13994 #12073 #12768
Origin Session ID: 1583113d-4deb-455a-bee4-16521e9d1479
Handoff Retrieval Hint:
TopologyInferenceEngine topologyConflicts LMS developer console HealthService Cache cleared log spam maxCompletionTokens parse failure zero conflicts