Raxx · internal docs

internal · gated

RCA — getraxx.com missing BLR-cleared compliance disclaimers (manual-deploy ref gap + stale develop→main promotion)

Incident ID: 2026-08-09-getraxx-blr-compliance-deploy-gap Date: 2026-08-09 (detected; underlying gap opened 2026-08-06) Severity: SEV-1 (public compliance gap on a live, customer-facing marketing site — hypothetical-return figure served without its BLR-mandated disclaimer) Duration: ~3 days 18 hours from gap-open to content-live (2026-08-06 ~05:24 UTC content diverged from compliant → 2026-08-09 23:xx UTC verified live, see Resolution); detection lag ~3 days 14 hours (gap opened 2026-08-06, caught by QA sweep 2026-08-09) Blast radius: getraxx.com public visitors (pre-signup marketing site) between 2026-08-06 ~05:24 UTC and resolution. No authenticated product surface affected. Author: sre-agent

Summary

Two BLR-cleared compliance disclaimers (§5A investment-adviser footer, §5B hypothetical-backtest caption) were authored, reviewed, and merged to develop on 2026-08-06 as part of an authorized "copy wave" (epic #2855), but never reached getraxx.com production. A manual Woodpecker trigger of .woodpecker/deploy-getraxx.yaml — a trigger path with no branch/ref restriction — fired against develop mid-wave, after the hero-copy commit landed but before the two disclaimer commits landed 19–43 minutes later. That manual deploy shipped the new hero copy (and, with it, the "+34.2% total return" mock the §5B disclaimer is supposed to caption) without either disclaimer. main's git history received none of the four wave commits, so no subsequent main-push deploy ever corrected the gap — the live site and main's history diverged simultaneously, in opposite ways (the live site had newer-than-main content, missing newer-than-develop compliance copy).

The gap was caught 2026-08-09 by a QA compliance sweep (issue #4441), not by any automated signal. Remediation (cherry-picking the four wave commits onto a main-based hotfix, PR #4442) surfaced two further, independently blocking defects in the deploy path itself before the content could ship: a main-targeted PR's required ci-pr check was structurally guaranteed to fail (stale-branch-guard was still hardcoded to compare against develop, a bug already found and fixed on develop twice — 2026-07-25 and 2026-07-30 — but never promoted to main), and the deploy-getraxx pipeline itself failed on its first post-merge run due to unrelated Debian base-image drift (PEP-668 externally-managed-environment breaking a bare pip3 install).

Timeline (all times UTC)

Impact

What went well

What didn't go well

Root cause analysis

Detection

Resolution

Action items

# Action Owner Due Issue
1 DONE — Restrict deploy-getraxx.yaml's event: manual trigger to branch: main (or add an explicit ref-check guard step) so a manual run can never again deploy a non-main ref to prod. Verified against WP v3.16.0 source that when.branch IS evaluated for event: manual (only event: tag skips it) and the manual-trigger API only ever accepts a branch name resolved to its forge HEAD — no ref/SHA bypass exists — so the declarative branch: main when-item is a reliable guard, not an in-step assertion. Applied to the same push+manual/no-branch-guard shape in deploy-support.yaml, deploy-mockups.yaml, deploy-status-page.yaml too (same incident class). deploy-queue.yaml/deploy-velvet.yaml share the bare event: manual gap but have a different multi-branch topology (push: [release, main]) that a flat branch: main restriction would break — follow-up ticket filed for those. sre-agent / operator 2026-08-16 #4451
2 Fix queue-docker-smoke's detect-changes step (CI_COMMIT_BEFORE unset under set -eu) — found during this incident's CI diagnosis, genuine and unrelated sre-agent 2026-08-16 #4452
3 Apply the PEP-668 --break-system-packages fix to the four other pipeline files with the same unflagged pip3 install pattern (deploy-support.yaml, deploy-mockups.yaml, pr-preview.yaml ×2, deploy-status-page.yaml) before they fail on next real trigger sre-agent 2026-08-16 #4454
4 Establish a forcing function for develop→main CI-infra parity: either a scheduled/reminder-driven release→main promotion cadence (so infra fixes don't sit on develop indefinitely), or a lint that diffs .woodpecker/*.yaml + scripts/ci/** between develop and main and flags drift older than N days operator 2026-08-23 (to be filed by operator — cross-cutting ADR-0115 policy decision, not a single-repo fix)
5 Add a scheduled content-drift check comparing getraxx.com's live served bundle against what main's frontend/getraxx-landing/ source currently produces, alerting on divergence sre-agent 2026-08-23 (to be filed)

References