Track 3 · With BrewSLM · Lesson 12

RunEvent taxonomy & Coach catalogue

After this reference you can recognise any RunEvent on a project's timeline — stage, severity, reason code, payload — and you know the Coach contract behind the inline Coach notices: which workflow stages it speaks at, where each stage's notices appear in the workspace, what severity each suggestion can carry, and what the five action kinds do when clicked.

Level: intermediate Read time: ~12 min Type: Reference

BrewSLM's audit spine has two reference surfaces a developer reads daily: the RunEvent stream (what already happened) and the Coach suggestions (what to do next — the inline "Coach · warning" notices on each destination). Both are stable contracts the platform commits to. This catalogue documents them as they exist in the codebase — schema, taxonomy, action kinds — so the labels you see in the UI map straight to fields you can grep for. (Backend names keep the old Coach Mode label; the UI just says Coach.)

The RunEvent row

One canonical row per "interesting thing happened" across every stage. The schema is append-only — corrections are new rows, never updates. Every row carries:

id              int    primary key (autoincrement)
project_id      int    FK projects.id
run_id          str    "<stage>-<id>" by convention (exp-42, deploy-7, autopilot-{hex})
parent_run_id   str?   parent op when nested (training under autopilot)
stage           str    one of nine canonical values (below)
severity        str    info | warning | error | critical
reason_code     str?   stable code from the taxonomy (required when error/critical)
actor           str    "system" by default; user-id when an operator triggered the event
summary         str?   one-line human readable; UI uses as the row label
payload         json   structured details, free-form per emitter
ts              datetime  wall-clock time of the event
created_at      datetime  insert time (differs from ts for back-dated replays)

The nine canonical stages

Every emitter MUST tag its event with one of nine string constants. New stages are added by extending the lint-gated KNOWN_STAGES set — never by emitting an ad-hoc string.

ingestion     data import / annotation / teacher capture
cleaning      cleaning rules / PII scanning / outlier removal
adapter       Adapter Studio (data-transformation contracts)
training      training runs (SFT, KD)
eval          evaluation runs against eval packs
export        artifact bundling + quantization
deployment    deploy / promote / rollback / drift
autopilot     newbie / strict-mode autopilot orchestration
system        DB / config / extension load (catch-all)

The four severities

The reason-code taxonomy, by stage

Every error or critical RunEvent must set a reason_code from the canonical taxonomy. Emitting an unknown code is rejected at the service boundary (invalid_reason_code:<value>). The taxonomy is grouped by stage:

ingestion

ingest_unsupported_format         file extension not in the supported set
ingest_io_error                   disk write/read failure during ingest
ingest_validation_failed          row failed schema or content validation
dataset_import_run                INFO — generic import pipeline wrote rows
                                  (payload: source, locator, mapper,
                                  accepted/rejected counts, written_path, config_id)
dataset_import_failed             import pipeline raised before any rows written
annotation_job_created            INFO — label job created (payload: job_id, name, label_type, target_rows)
annotation_label_submitted        INFO — reviewer submitted a single label
annotation_rows_promoted          INFO — labeled rows materialized to a downstream dataset
distillation_teacher_capture      INFO — Track 4 slice 1 — teacher top-k logprobs captured

cleaning

cleaning_outlier_threshold_exceeded   outlier removal removed more rows than the configured cap
cleaning_pii_block                    PII / safety scan blocked the dataset from advancing

adapter

adapter_schema_mismatch        declared input/output schema could not be matched to the data
adapter_field_resolution_failed adapter could not resolve a field mapping (missing column, wrong type)

training

training_dispatch_error    failure dispatching the run to the runtime backend
training_runtime_error     generic runtime failure inside the training loop
training_oom               GPU out-of-memory during training
training_timeout           run exceeded its wallclock budget
training_cancelled         operator (or upstream signal) cancelled the run

eval

eval_runtime_error      generic failure inside the evaluation runner
eval_dataset_missing    eval pack referenced a dataset that no longer exists
eval_judge_unavailable  LLM-as-judge call failed (provider down / quota / config)

export

export_run_failed             generic export failure (artifact build, manifest write, smoke check)
export_artifact_missing       required model / tokenizer artifact missing at export time
export_quantization_failed    quantization step exited non-zero or produced an invalid artifact

deployment

deployment_smoke_failed              post-deploy smoke check failed against the live endpoint
deployment_promote_blocked           promote refused (status not promotable / readiness gate failed)
deployment_rollback_no_predecessor   rollback refused because no superseded predecessor exists
deployment_drift_detected            drift check found pass-rate delta beyond tolerance vs baseline

autopilot

autopilot_repair_blocked        autopilot refused a repair (strict mode or unsafe action)
autopilot_strict_mode_refused   strict mode rejected an auto-repair that would otherwise have applied
autopilot_no_safe_plan          autopilot could not construct a safe plan from the current intent

system

