Skip to content

Code ownership

Every repository has an owning team, declared in CODEOWNERS.

Updated View as Markdown

Every repository has an owning team. It is declared in CODEOWNERS and can be found without asking someone. Four-eyes depends on this: “request a qualified reviewer within the hour” works only when the qualifications are written down somewhere a newcomer can find.

  • Ownership belongs to a team, never one person. People change teams, take leave, and hand over work. Review windows do not stop because of this.
  • CODEOWNERS covers the whole repository. It also has narrower rules for paths that need special knowledge, the generated domain model, authentication and authorisation, money movement and risk, CI configuration, and infrastructure.
  • The owning team is responsible for meeting the review windows, handling the dependency and advisory backlog, and keeping the runbook accurate.
  • A shared package or platform component has an extra responsibility because every consumer receives its changes. It needs an RFC by default instead of a routine pull request. See design docs, RFCs and ADRs.
  • Unowned code is a liability. A repository without an owning team must be adopted or archived. Live and unowned is not a third option.
  • Ownership can change. Record the handover so the next person who works on the code knows who to ask.

Declare ownership in CODEOWNERS

Put a repo-root catch-all first. Then add narrower path rules. The last matching pattern wins, so put the most specific rules after the catch-all. Owners are GitHub teams, never usernames.

# .github/CODEOWNERS — catch-all first; last match wins
*                       @NT-NinjaTrader/platform
/modeling/generated/**  @NT-NinjaTrader/domain-model
/auth/**                @NT-NinjaTrader/identity
/risk/**                @NT-NinjaTrader/trading-core
/money/**               @NT-NinjaTrader/trading-core
*.tf                    @NT-NinjaTrader/sre
/.github/workflows/**   @NT-NinjaTrader/sre

List high-risk paths clearly for the stack, and give each one a dedicated owner:

Path Why it needs a named owner
The generated domain model (from tradovate/master-scheme) One change affects every consumer of the scheme.
Authentication and authorisation modules A mistake here is a security and authentication incident.
Money movement and risk Financial correctness matters. A missed issue directly affects customers.
*.tf and Atlantis config Infrastructure changes apply to live GCP; see CI/CD.
.github/workflows/** Workflow changes can weaken every other gate.

Ownership must resolve

A CODEOWNERS entry enforces review only when it points to a real owner that can write to the repository. Two failure modes create false coverage that looks protected but is not.

  • The owning team must have at least write access to the repository. GitHub silently ignores a code-owner team without write access. Required-code-owner review then passes without an owner assigned.
  • A typo’d or unresolvable owner is skipped, not flagged, at review time. Validate CODEOWNERS in CI. This makes the error fail a pull request instead of hiding it.

GitHub provides parse and resolution errors through its REST API. Fail the pull request when the list is not empty:

name: codeowners
on: [pull_request]
jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Validate CODEOWNERS
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          count=$(gh api "repos/${{ github.repository }}/codeowners/errors" --jq '.errors | length')
          if [ "$count" -ne 0 ]; then
            gh api "repos/${{ github.repository }}/codeowners/errors"
            echo "CODEOWNERS has $count unresolvable owner(s) or syntax error(s)." >&2
            exit 1
          fi

Pin any JavaScript action to a node24-native release before adding it. See CI/CD.

Ownership is operational, not just review

The team declared in CODEOWNERS also owns the code in production. It approves reviews, handles on-call and PagerDuty escalations, and owns the SLO. It is one team, not three. When ownership changes, the on-call rotation and escalation policy change with it. See releases and incidents.

Review ownership on a cadence

Reorganisations can orphan paths and leave CODEOWNERS pointing to teams that no longer exist. Run a scheduled ownership review (quarterly). Check each repository for unresolvable owners, catch-all coverage, and paths whose owning team has reorganised. This turns the “ownership can move” rule into a check instead of a hope.

Open questions

References

Navigation

Type to search…

↑↓ navigate↵ selectEsc close