Architecture Designer — methodology

Method version 1.24.0 · engine: /engines/architecture-designer/ · composes Hardware Match, Model Match, Compute Fit, Camera Stream Capacity, the Thermal Feasibility Checker, Carrier Finder, the Jetson Configuration Checker, Jetson Power & PSU, Frigate Fit, Drive Endurance and Deployment Cost & TCO.

One whole architecture, composed and re-decided nowhere. This engine has no ranking function of its own. It owns exactly one judgement — how to put more than one model stage on one accelerator — and that judgement is class E, so it is labelled on every result and it caps the verdict.

Contents

  1. What it decides, and what it does not
  2. The composition: which engine answers which question
  3. Hardware Match’s answer is copied verbatim
  4. The pipeline: stages, rates and the fan-out
  5. Composing stages on one accelerator — the class E assumption
  6. How the verdict is composed, and where it is capped
  7. Three inference envelopes
  8. Verdict drivers
  9. Alternatives keep Hardware Match’s order
  10. Where the whole-system rollups come from
  11. Legacy figures with no V2 owner, and what happened to each
  12. What the result reports about its own coverage
  13. What invalidates a result
  14. Method changelog

1. What it decides, and what it does not

The Architecture Designer answers one question: given this workload, these constraints and this pipeline, what is the whole deployment — which platform, at how many nodes, with the cameras split how, running which model at each stage, against which constraints, with what bill of materials, and what should be measured before any of it is bought.

It does not decide which platform wins. That is Hardware Match's question, and its answer is copied here without change. It does not decide which model to run either — that is Model Match's, per stage. It does not compute a throughput, a latency, a memory figure, a thermal margin or a carrier verdict of its own: every one of those comes from the engine that owns it, stamped with that engine's name, so any number on the page can be reproduced by calling that engine directly with the same inputs. That is what makes the composed answer checkable rather than asserted.

Derived carrier requirements (method 1.5.1). For bare modules, Hardware Match always composes Carrier Finder. This engine forwards environment-derived needs as DERIVED (industrial for factory / harsh indoor; outdoor and mobile pass ambient, fanless and enclosure independently — never industrial for outdoor alone), and derives module_included: false so bundled systems stay out of scope unless the caller states module_included: true or form_factor: system. Stated carrier needs override per id. The architecture block carries carrier_id, carrier_needs provenance, and prices the selected carrier through Deployment Cost & TCO when a registry price exists.

Environment → planning ambient (method 1.17.0). When no ambient_max_c is given, the environment sets the ambient the thermal checks run at. The figures are planning bands from the site's thermal research (the environmental-match bands and the vehicle zones), not measurements of any site: class E, published as an assumption, recorded in provenance.defaulted and provenance.derived, and overridden by any stated ambient_max_c.

EnvironmentPlanning ambientBasis
indoor, controlled25 °CThe 25 °C benchmark condition; this is also the thermal engine's own default, so nothing new is sent to Hardware Match.
indoor, warm · industrial / factory35 °CAbove the 20–30 °C indoor band, at the 35 °C point where the fanless and sealed-enclosure derating rules start.
outdoor (shaded / sheltered)40 °CThe “ambient up to 40 °C” outdoor band.
outdoor, exposed50 °CInside the 35–55 °C exposed fanless-outdoor band, 10 °C above the shaded figure.
mobile / vehicle55 °CThe top of the 25–55 °C typical cargo-area band; a parked cabin without air conditioning reaches 60 °C.

A derived ambient above 25 °C is sent to Hardware Match as ambient_max_c, so it also becomes a carrier temperature need, exactly as a stated ambient always has. The enclosure is not derived from the environment: state it, and the thermal checks add that enclosure's internal rise.

Battery and UPS (method 1.17.0). Battery and UPS runtime are not modelled: no energy-storage, runtime or power-limit model exists. The request still accepts power_source: battery or ups, and the result lists it under not_evaluated with that reason and an assumption line; it never becomes a constraint. Mains and PoE are modelled. See Jetson Power & PSU for supply sizing.

What it does own is the composition itself: how the per-stage results are put together on one node, and what that composition is allowed to claim. There is exactly one judgement in that, it is unmeasured, and §5 is about nothing else.

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.

2. The composition: which engine answers which question

QuestionOwnerWhat this engine takes from it
Which platform, how many nodes, how are the cameras splitHardware MatchThe winner verbatim: platform, node count, per-node camera assignment, unit and total hardware cost and power, the five term scores, the weight table, the ranked alternatives with their role labels, and the eliminated candidates with the constraint that eliminated each.
Which model runs at this stageModel MatchThe winning model for the stage's task on the chosen platform, at the stage's precision, with its throughput, utilization, latency tier, memory split, reference and deployment accuracy and that accuracy's evidence group — an estimate is flagged estimated — measurement needed, copied from Model Match unchanged — and the stage's own alternatives and universe counts.
Does a pinned model hold this stageCompute FitThe same constraint objects for a model the caller named, so pinning changes who answers but not what is answered.
Decode, inference and memory at the nodeCamera Stream CapacityThe per-node decode, inference and memory constraints for the cameras assigned to one node.
Will it survive the enclosureThermal Feasibility CheckerAmbient rating, cooling capacity, the module power ceiling and the fan-in-a-sealed-box conflict.
Is there a board to plug it intoCarrier FinderWhether a carrier meets merged stated and DERIVED needs (environment maps to industrial or outdoor ambient; never outdoor→industrial), and which.
Will the software stack line upJetson Configuration CheckerJetPack, runtime and power-mode compatibility for the chosen module.
How big a supply, and can PoE carry itJetson Power & PSUThe module power ceiling and the PoE path.
Does the NVR software have a detector for itFrigate FitDetector, decode preset, host CPU, host link and preprocessing — asserted only for the surveillance use cases.
Will the drives hold and survive the writesDrive EnduranceCapacity, endurance, warranty horizon and sustained throughput.

