docs: add AGENTS.md + authorization enforcement gates
NEW: AGENTS.md — complete agent workflow documentation - Step-by-step PR workflow for all agents - Authorization matrix (who can change which contracts) - Emergency bypass procedure - Quick start commands NEW: scripts/prose-auth-check.sh — authorization enforcement - Blocks unauthorized agents from changing CRITICAL contracts - infrastructure-control, proxmox-monitor: abiba only - hermes-config-template: abiba, mumuni, tanko - zulip-health: abiba, mumuni - All scripts: abiba only - Fails CI if unauthorized changes detected UPDATED: .gitea/workflows/pr-pipeline.yaml - Added Stage 0: auth check (runs first) - Added gate job that confirms all 4 checks passed - Expanded trigger paths to include scripts/*.sh UPDATED: branch protection — now requires 4 contexts: pr-pipeline / auth, validate, lint, ai-review
This commit is contained in:
Executable
+68
@@ -0,0 +1,68 @@
|
||||
#!/bin/bash
|
||||
# prose-auth-check.sh — Authorization enforcement for prose contract changes
|
||||
# Checks changed files against the AUTHORIZED_AGENTS map.
|
||||
# Fails if an unauthorized agent changes a restricted contract.
|
||||
set -euo pipefail
|
||||
|
||||
echo "╔═══════════════════════════════════╗"
|
||||
echo "║ Authorization Enforcement ║"
|
||||
echo "╚═══════════════════════════════════╝"
|
||||
echo ""
|
||||
|
||||
# Authorized agents for restricted contracts
|
||||
# Format: contract_pattern|authorized_agents (comma-separated)
|
||||
declare -A RESTRICTED
|
||||
RESTRICTED["infrastructure-control.prose.md"]="abiba"
|
||||
RESTRICTED["proxmox-monitor.prose.md"]="abiba"
|
||||
RESTRICTED["hermes-config-template.prose.md"]="abiba,mumuni,tanko"
|
||||
RESTRICTED["zulip-health.prose.md"]="abiba,mumuni"
|
||||
RESTRICTED["scripts/pm2-self-heal.sh"]="abiba"
|
||||
RESTRICTED["scripts/prose-lint.sh"]="abiba"
|
||||
RESTRICTED["scripts/prose-ai-review.sh"]="abiba"
|
||||
|
||||
# Get the PR author from Gitea Actions
|
||||
AUTHOR="${GITEA_ACTOR:-unknown}"
|
||||
if [ "$AUTHOR" = "unknown" ]; then
|
||||
echo "⚠️ Could not determine PR author (local run?). Skipping auth check."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "PR author: $AUTHOR"
|
||||
echo ""
|
||||
|
||||
# Get changed files from the PR
|
||||
CHANGED=$(git diff --name-only origin/main...HEAD 2>/dev/null || git diff --name-only HEAD~1 2>/dev/null || echo "")
|
||||
|
||||
if [ -z "$CHANGED" ]; then
|
||||
echo "No changed files to check."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
FAILED=0
|
||||
|
||||
for file in $CHANGED; do
|
||||
# Check if this file is restricted
|
||||
for pattern in "${!RESTRICTED[@]}"; do
|
||||
if [[ "$file" == *"$pattern"* ]]; then
|
||||
ALLOWED="${RESTRICTED[$pattern]}"
|
||||
if echo "$ALLOWED" | grep -qw "$AUTHOR"; then
|
||||
echo " ✅ $file — $AUTHOR is authorized"
|
||||
else
|
||||
echo " 🚫 $file — $AUTHOR is NOT authorized (allowed: $ALLOWED)"
|
||||
FAILED=1
|
||||
fi
|
||||
break
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
echo ""
|
||||
if [ $FAILED -eq 1 ]; then
|
||||
echo "❌ AUTHORIZATION FAILED — unauthorized agent attempted to change restricted contracts"
|
||||
echo ""
|
||||
echo "If this is an emergency fix, add [EMERGENCY] to the PR title."
|
||||
echo "Otherwise, ask an authorized agent ($ALLOWED) to make this change."
|
||||
exit 1
|
||||
else
|
||||
echo "✅ Authorization check passed"
|
||||
fi
|
||||
Reference in New Issue
Block a user