Description
Raised by the SKT-0008 producer validation, 2026-08-27, and decided by the root.
Both self-emitting lanes hard-code STATUS_CODE_OK on their success rows. Their own trace lanes stamp otlp.StatusUnset on every non-failed span, which is correct OTel behaviour — semconv leaves a server-span status unset unless there is an error. So a real metrics-generator fed synthkit own trace stream would derive status_code="STATUS_CODE_UNSET" for those rows, and synthkit self-emits STATUS_CODE_OK.
Neither constant is wrong against reality. Real estates contain both: gRPC instrumentation sets OK explicitly, HTTP instrumentation usually leaves it unset. signals/apm.md documents all three values as real. Picking one by preference would be arbitrary.
Decision: derive, do not choose. synthkit two lanes must agree with each other. Request correlation is a core property of this generator, and self-emitted span metrics that contradict the trace stream they claim to be derived from is a defect no real deployment has — a user joining spans to span-metrics by status gets an empty result against synthkit and a populated one against production. So the status on a span-metric row must come from the same source the trace lane stamps, rather than from a constant in the metrics path.
Cross-lane by construction: internal/workload/app/spanmetrics.go and internal/workload/webservice/metrics.go must move together or not at all, and internal/dashgen must stop matching a success denominator as status_code="STATUS_CODE_OK" — matching status_code!="STATUS_CODE_ERROR" is also what a panel built against a real generator has to do.
Acceptance Criteria
- #1 The status on a span-metric row is derived from the same status the trace lane stamps for that span, not from a constant
- #2 Both the app and web_service lanes change together, and a test proves the two lanes agree
- #3 Generated dashboards compute the success denominator as not-error rather than equals-OK
- #4 signals/apm.md records the derivation and why an arbitrary constant was rejected
Definition of Done
- #1 make gate (build vet test race rw-proto-check spdx-check forbidden-words)
- #2 make blueprint-schema (only if a blueprint field or construct/workload config struct changed)
- #3 DRY_RUN=true go run ./cmd/synthkit -once -dump — inventory diffed against signals/
Implementation Plan
Write failing tests for app/web_service status disagreement and dashboard equals-OK selection, then derive span-metric status from the trace-lane source in both workloads and change dashboard success to not-error.
Implementation Notes
2026-09-02 validation: failing regressions first proved the app and web-service mismatch and equals-OK dashboard selector. Both workloads now derive span-metric status from their trace helpers; the dashboard denominator selects status_code not equal to STATUS_CODE_ERROR; signals/apm.md records the derivation. Focused tests, integrated just check, and just dump passed; generation was not applicable.
Final Summary
2026-09-02: Derived span-metric status from the trace lane in both workloads and corrected the dashboard denominator to not-error, with focused regression coverage and green integrated gates.