Skip to content

chore(codeowners): re-tier per framework — governance/security/bot in T1, infra in T2#3053

Merged
ten9876 merged 8 commits into
mainfrom
auto/codeowners-tier4-root
May 24, 2026
Merged

chore(codeowners): re-tier per framework — governance/security/bot in T1, infra in T2#3053
ten9876 merged 8 commits into
mainfrom
auto/codeowners-tier4-root

Conversation

@ten9876

@ten9876 ten9876 commented May 24, 2026

Copy link
Copy Markdown
Collaborator

Summary

Final CODEOWNERS structure aligned to the maintainer-direction three-tier framework, with progressively narrower owner sets at higher tiers. All approvals human-only; @AetherClaude absent from every owner set.

Final state in commit `1aa9a446` (8 commits total on the branch documenting the iterative refinement).

Final tier structure

Tier Owners Coverage
Tier 1 @ten9876 Governance/direction, security, bot policy, CI workflows
Tier 2 @ten9876 + @jensenpat Project infrastructure (docs, tests, GH tooling, build config)
Tier 3 @ten9876 + @jensenpat + @NF0T + @rfoust Source code (broad default)

Each tier has a progressively wider roster:

  • T1 is single-approver for governance/security/bot policy where direction needs to be authoritative.
  • T2 narrows the source-review pool to 2 because infrastructure (docs, tests, CI, build config) needs deeper repo context than routine source review.
  • T3 has the full 4-human roster because routine source review benefits from more eyes.

Detailed path coverage

