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>
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
# 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`
|
||||
Reference in New Issue
Block a user