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

crates/craig-common/, crates/craig-auth/, crates/craig-db/, crates/craig-mq/, crates/craig-api/, crates/craig-store/, crates/craig-reference/, crates/craig-intake-sdk/, crates/craig-test-lib/, crates/craig-matching/, crates/craig-crypto/, crates/craig-signing/

@bitskrieg

Services

services/craig-rules/, services/craig-cases/, services/craig-placement/, services/craig-exchange/, services/craig-financial/, services/craig-reporting/, services/craig-security/, services/craig-intake/, services/craig-composition/, services/craig-web/, services/craig-cli/

@bitskrieg

Tooling + infra + docs

xtask/, tools/, docs/, .claude/, .gitlab-ci.yml, Dockerfile*, docker-compose*.yml

@bitskrieg

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

  1. 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.

  2. Update this page’s "current owner" column.

  3. 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:

  1. Comment on the MR: @<owner> ping — blocking #<dep> / 48h+

  2. If still no response after another 24 hours, request review from a co-maintainer (any handle in the CODEOWNERS file for an adjacent path).

  3. 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-auth are the highest-risk crates: every service depends on them. CODEOWNERS for these paths should always have ≥2 reviewers when the team grows.

  • craig-test-lib is the test harness; changes here can hide regressions. Same ≥2-reviewer rule.

  • craig-matching, craig-crypto, craig-signing are 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 ~urgent and ~security labels.

  • 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.

  • 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/)

Edit this page · latest