PR Pipeline — Authorize → Validate → Review → Merge / auth (pull_request) Successful in 4s
PR Pipeline — Authorize → Validate → Review → Merge / validate (pull_request) Successful in 1s
PR Pipeline — Authorize → Validate → Review → Merge / lint (pull_request) Successful in 1s
PR Pipeline — Authorize → Validate → Review → Merge / ai-review (pull_request) Successful in 1s
PR Pipeline — Authorize → Validate → Review → Merge / gate (pull_request) Successful in 1s
Tanko migrated from Hermes to DSH (DeepSeek Harness) on 2026-08-27. Update all records that described tanko as a Hermes agent / Hermes runtime: - infra-control: CT 112 tanko platform Hermes -> DSH - zulip-health / zulip-self-heal / zulip-mention-reliability / pi-approval: tanko is on DSH, mumuni remains on Hermes - memory-audit-maintenance: exclude tanko from Hermes roster (uses DSH-native memory) - hermes-config-template / hermes-agent-baseline: remove tanko from Hermes roster, keep LiteLLM key alias 'tanko' - hermes-zulip-plugin / hermes-zulip-restore / build-zulip-plugin: tanko excluded - infrastructure-maintenance: gateways check no longer probes Hermes on tanko CT112 - scripts/daily-infra-report.py: fix CT-ID regression (CT 122->112), report tanko as DSH - scripts/zulip-monitor.sh: stop probing tanko's retired Hermes gateway - scripts/agent-health-check.py: skip Hermes gateway checks for tanko (runtime=dsh) - scripts/prose-auth-check.sh + AGENTS.md: authorize tanko/tanko-bot for its own records Tanko remains CT 112 at 192.168.68.122; infrastructure facts unchanged. Dated/incident records (run logs, migration logs) left intact as history.
69 lines
2.3 KiB
Bash
Executable File
69 lines
2.3 KiB
Bash
Executable File
#!/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,abiba-bot,tanko,tanko-bot,mumuni,mumuni-bot"
|
|
RESTRICTED["proxmox-monitor.prose.md"]="abiba,abiba-bot"
|
|
RESTRICTED["hermes-config-template.prose.md"]="abiba,abiba-bot,mumuni,mumuni-bot,tanko,tanko-bot"
|
|
RESTRICTED["zulip-health.prose.md"]="abiba,abiba-bot,mumuni,mumuni-bot,tanko,tanko-bot"
|
|
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
|