gondolier — Roadmap
gondolier — Roadmap
Section titled “gondolier — Roadmap”Last updated: 2026-08-10
Production readiness audit: See PROD_READINESS.md for the comprehensive go-live gap analysis with dispatch-ready workstreams, acceptance criteria, and parallizability annotations.
Live Now
Section titled “Live Now”| What | Where | Status |
|---|---|---|
| Worker API | https://gondolier.laputa-cloud-co.workers.dev |
✅ Running |
| Custom domain gondolier.dev | ✅ Pointing to Pages (propagating) | |
| REST API | GET/POST /api/v1/tenants + CRUD |
✅ Working |
| Lease DO | Per-(tenant,repo) lease | ✅ Working (fix applied) |
| Rate limiter | KV-based, 100 req/window | ✅ Working |
| Sell site stub → Pages | ✅ Deployed at gondolier.dev (DNS updated) | |
| Dashboard stub | templates/dashboard.html in repo |
✅ Deployed at https://scaffold-shunt-integration.gondolier-dashboard.pages.dev (static only) |
| Cron trigger | */5 * * * * |
✅ Wired (handler complete) |
| Rate-limited batch | Max 50 repos/cron tick | ✅ Wired |
Sell site and dashboard now deployed to Pages. See entries above.
Sell site deployed to Pages at https://gondolier-site.pages.dev/. Custom domain gondolier.dev still points to the Worker — needs DNS migration to Pages.
Architecture Change: Webhooks > Cron Polling
Section titled “Architecture Change: Webhooks > Cron Polling”Decision: The queue engine should be webhook-driven, not cron-poll-driven.
| Cron Polling (current) | Webhooks (target) | |
|---|---|---|
| Trigger | Every 5 minutes, iterate all repos | Forgejo/Gitea pushes events |
| Latency | Up to 60s | Sub-second |
| Compute waste | Runs reconciliation ticks every 5 minutes | Only processes changed repos |
| Cron role | Primary engine | Reconciliation safety net only |
| LeaseDO role | acquire/check/release per tick | process_event per webhook |
Webhook event routing
Section titled “Webhook event routing”| Event | Action |
|---|---|
push |
New commit on a PR → re-evaluate gate |
pull_request.opened/reopened/ready_for_review |
Join queue |
pull_request.closed/cancelled |
Leave queue |
check_run / check_suite |
CI result → gate decision |
status (legacy) |
CI status → gate decision |
Active Blockers
Section titled “Active Blockers”| # | Blocker | Status | Impact |
|---|---|---|---|
| B1 | Webhook architecture redesign | Resolved ✅ | — |
| B2 | Sell site not deployed to Pages | Resolved ✅ | — |
| B3 | Dashboard not deployed or wired | Done | Deployed to Pages (static template — needs worker wiring for template rendering) |
| B4 | No auth (GitHub OAuth + JWT) | Resolved ✅ | Stub auth wired (redirect, callback, JWT session, /me, /logout) |
| B5 | No billing (Stripe) | Resolved ✅ | Stub billing wired (/checkout, /portal, /stripe/webhook) |
| B6 | No CI/CD pipeline | Resolved | Manual deploys → CI runs on PR/main |
| B7 | No JS test suite for index.mjs |
Done ✅ | 12 tests covering routes, auth, CORS, LeaseDO |
Active Tasks
Section titled “Active Tasks”T1: Webhook-driven queue (replaces cron polling)
Section titled “T1: Webhook-driven queue (replaces cron polling)”- Webhook endpoint:
POST /api/v1/webhooks/forgejo - Forgejo webhook signature verification
- Event router (map Forgejo events → engine actions)
- LeaseDO:
process_eventper webhook - Cron reconciliation safety net (rate-limited, max 50 repos/tick)
- Shunt engine port to JS (
shunt-engine.mjs) — batch-then-bisect algorithm - Shunt engine wired into LeaseDO reconcile handler
- Cron handler passes repo config (token, owner, base, status_context, merge_style) to engine
Engine features: discovers ready PRs via automerge state, builds staging branches via Forgejo Git API (cherry-pick), polls CI status, lands PRs via native automerge, bisects failing batches.
T2: Sell site deployment
Section titled “T2: Sell site deployment”- Review
site/index.htmlcontent (exists, ~566 lines) - Create Cloudflare Pages project for sell site
- Deploy
site/as Pages site athttps://gondolier-site.pages.dev/ - Redesign from SaaS template to engineering-tool aesthetic (IBM Plex Mono, amber/green palette, ~180 lines)
- Verify custom domain TLS (
gondolier.devstill points to Worker)
Completed: 2026-08-04 — deployed to gondolier-site.pages.dev
T3: Dashboard deployment
Section titled “T3: Dashboard deployment”- Review
templates/dashboard.html(exists, ~7040 bytes) - Create Cloudflare Pages project for dashboard
- Deploy to
https://scaffold-shunt-integration.gondolier-dashboard.pages.dev - Redesign dashboard to match sell site aesthetic (monospace, terminal palette)
- Wire dashboard HTML into worker for Go template rendering
Completed: 2026-08-04 — cron reconciliation handler wired
T4: GitHub OAuth + JWT sessions
Section titled “T4: GitHub OAuth + JWT sessions”- Register GitHub OAuth app
- Implement
GET /auth/github(redirect) - Implement
GET /auth/github/callback(token exchange, session creation) - Implement JWT session cookies (httpOnly, 30-day TTL)
- Implement
GET /api/v1/me - Implement
POST /api/v1/logout - Replace stub auth with real GitHub OAuth integration
T5: Billing
Section titled “T5: Billing”- Set up Stripe account + test mode
- Implement
POST /api/v1/billing/checkout - Implement
POST /api/v1/billing/portal - Implement
POST /api/v1/stripe/webhook - Wire billing tiers to repo/pr limits
- Replace stub billing with real Stripe integration
T6: CI/CD
Section titled “T6: CI/CD”- Create
.forgejo/workflows/ci.yaml - Workflow: vet → test → build → workers-check on PR
- Workflow: deploy to preview on merge to main
- Automated wrangler deploy dry-run in CI
T7: JS test suite
Section titled “T7: JS test suite”- Set up Vitest or BDD test framework for Workers
- Test route handling (all endpoints)
- Test auth middleware
- Test rate limiter
- Test LeaseDO (via local DO simulation)
Completed: 2026-08-04 — 12 tests via wrangler test
T8: Go Cloudflare Workers engine (replaces JS worker)
Section titled “T8: Go Cloudflare Workers engine (replaces JS worker)”Replace index.mjs + shunt-engine.mjs with native Go Workers compiled from main.go, using the shunt mq.Engine directly.
Status: ✅ Implemented — main.go replaces index.mjs + shunt-engine.mjs
Phase 1 — Build Go engine (parallel with JS):
- Update
internal/engine/engine.goto usemq.Config(public shunt API) - Create
internal/checkpoint/d1store.go— D1-backedCheckpointStore - Create
internal/lease/dolease.go— Durable ObjectQueueLease - Create
main.go— HTTP router, fetch handler, cron entrypoint - Update
wrangler.tomlfor Go build (build.command = "go build -target=cfworker") - Verify
go build -target=cfworkersucceeds -
go vet ./... && go test ./...clean
Phase 2 — Replace JS API routes:
- Implement all API handlers in Go (tenant CRUD, connections, repos, audit, queue state)
- Implement auth middleware in Go
- Wire Go Worker to handle
/api/v1/*via Workers routing - Blue-green deploy: Go alongside JS, route
/api/v1/*→ Go - Test all endpoints via curl
- Monitor error rates, switch back to JS if needed
Phase 3 — Replace webhooks and cron:
- Implement webhook HMAC verification in Go
- Implement cron reconciliation handler in Go (
engine.ReconcileAll) - Go Worker sends events to LeaseDO via fetch()
- Delete
index.mjsandshunt-engine.mjs - Keep
lease-do.mjs(LeaseDO must remain JS)
Phase 4 — Cleanup:
- Remove
shunt-engine.mjsandindex.mjsfrom repo - Update
go.mod(go mod tidy) - Update CI/CD pipeline (
.forgejo/workflows/ci.yaml) for Go build - Final
wrangler deploy - Update this roadmap
Key facts:
- Shunt engine interface:
mq.New(&mq.Config{...}, ForgeClient, Stager)→Engine.Reconcile(ctx) error internal/forge/forge.goalready implementsmq.ForgeClient(all 11 methods)internal/gitops/stager.goalready implementsmq.Stager(BuildStaging)internal/lease/lease.gohasManagerinterface — extend for D1 checkpoint + LeaseDO leasenet/httppolyfills to Workersfetch()on Cloudflare Workers Godatabase/sqlNOT polyfilled — use D1 binding directly
Risks:
net/httppolyfill status on Workers Go — test first with a simplehttp.Get()- D1 access from Workers Go — may need
fetch()to D1 REST API ifdatabase/sqlunavailable - WASM startup latency (~100-300ms) — negligible for cron ticks, important for HTTP latency
- No background goroutines in Workers — all work must complete within request/cron timeout
Documentation
Section titled “Documentation”| Doc | Path | Scope |
|---|---|---|
| System architecture | ARCHITECTURE.md | Data flow, encryption, DB schema, failure modes |
| Webhook design | WEBHOOK_DESIGN.md | Event types, HMAC verification, cron reconciliation |
| Lease management | LEASING.md | LeaseDO protocol, TTL, edge cases |
| Security model | SECURITY.md | Encryption, auth, OAuth2, rate limiting |
| API reference | API.md | All REST endpoints + webhook endpoint |
| Deployment guide | DEPLOYMENT.md | Cloudflare, Supabase, CI/CD, rollback |
| Development guide | DEVELOPMENT.md | Local setup, testing, debugging |
Docs index (cross-references)
Section titled “Docs index (cross-references)”| Doc | Cross-references |
|---|---|
| ARCHITECTURE.md | Links to all other docs |
| WEBHOOK_DESIGN.md | ARCHITECTURE, LEASING, SECURITY |
| LEASING.md | ARCHITECTURE, WEBHOOK_DESIGN, SECURITY |
| SECURITY.md | ARCHITECTURE, LEASING, WEBHOOK_DESIGN |
| API.md | ARCHITECTURE, SECURITY |
| DEPLOYMENT.md | ARCHITECTURE, SECURITY |
| DEVELOPMENT.md | ARCHITECTURE, DEPLOYMENT |
Design docs (referenced, not maintained here)
Section titled “Design docs (referenced, not maintained here)”| Doc | Scope |
|---|---|
| design.md | Product/infrastructure decisions (non-architectural) |
| IMPLEMENTATION.md | Phase-based implementation plan |
| SHUNT_FORK_SPEC.md | Interface abstraction for shunt engine |
| MVP_PLAN.md | MVP launch plan with phases |
| TODOS.md | Task tracker (operational) |
Development convention docs:
| Doc | Scope |
|---|---|
| development/agent-workflow.md | Git/worktree workflow |
| development/code-conventions.md | Go/JS code conventions |
Completed
Section titled “Completed”| # | Task | Date |
|---|---|---|
| D1 | Scaffold shunt integration (PR #2) | 2026-08-03 |
| D2 | Supabase migrations 001-003 (8 tables) | 2026-08-03 |
| D3 | KV namespace provisioned | 2026-08-03 |
| D4 | Cloudflare Worker deployed | 2026-08-03 |
| D5 | DNS CNAME configured | 2026-08-03 |
| D6 | Cloudflare Secrets injected | 2026-08-03 |
| D7 | Native JS REST API (index.mjs) | 2026-08-03 |
| D8 | All API endpoints working (tenants, connections, repos CRUD) | 2026-08-03 |
| D9 | Auth middleware (SHA-256 key hash) | 2026-08-03 |
| D10 | Rate limiter (KV-based) | 2026-08-03 |
| D11 | Wrangler.toml: DO binding, migration v1, cron trigger | 2026-08-03 |
| D12 | LeaseDO exported from entrypoint | 2026-08-04 |
| D13 | LeaseDO acquire/release/check verified working | 2026-08-04 |
| D14 | CI/CD pipeline (forgejo Actions) | 2026-08-04 |
| D15 | Sell site deployed to Cloudflare Pages | 2026-08-04 |
| D16 | Dashboard deployed to Pages | 2026-08-04 |
| D17 | JS test suite for index.mjs (12 tests) |
2026-08-04 |
| D18 | UI redesign — sell site + dashboard (monospace, amber/green palette) | 2026-08-04 |
| D19 | Webhook architecture — POST /api/v1/webhooks/forgejo, LeaseDO process_event, cron reconciliation |
2026-08-04 |
| D20 | Comprehensive documentation (ARCHITECTURE, WEBHOOK_DESIGN, LEASING, SECURITY, API, DEPLOYMENT, DEVELOPMENT) | 2026-08-04 |
| D21 | Stub auth endpoints — /auth/forgejo redirect, /auth/callback JWT session, /api/v1/me, /api/v1/logout |
TODAY |
| D22 | Stub billing endpoints — /api/v1/billing/checkout, /api/v1/billing/portal, /api/v1/stripe/webhook |
TODAY |
| D24 | Go Workers engine — main.go (HTTP router, auth, CRUD, webhook, cron, lease forwarding, billing stubs), internal/worker/webhook.go (HMAC verification, Forgejo event routing), shunt mq.Engine wired for reconciliation |
TODAY |