merge: bring the traces_endpoint rename forward from phase-10

Three conflicts, all between this branch's own sync-diagnostics work and
phase-10's older versions. Resolved to this branch in each case, since it
owns the newer content:

- InboundLedger.h keeps the missing-node and receive-depth gauges and the
  fuller acquire-span contract.
- MetricsRegistry.cpp keeps the namespaced label:: constants.
- LedgerMaster.cpp keeps makeLedgerTraceSpan(), which joins the store and
  validate spans into one per-ledger trace by hash.

LedgerMaster.cpp needed a second pass. The automatic merge had kept both
sides outside the conflict markers, nesting phase-10's older promotion
block inside this branch's `if (!pubLedger_)` — so setValidated,
setFull and setValidLedger would each have run twice. Taking this
branch's file wholesale removes the duplicate; brace balance and a single
"Advancing accepted ledger" confirm it.

That resolution drops two things phase-10 was carrying into this file:
the storeSpan/validateSpan guard names, and the explicit scope that keeps
the one-in-256 flag-ledger check outside the ledger.validate measurement.
Both are re-applied on this branch in the next commit; the scope needs a
variable-lifetime check that does not belong in a merge.
This commit is contained in:
Pratik Mankawde
2026-09-03 16:12:07 +01:00
53 changed files with 877 additions and 555 deletions

View File

@@ -2,13 +2,13 @@
"""Assert the C++ millisecond ladder agrees with the collector's spanmetrics ladder.
The two are specified to match so a span-derived latency panel and a native
histogram panel can be read on the same scale. They *were* identical when first
shipped. Then the collector ladder alone was extended -- sub-millisecond edges
below 1ms and second-scale edges up to 30s -- and nothing checked the other
side, so the C++ ladder stayed capped at 5s. Every quantile above 5s then read
back as a flat 5000, because Prometheus returns the second-highest edge for a
quantile landing in the `+Inf` bucket. That looks like a measurement rather
than an error, which is why it survived for eleven phases.
histogram panel can be read on the same scale. Nothing else couples them, so
extending one ladder alone -- sub-millisecond edges below 1ms, second-scale
edges up to 30s -- silently leaves the other short. That failure is quiet:
Prometheus returns the second-highest edge for a quantile landing in the
`+Inf` bucket, so every quantile above a too-low ceiling reads back as a flat
number that looks like a measurement rather than an error. This check is what
makes the drift loud.
The rule is containment, not equality:
@@ -17,7 +17,7 @@ The rule is containment, not equality:
* the C++ ladder MAY carry extra edges ABOVE the collector's highest edge,
because jobs outlive spans -- the updatepaths job type was measured
averaging ~60s, which no span approaches. Demanding equality would force a
ceiling that censors it, reintroducing the bug this guards against;
ceiling that censors it, recreating the failure this guards against;
* collector edges below 1ms are expected to be ABSENT rather than missing:
beast::insight::Event rounds every duration up to a whole millisecond
before it reaches the histogram, so those edges could never collect a
@@ -117,8 +117,10 @@ def main():
)
print(
"\nThe two ladders must agree over their shared range. Extra C++ edges are\n"
"permitted only ABOVE the collector's highest edge. Change both sides, or\n"
"change the spec in OpenTelemetryPlan/Phase7_taskList.md.",
"permitted only ABOVE the collector's highest edge. To re-price the shared\n"
f"range, edit the ladder in {HEADER} and the\n"
f"spanmetrics 'buckets:' list in {COLLECTOR}\n"
"in the same change, so both sides stay in step.",
file=sys.stderr,
)
return 1

View File

@@ -93,8 +93,7 @@ class CheckerCase(unittest.TestCase):
Read from the scratch copies of the real inputs rather than written as
literals, because a literal here is a copy of one particular baseline:
two of these tests previously hard-coded values from the 2026-08-24
capture and both broke the moment the baseline was refreshed, which is
a hard-coded figure breaks the moment the baseline is refreshed, which is
the very drift check_regression_bounds.py exists to catch. Deriving the
figure keeps the assertion pinned to the rule instead of to a snapshot.
"""