Benton Drones logo Benton Drones

Project Tracking & Detail

MVP Roadmap evolved: the 8 production gaps, execution order, architecture decisions, and the index into goals/, judges/, and tracking/.

Where We Are

402 tests green (unit + HTTP E2E + browser). The app is live on Render and the autonomous build phase is COMPLETE: real geocoder, persistent rate limiting, JIRA queue replay, email notification code, backup tooling, plus the full ADR-001 backend readout — Cloudflare Access JWT verification, JSON admin API + CORS, admin audit trail, noindex headers, and the pages-admin/ static dashboard bundle — all verified live on 2026-08-17.

Kickoff email sent 2026-08-17 — Anderson has the launch briefing, all live links, his action list, and offline copies of the cutover walkthrough. The critical path is now Anderson's account-access session (Namecheap → Cloudflare cutover + Google Workspace app password), not more engineering.

5 gaps built & judged ADR-001 backend assets shipped 2 gaps need one credential each 1 gap human-gated (cutover) 2 gaps post-launch

Goals Judges PRD & UAT Plan Completion Guide

The 8 Production Gaps — Status Board

Autonomy is the hero: green means an agent builds it with zero human help, red means only you can do it, split means the agent writes the code and you drop in one credential.

P0 DONE — judge PASS

G1 — Real Geocoder

US Census primary + Nominatim fallback, cached in geocode_cache, live-verified against real APIs. Mock kept for offline tests.

REQ-GEO-001 · EVID-GEO-001

P0 Needs Anderson

G2 — Custom Domain + Cloudflare Cutover

leads.bentondrones.com + admin.bentondrones.com not live. Anderson follows the nameserver walkthrough (in his inbox + attached) to move DNS to Cloudflare; then Tyler flips the Render custom domain, Cloudflare Pages project, and Access app — backend JWT/API/CORS/audit already shipped (ADR-001).

REQ-DEPLOY-001 / REQ-DNS-001 / REQ-CUTOVER-001 / REQ-CFPAGES-001

P0 Agent codes / you credential

G3 — Email Notifications

Code complete: stdlib smtplib, DB-backed email_queue with backoff + dead-letter, customer + internal templates. Live-send waits on the Workspace SMTP app password.

REQ-NOTIFY-001 · EVID-NOTIFY-001 · live-send BLOCKED

P1 Agent codes / you credential

G4 — Backups & Monitoring

Code+docs complete: DB-aware /healthz, read-only verify_backup.py, recovery playbook. Neon console values + monitor account are the remaining evidence.

REQ-BACKUP-001 · EVID-BACKUP-001 · console evidence BLOCKED

P1 DONE — judge PASS

G5 — Persistent Rate Limiting

Token-bucket-in-DB with atomic compare-and-set, per-route limits, 429 + Retry-After, loud in-memory fallback. No Redis.

REQ-RATELIMIT-001 · EVID-RATELIMIT-001

P1 DONE — judge PASS

G6 — JIRA Queue Replay

On-read sweep + daemon worker, exponential backoff, dead-letter after 5 attempts, idempotency keys kill duplicate tickets.

REQ-JIRA-002 · EVID-JIRA-002

P2 Agent codes / you credential

G7 — Shopify App Proxy

App Proxy not validated for production. Verify real Shopify request signing before enabling the /apps/... path.

Maps to existing REQ-SHOP-002 · post-launch

P2 Agent builds it

G8 — Internal Map UI

Map beyond the admin preview: leads, clusters, and service zones for day-to-day planning.

Maps to REQ-MAPUI-001 · post-launch

Execution Order

Everything before the red gate is DONE (built and judged in the wiggum loop, iterations 11–15). Everything after it unblocks the moment the human session happens.

G1 Geocoder G5 Rate Limit G6 JIRA Replay G3 Email Code G4 Backup Code Human Session G2 Domain G3/G4 Credentials Launch G7 Shopify Proxy G8 Map UI

Agents build green   Needs human input amber   Human gate red   Post-launch grey

Where the Tracking Lives

Every requirement has a goal file (what to build), a judge file (how we prove it), and tasks in the BDS tracking layer. CSVs in tracking/ are canonical.

RequirementGoal fileJudge fileJudge statusTasks
REQ-GEO-001goals/geocoding-provider-goal.mdjudges/geocoding-provider-judge.mdPASSTASK-GEO-001, TASK-GEO-002
REQ-NOTIFY-001goals/email-notifications-goal.mdjudges/email-notifications-judge.mdCode PASS / live-send BLOCKEDTASK-NOTIFY-001, TASK-NOTIFY-002
REQ-BACKUP-001goals/backups-monitoring-goal.mdjudges/backups-monitoring-judge.mdCode+docs PASS / evidence BLOCKEDTASK-BACKUP-001, TASK-BACKUP-002
REQ-RATELIMIT-001goals/persistent-rate-limiting-goal.mdjudges/persistent-rate-limiting-judge.mdPASSTASK-RATELIMIT-001
REQ-JIRA-002goals/jira-queue-replay-goal.mdjudges/jira-queue-replay-judge.mdPASSTASK-JIRA-002
REQ-MAPUI-001goals/internal-map-ui-goal.mdjudges/internal-map-ui-judge.mdNot readyTASK-MAPUI-001

Architecture Decisions

IDDecisionWhy
DEC-GEO-001US Census Geocoder primary + Nominatim fallback + DB response cache.Both free, keyless, public; Census has the best US street-address coverage; caching avoids repeat calls and respects usage policies.
DEC-NOTIFY-001stdlib smtplib over Google Workspace SMTP with an app password + DB send queue; SMS deferred.Zero new dependencies or paid services; reuses the existing mailbox; the queue guarantees no signup is lost or blocked by an email failure.
DEC-RATELIMIT-001Token-bucket-in-DB with atomic updates for cross-process shared limits; no Redis.The existing database provides the atomicity multi-process correctness needs; survives restarts; no new infrastructure for a single-host deployment.
DEC-JIRA-001On-read sweep + optional daemon replay with exponential backoff, dead-letter, and idempotency keys.The sweep guarantees progress without a running worker; the daemon adds timeliness; backoff + dead-letter prevents poison-message loops; idempotency makes at-least-once delivery safe.

Production Readiness Checklist

Must do

  • HTTPS
  • Production secrets
  • Backups
  • Privacy/consent legal review
  • Shopify landing page copy

Should do

  • Real geocoder shipped
  • PostgreSQL migration shipped (Neon)
  • Shared rate limiting shipped
  • Monitoring/logging (external monitor account pending)
  • Brand-matched styling

Later

  • Shopify App Proxy
  • Map dashboard
  • Cluster editing UI
  • Email/SMS automations
  • Advanced reporting