Agent skill

Verifier Web

by polarsource in polarsource/polar

Evidence-capture protocol for verifying web/dashboard/backoffice/checkout changes in the Polar local stack by driving the real UI with Playwright.

MITAuto-check: notesData & Analytics

Install Verifier Web

skills CLI
$ npx skills add polarsource/polar --skill verifier-web -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install polarsource/polar verifier-web --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/polarsource/polar.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/verifier-web .claude/skills/verifier-web && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
verifier-web
GitHub stars
10k
Token cost
~3k tokens
SKILL.md length
1,294 words
Files
1
Skills in repo
18
Repo updated
First seen
Licence
MIT

At a glance

Evidence-capture protocol for verifying web/dashboard/backoffice/checkout changes in the Polar local stack by driving the real UI with Playwright.

  • Works in 3 steps: Bring up the stack → Log in (dashboard + backoffice share one… → Purchase end-to-end (live Stripe test…
  • Tasks that involve DataFrames
  • SKILL.md covers When to use, Tooling, 1. Bring up the stack and 2. Log in (dashboard +…, plus 3 more sections
  • Calls curl, docker and uv; needs POLAR_STRIPE_SECRET_KEY and POLAR_STRIPE_PUBLISHABLE_KEY

What it does

Verifier Web is an agent skill from polarsource/polar. Evidence-capture protocol for verifying web/dashboard/backoffice/checkout changes in the Polar local stack by driving the real UI with Playwright. Auto-discovered by the built-in /verify skill; can also be invoked directly. Brings up the Docker stack, logs in via the real email-OTP flow, and exercises flows end-to-end (including a live Stripe checkout) capturing screenshots as evidence.

Its SKILL.md is about 3k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Data & Analytics, covering DataFrames, Browser testing and End-to-end testing. It works with Stripe, Docker and Playwright. The repository describes itself as: Polar — A billing platform for the intelligence era. The licence is MIT.

When your agent uses it

  • Tasks that involve DataFrames
  • Tasks that involve Browser testing
  • Tasks that involve End-to-end testing

Example prompts

  • “/verifier-web”

Requirements

  • Python 3
  • Docker
  • A credential in POLAR_STRIPE_SECRET_KEY
  • A credential in POLAR_STRIPE_PUBLISHABLE_KEY

Workflow steps

3 steps, taken from the step headings in SKILL.md.

  1. Bring up the stack
  2. Log in (dashboard + backoffice share one cookie)
  3. Purchase end-to-end (live Stripe test mode)

What it can do on your machine

Read from SKILL.md and the folder at commit 599c727. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • curl
    • docker
    • uv
    • stripe

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Links to these hosts (documentation or services it may open):

    • dashboard.stripe.com
    • docs.stripe.com

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names these keys or tokens, usually read from environment variables:

    • POLAR_STRIPE_SECRET_KEY
    • POLAR_STRIPE_PUBLISHABLE_KEY
    • NEXT_PUBLIC_STRIPE_KEY
    • POLAR_STRIPE_WEBHOOK_SECRET
    • POLAR_STRIPE_CONNECT_WEBHOOK_SECRET

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Verifier Web loads about 3k tokens when it runs. Until then it costs about 101 tokens; SKILL.md has 1,294 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~101
When it runs · the whole SKILL.md, loaded when a task matches
~3k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check: notes

The automated check noted patterns worth knowing about, such as sudo or a known installer.

  • NoteMentions a .env fileSKILL.md:138
    each worktree's `server/.env`. So you don't redo Stripe setup per worktree —
  • NoteMentions a .env fileSKILL.md:154
    set them in the central file (or `server/.env`) and
  • NoteMentions a .env fileSKILL.md:265
    ed` runs on the **host** against `server/.env`

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from polarsource/polar at commit 599c727, republished under its MIT licence (© polarsource). 1,294 words, ~2,967 tokens.

Download SKILL.mdSave it as .claude/skills/verifier-web/SKILL.md (or your agent's skills folder).
name
verifier-web
description
Evidence-capture protocol for verifying web/dashboard/backoffice/checkout changes in the Polar local stack by driving the real UI with Playwright. Auto-discovered by the built-in /verify skill; can also be invoked directly. Brings up the Docker stack, logs in via the real email-OTP flow, and exercises flows end-to-end (including a live Stripe checkout) capturing screenshots as evidence.
license
MIT
metadata.author
polar
metadata.version
1.0.0

Web Verifier (Polar)

The handle is the browser. The evidence is screenshots + the resulting DB/backoffice state. This skill is the repo's replay protocol for any change that a user — human or programmatic — meets through the web UI: the dashboard, the checkout, or the backoffice.

Use the local-environment skill for all stack mechanics (start/stop/logs/instances). This skill adds the browser-driving and auth/payment recipe on top.

When to use

  • Verifying a dashboard, checkout, or backoffice change.
  • Confirming login works, or a flow that requires being logged in.
  • Proving a purchase / subscription path end-to-end against live Stripe (test mode).

For CLI/API/library changes, use the built-in /verify surfaces instead — this skill is for pixels.

Tooling

Drive the browser with the Playwright MCP (mcp__playwright__*). Prefer browser_snapshot (accessibility tree, gives refs) over screenshots for acting; use browser_take_screenshot for evidence. Read backend state with dev docker exec db psql and docker logs.

1. Bring up the stack

bash
dev docker ps          # allocates/detects this worktree's instance number N
dev docker up -d       # build + migrate + seed on first run (several minutes)

dev docker up prints the authoritative ports — always read them from its output, do not compute them. They look like:

API:  http://localhost:81NN
Web:  http://localhost:31NN

(N is the instance; e.g. instance 7 → API :8107, Web :3107. Container names are polar-app-<N>-api-1, -web-1, -worker-1; DB is polar_dev_<N>.)

Poll readiness before driving anything:

bash
for i in $(seq 1 60); do
  a=$(curl -s -o /dev/null -w '%{http_code}' http://localhost:81NN/healthz)
  w=$(curl -s -o /dev/null -w '%{http_code}' http://localhost:31NN)
  # web may answer 200/307/308 (Next.js dev redirects/compiles on first hit)
  [ "$a" = 200 ] && [ "$w" -ge 200 ] && [ "$w" -lt 400 ] && break; sleep 5
done

Log in through the real email-OTP flow. The backoffice at http://localhost:81NN/backoffice/ uses the same user-session cookie, so logging into the dashboard authenticates the backoffice too.

  1. browser_navigate → http://localhost:31NN/auth (the nav "Login" link is hidden; go to /auth directly. /login 404s.)
  2. Type admin@polar.sh into the Email field, click Sign in with email. The seed account admin@polar.sh owns admin-org (approved, payout account, products) — go straight to checkout testing, no onboarding.
  3. The page advances to /auth/email-otp. Read the code from the api logs:
    bash
    docker logs --since 60s polar-app-<N>-api-1 2>&1 | grep -A1 "LOGIN CODE"
  4. Type the 6-character code (uppercase letters + digits, e.g. C9YLIF) → lands on /dashboard/admin-org.
  5. Backoffice: browser_navigate → http://localhost:81NN/backoffice/.

The backoffice needs compiled assets (Tailwind/DaisyUI → static/styles.css + scripts.js). On a clean start these are often not built yet — the backoffice then renders unstyled and /backoffice/static/styles.css + scripts.js 404 (served as application/json). Build them once:

bash
cd server && uv run task backoffice

The output lands in server/polar/backoffice/static/ on the host, which is mounted into the api container — it's picked up live, no recreate needed. (dev docker up has a "Building backoffice assets" step, but don't rely on it having run; check that the backoffice is styled and rebuild if not.)

Login through the browser requires the auth-session cookie domain to match the host the frontend uses (localhost). This is set in dev/docker/docker-compose.dev.yml:

yaml
POLAR_USER_SESSION_COOKIE_DOMAIN: localhost
POLAR_AUTHENTICATION_SESSION_COOKIE_DOMAIN: localhost   # both must be present

If you see POST /v1/auth/email-otp/request → 401 "Invalid or missing authentication session token", the Set-Cookie from /auth/start is being dropped because its Domain= doesn't match the page host. Check:

bash
curl -si -X POST http://localhost:81NN/v1/auth/start \
  -H 'Origin: http://localhost:31NN' -H 'Content-Type: application/json' \
  -d '{"return_to":"/dashboard"}' | grep -i set-cookie

Domain=localhost → good. Domain=127.0.0.1 → the override above is missing; add it, then recreate the api (dev docker up -d api — a restart does NOT reload compose env). Do not fall back to minting/injecting a session cookie.

3. Purchase end-to-end (live Stripe test mode)

A real purchase needs (a) a valid Stripe sandbox key on api and worker, and (b) a webhook listener forwarding to the api. Order creation is async — the api 202s the webhook and the worker creates the order.

3a. Stripe account + keys

Use your own Stripe sandbox (https://dashboard.stripe.com/sandboxes). Never a live account, and never a shared team account — dev stripe refuses both. The Stripe CLI profile is always polar-sandbox.

Secrets are set up once and reused across worktrees. They live centrally in ~/.config/polar/secrets.env and dev/setup-environment propagates them into each worktree's server/.env. So you don't redo Stripe setup per worktree — populate the central file once. The one-step path:

bash
dev stripe --listen --port <api-port>   # <api-port> = the API port from `dev docker up`

This installs/logs-in the Stripe CLI if needed, writes the API keys + webhook secret into the central secrets file, propagates them, and starts the webhook listener (3b). If the CLI is already configured it skips straight to listening.

CLI test keys expire every 90 days. Symptom of an expired key: checkout sticks on "We are processing your order" and the worker/api logs show AuthenticationError: Expired API Key provided. Refresh with dev stripe, which detects the expired key and re-runs the link flow, then recreate services (3c).

If you ever set keys by hand, set them in the central file (or server/.env) and keep them on the same account: POLAR_STRIPE_SECRET_KEY (the secret key), POLAR_STRIPE_PUBLISHABLE_KEY and NEXT_PUBLIC_STRIPE_KEY (the publishable key — the browser tokenizes the card with it). pk and sk must belong to one account or the card tokenizes against one account while the backend charges another.

3b. Webhook listener

dev stripe --listen --port <api-port> starts it for you. To run it directly in the background with its output captured to a log you can grep later:

bash
stripe listen \
  --forward-to http://localhost:81NN/v1/integrations/stripe/webhook \
  --forward-connect-to http://localhost:81NN/v1/integrations/stripe/webhook-connect \
  > /tmp/stripe-listen.log 2>&1 &

(If you started it via dev stripe --listen instead, its events print in that command's terminal — redirect to a file as above if you want to grep them in 3e.)

It prints Your webhook signing secret is whsec_.... Both POLAR_STRIPE_WEBHOOK_SECRET and POLAR_STRIPE_CONNECT_WEBHOOK_SECRET must equal that secret. Leave the listener running in the background. If webhooks come back 400 (signature failure), the configured secret is stale — re-sync it to the value the listener prints.

Show full SKILL.md (478 more words)Show less
3c. Recreate ALL THREE services after any key change
bash
dev docker up -d api web worker

The worker is easy to forget — if it keeps a stale/expired key, the api will 202 the webhook but order creation fails silently and retries forever. Recreate api, web, and worker on every env change.

3d. Drive the checkout
  1. Find/make a checkout link for an admin-org product, then open its redirect to start a checkout session. The redirect token is the link's client_secret (the polar_cl_... value — not the UUID id):
    http://localhost:81NN/v1/checkout-links/<polar_cl_...>/redirect
    List it (qualify the column — both tables have id/client_secret):
    sql
    select cl.client_secret from checkout_links cl
      join organizations o on o.id = cl.organization_id
      where o.slug = 'admin-org' limit 1;
  2. Fill the form:
    • Email — real domain + tag, e.g. petru+verify-<flow>@polar.sh. .local and example.com are rejected by checkout email validation.
    • Card (inside the Stripe iframe): 4242 4242 4242 4242, exp 12 / 34, CVC 123.
    • Cardholder name, then Billing country (Radix combobox — click to open, click the option). Selecting United States reveals required address line1, city, state (Radix combobox), ZIP — fill all. React inputs need the native value-setter + an input event if you set them via browser_evaluate.
  3. Click Subscribe now / Pay. The page goes to …/confirmation showing "We are processing your order", then "Thank you for your order!".

Test cards (Stripe test mode; any future expiry, any 3-digit CVC, any ZIP):

OutcomeNumber
Success4242 4242 4242 4242
Requires 3DS / authentication4000 0027 6000 3184
Generic decline4000 0000 0000 0002
Insufficient funds decline4000 0000 0000 9995

Verify the unhappy paths too: a decline should surface an inline card error and create no order; a 3DS card should pop the authentication modal. Full list: https://docs.stripe.com/testing.

3e. Verify the result (don't trust the UI alone)
bash
# webhook delivery (expect charge.succeeded + payment_intent.succeeded → 202)
# from the listener log you captured in 3b:
grep -E 'POST|payment_intent|charge' /tmp/stripe-listen.log

# order + subscription created by the worker
dev docker exec db psql -U polar -d polar_dev_<N> -tc \
 "select o.status, o.net_amount_v2, c.email from orders o
   join customers c on c.id=o.customer_id
   where c.email='petru+verify-<flow>@polar.sh' order by o.created_at desc limit 1;"

Expect paid | 2000 | …. Also confirm it renders in backoffice Orders (/backoffice/orders/). Screenshot the confirmation page and the backoffice row.

Report

Follow the built-in /verify report format: Verdict (PASS/FAIL/BLOCKED/SKIP), Claim, Method, and numbered Steps where each step is one thing you did to the running app and what it showed — attach the screenshots. Test runs and typechecks are not steps. Note anything that made you pause (a slow poll, a stale-key retry, a confusing validation message) — that's the signal.

Gotchas seen in practice

  • Restart ≠ recreate. dev docker restart keeps the old compose env; use dev docker up -d <svc> to load env/key changes.
  • The api session is DB-backed, so recreating the api keeps you logged in.
  • dev stripe --listen refreshes the webhook secret whenever it writes new API keys, so switching sandbox propagates the new signing secret too. It leaves the two secrets alone when they already differ from each other — that means they came from dashboard endpoints, not the CLI listener.
  • dev seed runs on the host against server/.env (POLAR_POSTGRES_*), which is not the dockerized polar_dev_<N>. For a docker instance, seed inside the container instead: docker exec polar-app-<N>-api-1 sh -c 'cd /app/server && uv run python -m scripts.seeds_load'

© polarsource, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .agents/skills/verifier-web of polarsource/polar.

Open the folder on GitHubat commit 599c727

Compare with similar skills

Verifier Web next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Verifier Web compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Verifier Web this skillpolarsource/polar10k—~3kAutomated safety check: NotesMIT
E2Eopenathleteorg/openathlete100—~675Automated safety check: PassAGPL-3.0
Acarshub Tool Additionssdr-enthusiasts/docker-acarshub117—~707Automated safety check: PassGPL-3.0
Run Dashboard E2E Local ChangesBlackBeltTechnology/pi-agent-dashboard316—~1.3kAutomated safety check: PassMIT
E2E TestingOpenHands/OpenHands90k—~308Automated safety check: PassMIT
Dozzle Visual Snapshot Updateramir20/dozzle15k—~797Automated safety check: PassMIT

Similar skills

  • E2E

    openathleteorg/openathlete

    Run, debug or extend the OpenAthlete Playwright end-to-end tests, which exercise the production Docker images (API, worker, web, PostgreSQL, Redis) through the API and a real browser on desktop and…

    100 GitHub stars~675 tokensUpdated yesterday
    Testing & QAAuto-check passed
  • Acarshub Tool Additions

    sdr-enthusiasts/docker-acarshub

    Use ONLY when working in the docker-acarshub repository AND a task may require adding a system tool, npm package, or other dependency.

    117 GitHub stars~707 tokensUpdated 3 days ago
    DevOps & CloudAuto-check passed
  • Run Dashboard E2E Local Changes

    BlackBeltTechnology/pi-agent-dashboard

    Run Playwright E2E (tests/e2e/) against the docker/ all-in-one harness so it reflects LOCAL code changes, not a stale cached image.

    316 GitHub stars~1.3k tokensUpdated yesterday
    Testing & QAAuto-check passed
  • E2E Testing

    OpenHands/OpenHands

    This skill should be used when the user asks to "add an E2E test", "run live E2E", "run mock-LLM tests", "debug Playwright CI", "test the Docker image", or changes tests/e2e, Playwright configs, E2E…

    90k GitHub stars~308 tokensUpdated today
    Testing & QAAuto-check passed
  • Regenerates Playwright visual snapshots for Dozzle after an intentional UI change, running them through Docker Compose so filenames match the Linux CI platform.

    15k GitHub stars~797 tokensUpdated yesterday
    Testing & QAAuto-check passed
  • E2E

    sendou-ink/sendou.ink

    Run, debug, and manage Playwright e2e tests. An agent skill from sendou-ink/sendou.ink.

    297 GitHub stars~2.1k tokensUpdated today
    Testing & QAAuto-check: notes

More from polarsource/polar

All 18 skills in this repo
  • Polar Python SDK

    polarsource/polar

    Integrate Polar billing in server-side Python applications using the versioned Polar and PolarAsync clients.

    10k GitHub stars~1.8k tokensUpdated today
    Auto-check passed
  • Polar Typescript SDK

    polarsource/polar

    Integrate Polar billing in server-side TypeScript applications using the versioned createPolar and createPolarCore clients.

    10k GitHub stars~2k tokensUpdated today
    Auto-check passed
  • Adr Check

    polarsource/polar

    Check a code change against the repo's Accepted Architecture Decision Records (ADRs) in handbook/engineering/decisions/ and report violations with citations.

    10k GitHub stars~771 tokensUpdated today
    Auto-check passed
  • API Surface Review

    polarsource/polar

    Review changes to Polar's API contract — Pydantic schemas, FastAPI endpoints, OpenAPI output and the generated SDKs.

    10k GitHub stars~1.3k tokensUpdated today
    Auto-check passed
  • Billing Review

    polarsource/polar

    Review a diff that touches Polar's billing domain — subscriptions, cycles and crons, orders, billing entries, meters and usage, discounts, checkout, payments and dunning, refunds, disputes, payouts…

    10k GitHub stars~2.3k tokensUpdated today
    Auto-check passed
  • Interview Task

    polarsource/polar

    Prepare an interview task for a candidate, as part of our hiring process.

    10k GitHub stars~933 tokensUpdated today
    Auto-check passed

Questions about Verifier Web

What does Verifier Web do?

Evidence-capture protocol for verifying web/dashboard/backoffice/checkout changes in the Polar local stack by driving the real UI with Playwright. Verifier Web is an agent skill from polarsource/polar. Evidence-capture protocol for verifying web/dashboard/backoffice/checkout changes in the Polar local stack by driving the real UI with Playwright.

When should I use Verifier Web?

Verifier Web fits situations like: tasks that involve DataFrames; tasks that involve Browser testing; tasks that involve End-to-end testing.

How do I install Verifier Web in Claude Code?

Run `npx skills add polarsource/polar --skill verifier-web -a claude-code`. Or copy the skill folder (.agents/skills/verifier-web in polarsource/polar) into .claude/skills/verifier-web in your project. Claude Code loads it when a task matches its description.

How do I install Verifier Web in Codex?

Run `npx skills add polarsource/polar --skill verifier-web -a codex`. Or copy the skill folder (.agents/skills/verifier-web in polarsource/polar) into .agents/skills/verifier-web in your project. Codex loads it when a task matches its description.

Can I use Verifier Web in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add polarsource/polar --skill verifier-web -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/verifier-web, .gemini/skills/verifier-web, .github/skills/verifier-web and .opencode/skills/verifier-web in your project.

What does Verifier Web need to run?

Going by SKILL.md and its folder, Verifier Web needs the command-line tools its instructions call (curl, docker, uv and stripe) and credentials named POLAR_STRIPE_SECRET_KEY, POLAR_STRIPE_PUBLISHABLE_KEY, NEXT_PUBLIC_STRIPE_KEY and POLAR_STRIPE_WEBHOOK_SECRET. Our summary lists: Python 3; Docker; A credential in POLAR_STRIPE_SECRET_KEY; A credential in POLAR_STRIPE_PUBLISHABLE_KEY.

Does Verifier Web access the network?

SKILL.md names 2 domains. As links in the text: dashboard.stripe.com and docs.stripe.com. This is read from the text; nothing was executed.

Is Verifier Web safe to install?

Our automated static check of SKILL.md found notes only (mentions a .env file), nothing it rates as a warning. It is not a guarantee. Review the folder before installing.

What licence does Verifier Web use?

Verifier Web is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Verifier Web use?

About 3k tokens (SKILL.md is roughly 12k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Verifier Web?

Skills that share tags, products or a category with Verifier Web: E2E (openathleteorg/openathlete, 100 stars), Acarshub Tool Additions (sdr-enthusiasts/docker-acarshub, 117 stars), Run Dashboard E2E Local Changes (BlackBeltTechnology/pi-agent-dashboard, 316 stars) and E2E Testing (OpenHands/OpenHands, 90k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Verifier Web?

polarsource (a GitHub organization) maintains it in polarsource/polar, which has 10,336 GitHub stars. The repository holds 18 skills in this directory. The repository was last updated on October 7, 2026.

Source: polarsource/polar on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.