Ownership
One service writes a given set of data. Everyone else reads its contract.
"Owner" is the load-bearing word in item 30, so it gets a definition rather than a connotation:
A dataset's owner is the single service permitted to write it. The owner decides the schema, and is the only party that may change it without asking anyone. Every other application — including other services owned by the same team — reaches that data through the owner's contract.
The asymmetry: writes and reads are not the same problem
A second writer and a second reader break different things, and conflating them is why "everyone should go through the API" gets argued about.
| Second writer | Second reader | |
|---|---|---|
| What breaks | Invariants. Two writers cannot both enforce "an order always has at least one line" — neither sees the other's transactions. | Change. The reader's queries pin the schema, so the owner can no longer change it. |
| Recoverable? | No. By the time you notice, the data is already inconsistent. | Yes, but only by finding every reader — see 02 · 03. |
| Rule | Never. One writer, always. | Through the contract, with the analytical exception below. |
The analytical exception matters: a bulk or historical read does not belong in a synchronous API at all. It goes to item 27's warehouse or item 28's event bus, which is stated in 05 · Migration.
How ownership is decided
In order, stopping at the first one that gives a clear answer:
- Who writes it today? If exactly one service writes a set of tables, that service is the owner. Most datasets resolve here.
- Whose invariants are they? If several write it, the owner is the service that would have to be correct for the data to make sense — the one that enforces the rules, not the one that writes the most rows.
- Who is called when it is wrong? If the invariants are unclear, ownership follows the pager. The team that gets woken up already owns it in every sense except the recorded one.
Step 1 is answered from the database side — audit output, pg_stat, proxy logs — not from a
survey. A survey records what teams remember; the estate is what it is regardless.
When it is genuinely unclear
Some datasets have no plausible owner: a shared lookup table everything reads and three things write, or a table left behind by a system that was retired.
Escalate. Do not default to the heaviest user. Handing a dataset to whoever touches it most produces an owner on paper and none in practice, and the contract it publishes will be nobody's to keep. The honest outcomes are:
- Split it. What looks like one dataset is often two, each with an obvious owner.
- Give it a home service. A genuinely shared reference dataset can get a small service whose only job is to own it.
- Retire it. A table nobody will own is frequently a table nobody needs.
Recording "unclear" is a valid result for milestone 30.1 and a better one than a guess.