Hardware Match — methodology

Method version 1.20.0 · engine: /engines/hardware-match/ · composes the decode, power-mode, model-memory, JetPack, carrier, camera-interface, thermal, Frigate, benchmark and module-power registries. No dataset of its own.

A ranking, not a recommendation engine with opinions. Every fact comes from the engine that owns it; the only judgement in the whole method is the weight table, and it is printed below in full.

Contents

  1. What it decides, and what it does not
  2. The candidate universe
  3. Where each fact comes from
  4. The feasibility filter
  5. The five ranking terms
  6. The weight table
  7. The multi-node rule
  8. The winner, and the alternatives that are not a second pass
  9. How UNKNOWN is treated
  10. Why ecosystem scoring was dropped
  11. Where the prices come from
  12. What invalidates a result
  13. Method changelog

1. What it decides, and what it does not

Hardware Match answers one question: for this workload and these constraints, which platform, at how many nodes, and why that one and not the next. It returns a single winner, the whole non-eliminated candidate set in score order, the platforms it eliminated with the constraint that eliminated each, and the arithmetic behind every score.

It does not price a deployment beyond the compute nodes, size a supply, plan a network, choose a carrier board or design an architecture. Those are separate questions with their own inputs and their own engines: Jetson Power & PSU, Carrier Finder, PoE Node Planner, Drive Endurance Fit. Asking those questions here, with nothing supplied to answer them, would return UNKNOWN for every candidate and cap every verdict on a question nobody asked. When retention is in scope, Drive Endurance runs with a host-compatible drive pool: interfaces come from the carrier or devkit registry (M.2 sizes, SATA only where the row states it); USB/SATA enclosures and other adapter paths stay out until a modeled adapter row exists.

Most importantly, it has no override. There is exactly one place a platform is chosen, and it is the top of the ranked list. No caller can request a different winner, no confidence tier re-picks one, and no complete-configuration economics winner is spliced to the front afterwards. If you disagree with the winner, change the inputs; there is nothing else to turn.

Inputs (WP-01). A field that is not stated takes its documented default and is listed in provenance.defaulted; a field that is stated but invalid — a count of 0, a negative, a fraction or a non-number, true in place of a count, an unknown value of an enumerated input, or an empty string — is rejected with VALIDATION_ERROR naming the field, never replaced by a default.

Input keys (WP-02). The engine accepts one list of input keys — the inputs documented here and their declared backward-compatible aliases. Unknown input keys are rejected with VALIDATION_ERROR naming the key: an invented or misspelt key is never silently ignored, a __ test hook never reaches the engine, and an alias sent together with the key it stands for is rejected too (the engine would read only one of them). export_json.inputs echoes every input the engine honoured, so replaying it reproduces the result.

Detection above the source rate. A stated detection_fps above fps is capped to the source frame rate and the cap is disclosed: every candidate’s Camera Stream Capacity stages run at the source rate, an assumption names both figures and workload.detection_fps_cap carries them.

2. The candidate universe

The candidates are the eighteen platforms in the hardware catalog, the same set the API publishes at /api/v1/catalog. Nothing is hardcoded in the page and nothing is added silently.

Several ids carry real registry data but have no catalog row — the AGX Orin Industrial, the Orin Nano 4GB, the Raspberry Pi 5, the Intel N100 and three data-centre GPUs. They are not candidates and are listed in the result's gaps so their absence is visible rather than silent. The catalog also carries an alias whose target is not a catalog platform; that too is reported as a gap rather than resolved to something it is not.

Coverage varies across the candidate set and the result says so. Ten platform-scoped registries are counted per candidate; a platform present in only two or three of them is evaluated and ranked like any other, but the checks it cannot answer come back UNKNOWN, which caps its verdict and lowers its evidence term. The pin input restricts the candidate set to named ids without changing a single other rule — every threshold, term and tie-break behaves identically on the smaller set.

3. Where each fact comes from

Hardware Match computes almost nothing itself. Each candidate is evaluated by calling the engine that owns each fact, and every constraint that comes back is stamped with the engine that asserted it, so any number on the page can be traced to a single owner and reproduced by running that engine directly.

EngineContributesWhen it runs
Camera Stream Capacitydecode, inference, camera-pipeline working memory, encode, network, preprocessing, and the host CPU / link / preprocessing budget for accelerator cardsalways
Model Memory Fitstandalone model-memory sizing for a named LLM or VLMwhen the workload names a model
Thermal Feasibility Checkerambient rating, power ceiling, cooling capacity, fan in a sealed enclosurealways
Jetson Configuration CheckerJetPack release, module support, install method, power mode, runtimeJetson candidates only — a non-Jetson skips it, which is not a failure
Carrier Finderone production constraint: does a carrier exist that meets the merged needsalways for bare module catalog platforms; otherwise when carrier needs or a form factor are given
Jetson Power & PSUthe vendor maximum module power, and — when the node is PoE-powered — a resolved poe_supply from the carrier's documented PD input or the registry splitter (plus psu_sizing and input_voltage against that supply)always; the PoE checks only when the node is to be PoE powered. A PoE-powered node is judged on its carrier's documented PD input or the registry splitter
Frigate Hardware & Detector Fitdetector, detector capacity, detect-stream decode, decode presetwhen the task is NVR / Frigate
Drive Endurance Fitcapacity, endurance, warranty, write throughputwhen retention or a recording mode is given — once, attached to every candidate unchanged
PoE Node Plannerports, per-port power, switch budget, standard, and node-PD standard compatibilitywhen the node is PoE powered — per candidate, after PoE supply composition, with that candidate's node_count and poe_supply

