Install
$ agentstack add skill-growthbook-skills-experiment-stop ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
experiment-stop
Stop a running experiment, optionally declaring a winning variation and ramping it to all eligible traffic via a temporary rollout. The endpoint is POST /api/v1/experiments//stop (a dedicated endpoint, not the generic update). All variation references are variation ID strings like var_abc123, not 0-based integer indexes.
All API calls go through the bundled helper: ${CLAUDE_PLUGIN_ROOT}/scripts/gb-call. It needs GB_API_KEY — set in your shell, or written to ~/.config/growthbook/.env by /growthbook:setup. If unset or invalid, gb-call's error message points back at /growthbook:setup.
Workflow
- Fetch the current experiment.
``bash gb-call GET /api/v1/experiments/ ``
Check the status field. Only running experiments should be stopped via this skill. If status === "draft", the experiment hasn't started — the user wants to delete it, not stop it (different operation). If status === "stopped", it's already done.
Also capture the type field. If type === "multi-armed-bandit", halt and tell the user this skill targets standard A/B tests; bandits have their own lifecycle (stop is similar but interpretation and rollout differ — recommend they review in the UI before scripting).
- Show the user the variations table. Surface the variations as the API records them — capture each one's
variationId(the string ID, e.g.var_treatment_a) andname. The user picks by the variation ID string, not by index:
``` The experiment has these variations: varcontrol 0: Control — (lift: baseline, users: N) vartreatmenta 1: Treatment A — (lift: +2.3%, users: N) vartreatment_b 2: Treatment B — (lift: -0.8%, users: N)
Which variation should ship? Reply with the variation ID (e.g. vartreatmenta), or say "no winner" to stop without declaring. ```
If the user has not already run experiment-analyze, suggest doing that first so the decision is informed.
- Decide on temporary rollout. If the user has a winner and wants to ship now, offer the temporary-rollout path:
> "Want me to also enable a temporary rollout? That keeps this experiment in the SDK payload and forces 100% of eligible traffic to `. It's the cleanest 'ship the winner' option — the linked feature flag's rule stays in place but routes everyone to the winner. You can toggle it off later with modify-temporary-rollout or clean up the rule via flag-targeting`."
If yes, set enableTemporaryRollout: true and releasedVariationId: in the payload. If no, the experiment stops but you leave the flag alone — surface that the user will need to clean up the experiment-ref rule manually.
- Confirm intent. Restate the action in plain English:
> "Stopping experiment '', declaring variation var_treatment_a (Treatment A) as the winner, and enabling temporary rollout to ship it to 100% of eligible traffic."
Get explicit confirmation before posting. Stopping itself is reversible (you can restart), but declaring a winner and enabling a rollout produces downstream signals — don't do it on a hunch.
- Build the payload. The body is flat; there is no nested
resultSummary.
Stop without a declared winner:
``json { "results": "inconclusive" } ``
Stop with a declared winner, no rollout:
``json { "results": "won", "winnerVariationId": "", "analysis": "" } ``
Stop with a declared winner and ship via temporary rollout:
``json { "results": "won", "winnerVariationId": "", "releasedVariationId": "", "enableTemporaryRollout": true, "analysis": "" } ``
Field reference:
results— required. One of"won","lost","inconclusive","dnf"(did not finish).winnerVariationId— string variation ID (e.g.var_abc123). Required whenresults === "won"and the experiment has multiple test variations.releasedVariationId— string variation ID. Required whenenableTemporaryRollout: true. Usually equalswinnerVariationId.enableTemporaryRollout— boolean. Keeps the stopped experiment in the SDK payload and forces traffic to thereleasedVariationId.analysis— markdown summary shown on the experiment results page.reason— optional reason text stored on the latest phase metadata.dateEnded— optional ISO datetime; defaults to now.
- Post the update.
``bash echo '' | gb-call POST /api/v1/experiments//stop - ``
- State what happens next, and link to the experiment. Tell the user:
- The experiment is now stopped; no more traffic accumulates against the experiment.
- If a winner was declared, the variation ID that "won."
- Direct UI link so they can verify the stopped state, the recorded
analysis, and the rollout status:
`` /experiment/ ` Derive from GBAPIURL by swapping api. → app. (matches experiment-launch's convention; on the default cloud host this produces https://app.growthbook.io`). What happens to the flag? Surface the disposition clearly based on what was sent:
With temporary rollout (enableTemporaryRollout: true): the winner is live — traffic is already routed to it via the existing experiment-ref rule. No further action required until the team decides to clean up the flag (which can happen days or weeks later). When ready:
- Convert to permanent rule: remove the experiment-ref rule via
flag-rules, add a permanent force rule for the winner viaflag-targeting. - Clean up entirely: if the feature will be inlined in code, use
flag-cleanupto walk through code cleanup and archive/delete the flag. - Roll back: turn off the temporary rollout first (
echo '{"enableTemporaryRollout": false}' | gb-call POST /api/v1/experiments//modify-temporary-rollout -), then remove the experiment-ref rule viaflag-rules.
Without temporary rollout: the experiment-ref rule is still on the flag, routing traffic to a stopped experiment (users will get the control value). The flag needs attention:
- Option A — Ship the winner: set
defaultValueto the winner's value viaflag-default-value, then remove the experiment-ref rule viaflag-rules. Or useflag-targetingto add a permanent force rule serving the winner, then remove the experiment-ref rule. - Option B — Roll back: the flag's default value already serves the control — just remove the experiment-ref rule via
flag-rulesand the flag returns to its pre-experiment state. - Option C — Full cleanup: use
flag-cleanupto inline the value in code and archive/delete the flag.
Guardrails
winnerVariationIdis a variation ID string (e.g.var_abc123), not an integer index, not a name, not the variation'skey. Get this wrong and the request 400s or the wrong variation is recorded as the winner.- The endpoint is
POST /api/v1/experiments//stop, notPOST /api/v1/experiments/. The body shape is flat — there is noresultSummarywrapper. The generic update endpoint exists but takes different fields; use the dedicated stop endpoint here. - Never declare a winner the user didn't pick. Even if the results look obvious, force the user to choose the variation ID. Surface results, but don't pre-fill. Skill convention, not GrowthBook policy: the API accepts any variation ID as
winnerVariationId; the safety is enforced here, not server-side. - Don't stop drafts. A
draftexperiment isn't running — what the user wants there isDELETE /api/v1/experiments/(separate skill, not covered here). Surface the confusion if they ask to stop a draft. - Don't stop already-stopped experiments. The API may accept the call but it's effectively a no-op; tell the user it's already done. To change the results metadata on an already-stopped experiment, post again with the new
results/winnerVariationId/analysis. - Bandits are out of scope.
type === "multi-armed-bandit"experiments need different handling — halt and tell the user. releasedVariationIdis required whenenableTemporaryRollout: true. The API rejects the combination otherwise. They're usually the same aswinnerVariationIdbut don't have to be — e.g., a "lost" result that rolls everyone back to control would setreleasedVariationId:withresults: "lost".- Always remind about the linked flag. Stopping the experiment does not remove the
experiment-refrule from the linked flag. Without a temporary rollout, the flag keeps routing to a stale experiment until the user cleans the rule up. analysisshould explain the decision in plain English (markdown). Future readers (including future-self) will want context. Don't leave it blank when declaring a winner.- Run
experiment-analyzefirst if the user hasn't. Stopping based on a glance at the dashboard is a common mistake — interim numbers can flip, and the data-quality checks inexperiment-analyzecan flag results that look conclusive but aren't.
Endpoints used
GET /api/v1/experiments/— fetch state, variations, andtypePOST /api/v1/experiments//stop— stop and optionally declare a winner + temporary rolloutPOST /api/v1/experiments//modify-temporary-rollout— toggle the temporary rollout off (or on) after stopping, without re-running this skill
Handoffs
experiment-analyze— run first if the user wants to interpret results before deciding.flag-rules— remove the experiment-ref rule after stopping (always needed eventually).flag-targeting— add a permanent force rule serving the winner value (replaces the experiment-ref rule).flag-default-value— set the flag's default to the winner value when shipping without a targeting rule.flag-cleanup— if the feature is fully shipped and the flag should be removed from code and archived.experiment-designandexperiment-launch— for the next test if this one informed a follow-up.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: growthbook
- Source: growthbook/skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.