Skip to content

ADR-001: Monorepo Structure

Status: Accepted Date: 2026-02-25

Context

OpenLatch consists of two main codebases: a Python/FastAPI backend and a C++/PlatformIO ESP32 firmware. We also have shared artifacts (the allow-list binary protocol, test vectors, tooling, documentation) that both sides depend on.

We need to decide whether to use separate repositories or a monorepo.

Options Considered

A) Separate Repos (backend, firmware, docs)

  • Pro: Independent versioning and CI pipelines
  • Pro: Smaller clones for contributors who only work on one side
  • Con: Cross-platform test vectors must be published/consumed across repos
  • Con: Protocol changes require synchronized PRs across repos
  • Con: Harder to maintain consistency (e.g., protocol spec vs implementation)

B) Monorepo

  • Pro: Single source of truth — protocol spec, backend serializer, firmware deserializer live together
  • Pro: Cross-platform CI test (Python signs → C++ verifies) runs in one pipeline
  • Pro: Atomic commits for protocol changes that touch both sides
  • Pro: Simpler onboarding — one clone, one CI config
  • Con: CI pipeline is more complex (multi-language)
  • Con: Larger repo size over time

Decision

Monorepo (Option B).

The allow-list binary protocol is the central integration point. Changes to the protocol (header format, entry layout, signing) must be updated atomically in the backend serializer, firmware deserializer, protocol spec, and test vectors. A monorepo makes this natural.

The CI complexity is manageable with GitLab CI job rules that only run backend jobs when backend/ changes and firmware jobs when firmware/ changes.

Consequences

  • All code, docs, and tooling live in one repository
  • CI pipeline has multi-language stages (Python + C++/PlatformIO)
  • Contributors clone the full repo but only need tooling for their area of work
  • Cross-platform test vectors in proto/test_vectors/ are generated and consumed in the same pipeline