[Bug][Telemetry][QA] #588 was closed but the fix never reached production — every .NET service STILL reports service.namespace=1.0.0 and no span carries node identity (verified in live Jaeger)
#602
QA Team — regression check on the recently-closed #588.
#588 ("Every service reports service.namespace='1.0.0'… spans also carry no node identity") was closed 2026-07-14 21:35Z. We audited live Jaeger data and the bug is still fully present in production. The fix appears to have merged but never reached the running containers — the same merge-but-never-deploy pattern as #553/#582.
Evidence (live Jaeger, http://192.168.0.105:16686, sampled 2,760 traces / 4,926 spans across all 23 reporting services)
service.namespace is still 1.0.0 on every .NET service — 15 confirmed: DockerMonitor, NodeAgent, SecurityMonitor, SystemRemediation, GpuCoordinator, and EventHandlers ArtPipeProcessor, ArtStudioMetrics, CodeExecution, InfluxDashboard, KeycloakEvents, MetadataExtractor, Notifications, QuizGeneration, SecurityScanner, UploadCoordinator.
Node identity is still absent. No host.name on any SpikerSoft service — only jaeger and traefik carry it, and those are third-party images self-instrumenting. We censused all 56 distinct span tag keys: there is no node/host tag at span level either. service.instance.id is a 12-hex Docker container id (e.g. 54f4d6d146ef), not a node hostname — so you still cannot answer "which node emitted this span".
Why we are confident this is a deploy gap, not a partial rollout:NodeAgent (7 replicas) and CodeExecution (3 replicas) each report multiple distinct service.instance.ids, and every single replica carries the bad value. A partially-deployed fix would show a mix. There is none.
Two variants worth folding in
SpikerSoft API: has neitherservice.namespace nor service.version — only service.instance.id + telemetry.sdk.*. It is on a different instrumentation path from the workers, so whatever fix landed for the workers would not have covered it anyway.
SpikerSoft.GpuCoordinator: service.namespace=1.0.0 but service.versionabsent.
Probable mechanism
Consistent with the registry problem we are reporting on #587: the :latest tag no longer resolves (manifest unknown), so nodes keep running stale cached images. A fix can merge, build, and still never appear in a running container. Recommend not re-closing #588 until service.namespace is verified in live Jaeger, not just in the diff.
Suggested acceptance
Query Jaeger for any SpikerSoft service and assert service.namespace != "1.0.0".
Assert a node-identity tag (host.name or equivalent) is present on spans from a service with >1 replica, and that it differs across nodes.
**QA Team** — regression check on the recently-closed #588.
#588 ("Every service reports `service.namespace='1.0.0'`… spans also carry no node identity") was **closed 2026-07-14 21:35Z**. We audited live Jaeger data and the bug is **still fully present in production**. The fix appears to have merged but never reached the running containers — the same merge-but-never-deploy pattern as #553/#582.
## Evidence (live Jaeger, http://192.168.0.105:16686, sampled 2,760 traces / 4,926 spans across all 23 reporting services)
**`service.namespace` is still `1.0.0` on every .NET service — 15 confirmed:**
`DockerMonitor`, `NodeAgent`, `SecurityMonitor`, `SystemRemediation`, `GpuCoordinator`, and EventHandlers `ArtPipeProcessor`, `ArtStudioMetrics`, `CodeExecution`, `InfluxDashboard`, `KeycloakEvents`, `MetadataExtractor`, `Notifications`, `QuizGeneration`, `SecurityScanner`, `UploadCoordinator`.
**Node identity is still absent.** No `host.name` on any SpikerSoft service — only `jaeger` and `traefik` carry it, and those are third-party images self-instrumenting. We censused all 56 distinct span tag keys: there is no node/host tag at span level either. `service.instance.id` is a 12-hex Docker **container** id (e.g. `54f4d6d146ef`), not a node hostname — so you still cannot answer "which node emitted this span".
**Why we are confident this is a deploy gap, not a partial rollout:** `NodeAgent` (7 replicas) and `CodeExecution` (3 replicas) each report multiple distinct `service.instance.id`s, and **every single replica** carries the bad value. A partially-deployed fix would show a mix. There is none.
## Two variants worth folding in
- **`SpikerSoft API`**: has *neither* `service.namespace` nor `service.version` — only `service.instance.id` + `telemetry.sdk.*`. It is on a different instrumentation path from the workers, so whatever fix landed for the workers would not have covered it anyway.
- **`SpikerSoft.GpuCoordinator`**: `service.namespace=1.0.0` but `service.version` **absent**.
## Probable mechanism
Consistent with the registry problem we are reporting on #587: the `:latest` tag no longer resolves (`manifest unknown`), so nodes keep running stale cached images. A fix can merge, build, and still never appear in a running container. **Recommend not re-closing #588 until `service.namespace` is verified in live Jaeger, not just in the diff.**
## Suggested acceptance
- Query Jaeger for any SpikerSoft service and assert `service.namespace != "1.0.0"`.
- Assert a node-identity tag (`host.name` or equivalent) is present on spans from a service with >1 replica, and that it differs across nodes.
Related: #587 (registry `:latest` missing), #597 (trace-context propagation), #582/#553 (closed-but-never-deployed precedent).
Reconciliation check 2026-07-22 (code vs. ticket): the code side is fully merged, the prod-verification side is not done, so this stays open.
Backend: SpikerSoft.Common/Telemetry/SpikerSoftResource.cs (commit 7425b64c, #588) is on master — named AddService(serviceName:, serviceVersion:) so service.namespace is no longer "1.0.0", plus host.name from NODE_HOSTNAME with container-name fallback.
Infrastructure: PR #82 (merged) passes NODE_HOSTNAME={{.Node.Hostname}} in the .NET service stack files.
What remains is exactly what this ticket is about: confirming every .NET service in live Jaeger now reports a real namespace + node identity, which requires all services redeployed on post-#588 images. Note the open deploy-reliability tickets (#774 silent rollback, #717 superseded builds) are plausible reasons a fleet-wide redeploy silently didn't take. Close only after re-checking live Jaeger.
Reconciliation check 2026-07-22 (code vs. ticket): the **code side is fully merged**, the **prod-verification side is not done**, so this stays open.
- Backend: `SpikerSoft.Common/Telemetry/SpikerSoftResource.cs` (commit 7425b64c, #588) is on master — named `AddService(serviceName:, serviceVersion:)` so `service.namespace` is no longer "1.0.0", plus `host.name` from `NODE_HOSTNAME` with container-name fallback.
- Infrastructure: PR #82 (merged) passes `NODE_HOSTNAME={{.Node.Hostname}}` in the .NET service stack files.
What remains is exactly what this ticket is about: confirming every .NET service in **live Jaeger** now reports a real namespace + node identity, which requires all services redeployed on post-#588 images. Note the open deploy-reliability tickets (#774 silent rollback, #717 superseded builds) are plausible reasons a fleet-wide redeploy silently didn't take. Close only after re-checking live Jaeger.
Audited against origin/master in both repos. The code fix is now complete and adopted fleet-wide — which was not true when this was filed. Deliberately not closing it; see the last paragraph.
Both bugs are fixed at the source.SpikerSoft.Common/Telemetry/SpikerSoftResource.cs:
Create() calls .AddService(serviceName: serviceName, serviceVersion: serviceVersion) with named arguments — the class comment at :14 records the original defect verbatim ("the third positional parameter is serviceNamespace, so every service reported service.namespace = "1.0.0"").
host.name is populated from ResolveNodeHostname() (:44), reading NODE_HOSTNAME and falling back to Environment.MachineName. service.instance.id is kept separately as the container identity, which is the right distinction.
One Create() is used for both the tracing and metrics resource builders (EventHandlers.Infrastructure/Extensions/ServiceCollectionExtensions.cs:150 and :220) — the doc comment notes those two had already drifted, with the metrics one carrying no deployment.environment at all.
Adoption is real, not partial.AddEventHandlerTelemetry is invoked from EventHandlerHostBuilder.cs:99, and 26 worker hosts build on EventHandlerHostBuilder — so every one inherits it rather than each having to opt in. Plus SpikerSoft.Api/Extensions/ServiceCollectionExtensions.cs and EventHandlers.GpuCoordinator/Program.cs directly.
The infrastructure half is wired too.NODE_HOSTNAME now appears in 46 stack files in spikersoft-infrastructure (of 81 docker-stack*.yml total — the remainder are non-.NET stacks that never emitted spans). When this ticket was written, SpikerSoftResourceTests.cs:100 still carried the note that "the stack files are a separate repo, so services will run without NODE_HOSTNAME for a while." That gap has closed.
Regression coverage exists for both, pinned to the observed symptoms: SpikerSoftResourceTests.cs:63ServiceNamespace_IsNotTheVersion, :92 asserting host.name == "dreamstream4" from an interpolated NODE_HOSTNAME, and :105 asserting the machine-name fallback.
Why I'm leaving this open. This ticket exists precisely because #588 was closed on a merged PR while production still showed the broken values. Closing it again on code-completeness alone would repeat that mistake exactly. The remaining step is the one that originally failed: confirm in live Jaeger that spans now carry a real service.namespace (not 1.0.0) and a populated host.name. One person, one query — then close with the result recorded here.
Audited against `origin/master` in both repos. **The code fix is now complete and adopted fleet-wide** — which was not true when this was filed. Deliberately **not** closing it; see the last paragraph.
**Both bugs are fixed at the source.** `SpikerSoft.Common/Telemetry/SpikerSoftResource.cs`:
- `Create()` calls `.AddService(serviceName: serviceName, serviceVersion: serviceVersion)` with **named arguments** — the class comment at `:14` records the original defect verbatim ("the third positional parameter is `serviceNamespace`, so every service reported `service.namespace = "1.0.0"`").
- `host.name` is populated from `ResolveNodeHostname()` (`:44`), reading `NODE_HOSTNAME` and falling back to `Environment.MachineName`. `service.instance.id` is kept separately as the container identity, which is the right distinction.
- One `Create()` is used for **both** the tracing and metrics resource builders (`EventHandlers.Infrastructure/Extensions/ServiceCollectionExtensions.cs:150` and `:220`) — the doc comment notes those two had already drifted, with the metrics one carrying no `deployment.environment` at all.
**Adoption is real, not partial.** `AddEventHandlerTelemetry` is invoked from `EventHandlerHostBuilder.cs:99`, and **26 worker hosts** build on `EventHandlerHostBuilder` — so every one inherits it rather than each having to opt in. Plus `SpikerSoft.Api/Extensions/ServiceCollectionExtensions.cs` and `EventHandlers.GpuCoordinator/Program.cs` directly.
**The infrastructure half is wired too.** `NODE_HOSTNAME` now appears in **46 stack files** in spikersoft-infrastructure (of 81 `docker-stack*.yml` total — the remainder are non-.NET stacks that never emitted spans). When this ticket was written, `SpikerSoftResourceTests.cs:100` still carried the note that "the stack files are a separate repo, so services will run without NODE_HOSTNAME for a while." That gap has closed.
**Regression coverage exists for both**, pinned to the observed symptoms: `SpikerSoftResourceTests.cs:63` `ServiceNamespace_IsNotTheVersion`, `:92` asserting `host.name == "dreamstream4"` from an interpolated `NODE_HOSTNAME`, and `:105` asserting the machine-name fallback.
**Why I'm leaving this open.** This ticket exists precisely because #588 was closed on a merged PR while production still showed the broken values. Closing it again on code-completeness alone would repeat that mistake exactly. The remaining step is the one that originally failed: confirm in **live Jaeger** that spans now carry a real `service.namespace` (not `1.0.0`) and a populated `host.name`. One person, one query — then close with the result recorded here.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
QA Team — regression check on the recently-closed #588.
#588 ("Every service reports
service.namespace='1.0.0'… spans also carry no node identity") was closed 2026-07-14 21:35Z. We audited live Jaeger data and the bug is still fully present in production. The fix appears to have merged but never reached the running containers — the same merge-but-never-deploy pattern as #553/#582.Evidence (live Jaeger, http://192.168.0.105:16686, sampled 2,760 traces / 4,926 spans across all 23 reporting services)
service.namespaceis still1.0.0on every .NET service — 15 confirmed:DockerMonitor,NodeAgent,SecurityMonitor,SystemRemediation,GpuCoordinator, and EventHandlersArtPipeProcessor,ArtStudioMetrics,CodeExecution,InfluxDashboard,KeycloakEvents,MetadataExtractor,Notifications,QuizGeneration,SecurityScanner,UploadCoordinator.Node identity is still absent. No
host.nameon any SpikerSoft service — onlyjaegerandtraefikcarry it, and those are third-party images self-instrumenting. We censused all 56 distinct span tag keys: there is no node/host tag at span level either.service.instance.idis a 12-hex Docker container id (e.g.54f4d6d146ef), not a node hostname — so you still cannot answer "which node emitted this span".Why we are confident this is a deploy gap, not a partial rollout:
NodeAgent(7 replicas) andCodeExecution(3 replicas) each report multiple distinctservice.instance.ids, and every single replica carries the bad value. A partially-deployed fix would show a mix. There is none.Two variants worth folding in
SpikerSoft API: has neitherservice.namespacenorservice.version— onlyservice.instance.id+telemetry.sdk.*. It is on a different instrumentation path from the workers, so whatever fix landed for the workers would not have covered it anyway.SpikerSoft.GpuCoordinator:service.namespace=1.0.0butservice.versionabsent.Probable mechanism
Consistent with the registry problem we are reporting on #587: the
:latesttag no longer resolves (manifest unknown), so nodes keep running stale cached images. A fix can merge, build, and still never appear in a running container. Recommend not re-closing #588 untilservice.namespaceis verified in live Jaeger, not just in the diff.Suggested acceptance
service.namespace != "1.0.0".host.nameor equivalent) is present on spans from a service with >1 replica, and that it differs across nodes.Related: #587 (registry
:latestmissing), #597 (trace-context propagation), #582/#553 (closed-but-never-deployed precedent).Reconciliation check 2026-07-22 (code vs. ticket): the code side is fully merged, the prod-verification side is not done, so this stays open.
SpikerSoft.Common/Telemetry/SpikerSoftResource.cs(commit 7425b64c, #588) is on master — namedAddService(serviceName:, serviceVersion:)soservice.namespaceis no longer "1.0.0", plushost.namefromNODE_HOSTNAMEwith container-name fallback.NODE_HOSTNAME={{.Node.Hostname}}in the .NET service stack files.What remains is exactly what this ticket is about: confirming every .NET service in live Jaeger now reports a real namespace + node identity, which requires all services redeployed on post-#588 images. Note the open deploy-reliability tickets (#774 silent rollback, #717 superseded builds) are plausible reasons a fleet-wide redeploy silently didn't take. Close only after re-checking live Jaeger.
Audited against
origin/masterin both repos. The code fix is now complete and adopted fleet-wide — which was not true when this was filed. Deliberately not closing it; see the last paragraph.Both bugs are fixed at the source.
SpikerSoft.Common/Telemetry/SpikerSoftResource.cs:Create()calls.AddService(serviceName: serviceName, serviceVersion: serviceVersion)with named arguments — the class comment at:14records the original defect verbatim ("the third positional parameter isserviceNamespace, so every service reportedservice.namespace = "1.0.0"").host.nameis populated fromResolveNodeHostname()(:44), readingNODE_HOSTNAMEand falling back toEnvironment.MachineName.service.instance.idis kept separately as the container identity, which is the right distinction.Create()is used for both the tracing and metrics resource builders (EventHandlers.Infrastructure/Extensions/ServiceCollectionExtensions.cs:150and:220) — the doc comment notes those two had already drifted, with the metrics one carrying nodeployment.environmentat all.Adoption is real, not partial.
AddEventHandlerTelemetryis invoked fromEventHandlerHostBuilder.cs:99, and 26 worker hosts build onEventHandlerHostBuilder— so every one inherits it rather than each having to opt in. PlusSpikerSoft.Api/Extensions/ServiceCollectionExtensions.csandEventHandlers.GpuCoordinator/Program.csdirectly.The infrastructure half is wired too.
NODE_HOSTNAMEnow appears in 46 stack files in spikersoft-infrastructure (of 81docker-stack*.ymltotal — the remainder are non-.NET stacks that never emitted spans). When this ticket was written,SpikerSoftResourceTests.cs:100still carried the note that "the stack files are a separate repo, so services will run without NODE_HOSTNAME for a while." That gap has closed.Regression coverage exists for both, pinned to the observed symptoms:
SpikerSoftResourceTests.cs:63ServiceNamespace_IsNotTheVersion,:92assertinghost.name == "dreamstream4"from an interpolatedNODE_HOSTNAME, and:105asserting the machine-name fallback.Why I'm leaving this open. This ticket exists precisely because #588 was closed on a merged PR while production still showed the broken values. Closing it again on code-completeness alone would repeat that mistake exactly. The remaining step is the one that originally failed: confirm in live Jaeger that spans now carry a real
service.namespace(not1.0.0) and a populatedhost.name. One person, one query — then close with the result recorded here.