Skip to content

Add Sandcastle AI agent workflow#1412

Open
ArendPeter wants to merge 9 commits into
Equal-Vote:mainfrom
ArendPeter:AddSandcastle
Open

Add Sandcastle AI agent workflow#1412
ArendPeter wants to merge 9 commits into
Equal-Vote:mainfrom
ArendPeter:AddSandcastle

Conversation

@ArendPeter

@ArendPeter ArendPeter commented Jul 1, 2026

Copy link
Copy Markdown
Member

Usage

Running npm run sandcastle locally will spawn the workflow. Any issues with the Sandcastle label are eligible to be picked up. Then the changes will be merged into the main branch locally.

Original Walkthrough Video

https://www.youtube.com/watch?v=E5-QK3CDVQM

Summary

  • Adds a .sandcastle/ directory with a multi-phase AI agent orchestration workflow for autonomously implementing GitHub issues
  • The workflow runs a Plan → Execute + Review → Merge → QA loop: a planner agent picks unblocked issues, parallel implementer + reviewer agents work in isolated Docker sandboxes, a merge agent integrates completed branches, and a QA agent files issues for any remaining problems
  • Includes coding standards, Dockerfile, and all prompt files to keep the agent grounded in project conventions

🤖 Generated with Claude Code

@netlify

netlify Bot commented Jul 1, 2026

Copy link
Copy Markdown

Deploy Preview for bettervoting ready!

Name Link
🔨 Latest commit cfb7a3c
🔍 Latest deploy log https://app.netlify.com/projects/bettervoting/deploys/6a47419f36ca430008b9a1f4
😎 Deploy Preview https://deploy-preview-1412--bettervoting.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai

coderabbitai Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR introduces a new .sandcastle/ directory implementing an automated multi-agent development workflow. It adds a Dockerfile defining a containerized "agent" environment with Node.js, GitHub CLI, and Claude Code CLI; a main.mts orchestration script that runs iterative planner/implementer/reviewer/merger/QA phases using Zod-validated agent outputs and docker sandboxes; Markdown prompt templates for each phase; a coding standards document; and gitignore rules. package.json gains a sandcastle script and new @ai-hero/sandcastle and zod dependencies. The root .gitignore gains a .playwright-mcp/** rule.

Sequence Diagram(s)

sequenceDiagram
  participant Main as main.mts
  participant Planner
  participant Sandbox
  participant Implementer
  participant Reviewer
  participant Merger
  participant QAAgent

  loop Up to MAX_ITERATIONS
    Main->>Planner: request unblocked issues
    Planner-->>Main: selected issues/branches
    par per branch
      Main->>Sandbox: create docker sandbox
      Sandbox->>Implementer: implement issue
      Implementer-->>Sandbox: commits (if any)
      Sandbox->>Reviewer: review (if commits produced)
    end
    Main->>Merger: merge completed branches
  end
  Main->>QAAgent: create QA issue (unless --noqa)
Loading

Related Issues: None specified in the provided changes.

Related PRs: None specified in the provided changes.

Suggested labels: tooling, infrastructure, ci

Suggested reviewers: None specified in the provided changes.

Poem

A burrow of scripts, a Dockerfile den,
Planner hops first, then implementers ten.
Reviewer sniffs commits, merger ties the knot,
QA issue filed while the loop turns hot.
🐇 Sandcastle built, one carrot at a time!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding a Sandcastle AI agent workflow.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The PR description is clear and mostly matches the template, with a summary and usage info provided.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.sandcastle/review-prompt.md:
- Around line 7-13: The review prompt in review-prompt.md still references
TARGET_BRANCH even though only BRANCH is injected, so the git commands will
expand incorrectly. Update the prompt content to either pass TARGET_BRANCH from
main.mts or replace the unresolved TARGET_BRANCH placeholder in the git diff and
git log commands so they reference the actual baseline branch consistently.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6446a8b2-b987-4a29-abce-c72f62358e6e

📥 Commits

Reviewing files that changed from the base of the PR and between fe84eb4 and f9932f4.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (11)
  • .gitignore
  • .sandcastle/.gitignore
  • .sandcastle/CODING_STANDARDS.md
  • .sandcastle/Dockerfile
  • .sandcastle/implement-prompt.md
  • .sandcastle/main.mts
  • .sandcastle/merge-prompt.md
  • .sandcastle/plan-prompt.md
  • .sandcastle/qa-issue-prompt.md
  • .sandcastle/review-prompt.md
  • package.json

Comment on lines +7 to +13
## Branch diff

!`git diff {{TARGET_BRANCH}}...{{BRANCH}}`

## Commits on this branch

!`git log {{TARGET_BRANCH}}..{{BRANCH}} --oneline`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Inject TARGET_BRANCH or stop referencing it here.

main.mts only passes BRANCH into this prompt, so git diff {{TARGET_BRANCH}}...{{BRANCH}} and git log {{TARGET_BRANCH}}..{{BRANCH}} will expand with an unresolved placeholder. The reviewer will not inspect the correct baseline.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.sandcastle/review-prompt.md around lines 7 - 13, The review prompt in
review-prompt.md still references TARGET_BRANCH even though only BRANCH is
injected, so the git commands will expand incorrectly. Update the prompt content
to either pass TARGET_BRANCH from main.mts or replace the unresolved
TARGET_BRANCH placeholder in the git diff and git log commands so they reference
the actual baseline branch consistently.

ArendPeter and others added 5 commits July 1, 2026 12:31
Task: Remove WizardExtra and replace multi-step wizard with single-page flow.
PRD: Issue Equal-Vote#1405 - Equal-Vote#1405

Key decisions:
- Deleted WizardExtra.tsx entirely; Wizard.tsx is now single-page (no slide animation)
- Added MultiRaceTitleSection sub-component in Wizard.tsx for multi-race title/description entry
- onCustomize() helper applies open voter access + device-ID auth + contact email defaults and navigates to /admin/build_ballot
- ConfirmationDialogProvider gains dismissable?: boolean option: adds X IconButton in DialogTitle, onClose resolves promise with null instead of boolean
- wizard.publish_confirm.cancel changed from 'See more options' to 'Customize in editor'
- Single-race onNext handles null (dismiss) as no-op so wizard stays visible with form values intact

Files changed:
- packages/frontend/src/components/ElectionForm/Wizard/Wizard.tsx (rewritten)
- packages/frontend/src/components/ElectionForm/Wizard/WizardExtra.tsx (deleted)
- packages/frontend/src/components/ConfirmationDialogProvider.tsx (added dismissable support)
- packages/frontend/src/i18n/en.yaml (updated cancel label)
- testing/tests/create-election.spec.ts (5 new tests replacing old 5)

Notes: E2E tests require full docker stack and cannot be verified here; backend unit tests all pass (133/133). TypeScript checks clean for modified files.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Simplify redundant `!election.title || election.title.length < 1` to
just `!election.title` (the falsy check already covers empty string).

Rename `dismiss dialog returns to page 1` test to
`dismiss dialog keeps wizard visible` since page 2 no longer exists
after the WizardExtra removal.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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