Skip to content
ClearFeature

Platform

One feature definition.
One execution model.
Historical and live ML.

Keep feature logic in Python, dependencies in a declarative DAG, and use the same tested Feature Project across historical materialization, point-in-time training, and request-time computation.

Three parts, one mental model

Everything in ClearFeature reduces to a small model: an engine, your code, and the combination of the two.

clearfeature-core

ClearFeature Core

The platform engine — API, workers, and storage integrations around a single compute core. Open source, Apache-2.0.

feature-project

Feature Project

A Python package your team owns: feature UDFs, a declarative registry, source definitions, versions, feature groups, and golden tests.

runtime

Feature Runtime

Core running with a compatible Feature Project. The same runtime executes historical jobs and live requests.

Feature Projects: your code stays your code

ClearFeature does not absorb your feature logic into a proprietary format. A Feature Project is a normal, reviewable Python package that lives in your repository, moves through your CI, and is versioned like the software it is.

Feature Project — your repository

snapshot-ratio/
├── feature_project.yaml
└── snapshot_ratio/
    ├── features.py
    ├── registry/features_v1.yaml
    └── tests/golden.yaml
  • features.py — feature UDFs in plain Python
  • registry — sources, features, versions, dependencies, groups
  • golden.yaml — expected values, run as tests

Feature Runtime

ClearFeature Core loads your Feature Project and executes the same registry-defined DAG for historical materialization, point-in-time training datasets, and live request-time computation.

Your code stays your code — Core is the engine, not the owner.

Dependencies are declared, not orchestrated

A feature is a function of sources and upstream features: (sources, deps) → value. Source features read raw report data. Dependent features read upstream feature values. UDFs never call one another — the registry defines the DAG, and the platform resolves execution order.

Source reports

credit_bureau_report

socdem_report

Source features (F1)

active_monthly_payment

monthly_income

Dependent features (F2)

payment_to_income_ratio

reads upstream values via deps

The real DAG from the public quickstart: two features from two independent source reports feed one dependent feature.

Multiple sources, one entity

Production features rarely read one dataset. A credit application, for example, might need a bureau report and a socio-demographic report that landed separately. Batch workflows consume multiple source manifests and join them by the complete canonical entity key — so the DAG computes over a consistent picture of each entity.

Historical materialization

Materialization executes the DAG over landed source history and persists computed feature values with their metadata. Jobs are durable and deterministic: re-running a materialization does not corrupt or duplicate state, which makes backfills and recovery boring — as they should be.

Feature history and job metadata live in PostgreSQL; raw report payloads stay in S3-compatible object storage.

Point-in-time training datasets

A training row is built from an observation time — the moment a historical prediction or decision was made. A source value is eligible only if it belongs to the past and was available by that observation time. Data that arrived later is excluded, which prevents leakage that silently inflates offline metrics.

The full temporal model, explained →

Request-time execution

Online computation is request-triggered: send current source reports into the execution path, and the runtime computes the requested feature groups — resolving the same dependencies, with the same versioned code used historically. The latest computed values are kept in Valkey for fast retrieval.

How real-time scoring works →

The centerpiece: one implementation, both paths

Everything above exists to make one architectural statement true: the feature values a model was trained on and the feature values it receives in production come from the same tested code and the same dependency graph. Not from two implementations kept in sync by discipline.

Runtime and storage, at a glance

Single-purpose services around one compute core, on infrastructure your team already knows how to operate.

Entry

HTTP API

routes to online, batch, and propagation workers

Compute

Shared compute core

executes your Feature Project DAG

Storage

PostgreSQL

feature history, metadata, jobs

Valkey

latest online values

MinIO / S3-compatible

raw report payloads

Kafka / Redpanda-compatible

events and references

High-level view. The full architecture is documented in the repository.

This is what a feature looks like

Real code from the public quickstart — a source feature per report, and a dependent feature that consumes both.

def active_monthly_payment(sources, deps):
    loans = sources["credit_bureau_report"]["loans"]
    return round(
        sum(x["monthly_payment"] for x in loans if x["status"] == "active"),
        2,
    )

def monthly_income(sources, deps):
    return float(sources["socdem_report"]["monthly_income"])

def payment_to_income_ratio(sources, deps):
    return round(
        deps["active_monthly_payment"] / deps["monthly_income"],
        6,
    )

The registry declares the dependency edge — the platform does the rest:

payment_to_income_ratio:
  kind: "udf"
  feature_version: 1
  udf: "udf.demo.payment_to_income_ratio"
  deps:
    - feature: active_monthly_payment
      version: 1
    - feature: monthly_income
      version: 1
  dtype: "float"
  status: "live"

Golden tests assert expected values for every feature before deployment. The complete example is in the quickstart.

Adopting it

The path from zero to a running Feature Project is deliberately short.

step 1

Run the Quickstart

Scaffold a Feature Project with fsctl, define three features, and run golden tests — in minutes, locally.

step 2

Model your first workflow

Point the registry at your real source reports and materialize history for one feature workflow.

step 3

Deploy self-hosted

Run the platform services in your infrastructure. Deployment model →

See it execute.

The quickstart takes a Feature Project from scaffold to tested features in about five minutes.