Skip to content

ADR-0006: Kernel implementation language

ADR-0006: Kernel implementation language

Status

Proposed — gated on a one-week TS-vs-Java build-off. Must not be marked Accepted until the build-off runs and its result is recorded here.

Date

2026-06-24

Context

The source pack recommends Java/Spring Boot for the kernel, TS+React for apps, Better Auth (TS) for the auth-service, Python for ML/agents, Rust where justified, Temporal for sagas. The stated rationale is hiring: “larger enterprise backend talent pool, familiar for external teams.”

That argument optimizes for a problem we don’t yet have (scaling to 50+ engineers; onboarding external Java integrators) at the cost of one we do: proving a kernel fast with a 2–3 person team (ADR-0014) whose existing depth and codebase are TypeScript/Vinxi/Node, with Better Auth (TS) already chosen. Java-first would make this a three-language platform on day one (Java kernel + TS apps/auth + Python agents) — three Value-Type codegen targets, three context-switches.

Crucially, the codegen pipeline already planned (POC 1 emits Java/TS/Python SDKs) means Java can be a generated client, not the kernel language.

Decision (proposed)

Run a one-week build-off: implement the same Action → Event → synchronous projection slice in TypeScript (Node/Vinxi + Postgres/PostGIS) and in Java (Spring Boot). The implementer is AI agents orchestrated by the team, so the two candidates are built in parallel (no individual-skill confound), and “velocity” means agent throughput + correctness + self-verifiability — how quickly an agent produces correct, idiomatic, test-passing kernel code with a tight type/compiler feedback loop — not human typing speed. Score on:

  1. Agent velocity + correctness (dominant): speed to a passing thin core, defect rate, idiomatic and navigable output.
  2. Value-Type codegen sharing between kernel and apps.
  3. Concurrency / expected-version ergonomics (ADR-0013 needs optimistic concurrency).
  4. Raw throughput (tie-breaker only).

Default if the result is a wash: TypeScript-first — codegen-sharing with the TS app layer, plus a fast tsc/vitest agent feedback loop. A microbenchmark win for the JVM does not justify six months of lost velocity for a TS-deep team. Java and Python remain generated SDK targets for external consumers regardless of the kernel language. Revisit a JVM kernel only if/when external Java extension-authoring becomes a funded requirement.

Alternatives Considered

Java-first as written

  • Pros: enterprise hiring, external-integrator familiarity, mature tooling, Temporal Java SDK.
  • Cons: three-language split now, slowest early velocity for this team.
  • Not chosen as default; remains the contender to beat in the build-off.

Go or Rust kernel

  • Pros: best concurrency/perf ceiling for the operational core.
  • Cons: smallest near-term talent pool, steepest learning curve for a TS team.
  • Rejected for the proof; Rust stays available for specific hot paths later.

Decide on paper, skip the build-off

  • Rejected: velocity and codegen-sharing are empirical and team-specific; one week of evidence beats a guess on an expensive-to-reverse choice.

Consequences

  • One week is spent before the language freeze. That is deliberate insurance on a costly-to-reverse decision.
  • This is a freeze gate alongside ADR-0003; no architecture freeze while Proposed.
  • The result is recorded by editing this ADR to Accepted with a “Build-off result” section.
  • Whatever wins, the SDK-generation boundary (POC 1) must stay language-agnostic so external Java/Python clients are unaffected.