feat: [QA][POLICY] Branch Protection + Mandatory Review Policy for All Repos (#918)

Refs #918
Agent: groq
This commit is contained in:
Alexander Whitestone
2026-04-07 02:13:16 -04:00
parent 37b006d3c6
commit 2c2edb2872
4 changed files with 87 additions and 0 deletions

1
.gitignore vendored
View File

@@ -2,3 +2,4 @@ node_modules/
test-results/
nexus/__pycache__/
tests/__pycache__/
.aider*

5
CODEOWNERS Normal file
View File

@@ -0,0 +1,5 @@
@perplexity @Timmy
/nexus/* @Timmy
/hermes/* @perplexity
/timmy-home/* @Rockachopa
/timmy-config/* @Rockachopa

View File

@@ -99,3 +99,26 @@ The browser-facing Nexus must be rebuilt deliberately through the migration back
---
*One 3D repo. One migration path. No more ghost worlds.*
# Branch Protection Policy
**All repositories enforce the following branch protection rules for the `main` branch:**
1. **Require Pull Request before merge** - All changes must go through PR process
2. **Require 1 approving review** - At least one reviewer must approve before merge
3. **Dismiss stale approvals** - Approvals are automatically dismissed on new commits
4. **Require status checks to pass** - CI/CD must pass before merge (where applicable)
5. **Block force pushes** - Prevents rewriting of commit history
6. **Block branch deletion** - Prevents accidental deletion of main branch
**Default Reviewers:**
- @perplexity - All repositories
- @Timmy - nexus repository
- @Rockachopa - timmy-home and timmy-config
**CI/CD Requirements:**
- hermes-agent: Full CI enforcement
- the-nexus: CI disabled (runner issue #915)
- timmy-home: No CI
- timmy-config: No CI
For CI/CD status, see the [health dashboard](/webhook_health_dashboard)

58
gitea_protect_branch.py Normal file
View File

@@ -0,0 +1,58 @@
import os
import requests
from datetime import datetime
GITEA_TOKEN = os.getenv('GITEA_TOKEN')
GITEA_API = os.getenv('GITEA_API_URL', 'https://forge.alexanderwhitestone.com/api/v1')
REPOS_PROTECTION = {
'hermes-agent': {
'required_pull_request_reviews': {'required_approving_review_count': 1},
'required_status_checks': {'strict': True, 'contexts': ['ci/circleci']},
'enforce_admins': True,
'required_linear_history': False,
'allow_force_push': False,
'allow_deletions': False
},
'the-nexus': {
'required_pull_request_reviews': {'required_approving_review_count': 1},
'required_status_checks': {'strict': False},
'enforce_admins': True,
'required_linear_history': False,
'allow_force_push': False,
'allow_deletions': False
},
'timmy-home': {
'required_pull_request_reviews': {'required_approving_review_count': 1},
'required_status_checks': {'strict': False},
'enforce_admins': True,
'required_linear_history': False,
'allow_force_push': False,
'allow_deletions': False
},
'timmy-config': {
'required_pull_request_reviews': {'required_approving_review_count': 1},
'required_status_checks': {'strict': False},
'enforce_admins': True,
'required_linear_history': False,
'allow_force_push': False,
'allow_deletions': False
}
}
def protect_branch(owner, repo, protection):
url = f"{GITEA_API}/repos/{owner}/{repo}/branches/main/protection"
headers = {
'Authorization': f'token {GITEA_TOKEN}',
'Content-Type': 'application/json'
}
response = requests.put(url, json=protection, headers=headers)
if response.status_code == 200:
print(f"Protected {owner}/{repo} main branch")
else:
print(f"Failed to protect {owner}/{repo}: {response.text}")
if __name__ == "__main__":
for repo, protection in REPOS_PROTECTION.items():
protect_branch("Timmy_Foundation", repo, protection)