From 9bd9dea73b876116cd8ba2a4ae1a822cb0a7fb86 Mon Sep 17 00:00:00 2001 From: damaz91 Date: Tue, 8 Sep 2026 21:02:31 +0000 Subject: [PATCH 1/2] feat(governance): update governance rules to use domain tech councils - Update team_hierarchy across all repository governance rule configurations (.github, conformance, js-sdk, meeting-minutes, python-sdk, samples, ucp, and ucp-schema) to replace legacy tech-council with shopping-tech-council, food-tech-council, lodging-tech-council, and payments-tech-council at Level 3. - Update meeting-minutes-rules.yml to reference shopping-tech-council. - Update pr_validator.py to gracefully handle 404 (team not found) when fetching team memberships from GitHub, preventing CI breaks during team renames and migrations. - Update documentation in README.md and validation_report.md. - Add test coverage in test_pr_validator.py. --- org-tools/governance/README.md | 7 +++-- .../governance/docs/validation_report.md | 10 +++---- org-tools/governance/rules/.github-rules.yml | 5 +++- .../governance/rules/conformance-rules.yml | 7 +++-- org-tools/governance/rules/js-sdk-rules.yml | 7 +++-- .../rules/meeting-minutes-rules.yml | 11 ++++--- .../governance/rules/python-sdk-rules.yml | 7 +++-- org-tools/governance/rules/samples-rules.yml | 7 +++-- org-tools/governance/rules/ucp-rules.yml | 9 ++++-- .../governance/rules/ucp-schema-rules.yml | 7 +++-- org-tools/governance/scripts/pr_validator.py | 13 +++++++-- .../governance/tests/test_pr_validator.py | 29 +++++++++++++++++-- 12 files changed, 89 insertions(+), 30 deletions(-) diff --git a/org-tools/governance/README.md b/org-tools/governance/README.md index 86d6674..5812b22 100644 --- a/org-tools/governance/README.md +++ b/org-tools/governance/README.md @@ -47,7 +47,10 @@ Defines hierarchical roles with integer clearance tiers. Approvals from higher l team_hierarchy: devops-maintainers: 1 maintainers: 2 - tech-council: 3 + shopping-tech-council: 3 + food-tech-council: 3 + lodging-tech-council: 3 + payments-tech-council: 3 governance-council: 4 ``` @@ -79,7 +82,7 @@ rules: patterns: - "source/**" requires: - - min_team: "tech-council" + - min_team: "shopping-tech-council" min_approvals: 1 ``` diff --git a/org-tools/governance/docs/validation_report.md b/org-tools/governance/docs/validation_report.md index ca66ccf..6da171e 100644 --- a/org-tools/governance/docs/validation_report.md +++ b/org-tools/governance/docs/validation_report.md @@ -55,7 +55,7 @@ This section aggregates and deduplicates all requirements across all changed fil If your PR modifies multiple files, the validator doesn't just add up all the approvals blindly. Instead, it uses a **Venn Diagram model**: - If multiple modified files require approval from the **same team or hierarchical level**, the requirements are merged. -- The validator keeps the **maximum** number of approvals (`min_approvals`) required by any single file for that target. E.g., if File A requires 1 approval from `tech-council` and File B requires 2 approvals from `tech-council`, the global requirement is merged to require **2 approvals** from `tech-council` (not 3). +- The validator keeps the **maximum** number of approvals (`min_approvals`) required by any single file for that target. E.g., if File A requires 1 approval from `shopping-tech-council` and File B requires 2 approvals from `shopping-tech-council`, the global requirement is merged to require **2 approvals** from `shopping-tech-council` (not 3). ### Understanding Requirement Items @@ -69,7 +69,7 @@ Each requirement in the summary is formatted with detailed progress: #### Key Fields: -1. **Requirement Line**: Describes the rule (e.g., `* **2 approvals** from team 'tech-council'` or `* **1 approval** from team 'tech-council' or higher in the UCP governance hierarchy`). +1. **Requirement Line**: Describes the rule (e.g., `* **2 approvals** from team 'shopping-tech-council'` or `* **1 approval** from team 'shopping-tech-council' or higher in the UCP governance hierarchy`). 2. **Met Line**: - **🟢 Yes**: The requirement is fully satisfied. - **🔴 No**: The requirement is not yet satisfied. @@ -112,11 +112,11 @@ For example, if the hierarchy is defined as: 1. `devops-maintainers` (Level 1) 2. `maintainers` (Level 2) -3. `tech-council` (Level 3) +3. Domain Tech Councils (`shopping-tech-council`, `food-tech-council`, `lodging-tech-council`, `payments-tech-council`) (Level 3) 4. `governance-council` (Level 4) -- A requirement for **`team 'maintainers' or higher in the UCP governance hierarchy`** (Level 2+) can be satisfied by approvals from members of `maintainers`, `tech-council`, or `governance-council`. -- A requirement for **`team 'tech-council' or higher in the UCP governance hierarchy`** (Level 3+) can be satisfied by approvals from members of `tech-council` or `governance-council`. +- A requirement for **`team 'maintainers' or higher in the UCP governance hierarchy`** (Level 2+) can be satisfied by approvals from members of `maintainers`, any Tech Council (`shopping-tech-council`, `food-tech-council`, `lodging-tech-council`, `payments-tech-council`), or `governance-council`. +- A requirement for **`team 'shopping-tech-council' or higher in the UCP governance hierarchy`** (Level 3+) can be satisfied by approvals from members of any Tech Council or `governance-council`. - A requirement for an exact team (e.g., **`team 'devops-maintainers'`**) must be approved by an explicit member of that team, regardless of hierarchy. --- diff --git a/org-tools/governance/rules/.github-rules.yml b/org-tools/governance/rules/.github-rules.yml index 73bde4f..18fbe10 100644 --- a/org-tools/governance/rules/.github-rules.yml +++ b/org-tools/governance/rules/.github-rules.yml @@ -51,5 +51,8 @@ proxy_reviewers: team_hierarchy: devops-maintainers: 1 maintainers: 2 - tech-council: 3 + shopping-tech-council: 3 + food-tech-council: 3 + lodging-tech-council: 3 + payments-tech-council: 3 governance-council: 4 diff --git a/org-tools/governance/rules/conformance-rules.yml b/org-tools/governance/rules/conformance-rules.yml index 57df211..c50a56b 100644 --- a/org-tools/governance/rules/conformance-rules.yml +++ b/org-tools/governance/rules/conformance-rules.yml @@ -29,7 +29,7 @@ rules: - "shopping-agent-test.json" - "test_data/**" requires: - # Grants access to devops (L1), maintainers (L2), tech-council (L3), + # Grants access to devops (L1), maintainers (L2), tech councils (L3), # and governance-council (L4) - min_team: "devops-maintainers" min_approvals: 2 @@ -47,5 +47,8 @@ proxy_reviewers: team_hierarchy: devops-maintainers: 1 maintainers: 2 - tech-council: 3 + shopping-tech-council: 3 + food-tech-council: 3 + lodging-tech-council: 3 + payments-tech-council: 3 governance-council: 4 diff --git a/org-tools/governance/rules/js-sdk-rules.yml b/org-tools/governance/rules/js-sdk-rules.yml index be7b2f2..ee03f1e 100644 --- a/org-tools/governance/rules/js-sdk-rules.yml +++ b/org-tools/governance/rules/js-sdk-rules.yml @@ -36,7 +36,7 @@ rules: - "tsconfig.json" - "tsconfig.types.json" requires: - # Grants access to devops (L1), maintainers (L2), tech-council (L3), + # Grants access to devops (L1), maintainers (L2), tech councils (L3), # and governance-council (L4) - min_team: "devops-maintainers" min_approvals: 1 @@ -54,5 +54,8 @@ proxy_reviewers: team_hierarchy: devops-maintainers: 1 maintainers: 2 - tech-council: 3 + shopping-tech-council: 3 + food-tech-council: 3 + lodging-tech-council: 3 + payments-tech-council: 3 governance-council: 4 diff --git a/org-tools/governance/rules/meeting-minutes-rules.yml b/org-tools/governance/rules/meeting-minutes-rules.yml index 31864f4..44a4425 100644 --- a/org-tools/governance/rules/meeting-minutes-rules.yml +++ b/org-tools/governance/rules/meeting-minutes-rules.yml @@ -20,8 +20,8 @@ rules: patterns: - "tc/**" requires: - # Grants access to tech-council (L3) and governance-council (L4) - - min_team: "tech-council" + # Grants access to Tech Councils (L3) and governance-council (L4) + - min_team: "shopping-tech-council" min_approvals: 1 # --------------------------------------------------------- @@ -48,7 +48,7 @@ rules: - "CONTRIBUTING.md" - "SECURITY.md" requires: - # Grants access to devops (L1), maintainers (L2), tech-council (L3), + # Grants access to devops (L1), maintainers (L2), tech councils (L3), # and governance-council (L4) - min_team: "devops-maintainers" min_approvals: 1 @@ -66,5 +66,8 @@ proxy_reviewers: team_hierarchy: devops-maintainers: 1 maintainers: 2 - tech-council: 3 + shopping-tech-council: 3 + food-tech-council: 3 + lodging-tech-council: 3 + payments-tech-council: 3 governance-council: 4 diff --git a/org-tools/governance/rules/python-sdk-rules.yml b/org-tools/governance/rules/python-sdk-rules.yml index 7acc724..1e4fa90 100644 --- a/org-tools/governance/rules/python-sdk-rules.yml +++ b/org-tools/governance/rules/python-sdk-rules.yml @@ -32,7 +32,7 @@ rules: - "tests/**" - "**/*.py" requires: - # Grants access to devops (L1), maintainers (L2), tech-council (L3), + # Grants access to devops (L1), maintainers (L2), tech councils (L3), # and governance-council (L4) - min_team: "devops-maintainers" min_approvals: 1 @@ -50,5 +50,8 @@ proxy_reviewers: team_hierarchy: devops-maintainers: 1 maintainers: 2 - tech-council: 3 + shopping-tech-council: 3 + food-tech-council: 3 + lodging-tech-council: 3 + payments-tech-council: 3 governance-council: 4 diff --git a/org-tools/governance/rules/samples-rules.yml b/org-tools/governance/rules/samples-rules.yml index f82ad80..6d718e3 100644 --- a/org-tools/governance/rules/samples-rules.yml +++ b/org-tools/governance/rules/samples-rules.yml @@ -30,7 +30,7 @@ rules: - "a2a/**" - "rest/**" requires: - # Grants access to devops (L1), maintainers (L2), tech-council (L3), + # Grants access to devops (L1), maintainers (L2), tech councils (L3), # and governance-council (L4) - min_team: "devops-maintainers" min_approvals: 2 @@ -48,5 +48,8 @@ proxy_reviewers: team_hierarchy: devops-maintainers: 1 maintainers: 2 - tech-council: 3 + shopping-tech-council: 3 + food-tech-council: 3 + lodging-tech-council: 3 + payments-tech-council: 3 governance-council: 4 diff --git a/org-tools/governance/rules/ucp-rules.yml b/org-tools/governance/rules/ucp-rules.yml index 85021b9..64acb3e 100644 --- a/org-tools/governance/rules/ucp-rules.yml +++ b/org-tools/governance/rules/ucp-rules.yml @@ -32,7 +32,7 @@ rules: patterns: - "docs/specification/**" requires: - # Grants access to maintainers (L2), tech-council (L3) and + # Grants access to maintainers (L2), tech councils (L3) and # governance-council (L4) - min_team: "maintainers" min_approvals: 2 @@ -69,7 +69,7 @@ rules: - "docs/specification/**" # Covered by Documentation Specification - ".github/CODEOWNERS" requires: - # Grants access to devops (L1), maintainers (L2), tech-council (L3), + # Grants access to devops (L1), maintainers (L2), tech councils (L3), # and governance-council (L4) - min_team: "devops-maintainers" min_approvals: 2 @@ -87,5 +87,8 @@ proxy_reviewers: team_hierarchy: devops-maintainers: 1 maintainers: 2 - tech-council: 3 + shopping-tech-council: 3 + food-tech-council: 3 + lodging-tech-council: 3 + payments-tech-council: 3 governance-council: 4 diff --git a/org-tools/governance/rules/ucp-schema-rules.yml b/org-tools/governance/rules/ucp-schema-rules.yml index 08a35a9..b3dc3c3 100644 --- a/org-tools/governance/rules/ucp-schema-rules.yml +++ b/org-tools/governance/rules/ucp-schema-rules.yml @@ -31,7 +31,7 @@ rules: - "src/**" - "tests/**" requires: - # Grants access to devops (L1), maintainers (L2), tech-council (L3), + # Grants access to devops (L1), maintainers (L2), tech councils (L3), # and governance-council (L4) - min_team: "devops-maintainers" min_approvals: 2 @@ -49,5 +49,8 @@ proxy_reviewers: team_hierarchy: devops-maintainers: 1 maintainers: 2 - tech-council: 3 + shopping-tech-council: 3 + food-tech-council: 3 + lodging-tech-council: 3 + payments-tech-council: 3 governance-council: 4 diff --git a/org-tools/governance/scripts/pr_validator.py b/org-tools/governance/scripts/pr_validator.py index fb7648d..8e1bdcc 100755 --- a/org-tools/governance/scripts/pr_validator.py +++ b/org-tools/governance/scripts/pr_validator.py @@ -73,9 +73,16 @@ def fetch_team_memberships( members = {m.login for m in team.get_members()} members_by_team[team_slug] = members except GithubException as e: - raise RuntimeError( - f"Could not fetch members for team '{team_slug}': {e}" - ) from e + if e.status == 404: + print( + f"⚠️ WARNING: Team '{team_slug}' not found in organization '{org_name}'. Treating as empty.", + file=sys.stderr, + ) + members_by_team[team_slug] = set() + else: + raise RuntimeError( + f"Could not fetch members for team '{team_slug}': {e}" + ) from e return TeamMemberships.create( members_by_team=members_by_team, teams=config.teams ) diff --git a/org-tools/governance/tests/test_pr_validator.py b/org-tools/governance/tests/test_pr_validator.py index 728817e..5816f31 100644 --- a/org-tools/governance/tests/test_pr_validator.py +++ b/org-tools/governance/tests/test_pr_validator.py @@ -1008,13 +1008,13 @@ def test_fetch_org_fails(self): self.assertIn("Failed to fetch organization 'my-org'", str(ctx.exception)) def test_fetch_team_fails(self): - """Test fetch_team_memberships raises RuntimeError when a team fetch fails.""" + """Test fetch_team_memberships raises RuntimeError when a team fetch fails with non-404.""" mock_github = MagicMock() mock_org = MagicMock() mock_github.get_organization.return_value = mock_org mock_org.get_team_by_slug.side_effect = MockGithubException( - status=404, data={"message": "Team Not Found"} + status=500, data={"message": "Internal Server Error"} ) config = GovernanceConfig( @@ -1030,6 +1030,31 @@ def test_fetch_team_fails(self): self.assertIn("Could not fetch members for team 'devops'", str(ctx.exception)) + def test_fetch_team_not_found_handled(self): + """Test fetch_team_memberships handles 404 by treating team as empty with warning.""" + mock_github = MagicMock() + mock_org = MagicMock() + mock_github.get_organization.return_value = mock_org + + mock_org.get_team_by_slug.side_effect = MockGithubException( + status=404, data={"message": "Team Not Found"} + ) + + config = GovernanceConfig( + teams={"shopping-tech-council": Team("shopping-tech-council", 3)}, + rules=[], + fallback=[], + proxy_reviewers=set(), + ) + + github_client = GitHubClient(mock_github) + with patch("sys.stderr"): + memberships = github_client.fetch_team_memberships("my-org", config) + self.assertEqual( + memberships.members_by_team, + {Team("shopping-tech-council", 3): set()}, + ) + class TestPRValidatorMain(unittest.TestCase): """Tests for the main function of pr_validator.""" From d0ff7705af1ce169e476e35e273ae15a72e96490 Mon Sep 17 00:00:00 2001 From: damaz91 Date: Wed, 9 Sep 2026 16:22:13 +0000 Subject: [PATCH 2/2] fix(governance): add vertical-specific meeting-minutes rules and retain tech-council in hierarchy --- org-tools/governance/README.md | 1 + .../governance/docs/validation_report.md | 4 +-- org-tools/governance/rules/.github-rules.yml | 1 + .../governance/rules/conformance-rules.yml | 1 + org-tools/governance/rules/js-sdk-rules.yml | 1 + .../rules/meeting-minutes-rules.yml | 36 ++++++++++++++++--- .../governance/rules/python-sdk-rules.yml | 1 + org-tools/governance/rules/samples-rules.yml | 1 + org-tools/governance/rules/ucp-rules.yml | 1 + .../governance/rules/ucp-schema-rules.yml | 1 + 10 files changed, 41 insertions(+), 7 deletions(-) diff --git a/org-tools/governance/README.md b/org-tools/governance/README.md index 5812b22..aae46f1 100644 --- a/org-tools/governance/README.md +++ b/org-tools/governance/README.md @@ -47,6 +47,7 @@ Defines hierarchical roles with integer clearance tiers. Approvals from higher l team_hierarchy: devops-maintainers: 1 maintainers: 2 + tech-council: 3 shopping-tech-council: 3 food-tech-council: 3 lodging-tech-council: 3 diff --git a/org-tools/governance/docs/validation_report.md b/org-tools/governance/docs/validation_report.md index 6da171e..29cd76d 100644 --- a/org-tools/governance/docs/validation_report.md +++ b/org-tools/governance/docs/validation_report.md @@ -112,10 +112,10 @@ For example, if the hierarchy is defined as: 1. `devops-maintainers` (Level 1) 2. `maintainers` (Level 2) -3. Domain Tech Councils (`shopping-tech-council`, `food-tech-council`, `lodging-tech-council`, `payments-tech-council`) (Level 3) +3. `tech-council` / Domain Tech Councils (`shopping-tech-council`, `food-tech-council`, `lodging-tech-council`, `payments-tech-council`) (Level 3) 4. `governance-council` (Level 4) -- A requirement for **`team 'maintainers' or higher in the UCP governance hierarchy`** (Level 2+) can be satisfied by approvals from members of `maintainers`, any Tech Council (`shopping-tech-council`, `food-tech-council`, `lodging-tech-council`, `payments-tech-council`), or `governance-council`. +- A requirement for **`team 'maintainers' or higher in the UCP governance hierarchy`** (Level 2+) can be satisfied by approvals from members of `maintainers`, any Tech Council (`tech-council`, `shopping-tech-council`, `food-tech-council`, `lodging-tech-council`, `payments-tech-council`), or `governance-council`. - A requirement for **`team 'shopping-tech-council' or higher in the UCP governance hierarchy`** (Level 3+) can be satisfied by approvals from members of any Tech Council or `governance-council`. - A requirement for an exact team (e.g., **`team 'devops-maintainers'`**) must be approved by an explicit member of that team, regardless of hierarchy. diff --git a/org-tools/governance/rules/.github-rules.yml b/org-tools/governance/rules/.github-rules.yml index 18fbe10..6cdffdc 100644 --- a/org-tools/governance/rules/.github-rules.yml +++ b/org-tools/governance/rules/.github-rules.yml @@ -51,6 +51,7 @@ proxy_reviewers: team_hierarchy: devops-maintainers: 1 maintainers: 2 + tech-council: 3 shopping-tech-council: 3 food-tech-council: 3 lodging-tech-council: 3 diff --git a/org-tools/governance/rules/conformance-rules.yml b/org-tools/governance/rules/conformance-rules.yml index c50a56b..edec3a5 100644 --- a/org-tools/governance/rules/conformance-rules.yml +++ b/org-tools/governance/rules/conformance-rules.yml @@ -47,6 +47,7 @@ proxy_reviewers: team_hierarchy: devops-maintainers: 1 maintainers: 2 + tech-council: 3 shopping-tech-council: 3 food-tech-council: 3 lodging-tech-council: 3 diff --git a/org-tools/governance/rules/js-sdk-rules.yml b/org-tools/governance/rules/js-sdk-rules.yml index ee03f1e..a19f5e6 100644 --- a/org-tools/governance/rules/js-sdk-rules.yml +++ b/org-tools/governance/rules/js-sdk-rules.yml @@ -54,6 +54,7 @@ proxy_reviewers: team_hierarchy: devops-maintainers: 1 maintainers: 2 + tech-council: 3 shopping-tech-council: 3 food-tech-council: 3 lodging-tech-council: 3 diff --git a/org-tools/governance/rules/meeting-minutes-rules.yml b/org-tools/governance/rules/meeting-minutes-rules.yml index 44a4425..a323856 100644 --- a/org-tools/governance/rules/meeting-minutes-rules.yml +++ b/org-tools/governance/rules/meeting-minutes-rules.yml @@ -14,16 +14,40 @@ rules: min_approvals: 1 # --------------------------------------------------------- - # Technical Council Minutes + # Technical Council Minutes - Domain Specific # --------------------------------------------------------- - - name: "tech_council_minutes" + - name: "shopping_tech_council_minutes" patterns: - - "tc/**" + - "tc/shopping/**" requires: - # Grants access to Tech Councils (L3) and governance-council (L4) + # Grants access to shopping-tech-council (L3) and governance-council (L4) - min_team: "shopping-tech-council" min_approvals: 1 + - name: "food_tech_council_minutes" + patterns: + - "tc/food/**" + requires: + # Grants access to food-tech-council (L3) and governance-council (L4) + - min_team: "food-tech-council" + min_approvals: 1 + + - name: "lodging_tech_council_minutes" + patterns: + - "tc/lodging/**" + requires: + # Grants access to lodging-tech-council (L3) and governance-council (L4) + - min_team: "lodging-tech-council" + min_approvals: 1 + + - name: "payments_tech_council_minutes" + patterns: + - "tc/payments/**" + requires: + # Grants access to payments-tech-council (L3) and governance-council (L4) + - min_team: "payments-tech-council" + min_approvals: 1 + # --------------------------------------------------------- # Governing Council Minutes # --------------------------------------------------------- @@ -36,7 +60,7 @@ rules: min_approvals: 1 # --------------------------------------------------------- - # Infrastructure, Tooling & General Files + # Infrastructure, Tooling, General Files & Shared Templates # --------------------------------------------------------- - name: "infra_and_tooling" patterns: @@ -47,6 +71,7 @@ rules: - "README.md" - "CONTRIBUTING.md" - "SECURITY.md" + - "tc/*.md" requires: # Grants access to devops (L1), maintainers (L2), tech councils (L3), # and governance-council (L4) @@ -66,6 +91,7 @@ proxy_reviewers: team_hierarchy: devops-maintainers: 1 maintainers: 2 + tech-council: 3 shopping-tech-council: 3 food-tech-council: 3 lodging-tech-council: 3 diff --git a/org-tools/governance/rules/python-sdk-rules.yml b/org-tools/governance/rules/python-sdk-rules.yml index 1e4fa90..4775185 100644 --- a/org-tools/governance/rules/python-sdk-rules.yml +++ b/org-tools/governance/rules/python-sdk-rules.yml @@ -50,6 +50,7 @@ proxy_reviewers: team_hierarchy: devops-maintainers: 1 maintainers: 2 + tech-council: 3 shopping-tech-council: 3 food-tech-council: 3 lodging-tech-council: 3 diff --git a/org-tools/governance/rules/samples-rules.yml b/org-tools/governance/rules/samples-rules.yml index 6d718e3..9caf99a 100644 --- a/org-tools/governance/rules/samples-rules.yml +++ b/org-tools/governance/rules/samples-rules.yml @@ -48,6 +48,7 @@ proxy_reviewers: team_hierarchy: devops-maintainers: 1 maintainers: 2 + tech-council: 3 shopping-tech-council: 3 food-tech-council: 3 lodging-tech-council: 3 diff --git a/org-tools/governance/rules/ucp-rules.yml b/org-tools/governance/rules/ucp-rules.yml index 64acb3e..35db916 100644 --- a/org-tools/governance/rules/ucp-rules.yml +++ b/org-tools/governance/rules/ucp-rules.yml @@ -87,6 +87,7 @@ proxy_reviewers: team_hierarchy: devops-maintainers: 1 maintainers: 2 + tech-council: 3 shopping-tech-council: 3 food-tech-council: 3 lodging-tech-council: 3 diff --git a/org-tools/governance/rules/ucp-schema-rules.yml b/org-tools/governance/rules/ucp-schema-rules.yml index b3dc3c3..5bfd65d 100644 --- a/org-tools/governance/rules/ucp-schema-rules.yml +++ b/org-tools/governance/rules/ucp-schema-rules.yml @@ -49,6 +49,7 @@ proxy_reviewers: team_hierarchy: devops-maintainers: 1 maintainers: 2 + tech-council: 3 shopping-tech-council: 3 food-tech-council: 3 lodging-tech-council: 3