Commit Graph

56 Commits

Author SHA1 Message Date
Simone 5bff7b4f0c docs: close Phase B (B7 concurrent burn-in PASS + B8 stability)
Concurrent capacity burn-in run on the Linux host as ci-runner with the
static-IP pool: WinBuild2025 40/40 PASS (~78.6s/round) and LinuxBuild2404
40/40 PASS (~70.2s/round) — 80/80 jobs, 20/20 rounds, near-deterministic
(static IP eliminates the DHCP IP-acquire variance of the §6/§7 baselines).

- RUNBOOK §9: concurrent burn-in result + ip-pool reset/recovery note.
- PhaseB-user-checklist Passo 7/8 marked done; fixed two checklist bugs:
  run as ci-runner (the simone path needs g+w on the /var/lib/ci root for
  ip-pool.tmp, not just the sub-dirs), and the Linux command was missing
  -SnapshotName BaseClean-Linux (default BaseClean is Windows-only).
- idea-2-linux-host §8 DoD: Phase B complete (B1–B7 + >2 weeks stability).
- TODO §2.8 [P2]: ip-pool is not reconciled against live clones; a killed
  job leaks its lease permanently and exhausts the 4-IP pool. Proposed fix.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 01:44:56 +02:00
Simone 0b69155b02 fix(plans): switch B7 burn-in to burnin-dummy repo
nsis-plugin-ns7zip is a real C++ project — wrong for lifecycle testing.
burnin-dummy simulates ~30s work and writes to dist/ with no external
deps. Documents one-time prerequisites (group, keyring, Gitea push).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 23:44:07 +02:00
Simone 40aae7ad16 fix(plans): add -BuildCommand to B7 burn-in commands
Without an explicit build command, job.py runs dotnet build (which fails
on nsis-plugin-ns7zip in a fresh VM) and expects bin\CIOutput as artifact
source. With a trivial BuildCommand, artifact_source defaults to "dist"
and the lightweight command always succeeds.

Also documents one-time simone group/keyring prerequisites for running
the burn-in as simone with ci-runner group access.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 23:03:52 +02:00
Simone 5982a88041 fix(plans): prefix B7 burn-in commands with sudo -u ci-runner
/var/lib/ci/ is owned by ci-runner; running as simone causes
PermissionError on artifact dir creation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 22:45:43 +02:00
Simone ce84afd901 fix(plans): correct Test-CapacityBurnIn.ps1 commands in B7
-Concurrency → -Parallelism, -Template → -TemplatePath; add mandatory
-RepoUrl and Linux-host paths (-CloneBaseDir, -ArtifactBaseDir,
-VmrunPath). Add explicit LinuxBuild2404 command with -GuestOS Linux.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 22:37:18 +02:00
Simone defb95bd22 fix(plans): restore PhaseB-user-checklist.md — phase not fully complete
Burn-in (4 jobs × 10 rounds), 7-day stability run, and RUNBOOK.md
Linux section are still open. Checklist stays active until all
acceptance criteria are met.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 22:02:38 +02:00
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
Simone 53649b40af docs(plan): close Phase B Passo 6 (cutover smoke + monitoring)
ns7zip matrix Win+Linux passes after the WinRM quotas + desktop-heap
fixes landed in the template scripts. Monitoring window completed
without regressions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 23:43:28 +02:00
Simone bbd376f057 docs: add B1–B4 closeout docs and rewrite B5-closeout as completed
B1: Linux Mint + VMware Workstation + setup-host-linux.sh (Python 3.12 note)
B2: rsync template transfer, VMX registration, smoke tests; keyrings.alt choice
B3: SSH key perms, BuildVMGuest + GiteaPAT via PlaintextKeyring (D-Bus-free)
B4: act-runner.service, config.yaml labels/envs fix, smoke job PASS
B5: rewritten — Python-only timers (no pwsh), 7z compression, --service-name
    act-runner fix, prerequisite dirs, root service for backup

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-05-21 20:57:19 +02:00
Simone 6db20d66bf docs: introduce Phase C (pwsh removal), rename ESXi to Phase D
- Add plans/idea-3-powershell-removal.md: Phase C goal is to eliminate
  the pwsh dependency from the Linux host by porting the remaining PS
  scripts (bench run, validate host, smoke run) to Python sub-commands.
- Update idea-3-esxi-support.md header: Fase C → Fase D.
- Update ideas-overview.md: new four-phase table (A/B/C/D) with
  prerequisiti and criteri for Phase C.
- Rename all "Hook futuri Fase C" (ESXi) → "Hook futuri Fase D" in
  implementation-plan-A-B.md; add Phase C/D entries to summary and
  references section.