system_db_error              unexpected database error from a service-internal write path
system_config_invalid        required configuration value missing or malformed at runtime
extension_load_failed        plugin module import / register hook raised
extension_contract_invalid   plugin module failed one or more contract checks

Stable vs evolving

The nine stages and four severities are stable — they change only with a major contract bump. The reason-code list grows as new failure modes are surfaced, but codes are never silently retired (each addition is a one-line change to the taxonomy file). Treat this as the catalog up to the current contract version; KNOWN_REASON_CODES in the codebase is the runtime source of truth.

Coach — the contract

The Coach is a per-stage suggestion service. Each workspace destination mounts CoachNotices for the stage it shows; that component calls GET /api/projects/{id}/coach/{stage} and renders every suggestion as an inline notice — the "Coach · info / warning / critical" tag, the title and body, one click-to-execute action button, a "why?" trace, and an × that dismisses that rule for the project (remembered in the browser). Two notices show at first; "Show N more" expands the rest. The Overview lists up to three under Worth a look. There is no Coach bar, strip or toggle any more; Settings → Show inline tips hides the notices for a project.

The eight workflow stages Coach speaks at — and where each one renders

data         dataset import / Adapter Studio / synthetic playbook activity   → Data → Sources
cleaning     cleaning rules and review queue                                → Data → Prepare
gold_set     answer-key (gold-set) status and top-up suggestions            → Data → Labels
synthetic    synthetic mix + pending review                                 → Data → Generate
dataprep     split missing / stale / test too small / leakage               → Data → Split
training     training config + preflight + active runs                     → Train
eval         pass/fail rules + failure clusters + remediation               → Results
export       export-vs-base verdict                                         → Ship

A stage the API accepts but no generator handles answers with an empty list and handler_available=false; an unknown stage is a 400 naming the valid ones.

The three severity levels

Each suggestion carries a severity the UI uses to colour the notice consistently (and to order them: critical first):

The canonical suggestion shape

{
  "id":       "data:gold-row-count",
  "rule_id":  "gold-row-count.below-comfortable",   /* the decision rule the "why?" trace names;
                                                      dismissing a notice remembers this */
  "severity": "warning",
  "title":    "Your gold set has 78 rows",
  "body":     "Most useful first models need at least 100 rows of labeled examples ...",
  "action":   { /* one of the five action kinds */ }
}

Generators are read-only — they never mutate project state. Side effects happen only when the user clicks the action button.

The five action kinds

Every action carries a kind, a label, and a params dict. The frontend routes the click on kind alone.

{
  "kind":   "navigate",
  "label":  "Pick a recipe first",
  "params": { "target": "recipe-picker" }
}

Concrete thresholds you'll see in suggestions

Some Coach generators use named numeric thresholds. The current values for the answer-key (gold-set) generator, for example:

GOLD_ROW_THIN_MAX             99    # <= thin (severity bumps to "critical")
GOLD_ROW_COMFORTABLE_MIN      300   # target the suggested top-up tries to reach
SUGGESTED_TOPUP_FLOOR         20    # don't suggest below this
SUGGESTED_TOPUP_CEILING       500   # don't suggest above this

Treat these as representative, not part of the public contract — they tune over time as the platform learns better defaults. The stable surface is the severity transitions and the action kinds.

Key idea

Two surfaces, one audit spine. RunEvent records what happened with a stable (stage, severity, reason_code) tuple and a JSON payload. The Coach tells you what to do next with a (stage, severity, action) shape and five action kinds — navigate, run_playbook, augment_from_cluster, start_flow, reroute_to_rag — rendered as inline notices where you are working. Both are contracts: stages and severities are stable, the reason-code list and threshold values grow with the platform.

The last reference catalogues the consumer that closes the loop on these events: the eval pack's gate schema and the failure-cluster surface that augment_from_cluster opens.

Key terms

RunEvent
The canonical audit-row schema. Append-only; one row per "interesting thing happened" across all nine stages.
RunEvent stage
One of nine canonical strings (ingestion, cleaning, adapter, training, eval, export, deployment, autopilot, system).
RunEvent severity
info / warning / error / critical. Errors and criticals must carry a reason code.
Reason code
Lint-gated string from the canonical taxonomy that names a failure mode (e.g. training_oom, deployment_drift_detected).
Coach stage
One of eight workflow surfaces Coach speaks at: data, cleaning, gold_set, synthetic, dataprep (the five Data steps), training (Train), eval (Results), export (Ship).
Coach notice
How one suggestion renders: an inline card with the "Coach · severity" tag, one action button, a "why?" trace and a dismiss ×. Settings → Show inline tips turns them off.
Coach action kind
One of five: navigate (route), run_playbook (trigger generation), augment_from_cluster (open a failure cluster as a data source), start_flow (start the documents → Q&A flow), reroute_to_rag (clone into a retrieval-first sibling).

Check yourself

Answers are saved to this browser.

Progress is stored locally in your browser.