Tier 1 — @ten9876:

  • Governance/direction: `AGENTS.md`, `CLAUDE.md`, `GEMINI.md`, `CONSTITUTION.md`, `GOVERNANCE.md`, `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`, `LICENSE`, `ROADMAP.md`
  • Security/compliance: `SECURITY.md`, `SECURITY-AUDIT.md`, `THIRD_PARTY_LICENSES`, `.github/CODEOWNERS`, `.github/codeql/`, `docs/RELEASE-SIGNING-KEY.pub.asc`
  • CI runtime (kept here despite the framework's CI-in-T2 default — workflow changes can exfiltrate secrets or publish unsigned releases): `.github/workflows/`
  • Bot/agent instruction: `.claude/commands/`

Tier 2 — @ten9876 + @jensenpat:

  • Documentation & tests: `tests/`, `docs/`, `*.md` (catches README.md, CHANGELOG.md, SUPPORT.md by fall-through)
  • GitHub-specific tooling: `.github/dependabot.yml`, `.github/docker/`, `.github/ISSUE_TEMPLATE/`
  • Build configuration: `CMakeLists.txt`

Tier 3 — @ten9876 + @jensenpat + @NF0T + @rfoust:

  • `*` catches source and anything not enumerated: `src/`, `third_party/`, `plugins/`, `hal-plugin/`, `resources/`, `packaging/`, `scripts/`

How last-match-wins resolves (post-merge)

File Pattern that matches Tier Owner set
`CLAUDE.md` T1: `CLAUDE.md` (overrides `*.md`) T1 @ten9876
`README.md` T2: `*.md` (no T1 override) T2 @ten9876 + @jensenpat
`CHANGELOG.md` T2: `*.md` T2 @ten9876 + @jensenpat
`docs/install.md` T2: `docs/` (last match) T2 @ten9876 + @jensenpat
`.github/workflows/ci.yml` T1: `.github/workflows/` T1 @ten9876
`.github/codeql/codeql-config.yml` T1: `.github/codeql/` T1 @ten9876
`.claude/commands/loop.md` T1: `.claude/commands/` (overrides `*.md`) T1 @ten9876
`src/gui/MainWindow.cpp` T3: `*` T3 4 humans
`tests/foo.cpp` T2: `tests/` T2 @ten9876 + @jensenpat
`CMakeLists.txt` T2: `CMakeLists.txt` T2 @ten9876 + @jensenpat

Co-maintainer roster

  • @NF0T (Ryan) — Windows-installer RADE integration; Windows-build + FreeDV protocol background. Source-code Tier 3 only.
  • @rfoust (Robbie Foust) — FlexControl wheel tuning overhaul (#3029); input/UX layer expertise. Source-code Tier 3 only.

Stats

  • 1 file change to `.github/CODEOWNERS`
  • 8 commits total on the branch documenting the iterative refinement

Test plan

  • Diff review confirms only `.github/CODEOWNERS` is touched
  • `grep -c AetherClaude .github/CODEOWNERS` returns 1 (only the documentary inline mention)
  • `grep "@NF0T" .github/CODEOWNERS` returns 2 matches (header doc + Tier 3 `*` line only)
  • GitHub validates CODEOWNERS syntax on push (red banner on PR if invalid)
  • After merge: PR touching `CLAUDE.md` requires `@ten9876` (T1)
  • After merge: PR touching `README.md` is approvable by @ten9876 or @jensenpat (T2 — narrower than before)
  • After merge: PR touching `docs/foo.md` requires @ten9876 or @jensenpat (T2)
  • After merge: PR touching `.github/workflows/ci.yml` requires `@ten9876` (T1)
  • After merge: PR touching `src/gui/MainWindow.cpp` approvable by any of 4 humans (T3)
  • After merge: bot-authored PRs cannot self-approve via CODEOWNERS regardless of path

🤖 Generated with Claude Code

ten9876 and others added 2 commits May 24, 2026 06:53
…MakeLists.txt

Promotes nine root-dir files from Tier 2 (bot-approvable via the *.md
glob) to Tier 4 (maintainer-only):

  AGENTS.md, CHANGELOG.md, CONSTITUTION.md, GEMINI.md, README.md,
  ROADMAP.md, SECURITY-AUDIT.md, SUPPORT.md, THIRD_PARTY_LICENSES

These are all project-policy / repo-canon documents. The repo's root
directory is now uniformly Tier 4 with one explicit exception:
CMakeLists.txt stays at Tier 3 because build-config edits are
appropriate for the architecture-owner subset (jensenpat + ten9876).

Last-matching-pattern wins per CODEOWNERS semantics. The Tier 4
section already lands after the Tier 2 *.md and docs/ globs, so the
new specific patterns override the broader Tier 2 patterns correctly.
docs/*.md keeps Tier 2 behaviour (bot-approvable).

Listed individually rather than via a `/*` glob so a future root-dir
file addition triggers a deliberate review of which tier it belongs
in (added or omitted by the PR that introduces it). Implicit Tier 2
coverage for new root-dir files would risk silent demotion to bot-
approvable when the intent should be maintainer-only.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Elevates two community contributors to Tier 3 owner status across
the architecture & infrastructure paths:

  - @NF0T (Ryan) — shipped Windows-installer RADE integration; deep
    Windows-build expertise and FreeDV / digital-voice protocol
    background. Distinct from @tmiw (Mooneer, FreeDV project lead).
  - @rfoust (Robbie Foust) — shipped the FlexControl wheel tuning
    overhaul (#3029, merged today) with thorough adherence to project
    conventions; demonstrated solid grasp of the input/UX layer.

Tier 3 paths covered (no change to which paths are at Tier 3):

  - src/gui/MainWindow.{cpp,h}              (visual/UX direction)
  - src/models/RadioModel.{cpp,h}           (central state, threading)
  - src/core/AudioEngine.{cpp,h}            (audio pipeline)
  - src/core/PanadapterStream.{cpp,h}       (VITA-49 protocol bedrock)
  - CMakeLists.txt                          (build configuration)
  - .github/codeql/                         (security tooling)
  - .claude/commands/                       (agent configuration)

Tier 3 means: can approve PRs touching these paths; the bot
(@AetherClaude) explicitly cannot. Tier 4 (maintainer-only) remains
@ten9876-only — Ryan and Robbie do NOT gain approval rights on
project-policy / repo-canon files.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ten9876 ten9876 changed the title chore(codeowners): expand Tier 4 to cover all root-dir files except CMakeLists.txt chore(codeowners): expand Tier 4 to all root-dir files + add @NF0T and @rfoust as Tier 3 owners May 24, 2026
…ntainer scope)

Tier-3-only addition in the prior commit meant Ryan and Robbie could
only approve the seven specific Tier 3 paths — anything that fell
through to the Tier 1 `*` default (most src/ files) stayed restricted
to @ten9876 + @jensenpat. That's more limited than intended for
"elevate to code-owner status."

Widen the scope:
  - Tier 1 broad default: add @NF0T @rfoust alongside @ten9876 @jensenpat
  - Tier 2 mechanical paths (tests/, docs/, *.md, dependabot.yml,
    docker/, ISSUE_TEMPLATE/): add @NF0T @rfoust alongside the existing
    @ten9876 @jensenpat @AetherClaude
  - Tier 3: unchanged (already added in 21ba4e4)
  - Tier 4: unchanged — @ten9876 remains sole owner of project-policy
    and repo-canon files

Updated the file header comment to make the no-hierarchy semantics
explicit: CODEOWNERS has no permission inheritance — each path
matches exactly one line, that line's owners completely replace
earlier matches. Co-maintainers must be listed on every tier they're
expected to approve.

Net effect: @NF0T and @rfoust are now effective co-maintainers
alongside @jensenpat for everything except Tier 4.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ten9876 ten9876 changed the title chore(codeowners): expand Tier 4 to all root-dir files + add @NF0T and @rfoust as Tier 3 owners chore(codeowners): expand Tier 4 to root files + add @NF0T and @rfoust as co-maintainers May 24, 2026
…ictive)

Restructures the CODEOWNERS file per maintainer direction. The prior
commits in this PR converged on a four-tier model where Tier 1 was the
broad default. This commit flips the numbering convention:

  Tier 1 = most exclusive (smallest owner set)
  Tier 3 = broadest fall-through default

The file layout stays broad → specific so CODEOWNERS' last-match-wins
semantics still promote specificity. The numbering is documentary; the
operative behavior comes from pattern order in the file.

Tier mapping:

  - Tier 3 (broad default `*`):       4 humans + @AetherClaude
  - Tier 2 (project collaborators):   4 humans, no bot
  - Tier 1 (project policy):          @ten9876 only

This is a meaningful semantic shift, not just renaming:

Before this commit, the bot could only approve a narrow set of
mechanical/safe paths (tests/, docs/, *.md, .github/dependabot.yml,
.github/docker/, .github/ISSUE_TEMPLATE/) — and broad fall-through code
was humans-only. After this commit, the bot can approve any path that
falls through to the `*` default, but is excluded from the explicitly-
listed Tier 2 paths (mechanical + architecture both — what used to be
Tiers 2 and 3 collapsed into one human-only tier).

Net effect: bot approval is wider on general source but narrower on
the docs/tests/architecture surface. Project policy / repo-canon
files remain @ten9876-only as before.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ten9876 ten9876 changed the title chore(codeowners): expand Tier 4 to root files + add @NF0T and @rfoust as co-maintainers chore(codeowners): rewrite with inverted tier numbering + collaborators model May 24, 2026
Bot-generated PRs now require a human reviewer regardless of which
paths they touch. The @AetherClaude machine user is removed from
the Tier 3 broad-default owner set; Tier 1 and Tier 2 already had
no bot membership in the prior commit.

Net effect: Tier 2 and Tier 3 now have identical owner sets (the four
humans). The tier split is preserved for documentary purposes — Tier 2
explicitly enumerates the architecture / collaborator surfaces, Tier 3
catches everything else via the `*` fall-through. Keeping them as
separate tiers means a future change (e.g. reintroducing bot approval
on the broad default, or widening the collaborator roster) doesn't
accidentally alter the high-touch Tier 2 coverage.

Header comment updated to make the all-human policy explicit and
explain why the Tier 2 / Tier 3 split is retained despite the
matching owner sets.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ten9876 ten9876 changed the title chore(codeowners): rewrite with inverted tier numbering + collaborators model chore(codeowners): rewrite with inverted tier numbering + human-only approvals May 24, 2026
ten9876 and others added 2 commits May 24, 2026 07:12
…fall through)

Removes eight files from Tier 2's explicit enumeration:

  - src/gui/MainWindow.{cpp,h}
  - src/models/RadioModel.{cpp,h}
  - src/core/AudioEngine.{cpp,h}
  - src/core/PanadapterStream.{cpp,h}

These now match the Tier 3 broad-default `*` line. Because Tier 2 and
Tier 3 currently have identical owner sets (the four humans), the move
is functionally a no-op today — the same four reviewers can approve
PRs touching these files either way.

The change matters for future flexibility. If the Tier 3 broad-default
owner set is ever widened (e.g. adding more contributors as general
co-reviewers, or selectively reintroducing bot approval there), these
files inherit the wider coverage automatically rather than staying
pinned at the prior collaborator roster.

Tier 2 retains its purpose as "explicit human-attention surfaces" but
now narrows to the categories where the explicit listing is doing
real policy work: mechanical/safe paths (tests, docs, *.md, GitHub
config), build configuration (CMakeLists.txt), and security/agent
configuration (.github/codeql, .claude/commands).

The CLAUDE.md "AI Agent Boundaries" note is not lost — that policy is
enforced by the boundaries documented in CLAUDE.md itself, not by
this file's tier categorization.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… T1, infra in T2

Audits the file against the maintainer-direction tiering framework:

  Tier 1 — Governance, direction, security controls, bot instruction
  Tier 2 — Project infrastructure (CI/CD config, docs, GH tooling, build)
  Tier 3 — AetherSDR source code

Concrete moves:

  Tier 2 → Tier 1:
    .github/codeql/       (security tooling)
    .claude/commands/     (bot/agent instruction)

  Tier 1 → Tier 2 (fall-through via the *.md glob, no explicit lines
  needed in T2):
    README.md             (documentation, not governance)
    SUPPORT.md            (documentation, not governance)
    CHANGELOG.md          (release notes / docs, not governance)

  Tier 1, kept (with comment update explaining the exception):
    .github/workflows/    (categorically T2 under the framework but
                           kept at T1 because a malicious workflow
                           change can exfiltrate secrets or publish
                           unsigned releases — workflow-config
                           sensitivity outweighs the categorical
                           match)

The header comment is rewritten to describe each tier's framework
purpose explicitly, replacing the prior "project policy / collaborators
/ broad default" framing. Tier 1 now reads as the cohesive set:
governance + security + bot instruction. Tier 2 is squarely
infrastructure. Tier 3 is source code.

@AetherClaude remains absent from all owner sets; the four-human
collaborator roster remains the only approver group outside Tier 1.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ten9876 ten9876 changed the title chore(codeowners): rewrite with inverted tier numbering + human-only approvals chore(codeowners): re-tier per framework — governance/security/bot in T1, infra in T2 May 24, 2026
…, @rfoust)

Per maintainer direction, tighten Tier 2's owner roster:

  Tier 1 — @ten9876
  Tier 2 — @ten9876 + @jensenpat       (was: 4 humans)
  Tier 3 — @ten9876 + @jensenpat + @NF0T + @rfoust   (unchanged)

Rationale: infrastructure changes (docs, tests, CI tooling, build
config) need deeper repo context than routine source review, so the
collaborator pool there is intentionally narrower than the source-
code Tier 3 roster.

@NF0T and @rfoust retain Tier 3 source-code approval rights —
they can still review and approve any change to src/, third_party/,
plugins/, hal-plugin/, resources/, packaging/, scripts/. Removed
only from the explicit T2 paths (tests/, docs/, *.md,
.github/dependabot.yml, .github/docker/, .github/ISSUE_TEMPLATE/,
CMakeLists.txt).

Header comment updated to explain the narrower-T2-vs-broader-T3
rationale ("infrastructure needs deeper repo context"). Tier 2 and
Tier 3 no longer share an owner set; the old "functionally identical"
note is removed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ten9876 ten9876 merged commit 5058487 into main May 24, 2026
3 checks passed
@ten9876 ten9876 deleted the auto/codeowners-tier4-root branch May 24, 2026 14:25
ten9876 added a commit that referenced this pull request May 24, 2026
## Summary

Replaces individual \`@user\` mentions in CODEOWNERS with GitHub team
mentions. Identical approval semantics — only the *shape* of each
owner-set line changes. Roster management moves from "edit CODEOWNERS"
to "edit team membership in the org Teams UI."

Builds on the framework merged in #3053.

## What changes

| Tier | Was | Now | Members today |
|---|---|---|---|
| Tier 1 | \`@ten9876\` | \`@aethersdr/maintainers\` | @ten9876 |
| Tier 2 | \`@ten9876 @jensenpat\` | \`@aethersdr/infrastructure\` |
@ten9876, @jensenpat |
| Tier 3 | \`@ten9876 @jensenpat @NF0T @rfoust\` |
\`@aethersdr/reviewers\` | @ten9876, @jensenpat, @NF0T, @rfoust |

The path-to-tier mapping is unchanged from #3053. No file moves tier;
only the mention shape on each line changes.

## Prerequisite — repo access for the teams

GitHub only honors \`@org/team\` mentions in CODEOWNERS when the team
has **Write or higher** access to the repository. Before this PR merges,
verify in the org Teams UI:

| Team | Required access | Recommended |
|---|---|---|
| \`@aethersdr/maintainers\` | Write (minimum) | **Admin** (manages
branch protection / settings) |
| \`@aethersdr/infrastructure\` | Write (minimum) | **Maintain** (can
edit some repo settings / manage releases) |
| \`@aethersdr/reviewers\` | Write (minimum) | **Write** |

Per team: org Teams page → click the team → **Repositories** tab → **Add
repository** → \`aethersdr/AetherSDR\` → set access level.

GitHub will surface a warning at the top of this PR's "Files changed"
tab if any of the team mentions fail to resolve (team doesn't exist,
doesn't have access, or has the wrong access level). If the file is
valid, no warning.

## Header comment changes

The doc block at the top of CODEOWNERS now:

- References team slugs as the source of truth, with \`(currently:
<users>)\` annotations naming the current human members for
documentation
- Points readers to \`https://github.com/orgs/aethersdr/teams\` as the
live roster source
- Notes that \`@AetherClaude\` is intentionally not a member of any team
(preserves the human-only-approval rule from #3053)

## How last-match-wins resolves (post-merge, semantically identical to
today)

| File | Pattern that matches | Team |
|---|---|---|
| \`CLAUDE.md\` | T1: \`CLAUDE.md\` | @aethersdr/maintainers |
| \`README.md\` | T2: \`*.md\` | @aethersdr/infrastructure |
| \`docs/install.md\` | T2: \`docs/\` (last match) |
@aethersdr/infrastructure |
| \`.github/workflows/ci.yml\` | T1: \`.github/workflows/\` |
@aethersdr/maintainers |
| \`.github/codeql/codeql-config.yml\` | T1: \`.github/codeql/\` |
@aethersdr/maintainers |
| \`.claude/commands/loop.md\` | T1: \`.claude/commands/\` |
@aethersdr/maintainers |
| \`src/gui/MainWindow.cpp\` | T3: \`*\` | @aethersdr/reviewers |
| \`tests/foo.cpp\` | T2: \`tests/\` | @aethersdr/infrastructure |
| \`CMakeLists.txt\` | T2: \`CMakeLists.txt\` |
@aethersdr/infrastructure |

## Why this is a follow-up rather than a fix-up of #3053

- #3053 settled the tier model + path categorization
- This PR is a pure mention-shape refactor on top of the settled model
- Keeping them separate makes each step easier to review and bisect
- This change requires the teams to exist (they do, as of today) and
have repo access (must be granted before merge)

## Stats

- 1 file change to \`.github/CODEOWNERS\`
- +35 / -31

## Test plan

- [x] Diff review confirms only \`.github/CODEOWNERS\` is touched
- [x] All owner-set lines now reference \`@aethersdr/<team>\` (no
individual @user mentions on owner-set lines)
- [ ] Org Teams UI: verify all three teams exist with the expected
member rosters
- [ ] Org Teams UI: verify each team has \`aethersdr/AetherSDR\` listed
under Repositories with Write+ access
- [ ] GitHub validates the CODEOWNERS syntax on this PR — no warning
banner on the Files changed tab
- [ ] After merge: test PR touching \`README.md\` shows "Requesting
review from @aethersdr/infrastructure"
- [ ] After merge: test PR touching \`CLAUDE.md\` shows "Requesting
review from @aethersdr/maintainers"
- [ ] After merge: test PR touching \`src/gui/MainWindow.cpp\` shows
"Requesting review from @aethersdr/reviewers"
- [ ] After merge: adding a new contributor to \`@aethersdr/reviewers\`
immediately makes them an eligible reviewer on any \`*\` path, with no
further CODEOWNERS edits required

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
G6PWY-Chris pushed a commit to G6PWY-Chris/AetherSDR that referenced this pull request Jun 22, 2026
… T1, infra in T2 (aethersdr#3053)

## Summary

Final CODEOWNERS structure aligned to the maintainer-direction
three-tier framework, with progressively narrower owner sets at higher
tiers. All approvals human-only; @AetherClaude absent from every owner
set.

Final state in commit \`1aa9a446\` (8 commits total on the branch
documenting the iterative refinement).

## Final tier structure

| Tier | Owners | Coverage |
|---|---|---|
| **Tier 1** | @ten9876 | Governance/direction, security, bot policy, CI
workflows |
| **Tier 2** | @ten9876 + @jensenpat | Project infrastructure (docs,
tests, GH tooling, build config) |
| **Tier 3** | @ten9876 + @jensenpat + @NF0T + @rfoust | Source code
(broad default) |

Each tier has a progressively wider roster:
- **T1 is single-approver** for governance/security/bot policy where
direction needs to be authoritative.
- **T2 narrows the source-review pool to 2** because infrastructure
(docs, tests, CI, build config) needs deeper repo context than routine
source review.
- **T3 has the full 4-human roster** because routine source review
benefits from more eyes.

## Detailed path coverage

**Tier 1 — @ten9876:**
- Governance/direction: \`AGENTS.md\`, \`CLAUDE.md\`, \`GEMINI.md\`,
\`CONSTITUTION.md\`, \`GOVERNANCE.md\`, \`CONTRIBUTING.md\`,
\`CODE_OF_CONDUCT.md\`, \`LICENSE\`, \`ROADMAP.md\`
- Security/compliance: \`SECURITY.md\`, \`SECURITY-AUDIT.md\`,
\`THIRD_PARTY_LICENSES\`, \`.github/CODEOWNERS\`, \`.github/codeql/\`,
\`docs/RELEASE-SIGNING-KEY.pub.asc\`
- CI runtime (kept here despite the framework's CI-in-T2 default —
workflow changes can exfiltrate secrets or publish unsigned releases):
\`.github/workflows/\`
- Bot/agent instruction: \`.claude/commands/\`

**Tier 2 — @ten9876 + @jensenpat:**
- Documentation & tests: \`tests/\`, \`docs/\`, \`*.md\` (catches
README.md, CHANGELOG.md, SUPPORT.md by fall-through)
- GitHub-specific tooling: \`.github/dependabot.yml\`,
\`.github/docker/\`, \`.github/ISSUE_TEMPLATE/\`
- Build configuration: \`CMakeLists.txt\`

**Tier 3 — @ten9876 + @jensenpat + @NF0T + @rfoust:**
- \`*\` catches source and anything not enumerated: \`src/\`,
\`third_party/\`, \`plugins/\`, \`hal-plugin/\`, \`resources/\`,
\`packaging/\`, \`scripts/\`

## How last-match-wins resolves (post-merge)

| File | Pattern that matches | Tier | Owner set |
|---|---|---|---|
| \`CLAUDE.md\` | T1: \`CLAUDE.md\` (overrides \`*.md\`) | T1 | @ten9876
|
| \`README.md\` | T2: \`*.md\` (no T1 override) | T2 | @ten9876 +
@jensenpat |
| \`CHANGELOG.md\` | T2: \`*.md\` | T2 | @ten9876 + @jensenpat |
| \`docs/install.md\` | T2: \`docs/\` (last match) | T2 | @ten9876 +
@jensenpat |
| \`.github/workflows/ci.yml\` | T1: \`.github/workflows/\` | T1 |
@ten9876 |
| \`.github/codeql/codeql-config.yml\` | T1: \`.github/codeql/\` | T1 |
@ten9876 |
| \`.claude/commands/loop.md\` | T1: \`.claude/commands/\` (overrides
\`*.md\`) | T1 | @ten9876 |
| \`src/gui/MainWindow.cpp\` | T3: \`*\` | T3 | 4 humans |
| \`tests/foo.cpp\` | T2: \`tests/\` | T2 | @ten9876 + @jensenpat |
| \`CMakeLists.txt\` | T2: \`CMakeLists.txt\` | T2 | @ten9876 +
@jensenpat |

## Co-maintainer roster

- **@NF0T (Ryan)** — Windows-installer RADE integration; Windows-build +
FreeDV protocol background. Source-code Tier 3 only.
- **@rfoust (Robbie Foust)** — FlexControl wheel tuning overhaul
([aethersdr#3029](aethersdr#3029)); input/UX
layer expertise. Source-code Tier 3 only.

## Stats

- 1 file change to \`.github/CODEOWNERS\`
- 8 commits total on the branch documenting the iterative refinement

## Test plan

- [x] Diff review confirms only \`.github/CODEOWNERS\` is touched
- [x] \`grep -c AetherClaude .github/CODEOWNERS\` returns 1 (only the
documentary inline mention)
- [x] \`grep "@NF0T" .github/CODEOWNERS\` returns 2 matches (header doc
+ Tier 3 \`*\` line only)
- [ ] GitHub validates CODEOWNERS syntax on push (red banner on PR if
invalid)
- [ ] After merge: PR touching \`CLAUDE.md\` requires \`@ten9876\` (T1)
- [ ] After merge: PR touching \`README.md\` is approvable by @ten9876
or @jensenpat (T2 — narrower than before)
- [ ] After merge: PR touching \`docs/foo.md\` requires @ten9876 or
@jensenpat (T2)
- [ ] After merge: PR touching \`.github/workflows/ci.yml\` requires
\`@ten9876\` (T1)
- [ ] After merge: PR touching \`src/gui/MainWindow.cpp\` approvable by
any of 4 humans (T3)
- [ ] After merge: bot-authored PRs cannot self-approve via CODEOWNERS
regardless of path

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
G6PWY-Chris pushed a commit to G6PWY-Chris/AetherSDR that referenced this pull request Jun 22, 2026
## Summary

Replaces individual \`@user\` mentions in CODEOWNERS with GitHub team
mentions. Identical approval semantics — only the *shape* of each
owner-set line changes. Roster management moves from "edit CODEOWNERS"
to "edit team membership in the org Teams UI."

Builds on the framework merged in aethersdr#3053.

## What changes

| Tier | Was | Now | Members today |
|---|---|---|---|
| Tier 1 | \`@ten9876\` | \`@aethersdr/maintainers\` | @ten9876 |
| Tier 2 | \`@ten9876 @jensenpat\` | \`@aethersdr/infrastructure\` |
@ten9876, @jensenpat |
| Tier 3 | \`@ten9876 @jensenpat @NF0T @rfoust\` |
\`@aethersdr/reviewers\` | @ten9876, @jensenpat, @NF0T, @rfoust |

The path-to-tier mapping is unchanged from aethersdr#3053. No file moves tier;
only the mention shape on each line changes.

## Prerequisite — repo access for the teams

GitHub only honors \`@org/team\` mentions in CODEOWNERS when the team
has **Write or higher** access to the repository. Before this PR merges,
verify in the org Teams UI:

| Team | Required access | Recommended |
|---|---|---|
| \`@aethersdr/maintainers\` | Write (minimum) | **Admin** (manages
branch protection / settings) |
| \`@aethersdr/infrastructure\` | Write (minimum) | **Maintain** (can
edit some repo settings / manage releases) |
| \`@aethersdr/reviewers\` | Write (minimum) | **Write** |

Per team: org Teams page → click the team → **Repositories** tab → **Add
repository** → \`aethersdr/AetherSDR\` → set access level.

GitHub will surface a warning at the top of this PR's "Files changed"
tab if any of the team mentions fail to resolve (team doesn't exist,
doesn't have access, or has the wrong access level). If the file is
valid, no warning.

## Header comment changes

The doc block at the top of CODEOWNERS now:

- References team slugs as the source of truth, with \`(currently:
<users>)\` annotations naming the current human members for
documentation
- Points readers to \`https://github.com/orgs/aethersdr/teams\` as the
live roster source
- Notes that \`@AetherClaude\` is intentionally not a member of any team
(preserves the human-only-approval rule from aethersdr#3053)

## How last-match-wins resolves (post-merge, semantically identical to
today)

| File | Pattern that matches | Team |
|---|---|---|
| \`CLAUDE.md\` | T1: \`CLAUDE.md\` | @aethersdr/maintainers |
| \`README.md\` | T2: \`*.md\` | @aethersdr/infrastructure |
| \`docs/install.md\` | T2: \`docs/\` (last match) |
@aethersdr/infrastructure |
| \`.github/workflows/ci.yml\` | T1: \`.github/workflows/\` |
@aethersdr/maintainers |
| \`.github/codeql/codeql-config.yml\` | T1: \`.github/codeql/\` |
@aethersdr/maintainers |
| \`.claude/commands/loop.md\` | T1: \`.claude/commands/\` |
@aethersdr/maintainers |
| \`src/gui/MainWindow.cpp\` | T3: \`*\` | @aethersdr/reviewers |
| \`tests/foo.cpp\` | T2: \`tests/\` | @aethersdr/infrastructure |
| \`CMakeLists.txt\` | T2: \`CMakeLists.txt\` |
@aethersdr/infrastructure |

## Why this is a follow-up rather than a fix-up of aethersdr#3053

- aethersdr#3053 settled the tier model + path categorization
- This PR is a pure mention-shape refactor on top of the settled model
- Keeping them separate makes each step easier to review and bisect
- This change requires the teams to exist (they do, as of today) and
have repo access (must be granted before merge)

## Stats

- 1 file change to \`.github/CODEOWNERS\`
- +35 / -31

## Test plan

- [x] Diff review confirms only \`.github/CODEOWNERS\` is touched
- [x] All owner-set lines now reference \`@aethersdr/<team>\` (no
individual @user mentions on owner-set lines)
- [ ] Org Teams UI: verify all three teams exist with the expected
member rosters
- [ ] Org Teams UI: verify each team has \`aethersdr/AetherSDR\` listed
under Repositories with Write+ access
- [ ] GitHub validates the CODEOWNERS syntax on this PR — no warning
banner on the Files changed tab
- [ ] After merge: test PR touching \`README.md\` shows "Requesting
review from @aethersdr/infrastructure"
- [ ] After merge: test PR touching \`CLAUDE.md\` shows "Requesting
review from @aethersdr/maintainers"
- [ ] After merge: test PR touching \`src/gui/MainWindow.cpp\` shows
"Requesting review from @aethersdr/reviewers"
- [ ] After merge: adding a new contributor to \`@aethersdr/reviewers\`
immediately makes them an eligible reviewer on any \`*\` path, with no
further CODEOWNERS edits required

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant