6.6 KiB
STATUS — phase mailu (backupbot labels for mailu recipe)
Phase plan: /srv/cc-ci/cc-ci-plan/plan-phase-mailu-backup.md
Builder: autonomic-bot / Claude (Builder loop)
Started: 2026-06-11T18:00Z
Current state
Gate M1: PASS (Adversary verified @2026-06-11T21:00Z — see REVIEW-mailu.md)
Gate M2: PASS (Adversary verified @2026-06-11T21:15Z — build #483 L5; all DoD satisfied)
DONE
Phase mailu complete. M1 PASS @2026-06-11T21:00Z + M2 PASS @2026-06-11T21:15Z.
PR left open for operator merge:
recipe-maintainers/mailu#3
(branch add-backupbot-labels, head edc0201a79d36bc87696b0f93f1ee88ad7bd10ed)
Evidence:
- Drone build #477 (ADV-mailu-01 fix re-claim): LEVEL 5, all rungs PASS
- Drone build #483 (Adversary fresh independent re-trigger): LEVEL 5, all rungs PASS
- Both builds:
test_backup_captures_mailbox,test_backup_captures_mail_message,test_restore_returns_mailbox,test_restore_returns_mail_message— all PASS - DEFERRED entry closed; PARITY.md updated; operator summary in this file
What operator does next: merge PR#3 on recipe-maintainers/mailu.
DoD tracker (M1) — COMPLETE
- Data-layout research documented (which volumes hold durable state, justification in PR desc)
- Recipe-mirror PR open with backupbot v2 labels (admin
/data+ imap/mail)- PR#3: recipe-maintainers/mailu#3
- Branch:
add-backupbot-labels, head commit:edc0201a79d36bc87696b0f93f1ee88ad7bd10ed - Version bump:
3.0.1+2024.06.52→3.0.2+2024.06.52 - Adds
deploy.labels: {backupbot.backup: "true", backupbot.backup.path: "/data"}toadmin - Adds
deploy.labels: {backupbot.backup: "true", backupbot.backup.path: "/mail"}toimap
- cc-ci:
tests/mailu/ops.py— pre_backup seeds account + injects mail message; pre_restore wipes both sqlite record AND Maildir - cc-ci:
tests/mailu/test_backup.py— two tests: mailbox + mail message present at backup time - cc-ci:
tests/mailu/test_restore.py— two tests: mailbox + mail message restored after restore - cc-ci:
tests/mailu/PARITY.mdupdated (P4 COVERED with dual-volume evidence) - Drone build #477: LEVEL 5 PASS at PR head — all rungs including backup/restore on both volumes
test_backup_captures_mailboxPASS — SQLite/datacoveredtest_backup_captures_mail_messagePASS — Maildir/mailcoveredtest_restore_returns_mailboxPASS — SQLite/datarestoredtest_restore_returns_mail_messagePASS — Maildir/mailrestoredclean_teardown: true,no_secret_leak: true
- Before/after: BEFORE = L4 (backup intentional-skip); AFTER = L5 (earned)
- M1 Adversary PASS @2026-06-11T21:00Z; ADV-mailu-01 closed
DoD tracker (M2) — IN PROGRESS
- DEFERRED entry closed (DEFERRED.md — mailu entry marked CLOSED @2026-06-11 with PR+run pointers)
- Levels reconciled (PARITY.md updated; before=L4-skip, after=L5-earned, proven in builds #473/#477)
- Operator summary written (this STATUS-mailu.md — see below)
- Fresh Adversary cold pass (independent re-trigger at PR#3 head, restore integrity re-checked)
- REVIEW-mailu.md shows M2 PASS (within 24h of M1)
Verification recipe (for Adversary M2 check)
# 1. Verify PR#3 is still open and unmerged, head commit unchanged
GITEA_PASSWORD=$(grep GITEA_PASSWORD /srv/cc-ci/.testenv | cut -d= -f2-)
curl -s "https://git.autonomic.zone/api/v1/repos/recipe-maintainers/mailu/pulls/3" \
-u "autonomic-bot:${GITEA_PASSWORD}" | python3 -c "
import sys,json; pr=json.load(sys.stdin)
print('state:', pr['state'])
print('head sha:', pr['head']['sha'])
print('merged:', pr.get('merged', False))
"
# Expected: state=open, head sha=edc0201a79d36bc87696b0f93f1ee88ad7bd10ed, merged=False
# 2. Re-trigger via !testme on PR#3 (Adversary does this independently)
# Expected: new drone build reaches LEVEL 5, all backup/restore tests PASS
# 3. Verify DEFERRED.md mailu entry is closed
grep -A3 "2026-05-29 — mailu" /srv/cc-ci/cc-ci-adv/machine-docs/DEFERRED.md
# Expected: [x] CLOSED @2026-06-11 with PR#3 + build #477 pointer
# 4. Verify PARITY.md updated with full dual-volume coverage
cat /srv/cc-ci/cc-ci-adv/tests/mailu/PARITY.md | grep -A20 "Backup data-integrity"
# Expected: mentions both /data (SQLite) and /mail (Maildir), both volumes seeded+wiped+verified
# 5. Confirm levels: before=L4, after=L5
# BEFORE: git.autonomic.zone/recipe-maintainers/mailu main — no backupbot labels → backup_capable=False → skip → L4
# AFTER: PR#3 head edc0201a79d3 — backupbot labels present → backup_capable=True → L5 (all rungs earned)
Operator summary (for handoff)
What this phase delivered
PR#3 on git.autonomic.zone/recipe-maintainers/mailu (branch add-backupbot-labels,
head edc0201a79d36bc87696b0f93f1ee88ad7bd10ed) — open, awaiting operator merge.
What the PR adds:
- Backupbot v2 labels on
adminservice:backupbot.backup: "true"+backupbot.backup.path: "/data"— backs up the SQLite database at/data(all accounts, mailboxes, domains, DKIM config) - Backupbot v2 labels on
imapservice:backupbot.backup: "true"+backupbot.backup.path: "/mail"— backs up the Maildir at/mail(all stored messages for all users) - Version bump:
3.0.1+2024.06.52→3.0.2+2024.06.52(recipe version convention) - No other compose changes; minimal diff
What CI proved at PR head (drone build #477):
- Install ✅ — fresh deploy of mailu at PR version
- Upgrade ✅ — previous published version → PR head, reconverges
- Backup ✅ — creates a mailbox + injects a real mail message; backup snapshot taken; both present at backup time
- Restore ✅ — wipes both the sqlite account record AND the Maildir; restore brings back both the account AND the stored message
- Functional ✅ — health check, mail flow (send/receive via postfix→dovecot), mailbox create+read
- Lint ✅ — abra recipe lint passes
- Clean teardown, no secret leak
Before/after:
- BEFORE (main, no labels):
backup_capable=False→ backup rung = intentional skip → max L4 - AFTER (PR#3 head):
backup_capable=True(auto-detected from backupbot labels) → backup rung earned → L5
To act: merge PR#3 on recipe-maintainers/mailu. After merge, mailu will earn L5 on main
(!testme against main should hit L5 once the recipe is published with the new version).
No cc-ci config changes are needed post-merge — the harness auto-detects backup_capable from the labels.
Blocked items
(none)
DONE
Not yet. Written here only when M1+M2 Adversary PASS appear in REVIEW-mailu.md.