- Update PhaseB-user-checklist.md end note and CLAUDE.md to point
  Phase C → pwsh removal, Phase D → ESXi.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-05-21 20:46:01 +02:00
Simone 43a69b82db feat: B5 — port retention/template-backup to Python, deploy systemd timers
- Add `retention run` command (ports Invoke-RetentionPolicy.ps1): purges
  old artifact/log dirs with aggressive mode when disk space is low.
- Add `template backup` command (ports Backup-CITemplate.ps1): 7z -mx=1
  compressed archives in /var/lib/ci/backups/, prunes to keep-count=3,
  stops/restarts act-runner.service around the copy.
- Update ci-retention-policy.service and ci-backup-template.service to use
  Python; pwsh is no longer required on the Linux host.
- Fix ci-watch-runner-health.service: pass --service-name act-runner
  (Linux service name, not Windows act_runner default).
- Fix _list_orphans in vm.py: wrap is_dir() inside the OSError try block
  so a stat() failure on an entry is silently skipped rather than raised.
- Mark B5 complete in PhaseB-user-checklist.md.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-05-21 20:35:07 +02:00
Simone 536fd688e8 feat: update runner configuration steps and add config.yaml generation instructions 2026-05-21 00:45:43 +02:00
Simone 3921758392 feat: update action.yml to use pwsh shell and enhance vm.py with start option; add credential management scripts
Lint / pssa (push) Failing after 7s
Lint / python (push) Failing after 1s
2026-05-21 00:11:20 +02:00
Simone b9d6994c85 feat: add setup-host-linux.sh script for CI host bootstrap and update Phase B checklist 2026-05-20 22:13:37 +02:00
Simone 573d11691d docs: Windows host compat is a categorical constraint (B8 cancelled)
User requirement (non-negotiable): the project must stay
first-class compatible with a Windows host permanently — Phase B
adds Linux *alongside* Windows, never replacing/degrading it.
- implementation-plan-A-B §2: categorical-constraint banner; B8
  decommissioning cancelled (kept only as historical record);
  master checklist B8 row updated.
- PhaseB-user-checklist: Passo 9 (B8) cancelled -> dual-host kept;
  Passo 8 no longer a decommission gate; tracking table + closing
  note updated.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 23:45:31 +02:00