Every constraint returned carries engine and check, its evidence class, its source records and the assumptions behind it. The result also carries sub_engines: the method version and dataset version of every engine that contributed, and a legacy flag on the one that is not V2 yet (the cost engine).

3. Hardware Match’s answer is copied verbatim

This is the rule the engine was built around, and it is worth stating in the flat form:

  • No second ranking pass. There is no scoring function in this engine. The platform, the node count, the per-node camera assignment, the hardware cost and the hardware power are what Hardware Match returned; the five term scores and the weight table on the page are its own, published so the total can be recomputed from the printed numbers.
  • No confidence re-pick. A LOW confidence on the winner is reported, never a reason to reach past it for the runner-up. The legacy orchestrator did exactly that — ranked, then spliced a multi-node economics winner to the front, then re-picked on a confidence tier — and the disagreements it produced are the reason this engine has one selection step instead of three.
  • No mutation of the alternatives. alternatives[] is Hardware Match's ranked list minus the winner, in its order, carrying its own role labels — lower_cost, lower_power, higher_headroom, stretch. Nothing here re-sorts it, filters it, re-scores it or adds a role to it. The page renders it in the order it arrives.
  • No override input. There is no field by which a caller picks the winner. Pinning a platform narrows the candidate set Hardware Match ranks and changes no other rule; it does not choose an answer, and if the pinned platform cannot hold the load the result says so instead of substituting one you did not ask about.

One consequence is worth being explicit about, because it looks like a bug until you see the alternative. Hardware Match ranks platforms against one model's load — the workload's model family and variant — because that is the question its five terms are defined over. The pipeline is then composed on the platform it picked. So a pipeline that does not fit on that platform is reported as not fitting, at whatever percentage of one accelerator it needs, rather than quietly triggering a second ranking pass against a different load. The result names the levers: reduce the fan-out, pin a smaller model, raise the node cap, or pin a platform.

The request put to Hardware Match carries that stage’s vision task (classification, detection, segmentation or pose) with its model, so the throughput it ranks on is read for the task the stage runs — unless the model is filed under another task (a detector named for a segmentation stage is sized as the detector it is, not as a cross-task estimate). With no model named, segmentation and pose are sized on their own defaults, YOLO11s-seg and YOLO11s-pose (method 1.17.0) — never on the detector. The benchmark corpus has measured FP16 rows for those two models on some Jetson Orin modules — YOLO11-seg on the Orin Nano Super and the AGX Orin, YOLO11-pose on the Orin Nano Super, the Orin NX 16GB and the AGX Orin 32GB — but no INT8 row on any Orin: no INT8 YOLO11-seg or calibrated INT8 YOLO11-pose measurement on an Orin is published. Segmentation and pose therefore default to FP16 (method 1.20.0): with no precision named they are sized on the measured FP16 rows, and the precision is recorded as a derived planning default, never as your choice. A named INT8 is evaluated as asked: on an Orin it reads NEEDS VALIDATION and names the missing benchmark. It also carries the caller’s power_mode unchanged. Hardware Match resolves the mode as a ceiling and the design is computed at the preset it selected (planning_configuration.power_mode); an unrecognised mode is a validation error naming power_mode, never dropped. The exact request is published as composed_requests.hardware_match.

