Files
Simone 0d6486b19b chore(plans): archive Phase A and B completed documents
Moves all A/B closeouts, checklists, idea docs, and implementation plans
to plans/archived/2026-05-23/. Both phases are production-stable.

Active plans remaining in plans/:
  - idea-3-powershell-removal.md  (Phase C — in progress)
  - idea-3-esxi-support.md        (Phase D — future)
  - ideas-overview.md             (roadmap reference)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 19:52:09 +02:00

101 lines
5.5 KiB
Markdown
Raw Permalink 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.
# A5 — Closeout
Fase A5 di `plans/implementation-plan-A-B.md`: polish, regression test
per gli errori frequenti `AGENTS.md` #9-#12, documentazione Python
allineata, gate coverage alzato a 80%.
Branch: `feature/python-rewrite-phase-a`.
## Stato attuale
- [x] `tests/python/test_agents_errors.py` aggiunto: 12 test dedicati che
coprono regressioni per `AGENTS.md` "Errori frequenti da evitare"
#9, #10, #11, #12.
- **#9** (snapshot template con VM accesa): `clone_linked` propaga
"should not be powered on" come `BackendOperationFailed` (subclass
di `BackendError`) con `operation == "clone"` e `output` che
contiene il messaggio originale di `vmrun`.
- **#10** (`vmrun getGuestIPAddress` lento): `is_running` usa solo
`vmrun list`. Tre asserzioni — happy path, VM non listata, errore
di `vmrun list` — verificano che `getGuestIPAddress` non venga MAI
chiamato come fallback.
- **#11** (machine-id duplicato → DHCP collision): la safety net
orchestrator-side è che `vm new` non riusi mai un clone-name
(timestamp suffix); il test invoca `vm new` due volte con lo stesso
`--job-id` e verifica che `clone_linked` riceva due
`name`/`destination` distinti. Il fix template-side
(`truncate -s 0 /etc/machine-id`) resta documentato in
`template/Prepare-LinuxBuild2404.ps1`.
- **#12** (`& nativecmd 2>$null` non sopprime stderr in PS 5.1):
`SshTransport` usa `paramiko.AutoAddPolicy` di default con
`known_hosts=None`, non chiama mai `subprocess.run`/`Popen`
(incluso `ssh-keygen`/`ssh.exe`/`scp.exe`), e wrappa errori
paramiko (import mancante, `exec_command` exception, SFTP
`put`/`get`) come `TransportConnectError` invece di propagare
eccezioni nude.
- [x] `AGENTS.md` aggiornato: nuova sezione "Python development" subito
dopo "PowerShell 5.1 — Vincoli critici", con tabella parametri,
convenzioni (type hints, no `Any`/globali/`print`/`shell=True`),
mappatura completa PS → Python sub-command, elenco PS che restano
e gate coverage 80%.
- [x] `docs/ARCHITECTURE.md` esteso con sezione "Python orchestrator
(Phase A)": layout package, `VmBackend` Protocol, factory
`load_backend(config)`, ricetta Phase C per backend ESXi
(`backends/esxi.py` + selettore `[backend]` in `config.toml`),
transport selection, gate CI.
- [x] `README.md` ampliato: setup venv produzione + dev, esempi CLI per
tutti i 10 sub-comandi (`wait-ready`, `vm new/remove/cleanup`,
`build run`, `artifacts collect`, `monitor disk/runner`,
`report job`, `job`), comandi validazione locale con gate 80%,
link a `test_agents_errors.py` e `pyproject.toml`.
- [x] Suite completa: ruff clean, mypy --strict clean, **116 pytest
PASS**, coverage totale **80.10%** (gate 80% raggiunto).
- [ ] Burn-in 4 job concorrenti × 10 round (versione Python di
`Test-CapacityBurnIn`) — **richiede VM reali, lasciato a carico
utente**.
- [ ] Workflow `build-ns7zip.yml` matrix (Win + Linux) end-to-end
PASS — eredita pendenza da A4 (richiede runner registrato).
## Definizione di "fatto" A5
| Criterio | Stato |
| ----------------------------------------------------- | -------------------------------- |
| Errori #9#12 coperti da test pytest | ✅ |
| `AGENTS.md` ha sezione "Python development" | ✅ |
| `docs/ARCHITECTURE.md` aggiornato (layout + hook C) | ✅ |
| `README.md` aggiornato (setup + esempi CLI) | ✅ |
| Coverage globale ≥80% (gate alzato in pyproject) | ✅ 80.10% |
| Shim PS non referenziati rimossi | ⏭️ nessuno candidato (vedi nota) |
| Burn-in 4×10 PASS | ⏳ utente — richiede VM reali |
**Nota shim PS**: tutti i 10 shim (`Wait-VMReady.ps1`, `New-BuildVM.ps1`,
`Remove-BuildVM.ps1`, `Cleanup-OrphanedBuildVMs.ps1`,
`Invoke-RemoteBuild.ps1`, `Get-BuildArtifacts.ps1`, `Watch-DiskSpace.ps1`,
`Watch-RunnerHealth.ps1`, `Get-CIJobSummary.ps1`, `Invoke-CIJob.ps1`)
sono ancora referenziati: `Register-CIScheduledTasks.ps1` registra
scheduled task che invocano `Watch-DiskSpace.ps1`,
`Watch-RunnerHealth.ps1`, `Cleanup-OrphanedBuildVMs.ps1`; `README.md`
documenta `Invoke-CIJob.ps1` per uso manuale; `Test-*.ps1` di smoke
chiamano gli shim. Nessuno shim è candidato a rimozione in A5 senza
prima migrare anche `Register-CIScheduledTasks.ps1` (Fase B5 lo
sostituirà con `*.service` + `*.timer` su systemd).
## Cosa resta a carico utente
1. Eseguire un burn-in concorrente (4 job × 10 round) usando il workflow
`build-ns7zip.yml` matrix o `scripts/Test-CapacityBurnIn.ps1` (che
ora delega via shim alla CLI Python `job`) e verificare:
- PASS senza VM orfane (`vm cleanup` non rimuove nulla a fine round).
- Wall-clock entro ±20% del baseline pre-Python (`Measure-CIBenchmark.ps1`).
2. Validare `build-ns7zip.yml` matrix (Win + Linux) end-to-end PASS
sul runner reale — pendenza ereditata da A4.
3. Validare `self-test.yml` e `lint.yml` post-switch.
## Riferimenti commit
- `test(a5): add pytest regression tests for AGENTS.md errors #9-#12`
`tests/python/test_agents_errors.py`
- `docs(a5): document Python orchestrator in AGENTS.md, ARCHITECTURE.md, README.md`
`AGENTS.md`, `docs/ARCHITECTURE.md`, `README.md`
- `docs(a5): mark A5 as code-complete; add A5-closeout.md`
`plans/implementation-plan-A-B.md`, `plans/A5-closeout.md`