Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 12 additions & 39 deletions .github/codeowners/areas.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -552,45 +552,18 @@ shared:
owners:
- ops
- runtime
# CODEOWNERS is a generated artifact, so co-ownership here is about who may
# approve it, not who reviews its contents. Every area is listed because under
# "any one approves" any single team satisfies the gate: without this, adding a
# file in an uncovered location needs an areas.yaml edit (ops) AND the
# regenerated CODEOWNERS (process), two approvals to land one file. The
# artifact cannot drift from the reviewed source -- emit_codeowners.py is a
# pure function of areas.yaml, and the workflow's regenerate-and-diff step
# fails on any hand-edit -- so widening approval here costs no safety.
- glob: CODEOWNERS
owners:
- process
- agents
- backend-sglang
- backend-trtllm
- backend-vllm
- diffusion
- docs
- epp
- fault-tolerance
- frontend
- gms
- kv-memory
- multimodal
- observability
- operator
- ops
- performance
- planner
- rl
- router
- runtime
- tokenspeed
- xpu
# areas.yaml is the routing decision itself, not a generated artifact, so it
# does not get the wide list above: nothing stops a rule here from re-routing
# review authority away from a team, and the strict gate only proves coverage,
# not that the owner is the right one. Ops and process both hold repo-wide
# process authority, and under "any one approves" either can unblock a routing
# change without a third team having to weigh in on paths it does not own.
# CODEOWNERS stays on the process area alone. GitHub requests every team on
# the matching line, even when one approval satisfies the gate, so listing
# every area here pages every codeowner group for a generated-file edit.
# areas.yaml is already shared by ops and process, so one process review
# still covers the source and the artifact.
# areas.yaml is the routing decision itself, not a generated artifact.
# Nothing stops a rule here from re-routing review authority away from a
# team, and the strict gate only proves coverage, not that the owner is the
# right one. Ops and process both hold repo-wide process authority, but a
# routing change also regenerates CODEOWNERS, which process owns alone, so a
# process approval is required. No third team has to weigh in on paths it
# does not own.
- glob: .github/codeowners/areas.yaml
owners:
- ops
Expand Down
10 changes: 10 additions & 0 deletions .github/codeowners/test_codeowners.py
Original file line number Diff line number Diff line change
Expand Up @@ -1134,6 +1134,16 @@ def test_script_in_policy_dir_is_policy(self) -> None:
def test_codeowners_output_is_policy(self) -> None:
assert is_policy_change(["CODEOWNERS"], self._AREAS, ".") is True

def test_codeowners_file_requests_only_process(self) -> None:
# GitHub requests every owner on the last matching line. A wide list
# on CODEOWNERS pages every codeowner group when the generated file
# changes, which is what happened on pull request 15170.
Comment thread
dagil-nvidia marked this conversation as resolved.
root = Path(__file__).resolve().parents[2]
rules = parse_codeowners((root / "CODEOWNERS").read_text())
assert resolve_owners(rules, "CODEOWNERS") == [
"@ai-dynamo/dynamo-process-codeowners"
]

def test_unrelated_change_is_not_policy(self) -> None:
assert (
is_policy_change(["src/foo.py", "owned/b.txt"], self._AREAS, ".") is False
Expand Down
1 change: 0 additions & 1 deletion CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,6 @@ requirements.txt
/.codex/ @ai-dynamo/dynamo-process-codeowners @ai-dynamo/dynamo-agents-codeowners
/agents/ @ai-dynamo/dynamo-process-codeowners @ai-dynamo/dynamo-agents-codeowners
/.agents/ @ai-dynamo/dynamo-process-codeowners @ai-dynamo/dynamo-agents-codeowners
/CODEOWNERS @ai-dynamo/dynamo-process-codeowners @ai-dynamo/dynamo-agents-codeowners @ai-dynamo/dynamo-backend-sglang-codeowners @ai-dynamo/dynamo-backend-trtllm-codeowners @ai-dynamo/dynamo-backend-vllm-codeowners @ai-dynamo/dynamo-diffusion-codeowners @ai-dynamo/dynamo-docs-codeowners @ai-dynamo/dynamo-epp-codeowners @ai-dynamo/dynamo-fault-tolerance-codeowners @ai-dynamo/dynamo-frontend-codeowners @ai-dynamo/dynamo-gms-codeowners @ai-dynamo/dynamo-kv-memory-codeowners @ai-dynamo/dynamo-multimodal-codeowners @ai-dynamo/dynamo-observability-codeowners @ai-dynamo/dynamo-operator-codeowners @ai-dynamo/dynamo-ops-codeowners @ai-dynamo/dynamo-performance-codeowners @ai-dynamo/dynamo-planner-codeowners @ai-dynamo/dynamo-rl-codeowners @ai-dynamo/dynamo-router-codeowners @ai-dynamo/dynamo-runtime-codeowners @ai-dynamo/dynamo-tokenspeed-codeowners @ai-dynamo/dynamo-xpu-codeowners
/agent-docs/ @ai-dynamo/dynamo-process-codeowners @ai-dynamo/dynamo-agents-codeowners
/.lycheeignore @ai-dynamo/dynamo-ops-codeowners @ai-dynamo/dynamo-docs-codeowners
/tests/deploy/ @ai-dynamo/dynamo-ops-codeowners @ai-dynamo/dynamo-operator-codeowners
Expand Down
Loading