Azione Immediata: Fase 1 - Creazione di DEPENDENCY-MANAGEMENT.md

Policy di Gestione delle Dipendenze (FIRE & quantum-core)

Versione: 1.0 Data: 2025-11-08 Scopo: Definire la policy obbligatoria per la gestione delle dipendenze Python in tutti i progetti, per garantire ambienti di sviluppo e produzione stabili, riproducibili e sicuri.


1. La Filosofia: Riproducibilità Deterministica

Un ambiente di sviluppo non riproducibile è la causa principale di bug “fantasma” e di ore di debug sprecate. La nostra policy si basa su un principio non negoziabile: ogni ambiente, in ogni momento, deve essere ricreabile in modo identico e prevedibile a partire dai file versionati su Git.

Per raggiungere questo obiettivo, abbandoniamo l’uso di pip freeze come strumento di gestione e adottiamo un workflow professionale basato su pip-tools.

2. I Nostri Strumenti e Artefatti

Il nostro sistema di gestione delle dipendenze si basa su tre componenti chiave:

ArtefattoRuoloGestione
requirements.inFonte di Verità LogicaUn file scritto a mano che elenca solo le nostre dipendenze dirette. È l’unico file che gli sviluppatori devono modificare.
pip-compileRisolutore DeterministicoLo strumento (pip-tools) che legge requirements.in e genera il lockfile, risolvendo l’intero albero delle dipendenze in modo coerente.
requirements.lock.txtFonte di Verità FisicaUn file generato automaticamente da pip-compile. Contiene ogni singolo pacchetto con la sua versione esatta e il suo hash. Non deve mai essere modificato a mano.

3. Il Workflow Obbligatorio (“Lockfile-First”)

Qualsiasi modifica alle dipendenze del progetto DEVE seguire questo processo. L’uso diretto di pip install <pacchetto> è vietato.

3.1. Aggiungere una Nuova Dipendenza

  1. Modifica requirements.in: Aggiungi il nome del pacchetto (es. requests). Se è richiesta una versione specifica, usa ==, altrimenti lascia che il risolutore scelga la migliore.
  2. Aggiorna il Lockfile: Esegui il comando per ricompilare le dipendenze.
    pip-compile requirements.in --output-file=requirements.lock.txt
  3. Sincronizza il Tuo Ambiente: Installa/aggiorna il tuo ambiente locale usando il nuovo lockfile.
    pip-sync requirements.lock.txt
  4. Committa Entrambi i File: Aggiungi e committa su Git sia requirements.in che requirements.lock.txt.

3.2. Rimuovere una Dipendenza

  1. Modifica requirements.in: Rimuovi la riga del pacchetto.
  2. Aggiorna il Lockfile: Esegui di nuovo pip-compile. pip-tools rileverà che il pacchetto non è più necessario e lo rimuoverà dal lockfile (insieme alle sue dipendenze transitive non più usate).
  3. Sincronizza il Tuo Ambiente: Esegui pip-sync per disinstallare i pacchetti rimossi.
  4. Committa Entrambi i File.

3.3. Aggiornare le Dipendenze

Per aggiornare tutti i pacchetti alle loro ultime versioni compatibili:

pip-compile --upgrade requirements.in --output-file=requirements.lock.txt
pip-sync requirements.lock.txt

Per aggiornare un singolo pacchetto:

pip-compile --upgrade-package <nome_pacchetto> requirements.in --output-file=requirements.lock.txt
pip-sync requirements.lock.txt

4. Gestione delle Dipendenze Speciali

Qualsiasi dipendenza che non proviene dal repository PyPI standard (es. da Git, URL speciali) deve essere gestita esplicitamente.

  • Installazione da Git: In requirements.in, usa la sintassi completa, bloccando sempre un commit hash specifico per garantire la riproducibilità.

    # BUONO: bloccato a un commit specifico
    timesfm @ git+https://github.com/google-research/timesfm.git@bf88c5dc88f6275b7071ebcd9051406c11435c0c
    
    # CATTIVO: non bloccato, installerà l'ultimo commit del branch `main`
    # timesfm @ git+https://github.com/google-research/timesfm.git
    
  • Pacchetti con Index URL Speciali (es. PyTorch): In requirements.in, aggiungi il flag --extra-index-url all’inizio del file. pip-compile lo includerà automaticamente nel requirements.lock.txt.

    --extra-index-url https://download.pytorch.org/whl/cu121
    
    torch==2.5.1+cu121
    torchvision==0.20.1+cu121
    torchaudio==2.5.1+cu121
    

5. Troubleshooting: “Dependency Hell”

Se pip-compile o pip-sync falliscono con un errore di conflitto (ResolutionImpossible), è perché le nostre richieste in requirements.in sono matematicamente incompatibili.

Strategia di Risoluzione:

  1. Leggi l’Errore: L’output di pip-tools è molto chiaro e indicherà esattamente quali pacchetti sono in conflitto.
  2. Allenta i Vincoli: In requirements.in, prova a rimuovere i vincoli di versione (==...) per i pacchetti in conflitto e lascia che pip-compile tenti di trovare una soluzione.
  3. “Pin-Down” Iterativo: Se necessario, blocca la versione di un pacchetto chiave (pandas==2.0.0) e lascia che pip-compile adatti gli altri. È un processo iterativo.
  4. Consulta la Documentazione: Verifica i changelog dei pacchetti per capire quali “breaking changes” hanno introdotto.

Questa policy è un requisito non negoziabile per tutti i nuovi commit. La stabilità e la riproducibilità del nostro ambiente di sviluppo sono una responsabilità condivisa.