# PARITY — drone Tracks which lifecycle rungs are covered and why any are skipped. ## Tiers | Tier | Status | Notes | |------|--------|-------| | Install | COVERED | Fresh deploy with gitea dep pre-provisioned | | Upgrade | COVERED | 1.8.0+2.25.0 → 1.9.0+2.26.0 (two published versions; viable) | | Backup/Restore | STRUCTURAL SKIP | See below | | Functional | COVERED | SCM-configured test (gitea OAuth redirect) | | Lint | COVERED | `abra recipe lint` (L5 target) | | Screenshot | COVERED | Drone login/landing page | ## Backup rung — structural skip **Justification:** The drone recipe declares no backupbot labels in `compose.yml` and ships no `abra_backup*` functions in `abra.sh` (which only exports `DRONE_ENV_VERSION=v2`). Therefore `backup_capable=False` is auto-detected by the harness — the backup rung is an intentional structural skip, not a gap. **Evidence:** ``` # compose.yml — no backupbot.* labels anywhere grep -i backupbot ~/.abra/recipes/drone/compose.yml # → (no output) # abra.sh — no backup functions cat ~/.abra/recipes/drone/abra.sh # → export DRONE_ENV_VERSION=v2 # (no abra_backup / abra_restore functions) ``` **Level impact:** With backup_capable=False (structural skip), the backup rung is an EXPECTED_NA-class intentional skip. The recipe can still reach L5 if all other rungs pass, because the backup rung's skip is declared-and-justified, not a surprise omission. **Path to L5:** install + upgrade + functional + lint + screenshot all PASS. ## Gitea dep teardown The gitea dep is co-deployed per run. Both gitea AND drone are torn down in the orchestrator's `finally` block (deps in reverse order: drone first, then gitea). A drone test failure mid-run still triggers the `finally` — the teardown guarantee is sacred.