Files
periscope/docs/piano-pcb-review.md
T
michele a2011dad91 Update PCB review plan: AI exam like schematic, no auto-place.
Adds per-IC LLM review, domains/groups as exam context, required
recommendations, and phased job MODE=pcb. Packing stays parked.
2026-09-19 22:43:58 +02:00

222 lines
9.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Piano — PCB review (esame AI + check deterministici)
Fonte di verità per **Periscope Layout review**. Non è un auto-placer.
**Delta vs revisione precedente:** lesame 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`](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 dellesame (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 allinventory. 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. LAI 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. LAI 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** | **INFO**
- `recommendation` **obbligatoria** anche per INFO (cosa fare: spostare, allungare/accorciare, cambiare rating, verificare stackup, …)
- `rule_id` sui 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 `status` schema.
- 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; `ApiLogger` stage `pcb_review`; billing via `get_billing()` (NullBilling in OSS).
- Senza API key in test: skip AI, check deterministici restano.
### Stages
1. `ensure_graph``design_graph.json` o graph_build.
2. `parse_pcb``layout_graph.json` / `parse_kicad_pcb`. Fail → error.
3. `classify` — domains + groups (`build_placement_plan`); scrive `functional_groups.json` se manca.
4. `inventory` — tracce, bus, lunghezze, Z0 → `pcb_inventory.json`.
5. `checks` — deterministici fail-soft (`run_pcb_checks`).
6. `ai_review` — per-IC come schema, contesto layout + group/domain + inventory del vicinato.
7. `write_report``pcb_report.json`, cad-bridge, IDs `PCB-*`.
---
## 2. Ingressi
| Ingresso | Obbligatorio v1 |
| --- | --- |
| `.kicad_pcb` (`has_pcb`) | Sì |
| `design_graph.json` | Sì |
| `extracted/` + `layout_rules` / pintable | Per check numerici e AI |
| PDF datasheet | Per AI (skip IC senza PDF, come schema) |
| Stackup nel PCB | Per Z0; 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 |
Filtri: `check_filters` **non** duplicato nel report PCB (resta schema). LAI e i groups usano `role_hint=filter` per proximity se c’è mm.
### 3.3 AI exam (schema-like)
Per ogni IC con PDF:
- System prompt **PCB** (placement, routing, decoupling, filtri, lunghezze, Z0, compliance layout).
- User: `build_component_context` + blocco layout (xy, satelliti del group, lunghezze net, domains).
- Stessi graph tools + `submit_review`.
- Quote verify. Recommendation obbligatoria su ogni finding.
- Isolamento per-IC; skip senza PDF.
### 3.4 Skip (no folklore)
3W, creepage IEC, CPWG, HV isolation, length-match USB spec, confronto foto TI vs gerber.
---
## 4. UI
| Superficie | Comportamento |
| --- | --- |
| Hub | **Run PCB review** se `hasPcb` |
| `/project/[id]/pcb` | Stepper SSE (include `ai_review`) |
| Sidebar | **Layout**`/pcb` |
| Report | Merge `report.json` + `pcb_report.json`; `?domain=layout`; badge Layout + `rule_id`; 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 PDF 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.
---
## 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)
1. Decoupling 15 mm vs regola 2 mm → `PE-PLC-001` + recommendation.
2. 1 mm → niente proximity.
3. Skew coppia > `length_match``PE-SI-001`.
4. Pad net mismatch → `PE-LAY-001`.
5. Senza PCB → 400 sul start.
6. 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.