Skip to content

Spec

Current version: 0.2.0

The spec definition is a single JSON document describing datasets, feature dependencies, and function bindings. JSON is the shared format used by analytical declarations and the tools that validate, document, and compile them.

Document Conventions

The root is one JSON object. Dimensions, entities, function templates, features, arguments, and mappings use object keys as identifiers; do not repeat their id inside those entries. Datasets are array entries and require an explicit id. Identifiers should be stable, lowercase, and descriptive.

Tables describe the current parser contract. A default applies when a field is omitted; it does not generally make explicit null valid. Unknown fields are rejected. The JSON structure defines the same contract regardless of how a document is authored or consumed.

For example, dimensions and entities use their identifiers as object keys:

{
  "dimensions": {
    "pump_id": {"type": "string"}
  },
  "entities": {
    "pump": {"name": "Pump", "dimensions": ["pump_id"]}
  }
}

Document root

Field JSON type Required Default Meaning
name string or null No null Display name.
version string No "0.2.0" Format version; only 0.2.0 is supported.
source object No {"name": "manual", "generated": false} Authoring metadata.
dimensions object No {} Dimension definitions keyed by identifier.
functions object No {} Reusable function definitions keyed by identifier.
entities object No {} Entity definitions keyed by identifier.

When supplied, source requires name (string) and generated (boolean). The default is {"name": "manual", "generated": false}. Generated documents can identify their generator in name and set generated to true.

{
  "name": "Pump analytics",
  "dimensions": {
    "pump_id": {"type": "string"}
  },
  "entities": {}
}

Dimensions

A dimension identifies observations, such as a pump identifier or timestamp. Each dimension declares type, optional description, and optional parent. Parents must reference declared dimensions and must not form cycles.

Field JSON type Required Default Meaning
type string Yes N/A Logical key type, such as string, integer, or datetime.
description string or null No null Explanation of the dimension.
parent string or null No null Bare identifier of a declared parent dimension.

Parent metadata describes a hierarchy. It does not automatically add parent columns to an entity, group calculations, or expand observations.

"dimensions": {
  "pump_id": {"type": "string"},
  "timestamp": {"type": "datetime"}
}

Entities

An entity describes an analytical subject. It has a name, optional description, a list of dimension identifiers, and a list of datasets. The complete entity dimension key identifies a dataset observation.

Field JSON type Required Default Meaning
name string Yes N/A Display name.
description string or null No null Explanation of the subject.
dimensions array of strings No [] Bare identifiers from the root dimension registry.
datasets array of objects No [] Datasets describing this subject.
"entities": {
  "pump": {
    "name": "Pump",
    "dimensions": ["pump_id"]
  }
}

Datasets

Field JSON type Required Default Meaning
id string Yes N/A Globally unique dataset identifier.
description string or null No null Explanation of the dataset.
row_scope object No Empty descriptions Observation grain, filtering, and coverage.
order array of objects No [] Logical ordering by entity dimensions.
features object No {} Feature metadata keyed by identifier.
mappings object No {} Function bindings keyed by identifier, unique within this dataset.
"datasets": [
  {
    "id": "telemetry",
    "row_scope": {"grain": "One row per pump and timestamp"},
    "order": [
      {"dimension": "$dimensions.timestamp", "direction": "asc"}
    ]
  }
]

Feature and Mapping Identifiers

Each key under features identifies a column's metadata. Each key under mappings identifies one function binding, unique within its dataset. A mapping identifier names a binding instance, not a reusable function or an output feature. Multiple mappings can invoke the same function with different arguments.

Row Scope

row_scope contains descriptive strings:

Field Required Default Description
grain No "" What one observation represents.
filtering No "" Which observations belong to the dataset.
coverage No "" Expected completeness across dimension keys.

These descriptions do not execute filters or source queries. Each field must be a string when supplied.

Logical Order

Field JSON type Required Default Description
dimension string Yes N/A Reference to a dimension of the owning entity.
direction string Yes N/A Sort direction: asc or desc.

Order keys must be distinct dimensions of the owning entity. Array position determines key precedence. Omission means no declared order. Null placement, collation, and ties are not specified.

Order is a logical convention, not a physical sort or partition guarantee. Functions implement sorting and grouping themselves. Mapping context inherits dataset order to interpret preceding and following observations.

Features

A feature is a column describing an entity, whether read from a source or calculated. Its dataset registry declares the metadata once:

