Skip to content

feat(rollout): report each tick's ramps and fail the run when one is overdue - #90

Open
scott-lowe-vapi wants to merge 1 commit into
gradual-deploy-rollout-health-gatefrom
gradual-deploy-rollout-tick-visibility
Open

scott-lowe-vapi wants to merge 1 commit into
gradual-deploy-rollout-health-gatefrom
gradual-deploy-rollout-tick-visibility

Conversation

@scott-lowe-vapi

@scott-lowe-vapi scott-lowe-vapi commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

Support partial GitOps promotions using traffic splitting

Part of DEPLOY-205. 5 of 5: make a stuck ramp visible, and count health-gate aborts apart from aborts someone ran.

What changes

  • Health-gate aborts are written as rollout-health-abort instead of rollout-abort. That is one more value in RolloutCommand, and no server change, since the x-vapi-client schema accepts [a-z0-9_-]. PostHog can now count how often the gate fires.
  • Each advance and status run appends a table to $GITHUB_STEP_SUMMARY: every ramp's state and what the health gate read (calls and error rate per version). Before, a stuck ramp was a console.log line in a green run.
  • advance fails when a ramp is overdue, so GitHub's failure notification reaches someone. Overdue means:
    • a step still waiting three intervals after it was written (the gate hasn't seen minCalls);
    • a stale pin from a killed promotion, left for a human after 6h;
    • the split changed under a step. Only the run that finds it fails, since the next tick no longer sees a ramp.
  • Holds and aborts are deliberate, so they never fail a run. Failing on them would turn every 15-minute tick red until the next promote.
  • status lists overdue ramps but doesn't fail.
  • Docs: promotion.md covers the summary, what fails a run, and who GitHub notifies; how-it-works.md lists the new command.

This doesn't catch a ticker that never runs: a disabled schedule, an Actions budget block, or VAPI_ROLLOUT_ENABLED unset. That needs the server-side stuck-ramp insight in PostHog, which waits on GitOps attribution reaching production.

Evidence

  • rollout-tick.test.ts: the gate abort's command; overdue for a starved gate after three intervals, a stale pin, and a malformed step; never overdue for a hold or an abort; the gate reading on a passing step.
  • rollout-cmd.test.ts: a split changed under a step fails that run, and the next one passes; a stale pin fails advance while a hold beside it doesn't; status lists it without failing; the exact step summary.
  • rollout-summary.test.ts: the table, its overdue count, pipe escaping, and the failure message.

Tests run with GITHUB_STEP_SUMMARY unset unless a test sets it, so CI's own summary stays clean. 695 tests pass (682 on #89).

🤖 Generated with Claude Code

…overdue

Part of DEPLOY-205.

Health-gate aborts are written as rollout-health-abort, so they are countable
apart from an abort someone ran. Each advance and status run writes every
ramp's state and the gate's reading to the step summary, and advance fails
when a ramp is overdue: a step still waiting three intervals on, a stale pin
left for a human, or a split changed under a step. Holds and aborts never fail.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Copy link
Copy Markdown
Contributor Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant