Skip to content

10. One package, one process

  • Status: Accepted
  • Date: 2026-11-05

Context

Warp, Fusion and Stargate were three repositories and, deployed together, three processes: Fusion read the database through Warp over HTTP, and an MCP server generated by Stargate would have called Warp over HTTP again. For an on-premises customer that is three things to install, three configurations that have to agree, and two network hops inside one product. It also put the governance in the wrong place: Warp enforced row rules and masks on its table routes, and Fusion, which runs arbitrary SQL over the same data, knew nothing of them.

Decision

One distribution (truejoin), one import package, one hexagonal tree. The three histories were imported with git filter-repo into subdirectories and then moved, so git log --follow and blame still work.

Inside each layer the origins stay recognisable (domain/olap, domain/gateway, domain/governance, domain/catalog, domain/mcp), ports are one flat package, and one dependency walker replaces three mechanisms. The one exception to "the domain imports nothing" is pydantic, for the catalog's file format.

One process serves the REST gateway, /olap and MCP on one port, behind one set of API keys. The OLAP side reads the databases through the gateway's own DatabaseGateway port, in process. The HTTP source survives as warp-remote, for a gateway on another node.

The MCP server is curated, not generated. Generating tools from the gateway's OpenAPI gives five write tools per table, the opposite of a read-only analyst surface. The product's MCP server exposes the analytical tools by profile (analyst, admin) and allow-list; Stargate remains as a library and truejoin mcp convert for turning any OpenAPI or Postman spec into an MCP server.

Consequences

  • One config file, one CLI, one image. The pre-1.0 FUSION_* and WARP_* variables are still applied on top of the file, and logged as deprecated.
  • The OLAP side needs its own database pools (see ADR 11), so each database has two.
  • A process holds what it loaded: one replica per deployment. Scaling out means a gateway on another node and warp-remote.
  • trio was a placeholder name; renaming it to truejoin (2026-11-13) was one mechanical commit.