CRUMB a card from devarno-cloud

Service Topology: What Actually Runs

sparki beginner 5 min read

ELI5

Sparki used to be drawn as a workshop with six stations. Today only three are switched on: the shop window (web-app), the front desk (api-engine), and a separate locked room where builds run (build-worker). The other stations in the floor plan (an auth desk, a deployer crane, a contract printer, an observability rig) are either retired or were never wired in.

Technical Deep Dive

Source: sparki-tools/api-engine cmd/api/main.go:40-118, pkg/api/server.go:215-354, cmd/build-worker/main.go:1-123, Dockerfile:50-59 @0b0309f; sparki-tools/platform-docs launch/gap-register.md:55, decisions/2026-08-09-retire-auth-shield.md @65a451e; live probe of sparki.tools, my.sparki.tools and api.sparki.tools/health, read 2026-10-25.

Deployed path

ProcessRepo / entrypointHostHolds
web-appsparki-tools/web-app, Next.js 14Vercel (sparki.tools, my.sparki.tools; server: Vercel)airlock handoff, __app_session cookie, same-origin /api/* rewrite to the engine
api-enginesparki-tools/api-engine, cmd/api (Go, Fiber)Railway (api.sparki.tools; server: railway-hikari)Postgres + Redis, airlock session check, TOLL client, worker API
build-workersparki-tools/api-engine, cmd/build-workerdedicated VPS (gate G9, not provisioned)one worker token + the API URL, nothing else

The Docker image builds only ./cmd/api and ./cmd/migrate (Dockerfile:50-59). The worker is a separate binary. On 2026-10-25 /health answered {"status":"degraded","workers":{"state":"unconfigured"}}: no worker token digests are set, so the worker routes are not registered and queued builds do not run.

flowchart LR
B["Browser"] --> W["web-app on Vercel"]
T["sparki-tui"] -. "device-code token" .-> A
W -- "same-origin /api/* rewrite" --> E["api-engine on Railway"]
W -- "OIDC sign-in" --> A["airlock"]
E --> PG[("Postgres")]
E --> RD[("Redis")]
E -- "toll.checkout and toll.entitlements" --> TL["null0-toll"]
K["build-worker on VPS"] -- "HTTPS /internal/worker/*" --> E
D["DSN Prometheus"] -. "GET /metrics bearer" .-> E

Not on the deployed path

flowchart TD
S["services/ in sparki-tools"] --> AS["auth-shield: retired 2026-08-09, airlock is sole IdP"]
S --> DL["deploy-loco: no route in cmd/api, not deployed"]
S --> SM["smithy: no deploy config, last main 2026-08-09"]
S --> OS["observability-storm: no deploy config, last main 2026-02-24"]
S --> BF["build-forgery: no code, last main 2026-03-12"]
E2["api-engine subsystems/"] --> NL["present on main, not linked into cmd/api or cmd/build-worker"]

There is no message broker on the deployed path. internal/mq (RabbitMQ, amqp091-go) is still in the tree, but only internal/service imports it and nothing reachable from cmd/api or cmd/build-worker imports internal/service. The build queue is the builds table itself (sparki-004).

Key Terms

  • api-engine → the Go/Fiber API; the only backend process in production.
  • build-worker → the separate binary that claims builds over HTTPS and runs each step in a container.
  • G9 → the launch gate “build worker VPS provisioned and verified”; open on 2026-10-25.
  • __app_session → the apex-local session cookie the web app mints after airlock sign-in; the engine verifies it.

Q&A

Q: Which three processes are on the deployed path, and where does each run? A: web-app on Vercel, api-engine on Railway, and build-worker on a dedicated VPS. The VPS has not been bought yet (G9), so the worker is designed and coded but not running.

Q: Which services in services/ have no deployment, and what replaced auth-shield? A: auth-shield (retired by ADR 2026-08-09), deploy-loco, smithy, observability-storm and build-forgery. airlock replaced auth-shield as the only identity provider.

Q: How does a build step get from a queued build row to a container? A: POST /api/v1/builds inserts a pending row; a worker claims it with POST /internal/worker/claim, then runs each step in its own sandboxed container and reports logs and the result back over HTTPS (sparki-004, sparki-018, sparki-019).

Examples

A user clicks Run on my.sparki.tools. The browser calls /api/v1/builds on its own origin; Vercel’s fallback rewrite forwards it to api.sparki.tools with the session cookie; the engine checks the plan through TOLL, inserts a pending build and returns 201. Until a worker token is configured, that build stays pending and /health reports degraded once it has waited five minutes.

neighbors on the map