The era2c repository is the operational center for the Eco-Restoration Alliance's membership management, autonomous AI collaboration, and community data systems.
All work flows through GitHub Issues on the ERA Development project board. A listener script runs every 3 minutes and automates the pipeline end-to-end.
Five columns:
Backlog → In Progress → Testing → Deployed → Retired
For routine work (bug fixes, docs, infra cleanup) labeled auto-merge:
- Issue lands in Backlog — created by Jon, CTO, or the file watcher
- Listener picks it up → moves to In Progress, spawns a Claude worker (Sonnet)
- Worker writes code → opens a PR on branch
issue/NNN - Listener spawns a reviewer (Opus) to evaluate the PR
- Reviewer PASS → listener auto-merges, waits for Render deploy, runs smoke tests
- Card moves to Deployed — Jon's review queue
- Jon comments "retire" → listener moves to Retired and closes the issue
For features or anything needing Jon's sign-off (no auto-merge label):
Steps 1-4 are the same, then:
- Reviewer PASS → listener posts "Ready for Review" comment with PR link and live URL
- Card moves to Testing — waiting for Jon
- Jon comments "approved" (or "lgtm", "ship it") → listener merges, deploys, smoke tests
- Card moves to Deployed → Jon comments "retire" when satisfied
| Label | Effect |
|---|---|
auto-merge |
Skip Jon's approval, merge on reviewer PASS |
needs-discussion |
Listener skips entirely — blocked on Jon's input |
| (no label) | Normal flow with Jon's approval gate in Testing |
- Create issues — describe what you want
- Add
auto-mergeif it's safe to ship without review - Comment "approved" on Testing items to trigger deploy
- Comment "retire" on Deployed items to clear them
- Add
needs-discussionto pause anything
Everything else is automated.
The listener also runs cleanup sweeps each cycle:
- Orphaned issues (not on board) → added to Backlog
- Closed issues in active columns → moved to Deployed
- Merged/closed PRs in active columns → moved to Deployed/Retired
- Duplicate PR entries (backing issue already tracked) → removed
needs-discussionissues in In Progress → demoted to Backlog- OPEN issues in Retired → moved back to Backlog
era2c/
├── CLAUDE.md ← CTO instructions (read this first)
├── era2/ ← Membership engine (attendees → members → donors)
│ ├── lib/ ← Core libraries (db, email, docs, sheets)
│ ├── scripts/ ← Operational scripts (followups, sync, search)
│ ├── data/ ← SQLite database (gitignored)
│ ├── website/ ← Static site deployed to Render
│ └── bigmap2/ ← BigMap2 source (synced to website/)
├── claude_collaborator/ ← CLCL autonomous email assistant
│ ├── startup.py ← Check email/docs on startup
│ └── clcl_email_listener.py ← Wake listener (launchd)
├── dashboard/ ← Web UI for monitoring
│ ├── server.py ← Python API server (port 8080)
│ └── xterm/server.js ← Browser terminal (port 3000)
├── scripts/ ← System scripts
│ ├── gh_listener.py ← GitHub Issues listener (the pipeline)
│ ├── board_view.py ← Quick board state viewer
│ ├── boot_check.sh ← Post-reboot health check
│ └── issue_from_download.py ← File watcher: markdown → GitHub issues
├── docs/ ← Architecture docs and guides
│ └── knowledge/ ← Strategic context (from Claude.ai analysis)
└── .claude/ ← Session state and hooks
├── hooks/ ← SessionStart, SessionEnd, PreCompact
└── handoff/ ← Session handoff notes
Archived code: Retired components (Dispatcher, Narrator, beads, ERA_Landscape, historical data) are preserved at jonschull/era2c-archive.
Jon (Captain) — sets direction, approves, retires
│
▼
CTO (Claude) — architecture, triage, code review, merge authority
│
▼
Listener — automated pipeline: pick up work, spawn workers, deploy
│
▼
Workers (Sonnet) — implement one issue at a time on a branch
Key rule: Workers recommend, CTO merges. The listener has merge authority for auto-merge items. Normal items require Jon's explicit approval.
| Service | Mechanism | Schedule |
|---|---|---|
| GH Issues listener | launchd | Every 3 min |
| GH Issues watchdog | launchd | Every 15 min |
| CLCL email listener | launchd | Continuous |
| Dashboard + xterm | pm2 | Ports 8080, 3000 |
| Database sync | cron | Daily 5am |
| Cloud backup | cron | Daily 6am |
| Fathom sync | cron | Daily 4am |
| Render health check | cron | Daily 8am |
All deploy from main on push:
| Service | Type | URL |
|---|---|---|
| era2 | Web service | https://era2.onrender.com |
| era-website | Static site | https://era-website.onrender.com |
| era2-followup | Cron (daily 2pm) | — |
# Board and listener
python3 scripts/board_view.py # View project board
python3 scripts/gh_listener.py --dry-run # Listener dry run
tail -50 scripts/gh_listener.log # Listener logs
# GitHub
gh issue list # Open issues
gh issue create --title "..." --body "..." # New issue
# Services
pm2 list # Dashboard status
~/era2c/scripts/boot_check.sh # Full health check
# ERA2 operations
cd ~/era2c/era2
python3 ../scripts/board_view.py # Board from anywhere- Local dev:
era2/data/era2_dev.db(SQLite) - Production: PostgreSQL on Render (via
DATABASE_URL) - Key tables:
participants(911),events(105),event_attendance(1982),calls(1817),projects(286) - Sync: Daily SQLite → PostgreSQL via
scripts/sync_databases.py
Claude.ai (Jon's conversation partner with 2+ years of strategic context) can communicate with CTO sessions via tmux:
- Read:
tmux capture-panefrom the browser terminal - Write:
tmux send-keyswithC-m(not Enter) - File watcher: Claude.ai drops
claude-ai-issue-*.mdin~/Downloads→ launchd → GitHub issues
This bridges strategic conversation context with operational execution.
For CTO-specific instructions see CLAUDE.md. For ERA2 membership system details see era2/CLAUDE.md.
Last updated: 2026-02-25