Sorter — Configuration reference
Sorting profile reference
ReferenceOn-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():
{color_id}-{part_id}— color-specific.any_color-{part_id}— color-agnostic.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:
- Set-progress persistence (keyed by hash → identical compiles share progress).
- 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.
Related
- Sorter architecture — how the profile is consumed by the distribution state machine.
- Sorter troubleshooting — symptoms for profile-related misrouting.