Precision (method 1.20.0). A precision you name is the precision of every stage and of the model Hardware Match sizes, exactly as named. With none named, each stage of a pipeline you send runs its own task’s planning default — FP16 for segmentation and pose, INT8 for detection and classification — and the model Hardware Match sizes runs the workload’s: the task you state, else — for a pipeline of exactly one stage naming a task Hardware Match sizes (detection, classification, segmentation or pose) — that stage’s own task and model, the stage’s named model if it names one, otherwise that task’s default (method 1.22.0, bug #268), else the task the model registry files the model you name under. Without a pipeline the single stage is the workload and runs that same default; a pipeline of two or more stages keeps the workload’s own (unstated → detection) task — there is no single stage to stand in for it. Pinned to (or filtered to a family of) platforms that run only INT8, the FP16 task default falls back to INT8, their supported precision, and the record says why. The result lists precision in provenance.defaulted, marks each such stage precision_defaulted and adds one DERIVED record per task-specific default, with the reason. When you state a JetPack, a sourced build limitation of a model at its precision on that JetPack’s TensorRT release is carried from Hardware Match into compatibility_risks and risks: YOLO11-seg INT8 is reported not buildable through any upstream-supported path on TensorRT 10.3.0 (JetPack 6.1, 6.2 and 6.2.1). It is a validation requirement, never a reason to change the platform or the verdict.

4. The pipeline: stages, rates and the fan-out

A pipeline is up to four stages. Each stage carries a task, what it runs on, and a rate:

  • A stage that runs on camera frames is sized at cameras on one node × the detect rate × the motion share. An explicit per-stage frames-per-second figure overrides that; left blank, the stage inherits the workload's detect rate.
  • A stage that runs on an earlier stage's output is sized at the parent's rate × the fan-out, where the fan-out is how many detections each frame produces. It defaults to one per frame and the result marks it as defaulted when it was.

The fan-out is class E. Nothing measures how many objects your scenes contain; it is a statement about your deployment, not about the hardware, and it multiplies straight into the throughput the downstream stage is asked for — two detections per frame doubles that stage's required rate. It is therefore always shown, always labelled, and never silently chosen for you beyond the default of one.

Every stage is sized on one node, not on the fleet, because that is the machine the models actually share. A stage's model is Model Match's pick out of the models with a benchmark row on that platform, or Compute Fit's verdict on the model you pinned; either way, the throughput, latency, precision, runtime, batch and memory figures are that engine's own and are reproduced unchanged.

Model preference (method 1.17.0). The preference chooses the variant inside the family the platform was sized on; it never changes the platform. On balanced the default frames stage keeps the exact model Hardware Match ranked on (YOLO11s by default). On accuracy, speed or size the variant is left open and Model Match ranks the variants of that family that fit this node with its own weights for that preference: accuracy takes the most accurate variant that still fits, speed the one with the most throughput margin, size the smallest weights. When one variant is both the fastest and the smallest (YOLO11n in the YOLO11 family) speed and size agree. A family and variant you name are never overridden. Each stage publishes model_selection — the basis, the family, the preference and why this variant.

5. Composing stages on one accelerator — the class E assumption

When more than one stage lands on one node, they share one accelerator. This engine composes them by summing their utilizations and adding their memory on the shared memory budget. That is the whole model, and it has no measurement behind it.

There is no measured concurrent-model throughput anywhere in this corpus. That statement is precise, and it is worth unpacking, because two things that look like evidence for it are not:

  • The multi-stream scaling curve models N streams of ONE model. It says what happens to throughput when you feed a single loaded network more concurrent streams. It says nothing about two different networks contending for the same compute units, the same memory bandwidth and the same scheduler — and treating it as if it did would be borrowing a number from a question it was never asked.
  • The one multi-model source on record is a recommendation, not a measurement. It advises running the models in separate containers with CUDA stream priority rather than under MPS, and it budgets roughly 3 % container overhead. It does not measure the throughput either model achieves while the other is running. So it is cited as guidance and it is never turned into a coefficient; a 3 % container overhead is not a concurrency model.
  • The stage vocabulary in the research corpus is decode → preprocess → infer → postprocess — the internal stages of running one model, not two models sharing a device.

Summing is the honest choice among the available ones. It is not conservative in every direction: real contention can be worse than a sum, because two resident networks also contend for memory bandwidth and cache, and it can be better, because a stage that is latency-bound rather than throughput-bound may interleave into the other's gaps. Which of those dominates on your silicon, your runtime and your models is exactly the thing nobody has measured here.

So the sum is stamped class E — engineering heuristic, no source record — on the pipeline block, on the pipeline_accelerator_share constraint and in the assumptions, and the result links to the measurement protocol, which is how you replace this assumption with a number. Memory is composed the same way and reports UNKNOWN rather than an estimate whenever a stage has no memory split on record — an unknown is never filled in with a guess.

6. How the verdict is composed, and where it is capped

The architecture's verdict is the worst of: Hardware Match's verdict on the winning platform, every stage's verdict, and the status of every composed constraint. A FAIL anywhere makes it NO FIT; a NEAR LIMIT makes it FIT WITH RISKS; an UNKNOWN caps it at NEEDS VALIDATION and never eliminates anything. Every row keeps the elimination authority its owner stamped, and a FAIL is only ever raised on authoritative or bounded evidence — a miss on planning-only evidence is REQUIRES VALIDATION wherever it is composed.

On top of that there is one hard cap. Whenever more than one stage shares an accelerator, the verdict is capped at NEEDS VALIDATION, regardless of how much headroom the sum shows. A class E sum can show a miss — 155 % of one accelerator — but it cannot eliminate on its own: class E never independently eliminates (elimination authority), so the shared-accelerator row is REQUIRES VALIDATION with the modelled shortfall stated. Nor can it ever confirm a fit, because the arithmetic that would confirm it is the arithmetic nobody has checked. A stage that misses on its own is judged by its owner's row, with that row's elimination authority. A single-stage architecture is not capped: nothing is composed, so there is no assumption to carry.

Each stage is also reported on its own, with its own verdict, so a reader can see which part of the composition is solid and which part is the assumption.

A NO FIT with no platform to design on is an answer (method 1.17.0). When Hardware Match finds no feasible platform, or only planning-only ones, the response is HTTP 200 with verdict: NO_FIT, architecture: null and refusal_reason — never an HTTP 400. It carries the excluded platforms with the row that eliminated each, the planning-only candidates with their reasons, Hardware Match's best planning candidate capped at NEEDS VALIDATION, the questions that could change the answer (including “design on the best planning candidate anyway”, a pin), the workload echo, provenance and the composed Hardware Match request. HTTP 400 is kept for malformed or invalid requests.

Two refusal kinds (method 1.17.2). The shared refusal row names which one it is. When every candidate failed a hard requirement it is ALL_CANDIDATES_EXCLUDED, and each excluded platform names its reason row. When candidates survived but every survivor is planning-only it is NO_RECOMMENDATION_ELIGIBLE (reason INSUFFICIENT_EVIDENCE, still verdict NO FIT): nothing failed, so there may be no excluded platform at all — the planning-only rows, each with its disposition reason code, are the reason, and the question pins the best of them. Applying that option designs on the pinned platform, capped at NEEDS VALIDATION, even when a family filter was set (the option clears it).

Use case and budget tier are not design inputs (method 1.17.2). Security, retail analytics, industrial inspection and traffic are labels: no engine models a difference between them, so the result lists use_case under not_evaluated as informational and the design is the same for all four. The NVR (Frigate) path is a task (task: nvr), not a use case. A budget_tier is accepted and listed as not evaluated; budget_usd is the budget Hardware Match compares each configuration's total cost against, as a label (never a filter).

6a. Three inference envelopes

Several constraints share the check id inference. They are different operating envelopes and are labelled separately on every result (label, represents, envelope). primary_bottleneck names which envelope breaks first — on NVR workloads that is usually Frigate Fit's detector budget, not generic platform throughput.

  • Platform detection throughput (camera_stream_capacity.inference, envelope platform_inference) — benchmark-scaled detection fps the accelerator sustains for the streams on one node.
  • Frigate detector envelope (frigate_fit.inference, envelope frigate_detector) — detect fps × cameras against the detector's measured detections/s at the detect rate.
  • Stage model throughput (compute_fit.throughput, envelope stage_model) — the pinned or selected stage model's benchmark fps on this accelerator.

Decode and preprocessing rows follow the same pattern: Camera Stream Capacity vs Frigate Fit, each with its own label.

6b. Verdict drivers

When the verdict is not FIT, verdict_drivers (on the results and on the architecture) lists every owner row that produced it, verbatim from the engine that owns it (method 1.18.0): each constraint whose own verdict is worse than FIT, each row of Hardware Match’s winner that the design re-ran for its own inputs and does not hold itself, Hardware Match’s planning-only admission on a pinned platform, a material risk on its winner, the class E multi-stage pipeline cap, and any blocking unknown not already listed. A FIT WITH RISKS names at least one NEAR LIMIT row (or a material risk), a NEEDS VALIDATION an UNKNOWN or REQUIRES VALIDATION row, a NO FIT a failed row; a FIT names none.

Each driver carries its owner’s engine, check, status, value and limit (required, available, unit), its stage or scope and a row_source (architecture, hardware_match_winner, hardware_match_admission, hardware_match_winner_risk, pipeline_composition, blocking_unknown), plus cause, validate, to_reach_fit and flips_verdict_to (FIT only when a single NEAR_LIMIT or REQUIRES_VALIDATION driver remains). A row Hardware Match’s verdict rests on is carried even when the designer re-ran that check for its own recording topology and reads it differently, because an architecture verdict is never better than the hardware verdict; every FAIL or NEAR LIMIT driver also has its high- or medium-severity risk. The order is FAIL → NEAR_LIMIT with utilization ≥ 0.95 → REQUIRES_VALIDATION → other NEAR_LIMIT → UNKNOWN, then utilization descending (class E presentation). Rows that produced nothing (a non-flipping or not-asked prerequisite) are listed under verdict_prerequisites.

The evidence gap that decided the platform (method 1.18.0). Hardware Match publishes its best planning candidate even when a winner exists. When that candidate is planning-only and ranks above the winner on Hardware Match’s own ordering past the disposition key (score, then platform, then node count), the result names it in platform_evidence_gap: the candidate and the winner with their scores, Hardware Match’s disposition reason code and the missing evidence. It is informational, not a verdict driver, and changes neither the winner nor the verdict.

6c. Alternatives keep Hardware Match’s order

alternatives[] is Hardware Match's ranked[] minus the winner, in the same lexicographic order: recommendation disposition and eligibility, thin registry coverage, then score — not score-descending. Each alternative carries ordering_key with hardware_match_rank (its index in ranked[]), disposition, coverage flag and score. results.alternatives_ordering_note repeats Hardware Match's weights.ordering_note verbatim.

7. Where the whole-system rollups come from

Bitrate, storage, power and cost come from the V2 engines that own them; each totals tile carries that line's class in totals.classes (and totals.sources names the owner). totals.cost_label is Sourced hardware BOM when every line is priced; totals.cost_scope lists included line kinds and known omissions (switch, cabling, installation, and similar). The bill of materials is Deployment Cost & TCO — registry-priced lines with per-row evidence classes (camera resolution classes remain class E planning allowances). The annual energy rate is a class E input. totals.evidence_class is the weakest class among the rollup lines.

FigureOwnerClassHow it is composed
Aggregate ingress bitrate and network utilizationcamera_stream_capacityowner's (D on the reference)The winner's per-node network constraint × node count; uplink and NVR bandwidth are not sized here
Storage footprint and drive sizing at retentiondrive_enduranceowner's (A on the reference)Drive Endurance, following the recording topology. Node-local: each node's drives are sized on the heaviest camera split and every node installs the same whole drives; storage_required_tb sums the actual per-node camera assignment (never per-node × node count) and storage_tb is the installed capacity that covers it. Shared recording: retention lives on one central pool sized for all cameras, storage_tb is the pool's usable capacity, and each node keeps a buffer drive (storage_per_node_tb). Pool and buffer drives are separate bill-of-materials lines, and drives_total is the sum of the drive lines' quantities. BOM storage capacity covers the whole-system storage footprint. The pool's own rows are Drive Endurance's, carried verbatim into the architecture's constraints and its verdict: pool capacity, bays, endurance, throughput, network ports and redundancy, and the pool drive's warranty and service life, each with the owner's constraint id, value, status and evidence class (scope shared_recording_pool). The pool's RAID level is Drive Endurance's redundancy-aware planning default for the chosen host: the host's single-parity level across at least three drives with three or more recording bays, a two-drive RAID 1 with two, otherwise basic with no redundancy, which requires validation; every level is sized only at drive counts its vendor allows. The pool host is chosen by Drive Endurance's host sweep: configurations whose RAID level survives a drive failure rank ahead of those that do not, price-first within each group, so a pool without redundancy is chosen only when no redundant configuration holds the recording. The designer states no level of its own, and storage.shared_recording publishes the level, its input state and the drive failures the pool survives; the Deployment Cost & TCO pool lines price exactly that pool's drives. The architecture verdict is never better than Drive Endurance's verdict on the same pool, and composed_requests.drive_endurance_pool publishes the exact request so the pool can be re-run.
System power and supply sizingpoe_planner + jetson_power_psu (module/PSU) + catalog TDP fallbackweakest of owners (E when TDP fills module draw)PoE camera and node demand come from PoE Planner when poe_powered is true (camera_poe_w and node_poe_w; both 0 when cameras are not PoE-powered). The planner call carries the winner's node_count and planning_configuration.poe_supply, and the result publishes the selected poe_switch_id used for BOM/TCO switch pricing. Module draw per node uses Jetson Power & PSU's planning-mode ceiling when the platform has a power-input registry row and the engine returns a finite figure; otherwise catalog tdp_watts × nodes as class E with the assumption named. totals.power_w equals the sum of the published power breakdown: module + drive draw per node × nodes plus camera PoE. totals.power_breakdown.excluded names switch own draw, network gear and supply losses beyond the PSU sizing factor, and camera power when the cameras are not PoE-powered. totals.power_scope is system_partial on today's composition. psu_w is Jetson Power & PSU per node × nodes plus the PoE switch budget when the engine sizes a supply; when it cannot, the composed BOM carries an unpriced psu selection unavailable line (no PSU model for <platform>) so Deployment Cost & TCO reports the gap rather than omitting PSU.
Hardware bill of materials and annual energydeployment_cost_tcoweakest line (A–E)Registry-priced BOM from composed quantities; compute line reproduces Hardware Match's price; energy uses designer totals.power_w × duty × rate

Frigate inference when the pipeline names another detector. When the user names a stage model that is not Frigate's stock detector on that platform, the Frigate inference check is carried as detail.advisory with reason: stock_detector_differs. It does not bind feasibility, node count, verdict rollup, primary bottleneck or risks[]; the other Frigate checks stay binding. A pipeline stage without a model is sized as if no model were named: Model Match picks it and a Frigate workload is judged on the stock detector.

Frigate load parity on NVR workloads. Frigate Fit's per-node detection demand is the pipeline's stated frames-stage rate when one is given (otherwise the shared NVR default). On the reference sixteen-camera NVR input, Frigate inference required equals the frames stage's required_fps.

Invariant: totals.power_w equals the sum of the published power breakdown (module draw × nodes, node-local drive draw, pool drive draw, storage-host typical draw when published, plus camera PoE when PoE-powered). Pool and host draw are separate from the edge-node PSU rating in totals.psu_w.

The compute line is Hardware Match's price — class A–C when a vendor listing is on record, otherwise the catalog planning price (class E). The hardware cost and hardware power on the architecture block are likewise Hardware Match's, not the whole-system rollup's — which is why those two figures and the whole-system rollup can differ on the same result and are shown separately rather than reconciled into one number.

A rollup that does not resolve is reported as null with a risk explaining why, never estimated. When a registry line has no listing, unit_usd stays null, cost_complete is false and the note names the gap.

8. Legacy figures with no V2 owner, and what happened to each

The engine this one replaces produced several figures that no V2 engine owns. Dropping them silently would hide a change in what the page claims, so each one is listed here with its disposition.

Legacy figureWhat it assertedDisposition
ENCODE_STREAM_CEILING A per-platform ceiling on simultaneous hardware encode sessions. Carried as a gap. The session counts have not yet been carried into a sourced V2 row, so no encode-session constraint is asserted here. Encode capacity is a real limit on a re-encoding NVR deployment; its absence is reported in gaps[] rather than replaced with a number.
ENCODE_DECODE_CONTENTION A penalty applied when the same block does encode and decode at once. Carried as a gap. Same reason: not yet a sourced V2 row. Decode is asserted by Camera Stream Capacity with its own sources; the contention penalty is not re-applied on top of it from an unsourced table.
memory_bandwidth_ceiling A throughput ceiling derived from module memory bandwidth. Dropped as unsourced. No source record stood behind the derivation, and a ceiling that cannot be cited cannot cap a published throughput.
scaling_curve_used Which multi-stream scaling curve had been applied. Dropped as unsourced. The multi-stream efficiency that is applied now is Compute Fit's, named in its own assumptions with its own class; a second, separately-labelled curve on the composed result asserted nothing checkable.
int8_map_drop_expected An expected accuracy loss in mAP points from INT8 quantisation. Dropped as unsourced. Quantised accuracy is now Model Match's, resolved per model and per precision from published figures with the evaluation set named — or reported as absent. A single generic drop applied to every model was a guess wearing a number.
sync_recommendation Advice on synchronising multi-node capture. Dropped as unsourced. It was editorial guidance with no record behind it and no engine that owned it.
_modules_required How many modules the deployment needed, computed inside the legacy orchestrator. Replaced. Node count is now part of the candidate Hardware Match ranks, so the figure on the result is hardware_match.winner.node_count — chosen inside the ranking rather than corrected afterwards, with the per-node camera assignment beside it.

9. What the result reports about its own coverage

  • Candidates, evaluated, feasible, excluded — and a per-registry count, so a platform that ten registries know well is distinguishable from one that three of them mention.
  • Thin coverage is named. A platform present in three or fewer of the platform registries is still evaluated and still ranked, and is capped at NEEDS VALIDATION with the reason stated.
  • Registry-only platforms are named. A platform that exists in a data registry but not in the hardware catalog is not a candidate, and the result lists which ones those are rather than leaving them silently absent.
  • Stages resolved and rollups resolved are counted, so a partial answer is visibly partial.
  • Every eliminated platform comes back with the exact constraint that eliminated it — the check, the engine, the status, what was required and what was available.

Typed comparisons and scope labels (v2.51). Every constraint row on the page and in the copied summary prints its relation with the operator its comparison type declares — required ≤ available for a minimum-capacity check, actual ≤ maximum for a ceiling, minimum ≤ actual ≤ maximum for a range, = / ≠ with the words compatible, satisfied or true for a compatibility, prerequisite or boolean check, ∈ / ∉ for membership, and n/a where the check does not apply — followed by a mark taken from the engine's status: ✓ when the relation holds, ✗ when it fails, ? when it is not established. A failed check therefore reads 40 /s ≤ 25 /s ✗, never as a true assertion. Each row also carries its constraint id (engine.check) and its scope — per node for the checks Hardware Match composes on one candidate node (thermal, power, stream capacity, JetPack, carrier, Frigate, drives), per stage for a pipeline stage's checks, deployment for the PoE switch, pipeline for this engine's own composition rows. Only rows with an identical owner, check, scope, required, available and status collapse into one line with a ×N badge; a node-level check and the same check re-asserted for a stage stay separate. Above the table, four things the verdict badge used to blend are stated one by one: the winner's feasibility (Hardware Match's verdict), its recommendation admission (eligible, planning-only, insufficient evidence), the search coverage (scoped or exhaustive, candidates evaluated, open questions) and the confidence label. No number or status changes in the engine for any of this; it is display only.

10. What invalidates a result

  • A new benchmark row. Throughput here is the pessimistic edge of the rows that resolve for each model on this platform. One new measured row can move a stage's available fps, its utilization, its evidence class and therefore the platform ranking underneath the whole architecture.
  • A firmware or JetPack change. A different JetPack, runtime or power mode changes what the configuration checker asserts, what throughput the benchmark rows apply to, and in some cases whether the configuration is supported at all. An architecture designed against one release is not evidence about another.
  • A different fan-out. The detections-per-frame figure multiplies straight into every downstream stage's required throughput. If your scenes carry four objects where the result assumed one, the downstream stage needs four times the rate and the composition changes completely.
  • A measurement that contradicts the sharing assumption. This is the one that matters most. The moment somebody measures two models running concurrently on this silicon, the summed utilization on this page is either confirmed or falsified — and if it is falsified, every multi-stage verdict computed from it moves. Until then the cap at NEEDS VALIDATION is the honest reading, and the measurement protocol is how you close it.
  • Anything the sub-engines' own caveats cover. Software versions, thermal state, input resolution, batch size, the multi-stream efficiency curve, and the fact that every benchmark row is inference-only.
  • The class E rollups. Network, storage, system power and the non-compute bill of materials are heuristics, not sourced figures. Do not put them in a purchase order without checking them against the vendor quotes.

11. Method changelog

MethodDateChange
1.24.02026-09-29Shared-recording per-node buffer (#260): Drive Endurance is called with role: node_buffer for the one-day local buffer; stamped constraints use drive_endurance.buffer_capacity so they never share an id with Hardware Match's node-local drive_endurance.capacity row. Numbers and verdicts are unchanged.
1.23.02026-09-29An accelerator card (Coral, Hailo) attaches to a host system that is priced separately and never carries a sourced power figure of its own; the BOM's host line is now named in totals.power_breakdown.excluded ("the host computer's power is not modelled; the figure covers the accelerator only") instead of being left out of both the breakdown and the exclusion list (bug #273). The accelerator card's own draw is unaffected — it is still summed in modules_w from the same catalog TDP figures as before. totals.power_w does not change for any platform; only accelerator-pinned designs' excluded[] gains this line.
1.22.02026-09-29A pipeline of exactly one stage naming a vision task Hardware Match sizes (detection, classification, segmentation or pose), with no workload task_type stated — the shape the page always sends — sizes Hardware Match on that stage’s task and model (bug #268, duplicate #272): the stage’s own named model if it names one, otherwise that task’s default model, at the stage’s own resolved precision (segmentation and pose still default to FP16, 1.20.0). Before, Hardware Match was always asked about the unstated task_type’s detection default regardless of what the one stage actually ran, so a sixteen-camera segmentation pipeline sized the platform (Jetson Orin Nano Super × 2) on a YOLO11s detector while the stage itself ran a YOLO11-seg model Model Match picked independently; it now sizes on segmentation and reads Jetson Orin Nano Super × 3, FIT WITH RISKS — the same design stating task_type: segmentation gives. A named precision is evaluated as named: a named INT8 on the same body still has no INT8 segmentation evidence and is unchanged. A stated task_type (even one that disagrees with the stage), a pipeline of two or more stages, and the NVR/Frigate task are unaffected — there is no single stage to stand in for the workload, or the caller already answered the question, or Frigate has its own path. The task is recorded DERIVED from the stage, never as though the caller stated task_type.
1.21.02026-09-29elimination authority (#263, owner ruling 2026-09-29). Every architecture and stage row carries its owner's elimination_authority verbatim, and so does every verdict driver that names a row. The class E shared-accelerator and pipeline-memory rows are planning-only: over 100 % they are REQUIRES VALIDATION with the shortfall stated (a pinned YOLO11x at 8 × 15 fps is NEEDS VALIDATION, was NO FIT); a single-stage memory miss FAILs when the weights alone exceed the module. The design follows Hardware Match's eliminations and planning candidates.
1.20.02026-09-29Segmentation and pose default to FP16 (owner ruling of 2026-09-29): “the default should be a broadly runnable configuration, not the theoretically smallest precision.” With no precision named, the workload is sized and every stage is run at its task’s planning default — FP16 for segmentation and pose, INT8 for detection and classification — per stage, from one registry table; the result lists precision in provenance.defaulted, marks the stage precision_defaulted (precision_rule for a task-specific default) and publishes a DERIVED record and an assumption saying it is not your choice. Before, the shared INT8 default applied to every task, and at INT8 no YOLO11-seg or YOLO11-pose row exists on any Orin: the Full Deployment Planner’s segmentation and pose tiles refused (NO_FIT, NO_RECOMMENDATION_ELIGIBLE_PLATFORM); they now design (segmentation 16 cameras: Jetson Orin Nano Super × 3, FIT WITH RISKS; pose 4 cameras: AGX Orin 32GB × 1, FIT), the same design a named FP16 gave. Pinned to INT8-only accelerators the FP16 default falls back to INT8, with the reason. A named precision is used as named — a named INT8 segmentation still refuses — and a sourced build limitation on the stated JetPack is carried from Hardware Match into compatibility_risks and risks.
1.19.02026-09-29Composes Drive Endurance 1.5.0 (bug #259): the shared-recording pool is sized in Drive Endurance's redundancy-aware RAID planning default instead of the first level the host's vendor page lists. A sixteen-camera 1080p, 30-day design's pool moves from a QNAP TS-464 with 1 × 16 TB in JBOD (no drive-failure tolerance) to a Ubiquiti UNVR with 3 × 8 TB in RAID 5 (the vendor minimum for RAID 5 is three drives), 16 TB usable either way, priced by Deployment Cost & TCO at that drive count. The pool host comes from Drive Endurance's host sweep, which ranks redundant configurations ahead of non-redundant ones and then suitability ahead of price (owner ruling of 2026-09-29), so a one-bay recorder is chosen only when no redundant pool holds the recording. The owner's pool_redundancy row is carried with the other pool rows, so a pool without redundancy (an industrial site whose only fanless industrial host has one recording bay) requires validation here as it does in Drive Endurance, and that row is named among the design's verdict drivers with Drive Endurance's remediation. storage.shared_recording publishes raid_level, raid_level_input_state, raid_level_rule and drive_failures_tolerated, the assumptions carry Drive Endurance's line saying why the level was chosen, and the storage tile names the level and that it is the planning default. A design whose shared pool no registry host holds is NO FIT and names Drive Endurance's failing pool capacity row, with the largest pool a candidate host holds as the available figure; it read NEEDS VALIDATION behind that failing row, whose available figure was missing (25 × 4K, 151 days: 407.7 TB required against 352 TB).
1.18.02026-09-28A verdict worse than FIT names the owner rows that produced it (bug #253). The Full Deployment Planner’s detection tile at 720p × 1 and × 8 cameras read FIT WITH RISKS with no driver and no risk: Hardware Match’s winner held node-local drive capacity at NEAR LIMIT, the designer re-ran storage for its own recording topology and carried the verdict without the row. Every row whose own kernel verdict is worse than FIT is now a driver whatever its can_flip_verdict stamp (the shared-pool NEAR LIMIT rows were dropped by the stamp Hardware Match’s projection writes on every carried row), Hardware Match’s winner rows the design re-ran, its planning-only admission and a material winner risk are carried, the cap of three drivers is gone (it could cut the only row that explained the verdict), a blocking unknown is listed once, and each driver carries its value, limit, scope and row_source. results.verdict_drivers is published (the page read it there and fell back to the risk list), and the new platform_evidence_gap names a planning-only candidate Hardware Match ranks above the winner without changing either.
1.17.32026-09-28An absent power_mode is listed in provenance.defaulted and in the “Defaults applied” assumption whenever Hardware Match records it (bug #248): the designer forwards no mode, so Hardware Match plans every candidate with presets at its registry default. The designer carries that record and decides nothing new. A named mode is never listed. No design change.
1.17.22026-09-28The use case and a budget tier are stated as what they are (bugs #238, #240): the use case is listed under not_evaluated as an informational label (security, retail analytics, industrial inspection and traffic give the same design; NVR is the task nvr), and a budget_tier as not evaluated, pointing at budget_usd. The “design on the best planning candidate” option now pins in the designer's own shape and clears a family filter (bug #241) — with a family set, applying it returned the same refusal. A refusal whose survivors are all planning-only is NO_RECOMMENDATION_ELIGIBLE and carries sub_engines; it was labelled ALL_CANDIDATES_EXCLUDED with no excluded rows. The public envelope now carries the refusal row.
1.17.12026-09-28Input rules (WP-01 remainder, WP-02): ambient_max_c, budget_usd, detection_fps, latency_target_ms, motion_share, power_limit_w, headroom_target, hours_per_day, energy_rate, drives_per_node, fanless, poe_powered, media, storage_topology (an unknown value used to become auto), recording, search, model_complexity and install_method are checked before the canonical normaliser can default them; an empty string is a stated value. Unknown input keys are rejected; top-level carrier needs (never read) are rejected — send them in needs. No formula changed.
1.17.02026-09-28Four dead or misleading controls fixed and the refusal made an answer. Model preference (bug #201): accuracy, speed and size now choose the variant inside the stage's family through Model Match's ranking with that preference (balanced keeps the Hardware Match model); each stage publishes model_selection. Environment (bug #202): each environment derives a planning ambient (25 / 35 / 40 / 50 / 55 °C, class E, overridable with ambient_max_c) that the thermal checks run at; before, every environment ran at a defaulted 25 °C. Battery / UPS (bug #203): accepted, listed under not_evaluated, never a constraint. Refusals (bugs #226, #232): a NO FIT with no platform is HTTP 200, verdict: NO_FIT, refusal_reason, excluded / planning-only platforms, the best planning candidate, questions and provenance; Hardware Match's NO FIT is read by its verdict, and the engine itself answers in the shared refusal envelope (success, verdict NO_FIT), so every composer — the Full Deployment Planner included — reads the designer's verdict, not a failure flag. Segmentation and pose default to YOLO11s-seg / YOLO11s-pose (bug #228).
1.16.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, an unknown optimize_for (e.g. "speed"), environment, use_case or precision, retention_days outside 1–365 (the agent-tool and Full Deployment Planner range), max_nodes above 8, a pipeline stage whose task is unknown or that exceeds the four-stage cap (previously answered with the stage listed in gaps) — 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.
1.16.02026-09-27power_mode is forwarded to Hardware Match. It was dropped: an unknown mode such as banana was accepted, and 7w designed the 25 W configuration (8 × 1080p: Orin Nano Super × 1 at 25W, where Hardware Match at 7w picks Orin Nano Super × 2 at 7W). An unrecognised mode is now Hardware Match’s 400 validation error naming power_mode; a recognised one is designed at the preset Hardware Match resolves for it. The Hardware Match request also carries the workload stage’s vision task (bug #213): a classification workload reached Camera Stream Capacity as detection, so every inference row was a cross-task estimate and the 16-camera Classification design in the Full Deployment Planner was refused; it is now designed on Jetson Orin Nano Super × 2 at NEEDS VALIDATION (MobileNetV2 has no model-memory row). A model filed under another task keeps its own (the segmentation and pose default is still the YOLO11s detector). When no board is recommendation-eligible, the best planning candidate’s reason names the missing benchmark (“no classification benchmark on record for …”).
1.15.02026-09-27A shared-recording pool now carries Drive Endurance's result for it (bug #215). The pool rows (pool capacity, bays, endurance, throughput, network ports) and the pool drive's warranty and service life reach architecture.constraints and the verdict with the owner's constraint id, value, status and evidence class; before, only the node-local buffer rows did, so a pool the owner calls NO FIT was published under FIT WITH RISKS (8 × 1080p15, continuous, 30 days: a UNVR with 3 × 4 TB drives whose 3-year warranty is shorter than the 5-year service life is now NO FIT, as Drive Endurance says). composed_requests.drive_endurance_pool publishes the pool request. When no board is recommendation-eligible, the NO_FIT result also names Hardware Match's best_planning_candidate with the reason it is planning-only, capped at NEEDS VALIDATION (bug #213). A stage for which Model Match finds no model that holds the load (its NO_FIT) is a NO_FIT stage and a NO_FIT architecture, carrying every excluded model's reason row and Model Match's questions; it used to be published as NEEDS VALIDATION, which read better than the owner's answer (bug #212 follow-up).
1.14.12026-09-26Composes Hardware Match 1.13.1 (bug #192): a PoE-powered design no longer wins on a module with no carrier when no carrier meets its other requirements; the winner moves to a module whose carrier does (4 × 1080p outdoor-exposed PoE: Jetson Orin NX with “carrier selection unavailable” → Jetson AGX Orin on the Seeed reServer Industrial J501, with a priced carrier line).
1.14.02026-09-26Composes Hardware Match 1.13.0, which sizes each platform at its smallest recommendation-eligible node count (bug #190): an NVR design whose per-node Frigate detection rate sat inside the stock detector's latency band now gets the node count that clears it (16 × 1080p at detect 5: Jetson Orin Nano Super × 4, where it was NO_FIT). A NO_FIT with no recommendation-eligible board now also publishes planning_only: each planning-only board, its node count, its disposition reason and the rows that keep it planning-only (for example the Frigate inference band).
1.13.22026-09-26A pipeline stage sent without a model is no longer read as a model the caller named (bug #189). The designer fills such a stage with the workload default so Model Match stays on the family Hardware Match ranked, and that fill was being passed to Hardware Match as the pipeline’s named model — so a Frigate workload that sent pipeline had its inference check carried as advisory and sized on generic throughput. Sending the designer’s default pipeline explicitly now gives exactly the result of omitting it. A stage whose model the caller did name is unchanged.
1.13.12026-09-26The “Clear the platform pin” option on a NO_FIT now clears every input the engine reads as a platform pin (pin.platform, pin_platform, platform_id); a pin stated through pin_platform or platform_id used to survive the option and the result stayed NO_FIT. Hardware Match’s platform/platforms keys, which this engine does not read, are no longer passed through. The architecture, the alternatives and every rollup are unchanged.
1.13.02026-09-26Carries Hardware Match 1.12.0’s informational lowest_power_eligible through verbatim beside alternatives (not re-computed). The architecture, the alternatives and every rollup are unchanged.
1.12.02026-09-25PoE power rollups now compose PoE Planner with the winner's node_count and poe_supply, so switch sizing and standard compatibility include PoE-powered node demand. The architecture publishes totals.power.node_poe_w, carries the planner-selected poe_switch_id, and keeps TCO switch pricing aligned to that planner selection.
1.11.12026-09-24Power rollup publishes totals.power.pse_required_w from Hardware Match's poe_supply. psuRatingKeyFor takes that supply: onboard_pd needs no separate PSU line; splitter prices the registry splitter (preferring psu_id).
1.11.02026-09-20The default frames stage is pinned to the Hardware Match-ranked workload model (YOLO11s), so the architecture card no longer designs YOLO11n after ranking YOLO11s. When Hardware Match has no recommendation-eligible winner, the designer is NO_FIT — it does not compose an architecture on a planning-only sibling.
1.10.02026-09-19The designer forwards the recording contract it applies for the verdict — including canonical continuous / 30-day defaults — into Hardware Match, so both engines share a winner. drives_per_node || 1 no longer invents a drive when Hardware Match installed none. Material Drive Endurance FAILs can flip the verdict, appear in verdict_drivers, and publish recovery questions (do not record, record on motion, more drives, prefer SSD).
1.9.02026-09-19The Hardware Match request is sized on the one workload default, YOLO11s, instead of YOLOv8s, so a bare Hardware Match call and the designer ask the same question; each stage's model is still Model Match's pick. composed_requests.hardware_match publishes that request verbatim. Every stage's available_fps is the load-derated figure its utilization was computed from; the one-stream figure is single_stream_fps (a pinned stage published the one-stream figure before). The carrier in the bill of materials is a priced one whenever a priced carrier meets the needs as well as the best-documented one (Carrier Finder prefer_priced, set by Hardware Match). Methodology storage composition now matches the v2.114 recording topologies (node-local assignment sum vs shared pool + buffer); method version unchanged.
1.8.02026-09-18Pipeline memory is node-level: total_memory_mb adds Camera Stream Capacity's per-stream decode/preprocess/tracker buffers × cameras on the fullest node (OS and reserve still once); model_memory_mb keeps the previous one-stream model-side figure for contract XI25.
1.4.02026-09-15Named inference/decode/preprocess envelopes on constraints and primary_bottleneck; verdict_drivers for actionable FIT WITH RISKS; ordering_key on alternatives preserving Hardware Match lexicographic order; honest partial/planning BOM labels.
1.02026-09-09First release. Composition with no ranking function of its own: Hardware Match's platform, node count, per-node camera assignment, cost and power copied verbatim, with no second ranking pass, no confidence re-pick and no mutation of the alternatives or their role labels; Model Match per stage, or Compute Fit for a pinned model; node-level constraints from the V2 engines that assert them, each stamped with its engine, class and sources. Multi-stage composition by summing per-stage accelerator utilization and adding memory on the shared budget, labelled class E and capping every multi-stage verdict at NEEDS VALIDATION. Network bandwidth, storage size, system power and the non-compute bill of materials retained as labelled class E legacy rollups. Legacy figures with no V2 owner disposed of explicitly rather than dropped silently.

Method changes bump the method version; the composite dataset version follows the newest of the registries the sub-engines read, and every result also carries the per-engine versions in sub_engines, with a legacy flag on the four rollup engines.