Skip to main content

se-codeowners

PyPI Docs Site Repo Python 3.14 License

CI-Lean CI Docs-Deploy Pre-Release Release Links Dependabot

Standalone CLI utility that implements GitHub CODEOWNERS projection

Overview

Generate a GitHub CODEOWNERS file from the role-based oversight metadata in .accountability/surfaces.toml.

The surfaces file is the advisory rationale: it names each accountability surface, the paths it covers, and the oversight_role responsible for it. se-codeowners resolves each role to a GitHub handle or team via [codeowners.role_handles] and emits the corresponding CODEOWNERS entries.

The generated CODEOWNERS file provides GitHub review routing. It becomes a merge gate only when repository branch protection or rulesets require code-owner review.

Install

uv tool install se-codeowners

Uses the standard-library tomllib. No runtime dependencies.

Run Without Installing

uvx se-codeowners --help

Usage

# Render to stdout
uv run se-codeowners generate

# Write the file
uv run se-codeowners generate --output .github/CODEOWNERS

# Fail if any role still maps to a placeholder handle (e.g. `@OWNER`):
uv run se-codeowners generate --strict --output .github/CODEOWNERS

# Verify
uv run se-codeowners check

Both subcommands accept --surfaces PATH; check also accepts --codeowners PATH. The defaults are .accountability/surfaces.toml and .github/CODEOWNERS.

What the surfaces file must contain

[codeowners]
informs = true                           # opt in; generation refuses without an entry
requires_code_owner_review = false       # opt in; generation refuses without an entry

[codeowners.role_handles]
owner = "@octocat"                       # a single handle
maintainer = ["@octocat", "@org/team"]   # or several owners
data-steward = "@octocat"

[[surface]]
id = "data-contract"
name = "Data contract"
paths = ["data/raw/**"]
oversight_role = "data-steward"          # must have an entry in role_handles
oversight_role = "data-steward"
codeowners_order = 100

Surfaces without an oversight_role are skipped. A role used by a surface but missing from role_handles is a hard error.

Projected surfaces must declare codeowners_order. Lower values emit earlier; later matching CODEOWNERS patterns take precedence.

Path translation

surfaces.toml uses repository-root-relative globs. CODEOWNERS uses gitignore-style patterns with a smaller feature set, so patterns are converted:

surfaces.toml CODEOWNERS meaning
README.md /README.md one file at the repo root
docs/** /docs/** a directory, recursively
sql/duckdb/** /sql/duckdb/** a nested directory, recursively
docs/* /docs/* direct children only
src/app/case.py /src/app/case.py one nested file

Patterns CODEOWNERS cannot express:

  • negation (!),
  • single-character (?),
  • character ranges ([...]), or a
  • ** segment anywhere but a trailing /**

These are rejected at generation time with a message naming the offending pattern, so the failure surfaces during generation.

GitHub applies the last matching pattern for a path. Entries are emitted by codeowners_order, then surface id.

Keeping it in sync (CI / pre-commit)

Add a hook to the consuming repository so a stale CODEOWNERS fails review:

# .pre-commit-config.yaml in the repo that owns surfaces.toml
- repo: local
  hooks:
    - id: codeowners-up-to-date
      name: CODEOWNERS matches surfaces.toml
      entry: uv run se-codeowners check --strict
      language: system
      files: ^(\.accountability/surfaces\.toml|\.github/CODEOWNERS)$
      pass_filenames: false

Layout

se-codeowners/
├── src/se_codeowners/
│   ├── __init__.py        public API: load_surfaces, render_codeowners, ...
│   ├── __main__.py        module entry: python -m se_codeowners (PATH-independent)
│   ├── _narrow.py         boundary narrowing: tomllib Any -> typed values
│   ├── model.py           frozen dataclasses (Surface, SurfacesDoc)
│   ├── load.py            parse + validate surfaces.toml into the model
│   ├── translate.py       surface glob -> CODEOWNERS pattern
│   ├── generate.py        SurfacesDoc -> CODEOWNERS text
│   └── cli.py             generate / check subcommands
└── tests/

Dependency direction is one-way:

  • _narrow and model depend on nothing in the package;
  • load depends on both;
  • translate is standalone;
  • generate depends on model and translate;
  • cli depends on load and generate.

No raw Any from tomllib escapes _narrow/load.

Developer Command Reference

Show command reference

In a machine terminal

Open a machine terminal where you want the project:

git clone https://github.com/structural-explainability/se-codeowners

cd se-codeowners
code .

In a VS Code terminal

Use VS Code Menu: View / Command Palette / Developer: Reload Window to refresh.

uv self update
uv python pin 3.14
uv lock --upgrade
uv sync --extra dev --extra docs --upgrade

uvx pre-commit install

uv run se-codeowners --help
uv run se-codeowners generate --help
uv run se-codeowners check --help

# validate manifest file
uvx se-manifest-schema validate-manifest --path SE_MANIFEST.toml --strict

git add -A
uvx pre-commit run --all-files
# repeat if changes were made
uvx pre-commit run --all-files

uv run python -m pyright
uv run python -m pytest
uv run python -m zensical build

# check import layers
uvx --with-editable . --from import-linter lint-imports --config .github/.importlinter

# check complexity; no output is good (all A or B)
uvx radon cc src/se_codeowners -s -a -n C

uv build
uvx twine check dist/*

# save progress
git add -A
git commit -m "update"
git push -u origin main

Authority Manifest

.accountability/surfaces.toml

Citation

CITATION.cff

License

MIT

Repository Manifest

SE_MANIFEST.toml

Metadata

Release files for se-codeowners 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for se-codeowners 0.2.0
File Size Uploaded Provenance Actions
se_codeowners-0.2.0.tar.gz 69.4 kB With provenance Details for se_codeowners-0.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for se-codeowners 0.2.0
File Interpreter ABI Platform Actions
se_codeowners-0.2.0-py3-none-any.whl Python 3 none any Details for se_codeowners-0.2.0-py3-none-any.whl

Total release size: 83.7 kB

Release files / se_codeowners-0.2.0.tar.gz

Download URL se_codeowners-0.2.0.tar.gz
Size 69.4 kB
Tags Source
SHA-256 checksum
How to use checksums
00dc8fb4cc15e2e681ad0b885d54d3ea5153496b702503c76b45b5e211a5d8d2
BLAKE2b-256 checksum
How to use checksums
ee0beee8ab237635fc8cdf13e7a12b580950dcae9f1e0c6395a9a9dfda9ddd00
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 5, 2026.

Transparency log

Release files / se_codeowners-0.2.0-py3-none-any.whl

Download URL se_codeowners-0.2.0-py3-none-any.whl
Size 14.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
143ecc1908863b4de793c3efac3188120e8b3a14ec87a6c07027e621bfcde905
BLAKE2b-256 checksum
How to use checksums
a9fe7c1fb1a0dfeff751e3a285bf0f13d16d105a964bb7e1ccd1145085d3e792
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 5, 2026.

Transparency log

Security for se-codeowners 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for se_codeowners-0.2.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 5, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page