From bb4057d1ce3072057f1263f7458e09601cbb4522 Mon Sep 17 00:00:00 2001 From: Jim Meyer Date: Thu, 22 Oct 2026 17:04:14 +0000 Subject: [PATCH 01/11] docs(review): propose area and topic reviewer registry Signed-off-by: Jim Meyer --- REVIEWERS.md | 274 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 274 insertions(+) create mode 100644 REVIEWERS.md diff --git a/REVIEWERS.md b/REVIEWERS.md new file mode 100644 index 0000000000..21dfbb1a5a --- /dev/null +++ b/REVIEWERS.md @@ -0,0 +1,274 @@ +# Review areas and topics + +Draft for community review. All names below are suggestions, not confirmed volunteers. No automatic requests, notifications, or new approval requirements are enabled by this draft. + +Related work: [review routing and membership workflow (#4839)](https://github.com/NVIDIA/OpenShell/issues/4839). + +## Purpose + +Help authors and tools invite the right people to review OpenShell changes. Areas identify components and system boundaries with coordinating ownership. Topics identify expertise that can apply across several areas. An issue or PR can involve several topics. + +These definitions follow the group's reviewed areas/topics proposal. This file is the proposed repository registry; the initial roster and format remain open for review. + +## Join, change, or leave a roster + +Open a PR editing the relevant membership tables below. Include your GitHub handle, role, status, and review scope. Explain the change in the PR description. A reviewed and merged PR is the sign-up mechanism for every role. + +For the initial proposal, comment on the forthcoming registry PR to suggest additions, removals, or scope corrections. A proposed person's agreement is needed before their entry becomes confirmed. Contributions linked below are evidence for discussion, not proof of willingness or complete subject-matter coverage. + +Subscriber entries require the individual's opt-in. No subscribers have been enrolled in this draft. + +## Roles and coverage + +| Role | Participation | Repository privilege | +| --- | --- | --- | +| maintainer | Available for review and approval in the recorded scope. | Maintain or admin. | +| reviewer | Available for selected review requests in the recorded scope. | Write. | +| subscriber | Receives relevant-work notifications and can contribute feedback without a review obligation. | Read, including public access. | + +Roles follow repository privileges. Aligning today's privileges and the CNCF organization's permissions is outside this proposal. Suggested maintainer entries are drawn from [MAINTAINERS.md](MAINTAINERS.md); this registry does not grant repository access or change the existing maintainer approval check. + +Target at least two confirmed maintainers covering every area and topic. Suggestions do not count as confirmed coverage. Scope limitations matter: two names do not establish two-person coverage of every specialty. All categories currently need confirmation; compliance and MCP also need additional maintainer nominations. + +## Proposed routing behavior + +Every ready-for-review PR has exactly one primary area for coordination and zero or more relevant topics. There is no hard topic limit; apply topics that merit specialist review. Other materially affected areas still contribute reviewers even when they are not the primary area. + +Select a non-author maintainer from the primary area and relevant reviewers for the topics and secondary-area impact. Reuse people who cover several categories, distribute requests among eligible volunteers, and allow human reassignment. Notify opted-in subscribers separately and deduplicate notifications across categories. + +Routing must use confirmed membership from the trusted merged registry. A PR changing this file cannot use its proposed membership to authorize its own review. Selection and notifications are follow-up work in #4839; they do not make every roster member a required approver. + +## Registry format + +Each category has a level-three heading containing its exact label, a scope description, and a membership table with these fixed columns: + +| Column | Meaning | +| --- | --- | +| GitHub | One GitHub login, written as an @mention. | +| Role | `maintainer`, `reviewer`, or `subscriber`. | +| Status | `suggested` or `confirmed`. Only confirmed entries may receive automated requests or notifications. | +| Scope | The person's review scope or notification interests. | +| Basis | Optional contribution evidence for a suggestion, or `Self-nominated` for a volunteer. | + +Use one row per person in a category. A maintainer or reviewer can cover several categories, but should not also have a subscriber row in the same category. Remove an entry through a reviewed PR to withdraw, or change it to subscriber when the person wants notifications without review requests. + +## Areas + +Areas are OpenShell-specific components or system boundaries. They represent the division of labor across the project. Keep the number of areas small enough to support named leads and reporting during community calls. + +### area:build + +CI/CD workflows, release pipelines, build targets, packaging, and artifact publication. + +| GitHub | Role | Status | Scope | Basis | +| --- | --- | --- | --- | --- | +| @matthewgrossman | maintainer | suggested | Release pipelines and packaging | [#4754](https://github.com/NVIDIA/OpenShell/pull/4754) | +| @SDAChess | maintainer | suggested | Build tooling and compatibility checks | [#4611](https://github.com/NVIDIA/OpenShell/pull/4611) | + +### area:drivers + +Infrastructure orchestration, including compute scheduling, secret management, runtime integrations (GPU, Docker, virtual machines, Kata Containers, and Kubernetes), deployment topologies, and pause/resume lifecycle operations. Includes host OS and architecture support (including amd64 and arm64), backend-specific isolation (including Windows AppContainer and isolation sessions), and compatibility. + +| GitHub | Role | Status | Scope | Basis | +| --- | --- | --- | --- | --- | +| @elezar | maintainer | suggested | Compute capabilities and backend integration | [#3010](https://github.com/NVIDIA/OpenShell/pull/3010) | +| @drew | maintainer | suggested | Compute-driver and supervisor integration | [#4656](https://github.com/NVIDIA/OpenShell/pull/4656) | +| @mrunalp | maintainer | suggested | Kubernetes compute driver | [#4527](https://github.com/NVIDIA/OpenShell/pull/4527) | + +### area:runtime + +Sandbox execution, isolation, process supervision, policy enforcement, network proxying, middleware, volumes, and (agent) memory. Includes shared isolation primitives such as Linux namespaces, seccomp and Landlock, and process/executable identity. + +Provider discovery and configuration, profiles, sandbox attachments, provider-contributed policy, credential resolution and delivery, refresh and rotation, and provider lifecycle management. + +| GitHub | Role | Status | Scope | Basis | +| --- | --- | --- | --- | --- | +| @drew | maintainer | suggested | Isolation, workload execution, and supervisor lifecycle | [#4106](https://github.com/NVIDIA/OpenShell/pull/4106) | +| @TaylorMutch | maintainer | suggested | Sandbox and supervisor integration | [#4823](https://github.com/NVIDIA/OpenShell/pull/4823) | +| @shiju-nv | reviewer | suggested | Provider credentials and protocol inspection | [#4152](https://github.com/NVIDIA/OpenShell/pull/4152) | + +### area:enterprise + +Authentication, multitenancy, gateway interceptors, FIPS compliance, and other enterprise requirements. + +| GitHub | Role | Status | Scope | Basis | +| --- | --- | --- | --- | --- | +| @sjenning | maintainer | suggested | Extension contracts and provider authorization | [#4357](https://github.com/NVIDIA/OpenShell/pull/4357) | +| @derekwaynecarr | maintainer | suggested | Service authorization | [#3796](https://github.com/NVIDIA/OpenShell/pull/3796) | + +### area:platform + +SDKs, CLIs, API machinery, gateway infrastructure, persistence (eg postgres, sqlite support), configuration (gateway.toml), and gateway-side sandbox and session management. + +| GitHub | Role | Status | Scope | Basis | +| --- | --- | --- | --- | --- | +| @pimlock | maintainer | suggested | Gateway configuration and supervisor sessions | [#4320](https://github.com/NVIDIA/OpenShell/pull/4320) | +| @TaylorMutch | maintainer | suggested | CLI and Rust SDK integration | [#4817](https://github.com/NVIDIA/OpenShell/pull/4817) | + +## Topics + +Topics connect contributors with work matching their expertise or interests. They describe technical concerns across areas rather than separate component ownership. + +### topic:api + +Public API contracts, gRPC and protobuf definitions, SDK interfaces, versioning, compatibility, API ergonomics, design patterns, component and communication standards. + +| GitHub | Role | Status | Scope | Basis | +| --- | --- | --- | --- | --- | +| @drew | maintainer | suggested | Public API entities and references | [#3272](https://github.com/NVIDIA/OpenShell/pull/3272) | +| @mrunalp | maintainer | suggested | Workspace selectors and mutation contracts | [#3321](https://github.com/NVIDIA/OpenShell/pull/3321) | + +### topic:architecture + +Cross-cutting system design, component boundaries, data and control flow, architectural decisions, and RFC-level concerns. + +| GitHub | Role | Status | Scope | Basis | +| --- | --- | --- | --- | --- | +| @drew | maintainer | suggested | Runtime and compute-driver boundaries | [#4106](https://github.com/NVIDIA/OpenShell/pull/4106) | +| @mrunalp | maintainer | suggested | Gateway mutation architecture | [#3321](https://github.com/NVIDIA/OpenShell/pull/3321) | + +### topic:authnz + +Authentication, authorization, credential protection, policy integrity/signed policiesIncludes identity verification, login and session handling, OIDC integration, bearer-token validation, access permissions, and authorization across tenant and workspace boundaries. + +| GitHub | Role | Status | Scope | Basis | +| --- | --- | --- | --- | --- | +| @sjenning | maintainer | suggested | Provider authorization and extension negotiation | [#4357](https://github.com/NVIDIA/OpenShell/pull/4357) | +| @krishicks | maintainer | suggested | Gateway and sandbox authentication | [#4762](https://github.com/NVIDIA/OpenShell/pull/4762) | + +### topic:compliance + +FIPS, regulatory alignment, auditability, and standardization requirements. + +| GitHub | Role | Status | Scope | Basis | +| --- | --- | --- | --- | --- | +| @johntmyers | maintainer | suggested | Repository license and compliance text; FIPS coverage needs nomination | [#3467](https://github.com/NVIDIA/OpenShell/pull/3467) | + +### topic:documentation + +Architecture documentation, README maintenance, project website updates, and automated documentation generation. + +| GitHub | Role | Status | Scope | Basis | +| --- | --- | --- | --- | --- | +| @krishicks | maintainer | suggested | Observability documentation | [#4560](https://github.com/NVIDIA/OpenShell/pull/4560) | +| @drew | maintainer | suggested | Deployment and contributor-facing documentation | [#4622](https://github.com/NVIDIA/OpenShell/pull/4622) | + +### topic:dx + +Ensure OpenShell is easy to contribute to for humans and agents. + +| GitHub | Role | Status | Scope | Basis | +| --- | --- | --- | --- | --- | +| @elezar | maintainer | suggested | Contributor triage and workflow tooling | [#4534](https://github.com/NVIDIA/OpenShell/pull/4534) | +| @johntmyers | maintainer | suggested | Agent review and contributor workflows | [#4309](https://github.com/NVIDIA/OpenShell/pull/4309) | + +### topic:gpu + +GPU scheduling, Kubernetes Dynamic Resource Allocation (DRA), Container Device Interface (CDI) configuration, Multi-Instance GPU (MIG) support, and hardware-accelerated runtime integration. + +| GitHub | Role | Status | Scope | Basis | +| --- | --- | --- | --- | --- | +| @elezar | maintainer | suggested | Device capabilities and compute integration | [#3010](https://github.com/NVIDIA/OpenShell/pull/3010) | +| @alangou | maintainer | suggested | CDI device identity and validation | [#4306](https://github.com/NVIDIA/OpenShell/pull/4306) | + +### topic:kubernetes + +Kubernetes operator development, custom resource definitions (CRDs), deployment controllers, and native integration with Kubernetes APIs. + +| GitHub | Role | Status | Scope | Basis | +| --- | --- | --- | --- | --- | +| @mrunalp | maintainer | suggested | Kubernetes compute-driver behavior | [#4527](https://github.com/NVIDIA/OpenShell/pull/4527) | +| @drew | maintainer | suggested | Shared supervisor deployment | [#4695](https://github.com/NVIDIA/OpenShell/pull/4695) | + +### topic:mcp + +Model Context Protocol (MCP) support, server and client implementations, and standard integration. + +| GitHub | Role | Status | Scope | Basis | +| --- | --- | --- | --- | --- | +| @johntmyers | maintainer | suggested | Network enforcement integration; MCP-specific coverage needs confirmation | [#2723](https://github.com/NVIDIA/OpenShell/pull/2723) | +| @shiju-nv | reviewer | suggested | MCP protocol and revision enforcement | [#3850](https://github.com/NVIDIA/OpenShell/pull/3850) | + +### topic:networking + +General network transport, connectivity, and proxy behavior not covered by the more specialized L7 category. + +| GitHub | Role | Status | Scope | Basis | +| --- | --- | --- | --- | --- | +| @johntmyers | maintainer | suggested | Proxy egress and transparent TCP | [#2723](https://github.com/NVIDIA/OpenShell/pull/2723) | +| @alangou | maintainer | suggested | DNS and hostname policy enforcement | [#4602](https://github.com/NVIDIA/OpenShell/pull/4602) | +| @shiju-nv | reviewer | suggested | HTTP and application-protocol inspection | [#3753](https://github.com/NVIDIA/OpenShell/pull/3753) | + +### topic:observability + +Logging, metrics, tracing, telemetry, dashboards, event correlation, and the collection or export of operational data from gateways and sandboxes. + +| GitHub | Role | Status | Scope | Basis | +| --- | --- | --- | --- | --- | +| @krishicks | maintainer | suggested | OCSF and OpenTelemetry | [#4545](https://github.com/NVIDIA/OpenShell/pull/4545) | +| @matthewgrossman | maintainer | suggested | Tracing correctness and log handling | [#4212](https://github.com/NVIDIA/OpenShell/pull/4212) | + +### topic:operability + +Deployment and configuration of OpenShell installations, upgrades, backup and restore, disaster recovery, operational diagnostics, and maintenance of running installations. + +| GitHub | Role | Status | Scope | Basis | +| --- | --- | --- | --- | --- | +| @pimlock | maintainer | suggested | Gateway configuration and Kubernetes reconciliation | [#4676](https://github.com/NVIDIA/OpenShell/pull/4676) | +| @TaylorMutch | maintainer | suggested | HA gateway operation | [#1868](https://github.com/NVIDIA/OpenShell/pull/1868) | + +### topic:performance + +Startup time, latency, throughput, resource overhead, scalability, and benchmarking. Includes rate limiting. + +| GitHub | Role | Status | Scope | Basis | +| --- | --- | --- | --- | --- | +| @matthewgrossman | maintainer | suggested | Gateway and supervisor overhead | [#4619](https://github.com/NVIDIA/OpenShell/pull/4619) | +| @drew | maintainer | suggested | Sandbox process lifecycle overhead | [#3757](https://github.com/NVIDIA/OpenShell/pull/3757) | + +### topic:policy + +Policy authoring, validation, proving, distribution, enforcement, and policy ergonomics across runtimes and APIs. Includes policy hardening. + +| GitHub | Role | Status | Scope | Basis | +| --- | --- | --- | --- | --- | +| @alangou | maintainer | suggested | Policy matching and proof correctness | [#4326](https://github.com/NVIDIA/OpenShell/pull/4326) | +| @pimlock | maintainer | suggested | Policy authoring and rule proposals | [#3707](https://github.com/NVIDIA/OpenShell/pull/3707) | +| @shiju-nv | reviewer | suggested | Provider and application-protocol policy | [#3850](https://github.com/NVIDIA/OpenShell/pull/3850) | + +### topic:reliability + +High availability, failure recovery, retries, graceful degradation, fault tolerance, and operational resilience. Includes correctness across restarts. + +| GitHub | Role | Status | Scope | Basis | +| --- | --- | --- | --- | --- | +| @TaylorMutch | maintainer | suggested | HA gateway behavior | [#1868](https://github.com/NVIDIA/OpenShell/pull/1868) | +| @pimlock | maintainer | suggested | Gateway reconciliation and lifecycle | [#4676](https://github.com/NVIDIA/OpenShell/pull/4676) | + +### topic:sdk + +Software Development Kit (SDK) creation, maintenance, language bindings, and distribution. + +| GitHub | Role | Status | Scope | Basis | +| --- | --- | --- | --- | --- | +| @TaylorMutch | maintainer | suggested | Rust SDK and CLI integration | [#4817](https://github.com/NVIDIA/OpenShell/pull/4817) | +| @SDAChess | maintainer | suggested | TypeScript SDK | [#4495](https://github.com/NVIDIA/OpenShell/pull/4495) | +| @maxdubrinsky | reviewer | suggested | Python SDK and credential-driver bindings | [#4760](https://github.com/NVIDIA/OpenShell/pull/4760) | + +### topic:security + +Vulnerability management, static/dynamic analysis, FSR (Functional Security Requirement) implementation, and security auditing. Includes bypass detection, abuse prevention, and vulnerability remediation. + +| GitHub | Role | Status | Scope | Basis | +| --- | --- | --- | --- | --- | +| @alangou | maintainer | suggested | Security scanning and policy validation | [#4203](https://github.com/NVIDIA/OpenShell/pull/4203) | +| @johntmyers | maintainer | suggested | Security regression review | [#4338](https://github.com/NVIDIA/OpenShell/pull/4338) | + +### topic:testing + +Unit, integration, regression, conformance, and end-to-end testing, including test infrastructure, coverage gaps, flaky tests, and environment-specific test failures. + +| GitHub | Role | Status | Scope | Basis | +| --- | --- | --- | --- | --- | +| @matthewgrossman | maintainer | suggested | Conformance and tracing tests | [#4521](https://github.com/NVIDIA/OpenShell/pull/4521) | +| @SDAChess | maintainer | suggested | Test infrastructure and compatibility checks | [#4488](https://github.com/NVIDIA/OpenShell/pull/4488) | From b45320ab90aa4322c5766dc6ec35152f74d7895b Mon Sep 17 00:00:00 2001 From: Jim Meyer Date: Thu, 22 Oct 2026 20:55:13 +0000 Subject: [PATCH 02/11] docs(review): keep registry focused on areas and rosters Signed-off-by: Jim Meyer --- REVIEWERS.md | 52 ---------------------------------------------------- 1 file changed, 52 deletions(-) diff --git a/REVIEWERS.md b/REVIEWERS.md index 21dfbb1a5a..6ae2711396 100644 --- a/REVIEWERS.md +++ b/REVIEWERS.md @@ -1,57 +1,5 @@ # Review areas and topics -Draft for community review. All names below are suggestions, not confirmed volunteers. No automatic requests, notifications, or new approval requirements are enabled by this draft. - -Related work: [review routing and membership workflow (#4839)](https://github.com/NVIDIA/OpenShell/issues/4839). - -## Purpose - -Help authors and tools invite the right people to review OpenShell changes. Areas identify components and system boundaries with coordinating ownership. Topics identify expertise that can apply across several areas. An issue or PR can involve several topics. - -These definitions follow the group's reviewed areas/topics proposal. This file is the proposed repository registry; the initial roster and format remain open for review. - -## Join, change, or leave a roster - -Open a PR editing the relevant membership tables below. Include your GitHub handle, role, status, and review scope. Explain the change in the PR description. A reviewed and merged PR is the sign-up mechanism for every role. - -For the initial proposal, comment on the forthcoming registry PR to suggest additions, removals, or scope corrections. A proposed person's agreement is needed before their entry becomes confirmed. Contributions linked below are evidence for discussion, not proof of willingness or complete subject-matter coverage. - -Subscriber entries require the individual's opt-in. No subscribers have been enrolled in this draft. - -## Roles and coverage - -| Role | Participation | Repository privilege | -| --- | --- | --- | -| maintainer | Available for review and approval in the recorded scope. | Maintain or admin. | -| reviewer | Available for selected review requests in the recorded scope. | Write. | -| subscriber | Receives relevant-work notifications and can contribute feedback without a review obligation. | Read, including public access. | - -Roles follow repository privileges. Aligning today's privileges and the CNCF organization's permissions is outside this proposal. Suggested maintainer entries are drawn from [MAINTAINERS.md](MAINTAINERS.md); this registry does not grant repository access or change the existing maintainer approval check. - -Target at least two confirmed maintainers covering every area and topic. Suggestions do not count as confirmed coverage. Scope limitations matter: two names do not establish two-person coverage of every specialty. All categories currently need confirmation; compliance and MCP also need additional maintainer nominations. - -## Proposed routing behavior - -Every ready-for-review PR has exactly one primary area for coordination and zero or more relevant topics. There is no hard topic limit; apply topics that merit specialist review. Other materially affected areas still contribute reviewers even when they are not the primary area. - -Select a non-author maintainer from the primary area and relevant reviewers for the topics and secondary-area impact. Reuse people who cover several categories, distribute requests among eligible volunteers, and allow human reassignment. Notify opted-in subscribers separately and deduplicate notifications across categories. - -Routing must use confirmed membership from the trusted merged registry. A PR changing this file cannot use its proposed membership to authorize its own review. Selection and notifications are follow-up work in #4839; they do not make every roster member a required approver. - -## Registry format - -Each category has a level-three heading containing its exact label, a scope description, and a membership table with these fixed columns: - -| Column | Meaning | -| --- | --- | -| GitHub | One GitHub login, written as an @mention. | -| Role | `maintainer`, `reviewer`, or `subscriber`. | -| Status | `suggested` or `confirmed`. Only confirmed entries may receive automated requests or notifications. | -| Scope | The person's review scope or notification interests. | -| Basis | Optional contribution evidence for a suggestion, or `Self-nominated` for a volunteer. | - -Use one row per person in a category. A maintainer or reviewer can cover several categories, but should not also have a subscriber row in the same category. Remove an entry through a reviewed PR to withdraw, or change it to subscriber when the person wants notifications without review requests. - ## Areas Areas are OpenShell-specific components or system boundaries. They represent the division of labor across the project. Keep the number of areas small enough to support named leads and reporting during community calls. From 0232b6bcc3235f2684bfb3b72b6c99b48429a617 Mon Sep 17 00:00:00 2001 From: Jim Meyer Date: Thu, 22 Oct 2026 21:24:51 +0000 Subject: [PATCH 03/11] docs(review): match roster tables to maintainer format Signed-off-by: Jim Meyer --- REVIEWERS.md | 192 +++++++++++++++++++++++++-------------------------- 1 file changed, 96 insertions(+), 96 deletions(-) diff --git a/REVIEWERS.md b/REVIEWERS.md index 6ae2711396..f56f06dfd9 100644 --- a/REVIEWERS.md +++ b/REVIEWERS.md @@ -8,20 +8,20 @@ Areas are OpenShell-specific components or system boundaries. They represent the CI/CD workflows, release pipelines, build targets, packaging, and artifact publication. -| GitHub | Role | Status | Scope | Basis | -| --- | --- | --- | --- | --- | -| @matthewgrossman | maintainer | suggested | Release pipelines and packaging | [#4754](https://github.com/NVIDIA/OpenShell/pull/4754) | -| @SDAChess | maintainer | suggested | Build tooling and compatibility checks | [#4611](https://github.com/NVIDIA/OpenShell/pull/4611) | +| Name | GitHub ID | Company/Organization | +| --- | --- | --- | +| Matthew Grossman | [@matthewgrossman](https://github.com/matthewgrossman) | NVIDIA | +| Simon Scatton | [@SDAChess](https://github.com/SDAChess) | NVIDIA | ### area:drivers Infrastructure orchestration, including compute scheduling, secret management, runtime integrations (GPU, Docker, virtual machines, Kata Containers, and Kubernetes), deployment topologies, and pause/resume lifecycle operations. Includes host OS and architecture support (including amd64 and arm64), backend-specific isolation (including Windows AppContainer and isolation sessions), and compatibility. -| GitHub | Role | Status | Scope | Basis | -| --- | --- | --- | --- | --- | -| @elezar | maintainer | suggested | Compute capabilities and backend integration | [#3010](https://github.com/NVIDIA/OpenShell/pull/3010) | -| @drew | maintainer | suggested | Compute-driver and supervisor integration | [#4656](https://github.com/NVIDIA/OpenShell/pull/4656) | -| @mrunalp | maintainer | suggested | Kubernetes compute driver | [#4527](https://github.com/NVIDIA/OpenShell/pull/4527) | +| Name | GitHub ID | Company/Organization | +| --- | --- | --- | +| Evan Lezar | [@elezar](https://github.com/elezar) | NVIDIA | +| Drew Newberry | [@drew](https://github.com/drew) | NVIDIA | +| Mrunal Patel | [@mrunalp](https://github.com/mrunalp) | Red Hat | ### area:runtime @@ -29,29 +29,29 @@ Sandbox execution, isolation, process supervision, policy enforcement, network p Provider discovery and configuration, profiles, sandbox attachments, provider-contributed policy, credential resolution and delivery, refresh and rotation, and provider lifecycle management. -| GitHub | Role | Status | Scope | Basis | -| --- | --- | --- | --- | --- | -| @drew | maintainer | suggested | Isolation, workload execution, and supervisor lifecycle | [#4106](https://github.com/NVIDIA/OpenShell/pull/4106) | -| @TaylorMutch | maintainer | suggested | Sandbox and supervisor integration | [#4823](https://github.com/NVIDIA/OpenShell/pull/4823) | -| @shiju-nv | reviewer | suggested | Provider credentials and protocol inspection | [#4152](https://github.com/NVIDIA/OpenShell/pull/4152) | +| Name | GitHub ID | Company/Organization | +| --- | --- | --- | +| Drew Newberry | [@drew](https://github.com/drew) | NVIDIA | +| Taylor Mutch | [@TaylorMutch](https://github.com/TaylorMutch) | NVIDIA | +| Shiju | [@shiju-nv](https://github.com/shiju-nv) | NVIDIA | ### area:enterprise Authentication, multitenancy, gateway interceptors, FIPS compliance, and other enterprise requirements. -| GitHub | Role | Status | Scope | Basis | -| --- | --- | --- | --- | --- | -| @sjenning | maintainer | suggested | Extension contracts and provider authorization | [#4357](https://github.com/NVIDIA/OpenShell/pull/4357) | -| @derekwaynecarr | maintainer | suggested | Service authorization | [#3796](https://github.com/NVIDIA/OpenShell/pull/3796) | +| Name | GitHub ID | Company/Organization | +| --- | --- | --- | +| Seth Jennings | [@sjenning](https://github.com/sjenning) | Red Hat | +| Derek Carr | [@derekwaynecarr](https://github.com/derekwaynecarr) | Red Hat | ### area:platform SDKs, CLIs, API machinery, gateway infrastructure, persistence (eg postgres, sqlite support), configuration (gateway.toml), and gateway-side sandbox and session management. -| GitHub | Role | Status | Scope | Basis | -| --- | --- | --- | --- | --- | -| @pimlock | maintainer | suggested | Gateway configuration and supervisor sessions | [#4320](https://github.com/NVIDIA/OpenShell/pull/4320) | -| @TaylorMutch | maintainer | suggested | CLI and Rust SDK integration | [#4817](https://github.com/NVIDIA/OpenShell/pull/4817) | +| Name | GitHub ID | Company/Organization | +| --- | --- | --- | +| Piotr Mlocek | [@pimlock](https://github.com/pimlock) | NVIDIA | +| Taylor Mutch | [@TaylorMutch](https://github.com/TaylorMutch) | NVIDIA | ## Topics @@ -61,162 +61,162 @@ Topics connect contributors with work matching their expertise or interests. The Public API contracts, gRPC and protobuf definitions, SDK interfaces, versioning, compatibility, API ergonomics, design patterns, component and communication standards. -| GitHub | Role | Status | Scope | Basis | -| --- | --- | --- | --- | --- | -| @drew | maintainer | suggested | Public API entities and references | [#3272](https://github.com/NVIDIA/OpenShell/pull/3272) | -| @mrunalp | maintainer | suggested | Workspace selectors and mutation contracts | [#3321](https://github.com/NVIDIA/OpenShell/pull/3321) | +| Name | GitHub ID | Company/Organization | +| --- | --- | --- | +| Drew Newberry | [@drew](https://github.com/drew) | NVIDIA | +| Mrunal Patel | [@mrunalp](https://github.com/mrunalp) | Red Hat | ### topic:architecture Cross-cutting system design, component boundaries, data and control flow, architectural decisions, and RFC-level concerns. -| GitHub | Role | Status | Scope | Basis | -| --- | --- | --- | --- | --- | -| @drew | maintainer | suggested | Runtime and compute-driver boundaries | [#4106](https://github.com/NVIDIA/OpenShell/pull/4106) | -| @mrunalp | maintainer | suggested | Gateway mutation architecture | [#3321](https://github.com/NVIDIA/OpenShell/pull/3321) | +| Name | GitHub ID | Company/Organization | +| --- | --- | --- | +| Drew Newberry | [@drew](https://github.com/drew) | NVIDIA | +| Mrunal Patel | [@mrunalp](https://github.com/mrunalp) | Red Hat | ### topic:authnz Authentication, authorization, credential protection, policy integrity/signed policiesIncludes identity verification, login and session handling, OIDC integration, bearer-token validation, access permissions, and authorization across tenant and workspace boundaries. -| GitHub | Role | Status | Scope | Basis | -| --- | --- | --- | --- | --- | -| @sjenning | maintainer | suggested | Provider authorization and extension negotiation | [#4357](https://github.com/NVIDIA/OpenShell/pull/4357) | -| @krishicks | maintainer | suggested | Gateway and sandbox authentication | [#4762](https://github.com/NVIDIA/OpenShell/pull/4762) | +| Name | GitHub ID | Company/Organization | +| --- | --- | --- | +| Seth Jennings | [@sjenning](https://github.com/sjenning) | Red Hat | +| Kris Hicks | [@krishicks](https://github.com/krishicks) | NVIDIA | ### topic:compliance FIPS, regulatory alignment, auditability, and standardization requirements. -| GitHub | Role | Status | Scope | Basis | -| --- | --- | --- | --- | --- | -| @johntmyers | maintainer | suggested | Repository license and compliance text; FIPS coverage needs nomination | [#3467](https://github.com/NVIDIA/OpenShell/pull/3467) | +| Name | GitHub ID | Company/Organization | +| --- | --- | --- | +| John T. Myers | [@johntmyers](https://github.com/johntmyers) | NVIDIA | ### topic:documentation Architecture documentation, README maintenance, project website updates, and automated documentation generation. -| GitHub | Role | Status | Scope | Basis | -| --- | --- | --- | --- | --- | -| @krishicks | maintainer | suggested | Observability documentation | [#4560](https://github.com/NVIDIA/OpenShell/pull/4560) | -| @drew | maintainer | suggested | Deployment and contributor-facing documentation | [#4622](https://github.com/NVIDIA/OpenShell/pull/4622) | +| Name | GitHub ID | Company/Organization | +| --- | --- | --- | +| Kris Hicks | [@krishicks](https://github.com/krishicks) | NVIDIA | +| Drew Newberry | [@drew](https://github.com/drew) | NVIDIA | ### topic:dx Ensure OpenShell is easy to contribute to for humans and agents. -| GitHub | Role | Status | Scope | Basis | -| --- | --- | --- | --- | --- | -| @elezar | maintainer | suggested | Contributor triage and workflow tooling | [#4534](https://github.com/NVIDIA/OpenShell/pull/4534) | -| @johntmyers | maintainer | suggested | Agent review and contributor workflows | [#4309](https://github.com/NVIDIA/OpenShell/pull/4309) | +| Name | GitHub ID | Company/Organization | +| --- | --- | --- | +| Evan Lezar | [@elezar](https://github.com/elezar) | NVIDIA | +| John T. Myers | [@johntmyers](https://github.com/johntmyers) | NVIDIA | ### topic:gpu GPU scheduling, Kubernetes Dynamic Resource Allocation (DRA), Container Device Interface (CDI) configuration, Multi-Instance GPU (MIG) support, and hardware-accelerated runtime integration. -| GitHub | Role | Status | Scope | Basis | -| --- | --- | --- | --- | --- | -| @elezar | maintainer | suggested | Device capabilities and compute integration | [#3010](https://github.com/NVIDIA/OpenShell/pull/3010) | -| @alangou | maintainer | suggested | CDI device identity and validation | [#4306](https://github.com/NVIDIA/OpenShell/pull/4306) | +| Name | GitHub ID | Company/Organization | +| --- | --- | --- | +| Evan Lezar | [@elezar](https://github.com/elezar) | NVIDIA | +| Adrien Langou | [@alangou](https://github.com/alangou) | NVIDIA | ### topic:kubernetes Kubernetes operator development, custom resource definitions (CRDs), deployment controllers, and native integration with Kubernetes APIs. -| GitHub | Role | Status | Scope | Basis | -| --- | --- | --- | --- | --- | -| @mrunalp | maintainer | suggested | Kubernetes compute-driver behavior | [#4527](https://github.com/NVIDIA/OpenShell/pull/4527) | -| @drew | maintainer | suggested | Shared supervisor deployment | [#4695](https://github.com/NVIDIA/OpenShell/pull/4695) | +| Name | GitHub ID | Company/Organization | +| --- | --- | --- | +| Mrunal Patel | [@mrunalp](https://github.com/mrunalp) | Red Hat | +| Drew Newberry | [@drew](https://github.com/drew) | NVIDIA | ### topic:mcp Model Context Protocol (MCP) support, server and client implementations, and standard integration. -| GitHub | Role | Status | Scope | Basis | -| --- | --- | --- | --- | --- | -| @johntmyers | maintainer | suggested | Network enforcement integration; MCP-specific coverage needs confirmation | [#2723](https://github.com/NVIDIA/OpenShell/pull/2723) | -| @shiju-nv | reviewer | suggested | MCP protocol and revision enforcement | [#3850](https://github.com/NVIDIA/OpenShell/pull/3850) | +| Name | GitHub ID | Company/Organization | +| --- | --- | --- | +| John T. Myers | [@johntmyers](https://github.com/johntmyers) | NVIDIA | +| Shiju | [@shiju-nv](https://github.com/shiju-nv) | NVIDIA | ### topic:networking General network transport, connectivity, and proxy behavior not covered by the more specialized L7 category. -| GitHub | Role | Status | Scope | Basis | -| --- | --- | --- | --- | --- | -| @johntmyers | maintainer | suggested | Proxy egress and transparent TCP | [#2723](https://github.com/NVIDIA/OpenShell/pull/2723) | -| @alangou | maintainer | suggested | DNS and hostname policy enforcement | [#4602](https://github.com/NVIDIA/OpenShell/pull/4602) | -| @shiju-nv | reviewer | suggested | HTTP and application-protocol inspection | [#3753](https://github.com/NVIDIA/OpenShell/pull/3753) | +| Name | GitHub ID | Company/Organization | +| --- | --- | --- | +| John T. Myers | [@johntmyers](https://github.com/johntmyers) | NVIDIA | +| Adrien Langou | [@alangou](https://github.com/alangou) | NVIDIA | +| Shiju | [@shiju-nv](https://github.com/shiju-nv) | NVIDIA | ### topic:observability Logging, metrics, tracing, telemetry, dashboards, event correlation, and the collection or export of operational data from gateways and sandboxes. -| GitHub | Role | Status | Scope | Basis | -| --- | --- | --- | --- | --- | -| @krishicks | maintainer | suggested | OCSF and OpenTelemetry | [#4545](https://github.com/NVIDIA/OpenShell/pull/4545) | -| @matthewgrossman | maintainer | suggested | Tracing correctness and log handling | [#4212](https://github.com/NVIDIA/OpenShell/pull/4212) | +| Name | GitHub ID | Company/Organization | +| --- | --- | --- | +| Kris Hicks | [@krishicks](https://github.com/krishicks) | NVIDIA | +| Matthew Grossman | [@matthewgrossman](https://github.com/matthewgrossman) | NVIDIA | ### topic:operability Deployment and configuration of OpenShell installations, upgrades, backup and restore, disaster recovery, operational diagnostics, and maintenance of running installations. -| GitHub | Role | Status | Scope | Basis | -| --- | --- | --- | --- | --- | -| @pimlock | maintainer | suggested | Gateway configuration and Kubernetes reconciliation | [#4676](https://github.com/NVIDIA/OpenShell/pull/4676) | -| @TaylorMutch | maintainer | suggested | HA gateway operation | [#1868](https://github.com/NVIDIA/OpenShell/pull/1868) | +| Name | GitHub ID | Company/Organization | +| --- | --- | --- | +| Piotr Mlocek | [@pimlock](https://github.com/pimlock) | NVIDIA | +| Taylor Mutch | [@TaylorMutch](https://github.com/TaylorMutch) | NVIDIA | ### topic:performance Startup time, latency, throughput, resource overhead, scalability, and benchmarking. Includes rate limiting. -| GitHub | Role | Status | Scope | Basis | -| --- | --- | --- | --- | --- | -| @matthewgrossman | maintainer | suggested | Gateway and supervisor overhead | [#4619](https://github.com/NVIDIA/OpenShell/pull/4619) | -| @drew | maintainer | suggested | Sandbox process lifecycle overhead | [#3757](https://github.com/NVIDIA/OpenShell/pull/3757) | +| Name | GitHub ID | Company/Organization | +| --- | --- | --- | +| Matthew Grossman | [@matthewgrossman](https://github.com/matthewgrossman) | NVIDIA | +| Drew Newberry | [@drew](https://github.com/drew) | NVIDIA | ### topic:policy Policy authoring, validation, proving, distribution, enforcement, and policy ergonomics across runtimes and APIs. Includes policy hardening. -| GitHub | Role | Status | Scope | Basis | -| --- | --- | --- | --- | --- | -| @alangou | maintainer | suggested | Policy matching and proof correctness | [#4326](https://github.com/NVIDIA/OpenShell/pull/4326) | -| @pimlock | maintainer | suggested | Policy authoring and rule proposals | [#3707](https://github.com/NVIDIA/OpenShell/pull/3707) | -| @shiju-nv | reviewer | suggested | Provider and application-protocol policy | [#3850](https://github.com/NVIDIA/OpenShell/pull/3850) | +| Name | GitHub ID | Company/Organization | +| --- | --- | --- | +| Adrien Langou | [@alangou](https://github.com/alangou) | NVIDIA | +| Piotr Mlocek | [@pimlock](https://github.com/pimlock) | NVIDIA | +| Shiju | [@shiju-nv](https://github.com/shiju-nv) | NVIDIA | ### topic:reliability High availability, failure recovery, retries, graceful degradation, fault tolerance, and operational resilience. Includes correctness across restarts. -| GitHub | Role | Status | Scope | Basis | -| --- | --- | --- | --- | --- | -| @TaylorMutch | maintainer | suggested | HA gateway behavior | [#1868](https://github.com/NVIDIA/OpenShell/pull/1868) | -| @pimlock | maintainer | suggested | Gateway reconciliation and lifecycle | [#4676](https://github.com/NVIDIA/OpenShell/pull/4676) | +| Name | GitHub ID | Company/Organization | +| --- | --- | --- | +| Taylor Mutch | [@TaylorMutch](https://github.com/TaylorMutch) | NVIDIA | +| Piotr Mlocek | [@pimlock](https://github.com/pimlock) | NVIDIA | ### topic:sdk Software Development Kit (SDK) creation, maintenance, language bindings, and distribution. -| GitHub | Role | Status | Scope | Basis | -| --- | --- | --- | --- | --- | -| @TaylorMutch | maintainer | suggested | Rust SDK and CLI integration | [#4817](https://github.com/NVIDIA/OpenShell/pull/4817) | -| @SDAChess | maintainer | suggested | TypeScript SDK | [#4495](https://github.com/NVIDIA/OpenShell/pull/4495) | -| @maxdubrinsky | reviewer | suggested | Python SDK and credential-driver bindings | [#4760](https://github.com/NVIDIA/OpenShell/pull/4760) | +| Name | GitHub ID | Company/Organization | +| --- | --- | --- | +| Taylor Mutch | [@TaylorMutch](https://github.com/TaylorMutch) | NVIDIA | +| Simon Scatton | [@SDAChess](https://github.com/SDAChess) | NVIDIA | +| Max Dubrinsky | [@maxdubrinsky](https://github.com/maxdubrinsky) | Gretel | ### topic:security Vulnerability management, static/dynamic analysis, FSR (Functional Security Requirement) implementation, and security auditing. Includes bypass detection, abuse prevention, and vulnerability remediation. -| GitHub | Role | Status | Scope | Basis | -| --- | --- | --- | --- | --- | -| @alangou | maintainer | suggested | Security scanning and policy validation | [#4203](https://github.com/NVIDIA/OpenShell/pull/4203) | -| @johntmyers | maintainer | suggested | Security regression review | [#4338](https://github.com/NVIDIA/OpenShell/pull/4338) | +| Name | GitHub ID | Company/Organization | +| --- | --- | --- | +| Adrien Langou | [@alangou](https://github.com/alangou) | NVIDIA | +| John T. Myers | [@johntmyers](https://github.com/johntmyers) | NVIDIA | ### topic:testing Unit, integration, regression, conformance, and end-to-end testing, including test infrastructure, coverage gaps, flaky tests, and environment-specific test failures. -| GitHub | Role | Status | Scope | Basis | -| --- | --- | --- | --- | --- | -| @matthewgrossman | maintainer | suggested | Conformance and tracing tests | [#4521](https://github.com/NVIDIA/OpenShell/pull/4521) | -| @SDAChess | maintainer | suggested | Test infrastructure and compatibility checks | [#4488](https://github.com/NVIDIA/OpenShell/pull/4488) | +| Name | GitHub ID | Company/Organization | +| --- | --- | --- | +| Matthew Grossman | [@matthewgrossman](https://github.com/matthewgrossman) | NVIDIA | +| Simon Scatton | [@SDAChess](https://github.com/SDAChess) | NVIDIA | From bed467b608a5e4d7778cff792b67128578c370ff Mon Sep 17 00:00:00 2001 From: Jim Meyer Date: Thu, 22 Oct 2026 21:55:08 +0000 Subject: [PATCH 04/11] feat(review): add offline reviewer registry parser Signed-off-by: Jim Meyer --- tasks/scripts/parse_reviewers.md | 83 +++++++++ tasks/scripts/parse_reviewers.py | 243 ++++++++++++++++++++++++++ tasks/scripts/parse_reviewers_test.py | 165 +++++++++++++++++ tasks/test.toml | 6 + 4 files changed, 497 insertions(+) create mode 100644 tasks/scripts/parse_reviewers.md create mode 100644 tasks/scripts/parse_reviewers.py create mode 100644 tasks/scripts/parse_reviewers_test.py diff --git a/tasks/scripts/parse_reviewers.md b/tasks/scripts/parse_reviewers.md new file mode 100644 index 0000000000..5bbc9db70d --- /dev/null +++ b/tasks/scripts/parse_reviewers.md @@ -0,0 +1,83 @@ +# Reviewer registry parser + +`parse_reviewers.py` provides an offline Python API and a JSON CLI for +[`REVIEWERS.md`](../../REVIEWERS.md). It uses only the Python standard library. +It reads membership, category labels, and scope descriptions. Repository roles, +permission checks, reviewer selection, notifications, and approval requirements +belong to consumers of this data. + +Validate the registry: + +```shell +uv run --no-project tasks/scripts/parse_reviewers.py --reviewers REVIEWERS.md --check +``` + +Export JSON: + +```shell +uv run --no-project tasks/scripts/parse_reviewers.py --reviewers REVIEWERS.md +``` + +Run the focused tests: + +```shell +mise run test:reviewers +``` + +## Supported format + +- Categories use level-three headings such as `### area:runtime` under `## Areas` + or `### topic:policy` under `## Topics`. Labels use lowercase letters, digits, + and hyphen-separated words. Category labels are unique. +- Each category has a nonempty scope description followed by one contiguous + table with exactly `Name`, `GitHub ID`, and `Company/Organization` columns. +- Tables use leading and trailing pipes. Separator alignment markers and escaped + pipes in values are supported. Names and organizations must be nonempty. +- The GitHub ID is a link such as `[@Alice](https://github.com/alice)` whose + displayed handle matches the profile path, case-insensitively. A trailing slash + on the profile URL is accepted. Stored logins are lowercase. +- A person may belong to several categories. Duplicate handles within one + category are errors, including duplicates with different capitalization. +- An explicitly empty membership table is valid. Coverage requirements are + separate from syntax validation and need repository permission information. +- Profile links in prose, code examples, or HTML comments do not add members. + The parser does not support arbitrary Markdown table extensions, reference + links, or HTML tables. + +## Python API and JSON contract + +`parse_reviewers(markdown)` returns a tuple of immutable `Category` records. +Each record contains `label`, `description`, and a tuple of `Member` records. +Members contain `name`, `login`, and `organization`. Category/member order follows +the document; descriptions retain Markdown text and paragraph breaks. + +The CLI emits this versioned structure: + +```json +{ + "schema_version": 1, + "categories": [ + { + "label": "area:runtime", + "description": "Workload execution.", + "members": [ + {"name": "Alice", "login": "alice", "organization": "Example"} + ] + } + ] +} +``` + +Consumers can look up categories, combine/deduplicate their member sets, reverse +the mapping to find a person's memberships, or compare two parsed versions to +report membership changes. Empty categories produce an empty `members` array. + +Malformed registries raise `RegistryError` in Python. The CLI reports the input +path and diagnostic on stderr, exits nonzero, and emits no partial JSON. Structural +errors include a source line number. `--check` prints a validation summary instead +of JSON. Missing or unreadable input also exits nonzero. + +For operational routing or approval decisions, read both the helper and registry +from a trusted merged ref, as the existing maintainer-approval check does. Parsing +a proposed PR version is useful for reporting changes; it does not authorize +that proposed membership to review the same PR. diff --git a/tasks/scripts/parse_reviewers.py b/tasks/scripts/parse_reviewers.py new file mode 100644 index 0000000000..36c8afce9b --- /dev/null +++ b/tasks/scripts/parse_reviewers.py @@ -0,0 +1,243 @@ +#!/usr/bin/env python3 +# /// script +# requires-python = ">=3.11" +# dependencies = [] +# /// + +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +"""Validate REVIEWERS.md and emit its categories and members as JSON. + +This dependency-free parser reads the documented registry format, not arbitrary +Markdown. It performs no GitHub requests and assigns no roles or review rights. +""" + +from __future__ import annotations + +import argparse +import json +import re +import sys +from dataclasses import asdict, dataclass +from pathlib import Path + +HEADER = ("Name", "GitHub ID", "Company/Organization") +LABEL = re.compile(r"(?:area|topic):[a-z0-9]+(?:-[a-z0-9]+)*") +PROFILE = re.compile( + r"\[@([a-z0-9](?:[a-z0-9-]{0,37}[a-z0-9])?)\]" + r"\(https://github\.com/([a-z0-9](?:[a-z0-9-]{0,37}[a-z0-9])?)/?\)", + re.IGNORECASE, +) + + +class RegistryError(ValueError): + """The source does not satisfy the registry format.""" + + +@dataclass(frozen=True) +class Member: + name: str + login: str + organization: str + + +@dataclass(frozen=True) +class Category: + label: str + description: str + members: tuple[Member, ...] + + +def _error(line: int, message: str) -> RegistryError: + return RegistryError(f"line {line}: {message}") + + +def _visible_lines(markdown: str): + """Ignore comments and code examples without treating their links as members.""" + fence = None + comment = False + last_line = 1 + for number, raw in enumerate(markdown.splitlines(), 1): + last_line = number + if fence: + closing = r" {0,3}" + re.escape(fence[0]) + "{" + str(len(fence)) + r",}\s*" + if re.fullmatch(closing, raw): + fence = None + continue + visible = "" + remaining = raw + while remaining: + if comment: + _, closing, remaining = remaining.partition("-->") + if not closing: + break + comment = False + else: + before, opening, remaining = remaining.partition("\n" + "```markdown\n### topic:fake\n" + HEADER + ALICE + "```\n" + "~~~\n" + HEADER + ALICE + "~~~\n" + ) + text = DOCUMENT.replace("Workload execution.", examples + "Workload execution.") + result = registry.parse_reviewers(text) + self.assertEqual(len(result), 1) + self.assertEqual([m.login for m in result[0].members], ["alice"]) + + def test_comments_between_members_do_not_end_the_table(self): + other = "| Other | [@other](https://github.com/other) | Example |\n" + text = DOCUMENT + "\n" + other + self.assertEqual( + [m.login for m in registry.parse_reviewers(text)[0].members], + ["alice", "other"], + ) + + def test_profile_links_outside_category_tables_do_not_count(self): + text = "[@outside](https://github.com/outside)\n\n" + DOCUMENT + self.assertEqual([m.login for m in registry.parse_reviewers(text)[0].members], ["alice"]) + + def test_escaped_pipes_and_aligned_separator(self): + text = DOCUMENT.replace("| --- | --- | --- |", "| :--- | :---: | ---: |") + text = text.replace("| Example |", r"| Example\|Labs |") + self.assertEqual(registry.parse_reviewers(text)[0].members[0].organization, "Example|Labs") + + def test_profile_case_and_trailing_slash_are_accepted(self): + text = DOCUMENT.replace("https://github.com/alice", "https://github.com/ALICE/") + self.assertEqual(registry.parse_reviewers(text)[0].members[0].login, "alice") + + def test_rejects_rows_with_ambiguous_or_invalid_identity(self): + invalid = [ + ALICE.replace("/alice)", "/someone-else)"), + ALICE.replace("https://github.com/alice", "https://github.com/alice/repo"), + ALICE.replace("https://github.com/alice", "https://github.com.evil/alice"), + ALICE.replace("https://github.com/alice", "http://github.com/alice"), + ALICE.replace("[@Alice](https://github.com/alice)", "@Alice"), + ALICE.replace("[@Alice](https://github.com/alice)", "[@Alice](https://github.com/alice) extra"), + ALICE.replace("| Alice |", "| |"), + ALICE.replace("| Example |", "| |"), + ] + for row in invalid: + with self.subTest(row=row), self.assertRaises(registry.RegistryError): + registry.parse_reviewers(DOCUMENT.replace(ALICE, row)) + + def test_rejects_duplicate_members_case_insensitively(self): + with self.assertRaisesRegex(registry.RegistryError, "duplicate member @alice"): + registry.parse_reviewers(DOCUMENT + ALICE.replace("@Alice", "@alice")) + + def test_rejects_bad_table_structure(self): + invalid = [ + DOCUMENT.replace(HEADER, ""), + DOCUMENT.replace("| --- | --- | --- |\n", ""), + DOCUMENT.replace("| GitHub ID |", "| Role |"), + DOCUMENT.replace("| --- | --- | --- |", "| --- | --- |"), + DOCUMENT.replace(ALICE, ALICE.rstrip().rstrip("|") + "\n"), + DOCUMENT.replace(ALICE, ALICE.removeprefix("|")), + DOCUMENT.replace(ALICE, ALICE.rstrip() + " Extra |\n"), + DOCUMENT + "\n" + HEADER + ALICE, + ] + for text in invalid: + with self.subTest(text=text), self.assertRaises(registry.RegistryError): + registry.parse_reviewers(text) + + def test_rejects_duplicate_or_misplaced_categories(self): + invalid = [ + DOCUMENT + "\n### area:runtime\n\nOther scope.\n\n" + HEADER, + DOCUMENT.replace("area:runtime", "topic:runtime"), + DOCUMENT.replace("area:runtime", "area:Runtime"), + DOCUMENT.replace("area:runtime", "area:runtime_"), + DOCUMENT.replace("## Areas\n", ""), + DOCUMENT + "\n## Areas\n", + ] + for text in invalid: + with self.subTest(text=text), self.assertRaises(registry.RegistryError): + registry.parse_reviewers(text) + + def test_rejects_missing_scope_or_no_registry(self): + for text in [DOCUMENT.replace("Workload execution.", ""), "# Reviewers\n", ""]: + with self.subTest(text=text), self.assertRaises(registry.RegistryError): + registry.parse_reviewers(text) + + def test_rejects_unterminated_comments_and_examples(self): + for suffix in ["\n") + if not closing: + break + comment = False + else: + before, opening, remaining = remaining.partition("\n" + "```markdown\n### topic:fake\n" + HEADER + ALICE + "```\n" + "~~~\n" + HEADER + ALICE + "~~~\n" + ) + text = DOCUMENT.replace("Workload execution.", examples + "Workload execution.") + result = registry.parse_reviewers(text) + self.assertEqual(len(result), 1) + self.assertEqual([m.login for m in result[0].members], ["alice"]) + + def test_comments_between_members_do_not_end_the_table(self): + other = "| Other | [@other](https://github.com/other) | Example |\n" + text = DOCUMENT + "\n" + other + self.assertEqual( + [m.login for m in registry.parse_reviewers(text)[0].members], + ["alice", "other"], + ) + + def test_profile_links_outside_category_tables_do_not_count(self): + text = "[@outside](https://github.com/outside)\n\n" + DOCUMENT + self.assertEqual( + [m.login for m in registry.parse_reviewers(text)[0].members], ["alice"] + ) + + def test_escaped_pipes_and_aligned_separator(self): + text = DOCUMENT.replace("| --- | --- | --- |", "| :--- | :---: | ---: |") + text = text.replace("| Example |", r"| Example\|Labs |") + self.assertEqual( + registry.parse_reviewers(text)[0].members[0].organization, "Example|Labs" + ) + + def test_profile_case_and_trailing_slash_are_accepted(self): + text = DOCUMENT.replace("https://github.com/alice", "https://github.com/ALICE/") + self.assertEqual(registry.parse_reviewers(text)[0].members[0].login, "alice") + + def test_rejects_rows_with_ambiguous_or_invalid_identity(self): + invalid = [ + ALICE.replace("/alice)", "/someone-else)"), + ALICE.replace("https://github.com/alice", "https://github.com/alice/repo"), + ALICE.replace("https://github.com/alice", "https://github.com.evil/alice"), + ALICE.replace("https://github.com/alice", "http://github.com/alice"), + ALICE.replace("[@Alice](https://github.com/alice)", "@Alice"), + ALICE.replace( + "[@Alice](https://github.com/alice)", + "[@Alice](https://github.com/alice) extra", + ), + ALICE.replace("| Alice |", "| |"), + ALICE.replace("| Example |", "| |"), + ] + for row in invalid: + with self.subTest(row=row), self.assertRaises(registry.RegistryError): + registry.parse_reviewers(DOCUMENT.replace(ALICE, row)) + + def test_rejects_duplicate_members_case_insensitively(self): + with self.assertRaisesRegex(registry.RegistryError, "duplicate member @alice"): + registry.parse_reviewers(DOCUMENT + ALICE.replace("@Alice", "@alice")) + + def test_rejects_bad_table_structure(self): + invalid = [ + DOCUMENT.replace(HEADER, ""), + DOCUMENT.replace("| --- | --- | --- |\n", ""), + DOCUMENT.replace("| GitHub ID |", "| Role |"), + DOCUMENT.replace("| --- | --- | --- |", "| --- | --- |"), + DOCUMENT.replace(ALICE, ALICE.rstrip().rstrip("|") + "\n"), + DOCUMENT.replace(ALICE, ALICE.removeprefix("|")), + DOCUMENT.replace(ALICE, ALICE.rstrip() + " Extra |\n"), + DOCUMENT + "\n" + HEADER + ALICE, + ] + for text in invalid: + with self.subTest(text=text), self.assertRaises(registry.RegistryError): + registry.parse_reviewers(text) + + def test_rejects_duplicate_or_misplaced_categories(self): + invalid = [ + DOCUMENT + "\n### area:runtime\n\nOther scope.\n\n" + HEADER, + DOCUMENT.replace("area:runtime", "topic:runtime"), + DOCUMENT.replace("area:runtime", "area:Runtime"), + DOCUMENT.replace("area:runtime", "area:runtime_"), + DOCUMENT.replace("## Areas\n", ""), + DOCUMENT + "\n## Areas\n", + ] + for text in invalid: + with self.subTest(text=text), self.assertRaises(registry.RegistryError): + registry.parse_reviewers(text) + + def test_rejects_missing_scope_or_no_registry(self): + for text in [DOCUMENT.replace("Workload execution.", ""), "# Reviewers\n", ""]: + with self.subTest(text=text), self.assertRaises(registry.RegistryError): + registry.parse_reviewers(text) + + def test_rejects_unterminated_comments_and_examples(self): + for suffix in ["\n") - if not closing: - break - comment = False - else: - before, opening, remaining = remaining.partition("\n" - "```markdown\n### topic:fake\n" + HEADER + ALICE + "```\n" - "~~~\n" + HEADER + ALICE + "~~~\n" - ) - text = DOCUMENT.replace("Workload execution.", examples + "Workload execution.") - result = registry.parse_reviewers(text) - self.assertEqual(len(result), 1) - self.assertEqual([m.login for m in result[0].members], ["alice"]) - - def test_comments_between_members_do_not_end_the_table(self): - other = "| Other | [@other](https://github.com/other) | Example |\n" - text = DOCUMENT + "\n" + other - self.assertEqual( - [m.login for m in registry.parse_reviewers(text)[0].members], - ["alice", "other"], - ) - - def test_profile_links_outside_category_tables_do_not_count(self): - text = "[@outside](https://github.com/outside)\n\n" + DOCUMENT - self.assertEqual([m.login for m in registry.parse_reviewers(text)[0].members], ["alice"]) - - def test_escaped_pipes_and_aligned_separator(self): - text = DOCUMENT.replace("| --- | --- | --- |", "| :--- | :---: | ---: |") - text = text.replace("| Example |", r"| Example\|Labs |") - self.assertEqual(registry.parse_reviewers(text)[0].members[0].organization, "Example|Labs") - - def test_profile_case_and_trailing_slash_are_accepted(self): - text = DOCUMENT.replace("https://github.com/alice", "https://github.com/ALICE/") - self.assertEqual(registry.parse_reviewers(text)[0].members[0].login, "alice") - - def test_rejects_rows_with_ambiguous_or_invalid_identity(self): - invalid = [ - ALICE.replace("/alice)", "/someone-else)"), - ALICE.replace("https://github.com/alice", "https://github.com/alice/repo"), - ALICE.replace("https://github.com/alice", "https://github.com.evil/alice"), - ALICE.replace("https://github.com/alice", "http://github.com/alice"), - ALICE.replace("[@Alice](https://github.com/alice)", "@Alice"), - ALICE.replace("[@Alice](https://github.com/alice)", "[@Alice](https://github.com/alice) extra"), - ALICE.replace("| Alice |", "| |"), - ALICE.replace("| Example |", "| |"), - ] - for row in invalid: - with self.subTest(row=row), self.assertRaises(registry.RegistryError): - registry.parse_reviewers(DOCUMENT.replace(ALICE, row)) - - def test_rejects_duplicate_members_case_insensitively(self): - with self.assertRaisesRegex(registry.RegistryError, "duplicate member @alice"): - registry.parse_reviewers(DOCUMENT + ALICE.replace("@Alice", "@alice")) - - def test_rejects_bad_table_structure(self): - invalid = [ - DOCUMENT.replace(HEADER, ""), - DOCUMENT.replace("| --- | --- | --- |\n", ""), - DOCUMENT.replace("| GitHub ID |", "| Role |"), - DOCUMENT.replace("| --- | --- | --- |", "| --- | --- |"), - DOCUMENT.replace(ALICE, ALICE.rstrip().rstrip("|") + "\n"), - DOCUMENT.replace(ALICE, ALICE.removeprefix("|")), - DOCUMENT.replace(ALICE, ALICE.rstrip() + " Extra |\n"), - DOCUMENT + "\n" + HEADER + ALICE, - ] - for text in invalid: - with self.subTest(text=text), self.assertRaises(registry.RegistryError): - registry.parse_reviewers(text) - - def test_rejects_duplicate_or_misplaced_categories(self): - invalid = [ - DOCUMENT + "\n### area:runtime\n\nOther scope.\n\n" + HEADER, - DOCUMENT.replace("area:runtime", "topic:runtime"), - DOCUMENT.replace("area:runtime", "area:Runtime"), - DOCUMENT.replace("area:runtime", "area:runtime_"), - DOCUMENT.replace("## Areas\n", ""), - DOCUMENT + "\n## Areas\n", - ] - for text in invalid: - with self.subTest(text=text), self.assertRaises(registry.RegistryError): - registry.parse_reviewers(text) - - def test_rejects_missing_scope_or_no_registry(self): - for text in [DOCUMENT.replace("Workload execution.", ""), "# Reviewers\n", ""]: - with self.subTest(text=text), self.assertRaises(registry.RegistryError): - registry.parse_reviewers(text) - - def test_rejects_unterminated_comments_and_examples(self): - for suffix in ["\n") - if not closing: - break - comment = False - else: - before, opening, remaining = remaining.partition("\n" - "```markdown\n### topic:fake\n" + HEADER + ALICE + "```\n" - "~~~\n" + HEADER + ALICE + "~~~\n" +class RegistryTests(unittest.TestCase): + def test_reads_only_membership_rows_and_allows_empty_categories(self): + text = DOCUMENT.replace( + "Scope.", "Thanks [@outside](https://github.com/outside)." ) - text = DOCUMENT.replace("Workload execution.", examples + "Workload execution.") - result = registry.parse_reviewers(text) - self.assertEqual(len(result), 1) - self.assertEqual([m.login for m in result[0].members], ["alice"]) - - def test_comments_between_members_do_not_end_the_table(self): - other = "| Other | [@other](https://github.com/other) | Example |\n" - text = DOCUMENT + "\n" + other + text += "\n## Topics\n\n### topic:policy\n\n" + TABLE self.assertEqual( - [m.login for m in registry.parse_reviewers(text)[0].members], - ["alice", "other"], + routing.parse_reviewers(text), + {"area:runtime": {"alice"}, "topic:policy": set()}, ) - def test_profile_links_outside_category_tables_do_not_count(self): - text = "[@outside](https://github.com/outside)\n\n" + DOCUMENT - self.assertEqual( - [m.login for m in registry.parse_reviewers(text)[0].members], ["alice"] - ) + def test_same_person_can_belong_to_multiple_categories(self): + text = DOCUMENT + "\n### area:build\n\n" + TABLE + ALICE + self.assertEqual(routing.parse_reviewers(text)["area:build"], {"alice"}) - def test_escaped_pipes_and_aligned_separator(self): - text = DOCUMENT.replace("| --- | --- | --- |", "| :--- | :---: | ---: |") - text = text.replace("| Example |", r"| Example\|Labs |") - self.assertEqual( - registry.parse_reviewers(text)[0].members[0].organization, "Example|Labs" - ) + def test_rejects_duplicate_category_or_member(self): + for text in (DOCUMENT + ALICE, DOCUMENT + "\n### area:runtime\n" + TABLE): + with ( + self.subTest(text=text), + self.assertRaisesRegex(ValueError, "duplicate"), + ): + routing.parse_reviewers(text) - def test_profile_case_and_trailing_slash_are_accepted(self): - text = DOCUMENT.replace("https://github.com/alice", "https://github.com/ALICE/") - self.assertEqual(registry.parse_reviewers(text)[0].members[0].login, "alice") - - def test_rejects_rows_with_ambiguous_or_invalid_identity(self): - invalid = [ - ALICE.replace("/alice)", "/someone-else)"), - ALICE.replace("https://github.com/alice", "https://github.com/alice/repo"), - ALICE.replace("https://github.com/alice", "https://github.com.evil/alice"), - ALICE.replace("https://github.com/alice", "http://github.com/alice"), - ALICE.replace("[@Alice](https://github.com/alice)", "@Alice"), - ALICE.replace( - "[@Alice](https://github.com/alice)", - "[@Alice](https://github.com/alice) extra", - ), - ALICE.replace("| Alice |", "| |"), - ALICE.replace("| Example |", "| |"), - ] - for row in invalid: - with self.subTest(row=row), self.assertRaises(registry.RegistryError): - registry.parse_reviewers(DOCUMENT.replace(ALICE, row)) - - def test_rejects_duplicate_members_case_insensitively(self): - with self.assertRaisesRegex(registry.RegistryError, "duplicate member @alice"): - registry.parse_reviewers(DOCUMENT + ALICE.replace("@Alice", "@alice")) - - def test_rejects_bad_table_structure(self): - invalid = [ - DOCUMENT.replace(HEADER, ""), - DOCUMENT.replace("| --- | --- | --- |\n", ""), + def test_rejects_missing_or_malformed_membership_table(self): + cases = [ + "# Reviewers", + DOCUMENT.replace(TABLE, ""), DOCUMENT.replace("| GitHub ID |", "| Role |"), DOCUMENT.replace("| --- | --- | --- |", "| --- | --- |"), - DOCUMENT.replace(ALICE, ALICE.rstrip().rstrip("|") + "\n"), - DOCUMENT.replace(ALICE, ALICE.removeprefix("|")), - DOCUMENT.replace(ALICE, ALICE.rstrip() + " Extra |\n"), - DOCUMENT + "\n" + HEADER + ALICE, + DOCUMENT.replace(ALICE, ALICE.rstrip().removesuffix("|")), ] - for text in invalid: - with self.subTest(text=text), self.assertRaises(registry.RegistryError): - registry.parse_reviewers(text) - - def test_rejects_duplicate_or_misplaced_categories(self): - invalid = [ - DOCUMENT + "\n### area:runtime\n\nOther scope.\n\n" + HEADER, - DOCUMENT.replace("area:runtime", "topic:runtime"), - DOCUMENT.replace("area:runtime", "area:Runtime"), - DOCUMENT.replace("area:runtime", "area:runtime_"), - DOCUMENT.replace("## Areas\n", ""), - DOCUMENT + "\n## Areas\n", - ] - for text in invalid: - with self.subTest(text=text), self.assertRaises(registry.RegistryError): - registry.parse_reviewers(text) - - def test_rejects_missing_scope_or_no_registry(self): - for text in [DOCUMENT.replace("Workload execution.", ""), "# Reviewers\n", ""]: - with self.subTest(text=text), self.assertRaises(registry.RegistryError): - registry.parse_reviewers(text) - - def test_rejects_unterminated_comments_and_examples(self): - for suffix in ["\n