Code Ownership
Every service and directory has an owning team: CODEOWNERS for reviews, a catalog entry for operations, and a README that gets anyone running in one command.
Code without an owner decays. Nobody upgrades its dependencies, nobody answers its alerts, and the first person to touch it in a year inherits every surprise. Ownership is cheap to write down and expensive to reconstruct, so it's written down from the first commit.
Every Path Has an Owner
Ownership is assigned to teams, not individuals. People change roles and go on vacation; a team's queue is always staffed.
- Repository level: a
CODEOWNERSfile maps paths to the teams that review changes to them. - Organization level: a service catalog maps each deployable to the team that runs it.
- No orphans. A path with no owner is a bug, and a check in CI can fail on it.
CODEOWNERS
GitHub reads CODEOWNERS from .github/, the repository root, or docs/, using the first it finds, and it must exist on the pull request's base branch.
# Default owner for everything
* @acme/platform
# More specific paths override earlier lines: the last match wins
/services/payments/ @acme/payments
/services/payments/ui/ @acme/payments @acme/frontend
/.github/ @acme/platform
/.github/CODEOWNERS @acme/platform @acme/eng-leads
- Require code owner review in branch protection or a ruleset. A listing that isn't required is a suggestion.
- Own the file itself. Whoever owns
CODEOWNERSdecides who owns everything else, so it gets a deliberately small owner list. - Order matters. The last matching pattern takes precedence, so broad defaults go first and specific paths after.
The Service Catalog
CODEOWNERS answers "who reviews this change?". The catalog answers "who do I call at 3 a.m.?". Every deployable service has an entry, usually a file in its repository that a catalog like Backstage indexes:
| Field | Why |
|---|---|
| Owning team | Who decides, who's accountable |
| On-call rotation | Who gets paged. See On-Call & Runbooks |
| Runbook | What to do when it breaks |
| SLOs and dashboards | What "healthy" means. See SLOs & Error Budgets |
| Dependencies | What it calls, and what calls it |
| Repository and docs | Where the code, ADRs and design docs live |
| Lifecycle | Experimental, production, or deprecated |
An entry that's wrong is worse than none, so the catalog file lives next to the code and changes in the same pull request.
What Every README Contains
A README is the front door. Someone new should go from clone to running in minutes, without asking anyone.
- What it is, in two sentences, and who owns it.
- Run it locally, in one command, with every dependency it needs (
docker compose up,npm run dev). If it takes a wiki page, it's a bug. - Test it, in one command.
- How it deploys, and how to roll back.
- Where the rest lives: ADRs, design docs, runbook, dashboards.
Anything longer than a screen belongs in linked docs, not the README.
Shared Code
Shared libraries are where ownership quietly disappears: everyone uses them, so nobody owns them.
- Shared code still has one owning team. Other teams contribute through pull requests that the owner reviews.
- Prefer copying over premature sharing. Two services with similar code can diverge freely; a shared library couples their release schedules, and every change now needs every consumer's agreement. Share once the third copy appears and the abstraction is obvious, not on the second.
- A shared library is a product. It has versions, a changelog and a deprecation policy, like any API. See Versioning & Deprecation.
Changing Owners
Ownership changes are explicit handoffs, never drift:
- The receiving team accepts it, in writing, with the catalog and
CODEOWNERSchanged in the same pull request. - The handoff includes the runbook, open incidents and action items, known debt, and on-call shadowing for at least one rotation.
- Nobody inherits a service in the middle of an incident.
Code no team will accept is a candidate for deletion, not for a "shared" label. See Tech Debt.
This Site
syntaqx.com has one owner, so a CODEOWNERS file would only list one name; review is enforced by required CI checks instead. Its README covers what the site is and who it belongs to, npm run dev to run it with nothing else required, docker compose up -d for the optional local Redis, the test commands, and a link to the ADR index. It also says that every merge to main deploys and how to roll back, which completes the checklist.
References
Reference
- GitHub: About code owners, file locations, last-match precedence and required reviews
- Backstage: Software Catalog, tracking ownership and metadata for every service
In practice
- Google SRE Book: Being On-Call, why operational ownership needs a staffed rotation