Add /api/library datasheet import and component GET/PUT with no exam. Reorganize pytest into datasheet, library, schematic, PCB, and AF+AI. Document Rust criteria (none chosen; no rustup) and coding conformity.
3.5 KiB
Criteri Rust — Periscope
Costituzione: Python è il default. Rust non è un default. Questo documento dice quando un pezzo può entrare in Rust. Non sceglie ancora un pezzo. Niente rustup, crate, né FFI finché una riga sotto non è scelta e misurata.
FEM / OpenEMS / field solver: fuori dal prodotto. Non sono candidati Rust.
DRC: KiCad. Non è un candidato Rust in Periscope.
Non solo velocità
Un bottleneck di CPU non basta. Un pezzo va in Rust solo se tutti i punti seguenti sono veri.
- Correttezza geometrica — pad ≠ via ≠ traccia ≠ zona deve sopravvivere al confine. Se Rust collassa oggetti per “è più facile in un AABB”, il pezzo è rifiutato anche se è più veloce.
- Memoria / ownership — pressione reale (PCB grandi, segmenti, zone) o lifetime che Python non può possedere senza copie cieche. Non “magari un giorno”.
- Parser o hot path — il costo sta in un ciclo stretto (parse
.kicad_pcb, walk segmenti, predicate geometriche) dopo profiling. Non nell’orchestrazione, non nell’I/O HTTP, non nell’LLM. - Determinismo — stessa input + config → stesso modello e stessi numeri. Niente hash random, niente ordine di hash map visibile nei finding, niente dipendenza dall’LLM.
- Confine Python grosso — una chiamata: struct in → struct out. Vietato un round-trip per pad, per via, per “is_point_in_poly” dal loop Python.
Se manca anche uno solo di questi, il pezzo resta in Python.
Sequenza obbligatoria (costituzione §§33–36)
implementazione corretta in Python
↓
misura (wall + allocazioni, board reale: HubAudio / Emmaforo)
↓
profiling (il hot path ha un nome di funzione)
↓
scelta esplicita del pezzo in questo file
↓
Rust con confine grosso
↓
benchmark sulla stessa board
↓
accetta / rifiuta sui numeri e sulla semantica (via resta via)
Finché la riga “Pezzo scelto” sotto è vuota: nessun rustup.
Cosa non va in Rust
| Area | Perché |
|---|---|
| Pipeline, job, SSE, FastAPI | orchestrazione |
| Estrazione datasheet, skills, LLM | I/O + modello |
| Review AI, normalize, dedup | non deterministico in autorità |
| Project CRUD, storage, report JSON | I/O |
| Frontend | altro runtime |
| Auth / JWT / users | fuori perimetro; non toccare |
| FEM, OpenEMS, ampacity IPC via, DRC | non è Periscope |
| ImpedenceFinder venduto | già un core chiuso; non riscrivere “per Rust” |
Un check PE-* isolato |
il check è regola + evidenza; il costo è il parser/geometria a monte |
Candidati solo dopo misura (nessuno scelto)
Questi sono i posti dove un profilo potrebbe mostrare un hot path. Non sono un piano di porting.
- Parser
.kicad_pcb(parsers_kicad_pcb.py) se il wall su HubAudio è il parse, non i check. - Predicate geometriche usate da stub / zone / courtyard (track graph, point-in-poly) se il walk segmenti domina.
- Walk grafo net→pin su BOM grandi, se misurato.
Non candidati: run_pcb_checks come god-object Rust; “tutto il core”; Z inventata più veloce.
Pezzo scelto
Nessuno.
Nessuna misura registrata in questo file. Quindi: niente toolchain Rust in questa macro-fase.
Come registrare una scelta (futuro)
Quando una misura esiste, aggiungere qui:
Pezzo: <modulo / funzione>
Board: <HubAudio / Emmaforo / …>
Python wall: <s> alloc: <MB>
Hot path: <nome>
Ipotesi Rust: correttezza geometrica | memoria | parser | determinismo | confine
Benchmark dopo: <s> e test via≠pad ancora verdi
Decisione: accetta | rifiuta