From c53e62d63fc00020bc51653fa7ab2a11dccce589 Mon Sep 17 00:00:00 2001 From: Gabriele Bartolini Date: Tue, 14 Jul 2026 15:42:21 +1000 Subject: [PATCH 1/3] docs: draft federated subproject governance model MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split governance into two documents: GOVERNANCE.md (collective bodies and their authority) and CONTRIBUTOR_LADDER.md (individual progression), so each can be amended at its own threshold (⅔ org-balanced for the former, simple majority for the latter). Establish a federated model: a Steering Committee (5-7 seats, max 2 per organisation) sits above four Subproject Maintainer Committees (Core Projects, Supply Chain, Community, Docs & Ecosystem, Extensibility), each holding technical authority over its own repositories and selecting one representative to Steering. Split voting into organization-level decisions (org-balanced, one vote per organisation: Steering Committee elections, GOVERNANCE.md changes, CONTRIBUTOR_LADDER.md changes, adding/removing subprojects) and subproject-level decisions (per-person, lazy consensus falling back to a plain vote). Add a Community Representative election process: nominations open in a public Discussion in the governance repository, seats filled by ranked-choice voting (Condorcet or instant-runoff, e.g. via CIVS), and a vacancy rule that promotes the next-highest-ranked candidate from the original election before calling a special one. Add organizational cap enforcement for the 2-per-organisation Steering seat limit, covering election results, subproject committee selections, and affiliation drift from an acquisition or a job change. The cap binds from the Steering Committee's very first appointment rather than only after initial terms expire, so the restructuring cannot itself reintroduce, even temporarily, the single-organisation majority it exists to end. Add a documented path for proposing a new repository to join an existing subproject, and for archiving one that goes inactive, both decided by that subproject's own maintainer committee. Collapse the Reviewer rung into Component Owner. Folder-scoped CODEOWNERS recognition (e.g. a docs/ or testing/ owner within a larger repository) becomes an operational tag a repository's own Component Owners can assign to any Contributor for review-routing, carrying no vote, no additional GitHub permission, and no CNPG Organization Member status. The ladder is now Community Participant, Contributor, Component Owner, Subproject Maintainer, with Steering Committee membership deliberately kept off the ladder as a representative role rather than a rung climbed to. Redefine "component" as strictly a GitHub repository, dropping the earlier allowance for a functionally independent subdirectory to count as its own component. Rename "Organization Member" to "CNPG Organization Member" throughout, to avoid confusion with the org-balanced-voting sense of "organization" (the employer an individual works for). Restructure MAINTAINERS.md into per-subproject tables (Last Name, First Name, Handle, Organization, Component(s)) in place of bullet lists, and add an empty Steering Committee table, ready for Last Name, First Name, Handle, Organization, Seat, Email, Term Start, and Term End once seats are actually filled. Add three previously undocumented maintainers found by cross-referencing CODEOWNERS data against the committee rosters: Itay Grudev to Supply Chain (owns charts), Armando Ruocco to Community, Docs & Ecosystem (owns webtest), and Niccolò Fei to Extensibility (owns plugin-barman-cloud). Rescope CONTRIBUTORS.md to the Contributor tier specifically, removing nine names that had already progressed to Subproject Maintainer and are now recorded in MAINTAINERS.md instead, alongside a Component(s)-aware roster there. Replace COMPONENT-OWNERS.md with the subprojects/ folder, one file per subproject listing real CODEOWNERS-derived repository ownership, plus a root CODEOWNERS file scoping each subprojects/*.md file to its own subproject's maintainer committee. Update README.md's links to point at the new document set. Open items not resolved in this change, flagged inline for follow-up: the Steering Committee's term-stagger schedule, inactivity thresholds for any tier, the Security Response Team and Infrastructure Team rosters, and whether Component Owner status should count toward CNCF's own foundation-level maintainer list and mailing list. Closes #67 Refs #69 Assisted-by: Claude Signed-off-by: Gabriele Bartolini --- .gitvote.yml | 4 +- CODEOWNERS | 27 + COMPONENT-OWNERS.md | 173 ------- CONTRIBUTORS.md | 40 +- CONTRIBUTOR_LADDER.md | 374 ++++++++++++++ GOVERNANCE.md | 760 ++++++++++++++++++++++++----- MAINTAINERS.md | 109 ++++- README.md | 104 ++-- subprojects/README.md | 109 +++++ subprojects/community-ecosystem.md | 18 + subprojects/core-projects.md | 28 ++ subprojects/extensibility.md | 58 +++ subprojects/supply-chain.md | 72 +++ 13 files changed, 1485 insertions(+), 391 deletions(-) create mode 100644 CODEOWNERS delete mode 100644 COMPONENT-OWNERS.md create mode 100644 CONTRIBUTOR_LADDER.md create mode 100644 subprojects/README.md create mode 100644 subprojects/community-ecosystem.md create mode 100644 subprojects/core-projects.md create mode 100644 subprojects/extensibility.md create mode 100644 subprojects/supply-chain.md diff --git a/.gitvote.yml b/.gitvote.yml index bd80599..b4fe328 100644 --- a/.gitvote.yml +++ b/.gitvote.yml @@ -53,7 +53,7 @@ profiles: # days | day | d # weeks | week | w # - duration: 4w + duration: 2w # Pass threshold (required) # @@ -181,7 +181,7 @@ profiles: # default values when they are not provided on other profiles. # governance: - duration: 4w + duration: 2w pass_threshold: 66 close_on_passing: true announcements: diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000..4328c50 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,27 @@ +# CloudNativePG governance repository CODEOWNERS. +# +# See GOVERNANCE.md and subprojects/README.md for what these teams are and +# how they roll out. Team slugs referenced here that don't exist yet in the +# GitHub organization fall back to @cloudnative-pg/maintainers, the same +# transitional rule described in subprojects/README.md's GitHub Teams table. + +# Default owners for everything not matched more specifically below. +* @cloudnative-pg/maintainers + +# GOVERNANCE.md, MAINTAINERS.md, and CONTRIBUTOR_LADDER.md are Steering +# Committee-owned documents (see GOVERNANCE.md's Voting section); until the +# Steering Committee and its GitHub team exist, they fall back to the +# default rule above. +/GOVERNANCE.md @cloudnative-pg/maintainers +/MAINTAINERS.md @cloudnative-pg/maintainers +/CONTRIBUTOR_LADDER.md @cloudnative-pg/maintainers + +# Each subproject's own component listing is scoped to that subproject's +# maintainer committee, so a subproject can update its own listing without +# sign-off from the others. The subprojects index itself stays +# maintainer-wide, since it isn't owned by any single subproject. +/subprojects/README.md @cloudnative-pg/maintainers +/subprojects/core-projects.md @cloudnative-pg/core-maintainers +/subprojects/supply-chain.md @cloudnative-pg/supply-chain-maintainers +/subprojects/community-ecosystem.md @cloudnative-pg/community-ecosystem-maintainers +/subprojects/extensibility.md @cloudnative-pg/extensibility-maintainers diff --git a/COMPONENT-OWNERS.md b/COMPONENT-OWNERS.md deleted file mode 100644 index e027d19..0000000 --- a/COMPONENT-OWNERS.md +++ /dev/null @@ -1,173 +0,0 @@ -# CloudNativePG Component Owners - -This document identifies the individuals responsible for specific components -and subprojects within CloudNativePG. - -As defined in [GOVERNANCE.md](GOVERNANCE.md), Component Owners are implicitly -considered Contributors and are included in the -[CONTRIBUTORS.md](CONTRIBUTORS.md) file. - -## artifacts - -**Repository:** [cloudnative-pg/artifacts](https://github.com/cloudnative-pg/artifacts) - -**Owners:** - -- Niccolò Fei (@NiccoloFei) - -## Chaos Testing - -**Repository:** [cloudnative-pg/chaos-testing](https://github.com/cloudnative-pg/chaos-testing) - -**Owners:** - -- Yash Agarwal (@XploY04) - -## charts - -**Repository:** [cloudnative-pg/charts](https://github.com/cloudnative-pg/charts) - -### Operator Chart - -**Folder:** [charts/cloudnativepg](https://github.com/cloudnative-pg/charts/tree/main/charts/cloudnative-pg) - -**Owners:** - -- Niccolò Fei (@NiccoloFei) -- Itay Grudev (@itay-grudev) -- Philippe Scorsolini (@phisco, Maintainer) -- Jaime Silvela (@jsilvela) - -### PostgreSQL Cluster Chart - -**Folder:** [charts/cluster](https://github.com/cloudnative-pg/charts/tree/main/charts/cluster) - -**Owners:** - -- Itay Grudev (@itay-grudev) -- Philippe Scorsolini (@phisco, Maintainer) - -## ciclops - -**Repository:** [cloudnative-pg/ciclops](https://github.com/cloudnative-pg/ciclops) - -**Owners:** - -- Jaime Silvela (@jsilvela) - -## cloudnative-pg.github.io - -**Repository:** [cloudnative-pg/cloudnative-pg.github.io](https://github.com/cloudnative-pg/cloudnative-pg.github.io) - -**Owners:** - -- Gabriele Bartolini (@gbartolini, Maintainer) -- Jonathan Battiato (@jbattiato) -- Jaime Silvela (@jsilvela) -- Floor Drees (@FloorD) - -## cloudnative-pg - -*Note:* this is the main project of the CloudNativePG organization and it is -primarily the maintainers' responsibility to manage it. - -**Repository:** [cloudnative-pg/cloudnative-pg](https://github.com/cloudnative-pg/cloudnative-pg) - -### Documentation - -**Folder:** [cloudnative-pg/docs](https://github.com/cloudnative-pg/cloudnative-pg/tree/main/docs) - -**Owners:** - -- Jaime Silvela (@jsilvela) - -### Operator Lifecycle Manager (OLM) - -**Folders:** [cloudnative-pg/config/olm-*/](https://github.com/cloudnative-pg/cloudnative-pg/tree/main/config) - -**Owners:** - -- Niccolò Fei (@NiccoloFei) - -### Testing - -**Folders:** - -- [cloudnative-pg/.github](https://github.com/cloudnative-pg/cloudnative-pg/tree/main/.github) -- [cloudnative-pg/hack](https://github.com/cloudnative-pg/cloudnative-pg/tree/main/hack) -- [cloudnative-pg/tests](https://github.com/cloudnative-pg/cloudnative-pg/tree/main/tests) - -*Note:* access to additional files might be required. - -**Owners:** - -- Niccolò Fei (@NiccoloFei) -- Tao Li (@litaocdl) -- Jaime Silvela (@jsilvela) - -## docs - -**Repository:** [cloudnative-pg/docs](https://github.com/cloudnative-pg/docs) - -**Owners:** - -- Anushka Saxena (@SaxenaAnushka102) - -## grafana-dashboards - -**Repository:** [cloudnative-pg/grafana-dashboards](https://github.com/cloudnative-pg/grafana-dashboards) - -**Owners:** - -- Itay Grudev (@itay-grudev) -- Philippe Scorsolini (@phisco, Maintainer) -- Jaime Silvela (@jsilvela) - -## pgbouncer-containers - -**Repository:** [cloudnative-pg/pgbouncer-containers](https://github.com/cloudnative-pg/pgbouncer-containers) - -**Owners:** - -- Niccolò Fei (@NiccoloFei) - -## postgis-containers - -**Repository:** [cloudnative-pg/postgis-containers](https://github.com/cloudnative-pg/postgis-containers) - -**Owners:** - -- Niccolò Fei (@NiccoloFei) - -## postgres-containers - -**Repository:** [cloudnative-pg/postgres-containers](https://github.com/cloudnative-pg/postgres-containers) - -**Owners:** - -- Niccolò Fei (@NiccoloFei) - -## postgres-extensions-containers - -**Repository:** [cloudnative-pg/postgres-extensions-containers](https://github.com/cloudnative-pg/postgres-extensions-containers) - -**Owners:** - -- Niccolò Fei (@NiccoloFei) - -## postgres-keycloak-oauth-validator - -**Repository:** [cloudnative-pg/postgres-keycloak-oauth-validator](https://github.com/cloudnative-pg/postgres-keycloak-oauth-validator) - -**Owners:** - -- Yoshiyuki Tabata (@y-tabata) - -## postgres-trunk-containers - -**Repository:** [cloudnative-pg/postgres-trunk-containers](https://github.com/cloudnative-pg/postgres-trunk-containers) - -**Owners:** - -- Gabriele Bartolini (@gbartolini, Maintainer) -- Niccolò Fei (@NiccoloFei) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index b7fd4cc..b7b13a0 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -1,32 +1,32 @@ # CloudNativePG Contributors -This document identifies the individuals who have been formally recognized as -**Contributors** or **Component Owners** to the CloudNativePG project, as -defined in [GOVERNANCE.md](GOVERNANCE.md). +This document lists individuals holding the **Contributor** tier specifically, +the entry rung of the ladder in [CONTRIBUTOR_LADDER.md](CONTRIBUTOR_LADDER.md), +with no repository-scoped access yet. It is not a roster of everyone active in +the project: Component Owners are listed by repository in the +[subprojects/](subprojects/README.md) folder, and Subproject Maintainers and +Steering Committee members in [MAINTAINERS.md](MAINTAINERS.md), rather than +repeated here. A Contributor who is later promoted to Component Owner moves +to that listing and is removed from this one. A Contributor may also be +tagged in a repository's `CODEOWNERS` file for review-routing without +leaving this list: that's an operational choice by the repository's +Component Owners, not a promotion (see +[CONTRIBUTOR_LADDER.md's Component Owner section](CONTRIBUTOR_LADDER.md#component-owner)). -Contributors and Component Owners are listed in alphabetical order by last -name. -The project is grateful for their ongoing dedication to the community, -documentation, and technical excellence. +Contributors are listed in alphabetical order by last name. The project is +grateful for their ongoing dedication to the community, documentation, and +technical excellence. | Name | GitHub Handle | Country | | :--- | :--- | :--- | -| Yash Agarwal | [@XploY04](https://github.com/XploY04) | India | -| Jonathan Battiato | [@jbattiato](https://github.com/jbattiato) | Italy | -| Floor Drees | [@FloorD](https://github.com/FloorD) | Netherlands | -| Niccolò Fei | [@NiccoloFei](https://github.com/NiccoloFei) | Italy | -| Itay Grudev | [@itay-grudev](https://github.com/itay-grudev) | Bulgaria | -| Tao Li | [@litaocdl](https://github.com/litaocdl) | China | | Gabriele Quaresima | [@gabriele-wolfox](https://github.com/gabriele-wolfox) | Italy | -| Anushka Saxena | [@SaxenaAnushka102](https://github.com/SaxenaAnushka102) | India | -| Jaime Silvela | [@jsilvela](https://github.com/jsilvela) | Spain | -| Yoshiyuki Tabata | [@y-tabata](https://github.com/y-tabata) | Japan | --- ## How to become a Contributor -Formal Contributor status is awarded through a nomination by an existing -Maintainer and a simple majority vote. -For more information on the requirements and the nomination process, please -refer to the **Project Roles** section in our [Governance document](GOVERNANCE.md). +Formal Contributor status is awarded through a nomination by, and a simple +majority vote of, the relevant repository's existing Component Owners. For +the full requirements and process, see the +[Contributor section](CONTRIBUTOR_LADDER.md#contributor) of +[CONTRIBUTOR_LADDER.md](CONTRIBUTOR_LADDER.md). diff --git a/CONTRIBUTOR_LADDER.md b/CONTRIBUTOR_LADDER.md new file mode 100644 index 0000000..3278e77 --- /dev/null +++ b/CONTRIBUTOR_LADDER.md @@ -0,0 +1,374 @@ +# CloudNativePG Contributor Ladder + +> [!IMPORTANT] +> **Draft, not yet ratified.** This whole document describes the target +> ladder under the proposed federated governance model. It has not been +> adopted by a Steering Committee vote (Steering doesn't exist yet), so read +> every role, threshold, and process below as a proposal. + +This document outlines the contributor roles within CloudNativePG, along with +the responsibilities and privileges that come with each. Community members +generally start at the first rung and advance as their involvement grows; +existing contributors are happy to help newcomers climb it. The ladder is +split at the top into per-subproject rungs, to match CloudNativePG's +federated repository structure. Steering Committee membership is covered too, +but deliberately kept off the numbered climb; see +[the note below](#steering-committee-a-representative-role-not-a-ladder-rung) +for why. + +> [!NOTE] +> **Editorial reference, to be removed before ratification:** this document +> is adapted from the [CNCF Contributor Ladder template](https://github.com/cncf/project-template/blob/main/CONTRIBUTOR_LADDER.md), +> with one structural change: the template's single project-wide ladder +> becomes CloudNativePG's per-subproject split above. Noted for reviewers +> during due diligence; the final text should stand on its own without +> naming the template. + +This document is owned by the [Steering Committee](GOVERNANCE.md#steering-committee): +changes to the ladder's structure, requirements, or thresholds go through a +Steering Committee vote, simple majority (see +[GOVERNANCE.md's Voting section](GOVERNANCE.md#voting), and the note below +for why this bar is lighter than GOVERNANCE.md's own). Day-to-day +promotions and removals under the rules below follow each tier's own +process, unchanged. + +> [!IMPORTANT] +> **Why the Steering Committee and Subproject Maintainer Committee charters +> aren't here:** this document only needs a simple-majority Steering vote to +> amend, while [GOVERNANCE.md](GOVERNANCE.md) needs ⅔. The Steering +> Committee's own composition (seat count, the 2-per-organization cap, the +> owns/does-not-own split) and each Subproject Maintainer Committee's +> removal mechanism are structural safeguards that should sit behind the +> heavier bar, not the lighter one this document has. So this document +> covers individual progression (what a person gets and how they get +> there); [GOVERNANCE.md](GOVERNANCE.md) covers collective bodies and their +> authority (what a committee can do, how it's composed, how it's amended). + +- [At a Glance](#at-a-glance) +- [Community Participant](#community-participant) +- [Contributor](#contributor) +- [CNPG Organization Member](#cnpg-organization-member) +- [Component Owner](#component-owner) +- [Subproject Maintainer](#subproject-maintainer) +- [Steering Committee: a representative role, not a ladder rung](#steering-committee-a-representative-role-not-a-ladder-rung) +- [Recording a Role Change](#recording-a-role-change) +- [Inactivity](#inactivity) +- [Involuntary Removal](#involuntary-removal) +- [Stepping Down / Emeritus](#stepping-down--emeritus) + +## At a Glance + +| Tier | Scope | `CODEOWNERS` entry | GitHub access | Promotion vote | Organization cap | +| --- | --- | --- | --- | --- | --- | +| Community Participant | None | None | None | N/A | None | +| Contributor | None (recognition only) | None (may be tagged in a folder-scoped line for review-routing, see note below) | None | Repository's existing Component Owners, simple majority | None | +| Component Owner | Whole repository | Default (`*`) line | `Write` on the repository | Repository's existing Component Owners, ⅔ majority | None | +| Subproject Maintainer | Whole subproject | N/A (committee seat) | `Maintain` across the subproject's repositories | Self-selected by the committee, Steering oversight | None | +| Steering Committee | Project-wide governance | N/A | Not a GitHub permission tier; `Admin` is granted separately (see [GitHub Project Administration](GOVERNANCE.md#github-project-administration-steering-committee)) | Selected by subproject committee, or elected (Community Representative seats) | 2 seats per organization (see [GOVERNANCE.md's Organizational Cap Enforcement](GOVERNANCE.md#organizational-cap-enforcement)) | + +A repository's existing Component Owners may, at their own discretion, tag +any Contributor in a folder-scoped `CODEOWNERS` line for review-routing +(e.g. `docs/ @some-contributor`), so GitHub auto-requests them on matching +pull requests. This is an operational choice, not a promotion: it carries +no additional GitHub permission, no vote, and no +[CNPG Organization Member](#cnpg-organization-member) status, since a +"Require review from Code Owners" branch-protection rule only counts an +approval from someone holding `Write` on the repository (see the GitHub +mechanics note under [Component Owner](#component-owner)). Contributor and +Component Owner promotions are both decided at the repository level, by +that repository's existing Component Owners, with the subproject maintainer +committee stepping in only as a backstop for a stalled or too-small +repository; the subproject committee decides its own membership directly +(see each section below). + +```mermaid +flowchart TD + CP["Community Participant
engages, no formal tier"] + CT["Contributor
recognized contribution,
no repository access
"] + CO["Component Owner
whole-repo CODEOWNERS,
Write access
"] + SM["Subproject Maintainer
committee seat,
Maintain access subproject-wide
"] + SC["Steering Committee
representative role,
not a ladder rung
"] + + CP --> CT + CT -->|"repo's Component Owners
⅔ majority"| CO + CO -->|"subproject committee
self-selects, simple majority"| SM + SM -.->|"selected as subproject's
representative"| SC + + OM["CNPG Organization Member
anyone holding Component Owner
status or above, on any repository
"] + CO -.- OM + SM -.- OM + OM -.->|"electorate for Community
Representative seats"| SC + + classDef rung fill:#eef4ff,stroke:#3b6fd6,stroke-width:1px,color:#1a1a1a; + classDef rep fill:#fff4e0,stroke:#c9822a,stroke-width:2px,stroke-dasharray:4 3,color:#1a1a1a; + classDef note fill:#f5f5f5,stroke:#999999,stroke-width:1px,color:#333333; + + class CP,CT,CO,SM rung; + class SC rep; + class OM note; +``` + +## Community Participant + +A Community Participant engages with the project and its community without +(yet) being a formally recognized Contributor. Most people start here. + +- Responsibilities: follow the [Code of Conduct](CODE_OF_CONDUCT.md). +- Ways to get involved: participating in community discussions, helping + other users, submitting bug reports, commenting on issues, trying out new + releases, attending community meetings, promoting the project publicly. + +## Contributor + +Contributors are members of the community who contribute directly to the +project and add value to it. This is the first formal tier of the ladder. +Contributions are not limited to code: documentation and community work count +too. + +- Responsibilities: follow the Code of Conduct and the + [contributing guide](CONTRIBUTING.md). +- Requirements (one or more of the following): reporting or resolving + issues, submitting pull requests, contributing to documentation, + participating in meetings, helping community members, providing feedback + on issues/PRs, testing releases, or promoting the project in public. +- Privileges: listed in [CONTRIBUTORS.md](CONTRIBUTORS.md); eligible to be + proposed for Component Owner; may, at a repository's discretion, be + tagged in a folder-scoped `CODEOWNERS` line for review-routing (see + [At a Glance](#at-a-glance)). +- Promotion: proposed by any Maintainer or Component Owner of the relevant + repository, elected by simple majority vote of that repository's existing + Component Owners. Where a repository has no Component Owner named + explicitly in its `CODEOWNERS` file, the subproject's own maintainer + committee is the default owner (see + [subprojects/README.md](subprojects/README.md#github-teams)) and decides + directly. While that committee is still forming, the vote defaults to + today's existing maintainers. + +Requirements here are deliberately qualitative rather than numeric. +Advancement is a judgment call by the people closest to the work, not a +metrics threshold. + +> [!NOTE] +> **Editorial reference, to be removed before ratification:** the CNCF +> template ties some contributor tiers to counts (PRs per year, months of +> activity); CloudNativePG's maintainers have chosen not to, on the view +> that count-based bars invite gaming (drive-by PRs, padding) more than they +> capture real, trusted contribution. Noted for reviewers during due +> diligence; the final text should stand on its own without naming the +> template. + +## CNPG Organization Member + +"CloudNativePG Organization Member" (**CNPG Organization Member** for short) +is not a separate promotion tier; it's the umbrella term GOVERNANCE.md uses +wherever a rule needs to name a broad electorate, most notably Steering +Community Representative elections. It means anyone holding Component Owner +status or above, on any repository. The "CNPG" qualifier is deliberate: +plain "organization" is used throughout these documents to mean the +employer an individual works for (for org-balanced voting), and this term +should never be confused with that. + +## Component Owner + +Component Owners are tasked with the development of an entire component +within CloudNativePG: a dedicated repository (e.g. `postgres-containers`), +no more and no less (see [GOVERNANCE.md's Subprojects +section](GOVERNANCE.md#subprojects) for the component definition). A +Component Owner has full technical authority over "everything there": they +don't need sign-off from a subproject committee for routine work in their +own repository. + +> [!NOTE] +> **Editorial reference, to be removed before ratification:** this +> corresponds to the CNCF template's optional "Subproject Maintainer" role +> (see the template's commented-out "Additional Maintainer Roles" section). +> CloudNativePG has chosen not to adopt the template's separate "Reviewer" +> role: folder-scoped recognition is an operational `CODEOWNERS` tag a +> repository's Component Owners can assign at their own discretion (see +> [At a Glance](#at-a-glance)), not a formal ladder rung with its own vote +> and electorate. Noted for reviewers during due diligence; the final text +> should stand on its own without naming the template. + +- Requirements: an established Contributor with a track record and + demonstrated expertise in the specific component being proposed for. +- Privileges: `Write` access to the relevant repository, whole-repository + entry in its `CODEOWNERS` file, listed in the + [subprojects/](subprojects/README.md) folder; counts as a + [CNPG Organization Member](#cnpg-organization-member); eligible to be + proposed for Subproject Maintainer. +- Promotion: proposed by any Maintainer or existing Component Owner of the + same repository, elected by ⅔ majority vote of that repository's existing + Component Owners. Where a repository has fewer than three Component + Owners named explicitly in `CODEOWNERS` (including none, in which case the + subproject's own maintainer committee is the default owner, see + [subprojects/README.md](subprojects/README.md#github-teams)), the vote + defaults to the subproject maintainer committee. While that committee is + still forming, the vote defaults to today's existing maintainers. Removal + follows the same process. + +> [!NOTE] +> **GitHub mechanics:** GitHub grants `Write` at the repository level; there +> is no native way to scope permissions by path. A Component Owner's +> `CODEOWNERS` line is the repository's default (`*`) entry, so they're +> auto-requested and required for review on anything not otherwise covered +> by a folder-scoped line. + +> [!NOTE] +> **Folder-scoped review routing:** a repository's Component Owners may add +> a folder-scoped `CODEOWNERS` line naming any Contributor, for +> review-routing convenience only (e.g. `docs/ @some-contributor`). This is +> an operational choice made by lazy consensus among that repository's own +> Component Owners, not a promotion: it grants no additional GitHub +> permission, no vote, and no CNPG Organization Member status. Because a +> "Require review from Code Owners" branch-protection rule only counts an +> approval from someone holding `Write` on the repository, a Contributor +> tagged this way is auto-requested but their approval alone doesn't +> satisfy that rule until they're promoted to Component Owner. + +- Path onward: Component Owners of repositories within a formalized + subproject are expected to become members of that subproject's maintainer + committee over time, rather than remaining a separate, non-voting tier + indefinitely. Component ownership continues unchanged for tooling + repositories that do not have subproject representation. + +A repository's existing Component Owners are expected to act on qualified +nominations within a reasonable time. If they don't, or a repository has too +few Component Owners to reach the required threshold, the subproject +maintainer committee may add a Component Owner to that repository directly +(see [GOVERNANCE.md's Contributors and Component Owners +section](GOVERNANCE.md#contributors-and-component-owners)). Steering does +not intervene at the repository level: the subproject maintainer committee +is always the backstop for its own repositories, just as Steering is the +backstop for a subproject maintainer committee's own membership. + +## Subproject Maintainer + +Subproject Maintainers are established contributors responsible for an +entire subproject: technical direction, code review, merge, and release +across every repository under it. "Maintainer" here means membership in one +of the four subproject maintainer committees defined in +[GOVERNANCE.md](GOVERNANCE.md#subprojects); it isn't scoped to a single flat +pool anymore. See +[GOVERNANCE.md's Subproject Maintainer Committees section](GOVERNANCE.md#subproject-maintainer-committees) +for the full responsibilities list, and [MAINTAINERS.md](MAINTAINERS.md) for +current committee rosters. + +- Requirements: demonstrated technical judgment and sustained contribution + across the subproject, as an established Component Owner of one or more + of its repositories. Being tagged in a folder-scoped `CODEOWNERS` line for + review-routing does not qualify on its own. A seat also carries an + ongoing time commitment, + meaningful enough to sustain the subproject's pace, guidance rather than + a hard numeric gate, consistent with CloudNativePG's preference for + qualitative over count-based bars (see the note under + [Contributor](#contributor) above). +- Responsibilities: the subproject-wide duties in + [GOVERNANCE.md's Subproject Maintainer Committees section](GOVERNANCE.md#subproject-maintainer-committees), + including regularly attending the project's community meetings and + periodically attending Steering Committee meetings to provide input. +- Privileges: `Maintain` GitHub access on the subproject's repositories (see + [GitHub Teams](GOVERNANCE.md#github-teams-and-communication-channels)); a + vote in subproject technical decisions; eligible to be selected as the + subproject's representative to the Steering Committee. +- Promotion: subproject maintainer committees are self-selecting, with + Steering Committee oversight (see + [GOVERNANCE.md's Changes in subproject maintainer committee membership](GOVERNANCE.md#changes-in-subproject-maintainer-committee-membership)). + +## Steering Committee: a representative role, not a ladder rung + +The rungs above are a merit climb: more contribution and trust earn more +access. Steering Committee membership doesn't work that way, so it isn't +listed as a rung here. A seat is filled by a subproject maintainer committee +*selecting* its representative, or by an org-wide election for the Community +Representative seats (see +[GOVERNANCE.md's Steering Committee section](GOVERNANCE.md#steering-committee)). +It's a representative function, not something an individual climbs to by +accumulating enough Subproject Maintainer-level contribution. Presenting it +as a normal ladder rung would misleadingly imply that contributing enough as +a Maintainer guarantees eventual Steering membership, which isn't how the +model works. + +## Recording a Role Change + +A promotion or removal isn't complete once the vote passes; the people who +ran the vote are also responsible for updating every place that role is +recorded, so GitHub access and the public record match the decision. + +| Tier | Recorded in | +| --- | --- | +| Contributor | [CONTRIBUTORS.md](CONTRIBUTORS.md) | +| Component Owner | Default (`*`) `CODEOWNERS` line in the repository; [subprojects/](subprojects/README.md) entry | +| Subproject Maintainer | [MAINTAINERS.md](MAINTAINERS.md) committee roster; `subproject-*` GitHub team membership (see [GitHub Teams](GOVERNANCE.md#github-teams-and-communication-channels)) | +| Steering Committee | [MAINTAINERS.md](MAINTAINERS.md) Steering Committee table; `steering-committee` GitHub team membership | + +> [!IMPORTANT] +> **Open item (needs discussion):** CNCF projects typically also keep a +> foundation-level maintainer list, a `project-maintainers.csv` entry in +> [cncf/foundation](https://github.com/cncf/foundation/blob/main/project-maintainers.csv) +> and a `cncf-cloudnative-pg-maintainers@lists.cncf.io`-style mailing list, +> updated the same way; see the foundation's own +> [new maintainer guidance](https://github.com/cncf/foundation/blob/main/.github/pull_request_template.md) +> for the exact process. Which of CNPG's tiers count as "maintainer" for +> that foundation-level list, Subproject Maintainer and Steering only, or +> Component Owner too, hasn't been decided. Worth resolving before this +> section is considered complete. + +> [!NOTE] +> **Editorial reference, to be removed before ratification:** this section +> is adapted from +> [Crossplane's own GOVERNANCE.md](https://github.com/crossplane/crossplane/blob/main/GOVERNANCE.md#becoming-a-maintainer), +> a graduated CNCF project, rather than invented from scratch. Noted for +> reviewers during due diligence; the final text should stand on its own +> without naming the source. + +## Inactivity + +A tier is considered inactive after at least 6 months with no contribution +or communication in that capacity. Inactivity is a trigger for the +[Involuntary Removal](#involuntary-removal) process below, not a removal in +itself, decided at the same level as promotion for that tier. + +A prolonged absence that's been communicated in advance, a parental leave, +a sabbatical, or a known personal circumstance, doesn't count as inactivity +regardless of length: the concern is disappearing without notice, not +simply being away. Someone returning from a communicated absence resumes +their role without needing to re-earn it. + +> [!NOTE] +> **Editorial reference, to be removed before ratification:** the 6-month +> floor matches the CNCF template's own approach of measuring inactivity in +> months of no contribution or communication. Noted for reviewers during +> due diligence; the final text should stand on its own without naming the +> template. + +## Involuntary Removal + +Involuntary removal or demotion follows the same vote-based process, and is +decided at the same level, as promotion for each tier: a repository's +existing Component Owners, for Contributors by simple majority and for +Component Owners by ⅔ majority, with the subproject maintainer committee as +backstop where a repository's owners are stalled or too few to reach the +threshold. This may be triggered by repeated inactivity, failing to meet a +role's requirements, or a Code of Conduct violation. + +For Subproject Maintainers, a subproject maintainer committee member may be +removed by a ⅔ majority vote of the other committee members. The Steering +Committee cannot do this on its own initiative; it may only step in, by a +plain majority vote of its own members, once that committee's own vote has +been tried and failed, or the committee is demonstrably unable to convene +one, and only at the request of one of that committee's own members (see +[GOVERNANCE.md's Changes in subproject maintainer committee membership](GOVERNANCE.md#changes-in-subproject-maintainer-committee-membership) +for the exact preconditions). + +> [!NOTE] +> **Editorial reference, to be removed before ratification:** this +> mechanism is the CNCF template's own starting point, adopted here rather +> than inventing a new one. Noted for reviewers during due diligence; the +> final text should stand on its own without naming the template. + +## Stepping Down / Emeritus + +Contributors at any level can step down voluntarily. Maintainers who step +down are recognized as Emeritus Maintainers (see +[MAINTAINERS.md](MAINTAINERS.md)). Contact the Maintainers of the relevant +subproject about changing your status. diff --git a/GOVERNANCE.md b/GOVERNANCE.md index cedf7df..e37b24a 100644 --- a/GOVERNANCE.md +++ b/GOVERNANCE.md @@ -47,129 +47,533 @@ CloudNativePG and its leadership embrace the following values: - Community over Product or Company: Sustaining and growing our community takes priority over shipping code or sponsors' organizational goals. Each - contributor participates in the project as an individual. + contributor participates in the project as an individual, and no single + organization controls project direction regardless of how many contributors + it employs. - Inclusivity: We innovate through different perspectives and skill sets, which can only be accomplished in a welcoming and respectful environment. - Participation: Responsibilities within the project are earned through - participation, and there is a clear path up the contributor ladder into leadership - positions. + participation, and there is a clear path up the contributor ladder into + leadership positions, regardless of organizational affiliation. + +## Project Structure + +CloudNativePG separates **governance authority** from **technical authority**: + +- The **Steering Committee** owns project-wide governance: vision, the CNCF + interface, adding/removing subprojects, subproject maintainer committee + oversight, security response coordination, and changes to this document. + Its foundational decisions (electing itself, amending this document or + [CONTRIBUTOR_LADDER.md](CONTRIBUTOR_LADDER.md), adding or removing a + subproject) are org-balanced; its day-to-day business, including acting + as backstop for a subproject maintainer committee, is decided like any + committee's, per person. See [Voting](#voting) for the full split. +- **Subproject Maintainer Committees** own technical authority within their + subproject: code review, merge, release, and day-to-day decisions by lazy + consensus. Technical decisions remain per-person, in recognition of the + engineering investment individual contributors and their employers make. + +This split exists so that organizational diversity in governance does not come +at the expense of the deep technical expertise that got CloudNativePG here. +See [Voting](#voting) for exactly which decisions use which mechanism. + +```mermaid +flowchart TD + subgraph GOV["Governance authority (org-balanced)"] + SC["Steering Committee
5-7 seats, max 2 per organization"] + CR["Community Representative seat(s)
1-3, elected annually by all
CNPG Organization Members"] + end + + subgraph TECH["Technical authority (per person)"] + CPC["Core Projects
Maintainer Committee"] + SUC["Supply Chain
Maintainer Committee"] + CDC["Community, Docs and Ecosystem
Maintainer Committee"] + EXC["Extensibility
Maintainer Committee"] + + CPR[("Repositories
e.g. cloudnative-pg, api,
barman-cloud")] + SUR[("Repositories
e.g. charts, container images")] + CDR[("Repositories
e.g. docs, website")] + EXR[("Repositories
e.g. cnpg-i, plugin-barman-cloud")] + + CPC --> CPR + SUC --> SUR + CDC --> CDR + EXC --> EXR + end + + GREPO[("governance, .project
administered directly by Steering,
not part of any subproject")] + SC --> GREPO + + CPC ==>|selects representative| SC + SUC ==>|selects representative| SC + CDC ==>|selects representative| SC + EXC ==>|selects representative| SC + CR -.-> SC + + SC -.->|"backstop: removes a stuck
committee member,
plain majority, per person"| CPC + SC -.-> SUC + SC -.-> CDC + SC -.-> EXC + + CPC -.->|"backstop: stalled repo or
too few Component Owners"| CPR + SUC -.-> SUR + CDC -.-> CDR + EXC -.-> EXR + + classDef gov fill:#fff4e0,stroke:#c9822a,stroke-width:2px,color:#1a1a1a; + classDef committee fill:#eef4ff,stroke:#3b6fd6,stroke-width:1px,color:#1a1a1a; + classDef repo fill:#eef9ee,stroke:#3a8a4d,stroke-width:1px,color:#1a1a1a; + + class SC,CR gov; + class CPC,SUC,CDC,EXC committee; + class CPR,SUR,CDR,EXR,GREPO repo; +``` + +## Subprojects + +CloudNativePG is organized into four subprojects, aligned directly with the +repository groupings maintained in the [subprojects/](subprojects/README.md) +folder, one file per subproject. + +| Subproject | Groupings (see `subprojects/`) | +| :---- | :---- | +| **Core Projects** | [core-projects.md](subprojects/core-projects.md) | +| **Supply Chain** | [supply-chain.md](subprojects/supply-chain.md): Distribution, Container Images, Libraries & Automation, Testing & Automation | +| **Community, Docs & Ecosystem** | [community-ecosystem.md](subprojects/community-ecosystem.md) | +| **Extensibility** | [extensibility.md](subprojects/extensibility.md): Interface & Plugins (CNPG-I), PostgreSQL Extensions & Tooling | + +A subproject is made up of one or more **components**, each a GitHub +repository, no more and no less (see +[Contributors and Component Owners](#contributors-and-component-owners) +for how a subdirectory within one is scoped instead). Each subproject's +maintainer committee has technical authority over every component listed in +its file under [subprojects/](subprojects/README.md) and selects one +representative to the Steering Committee. + +Technical authority and GitHub write access are granted at the component +(repository) level, not the subproject level: owning one component in a +subproject does not by itself grant access to, or a vote over, the +subproject's other components. Subproject Maintainer Committee membership, +which does carry subproject-wide access and a subproject-wide vote, is a +separate, higher tier built out of established Component Owners; see +[CONTRIBUTOR_LADDER.md](CONTRIBUTOR_LADDER.md) for the full progression. + +The `governance` and `.project` repositories are not part of any subproject. +Both are a special case, administered directly by the Steering Committee +(`.project` is the standard CNCF project metadata repository that enables +automation from CNCF infrastructure). See +[README.md's Governance section](README.md#governance) and the +`steering-committee` team in [GitHub Teams](#github-teams-and-communication-channels). + +Current subproject maintainer committee membership is kept in +[MAINTAINERS.md](MAINTAINERS.md), not here; committee membership changes +follow the self-selection process in +[Changes in subproject maintainer committee membership](#changes-in-subproject-maintainer-committee-membership) +and don't require a governance vote on this document. + +Extensibility is the intended home for anything that extends CloudNativePG or +operates on PostgreSQL from outside the operator's core, including future +backup and recovery plugins and Postgres tooling that has nothing to do with +Kubernetes at all. The classification rules for what falls under Extensibility +versus Supply Chain, and the routing logic for new plugins, extensions, or +tools, are editorial detail that changes as the ecosystem grows; they live in +[subprojects/extensibility.md](subprojects/extensibility.md), not here. + +Because subproject boundaries are the `subprojects/` folder's existing +component groupings, every component already has a subproject; there is no +separate mapping to maintain here or to fall out of sync. Reorganizing which +grouping belongs to which subproject, adding a new grouping, or moving a +component to a different grouping is a routine editorial change to the +relevant `subprojects/*.md` file and does not require a governance vote. +Creating or retiring a subproject itself, i.e. changing this table, is a +Steering Committee decision (see [Voting](#voting)). + +### Proposing a New Component + +Anyone, inside or outside the project, may propose that a new repository +join CloudNativePG as a component. The proposal is opened as a GitHub issue +against the [governance repository](https://github.com/cloudnative-pg/governance), +describing: + +- The proposed repository's name and purpose +- Which existing subproject it belongs to, or, if none fit, a case for why + a new subproject is needed instead (see + [Organization-level decisions](#organization-level-decisions)) +- The initial Component Owner(s) proposed for it (GitHub handles) +- A description of the proposer's, or proposed owners', long-term + commitment to maintaining it + +The target subproject's maintainer committee reviews the proposal and +decides whether to accept it, by the same simple-majority, per-person vote +the committee uses for its own membership (see +[Changes in subproject maintainer committee membership](#changes-in-subproject-maintainer-committee-membership)). +Accepting it is the routine editorial change to that subproject's +`subprojects/*.md` file already described above; no separate Steering +Committee vote is required, since the component is joining an existing +subproject rather than creating a new one. If the proposal doesn't fit any +existing subproject, it's escalated to the Steering Committee as a request +to add a new subproject instead. + +A component that becomes inactive, or stops meeting the project's basic +health expectations (security response, Code of Conduct compliance, +maintained CI), may be archived by the same committee vote, removing it +from the subproject's file. This mirrors the addition process in reverse +and doesn't require a Steering Committee vote either, unless archiving it +would leave a subproject with no components at all, in which case it +becomes a [subproject removal](#organization-level-decisions). + +> [!NOTE] +> **Editorial reference, to be removed before ratification:** this intake +> and archival path is adapted from Crossplane's own +> [Community Extension Project lifecycle](https://github.com/crossplane/crossplane/blob/main/GOVERNANCE.md#community-extension-project-lifecycle), +> scoped down to CNPG's single-organization-of-repositories model (CNPG has +> no equivalent of a separate `crossplane-contrib` organization). Noted for +> reviewers during due diligence; the final text should stand on its own +> without naming the source. + +### GitHub Teams and Communication Channels + +Team membership on GitHub is only visible to other members of the +organization, never to the public, regardless of a team's "Visible" or +"Secret" setting; the same is true of private Slack channels. That makes +neither one suitable as the document of record for who holds authority: +[MAINTAINERS.md](MAINTAINERS.md) and the [subprojects/](subprojects/README.md) +folder are, and stay, the public source of truth. GitHub Teams and Slack +channels exist only +to *enforce* and support what those files already say, never as an +alternative way to find out who's on a committee. The actual team slugs, +grants, and channel names, and how they roll out as each subproject +committee is formalized, are operational detail kept in +[subprojects/README.md](subprojects/README.md). ## Project Roles The project recognizes different levels of responsibility within the community, -forming a contributor ladder that rewards participation and commitment. - -### Maintainers - -Maintainers hold a crucial role in the comprehensive development of the entire -CloudNativePG project and its associated components. This privilege is granted -with some expectation of responsibility: maintainers are people who care about -the CloudNativePG project and want to help it grow and improve. A maintainer is -not just someone who can make changes, but someone who has demonstrated their -ability to collaborate with the team, get the most knowledgeable people to -review code, contribute high-quality code, and follow through to fix issues (in -code or tests). - -A maintainer is a contributor to the CloudNativePG project's success and a -citizen helping the project succeed. - -The maintainers are identified in the [`MAINTAINERS.md`](MAINTAINERS.md) file. - -#### Changes in Maintainership - -New maintainers are proposed by an existing maintainer and are elected by a ⅔ -majority maintainers vote. Maintainers can be removed by a ⅔ majority -maintainers vote, leading to their transition to emeritus status. -Votes are conducted as defined in the [Voting](#voting) section. - -#### GitHub Project Administration - -Members designated as Maintainers will be included in the `maintainers` team, -where they will possess the `Maintain` role for every CloudNativePG repository. -Those Maintainers who are interested in assuming administrative -responsibilities for the organization's repositories can be appointed to the -`admins` team at any point, granting them the `Admin` role across all -repositories. - -### Component owners - -The component owners are tasked with the development of specific subprojects or -components within CloudNativePG. These components may be represented either by -a separate GitHub repository within the CloudNativePG organization (e.g., -`postgres-containers`) or by a subdirectory in a GitHub repository (e.g., -`./docs/` in `cloudnativepg`). - -The owners of these components are delineated in the -[`COMPONENT-OWNERS.md`](COMPONENT-OWNERS.md) file within this repository, which also -specifies the component for which each individual is responsible. -Component owners are implicitly considered Contributors and are included in the -`CONTRIBUTORS.md` file. - -#### Changes in component ownership - -New component owners can be proposed by any maintainer and are elected by a ⅔ -majority maintainers vote. Component owners can be removed by a ⅔ majority -maintainers vote. - -#### GitHub Project Administration - -Owners of components with dedicated GitHub repositories will be granted `Write` -access to their respective repositories, enabling them to merge approved pull -requests. Additionally, component owners will be incorporated into the -repository's `CODEOWNERS` file, ensuring clear attribution and accountability -for code contributions. - -It's important to note that these owners will not receive `Maintain` or `Admin` -privileges for any CloudNativePG GitHub repositories. - -### Contributors - -Contributors are members of the community who contribute directly to the project -and add value to it. This role represents the first formal tier of the -CloudNativePG contributor ladder. Contributions are not limited to code, but -also include documentation and community work. - -Responsibilities of a contributor include following the CloudNativePG Code of -Conduct and the project contributing guide. Requirements for this role include -one or more of the following: reporting or resolving issues, submitting pull -requests, contributing to documentation, participating in meetings, helping -community members, providing feedback on issues/PRs, testing releases, or -promoting the project in public. - -The contributors are identified in the [`CONTRIBUTORS.md`](CONTRIBUTORS.md) -file, which also includes all individuals holding the Component Owner role. - -#### Changes in contributor status - -New contributors are proposed by an existing maintainer and are elected by a -simple majority maintainers vote. Contributors can be removed by a simple -majority maintainers vote. - -#### GitHub Project Administration - -The contributor level does not imply that the individual will be added to the -GitHub organization or any specific project teams as a collaborator or member. +forming a contributor ladder that rewards participation and commitment. The +ladder itself (role definitions, requirements, and promotion/removal +process) is documented in [CONTRIBUTOR_LADDER.md](CONTRIBUTOR_LADDER.md), +owned by the Steering Committee (see [Voting](#voting)). This section covers +the two roles with project-wide governance or technical authority (Steering +Committee and Subproject Maintainer Committees); Contributors and Component +Owners are covered by the ladder document instead, to avoid keeping the same +rules in two places. + +> [!IMPORTANT] +> **Why these two stay here instead of moving to CONTRIBUTOR_LADDER.md:** +> amendment thresholds differ between the two documents. This document +> requires a ⅔ Steering Committee vote to amend; CONTRIBUTOR_LADDER.md only +> requires a simple majority (see [Voting](#voting)). The Steering +> Committee's own composition (seat count, the 2-per-organization cap, the +> owns/does-not-own split) and each Subproject Maintainer Committee's +> removal mechanism are the structural safeguards CNCF due diligence weighs +> most heavily, so they stay behind the heavier bar rather than the lighter +> one. The general principle: CONTRIBUTOR_LADDER.md covers individual +> progression (what a person gets and how they get there); this document +> covers collective bodies and their authority (what a committee can do, +> how it's composed, how it's amended). + +### Steering Committee + +The Steering Committee holds project-wide governance authority. It does not +replace the technical authority of subproject maintainer committees; it exists +to ensure that authority over vision, CNCF relations, and cross-project +decisions is not concentrated in a single organization. + +**Structure:** 5–7 seats. No single organization may hold more than 2 seats, +regardless of how many of its employees serve across subproject maintainer +committees. Seats serve 2-year staggered terms. + +> [!IMPORTANT] +> **Open item (needs discussion):** the actual stagger schedule isn't +> defined, which seats renew in which year, how the offset gets seeded at +> bootstrap (typically by shortening some initial terms so renewals don't +> all land in the same year), and what happens to a seat's clock if a +> subproject swaps its representative mid-term. Worth deciding a concrete +> schedule before this section can be considered complete. + +**Composition:** + +- One representative selected by each subproject's maintainer committee (see + [Subprojects](#subprojects)) +- One to three Community Representatives, elected annually by all + [CNPG Organization Members](CONTRIBUTOR_LADDER.md#cnpg-organization-member) + across all subprojects (4 subproject seats plus 1 to 3 Community + Representative seats span the 5-7 total) + +**The Steering Committee owns:** + +- **Foundational** (org-balanced, see [Organization-level decisions](#organization-level-decisions)): + - Curating and proposing changes to this document, ratified by the Steering + Committee itself + - Ownership of [CONTRIBUTOR_LADDER.md](CONTRIBUTOR_LADDER.md): the ladder's + structure, promotion criteria, and any numeric thresholds are a Steering + Committee decision, including advancement for contributors whose work + spans multiple subprojects or falls outside any single one + - Reviewing and deciding on new subprojects to add; removing subprojects + that have become inactive +- **Standard duties** (day-to-day, per person, see [Voting](#voting)): + - Project vision and strategic direction + - The CNCF interface: due diligence responses, public comment, foundation + communications, and organizing participation in CNCF/LFX programs (for + example mentorship initiatives) and CNCF events + - Arbitrating inter-subproject disagreements (for example, a conflict + between Extensibility and Core Projects over CNPG-I plugin framework + direction) + - Code of Conduct committee selection and ratification of CoC enforcement + decisions + - Security response coordination (who triages, who patches, the escalation + path across subprojects) and acting on other escalated code-quality + issues a subproject can't resolve on its own + - Resolving other issues that an individual subproject is unable to + resolve internally + - Administering project infrastructure, intellectual property, and shared + resources, including oversight of who holds GitHub organization + administration and access to sensitive credentials (secrets, CI/CD + provider accounts). Steering owns this responsibility structurally, so + it survives individual turnover, but may delegate day-to-day execution + to a named Infrastructure Team, the same pattern used for security + response above + - Determining overall direction for brand, advocacy, and marketing + - Issuing official statements on behalf of CloudNativePG and its + subprojects + - Passive oversight of subproject maintainer committee composition, and + removal of a committee member when that committee cannot act on its own + (see [Changes in subproject maintainer committee membership](#changes-in-subproject-maintainer-committee-membership)) + +**The Steering Committee does not own**, deferring instead to subproject +maintainer committees for: + +- Code review and merge decisions +- The release process +- Day-to-day technical decisions within a component or repository, handled + by lazy consensus among that component's owners (see + [Voting](#voting) for what "lazy consensus" means); subproject-wide + decisions spanning multiple components follow the same principle at the + subproject committee level + +#### Changes in Steering Committee composition + +A subproject maintainer committee may replace its Steering representative at +any time by simple majority of that committee, per person, uncapped by +organization. Community Representative seats are filled by annual election, +one vote per organization among all +[CNPG Organization Members](CONTRIBUTOR_LADDER.md#cnpg-organization-member) +across subprojects (see [Voting](#voting)); the nomination, election, and +vacancy mechanics are set out below. + +#### Community Representative Election Process + +Each organization casts one ranked ballot, reflecting the internally +coordinated preference of its own +[CNPG Organization Members](CONTRIBUTOR_LADDER.md#cnpg-organization-member); +unaffiliated individuals each cast their own ranked ballot, consistent with +the org-balanced mechanism this decision already uses (see +[Organization-level decisions](#organization-level-decisions)). + +- **Nomination:** the outgoing Steering Committee opens a public GitHub + Discussion in the [governance repository](https://github.com/cloudnative-pg/governance) + at the start of the annual election window, open to every CNPG + Organization Member across every subproject. Any CNPG Organization + Member may nominate up to two candidates there, including themselves. A + candidate does not need to be a CNPG Organization Member to be + nominated, but must accept the nomination and be endorsed by CNPG + Organization Members from two different organizations, in the same + discussion, before appearing on the ballot. +- **Election:** seats are filled by ranked-choice voting (a Condorcet or + instant-runoff method, run on an open ranked-choice tool such as + [CIVS](https://civs1.civs.us/)), one ballot per eligible voter as defined + above. The top vote-getters, up to the number of open seats, are elected, + subject to [organizational cap enforcement](#organizational-cap-enforcement) + below. +- **Vacancy:** a seat vacated mid-term goes to the next-highest-ranked + candidate from that seat's original election. If no candidate remains, a + special election is called using the same electorate as the original + election; eligibility isn't redetermined. The winner serves out the + remainder of the vacated term. + +> [!NOTE] +> **Editorial reference, to be removed before ratification:** the +> nomination, election, and vacancy mechanics above are adapted from +> [Crossplane's own GOVERNANCE.md](https://github.com/crossplane/crossplane/blob/main/GOVERNANCE.md#election-process), +> a graduated CNCF project with a broadly similar Steering model, rather +> than invented from scratch. Noted for reviewers during due diligence; the +> final text should stand on its own without naming the source. + +#### Organizational Cap Enforcement + +No single organization may hold more than 2 of the 5-7 Steering seats, +counting committee-selected and elected seats together. Unlike Crossplane's +version of this cap, which only binds once its initial terms expire, CNPG's +cap is enforced from the Steering Committee's very first appointment: the +purpose of this restructuring is to end a single organization's implicit +majority, so the cap cannot be allowed to lapse even temporarily at +bootstrap. + +- **At an election:** if the ranked results would seat more than 2 + representatives from one organization, the lowest-ranked candidate(s) + from the over-represented organization are skipped in favor of the + next-highest-ranked candidate from a different organization, repeated + until the cap is satisfied. +- **At a subproject selection:** if a subproject maintainer committee's + choice of representative would breach the cap, the committee selects a + different representative instead; the cap constrains who a committee may + send, not whether it gets a seat. +- **On an affiliation change after the fact** (an acquisition, a merger, or + a seat-holder changing employer): sufficient seat-holders from the + now-over-represented organization must resign until the cap is restored. + If the organization cannot agree who resigns, the question is decided by + a majority vote of the unaffected Steering Committee members. A vacated + elected seat is refilled per the vacancy rule above; a vacated + committee-selected seat is refilled by that subproject's committee + selecting a new representative. + +#### GitHub Project Administration (Steering Committee) + +See [GitHub Teams](#github-teams-and-communication-channels): the `steering-committee` team grants +`Admin` on `governance` and `.project` only, the two repositories Steering +administers directly (see [Subprojects](#subprojects)). + +### Subproject Maintainer Committees + +A member of a subproject's maintainer committee is what CloudNativePG +simply called a "Maintainer" before this restructuring, back when there was +only one project-wide group by that name. The role hasn't changed, only its +scope has: a committee member is now a CloudNativePG *Subproject* +Maintainer, named for the subproject they serve, CloudNativePG Core +Maintainer, CloudNativePG Supply Chain Maintainer, CloudNativePG Community, +Docs & Ecosystem Maintainer, or CloudNativePG Extensibility Maintainer, +matching the section names already used in [MAINTAINERS.md](MAINTAINERS.md). +Any unqualified "Maintainer" elsewhere in this document means a member of +one of these four committees, regardless of which. + +Each subproject (see [Subprojects](#subprojects)) has its own maintainer +committee, responsible for: + +- Technical direction within the subproject +- Code review, merge, and release +- Regular releases and issue triage +- Holding regular subproject-wide discussions on issues and planning +- Making final decisions on subproject changes that involve controversial + trade-offs +- Responding to security reports within the subproject's scope, escalating to + the Steering Committee as needed +- Supporting the Code of Conduct within the subproject and referring + violations to the Code of Conduct committee +- Selecting the subproject's representative to the Steering Committee +- Regularly attending the project's recurring community meetings +- Periodically attending Steering Committee meetings to provide input, when + invited or when subproject business is on the agenda + +#### Changes in subproject maintainer committee membership + +Subproject maintainer committees are self-selecting, with Steering Committee +oversight. Eligibility is scoped to established Component Owners of that +subproject's repositories, since that's where subproject-wide technical +judgment gets demonstrated first; being tagged in a folder-scoped +`CODEOWNERS` line for review-routing isn't a substitute for having run a +whole repository. This gives contributors to +charts, plugins, container images, or documentation the same path to +governance influence, via their subproject's Steering seat, as contributors +to the core operator, once they've become a Component Owner of one of that +subproject's repositories. A nominee is added by a simple majority +vote of the existing committee members, per person, uncapped by +organization: deliberately a lighter bar than the ⅔ required to remove one, +consistent with the general principle that a body should be harder to remove +someone from than to add them to. Steering's oversight here is passive, +limited to the general power to intervene under +[Governance changes](#voting) if a committee's composition itself became a +problem, not a second vote on every addition. + +Self-selection is expected to work in the removal direction too: a committee +should remove a member who has gone unresponsive, breached the Code of +Conduct, or stepped outside the subproject's remit, by a ⅔ majority of the +other committee members: the member under review neither votes nor counts +toward the total the ⅔ is computed against, only the remaining members do. +Self-selection alone isn't a complete safeguard, +though: it assumes the committee can reach that majority without the member +in question, which isn't guaranteed if the group is small or deadlocked. + +Steering's route is a true backstop, not a power it holds concurrently with +the committee: Steering does not remove a subproject maintainer committee +member on its own initiative, and does not monitor committees looking for +cause to intervene. It may only act when both of the following hold: at +least one other member of that committee has requested it, and the +committee has already tried, and failed, its own ⅔ vote above, or is +demonstrably unable to convene one at all (too few members, or a deadlock). +Once both conditions are met, Steering removes the member by a plain +majority vote of its own members, per person, the same way it conducts its +own day-to-day business. + +> [!NOTE] +> **Editorial reference, to be removed before ratification:** this +> committee/Steering split mirrors the CNCF project-template's own mechanism +> (see the template's [GOVERNANCE-subprojects.md](https://github.com/cncf/project-template/blob/main/GOVERNANCE-subprojects.md#individual-subproject-governance)), +> adopted here rather than inventing a new one. Noted for reviewers during +> due diligence; the final text should stand on its own without naming the +> template. + +#### GitHub Project Administration (Subproject Maintainer Committees) + +See [GitHub Teams](#github-teams-and-communication-channels) for the `subproject-*` team granting +`Maintain` on this subproject's repositories. Administrative (`Admin`) access +continues to be granted only to those who take on organization-wide +administrative responsibilities, as under the current model. + +### Contributors and Component Owners + +These two roles sit below Subproject Maintainer on the ladder: a Contributor +adds value without a defined area of ownership, and a Component Owner owns +an entire component. Their requirements, promotion process, and GitHub +access are defined in [CONTRIBUTOR_LADDER.md](CONTRIBUTOR_LADDER.md), not +here, to avoid keeping the same rules in two places. Component Owners are +listed by repository in the [subprojects/](subprojects/README.md) folder, +not repeated by name in [CONTRIBUTORS.md](CONTRIBUTORS.md), which is +reserved for the Contributor tier, the one rung with no repository to be +listed under. A repository's Component Owners may also tag a Contributor in +a folder-scoped `CODEOWNERS` line for review-routing, an operational choice, +not a promotion (see +[CONTRIBUTOR_LADDER.md's Component Owner section](CONTRIBUTOR_LADDER.md#component-owner) +for what that does and doesn't carry). + +Contributor and Component Owner status for a specific repository is decided +by that repository's own existing Component Owners, not by the subproject +maintainer committee, with the committee stepping in only as backstop for a +stalled or too-small repository, the same shape as +[Changes in subproject maintainer committee membership](#changes-in-subproject-maintainer-committee-membership) +above. See [CONTRIBUTOR_LADDER.md's Component Owner section](CONTRIBUTOR_LADDER.md#component-owner) +for the full mechanism, not repeated here. ## Meetings -Time zones permitting, Maintainers are expected to participate in the public -developers meeting (see ["CloudNativePG Community Meetings" in the organization page](https://github.com/cloudnative-pg#cloudnativepg-community-meetings) -page for details). +Meeting cadence, format, and joining details for the community, the Steering +Committee, and each subproject are published on the organization page (see +the [CloudNativePG GitHub organization profile](https://github.com/cloudnative-pg)), +not fixed here, so they can evolve without a governance edit. The Steering +Committee's own regular meeting is open to all contributors, with minutes +published for the community; each subproject maintainer committee holds +regular subproject-wide discussions of its own (see +[Subproject Maintainer Committees](#subproject-maintainer-committees)). Maintainers will also have closed meetings to discuss security reports or Code of Conduct violations. Such meetings should be scheduled by any Maintainer on receipt of a security issue or CoC report. All current Maintainers -must be invited to such closed meetings, except for any Maintainer accused of a CoC violation. +must be invited to such closed meetings, except for any Maintainer accused of +a CoC violation. Other sensitive matters, such as removing a Maintainer, may +also be handled in a closed meeting at the discretion of the Steering +Committee or the relevant subproject committee; see [Voting](#voting) for the +principle that governs this. ## CNCF Resources Any Maintainer may suggest a request for CNCF resources by creating a new [GitHub discussion under the "Maintainers room" category](https://github.com/cloudnative-pg/cloudnative-pg/discussions/categories/maintainers-room), -or during a meeting. A simple majority of Maintainers approves the request. -The Maintainers may also choose to delegate working with the CNCF to -non-Maintainer community members. +or during a meeting. The Steering Committee approves the request as +standard, day-to-day business (see [Voting](#voting)): lazy consensus, +falling back to a simple majority per person. The Steering Committee may +also choose to +delegate working with the CNCF to non-Steering community members. ## Code of Conduct @@ -178,21 +582,143 @@ violations by community members will be discussed and resolved on the [private Maintainer mailing list](mailto:conduct@cloudnative-pg.io). If the reported CoC violator is a Maintainer, the Maintainers will instead designate two Maintainers to work with CNCF staff in resolving the report. +The Steering Committee selects the standing CoC committee and ratifies CoC +enforcement decisions. + +## Security Response + +CloudNativePG uses a hybrid, repository-first model, matching how CVEs are +already handled in the `cloudnative-pg` repository today: a single intake +point at [security@cloudnative-pg.io](mailto:security@cloudnative-pg.io), +triaged by a named Security Response Team, then routed to that component's +Component Owners to develop and validate the fix under embargo. +Subproject maintainer committees own the fix and disclosure timeline for +issues within their own scope; the Security Response Team and Steering +Committee get directly involved only to coordinate across subprojects (for +example, a vulnerability in a component one subproject owns that also +affects a plugin or tool maintained by another subproject), to coordinate +CNCF-level disclosure, or when a subproject can't resolve an issue on its +own. Reporters only ever need to know the single intake address, not +CloudNativePG's internal component structure. + +The Steering Committee oversees the security response process, coordinates +across subprojects, and ensures coverage when personnel change. + +> [!IMPORTANT] +> This section will be expanded with the named Security Response Team roster +> and detailed escalation procedure as a follow-up to this proposal; it needs +> discussion before it's considered complete. + +## Infrastructure Administration + +The Steering Committee is responsible for the project's infrastructure: +GitHub organization administration, and access to sensitive credentials +such as CI/CD secrets and cloud accounts used by automation, the same way +it is for Security Response, so responsibility survives individual turnover +rather than being tied informally to whoever happens to hold `admins` +access today. The Steering Committee may delegate day-to-day execution to +a named Infrastructure Team. + +> [!IMPORTANT] +> **Open item (needs discussion):** the Infrastructure Team's roster, and how +> it relates to the existing `admins` GitHub team (today, CloudNativePG's +> existing maintainers), still needs to be named explicitly, the same way the +> Security Response Team is a stub above. Tracked as a follow-up. ## Voting -While most business in CloudNativePG is conducted by "lazy consensus", -periodically, the Maintainers may need to vote on specific actions or changes. - -CloudNativePG relies on [gitvote](https://github.com/cncf/gitvote) for formal -voting within GitHub issues or discussions. - -- **Simple majority:** Most votes require a simple majority of all Maintainers - to succeed. A vote can be requested by a Maintainer using the `/vote` - command. -- **Governance changes:** Changes to this Governance require a ⅔ vote of - all Maintainers. This can be requested using the `/vote-governance` command. - -Votes can also be taken on [the private Maintainer mailing list](mailto:security@cloudnative-pg.io) -for security or conduct matters, or during developer meetings. -Any Maintainer may demand a vote be taken. +Most business in CloudNativePG is conducted by lazy consensus: a proposal is +considered accepted if no Steering Committee member, Subproject Maintainer, +or Component Owner with standing over that decision raises an objection +within a reasonable review window, so everyday decisions don't need an +explicit vote, only the absence of a block. Periodically, a decision needs +an explicit vote instead. + +Votes happen in the open: a public GitHub issue or discussion, explicit ++1/-1 comments from eligible voters, and a final tally posted by whoever +called the vote. A vote stays open for two weeks by default, closing +early once the required threshold is unambiguously met so a decision +isn't held up needlessly once it's already settled. The specific tooling +used to run a vote (CloudNativePG currently uses +[gitvote](https://github.com/cncf/gitvote) for some of this, see +[.gitvote.yml](.gitvote.yml)) is an implementation detail that may change +without a governance edit; the duration and early-closing behavior above +are policy, not tied to any one tool, and the process as a whole is what's +actually required. + +### Organization-level decisions + +These are Steering's foundational, constitutional-level decisions: the ones +that shape the project's structure or Steering's own composition. They use +**org-balanced voting**: each organization represented among the eligible +voters casts one vote, regardless of how many individuals it has among +those voters. If an organization has multiple eligible voters, those +individuals coordinate internally and cast a single organizational vote; +unaffiliated individuals each cast their own vote. The 2-per-organization +seat cap on Steering limits how skewed its composition can get, but doesn't +by itself make a per-seat vote balanced: an organization holding 2 seats +would otherwise cast 2 votes to every other organization's 1. So these +specific decisions are org-balanced rather than per-seat. Steering's other, +day-to-day business (see [Subproject-level decisions](#subproject-level-decisions) +below for the one example that recurs, backstopping a subproject maintainer +committee) is decided the same way any committee decides routine business: +lazy consensus, falling back to a plain per-person vote among Steering +members. + +| Decision Type | Who Votes | Mechanism | +| :---- | :---- | :---- | +| Steering Committee elections (Community Representative seats) | All CNPG Organization Members, across all subprojects | One vote per organization | +| Governance changes (this document) | Steering Committee | ⅔ majority, one vote per organization represented on Steering | +| Changes to [CONTRIBUTOR_LADDER.md](CONTRIBUTOR_LADDER.md) | Steering Committee | Simple majority, one vote per organization | +| Adding/removing subprojects | Steering Committee | Majority, one vote per organization | + +The other kind of Steering seat, one per subproject, isn't filled by an +org-balanced vote at all: each subproject's own maintainer committee +selects its representative internally, simple majority, per person (see +[Changes in Steering Committee composition](#changes-in-steering-committee-composition)). + +> [!NOTE] +> **Editorial reference, to be removed before ratification:** this matches +> the [CNCF's own project-template](https://github.com/cncf/project-template/blob/main/GOVERNANCE-subprojects.md#amendments) +> rather than the broader all-maintainer vote considered in an earlier draft +> of this document. Noted for reviewers during due diligence; the final +> text should stand on its own without naming the template. + +> [!IMPORTANT] +> **Bootstrap exception:** the Steering Committee doesn't exist yet, so it +> can't ratify the governance changes that create it. Adopting this +> restructuring for the first time is proposed to happen by simple majority +> vote of the collective subproject maintainers (in practice, today's +> existing maintainers, since subprojects aren't formalized yet either). All +> later governance changes follow the Steering Committee mechanism above. + +> [!NOTE] +> **Editorial reference, to be removed before ratification:** this bootstrap +> mechanism mirrors the CNCF project-template's own bootstrap clause. Noted +> for reviewers during due diligence; not part of the ratified policy text. + +### Subproject-level decisions + +Subproject technical decisions remain per-person, uncapped by organization, +in recognition of the engineering investment individual contributors and +their employers make (see [Project Structure](#project-structure)). + +| Decision Type | Who Votes | Mechanism | +| :---- | :---- | :---- | +| Adding a subproject maintainer committee member | The existing members of that committee | Simple majority, per person | +| Removing a subproject maintainer committee member (committee route) | The other members of that committee | ⅔ majority, per person | +| Removing a subproject maintainer committee member (Steering backstop) | Steering Committee | Plain majority, per person | + +Repository-level decisions follow the same per-person principle, one level +further down; see [Contributors and Component Owners](#contributors-and-component-owners) +above, and [CONTRIBUTOR_LADDER.md's At a Glance table](CONTRIBUTOR_LADDER.md#at-a-glance) +for the full breakdown. + +At the discretion of the Steering Committee or a subproject committee, the +deliberation behind a vote may happen privately, for example on +[the private Maintainer mailing list](mailto:security@cloudnative-pg.io) or +during a closed meeting, for a Maintainer removal or a security matter (see +[Meetings](#meetings)). Privacy applies to the discussion, not the outcome: +the final decision and its rationale, redacted for privacy where needed, are +still announced publicly, consistent with CloudNativePG's commitment to +openness. Any Maintainer may demand a vote be taken. diff --git a/MAINTAINERS.md b/MAINTAINERS.md index ab3fcee..9d785c9 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -1,13 +1,106 @@ # CloudNativePG Maintainers -The current maintainers of the CloudNativePG project are (in alphabetical -order): - -- Gabriele Bartolini (EDB) -- Francesco Canovai (EDB) -- Leonardo Cecchi (EDB) -- Marco Nenciarini (EDB) -- Armando Ruocco (EDB) +> [!IMPORTANT] +> **Provisional (needs discussion):** everything below the Core Maintainers +> list is a first-pass reading of who currently holds `CODEOWNERS` entries +> in each subproject's repositories, not a finalized roster. It has not been +> ratified by a governance vote, and the Steering Committee that would +> oversee subproject committee membership doesn't exist yet either. Read +> every section here other than Core Maintainers as provisional. + +## Steering Committee + +*(to be appointed)* + +Per [GOVERNANCE.md's Steering Committee section](GOVERNANCE.md#steering-committee), +seats are filled by each subproject's maintainer committee selecting one +representative, plus one to three Community Representatives elected +annually (see +[Community Representative Election Process](GOVERNANCE.md#community-representative-election-process)). +Neither can happen until the subproject committees below are themselves +ratified, so the table stays empty until then. + +| Last Name | First Name | Handle | Organization | Seat | Email | Term Start | Term End | +| --- | --- | --- | --- | --- | --- | --- | --- | + +## Core Maintainers + +The current maintainers of the CloudNativePG project (in alphabetical +order), forming the Core Projects subproject's committee: + +| Last Name | First Name | Handle | Organization | Component(s) | +| --- | --- | --- | --- | --- | +| Bartolini | Gabriele | @gbartolini | EDB | cloudnative-pg, api, machinery, barman-cloud (default) | +| Canovai | Francesco | @fcanovai | EDB | cloudnative-pg, api, machinery, barman-cloud (default) | +| Cecchi | Leonardo | @leonardoce | EDB | cloudnative-pg, api, machinery, barman-cloud (default) | +| Nenciarini | Marco | @mnencia | EDB | cloudnative-pg, api, machinery, barman-cloud (default) | +| Ruocco | Armando | @armru | EDB | cloudnative-pg, api, machinery, barman-cloud (default) | + +## Supply Chain Maintainers (proposed, pending ratification) + +| Last Name | First Name | Handle | Organization | Component(s) | +| --- | --- | --- | --- | --- | +| Agarwal | Yash | @XploY04 | | chaos-testing | +| Bartolini | Gabriele | @gbartolini | EDB | charts, artifacts, postgres-containers, postgres-extensions-containers, pgbouncer-containers, postgis-containers, postgres-trunk-containers, daggerverse, chaos-testing | +| Battiato | Jonathan | @jbattiato | EDB | daggerverse, postgres-trunk-containers | +| Canovai | Francesco | @fcanovai | EDB | charts, artifacts, postgres-containers, postgres-extensions-containers, postgis-containers, postgres-trunk-containers, daggerverse, chaos-testing | +| Cecchi | Leonardo | @leonardoce | EDB | charts, artifacts, postgres-extensions-containers, pgbouncer-containers, postgis-containers, daggerverse | +| Fei | Niccolò | @NiccoloFei | EDB | artifacts, postgres-containers, postgres-extensions-containers, pgbouncer-containers, postgis-containers, postgres-trunk-containers, daggerverse, ciclops | +| Grudev | Itay | @itay-grudev | | charts | +| Li | Tao | @litaocdl | EDB | postgres-containers, pgbouncer-containers, postgis-containers, postgres-trunk-containers | +| Nenciarini | Marco | @mnencia | EDB | charts, artifacts, postgres-containers, postgres-extensions-containers, pgbouncer-containers, postgis-containers, postgres-trunk-containers, daggerverse, chaos-testing | +| Ruocco | Armando | @armru | EDB | artifacts, postgres-extensions-containers | +| Silvela | Jaime | @jsilvela | | ciclops | + +Nothing here restricts a Component Owner from qualifying for more than one +committee: several names above also sit on other committees below, via +their ownership of components in those subprojects instead. + +## Community, Docs & Ecosystem Maintainers (proposed, pending ratification) + +| Last Name | First Name | Handle | Organization | Component(s) | +| --- | --- | --- | --- | --- | +| Bartolini | Gabriele | @gbartolini | EDB | docs, cloudnative-pg.github.io, cnpg-playground, webtest | +| Canovai | Francesco | @fcanovai | EDB | docs, cnpg-playground, webtest | +| Cecchi | Leonardo | @leonardoce | EDB | docs, cloudnative-pg.github.io, cnpg-playground, webtest | +| Drees | Floor | @FloorD | EDB | cloudnative-pg.github.io | +| Grudev | Itay | @itay-grudev | | grafana-dashboards | +| Nenciarini | Marco | @mnencia | EDB | docs, cloudnative-pg.github.io, cnpg-playground, webtest | +| Ruocco | Armando | @armru | EDB | webtest | +| Saxena | Anushka | @SaxenaAnushka102 | | docs | +| Schneider | Jeremy | @ardentperf | GEICO | cnpg-playground | +| Silvela | Jaime | @jsilvela | | cloudnative-pg.github.io | + +> [!IMPORTANT] +> **Open item (needs discussion):** **Philippe Scorsolini** holds whole-repo +> `CODEOWNERS` on `grafana-dashboards` (the same repository that qualifies +> Itay Grudev above) plus partial `CODEOWNERS` on `charts/cluster`. He's also +> already listed as an Emeritus Maintainer below, which sits awkwardly next +> to otherwise qualifying for an active committee seat by the same standard +> applied to everyone else on this page. Worth confirming which status is +> current before deciding whether to include him, rather than resolving it +> here unilaterally. + +## Extensibility Maintainers (proposed, pending ratification) + +| Last Name | First Name | Handle | Organization | Component(s) | +| --- | --- | --- | --- | --- | +| Bartolini | Gabriele | @gbartolini | EDB | cnpg-i, cnpg-i-machinery, plugin-barman-cloud, cnpg-i-hello-world, postgres-keycloak-oauth-validator | +| Canovai | Francesco | @fcanovai | EDB | cnpg-i, cnpg-i-machinery, plugin-barman-cloud, cnpg-i-hello-world, postgres-keycloak-oauth-validator | +| Cecchi | Leonardo | @leonardoce | EDB | cnpg-i, cnpg-i-machinery, plugin-barman-cloud, cnpg-i-hello-world, postgres-keycloak-oauth-validator | +| Fei | Niccolò | @NiccoloFei | EDB | plugin-barman-cloud | +| Nenciarini | Marco | @mnencia | EDB | cnpg-i, cnpg-i-machinery, plugin-barman-cloud, cnpg-i-hello-world, postgres-keycloak-oauth-validator | +| Ruocco | Armando | @armru | EDB | cnpg-i, cnpg-i-machinery, plugin-barman-cloud, cnpg-i-hello-world, postgres-keycloak-oauth-validator | +| Tabata | Yoshiyuki | @y-tabata | Hitachi | postgres-keycloak-oauth-validator | + +Once ratified, changes to a subproject's committee membership follow the +self-selection process in +[GOVERNANCE.md's Voting section](GOVERNANCE.md#voting) and are recorded +directly in the sections above; they do not require editing GOVERNANCE.md +itself. `governance` and `.project` sit outside this file entirely: both +are administered directly by the Steering Committee (see +[GOVERNANCE.md's Subprojects section](GOVERNANCE.md#subprojects)), not by a +subproject maintainer committee. ## Emeritus Maintainers diff --git a/README.md b/README.md index 9a3072e..61bf022 100644 --- a/README.md +++ b/README.md @@ -10,85 +10,47 @@ project: - [Contributing guidelines](./CONTRIBUTING.md) - [AI Policy](./AI_POLICY.md) - [List of Maintainers](./MAINTAINERS.md) -- [List of Component owners](./COMPONENT-OWNERS.md) +- [Contributor Ladder](./CONTRIBUTOR_LADDER.md) +- [Subprojects & Component Owners](./subprojects/README.md) - [List of Contributors](./CONTRIBUTORS.md) - [License](./LICENSE) -## Repositories - -### Core Projects - -The primary components for deploying and managing the project lifecycle. - -| Repository | Description | -| --- | --- | -| [governance](https://github.com/cloudnative-pg/governance) | Central hub for project policies, AI policy, and general guidelines. | -| [cloudnative-pg](https://github.com/cloudnative-pg/cloudnative-pg) | The main Kubernetes Operator for PostgreSQL. | -| [charts](https://github.com/cloudnative-pg/charts) | Official Helm charts for the operator, database clusters and the Barman Cloud plugin. | -| [artifacts](https://github.com/cloudnative-pg/artifacts) | Storage for generated manifests, checksums, metadata, and image catalogs. | -| [cnpg-template](https://github.com/cloudnative-pg/cnpg-template) | A template repository for creating new CloudNativePG-related projects. | - -### Container Images +## Table of Contents -Standardized images built for security, minimal footprint, and CNPG compatibility. - -| Repository | Description | -| --- | --- | -| [postgres-containers](https://github.com/cloudnative-pg/postgres-containers) | Operand images for all community-supported PostgreSQL versions. | -| [postgres-extensions-containers](https://github.com/cloudnative-pg/postgres-extensions-containers) | Images for community extensions used as pluggable image volumes. | -| [pgbouncer-containers](https://github.com/cloudnative-pg/pgbouncer-containers) | Optimized images for PgBouncer connection pooling. | -| [postgis-containers](https://github.com/cloudnative-pg/postgis-containers) | PostgreSQL images bundled with PostGIS extensions. | -| [postgres-trunk-containers](https://github.com/cloudnative-pg/postgres-trunk-containers) | Images built from PostgreSQL `main` branch for early testing. | - -### Community, Docs & Monitoring - -User-facing resources, observability, and distribution. - -| Repository | Description | -| --- | --- | -| [docs](https://github.com/cloudnative-pg/docs) | The documentation project and Hugo source for the operator docs. | -| [cloudnative-pg.github.io](https://github.com/cloudnative-pg/cloudnative-pg.github.io) | The main project landing page/website. | -| [cnpg-playground](https://github.com/cloudnative-pg/cnpg-playground) | Local learning environment scripts using Docker/Kind. | -| [grafana-dashboards](https://github.com/cloudnative-pg/grafana-dashboards) | Standardized Grafana dashboards for monitoring CNPG clusters. | -| [community-operators](https://github.com/cloudnative-pg/community-operators) | Fork for publishing the operator to OperatorHub.io. | -| [webtest](https://github.com/cloudnative-pg/webtest) | Internal tooling for website and documentation testing. | +- [Governance](#governance) +- [Repositories](#repositories) -### Libraries & Automation +## Governance -Shared logic, API definitions, and CI/CD modules consumed by other components. +The `governance` and `.project` repositories are a special case: neither is +part of any subproject, and both are administered directly by the Steering +Committee (see [GOVERNANCE.md's GitHub Teams section](./GOVERNANCE.md#github-teams-and-communication-channels)), +not by a subproject maintainer committee. | Repository | Description | | --- | --- | -| [api](https://github.com/cloudnative-pg/api) | The CloudNativePG API definitions and types. | -| [machinery](https://github.com/cloudnative-pg/machinery) | Common Go library for internal logic (extracted from the operator). | -| [barman-cloud](https://github.com/cloudnative-pg/barman-cloud) | Go library for interacting with Barman Cloud object stores. | -| [daggerverse](https://github.com/cloudnative-pg/daggerverse) | Dagger modules for portable CI/CD workflows. | - -### Interface & Plugins (CNPG-I) - -The extensibility layer that allows for custom backups and additional logic. - -| Repository | Description | -| --- | --- | -| [cnpg-i](https://github.com/cloudnative-pg/cnpg-i) | The CloudNativePG Interface (CNPG-I) gRPC specification. | -| [cnpg-i-machinery](https://github.com/cloudnative-pg/cnpg-i-machinery) | Shared Go code for developing CNPG-I compatible plugins. | -| [plugin-barman-cloud](https://github.com/cloudnative-pg/plugin-barman-cloud) | The reference CNPG-I backup/restore plugin for Barman Cloud. | -| [cnpg-i-hello-world](https://github.com/cloudnative-pg/cnpg-i-hello-world) | A simplified template/example for building new plugins. | - -### PostgreSQL Modules & Extensions - -Software designed to run inside or alongside the PostgreSQL database engine. - -| Repository | Description | -| --- | --- | -| [postgres-keycloak-oauth-validator](https://github.com/cloudnative-pg/postgres-keycloak-oauth-validator) | A PostgreSQL module for OAuth2/Keycloak token validation. | - -### Testing & Automation +| [governance](https://github.com/cloudnative-pg/governance) | Central hub for project policies, AI policy, and general guidelines. | +| [.project](https://github.com/cloudnative-pg/.project) | The standard CNCF project metadata repository, enabling automation from CNCF infrastructure. | -Tools dedicated to CI/CD, resilience testing, and GitHub Actions development. +## Repositories -| Repository | Description | -| --- | --- | -| [ciclops](https://github.com/cloudnative-pg/ciclops) | The Continuous Integration Circular Operations tool for the project. | -| [chaos-testing](https://github.com/cloudnative-pg/chaos-testing) | Infrastructure and scripts for running chaos experiments against CNPG. | -| [github-test](https://github.com/cloudnative-pg/github-test) | Playground and testing ground for GitHub Actions and automation workflows. | +CloudNativePG's repositories are grouped into four subprojects, defined in +[GOVERNANCE.md's Subprojects section](./GOVERNANCE.md#subprojects). The full +repository listing, descriptions, and component ownership are kept in the +[subprojects/](./subprojects/README.md) folder, one file per subproject, not +duplicated here. + +- **Core Projects**: the operator itself. +- **Supply Chain**: build, packaging, and testing infrastructure that + supports the operator and its images, including how it's distributed to + users (Helm charts, manifests, OperatorHub). +- **Community, Docs & Ecosystem**: the website, documentation, and + observability integrations (Grafana). +- **Extensibility**: interfaces, modules, and standalone tooling that extend + CloudNativePG or PostgreSQL without changing the operator's core. + +Reorganizing which repository belongs to which subproject, adding a new +grouping, or moving a repository between groupings is a routine editorial +change to the relevant `subprojects/*.md` file and does not require a +governance vote; adding, removing, or renaming a subproject itself does (see +[GOVERNANCE.md's Voting section](./GOVERNANCE.md#voting)). diff --git a/subprojects/README.md b/subprojects/README.md new file mode 100644 index 0000000..a25a011 --- /dev/null +++ b/subprojects/README.md @@ -0,0 +1,109 @@ +# CloudNativePG Subprojects + +> [!IMPORTANT] +> **Draft, not yet ratified.** The subproject structure, GitHub Teams, and +> `CODEOWNERS` scoping described in this folder are part of the federated +> governance model proposed in [GOVERNANCE.md](../GOVERNANCE.md), which +> hasn't been ratified by a Steering Committee vote (Steering doesn't exist +> yet). The repository listings themselves reflect real, current +> `CODEOWNERS` data; the governance mechanism around them (team names, +> committee-scoped edit rights) is still a proposal. + +This is the index of CloudNativePG's four subprojects and their components. +Each subproject has its own file, listing every repository that falls under +it, plus who owns each one. Subprojects themselves, and the access/voting rights each +role carries, are defined in +[GOVERNANCE.md's Subprojects section](../GOVERNANCE.md#subprojects), not +here; subproject maintainer committee rosters are in +[MAINTAINERS.md](../MAINTAINERS.md). Component Owners are recorded here, by +repository, and nowhere else: [CONTRIBUTORS.md](../CONTRIBUTORS.md) is +reserved for the Contributor tier, which has no repository to be listed +under. Some Owners column entries below are folder-scoped rather than +whole-repository: that's a repository's own Component Owners tagging a +Contributor in a `CODEOWNERS` line for review-routing, an operational +choice, not a promotion, so it carries no vote and no CNPG Organization +Member status (see +[CONTRIBUTOR_LADDER.md's Component Owner section](../CONTRIBUTOR_LADDER.md#component-owner)). + +- [Core Projects](core-projects.md) +- [Supply Chain](supply-chain.md) +- [Community, Docs & Ecosystem](community-ecosystem.md) +- [Extensibility](extensibility.md) + +Two things apply to every file above, stated once here rather than repeated +in each: every repository in each file is already owned by that subproject's +own maintainer committee, via the corresponding [GitHub Team](#github-teams); +each file's Owners column lists only individuals or teams named explicitly +in that repository's own `CODEOWNERS` file, in addition to the committee. + +The `governance` and `.project` repositories are not listed in any of these: +neither is part of any subproject; see +[README.md's Governance section](../README.md#governance). + +Reorganizing which component belongs to which subproject, adding a new +grouping within a subproject file, or moving a component between groupings is +a routine editorial change to the relevant `subprojects/*.md` file and does +not require a governance vote; adding, removing, or renaming a subproject +itself does (see [GOVERNANCE.md's Voting section](../GOVERNANCE.md#voting)). +Each `subprojects/*.md` file, other than this index, is scoped in +`CODEOWNERS` to its own subproject's maintainer committee (see +[CODEOWNERS](../CODEOWNERS)), so a subproject can update its own component +listing without needing sign-off from the others. This index stays scoped +to `@cloudnative-pg/maintainers`, since it isn't owned by any single +subproject. + +## GitHub Teams + +Team membership on GitHub is only visible to other members of the +organization, never to the public. [MAINTAINERS.md](../MAINTAINERS.md) and +this folder are, and stay, the public source of truth; GitHub Teams exist +only to *enforce* what those files already say. Names are fixed below so +nobody invents an ad hoc team when a repo is created or a subproject rolls +out. + +| Team (GitHub slug) | Grants | Access | +| :---- | :---- | :---- | +| `maintainers` (existing) | Current maintainers, until subproject teams below are rolled out | `Maintain` on every repository | +| `admins` (existing) | Maintainers with org-administration duties | `Admin` on every repository | +| `steering-committee` | Steering Committee | `Admin` on `governance` and `.project` only, the two repositories Steering administers directly; Steering doesn't own code review, merge, or release, so it doesn't need repo-wide access elsewhere | +| `core-maintainers` | Core Projects committee | `Maintain` on the [Core Projects](core-projects.md) repositories | +| `supply-chain-maintainers` | Supply Chain committee | `Maintain` on the [Supply Chain](supply-chain.md) repositories | +| `community-ecosystem-maintainers` | Community, Docs & Ecosystem committee | `Maintain` on the [Community, Docs & Ecosystem](community-ecosystem.md) repositories | +| `extensibility-maintainers` | Extensibility committee | `Maintain` on the [Extensibility](extensibility.md) repositories | + +Team membership must mirror the rosters in MAINTAINERS.md; when a roster +changes, any maintainer with organization-admin access updates the +corresponding team to match. Set new teams to "Visible" within the +organization for internal clarity; this does not make membership public, it +only helps other maintainers and component owners see who's on which team. + +> [!IMPORTANT] +> **Transitional, to be removed once rollout completes:** subproject teams +> roll out gradually as each subproject's maintainer committee is formalized +> (tracked separately); until a given subproject's team exists, `maintainers` +> continues to hold `Maintain` on its repositories, unchanged from today. If +> the number of teams grows significantly, consider a declarative "teams as +> code" tool that reconciles actual GitHub org/team state against a committed +> config file (Kubernetes' [peribolos](https://github.com/kubernetes-sigs/prow/tree/main/cmd/peribolos) +> is the standard precedent), but that's more tooling than six teams need +> right now. + +## Communication Channels + +Slack channel names are the corresponding GitHub team name above, prefixed +with `cloudnativepg-` (e.g. `core-maintainers` the team, +`cloudnativepg-core-maintainers` the channel), so a GitHub team and its +Slack channel map onto each other without guessing. + +| Channel | Maps to | +| :---- | :---- | +| `cloudnativepg-core-maintainers` (renamed from `cloudnativepg-maintainers`) | Core Projects committee | +| `cloudnativepg-supply-chain-maintainers` | Supply Chain committee | +| `cloudnativepg-community-ecosystem-maintainers` | Community, Docs & Ecosystem committee | +| `cloudnativepg-extensibility-maintainers` | Extensibility committee | +| `cloudnativepg-steering-committee` | Steering Committee (security response and CoC ratification are discussed here) | + +All of these channels are private, so channel membership is no more visible +to the public than a GitHub Team is. MAINTAINERS.md stays the document of +record for who holds authority; these channels are operational plumbing that +must mirror it, not an alternative way to find out who's on a committee. diff --git a/subprojects/community-ecosystem.md b/subprojects/community-ecosystem.md new file mode 100644 index 0000000..85b06bc --- /dev/null +++ b/subprojects/community-ecosystem.md @@ -0,0 +1,18 @@ +# Community, Docs & Ecosystem + +User-facing resources and ecosystem integration: the [cloudnative-pg.io](https://cloudnative-pg.io/) +website, documentation, observability integrations (Grafana), and other +community-facing tooling. See the [subprojects index](README.md) for how this +fits into the wider structure, and [GOVERNANCE.md](../GOVERNANCE.md#subprojects) +for how subprojects are defined. + +> See [subprojects/README.md](README.md) for default component ownership +> and this file's own edit rights. + +| Repository | Description | Scope | Owners | +| --- | --- | --- | --- | +| [docs](https://github.com/cloudnative-pg/docs) | The documentation project and Hugo source for the operator docs. | *(whole repository)* | Leonardo Cecchi (@leonardoce, Maintainer), Marco Nenciarini (@mnencia, Maintainer), Gabriele Bartolini (@gbartolini, Maintainer), Francesco Canovai (@fcanovai, Maintainer), Anushka Saxena (@SaxenaAnushka102) | +| [cloudnative-pg.github.io](https://github.com/cloudnative-pg/cloudnative-pg.github.io) | The main project landing page/website. | *(whole repository)* | Gabriele Bartolini (@gbartolini, Maintainer), Jaime Silvela (@jsilvela), Floor Drees (@FloorD), Marco Nenciarini (@mnencia, Maintainer), Leonardo Cecchi (@leonardoce, Maintainer) | +| [cnpg-playground](https://github.com/cloudnative-pg/cnpg-playground) | Local learning environment scripts using Docker/Kind. | *(whole repository)* | Leonardo Cecchi (@leonardoce, Maintainer), Marco Nenciarini (@mnencia, Maintainer), Gabriele Bartolini (@gbartolini, Maintainer), Francesco Canovai (@fcanovai, Maintainer), Jeremy Schneider (@ardentperf) | +| [grafana-dashboards](https://github.com/cloudnative-pg/grafana-dashboards) | Standardized Grafana dashboards for monitoring CNPG clusters. | *(whole repository)* | Itay Grudev (@itay-grudev), Philippe Scorsolini (@phisco) | +| [webtest](https://github.com/cloudnative-pg/webtest) | Internal tooling for website and documentation testing. | *(whole repository)* | Leonardo Cecchi (@leonardoce, Maintainer), Marco Nenciarini (@mnencia, Maintainer), Gabriele Bartolini (@gbartolini, Maintainer), Francesco Canovai (@fcanovai, Maintainer), Armando Ruocco (@armru, Maintainer) | diff --git a/subprojects/core-projects.md b/subprojects/core-projects.md new file mode 100644 index 0000000..c4d3305 --- /dev/null +++ b/subprojects/core-projects.md @@ -0,0 +1,28 @@ +# Core Projects + +The operator itself, plus repositories that are effectively its own logic +rather than genuinely independent infrastructure, even though they live in +separate GitHub repositories: `api` and `machinery` are split out for Go +module reasons (see [Supply Chain's "Libraries & Automation"](supply-chain.md#libraries--automation) +for the distinction), and `barman-cloud` is consumed directly by the +operator's own native backup and restore support, not only by the +`plugin-barman-cloud` CNPG-I plugin (see [Extensibility](extensibility.md) +for when that might change). Primarily the maintainers' responsibility; +the folder-scoped rows below are review-routing tags within the +`cloudnative-pg` component, not components of their own (see +[GOVERNANCE.md's Subprojects section](../GOVERNANCE.md#subprojects)). See +the [subprojects index](README.md) for how this fits +into the wider structure, and [GOVERNANCE.md](../GOVERNANCE.md#subprojects) +for how subprojects are defined. + +> See [subprojects/README.md](README.md) for default component ownership +> and this file's own edit rights, both apply here unchanged. + +| Repository | Description | Scope | Owners | +| --- | --- | --- | --- | +| [cloudnative-pg](https://github.com/cloudnative-pg/cloudnative-pg) | The main Kubernetes Operator for PostgreSQL. | Documentation ([`docs/`](https://github.com/cloudnative-pg/cloudnative-pg/tree/main/docs)) | Jaime Silvela (@jsilvela) | +| [cloudnative-pg](https://github.com/cloudnative-pg/cloudnative-pg) | The main Kubernetes Operator for PostgreSQL. | Operator Lifecycle Manager ([`config/olm-*/`](https://github.com/cloudnative-pg/cloudnative-pg/tree/main/config)) | Niccolò Fei (@NiccoloFei) | +| [cloudnative-pg](https://github.com/cloudnative-pg/cloudnative-pg) | The main Kubernetes Operator for PostgreSQL. | Testing ([`.github/`](https://github.com/cloudnative-pg/cloudnative-pg/tree/main/.github), [`hack/`](https://github.com/cloudnative-pg/cloudnative-pg/tree/main/hack), [`tests/`](https://github.com/cloudnative-pg/cloudnative-pg/tree/main/tests); access to additional files might be required) | Niccolò Fei (@NiccoloFei), Tao Li (@litaocdl), Jaime Silvela (@jsilvela) | +| [api](https://github.com/cloudnative-pg/api) | The CloudNativePG API definitions and types. | *(whole repository)* | *(none documented)* | +| [machinery](https://github.com/cloudnative-pg/machinery) | Common Go library for internal logic (extracted from the operator). | *(whole repository)* | *(none documented)* | +| [barman-cloud](https://github.com/cloudnative-pg/barman-cloud) | Go library for interacting with Barman Cloud object stores, used by the operator's native backup support. | *(whole repository)* | *(none documented)* | diff --git a/subprojects/extensibility.md b/subprojects/extensibility.md new file mode 100644 index 0000000..2a10226 --- /dev/null +++ b/subprojects/extensibility.md @@ -0,0 +1,58 @@ +# Extensibility + +The interfaces, modules, and standalone tooling that let CloudNativePG and +PostgreSQL be extended or operated on without changing the operator's core, +including future backup and recovery solutions beyond Barman Cloud, and +Postgres tooling that has nothing to do with Kubernetes at all. See the +[subprojects index](README.md) for how this fits into the wider structure, +and [GOVERNANCE.md](../GOVERNANCE.md#subprojects) for how subprojects are +defined. + +> See [subprojects/README.md](README.md) for default component ownership +> and this file's own edit rights. + +`plugin-barman-cloud` is the template to follow when classifying a new +CNPG-I plugin: + +- The plugin itself (the thing that talks to CNPG) belongs under + "Interface & Plugins (CNPG-I)" below. +- A shared library reused across multiple plugins, and genuinely independent + of any one of them, belongs under + [Supply Chain's "Libraries & Automation"](supply-chain.md#libraries--automation) + instead. +- Anything Postgres-native that isn't delivered as a CNPG-I plugin, whether a + compiled extension/module (like `postgres-keycloak-oauth-validator`) or a + standalone tool or utility that operates on Postgres independent of + Kubernetes, belongs under "PostgreSQL Extensions & Tooling" below. Being + Postgres-native rather than Kubernetes-native is what puts a project here + rather than under Core Projects or Supply Chain. + +`barman-cloud`, the library `plugin-barman-cloud` wraps, doesn't currently +fit the second bullet: it's consumed directly by the operator's own native +backup and restore support, not only by the plugin, so it lives under +[Core Projects](core-projects.md) for now, not here or under Supply Chain. If +native `barman-cloud` support in the operator is ever fully deprecated in +favor of the plugin-only model, it becomes a pure plugin-support library and +should move here (or to Supply Chain, if it's reusable beyond this one +plugin by then). + +## Interface & Plugins (CNPG-I) + +The extensibility layer that allows for custom backups and additional logic. + +| Repository | Description | Scope | Owners | +| --- | --- | --- | --- | +| [cnpg-i](https://github.com/cloudnative-pg/cnpg-i) | The CloudNativePG Interface (CNPG-I) gRPC specification. | *(whole repository)* | Leonardo Cecchi (@leonardoce, Maintainer), Marco Nenciarini (@mnencia, Maintainer), Gabriele Bartolini (@gbartolini, Maintainer), Francesco Canovai (@fcanovai, Maintainer), Armando Ruocco (@armru, Maintainer) | +| [cnpg-i-machinery](https://github.com/cloudnative-pg/cnpg-i-machinery) | Shared Go code for developing CNPG-I compatible plugins. | *(whole repository)* | Leonardo Cecchi (@leonardoce, Maintainer), Marco Nenciarini (@mnencia, Maintainer), Gabriele Bartolini (@gbartolini, Maintainer), Francesco Canovai (@fcanovai, Maintainer), Armando Ruocco (@armru, Maintainer) | +| [plugin-barman-cloud](https://github.com/cloudnative-pg/plugin-barman-cloud) | The reference CNPG-I backup/restore plugin for Barman Cloud. | *(whole repository)* | Leonardo Cecchi (@leonardoce, Maintainer), Marco Nenciarini (@mnencia, Maintainer), Gabriele Bartolini (@gbartolini, Maintainer), Francesco Canovai (@fcanovai, Maintainer), Armando Ruocco (@armru, Maintainer), Niccolò Fei (@NiccoloFei) | +| [cnpg-i-hello-world](https://github.com/cloudnative-pg/cnpg-i-hello-world) | A simplified template/example for building new plugins. | *(whole repository)* | Leonardo Cecchi (@leonardoce, Maintainer), Marco Nenciarini (@mnencia, Maintainer), Gabriele Bartolini (@gbartolini, Maintainer), Francesco Canovai (@fcanovai, Maintainer), Armando Ruocco (@armru, Maintainer) | + +## PostgreSQL Extensions & Tooling + +Software that operates on or with PostgreSQL directly: compiled extensions +and modules, or standalone Postgres-native tools and utilities, independent +of Kubernetes and not delivered as a CNPG-I plugin. + +| Repository | Description | Scope | Owners | +| --- | --- | --- | --- | +| [postgres-keycloak-oauth-validator](https://github.com/cloudnative-pg/postgres-keycloak-oauth-validator) | A PostgreSQL module for OAuth2/Keycloak token validation. | *(whole repository)* | Leonardo Cecchi (@leonardoce, Maintainer), Marco Nenciarini (@mnencia, Maintainer), Gabriele Bartolini (@gbartolini, Maintainer), Francesco Canovai (@fcanovai, Maintainer), Armando Ruocco (@armru, Maintainer), Yoshiyuki Tabata (@y-tabata) | diff --git a/subprojects/supply-chain.md b/subprojects/supply-chain.md new file mode 100644 index 0000000..54da4a3 --- /dev/null +++ b/subprojects/supply-chain.md @@ -0,0 +1,72 @@ +# Supply Chain + +Build, packaging, and testing infrastructure that supports the operator and +its images without being the operator's reconciliation logic itself. See the +[subprojects index](README.md) for how this fits into the wider structure, +and [GOVERNANCE.md](../GOVERNANCE.md#subprojects) for how subprojects are +defined. + +> See [subprojects/README.md](README.md) for default component ownership +> and this file's own edit rights. + +## Distribution + +How the operator and its clusters get to users: Helm charts, generated +manifests and catalogs, and listings in other platforms' marketplaces. + +| Repository | Description | Scope | Owners | +| --- | --- | --- | --- | +| [charts](https://github.com/cloudnative-pg/charts) | Official Helm charts for the operator, database clusters and the Barman Cloud plugin. | *(default, includes the Operator chart, `charts/cloudnative-pg`)* | Francesco Canovai (@fcanovai, Maintainer), Gabriele Bartolini (@gbartolini, Maintainer), Leonardo Cecchi (@leonardoce, Maintainer), Marco Nenciarini (@mnencia, Maintainer), Itay Grudev (@itay-grudev) | +| [charts](https://github.com/cloudnative-pg/charts) | Official Helm charts for the operator, database clusters and the Barman Cloud plugin. | PostgreSQL Cluster Chart ([`charts/cluster`](https://github.com/cloudnative-pg/charts/tree/main/charts/cluster)) | Itay Grudev (@itay-grudev), Philippe Scorsolini (@phisco) | +| [artifacts](https://github.com/cloudnative-pg/artifacts) | Storage for generated manifests, checksums, metadata, and image catalogs. | *(whole repository)* | Leonardo Cecchi (@leonardoce, Maintainer), Marco Nenciarini (@mnencia, Maintainer), Gabriele Bartolini (@gbartolini, Maintainer), Francesco Canovai (@fcanovai, Maintainer), Armando Ruocco (@armru, Maintainer), Niccolò Fei (@NiccoloFei) | +| [community-operators](https://github.com/cloudnative-pg/community-operators) | Fork of the upstream [k8s-operatorhub/community-operators](https://github.com/k8s-operatorhub/community-operators), used only to submit the operator's OperatorHub bundle upstream via PR. | *(whole repository, see note below)* | *(no `CODEOWNERS`, see note below)* | + +> `community-operators` is a fork of an external project, not a +> CloudNativePG-authored codebase, so it doesn't follow the same ownership +> model as the rest of this table: there's no ongoing feature review to gate +> with `CODEOWNERS`, just occasional pushes to update the bundle before +> opening a PR upstream. `@cloudnative-pg/supply-chain-maintainers` still +> needs `Maintain` access to push those updates, but "owns" it only in the +> sense of keeping it in sync, not technical authority over its content +> (that belongs to the upstream project). + +## Container Images + +Standardized images built for security, minimal footprint, and CNPG compatibility. + +| Repository | Description | Scope | Owners | +| --- | --- | --- | --- | +| [postgres-containers](https://github.com/cloudnative-pg/postgres-containers) | Operand images for all community-supported PostgreSQL versions. | *(whole repository)* | Gabriele Bartolini (@gbartolini, Maintainer), Marco Nenciarini (@mnencia, Maintainer), Francesco Canovai (@fcanovai, Maintainer), Niccolò Fei (@NiccoloFei), Tao Li (@litaocdl) | +| [postgres-extensions-containers](https://github.com/cloudnative-pg/postgres-extensions-containers) | Images for community extensions used as pluggable image volumes. | *(default, unlisted extensions)* | Leonardo Cecchi (@leonardoce, Maintainer), Marco Nenciarini (@mnencia, Maintainer), Gabriele Bartolini (@gbartolini, Maintainer), Francesco Canovai (@fcanovai, Maintainer), Armando Ruocco (@armru, Maintainer), Niccolò Fei (@NiccoloFei) | +| [postgres-extensions-containers](https://github.com/cloudnative-pg/postgres-extensions-containers) | Images for community extensions used as pluggable image volumes. | TimescaleDB (OSS) ([`timescaledb-oss/`](https://github.com/cloudnative-pg/postgres-extensions-containers/tree/main/timescaledb-oss)) | Husn E Rabbi (@shusaan) | +| [postgres-extensions-containers](https://github.com/cloudnative-pg/postgres-extensions-containers) | Images for community extensions used as pluggable image volumes. | wal2json ([`wal2json/`](https://github.com/cloudnative-pg/postgres-extensions-containers/tree/main/wal2json)) | @solidDoWant | +| [postgres-extensions-containers](https://github.com/cloudnative-pg/postgres-extensions-containers) | Images for community extensions used as pluggable image volumes. | pg-ivm ([`pg-ivm/`](https://github.com/cloudnative-pg/postgres-extensions-containers/tree/main/pg-ivm)) | Husn E Rabbi (@shusaan) | +| [pgbouncer-containers](https://github.com/cloudnative-pg/pgbouncer-containers) | Optimized images for PgBouncer connection pooling. | *(whole repository)* | Gabriele Bartolini (@gbartolini, Maintainer), Marco Nenciarini (@mnencia, Maintainer), Leonardo Cecchi (@leonardoce, Maintainer), Niccolò Fei (@NiccoloFei), Tao Li (@litaocdl) | +| [postgis-containers](https://github.com/cloudnative-pg/postgis-containers) | PostgreSQL images bundled with PostGIS extensions. | *(whole repository)* | Gabriele Bartolini (@gbartolini, Maintainer), Marco Nenciarini (@mnencia, Maintainer), Leonardo Cecchi (@leonardoce, Maintainer), Francesco Canovai (@fcanovai, Maintainer), Niccolò Fei (@NiccoloFei), Tao Li (@litaocdl) | +| [postgres-trunk-containers](https://github.com/cloudnative-pg/postgres-trunk-containers) | Images built from PostgreSQL `main` branch for early testing. | *(whole repository)* | Niccolò Fei (@NiccoloFei), Francesco Canovai (@fcanovai, Maintainer), Gabriele Bartolini (@gbartolini, Maintainer), Jonathan Battiato (@jbattiato), Tao Li (@litaocdl), Marco Nenciarini (@mnencia, Maintainer) | + +## Libraries & Automation + +Shared, reusable infrastructure consumed by other components, distinct from +the operator's own code even when extracted into a separate repository. Two +things that might look like they belong here don't, today: `api` and +`machinery` are the operator's own logic split out for Go module reasons (see +[Core Projects](core-projects.md)), and `barman-cloud` is still consumed +directly by the operator's own native backup support, not only by the +`plugin-barman-cloud` CNPG-I plugin, so it's under Core Projects too for now +(see [Extensibility](extensibility.md) for when that might change). + +| Repository | Description | Scope | Owners | +| --- | --- | --- | --- | +| [daggerverse](https://github.com/cloudnative-pg/daggerverse) | Dagger modules for portable CI/CD workflows. | *(whole repository)* | Leonardo Cecchi (@leonardoce, Maintainer), Marco Nenciarini (@mnencia, Maintainer), Gabriele Bartolini (@gbartolini, Maintainer), Francesco Canovai (@fcanovai, Maintainer), Niccolò Fei (@NiccoloFei), Jonathan Battiato (@jbattiato) | +| [cnpg-template](https://github.com/cloudnative-pg/cnpg-template) | A template repository for creating new CloudNativePG-related projects. | *(whole repository)* | *(none documented)* | + +## Testing & Automation + +Tools dedicated to CI/CD, resilience testing, and GitHub Actions development. + +| Repository | Description | Scope | Owners | +| --- | --- | --- | --- | +| [ciclops](https://github.com/cloudnative-pg/ciclops) | The Continuous Integration Circular Operations tool for the project. | *(whole repository)* | Jaime Silvela (@jsilvela), Niccolò Fei (@NiccoloFei) | +| [chaos-testing](https://github.com/cloudnative-pg/chaos-testing) | Infrastructure and scripts for running chaos experiments against CNPG. | *(whole repository)* | Gabriele Bartolini (@gbartolini, Maintainer), Marco Nenciarini (@mnencia, Maintainer), Francesco Canovai (@fcanovai, Maintainer), Yash Agarwal (@XploY04) | +| [github-test](https://github.com/cloudnative-pg/github-test) | Playground and testing ground for GitHub Actions and automation workflows. | *(whole repository)* | *(none documented)* | From a9e06f8f58b9ab208009171b4f62d518201909b0 Mon Sep 17 00:00:00 2001 From: Gabriele Bartolini Date: Tue, 4 Aug 2026 15:42:34 +1000 Subject: [PATCH 2/3] docs: reconcile governance model with real cnpg-infra state, add missing org repos Bring dev/67's federated governance model in line with the real GitHub org state produced by a parallel cnpg-infra admin pass, and tidy up naming along the way. - Add `.github` and `cnpg-infra` to the set of repositories administered directly by the Steering Committee, alongside `governance` and `.project` (GOVERNANCE.md prose, embedded diagram, GitHub Project Administration section; subprojects/README.md; MAINTAINERS.md; project-organization.mermaid). - Rewrite this repo's own CODEOWNERS: the `maintainers` team it referenced has been deleted org-wide, and the four subproject-committee teams it referenced never existed until now. All lines fall back to `governance-owners` (Steering-designate files and the default rule) or pair the four real-but-placeholder subproject-committee teams with `admins` (core-maintainers, supply-chain-maintainers, community-ecosystem-maintainers, extensibility-maintainers), since none of the four has been granted repo access yet. - Update subprojects/README.md's GitHub Teams table and transitional note to match: the `maintainers` team is gone, `-owners` teams are real and cnpg-infra-managed today, and the four subproject-committee teams exist with placeholder membership only. - State plainly, in GOVERNANCE.md's Infrastructure Administration section and subprojects/README.md's GitHub Teams section, that all GitHub teams and repository permissions are managed declaratively through the cnpg-infra repository rather than by hand. - Rename the Core Projects subproject to Core (subprojects/core-projects.md -> subprojects/core.md), so its slug matches the existing `core-maintainers` team the same way the other three subprojects already do (-maintainers). - Add the two standalone project-organization.mermaid and contributor-ladder.mermaid diagrams to version control; they were edited earlier in this branch's history but never committed. Refs #67 Signed-off-by: Gabriele Bartolini Assisted-by: Claude --- CODEOWNERS | 32 ++++----- GOVERNANCE.md | 35 ++++++---- MAINTAINERS.md | 10 +-- README.md | 2 +- contributor-ladder.mermaid | 24 +++++++ project-organization.mermaid | 49 +++++++++++++ subprojects/README.md | 83 ++++++++++++++--------- subprojects/{core-projects.md => core.md} | 2 +- subprojects/extensibility.md | 4 +- subprojects/supply-chain.md | 4 +- 10 files changed, 173 insertions(+), 72 deletions(-) create mode 100644 contributor-ladder.mermaid create mode 100644 project-organization.mermaid rename subprojects/{core-projects.md => core.md} (99%) diff --git a/CODEOWNERS b/CODEOWNERS index 4328c50..e600378 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,27 +1,25 @@ # CloudNativePG governance repository CODEOWNERS. # # See GOVERNANCE.md and subprojects/README.md for what these teams are and -# how they roll out. Team slugs referenced here that don't exist yet in the -# GitHub organization fall back to @cloudnative-pg/maintainers, the same -# transitional rule described in subprojects/README.md's GitHub Teams table. - -# Default owners for everything not matched more specifically below. -* @cloudnative-pg/maintainers +# how they roll out. +* @cloudnative-pg/governance-owners @cloudnative-pg/admins # GOVERNANCE.md, MAINTAINERS.md, and CONTRIBUTOR_LADDER.md are Steering # Committee-owned documents (see GOVERNANCE.md's Voting section); until the # Steering Committee and its GitHub team exist, they fall back to the # default rule above. -/GOVERNANCE.md @cloudnative-pg/maintainers -/MAINTAINERS.md @cloudnative-pg/maintainers -/CONTRIBUTOR_LADDER.md @cloudnative-pg/maintainers +/GOVERNANCE.md @cloudnative-pg/governance-owners @cloudnative-pg/admins +/MAINTAINERS.md @cloudnative-pg/governance-owners @cloudnative-pg/admins +/CONTRIBUTOR_LADDER.md @cloudnative-pg/governance-owners @cloudnative-pg/admins # Each subproject's own component listing is scoped to that subproject's -# maintainer committee, so a subproject can update its own listing without -# sign-off from the others. The subprojects index itself stays -# maintainer-wide, since it isn't owned by any single subproject. -/subprojects/README.md @cloudnative-pg/maintainers -/subprojects/core-projects.md @cloudnative-pg/core-maintainers -/subprojects/supply-chain.md @cloudnative-pg/supply-chain-maintainers -/subprojects/community-ecosystem.md @cloudnative-pg/community-ecosystem-maintainers -/subprojects/extensibility.md @cloudnative-pg/extensibility-maintainers +# maintainer committee team, which now exists on GitHub but still has +# placeholder membership and no granted repo access (see note above), so +# `admins` is listed alongside each as a working fallback. The subprojects +# index itself stays on the `governance-owners` fallback, since it isn't +# owned by any single subproject. +/subprojects/README.md @cloudnative-pg/governance-owners @cloudnative-pg/admins +/subprojects/core.md @cloudnative-pg/core-maintainers @cloudnative-pg/admins +/subprojects/supply-chain.md @cloudnative-pg/supply-chain-maintainers @cloudnative-pg/admins +/subprojects/community-ecosystem.md @cloudnative-pg/community-ecosystem-maintainers @cloudnative-pg/admins +/subprojects/extensibility.md @cloudnative-pg/extensibility-maintainers @cloudnative-pg/admins diff --git a/GOVERNANCE.md b/GOVERNANCE.md index e37b24a..85ca340 100644 --- a/GOVERNANCE.md +++ b/GOVERNANCE.md @@ -87,7 +87,7 @@ flowchart TD end subgraph TECH["Technical authority (per person)"] - CPC["Core Projects
Maintainer Committee"] + CPC["Core
Maintainer Committee"] SUC["Supply Chain
Maintainer Committee"] CDC["Community, Docs and Ecosystem
Maintainer Committee"] EXC["Extensibility
Maintainer Committee"] @@ -103,7 +103,7 @@ flowchart TD EXC --> EXR end - GREPO[("governance, .project
administered directly by Steering,
not part of any subproject")] + GREPO[("governance, .project, .github, cnpg-infra
administered directly by Steering,
not part of any subproject")] SC --> GREPO CPC ==>|selects representative| SC @@ -139,7 +139,7 @@ folder, one file per subproject. | Subproject | Groupings (see `subprojects/`) | | :---- | :---- | -| **Core Projects** | [core-projects.md](subprojects/core-projects.md) | +| **Core** | [core.md](subprojects/core.md) | | **Supply Chain** | [supply-chain.md](subprojects/supply-chain.md): Distribution, Container Images, Libraries & Automation, Testing & Automation | | **Community, Docs & Ecosystem** | [community-ecosystem.md](subprojects/community-ecosystem.md) | | **Extensibility** | [extensibility.md](subprojects/extensibility.md): Interface & Plugins (CNPG-I), PostgreSQL Extensions & Tooling | @@ -160,10 +160,16 @@ which does carry subproject-wide access and a subproject-wide vote, is a separate, higher tier built out of established Component Owners; see [CONTRIBUTOR_LADDER.md](CONTRIBUTOR_LADDER.md) for the full progression. -The `governance` and `.project` repositories are not part of any subproject. -Both are a special case, administered directly by the Steering Committee -(`.project` is the standard CNCF project metadata repository that enables -automation from CNCF infrastructure). See +The `governance`, `.project`, `.github`, and `cnpg-infra` repositories are +not part of any subproject. All four are a special case, administered +directly by the Steering Committee (`.project` is the standard CNCF +project metadata repository that enables automation from CNCF +infrastructure; `.github` is GitHub's own org-wide default repository, +holding community health files such as the Code of Conduct and +Contributing guide that other repositories fall back to when they don't +have their own; `cnpg-infra` holds the tooling that manages the org's +GitHub settings, teams, and `CODEOWNERS`, so it is infrastructure for the +organisation itself rather than a subproject deliverable). See [README.md's Governance section](README.md#governance) and the `steering-committee` team in [GitHub Teams](#github-teams-and-communication-channels). @@ -319,7 +325,7 @@ committees. Seats serve 2-year staggered terms. communications, and organizing participation in CNCF/LFX programs (for example mentorship initiatives) and CNCF events - Arbitrating inter-subproject disagreements (for example, a conflict - between Extensibility and Core Projects over CNPG-I plugin framework + between Extensibility and Core over CNPG-I plugin framework direction) - Code of Conduct committee selection and ratification of CoC enforcement decisions @@ -432,8 +438,8 @@ bootstrap. #### GitHub Project Administration (Steering Committee) See [GitHub Teams](#github-teams-and-communication-channels): the `steering-committee` team grants -`Admin` on `governance` and `.project` only, the two repositories Steering -administers directly (see [Subprojects](#subprojects)). +`Admin` on `governance`, `.project`, `.github`, and `cnpg-infra` only, the +four repositories Steering administers directly (see [Subprojects](#subprojects)). ### Subproject Maintainer Committees @@ -616,8 +622,13 @@ GitHub organization administration, and access to sensitive credentials such as CI/CD secrets and cloud accounts used by automation, the same way it is for Security Response, so responsibility survives individual turnover rather than being tied informally to whoever happens to hold `admins` -access today. The Steering Committee may delegate day-to-day execution to -a named Infrastructure Team. +access today. In practice, GitHub team membership and repository +permissions are managed declaratively through the +[`cnpg-infra`](https://github.com/cloudnative-pg/cnpg-infra) repository +rather than by hand, so that access always reflects a committed, +reviewable configuration instead of undocumented manual changes. The +Steering Committee may delegate day-to-day execution to a named +Infrastructure Team. > [!IMPORTANT] > **Open item (needs discussion):** the Infrastructure Team's roster, and how diff --git a/MAINTAINERS.md b/MAINTAINERS.md index 9d785c9..0c54b4d 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -26,7 +26,7 @@ ratified, so the table stays empty until then. ## Core Maintainers The current maintainers of the CloudNativePG project (in alphabetical -order), forming the Core Projects subproject's committee: +order), forming the Core subproject's committee: | Last Name | First Name | Handle | Organization | Component(s) | | --- | --- | --- | --- | --- | @@ -97,10 +97,10 @@ Once ratified, changes to a subproject's committee membership follow the self-selection process in [GOVERNANCE.md's Voting section](GOVERNANCE.md#voting) and are recorded directly in the sections above; they do not require editing GOVERNANCE.md -itself. `governance` and `.project` sit outside this file entirely: both -are administered directly by the Steering Committee (see -[GOVERNANCE.md's Subprojects section](GOVERNANCE.md#subprojects)), not by a -subproject maintainer committee. +itself. `governance`, `.project`, `.github`, and `cnpg-infra` sit outside +this file entirely: all four are administered directly by the Steering +Committee (see [GOVERNANCE.md's Subprojects section](GOVERNANCE.md#subprojects)), not +by a subproject maintainer committee. ## Emeritus Maintainers diff --git a/README.md b/README.md index 61bf022..68bb2a3 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ repository listing, descriptions, and component ownership are kept in the [subprojects/](./subprojects/README.md) folder, one file per subproject, not duplicated here. -- **Core Projects**: the operator itself. +- **Core**: the operator itself. - **Supply Chain**: build, packaging, and testing infrastructure that supports the operator and its images, including how it's distributed to users (Helm charts, manifests, OperatorHub). diff --git a/contributor-ladder.mermaid b/contributor-ladder.mermaid new file mode 100644 index 0000000..25c52b9 --- /dev/null +++ b/contributor-ladder.mermaid @@ -0,0 +1,24 @@ +flowchart TD + CP["Community Participant
engages, no formal tier"] + CT["Contributor
recognized contribution,
no repository access
"] + CO["Component Owner
whole-repo CODEOWNERS,
Write access
"] + SM["Subproject Maintainer
committee seat,
Maintain access subproject-wide
"] + SC["Steering Committee
representative role,
not a ladder rung
"] + + CP --> CT + CT -->|"repo's Component Owners
⅔ majority"| CO + CO -->|"subproject committee
self-selects, simple majority"| SM + SM -.->|"selected as subproject's
representative"| SC + + OM["CNPG Organization Member
anyone holding Component Owner
status or above, on any repository
"] + CO -.- OM + SM -.- OM + OM -.->|"electorate for Community
Representative seats"| SC + + classDef rung fill:#eef4ff,stroke:#3b6fd6,stroke-width:1px,color:#1a1a1a; + classDef rep fill:#fff4e0,stroke:#c9822a,stroke-width:2px,stroke-dasharray:4 3,color:#1a1a1a; + classDef note fill:#f5f5f5,stroke:#999999,stroke-width:1px,color:#333333; + + class CP,CT,CO,SM rung; + class SC rep; + class OM note; diff --git a/project-organization.mermaid b/project-organization.mermaid new file mode 100644 index 0000000..35db9a2 --- /dev/null +++ b/project-organization.mermaid @@ -0,0 +1,49 @@ +flowchart TD + subgraph GOV["Governance authority (org-balanced)"] + SC["Steering Committee
5-7 seats, max 2 per organization"] + CR["Community Representative seat(s)
1-3, elected annually by all
CNPG Organization Members"] + end + + subgraph TECH["Technical authority (per person)"] + CPC["Core
Maintainer Committee"] + SUC["Supply Chain
Maintainer Committee"] + CDC["Community, Docs and Ecosystem
Maintainer Committee"] + EXC["Extensibility
Maintainer Committee"] + + CPR[("Repositories
e.g. cloudnative-pg, api,
barman-cloud")] + SUR[("Repositories
e.g. charts, container images")] + CDR[("Repositories
e.g. docs, website")] + EXR[("Repositories
e.g. cnpg-i, plugin-barman-cloud")] + + CPC --> CPR + SUC --> SUR + CDC --> CDR + EXC --> EXR + end + + GREPO[("governance, .project, .github, cnpg-infra
administered directly by Steering,
not part of any subproject")] + SC --> GREPO + + CPC ==>|selects representative| SC + SUC ==>|selects representative| SC + CDC ==>|selects representative| SC + EXC ==>|selects representative| SC + CR -.-> SC + + SC -.->|"backstop: removes a stuck
committee member,
plain majority, per person"| CPC + SC -.-> SUC + SC -.-> CDC + SC -.-> EXC + + CPC -.->|"backstop: stalled repo or
too few Component Owners"| CPR + SUC -.-> SUR + CDC -.-> CDR + EXC -.-> EXR + + classDef gov fill:#fff4e0,stroke:#c9822a,stroke-width:2px,color:#1a1a1a; + classDef committee fill:#eef4ff,stroke:#3b6fd6,stroke-width:1px,color:#1a1a1a; + classDef repo fill:#eef9ee,stroke:#3a8a4d,stroke-width:1px,color:#1a1a1a; + + class SC,CR gov; + class CPC,SUC,CDC,EXC committee; + class CPR,SUR,CDR,EXR,GREPO repo; diff --git a/subprojects/README.md b/subprojects/README.md index a25a011..9d95975 100644 --- a/subprojects/README.md +++ b/subprojects/README.md @@ -25,7 +25,7 @@ choice, not a promotion, so it carries no vote and no CNPG Organization Member status (see [CONTRIBUTOR_LADDER.md's Component Owner section](../CONTRIBUTOR_LADDER.md#component-owner)). -- [Core Projects](core-projects.md) +- [Core](core.md) - [Supply Chain](supply-chain.md) - [Community, Docs & Ecosystem](community-ecosystem.md) - [Extensibility](extensibility.md) @@ -36,9 +36,12 @@ own maintainer committee, via the corresponding [GitHub Team](#github-teams); each file's Owners column lists only individuals or teams named explicitly in that repository's own `CODEOWNERS` file, in addition to the committee. -The `governance` and `.project` repositories are not listed in any of these: -neither is part of any subproject; see -[README.md's Governance section](../README.md#governance). +The `governance`, `.project`, `.github`, and `cnpg-infra` repositories are +not listed in any of these: none is part of any subproject; see +[README.md's Governance section](../README.md#governance). `cnpg-infra` +holds the org's admin tooling (repo settings, teams, CODEOWNERS): Steering/ +CNCF-owned infrastructure for the org itself, same as the other three, not +a subproject deliverable. Reorganizing which component belongs to which subproject, adding a new grouping within a subproject file, or moving a component between groupings is @@ -46,47 +49,63 @@ a routine editorial change to the relevant `subprojects/*.md` file and does not require a governance vote; adding, removing, or renaming a subproject itself does (see [GOVERNANCE.md's Voting section](../GOVERNANCE.md#voting)). Each `subprojects/*.md` file, other than this index, is scoped in -`CODEOWNERS` to its own subproject's maintainer committee (see -[CODEOWNERS](../CODEOWNERS)), so a subproject can update its own component -listing without needing sign-off from the others. This index stays scoped -to `@cloudnative-pg/maintainers`, since it isn't owned by any single -subproject. +`CODEOWNERS` to its own subproject's maintainer committee team (see +[CODEOWNERS](../CODEOWNERS)), so that a subproject can eventually update +its own component listing without needing sign-off from the others. Those +four teams now exist on GitHub, but their membership is still a +placeholder (all four currently mirror `admins`, not a ratified +per-committee roster) and none has been granted repo access yet, so each +line also lists `@cloudnative-pg/admins` as a working fallback until +that's sorted out. This index itself stays on the `@cloudnative-pg/governance-owners` +fallback permanently, since it isn't owned by any single subproject. ## GitHub Teams Team membership on GitHub is only visible to other members of the organization, never to the public. [MAINTAINERS.md](../MAINTAINERS.md) and this folder are, and stay, the public source of truth; GitHub Teams exist -only to *enforce* what those files already say. Names are fixed below so -nobody invents an ad hoc team when a repo is created or a subproject rolls -out. +only to *enforce* what those files already say. All GitHub teams and +repository permissions across the organization, including every team +listed below, are managed declaratively through the +[`cnpg-infra`](https://github.com/cloudnative-pg/cnpg-infra) repository's +scripts and config files, not created or edited by hand on GitHub. Names +are fixed below so nobody invents an ad hoc team when a repo is created or +a subproject rolls out. | Team (GitHub slug) | Grants | Access | | :---- | :---- | :---- | -| `maintainers` (existing) | Current maintainers, until subproject teams below are rolled out | `Maintain` on every repository | +| `-owners` (existing, per repository, e.g. `governance-owners`) | That repository's real `CODEOWNERS` owners, managed via `cnpg-infra` | Repository-scoped, per `cnpg-infra`'s `repo-tiers.yaml` | | `admins` (existing) | Maintainers with org-administration duties | `Admin` on every repository | -| `steering-committee` | Steering Committee | `Admin` on `governance` and `.project` only, the two repositories Steering administers directly; Steering doesn't own code review, merge, or release, so it doesn't need repo-wide access elsewhere | -| `core-maintainers` | Core Projects committee | `Maintain` on the [Core Projects](core-projects.md) repositories | -| `supply-chain-maintainers` | Supply Chain committee | `Maintain` on the [Supply Chain](supply-chain.md) repositories | -| `community-ecosystem-maintainers` | Community, Docs & Ecosystem committee | `Maintain` on the [Community, Docs & Ecosystem](community-ecosystem.md) repositories | -| `extensibility-maintainers` | Extensibility committee | `Maintain` on the [Extensibility](extensibility.md) repositories | +| `steering-committee` | Steering Committee | `Admin` on `governance`, `.project`, `.github`, and `cnpg-infra` only, the four repositories Steering administers directly; Steering doesn't own code review, merge, or release, so it doesn't need repo-wide access elsewhere | +| `core-maintainers` (existing, placeholder membership) | Core committee | Not yet granted; target is `Maintain` on the [Core](core.md) repositories | +| `supply-chain-maintainers` (existing, placeholder membership) | Supply Chain committee | Not yet granted; target is `Maintain` on the [Supply Chain](supply-chain.md) repositories | +| `community-ecosystem-maintainers` (existing, placeholder membership) | Community, Docs & Ecosystem committee | Not yet granted; target is `Maintain` on the [Community, Docs & Ecosystem](community-ecosystem.md) repositories | +| `extensibility-maintainers` (existing, placeholder membership) | Extensibility committee | Not yet granted; target is `Maintain` on the [Extensibility](extensibility.md) repositories | Team membership must mirror the rosters in MAINTAINERS.md; when a roster -changes, any maintainer with organization-admin access updates the -corresponding team to match. Set new teams to "Visible" within the -organization for internal clarity; this does not make membership public, it -only helps other maintainers and component owners see who's on which team. +changes, that change is made in `cnpg-infra`'s config and applied from +there, not by editing a team's membership directly on GitHub. Set new +teams to "Visible" within the organization for internal clarity; this does +not make membership public, it only helps other maintainers and component +owners see who's on which team. > [!IMPORTANT] -> **Transitional, to be removed once rollout completes:** subproject teams -> roll out gradually as each subproject's maintainer committee is formalized -> (tracked separately); until a given subproject's team exists, `maintainers` -> continues to hold `Maintain` on its repositories, unchanged from today. If -> the number of teams grows significantly, consider a declarative "teams as -> code" tool that reconciles actual GitHub org/team state against a committed -> config file (Kubernetes' [peribolos](https://github.com/kubernetes-sigs/prow/tree/main/cmd/peribolos) -> is the standard precedent), but that's more tooling than six teams need -> right now. +> **Transitional, to be removed once rollout completes:** the org-wide +> `maintainers` team has already been deleted (superseded by the per-repo +> `-owners` teams above, which `cnpg-infra` already provisions and +> syncs today via `scripts/sync-project-owner-teams.sh` and +> `repo-tiers.yaml`'s `owners:` field). Subproject-committee teams +> (`core-maintainers` and the other three) are a separate, coarser-grained +> concept this document proposes on top of that per-repo layer. All four now +> exist on GitHub, but with placeholder membership only (mirroring `admins`, +> not a ratified per-committee roster; tracked in `cnpg-infra/org-policy.yaml`'s +> `subproject_committees` section, edited by hand rather than auto-synced) +> and no granted repo access, so `CODEOWNERS` lists `admins` alongside each +> as a working fallback. Update team membership and grant real repo access +> once dev/67 ratifies and each committee has a real roster; `cnpg-infra` +> already reconciles GitHub team state against a committed config +> declaratively, which covers the "teams as code" need noted in an earlier +> draft of this note. ## Communication Channels @@ -97,7 +116,7 @@ Slack channel map onto each other without guessing. | Channel | Maps to | | :---- | :---- | -| `cloudnativepg-core-maintainers` (renamed from `cloudnativepg-maintainers`) | Core Projects committee | +| `cloudnativepg-core-maintainers` (renamed from `cloudnativepg-maintainers`) | Core committee | | `cloudnativepg-supply-chain-maintainers` | Supply Chain committee | | `cloudnativepg-community-ecosystem-maintainers` | Community, Docs & Ecosystem committee | | `cloudnativepg-extensibility-maintainers` | Extensibility committee | diff --git a/subprojects/core-projects.md b/subprojects/core.md similarity index 99% rename from subprojects/core-projects.md rename to subprojects/core.md index c4d3305..c33a7bb 100644 --- a/subprojects/core-projects.md +++ b/subprojects/core.md @@ -1,4 +1,4 @@ -# Core Projects +# Core The operator itself, plus repositories that are effectively its own logic rather than genuinely independent infrastructure, even though they live in diff --git a/subprojects/extensibility.md b/subprojects/extensibility.md index 2a10226..ba4fd5f 100644 --- a/subprojects/extensibility.md +++ b/subprojects/extensibility.md @@ -25,12 +25,12 @@ CNPG-I plugin: standalone tool or utility that operates on Postgres independent of Kubernetes, belongs under "PostgreSQL Extensions & Tooling" below. Being Postgres-native rather than Kubernetes-native is what puts a project here - rather than under Core Projects or Supply Chain. + rather than under Core or Supply Chain. `barman-cloud`, the library `plugin-barman-cloud` wraps, doesn't currently fit the second bullet: it's consumed directly by the operator's own native backup and restore support, not only by the plugin, so it lives under -[Core Projects](core-projects.md) for now, not here or under Supply Chain. If +[Core](core.md) for now, not here or under Supply Chain. If native `barman-cloud` support in the operator is ever fully deprecated in favor of the plugin-only model, it becomes a pure plugin-support library and should move here (or to Supply Chain, if it's reusable beyond this one diff --git a/subprojects/supply-chain.md b/subprojects/supply-chain.md index 54da4a3..a3ab761 100644 --- a/subprojects/supply-chain.md +++ b/subprojects/supply-chain.md @@ -51,9 +51,9 @@ Shared, reusable infrastructure consumed by other components, distinct from the operator's own code even when extracted into a separate repository. Two things that might look like they belong here don't, today: `api` and `machinery` are the operator's own logic split out for Go module reasons (see -[Core Projects](core-projects.md)), and `barman-cloud` is still consumed +[Core](core.md)), and `barman-cloud` is still consumed directly by the operator's own native backup support, not only by the -`plugin-barman-cloud` CNPG-I plugin, so it's under Core Projects too for now +`plugin-barman-cloud` CNPG-I plugin, so it's under Core too for now (see [Extensibility](extensibility.md) for when that might change). | Repository | Description | Scope | Owners | From d76677287220076498b5ffc227a2ebcdb6eaee62 Mon Sep 17 00:00:00 2001 From: Gabriele Bartolini Date: Mon, 17 Aug 2026 12:45:37 +1000 Subject: [PATCH 3/3] docs: sync dev/67 with cnpg-infra state, add LFID requirement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reconcile the federated governance draft against everything cnpg-infra's real, current config has changed since the last sync (a9e06f8), and add a new requirement raised by .project's LFID mandate. Ownership/roster sync (real CODEOWNERS/repo-tiers.yaml state): - Add `klio`, a real repo entirely missing from any subprojects/*.md listing, to extensibility.md's Interface & Plugins (CNPG-I) table and to MAINTAINERS.md's Extensibility committee (Francesco Canovai, Leonardo Cecchi, and two individuals new to this document, Gabriele Quaresima/@gabriele-wolfox and @GabriFedi97). - Reflect Jaime Silvela's reduced ownership (cnpg-infra#7): drop him from cloudnative-pg's Documentation and Testing scopes (core.md), from cloudnative-pg.github.io (community-ecosystem.md), and from the Community, Docs & Ecosystem Maintainers table; he keeps `ciclops`. - Add @GabriFedi97 to postgres-extensions-containers' owners (supply-chain.md, MAINTAINERS.md) and to Supply Chain Maintainers, matching componentowners-policy.yaml's own note that this was missing. - Add Armando Ruocco to cnpg-playground, Francesco Canovai to pgbouncer-containers, and Leonardo Cecchi to postgres-trunk-containers — plain omissions against repo-tiers.yaml's real owners lists. - Correct webtest's description to match its real GitHub description (a PostgreSQL stress tool, not website/doc test tooling) — repo-tiers.yaml flagged this as "confirmed wrong by Gabriele." Structural fix: - Reclassify `cnpg-template` from Supply Chain to the Steering-administered org-control group (alongside governance, .project, .github, cnpg-infra), per repo-tiers.yaml's own note that this was "a real discrepancy with governance worth reconciling there." Updates GOVERNANCE.md (prose, embedded diagram, GitHub Project Administration), the standalone project-organization.mermaid, subprojects/README.md, MAINTAINERS.md, and README.md — the last of which was still only listing `governance` and `.project` as the special case, predating even the .github/cnpg-infra addition from the previous sync. - Add a note to GOVERNANCE.md's "Proposing a New Component" section that onboarding an accepted repo is now automated end-to-end by cnpg-infra's create-new-repo.sh. New requirement: Linux Foundation ID (LFID) - Add a "Determining Organizational Affiliation" subsection to GOVERNANCE.md, next to Organizational Cap Enforcement: every Maintainer, Component Owner, and Steering Committee member must hold an LFID with their correct, current employer, since that's what the 2-per-organization cap and org-balanced voting actually rely on to determine "organization" — not self-reporting. MAINTAINERS.md's Organization column is sourced from this record, not entered independently. - Add the same requirement to CONTRIBUTOR_LADDER.md's CNPG Organization Member section, and a pointer note to MAINTAINERS.md explaining that a blank Organization cell means a missing LFID record, not a real gap. - Flagged as an open item: .project's maintainers.yaml doesn't carry LFID/organization data yet today, so this is the mechanism proposed, not something already in place. Refs #67 Signed-off-by: Gabriele Bartolini Assisted-by: Claude --- CONTRIBUTOR_LADDER.md | 10 ++++ GOVERNANCE.md | 73 ++++++++++++++++++++++++------ MAINTAINERS.md | 24 +++++++--- README.md | 10 ++-- project-organization.mermaid | 2 +- subprojects/README.md | 20 +++++--- subprojects/community-ecosystem.md | 14 ++++-- subprojects/core.md | 9 +++- subprojects/extensibility.md | 5 +- subprojects/supply-chain.md | 13 ++++-- 10 files changed, 138 insertions(+), 42 deletions(-) diff --git a/CONTRIBUTOR_LADDER.md b/CONTRIBUTOR_LADDER.md index 3278e77..91b0ff5 100644 --- a/CONTRIBUTOR_LADDER.md +++ b/CONTRIBUTOR_LADDER.md @@ -168,6 +168,16 @@ plain "organization" is used throughout these documents to mean the employer an individual works for (for org-balanced voting), and this term should never be confused with that. +Holding CNPG Organization Member status, from Component Owner upward, +requires a Linux Foundation ID (LFID) that correctly states that +person's current employer, kept up to date in +[`.project`](https://github.com/cloudnative-pg/.project)'s +`maintainers.yaml`. This is what makes an individual's "organization" for +org-balanced voting and the [Steering seat cap](GOVERNANCE.md#organizational-cap-enforcement) +a verifiable record rather than a self-report; see +[GOVERNANCE.md's Determining Organizational Affiliation section](GOVERNANCE.md#determining-organizational-affiliation) +for why this matters and what breaks if it drifts. + ## Component Owner Component Owners are tasked with the development of an entire component diff --git a/GOVERNANCE.md b/GOVERNANCE.md index 85ca340..a8f8965 100644 --- a/GOVERNANCE.md +++ b/GOVERNANCE.md @@ -103,7 +103,7 @@ flowchart TD EXC --> EXR end - GREPO[("governance, .project, .github, cnpg-infra
administered directly by Steering,
not part of any subproject")] + GREPO[("governance, .project, .github,
cnpg-infra, cnpg-template
administered directly by Steering,
not part of any subproject")] SC --> GREPO CPC ==>|selects representative| SC @@ -160,16 +160,23 @@ which does carry subproject-wide access and a subproject-wide vote, is a separate, higher tier built out of established Component Owners; see [CONTRIBUTOR_LADDER.md](CONTRIBUTOR_LADDER.md) for the full progression. -The `governance`, `.project`, `.github`, and `cnpg-infra` repositories are -not part of any subproject. All four are a special case, administered -directly by the Steering Committee (`.project` is the standard CNCF -project metadata repository that enables automation from CNCF -infrastructure; `.github` is GitHub's own org-wide default repository, -holding community health files such as the Code of Conduct and -Contributing guide that other repositories fall back to when they don't -have their own; `cnpg-infra` holds the tooling that manages the org's -GitHub settings, teams, and `CODEOWNERS`, so it is infrastructure for the -organisation itself rather than a subproject deliverable). See +The `governance`, `.project`, `.github`, `cnpg-infra`, and `cnpg-template` +repositories are not part of any subproject. All five are a special case, +administered directly by the Steering Committee (`.project` is the +standard CNCF project metadata repository that enables automation from +CNCF infrastructure; `.github` is GitHub's own org-wide default +repository, holding community health files such as the Code of Conduct +and Contributing guide that other repositories fall back to when they +don't have their own; `cnpg-infra` holds the tooling that manages the +org's GitHub settings, teams, and `CODEOWNERS`, so it is infrastructure +for the organisation itself rather than a subproject deliverable; +`cnpg-template` is the template every new org repository, including the +other four org-control repositories themselves, is created from, which +makes it organisation tooling rather than any one subproject's +deliverable — it was previously misclassified under Supply Chain in +[supply-chain.md](subprojects/supply-chain.md), a discrepancy identified +while reconciling this document against `cnpg-infra`'s real, current +config). See [README.md's Governance section](README.md#governance) and the `steering-committee` team in [GitHub Teams](#github-teams-and-communication-channels). @@ -222,6 +229,15 @@ subproject rather than creating a new one. If the proposal doesn't fit any existing subproject, it's escalated to the Steering Committee as a request to add a new subproject instead. +Once accepted, the mechanical work of onboarding a genuinely new +repository — creating it on GitHub from `cnpg-template`, registering it +with a settings baseline and a dedicated `-owners` team, and +rendering its real `CODEOWNERS` — is automated end-to-end by +[`cnpg-infra`](https://github.com/cloudnative-pg/cnpg-infra)'s +`create-new-repo.sh` (see [Infrastructure Administration](#infrastructure-administration)), +not done by hand. This is tooling that executes a decision already made +above; it has no bearing on who gets to make that decision. + A component that becomes inactive, or stops meeting the project's basic health expectations (security response, Code of Conduct compliance, maintained CI), may be archived by the same committee vote, removing it @@ -435,11 +451,42 @@ bootstrap. committee-selected seat is refilled by that subproject's committee selecting a new representative. +#### Determining Organizational Affiliation + +Every enforcement mechanism above — the 2-per-organization Steering cap, +org-balanced voting (see [Organization-level decisions](#organization-level-decisions)), +and the affiliation-change rule just above — depends on knowing, reliably, +which organization an individual actually belongs to. That determination +is not self-reported: it is each individual's Linux Foundation ID (LFID), +which every Maintainer, Component Owner, and Steering Committee member +must hold and keep current with their correct, present employer. The LFID +record lives in the [`.project`](https://github.com/cloudnative-pg/.project) +repository's `maintainers.yaml`, the same record CNCF's own tooling reads; +[MAINTAINERS.md](MAINTAINERS.md)'s Organization column is sourced from it, +not entered independently, so the two are not two competing records to +reconcile by hand. An LFID that lists the wrong company, or none at all, +doesn't just miss a formality: it can silently understate an +organization's real seat count and break the cap this section exists to +enforce. Registering, or correcting, an LFID is therefore a precondition +of holding a Steering seat or a Subproject Maintainer seat, or of casting +an org-balanced vote as a [CNPG Organization Member](CONTRIBUTOR_LADDER.md#cnpg-organization-member), +not paperwork to catch up on afterward. + +> [!IMPORTANT] +> **Open item (needs discussion):** `maintainers.yaml` as it exists in +> `.project` today only lists GitHub handles, with no LFID or +> organization field populated yet; several individuals across +> [MAINTAINERS.md](MAINTAINERS.md)'s tables also have a blank +> Organization cell for the same reason. Populating both is tracked as a +> follow-up to this proposal, not a blocker to ratifying the mechanism +> above. + #### GitHub Project Administration (Steering Committee) See [GitHub Teams](#github-teams-and-communication-channels): the `steering-committee` team grants -`Admin` on `governance`, `.project`, `.github`, and `cnpg-infra` only, the -four repositories Steering administers directly (see [Subprojects](#subprojects)). +`Admin` on `governance`, `.project`, `.github`, `cnpg-infra`, and +`cnpg-template` only, the five repositories Steering administers directly +(see [Subprojects](#subprojects)). ### Subproject Maintainer Committees diff --git a/MAINTAINERS.md b/MAINTAINERS.md index 0c54b4d..8ff9993 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -45,6 +45,7 @@ order), forming the Core subproject's committee: | Battiato | Jonathan | @jbattiato | EDB | daggerverse, postgres-trunk-containers | | Canovai | Francesco | @fcanovai | EDB | charts, artifacts, postgres-containers, postgres-extensions-containers, postgis-containers, postgres-trunk-containers, daggerverse, chaos-testing | | Cecchi | Leonardo | @leonardoce | EDB | charts, artifacts, postgres-extensions-containers, pgbouncer-containers, postgis-containers, daggerverse | +| Fedi | Gabriele | @GabriFedi97 | | postgres-extensions-containers | | Fei | Niccolò | @NiccoloFei | EDB | artifacts, postgres-containers, postgres-extensions-containers, pgbouncer-containers, postgis-containers, postgres-trunk-containers, daggerverse, ciclops | | Grudev | Itay | @itay-grudev | | charts | | Li | Tao | @litaocdl | EDB | postgres-containers, pgbouncer-containers, postgis-containers, postgres-trunk-containers | @@ -66,10 +67,9 @@ their ownership of components in those subprojects instead. | Drees | Floor | @FloorD | EDB | cloudnative-pg.github.io | | Grudev | Itay | @itay-grudev | | grafana-dashboards | | Nenciarini | Marco | @mnencia | EDB | docs, cloudnative-pg.github.io, cnpg-playground, webtest | -| Ruocco | Armando | @armru | EDB | webtest | +| Ruocco | Armando | @armru | EDB | webtest, cnpg-playground | | Saxena | Anushka | @SaxenaAnushka102 | | docs | | Schneider | Jeremy | @ardentperf | GEICO | cnpg-playground | -| Silvela | Jaime | @jsilvela | | cloudnative-pg.github.io | > [!IMPORTANT] > **Open item (needs discussion):** **Philippe Scorsolini** holds whole-repo @@ -86,10 +86,12 @@ their ownership of components in those subprojects instead. | Last Name | First Name | Handle | Organization | Component(s) | | --- | --- | --- | --- | --- | | Bartolini | Gabriele | @gbartolini | EDB | cnpg-i, cnpg-i-machinery, plugin-barman-cloud, cnpg-i-hello-world, postgres-keycloak-oauth-validator | -| Canovai | Francesco | @fcanovai | EDB | cnpg-i, cnpg-i-machinery, plugin-barman-cloud, cnpg-i-hello-world, postgres-keycloak-oauth-validator | -| Cecchi | Leonardo | @leonardoce | EDB | cnpg-i, cnpg-i-machinery, plugin-barman-cloud, cnpg-i-hello-world, postgres-keycloak-oauth-validator | +| Canovai | Francesco | @fcanovai | EDB | cnpg-i, cnpg-i-machinery, plugin-barman-cloud, cnpg-i-hello-world, postgres-keycloak-oauth-validator, klio | +| Cecchi | Leonardo | @leonardoce | EDB | cnpg-i, cnpg-i-machinery, plugin-barman-cloud, cnpg-i-hello-world, postgres-keycloak-oauth-validator, klio | +| Fedi | Gabriele | @GabriFedi97 | | klio | | Fei | Niccolò | @NiccoloFei | EDB | plugin-barman-cloud | | Nenciarini | Marco | @mnencia | EDB | cnpg-i, cnpg-i-machinery, plugin-barman-cloud, cnpg-i-hello-world, postgres-keycloak-oauth-validator | +| Quaresima | Gabriele | @gabriele-wolfox | | klio | | Ruocco | Armando | @armru | EDB | cnpg-i, cnpg-i-machinery, plugin-barman-cloud, cnpg-i-hello-world, postgres-keycloak-oauth-validator | | Tabata | Yoshiyuki | @y-tabata | Hitachi | postgres-keycloak-oauth-validator | @@ -97,11 +99,19 @@ Once ratified, changes to a subproject's committee membership follow the self-selection process in [GOVERNANCE.md's Voting section](GOVERNANCE.md#voting) and are recorded directly in the sections above; they do not require editing GOVERNANCE.md -itself. `governance`, `.project`, `.github`, and `cnpg-infra` sit outside -this file entirely: all four are administered directly by the Steering -Committee (see [GOVERNANCE.md's Subprojects section](GOVERNANCE.md#subprojects)), not +itself. `governance`, `.project`, `.github`, `cnpg-infra`, and +`cnpg-template` sit outside this file entirely: all five are administered +directly by the Steering Committee (see [GOVERNANCE.md's Subprojects section](GOVERNANCE.md#subprojects)), not by a subproject maintainer committee. +Every Organization cell above must match the individual's registered +Linux Foundation ID (LFID), the record `.project`'s `maintainers.yaml` +and CNCF's own tooling read — see +[GOVERNANCE.md's Determining Organizational Affiliation section](GOVERNANCE.md#determining-organizational-affiliation). +A blank cell above means that person's LFID/employer isn't on file yet, +not that they're unaffiliated; filling these in is tracked as a follow-up +to this proposal, not a blocker to ratifying it. + ## Emeritus Maintainers The following individuals have previously served as maintainers and are diff --git a/README.md b/README.md index 68bb2a3..13fbc9d 100644 --- a/README.md +++ b/README.md @@ -22,15 +22,19 @@ project: ## Governance -The `governance` and `.project` repositories are a special case: neither is -part of any subproject, and both are administered directly by the Steering -Committee (see [GOVERNANCE.md's GitHub Teams section](./GOVERNANCE.md#github-teams-and-communication-channels)), +The `governance`, `.project`, `.github`, `cnpg-infra`, and `cnpg-template` +repositories are a special case: none is part of any subproject, and all +five are administered directly by the Steering Committee (see +[GOVERNANCE.md's GitHub Teams section](./GOVERNANCE.md#github-teams-and-communication-channels)), not by a subproject maintainer committee. | Repository | Description | | --- | --- | | [governance](https://github.com/cloudnative-pg/governance) | Central hub for project policies, AI policy, and general guidelines. | | [.project](https://github.com/cloudnative-pg/.project) | The standard CNCF project metadata repository, enabling automation from CNCF infrastructure. | +| [.github](https://github.com/cloudnative-pg/.github) | GitHub's own org-wide default repository: profile page and default community health files (Code of Conduct, Contributing guide). | +| [cnpg-infra](https://github.com/cloudnative-pg/cnpg-infra) | Admin tooling that manages the org's GitHub settings, teams, and `CODEOWNERS` declaratively. | +| [cnpg-template](https://github.com/cloudnative-pg/cnpg-template) | The template every new org repository, including the other four above, is created from. | ## Repositories diff --git a/project-organization.mermaid b/project-organization.mermaid index 35db9a2..83478e6 100644 --- a/project-organization.mermaid +++ b/project-organization.mermaid @@ -21,7 +21,7 @@ flowchart TD EXC --> EXR end - GREPO[("governance, .project, .github, cnpg-infra
administered directly by Steering,
not part of any subproject")] + GREPO[("governance, .project, .github,
cnpg-infra, cnpg-template
administered directly by Steering,
not part of any subproject")] SC --> GREPO CPC ==>|selects representative| SC diff --git a/subprojects/README.md b/subprojects/README.md index 9d95975..542a7ff 100644 --- a/subprojects/README.md +++ b/subprojects/README.md @@ -36,12 +36,18 @@ own maintainer committee, via the corresponding [GitHub Team](#github-teams); each file's Owners column lists only individuals or teams named explicitly in that repository's own `CODEOWNERS` file, in addition to the committee. -The `governance`, `.project`, `.github`, and `cnpg-infra` repositories are -not listed in any of these: none is part of any subproject; see -[README.md's Governance section](../README.md#governance). `cnpg-infra` -holds the org's admin tooling (repo settings, teams, CODEOWNERS): Steering/ -CNCF-owned infrastructure for the org itself, same as the other three, not -a subproject deliverable. +The `governance`, `.project`, `.github`, `cnpg-infra`, and `cnpg-template` +repositories are not listed in any of these: none is part of any +subproject; see [README.md's Governance section](../README.md#governance). +`cnpg-infra` holds the org's admin tooling (repo settings, teams, +CODEOWNERS); `cnpg-template` is the template every new repository in the +org, including the other org-control repositories, is created from. Both +are Steering/CNCF-owned infrastructure for the org itself, same as the +other three, not a subproject deliverable. `cnpg-template` was previously +listed under Supply Chain in [supply-chain.md](supply-chain.md); that was +a discrepancy against `cnpg-infra`'s real, current classification, fixed +here as a routine editorial move rather than something requiring a vote +(see [GOVERNANCE.md's Subprojects section](../GOVERNANCE.md#subprojects)). Reorganizing which component belongs to which subproject, adding a new grouping within a subproject file, or moving a component between groupings is @@ -76,7 +82,7 @@ a subproject rolls out. | :---- | :---- | :---- | | `-owners` (existing, per repository, e.g. `governance-owners`) | That repository's real `CODEOWNERS` owners, managed via `cnpg-infra` | Repository-scoped, per `cnpg-infra`'s `repo-tiers.yaml` | | `admins` (existing) | Maintainers with org-administration duties | `Admin` on every repository | -| `steering-committee` | Steering Committee | `Admin` on `governance`, `.project`, `.github`, and `cnpg-infra` only, the four repositories Steering administers directly; Steering doesn't own code review, merge, or release, so it doesn't need repo-wide access elsewhere | +| `steering-committee` | Steering Committee | `Admin` on `governance`, `.project`, `.github`, `cnpg-infra`, and `cnpg-template` only, the five repositories Steering administers directly; Steering doesn't own code review, merge, or release, so it doesn't need repo-wide access elsewhere | | `core-maintainers` (existing, placeholder membership) | Core committee | Not yet granted; target is `Maintain` on the [Core](core.md) repositories | | `supply-chain-maintainers` (existing, placeholder membership) | Supply Chain committee | Not yet granted; target is `Maintain` on the [Supply Chain](supply-chain.md) repositories | | `community-ecosystem-maintainers` (existing, placeholder membership) | Community, Docs & Ecosystem committee | Not yet granted; target is `Maintain` on the [Community, Docs & Ecosystem](community-ecosystem.md) repositories | diff --git a/subprojects/community-ecosystem.md b/subprojects/community-ecosystem.md index 85b06bc..ce617ee 100644 --- a/subprojects/community-ecosystem.md +++ b/subprojects/community-ecosystem.md @@ -12,7 +12,15 @@ for how subprojects are defined. | Repository | Description | Scope | Owners | | --- | --- | --- | --- | | [docs](https://github.com/cloudnative-pg/docs) | The documentation project and Hugo source for the operator docs. | *(whole repository)* | Leonardo Cecchi (@leonardoce, Maintainer), Marco Nenciarini (@mnencia, Maintainer), Gabriele Bartolini (@gbartolini, Maintainer), Francesco Canovai (@fcanovai, Maintainer), Anushka Saxena (@SaxenaAnushka102) | -| [cloudnative-pg.github.io](https://github.com/cloudnative-pg/cloudnative-pg.github.io) | The main project landing page/website. | *(whole repository)* | Gabriele Bartolini (@gbartolini, Maintainer), Jaime Silvela (@jsilvela), Floor Drees (@FloorD), Marco Nenciarini (@mnencia, Maintainer), Leonardo Cecchi (@leonardoce, Maintainer) | -| [cnpg-playground](https://github.com/cloudnative-pg/cnpg-playground) | Local learning environment scripts using Docker/Kind. | *(whole repository)* | Leonardo Cecchi (@leonardoce, Maintainer), Marco Nenciarini (@mnencia, Maintainer), Gabriele Bartolini (@gbartolini, Maintainer), Francesco Canovai (@fcanovai, Maintainer), Jeremy Schneider (@ardentperf) | +| [cloudnative-pg.github.io](https://github.com/cloudnative-pg/cloudnative-pg.github.io) | The main project landing page/website. | *(whole repository)* | Gabriele Bartolini (@gbartolini, Maintainer), Floor Drees (@FloorD), Marco Nenciarini (@mnencia, Maintainer), Leonardo Cecchi (@leonardoce, Maintainer) | +| [cnpg-playground](https://github.com/cloudnative-pg/cnpg-playground) | Local learning environment scripts using Docker/Kind. | *(whole repository)* | Leonardo Cecchi (@leonardoce, Maintainer), Marco Nenciarini (@mnencia, Maintainer), Gabriele Bartolini (@gbartolini, Maintainer), Francesco Canovai (@fcanovai, Maintainer), Armando Ruocco (@armru, Maintainer), Jeremy Schneider (@ardentperf) | | [grafana-dashboards](https://github.com/cloudnative-pg/grafana-dashboards) | Standardized Grafana dashboards for monitoring CNPG clusters. | *(whole repository)* | Itay Grudev (@itay-grudev), Philippe Scorsolini (@phisco) | -| [webtest](https://github.com/cloudnative-pg/webtest) | Internal tooling for website and documentation testing. | *(whole repository)* | Leonardo Cecchi (@leonardoce, Maintainer), Marco Nenciarini (@mnencia, Maintainer), Gabriele Bartolini (@gbartolini, Maintainer), Francesco Canovai (@fcanovai, Maintainer), Armando Ruocco (@armru, Maintainer) | +| [webtest](https://github.com/cloudnative-pg/webtest) | A simple PostgreSQL stress tool. | *(whole repository)* | Leonardo Cecchi (@leonardoce, Maintainer), Marco Nenciarini (@mnencia, Maintainer), Gabriele Bartolini (@gbartolini, Maintainer), Francesco Canovai (@fcanovai, Maintainer), Armando Ruocco (@armru, Maintainer) | + +> Jaime Silvela (@jsilvela) stepped down as an owner of +> `cloudnative-pg.github.io` ([cnpg-infra#7](https://github.com/cloudnative-pg/cnpg-infra/pull/7)); +> he remains a Component Owner of `ciclops` (see +> [Supply Chain's Testing & Automation](supply-chain.md#testing--automation)). +> `webtest`'s description above was corrected to match its real GitHub +> description — it's a stress-testing tool, not website/documentation +> test tooling. diff --git a/subprojects/core.md b/subprojects/core.md index c33a7bb..e7dd9a3 100644 --- a/subprojects/core.md +++ b/subprojects/core.md @@ -20,9 +20,14 @@ for how subprojects are defined. | Repository | Description | Scope | Owners | | --- | --- | --- | --- | -| [cloudnative-pg](https://github.com/cloudnative-pg/cloudnative-pg) | The main Kubernetes Operator for PostgreSQL. | Documentation ([`docs/`](https://github.com/cloudnative-pg/cloudnative-pg/tree/main/docs)) | Jaime Silvela (@jsilvela) | +| [cloudnative-pg](https://github.com/cloudnative-pg/cloudnative-pg) | The main Kubernetes Operator for PostgreSQL. | Documentation ([`docs/`](https://github.com/cloudnative-pg/cloudnative-pg/tree/main/docs)) | *(none documented)* | | [cloudnative-pg](https://github.com/cloudnative-pg/cloudnative-pg) | The main Kubernetes Operator for PostgreSQL. | Operator Lifecycle Manager ([`config/olm-*/`](https://github.com/cloudnative-pg/cloudnative-pg/tree/main/config)) | Niccolò Fei (@NiccoloFei) | -| [cloudnative-pg](https://github.com/cloudnative-pg/cloudnative-pg) | The main Kubernetes Operator for PostgreSQL. | Testing ([`.github/`](https://github.com/cloudnative-pg/cloudnative-pg/tree/main/.github), [`hack/`](https://github.com/cloudnative-pg/cloudnative-pg/tree/main/hack), [`tests/`](https://github.com/cloudnative-pg/cloudnative-pg/tree/main/tests); access to additional files might be required) | Niccolò Fei (@NiccoloFei), Tao Li (@litaocdl), Jaime Silvela (@jsilvela) | +| [cloudnative-pg](https://github.com/cloudnative-pg/cloudnative-pg) | The main Kubernetes Operator for PostgreSQL. | Testing ([`.github/`](https://github.com/cloudnative-pg/cloudnative-pg/tree/main/.github), [`hack/`](https://github.com/cloudnative-pg/cloudnative-pg/tree/main/hack), [`tests/`](https://github.com/cloudnative-pg/cloudnative-pg/tree/main/tests); access to additional files might be required) | Niccolò Fei (@NiccoloFei), Tao Li (@litaocdl) | | [api](https://github.com/cloudnative-pg/api) | The CloudNativePG API definitions and types. | *(whole repository)* | *(none documented)* | | [machinery](https://github.com/cloudnative-pg/machinery) | Common Go library for internal logic (extracted from the operator). | *(whole repository)* | *(none documented)* | | [barman-cloud](https://github.com/cloudnative-pg/barman-cloud) | Go library for interacting with Barman Cloud object stores, used by the operator's native backup support. | *(whole repository)* | *(none documented)* | + +> Jaime Silvela (@jsilvela) stepped down from both the Documentation and +> Testing scopes above ([cnpg-infra#7](https://github.com/cloudnative-pg/cnpg-infra/pull/7)); +> he remains a Component Owner of `ciclops` (see +> [Supply Chain's Testing & Automation](supply-chain.md#testing--automation)). diff --git a/subprojects/extensibility.md b/subprojects/extensibility.md index ba4fd5f..bc02171 100644 --- a/subprojects/extensibility.md +++ b/subprojects/extensibility.md @@ -2,8 +2,8 @@ The interfaces, modules, and standalone tooling that let CloudNativePG and PostgreSQL be extended or operated on without changing the operator's core, -including future backup and recovery solutions beyond Barman Cloud, and -Postgres tooling that has nothing to do with Kubernetes at all. See the +including backup and recovery solutions beyond Barman Cloud (e.g. `klio`), +and Postgres tooling that has nothing to do with Kubernetes at all. See the [subprojects index](README.md) for how this fits into the wider structure, and [GOVERNANCE.md](../GOVERNANCE.md#subprojects) for how subprojects are defined. @@ -45,6 +45,7 @@ The extensibility layer that allows for custom backups and additional logic. | [cnpg-i](https://github.com/cloudnative-pg/cnpg-i) | The CloudNativePG Interface (CNPG-I) gRPC specification. | *(whole repository)* | Leonardo Cecchi (@leonardoce, Maintainer), Marco Nenciarini (@mnencia, Maintainer), Gabriele Bartolini (@gbartolini, Maintainer), Francesco Canovai (@fcanovai, Maintainer), Armando Ruocco (@armru, Maintainer) | | [cnpg-i-machinery](https://github.com/cloudnative-pg/cnpg-i-machinery) | Shared Go code for developing CNPG-I compatible plugins. | *(whole repository)* | Leonardo Cecchi (@leonardoce, Maintainer), Marco Nenciarini (@mnencia, Maintainer), Gabriele Bartolini (@gbartolini, Maintainer), Francesco Canovai (@fcanovai, Maintainer), Armando Ruocco (@armru, Maintainer) | | [plugin-barman-cloud](https://github.com/cloudnative-pg/plugin-barman-cloud) | The reference CNPG-I backup/restore plugin for Barman Cloud. | *(whole repository)* | Leonardo Cecchi (@leonardoce, Maintainer), Marco Nenciarini (@mnencia, Maintainer), Gabriele Bartolini (@gbartolini, Maintainer), Francesco Canovai (@fcanovai, Maintainer), Armando Ruocco (@armru, Maintainer), Niccolò Fei (@NiccoloFei) | +| [klio](https://github.com/cloudnative-pg/klio) | Multi-Tiered Backup and Recovery Plugin for CloudNativePG. | *(whole repository)* | Francesco Canovai (@fcanovai, Maintainer), Leonardo Cecchi (@leonardoce, Maintainer), Gabriele Quaresima (@gabriele-wolfox), Gabriele Fedi (@GabriFedi97) | | [cnpg-i-hello-world](https://github.com/cloudnative-pg/cnpg-i-hello-world) | A simplified template/example for building new plugins. | *(whole repository)* | Leonardo Cecchi (@leonardoce, Maintainer), Marco Nenciarini (@mnencia, Maintainer), Gabriele Bartolini (@gbartolini, Maintainer), Francesco Canovai (@fcanovai, Maintainer), Armando Ruocco (@armru, Maintainer) | ## PostgreSQL Extensions & Tooling diff --git a/subprojects/supply-chain.md b/subprojects/supply-chain.md index a3ab761..364bd8e 100644 --- a/subprojects/supply-chain.md +++ b/subprojects/supply-chain.md @@ -37,13 +37,13 @@ Standardized images built for security, minimal footprint, and CNPG compatibilit | Repository | Description | Scope | Owners | | --- | --- | --- | --- | | [postgres-containers](https://github.com/cloudnative-pg/postgres-containers) | Operand images for all community-supported PostgreSQL versions. | *(whole repository)* | Gabriele Bartolini (@gbartolini, Maintainer), Marco Nenciarini (@mnencia, Maintainer), Francesco Canovai (@fcanovai, Maintainer), Niccolò Fei (@NiccoloFei), Tao Li (@litaocdl) | -| [postgres-extensions-containers](https://github.com/cloudnative-pg/postgres-extensions-containers) | Images for community extensions used as pluggable image volumes. | *(default, unlisted extensions)* | Leonardo Cecchi (@leonardoce, Maintainer), Marco Nenciarini (@mnencia, Maintainer), Gabriele Bartolini (@gbartolini, Maintainer), Francesco Canovai (@fcanovai, Maintainer), Armando Ruocco (@armru, Maintainer), Niccolò Fei (@NiccoloFei) | +| [postgres-extensions-containers](https://github.com/cloudnative-pg/postgres-extensions-containers) | Images for community extensions used as pluggable image volumes. | *(default, unlisted extensions)* | Leonardo Cecchi (@leonardoce, Maintainer), Marco Nenciarini (@mnencia, Maintainer), Gabriele Bartolini (@gbartolini, Maintainer), Francesco Canovai (@fcanovai, Maintainer), Armando Ruocco (@armru, Maintainer), Niccolò Fei (@NiccoloFei), Gabriele Fedi (@GabriFedi97) | | [postgres-extensions-containers](https://github.com/cloudnative-pg/postgres-extensions-containers) | Images for community extensions used as pluggable image volumes. | TimescaleDB (OSS) ([`timescaledb-oss/`](https://github.com/cloudnative-pg/postgres-extensions-containers/tree/main/timescaledb-oss)) | Husn E Rabbi (@shusaan) | | [postgres-extensions-containers](https://github.com/cloudnative-pg/postgres-extensions-containers) | Images for community extensions used as pluggable image volumes. | wal2json ([`wal2json/`](https://github.com/cloudnative-pg/postgres-extensions-containers/tree/main/wal2json)) | @solidDoWant | | [postgres-extensions-containers](https://github.com/cloudnative-pg/postgres-extensions-containers) | Images for community extensions used as pluggable image volumes. | pg-ivm ([`pg-ivm/`](https://github.com/cloudnative-pg/postgres-extensions-containers/tree/main/pg-ivm)) | Husn E Rabbi (@shusaan) | -| [pgbouncer-containers](https://github.com/cloudnative-pg/pgbouncer-containers) | Optimized images for PgBouncer connection pooling. | *(whole repository)* | Gabriele Bartolini (@gbartolini, Maintainer), Marco Nenciarini (@mnencia, Maintainer), Leonardo Cecchi (@leonardoce, Maintainer), Niccolò Fei (@NiccoloFei), Tao Li (@litaocdl) | +| [pgbouncer-containers](https://github.com/cloudnative-pg/pgbouncer-containers) | Optimized images for PgBouncer connection pooling. | *(whole repository)* | Gabriele Bartolini (@gbartolini, Maintainer), Marco Nenciarini (@mnencia, Maintainer), Francesco Canovai (@fcanovai, Maintainer), Leonardo Cecchi (@leonardoce, Maintainer), Niccolò Fei (@NiccoloFei), Tao Li (@litaocdl) | | [postgis-containers](https://github.com/cloudnative-pg/postgis-containers) | PostgreSQL images bundled with PostGIS extensions. | *(whole repository)* | Gabriele Bartolini (@gbartolini, Maintainer), Marco Nenciarini (@mnencia, Maintainer), Leonardo Cecchi (@leonardoce, Maintainer), Francesco Canovai (@fcanovai, Maintainer), Niccolò Fei (@NiccoloFei), Tao Li (@litaocdl) | -| [postgres-trunk-containers](https://github.com/cloudnative-pg/postgres-trunk-containers) | Images built from PostgreSQL `main` branch for early testing. | *(whole repository)* | Niccolò Fei (@NiccoloFei), Francesco Canovai (@fcanovai, Maintainer), Gabriele Bartolini (@gbartolini, Maintainer), Jonathan Battiato (@jbattiato), Tao Li (@litaocdl), Marco Nenciarini (@mnencia, Maintainer) | +| [postgres-trunk-containers](https://github.com/cloudnative-pg/postgres-trunk-containers) | Images built from PostgreSQL `main` branch for early testing. | *(whole repository)* | Niccolò Fei (@NiccoloFei), Francesco Canovai (@fcanovai, Maintainer), Gabriele Bartolini (@gbartolini, Maintainer), Leonardo Cecchi (@leonardoce, Maintainer), Jonathan Battiato (@jbattiato), Tao Li (@litaocdl), Marco Nenciarini (@mnencia, Maintainer) | ## Libraries & Automation @@ -59,7 +59,12 @@ directly by the operator's own native backup support, not only by the | Repository | Description | Scope | Owners | | --- | --- | --- | --- | | [daggerverse](https://github.com/cloudnative-pg/daggerverse) | Dagger modules for portable CI/CD workflows. | *(whole repository)* | Leonardo Cecchi (@leonardoce, Maintainer), Marco Nenciarini (@mnencia, Maintainer), Gabriele Bartolini (@gbartolini, Maintainer), Francesco Canovai (@fcanovai, Maintainer), Niccolò Fei (@NiccoloFei), Jonathan Battiato (@jbattiato) | -| [cnpg-template](https://github.com/cloudnative-pg/cnpg-template) | A template repository for creating new CloudNativePG-related projects. | *(whole repository)* | *(none documented)* | + +> `cnpg-template` used to be listed here. It's now classified as +> org-control infrastructure administered directly by the Steering +> Committee instead, alongside `governance`, `.project`, `.github`, and +> `cnpg-infra` — see [GOVERNANCE.md's Subprojects section](../GOVERNANCE.md#subprojects) +> and [subprojects/README.md](README.md). ## Testing & Automation