Skip to content

FlowPrint v1

Overview

FlowPrint v1 evaluates a complete training and inference pipeline. Miners submit a trainer and detector instead of a single fixed heuristic file.

The challenge trains every submission with the same mandatory v1_train_data.csv, then evaluates the trained model against v1_test_data.csv on the official scoring server. v1_test_data.csv is not published to miners, including for local testing, for security reasons.

Miner Output

The miner API must return:

{
  "commit_files": [
    {
      "file_name": "train.py",
      "content": "..."
    },
    {
      "file_name": "submissions.py",
      "content": "..."
    }
  ]
}

commit_files must contain exactly one train.py and one submissions.py.

Training Contract

The challenge invokes:

python train.py <training_csv> <model_json>

train.py must:

  • read the mandatory CSV path from sys.argv[1]
  • use device_os as the label
  • train against these classes: Android, iOS, Windows, Linux, Chromium OS, Mac OS
  • write valid JSON to sys.argv[2]
  • finish within the configured training timeout
  • keep the generated JSON below the configured model-size limit

Production always provides v1_train_data.csv. A miner cannot provide or choose a different training dataset.

The model JSON remains temporary inside the FlowPrint container and is removed after scoring.

Model Weight Policy

Miners must not embed model weights in train.py or submissions.py.

Prohibited content includes:

  • pretrained parameters
  • serialized or encoded model blobs
  • hard-coded learned coefficients or weight arrays
  • lookup tables representing externally learned model state
  • fallback weights used when the generated model is unavailable

All learned weights must be generated by train.py from the mandatory v1_train_data.csv during the current scoring run. submissions.py may only use those weights through the provided model argument.

Ordinary algorithm configuration and hyperparameters are allowed when they do not contain pretrained or externally generated learned state.

Inference Contract

submissions.py must expose:

def detect_os(features: dict, model: dict) -> str:
    ...
  • features contains one row from v1_test_data.csv.
  • The challenge removes device_os before inference.
  • model is the parsed JSON produced by train.py.
  • The function must return one of the six OS class names.

Empty CSV cells are passed as JSON null. Inference should tolerate missing optional fields, numeric values, and network-flow fields.

Each /os_detector request has a 0.1 second timeout. Returning too slowly, returning no device_os, or raising request errors counts as a missed request. After more than 10 missed requests, the scorer stops inference and the submission fails to complete scoring normally.

Isolation

Training and inference execute inside an isolated FlowPrint container:

  • miner scripts and training data are mounted read-only
  • the model is written only to temporary container storage
  • the container uses an internal network
  • training timeout and model JSON validation are enforced
  • miners cannot extend the runtime requirements and must use only the provided packages from src/challenges/flowradar/requirements.txt
  • the container is destroyed after scoring

Scoring

FlowPrint uses macro F1 across OS classes.

For every label seen in either expected or predicted values, the scorer calculates:

  • true positives
  • false positives
  • false negatives
  • precision
  • recall
  • F1
  • support

The final score is the arithmetic mean of per-class F1 values, rounded to three decimal places. Predicted labels outside the expected class set are included in the macro calculation with zero support, which lowers the final score.

FlowPrint requires a minimum score of 0.9 for emission eligibility.

Ruff Validation

FlowPrint miner commits use the commit template's local Ruff configuration. Run these checks from src/challenges/flowprint/examples/miner_commit:

ruff check --config=.ruff.toml --output-format=json --no-fix src/commit/submissions.py
ruff check --config=.ruff.toml --output-format=json --no-fix src/commit/train.py

References