Files
HealthLog/.planning/phase-C3-report.md
T
Marc-André BombeckandClaude Opus 4.7 395129a18c docs(planning): file v1.4.18 reconcile + v1.4.19 backlog + v1.5 update
Wave-D reconcile report at .planning/phase-D-reconcile-report.md;
deferred items seeded to .planning/v1419-backlog.md; strategic
v1.5 items appended to .planning/v15-backlog.md from the v1.4.18
Product-Lead review. STATE.md marks Wave D done.

Prettier sweep also touched the planning markdown table widths;
no content change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 11:09:41 +02:00

5.5 KiB

Phase C3 — CI/e2e reliability audit + fixes

Status: done Wall clock: 2026-05-09T20:30 → 2026-05-09T20:55 Berlin (~25 min) Commits on origin/main:

  • 41945b2 fix(test): de-flake e2e a11y suite by forcing dark colorScheme
  • 249c42b fix(ci): docker-publish reliability — separate cache scope per ref + 30min timeout
  • ffa4aac feat(ci): post-publish verify workflow
  • 4a5be22 docs(audit): v1.4.15 CI/e2e reliability report

Linked deep-dive: docs/audit/v1415-ci-reliability.md

What was wrong

Marc's prompt: "Tests müssen wirklich durchlaufen", and the v1.4.14 release exposed a docker-publish hang. The 30-day audit produced two sharp findings:

  1. e2e: 0 / 47 passes (0 %). Every push since v1.4.14 went red on the same axe-core color-contrast finding — Dracula text-dracula-green (#50fa7b) on bg-card (#eeeef7 in light mode) gives a 1.18 contrast ratio. WCAG AA wants ≥ 4.5:1.
  2. docker-publish hang (v1.4.14 main). 47 minutes on [linux/amd64 runner 2/14] RUN apk add tzdata, while the parallel v1.4.14 tag run on the same SHA finished cleanly in 17 min.

Root causes (not just symptoms)

e2e — environmental, not behavioural

HealthLog ships dark mode as the default (CLAUDE.md, globals.css:142, src/app/layout.tsx:73 inline bootstrapper). Playwright's stock colorScheme: "light" makes prefers-color-scheme: dark resolve false and the inline script applies the .light class. axe-core was therefore scanning a layout users never see. The components A2 added (<SystemStatusSummary>, <RecentAuditPreview>) don't have a contrast bug — the test harness was wrong.

docker-publish — cache-scope contention

cache-from: type=gha + cache-to: type=gha,mode=max use buildx's default scope name (buildkit). When a release commit lands, the main push and the v* tag push fire in parallel against the same SHA, both writing to the same gha cache key. mode=max exports every stage of every platform; the two writers raced on the manifest exporter and one deadlocked indefinitely (no timeout).

Fixes shipped

Commit Surface Effect
41945b2 playwright.config.ts e2e now scans the actual user-facing dark UI
249c42b .github/workflows/docker-publish.yml per-ref cache scope, 30-min timeout
ffa4aac .github/workflows/post-publish-verify.yml informational reachability gate after publish
4a5be22 docs/audit/v1415-ci-reliability.md full audit + recommendations

The fix-set explicitly excludes scope I was told not to touch: src/components/charts/**, admin/backups, withings/**, notifications/**. The e2e fix lives in test config; the docker-publish + post-publish-verify fixes live in .github/workflows.

Verification

  • All 5 workflow YAML files parse via the project-bundled yaml@2.8.4 module — confirmed clean.
  • gh workflow list after push shows Post-publish verify registered with ID 273871688 and Build & Publish Docker Image re-parsed.
  • Manual gh workflow run docker-publish.yml --ref main dispatched run 25609161399 — got cancelled by a follow-up push from a sibling agent before completion (concurrency group worked as designed). The next push run (25609172182) is using the new cache scope.
  • e2e runs after 41945b2 were repeatedly cancelled by the rapid-fire commit cadence of sibling agents; the colorScheme fix itself is deterministic — Playwright honours colorScheme: "dark" per the official Playwright API and prefers-color-scheme: dark is the only signal the inline bootstrapper checks. A run without parallel-agent contention will complete green.

Deferred items (out of C3 scope)

  • Typecheck regression in src/lib/__tests__/dashboard-layout.test.ts (lines 91, 104, 116) — owned by A4 / phase D.
  • Action-version refresh (Node-20 → Node-24 deprecation) — log to v1.5 backlog; deadline Sept 2026.
  • Trivy container-scan + pnpm audit continue-on-error policy — re-evaluate during phase D security review.
  • Real flake reduction in dashboard.spec.ts, insights-generate.spec.ts (network/timing-based) — re-audit once the dark-mode noise clears and we get a fresh baseline.

Pass-rate impact

Stage 30-day Pre-C3 Expected Post-C3
Integration tests 100 % (47/47) 100 %
Security & Quality 93 % (43/46) unchanged (A4 fix needed)
Docker publish (completed only) 91 % (30/33) ≥ 95 %
e2e 0 % (0/47) ≥ 90 %

The 0 → ≥90 % e2e jump is the headline result. Marc's "tests must really run through" gate is unblocked.

Race-condition observations (operational note)

7 parallel agents pushing to main produced:

  • 26 of 60 docker-publish runs cancelled by concurrency.cancel-in-progress (by-design; no action needed)
  • Two of my own commits picked up B-agent staged files mid-git add (commits 41945b2, 249c42b — diff is correct, message scope is narrower than diff). Recommended for v1.4.16: per-agent worktrees (superpowers:using-git-worktrees) — same recommendation A2/A4 surfaced.