Skip to content

AI-Native PA Selection — Tools & Guardrails Reference Map

Purpose

A read-only map of how power-amplifier (PA) selection works in the AI-native agent-loop flow, across different applications, frequencies, and power levels — the tools the model can call, how the scoring weights application/frequency/power, and the full guardrail perimeter that gates it. Captured against the harden-ai-native-perimeter branch, where most of the guardrails below were added/hardened. This is documentation of the production state, not a change proposal.

Related: AI_NATIVE_SHELL.md (the shell + agent loop overall), APPLICATION_FREQUENCY_STACKUP.md.


1. The flow (two selection systems, one power SSOT)

user msg → application_intent → [auto-pin user MPNs] → model tool-loop
        ┌─────────────────────────────────────────────────┘
        ├─ select_components_batch  ── single PA  → System B  (agents/simple_pa_agent.py)
        │                           ── pa+driver   → System A  (delegates to design_rf_chain)
        ├─ design_rf_chain          ── full chain  → System A  (rf_chain/steps/pa_step.py)
        ├─ compare_rf_chains        ── variants     → System A + multi_chain_orchestrator
        ├─ lookup_component_by_mpn  ── confirm specs (read-only catalog)
        ├─ set_active_component     ── pin a part   (pin guards live here)
        └─ update_rf_specs          ── set freq/power target (regulatory pre-warn)
                                                  output_guard (prose grounding)
  • System A = services/rf_chain/orchestrator.pysteps/pa_step.py (full TX chain, convergent).
  • System B = agents/simple_pa_agent.py via routes/agents.py::_run_agent_selection (single slot).
  • Shared power SSOT = services/component_power.py (max_pout_dbm, assess_power, output_power_target, linear-vs-saturated). Both systems call it; they never disagree on adequacy.

2. Tools (each delegates to the same engine Guided uses; _parity.py enforces)

Tool File App / Freq / Power inputs Engine Card
select_components_batch tools/select_components_batch.py application, frequency_ghz / min/max, output_power_dbm, mode=browse System A or System B bom_preview (+ powerCheck/powerShortfall/regulatoryWarning)
design_rf_chain tools/design_rf_chain.py application (or band-derived), frequency, target_output_power rf_chain.orchestrator → pa_step bom_preview (+ chainPayload, achievedOutputDbm, powerCheck)
compare_rf_chains tools/compare_rf_chains.py application, frequency, target_output_power, weights{cost,size,perf} System A + multi_chain_orchestrator chain_comparison (Pareto)
lookup_component_by_mpn tools/lookup_component.py part_number DB find_component_by_mpn component_lookup
set_active_component tools/set_active_component.py slot, part_number (+ power/band re-check) DB lookup + assess_power component_pinned (+ power_warning/band_warning)
update_rf_specs tools/rf_specs.py freq_min/max, output_power_dbm validation + regulatory flag rf_specs (+ clientUpdate)

3. How APPLICATION / FREQUENCY / POWER drive scoring

System B default weights (simple_pa_agent.py): freq 0.20, power 0.25, application_fit 0.25, efficiency 0.15, cost 0.15. Optional profiles (APPLICATION_SCORING_PROFILES): linear_comms, pulsed_radar, broadband_test, low_power_iot, high_power_infra reweight linearity/ruggedness/BW.

  • Applicationapplication_fit_score() (scoring_helpers): domain map (consumer_wireless / cellular / satcom / radar / defense / …). Match=1.0, specialist-for-consumer=0.15, inert=0.5. PREFERENCE, never a gate. Also drives score_cost thresholds (APPLICATION_COST_THRESHOLDS).
  • Frequencyscore_frequency_range() (in-band center=1.0, out-of-band penalty). Gated at SEARCH in System A; a ranking preference in System B. Convention: frequency_min_ghz/max_ghz.
  • Powerscore_power() (3–6 dB headroom ideal; oversizing & undersizing penalized) PLUS a hard two-tier adequacy FLOOR before scoring (linear-adequate → saturated-adequate → all). Context-free browse nullifies the power weight (no phantom 30 dBm default).

System A scoring (steps/_pa_scoring.py, distinct weights): power 0.35, efficiency 0.25, gain 0.20, cost 0.10, technology 0.10; honors pinned PA; sizes post-PA losses first.

4. Guardrails (the "harden-ai-native-perimeter" perimeter)

Selection / power floors - Two-tier adequacy floor — routes/agents.py + pa_step.py via assess_power (linear for WiFi/5G OFDM, saturated for constant-envelope). Adequate part always beats under-spec. - powerShortfall + _adequate_pa_alternatives (≤5 real upgrades) when nothing reaches target. - powerCheck verdict on every PA pick (grounded note, never deflect). - Linear-output awareness — usable_output_dbm() (SE2576L 26 dBm linear ≠ 32 dBm Psat for 30 dBm WiFi).

Pin guards (set_active_component.py, model-dispatch only — auto-pin/direct callers exempt) - Catalog-only sourcing — reject model-guessed MPN not user-named or catalog-selected. - pin_under_spec_unconfirmed — reject committing a catalog-selected PA that misses target. - Honor-and-flag — user-named under-spec PA pins with power_warning. - Pinned-PA power backstop + band-coverage warning.

Regulatory / compliance - regulatory.py::clamped_desired_output — clamp convergence aim to ISM conducted ceiling (FCC §15.247 ISM_CONDUCTED_LIMITS, SSOT). Above-limit user target honored + flagged. - Pre-design FCC §15.247 warning in update_rf_specs / select_components_batch. - run_compliance_analysis auto-trigger post-design.

Prose grounding (output_guard/ + output_guard_patterns/ packages, registry-derived) - Flat-text + JSON-leaf: ungrounded part numbers / specs / units rejected. - Efficiency-scope (chain vs PA PAE), position labels (pre/post-PA), attenuator-rating binding. - Compliance-status claim binding (can't say "FCC-compliant" against a NON-COMPLIANT card). - Scarcity-claim guard ("no/only PA" rejected when alternatives list is non-empty). - Application-intent (services/application_intent.py) injects app so linear-strict filter fires.

5. Feature flags

PA selection tools have no per-tool flag. System A respects agent_config.pa_enabled etc. Guardrails are always-on; deferral is by condition (under-spec guard needs user_message_tokens; compliance-status binding fail-opens until a compliance_result exists).

Verification (to confirm any claim above)

  • Targeted reads: backend/agents/simple_pa_agent.py, backend/services/component_power.py, backend/tools/set_active_component.py, backend/services/rf_chain/regulatory.py, backend/services/output_guard/.
  • Tests: test_scoring_application_fit.py, test_scoring_cost_field.py, test_agent_application_intent.py, test_agent_loop_recommend_no_pin.py, test_set_active_component_tool.py, test_select_components_batch_tool.py.