Simone 0f99549b70 docs: implementation-plan-A-B — Phase A closed, B kept as forward plan
Medium update: exec-summary status (A COMPLETATA, B ready), master
checklist A items [x], Phase A gating satisfied, §1 COMPLETATA banner
with real validation deviations (LocalSystem venv/keyring, github-free
artifacts, transport, shim common-params, deferred §8.1/§8.2), §7
A-side definition-of-done [x]. Fase B (§2/§3/§4) + risk matrix +
cronoprogramma left intact as the Phase B design reference alongside
PhaseB-user-checklist.md.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 23:29:19 +02:00
Simone fce85b72b4 docs(phaseA): Phase A closed — Passo 9 done (merge + tag)
feature merged to main (2aa12bb), tag v2.0.0-phaseA pushed
(triggers build-ns7zip as final end-to-end validation of main).
All Passi 1-9 [x]. Residual non-blocking cleanup: delete the test
Gitea releases via UI (tags kept).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 23:23:12 +02:00
Simone b4ca7f3236 docs(phaseA): Passo 9 merge done; global table 6-8 PASS
Lint / pssa (push) Successful in 30s
Lint / python (push) Successful in 1m2s
Build ns7zip (Local CI) / release (push) Has been cancelled
Build ns7zip (Local CI) / build (linux) (push) Has been cancelled
Build ns7zip (Local CI) / build (windows) (push) Has been cancelled
feature merged to main (2aa12bb, tree == feature). Passi 6/7/8 [x],
Passo 9 in progress (release tag pending).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 23:20:40 +02:00
Simone 5539eddba2 docs(phaseA): mark baseline comparison skipped (decided)
No reliable pre-Python PS baseline; not blocking Phase A close.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 23:17:10 +02:00
Simone 36913ab6c6 docs(phaseA): Passo 8 benchmark recorded (destroy fixed)
Measure-CIBenchmark.ps1 x4 clean: clone/start/WinRM negligible,
destroy ~4-6s (shim common-param fix), 0 orphans. IP-acquire phase
(20-85s) is the dominant variable cost (VMware Tools IP detect) —
known, non-blocking. No reliable pre-Python PS baseline; infra
metrics tracked in benchmark.jsonl.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 23:09:56 +02:00
Simone f7cfc74290 docs(phaseA): Passo 7 burn-in PASS (12/12, 0 orphans)
Start-BurnInTest.ps1 (lab wrapper: burnin-dummy + build.ps1) — 4
concurrent x 3 rounds all PASS, clean VM/lock teardown each round.
Note the gotcha: raw Test-CapacityBurnIn.ps1 without -BuildCommand
defaults to dotnet and fails on the non-.NET dummy repo.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 22:57:55 +02:00
Simone 2aeb390f62 docs(phaseA): drop moot failure-contingency checkbox (Passo 6)
All workflows passed; the "if one fails" item never triggered. Replace
the dangling [ ] with a historical note so Passo 6 has no false-open
task.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 22:44:32 +02:00
Simone 61d80ae47e docs(phaseA): Passo 6 complete — build-ns7zip matrix + release PASS
lint, self-test, build-ns7zip (Win+Linux) and the release job
(Gitea release + asset upload via REST API, auto token) all green.
Phase A Gitea end-to-end validated.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 22:41:41 +02:00
Simone 97ec820ebb ci: rename build-nsInnoUnp.yml -> build-ns7zip.yml; update doc refs
Workflow now targets Simone/nsis-plugin-ns7zip. Renamed the file and
the workflow `name:`, and updated all references in active docs
(plans/archived and docs/archived left as frozen history).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 20:12:25 +02:00
Simone 2201d0ace6 docs(phaseA): record self-test smoke matrix (both transports PASS)
Passo 6: self-test.yml validated — in-guest clone (default) and
host-side clone+zip, Windows + Linux, all SUCCESS. Artifact handling
github-free.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 17:11:40 +02:00
Simone ce71c95083 docs(phaseA): mark self-test.yml validated
Both smoke jobs (Linux + Windows) passed end-to-end this session.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 16:09:52 +02:00
Simone 662a4eb85d docs(phaseA): fix Windows smoke artifact-source to match build cmd
The Windows manual smoke used --guest-artifact-source
'C:\ci\workspace\artifact.txt' (a stale absolute path that does not
exist in the build flow; workdir is C:\CI\build). The build command
writes artifact.txt into the workdir, so the source must be relative
'artifact.txt' — matching the Linux example.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 15:55:52 +02:00
Simone 9972010230 docs(phaseA): production venv install must be non-editable
act_runner runs as LocalSystem; `pip install -e .` writes a .pth to a
path LocalSystem can't resolve (N: user drive or a transient
F:\CI\RunnerWork job dir), causing "No module named ci_orchestrator".
Prescribe `pip install .` and warn about the cd target.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 12:08:57 +02:00
Simone c5b2f36c77 docs: aggiorna checklist FaseA (tracking workflow) 2026-05-17 00:29:21 +02:00
Simone e810747557 docs,config: aggiorna AGENTS.md, config.example, HOST-SETUP.md, checklist faseA e fix vari orchestrator (workstation, build, job, wait, winrm, test) 2026-05-17 00:14:04 +02:00
Simone 137287176e docs: rename branch references to feature/python-rewrite-and-linux-migration
Update active docs (PhaseA/B checklists, README) after rename of feature/python-rewrite-phase-a -> feature/python-rewrite-and-linux-migration. Historical A1-A5 closeouts left untouched as they document state at the time of writing.
2026-05-14 18:34:04 +02:00
Simone 28523375b9 docs(plans): add A->B bridge checklist (windows prereqs + baseline + logistics)
Bridges the gap between PhaseA-user-checklist.md (Windows validation) and PhaseB-user-checklist.md (Linux setup):

  Section 1: capture pre-migration benchmark to docs/RUNBOOK.md (referenced by B7)

  Section 2: 7 Windows prerequisites (SSH keys, BuildVMGuest password, Gitea PAT, OpenSSH server, template power-off check per AGENTS.md #9, F:\CI\ backup, scheduled task cadence audit)

  Section 3: logistics (hardware, DNS, maintenance window, user comms)
2026-05-14 18:34:04 +02:00
Simone bd61258a42 feat(b6): add Phase B user checklist for CI migration to Linux Mint 2026-05-14 18:34:04 +02:00
Simone 0bd3b52fb5 feat(b5): add systemd unit files for CI periodic tasks (Linux host)
Implements the repo-side artifacts of Phase B5 (plans/implementation-plan-A-B.md). Creates 5 .service + .timer pairs under deploy/systemd/ that replicate the periodic tasks registered on Windows by scripts/Register-CIScheduledTasks.ps1:

  - ci-cleanup-orphans       -> python -m ci_orchestrator vm cleanup --max-age-hours 6 (every 6h + boot)

  - ci-retention-policy      -> pwsh Invoke-RetentionPolicy.ps1 (daily 03:00)

  - ci-watch-disk-space      -> python -m ci_orchestrator monitor disk (every 15min)

  - ci-watch-runner-health   -> python -m ci_orchestrator monitor runner (every 15min)

  - ci-backup-template       -> pwsh Backup-CITemplate.ps1 (weekly Sun 02:00, NEW)

Includes deploy/systemd/README.md with mapping table, install/test/rollback instructions, and PowerShell Core install note for the two PS-only scripts. Plan checklist updated; B5-closeout.md added. Hardware install steps (systemctl enable + smoke) remain user responsibility on the Linux host.
2026-05-14 18:34:04 +02:00
Simone 4e0b796f81 docs: add Fase A user checklist for hardware validation 2026-05-14 18:34:04 +02:00
Simone a658f4ed3b docs(a5): mark A5 as code-complete; add A5-closeout.md
Master checklist + step A5 attivita + 'definizione di fatto' updated; A5-closeout.md added (116 pytest, coverage 80.10% total, gate raised to 80%). Hardware validation (burn-in 4x10 + workflow matrix end-to-end) deferred to user. Shim PS removal deferred to B5 (systemd timers): all 10 shims still referenced by Register-CIScheduledTasks.ps1 / docs / Test-*.ps1.
2026-05-14 18:34:04 +02:00
Simone 1bcd40e483 docs(a4): mark A4 as code-complete; add A4-closeout.md
Master checklist + step A4 attivita + 'definizione di fatto' updated; A4-closeout.md added (104 pytest, coverage 79.25% total / 83% commands/job.py). Hardware validation (matrix workflow + benchmark) deferred to user.
2026-05-14 18:34:04 +02:00
Simone 816a15503e feat(a3): port build pipeline (vm new, build run, artifacts collect)
Implements Phase A3 of plans/implementation-plan-A-B.md:

- commands/vm.py: vm new (replaces New-BuildVM.ps1)

- commands/build.py: build run (replaces Invoke-RemoteBuild.ps1) with WinRM/SSH dispatch and stdout streaming for act_runner

- commands/artifacts.py: artifacts collect (replaces Get-BuildArtifacts.ps1) using transport.fetch()

- 3 PS scripts reduced to shims preserving \0

- Pester tests/{New-BuildVM,Wait-VMReady,Remove-BuildVM}.Tests.ps1 removed; equivalent cases covered in pytest

- Phase C hook: build/artifacts accept opaque VmHandle/vmx; no Windows path assumptions

Tests: 91 pytest, ruff clean, mypy --strict clean, coverage 78.27% (>=70 gate).

Master checklist + step A3 attivita + 'definizione di fatto' updated; A3-closeout.md added.
2026-05-14 18:34:03 +02:00
Simone 096ba7fe16 docs(a1): sync master checklist + A1 'definizione di fatto' to actual state
A1 items were completed but only A1-closeout.md was updated. Mark all A1 checkboxes done in implementation-plan-A-B.md (master checklist + step-A1 attivita + definizione di fatto), leaving only the real-VM PoC pending (hardware validation deferred).
2026-05-14 18:34:03 +02:00
Simone ad9e6e9673 docs(a2): mark A2 as code-complete; add A2-closeout.md 2026-05-14 18:34:03 +02:00
Simone 10da8f4e81 docs(A1): mark lint.yml python job as PASS on act_runner 2026-05-14 18:34:03 +02:00
Simone 44a99af14f feat: add closeout checklist for Phase A1 implementation 2026-05-14 18:34:02 +02:00
Simone 4d957d34b2 fix: correct table formatting in ideas-overview.md for better readability 2026-05-13 11:12:28 +02:00
Simone 4ac6dd85f9 refactor: restructure implementation plan for clarity and readability 2026-05-13 11:08:01 +02:00
Simone 770ac1edf8 Add unified implementation plan for Phase A and Phase B in Markdown format
- Create a new document `plans/implementation-plan-A-B.md` that consolidates the implementation plans for the Python rewrite (Phase A) and the migration to Linux Mint (Phase B).
- The document includes detailed sections such as executive summary, checklist, prerequisites, step-by-step activities, architectural hooks for future phases, risk matrix, and references.
- Ensure the plan is self-contained, adhering to specified structure and style guidelines, and does not introduce new technologies or modify existing files.
2026-05-13 10:49:10 +02:00
Simone 081f7e1d16 archive: move completed plans and sprint test plan to dated folders
- plans/archived/2026-05-13/: final-master-plan (done), 4 AI analysis/review
  docs (gpt55-analysis, gpt55-review-of-opus, opus47-analysis,
  opus47-review-of-gpt55)
- docs/archived/2026-05-13/: TEST-PLAN-v1.3-to-HEAD (sprint complete)
2026-05-13 10:47:06 +02:00
Simone 6cd6bff882 nice-to-have: implement all 6 tier items
- Get-CIJobSummary.ps1: already present with full implementation (marked done)
- Get-BuildArtifacts.ps1: add -JobId/-Commit params; Write-ArtifactManifest writes
  manifest.json (name, size, sha256, commit, jobId) after both Linux and Windows
  artifact collection branches
- Invoke-CIJob.ps1: add -GuestCPU/-GuestMemoryMB params; insert post-clone VMX
  override block (numvcpus/memsize rewrite) before vmrun start; pass -JobId/-Commit
  to Get-BuildArtifacts calls
- Watch-RunnerHealth.ps1: add -GiteaUrl/-GiteaCredentialTarget params; optional
  GET /api/v1/admin/runners check in Running branch warns if 0 online runners
- Install-CIToolchain-WinBuild2025.ps1: fill SHA256 hashes for Python 3.13.3,
  7-Zip 26.01, Node.js 22.14.0, dotnet-install.ps1
- Measure-CIBenchmark.ps1: add deltaKB field (linked-clone disk footprint in KB)
  measured post-clone; added to result object and summary Format-Table
2026-05-13 10:38:49 +02:00
Simone 8ca3e530c5 feat(low): sprint 4 Low items tutti 5 completati
codice:
- template/Validate-SetupState.ps1: docblock HTTP/Basic -> HTTPS/Basic, port 5986
- scripts/Validate-HostState.ps1 (nuovo): check ACL SSH key ci_linux, Credential Manager
  target BuildVMGuest, struttura dir F:\CI\, vmrun.exe raggiungibile

docs:
- docs/TEST-PLAN-v1.3-to-HEAD.md sezione 3.6: campi JSONL corretti (cloneSec/startSec/
  ipSec/winrmSec/destroySec/totalBootSec) per riflettere output reale di Measure-CIBenchmark.ps1
- docs/CI-FLOW.md tabella failure: 'partial artifacts' -> Get-GuestDiagnostics a diagnostics/
- docs/CHANGELOG.md (nuovo): log reverse-cronologico di tutti gli sprint completati
- plans/final-master-plan.md: tutti i Low marcati done
2026-05-13 10:26:08 +02:00
Simone e9d0f38f9f feat(medium): sprint 3 Medium items 6 implementati, 6 confermati gia' presenti
codice:
- Watch-DiskSpace.ps1: Event Log source CI-DiskAlert -> CI-DiskSpaceAlert
  (allineato con task scheduler CI-DiskSpaceAlert)
- Watch-RunnerHealth.ps1: maintenance flag  salta restart se
  F:\CI\State\runner-maintenance.flag esiste
- Invoke-CIJob.ps1:
  - param WebhookUrl (default '') per alert webhook
  - sanity check TemplatePath: Write-Warning se non sotto F:\CI\Templates\
  - 90-min duration warning: Start-Job che posta [WARNING] dopo 5400s
  - finally: Remove-Job per cancellare il warn se build finisce prima

docs:
- BEST-PRACTICES.md sezione 11: VMware HGFS write semantics e cache-poisoning risk
- final-master-plan.md: marcati done  post-failure diagnostics, UseSharedCache,
  VMDK SHA256, SSH host-key, template-refresh runbook, 90-min warn, HGFS,
  Event Log names, TemplatePath sanity, maintenance flag, Setup-Host pass docs,
  emoji-free webhooks
2026-05-13 10:19:55 +02:00
Simone 91f2305bb0 docs(plan): sprint 3 verification pass tutti gli High restanti gia' implementati
- H9 (ci-report-ip.service check): gia' in Validate-DeployState.ps1 branch Linux
- H10 (smoke test workflow): gia' in gitea/workflows/self-test.yml + scripts/Test-Smoke.ps1
- H12 (Get-GuestIPAddress): gia' estratto in _Common.psm1 e usato da Measure-CIBenchmark
- Medium: disk gate (L339), JobId ValidatePattern (L77), ExtraGuestEnv key validation
  (L184), phase-duration summary (L541), TEST-PLAN PS7 syntax gia' corretta
- Low: Install-Runner.ps1 gia' assente dal repo
- Aggiornato header Last updated + Status
2026-05-13 10:10:55 +02:00