diff --git a/.github/ISSUE_TEMPLATE/committee_member_add.yml b/.github/ISSUE_TEMPLATE/committee_member_add.yml new file mode 100644 index 0000000..2f34db2 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/committee_member_add.yml @@ -0,0 +1,52 @@ +name: "Subproject Committee: Add Member" +description: "Propose adding a member to a subproject maintainer committee" +title: "[Committee Add]: to " +labels: ["committee-membership"] +body: + - type: markdown + attributes: + value: | + See [GOVERNANCE.md's Changes in subproject maintainer committee + membership section](https://github.com/cloudnative-pg/governance/blob/main/GOVERNANCE.md#changes-in-subproject-maintainer-committee-membership) + for the full process. Once this issue has the nominee's details + below, run the vote for the target subproject using its own + profile in `.gitvote.yml` (simple majority, per person): + + - Core: `/vote-core` + - Supply Chain: `/vote-supply-chain` + - Community, Docs & Ecosystem: `/vote-community-ecosystem` + - Extensibility: `/vote-extensibility` + + Committees are self-selecting: Steering does not vote on an + addition. The exception is a committee that has fallen below its + three-member floor, which is too small to self-select: while + Steering is its caretaker, Steering decides additions instead, by + simple majority with `/vote` (see the section linked above). + - type: dropdown + id: subproject + attributes: + label: Subproject + options: + - Core + - Supply Chain + - Community, Docs & Ecosystem + - Extensibility + validations: + required: true + - type: input + id: nominee + attributes: + label: Nominee + description: GitHub handle of the person being proposed + validations: + required: true + - type: textarea + id: justification + attributes: + label: Justification + description: > + Which component(s) is the nominee an established Component Owner + of within this subproject? See CONTRIBUTOR_LADDER.md's Subproject + Maintainer section for eligibility. + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/committee_member_remove.yml b/.github/ISSUE_TEMPLATE/committee_member_remove.yml new file mode 100644 index 0000000..c2a22c7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/committee_member_remove.yml @@ -0,0 +1,67 @@ +name: "Subproject Committee: Remove Member" +description: "Propose removing a member from a subproject maintainer committee" +title: "[Committee Remove]: from " +labels: ["committee-membership"] +body: + - type: markdown + attributes: + value: | + See [GOVERNANCE.md's Changes in subproject maintainer committee + membership section](https://github.com/cloudnative-pg/governance/blob/main/GOVERNANCE.md#changes-in-subproject-maintainer-committee-membership) + for the full process. Once this issue has the details below, run + the removal vote for the target subproject using its own + `-removal` profile in `.gitvote.yml` (⅔ majority, per person, of + the committee, with the member under review abstaining): + + - Core: `/vote-core-removal` + - Supply Chain: `/vote-supply-chain-removal` + - Community, Docs & Ecosystem: `/vote-community-ecosystem-removal` + - Extensibility: `/vote-extensibility-removal` + + The member under review stays in the electorate GitVote counts + against, so ask them to abstain rather than vote on their own + removal: the ⅔ bar is measured against the whole committee + either way. If the committee can't reach ⅔ without them, or can't + convene the vote at all, any other committee member requests + Steering's backstop on this same issue; Steering then decides by + simple majority using `.gitvote.yml`'s `default` profile, `/vote` + (see the section linked above). + - type: dropdown + id: subproject + attributes: + label: Subproject + options: + - Core + - Supply Chain + - Community, Docs & Ecosystem + - Extensibility + validations: + required: true + - type: input + id: member + attributes: + label: Member proposed for removal + description: GitHub handle + validations: + required: true + - type: dropdown + id: reason + attributes: + label: Reason + options: + - Inactivity + - Code of Conduct violation + - Out-of-remit / no longer meets requirements + validations: + required: true + - type: textarea + id: details + attributes: + label: Details + description: > + Explain the reason above. For inactivity, see + CONTRIBUTOR_LADDER.md's Inactivity section (6 months with no + contribution or communication, not counting a communicated + absence). + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/component-owner-proposal.yml b/.github/ISSUE_TEMPLATE/component-owner-proposal.yml new file mode 100644 index 0000000..1f20912 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/component-owner-proposal.yml @@ -0,0 +1,110 @@ +name: "Propose a Component Owner" +description: "Nominate a Contributor to become Component Owner of a repository" +title: "[Component Owner Proposal]: " +labels: ["component-owner-proposal"] +body: + - type: markdown + attributes: + value: | + ## Component Owner proposal + + This template is an org-wide default (defined in `cloudnative-pg/.github`), + but **the issue itself must be created in the repository the nominee is + being proposed for** -- if you opened "New issue" from that repository's + own page, you're already in the right place; don't move this to + `governance`, `.github`, or `cnpg-infra`. gitvote reads a repository's + own `.gitvote.yml`, so the vote this issue leads to only uses the right + voters (that repository's Component Owners) if the issue lives there. + + Promotion process, thresholds, and who may propose: see + `CONTRIBUTOR_LADDER.md` in + [cloudnative-pg/governance](https://github.com/cloudnative-pg/governance). + That document arrives with the federated-model rewrite, which is + pending ratification; progress is tracked in + [cloudnative-pg/governance#67](https://github.com/cloudnative-pg/governance/issues/67). + + - type: input + id: nominee + attributes: + label: Proposed Component Owner + description: GitHub handle of the person being nominated. + placeholder: "@handle" + validations: + required: true + + - type: input + id: lfid + attributes: + label: Nominee's LFID profile + description: "Component Owner status requires a Linux Foundation ID (LFID) with the nominee's GitHub account linked to it -- this is what lets CNCF's own tooling map the GitHub handle above to an organization at all. Look it up, or register/link one, at https://openprofile.dev. Paste the profile URL." + placeholder: "e.g. https://openprofile.dev/profile/gabriele.bartolini" + validations: + required: true + + - type: input + id: organization + attributes: + label: Nominee's organization (employer) + description: "Must match the LFID profile's own \"Current Organization\" field above, not just what you believe it to be. This is what org-balanced voting and the Steering seat cap actually count -- a profile with no employer set, or the wrong one, silently misstates an organization's real seat count. Use the literal word Independent (not blank, not N/A) if the nominee has no employer tied to their contribution." + placeholder: "e.g. EDB -- or literally: Independent" + validations: + required: true + + - type: checkboxes + id: eligibility + attributes: + label: Proposer eligibility + description: "Per CONTRIBUTOR_LADDER.md, a nomination comes from a member of the body that decides it: this repository's Component Owners, or, where fewer than three of them are named, its subproject's maintainer committee. If that isn't you, ask one of them to open this issue instead of opening it on their behalf, so the record shows who actually nominated. Nobody here can verify the LFID/organization fields above by API -- this is a self-attestation, same as the two below." + options: + - label: I am a Component Owner of this repository, or a member of its subproject's maintainer committee. + required: true + - label: I opened this issue inside the target repository itself (see note above), not in governance, .github, or cnpg-infra. + required: true + - label: I opened the LFID profile above myself and confirmed the nominee's GitHub account is linked to it, and its "Current Organization" field matches the organization given above (or Independent). + required: true + + - type: textarea + id: justification + attributes: + label: Track record / justification + description: Why does this contributor merit Component Owner status on this repository? Reference specific contributions -- PRs authored or reviewed, issue triage, sustained involvement, etc. + validations: + required: true + + - type: textarea + id: links + attributes: + label: Relevant links + description: PRs, issues, or discussions that support this nomination. + validations: + required: false + + - type: markdown + attributes: + value: | + ## Next steps + + 1. Let this issue sit long enough for this repository's other Component + Owners to weigh in. + 2. An existing Maintainer or Component Owner of this repository comments + `/vote-component-owner` to open voting: two-thirds majority of this + repository's Component Owners, one week, per this repository's own + `.gitvote.yml`. If this repository has fewer than three named + Component Owners (or none), the vote defaults to the subproject + maintainer committee instead -- see `CONTRIBUTOR_LADDER.md` in the + governance repository. + 3. If the vote passes: open a PR against + [cloudnative-pg/cnpg-infra](https://github.com/cloudnative-pg/cnpg-infra) + adding the nominee to this repository's `owners:` list in + `repo-tiers.yaml`. Once merged, `scripts/sync-project-owner-teams.sh + --apply` (run by an admin, from their own machine -- + see that repo's README) grants the actual GitHub access. + Automating this step from a passed vote is on the roadmap; for now + it's a manual follow-up. + 4. The LFID and organization collected above have nowhere durable to + land yet: `.project`'s `maintainers.yaml` doesn't have fields for + either today (confirmed against the + [dot-project schema](https://github.com/cncf/automation/tree/main/utilities/dot-project) + -- it only lists GitHub handles). Until that's resolved, note the + organization in this issue and in the `cnpg-infra` PR from step 3, + so it's at least on the record somewhere. diff --git a/.github/ISSUE_TEMPLATE/delegated_team_membership.yml b/.github/ISSUE_TEMPLATE/delegated_team_membership.yml new file mode 100644 index 0000000..9679d66 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/delegated_team_membership.yml @@ -0,0 +1,58 @@ +name: "Delegated Team: Membership Change" +description: "Propose adding or removing an Infrastructure Team or Security Response Team member" +title: "[Team]: to/from " +labels: ["team-membership"] +body: + - type: markdown + attributes: + value: | + Both teams below hold responsibilities the Steering Committee has + delegated rather than given away, so Steering decides their + membership: see [GOVERNANCE.md's Infrastructure + Administration](https://github.com/cloudnative-pg/governance/blob/main/GOVERNANCE.md#infrastructure-administration) + and [Security Response + Team](https://github.com/cloudnative-pg/governance/blob/main/GOVERNANCE.md#security-response-team) + sections for what each one does. + + Once this issue has the details below, run the vote using + `.gitvote.yml`'s `default` profile, `/vote` (lazy consensus, + falling back to simple majority, per person, of the Steering + Committee). + + A passed vote is not the end of it. Adding someone means putting + them in the roster table in `MAINTAINERS.md`, in the GitHub team + (`admins` for Infrastructure), and, for the Security Response + Team, on the intake address, in the private channel where + embargoed reports are discussed, and in `SECURITY-INSIGHTS.yml`. + Removing someone reverses each of those in the same pass. + - type: dropdown + id: team + attributes: + label: Team + options: + - Infrastructure Team + - Security Response Team + validations: + required: true + - type: dropdown + id: change + attributes: + label: Change + options: + - Add + - Remove + validations: + required: true + - type: input + id: member + attributes: + label: Member + description: GitHub handle + validations: + required: true + - type: textarea + id: reason + attributes: + label: Reason + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/new_component_proposal.yml b/.github/ISSUE_TEMPLATE/new_component_proposal.yml new file mode 100644 index 0000000..7200b25 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/new_component_proposal.yml @@ -0,0 +1,119 @@ +name: "New Component Proposal" +description: "Propose that a new repository join CloudNativePG as a component" +title: "[New Component]: " +labels: ["component-proposal"] +body: + - type: markdown + attributes: + value: | + See [GOVERNANCE.md's Proposing a New Component section](https://github.com/cloudnative-pg/governance/blob/main/GOVERNANCE.md#proposing-a-new-component) + for the full process. This proposal will be presented at the first + available community meeting for open discussion, then decided by + simple-majority, per-person vote of the target subproject's + maintainer committee, run on this issue with that subproject's + own profile in `.gitvote.yml`: + + - Core: `/vote-core` + - Supply Chain: `/vote-supply-chain` + - Community, Docs & Ecosystem: `/vote-community-ecosystem` + - Extensibility: `/vote-extensibility` + + If you select "None of these" below, the proposal fits no + existing subproject and is escalated to the Steering Committee as + a request to add a new one instead: proposed by a Steering + Committee member, ⅔ majority, per person, run with + `/vote-governance`. See + [GOVERNANCE.md's Adding New Subprojects section](https://github.com/cloudnative-pg/governance/blob/main/GOVERNANCE.md#adding-new-subprojects). + - type: input + id: repo-name + attributes: + label: Proposed repository name + validations: + required: true + - type: textarea + id: purpose + attributes: + label: Purpose + description: What does this repository do, and why should it join CloudNativePG? + validations: + required: true + - type: dropdown + id: subproject + attributes: + label: Subproject + description: > + Which existing subproject does this belong to? See the + subprojects/ folder. If none fit, explain why a new subproject is + needed instead in the field below. + options: + - Core + - Supply Chain + - Community, Docs & Ecosystem + - Extensibility + - None of these (new subproject needed) + validations: + required: true + - type: textarea + id: new-subproject-case + attributes: + label: Case for a new subproject (if applicable) + description: > + Only needed if you selected "None of these" above. See + GOVERNANCE.md's Adding New Subprojects section for what's expected. + - type: textarea + id: activity + attributes: + label: Active development and user base + description: > + If this repository already exists, describe its current + development activity and real-world usage. Not applicable to a + brand-new, from-scratch repository. + - type: textarea + id: quality + attributes: + label: Code and design quality + description: How does it compare to the rest of CloudNativePG? + validations: + required: true + - type: checkboxes + id: consensus + attributes: + label: Internal consensus + options: + - label: > + This repository already has its own contributor base (e.g. + an existing external project), and they've held an internal + consensus vote to join CloudNativePG before this proposal was + opened. + - type: input + id: owners + attributes: + label: Initial Component Owner(s) + description: GitHub handles of who will own this component + validations: + required: true + - type: textarea + id: commitment + attributes: + label: Long-term commitment + description: > + Describe the proposer's, or proposed owners', long-term commitment + to maintaining this component. + validations: + required: true + - type: textarea + id: license-ip + attributes: + label: License adoption and IP transfer + description: > + Confirm that whoever holds rights to this repository's code is in + a position to license it under the Apache License 2.0, with a + Developer Certificate of Origin sign-off on every contribution, + and to transfer any project trademark and logo assets to the + Linux Foundation (CNCF Charter, section 11). CloudNativePG asks + for no copyright assignment and operates no CLA. If there's a gap + (an incompatible license, prior contributors who can't be reached, + a trademark held elsewhere), describe the concrete plan for + resolving it before this is accepted. + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/task_add_codeowner.yml b/.github/ISSUE_TEMPLATE/task_add_codeowner.yml deleted file mode 100644 index 8c02dea..0000000 --- a/.github/ISSUE_TEMPLATE/task_add_codeowner.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: "CodeOwner Onboarding" -description: "Add a code owner to a repository" -title: "[CodeOwner Onboarding]: Adding as code owner" -labels: ["onboarding", "codeowner"] -projects: ["cloudnative-pg/governance"] -assignees: - - gbartolini - - sxd -body: - - type: markdown - attributes: - value: | - ## Code Owner Onboarding - This issue is to track the onboarding of a new code owner for the repository . - Please follow the next set of tasks: - - [ ] Close the ticket with the vote and open this one as a follow up - - [ ] Add the new code owner to the organization - - [ ] Add the new code owner to the proper team(s) - - [ ] Make sure the new code owner exists on the CODEOWNERS file if the team is not in the - - [ ] Add the new code owner to https://github.com/cloudnative-pg/governance/blob/main/COMPONENT-OWNERS.md - - [ ] Announce thew new code owner in the mailing list diff --git a/.gitvote.yml b/.gitvote.yml index e76b511..9d5383e 100644 --- a/.gitvote.yml +++ b/.gitvote.yml @@ -25,10 +25,25 @@ # - "*.txt" # profile: default # +# Amending GOVERNANCE.md or CONTRIBUTOR_LADDER.md is a ⅔ Steering +# Committee decision (see GOVERNANCE.md's Amendments and Voting +# sections). Both are amended by pull request, so the vote runs on the +# PR itself and is opened automatically here: the diff is the proposal, +# and a governance change can't be merged without a vote having been +# called on it. Every other decision in GOVERNANCE.md is raised as an +# issue instead, from one of the templates in .github/ISSUE_TEMPLATE, +# and the vote is called there by hand. +# +# Deliberately not listed below: MAINTAINERS.md (a roster change records +# a decision already taken by the relevant committee, at that +# committee's own threshold) and subprojects/*.md (routine editorial +# changes, explicitly no governance vote). automation: - enabled: false + enabled: true rules: - - patterns: [] + - patterns: + - "GOVERNANCE.md" + - "CONTRIBUTOR_LADDER.md" profile: governance # Configuration profiles (required) @@ -53,7 +68,7 @@ profiles: # days | day | d # weeks | week | w # - duration: 4w + duration: 2w # Pass threshold (required) # @@ -181,12 +196,136 @@ profiles: # default values when they are not provided on other profiles. # governance: - duration: 4w + duration: 2w pass_threshold: 66 close_on_passing: true + # Held open for a week even once it would pass, so the amendment is + # actually circulated for comment before it's adopted (see + # GOVERNANCE.md's Amendments section). + close_on_passing_min_wait: "1 week" announcements: discussions: category: announcements allowed_voters: teams: - steering-committee + + # Note: Steering's plain-majority business (the subproject-committee + # removal backstop, and everything else Steering owns by lazy + # consensus falling back to simple majority, see GOVERNANCE.md's + # Voting section) doesn't need its own profile; the `default` profile + # above already has pass_threshold: 50 and allowed_voters.teams: + # [steering-committee], invoked with plain `/vote`. + # + # The `governance` profile above is the ⅔ bar. It covers amending + # GOVERNANCE.md or CONTRIBUTOR_LADDER.md (opened automatically, see + # the automation block at the top of this file) and adding or removing + # a subproject, which carries the same bar because each subproject is + # expected to hold a seat on the Steering Committee once the + # seat-selection mechanism is ratified: it changes Steering's own + # future composition, not just the repository listing. A MAINTAINERS.md + # roster change is not on this list; it records a decision already + # taken at that committee's own threshold. + + # Per-subproject profiles + # + # Simple majority, per person, of that subproject's own maintainer + # committee team. Covers both a new-component proposal (see GOVERNANCE.md's + # Proposing a New Component section) and adding a subproject maintainer + # committee member (see GOVERNANCE.md's Changes in subproject maintainer + # committee membership section); both use this same rule. + core: + duration: 2w + pass_threshold: 50 + close_on_passing: true + announcements: + discussions: + category: announcements + allowed_voters: + teams: + - core-maintainers + + supply-chain: + duration: 2w + pass_threshold: 50 + close_on_passing: true + announcements: + discussions: + category: announcements + allowed_voters: + teams: + - supply-chain-maintainers + + community-ecosystem: + duration: 2w + pass_threshold: 50 + close_on_passing: true + announcements: + discussions: + category: announcements + allowed_voters: + teams: + - community-ecosystem-maintainers + + extensibility: + duration: 2w + pass_threshold: 50 + close_on_passing: true + announcements: + discussions: + category: announcements + allowed_voters: + teams: + - extensibility-maintainers + + # Per-subproject removal profiles + # + # ⅔ majority, per person, of that subproject's own maintainer committee + # team (see GOVERNANCE.md's Changes in subproject maintainer committee + # membership section). GitVote has no way to exclude one specific team + # member from the electorate, so the member under review is asked to + # abstain rather than being mechanically excluded from the tally; see + # that section for the full removal process. + core-removal: + duration: 2w + pass_threshold: 66 + close_on_passing: true + announcements: + discussions: + category: announcements + allowed_voters: + teams: + - core-maintainers + + supply-chain-removal: + duration: 2w + pass_threshold: 66 + close_on_passing: true + announcements: + discussions: + category: announcements + allowed_voters: + teams: + - supply-chain-maintainers + + community-ecosystem-removal: + duration: 2w + pass_threshold: 66 + close_on_passing: true + announcements: + discussions: + category: announcements + allowed_voters: + teams: + - community-ecosystem-maintainers + + extensibility-removal: + duration: 2w + pass_threshold: 66 + close_on_passing: true + announcements: + discussions: + category: announcements + allowed_voters: + teams: + - extensibility-maintainers diff --git a/CODEOWNERS b/CODEOWNERS index 1c74dd9..25f640d 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1 +1,13 @@ -* @cloudnative-pg/governance-owners @cloudnative-pg/admins +# This file is generated from componentowners-policy.yaml in +# cloudnative-pg/cnpg-infra — do not hand-edit, propose changes there instead. +# +# Path-scoped rules below always include the repo's own general owners +# (the "*" line) in addition to their own specific teams/users, since +# CODEOWNERS only honors the LAST matching pattern for a given path — +# it does not merge an earlier, less-specific rule into a later one. + +* @cloudnative-pg/governance-owners +/subprojects/core.md @cloudnative-pg/governance-owners @cloudnative-pg/core-maintainers +/subprojects/supply-chain.md @cloudnative-pg/governance-owners @cloudnative-pg/supply-chain-maintainers +/subprojects/community-ecosystem.md @cloudnative-pg/governance-owners @cloudnative-pg/community-ecosystem-maintainers +/subprojects/extensibility.md @cloudnative-pg/governance-owners @cloudnative-pg/extensibility-maintainers diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 04c3d5a..9ae6e38 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,3 +1,18 @@ # Code of Conduct CloudNativePG follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md). + +## Reporting + +Report a violation to either address; both are read, and a reporter does +not have to pick the right one: + +- **conduct@cloudnative-pg.io**, which reaches CloudNativePG. +- **conduct@cncf.io**, the CNCF Code of Conduct Committee, which is + independent of this project. Use this one for a report concerning + anyone in CloudNativePG's leadership, or whenever you would rather the + project not read it first. + +See [GOVERNANCE.md's Code of Conduct section](GOVERNANCE.md#code-of-conduct) +for who reviews a report, what responses are available, and when a matter +goes to the CNCF instead. diff --git a/COMPONENT-OWNERS.md b/COMPONENT-OWNERS.md deleted file mode 100644 index 4f18408..0000000 --- a/COMPONENT-OWNERS.md +++ /dev/null @@ -1,167 +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) - -### 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) -- 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:** - -### 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) - -## 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) - -## 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/COMPONENT_OWNERS.md b/COMPONENT_OWNERS.md new file mode 100644 index 0000000..2fd4027 --- /dev/null +++ b/COMPONENT_OWNERS.md @@ -0,0 +1,33 @@ +# Component Owners + + + +`governance` is one of the CloudNativePG organization-control repositories, +administered directly by the Steering Committee rather than by a +subproject maintainer committee. + +The people below are its **Component Owners**: they hold `Write` on this +repository through the `governance-owners` GitHub team, and are its default +[`CODEOWNERS`](CODEOWNERS) entry, so every pull request here is routed to +them for review. + +| Name | GitHub Handle | Country | +| :--- | :--- | :--- | +| Gabriele Bartolini | [@gbartolini](https://github.com/gbartolini) | | +| Francesco Canovai | [@fcanovai](https://github.com/fcanovai) | | +| Leonardo Cecchi | [@leonardoce](https://github.com/leonardoce) | | +| Marco Nenciarini | [@mnencia](https://github.com/mnencia) | | +| Armando Ruocco | [@armru](https://github.com/armru) | | + +Component Owner is a rung of the CloudNativePG contributor ladder. A new +owner is added by a ⅔ vote of this repository's existing Component Owners, +held on an issue in this repository; the change is then recorded in +`cnpg-infra`, which grants the access and regenerates this file. See +`CONTRIBUTOR_LADDER.md` in [cloudnative-pg/governance](https://github.com/cloudnative-pg/governance) +for the full process, including what happens when a repository has too few +owners to reach that threshold. diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md deleted file mode 100644 index b7fd4cc..0000000 --- a/CONTRIBUTORS.md +++ /dev/null @@ -1,32 +0,0 @@ -# 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). - -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. - -| 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). diff --git a/CONTRIBUTOR_LADDER.md b/CONTRIBUTOR_LADDER.md new file mode 100644 index 0000000..b87272d --- /dev/null +++ b/CONTRIBUTOR_LADDER.md @@ -0,0 +1,428 @@ +# CloudNativePG Contributor Ladder + +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, before converging on the Steering Committee +as the top rung; see [the note below](#steering-committee) for what's still +open about how that seat is actually filled. + + + +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, ⅔ majority (see +[GOVERNANCE.md's Voting section](GOVERNANCE.md#voting)). Day-to-day +promotions and removals under the rules below follow each tier's own +process, unchanged. + +- [At a Glance](#at-a-glance) +- [Community Participant](#community-participant) +- [Contributor](#contributor) +- [Reviewer](#reviewer) +- [CNPG Organization Member](#cnpg-organization-member) +- [Component Owner](#component-owner) +- [Subproject Maintainer](#subproject-maintainer) +- [Steering Committee](#steering-committee) +- [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 | None | Repository's existing Component Owners, simple majority (its subproject committee, if none are named) | None | +| Reviewer | Named paths in one repository | Named individually on those paths, advisory | `Write` on the repository; GitHub cannot scope it to those paths | Repository's existing Component Owners, simple majority (its subproject committee, if none are named) | None | +| Component Owner | Whole repository | None individually; the `*` rule names the `-owners` team they belong to | `Write` on the repository | Repository's existing Component Owners, ⅔ majority (its subproject committee, below three named owners) | None | +| Subproject Maintainer | Whole subproject | N/A (committee seat) | `Maintain` across the subproject's repositories, granted to the committee's GitHub team by `cnpg-infra` from each repository's subproject classification (see [subprojects/README.md](subprojects/README.md#github-teams)) | Self-selected by the committee, Steering oversight | None | +| Steering Committee | Project-wide governance | N/A | Not a GitHub permission tier; the `steering-committee` team is the electorate for Steering-scoped `.gitvote.yml` profiles, not a repo-access grant (`Admin` on the org-control repos already comes from the Infrastructure Team, see [Infrastructure Administration](GOVERNANCE.md#infrastructure-administration)) | Open item, not yet defined (see the note below) | None yet | + +`CODEOWNERS` is not where any of this is decided. It is generated from +[`cnpg-infra`](https://github.com/cloudnative-pg/cnpg-infra) and reflects +two different things: **a team named there means ownership**, via the +`-owners` team the `*` rule points at, and **an individual named +there means review** of the paths that name them. Ownership itself is +recorded in `repo-tiers.yaml` and published in each repository's +`COMPONENT_OWNERS.md`; no Component Owner appears in `CODEOWNERS` by +name. + +```mermaid +flowchart TD + CP["Community Participant
engages, no formal tier"] + CT["Contributor
recognized contribution,
no repository access
"] + RV["Reviewer
named on paths in CODEOWNERS,
Write access
"] + CO["Component Owner
in the repo's owners team,
Write access
"] + SM["Subproject Maintainer
committee seat,
Maintain access subproject-wide
"] + SC["Steering Committee
project-wide governance,
seat mechanism not yet defined
"] + + CP --> CT + CT -->|"repo's Component Owners
simple majority"| RV + CT -->|"repo's Component Owners
⅔ majority"| CO + RV -->|"repo's Component Owners
⅔ majority"| CO + CO -->|"subproject committee
self-selects, simple majority"| SM + SM -.->|"not yet defined"| SC + + OM["CNPG Organization Member
anyone holding Component Owner
status or above, on any repository
"] + CO -.- OM + SM -.- OM + + classDef rung fill:#eef4ff,stroke:#3b6fd6,stroke-width:1px,color:#1a1a1a; + classDef open 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,RV,CO,SM rung; + class SC open; + 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 that repository's own `CONTRIBUTORS.md`; eligible + to be proposed for [Reviewer](#reviewer), which is the usual next step, + or for Component Owner directly. A Contributor cannot be named in + `CODEOWNERS`: GitHub ignores an entry for anyone without `Write` (see + [At a Glance](#at-a-glance)). +- Promotion: elected by simple majority vote of whichever body currently + owns the repository by default: its existing Component Owners; if none + have been recorded, its subproject maintainer committee (see + [subprojects/README.md](subprojects/README.md#github-teams)). Nomination + comes from any member of that same deciding body, and the vote is held on + an issue in the repository the nominee contributed to. + +Requirements here are deliberately qualitative rather than numeric. +Advancement is a judgment call by the people closest to the work, not a +metrics threshold. + + + +## Reviewer + +Reviewers are trusted with review of part of a repository: a directory, a +subsystem, a set of files. They are named individually on those paths in +that repository's `CODEOWNERS`, so GitHub requests them automatically on +any pull request touching their area. + +- Requirements: an established Contributor with a track record in the area + being proposed for. +- Responsibilities: review what you are named on within a reasonable time, + or say when you cannot. [Inactivity](#inactivity) applies to this rung + like any other. +- Privileges: named on those paths in `CODEOWNERS`; `Write` on that one + repository; listed in its `COMPONENT_OWNERS.md` under Reviewers; + eligible to be proposed for Component Owner. +- Not conferred: organization membership, or + [CNPG Organization Member](#cnpg-organization-member) status. `Write` is + granted on that repository alone and can be held as a direct + collaborator; someone already a member for other reasons keeps that. +- Promotion: elected by simple majority of that repository's existing + Component Owners, or of its subproject maintainer committee where none + are recorded, nominated by any member of that body, on an issue in the + repository itself. + +> [!IMPORTANT] +> GitHub grants permissions per repository, never per path, and ignores a +> `CODEOWNERS` entry for anyone without `Write`. A Reviewer therefore holds +> the same repository-wide permission a Component Owner does, including the +> ability to merge a pull request that has met its requirements; the named +> paths are what the project asks of them, not a boundary GitHub enforces. +> The branch ruleset's approvals and checks apply to them as to anyone. + +Being named on a path is advisory: the repository's owners are co-owners of +every path, so a Reviewer is always requested and never blocking. + +## CNPG Organization Member + +"CloudNativePG Organization Member" (**CNPG Organization Member** for +short) is not a separate promotion tier; it's the umbrella term for anyone +holding Component Owner status or above, on any repository. +[Reviewers](#reviewer) are not included despite holding `Write`: the term +marks authority over a component, not access to one. The "CNPG" +qualifier is deliberate: plain "organization" is used throughout these +documents to mean the employer an individual works for, and this term +should never be confused with that. + +Every CNPG Organization Member must hold a Linux Foundation ID (LFID) with +their GitHub account linked to it and their current employer recorded on +it. That link is what lets any counting of organizational balance work at +all: without it a GitHub handle maps to no organization. A nomination to +Component Owner collects the LFID profile up front; Component Owners named +before that requirement existed are asked to link one, and a missing link +is a gap to close, not a reason to drop anyone. + +Holding an LFID is not the same as being a maintainer of CloudNativePG in +the CNCF's sense. **For CNCF purposes the project's maintainers are the +members of the four subproject maintainer committees and of the Steering +Committee**, and that is who +[`.project`](https://github.com/cloudnative-pg/.project)'s +`maintainers.yaml` and the foundation's own +[`project-maintainers.csv`](https://github.com/cncf/foundation/blob/main/project-maintainers.csv) +record. `maintainers.yaml` carries them under a single +`project-maintainers` team today, one entry per committee once this +document is ratified. Component Owners hold an LFID and appear in their component's +`COMPONENT_OWNERS.md`, but are not listed there: their authority is over +one repository, not the project. See the foundation's +[new maintainer guidance](https://github.com/cncf/foundation/blob/main/.github/pull_request_template.md) +for what that listing involves. + +## 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#individual-subproject-governance) 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. + + + +- Requirements: an established Contributor or [Reviewer](#reviewer) with a + track record and demonstrated expertise in the component being proposed + for. Most people arrive here from Reviewer, having already carried review + of part of it. +- Privileges: `Write` access to the relevant repository, whole-repository + entry in its `CODEOWNERS` file, listed in that repository's own + `COMPONENT_OWNERS.md`; counts as a + [CNPG Organization Member](#cnpg-organization-member); eligible to be + proposed for Subproject Maintainer. +- Promotion: elected by ⅔ majority vote of whichever body currently owns + the repository by default: its existing Component Owners, provided at + least three Component Owners are recorded for it, which Reviewers do not + count towards; below that threshold (including + none), its subproject maintainer committee (see + [subprojects/README.md](subprojects/README.md#github-teams)). Nomination + comes from any member of that same deciding body, and the vote is held on + an issue in the component's own repository. Removal follows the same + process. The threshold at which this rung falls back to the committee is + higher than the Contributor rung's on purpose: a ⅔ vote among one or two + owners is either meaningless or a veto, whereas a simple majority still + behaves sensibly with two. + +> [!NOTE] +> **GitHub mechanics:** GitHub grants `Write` at the repository level and +> has no native way to scope permissions by path, so every rung from +> Component Owner down that appears in `CODEOWNERS` at all holds the same +> repository-wide permission. What differs is scope of responsibility, not +> reach. Component Owners are reached through the `-owners` team on +> the `*` rule, which makes them the reviewers of record for anything no +> narrower rule covers. + +> [!NOTE] +> **Naming an individual on a path:** GitHub ignores a `CODEOWNERS` entry +> for anyone without `Write`, silently. It is not that their approval +> counts for less; they are not requested at all, and the line looks +> correct while doing nothing. So an individual named on a path holds +> `Write`, which a Contributor by definition does not, and the practice +> therefore describes a rung above Contributor rather than a way of +> involving one. +> +> That is what the [Reviewer](#reviewer) rung is: the people named on +> paths. It exists in fact today, five of them across `cloudnative-pg`, +> `postgres-extensions-containers` and `klio`, each with `Write` granted by +> hand and recorded in no policy file; naming the rung is what brings that +> access under the same management as everything else. + +- 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-reviewers-and-component-owners)). Steering does +not intervene at the repository level: the committee is always the backstop +for its own repositories, just as Steering is the backstop for a subproject +maintainer committee's own membership, and for a committee that has fallen +below its three-member floor (see +[GOVERNANCE.md's Changes in subproject maintainer committee membership](GOVERNANCE.md#changes-in-subproject-maintainer-committee-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#individual-subproject-governance); 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 named on a path in `CODEOWNERS` 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 + +The Steering Committee holds project-wide governance authority, sitting +above the per-subproject climb below it (see +[GOVERNANCE.md's Steering Committee section](GOVERNANCE.md#steering-committee) +for its duties and decision-making). Today it's simply the group of +Maintainers listed in [MAINTAINERS.md](MAINTAINERS.md). + +- Requirements: today, membership in the existing Maintainers group (see + [MAINTAINERS.md](MAINTAINERS.md)). A requirement tied to Subproject + Maintainer standing is expected once the seat mechanism below is + defined. +- Responsibilities: the project-wide duties in + [GOVERNANCE.md's Steering Committee Duties section](GOVERNANCE.md#steering-committee-duties). +- Privileges: project-wide governance authority; `Admin` on the + org-control repos comes from the Infrastructure Team (see + [Infrastructure Administration](GOVERNANCE.md#infrastructure-administration)), + not as a consequence of this rung. +- Promotion: **open item**, tracked in + [cloudnative-pg/governance#68](https://github.com/cloudnative-pg/governance/issues/68). + How many seats, any per-organisation cap, and how each seat is actually + filled (for example, each subproject committee selecting a + representative, plus elected Community Representatives) isn't defined + in [GOVERNANCE.md](GOVERNANCE.md) yet. Until that's drafted and + ratified, Steering membership stays today's Maintainers list, not + something reached by climbing the rungs below. + +### Worked Example + +> Ana, Ben, and Cleo are Component Owners of `docs`. +> Ana and Cleo are also members of the Community, Docs & Ecosystem +> Maintainer Committee, so they have technical authority over every +> component in that subproject (`docs`, `cloudnative-pg.github.io`, +> `cnpg-playground`, `webtest`, `grafana-dashboards`); Ben's authority +> stays scoped to `docs` alone. (That committee seat doesn't carry +> Steering membership automatically — see Promotion above.) + +## 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 | That repository's `CONTRIBUTORS.md`, generated from [`cnpg-infra`](https://github.com/cloudnative-pg/cnpg-infra)'s `repo-tiers.yaml` (`contributors:`) | +| Reviewer | That repository's `COMPONENT_OWNERS.md` under Reviewers, the paths naming them in its `CODEOWNERS`, and a `Write` grant on that repository alone, held directly rather than through a team, since the rung implies no organization membership. All three come from one entry in [`cnpg-infra`](https://github.com/cloudnative-pg/cnpg-infra)'s `repo-tiers.yaml` | +| Component Owner | That repository's `COMPONENT_OWNERS.md`, and its `-owners` GitHub team membership (see [subprojects/README.md's GitHub Teams section](subprojects/README.md#github-teams)); both are generated from one entry in [`cnpg-infra`](https://github.com/cloudnative-pg/cnpg-infra)'s `repo-tiers.yaml`, so recording the vote there does both | +| 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 | +| Infrastructure Team | [MAINTAINERS.md](MAINTAINERS.md) Infrastructure Team table; `admins` GitHub team membership (see [GOVERNANCE.md's Infrastructure Administration section](GOVERNANCE.md#infrastructure-administration)) | + +A promotion to, or removal from, one of the two committee tiers is also a +change to the project's CNCF-facing maintainer list: update +[`.project`](https://github.com/cloudnative-pg/.project)'s +`maintainers.yaml` and the foundation's `project-maintainers.csv` in the +same pass (see +[CNPG Organization Member](#cnpg-organization-member) for why those two +cover the committee tiers only). + +### Keeping affiliation current + +Anyone from Component Owner upward who changes employer updates their +affiliation **within 30 days**: their LFID profile first, since everything +else is meant to match it, then whichever of these records names them. For +a committee member that is [MAINTAINERS.md](MAINTAINERS.md)'s Organization +column and `.project`'s `maintainers.yaml`; for a Component Owner it is +`people.yaml` in +[`cnpg-infra`](https://github.com/cloudnative-pg/cnpg-infra), which is what +the generated `COMPONENT_OWNERS.md` files are rendered from. Someone who +leaves an employer without joining another writes "Independent" rather than +leaving the field empty. The Steering Committee checks these against the +LFID records as part of its annual review of organizational diversity (see +[GOVERNANCE.md](GOVERNANCE.md#organizational-diversity)). + + + +## 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. + + + +## 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 and Reviewers 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, removal is a ⅔ majority of the committee with +the member under review abstaining, and the Steering Committee is the +backstop only when that vote has failed or the committee can't convene one +(see +[GOVERNANCE.md's Changes in subproject maintainer committee membership](GOVERNANCE.md#changes-in-subproject-maintainer-committee-membership) +for the full mechanism). + + + +## 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..f81887d 100644 --- a/GOVERNANCE.md +++ b/GOVERNANCE.md @@ -1,5 +1,9 @@ # CloudNativePG Governance + + This document defines governance policies for the CloudNativePG project. ## Our Mission @@ -47,152 +51,673 @@ 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. - -## 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 + 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 + (see [Steering Committee](#steering-committee) below for composition and + voting, including its backstop role for a subproject maintainer + committee). +- **Subproject Maintainer Committees** own technical authority within their + subproject: code review, merge, release, and day-to-day decisions by lazy + consensus. Technical decisions stay per-person, regardless of + organization. + +See [Voting](#voting) for exactly which decisions use which mechanism. + +```mermaid +flowchart TD + subgraph GOV["Governance authority"] + SC["Steering Committee
(today's Maintainers, see MAINTAINERS.md)"] + 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,
machinery")] + 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, cnpg-template
administered directly by Steering,
not part of any subproject")] + SC --> GREPO + + SC -.->|"backstop: removes a stuck
committee member,
simple 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 gov; + class CPC,SUC,CDC,EXC committee; + class CPR,SUR,CDR,EXR,GREPO repo; +``` + +## Individual Subproject Governance + +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**](subprojects/core.md) | (no groupings; one flat listing) | +| [**Supply Chain**](subprojects/supply-chain.md) | Distribution, Container Images, Libraries & Automation, Testing & Automation | +| [**Community, Docs & Ecosystem**](subprojects/community-ecosystem.md) | (no groupings; one flat listing) | +| [**Extensibility**](subprojects/extensibility.md) | Interface & Plugins (CNPG-I), External Dependencies, PostgreSQL Extensions & Tooling | + +A subproject is made up of one or more **components**, each a GitHub +repository, no more and no less. Each subproject's +maintainer committee has technical authority over every component listed in +its file under [subprojects/](subprojects/README.md). + +Component Owner authority and GitHub write access are granted at the +component (repository) level, not automatically across the subproject: +owning one component 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. + +> **Example:** Ana, Ben, and Cleo are Component Owners of `docs`. Ana and +> Cleo are also on the Community, Docs & Ecosystem Maintainer Committee, +> which gives them (not Ben) authority across every component in that +> subproject. See +> [CONTRIBUTOR_LADDER.md's worked example](CONTRIBUTOR_LADDER.md#worked-example) +> for the full walk-through. + +Five repositories sit outside any subproject, administered directly by the +Steering Committee: + +- `governance`: this document set +- `.project`: CNCF project metadata for landscape/tooling automation +- `.github`: org-wide default Code of Conduct, Contributing guide, and + other community health files other repositories fall back to +- `cnpg-infra`: tooling that manages GitHub settings, teams, and + `CODEOWNERS` +- `cnpg-template`: the template every new org repository, including these + five, is created from + +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. + +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), +using the +[New Component Proposal issue template](.github/ISSUE_TEMPLATE/new_component_proposal.yml), +which collects: + +- 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 + [Adding New Subprojects](#adding-new-subprojects)) +- Confirmation that whoever holds rights to the repository's code is in a + position to license it under the Apache License 2.0, with a Developer + Certificate of Origin sign-off on every contribution, and to transfer + any project trademark and logo assets to the Linux Foundation (CNCF + Charter §11). CloudNativePG asks for no copyright assignment and + operates no CLA. Either the rights are already in that position, or the + proposal describes a concrete plan to get there +- Active development and a real user base, for a repository that already + has one +- Code and design quality in line with the rest of the project +- 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 + +Where the repository already has its own contributor base (e.g. an +existing external project), they hold an internal consensus vote to join +CloudNativePG before this proposal is opened. + +The proposal is presented at the first available community meeting and +added to its agenda for open discussion (see [Meetings](#meetings)). The +target subproject's maintainer committee then reviews and decides by the +same simple-majority, per-person vote it uses for its own membership (see +[Changes in subproject maintainer committee membership](#changes-in-subproject-maintainer-committee-membership)); +a proposal is only accepted once the committee has confirmed the +licensing and IP transfer above. Accepting a proposal is a routine edit +to that subproject's `subprojects/*.md` file, no separate Steering vote +needed. A +proposal that fits no existing subproject is escalated to Steering +instead, as a request to [add a new subproject](#adding-new-subprojects). + +Once accepted, onboarding the repository itself is automated end-to-end +by [`cnpg-infra`](https://github.com/cloudnative-pg/cnpg-infra) (see +[Infrastructure Administration](#infrastructure-administration)); this +executes a decision already made above and has no bearing on who makes +it. + +A component that isn't yet ready for full status, but is otherwise a good +fit, may instead be accepted as an **Experimental Component**. It joins on +the same terms as any other component and is marked "Experimental" in its +repository and on the website, so adopters can see what they are taking +on. The subproject's committee reviews its Experimental components at +least twice a year and decides, by the same vote it used to accept them, +whether each has matured to full status, should stay Experimental, or +should be archived. A component stays Experimental until that vote says +otherwise. + +A component that goes 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, the addition process in reverse. This needs a +Steering vote only if archiving it would leave the subproject with no +components at all, which becomes a +[subproject removal](#removing-subprojects) instead. + + + +### 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, matching the section +names already used in [MAINTAINERS.md](MAINTAINERS.md): + +- **CloudNativePG Core Maintainer** +- **CloudNativePG Supply Chain Maintainer** +- **CloudNativePG Community, Docs & Ecosystem Maintainer** +- **CloudNativePG Extensibility Maintainer** + +Any unqualified "Maintainer" elsewhere in this document means a member of +one of these four committees, regardless of which. + +Each subproject 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 addresses in [Code of Conduct](#code-of-conduct), + rather than handling them within the 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 + +#### Organizational Diversity + +A subproject can end up dominated by a single organization even when +CloudNativePG as a whole is not, so each subproject should aspire to +organizational diversity in its own maintainer committee. The Steering +Committee reviews per-subproject diversity at least annually, alongside +the [MAINTAINERS.md](MAINTAINERS.md) Organization column, and gently +encourages a concentrated subproject's committee to grow outside +participation. + +#### Changes in subproject maintainer committee membership + +Each subproject always has a maintainer committee, of at least three +members. If a committee falls below three, the Steering Committee acts as +caretaker for that subproject, holding its technical authority, until the +committee is back to three; a committee that cannot return to three within +a reasonable period is grounds for reviewing whether the subproject should +be merged or retired. In caretaker mode the committee is, by definition, +too small to self-select: Steering decides additions to it by simple +majority, per person, until it is back to three (see [Voting](#voting)). + +Subproject maintainer committees are self-selecting, with Steering +oversight. Eligibility is scoped to established Component Owners of that +subproject's repositories; being named on a path in `CODEOWNERS` doesn't +count. This gives contributors to charts, +plugins, container images, or documentation the same path to governance +influence as contributors to the core operator. A nominee is proposed via +the [Committee Add issue template](.github/ISSUE_TEMPLATE/committee_member_add.yml) +and added by simple majority of the existing committee, per person, +uncapped by organization, deliberately a lighter bar than removal (see +below). Steering's oversight is passive here; it doesn't hold a second +vote on every addition. + +A committee removes an unresponsive, CoC-violating, or out-of-remit member +via the [Committee Remove issue template](.github/ISSUE_TEMPLATE/committee_member_remove.yml), +by ⅔ majority of the committee, per person, with the member under review +expected to abstain rather than vote on their own removal. This assumes +the committee can reach that majority without the member's own vote, +which a small or deadlocked committee might not manage. +Steering is the backstop for that case only: it doesn't act on its own +initiative, only when another committee member requests it *and* the +committee's own ⅔ vote has already failed or is demonstrably impossible to +convene. That request is made on the same Committee Remove issue, +escalating it to Steering, which then removes the member by simple +majority of its own members, per person. + + + +### 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) is, and stays, the public source of +truth for that. GitHub Teams and Slack channels exist only +to *enforce* and support what it already says, 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). + +## Steering Committee + +The Steering Committee holds project-wide governance authority. It does not +replace the technical authority of subproject maintainer committees; it +exists to hold vision, CNCF relations, and cross-project decisions at a +level above any one subproject. + +**Composition:** the Steering Committee is, for now, the group of +Maintainers listed in [MAINTAINERS.md](MAINTAINERS.md), deciding by +per-person vote uncapped by organization; moving to an org-balanced, +seat-capped model is tracked in +[cloudnative-pg/governance#68](https://github.com/cloudnative-pg/governance/issues/68). +Members are expected to represent CloudNativePG as a whole rather than +their own subproject or employer, and to deal with other participants +professionally and in keeping with the Code of Conduct. + +### Steering Committee Duties + +**The Steering Committee owns**, decided per [Voting](#voting) (lazy +consensus, falling back to a simple majority per person, except where +noted otherwise below): + + - Curating and proposing changes to this document, ratified by the Steering + Committee itself, ⅔ majority per person (see [Voting](#voting)) + - Ownership of [CONTRIBUTOR_LADDER.md](CONTRIBUTOR_LADDER.md): the ladder's + structure, promotion criteria, and any numeric thresholds are a Steering + Committee decision. Advancement itself is not: every promotion is decided + per repository or per committee, by the bodies the ladder names + - Reviewing and deciding on new subprojects to add; removing subprojects + that have become inactive + - 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 over CNPG-I plugin framework + direction) + - Code of Conduct reports: reviewing them and ratifying enforcement + decisions today, and constituting the standing committee that will + take that over (see [Code of Conduct](#code-of-conduct)) + - 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 -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 +## Code of Conduct -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. +CloudNativePG has adopted the [CNCF Code of Conduct](CODE_OF_CONDUCT.md) +unchanged. A report can be made in either of two places, and a reporter +never has to choose correctly for it to be handled: + +- [conduct@cloudnative-pg.io](mailto:conduct@cloudnative-pg.io), which + reaches the project. +- [conduct@cncf.io](mailto:conduct@cncf.io), the CNCF Code of Conduct + Committee, which is independent of this project and can act on any + report regardless of who it concerns. + +**Who handles a report today.** The Steering Committee reviews reports +sent to the project address, confidentially and in closed session, acting +in that capacity rather than as the project's governing body. Where it +finds a violation it decides a response scaled to its severity, from a +private conversation up to expulsion from the project; a demotion or +expulsion is ratified by the Steering Committee in closed session before +it takes effect. + +**Where that is not appropriate.** If a report concerns a member of the +Steering Committee, or the reporter would rather it not be read by anyone +in CloudNativePG's leadership, it goes to the CNCF Code of Conduct +Committee instead, whose decision the project applies. Steering does not +review a report about one of its own members, and does not need to be told +that a report has been made to the CNCF. + +**Where this is heading.** Handling reports inside Steering is workable +while the project's leadership is small, but it is not the arrangement +this project wants: the reviewer and the governing body should not be the +same five people. The target is a standing **Code of Conduct Committee** +of 3 to 5 people, selected by Steering for diverse representation +(employer, gender, race, background, and region) rather than project +seniority, not limited to existing CloudNativePG contributors, with at +least one member rotated out each year to avoid reviewer fatigue. Steering +constitutes it and records the roster in +[MAINTAINERS.md](MAINTAINERS.md); until that happens, this section +describes what actually occurs. + +## Adding New Subprojects + +A Steering Committee member proposes a wholly new subproject (as opposed +to a new component joining an existing one, see [Proposing a New +Component](#proposing-a-new-component)), when a candidate doesn't fit any +of the four existing groupings, typically Steering reorganizing existing +components into a new grouping. Anyone may prompt that proposal without +being on Steering themselves, either by asking for it directly or by +opening a component proposal that turns out to fit no existing subproject +(see [Proposing a New Component](#proposing-a-new-component)); only a +Steering member can put it forward. The candidate should show: + +- A mission consistent with CloudNativePG's own; +- Appropriate licensing and a compatible governance model, or willingness + to adopt one; +- Active development and a real user base; +- Code and design quality in line with the rest of the project. + +Before applying, the candidate's own contributors hold an internal +consensus vote to join CloudNativePG. Steering then decides by ⅔ +majority, per person (see [Voting](#voting)), the same bar as amending +this document, since each subproject is +expected to hold its own Steering seat once the seat-selection mechanism +is ratified ([#68](https://github.com/cloudnative-pg/governance/issues/68)). +If accepted, Steering assigns one of +its members to help the new subproject integrate (GitHub Teams, +`CODEOWNERS`, its `subprojects/*.md` entry); as part of that integration, +whoever holds rights to the candidate's code confirms they're in a +position to license it under CloudNativePG's Apache License 2.0 and +assign the relevant IP to the CloudNativePG organization under the CNCF, +either because all contributors agree or because a proper DCO process +governs the contribution. + +## Removing Subprojects + +Any Steering Committee member may propose retiring a subproject that has +gone inactive, become unmaintainable, or asked to leave, decided by the +same vote as adding one. Its components are reassigned to +another subproject by that subproject's committee, or archived per +[Proposing a New Component](#proposing-a-new-component) if none fits; +CloudNativePG has no separate namespace to move an entire subproject into. + +## Amendments + +This document is amended by a ⅔ majority of the Steering Committee, per +person (see [Voting](#voting) for the full decision-type table, including +[CONTRIBUTOR_LADDER.md](CONTRIBUTOR_LADDER.md) and subproject changes). +An amendment is proposed as a pull request against this repository, and +the vote is held on that pull request, so the diff under discussion is +the proposal itself. The vote stays open for at least one week even if it +would already pass, so an amendment is genuinely circulated for comment +before it's adopted. + +Every change to this document is an amendment, including one that looks +purely editorial: the vote opens on any pull request that touches it, +with no exception for a typo. That is deliberate, and it is the reason +the repository listings live in +[subprojects/](subprojects/README.md) instead, where reorganising a +component grouping is routine editorial work needing no vote (see +[Individual Subproject Governance](#individual-subproject-governance)). + +## Contributors, Reviewers and Component Owners + +The project recognizes different levels of responsibility, 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 only the +two rungs below Subproject Maintainer. + +Three roles sit below Subproject Maintainer on the ladder: a Contributor +adds value without a defined area of ownership, a Reviewer is trusted with +review of named paths within one component, 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 +recorded in their own component's `COMPONENT_OWNERS.md`, and Contributors +in that same repository's `CONTRIBUTORS.md`, rather than in +[MAINTAINERS.md](MAINTAINERS.md), which lists the committees. Both files +are generated from +[`cnpg-infra`](https://github.com/cloudnative-pg/cnpg-infra), so a +promotion is recorded once and lands wherever it applies. See +[CONTRIBUTOR_LADDER.md's Component Owner section](CONTRIBUTOR_LADDER.md#component-owner) +for what being named in `CODEOWNERS` does and doesn't mean, and the full +promotion mechanism including the subproject committee's backstop role; +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). - -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. +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)). + +Closed meetings are also held to discuss security reports or Code of +Conduct violations, scheduled by any Maintainer on receipt of one. The +Steering Committee and the maintainer committee of each affected +subproject must be invited, rather than every committee in the project: +a security report usually concerns one subproject, and its own +maintainers are the people who can act on it. Anyone accused of a Code of +Conduct violation is not invited. 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. - -## Code of Conduct - -[Code of Conduct](CODE_OF_CONDUCT.md) -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. +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. + +## 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. + +### Security Response Team + +The **Security Response Team** is the named group that watches the intake +address, triages what arrives, decides severity and embargo, and routes +each report to the Component Owners who can fix it. Today it is the +Steering Committee, acting in that capacity; it is a distinct role from +Steering's governance authority, and is expected to grow beyond it as +contributors outside the committee take on security work. + +Steering adds and removes members as ordinary Steering business (lazy +consensus, falling back to a simple majority per person), via the +[Delegated Team Membership issue template](.github/ISSUE_TEMPLATE/delegated_team_membership.yml). +A member is onboarded by being added to the roster in +[MAINTAINERS.md](MAINTAINERS.md), to the intake address, and to the +private channel where embargoed reports are discussed; removal reverses +all three, and is also the step taken when someone steps back or becomes +unreachable. Current membership is recorded in +[MAINTAINERS.md](MAINTAINERS.md)'s Security Response Team section, which +is the public record; the same people, with the email addresses reports +reach them at, are listed in +[SECURITY-INSIGHTS.yml](SECURITY-INSIGHTS.yml) (`project.administrators` +and `repository.core-team`), and that file must be updated in the same +pass. + +## 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, so +responsibility survives individual turnover rather than being tied +informally to whoever happens to hold that 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. + +Steering delegates day-to-day execution of this responsibility to a named +**Infrastructure Team**: the existing `admins` GitHub team, which holds +`Admin` on every repository in the organization (`cnpg-infra`'s +`global_admin_teams`) and access to the sensitive credentials above. It +is not a ladder rung and not the same body as the Steering Committee, +even though the two happen to have identical membership today. + +Steering adds or removes Infrastructure Team (`admins`) members via the +[Delegated Team Membership issue template](.github/ISSUE_TEMPLATE/delegated_team_membership.yml), +per [Voting](#voting): lazy consensus, falling back to a simple majority +per person, the same as its other day-to-day business. Current membership is +recorded in [MAINTAINERS.md](MAINTAINERS.md)'s Infrastructure Team +section; a membership change means updating that roster and reconciling +`cnpg-infra`'s config and the GitHub team from it, same as any other team +in this document. ## 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. + +A threshold is measured against everyone eligible to vote, not against the +votes actually cast, and a proposal carries once support reaches it. Two +consequences are worth stating rather than leaving to be discovered. A +simple majority is reached at exactly half, so two in favour out of four +eligible voters carries. And at ⅔, a committee of three to five members +needs every eligible member except the abstaining one, which makes a +committee-route removal unanimity of the members other than the person +under review. + +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. + +### Steering Committee decisions + +Every Steering decision is per person, uncapped by organization, the same +rule CloudNativePG has always used. + +| Decision Type | Who Votes | Mechanism | +| :---- | :---- | :---- | +| Governance changes (this document, see [Amendments](#amendments)) | Steering Committee | ⅔ majority, per person | +| Changes to [CONTRIBUTOR_LADDER.md](CONTRIBUTOR_LADDER.md) | Steering Committee | ⅔ majority, per person | +| Adding/removing subprojects | Steering Committee | ⅔ majority, per person | +| Infrastructure Team and Security Response Team membership | Steering Committee | Lazy consensus, falling back to simple majority per person | +| Adding a member to a committee in caretaker mode (below three members) | Steering Committee | Simple majority, per person | +| Everything else Steering owns (see [Steering Committee Duties](#steering-committee-duties)) | Steering Committee | Lazy consensus, falling back to simple majority per person | + +### Subproject-level decisions + +Subproject technical decisions are 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) | That committee, with the member under review abstaining | ⅔ majority, per person | +| Removing a subproject maintainer committee member (Steering backstop) | Steering Committee | Simple majority, per person | +| Accepting a new component into the subproject | That subproject's committee | Simple majority, per person | +| Confirming an Experimental component has reached full status | That subproject's committee | Simple majority, per person | +| Archiving a component | That subproject's committee | Simple majority, per person | + +Repository-level decisions follow the same per-person principle, one level +further down; see [Contributors, Reviewers and Component Owners](#contributors-reviewers-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 security intake address](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..c5db6b5 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -1,13 +1,152 @@ # 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) +This file records the committees: the Steering Committee, the +Infrastructure Team and Security Response Team it delegates to, and each +subproject's maintainer committee. The section a person appears under is +their domain of responsibility. Component Owners and Contributors are +recorded per component, in that repository's own `COMPONENT_OWNERS.md` +and `CONTRIBUTORS.md` (see +[CONTRIBUTOR_LADDER.md](CONTRIBUTOR_LADDER.md)), not here. + +**Contact.** Security reports go to +[security@cloudnative-pg.io](mailto:security@cloudnative-pg.io) and Code +of Conduct reports to +[conduct@cloudnative-pg.io](mailto:conduct@cloudnative-pg.io), never to an +individual. For anything else, each committee has a channel listed in +[subprojects/README.md](subprojects/README.md#communication-channels), and +every person below is reachable on GitHub at the handle given. Individual +email addresses for security purposes are recorded in +[SECURITY-INSIGHTS.yml](SECURITY-INSIGHTS.yml). + +Every subproject has a committee, of at least three members (see +[GOVERNANCE.md's Changes in subproject maintainer committee +membership](GOVERNANCE.md#changes-in-subproject-maintainer-committee-membership)). +All four are seeded with the same five people, the CloudNativePG +Maintainers as they stood before this restructuring, because that is who +held the authority being divided up. That is the starting point, not the +intended end state: each committee is self-selecting from the established +Component Owners of its own subproject's repositories, and the four are +expected to diverge as those people are promoted into them. Two changes +still to come are tracked publicly: +[#68](https://github.com/cloudnative-pg/governance/issues/68) for +org-balanced voting and the Steering seat mechanism, and +[#69](https://github.com/cloudnative-pg/governance/issues/69) for the +pathway that brings maintainers from outside EDB onto these committees. + +## Steering Committee + +Per [GOVERNANCE.md's Steering Committee section](GOVERNANCE.md#steering-committee), +the Steering Committee is the group of CloudNativePG Maintainers, carried +forward unchanged from before this restructuring: + +| Last Name | First Name | Handle | Organization | +| --- | --- | --- | --- | +| Bartolini | Gabriele | @gbartolini | EDB | +| Canovai | Francesco | @fcanovai | EDB | +| Cecchi | Leonardo | @leonardoce | EDB | +| Nenciarini | Marco | @mnencia | EDB | +| Ruocco | Armando | @armru | EDB | + +## Infrastructure Team + +Per [GOVERNANCE.md's Infrastructure Administration section](GOVERNANCE.md#infrastructure-administration), +the Infrastructure Team is a distinct body from the Steering Committee, +even though today's membership happens to be identical. It's the existing +`admins` GitHub team: + +| Last Name | First Name | Handle | Organization | +| --- | --- | --- | --- | +| Bartolini | Gabriele | @gbartolini | EDB | +| Canovai | Francesco | @fcanovai | EDB | +| Cecchi | Leonardo | @leonardoce | EDB | +| Nenciarini | Marco | @mnencia | EDB | +| Ruocco | Armando | @armru | EDB | + +## Security Response Team + +Per [GOVERNANCE.md's Security Response Team section](GOVERNANCE.md#security-response-team), +this is the group that triages what arrives at the intake address and +routes it. Today it is the Steering Committee acting in that capacity, a +distinct role from its governance authority: + +| Last Name | First Name | Handle | Organization | +| --- | --- | --- | --- | +| Bartolini | Gabriele | @gbartolini | EDB | +| Canovai | Francesco | @fcanovai | EDB | +| Cecchi | Leonardo | @leonardoce | EDB | +| Nenciarini | Marco | @mnencia | EDB | +| Ruocco | Armando | @armru | EDB | + +## Core Maintainers + +Technical authority over every component listed in +[subprojects/core.md](subprojects/core.md): + +| Last Name | First Name | Handle | Organization | +| --- | --- | --- | --- | +| Bartolini | Gabriele | @gbartolini | EDB | +| Canovai | Francesco | @fcanovai | EDB | +| Cecchi | Leonardo | @leonardoce | EDB | +| Nenciarini | Marco | @mnencia | EDB | +| Ruocco | Armando | @armru | EDB | + +## Supply Chain Maintainers + +Technical authority over every component listed in +[subprojects/supply-chain.md](subprojects/supply-chain.md): + +| Last Name | First Name | Handle | Organization | +| --- | --- | --- | --- | +| Bartolini | Gabriele | @gbartolini | EDB | +| Canovai | Francesco | @fcanovai | EDB | +| Cecchi | Leonardo | @leonardoce | EDB | +| Nenciarini | Marco | @mnencia | EDB | +| Ruocco | Armando | @armru | EDB | + +## Community, Docs & Ecosystem Maintainers + +Technical authority over every component listed in +[subprojects/community-ecosystem.md](subprojects/community-ecosystem.md): + +| Last Name | First Name | Handle | Organization | +| --- | --- | --- | --- | +| Bartolini | Gabriele | @gbartolini | EDB | +| Canovai | Francesco | @fcanovai | EDB | +| Cecchi | Leonardo | @leonardoce | EDB | +| Nenciarini | Marco | @mnencia | EDB | +| Ruocco | Armando | @armru | EDB | + +## Extensibility Maintainers + +Technical authority over every component listed in +[subprojects/extensibility.md](subprojects/extensibility.md): + +| Last Name | First Name | Handle | Organization | +| --- | --- | --- | --- | +| Bartolini | Gabriele | @gbartolini | EDB | +| Canovai | Francesco | @fcanovai | EDB | +| Cecchi | Leonardo | @leonardoce | EDB | +| Nenciarini | Marco | @mnencia | EDB | +| Ruocco | Armando | @armru | EDB | + +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. The org-control repositories, enumerated in +[GOVERNANCE.md's Subprojects section](GOVERNANCE.md#individual-subproject-governance), sit +outside this file entirely: they are administered directly by the Steering +Committee, not by a subproject maintainer committee. + +Every Organization cell above states the employer on that person's +registered Linux Foundation ID (LFID). Everyone listed holds one; +`.project`'s `maintainers.yaml` does not record employers yet, which is a +follow-up rather than a blocker to ratifying this roster. A change of +employer is updated here within 30 days, per +[CONTRIBUTOR_LADDER.md's Recording a Role Change](CONTRIBUTOR_LADDER.md#recording-a-role-change); +"Independent" is written out in full for someone with no employer tied to +their contribution, so an empty cell always means missing data rather +than no affiliation. ## Emeritus Maintainers diff --git a/README.md b/README.md index 9a3072e..64445ba 100644 --- a/README.md +++ b/README.md @@ -10,85 +10,48 @@ project: - [Contributing guidelines](./CONTRIBUTING.md) - [AI Policy](./AI_POLICY.md) - [List of Maintainers](./MAINTAINERS.md) -- [List of Component owners](./COMPONENT-OWNERS.md) -- [List of Contributors](./CONTRIBUTORS.md) +- [Contributor Ladder](./CONTRIBUTOR_LADDER.md) +- [Subprojects & Component Owners](./subprojects/README.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 +Component Owners and Contributors are listed per component, in each +repository's own `COMPONENT_OWNERS.md` and `CONTRIBUTORS.md`, next to the +people who vote on them, rather than in one org-wide list here. Those +files are generated from +[`cnpg-infra`](https://github.com/cloudnative-pg/cnpg-infra)'s +`repo-tiers.yaml` and are being landed repository by repository; until a +given repository has one, `repo-tiers.yaml` is the record for it. -Standardized images built for security, minimal footprint, and CNPG compatibility. +## Table of Contents -| 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`, `.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 Subprojects section](./GOVERNANCE.md#individual-subproject-governance)), +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. | +| [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. | -### Testing & Automation +## Repositories -Tools dedicated to CI/CD, resilience testing, and GitHub Actions development. +CloudNativePG's repositories are grouped into four subprojects, defined in +[GOVERNANCE.md's Subprojects section](./GOVERNANCE.md#individual-subproject-governance). The full +repository listing, descriptions, and component ownership are kept in the +[subprojects/](./subprojects/README.md) folder, one file per subproject, not +duplicated here. -| 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. | +- [Core](./subprojects/core.md) +- [Supply Chain](./subprojects/supply-chain.md) +- [Community, Docs & Ecosystem](./subprojects/community-ecosystem.md) +- [Extensibility](./subprojects/extensibility.md) diff --git a/subprojects/README.md b/subprojects/README.md new file mode 100644 index 0000000..ed2ec0a --- /dev/null +++ b/subprojects/README.md @@ -0,0 +1,141 @@ +# CloudNativePG Subprojects + +> [!NOTE] +> The subproject structure and its four committees are adopted per +> [GOVERNANCE.md](../GOVERNANCE.md); what is still rolling out is the +> repository access behind them (see the note under +> [GitHub Teams](#github-teams) below). The repository listings themselves +> reflect which repositories exist in each subproject; who owns them is +> recorded in [MAINTAINERS.md](../MAINTAINERS.md) and in each component's +> own `COMPONENT_OWNERS.md`, not here. + +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 with a short description. Subprojects themselves, and the access/voting +rights each role carries, are defined in +[GOVERNANCE.md's Subprojects section](../GOVERNANCE.md#individual-subproject-governance), not +here. Who owns what is recorded in two places, neither of them this +folder: [MAINTAINERS.md](../MAINTAINERS.md) lists each subproject's +maintainer committee, and each component's own `COMPONENT_OWNERS.md` +lists that repository's Component Owners, generated from +[`cnpg-infra`](https://github.com/cloudnative-pg/cnpg-infra)'s +`repo-tiers.yaml` alongside the `-owners` team that grants them +access. The Contributor tier is recorded the same way, in each +repository's own `CONTRIBUTORS.md`, and only where a repository has any. + +- [Core](core.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 falls under that subproject's own +maintainer committee, with any additional named Component Owner recorded +in that repository's own `COMPONENT_OWNERS.md` as above, not here. The +committee's authority is what this document set establishes; the +[GitHub Team](#github-teams) that enforces it holds `Maintain` on those +repositories, granted by `cnpg-infra` from each repository's subproject +classification. Path-scoped `CODEOWNERS` review-routing (a Component Owner +tagging a Contributor for review purposes, an operational choice that +carries no vote and no CNPG Organization Member status; see +[CONTRIBUTOR_LADDER.md's Component Owner section](../CONTRIBUTOR_LADDER.md#component-owner)) +is tracked at full fidelity in +[`cnpg-infra`'s `componentowners-policy.yaml`](https://github.com/cloudnative-pg/cnpg-infra/blob/main/componentowners-policy.yaml) +instead. + +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#individual-subproject-governance)). + +Which changes to these files need a governance vote and which are routine +editorial work is defined in +[GOVERNANCE.md's Subprojects section](../GOVERNANCE.md#individual-subproject-governance), not +restated here. Each `subprojects/*.md` file, other than this index, is scoped in +`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. Each +of those lines also carries `@cloudnative-pg/governance-owners`, this +repo's own owners team, so review routing works while all four committees +still hold the same five people. This index itself stays on the `@cloudnative-pg/governance-owners` +fallback permanently, since it isn't owned by any single subproject. + +## GitHub Teams + +Why a GitHub Team can never be the public record of who holds authority, +and why [MAINTAINERS.md](../MAINTAINERS.md) is, is covered in +[GOVERNANCE.md's GitHub Teams and Communication Channels section](../GOVERNANCE.md#github-teams-and-communication-channels). +This section is the operational half of that: the team names themselves. +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 | +| :---- | :---- | :---- | +| `-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) | Infrastructure Team, delegated by Steering (see [GOVERNANCE.md's Infrastructure Administration section](../GOVERNANCE.md#infrastructure-administration)) | `Admin` on every repository | +| `steering-committee` | Steering Committee | No repo access of its own; Admin on the org-control repos already comes from `admins` above. Its role is being the electorate for Steering-scoped [`.gitvote.yml`](../.gitvote.yml) profiles (`default`, `governance`) | +| `core-maintainers` | Core committee | `Maintain` on the [Core](core.md) repositories; `Write` on this repo, so its `CODEOWNERS` line is honored | +| `supply-chain-maintainers` | Supply Chain committee | `Maintain` on the [Supply Chain](supply-chain.md) repositories; `Write` on this repo, so its `CODEOWNERS` line is honored | +| `community-ecosystem-maintainers` | Community, Docs & Ecosystem committee | `Maintain` on the [Community, Docs & Ecosystem](community-ecosystem.md) repositories; `Write` on this repo, so its `CODEOWNERS` line is honored | +| `extensibility-maintainers` | Extensibility committee | `Maintain` on the [Extensibility](extensibility.md) repositories; `Write` on this repo, so its `CODEOWNERS` line is honored | + +The `Maintain` grant is not listed repository by repository: `cnpg-infra`'s +`org-policy.yaml` sets `subproject_committee_permission: maintain`, and each +repository's `subproject` field in `repo-tiers.yaml` names the committee +team that receives it, so a repository is covered the day it is classified. +The org-control repositories have no subproject and grant no committee team +anything. + +Team membership must mirror the rosters in MAINTAINERS.md; when a roster +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:** 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 layered on top of that per-repo one. All four exist on GitHub and +> match the rosters in [MAINTAINERS.md](../MAINTAINERS.md), tracked in +> `cnpg-infra/org-policy.yaml`'s `subproject_committees` section and edited +> by hand rather than auto-synced, so a roster change needs the GitHub team +> reconciled in the same pass. Each team is also granted `write` on this +> repo (`cnpg-infra`'s `repo-policy.yaml`), without which GitHub ignores +> its `CODEOWNERS` lines entirely. + +## 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 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..070b4e7 --- /dev/null +++ b/subprojects/community-ecosystem.md @@ -0,0 +1,21 @@ +# Community, Docs & Ecosystem + +User-facing resources and ecosystem integration: the [cloudnative-pg.io](https://cloudnative-pg.io/) +website, documentation, brand assets, observability and UI integrations +(Grafana, Headlamp), and other community-facing tooling. See the +[subprojects index](README.md) for how this +fits into the wider structure, and [GOVERNANCE.md](../GOVERNANCE.md#individual-subproject-governance) +for how subprojects are defined. + +> See [subprojects/README.md](README.md) for who owns these repositories +> and this file's own edit rights. + +| 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. | +| [artwork](https://github.com/cloudnative-pg/artwork) | Logos and brand assets for CloudNativePG. | +| [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. | +| [cnpg-headlamp-plugin](https://github.com/cloudnative-pg/cnpg-headlamp-plugin) | Headlamp plugin for managing CloudNativePG clusters from the Kubernetes UI. | +| [webtest](https://github.com/cloudnative-pg/webtest) | A simple PostgreSQL stress tool. | diff --git a/subprojects/core.md b/subprojects/core.md new file mode 100644 index 0000000..d70ade4 --- /dev/null +++ b/subprojects/core.md @@ -0,0 +1,22 @@ +# Core + +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). Primarily the maintainers' responsibility; +path-level review-routing within the `cloudnative-pg` component is tracked +in [`cnpg-infra`'s `componentowners-policy.yaml`](https://github.com/cloudnative-pg/cnpg-infra/blob/main/componentowners-policy.yaml), +not here (see [GOVERNANCE.md's Subprojects section](../GOVERNANCE.md#individual-subproject-governance)). +See the [subprojects index](README.md) for how this fits +into the wider structure, and [GOVERNANCE.md](../GOVERNANCE.md#individual-subproject-governance) +for how subprojects are defined. + +> See [subprojects/README.md](README.md) for who owns these repositories +> and this file's own edit rights, both apply here unchanged. + +| Repository | Description | +| --- | --- | +| [cloudnative-pg](https://github.com/cloudnative-pg/cloudnative-pg) | The main Kubernetes Operator for PostgreSQL. | +| [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). | diff --git a/subprojects/extensibility.md b/subprojects/extensibility.md new file mode 100644 index 0000000..037ab39 --- /dev/null +++ b/subprojects/extensibility.md @@ -0,0 +1,76 @@ +# Extensibility + +The interfaces, modules, and standalone tooling that let CloudNativePG and +PostgreSQL be extended or operated on without changing the operator's core, +including the plugin-based backup and recovery ecosystem +(`plugin-barman-cloud`, `klio`) and the libraries behind it, 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#individual-subproject-governance) for how subprojects are +defined. + +> See [subprojects/README.md](README.md) for who owns these repositories +> 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 or Supply Chain. + +`barman-cloud`, the library `plugin-barman-cloud` wraps, sits here with the +plugin rather than under Supply Chain: the second bullet above is for a +library reused across several plugins and independent of any one of them, +and this one supports a single plugin. It was previously listed under +[Core](core.md), on the grounds that the operator still consumes it +directly for native backup and restore; it moved here as a routine +editorial change, ahead of that native support being removed, rather than +waiting for it. + +## 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. | +| [barman-cloud](https://github.com/cloudnative-pg/barman-cloud) | Go library for interacting with Barman Cloud object stores, wrapped by `plugin-barman-cloud` and still used by the operator's native backup support. | +| [klio](https://github.com/cloudnative-pg/klio) | Multi-Tiered Backup and Recovery Plugin for CloudNativePG. | +| [cnpg-i-hello-world](https://github.com/cloudnative-pg/cnpg-i-hello-world) | A simplified template/example for building new plugins. | + +## External Dependencies + +Forks of external upstream projects that a component above depends on. +Not CloudNativePG-authored code, so it doesn't follow the same ownership +model as the rest of this file (see the note below). + +| Repository | Description | +| --- | --- | +| [kopia](https://github.com/cloudnative-pg/kopia) | Fork of the upstream [kopia/kopia](https://github.com/kopia/kopia), the deduplication/backup engine `klio` depends on. | + +> `kopia` is a fork of an external project, not a CloudNativePG-authored +> codebase: there's no ongoing feature review to gate with `CODEOWNERS`, +> just occasional pushes to keep it in sync with what `klio` needs. Its +> default branch is `klio`, not `main`. + +## 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 | +| --- | --- | +| [postgres-keycloak-oauth-validator](https://github.com/cloudnative-pg/postgres-keycloak-oauth-validator) | A PostgreSQL module for OAuth2/Keycloak token validation. | diff --git a/subprojects/supply-chain.md b/subprojects/supply-chain.md new file mode 100644 index 0000000..cd52a41 --- /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#individual-subproject-governance) for how subprojects are +defined. + +> See [subprojects/README.md](README.md) for who owns these repositories +> 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 | +| --- | --- | +| [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. | +| [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 (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 | +| --- | --- | +| [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. | + +## 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: `api` and `machinery` +are the operator's own logic split out for Go module reasons (see +[Core](core.md)), and `barman-cloud` supports a single plugin rather than +being reused across several, so it sits with that plugin under +[Extensibility](extensibility.md). + +| Repository | Description | +| --- | --- | +| [daggerverse](https://github.com/cloudnative-pg/daggerverse) | Dagger modules for portable CI/CD workflows. | + +> `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#individual-subproject-governance) +> and [subprojects/README.md](README.md). + +## Testing & Automation + +Tools dedicated to CI/CD, resilience testing, and GitHub Actions development. + +| 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. |