"features": {
  "bearing_temperature": {
    "type": "float",
    "unit": "C"
  },
  "temperature_mean": {
    "type": "float",
    "description": "Trailing temperature mean",
    "unit": "C"
  }
}
Field JSON type Required Default Meaning
type string or null No null Logical type of the feature.
description string or null No null Explanation of the feature.
unit string or null No null Unit of measurement for the feature.

The built-in engine supports these feature types:

Type Meaning
string Text value.
integer Integer value.
float Floating-point value.
numeric Numeric value.
boolean Boolean value.
datetime Datetime value, optionally timezone-aware.
date Calendar date.
object Structured value.
array List or array value.

Declare feature types explicitly: a tabular result's general type does not describe the types of its individual columns.

Non-dimension feature identifiers must be globally unique and have exactly one producer. Dimension columns can recur across datasets.

Feature and dimension registries describe the columns expected in tabular results. Runtime type checks and dataframe merge behavior are described in the execution engine guide.

Functions

A function is a logical analytical function definition bound to an implementation. Each function declares an operation and implementation entrypoint, plus the schema for its arguments. A mapping binds a function to concrete arguments and feature inputs and outputs. Compilation turns each mapping into a callable in the execution plan.

Functions are expressed as objects keyed by globally unique function identifiers.

Field JSON type Required Default Meaning
operation string Yes N/A Analytical operation performed by the function.
returns string Yes N/A Return contract: dataframe for data-producing operations or none for write.
entrypoint string Yes N/A Implementation reference resolved by the execution environment.
validate_signature boolean No true Whether compilation and documentation inspect the Python signature and check implementation return annotations.
args object No {} Argument definitions keyed by argument name.
description string or null No null Explanation of the function.

When validate_signature is true, the Python entrypoint must declare a return annotation compatible with returns; an unannotated return is invalid. When it is false, compilation and documentation do not load the implementation or inspect its signature. This disables only implementation signature and return-annotation checks: declared contracts, binding arguments, feature dependencies, and entrypoint syntax are still validated. Execution still requires a loadable implementation.

An entrypoint identifies the implementation associated with a function. Its resolution is determined by the execution environment. The value below is symbolic; a concrete runtime defines its accepted entrypoint syntax.

"sum_features": {
  "operation": "vectorize",
  "returns": "dataframe",
  "entrypoint": "spec.sum_features",
  "validate_signature": false,
  "args": {
    "dataset": {"type": "dataframe"},
    "left_feature": {"type": "string"},
    "right_feature": {"type": "string"},
    "output": {"type": "string"}
  }
}

Python spec declarations execute during source loading. If an analytical implementation is unavailable in that environment, declare its entrypoint as a string and do not import the implementation from the spec declaration itself.

Use operation-oriented function names. Mapping identifiers and feature names can differ from the function identifier. Each mapping binds one function, whose declared operation determines its analytical role.

Operations

Each function is labeled with exactly one operation. The function's inputs determine which datasets it consumes. The table defines the dataset input and output counts for each operation:

Operation Datasets in Datasets out Analytical Dimension change Purpose
read 0 1 No Read external observations into a dataset.
collapse 1 1 Yes Down Calculate features at a coarser grain.
conform 2 1 No Adapt observations to the target row scope.
expand 2 1 No Up Transfer or join observations into target dimensional coverage.
vectorize 1 1 Yes Calculate features while preserving observation keys.
write 1 0 No Persist or evaluate selected data.

All data-producing functions return tabular data. They perform their own calculations, grouping, output naming, and scalar broadcasting. Analytical functions should not perform external I/O.

Arguments

The args schema must declare exactly the number of dataframe arguments listed for the function's operation. A dataframe argument represents a dataset input; other arguments may carry identifiers, features, or external resource settings.

Field JSON type Required Default Meaning
type string Yes N/A Argument type expression.
comment string or null No null Optional explanatory comment.

Argument definitions are keyed by argument name in the function's args object.

Argument Types

Common argument type expressions are:

Type Meaning
string String value.
integer Integer value.
float Floating-point value.
boolean Boolean value.
dataframe Tabular dataset input.
array Collection value.
object Dictionary value.

Homogeneous collections use recursive type expressions:

"args": {
  "dataset": {"type": "dataframe"},
  "column": {"type": "string"},
  "window": {"type": "string"},
  "output": {"type": "string"},
  "partition_by": {"type": "array[string]"},
  "limits": {"type": "object{str: float}"}
}

