Skill: read a design result¶
For: an AI agent that just got a 200 back from a MagicON AI design engine and
is about to tell a human what it means.
Load this before you summarise a result. A design response is not a number with some prose around it. It is a verdict, a list of things the engine chose for you, and a list of things it wants you to decide. Summarise only the numbers and you will hand your user a clean-looking report over a problem the engine already caught.
Every figure on this page was measured against the production API on 2026-09-09. Nothing here is illustrative.
The one rule¶
A 200 is not a verdict. It means the engine answered. It does not mean the
design works, that every slot was filled, or that you asked a meaningful question.
Measured — an empty body to the transmit-chain route:
curl -X POST https://api.pcbgenerator.com/api/rf-chain/design-sync \
-H "Content-Type: application/json" -d '{}'
200, "status": "success", a real catalogue PA (CG2H40010F) and an output of
1.0 dBm. You stated no frequency and no target, and it answered anyway — and it
said so, in chain.params, which echoes the design point it actually used:
{"frequency": null, "target_output_power": 0, "application": null, …}.
The status code tells you the transport worked. Everything that matters is in the body.
Read these four things, in this order, before you write a sentence:
| Read | Field | If you skip it |
|---|---|---|
| 1 | needsPartFlags |
You report a complete module that has a hole in it |
| 2 | warnings and assumptions |
You present the engine's choices as your user's decisions |
| 3 | the power verdict | You tell someone a chain met a target it missed |
| 4 | the as-built output | You quote an aim instead of what the board ships |
1. needsPartFlags — the honesty flag¶
A list of slot names the catalogue could not fill. [] means every slot was
genuinely filled from real parts.
A non-empty list looks like ["substrate"] — the slot name, and the slot left
empty.
⚠ Which routes carry it — measured today: POST /api/receiver/design and
POST /api/tr-module/design both return the key. POST /api/rf-chain/design-sync
does not return it at all. Its absence there is not an empty list and not a
statement that nothing is missing; there is simply no such field on that route, so
read that response's warnings instead.
What it is not: a failure, and never a placeholder. The engines do not substitute a plausible part for a missing one. If no catalogue part satisfies a position in the chain, the position comes back named here and stays empty. That is the whole contract: an engine that will not invent a part has to have somewhere to say so.
What to do: name the flagged slots to your user as an open item. Do not fill them yourself. A part number you produce is not a part number the catalogue stands behind, and your user cannot tell the two apart in your prose.
2. warnings and assumptions are disclosures, not errors¶
Both are lists of plain-language sentences. Neither one means the call failed —
a failure is a 422 or a 500, and it arrives as {"detail": "..."} instead of
a result.
⚠ Which routes carry which, measured today: warnings is on all three design
routes. assumptions is on the receiver route only — /api/rf-chain/design-sync
and /api/tr-module/design do not return that key, and their equivalent
disclosures ride inside warnings and inside the per-budget disclosures lists.
Measured on the 9.4 GHz receiver design (POST /api/receiver/design, {"rfFrequencyHz":
9400000000, "bandwidthHz": 10000000, "requiredSnrDb": 12}): 10 assumptions and
6 warnings, alongside a complete, fully-filled design.
assumptions are the things the engine chose because you did not state them:
"IF of 1128.0 MHz was CHOSEN BY THE ENGINE (~12% of RF, floored at 5x the signal bandwidth), not supplied. Pass an explicit IF to override."
"LO injection side was not specified; high-side chosen (deterministic default)."
"PAPR assumed 9 dB (modulated/pulsed); pass papr_db to override — ~3 dB would be right for CW."
Report a result without these and you are presenting our default as your user's decision. Each one names the field that would override it, so every assumption is also a question you can put back to your user.
warnings are findings about the design as built:
"BFP840ESD's 21.5 dB is the MIDPOINT of a 9.5-33.5 dB range the record states as one block, not a gain measured at this frequency. The endpoints differ by 24.0 dB."
That is not noise. It says the headline noise figure rests on a mid-range gain number, which is exactly the caveat a human reviewer would want and exactly the sentence a tidy summary deletes.
Measured on the 9.4 GHz transmit chain: 8 warnings with a 200, including
"Isolator/circulator JIM9250T9750VM1R is rated 40.0 dBm average and this design delivers 43.4 dBm average (CW). That is an overstress on the rating's own terms."
A design that ships with a stated overstress is not a broken call. It is a design with a decision in it. Hand the decision over; do not resolve it silently.
Quote them. Do not paraphrase them into reassurance.
3. The power verdict — which field, on which surface¶
This is the section that matters most, because getting it wrong means telling someone a chain met a target it missed.
Two surfaces carry different field names¶
HTTPS (POST /api/rf-chain/design-sync) |
the design tool (design_rf_chain) |
|
|---|---|---|
| verdict field | chain.meets_power_target |
powerCheck.meets_target |
meets_power_target present? |
yes | no — the key does not exist |
| shipped output | chain.as_built_output_power |
achievedOutputDbm |
| delta | chain.output_delta |
outputDeltaDb |
If you are calling with curl, you are on the first column. Read
chain.meets_power_target. Looking for powerCheck over HTTPS finds nothing;
looking for meets_power_target in a tool result finds nothing.
The verdict is reference-relative, and the two references differ¶
The same helper judges the same part against two different references, so the two
surfaces can return opposite verdicts for one design. Measured at 2.4 GHz,
30 dBm target, application: "wifi":
HTTPS chain.* |
tool powerCheck.* |
|
|---|---|---|
| selected PA | MGA-242740-02 |
MGA-242740-02 — same part |
| verdict | meets_power_target: false |
meets_target: true |
| judged against | 33.65 dBm — the output required at the PA, i.e. your target plus the losses after it | 30 dBm — your target at the antenna port |
| PA's usable linear output | 33.0 dBm (power_range_floor) |
33.0 dBm — same figure |
| result | 0.65 dB short of 33.65 | 3.0 dB of margin over 30 |
Both are true. false means this PA cannot deliver the target through the losses
that follow it. true means this PA is rated above the target itself. Neither
one is the other's error.
⚠ Never report that the two surfaces agree, and never carry a verdict from one
into a sentence about the other. The tool discloses its reference in its own
note field:
"MGA-242740-02: 33 dBm linear (power-range floor) output — meets the 30 dBm target with 3 dB device-capability margin (PA rated output vs target, before chain losses); saturated 40 dBm."
The bare HTTPS boolean does not. When you have only the boolean, say which question it answers, or say nothing about it.
The HTTPS response tells you the same story in warnings, and this is the
sentence to quote:
"PA power: MGA-242740-02 is 0.7 dB short of the 33.65 dBm required PA output (delivers 33 dBm linear output). The reported chain output is a gain-cascade (saturated/CW-basis) figure and does not reflect this shortfall; verify the PA's rated EVM/linear output or choose a higher-power PA."
The verdict is TRI-STATE, and null is the dangerous one¶
powerCheck.meets_target has three values, not two:
| Value | basis |
Means |
|---|---|---|
true |
e.g. power_range_floor, rated_linear |
Proven adequate on a figure that is on record |
false |
as above | Proven short |
null |
uncertain |
Unknown. Not "fine". |
null happens on a modulated application when the part's record carries no linear
or rated-average output figure at all — only saturated / P1dB. The engine will not
invent a back-off to fill the gap, so it returns the honest unknown. Measured
shape (ADPA9007, 30 dBm, application: "wifi"):
{
"mpn": "ADPA9007",
"target_output_dbm": 30.0,
"basis": "uncertain",
"usable_output_dbm": null,
"saturated_dbm": 34.0,
"p1db_dbm": 33.0,
"meets_target": null,
"note": "..."
}
…and the note spells the unknown out rather than papering over it:
"ADPA9007: saturated 34 dBm / P1dB 33 dBm; linear/modulated output for this application is not specified in catalog data — verify the datasheet's rated EVM output before relying on 30 dBm."
null is more dangerous than false, because a null reads as absence of a
problem. An agent that treats a missing verdict as a passing verdict reports "no
issues" where the honest answer is "unknown — verify the EVM rating". Say
"unknown", and pass the note through verbatim.
⚠ On the HTTPS surface the unknown is not visible. chain.meets_power_target
is false only on a proven shortfall; an unknown reads as true, and no
warning is emitted for it. So on HTTPS:
meets_power_target: false→ proven short. Lead with it.meets_power_target: true→ not proven short. That is not the same as proven adequate.meets_power_target: null→ no PA was selected at all, so there was no power judgement to make. Checkchain.selected_paand thewarningsbefore saying anything else about the design.
For a modulated application (wifi, lte, 5g — anything with a high
peak-to-average ratio), do not turn true into "the PA meets the target". Say the
chain is not flagged short, and ask for the PA's rated EVM/linear output. For a
constant-envelope application (radar, CW), the part can be driven to
compression and true carries its ordinary meaning.
4. As-built is not the target, and the gap has no fixed sign¶
Three output figures travel together and they are not interchangeable:
| Field | What it is |
|---|---|
chain.actual_output_power |
the convergence figure — what the design loop aimed at |
chain.as_built_output_power |
the shipped figure — after the discrete attenuator pads that actually exist |
chain.output_delta |
actual minus target — computed against the aim, not against as-built |
Measured, both directions, same route, same day:
| Design point | target | actual_output_power |
as_built_output_power |
output_delta |
as-built vs target |
|---|---|---|---|---|---|
| 2.4 GHz, wifi | 30 | 30.0 | 29.9 | 0.0 | −0.1 |
| 9.4 GHz, radar | 40 | 41.0 | 41.15 | 1.0 | +1.15 |
Three things follow, and each one is a mistake agents actually make:
- Quote
as_built_output_power. It is what the board ships. The design tool headlines this same figure asachievedOutputDbm. output_delta: 0.0does not mean the design lands exactly on target. At 2.4 GHz the delta is0.0while as-built is29.9— the delta is measured against the aim, and the pads then took 0.1 dB. The chain says so in a warning: "Discrete attenuator pads total 4.0 dB vs 3.9 dB computed — downstream stages are driven 0.1 dB low."- The gap is not always a shortfall, and it is not always there. At 9.4 GHz as-built sits 1.15 dB above target; at 2.4 GHz, 0.1 dB below. Never write a sentence implying the design always falls short of target, and never write one implying it always hits it exactly. Report the two numbers.
The T/R module route reports the same idea under its own names —
transmit.targetOutputDbm 40.0 against transmit.asBuiltOutputDbm 40.65,
measured at 9.4 GHz.
5. A regulatory clamp is a compliance action, not a failure¶
When a design point sits in a band with a conducted-power ceiling, the engine holds the design at the limit rather than aiming past it, and says so. Measured at 2.4 GHz, 30 dBm:
"Output aim clamped to the FCC 15.247 conducted limit (30 dBm, 2400-2483.5 MHz ISM): the standard +1 dB convergence margin would exceed it"
That is the engine choosing to be legal. It is the reason the 2.4 GHz row above aims at 30.0 rather than 31.0, and it is why the 9.4 GHz radar row — outside any ISM band — keeps its +1 dB aim.
Do not report a clamp as an unmet target or a design defect. Report it as what it is: the target was held at the regulatory ceiling. If your user asked for more power than the band allows, that is the sentence they need, and the engine has already written it for you.
Before you send your summary¶
-
needsPartFlagsquoted where the route carries it —[], or the slot names as open items - Every
assumptions/disclosuresentry that shaped a headline figure passed through -
warningsreported as findings, not deleted or softened - The power verdict named with its reference, or not stated at all
- A
null/uncertainverdict called unknown, never fine - The output figure you quoted is the as-built one —
chain.as_built_output_power, ortransmit.asBuiltOutputDbmon a T/R module - A regulatory clamp described as compliance, not as a miss
- Every number in your summary came out of the response body — none of them came out of you
That last one is the whole point. The engines compute so that you do not have to, and the value of the result is that a human can trace every figure in it back to a published component spec. A figure you supplied looks exactly like one we computed once it is inside your paragraph.
Related¶
- Pick the engine — which endpoint answers which question.
- Design a module — the end-to-end procedure.
- API reference for LLMs — every path, limit and error code.
- RF chain design rules — the constraints the selection engine enforces.