# 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.
