0001 — One repository
Status: accepted, 2026-09-02. The record is
docs/adr/0001-one-repository.md;
this page is its map and its summary and states nothing the record does not.
The map
decisions/0001-one-repository in the recordContext
PlatformKit was 67 git repositories in one workspace: a kernel, a module
catalog, a design system, a dozen pk-* libraries, client overlays, infra. A
change to a contract meant a commit in four repositories in a fixed order, and
2,122 packages were linked into the one binary that consumed them. The split
bought nothing: there was one consumer of almost every repository, and no
repository was released on its own cadence.
Decision
One public repository, github.com/septagon-oss/platformkit, holds the kernel,
reference modules, UI stack and reference app in a single Go module; shared
implementations live as ordinary packages under ui/, design/ and kit/.
Commercial capabilities and client applications remain private consumers, as
docs/adr/0009-what-is-public.md
describes. Package count is one reviewed cost of composition: the package gate
checks the ceiling in packages-budget.json, and a new package must justify
its ownership and maintenance cost rather than exist only to bridge
repositories.
Consequences
-
One
go.mod, oneMakefile, one CI workflow, one version. -
A contract change is one commit and one compile error set.
-
Nothing enforces a boundary by version string any more, so the boundaries that remain (
contracts/,internal/) are the ones the compiler can check. -
Independent release of a single library is no longer possible. No consumer wanted it.
Where it lives
-
go.mod— the one module,module github.com/septagon-oss/platformkit; every package underkit/,modules/,ui/,design/andapps/shares that path. -
ARCHITECTURE.md— the implemented boundaries of the one tree: the public repository owns the runtime and shared UI, a module iscontracts/,internal/andmodule.go, and shared code belongs inkit/only when it is runtime infrastructure rather than a business rule. -
.github/workflows/release.yml— the one release: av*tag that is onmainrunsmake checkandmake e2eagainst the tagged tree, then builds and pushes the image, attaches its SBOM and creates the GitHub release. -
packages-budget.json— the current package ceiling, one number the gate reads and--writelowers when the count falls. -
scripts/check_packages.sh— the package gate: it counts the first-party packagesgo list -deps ./apps/platformkitlinks into the reference app and fails when the count exceeds the ceiling. -
Makefile—check-packagesruns the script and is a prerequisite ofcheck, so the gate is part of everything a pull request must pass.
Evidence
make check-packages # checks the current ceiling in packages-budget.json
The record names one command and no test. check-packages is a prerequisite
of make check, which CI runs on every pull request and release.yml runs on
the tagged tree, so the ceiling is checked wherever the gates run. What the
record gives up on purpose is the independent release of a single library; no
consumer wanted it.