Schemas

Warning

Pre-implementation. This page describes proposed contracts. Class signatures, parameter types, schema fields, and behavior are subject to change before code lands. Once implementation exists, content here will be regenerated from docstrings or sourced from running tests.

Serialized contracts that define tasks, datasets, submissions, runs, and governance records. Every model is a Pydantic v2 BaseModel; data types are frozen dataclasses (frozen=True, slots=True) following the same convention as rfgen core types. Field lists mirror the schema reference pages in Reference / Schemas so the API page and the schema page agree.

Three roles

Role

Examples

Data types (frozen dataclasses)

TaskSpec, PredictionBundle

Manifest models (Pydantic v2)

DatasetRecipe, SceneManifest, DataReleaseManifest

Record models (Pydantic v2)

Submission, LeaderboardRow, RunManifest, PreRegistration, ReScoringLog

Class index

Class

Role

Purpose

TaskSpec

Data type

Per-task contract: id, pillar, metric, OOD axis, readout head

DatasetRecipe

Manifest

Frozen rfgen configuration plus a label-extraction map

SceneManifest

Manifest

Per-scene provenance record

DataReleaseManifest

Manifest

Release-level envelope bundling recipes and scenes

PredictionBundle

Data type

Per-task prediction output, one Parquet file

Submission

Record

A leaderboard submission carrying one or more prediction bundles

LeaderboardRow

Record

A scored row on the leaderboard

RunManifest

Record

Provenance for one evaluation run

PreRegistration

Record

Pre-registered baseline declaration

ReScoringLog

Record

Third-party re-scoring audit entry


class emma.schemas.TaskSpec

Per-task contract. One TaskSpec exists per TaskID member, pinned by the TaskRegistry. It wires the task to its pillar, metric, OOD (out-of-distribution) axis, readout protocol, and target domain.

@dataclass(frozen=True, slots=True)
class TaskSpec:
    id: TaskID
    pillar: Pillar
    version: ReleaseVersion
    input_view: str
    label_schema_ref: str
    metric_id: str
    ood_axis: OODAxis
    readout_protocol: str
    target_domain: Domain
    maturity: Maturity
    rationale: str

Fields

Field

Type

Purpose

id

TaskID

Canonical task identifier

pillar

Pillar

Top-level task family

version

ReleaseVersion

Release the task ships in

input_view

str

Canonical input representation name, for example multi_antenna_iq

label_schema_ref

str

Reference to the label schema document for the task

metric_id

str

Identifier of the primary metric class, for example the MeanAngularError class name

ood_axis

OODAxis

Primary transfer dimension the task is scored under

readout_protocol

str

Name of the readout head ABC the task uses

target_domain

Domain

Target application community

maturity

Maturity

Contract state

rationale

str

One-sentence statement of why the task exists

Notes

  • input_view is multi_antenna_iq for every v0.1 task. The raw multi-antenna I/Q (in-phase and quadrature) input is non-negotiable for AoA (angle of arrival) and beam tasks; derived views are secondary.

  • metric_id names the metric class; the per-task metric wiring lives in Metric reference.


class emma.schemas.DatasetRecipe(BaseModel)

A frozen rfgen configuration plus a label-extraction map. The unit of content-hashed reproducibility: the artifact a dataset page documents, the input to EMMADataset, and the contract between rfgen (which owns signal generation) and EMMA (which owns evaluation). See Dataset recipe for the schema reference.

class DatasetRecipe(BaseModel):
    dataset_id: str
    task_id: TaskID
    version: ReleaseVersion
    rfgen: RfgenRecipe
    splits: dict[Split, SeedRange]
    label_extraction: dict[str, MetadataPath]
    target_domain: Domain
    real_capture_counterpart: str | None = None

Fields

Field

Type

Purpose

dataset_id

str

Canonical dataset identifier, for example EMMA-LOC-v0.1

task_id

TaskID

Primary task the recipe feeds

version

ReleaseVersion

Release the recipe ships in

rfgen

RfgenRecipe

Frozen rfgen pin: commit, resolved config, array geometry

splits

dict[{ref}Split , SeedRange]

Map of split to seed range and scene count; holdout range is never published

label_extraction

dict[str, MetadataPath]

Map of label name to the rfgen metadata field LabelExtractor reads

target_domain

Domain

Domain the recipe targets

real_capture_counterpart

str | None

Optional dataset id of the paired real-capture OOD subset

Notes

  • label_extraction keys are label names, not TaskID members. A label such as aoa_deg can feed one task while los_flag feeds another off the same scene set.

  • splits partitions integer seeds into Split members. The holdout range is a frozen secret held by the external co-steward.


class emma.schemas.SceneManifest(BaseModel)

Per-scene provenance record. The on-disk evidence that a scene came from a specific frozen rfgen commit, config, and seed, carrying the realized emitter, channel, and SNR values that LabelExtractor turns into task labels. See Scene manifest.

class SceneManifest(BaseModel):
    scene_id: str
    generator: str
    commit: str
    config: str
    seed: int
    content_hash: str
    arrays: list[str]
    emitters: list[EmitterRecord]
    channel: str
    snr_db: float

