Service Ownership
On this page
The CODEOWNERS file is the canonical record
The repo-root CODEOWNERS file is the source of truth. GitLab uses it to auto-assign reviewers when an MR touches a path, and it gates merge per the CONTRIBUTING.adoc rule that every MR needs at least one CODEOWNERS approval.
This page describes the model; the file describes the assignments. When the two disagree, the file wins — open an MR to fix the file.
Current ownership shape
CRAIG is structured around three ownership tiers:
| Tier | Paths | Today’s owner |
|---|---|---|
Shared crates |
|
|
Services |
|
|
Tooling + infra + docs |
|
|
CRAIG is currently single-maintainer. The CODEOWNERS file is structured for per-tier and per-service granularity so that when contributors join, ownership reassignments are mechanical (replace @bitskrieg on a path with the new owner’s handle).
When the team grows
The forward-looking model — written ahead of need so the structure is in place when contributors are added.
Adding a co-maintainer
-
Add the new contributor’s GitLab handle to CODEOWNERS for the paths they’ll own. Do not remove the existing owner — co-ownership (multiple handles on one line) is supported and the right default when transferring.
-
Update this page’s "current owner" column.
-
After 30 days of clean MRs, drop the original owner from the path lines they’re handing off.
Service-level ownership transfer
When a service moves from one owner to another, CODEOWNERS is the only place that changes. Update:
-
services/<name>/— primary owner -
crates/<name>/— if the service has a sibling shared crate -
docs/modules/ROOT/pages/api/craig-<name>.adoc— the service’s API doc
The MR description should call out the transfer explicitly so reviewers know the change is administrative, not technical.
Escalation
If a CODEOWNERS reviewer is unavailable for >48 hours and the MR is blocking other work:
-
Comment on the MR:
@<owner> ping — blocking #<dep> / 48h+ -
If still no response after another 24 hours, request review from a co-maintainer (any handle in the CODEOWNERS file for an adjacent path).
-
If no co-maintainer exists yet (single-maintainer phase), the MR waits.
Shared crate ownership rules
Shared crates have stricter rules than services because a breaking change in a shared crate hits every consumer:
-
Public API changes require co-ownership review even if a single owner is listed. When transferring a shared-crate path, the sentinel co-owner should be the project maintainer (
@bitskrieg) — at least temporarily. -
craig-common,craig-api,craig-authare the highest-risk crates: every service depends on them. CODEOWNERS for these paths should always have ≥2 reviewers when the team grows. -
craig-test-libis the test harness; changes here can hide regressions. Same ≥2-reviewer rule. -
craig-matching,craig-crypto,craig-signingare domain-pure; lower risk because the consumer surface is smaller.
On-call rotation framework
Forward-looking; not active in single-maintainer phase.
When the team has ≥3 contributors with sufficient context, on-call rotates weekly across:
-
Primary: triages new issues within 24h, responds to MR review requests within 48h, watches the
~urgentand~securitylabels. -
Secondary: backup if primary is unavailable; otherwise hands-off.
The rotation is tracked in a separate doc (TBD when team scales). On-call does not substitute for CODEOWNERS — primary still needs the right path-owner approval on MRs they triage.
Changing ownership for a single MR
If a CODEOWNERS owner is genuinely the wrong reviewer for a specific MR (e.g., the MR is a doc-only change touching a service path), they can defer to another reviewer in the MR description. This is per-MR, not a permanent transfer.
Why we don’t have ownership groups
GitLab supports CODEOWNERS group syntax (@<group-name>). CRAIG uses individual handles deliberately:
-
The maintainer-to-contributor ratio is currently 1:0; groups add ceremony without value.
-
Group expansion makes audit-log noise — every push triggers approvals from every group member.
-
When transferring ownership, individual handles are the easier diff.
If the team grows past ~10 contributors, revisit. Until then: individuals.
Related docs
-
CONTRIBUTING.adoc — MR completion protocol; CODEOWNERS approval is step 8
-
Contributor Onboarding — first-MR walkthrough
-
Writing ADRs — ADR process; ADRs do not require CODEOWNERS approval beyond the path of the ADR file itself (currently
docs/modules/ROOT/pages/adrs/)