# Flag Schedule

> Add a timed activation window to a GrowthBook feature flag rule — automatically enable it at a start time and/or disable it at an end time. Use when the user says "turn this on at 9am", "schedule the flag to go live Friday at noon", "disable the rule after the sale ends", "set an end date on this rule", "run this rule during the promotion window", or "time-gate this rule". Applies to force and ro…

- **Type:** Skill
- **Install:** `agentstack add skill-growthbook-skills-flag-schedule`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [growthbook](https://agentstack.voostack.com/s/growthbook)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [growthbook](https://github.com/growthbook)
- **Source:** https://github.com/growthbook/skills/tree/main/skills/flag-schedule

## Install

```sh
agentstack add skill-growthbook-skills-flag-schedule
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# flag-schedule

Add a timed activation window to a GrowthBook feature flag rule. A scheduled rule activates automatically at a start time and/or deactivates automatically at an end time, without requiring a manual publish each time.

Scheduling applies to `force` and `rollout` rule types. It does not apply to `experiment-ref` or `safe-rollout` rules.

All API calls go through the bundled helper: `${CLAUDE_PLUGIN_ROOT}/scripts/gb-call`. It needs `GB_API_KEY` set in env or written to `~/.config/growthbook/.env` by `/growthbook:setup`.

## How scheduling works

GrowthBook supports two scheduling mechanisms on rules:

**Simple schedule** (`schedule` field on rule creation) — the preferred approach. Specify `startDate` and/or `endDate` as ISO 8601 timestamps. The server sets up the underlying `scheduleRules` automatically.

**Legacy `scheduleRules`** — a 2-element array `[start, end]` where each element is `{ timestamp: "", enabled:  }`. Still accepted by the API; the simple `schedule` field is cleaner for new rules.

## How the OFF state works

A scheduled rule is a **rule-level** mechanism, not a flag-level toggle. When the rule is inactive (outside its window), it is skipped in evaluation — the flag falls through to whatever comes next in rule order, ultimately landing on `defaultValue`.

This means:
- The rule should serve the **ON value** (`"true"` for a boolean flag) during the active window.
- `defaultValue` is the **OFF state** when no rules match. Verify it is set correctly before publishing.
- The scheduled rule should be **last in the rules array** (for new rules) so nothing below it can accidentally serve the ON value when the schedule is inactive. For existing rules, check what's below — anything serving a matching value below this rule would fire when the schedule is off.

## Workflow

### Path A — Create a new rule with a schedule

1. **Fetch the flag:**
   ```bash
   gb-call GET /api/v2/features/
   ```
   Capture `valueType`, `defaultValue`, `environmentSettings`, and current rules.

   **Check the target environment is enabled.** If `environmentSettings..enabled` is `false`, the scheduled rule will silently do nothing — warn the user:
   > "The flag is currently disabled in ``. The scheduled rule won't fire until the flag is enabled. Enable it via flag-toggle (it can land in the same draft as this change)."

   **Check `defaultValue` is the OFF state.** For a boolean flag, it should be `"false"`. If it isn't, warn the user:
   > "When the scheduled rule is inactive, the flag will return ``. Is that the intended off-state? If not, update it first via flag-default-value."

   **Check rule order.** The new rule will append to the bottom. If existing rules above it serve the ON value unconditionally to all users, they'll fire before the schedule can — warn the user and suggest reviewing rule order via flag-rules after adding.

2. **Collect the schedule times:**

   Ask for:
   - Start time (or `null` for "immediately")
   - End time (or `null` for "never expires")
   - The user's timezone, unless they explicitly specify one in the time string

   The API accepts ISO 8601 with timezone offset — use the user's local timezone directly, no UTC conversion needed. Use the correct offset for the date in question (account for daylight saving time):
   ```
   "tomorrow at midnight" in US Eastern (summer, EDT) → "2026-05-30T00:00:00-04:00"
   "right after Christmas" in US Eastern (winter, EST) → "2026-12-26T00:00:00-05:00"
   ```

   For natural-language times, use `currentDate` from context to anchor relative dates ("tomorrow", "next Friday"). For ambiguous phrases like "right after Christmas" or "end of the sale", confirm the exact datetime with the user before proceeding. Always confirm the full resolved datetime back to the user before building the payload.

3. **Build the payload and post:**

   Pre-validate `value` against the flag's `valueType` (captured in step 1): boolean flags must use `"true"`/`"false"`, number flags must parse as a number, json flags must be valid JSON.

   ```bash
   echo '{
     "rule": {
       "type": "force",
       "value": "",
       "description": "",
       "enabled": true,
       "allEnvironments": false,
       "environments": [""]
     },
     "schedule": {
       "startDate": "2026-05-30T00:00:00-05:00",
       "endDate": "2026-12-26T00:00:00-05:00"
     }
   }' | gb-call POST /api/v2/features//revisions/new/rules -
   ```

   Omit `startDate` or `endDate` if no bound on that side.

4. Capture the returned `version`. Hand off to flag-publish.

### Path B — Add a schedule to an existing rule

1. **Fetch the flag and identify the rule:**
   ```bash
   gb-call GET /api/v2/features/
   ```
   Show the rules list. Get the rule `id` (UUID) the user wants to schedule. Note the rule's current position in the array — if it's not last, check whether rules below it would serve an unintended value when this schedule is inactive.

2. **Collect the schedule times** (same as Path A step 2).

3. **Build the scheduleRules patch:**
   ```json
   {
     "scheduleRules": [
       { "timestamp": "2026-05-30T00:00:00-05:00", "enabled": true },
       { "timestamp": "2026-12-26T00:00:00-05:00", "enabled": false }
     ],
     "scheduleType": "schedule"
   }
   ```
   - Element 0: the start event (`enabled: true` — rule turns on at this time)
   - Element 1: the end event (`enabled: false` — rule turns off at this time)
   - Use `null` for a timestamp to omit that bound (open-ended start or end)
   - `scheduleType` must be `"schedule"`

4. **Apply the patch:**
   ```bash
   echo '' | gb-call PUT /api/v2/features//revisions/new/rules/ -
   ```

5. Capture the returned `version`. Hand off to flag-publish.

### Path C — Remove a schedule from a rule

```bash
echo '{
  "scheduleRules": [
    { "timestamp": null, "enabled": true },
    { "timestamp": null, "enabled": false }
  ],
  "scheduleType": "none"
}' | gb-call PUT /api/v2/features//revisions/new/rules/ -
```

Setting all timestamps to `null` and `scheduleType: "none"` clears the schedule. The rule becomes always-active (subject to its `enabled` field and conditions).

## Guardrails

- **Draft version threading.** If a version number is already in context from a previous write skill in this session, use it explicitly (e.g. `.../revisions/42/rules`) instead of `new`. This keeps all changes in the same draft. Fall back to `new` when starting fresh.
- **The OFF state is `defaultValue`, not a toggle.** Scheduling works at the rule level — outside the active window the rule is skipped and the flag falls through to `defaultValue`. Always verify `defaultValue` is the intended off state before publishing.
- **Place new scheduled rules last.** Rules evaluate top-to-bottom; a scheduled rule that's inactive is simply skipped. If another rule below it serves the ON value unconditionally, that rule fires during the inactive period. For new rules, last position is safest.
- **The API accepts ISO 8601 with timezone offset.** Send times in the user's local timezone using the offset form: `"2026-12-26T00:00:00-05:00"`. No UTC conversion needed. Confirm the resolved datetime with the user before building the payload — never silently assume a timezone.
- **Resolve natural-language times explicitly.** Use `currentDate` from context for relative dates ("tomorrow", "next Friday"). For ambiguous phrases ("right after Christmas", "end of the sale"), confirm the exact date and time with the user before proceeding.
- **`scheduleRules` is a 2-element array.** Element 0 = start event (`enabled: true`), element 1 = end event (`enabled: false`). The server enforces this shape — it is not a list of arbitrary events.
- **Use `schedule` field for new rules, `scheduleRules` for patching existing ones.**
- **Scheduled rules must have `enabled: true`.** The schedule controls when the rule is active within the evaluation cycle, but `enabled: false` on the rule overrides the schedule entirely.
- **Publishing activates the schedule.** If publish is delayed by approvals and the start time passes before the revision goes live, the rule will activate immediately on publish rather than at the scheduled time.
- **For multi-step progressive rollouts, use flag-ramp.** This skill handles on/off windows only.

## Endpoints used

- `GET /api/v2/features/:id` — fetch flag and current rules
- `POST /api/v2/features/:id/revisions/new/rules` — create rule with `schedule` field (body includes `rule` + `schedule`)
- `PUT /api/v2/features/:id/revisions/new/rules/:ruleId` — patch existing rule's `scheduleRules` and `scheduleType`

## Handoffs

- `flag-targeting` — to build the rule's targeting conditions alongside the schedule
- `flag-ramp` — for multi-step progressive rollouts with intervals between coverage increases
- `flag-rules` — to reorder rules after adding a scheduled rule
- `flag-publish` — to publish the draft

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [growthbook](https://github.com/growthbook)
- **Source:** [growthbook/skills](https://github.com/growthbook/skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-growthbook-skills-flag-schedule
- Seller: https://agentstack.voostack.com/s/growthbook
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
