Skip to content

feat(feature-flags): add the wizard feature-flags command - #1322

Open
johncwaters wants to merge 7 commits into
mainfrom
johnw/feature-flags-command
Open

johncwaters wants to merge 7 commits into
mainfrom
johnw/feature-flags-command

Conversation

@johncwaters

@johncwaters johncwaters commented Sep 23, 2026 •

Copy link
Copy Markdown

Problem

Feedback wanted: polish. Feature complete, with unit tests and workbench e2e grading. The companion context-mill and wizard-workbench PRs are merged.

Setting up a first feature flag means creating it in PostHog, installing the right SDKs, and evaluating it correctly: once per request, with the identified distinct id, the key in one place, and the evaluation reported back. The wizard has no command for this.

Companion PRs (merged): context-mill (PostHog/context-mill#405) and wizard-workbench (PostHog/wizard-workbench#4136).

Changes

  • wizard feature-flags: a native command running an orchestrator flow with bundled prompts (seed, install, init, create-flag, evaluate, report).
  • The seed decides which sides the app has, backend and/or frontend, and passes them to every task as a sides input. A side counts only when the app already has code there: the frontend is JavaScript the app owns and loads (inline, as files, or through import maps or Vite), so server-rendered templates that load none are backend-only.
  • create-flag makes one example flag per side, wizard-example-backend-flag and wizard-example-frontend-flag, inactive at 0% rollout. An existing flag with the same key is reused unchanged.
  • evaluate adds one evaluation per flag on its own side (server SDK for the backend flag, client SDK for the frontend flag), with the keys in a constants module and the same distinct id on both sides. It loads the integration-v2-feature-flags-step skill from context-mill for the framework's posthog.com flag docs; the instructions stay in the prompt.
  • report writes posthog-feature-flags-report.md, then offers one verify-flag check for recent $feature_flag_called events.
  • TUI: a feature-flags-intro screen, a run-screen learn deck explaining what flags are (gating code, gradual rollout, targeting, the off switch, experiments) and what the run sets up, and sidebar tips on payloads, local evaluation, and experiments. The intro offers only Cancel while detection runs, when no framework is detected, or when the framework version is unsupported, so a run never reaches login without a supported framework.
  • The orchestrator can run a program's bundled prompts without fetching the agent menu (agentPrompts), and the command gets its own OAuth scope list (feature_flag:read, feature_flag:write), registry entry, and e2e profile.

Before merge: feature-flags must be added to WIZARD_GATEWAY_PROGRAM_IDS (PostHog/charts#16288, held in draft so the program cannot mint before it ships), and a gateway operator must add a wizard:feature-flags budget row. Until then the gateway refuses the mint with program_unknown. Two e2e runs cost $1.05 and $0.93, under every posture cap, so the program needs no cap entry of its own.

Test plan

  • pnpm typecheck and pnpm test pass. cli.test.ts and health-checks.test.ts time out when the machine is loaded and pass when run alone; this PR does not touch them.
  • Ran through wizard-workbench --e2e against a test project, starting with no example flags. Next.js passed with both flags created inactive at 0% and each evaluated once on its own side. Django passed with only the backend flag, because its templates contain no scripts. Each run took about 5 minutes, using a gateway token minted locally. A Next.js rerun with the context-mill skill trimmed to docs only also passed. After tightening the side rule: three Django runs were backend-only, Next.js got both sides, and a Rails import-map app (workbench rails/fizzy) got both sides, with the SDK gems in the Gemfile, the snippet in the layout, and no npm. After rebasing onto the refactor's agent layer, both apps passed again with the flags deleted first: Next.js created both flags, Django only the backend flag.
  • After rebasing onto main at e63b0ad, with both example flags deleted first, wizard-workbench pnpm wizard-ci feature-flags/<app> --e2e passed every check: next-js/15-app-router-saas created both flags inactive at 0% with the keys in lib/posthog-flags.ts, and django/django3-saas created only the backend flag with the key in config/posthog_feature_flags.py.
  • Ran the interactive TUI once on Next.js, and checked the new intro, learn deck, and tips in the e2e run-screen snapshots.

LLM context

Written with Claude Code.

@github-actions

Copy link
Copy Markdown

🧙 Wizard CI

Run the Wizard CI and test your changes against wizard-workbench example apps by replying with a GitHub comment using one of the following commands:

Test all apps:

  • /wizard-ci all

Test all apps in a directory:

  • /wizard-ci ai-observability
  • /wizard-ci basic-integration
  • /wizard-ci mcp-analytics
  • /wizard-ci replay-vision
  • /wizard-ci revenue
  • /wizard-ci self-driving
  • /wizard-ci warehouse
  • /wizard-ci warehouse-seeded

Test an individual app:

  • /wizard-ci ai-observability/anthropic
  • /wizard-ci ai-observability/google-adk
  • /wizard-ci ai-observability/groq
Show more apps
  • /wizard-ci ai-observability/manual-capture
  • /wizard-ci ai-observability/openai
  • /wizard-ci ai-observability/openai-agents
  • /wizard-ci ai-observability/opentelemetry
  • /wizard-ci ai-observability/vercel-ai
  • /wizard-ci basic-integration/android
  • /wizard-ci basic-integration/angular
  • /wizard-ci basic-integration/astro
  • /wizard-ci basic-integration/django
  • /wizard-ci basic-integration/fastapi
  • /wizard-ci basic-integration/flask
  • /wizard-ci basic-integration/flutter
  • /wizard-ci basic-integration/javascript-node
  • /wizard-ci basic-integration/javascript-web
  • /wizard-ci basic-integration/laravel
  • /wizard-ci basic-integration/next-js
  • /wizard-ci basic-integration/nuxt
  • /wizard-ci basic-integration/python
  • /wizard-ci basic-integration/rails
  • /wizard-ci basic-integration/react-native
  • /wizard-ci basic-integration/react-router
  • /wizard-ci basic-integration/sveltekit
  • /wizard-ci basic-integration/swift
  • /wizard-ci basic-integration/tanstack-router
  • /wizard-ci basic-integration/tanstack-start
  • /wizard-ci basic-integration/vue
  • /wizard-ci mcp-analytics/custom-dispatcher
  • /wizard-ci mcp-analytics/typescript-sdk
  • /wizard-ci replay-vision/javascript-node
  • /wizard-ci replay-vision/next-js
  • /wizard-ci replay-vision/react-vite
  • /wizard-ci revenue/stripe
  • /wizard-ci self-driving/astro
  • /wizard-ci self-driving/fastapi
  • /wizard-ci self-driving/nuxt
  • /wizard-ci self-driving/react-router
  • /wizard-ci self-driving/sveltekit
  • /wizard-ci warehouse/monorepo-env
  • /wizard-ci warehouse/multi-source-next
  • /wizard-ci warehouse/stripe-node
  • /wizard-ci warehouse/zero-source
  • /wizard-ci warehouse-seeded/next-stripe
  • /wizard-ci warehouse-seeded/next-stripe-declined

Test against a Context Mill branch:

  • /wizard-ci all context-mill:my-branch

Add context-mill:<branch> to any command above to pin the Context Mill branch. It defaults to main.

Results will be posted here when complete.

@johncwaters
johncwaters force-pushed the johnw/feature-flags-command branch from adab746 to f3eb515 Compare September 23, 2026 22:24
@johncwaters
johncwaters force-pushed the johnw/feature-flags-command branch 2 times, most recently from 34213e2 to b70460a Compare September 24, 2026 18:55
@johncwaters
johncwaters marked this pull request as ready for review September 24, 2026 20:38
@johncwaters
johncwaters requested a review from a team as a code owner September 24, 2026 20:38
Adds `wizard feature-flags`: an orchestrator flow with bundled prompts that creates one example flag per side of the app (backend, frontend), inactive at 0%, evaluates each once on its own side, and writes a report with an optional check that the evaluations reach PostHog.
The feature-flags program gets its own intro screen, a run-screen learn deck explaining what flags are and what the run sets up, and sidebar tips, in place of the generic agent-skill screens.
Give feature-flags its own OAuth scope list and share the step skill id
between the evaluate prompt and the intro screen.
A Django run whose templates load no app JavaScript added a PostHog
snippet to host the frontend flag. The seed now defines the frontend by
JavaScript the app owns and loads, including through import maps or
Vite, and names script-less server templates as backend-only.
@johncwaters
johncwaters force-pushed the johnw/feature-flags-command branch from b70460a to b977652 Compare September 25, 2026 15:07
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