CarbonPlan Roadmap¶
Team Assignment¶
| Agent | Focus Area | Tasks |
|---|---|---|
| @alpha | Platform & Ingestion | 001, 002, 003, 004, 005, 009, 011 |
| @bravo | Billing & Compliance | 006, 007, 008, 010, 012, 013 |
Epic 0: Foundation P0 — DONE¶
- 000-foundation — Core infrastructure
- Config (pydantic-settings), async SQLAlchemy+asyncpg, Clerk JWT auth, Secrets Manager client, error classification, all 11 ORM models, Alembic migrations, health endpoint, CORS/correlation-ID middleware
Epic 1: Provider Connections P0¶
Connect AI provider accounts (OpenAI, Anthropic, OpenRouter) with API key validation, Secrets Manager encryption, and connection lifecycle management.
- 001-provider-connectors
@alpha - Connector Protocol (
validate_key,poll_usage,map_tokens) + three adapters:- OpenAI: admin key,
/v1/organization/usage, all input uncached - Anthropic: three-way token split
- OpenRouter: all input uncached
- OpenAI: admin key,
- Files:
app/connectors/{base,openai,anthropic,openrouter}.py -
Blocked by:
000-foundation -
002-connection-api
@alpha - ConnectionService: create/list/get/delete/sync/remap
- API:
POST,GETlist,GETby id,DELETE,POST /{id}/sync,PUT /{id}/project - Error classification: transient retry with backoff, permanent stop at 5 consecutive failures
- Files:
app/services/connection_service.py,app/schemas/connections.py,app/api/v1/connections.py - Blocked by: 001
Epic 2: Telemetry Pipeline P0¶
Core value loop: hourly polling, idempotent ingestion, emissions calculation (tokens to energy to CO2), trailing reconciliation, and dashboard query endpoints.
- 003-telemetry-ingestion
@alpha - TelemetryService:
ingest_events(SHA-256 idempotency hash, upsert ON CONFLICT),get_summary,list_events,list_models - EmissionsEngine:
calculate(event)— fnmatch model-to-tier, three-phase energy calc (prefill/decode/cached), kWh, CO2 with PUE and uncertainty bounds - Seed script for CarbonFactors v1.0
- Files:
app/services/{telemetry_service,emissions_engine}.py,app/scripts/seed_factors.py -
Blocked by:
000-foundation -
004-telemetry-jobs
@alpha - ARQ WorkerSettings with redis config and
cron_jobs poll_all_connections: iterate active connections, fetch key, callconnector.poll_usage(), ingest, calculate emissions, update cursor, handle errorstrailing_reconciliation: daily 03:00 UTC, re-poll last 24h- Files:
app/jobs/{worker,poll_usage,reconciliation}.py -
Blocked by: 001, 003
-
005-telemetry-api
@alpha— MVP MILESTONE - Telemetry schemas and API router
GET /summary(total CO2, per-model, daily chart, cached vs uncached)GET /events(paginated)GET /models(aggregated)- Date range and
project_idfilters - Files:
app/schemas/telemetry.py,app/api/v1/telemetry.py - Blocked by: 003
Epic 3: Billing & Receipts P1¶
Revenue path: Stripe subscription tiers, billing period lifecycle, T+48h deferred receipt generation, Ed25519 signing, branded PDF output, public verification.
- 006-billing-stripe
@bravo - BillingService:
create_checkout_session,get_billing_status,handle_webhook,create_portal_session,ensure_billing_period - Webhooks:
invoice.payment_succeeded(closing),payment_failed(failed), subscription events - Stripe signature verification
- Files:
app/services/billing_service.py,app/schemas/billing.py,app/api/v1/billing.py -
Blocked by:
000-foundation -
007-carbon-receipts
@bravo - ReceiptService: Ed25519 signing (PyNaCl, SHA-256 payload hash, key versioning)
generate_receipt: aggregate CO2, retire credits, serialCL-YYYYMM-XXXXX, render PDF via WeasyPrint+Jinja2billing_closejob (T+48h deferred)- Prior-period adjustment logic for late telemetry
- Files:
app/services/receipt_service.py,app/jobs/billing_close.py,app/templates/receipt.html -
Blocked by: 003, 006
-
008-receipt-verification
@bravo— REVENUE MILESTONE - Public
GET /public/receipts/verify/{serial_number}(no auth, rate-limited 60/min/IP) - Authenticated
GET /api/v1/receipts(paginated, paid only — 403 for free tier with upgrade CTA) GET /{id}/pdfdownload- Files:
app/schemas/receipts.py,app/api/v1/receipts.py - Blocked by: 007
Epic 4: Project Organization P2¶
Organize connections into projects with per-project analytics, workload routing, and CSV/JSON export.
- 009-projects
@alpha - ProjectService: create/list/get/update/delete,
ensure_default_project, reject delete with active workloads - ExportService: CSV/JSON telemetry export with project filter
- Project schemas and API router
- Files:
app/services/{project_service,export_service}.py,app/schemas/projects.py,app/api/v1/{projects,export}.py - Blocked by: 005
Epic 5: Audit & Compliance P2¶
Enterprise upsell: monthly audit pack generation (zip with receipts, calculations, methodology), S3 storage, manifest hashing.
- 010-audit-packs
@bravo - AuditService:
generate_audit_pack(collect receipts, bundle calculations, manifest, zip, upload S3, store AuditPack withmanifest_hash) - Monthly cron on 3rd of month
- Download endpoint (paid tiers only, 403 for free)
- Files:
app/services/audit_service.py,app/jobs/audit_pack.py,app/api/v1/export.py - Blocked by: 008
Epic 6: SDK Ecosystem & Polish P3¶
Phase 2 scaffold: OpenAPI spec validation, Python SDK skeleton, MCP server skeleton. Plus cross-cutting polish.
- 011-sdk-scaffold
@alpha - Generate and validate OpenAPI spec from FastAPI app against
contracts/ - Python SDK package in
sdk/python/with httpx client class - MCP server skeleton in
mcp/exposingestimate_emissionsandlist_receiptstools - Scaffold only — full implementation deferred
- Files:
sdk/python/,mcp/ -
Blocked by: 005
-
012-rate-limiting
@bravo - slowapi rate limiting: 100 req/min per org, 60 req/min per IP, 1 per 5min on manual sync
- Correlation ID propagation to background jobs
- Files:
app/main.py -
Blocked by:
000-foundation -
013-test-suite
@bravo tests/conftest.py: async session factory, httpx AsyncClient, factory_boy factories- Unit tests:
test_emissions_engine.py(all tiers, cached vs uncached, uncertainty, unknown model fallback),test_receipt_signing.py(sign/verify round trip, key versioning) - Integration tests:
test_connection_flow.py(create, validate, poll, ingest, query),test_billing_lifecycle.py(open, closing, closed, receipts, prior-period) - Files:
tests/conftest.py,tests/unit/*.py,tests/integration/*.py - Blocked by: 003, 007
Dependency Graph¶
000-foundation ✓
├── 001-provider-connectors (@alpha)
│ ├── 002-connection-api (@alpha)
│ └── 004-telemetry-jobs (@alpha) ← also needs 003
├── 003-telemetry-ingestion (@alpha)
│ ├── 004-telemetry-jobs (@alpha)
│ ├── 005-telemetry-api (@alpha) ★ MVP
│ │ ├── 009-projects (@alpha)
│ │ └── 011-sdk-scaffold (@alpha)
│ ├── 007-carbon-receipts (@bravo) ← also needs 006
│ │ ├── 008-receipt-verification (@bravo) ★ REVENUE
│ │ │ └── 010-audit-packs (@bravo)
│ │ └── 013-test-suite (@bravo)
│ └── 013-test-suite (@bravo)
├── 006-billing-stripe (@bravo)
│ └── 007-carbon-receipts (@bravo)
└── 012-rate-limiting (@bravo)
Parallel Lanes¶
@alpha @bravo
────── ──────
001-provider-connectors 006-billing-stripe
│ │
002-connection-api │
│ │
003-telemetry-ingestion ─────────── 007-carbon-receipts
│ │
004-telemetry-jobs 008-receipt-verification ★
│ │
005-telemetry-api ★ 010-audit-packs
│ │
009-projects 012-rate-limiting
│ │
011-sdk-scaffold 013-test-suite