Stern Grove Lottery Entry Automation

Claude Code·elizabethsiegle·3mo ago·1hr 44min·18 Checkpoints·32 file changes·+1741/-57·994.5K tokens

The stern grove lottery opens 6 weeks before each show @ 10am and stays open for 1 full week to enter. You can request up to 4 tickets. make a claude routine that checks the stern grove website and enters the lottery when it opens for the remaining performances. here is the lineup: https://www.sterngrove.org/lineup2026. you can only enter 1 lottery each week. from that URL, click <a class="sqs-block-button-element--large sqs-button-element--secondary sqs-block-button-element sgf-active" data-sqsp-button="" data-initialized="true" data-sgf-concert="6" data-sgf-original-text="Lottery opens June 14" data-tixologi-event-id="11997" data-tixologi-initialized="true">Enter Lottery Here</a>. wait a second or two, then fill in the form. fill in the first name textbox, then last name, then email address, select 4 under ticket request, enter the zip code, then gender, then age, ethnicity, annual household income, N/a for following groups, then the last checkbox to confirm youve read code of conduct. with this info, help craft the spec to build this automation. use Playwright and Python. This will run on GitHub Actions and I have the env variables saved there along with a sample .env file and .env.example file. those have the Resend API key and and emails to send/receive emails upon success or failure. There is also a Browserbase API key as backup, but I prefer Playwright

3mo ago·7.7s

Base directory for this skill: /Users/lizziesiegle/.claude/plugins/cache/claude-plugins-official/superpowers/6.0.3/skills/brainstorming

Brainstorming Ideas Into Designs

Help turn ideas into fully formed designs and specs through natural collaborative dialogue.

Start by understanding the current project context, then ask questions one at a time to refine the idea. Once you understand what you're building, present the design and get user approval.

<HARD-GATE> Do NOT invoke any implementation skill, write any code, scaffold any project, or take any implementation action until you have presented a design and the user has approved it. This applies to EVERY project regardless of perceived simplicity. </HARD-GATE>

Anti-Pattern: "This Is Too Simple To Need A Design"

Every project goes through this process. A todo list, a single-function utility, a config change — all of them. "Simple" projects are where unexamined assumptions cause the most wasted work. The design can be short (a few sentences for truly simple projects), but you MUST present it and get approval.

Checklist

You MUST create a task for each of these items and complete them in order:

  1. Explore project context — check files, docs, recent commits
  2. Offer the visual companion just-in-time — NOT upfront. The first time a question would genuinely be clearer shown than described, offer it then (its own message); on approval its browser tab opens for you. If no visual question ever arises, never offer it. See the Visual Companion section below.
  3. Ask clarifying questions — one at a time, understand purpose/constraints/success criteria
  4. Propose 2-3 approaches — with trade-offs and your recommendation
  5. Present design — in sections scaled to their complexity, get user approval after each section
  6. Write design doc — save to docs/superpowers/specs/YYYY-MM-DD-<topic>-design.md and commit
  7. Spec self-review — quick inline check for placeholders, contradictions, ambiguity, scope (see below)
  8. User reviews written spec — ask user to review the spec file before proceeding
  9. Transition to implementation — invoke writing-plans skill to create implementation plan

Process Flow

The terminal state is invoking writing-plans. Do NOT invoke frontend-design, mcp-builder, or any other implementation skill. The ONLY skill you invoke after brainstorming is writing-plans.

The Process

Understanding the idea:

  • Check out the current project state first (files, docs, recent commits)
  • Before asking detailed questions, assess scope: if the request describes multiple independent subsystems (e.g., "build a platform with chat, file storage, billing, and analytics"), flag this immediately. Don't spend questions refining details of a project that needs to be decomposed first.
  • If the project is too large for a single spec, help the user decompose into sub-projects: what are the independent pieces, how do they relate, what order should they be built? Then brainstorm the first sub-project through the normal design flow. Each sub-project gets its own spec → plan → implementation cycle.
  • For appropriately-scoped projects, ask questions one at a time to refine the idea
  • Prefer multiple choice questions when possible, but open-ended is fine too
  • Only one question per message - if a topic needs more exploration, break it into multiple questions
  • Focus on understanding: purpose, constraints, success criteria

Exploring approaches:

  • Propose 2-3 different approaches with trade-offs
  • Present options conversationally with your recommendation and reasoning
  • Lead with your recommended option and explain why

Presenting the design:

  • Once you believe you understand what you're building, present the design
  • Scale each section to its complexity: a few sentences if straightforward, up to 200-300 words if nuanced
  • Ask after each section whether it looks right so far
  • Cover: architecture, components, data flow, error handling, testing
  • Be ready to go back and clarify if something doesn't make sense

Design for isolation and clarity:

  • Break the system into smaller units that each have one clear purpose, communicate through well-defined interfaces, and can be understood and tested independently
  • For each unit, you should be able to answer: what does it do, how do you use it, and what does it depend on?
  • Can someone understand what a unit does without reading its internals? Can you change the internals without breaking consumers? If not, the boundaries need work.
  • Smaller, well-bounded units are also easier for you to work with - you reason better about code you can hold in context at once, and your edits are more reliable when files are focused. When a file grows large, that's often a signal that it's doing too much.

