Decisions
Repository-level decisions, taken when the three service repositories were merged, with the evidence for each. It is for maintainers; contract decisions live with each service: Gateway, Access, Data.
Read byRepository maintainer
Decision numbers are stable, because code and other pages cite them ("decision 12").
| # | Decision | Evidence | Status |
|---|---|---|---|
| 1 | The three services are three workspaces of one repository, not one service. | They have separate deployments, secrets, databases and contracts, and shared source would couple their builds. The merge keeps the boundary their specs draw. | resolved |
| 2 | No workspace imports another workspace's source. | Services talk over HTTP. Each architecture check rejects cross-workspace imports (packages/gateway/scripts/gates/architecture.ts, packages/access/scripts/gates/architecture.ts, packages/data/scripts/gates/architecture.ts); the compatibility suite runs the acceptance scenario through all three. | resolved |
| 3 | All three images build with the repository root as context. | Dependencies come from the root bun install and bun.lock; building from a workspace directory would install a tree that the root lockfile rejects. | resolved |
| 4 | There is one version: the platform's. | The repository, the tag, three images, three binaries and the three specs' status share it; the retired version lines are not continued. scripts/version.ts checks that they agree. | resolved |
| 5 | Images and environment prefixes are renamed. | They are deployment coordinates, so the rename is a migration, recorded in the changelog. No service reads a variable with a retired name. | resolved |
| 6 | Data's published client keeps its name. | Consumers install @data-backend/client (packages/data/packages/client/package.json); renaming it would break them. | resolved |
| 7 | The compatibility baseline is a revision of this repository. | The references are workspaces here now, and running this repository at a revision proves more than cloning a copy. An environment override still names a published revision and tests a candidate. Manifest: compatibility.json. | resolved |
| 8 | One tagger, one CI workflow, one image workflow, one binary workflow. | There used to be three of each, and they drifted. Every service runs the same jobs, so a gate missing for one is visible. See scripts/tag.ts, .github/workflows/ci.yml, .github/workflows/release.yml, .github/workflows/release-binaries.yml. | resolved |
| 9 | All documentation is one tree at the repository root. | Contracts are read alongside the shared pages: docs/platform/ holds cross-cutting pages and each service's directory holds its contract. The code boundary did not move. | resolved |
| 10 | Platform tools are declared at the root; a service's dependencies are declared in its workspace. | The compiler, linter, formatter and dead-code checker serve all three at one version (root package.json); a workspace carries only what it uses. | resolved |
| 11 | Specs name services by role, and so does the platform. | A retired repository's name no longer names anything. Workspaces, images, environment and docs say gateway, Access and Data. | resolved |
| 12 | The platform never names the retired repositories, and a check enforces it. | Clones of the old repositories fail and their releases are unreachable. scripts/check-repositories.ts fails the build when a file names any other repository; it accepts only the platform's own and lists no retired names. No record of the old state is kept. | resolved |
| 13 | Each service's vocabulary carries its role name. | Metrics, identity headers, cookies, tables, shared-state namespaces and env prefixes moved to role names. A dashboard that watches a retired metric sees nothing. | resolved |
| 14 | A vocabulary check rejects identifiers that do not carry their service's role name. | scripts/check-vocabulary.ts accepts only role names in env prefixes, metric names and reported names; it lists no retired names (decision 12). | resolved |
| 15 | All three services answer probes the same way and publish an API description. | Readiness uses ready, draining and not-ready; health carries status, role name and version. scripts/check-api.ts checks each description against the registered routes. | resolved |
| 16 | A decision that changes a contract is recorded in the workspace's spec, its decisions table and the changelog, never only in code. | The spec is the contract, the decisions table names the section that states each decision, and the changelog is what people read at release time. | resolved |
| 17 | A check proves that CI runs every test of the platform, and that every CI job points at a workspace that exists. | scripts/check-coverage.ts refuses a matrix job whose workspace does not exist, and a test file in the repository that no job runs. A harness's suite is read from the harness itself, because no job names it. | resolved |
| 18 | The four processes of the platform redact the same names, and a check holds them to it. | A credential never reaches a log line. The lists were written one process at a time and they drifted: a name that one process held back and the next one did not is a credential that reaches a log of a deployment that reads it. tooling/redaction.ts holds the list and scripts/check-redaction.ts refuses the logger that does not hold it back. | resolved |
| 19 | The published client of Data and the client of the console and of the CLI speak the same paths, and a check holds them to it. | The published client is installed outside of this repository and cannot import the client workspace, so the paths are written twice. scripts/check-client-paths.ts reads the two sources and refuses the published client when it names a path the console and the CLI do not know. | resolved |
| 20 | The console and the CLI share their clients in one workspace; the services share nothing. | The two clients read the same contracts, and a contract that is written twice is a contract that drifts. packages/client holds the paths, the queries and the refusals of the contracts, and packages/client/scripts/architecture.ts refuses an import that leaves it. The services stay apart: a shared source would couple their builds (decision 1). | resolved |