Derived carrier requirements (method 1.6.0). Bare compute modules always compose Carrier Finder. Minimum needs — wired Ethernet (gbe_min) or CSI lanes when camera_interface is CSI, M.2 when a drive pool is assigned, PoE PD and fanless when those constraints are set, industrial rating only for indoor_industrial / factory, and outdoor ambient on the carrier when the environment or a stated ambient requires it — are merged with any caller-stated needs (stated wins per id). Bare-module composition also derives module_included: false so bundled systems stay out of scope unless the caller states module_included: true or form_factor: system. A PoE-powered node falls back to a PoE splitter only when a carrier exists that meets every other requirement; otherwise the carrier requirement is not met: a failure when the carrier records prove it, a validation item when a carrier’s storage interfaces are only assumed. Each need is labelled DERIVED or STATED in needs_provenance on the production constraint; the constraint's input_state is DERIVED when any need was derived. Ranked rows publish carrier_id and carrier_needs for downstream TCO.

Every result carries sub_engines: the method version and dataset version of each engine that actually ran, alongside the single composite dataset_version. A number that changes between two runs can therefore be attributed to the registry that moved.

Deployment prerequisites are conditions on the deployed unit (a flash configuration, a firmware level) that the resolved configuration satisfies by default and that a deployment step can invalidate. They are not verdict inputs: a PASS row that carries deployment_prerequisites stays applicable; the prerequisites are listed so the installer can keep them true. When the caller does not provide a power mode, Hardware Match uses the planning power mode the registry marks as default; Super presets additionally require the Super flash configuration — satisfied by default on JetPack 7.2.1 ISO installs, invalidated if the board was previously flashed standard-only.

A requested power mode is read as a power ceiling for every candidate. A requested mode that is not a preset of the module is sized at the module's highest preset at or below the requested ceiling, and the candidate publishes the ceiling, the preset it was sized at and the resolution; when every preset of the module exceeds the ceiling, the candidate fails with a power ceiling FAIL and is never recommended. A requested mode that is neither a preset, a wattage, MAXN nor default is rejected with a validation error naming power_mode and the accepted ids; it is never sized at the registry default. The Jetson configuration check judges the preset the candidate was sized at, with that preset's prerequisites — a 30 W request on an Orin Nano is checked as its 25 W Super preset. For example, a 40 W request sizes a Jetson AGX Orin 64GB (presets 15 W, 30 W, 50 W, MAXN) at its 30 W preset, and a 7 W request excludes it: its lowest preset is 15 W. A module with no power-mode presets fails the same way when its stated power exceeds the ceiling, and otherwise carries a note that the mode does not apply.

Power comparisons follow a SELF vs INDEPENDENT rule: a draw taken from a power-mode preset or the module's rating is compared with itself and is informational; only a caller-supplied draw is a deployment demand.

Precision (method 1.18.0). A named precision sizes every candidate as named. With none named, the workload is sized at its task’s planning default — FP16 for segmentation and pose, INT8 for detection and every other task — taking the task you state, else the task the model registry files the model you name under; precision is listed in provenance.defaulted, and a task-specific default is marked on workload.precision_default as a DERIVED planning default. When every candidate in scope — the platforms you pin, or a family — runs only INT8 (Coral, Hailo), the FP16 task default falls back to INT8, their supported precision, and the record says why; a wider scope keeps FP16. When you state a JetPack whose TensorRT release a sourced build limitation names for the sized model at that precision, the limitation is published in compatibility_risks with its source and warned: YOLO11-seg INT8 on TensorRT 10.3.0 (JetPack 6.1, 6.2 and 6.2.1). It is a validation requirement with elimination authority planning_only: it eliminates no candidate. With no JetPack stated it does not apply, because each candidate is planned on its latest JetPack, a TensorRT release the source says nothing about.

Node-local recording vs slots (Package 5f slice 5). Hardware Match composes Drive Endurance only in the node_local role and sweeps drives_per_node up to the carrier slot count. When retention still does not fit at that cap, the capacity row is stamped REQUIRES_VALIDATION with reason_code: RECORDING_POOL_EXCEEDS_NODE_SLOTS, rollup_significance: INFORMATIONAL, and required_for_verdict: false — it is published on the candidate for standalone callers and for Architecture Designer, but it does not change recommendation_disposition, capacity_limited_by, the margin term, or elimination. Shared recording topology is decided in Architecture Designer, not here.

