Entity baselines
An entity baseline model scores each entity from aggregate features of its recent history (counts, recencies and summaries of its events) with one calibrated model per label. It is a strong, simple fallback model to compare with the sequence models trained on the same dataset, and to serve when you choose it: for example when a sequence candidate failed promotion gate G1 on quality, or a training study found no competitive candidate. You can train one on any dataset build, evaluate it under the same gates, read what they found and decide whether to serve its scores.
The family is a distinct model with its own operations, report, bundle and
ids. The released model, dataset and bundle responses are unchanged, and a
family model is 404 on every released model operation.
| Step | Operations | What it does |
|---|---|---|
| Create | POST /entity-baseline-models, GET, :cancel, :archive | train one calibrated model per label on an existing sequence dataset build |
| Evaluation | GET /entity-baseline-models/{model_id}/eval-report | gates G1–G6 on the dataset's test split, produced automatically after training |
| Bundles | POST /entity-baseline-models/{model_id}/bundles, GET, GET /entity-baseline-bundles/{bundle_id} | the immutable, fingerprinted artifact a slot serves |
| Serve | POST /slots/{slot_id}:activate, POST /slots/{slot}/refreshes, GET /slots/{slot}/entities/{entity_type}/{entity_id}/scores | activate on a batch slot, refresh, read scores |
Create a baseline model
POST /entity-baseline-models with the dataset build to train on:
{
"dataset_id": "ds_01jb7m2v6q4c8d3x9w0n5t1k2r"
}
dataset_idnames asucceededsequence dataset build of the project, in any tokenizer format (v1,descriptions.v1orsemantic.v2). The model reuses its shards, its train-fit encoders, its targets and its splits (a time holdout included).- Provenance. Any succeeded build is admitted (the bounds below and an
unservable candidate are still refused). Tessera records what it
found on the dataset at creation as
admitted_by, for context: a completed training study on its fingerprint, or else an evaluated or promoted sequence model on it with a recorded G1 failure (quality, the internal reference check or support).admitted_byis absent when there is neither. The console also shows any sequence model on the same dataset that passed G1, so you can compare before you choose. - Candidates (
arms). Each label's model is one of a small set of servable fallback candidates. By default every candidate is fitted on the train split and the best validation score wins (selection.basis: validation). Name one per label witharms(a map from label id to candidate name,explicit; the report'sfamilyblock records each label's chosen candidate, so you can pass the same name back), or passstudy_idto take the candidate a study's gate holdout ranked first (study_strongest_on_gate_holdout; that estimate is optimistic by construction, so the validation-chosen candidate is the unbiased alternative).study_idnames acompletedtraining study of the project on the same dataset fingerprint, whatever its outcome; a running study, another fingerprint or a study whose winning evaluation report can no longer be read is400 failed_precondition(study_not_applicable), and a missing or another project's study is404 not_found. - Bounds. Training runs on the
cpu-standardclass and counts towardconcurrent_training_runs. A dataset above the admission bound (100,000 train and validation rows) is refused withentity_baseline_too_large. - The request is idempotent: an identical request returns the existing model while it is training, evaluated or promoted.
Binary and multiclass outputs are calibrated on the validation split. A model
whose training fails records a typed training.error; :cancel stops a
training between two candidate fits and :archive retires a model that no slot
serves.
Evaluation and gates
The evaluation runs on the dataset's test split with the same masked targets
a sequence model would have, and writes a report in the standard
eval_report.json shape:
| Gate | For this family |
|---|---|
| G1 | beats the previous promoted entity baseline bundle covering the label minus 0.005, else the prevalence predictor |
| G2 | expected calibration error at most 0.05 on the served, calibrated scores |
| G3 | not_applicable (metrics.reason: no_entity_embedding) |
| G4 | input parity: held-out entities rebuilt from the event store and tokenized as the dataset build did must give identical feature rows and identical scores |
| G5 | the dataset's audit, as for sequence models: the censor clock and, on a build with a time holdout, the holdout windows and masks (G1 then records the holdout as time_and_entity) |
| G6 | the drift baseline for monitoring |
G1 and G2 follow your promotion policy, as for every
model: under the default warn policy a failure is shown with what it found
and needs an acknowledgement with a reason before the model is bundled, and
the acknowledgement is recorded in the bundle and the audit log; a strict
policy blocks them. G4, G5 and G6 check that the measurement itself is sound
and always block. The report's family block records each label's candidate,
how it was chosen and the uncalibrated estimate beside the served one.
A baseline model created for a training study must reproduce the candidate the
study ranked: on the same compute class its fitted model is byte-identical to
the study report's, and otherwise its uncalibrated estimate must equal the
report's. A model that does not reproduce it fails arm_reproduction_mismatch,
and the study's fallback shows that error.
Bundles
POST /entity-baseline-models/{model_id}/bundles once the model is
evaluated (acknowledge_gates covers a failed G1 or G2 with a reason; a
failed G4, G5 or G6 blocks):
{}
A bundle pins every artifact by fingerprint: one fitted model per label, the
frozen feature spec, the encoders, the calibration and the report. A bundle
of a descriptions.v1 or semantic.v2 build also pins the build's
description registry or semantic inputs, so serving tokenizes exactly as the
build did. The bundle reads return the bundle without these tokenizer inputs;
GET /entity-baseline-bundles/{bundle_id}/tokenizer-inputs returns them, with
the bundle fingerprint that covers them. To re-verify such a bundle, add every
pins entry of that response to the bundle's pins, and insert each of its
artifacts (without position) at its position in the bundle's
artifacts, in ascending position order: the result is the stored manifest,
and its fingerprint equals fingerprint. The manifest declares
runtime.model_family: entity_baseline.
Activate, refresh and read scores
Activate the bundle on a batch_only slot whose entity type matches the
bundle's with POST /slots/{slot_id}:activate, as for any bundle. Realtime
slots are refused until realtime scoring of this family ships, and
allow_mismatch is refused. Then run a refresh with
POST /slots/{slot}/refreshes, as for a sequence slot. The refresh scores
each entity at its latest event from its recent window and writes its
scores; a refreshed score equals the evaluated score of the same
entity at the same event. Read one entity's scores with
GET /slots/renewals/entities/account/acct-1042/scores:
{
"entity": {"type": "account", "id": "acct-1042"},
"slot": "renewals",
"model_family": "entity_baseline",
"scores": {"renewed": 0.81},
"freshness": {
"event_cursor": {"timestamp": "2026-10-14T09:12:00Z", "event_id": "evt-77"},
"computed_at": "2026-10-15T02:00:04.000000Z",
"bundle_id": "bnd_01jb7m2v6q4c8d3x9w0n5t1k2r",
"model_fingerprint": "4f1c…"
}
}
An entity without a row (or one that is suppressed or erased) is
404 no_state. The read passes the same purpose gate, suppression filter and
metering as GET …/state.
What a baseline slot serves
| Served | Refused (400 model_family_not_supported) |
|---|---|
GET …/scores, POST /slots/{slot}/scores:batch (no embedding key) | GET …/state (its response requires an embedding) |
GET /slots/{slot}/entities:top with by=score or by=delta | by=signal, markers, observation, evidence timeline |
GET …/history, GET …/bands and the slot's band bindings | trajectories, feature views, segment rebuilds, similar jobs |
POST /slots/{slot}/exports (scores only) | warehouse exports and export schedules |
| destinations, the freshness monitor, alert evaluation of existing rules | new alert rules, audiences built from a definition |
Stored records (refreshes, exports, monitor points, alert episodes and the like) stay readable on a slot of any family. Switching a slot from a sequence bundle to a baseline bundle removes the embedding-based reads; the first refresh replaces every entity's row.