- A run is one calibration of a judgment, and each run has an id,
run. Brussle makes one each night, when you ask for Fit now, when you pin a fit, when you make a named run, and when a composite’s confirmed shadow report fits its weights. Brussle keeps every run for the life of the namespace. - A fit is the correction for one judgment version on one engine epoch, inside a run. Its id is
fit_and 16 hexadecimal characters (such asfit_9f3a2c7e1b04d6a8), and a run that makes the same correction again gives it the same id. A fit that did not beat the raw numbers has no id, and neither do a composite’s weights.
fit and its run. When a new fit replaces the current one says which fit answers read, and when a new one replaces it.
List the fits
The judgment’s Calibration section in the dashboard lists the fits by version and epoch, newest run first. Each row has Details (the formula), Compare, Pin and Lift pin, and a challenger’s row also has Promote. A line at the top showsauto or the pins. The judgments list shows each judgment’s calibration as a badge: Raw, Early, Full, Features or Pinned.
GET /namespaces/{ns}/judgments/{name}/calibration/fits lists the fits, newest run first, one row for each version and epoch of a run:
runandcause: the run, and why it ran.nightlyis the scheduled run, or one Brussle brought forward (after your first outcomes, after the engine changed, or after you lifted a pin).fit_nowis a Fit now,pinis the run that a pin writes, andnamedis a named run.shadowis a composite’s weights, fitted when you confirmed its shadow report.fit: the fit’s id, the same in every run that holds the same correction. It isnullwhen the fit did not beat the raw numbers; thenappliedisfalse, and there is nothing to pin.current:trueon the fits answers read now.pinned:truewhen the run holds the fit because it is pinned, andpinned_fromthen names the run you pinned it from.role,promotion,heldandversus_current: from 2026-10-13, a run can keep the current fit and list its new fit beside it. The current fit’s row hasrole: currentand, inpromotion, what the run did (first,promoted,withdrawn,heldorpinned), withheldsaying why it was kept. Itsfitid stays the same night after night while it is kept. The new fit is on the row under it, withrole: challengerandversus_current, and you can compare it and pin it. A pin of a run that holds two fits for a version and epoch must name itsfit(see why a new fit was held).held_out: the fit’s held-out test, as recorded when the fit was made. On aboolit also givesranking(aurocand precision at the top 5% and 10%, raw and with the fit).features_only: on a judgment with features, the same test of a fit on the features alone.- Filters:
version,engine_version(one epoch),since(runs made at or after a time) andcause, such ascause=named. - Pages. A page has about 100 rows and never divides a run. For the next page, send
next_cursorback ascursorwith the same filters. It isnullon the last page. - Templates. On a namespace that inherits the judgment, the list shows the template’s fits, which are what its answers read.
held_out was measured on the outcomes the fit had when it was made, and two runs had different outcomes, so do not compare the held_out numbers of two runs. Compare the fits instead.
Read the formula of a fit
GET .../calibration/fits/{fit} (ns.judgments.calibrationFit(name, fit) in TypeScript, calibration_fit(name, fit) in Python) returns one fit, from the newest run that holds it. The fit has the row’s fields, and also:
-
model: the terms that turn the engine’s raw value into the corrected value.formsays which formula applies. The formulas uselogit(p) = ln(p / (1 − p)), withpfirst clamped to 0.005 to 0.995, andσ(z) = 1 / (1 + e^−z):modelisnullwhen the fit did not beat the raw numbers. -
range: the lowest and highest raw value the fit used. Outside it, a corrected number isextrapolated.
not_found.
On a template’s tenant that reads a fit of its own (tenant.applied is tenant_shrunk), the corrected number blends the tenant’s fit with the template’s fit that fit names, and this route does not give the tenant’s own formula (see per-customer corrections).
Compare two fits
Each fit’sheld_out comes from the outcomes it had when it was made. To know which of two fits is better on your outcomes now, compare them on the same outcomes:
reliability curve, which the example leaves out.
- The same outcomes. Brussle reads the epoch’s outcomes as they are now (as the next run would fit them) and scores both fits as answers read them, beside the raw answers.
outcomesis how many it scored. When the epoch’s queue labels alone meet the minimums,fitted_onisqueue, and Brussle scores those labels, weighted to your traffic. - The stored fits. Brussle scores each fit as it was made, without fitting it again. The outcomes a fit was made on are scored too, so a fit made on more of them can look better. Read
differencewith that in mind. difference: the mean log loss ofaminus that ofb, per outcome, with its standard error. A positive value favoursb, and a negative one favoursa. Treat a difference that is small next to its standard error as not clear.differenceisnullwith fewer than two outcomes.- Rules. Both fits must be for the same version and epoch, or the call is
invalid_request.withis required. - Limit. One compare for each judgment each minute; within that minute the call is
rate_limited(429) withRetry-After. A compare can take longer than the limit for a request while Brussle reads the outcomes. It is thenunavailable(503) withRetry-After, and you retry after that time. The SDKs wait out a shortRetry-Afterand retry for you.
Fit on outcomes you choose
A named run fits only the outcomes you choose, by where they came from and when they were observed (your labelled examples alone, for example, or one quarter’s outcomes). Answers never read a named run unless you pin one of its fits. A named run is never billed.POST /namespaces/{ns}/judgments/{name}/calibration/fit with a body makes one:
label(required): what you call the run, 1 to 200 characters.outcomes.sources: any ofposted,rule(from outcome rules),queue(labelling-queue labels) andimplicit(implicit negatives). Absent or empty keeps every source.outcomes.sinceandoutcomes.until: outcomes observed at or aftersinceand beforeuntil. An implicit negative counts as observed when its window closed.sincemust be beforeuntil.- An outcome you leave out still labels its answer, so it never turns that answer into an implicit negative.
- The same rules as any fit: the minimums, the held-out test and the queue weights apply to the outcomes you chose. The queue weights come from the queue labels you kept; without
queuethere are none. - The response (202) has
queued_at,next_request_atand yourlabel. The run usually ends within a minute or two. - Limit. Named runs and Fit now share one limit: one request an hour for each judgment. Within that hour the call is
rate_limited(429) withRetry-After. - Templates. On a template’s prefix path, a named run fits the pooled outcomes of the tenants and makes no tenant’s own fit. On a namespace that inherits the judgment, a named run is
invalid_request; make it on the template.
cause: named, its label and its filter, and ?cause=named lists named runs only. A version and epoch whose chosen outcomes do not meet the minimums has fit: null and not_fitted, with the reason and a message. To use a named run’s fit, compare it with the current fit, then pin it.