Repository navigation
Tracking: Go HTTP Daemon — REST #10
Description
⚠️ Disclaimer: This issue is primarily focused on defining interfaces and service boundaries. Implementation details, data models, and internal wiring are intentionally pushed to later phases — the goal right now is to agree on the shape of the system before writing any code.
Tracking issue for the Go HTTP Daemon lane of the backend rewrite.
Goal
Replace the current Next.js API routes with a single Go binary on 127.0.0.1:3001 that serves:
/api/v1/*— REST endpoints (25 routes, path-parity with current TS)
The daemon is spawned as a sidecar child process by the Electron main process, supervised over loopback only. No auth, no CORS, no public URL.
Approach: phase-by-phase, contract-first
feat/go-http-daemon is the lane integration branch: every sub-PR branches off it and merges into it; the whole lane lands on main as one unit once complete.
Design doc & HTML overview: https://htmlpreview.github.io/?https://gist.githubusercontent.com/neversettle17-101/00c659adf978b80b1e2eb600d451932a/raw/ao-backend-rewrite-phase1.html
Startup sequence
1. Electron main spawns ./ao-daemon
2. Daemon binds :3001, starts listening
3. Main polls /healthz until ready
4. Renderer connects and loads UI
TODO — open question: How are agent sessions & projects loaded on daemon startup?
Warm cache from disk, lazy-load on first request, or explicit restore step?
PR sequence
Phase 1 — HTTP server skeleton + Electron integration
-
1a — Skeleton — Go module init,
config(port, env),127.0.0.1bind, 5-middleware stack (recoverer → request ID → logger → real IP → timeout),/healthz+/readyz, graceful shutdown (10s timeout, SIGTERM/SIGINT) -
1b — Route shell — All 25 routes registered under
/api/v1as501 Not Implementedstubs; subrouter layout (/events,/mux,/api/v1,/) with correct middleware applied per surface -
1c — Electron integration —
embed.FSstatic serving, Electron main process spawns + supervises daemon, health-check polling before renderer connects, dev proxy (Next.js:3000→ Go:3001), packaged build withextraResources -
Sessions — list (with
?project,?active,?orchestratorOnly,?fresh), get, spawn, kill, message, send, restore -
Projects — list, get, reload
-
Issues, backlog, PRs —
GET /issues,GET /backlog,POST /prs/:id/merge -
Meta —
GET /version,POST /update,POST /webhooks/* -
Unclear routes remain explicit no-ops —
/remap,/patches,/orchestrators,/observability,/verify,/setup-labels
Key decisions (settled)
| # | Decision |
|---|---|
| Framework | chi — http.Handler-compatible, subrouters, standard middleware ecosystem |
| Port strategy | Single port localhost:3001 — same-origin, no CORS, one token, one lifecycle |
| State push | SSE for backend → frontend; WS reserved for terminal (/mux) only |
| Route surface | 25 routes at exact path parity with current TS under /api/v1; unclear routes ship as no-ops |
| Port binding | Bind 127.0.0.1 only; default 3001; fail fast on conflict |
| Shutdown | signal.NotifyContext; 10s hard timeout; SSE connections just closed (EventSource auto-reconnects) |
| Middleware | recoverer → request ID → logger → real IP → timeout (timeout on /api/v1 only) |
| Future split | 6 disciplines adopted day-one so a port split stays a ~50-line change, not a rewrite |
Open items
- TODO — How are agent sessions & projects loaded on daemon startup? (warm cache, lazy-load, or explicit restore)
- Q1.3 — Error envelope shape +
/api/v1versioning strategy - Q1.5 — OpenAPI: hand-written spec vs. code-first vs. spec-first codegen
- Q1.6 — Static asset
embed.FScache-control headers - Q1.11 — Filesystem routes (
/api/v1/filesystem/browse) — native machine FS design pending - Phase 2 blocker — Event taxonomy (which events each topic emits, exact payload shapes) must be agreed before wiring frontend dispatch
- Q2.x — WebSocket
/muxfull design (mux semantics, framing, backpressure, auth on upgrade)
Architecture overview
┌─────────────── Electron App ───────────────────────┐
│ Renderer (React) ←IPC→ Main process (Node.js) │
│ │ spawn + supervise │
└───────────────────────────────┼────────────────────┘
│ HTTP + WS
▼ 127.0.0.1:3001
┌───────────────────────────┐
│ Go daemon │
│ / static │
│ /api/v1/* REST │
│ /events SSE │
│ /mux WS terminal │
└───────────────────────────┘
Open contract questions — for integration partners
- Persistence —
LifecycleStoreadapter: does the storage layer expose what the Go daemon needs for session read-model? (Tom) - SCM facts — does the SCM poller output match what
/api/v1/issues+/api/v1/backlogneed to read? (adil) - API shape — are the 25 route response shapes OpenAPI-friendly as-is, or do we need a normalisation pass before Phase 3? (aditi)
- Event taxonomy — which events does each SSE topic (
sessions,prs,ci) actually emit, and what are the payload shapes? (all lanes)
Owner: @neversettle17-101
Activity
harshitsinghbhandari commentedon May 27, 2026
Heads-up for the API/frontend lane — new
draftvalue in the session enums (already landed in the LCM/SM lane, PR #13).The canonical model now has a draft PR substate, so two enums your OpenAPI client + frontend display layer consume gained a value:
PRState→none | draft | open | merged | closedSessionStatus(the derived display status) → now includesdraftBehavior to mirror in the UI:
draftstatus (it can't be reviewed or merged, so review/approval/mergeable states don't apply to it).ci_failed, notdraft— CI still dominates so the auto-fix reaction fires on drafts too.PRState = draftfrom GitHub'sisDraft.Action for your lane: add
draftto the generated/display status enum so it deserializes + renders, with its own badge/treatment (andci_failedtakes precedence when CI is red on a draft). No shape change toSession/SessionRecord— just the enum value.refactor(backend): drop Env config field — not needed yet (#10)
docs: add backend run + config quick-start to README (#10)
fix(backend): address Phase 1a review comments (#10)
fix(backend): strip trailing blank line from runfile.go (#10)
fix(backend): cross-platform run-file replace + AO_HOST rationale (#10)
neversettle17-101 commentedon May 28, 2026
Phase 1 sub-issue added: #19 (OpenAPI spec + validation), follows #18 (route shell).
fix(backend): route chi access logs through slog/stderr (#10)
feat(backend): HTTP daemon skeleton (Phase 1a) — #10 (#14)
feat(api): projects route shell (7 routes, REST-corrected) — #20
feat(api): projects route shell (7 routes, REST-corrected) — #20
feat(api): implement project routes with mock manager/store (#47)
[-]Tracking: Go HTTP Daemon — Phase 1 (REST + SSE + Static)[/-][+]Tracking: Go HTTP Daemon — REST[/+]