/
kochenov
/
uni
Обзор
Документация
Войти
/
kochenov
/
uni
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
main
scripts/git_commit_guard.sh
107 строк
4 KB
Dmitry Kochenov
Initial commit: UMP base structure
16 июл 2026, 21:14
16 июл 2026, 21:14
86b4d0e
Код
Авторство
О чём код?
#!/usr/bin/env bash # Pre-commit guard: блокирует commit в main вне finalize_step.py # И блокирует изменения .agent/ и scripts/ без явного разрешения # # Аудит v21: список защищённых путей теперь в .agent/immutable.txt # # Установка: # cp scripts/git_commit_guard.sh .git/hooks/pre-commit # chmod +x .git/hooks/pre-commit set -euo pipefail branch="$(git branch --show-current 2>/dev/null || echo '')" # 1. Блокировка прямых коммитов в main if [ "$branch" = "main" ]; then if [ -z "${STEP_FINALIZER_ACTIVE:-}" ]; then cat >&2 <<'EOF' БЛОКИРОВКА: прямой commit в main вне scripts/finalize_step.py запрещён. Если ты finalize_step.py — установи STEP_FINALIZER_ACTIVE=1 перед git commit: export STEP_FINALIZER_ACTIVE=1 git commit -F <file> Если ты агент — НЕ коммить в main. Используй feature-ветку: git checkout -b feature/step-X.Y-<slug> git commit -F <file> EOF exit 1 fi fi # 2. Защита immutable-файлов от изменений агентом (аудит v21) # Список защищённых путей — в .agent/immutable.txt # Если файл не существует — используем встроенный список (DEFAULT_IMMUTABLE) SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" BASE="$(cd "$SCRIPT_DIR/.." && pwd)" IMMUTABLE_LIST="$BASE/.agent/immutable.txt" if [ -f "$IMMUTABLE_LIST" ]; then # Читать список, игнорируя пустые строки и комментарии PROTECTED_PATHS=() while IFS= read -r line; do line="${line%%#*}" # убрать комментарии line="$(echo "$line" | xargs)" # trim if [ -n "$line" ]; then PROTECTED_PATHS+=("$line") fi done < "$IMMUTABLE_LIST" else # Fallback список PROTECTED_PATHS=( ".agent/rules/" ".agent/prompts/" ".agent/cards/" ".agent/immutable.txt" "scripts/" "plans/" "00-manifest.md" "AGENTS.md" "Makefile" "pyproject.toml" "package.json" ".gitignore" ".nvmrc" "STEP_STATE.template.md" "CHANGELOG-META.md" ) fi # Проверить staged файлы staged_files=$(git diff --cached --name-only 2>/dev/null || true) if [ -n "$staged_files" ]; then for file in $staged_files; do for protected in "${PROTECTED_PATHS[@]}"; do # Проверить, начинается ли путь с protected if [[ "$file" == "$protected"* ]]; then # Разрешить если есть файл-маркер разрешения if [ -f "_meta/.allow-protected-edit" ]; then continue 2 fi cat >&2 <<EOF БЛОКИРОВКА: файл '$file' защищён от изменений (immutable). Полный список защищённых путей — в .agent/immutable.txt. См. 06-interactive-protocol.md §11 (PROTECT-ГЕЙТ). Если агент считает, что нужно изменить защищённый файл: 1. Агент должен объяснить ПОЧЕМУ нужно изменение 2. Пользователь должен подтвердить: "разрешаю изменить <файл>" 3. Создать маркер: touch _meta/.allow-protected-edit 4. Внести изменения 5. Обновить snapshot: uv run python3 scripts/protect_files.py --update 6. После коммита удалить маркер: rm _meta/.allow-protected-edit Для экстренного обхода (НЕ рекомендуется): touch _meta/.allow-protected-edit && git commit ... rm _meta/.allow-protected-edit EOF exit 1 fi done done fi exit 0