Use plain array or object for heterogeneous or unspecified contents. Argument types describe implementation values, not data dependencies. Nested expressions such as object{str: array[string]} are supported.

Feature Mappings

A mapping separates analytical requirements from the implementation binding:

"temperature_mean": {
  "features": {
    "inputs": ["$features.bearing_temperature"],
    "outputs": ["$features.temperature_mean"]
  },
  "row_context": {
    "dimension": "$dimensions.timestamp",
    "before": {"time": "8h"},
    "after": {"time": "0s"}
  },
  "binding": {
    "function": "rolling_mean",
    "args": {
      "dataset": "$datasets.@.dataframe",
      "column": "$features.bearing_temperature.id",
      "window": "8h",
      "output": "$features.temperature_mean.id"
    }
  }
}
Field JSON type Required Default Meaning
features object No Empty lists Explicit prerequisites and outputs.
features.inputs array of strings No [] Materialized features required before the call.
features.outputs array of strings No [] Features produced in the owning dataset.
row_context object or null No null Surrounding-observation requirements.
binding object Yes N/A Function invocation.
binding.function string Yes N/A Identifier of the function definition to bind.
binding.args object No {} Concrete arguments matching the template schema.

Input and output lists contain distinct $features.<id> references, without selectors. Inputs establish dependencies even when not passed as arguments. Conversely, passing a feature identifier is not a declaration that its data must exist. Declare every consumed feature in inputs.

Outputs reference the owning dataset's feature registry. Entity dimension keys are required in every returned table, even when omitted from outputs. A write mapping declares empty outputs and explicitly lists its required inputs. Data-producing mappings require at least one output. Vectorize outputs cannot redeclare entity dimensions. Collapse must produce at least one non-dimension feature. There is no binding-level return field.

Binding syntax

Argument reference Argument type Value supplied to the implementation
$features.<id>.id string Feature identifier string.
$dimensions.<id>.id string Dimension identifier string.
$datasets.<id>.dataframe dataframe Materialized table for that dataset.
$datasets.@.dataframe dataframe Current dataset's input-ready table.
$datasets.<id>.id string Dataset identifier string.
$features.@.id string The sole vectorize output, or sole non-dimension collapse output.

Unsuffixed references remain supported; their template argument type determines whether a dataset identifier is resolved to data. Prefer explicit selectors when writing new declarations. .id arguments require string, and .dataframe arguments require dataframe. Use only the reference forms above.

Row Context

row_context belongs to the mapping, not its features or function template. It describes the greatest required input reach across all calculations in that mapping. It does not describe returned rows or alter full-table execution.

Field Required Default Meaning
dimension Conditional N/A Reference to a declared input dimension; required for time or steps.
before No {} Required preceding context.
after No {} Required following context.

Each direction is an object containing at most one measurement, or the string "unbounded". Both directions use the same measurement:

Measurement Allowed bound Dimension
time Fixed duration, such as "8h", or "unbounded". Datetime.
steps Nonnegative integer or "unbounded". Integer.
rows Nonnegative integer or "unbounded". None; uses dataset order.

Only fixed dimension-based windows and row counts are supported. Feature-valued axes and data-dependent window sizes are not supported.

"row_context": {
  "before": {"rows": 1},
  "after": {"rows": 0}
}

An omitted or null context is unknown. Empty or zero directions explicitly mean current-row-only context. Two unbounded directions require the whole input and need no order; one unbounded direction still needs logical ordering. Functions handle grouping and sorting themselves.

Nonzero directional requirements need dataset order. A time/step dimension must belong to the input entity and have the matching type. When directional context requires ordering, that dimension must also occur in the dataset's order. For collapse, validation uses the inferred source dataset rather than the target.

Fixed durations use these distinct lowercase suffixes:

Suffix Unit
w Weeks (7 days)
d Days (24 hours)
h Hours
m Minutes
s Seconds
ms Milliseconds
us Microseconds
ns Nanoseconds

Durations are nonnegative, contain no whitespace, and have nanosecond or coarser precision.

An eight-row rolling window including the current row needs seven preceding rows. An eight-hour window ending two hours ago needs ten hours before. Declarations must describe actual reach, not merely the window parameter.

Validation

Spec validation checks document structure and semantic consistency:

  • Supported version, field types, required values, and no unknown fields.
  • Valid and unambiguous identifiers and references for dimensions, datasets, and feature producers.
  • Mapping and function operation, input, output, and argument contracts.
  • Row-context requirements against input dimensions and dataset order.
  • Valid, acyclic feature dependencies.