agentsclimarketplace

Rollback guard

Skill iampawan/Manifest/skills/rollback-guard

During a feature's rollout window, watch Sentry errors, crash-free rate, and release adoption against the contract's budgets and RECOMMEND proceed / hold / recommend-rollback. Never executes a rollback — it proposes and a human approves. Invoked by /rollback-check or the rollback-guard.yml workflow (tight cadence while a canary is live). Closes the gap between "deployed" and "safe."From its SKILL.md

Install
npx -y skills add iampawan/Manifest --skill rollback-guard

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 5 stars5 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

7.8 KB, as published. Nobody here has run it

Rollback guard

verify-deployment decides whether a build is ready to start rolling out. You are the watcher for the period after that — while the feature ramps from canary to 100%, you keep asking "is this still healthy, or is it quietly on fire?" and surface a clear recommendation the moment it stops being healthy.

You recommend; you do not act. Pausing a canary or rolling back is a production change with blast radius — a human approves and performs it (or flips the flag). Auto-executing a rollback is out of scope by design, and matches verify-deployment's "don't auto-rollback" stance.

Inputs

  • Contract ID (+ revision)
  • Optional: explicit time window (default: since canaryStartedAt, or the last 30 min if a tighter sample is requested)

When you should run

While a contract is in its rollout window: canaryStartedAt is set and prodRollout100At is not — or it just reached 100% and you're in the first 24h of full traffic. Outside that window, the slower launch-report cadence (day 1/7/14/28) takes over. The rollback-guard.yml workflow runs you on a tight cadence during that window; /rollback-check <ID> triggers you manually.

Process

1. Read the contract's budgets

From .manifest/contracts/<ID>.r<N>.md, pull the thresholds you'll judge against. These come from existing fields plus an optional rollbackTriggers block:

  • Per-behavior perfBudget (latency / render / cold-start numbers).
  • The crash-free / error-rate budget if declared.
  • Optional rollbackTriggers frontmatter (explicit guardrails):
rollbackTriggers:
  errorRateMultiplier: 3      # error rate > 3× pre-launch baseline → breach
  crashFreeFloor: 99.0        # crash-free users % must stay ≥ this
  newIssueSeverity: blocker   # any new Sentry issue at/above this → breach
  minAdoptionForSignal: 0.05  # ignore noise until ≥5% of users are on the release

If rollbackTriggers is absent, fall back to sensible defaults (error rate > 3× baseline, crash-free < 99%, any new high-volume unhandled-exception issue), and say in the report that defaults were used.

2. Sample the live signals

Use the Sentry MCP (and Crashlytics / APM if connected) for the window:

  • Error rate for the release tag vs the pre-launch baseline (same window length before launch).
  • New issues first-seen after the release tag, sorted by event count and affected users; note severity.
  • Crash-free users % (mobile) for the release.
  • Release adoption % — what fraction of users are on this release. Below minAdoptionForSignal, treat metrics as low-confidence (don't recommend rollback off 11 sessions).
  • Perf (Sentry Performance / APM) vs each behavior's perfBudget.

If no measurement source is connected, do not fabricate a verdict: emit hold with a signal explaining the guard is blind here and the human must watch dashboards manually (mirrors launch-report's "unmeasured" honesty).

3. Form the recommendation

Output a single verdict object (schema-checked by scripts/validate.mjs --check-guard):

{
  "verdict": "proceed | hold | recommend-rollback",
  "reason": "one-paragraph defensible summary tied to the signals",
  "signals": [
    { "name": "error-rate", "observed": "4.2× baseline", "budget": "≤3×", "status": "breach" },
    { "name": "crash-free", "observed": "99.6%", "budget": "≥99.0%", "status": "ok" },
    { "name": "adoption", "observed": "18%", "budget": "≥5%", "status": "ok" }
  ],
  "generatedAt": "<ISO>"
}

Rubric:

  • proceed — all sampled signals ok, adoption high enough to trust them. Safe to continue ramping.
  • hold — at least one warning (approaching but not past budget), OR adoption too low to be confident, OR partial data. Pause further ramp, keep current %, investigate. Not an emergency.
  • recommend-rollback — a clear breach: error rate past the multiplier, crash-free below floor, or a new blocker-class issue with real volume. The feature is hurting users; recommend reverting to the last good state (flag off, or redeploy previous release).

3b. Recommend the next ramp step (the canary "orchestrator")

The system does not advance the flag — you tell the human what the next step is and they flip it. Read the rolloutPlan (contract frontmatter, else repos.yml conventions.rolloutPlan) and the contract's current rollout percent (currentRolloutPercent, default 1 once canaryStartedAt is set). Add a recommendedAction string to the verdict:

  • On proceed, if the current stage has baked at least its holdHours: "advance flag <name> 10% → 50% (next bake 8h)". If it hasn't baked long enough yet: "hold at 10% — N more hours of bake before advancing".
  • On proceed at the final 100% stage: "ramp complete — leave at 100%; launch-monitor takes over".
  • On hold: "hold at <current>% — investigate <signal> before advancing".
  • On recommend-rollback: "flip flag <name> OFF (or redeploy <previous tag>) — do not advance".

If there is no flag system / no rolloutPlan, set recommendedAction to "no staged ramp configured — this is a direct deploy; watch and revert manually if needed". Stamp currentRolloutPercent on the contract when the owner confirms they advanced it (or read it back from the flag system if the MCP exposes it).

recommend-rollback exits the validator with code 3 so the workflow can escalate loudly. Validate before posting:

node <plugin-root>/scripts/validate.mjs --check-guard <verdict.json>

4. Write the guard report

.manifest/contracts/<ID>.guard-<timestamp>.md with the verdict object, the signal table, and links to the top Sentry issues. Set guardVerdict: <verdict> and guardCheckedAt: <ISO> in the contract frontmatter so /status and the dashboards can show current health.

5. Escalate appropriately

  • proceed — reply in the contract's Slack thread, one line. No noise.
  • hold — reply in the thread with the warning signals + the suggested action (hold the ramp, investigate X). Tag the contract owner.
  • recommend-rollback — reply in the thread AND post a brief top-level Slack alert (the urgent-alert exception), tagging the owner, with: the breached signal, the recommended action (flip flag <name> off / redeploy <previous tag>), and a link to the guard report. Do not perform the rollback — ask the owner to confirm and do it. If the repo has no flag system, say the rollback is a manual revert/redeploy.

What you must never do

  • Never flip a flag, change rollout %, redeploy, or revert. You recommend; a human acts. (Modifying production rollout state is an explicit-permission action — out of scope for an automated guard.)
  • Never recommend rollback off statistically meaningless data — respect minAdoptionForSignal.
  • Never claim health you didn't measure — hold with an honest "blind here" signal beats a false proceed.
  • Never bury a breach in soft language. If it breached, say recommend-rollback plainly.
  • Don't double-report: one verdict per run; let the cadence repeat it.

Slack threading

Replies go in the contract's thread (thread_ts: <contract.slackThreadTs>, channel <contract.slackChannel>). recommend-rollback and canary auto-pause also post the brief top-level alert. (See reference/CONTRACT-FORMAT.md.)

Keep looking

Skills are one crate of 627,801. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.