Fields

Field

Type

Purpose

scene_id

str

Stable per-scene identifier

generator

str

Always rfgen for synthetic recipes; the adapter name for real captures

commit

str

Frozen rfgen git SHA (or capture-testbed record id)

config

str

Path to the resolved rfgen GenerationConfig

seed

int

Integer seed that parameterized the scene

content_hash

str

Content hash of the generated I/Q and metadata, for example sha256:b7e3...

arrays

list[str]

Receiver array identifiers, resolved into ArraySpec at load time

emitters

list[EmitterRecord]

Realized emitters, each carrying waveform, family, and direction

channel

str

Channel environment identifier, maps to an Environment member

snr_db

float

Realized signal-to-noise ratio in decibels after the rfgen channel chain


class emma.schemas.DataReleaseManifest(BaseModel)

Release-level envelope. Bundles SceneManifest records for one or more DatasetRecipe instances into a single content-hashed release, pins the rfgen commit, and records split assignments. See Data release manifest.

class DataReleaseManifest(BaseModel):
    release_id: str
    version: ReleaseVersion
    recipes: list[str]
    scene_manifests: list[SceneManifest]
    split_assignments: dict[str, Split]
    rfgen_commit: str
    content_hash: str

Fields

Field

Type

Purpose

release_id

str

Canonical release identifier, for example EMMA-v0.1-rc1

version

ReleaseVersion

Release the manifest belongs to

recipes

list[str]

The dataset_id values bundled in this release

scene_manifests

list[{ref}SceneManifest ]

Per-scene provenance records across all bundled recipes

split_assignments

dict[str, {ref}Split ]

Map of scene_id to split; holdout scene ids are never published with labels

rfgen_commit

str

Single frozen rfgen git SHA that generated every synthetic scene

content_hash

str

Content hash over the manifest and referenced scene hashes

Notes

  • A release pins one rfgen_commit for all synthetic recipes. A later recipe requiring a newer rfgen commit ships as a new release with a new release_id and content_hash.


class emma.schemas.PredictionBundle

Per-task prediction output. One Parquet file per task, keyed by scene_id. Validated by SubmissionValidator before scoring.

@dataclass(frozen=True, slots=True)
class PredictionBundle:
    task_id: TaskID
    split: Split
    rows: str
    prediction_bundle_hash: str

Fields

Field

Type

Purpose

task_id

TaskID

Task the predictions are for

split

Split

Split the predictions cover (typically HOLDOUT)

rows

str

Path to the Parquet file containing prediction rows

prediction_bundle_hash

str

Content hash of the Parquet file; pins exactly which outputs were scored

Notes

  • The Parquet file at rows is keyed by scene_id. One row per held-out scene; column schema is pinned per task by TaskSpec and validated by SubmissionValidator.

  • prediction_bundle_hash covers the Parquet bytes on disk, not the in-memory tensor layout, so a reviewer re-running the loader recovers the same hash.


class emma.schemas.Submission(BaseModel)

A leaderboard submission carrying one or more prediction bundles. Validated, then scored by HoldoutScorer.

class Submission(BaseModel):
    leaderboard_version: ReleaseVersion
    model_name: str
    submitter: str
    model_provenance: str
    prediction_bundles: list[PredictionBundle]
    pre_registration_id: str | None = None

Fields

Field

Type

Purpose

leaderboard_version

ReleaseVersion

Leaderboard track the submission targets

model_name

str

Display name of the model

submitter

str

Submitter handle or team name

model_provenance

str

Training config, code commit, or checkpoint reference

prediction_bundles

list[{ref}PredictionBundle ]

One bundle per task in the submission

pre_registration_id

str | None

Required for operator submissions; links to the PreRegistration record


class emma.schemas.LeaderboardRow(BaseModel)

A scored row on the leaderboard. Carries three auditable references: the model display name, the data release hash (the data the scores were computed on), and the per-task metric scores. The prediction-bundle hash that pins exactly which outputs were scored lives on the RunManifest, not the row; a reviewer recovers it from the linked run record.

class LeaderboardRow(BaseModel):
    rank: int
    model: str
    submitter: str
    task_scores: dict[str, float]
    ood_avg: float
    sim_real_gap: float
    data_release_hash: str

Fields

Field

Type

Purpose

rank

int

Leaderboard rank by ood_avg

model

str

Model display name

submitter

str

Submitter handle or team name

task_scores

dict[str, float]

Per-task metric values, keyed by TaskID value

ood_avg

float

Normalized OOD average across scored tasks; the headline number

sim_real_gap

float

Sim-to-real gap in percentage points

data_release_hash

str

Content hash of the DataReleaseManifest the scores were computed on

Notes

  • The row’s prediction_bundle_hash (the per-task output hash) lives on the linked RunManifest, not on the row, so the row stays small and the per-task artifact is recovered through the run record.

  • rank is assigned by the LeaderboardStore on insert (or as a derived view on read); scoring produces a row with an unranked placeholder. See Leaderboard for the ranking contract.


class emma.schemas.RunManifest(BaseModel)

Provenance for one evaluation run. Produced by Evaluator and recorded alongside the EvalRun.

class RunManifest(BaseModel):
    model_provenance: str
    data_release_hash: str
    prediction_bundle_hashes: dict[str, str]
    task_metrics: dict[str, float]
    seed: int
    harness_version: str

Fields

Field

Type

Purpose

model_provenance

str

Training config, code commit, or checkpoint reference

data_release_hash

str

Content hash of the data release scored

prediction_bundle_hashes

dict[str, str]

Per-task PredictionBundle content hashes, keyed by TaskID value; pin exactly which outputs were scored. The model half of the auditable result triple, surfaced here because the LeaderboardRow does not carry it

task_metrics

dict[str, float]

Per-task metric values from the run

seed

int

Seed used for readout-head fitting and fold construction

harness_version

str

EMMA harness version that produced the run


class emma.schemas.PreRegistration(BaseModel)

Pre-registered baseline declaration, recorded before the held-out split is unsealed. Clinical-trial-style provenance so a model-builder cannot retroactively claim an architecture choice. See Governance.

class PreRegistration(BaseModel):
    model_arch: str
    training_config: str
    declared_before_holdout_unseal: bool
    timestamp: str
    hash: str

Fields

Field

Type

Purpose

model_arch

str

Architecture description

training_config

str

Training configuration reference

declared_before_holdout_unseal

bool

Timestamped proof the declaration preceded holdout unseal

timestamp

str

ISO 8601 timestamp of the declaration

hash

str

Content hash of the declaration for tamper detection


class emma.schemas.ReScoringLog(BaseModel)

Third-party re-scoring audit entry. Records that an external co-steward re-scored a submission on the held-out split, with published logs. The ring-fence instrument between Superpose’s model team and EMMA ops.

class ReScoringLog(BaseModel):
    submission_id: str
    scored_by: str
    scores: dict[str, float]
    timestamp: str
    logs_uri: str

Fields

Field

Type

Purpose

submission_id

str

Identifier of the re-scored submission

scored_by

str

External co-steward identity

scores

dict[str, float]

Re-computed per-task scores

timestamp

str

ISO 8601 timestamp of the re-scoring run

logs_uri

str

URI to the full scoring log artifact


Helper types

Three types appear in the field tables above without their own API page. They are defined here so an implementer can code against them. They are EMMA-owned aliases over rfgen metadata and EMMA split bookkeeping, not rfgen types.

SeedRange

A closed integer seed range plus a scene count, used to partition the seed space into Split members.

@dataclass(frozen=True, slots=True)
class SeedRange:
    start: int
    stop: int
    count: int

Field

Type

Purpose

start

int

Inclusive first seed in the range

stop

int

Inclusive last seed in the range

count

int

Number of scenes the range yields; stop - start + 1 when the range is contiguous

The holdout SeedRange is a frozen secret held by the external co-steward and never published with labels. The realized scene count per split must equal count, enforced by the loader.

MetadataPath

A dotted path into the realized rfgen scene metadata that LabelExtractor resolves to produce a label. It is a str alias constrained by the path grammar below, not a free-form string.

MetadataPath = str  # grammar: "<container>[].<rfgen_metadata_key>"

Token

Meaning

<container>[]

A repeated rfgen container indexed over every element, for example emitters[] for every emitter in the scene

<rfgen_metadata_key>

A key in the realized rfgen per-emitter or scene metadata bag, for example aoa_deg or los_flag

A path that does not resolve on a realized scene yields an empty label rather than a score. When every scene in a split misses the path, the loader raises RecipeMismatchError rather than scoring silently. The canonical rfgen metadata keys a path may target are owned by rfgen; EMMA pins them in the recipe, it does not define them.

EmitterRecord

A frozen record describing one realized emitter in a scene, carried in SceneManifest.emitters. It promotes the rfgen per-emitter metadata subset EMMA consumes for labeling and provenance; the raw rfgen metadata bag travels separately.

@dataclass(frozen=True, slots=True)
class EmitterRecord:
    emitter_idx: int
    family: str
    class_name: str
    waveform: str
    aoa_deg: float | None
    los_flag: bool | None

Field

Type

Purpose

emitter_idx

int

Stable emitter index within the scene

family

str

rfgen emitter family, for example comms or drone-rf

class_name

str

Canonical taxonomy label

waveform

str

Waveform identifier, for example qpsk or ofdm

aoa_deg

float | None

rfgen per-emitter angle-of-arrival metadata, in degrees, when the scene carries it; the E-LOC-AOA label source

los_flag

bool | None

rfgen ray-tracer path-class flag, when the scene carries it; the E-LOC-LOS label source

Fields beyond these (SNR, channel profile, fingerprint id) stay in the raw rfgen metadata bag; only the fields a task labels are promoted onto the record.

References

  • Library: Pydantic v2 (pydantic.BaseModel) for the manifest and record models. (verify)

  • Convention: Parquet columnar format for PredictionBundle row storage and interchange.

  • Convention: ISO 8601 timestamps for PreRegistration and ReScoringLog time fields.

See Also