I.How the work gets done
This document complements the Roadmap. The roadmap says what ships and why; this document says who does which piece, in what order, and roughly how much it costs in time and tokens. It assumes the working pattern of the last several months: Jonathan directs and approves, Claude Code does the heavy lifting on code and configuration.
How to read this document
Each phase block lists tasks with three columns of metadata:
Token estimates are rough orders of magnitude — the actual number depends heavily on how much exploration each task needs and how many iterations land it. Treat them as a budget for planning, not a forecast. Calendar estimates assume Jonathan can dedicate roughly 5–10 hours per week to CBF tech alongside other obligations.
Outside the phase plan. An internal kanban board (kan, self-hosted) was stood up on the Unraid VM in June 2026 as a parallel internal-tooling track. Like the volunteer app, it lives in its own stack and codebase (CBF-kanban) and neither blocks nor depends on the CRM/donation phases, so it carries no phase number or budget line below. Standing up the dev instance was a single short session; future CRM tie-ins are deferred to a Phase 2-style integration via kan's REST API. See the Roadmap's current-state table (§ II) and decisions log (§ VI).
II.Timeline at a glance
The Gantt below shows the sequencing of the remaining phases. Phase 4 (volunteer tool) is shown in parallel because it is on a separate codebase and a separate organizational track — it does not block CRM/donation work. Phase 5 (Tina expansion) depends on Phase 2's CBF-site ↔ Twenty integration being live.
III.Phase-by-phase task breakdown
CRM production & data pipeline
| Task | Owner | Tokens | Time | Notes |
|---|---|---|---|---|
| Provision prod droplet | Jonathan | — | ~1 hr | DigitalOcean dashboard. $24/mo, 4GB RAM, Ubuntu 24.04. |
DNS + SSL for crm.cloudbase.foundation |
Both | ~15K | ~1 hr | Claude writes the nginx config; Jonathan creates the Cloudflare A record (proxy OFF) and runs certbot interactively. |
| Twenty CRM deploy on prod | Claude | ~30K | 2–3 hr | Mostly invoking server/scripts/setup.sh and verifying. Some env-var rotation. |
| Data model extensions on dev first | Claude | ~40K | 3–4 hr | Add RecurringAgreement, expand Donation, add receiptStatus, Partner SELECT. Edit data-model.json + apply via apply_data_model.py. |
| Mirror data model on prod | Claude | ~10K | ~1 hr | Same apply_data_model.py run, prod API key. |
| Saved views in Twenty UI | Jonathan | ~5K | 2–3 hr | Twenty UI doesn't expose view config via API; must be clicked. Claude can write a step-by-step doc. |
| GiveLively CSV import | Jonathan | ~5K | 2 hr | Run anonymize_givelively.py first to dry-run; then Twenty's UI import for the real CSV. |
| CBF-site → Twenty REST proxy | Claude | ~50K | ~1 day | Catch-all [...path]/route.ts; tests; lib/api.ts rewrite from USE_CIVICRM to USE_TWENTY. |
| Cloudflare Worker env-var setup | Jonathan | — | ~15 min | TWENTY_API_URL, TWENTY_API_KEY, USE_TWENTY. CF dashboard. |
| Projects page from Twenty + contact form POST | Claude | ~40K | ~1 day | Update fetchers; test full flow on dev before flipping USE_TWENTY in prod. |
| ListMonk container + nginx + DNS | Both | ~30K | ~3 hr | Claude updates docker/compose.yaml, nginx; Jonathan creates DNS A record and runs certbot. |
| ListMonk admin user + list config | Jonathan | — | ~2 hr | ListMonk web UI. Initial admin user, default list, transactional templates. |
| Twenty Workflow: Donor.created → ListMonk | Both | ~20K | ~3 hr | Twenty Workflow built in UI; Claude writes the HTTP-call configuration snippet and tests it. |
| CF Worker: ListMonk unsubscribe → Twenty | Claude | ~40K | ~1 day | Thin stateless Worker. Signature verification + PATCH to Twenty Person record. |
Claude Code agents and skills
- Explore — mapping the existing CBF-site lib/api.ts and contact form before editing
- test-driven-development — for the proxy route and Worker (boundary code; tests cheap, regressions expensive)
- verification-before-completion — run the verification commands in CLAUDE.md after each deploy step
Critical-path callouts
- The data-model extensions (RecurringAgreement, etc.) must ship on dev before Phase 3 starts; Phase 3 depends on them.
- Test the proxy route on dev fully before flipping
USE_TWENTY=truein prod — the GiveLively static-JSON path remains the fallback.
Donation processing — Donorbox, intake service, matching library
| Task | Owner | Tokens | Time | Notes |
|---|---|---|---|---|
| Donorbox 501(c)(3) account verification | Jonathan | — | ~2 hr + wait | Application + EIN docs. 7–15 business days for approval. Start early; gates the rest of the phase. |
| Stripe nonprofit rate (2.2% + 30¢) application | Jonathan | — | ~1 hr + wait | Run in parallel with Donorbox verification. |
| Connect Stripe to Donorbox | Jonathan | — | ~30 min | Browser OAuth flow. |
| Donorbox donation forms + receipt templates | Both | ~30K | ~4 hr | Jonathan configures in Donorbox UI; Claude writes the brand-asset notes (navy + gold) and embed-on-CBF-site code. |
@nonprofit-crm/matching — scaffold + types |
Claude | ~80K | ~2 days | New npm package. DonorRecord, MatchResult, dedup-client adapter interface. TDD from the start. |
@nonprofit-crm/matching — resolution logic |
Claude | ~150K | ~3–4 days | Email → external ID → name+city → name-only. Each signal a separate testable function. Fixtures from anonymized GiveLively data. |
Matching CLI (check-import.ts) |
Claude | ~50K | ~1 day | One-shot reconciliation pass over GiveLively historical data. Output: report of definitive/high/medium/none matches. |
| Historical reconciliation dry run | Jonathan | ~10K | ~3 hr | Review CLI output; spot-check the medium-confidence and no-match buckets. Decide whether to merge by hand or stage. |
cbf-intake-service — project scaffold |
Claude | ~120K | ~3 days | Node/TS service, Express or Fastify, Postgres (separate schema in Twenty DB initially). Dockerfile + compose entry. |
| Staging table + event-ID idempotency ledger | Claude | ~80K | ~2 days | Schema modelled on James's GiftStagingRecord. Migrations via node-pg-migrate or similar. |
| Donorbox webhook receiver + signature verify | Claude | ~120K | ~3 days | Test with Donorbox sandbox before live. Idempotent on Donorbox event ID. |
| Normalizer + promote-or-stage decision path | Claude | ~150K | ~3–4 days | Calls matching library; high-confidence → Twenty REST POST; low-confidence → staging row with diagnostics. |
| Background retry worker | Claude | ~80K | ~2 days | Exponential backoff, Retry-After honoring on 429s. BullMQ or a simple in-process loop initially. |
| Donorbox webhook URL configured | Jonathan | — | ~30 min | Point Donorbox webhook to intake.crm.cloudbase.foundation/webhooks/donorbox. |
| End-to-end Donorbox sandbox testing | Both | ~80K | ~1 week | Real donations in sandbox, verify Twenty rows appear with correct linkage. Iterate on edge cases. |
| Recurring donor migration communications | Jonathan | ~10K | ~3–4 hr | Draft + send notification to existing GiveLively recurring donors. Claude can draft the email copy. |
| CBF-site: redirect GiveLively URLs to Donorbox | Claude | ~20K | ~3 hr | Next.js redirects in next.config.js or middleware. |
| GiveLively final export + archival | Jonathan | ~5K | ~2 hr | Final CSV. Reconciliation pass. Keep GiveLively account read-only for 90 days as fallback. |
| Production cutover | Both | ~30K | ~1 day | Flip live Donorbox webhook, monitor first 50 transactions closely. Have a rollback plan ready (point Donorbox at staging). |
Claude Code agents and skills
- writing-plans — both the matching library and the intake service deserve formal plans before execution
- executing-plans — subagent-driven execution for the matching library's testable functions in parallel
- test-driven-development — non-negotiable for the matching library; correctness is foundational
- Explore — reading James's
nonprofit-crm-fundraising-servicesource as a reference - systematic-debugging — webhook edge cases (replays, partial payloads, signature mismatches) will surface bugs
- using-git-worktrees — matching library and intake service can be developed in parallel branches
- dispatching-parallel-agents — for independent unit-test suites within the matching library
Critical-path callouts
- Start Donorbox + Stripe applications on day one of Phase 3. The 10–15 day approval windows are real and not parallelizable with code work that depends on real webhook payloads.
- Build the matching library first. The intake service depends on it. The CLI is a forcing function to harden it before background flows.
- Do not skip TDD on the matching library. Mis-matches in production are extraordinarily expensive to unwind — donor records linked to the wrong person, donations counted twice, ListMonk emails to the wrong human.
Background data integrity
| Task | Owner | Tokens | Time | Notes |
|---|---|---|---|---|
| Review queue UI — backend endpoints | Claude | ~80K | ~2 days | REST endpoints over the staging table: list, approve, merge, reject. |
| Review queue UI — frontend | Claude | ~150K | ~4 days | Small admin-only React or HTMX surface on the intake service. Same CBF brand language. |
| Approval → Twenty REST promotion path | Claude | ~50K | ~1 day | Critical: approval must go through the same REST endpoints as live intake so workflows (ListMonk sync) fire. |
| Dedupe sweep job | Claude | ~60K | ~2 days | Daily cron in intake service. Scans Twenty Person records via REST. Surfaces candidates in same review queue. |
| Recurring lifecycle handlers | Claude | ~80K | ~2–3 days | Subscription created / renewed / failed / cancelled events → RecurringAgreement updates. |
| Rollup recompute (totalDonated, firstDonation) | Claude | ~30K | ~1 day | Decide: Twenty Workflow on Donation.created/updated, or nightly job in sweep. Treat as derived, never authoritative. |
| Initial review-queue validation | Jonathan | ~10K | ~6–8 hr over 2 weeks | Work through the first weeks' staging queue with Claude. Build muscle memory and refine thresholds. |
Claude Code agents and skills
- frontend-design — review queue UI deserves a polished, distinctive design rather than generic admin scaffolding
- test-driven-development — promotion path correctness is high-stakes
Volunteer tool: OSS-ification & Twenty integration
The app already exists at chelancomps.org (React 19 + Vite + Supabase + Resend + Cloudflare Pages, repo: Cloudbase-Foundation/chelan-comps). Phase 4 is not a greenfield build. It is two narrower tracks: generalize the codebase for other comp organizers to fork-and-deploy, and add an optional Twenty integration so CBF's CRM gets visibility into volunteer pipelines.
| Task | Owner | Tokens | Time | Notes |
|---|---|---|---|---|
| Audit codebase for Chelan-specific assumptions | Claude | ~40K | ~1 day | Explore agent across chelan-comps; produce a list of hard-coded values, schema assumptions, and Resend templates that need extraction. |
| Extract per-event configuration | Claude | ~70K | ~2–3 days | Build on existing config/event.ts pattern. Event name, dates, roles, branding tokens, email templates, support contacts — all config-driven. |
| Generalize branding / theming | Claude | ~50K | ~2 days | Tailwind tokens overridable per deployment; replace Chelan-specific imagery with neutral defaults; theme docs. |
| Self-host setup documentation | Claude | ~50K | ~2 days | End-to-end: Supabase project creation, migrations, Edge Function deployment, Resend setup, Cloudflare Pages deployment, config file customization. |
| License, CONTRIBUTING, code of conduct, public README | Claude | ~25K | ~1 day | OSS hygiene. Jonathan picks the license (MIT or Apache 2.0 likely). |
| Decide Twenty integration scope | Both | ~20K | ~3 hr | Brainstorming session: do volunteer applicants become Twenty Person records, or only the comp organizer? Define the contract. |
| Twenty sync layer (optional, feature-flagged) | Claude | ~80K | ~3–4 days | Supabase trigger or Edge Function → cbf-intake-service. Reuses the matching library with intakeSource: 'volunteer'. Opt-in per deployment via env var. |
Docs site — volunteers.cloudbase.foundation |
Claude | ~50K | ~2 days | Tutorial-driven: "Set up your own comp's volunteer system in 45 minutes." Mirrors the brand language of cloudbase.foundation. |
| Flip repo from private to public | Jonathan | — | ~30 min | GitHub settings. Verify no secrets in history first (Claude scans before flip). |
| Pre-flip secret-history scan | Claude | ~15K | ~1 hr | gitleaks or equivalent across the full history. Document any rotations needed. |
| Resources page enhancement on CBF-site | Claude | ~30K | ~3 hr | Chelan case study, screenshots, link to docs site, "Get help setting up" form → Twenty Project Submission. |
| Recruit fork-adopter comp organizers | Jonathan | — | ~5–10 hr | Outreach to 2–3 other paragliding/HG comp organizers; offer help with their first deployment. Real-world fork tests find what docs miss. |
Claude Code agents and skills
- Explore — first action in the phase; map what Chelan-specific code actually looks like before changing anything
- brainstorming — specifically for the Twenty integration scope decision
- writing-plans — for the de-Chelanification refactor; touches many files and benefits from up-front design
- test-driven-development — only where the existing repo already has Vitest coverage; this is a refactor, not greenfield
- frontend-design — for the public-facing docs site at
volunteers.cloudbase.foundation
Critical-path callouts
- This phase no longer blocks on pilot recruitment. The 2026 Chelan comp is the production pilot. That assumption from Rev. 1 is dropped.
- Twenty integration is genuinely optional — the OSS adopter shouldn't be forced to run a CRM. Build it as a feature-flagged addition, not a hard dependency.
- Secret-history scan before going public. Always. Even if the repo is "clean," verify with a tool.
Tina CMS expansion
| Task | Owner | Tokens | Time | Notes |
|---|---|---|---|---|
| Past projects collection schema | Claude | ~25K | ~4 hr | Tina collection: photos, impact metrics, story, location. |
| Board headshots media manager setup | Claude | ~15K | ~2 hr | Tina media field on board roster items. |
| News post featured images | Claude | ~10K | ~2 hr | Schema field + frontend. |
| Homepage featured-projects selector from Twenty | Claude | ~30K | ~6 hr | Pulls candidate projects from Twenty; Tina picks which to feature. Depends on Phase 2 integration. |
| Past project content entry | Jonathan | — | ~10–20 hr | Real writing work: stories, impact metrics, photo curation. Cannot be Claude-generated. |
Donor communications
| Task | Owner | Tokens | Time | Notes |
|---|---|---|---|---|
| Donorbox receipt template brand customization | Jonathan | ~10K | ~3 hr | In Donorbox UI. Claude provides brand-token reference + HTML/CSS snippets. |
| Donorbox year-end summary template | Jonathan | ~10K | ~2 hr | Same approach. |
SPF / DKIM / DMARC for cloudbase.foundation |
Both | ~15K | ~2 hr | Claude generates DNS records; Jonathan creates them in Cloudflare. Test via mail-tester.com. |
| ListMonk branded HTML newsletter template | Claude | ~30K | ~1 day | Email-safe HTML; tested in Litmus or similar. |
| Lapsed donor re-engagement campaign | Both | ~15K | ~3 hr | Claude drafts copy; Jonathan reviews + sends. |
| New project announcement template | Both | ~10K | ~2 hr | ListMonk campaign template + dynamic content from Twenty. |
IV.Agent & skill reference
A quick reference for which Claude Code agents and skills are most useful for which kinds of work. This is the working pattern for the remaining phases.
Skills (process)
- brainstorming — before any new feature or design
- writing-plans — for multi-day builds with clear scope
- executing-plans — structured implementation from a written plan
- subagent-driven-development — parallel independent tasks (e.g., multiple matching signals)
- test-driven-development — correctness-critical work (matching library, promotion path)
- systematic-debugging — webhook edge cases, race conditions, signature mismatches
- verification-before-completion — before claiming work is done; runs verification commands
- using-git-worktrees — for parallel work on independent components
- requesting-code-review — before major merges
Agents (specialist subagents)
- Explore — codebase research; reading James's stack patterns; finding existing utilities to reuse
- Plan — design implementation strategies for new components
- frontend-design — review queue UI, volunteer app, branded templates
- claude-api — if any AI features land (e.g., donor insight summarization)
- general-purpose — multi-step tasks that don't match a specialist
Operating cadence
- One workstream per session. Don't interleave Phase 2 droplet work with Phase 3 matching-library code in the same Claude session; context bleed makes both worse.
- Start each phase with a plan. Brainstorm → write the plan to disk → have Jonathan review → execute. The plan is the contract; mid-execution drift wastes tokens.
- Verify before declaring done. The verification-before-completion skill exists because untested claims of completion are how regressions happen.
- Commit often, push less often. Each meaningful unit gets its own commit. Push when the unit is verified and the user has approved.
- Hard problems get fresh sessions. If a debugging loop has run 60K+ tokens without progress, start a new session with a clean transcript and the systematic-debugging skill.
V.Aggregate budget
| Phase | Claude tokens | Jonathan hours | Calendar weeks | Dominant cost driver |
|---|---|---|---|---|
| Phase 2 — CRM prod & pipeline | ~250K | 12–18 | 6–8 | Many small integrations; light on individual depth |
| Phase 3 — Donations | ~1.0M | 18–25 | 10–14 | Matching library + intake service are the two big builds |
| Phase 3.5 — Data integrity | ~400K | 10–15 | 5–7 | Review queue UI is the largest single piece |
| Phase 4 — Volunteer OSS & Twenty integration | ~400K | 10–15 | 6–8 (parallel) | Refactor + docs of an existing production app; not a greenfield build |
| Phase 5 — Tina expansion | ~80K | 10–20 | 2–3 | Content writing, not code, dominates Jonathan's time |
| Phase 6 — Donor comms | ~80K | 10–15 | 2–3 | Brand customization in vendor UIs |
| Total (rough) | ~2.2M | 70–108 | ~9–12 mo | With Phase 4 in parallel; sequential would be ~12–15 months |
Token estimates assume Claude Code Opus 4.7. A meaningful share of those tokens is cache-hit (the project context is largely the same across sessions in a phase), so actual billable tokens may be 40–60% of the headline figures. Calendar estimates assume Jonathan can sustain ~5–10 focused hours/week on CBF tech; longer pauses extend the calendar but not the token budget.
VI.External dependencies & gates
| Dependency | Gates | Lead time | Action |
|---|---|---|---|
| Donorbox 501(c)(3) verification | Phase 3 | 7–15 days | Apply on day 1 of Phase 3. EIN docs in hand. |
| Stripe nonprofit-rate approval | Phase 3 (cost) | 5–10 days | Apply in parallel with Donorbox. Doesn't block code work, only affects fee math. |
| DigitalOcean production droplet | Phase 2 | ~1 hr | Spin up first thing in Phase 2. No approval needed. |
| DNS propagation for new subdomains | Phase 2 (ListMonk), Phase 3 (intake) | ~1–24 hr | Cloudflare is typically minutes, but plan for next-day buffer before scheduling certbot. |
| Fork-adopter comp organizers (Phase 4) | Phase 4 validation | 2–3 months | Not blocking — the 2026 Chelan comp is the production pilot. But recruiting 2–3 other organizers to attempt a fork-and-deploy is the strongest validation that the de-Chelanification work is complete. Outreach is a Jonathan task. |
| Board approval for production spend | Phase 2 (prod droplet) | varies | $24/mo droplet + ~$17/mo Donorbox API. Check whether this needs to clear the board ahead of Phase 2 kickoff. |
VII.Recommended next action
Start Phase 2 with two parallel threads:
- Jonathan track — provision the production droplet, configure DNS for
crm.cloudbase.foundation, and (in parallel) submit the Donorbox 501(c)(3) verification and Stripe nonprofit-rate applications. The Donorbox/Stripe applications gate Phase 3 and have multi-week lead times; submitting them during Phase 2 means the approvals land just as Phase 3 starts. - Claude track — land the data-model extensions on dev (
RecurringAgreement, expanded Donation fields,receiptStatus,Partner) so they ship before Phase 3 begins. Then build the CBF-site ↔ Twenty REST proxy.
The first concrete Claude session to schedule: writing the plan for the matching library, even though execution is weeks away. Having the plan written early lets Jonathan review it during the Donorbox approval wait, and surfaces design questions early enough to be answered without blocking.