Skip to main content
Every correction Brussle makes has an id you can quote, and Brussle keeps it. Find the fit behind any corrected number, read the formula it went through, compare two fits on the same outcomes, and fit on the outcomes you choose beside the automatic fit.
  • A run is one calibration of a judgment. 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. Each run has an id, run. 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 as fit_9f3a2c7e1b04d6a8. 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.
Each corrected answer names its fit and its run. Which fit answers read, and when a new one replaces it, is on when a new fit replaces the current one.

List the fits

In the dashboard, the judgment’s Calibration section 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 shows auto 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:
  • run and cause: the run, and why it ran. nightly is the scheduled run, or one Brussle brought forward: after your first outcomes, after the engine changed, or after you lifted a pin. fit_now is a Fit now. pin is the run that a pin writes. named is a named run. shadow is 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. null when the fit did not beat the raw numbers; then applied is false, and there is nothing to pin.
  • current: true on the fits answers read now. pinned: true when the run holds the fit because it is pinned; pinned_from then names the run you pinned it from.
  • role, promotion, held and versus_current: from 2026-10-13, a run can keep the current fit and list its new fit beside it. The current fit’s row has role: current and, in promotion, what the run did: first, promoted, withdrawn, held or pinned, with held saying why it was kept. Its fit id stays the same night after night while it is kept. The new fit is on the row under it, with role: challenger and versus_current. You can compare it and pin it. A pin of a run that holds two fits for a version and epoch must name its fit. See why a new fit was held.
  • held_out: the fit’s held-out test, as recorded when the fit was made. On a bool, it also gives ranking: auroc and 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) and cause, such as cause=named.
  • Pages. A page has about 100 rows and never divides a run. Send next_cursor back as cursor, with the same filters, for the next page. It is null on 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. Do not compare the held_out numbers of two runs; compare the fits instead.

Read the formula of a fit

GET .../calibration/fits/{fit} returns one fit, from the newest run that holds it. It is ns.judgments.calibrationFit(name, fit) in TypeScript and calibration_fit(name, fit) in Python. It has the row’s fields, and also:
  • model: the terms that turn the engine’s raw value into the corrected value. form says which formula applies. With logit(p) = ln(p / (1 − p)), p first clamped to 0.005 to 0.995, and σ(z) = 1 / (1 + e^−z): model is null when the fit did not beat the raw numbers.
  • range: the lowest and highest raw value the fit used. Outside it, a corrected number is extrapolated.
From the raw value in an answer and the fit it names, you can calculate its corrected number again. Brussle keeps answers’ numbers to about seven significant digits. A fit id that no run of the judgment holds is 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’s held_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:
The example leaves out each side’s calibration error, ranking and ten-bin reliability curve.
  • 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. outcomes is how many it scored. When the epoch’s queue labels alone meet the minimums, fitted_on is queue, and it scores those labels, weighted to your traffic.
  • The stored fits. Each fit is scored as it was made, not fitted again. The outcomes a fit was made on are scored too, so a fit made on more of them can look better. Read difference with this in mind.
  • difference: the mean log loss of a minus that of b, per outcome, with its standard error. Positive favours b; negative favours a. Treat a difference under about two standard errors as not clear. null with fewer than two outcomes.
  • Rules. Both fits must be for the same version and epoch, or the call is invalid_request. with is required.
  • Limit. One compare for each judgment each minute; within it, rate_limited (429) with Retry-After. A compare can take longer than the limit for a request while Brussle reads the outcomes; it is then unavailable (503) with Retry-After. Retry after that time. The SDKs wait out a short Retry-After and retry for you.
When the comparison clearly favours one fit, you can pin it.

Fit on outcomes you choose

A named run fits only the outcomes you choose, by where they came from and when they were observed: for example, your labelled examples alone, 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 of posted, rule (from outcome rules), queue (labelling-queue labels) and implicit (implicit negatives). Absent or empty keeps every source.
  • outcomes.since and outcomes.until: outcomes observed at or after since and before until. An implicit negative counts as observed when its window closed. since must be before until.
  • 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 queue there are none.
  • The response (202) has queued_at, next_request_at and your label. 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 it, the call is rate_limited (429) with Retry-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, it is invalid_request; make it on the template.
The list of fits shows the named run with cause: named, its label and its filter; ?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.