One rule governs the composition: a figure is only ever pushed into an engine whose registry it belongs to. The catalog's maximum module power, for instance, is not fed to the thermal or power-input checks — for the Orin NX 8GB that figure is the 40 W Super mode while the power-input registry states a 20 W maximum, and comparing one registry's number against another's ceiling manufactures failures. The catalog figure is used only for the cross-platform power term, where it is the one number every candidate has.

4. The feasibility filter

Hard facts only. A candidate is infeasible at a given node count when any constraint comes back FAIL or UNSUPPORTED, or when the node count times the unit power exceeds a power ceiling you stated. It is infeasible outright when that holds at every node count up to the cap. A constraint only comes back FAIL or UNSUPPORTED when the evidence behind it can prove the miss: its elimination_authority is authoritative (class A/B/C) or bounded_model (class D whose every derivation step is a documented, deterministic, directionally safe bound) — see evidence class and elimination authority.

There is deliberately nothing else in the filter. In particular:

  • No tolerance multiplier on stream counts — a load 1.5× over a published capacity is over it.
  • No soft penalty for a platform in preview, and no multiplier on an interpolated benchmark. Both are handled where they belong, as evidence class.
  • No budget filter. A platform you cannot afford is a different decision from one that cannot do the job; over-budget candidates stay in the ranked list, flagged, and can carry the stretch role.
  • No elimination on UNKNOWN. See §9.
  • No elimination on planning-only evidence. A miss that rests on class E evidence, or on class D evidence with any estimated step — the multi-stream efficiency curve, a hand-estimated power-mode factor, a cross-platform scaling, a class E cooling band or enclosure rise, a default PSU peak factor, a host CPU budget, a modelled decode ceiling with no source — is demoted to REQUIRES_VALIDATION with the shortfall stated, and the candidate is listed as planning-only, not eliminated. A miss that holds with every estimated term at its physical bound (for example a decode load over the datasheet pixel rate, or the throughput a lower power mode can never exceed) rests on bounded evidence and eliminates.

Detection rate defaults to the source frame rate when you do not send detection_fps; the assumption names the implied detections per second per node and a Frigate-style 5 fps motion-gated contrast.

coverage.evaluated counts every platform that ran a constraint set; coverage.not_eliminated is recommendation-eligible plus planning-only only and never exceeds coverage.evaluated.

Every eliminated candidate is returned with the single constraint that eliminated it — the engine, the check, the status and the two numbers — so an exclusion is always arguable rather than asserted.

Results are shown in three sections and in this order: recommendation-eligible candidates (ranked in score order), planning-only candidates (for an NVR task, candidates with Frigate detector evidence first; then modelled fit first, then presentation verdict, then score — see below), then eliminated candidates (with their hard failure reason). The operations behind that display order are fixed: evaluate hard constraints, classify non-eliminated candidates by evidence admission, rank recommendation-eligible survivors once, then list planning-only candidates separately. There is no second pass and no re-pick.

Candidates are scored once using the published five-term score against fixed published anchors. Hardware Match also applies the published recommendation-evidence admission policy: recommendation-eligible candidates rank ahead of planning-only candidates, and measured or vendor-backed capacity ahead of modelled capacity. Candidates are not silently dropped or rescored; planning-only candidates remain visible with their numerical scores. Ordering is lexicographic — primary: recommendation admission class; secondary: capacity evidence class; then the five-term score. Inside the planning-only tier two sort keys come before the score: modelled fit (the tightest modelled check’s modelled_utilization at or below 1, then no modelled figure, then above 1) and then the presentation verdict (FIT, FIT WITH RISKS, validation required, insufficient evidence). They are a tier-internal sort key, not a second ranking: planning-only evidence still eliminates nothing, but a board modelled at many times its own capacity is no longer listed above one modelled within it. Evidence admission is not another weight; it is a recommendation-authority policy. The winner is the first entry of that ordered list; there is no second pass and no re-pick.

A request that names no model is sized on the task's default model: MobileNetV2 for classification, YOLO11s-seg for segmentation, YOLO11s-pose for pose, and YOLO11s, the one workload sizing-model default, for detection or no task — the same defaults Camera Stream Capacity applies. The Architecture Designer puts the same model and task to Hardware Match.

At the default Hardware Match inputs, the cooling-resistance check is PASS and the candidate thermal resistance stays below the maximum allowed value.

At the default Hardware Match inputs, the winner is capacity limited by inference, not by a power ceiling, and the published margin equals the inference check headroom (one minus the binding utilisation, rounded for display).

At the default Hardware Match inputs, the winner's simplicity term score equals one divided by its node count.

At the default Hardware Match inputs, the winner scores 1.0 on cost and 0.64 on power against the fixed per-camera anchors.

At the default Hardware Match inputs, evidence_summary.classes_present includes class E.

At the default Hardware Match inputs, capacity_limited_by.check is inference.

At the default Hardware Match inputs, disposition counts (including eliminated in screening) reconcile to coverage.candidates.

5. The five ranking terms

Every survivor gets one score: TOTAL = Σ wᵢ sᵢ over five terms, each in [0, 1]. There are no multipliers, no overlays and no goal-specific code paths; the goal selects a row of the weight table and nothing else changes. Every ranked row carries scoring_provenance with the raw inputs, per-term score, weight, contribution and total for that row — recomputing the sum from those fields must reproduce score exactly.

TermDefinitionEvidence
MARGIN1 − the highest utilisation among consumed-capacity constraints (declared quantity kind CONSUMPTION: MIN_CAPACITY / MAX_ALLOWED against an independent limit); thermal resistance is a design requirement and a module at its published maximum is an identity check — reported, never ranked.inherited from the constraints (A–D)
Ranking evidence termMean class weight over every constraint on the candidate: A 1.0, B 0.9, C 0.75, D 0.5, E 0.25. A constraint whose status is UNKNOWN counts as class E for this term regardless of the class it claims. This is a ranking input, not a confidence label.derived
COSTcamera count × $100 anchor (v1) ÷ this candidate's total cost, clamped to [0, 1]; at or below the anchor scores 1.0class C where a vendor or distributor listing is on record, class E otherwise (§11)
POWERcamera count × 2 W anchor (v1) ÷ this candidate's total power, clamped to [0, 1]; at or below the anchor scores 1.0class A — the vendor maximum module power, plus the host's for an accelerator card
SIMPLICITY1 ÷ node count (policy inverse_nodes_v1, reference 1 node)derived

Reading the evidence columns

  • Evidence class (A–E): what kind of document backs the number.
  • Source confidence (HIGH/MEDIUM/LOW): the recommendation label is the weakest source confidence among material, verdict-affecting constraints (non-PASS rows, the capacity bottleneck, tight-band consumed capacity, and consumed capacity where a plausible evidence error — ×1.1 HIGH, ×1.5 MEDIUM, ×2.0 LOW — could reach the tight band); comfortable PASS checks are listed in evidence_confidence.excluded_incidental.
  • Certainty: how the comparison sits against its limit — the kernel vocabulary on each row (VALIDATED, MODELED, LIKELY, UNKNOWN, …).
  • Ranking evidence term: the score component in scoring_provenance — a ranking input, not a confidence.

scoring_provenance.terms.margin.raw records the worst eligible utilisation; terms.evidence.raw is the mean class weight; cost and power terms echo the anchor inputs and the candidate totals; simplicity echoes node_count and the policy id. Weights and contributions are published beside each score so the TOTAL is auditable without reading engine code.

6. The weight table

This is the only judgement in the method, and it is class E: engineering judgement, not measurement. There is one table. It lives in one constant in the engine, is published here, is echoed on every result and is served in the API catalog. No second table, overlay or goal-specific branch exists anywhere else. Each row sums to 1.0.

GoalmarginevidencecostpowersimplicityReading
balanced0.300.250.200.150.10Headroom leads, but a well-sourced answer is worth nearly as much as a roomy one.
cost0.150.150.550.050.10Price dominates; enough margin and evidence remain that a cheap unverifiable answer still loses to a cheap verified one.
power0.150.150.100.500.10Watts dominate. This is the goal the legacy stack got wrong most often, picking a 130 W module over a 25 W one because an ecosystem score outweighed the stated goal.
headroom0.550.200.050.100.10Room to grow dominates; cost is nearly ignored but never quite, so an order-of-magnitude price jump still has to buy something.

Optimize for power uses a balanced objective: lower power improves ranking but does not automatically override fit quality and other weighted factors. When a different recommendation-eligible configuration has the lowest power draw, Hardware Match identifies it separately.

That configuration is published as lowest_power_eligible under every goal, and shown as the lowest-power eligible configuration: the recommendation-eligible configuration with the lowest total power (ties go to the higher score, then fewer nodes), with its watts against the winner’s, the saving (per node only when both use the same node count, otherwise the total and each side’s per-node watts), both scores, and ranks_lower_because — each term on which the winner’s weighted contribution (weight × term score) exceeds this configuration’s, largest gap first, recomputable from the published terms and weights. It is informational: it never changes the winner, the ranked order or the alternative roles, and it is omitted when the winner already draws the least.

Cost and power term scores use fixed published anchors so the ratios do not shift when a different loser drops out of the candidate set. The anchors are policy constants (class E), not measured calibration:

Anchor versionCost anchorPower anchor
2026-09-13100 USD per camera2 W per camera

Lexicographic ordering (after the five-term score is computed for every survivor) is published on every result as weights.ordering: recommendation_disposition (RECOMMENDATION_ELIGIBLE before PLANNING_ONLY), then, for an NVR task only, candidates with Frigate detector evidence before those without (winner_pool; a candidate outside it carries winner_pool_reason), then, inside PLANNING_ONLY only, modelled_fit (modelled_utilization ≤ 1, then not modelled, then > 1) and presentation_verdict, then score descending within each group, then platform ascending, then node_count ascending. A platform with no Frigate detector figure cannot be compared on the rule that picks an NVR winner, so it is listed after the ones that can, whatever its score. Disposition is determined first; planning-only candidates keep their raw scores and are ranked separately. The authoritative winner is the highest-scoring recommendation-eligible candidate. Two identical requests always return byte-identical results.

7. The multi-node rule

Node count is part of the candidate, not a correction applied afterwards. Each platform is evaluated at one node, then two, and so on to the cap (default and maximum 8, settable to any value from 1 to 8); the node count reported is the smallest count at which compute admission fits — decode, inference, memory, network, thermal, and the other constraints that decide whether a node can run its camera share. Node-local retention and carrier drive pools are composed at that count; when the retention pool still exceeds the modeled slot cap, the informational RECORDING_POOL_EXCEEDS_NODE_SLOTS row is published and the sweep does not continue to add nodes for storage. A platform is sized at the smallest node count that is recommendation-eligible; a load-dependent uncertainty is resolved by adding nodes before the platform is reported planning-only. Only a per-node load counts: a consumed-capacity check of Camera Stream Capacity, Frigate Fit or Drive Endurance (the engines sized on each node's camera share) whose demand was computed and is not a clean pass, such as a Frigate detection rate inside the stock detector's published 20–40 ms latency band. Software support, thermal class, configuration unknowns, thin coverage and the capacity-evidence tier do not change with the node count, so a platform held back by any of them stays planning-only; so does one that reaches the cap without becoming eligible. A planning-only platform is still sized honestly: when its tightest modelled check is a per-node load over its modelled capacity (modelled_utilization above 1), it is sized at the smallest node count within the cap at which that check is modelled at or below 1, or, when no count within the cap gets there, at the count with the lowest modelled utilization, and the overload is published. The validation suite checks the minimum directly: for every multi-node candidate, one node fewer must fail compute admission, or be planning-only while this count is recommendation-eligible, or, for a planning-only candidate, be a modelled overload above this count’s (EV162); no planning-only result may leave an eligible higher node count within the cap untried (EV245); and the planning head is modelled within capacity whenever any planning-only candidate is (EV252).

Cameras are split by a balanced assignment, so sixteen across six nodes is 3 / 3 / 3 / 3 / 2 / 2 and sums to exactly sixteen — not "six nodes of three", which would be eighteen. Each node is checked at the busiest share, so the assignment is honest at its worst node rather than its average one.

Comparison is always N × the same platform: total cost is N × the unit price, total power N × the unit power, evidence unchanged. A cheap module that needs eight nodes therefore competes honestly against an expensive one that needs two, which is exactly the comparison the legacy engine had to make with a post-hoc splice. There is no hand-off to another engine above any stream count: if nothing fits at the cap, the answer is NO FIT, said plainly.

A NO FIT is an answer, not a request error. The response is a success with verdict: NO_FIT, winner: null, no planning candidate and an empty ranked list, every evaluated platform in excluded with the constraint that eliminated it, questions naming the inputs whose change could alter the answer (clear a pin, allow more nodes, raise a power mode), and a refusal row naming the binding checks — on the same envelope as a FIT, with the weight table, coverage, provenance and method version. Only a malformed, invalid or unsupported request is an HTTP 400.

8. The winner, and the alternatives that are not a second pass

The winner is the first entry of the ranked list. That is the entire selection step.

Alternatives are labels on that same list, computed against the winner — never a second selection pass, and never a separate block that could disagree with the ranking. A platform may carry several roles or none:

RoleCondition against the winner
lower_costtotal cost ≤ 0.85 × the winner's
lower_powertotal power ≤ 0.75 × the winner's
higher_headroommargin ≥ 1.50 × the winner's
stretchtotal cost ≤ 1.30 × the winner's and margin ≥ 1.20 × the winner's — over-budget candidates included

One informational field sits beside the roles: lowest_power_eligible, the recommendation-eligible configuration with the lowest total power when that is not the winner (see the weight table). It is read off the same ranked list, carries the reasons it ranks lower, and never replaces the winner.

The verdict on the winner — FIT, FIT WITH RISKS, NEEDS VALIDATION or NO FIT — is reported, never acted on. A low confidence or an unvalidated check is something to tell you about, not a reason to hand you a different platform.

9. How UNKNOWN is treated

UNKNOWN is never fatal and never free. A missing registry row, a benchmark with no matching entry, an alias we do not trust: none of them eliminate a candidate. INDETERMINATE never eliminates a candidate; only a canonical FAIL does, and only authoritative or bounded evidence can produce one (§4). An established unsupported configuration is a FAIL with a reason code; support that cannot be established stays INDETERMINATE.

But an UNKNOWN is not costless either. It:

  • caps that candidate's verdict at NEEDS VALIDATION, whatever else passes;
  • counts as class E in the evidence term, so a datasheet-backed platform outranks an unverifiable one at equal margin;
  • and, when decode, memory and inference are all unknown, drops the candidate below every candidate that has coverage, so it cannot win.

An example of the principle in practice: the Hailo-10H previously inherited the Hailo-8's thermal limits through an alias. That alias was wrong data — a different part with different limits — so it was removed at source. The Hailo-10H now reports its thermal check as UNKNOWN, which is a worse-looking answer and a truer one.

10. Why ecosystem scoring was dropped

The legacy ranking carried an ecosystem term built from four numbers — SDK maturity, model breadth, documentation quality and community tooling — and under one goal it carried a weight of 0.60. None of those four figures has a source behind it. They are opinions with a decimal point, and weighting them at 0.60 made them the loudest voice in the room.

V2 does not rescale that term or find better numbers for it. It removes it. The consequences are visible and intended: winners change on many workloads, and in particular the cases where a high-power module beat a low-power one under a stated power goal, or a low-headroom platform beat a far roomier one under a headroom goal, resolve the way the goal says they should.

What ecosystem maturity genuinely affects — whether a runtime is supported on a JetPack release, whether a detector image exists, whether a model family runs at all — is not an opinion and has not been dropped. It is a sourced software constraint from the Jetson Configuration Checker and the Frigate registry, and it can eliminate a candidate outright.

11. Where the prices come from

No price is ever invented. Each candidate's unit price is one of two things, and the result says which on every entry as cost_evidence_class:

  • Class B — a current vendor listing that resolves to a URL and a date it was checked, for the unit you actually buy: the bare module, the developer kit where that is the retail SKU, or for the accelerator boards the board itself. Nine of the eighteen catalog platforms have one today: the Orin Nano and Orin Nano Super Developer Kit (Arrow); the AGX Orin 32GB and 64GB and the Thor T4000 from Arrow; the Coral USB Accelerator, the Hailo-8 and Hailo-8L boards and the RK3588 single-board computer from their retailers.
  • Class E — the catalog planning price, which carries a note rather than a source record. Every other platform, including both Orin NX modules, the Thor T5000, the Hailo-10H, the Neousys system and the four server GPUs.

A platform with neither would get a cost term of zero and a warning, never a guessed number.

One asymmetry is stated rather than papered over. An accelerator card is not a node: a Coral stick or a Hailo board needs a host to decode, pre-process and run the OS. The host's power is included in the figures, because the host's maximum power is a published vendor number. Its price is not, because no vendor listing for it is on record — so an accelerator candidate shows the card price, its cost evidence drops to class E, and the omission is stated in the planning notes and on every entry as cost_excludes_host.

12. What invalidates a result

  • Prices move. The class C listings carry the date they were checked; a repricing of the kind the Jetson line saw in 2026 invalidates every cost term at once.
  • A workload whose real frame content is far from the modelled one — very high motion, heavy scene complexity, or a detection rate that differs from the source rate in ways the inputs did not capture.
  • Any figure a vendor does not publish. An UNKNOWN check is a hole in the answer, not a pass; a NEEDS VALIDATION winner has not been shown to work, only shown not to fail.
  • The weight table itself. It is judgement, and a deployment with a real constraint the terms do not model — a rack unit budget, an existing spares pool, a certification the site demands — will rank differently than this does.
  • The margin term reflects the tightest check we can measure. A platform that is comfortable on decode and unverifiable on memory can still be the platform that runs out of memory.
  • Accelerator totals exclude the host price, and every node total excludes storage, networking, enclosure, mounting and installation.
  • The node cap. Eight is a policy, not a physical limit; a workload that needs nine nodes returns NO FIT rather than a nine-node answer.

13. Method changelog

MethodDateChange
1.20.02026-09-29When the caller states carrier_id, Jetson Power & PSU is composed with that carrier (not only on the PoE-powered path) and its carrier_module_power row is carried verbatim (#269). With no stated carrier the PoE path is unchanged and no carrier_module_power row is added for non-PoE candidates.
1.19.02026-09-29Evidence gets an elimination authority (#263, owner ruling 2026-09-29). Every constraint row carries elimination_authority — authoritative (class A/B/C), bounded_model (class D whose every derivation step is a documented, deterministic, directionally safe bound) or planning_only — stamped by the owning engine and carried verbatim. A platform is eliminated only on an authoritative or bounded FAIL; a miss on planning-only evidence (the multi-stream efficiency curve, a power-mode factor, a host CPU budget, a modelled decode ceiling, a class E band, a default PSU peak factor) is REQUIRES VALIDATION and the platform is planning-only (HEURISTIC_EVIDENCE_CANNOT_ELIMINATE), ordered in that tier as before. In the scoped search a planning-only overload is sized as in the full one instead of reading as a fit at one node, so its family is expanded only when a larger member exists. On a 1 800-run grid the winner, verdict and best planning candidate are unchanged; 3 096 platform eliminations became planning-only.
1.18.02026-09-29Segmentation and pose default to FP16 (owner ruling of 2026-09-29): with no precision named the workload is sized at its task’s planning default — FP16 for segmentation and pose (the stated task, else the model registry’s task of the named model), INT8 otherwise — listed in provenance.defaulted and marked workload.precision_default (DERIVED) with an assumption; a scope of INT8-only accelerators (a pin or a family) falls back to INT8, with the reason. Before, every task was sized at INT8, where no YOLO11-seg or YOLO11-pose row exists on any Orin. New public field compatibility_risks: a sourced build limitation of the sized model at the requested precision on the stated JetPack’s TensorRT release (YOLO11-seg INT8 on TensorRT 10.3.0), with its source, warned, never an elimination; the model-facts registry joins this engine’s datasets.
1.17.42026-09-28An absent power_mode is listed in provenance.defaulted when any candidate in scope has power-mode presets (bug #248): those candidates were already planned at their registry default preset, as planning_configuration.basis says, but the default was not recorded with the other defaults. A named mode is never listed, and neither is a scope with no presets (a Hailo pin, for example). No ranking or verdict change.
1.17.32026-09-28The Jetson configuration check judges the preset a candidate was sized at. A recognised power_mode the pinned module has no preset id for (maxn or 30w on Orin Nano, 50w on Orin NX) was resolved to a preset for sizing, but the raw word reached the configuration check, which read it as UNKNOWN and dropped that preset's prerequisites; it is now checked as the resolved preset (for example the 25 W Super preset, with its Super flash prerequisite), exactly as if that preset had been stated.
1.17.22026-09-28Input rules (WP-01 remainder, WP-02): the remaining numbers, enums and booleans (detection_rate_per_node, motion_share, codec, optimize_for, budget_tier, budget_usd, latency_target_ms, power_limit_w, ambient_max_c, retention_days, drives_per_node, media, fanless, poe_powered, enclosure, recording, recording_mode, search, family, camera_interface) are checked, and stated carrier needs are checked by Carrier Finder's own rules before any candidate is evaluated; codec, optimize_for and resolution defaults are listed in provenance.defaulted. Unknown input keys are rejected; needs_derived and pipeline_model are composition-only, and the configuration-checker test hook is read from the execution context only. No formula changed.
1.17.12026-09-28Present-invalid inputs are rejected; absent inputs default and are recorded (WP-01): a value that is stated but malformed — cameras 0 / "sixteen" / true / 3.5 / "", a fractional or non-numeric max_nodes, an fps or detection_fps that is not a number in range, an unknown precision — returns VALIDATION_ERROR naming the field instead of being replaced by a default; a field that is not stated takes its documented default and is listed in provenance.defaulted. No formula changed. A detection rate stated above the source frame rate is capped to it and the cap is disclosed (assumption and workload block), never silent.
1.17.02026-09-28A load no platform holds at the node cap (for example the page's 16 × 1080p load pinned to the RK3588 NPU or the Nuvo-9531) is a success with verdict: NO_FIT, winner: null, ranked: [], every eliminated platform with its reason row, the recovery questions and a new refusal row naming the binding checks, on the same envelope as a FIT; it was an HTTP 400 error with a results stub (bug #226). Winners and verdicts of every request with a candidate are unchanged.
1.16.02026-09-27A request that names a vision task but no model is sized on that task's default model, the one Camera Stream Capacity uses (classification → MobileNetV2), instead of YOLO11s (bug #213). A classification request was sized on a detector and every composed inference row was a cross-task estimate. A stated model is unchanged.
1.15.02026-09-27An unrecognised power_mode (neither a preset of the module, a wattage ceiling, MAXN nor default) is a 400 validation error naming the field and the accepted ids, through the same power-mode resolver Compute Fit, Camera Stream Capacity, Benchmark Explorer and Benchmark Reality Check use. It was sized at the registry default. Recognised modes keep the ceiling rule of 1.11.0; modules without power-mode presets keep the not-applicable note.
1.14.02026-09-27Planning-only tier (bug #211). A planning-only platform whose tightest modelled check is a per-node load over capacity is sized at the fewest nodes within the cap at which it is modelled at or below 1 (else at the lowest modelled utilization), and the planning-only tier is ordered modelled fit first, then presentation verdict, then score. Every ranked entry publishes modelled_utilization; weights.ordering names the two tier-internal keys. Class D/E evidence still eliminates nothing, and the recommendation-eligible tier and the winner are unchanged. The summary states a modelled overload (“modelled demand is 209× the modelled capacity (class D)”) instead of “0 % headroom”. The price sweep names only competitors that could take the winner’s place (same recommendation disposition). Examples: 16 × 1080p30 on one node — planning head Rockchip RK3568 at 209× its modelled capacity → Jetson T4000 at 1.0; 16 × 1080p at 120 fps — RK3568 × 4 at 52× → Jetson AGX Orin 32GB × 8 (0.83, FIT WITH RISKS, capacity evidence below the recommendation threshold). Input contract (bug #207): install_method must be one of the Jetson Configuration Checker values (sdk_manager, sd_card_image, iso_image, apt_upgrade, flash_sh, unknown); any other value, and any value the composed Checker rejects (for example an unknown JetPack), is a 400 VALIDATION_ERROR instead of a result in which every Jetson turned planning-only. The page’s “apt upgrade” tile now sends apt_upgrade. Sizing the planning-only boards costs a few more evaluations: the scoped default click now invokes Camera Stream Capacity at most 69 times (was 58). Composition (bug #213): the requested vision task (task: detection, classification, segmentation, pose) and the model input size (input_resolution from the caller, else the model-facts registry row for the sizing model) are forwarded into every Camera Stream Capacity request, published as composed_requests.camera_stream_capacity; before, a classification stage was sized as 640×640 detection. An NVR task is a Frigate workload and is not forwarded as a model task.
1.13.12026-09-26A PoE-powered node falls back to the registry 802.3bt splitter only when the carrier search without the PoE PD need finds a carrier that meets every other requirement (bug #192). Before, the fallback also applied when no carrier met the other needs (a SATA drive interface, an outdoor maximum ambient), so a PoE run in a harsh environment could win with no carrier at all while the same run without PoE excluded that module. Such a module is now ineligible exactly as without PoE; winners that change move to a module with a qualifying carrier (for example 4 × 1080p outdoor-exposed PoE: Jetson Orin NX with no carrier → Jetson AGX Orin on the Seeed reServer Industrial J501).
1.13.02026-09-26A platform is sized at the smallest recommendation-eligible node count, not the smallest one that is merely not a FAIL (bug #190). When the only obstacle to eligibility is a per-node load (for example a Frigate detection rate inside the stock detector's published latency band), the sweep adds nodes up to the cap; if no count is eligible, the smallest admitted count stays, planning-only. Scoped and exhaustive search apply the same rule. Ranking weights, terms and the published score are unchanged. Example: 16 × 1080p NVR at detect 5 fps had no winner (every board planning-only at 3 nodes, 30 detections/s per node); it is now Jetson Orin Nano Super × 4 (20/s per node).
1.12.02026-09-26Owner decision 2026-09-26: Optimize for power stays a balanced objective (no weight, anchor, role threshold or ranking change). The result adds lowest_power_eligible, computed under every goal: the recommendation-eligible winner-pool configuration with the lowest total power, published only when it is not the winner, with its watts against the winner’s, the saving (per node only on equal node counts), both scores and ranks_lower_because recomputable from the published terms and weights. Informational: the winner, the ranked order and the roles are unchanged.
1.11.02026-09-26A requested power mode the module has no preset for is no longer dropped with the node sized at catalog maximum watts (bug #186). The candidate is sized at its highest preset at or below the requested ceiling and publishes requested_ceiling_w, selected_preset and the resolution, with an informational note; when every preset exceeds the ceiling (or a module without presets states more power than it), a power_mode_ceiling FAIL excludes the candidate. A supported preset is unchanged.
1.10.02026-09-25PoE planner checks are now candidate-specific. For PoE-powered candidates, Hardware Match composes PoE Node Planner with that candidate's node_count and planning_configuration.poe_supply (pse_required_w + PD class), carries those constraints on that candidate, and publishes the planner-selected planning_configuration.poe_switch_id for downstream designer/TCO pricing.
1.9.12026-09-24Hardware Match now carries Jetson Power & PSU risks through candidate rollups and publishes them on ranked entries and the head result, so onboard-PD unknown-budget evidence gaps surface as FIT WITH RISKS in both Hardware Match and Architecture Designer.
1.9.02026-09-24A PoE-powered node is judged on its carrier's documented PD input or the registry splitter: Hardware Match passes the carrier-finder best into Jetson Power & PSU, widens the carried checks to poe_pd, psu_sizing and input_voltage, and publishes planning_configuration.poe_supply. An unknown onboard-PD budget (can_flip_verdict: false) is FIT WITH RISKS, not planning-only; a psu_sizing FAIL eliminates the candidate.
1.8.12026-09-24A sealed_fanless enclosure implies the fanless constraint: the thermal check takes the passive path (chassis as heatsink) instead of defaulting a fan heatsink inside the sealed box and failing every module on fan_in_sealed. Same answer as fanless: true; the carrier need fanless follows.
1.8.02026-09-20When nothing is recommendation-eligible, winner and authoritative_winner are empty. Unevidenced / heuristic-overload boards stay in ranked[] and best_planning_candidate — they are not a purchase recommendation. A family filter that eliminates the evidenced SKU no longer promotes an unevidenced sibling into winner. Scoped-default Camera Stream Capacity invocation claim restated to the measured 58 (already the count on main after #283; the previous 53 claim was stale).
1.7.12026-09-19A platform that fails screening and is re-evaluated by the full sweep is excluded once, not twice: tier 2 owns its single entry in excluded[], so coverage.evaluated counts each platform once. Winners and rankings are unchanged.
1.7.02026-09-19One workload sizing-model default: a request that names no model sizes on YOLO11s, the same model the Architecture Designer now puts to Hardware Match (it was YOLOv8n here and YOLOv8s in the designer's request). Answers for workloads that name no model change; a stated model_family / variant is unaffected. Scoped search re-sweeps a platform's node count at full depth before excluding it when the selected carrier's drive pool fails a storage check the screened pass did not, so scoped and exhaustive agree. The composed Carrier Finder call sets prefer_priced: among carriers that meet the needs equally, a priced one is chosen.
1.02026-09-09First release. Eighteen catalog candidates; the deterministic feasibility filter on hard facts only; one ranking function over five terms with one class E weight table; the minimum-feasible-node rule with the balanced camera split; alternative roles as labels on the ranked list; the ecosystem term dropped; class B vendor prices where a listing resolves and class E otherwise; UNKNOWN capping the verdict and the evidence term without eliminating a candidate.

Method changes bump the method version; the composite dataset version follows the newest of the registries this engine composes, and every result also carries the per-engine versions in sub_engines.