0003. Go for the core platform, Python for the ML layer, TypeScript for the dashboard
- Status: Accepted
- Date: 2026-10-22
Still current. Mentions of billing and customers below are historical (ADR-0011: Tensora is free). Since 2026-10-23 the Go binary also contains the node agent and must run on macOS (Apple Silicon) and Linux (ADR-0013); the dashboard is embedded in it for Solo installs (ADR-0012).
Context
Section titled “Context”The product layer has three distinct jobs:
- The core platform: API, reconciler, metering. It’s long-running, concurrent, deeply integrated with Kubernetes, and correctness-critical, since it handles tenancy and billing.
- The ML layer: model ingestion and validation, benchmarking, GPU burn-in. These need the Hugging Face, PyTorch, and safetensors ecosystem.
- The dashboard: a web UI for customers.
This is the same split most GPU clouds use.
Decision
Section titled “Decision”- Go for
controlplane/: onetensorabinary with subcommands (api, controller, metering, migrate, dev). It uses stdlibnet/http, pgx, client-go, and goose. - Python 3.12 for
ml/: thetensora-mlCLI and image, managed with uv, with heavy dependencies like torch kept optional. - TypeScript for
web/: React, Vite, and TanStack Query.
Boundaries: the Go platform orchestrates and never imports ML libraries. Python tools are invoked as CLIs or Kubernetes Jobs, with JSON on stdout. The dashboard talks only to the public API.
Consequences
Section titled “Consequences”- client-go is the native Kubernetes client, and Go builds a single static binary for distroless images.
- Python code stays where its ecosystem is irreplaceable, and isn’t on the request path.
- There are three toolchains in CI. The Makefile and the per-component AGENTS.md files keep this manageable.
- API types are duplicated between Go (
internal/api/json.go) and TS (web/src/api/types.ts). If that drifts, generate an OpenAPI spec (Phase 3).
Alternatives considered
Section titled “Alternatives considered”- Python everywhere (FastAPI control plane): one language, but the Kubernetes client and concurrency story is weaker, and runtime type safety for billing and tenancy code is weaker too.
- Go everywhere: no viable story for model validation or burn-in without reimplementing parts of the Python ML ecosystem.
Update 2026-10-23
Section titled “Update 2026-10-23”The regional inference gateway (ADR-0010) belongs to the Go core platform if it’s built as a custom
proxy rather than on Envoy. The tensora CLI and Python SDK (Phase 2) are client libraries: the CLI is in Go,
sharing the API types, and the SDK is in Python, for ML users.