Sorter — Configuration reference

Sorting profile reference

Reference

On-disk shape of `sorting_profile.json` — every field, every condition operator. Accurate for schema_version 1.

The sorting profile is the rulebook telling the Sorter which bin a part belongs in. Stored at software/sorter/backend/sorting_profile.json, hot-reloaded by the backend when the UI saves it. There is always exactly one active profile.

This page documents the on-disk schema. For editing profiles in the UI, see the profile editor pages.

Top-level fields

Field Type Required Purpose
id string no Stable UUID. Empty for never-published local profiles.
name string yes Display name.
description string no Free-form.
schema_version int yes Currently 1. Loader rejects unknown versions.
rules array yes Ordered. First-match wins. See Rules.
categories object yes { category_id: { name: string } }. Every rule id must appear here.
default_category_id string yes Fallback when no rule matches. Defaults to "misc".
part_to_category object yes Compiled lookup map. See part_to_category.
artifact_hash string yes SHA-256 of the compiled artifact. Keys set-progress state and detects stale profiles.
fallback_mode object no See fallback_mode.
set_inventories object no Present for set-based profiles. See Set-based profiles.
profile_type string no "set" for set-based profiles.
stats object no Runtime cache — regenerated, do not hand-edit.

Rules

Ordered list. First rule whose conditions match wins; later rules don’t evaluate.

{
  "id": "4340bd3e-…",
  "name": "Bricks",
  "disabled": false,
  "match_mode": "any",
  "conditions": [
    { "id": "3a8e16d2-…", "op": "contains", "field": "category_name", "value": "Brick" }
  ],
  "children": []
}
Field Notes
id UUID. Must also be a key in categories.
name Must match categories[id].name.
disabled If true, the rule is skipped.
match_mode "any" (OR) or "all" (AND).
conditions See below.
children Reserved for nested rules. Currently unused.

Condition fields and operators

field Source
category_name Catalogue category (e.g. "Brick").
name Catalogue name (e.g. "Brick 2 x 4").
part_id BrickLink / Rebrickable part number.
color_id Numeric color id.
color_name Human-readable color name.
op Semantics
equals Exact string match.
contains Case-insensitive substring.
starts_with Case-insensitive prefix.
ends_with Case-insensitive suffix.
regex Full-match regex.
in value is a list; passes on any element.

value is a string (or list for in). Empty string is valid — Presort uses contains "" on category_name as the catch-all.

part_to_category

The runtime does not re-evaluate rules per classification. It consults a pre-compiled map keyed by "{color_id}-{part_id}":

"part_to_category": {
  "any_color-3001": "4340bd3e-…",
  "5-3001": "4340bd3e-…"
}

Lookup order in JsonSortingProfile.getCategoryIdForPart():

  1. {color_id}-{part_id} — color-specific.
  2. any_color-{part_id} — color-agnostic.
  3. default_category_id — fallback.

Color-specific entries always beat any_color. The map is generated by Hive when a profile is built; the UI re-requests a compile on save and writes the result back. Do not hand-edit part_to_category — your changes are lost on the next save.

fallback_mode

"fallback_mode": {
  "by_color": false,
  "bricklink_categories": false,
  "rebrickable_categories": false
}

Layered booleans applied when a part is not in part_to_category:

Flag Effect
by_color Bin by color if known.
bricklink_categories Bin by BrickLink category.
rebrickable_categories Bin by Rebrickable category.

All false (default) → unmatched parts go to default_category_id.

Set-based profiles

When profile_type is "set" or set_inventories is populated, the profile represents a build-along:

"set_inventories": {
  "10266-1": {
    "name": "NASA Apollo Saturn V",
    "parts": [
      { "part_id": "3001", "color_id": "5", "quantity": 12 }
    ]
  }
}

SetProgressTracker (set_progress.py) decrements quantities as parts are classified. Progress is keyed by artifact_hash — editing the profile resets progress, intentionally.

artifact_hash

Content hash of the compiled map + categories. Used for:

  1. Set-progress persistence (keyed by hash → identical compiles share progress).
  2. Stale-profile detection — when Hive deploys a profile, the backend compares hashes and calls reload_sorting_profile() if they differ. No restart needed.

Recomputed on save. Don’t edit by hand.

Minimal valid profile

{
  "id": "",
  "name": "Minimal",
  "description": "",
  "schema_version": 1,
  "rules": [
    {
      "id": "1d6b0efe-08b7-466b-8794-ab4e6b34eeae",
      "name": "Other",
      "disabled": false,
      "match_mode": "any",
      "conditions": [
        { "id": "1297380c-…", "op": "contains", "field": "category_name", "value": "" }
      ],
      "children": []
    }
  ],
  "categories": { "1d6b0efe-08b7-466b-8794-ab4e6b34eeae": { "name": "Other" } },
  "default_category_id": "1d6b0efe-08b7-466b-8794-ab4e6b34eeae",
  "part_to_category": {},
  "artifact_hash": "",
  "fallback_mode": { "by_color": false, "bricklink_categories": false, "rebrickable_categories": false }
}

Routes everything to a single “Other” bin. Useful as a known-good baseline when debugging.