Under a CI burst (a batch merge fires ~13 workflows x ~4 jobs, each doing an
AppRole login = a raft write), the vault nodes return nginx 504s and the
rate-limit quota returns 429s. Both are non-JSON, which crashed jq and
hard-failed the job with a misleading "parse error". Add a bao_req helper that
retries connect-failures/429/5xx with backoff+jitter (~60s over 6 tries) and
surfaces real 4xx bodies unchanged. Transient throttling no longer fails CI.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Shared actions live in a PUBLIC repo so CI runners can clone them anonymously.
They can't clone the private spikersoft-infrastructure repo (a job token is
scoped to its own repo), which is why the notifications Bao cutover failed with
"Repository not found". bao-secrets is pure curl/jq logic — role_id/secret_id
come from the caller's Actions secrets — so nothing sensitive is exposed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>