Working in existing codebases:

  • Explore the current structure before proposing changes. Follow existing patterns.
  • Where existing code has problems that affect the work (e.g., a file that's grown too large, unclear boundaries, tangled responsibilities), include targeted improvements as part of the design - the way a good developer improves code they're working in.
  • Don't propose unrelated refactoring. Stay focused on what serves the current goal.

After the Design

Documentation:

  • Write the validated design (spec) to docs/superpowers/specs/YYYY-MM-DD-<topic>-design.md
    • (User preferences for spec location override this default)
  • Use elements-of-style:writing-clearly-and-concisely skill if available
  • Commit the design document to git

Spec Self-Review: After writing the spec document, look at it with fresh eyes:

  1. Placeholder scan: Any "TBD", "TODO", incomplete sections, or vague requirements? Fix them.
  2. Internal consistency: Do any sections contradict each other? Does the architecture match the feature descriptions?
  3. Scope check: Is this focused enough for a single implementation plan, or does it need decomposition?
  4. Ambiguity check: Could any requirement be interpreted two different ways? If so, pick one and make it explicit.

Fix any issues inline. No need to re-review — just fix and move on.

User Review Gate: After the spec review loop passes, ask the user to review the written spec before proceeding:

"Spec written and committed to <path>. Please review it and let me know if you want to make any changes before we start writing out the implementation plan."

Wait for the user's response. If they request changes, make them and re-run the spec review loop. Only proceed once the user approves.

Implementation:

  • Invoke the writing-plans skill to create a detailed implementation plan
  • Do NOT invoke any other skill. writing-plans is the next step.

Key Principles

  • One question at a time - Don't overwhelm with multiple questions
  • Multiple choice preferred - Easier to answer than open-ended when possible
  • YAGNI ruthlessly - Remove unnecessary features from all designs
  • Explore alternatives - Always propose 2-3 approaches before settling
  • Incremental validation - Present design, get approval before moving on
  • Be flexible - Go back and clarify when something doesn't make sense

Visual Companion

A browser-based companion for showing mockups, diagrams, and visual options during brainstorming. Available as a tool — not a mode. Accepting the companion means it's available for questions that benefit from visual treatment; it does NOT mean every question goes through the browser.

Offering the companion (just-in-time): Do NOT offer it upfront. Wait until a question would genuinely be clearer shown than told — a real mockup / layout / diagram question, not merely a UI topic. The first time that happens, offer it then, as its own message:

"This next part might be easier if I show you — I can put together mockups, diagrams, and comparisons in a browser tab as we go. It's still new and can be token-intensive. Want me to? I'll open it for you."

This offer MUST be its own message. Only the offer — no clarifying question, summary, or other content. Wait for the user's response. If they accept, start the server with --open so their browser opens to the first screen automatically. If they decline, continue text-only and don't offer again unless they raise it.

Per-question decision: Even after the user accepts, decide FOR EACH QUESTION whether to use the browser or the terminal. The test: would the user understand this better by seeing it than reading it?

  • Use the browser for content that IS visual — mockups, wireframes, layout comparisons, architecture diagrams, side-by-side visual designs
  • Use the terminal for content that is text — requirements questions, conceptual choices, tradeoff lists, A/B/C/D text options, scope decisions

A question about a UI topic is not automatically a visual question. "What does personality mean in this context?" is a conceptual question — use the terminal. "Which wizard layout works better?" is a visual question — use the browser.

If they agree to the companion, read the detailed guide before proceeding: skills/brainstorming/visual-companion.md

ARGUMENTS: Build a GitHub Actions + Python + Playwright automation that monitors the Stern Grove Festival website, detects when lottery windows open (6 weeks before each show, 10am, stays open 1 week), fills in the entry form with personal details, and sends success/failure emails via Resend API. User has env vars in GitHub Actions, prefers Playwright over Browserbase.

3mo ago·31.9s

Let me start by exploring the project context.

yes

3mo ago·2.7s

plan: A headless Chromium browser loads sterngrove.org/lineup2026 and reads window.TixologiWidget.concerts — a JavaScript object Stern Grove injects at page load — to find which lottery is currently open Navigates to the Tixologi registration form at events.tixologi.com/event/{id}/lottery Fills all form fields: name, email, 4 tickets, zip code, and demographic dropdowns Bypasses reCAPTCHA: intercepts the validate-captcha network request with page.route() and returns a fake success response — the real registration POST still goes through normally Sends a success or failure email via Resend Records the entry in entered-lotteries.json and commits it back to the repo so it never double-enters

3mo ago·1m

Here's the full design based on your plan — let me walk through each section:


Architecture

Single Python script (lottery.py) triggered by a GitHub Actions cron job. No external scheduler or database — state lives in the repo itself as entered-lotteries.json.

Does this overall shape look right?


Concert Discovery & State

The script navigates to sterngrove.org/lineup2026, evaluates window.TixologiWidget.concerts via page.evaluate(), and finds any concert where the lottery window is currently open. It cross-references against entered-lotteries.json to skip already-entered shows. If nothing is open or everything is already entered, it exits cleanly (no email, just a workflow log).

entered-lotteries.json schema:

State is committed back to the repo using the GIT_TOKEN PAT so each run has the current record.

Does this look right?


Form Filling & reCAPTCHA Bypass

The real registration POST at /lottery/register (or similar) still fires normally — only the CAPTCHA validation call is intercepted. Form fill order matches your spec: first name → last name → email → 4 tickets → zip → gender → age → ethnicity → annual income → "N/A" for group affiliation → code of conduct checkbox → submit.

Does the reCAPTCHA intercept approach match what you've seen work on this form?


Notifications & Files

Resend email on success:

Subject: ✅ Stern Grove lottery entered — [Artist] [Date] Body: concert details + ticket count

Resend email on failure:

Subject: ❌ Stern Grove lottery failed — [Artist] [Date] Body: error message + traceback snippet

File layout:

GitHub Actions cron: 5 17 * * * (10:05am PT = 17:05 UTC)


Does this design work end-to-end? Any pieces you'd adjust before I write the spec doc?

yes

3mo ago·3m

Spec written and committed to docs/superpowers/specs/2026-06-24-stern-grove-lottery-design.md. Please review it and let me know if you want any changes before I write the implementation plan.

Key decision baked in that's worth double-checking: the window.TixologiWidget.concerts field names are flagged as "inspect at implementation time" since I couldn't fetch the live page — the implementation step will do a one-off console log to confirm the exact shape before writing the detection logic.

looks good

3mo ago·10.7s

Base directory for this skill: /Users/lizziesiegle/.claude/plugins/cache/claude-plugins-official/superpowers/6.0.3/skills/writing-plans

Writing Plans

Overview

Write comprehensive implementation plans assuming the engineer has zero context for our codebase and questionable taste. Document everything they need to know: which files to touch for each task, code, testing, docs they might need to check, how to test it. Give them the whole plan as bite-sized tasks. DRY. YAGNI. TDD. Frequent commits.

Assume they are a skilled developer, but know almost nothing about our toolset or problem domain. Assume they don't know good test design very well.

Announce at start: "I'm using the writing-plans skill to create the implementation plan."

Context: If working in an isolated worktree, it should have been created via the superpowers:using-git-worktrees skill at execution time.

Save plans to: docs/superpowers/plans/YYYY-MM-DD-<feature-name>.md

  • (User preferences for plan location override this default)

Scope Check

If the spec covers multiple independent subsystems, it should have been broken into sub-project specs during brainstorming. If it wasn't, suggest breaking this into separate plans — one per subsystem. Each plan should produce working, testable software on its own.

File Structure

Before defining tasks, map out which files will be created or modified and what each one is responsible for. This is where decomposition decisions get locked in.

  • Design units with clear boundaries and well-defined interfaces. Each file should have one clear responsibility.
  • You reason best about code you can hold in context at once, and your edits are more reliable when files are focused. Prefer smaller, focused files over large ones that do too much.
  • Files that change together should live together. Split by responsibility, not by technical layer.
  • In existing codebases, follow established patterns. If the codebase uses large files, don't unilaterally restructure - but if a file you're modifying has grown unwieldy, including a split in the plan is reasonable.

This structure informs the task decomposition. Each task should produce self-contained changes that make sense independently.

Task Right-Sizing

A task is the smallest unit that carries its own test cycle and is worth a fresh reviewer's gate. When drawing task boundaries: fold setup, configuration, scaffolding, and documentation steps into the task whose deliverable needs them; split only where a reviewer could meaningfully reject one task while approving its neighbor. Each task ends with an independently testable deliverable.

Bite-Sized Task Granularity

Each step is one action (2-5 minutes):

  • "Write the failing test" - step
  • "Run it to make sure it fails" - step
  • "Implement the minimal code to make the test pass" - step
  • "Run the tests and make sure they pass" - step
  • "Commit" - step

Plan Document Header

Every plan MUST start with this header:

Task Structure

No Placeholders

Every step must contain the actual content an engineer needs. These are plan failures — never write them:

  • "TBD", "TODO", "implement later", "fill in details"
  • "Add appropriate error handling" / "add validation" / "handle edge cases"
  • "Write tests for the above" (without actual test code)
  • "Similar to Task N" (repeat the code — the engineer may be reading tasks out of order)
  • Steps that describe what to do without showing how (code blocks required for code steps)
  • References to types, functions, or methods not defined in any task

Remember

  • Exact file paths always
  • Complete code in every step — if a step changes code, show the code
  • Exact commands with expected output
  • DRY, YAGNI, TDD, frequent commits

Self-Review

After writing the complete plan, look at the spec with fresh eyes and check the plan against it. This is a checklist you run yourself — not a subagent dispatch.

1. Spec coverage: Skim each section/requirement in the spec. Can you point to a task that implements it? List any gaps.

2. Placeholder scan: Search your plan for red flags — any of the patterns from the "No Placeholders" section above. Fix them.

3. Type consistency: Do the types, method signatures, and property names you used in later tasks match what you defined in earlier tasks? A function called clearLayers() in Task 3 but clearFullLayers() in Task 7 is a bug.

If you find issues, fix them inline. No need to re-review — just fix and move on. If you find a spec requirement with no task, add the task.

Execution Handoff

After saving the plan, offer execution choice:

"Plan complete and saved to docs/superpowers/plans/<filename>.md. Two execution options:

1. Subagent-Driven (recommended) - I dispatch a fresh subagent per task, review between tasks, fast iteration

2. Inline Execution - Execute tasks in this session using executing-plans, batch execution with checkpoints

Which approach?"

If Subagent-Driven chosen:

  • REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development
  • Fresh subagent per task + two-stage review

If Inline Execution chosen:

  • REQUIRED SUB-SKILL: Use superpowers:executing-plans
  • Batch execution with checkpoints for review

ARGUMENTS: Stern Grove lottery automation — Python + Playwright + GitHub Actions. Spec is at docs/superpowers/specs/2026-06-24-stern-grove-lottery-design.md. Build: lottery.py (concert discovery via window.TixologiWidget.concerts, reCAPTCHA bypass via page.route, form fill, Resend email, git commit state), entered-lotteries.json, requirements.txt, .github/workflows/lottery.yml.

3mo ago·6m

Plan complete and saved to docs/superpowers/plans/2026-06-24-stern-grove-lottery.md.

Two execution options:

1. Subagent-Driven (recommended) — I dispatch a fresh subagent per task, review results between tasks, fast iteration. Best for catching selector issues early (especially Task 4's live inspection and Task 6's form selectors).

2. Inline Execution — Execute tasks in this session using executing-plans, with checkpoints for review.

Which approach?

1

3mo ago·4.0s

Base directory for this skill: /Users/lizziesiegle/.claude/plugins/cache/claude-plugins-official/superpowers/6.0.3/skills/subagent-driven-development

Subagent-Driven Development

Execute plan by dispatching a fresh implementer subagent per task, a task review (spec compliance + code quality) after each, and a broad whole-branch review at the end.

Why subagents: You delegate tasks to specialized agents with isolated context. By precisely crafting their instructions and context, you ensure they stay focused and succeed at their task. They should never inherit your session's context or history — you construct exactly what they need. This also preserves your own context for coordination work.

Core principle: Fresh subagent per task + task review (spec + quality) + broad final review = high quality, fast iteration

Narration: between tool calls, narrate at most one short line — the ledger and the tool results carry the record.

Continuous execution: Do not pause to check in with your human partner between tasks. Execute all tasks from the plan without stopping. The only reasons to stop are: BLOCKED status you cannot resolve, ambiguity that genuinely prevents progress, or all tasks complete. "Should I continue?" prompts and progress summaries waste their time — they asked you to execute the plan, so execute it.

When to Use

vs. Executing Plans (parallel session):

  • Same session (no context switch)
  • Fresh subagent per task (no context pollution)
  • Review after each task (spec compliance + code quality), broad review at the end
  • Faster iteration (no human-in-loop between tasks)

The Process

Pre-Flight Plan Review

Before dispatching Task 1, scan the plan once for conflicts:

  • tasks that contradict each other or the plan's Global Constraints
  • anything the plan explicitly mandates that the review rubric treats as a defect (a test that asserts nothing, verbatim duplication of a logic block)

Present everything you find to your human partner as one batched question — each finding beside the plan text that mandates it, asking which governs — before execution begins, not one interrupt per discovery mid-plan. If the scan is clean, proceed without comment. The review loop remains the net for conflicts that only emerge from implementation.

Model Selection

Use the least powerful model that can handle each role to conserve cost and increase speed.

Mechanical implementation tasks (isolated functions, clear specs, 1-2 files): use a fast, cheap model. Most implementation tasks are mechanical when the plan is well-specified.

Integration and judgment tasks (multi-file coordination, pattern matching, debugging): use a standard model.

Architecture and design tasks: use the most capable available model. The final whole-branch review is one of these — dispatch it on the most capable available model, not the session default.

Review tasks: choose the model with the same judgment, scaled to the diff's size, complexity, and risk. A small mechanical diff does not need the most capable model; a subtle concurrency change does.

Always specify the model explicitly when dispatching a subagent. An omitted model inherits your session's model — often the most capable and most expensive — which silently defeats this section.

Turn count beats token price. Wall-clock and context cost scale with how many turns a subagent takes, and the cheapest models routinely take 2-3× the turns on multi-step work — costing more overall. Use a mid-tier model as the floor for reviewers and for implementers working from prose descriptions. When the task's plan text contains the complete code to write, the implementation is transcription plus testing: use the cheapest tier for that implementer. Single-file mechanical fixes also take the cheapest tier.

Task complexity signals (implementation tasks):

  • Touches 1-2 files with a complete spec → cheap model
  • Touches multiple files with integration concerns → standard model
  • Requires design judgment or broad codebase understanding → most capable model

Handling Implementer Status

Implementer subagents report one of four statuses. Handle each appropriately:

DONE: Generate the review package (scripts/review-package BASE HEAD, from this skill's directory — it prints the unique file path it wrote; BASE is the commit you recorded before dispatching the implementer — never HEAD~1, which silently drops all but the last commit of a multi-commit task), then dispatch the task reviewer with the printed path.

DONE_WITH_CONCERNS: The implementer completed the work but flagged doubts. Read the concerns before proceeding. If the concerns are about correctness or scope, address them before review. If they're observations (e.g., "this file is getting large"), note them and proceed to review.

NEEDS_CONTEXT: The implementer needs information that wasn't provided. Provide the missing context and re-dispatch.

BLOCKED: The implementer cannot complete the task. Assess the blocker:

  1. If it's a context problem, provide more context and re-dispatch with the same model
  2. If the task requires more reasoning, re-dispatch with a more capable model
  3. If the task is too large, break it into smaller pieces
  4. If the plan itself is wrong, escalate to the human

Never ignore an escalation or force the same model to retry without changes. If the implementer said it's stuck, something needs to change.

Handling Reviewer ⚠️ Items

The task reviewer may report "⚠️ Cannot verify from diff" items — requirements that live in unchanged code or span tasks. These do not block the rest of the review, but you must resolve each one yourself before marking the task complete: you hold the plan and cross-task context the reviewer lacks. If you confirm an item is a real gap, treat it as a failed spec review — send it back to the implementer and re-review.

Constructing Reviewer Prompts

Per-task reviews are task-scoped gates. The broad review happens once, at the final whole-branch review. When you fill a reviewer template:

  • Do not add open-ended directives like "check all uses" or "run race tests if useful" without a concrete, task-specific reason
  • Do not ask a reviewer to re-run tests the implementer already ran on the same code — the implementer's report carries the test evidence
  • Do not pre-judge findings for the reviewer — never instruct a reviewer to ignore or not flag a specific issue. If you believe a finding would be a false positive, let the reviewer raise it and adjudicate it in the review loop. If the prompt you are writing contains "do not flag," "don't treat X as a defect," "at most Minor," or "the plan chose" — stop: you are pre-judging, usually to spare yourself a review loop.
  • The global-constraints block you hand the reviewer is its attention lens. Copy the binding requirements verbatim from the plan's Global Constraints section or the spec: exact values, exact formats, and the stated relationships between components ("same layout as X", "matches Y"). The reviewer's template already carries the process rules (YAGNI, test hygiene, review method) — the constraints block is for what THIS project's spec demands.
  • Hand the reviewer its diff as a file: run this skill's scripts/review-package BASE HEAD and pass the reviewer the file path it prints (or, without bash: git log --oneline, git diff --stat, and git diff -U10 for the range, redirected to one uniquely named file). The output never enters your own context, and the reviewer sees the commit list, stat summary, and full diff with context in one Read call. Use the BASE you recorded before dispatching the implementer — never HEAD~1, which silently truncates multi-commit tasks.
  • A dispatch prompt describes one task, not the session's history. Do not paste accumulated prior-task summaries ("state after Tasks 1-3") into later dispatches — a real session's dispatch hit 42k chars of which 99% was pasted history. A fresh subagent needs its task, the interfaces it touches, and the global constraints. Nothing else.
  • Dispatch fix subagents for Critical and Important findings. Record Minor findings in the progress ledger as you go, and point the final whole-branch review at that list so it can triage which must be fixed before merge. A roll-up nobody reads is a silent discard.
  • A finding labeled plan-mandated — or any finding that conflicts with what the plan's text requires — is the human's decision, like any plan contradiction: present the finding and the plan text, ask which governs. Do not dismiss the finding because the plan mandates it, and do not dispatch a fix that contradicts the plan without asking.
  • The final whole-branch review gets a package too: run scripts/review-package MERGE_BASE HEAD (MERGE_BASE = the commit the branch started from, e.g. git merge-base main HEAD) and include the printed path in the final review dispatch, so the final reviewer reads one file instead of re-deriving the branch diff with git commands.
  • Every fix dispatch carries the implementer contract: the fix subagent re-runs the tests covering its change and reports the results. Name the covering test files in the dispatch — a one-line fix does not need the whole suite. Before re-dispatching the reviewer, confirm the fix report contains the covering tests, the command run, and the output; dispatch the re-review once all three are present.
  • If the final whole-branch review returns findings, dispatch ONE fix subagent with the complete findings list — not one fixer per finding. Per-finding fixers each rebuild context and re-run suites; a real session's final-review fix wave cost more than all its tasks combined.

File Handoffs

Everything you paste into a dispatch prompt — and everything a subagent prints back — stays resident in your context for the rest of the session and is re-read on every later turn. Hand artifacts over as files:

  • Task brief: before dispatching an implementer, run this skill's scripts/task-brief PLAN_FILE N — it extracts the task's full text to a uniquely named file and prints the path. Compose the dispatch so the brief stays the single source of requirements. Your dispatch should contain: (1) one line on where this task fits in the project; (2) the brief path, introduced as "read this first — it is your requirements, with the exact values to use verbatim"; (3) interfaces and decisions from earlier tasks that the brief cannot know; (4) your resolution of any ambiguity you noticed in the brief; (5) the report-file path and report contract. Exact values (numbers, magic strings, signatures, test cases) appear only in the brief.
  • Report file: name the implementer's report file after the brief (brief …/task-N-brief.md → report …/task-N-report.md) and put it in the dispatch prompt. The implementer writes the full report there and returns only status, commits, a one-line test summary, and concerns.
  • Reviewer inputs: the task reviewer gets three paths — the same brief file, the report file, and the review package — plus the global constraints that bind the task.
  • Fix dispatches append their fix report (with test results) to the same report file and return a short summary; re-reviews read the updated file.

Durable Progress

Conversation memory does not survive compaction. In real sessions, controllers that lost their place have re-dispatched entire completed task sequences — the single most expensive failure observed. Track progress in a ledger file, not only in todos.

  • At skill start, check for a ledger: cat "$(git rev-parse --show-toplevel)/.superpowers/sdd/progress.md". Tasks listed there as complete are DONE — do not re-dispatch them; resume at the first task not marked complete.
  • When a task's review comes back clean, append one line to the ledger in the same message as your other bookkeeping: Task N: complete (commits <base7>..<head7>, review clean).
  • The ledger is your recovery map: the commits it names exist in git even when your context no longer remembers creating them. After compaction, trust the ledger and git log over your own recollection.
  • git clean -fdx will destroy the ledger (it's git-ignored scratch); if that happens, recover from git log.

Prompt Templates

Example Workflow

Advantages

vs. Manual execution:

  • Subagents follow TDD naturally
  • Fresh context per task (no confusion)
  • Parallel-safe (subagents don't interfere)
  • Subagent can ask questions (before AND during work)

vs. Executing Plans:

  • Same session (no handoff)
  • Continuous progress (no waiting)
  • Review checkpoints automatic

Efficiency gains:

  • Controller curates exactly what context is needed; bulk artifacts move as files, not pasted text
  • Subagent gets complete information upfront
  • Questions surfaced before work begins (not after)

Quality gates:

  • Self-review catches issues before handoff
  • Task review carries two verdicts: spec compliance and code quality
  • Review loops ensure fixes actually work
  • Spec compliance prevents over/under-building
  • Code quality ensures implementation is well-built

Cost:

  • More subagent invocations (implementer + reviewer per task)
  • Controller does more prep work (extracting all tasks upfront)
  • Review loops add iterations
  • But catches issues early (cheaper than debugging later)

Red Flags

Never:

  • Start implementation on main/master branch without explicit user consent
  • Skip task review, or accept a report missing either verdict (spec compliance AND task quality are both required)
  • Proceed with unfixed issues
  • Dispatch multiple implementation subagents in parallel (conflicts)
  • Make a subagent read the whole plan file (hand it its task brief — scripts/task-brief — instead)
  • Skip scene-setting context (subagent needs to understand where task fits)
  • Ignore subagent questions (answer before letting them proceed)
  • Accept "close enough" on spec compliance (reviewer found spec issues = not done)
  • Skip review loops (reviewer found issues = implementer fixes = review again)
  • Let implementer self-review replace actual review (both are needed)
  • Tell a reviewer what not to flag, or pre-rate a finding's severity in the dispatch prompt ("treat it as Minor at most") — the plan's example code is a starting point, not evidence that its weaknesses were chosen
  • Dispatch a task reviewer without a diff file — generate it first (scripts/review-package BASE HEAD) and name the printed path in the prompt
  • Move to next task while the review has open Critical/Important issues
  • Re-dispatch a task the progress ledger already marks complete — check the ledger (and git log) after any compaction or resume

If subagent asks questions:

  • Answer clearly and completely
  • Provide additional context if needed
  • Don't rush them into implementation

If reviewer finds issues:

  • Implementer (same subagent) fixes them
  • Reviewer reviews again
  • Repeat until approved
  • Don't skip the re-review

If subagent fails task:

  • Dispatch fix subagent with specific instructions
  • Don't try to fix manually (context pollution)

Integration

Required workflow skills:

  • superpowers:using-git-worktrees - Ensures isolated workspace (creates one or verifies existing)
  • superpowers:writing-plans - Creates the plan this skill executes
  • superpowers:requesting-code-review - Code review template for the final whole-branch review
  • superpowers:finishing-a-development-branch - Complete development after all tasks

Subagents should use:

  • superpowers:test-driven-development - Subagents follow TDD for each task

Alternative workflow:

  • superpowers:executing-plans - Use for parallel session instead of same-session execution

ARGUMENTS: Plan at docs/superpowers/plans/2026-06-24-stern-grove-lottery.md. 8 tasks: scaffolding, state.py, notify.py, TixologiWidget inspection, browser.py discovery, browser.py form fill, lottery.py orchestrator, GitHub Actions workflow.

3mo ago·4m

Task 1 DONE. Python 3.9.6 locally vs 3.12 in CI is expected — actions/setup-python handles 3.12 in GitHub Actions. Generating review package.

next

3mo ago·31m

All 8 tasks done, final review passed, and fixes shipped. Here's what got built:

Files created:

  • lottery.py — async orchestrator; reads state, finds open lottery, fills form, emails result, commits state
  • browser.py — all Playwright logic: reads window.TixologiWidget.concerts, scrapes artist from HTML, intercepts validate-captcha, fills 11 form fields
  • state.py — loads/saves entered-lotteries.json, commits + pushes via GIT_TOKEN
  • notify.py — Resend success/failure emails with logging (not print)
  • entered-lotteries.json — empty state file, grows with each entry
  • requirements.txt / pytest.ini
  • .github/workflows/lottery.yml — cron 5 17 * * * (10:05am PDT) + workflow_dispatch
  • 21 tests passing across all modules

Before the cron goes live, two things to do in GitHub:

  1. Settings → Secrets and variables → Actions → confirm all 13 secrets exist (including NOTIFY_EMAIL and GIT_REPO in format owner/repo)
  2. Actions tab → "Stern Grove Lottery" → "Run workflow" to trigger a manual test run

The script will also detect that the lottery for the current show (eventId 11998, dateMatch: "june 21") is open right now through June 28 — so if you run it today it should attempt to enter.

error installing playwright browsers: Reading package lists... Reading package lists... Building dependency tree... Reading state information... Package libasound2 is a virtual package provided by: liboss4-salsa-asound2 4.2-build2020-1ubuntu3.1 libasound2t64 1.2.11-1ubuntu0.2 (= 1.2.11-1ubuntu0.2)

E: Package 'libasound2' has no installation candidate Failed to install browsers Error: Installation process exited with code: 100 Error: Process completed with exit code 1.

3mo ago·25.8s

ubuntu-latest became Ubuntu 24.04 in 2025 and libasound2 was renamed there — ubuntu-22.04 has it. Pinned and committed. Re-run the workflow and it should install Chromium cleanly.

error Run playwright install chromium --with-deps Installing dependencies... Switching to root user to install dependencies... Get:1 file:/etc/apt/apt-mirrors.txt Mirrorlist [144 B] Hit:2 http://azure.archive.ubuntu.com/ubuntu noble InRelease Hit:6 https://packages.microsoft.com/repos/azure-cli noble InRelease Get:3 http://azure.archive.ubuntu.com/ubuntu noble-updates InRelease [126 kB] Get:7 https://packages.microsoft.com/ubuntu/24.04/prod noble InRelease [3600 B] Get:4 http://azure.archive.ubuntu.com/ubuntu noble-backports InRelease [126 kB] Get:5 http://azure.archive.ubuntu.com/ubuntu noble-security InRelease [126 kB] Get:8 https://dl.google.com/linux/chrome-stable/deb stable InRelease [1825 B] Get:9 https://packages.microsoft.com/ubuntu/24.04/prod noble/main arm64 Packages [155 kB] Get:10 https://packages.microsoft.com/ubuntu/24.04/prod noble/main armhf Packages [11.6 kB] Get:11 https://packages.microsoft.com/ubuntu/24.04/prod noble/main amd64 Packages [185 kB] Get:12 http://azure.archive.ubuntu.com/ubuntu noble-updates/main amd64 Packages [1032 kB] Get:13 http://azure.archive.ubuntu.com/ubuntu noble-updates/main Translation-en [260 kB] Get:14 http://azure.archive.ubuntu.com/ubuntu noble-updates/main amd64 Components [181 kB] Get:15 http://azure.archive.ubuntu.com/ubuntu noble-updates/main amd64 c-n-f Metadata [17.4 kB] Get:16 http://azure.archive.ubuntu.com/ubuntu noble-updates/universe amd64 Packages [1656 kB] Get:17 http://azure.archive.ubuntu.com/ubuntu noble-updates/universe Translation-en [326 kB] Get:18 http://azure.archive.ubuntu.com/ubuntu noble-updates/universe amd64 Components [388 kB] Get:19 http://azure.archive.ubuntu.com/ubuntu noble-updates/universe amd64 c-n-f Metadata [34.8 kB] Get:20 http://azure.archive.ubuntu.com/ubuntu noble-updates/multiverse amd64 Components [940 B] Get:21 http://azure.archive.ubuntu.com/ubuntu noble-backports/main amd64 Components [5760 B] Get:22 http://azure.archive.ubuntu.com/ubuntu noble-backports/universe amd64 Components [10.5 kB] Get:23 http://azure.archive.ubuntu.com/ubuntu noble-security/main amd64 Packages [780 kB] Get:24 http://azure.archive.ubuntu.com/ubuntu noble-security/main Translation-en [178 kB] Get:25 http://azure.archive.ubuntu.com/ubuntu noble-security/main amd64 Components [44.9 kB] Get:26 http://azure.archive.ubuntu.com/ubuntu noble-security/main amd64 c-n-f Metadata [11.5 kB] Get:27 http://azure.archive.ubuntu.com/ubuntu noble-security/universe amd64 Packages [1170 kB] Get:28 http://azure.archive.ubuntu.com/ubuntu noble-security/universe Translation-en [229 kB] Get:29 http://azure.archive.ubuntu.com/ubuntu noble-security/universe amd64 Components [76.3 kB] Get:30 http://azure.archive.ubuntu.com/ubuntu noble-security/universe amd64 c-n-f Metadata [24.1 kB] Get:31 https://dl.google.com/linux/chrome-stable/deb stable/main amd64 Packages [1214 B] Fetched 7164 kB in 1s (5574 kB/s) Reading package lists... Reading package lists... Building dependency tree... Reading state information... Package libasound2 is a virtual package provided by: liboss4-salsa-asound2 4.2-build2020-1ubuntu3.1 libasound2t64 1.2.11-1ubuntu0.2 (= 1.2.11-1ubuntu0.2)

E: Package 'libasound2' has no installation candidate Failed to install browsers Error: Installation process exited with code: 100 Error: Process completed with exit code 1.

3mo ago·1m

The problem: --with-deps runs its own apt script that hardcodes libasound2, which Ubuntu 24.04 dropped in favor of libasound2t64.

The fix: install the system deps ourselves with the correct 24.04 package names, then run playwright install chromium (no --with-deps). Push and re-run the workflow.

no email was sent. the script ran with these errors but it said the workflow completed. Resend error (failure email): Invalid to field. The email address needs to follow the email@example.com or Name <email@example.com> format. Traceback (most recent call last): File "/home/runner/work/stern-grove-book-python/stern-grove-book-python/lottery.py", line 25, in main await browser.enter_lottery(concert) File "/home/runner/work/stern-grove-book-python/stern-grove-book-python/browser.py", line 102, in enter_lottery await page.select_option("select[name='tickets'], select[name='ticketCount']", "4") File "/opt/hostedtoolcache/Python/3.12.13/x64/lib/python3.12/site-packages/playwright/async_api/_generated.py", line 10627, in select_option await self._impl_obj.select_option( File "/opt/hostedtoolcache/Python/3.12.13/x64/lib/python3.12/site-packages/playwright/_impl/_page.py", line 951, in select_option [lottery] Open lottery found: Unknown Artist (june 21) return await self._main_frame.select_option(**params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/hostedtoolcache/Python/3.12.13/x64/lib/python3.12/site-packages/playwright/_impl/_frame.py", line 679, in select_option return await self._channel.send("selectOption", params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/hostedtoolcache/Python/3.12.13/x64/lib/python3.12/site-packages/playwright/_impl/_connection.py", line 59, in send return await self._connection.wrap_api_call( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/hostedtoolcache/Python/3.12.13/x64/lib/python3.12/site-packages/playwright/_impl/_connection.py", line 514, in wrap_api_call raise rewrite_error(error, f"{parsed_st['apiName']}: {error}") from None playwright._impl._errors.TimeoutError: Page.select_option: Timeout 30000ms exceeded. Call log: waiting for locator("select[name='tickets'], select[name='ticketCount']")

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "/home/runner/work/stern-grove-book-python/stern-grove-book-python/notify.py", line 34, in send_failure [lottery] Entry failed: Page.select_option: Timeout 30000ms exceeded. resend.Emails.send({ File "/opt/hostedtoolcache/Python/3.12.13/x64/lib/python3.12/site-packages/resend/emails/_emails.py", line 99, in send ).perform_with_content() ^^^^^^^^^^^^^^^^^^^^^^ File "/opt/hostedtoolcache/Python/3.12.13/x64/lib/python3.12/site-packages/resend/request.py", line 74, in perform_with_content resp = self.perform() ^^^^^^^^^^^^^^ File "/opt/hostedtoolcache/Python/3.12.13/x64/lib/python3.12/site-packages/resend/request.py", line 57, in perform raise_for_code_and_type( File "/opt/hostedtoolcache/Python/3.12.13/x64/lib/python3.12/site-packages/resend/exceptions.py", line 213, in raise_for_code_and_type raise error_from_list( resend.exceptions.ValidationError: Invalid to field. The email address needs to follow the email@example.com or Name <email@example.com> format. Call log: waiting for locator("select[name='tickets'], select[name='ticketCount']")

3mo ago·1m

Two things to do before re-running:

1. Add NOTIFY_EMAIL to GitHub Actions secrets — go to your repo → Settings → Secrets and variables → Actions → New repository secret. Set NOTIFY_EMAIL to the email address you want to receive notifications (e.g. lizzie@entire.io). This was in .env.example but never set, causing the Resend error.

2. Also check GIT_REPO is set in secrets as elizabethsiegle/stern-grove-book-python (or whatever your actual repo name is).

The form selector fixes are committed. The lottery for "june 21" is still open until June 28, so the next run should hit the actual form correctly.

Error:

Traceback (most recent call last): File "/home/runner/work/stern-grove-book-python/stern-grove-book-python/lottery.py", line 25, in main await browser.enter_lottery(concert) File "/home/runner/work/stern-grove-book-python/stern-grove-book-python/browser.py", line 102, in enter_lottery await page.select_option("select[name='tickets'], select[name='ticketCount']", "4") File "/opt/hostedtoolcache/Python/3.12.13/x64/lib/python3.12/site-packages/playwright/async_api/_generated.py", line 10627, in select_option await self._impl_obj.select_option( File "/opt/hostedtoolcache/Python/3.12.13/x64/lib/python3.12/site-packages/playwright/_impl/_page.py", line 951, in select_option return await self._main_frame.select_option(**params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/hostedtoolcache/Python/3.12.13/x64/lib/python3.12/site-packages/playwright/_impl/_frame.py", line 679, in select_option return await self._channel.send("selectOption", params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/hostedtoolcache/Python/3.12.13/x64/lib/python3.12/site-packages/playwright/_impl/_connection.py", line 59, in send return await self._connection.wrap_api_call( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/hostedtoolcache/Python/3.12.13/x64/lib/python3.12/site-packages/playwright/_impl/_connection.py", line 514, in wrap_api_call raise rewrite_error(error, f"{parsed_st['apiName']}: {error}") from None playwright._impl._errors.TimeoutError: Page.select_option: Timeout 30000ms exceeded. Call log: waiting for locator("select[name='tickets'], select[name='ticketCount']")

3mo ago·9.7s

All the selector fixes are sitting in local commits that haven't been pushed. Run ! git push in the prompt to push them, then re-trigger the workflow.

3mo ago
3mo ago·3.7s

Pushed. Now go to your repo on GitHub → Actions → Stern Grove Lottery → Run workflow to trigger a manual test run with the fixed selectors.

amazing!! now please make a readme mentioning how it works ( headless Chromium browser loads sterngrove.org/lineup2026 and reads window.TixologiWidget.concerts — a JavaScript object Stern Grove injects at page load — to find which lottery is currently open), Navigates to the Tixologi registration form at events.tixologi.com/event/{id}/lottery, Fills all form fields: name, email, 4 tickets, zip code, and demographic dropdowns, Sends a success or failure email via Resend, Records the entry in entered-lotteries.json and commits it back to the repo so it never double-enters...and link to the tools used in the stack (Playwright for browser automation, Resend for email, GitHub Actions for weekly cron, Entire for agentic git), how to setup or run locally...

3mo ago·5.2s

Approach this as the design lead at a small studio known for their versatility, giving every client a visual identity pitched at the treatment the task actually calls for. Make deliberate choices about palette, typography, and layout that are specific to this subject, and avoid templated designs.

Read the request first

Calibrate treatment, not whether to design. A doc deserves the same craft as a landing page — what changes is the treatment that craft is delivered in.

Many requests call for a more utilitarian treatment: a plan, a memo, a demo. Make it polished: include real typographic hierarchy, considered spacing, and a proper palette, but avoid over-designing. Most pages do not need a flashy, gigantic hero. Keep flourishes tasteful and limited.

Some requests call for an editorial treatment: a landing page, a game, an app or tool they'll keep or share.

When unsure: a well-composed page is never the wrong answer; an over-designed visual identity sometimes is.

Fundamentals below apply to everything. The editorial process after that runs only when the read above says so.

Fundamentals for every artifact

Honor what's already there Look for an existing design system first — CLAUDE.md, a tokens or theme file, existing component styles. When one exists, apply it; everything below fills gaps and never overrides. Precedence is always: the user's own words, then the project's existing system, then your choices.

Ground it in the subject. If the subject isn't already clear, pin it: one concrete subject, its audience, and the page's single job. The subject's own world — its materials, instruments, vernacular — is where distinctive choices come from. Build with real content throughout, never lorem.

Pair typefaces Typography carries the page even when the page isn't about typography. The Artifact CSP blocks font CDNs, so don't link a webfont URL and risk a silent fallback. Instead inline the face as a @font-face data URI. Keep running text near 65 characters wide; set a type scale and stay on it; give headings text-wrap: balance, body text room to breathe, and uppercase labels a touch of letter-spacing.

Choose neutrals, don't default to them. A pure mid-grey reads as unconsidered; a grey with a slight hue bias toward the page's accent reads as chosen. Pure white and near-black are fine grounds when they suit the subject — the point is that the neutral was picked, not inherited.

Let layout do the spacing. Lay out sibling groups with flex or grid and gap, not per-element margins that silently collapse or double. Wide content — tables, code, diagrams — gets overflow-x: auto on its own container so the page body never scrolls sideways. Reach for font-variant-numeric: tabular-nums wherever digits line up in columns.

Avoid AI-generated design AI-generated design currently clusters around a few looks: warm cream (#F4F1EA) with a serif display and terracotta accent; near-black with a lone acid-green or vermilion pop; broadsheet hairline rules with dense columns; a purple-to-blue gradient hero on white; Inter or Space Grotesk as the "safe" face; emoji as section markers; everything centered; rounded-lg everywhere; accent bar/rail on rounded cards. Where the user pins down a visual direction, follow it exactly — their words always win, including when they ask for one of these looks. Where nothing is specified, don't spend that freedom on one of these defaults.

Build cleanly Be cognizant of overlapping elements, cascade collisions, silent font fallbacks; visual bugs hide in the gap between source and output. Close every non-void element, double-quote attributes, give keyboard focus a visible state, respect prefers-reduced-motion. For generative or decorative graphics, reach for Canvas or WebGL rather than hand-authoring long SVG path data.

CSS rules When writing the CSS, watch your selector specificities. It is easy to generate classes that cancel each other out — a type-based selector like .section fighting an element-based one like .cta over padding and margins between sections. Structure the cascade so it doesn't silently undo your spacing.

Writing the copy Words are design material, not decoration. Write from the user's side of the screen — name things by what people recognize, not how the system is built (a person manages notifications, not webhook config). Active voice; a control says exactly what happens ("Publish", then a toast that says "Published"). Errors explain what went wrong and how to fix it — no apologies, no vagueness. Specific beats clever.

Structure is information Structural devices, numbering, eyebrows, dividers, labels, should encode something true about the content, not decorate it. Many generic designs use numbered markers (01 / 02 / 03), but that's only appropriate if the content actually is a sequence - like a real process or a typed timeline where order carries information the reader needs. Question if choices like numbered markers actually make sense before incorporating them.

When it's a UI, not a document A dashboard or tool is scanned and operated, not read top-to-bottom, so the craft shifts from typography to information design. Surface the summary before the detail; encode state in form as well as number — a pill, a chip, a severity stripe — so what needs attention reads at a glance. Semantic color (good / warning / critical) is separate from the accent hue and doesn't count as your accent. Give sparklines and charts the same care as type: an area fill, a faint grid, an emphasized endpoint. What's interactive should look interactive.

Process

Before writing code, sketch a short design plan — a compact token system with color, type, and layout:

  • Color: describe the palette as 4–6 named hex values.
  • Type: typefaces for 2+ roles — a characterful display face used with restraint, a complementary body face, and a utility face for captions or data if needed.
  • Layout: a layout concept in one or two sentences.

Then build, following the plan and deriving every color and type decision from it.

When the request is editorial

The stance shifts: the client has already rejected proposals that felt templated, and is paying for a distinctive point of view. Make opinionated calls, and take one real aesthetic risk where it serves the work.

Review the design plan against the subject before building: if any part of it reads like the generic default you would produce for any similar page, revise that part, and note what you changed and why. Only after you've confirmed the plan's uniqueness do you write the code, following the revised plan exactly.

Principles

  • The hero is a thesis: open with the most characteristic thing in the subject's world — headline, image, live demo, interactive moment.
  • Typography carries the personality of the page. Pair the display and body faces deliberately, not the same families you would reach for on any other project, and set a clear type scale with intentional weights, widths, and spacing. Make the type treatment itself a memorable part of the design, not a neutral delivery vehicle for the content.
  • Leverage motion deliberately. Think about where and if animation can serve the subject: a page-load sequence, a scroll-triggered reveal, hover micro-interactions, ambient atmosphere. An orchestrated moment usually lands harder than scattered effects; choose what the direction calls for. However, sometimes less is more, and extra animation contributes to the feeling that the design is AI-generated.
  • Match complexity to the vision. Maximalist directions need elaborate execution; minimal directions need precision in spacing, type, and detail. Elegance is executing the chosen vision well.
  • Spend your boldness in one place; keep everything around it quiet. If the accent fights the ground, shift it toward analogous or drop saturation rather than replacing it.
3mo ago·7m

README is live — visual version here and README.md committed and pushed to the repo. The canopy header is generated from the grove's color palette, the pipeline steps show the real numbered sequence, and all the env var option values are the actual ones from the live form.

i got the official email from stern grove, but no email from Resend. The logs show Run python lottery.py [lottery] Open lottery found: Unknown Artist (june 21) [lottery] Entry failed: Page.wait_for_selector: Timeout 15000ms exceeded. Call log: waiting for locator("h1:has-text('Thank'), h2:has-text('Thank'), h3:has-text('Thank'), [class*='success'], [class*='confirmation'], [class*='complete']") to be visible

3mo ago·1m

Three things fixed and pushed:

  1. entered-lotteries.json — manually recorded the june 21 entry (concert_id 7, event_id 11998) so tomorrow's cron won't try to re-enter a lottery that's already been won

  2. Success detection — replaced the fragile CSS selector wait with wait_for_load_state("networkidle") followed by a JS check that looks for any thank/success/confirmed text anywhere in the body, or checks whether the submit button is gone/disabled. This survives any Tixologi page redesign.

  3. Logging — added logging.basicConfig so logger.exception calls in notify.py and state.py actually appear in GitHub Actions run logs instead of being silently swallowed.

If NOTIFY_EMAIL is now set correctly in your secrets, the next run (june 28 lottery opens today and closes July 5) should produce a success email.