Go data plane
A Connect/gRPC service over cleartext HTTP/2 (h2c). Speaks the DB contract. No TLS
in-process. core-database, core-mcp.
The backend is a contract-first polyrepo: ~20 git submodules under backend/core/
(enumerated in .gitmodules).
That sounds like a lot to hold in your head — but you don’t have to. Every service is
one of exactly three physical shapes. Once you know which shape a service is, you know
how it boots, how it’s reached over the wire, and how to debug it. This is the single most
useful lens for the whole fleet.
Go data plane
A Connect/gRPC service over cleartext HTTP/2 (h2c). Speaks the DB contract. No TLS
in-process. core-database, core-mcp.
Python service
A long-lived server with ingress — either grpc.aio or FastAPI+Hypercorn. Clients
connect to it. core-gateway-consumer, core-identity, core-storage, core-billing, core-conversion.
Python queue worker
No ingress. A poller built on the soundverse-py WorkerFleet. It claims tasks
off the queue, runs them, and drains on SIGTERM. All the core-tool-* repos.
Who: core-database and
core-mcp.
How it serves. One HTTP port speaking h2c (cleartext HTTP/2) + Connect, wired with
h2c.NewHandler(...). There is no TLS in-process — the platform (Azure Container Apps,
or a local proxy) terminates TLS in front. Both listen on the port named by LISTEN_ADDR
(:8080 in-container).
How it’s reached. Other services dial it by its published *_GRPC address
(CORE_DATABASE_GRPC, CORE_MCP_GRPC) and present the shared secret INTERNAL_RPC_SECRET
as a bearer token on every call. core-database is the single door to Postgres — it
mounts every proto-defined DataService (chat, identity, storage, generation task + tool,
billing, DNA, notifications, the compat trio, and more) behind one
registry.RegisterAllDBServices(...) call, and nobody else opens a DB connection.
core-mcp is the MCP tool registry the agent calls, and it runs the second billing
pipeline.
How to debug it. GET /healthz. Boot lives in
core-database/cmd/server/main.go
and core-mcp/cmd/server/main.go.
Run locally with go run ./cmd/server.
Who: core-gateway-consumer,
core-identity,
core-storage,
core-billing, and core-conversion.
How it serves. A long-lived server with ingress — clients connect to it. Two sub-flavours share the shape:
grpc.aio (native gRPC + a gRPC health service): core-gateway-consumer,
core-storage, core-conversion. These add_insecure_port(...) and let the platform
terminate TLS, same as the Go services.core-identity, core-billing. Served with
hypercorn app.main:app.How it’s reached. core-gateway-consumer is the consumer trust boundary — the only
service the browser’s BFF talks to. Its request pipeline is
authenticate → rate-limit → price → reserve → queue; everything downstream trusts that it
ran. The others are internal: the gateway and workers dial them by their *_GRPC /
service-discovery names.
How to debug it. gRPC services expose a gRPC health service (liveness/readiness);
FastAPI services expose GET /healthz. Run locally with make run (which is
uv run python -m app.main) or, for the FastAPI ones,
uv run hypercorn app.main:app -b 0.0.0.0:80. make check (ruff + pyright + pytest) is
the exact CI gate.
Who: every core-tool-* repo —
core-tool-agent,
core-tool-sansaarm,
core-tool-stitch, core-tool-media, core-tool-gpu, core-tool-dna — plus the
template-core-tool starter they’re
all copied from. See the other tool workers
page for the non-flagship ones.
How it serves — it doesn’t. No ingress There is no
HTTP port, no gRPC server, no health endpoint you curl. A worker is a long-running
poller built on the soundverse-py
WorkerFleet. app/main.py does exactly three things:
set up telemetry, build the gRPC client, then WorkerFleet(ALL_TOOLS).start() and block in
the poll loop. The fleet:
core-mcp can expose it),process() in a thread pool, heartbeats the
lease,GenerationOutput, reports raw usage,SIGTERM (ACA sends SIGTERM on scale-down / redeploy).How to debug it. Watch the logs / traces — the worker announces which tasks it claims.
Run locally with make run (needs Redis + core-database + core-storage + core-mcp
reachable). Adding one of these is the most common change you’ll make: see
Add a new generation tool worker.
| Shape | Language | Serves via | Ingress? | Reached by | In the fleet |
|---|---|---|---|---|---|
| Go data plane | Go | Connect/gRPC over h2c |
Yes | *_GRPC addr + INTERNAL_RPC_SECRET bearer |
core-database, core-mcp |
| Python gRPC service | Python | grpc.aio + gRPC health |
Yes | *_GRPC addr (gateway = BFF entry) |
core-gateway-consumer, core-storage, core-conversion |
| Python HTTP service | Python | FastAPI + Hypercorn | Yes | GET /healthz, REST |
core-identity, core-billing |
| Python queue worker | Python | nothing — polls the queue | No | not reached; claims tasks | every core-tool-* |
core-migration is the one repo that isn’t a
long-lived service at all. It’s a run-to-completion job (an ACA Job) that re-ingests
1.0 users, billing, and library content into 2.0, then exits. Think of it as a fourth,
rare shape: it boots, does a bounded amount of work, and stops.
Several repos are load-bearing but aren’t any of the shapes above:
WorkerFleet + TaskContext)consumer/v1, Logto auth)agent-synth)soundverse-py gets special mention: it’s not a service, but its WorkerFleet /
TaskContext API is the contract every tool author lives inside — read the
SDK deep-dive. The proto repos anchor the
contract cascade that keeps all the shapes in sync.
Because the shape is the operational contract:
go run ./cmd/server. Python service: make run / hypercorn.
Worker: make run (it just starts polling).*_GRPC address (internal
ones want INTERNAL_RPC_SECRET). Worker: never dialled — it pulls work.NotFound).h2c, lease, and the rest