PCB AI skips a second PDF exam (pintable cache, pdf_path=None) and the report gains a PCB exam section plus power-trace, thermal, via, Kelvin, and GND-stitch checks grounded in board geometry and extracted specs.
11 KiB
Piano — PCB review (esame AI + check deterministici)
Fonte di verità per Periscope Layout review. Non è un auto-placer.
Delta vs revisione precedente: l’esame del board è agentico come la pipeline schema (datasheet + neighborhood + tool, findings ERROR/WARNING/INFO con sempre una recommendation). Restano i check numerici gated. Auto-placement / pack / write-back pcbnew restano fuori.
Prodotto: esaminare un .kicad_pcb già (parzialmente) sbrogliato — placement, routing, impedenze, lunghezze, decoupling, filtri, derating, compliance datasheet — e dire cosa è sbagliato e come sistemarlo. Non si spostano footprint e non si scrive rame.
Contratto rispetto a docs/piano-implementazione.md:
| Schema (già in produzione) | PCB review (questo piano) | Placement F2 pack (fuori) | |
|---|---|---|---|
| Promessa | Lo schema rispetta il datasheet | Il layout esistente rispetta datasheet + geometria | Proporre xy nuovi |
| Metodo | Check deterministici + review LLM per-IC | Stesso spirito: check + review LLM per-IC sul PCB | Skeleton placement_pack.json |
| Trigger | BOM + netlist / .kicad_sch |
+ .kicad_pcb |
PCB + layout_rules numerici |
| Output | Finding pin/net, derating, review | Finding mm / net / Z0 / skew / via EP / layout AI; PE-PLC* PE-SI* PE-LAY* PE-Z0* |
Proposte xy |
| Job | MODE=run (status) |
MODE=pcb (pcb_status) |
MODE=placement (placement_status) |
Senza .kicad_pcb il progetto resta uno schema completo. Il report schema non si riempie di finding layout.
0. Postura: esame AI, non progettazione
Stesso spirito della Direct Datasheet Review: il modello legge datasheet + contesto del circuito e geometria del footprint/net, usa tool sul grafo, sottomette finding. Non progetta il board.
Domains e functional Groups
Obbligatori come contesto dell’esame (non come packing):
- Domains = isole sulle power net (
functional_groups.py/placement_plan.json). - Groups = IC + satelliti con
role_hint(decoupling,bulk,filter,crystal, …).
Il job PCB classifica (riusa build_placement_plan) e passa domains/groups al reviewer e all’inventory. Non propone coordinate.
La pipeline Placement (POST …/placement/start) resta topologia routing-first. F2 pack/export parcheggiati.
Placement = verifica (deterministico + AI)
Misura ciò che è già sul board: distanza pad-cap, layer, via EP, keepout, crystal load caps. placement_check (PE-PLC-001…004) è il nucleo numerico. L’AI copre note di layout del datasheet senza mm strutturato (citazione + Unverified: se la quote non verifica), sempre con recommendation.
Routing = la stessa postura
Lunghezze, coppie, bus, Z0, pad-net vs schema. si_check (PE-SI-001) solo con length_match mm. L’AI può flaggare crossing/loop evidenti solo se il contesto geometria lo mostra; niente 3W/IEC inventati.
Findings (come parte 1 / schema)
Ogni finding PCB:
status: ERROR | WARNING | INFOrecommendationobbligatoria anche per INFO (cosa fare: spostare, allungare/accorciare, cambiare rating, verificare stackup, …)rule_idsui check automatici; review AI:source=pcb_review- IDs
PCB-{designator}-{001}per non collidere con lo schema
Normalization resta downgrade-only.
1. Job parallelo (riuso stack)
┌─ MODE=run → status → report.json (schema)
Project files ───┼─ MODE=placement → placement_status → placement_plan.json
└─ MODE=pcb → pcb_status → pcb_report.json
Riuso
| Pezzo | Path | Ruolo PCB |
|---|---|---|
| Workspace / SSE | pipeline.py |
PipelineWorkspace, broker |
| Dispatch | job_runner.py, pipeline_worker.py |
MODE=pcb |
| API | routers/pipeline.py |
pcb/start, cancel, events, inventory |
| Meta | projects.py |
pcb_status, pcb_state, pcb_execution_name, pcb_cancel_requested |
| Parser | parsers_kicad_pcb.py |
LayoutGraph |
| Groups | functional_groups.py |
domains + groups |
| Placement | placement_check.py |
PE-PLC-* |
| SI | si_check.py |
PE-SI-001 |
| Filtri | filter_check.py |
contesto; proximity solo con mm |
| Derating | derating.py |
Vop vs Vrated se entrambi noti |
| Impedenza | impedance_traces.py |
inventory Z0; finding se target numerico |
| Review LLM | services/validation.py + prompt PCB |
per-IC, stesso loop tool/submit_review |
| Cad bridge | cad_bridge.py |
target: pcb |
| UI | report finding-card, sidebar, types.ts, api.ts |
tab Layout, merge findings |
Contratto job
- Non tocca
statusschema. - Soft-cancel
pcb_cancel_requested. - Mutex vs analisi e vs placement (event log condiviso).
- SSE
pcb_step_update/pcb_complete/pcb_error/pcb_cancelled. - Locale:
local/pcb/{id}. - Heal zombie come placement.
- LLM: stesso provider DeepSeek della review schema;
ApiLoggerstagepcb_review; billing viaget_billing()(NullBilling in OSS). - Senza API key in test: skip AI, check deterministici restano.
Stages
ensure_graph—design_graph.jsono graph_build.parse_pcb—layout_graph.json/parse_kicad_pcb. Fail → error.classify— domains + groups (build_placement_plan); scrivefunctional_groups.jsonse manca.inventory— tracce, bus, lunghezze, Z0 →pcb_inventory.json.checks— deterministici fail-soft (run_pcb_checks).ai_review— per-IC come schema, contesto layout + group/domain + inventory del vicinato.write_report—pcb_report.json, cad-bridge, IDsPCB-*.
2. Ingressi
| Ingresso | Obbligatorio v1 |
|---|---|
.kicad_pcb (has_pcb) |
Sì |
design_graph.json |
Sì |
extracted/ + layout_rules / pintable |
Per check numerici e AI |
Shared library library/extracted/{safe_mpn}.json |
Unico store schema+PCB. Deep exam PDF una volta (pipeline schema). |
| PDF datasheet | Solo per estrazione / review schema. PCB non riattacca il PDF. |
| Stackup nel PCB | Per Z0 e ampacity; skip se assente |
3. Check (deterministici) + AI
3.1 Inventario (non finding)
Net con rame: lunghezza, layer, width min/max, via, coppia, bus, Z0 se stackup. Domains/groups elencati.
3.2 Deterministici
| ID | Cosa | Gate |
|---|---|---|
PE-LAY-001 |
Pad net ≠ pin net schema | entrambi noti |
PE-LAY-002 |
Ref schema senza footprint (skip #PWR) |
graph + PCB |
PE-PLC-001…004 |
decoupling / via / same_layer / keepout | layout_rules numerici |
PE-SI-001 |
skew coppia | length_match mm |
PE-DRT-001 |
Vop > Vrated sul cap (derating.py) | entrambe le tensioni |
PE-Z0-001 |
Z0 fuori target | target in regola o netclass; mai 50 Ω default |
PE-PWR-001 |
Larghezza × spessore rame vs I_load | I_load + width; IPC-2221 solo con copper_thickness_mm e Tjmax (ΔT=Tjmax−25 °C) |
PE-VIA-001 |
I_load / N via | geometria via + I_load; INFO (niente tabella via inventata) |
PE-THM-001 |
P=I_load×(Vin−Vout) senza pour/via courtyard | I_load, Vin/Vout, courtyard |
PE-KEL-001 |
Pin sense/Kelvin su net di carico | nome pintable + ≥2 altri sul net |
PE-STCH-001 |
Segnale sopra pour GND senza via GND nel bbox | zone GND + segmenti; INFO |
| Creepage | — | skip senza numero datasheet/IEC |
| Crystal keepout | PE-PLC-004 |
layout_rules kind=keepout |
Filtri: check_filters non duplicato nel report PCB (resta schema). L’AI e i groups usano role_hint=filter per proximity se c’è mm.
3.3 AI exam (layout-only, shared library)
Per ogni IC con pintable in library/extracted o extracted/ di progetto (stesso JSON):
- Non si ri-legge il PDF. L’esame datasheet profondo è quello della pipeline schema.
- System prompt PCB: layout vs JSON di libreria.
- User:
format_library_extraction+build_pcb_layout_context. review_ic_async(..., pdf_path=None)— niente attach, niente quote-verify PDF.- Skip:
no library extraction — run schematic review first. - Recommendation obbligatoria; isolation per-IC.
UI: sezione report PCB exam (pcb-exam-section.tsx) — findings source=pcb_review e PE-PWR/THM/VIA/KEL/STCH. Nascosta con ?domain=schema.
3.4 Skip (no folklore)
3W, creepage IEC senza numero, CPWG, HV isolation, length-match USB spec, confronto foto TI vs gerber, 1 oz / 10 °C / 50 Ω di default.
4. UI
| Superficie | Comportamento |
|---|---|
| Hub | Run PCB review se hasPcb |
/project/[id]/pcb |
Stepper SSE (include ai_review) |
| Sidebar | Layout → /pcb |
| Report | Merge + sezione PCB exam; ?domain=layout; badge Layout; recommendation sempre visibile |
| Inventory | Traces/buses/Z0 + domains/groups |
5. Fasi di implementazione
Dopo ogni fase: test delle funzioni toccate, commit, push. Dopo ogni macro-fase operativa: deploy ssh periscope + scripts/update-periscope.sh (niente chiavi/sshd).
Fase 0 — Split schema / layout
Togliere placement_check / si_check da _run_deterministic_checks schema. Eval schema: layout=None resta no-op.
Done when: schema senza PCB = zero PE-PLC/PE-SI.
Fase 1 — Job + deterministici + UI (macro operativa)
Meta pcb_*, worker, router, run_pcb_checks, inventory, report merge, UI start/progress/filtro.
Done when: upload PCB → start → finding nel report. Deploy.
Fase 2 — AI exam + domains/groups (macro operativa)
classify + ai_review per-IC, prompt PCB, recommendation obbligatoria, changelog Layout.
Done when: con API key, IC con libreria producono finding source=pcb_review o coverage vuota; senza key, skip loggato. Deploy.
Fase 3 — Plugin + eval PCB
Cad-bridge pcbnew; golden fixture. Packing resta fuori.
Fase 4 — Libreria unica + sezione PCB exam (macro operativa)
Un store library/extracted (più extracted/ di progetto). PCB non duplica l’esame PDF. Sezione report PCB exam + PE-PWR/THM/VIA/KEL/STCH.
Done when: IC senza pintable skipped; con libreria, AI layout-only; check IPC solo con stackup+Tjmax. Deploy.
6. Fuori scope
- Auto-placement, packing mm, write-back pcbnew.
- Autore di sbroglio / change width.
- SPICE / IBIS / EM.
- Inventare mm, Ω, V/mm.
- EasyEDA, Gerber come ingresso, PADS layout.
- Unire il job PCB nella run schema.
- Toccare ssh keys /
sshd.
7. Done (fixture)
- Decoupling 15 mm vs regola 2 mm →
PE-PLC-001+ recommendation. - 1 mm → niente proximity.
- Skew coppia >
length_match→PE-SI-001. - Pad net mismatch →
PE-LAY-001. - Senza PCB → 400 sul start.
- AI: contesto contiene domain/group; finding senza recommendation rifiutati/completati dal parser.
8. Relazione
Wave G di piano-implementazione.md = questo job di esame (ora anche LLM). F2 pack non entra.