Gate any metric of any grid point, and let every matching threshold fire - #1018
Draft
epompeii wants to merge 1 commit into
Draft
Gate any metric of any grid point, and let every matching threshold fire#1018epompeii wants to merge 1 commit into
epompeii wants to merge 1 commit into
Conversation
epompeii
force-pushed
the
u/ep/parameters-api/thresholds
branch
2 times, most recently
from
August 26, 2026 10:19
abd44e8 to
70525c7
Compare
Contributor
|
| Project | Bencher |
| Branch | u/ep/parameters-api/thresholds |
| Testbed | intel-v1 |
Click to view all benchmark results
| Benchmark | Latency | Benchmark Result microseconds (µs) (Result Δ%) | Upper Boundary microseconds (µs) (Limit %) |
|---|---|---|---|
| Adapter::Json | 📈 view plot 🚷 view threshold | 5.26 µs(+10.33%)Baseline: 4.77 µs | 5.60 µs (93.82%) |
| Adapter::Magic (JSON) | 📈 view plot 🚷 view threshold | 5.07 µs(+9.54%)Baseline: 4.62 µs | 5.38 µs (94.12%) |
| Adapter::Magic (Rust) | 📈 view plot 🚷 view threshold | 27.45 µs(+5.08%)Baseline: 26.12 µs | 28.60 µs (95.97%) |
| Adapter::Rust | 📈 view plot 🚷 view threshold | 4.65 µs(+25.54%)Baseline: 3.71 µs | 5.39 µs (86.27%) |
| Adapter::RustBench | 📈 view plot 🚷 view threshold | 4.65 µs(+25.69%)Baseline: 3.70 µs | 5.37 µs (86.63%) |
epompeii
force-pushed
the
u/ep/parameters-api/thresholds
branch
from
August 26, 2026 12:18
70525c7 to
5d16149
Compare
epompeii
force-pushed
the
u/ep/parameters-api/thresholds
branch
from
August 27, 2026 03:46
5d16149 to
1a3e5a0
Compare
A threshold gated one thing: the `value` scalar of every grid point of its measure. A benchmark now reports as many grid points as it has parameter sets and as many named scalars as its harness measured, and neither was addressable. A project that wanted `p99` watched on the one configuration where it matters had nowhere to say so. A threshold gains two optional fields. `metric` is the name it gates, and a threshold that names none gates the conventional `value` name: a threshold always gates exactly one name and a bare one never gates all of them. `parameters` is a filter over grid points, a list of parameter sets that is an OR across the list and a subset match within each set, and a threshold with no filter gates every grid point. Both defaults are what every existing threshold already does, so no existing row moves and no project's alert volume changes. Every threshold that matches a metric row runs. There is no winner: not in gating, not in display. A grid point that a bare threshold and a filtered threshold both match earns a boundary from each and, on a regression, an alert from each. That is the design and it is pinned by a test, because a row that two people asked to be watched is a row two people hear about. Identity is the three dimensions plus the two new fields, under the null semantics they carry. SQLite treats nulls as distinct in a unique index, so two bare thresholds on one branch, testbed, and measure would no longer collide under a plain unique key over the five columns. The key is declared over the effective values instead, `COALESCE(metric, 'value')` and `COALESCE(parameters, x'')`, and the wire canonicalizes into them: an explicit `value` and an absent name are one threshold, an empty filter and an absent one are one threshold, and a filter has one spelling because its sets sort by their RFC 8785 canonical bytes and duplicates collapse. A threshold gates the sample it names. The historical query behind detection filters on the threshold's metric name, so a threshold on `p99` is tested against `p99` rows and never against the `value` rows beside them, and the per grid point separation stays exactly as it was. `boundary` keys on `(metric_id, threshold_id)` rather than on `metric_id` alone, because a metric row may now carry a boundary per threshold that gated it. Both tables are rebuilt with their unique keys built after the copy, which is what keeps the rebuild at the cost of the scan. `JsonAlert` gains `value`, the scalar the alert fired on, and its `metric` triple becomes optional: the triple is a convention over the `value` name, so an alert on any other name has none. Every alert that a threshold could raise before this carries the triple exactly as it did. The gated name is readable at `alert.threshold.metric`. The deprecated singular `threshold`, `boundary`, and `alert` fields carry the bare threshold's gate and no other's, everywhere they appear. That is precisely what a caller from before named gating has always been shown: a row that only a named or filtered threshold gates reports no gate in them at all. Where a list of boundaries is returned, it is ordered by threshold creation time, oldest first, with the UUID breaking a tie. The in-report `thresholds.models` map is unchanged and still addresses the bare threshold: a map that names a measure and a model says nothing about a name or a grid point, so it neither creates nor resets anything narrower.
epompeii
force-pushed
the
u/ep/parameters-api/thresholds
branch
from
August 27, 2026 05:11
1a3e5a0 to
6b139dc
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A threshold gated one thing: the
valuescalar of every grid point of its measure.A benchmark now reports as many grid points as it has parameter sets and as many
named scalars as its harness measured, and neither was addressable. A project that
wanted
p99watched on the one configuration where it matters had nowhere to sayso.
The model
A threshold gains two optional fields.
metricis the name it gates. A threshold that names none gates the conventionalvaluename: a threshold always gates exactly one name, and a bare one never gatesall of them.
parametersis a filter over grid points: a list of parameter sets, an OR acrossthe list and a subset match within each set. A filter names only the keys it cares
about, so
[{"size": 512}]matches a grid point that also pinsthreads. Athreshold with no filter gates every grid point.
Both defaults are what every threshold already does, so no existing row moves and no
project's alert volume changes.
Every matching threshold fires
There is no winner: not in gating, not in display. A grid point that a bare
threshold and a filtered threshold both match earns a boundary from each and, on a
regression, an alert from each. Two thresholds asked for that row to be watched, so
two of them are told about it. This is deliberate and it is pinned by a test rather
than smoothed over.
Identity, and the null semantics
Identity is the three dimensions plus the two new fields, under the null semantics
they carry. SQLite treats nulls as distinct in a unique index, so two bare
thresholds on one branch, testbed, and measure would no longer collide under a plain
unique key over the five columns, and an explicit
valuewould sit beside an absentone.
The key is declared over the effective values instead:
x''is a value no stored filter can take, because a filter that matches everythingis stored as
NULL.The wire canonicalizes into those stored values. An explicit
valueand an absentname are one threshold. An empty filter, a filter holding the empty set, and an
absent filter are one threshold, because the empty set is a subset of every grid
point. A filter has one spelling, because its sets sort by their RFC 8785 canonical
bytes and duplicates collapse, so
[{"a": 1}, {"a": 1.0}]is one set. The wireaccepts any order and any spelling; the response returns the canonical form.
The sample keys on the name
The historical query behind detection filters on the threshold's metric name, so a
threshold on
p99is tested againstp99rows and never against thevaluerowsbeside them. The per grid point separation is unchanged: a threshold still samples
one grid point's history and never the benchmark's grid pooled.
The boundary key
boundarykeys on(metric_id, threshold_id)rather than onmetric_idalone,because a metric row may now carry a boundary per threshold that gated it. Both
thresholdandboundaryare rebuilt, each with its unique keys built after thecopy rather than declared on the table, which is what keeps the rebuild at the cost
of the scan.
down.sqlrestores both old shapes.Responses
JsonAlertgainsvalue, the scalar the alert fired on, and itsmetrictriplebecomes optional. The triple is a convention over the
valuename, so an alert onany other name has none; every alert a threshold could raise before this carries the
triple exactly as it did, so no existing response changes. The gated name is
readable at
alert.threshold.metric.The base of this branch carried a
debug_assert_eq!ininto_json_for_reportholding that a gated row is always a point estimate. That is the invariant this
branch retires, so the assertion is removed by design rather than by accident, and
the comment in its place says so.
The deprecated singular
threshold,boundary, andalertfields carry the barethreshold's gate and no other's, wherever they appear. That is precisely what a
caller from before named gating has always been shown: a row that only a named or
filtered threshold gates reports no gate in them at all. Where a list of boundaries
is returned, it is ordered by threshold creation time, oldest first, with the UUID
breaking a tie. Nothing about that order is a ranking.
The in-report
thresholds.modelsmap is unchanged and still addresses the barethreshold. A map that names a measure and a model says nothing about a name or a
grid point, so it neither creates nor resets anything narrower. A threshold that
gates a name or a corner of the grid is created through the thresholds endpoint.