diff --git a/.claude/scripts/check-branch-sync.sh b/.claude/scripts/check-branch-sync.sh new file mode 100755 index 0000000..a828a7b --- /dev/null +++ b/.claude/scripts/check-branch-sync.sh @@ -0,0 +1,90 @@ +#!/bin/bash +# +# check-branch-sync.sh — Session başlangıç branch freshness kontrolü. +# +# Kullanım (her kod değişikliği session başında): +# bash .claude/scripts/check-branch-sync.sh +# +# Exit codes: +# 0 → branch fresh (main up-to-date VEYA kısa-ömürlü branch ≤5 commit behind) +# 1 → DUR: stale branch (>5 commit behind) — rebase/yeniden aç +# +# 2026-04-20 olay: claude/faz-c-master-plan 72 commit behind main iken +# Codex v3.2.0 → 4.0.0b1 jump yaptı, 11 minor release kaybedildi. +# Bu script bunu commit time'dan ÖNCE yakalar. + +set -e + +# Repo root'a in +cd "$(git rev-parse --show-toplevel)" 2>/dev/null || { + echo "✗ Not in a git repository" + exit 2 +} + +branch=$(git branch --show-current) + +# Detached HEAD +if [ -z "$branch" ]; then + echo "⚠ Detached HEAD — feature branch aç:" + echo " git checkout -b origin/main" + exit 1 +fi + +# Forbidden long-lived branch patterns +if [[ "$branch" =~ ^(claude/|master-plan/|wip/) ]]; then + echo "🚨 YASAK branch pattern: $branch" + echo " CLAUDE.md §17 — claude/*, master-plan/*, wip/* branch'leri stale üretir." + echo " Yeni short-lived branch aç from main:" + echo " git checkout -b feat/ origin/main" + exit 1 +fi + +# Backup branch — read-only, üstünde çalışılmaz +if [[ "$branch" =~ ^backup/ ]]; then + echo "⚠ backup/ branch — bu read-only referans, üstünde çalışılmaz." + echo " Yeni branch aç from main:" + echo " git checkout -b feat/ origin/main" + exit 1 +fi + +# Fetch main (silent, timeout 10s) +git fetch origin main --quiet --prune 2>/dev/null || { + echo "⚠ origin/main fetch failed — offline?" + echo " Check connection and retry." + exit 1 +} + +if [ "$branch" = "main" ]; then + behind=$(git rev-list --count HEAD..origin/main 2>/dev/null || echo 0) + if [ "$behind" -gt 0 ]; then + echo "⚠ main is $behind commits behind origin/main" + echo " Run: git pull" + exit 1 + fi + echo "✓ main, up-to-date with origin/main" + exit 0 +fi + +behind=$(git rev-list --count HEAD..origin/main) +ahead=$(git rev-list --count origin/main..HEAD) + +echo "Branch: $branch" +echo "Ahead of main: $ahead" +echo "Behind main: $behind" + +if [ "$behind" -gt 20 ]; then + echo "" + echo "🚨 BRANCH STALE: $behind commits behind — bu branch üstünde ÇALIŞMA" + echo " CLAUDE.md §17:" + echo " Opsiyon 1 (önerilen): git checkout -b origin/main" + echo " Opsiyon 2: git rebase origin/main (conflict manageable ise)" + exit 1 +elif [ "$behind" -gt 5 ]; then + echo "" + echo "⚠ WARN: branch $behind commits behind — rebase önerilir" + echo " git rebase origin/main" + exit 0 +fi + +echo "✓ Branch fresh" +exit 0 diff --git a/.claude/scripts/pre-commit-version-gate.sh b/.claude/scripts/pre-commit-version-gate.sh new file mode 100755 index 0000000..65afeb4 --- /dev/null +++ b/.claude/scripts/pre-commit-version-gate.sh @@ -0,0 +1,63 @@ +#!/bin/bash +# +# pre-commit-version-gate.sh — Stale base'de version bump'ı engelle. +# +# Install: +# cp .claude/scripts/pre-commit-version-gate.sh .git/hooks/pre-commit +# chmod +x .git/hooks/pre-commit +# +# 2026-04-20 olay: Codex stale branch'te version 3.2.0 → 4.0.0b1 bump +# yaptı, 11 minor release kaybı tehlikesi doğurdu. Bu hook aynı hatayı +# commit time'da yakalar. +# +# Override (gerçekten gerekliyse): +# git commit --no-verify + +set -e + +# Hangi dosyalar staged? +version_changed=$(git diff --cached --name-only \ + | grep -E "^(pyproject\.toml|ao_kernel/__init__\.py)$" || true) + +if [ -z "$version_changed" ]; then + # Version dosyası değişmiyor, check atla + exit 0 +fi + +# origin/main ile merge-base yaşını hesapla +git fetch origin main --quiet 2>/dev/null || { + echo "⚠ pre-commit: origin/main fetch failed, skipping staleness check" + exit 0 +} + +base_sha=$(git merge-base HEAD origin/main 2>/dev/null) +if [ -z "$base_sha" ]; then + echo "⚠ pre-commit: no merge-base with origin/main, skipping" + exit 0 +fi + +base_ts=$(git log -1 --format=%ct "$base_sha" 2>/dev/null || echo 0) +now=$(date +%s) +age_hours=$(( (now - base_ts) / 3600 )) + +if [ "$age_hours" -gt 24 ]; then + echo "" + echo "✗ PRE-COMMIT BLOCK: version bump on stale base" + echo " Branch: $(git branch --show-current)" + echo " Merge-base age: ${age_hours} hours old (limit: 24h)" + echo " Files triggering check:" + echo "$version_changed" | sed 's/^/ /' + echo "" + echo " CLAUDE.md §18: Version bump stale base'de yasak." + echo " Fix:" + echo " git rebase origin/main" + echo " git add " + echo " git commit" + echo "" + echo " Override (risk kabul ederek):" + echo " git commit --no-verify" + exit 1 +fi + +echo "✓ pre-commit: version bump OK (base $age_hours hours old, ≤24h limit)" +exit 0 diff --git a/CLAUDE.md b/CLAUDE.md index 3050992..375114c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -376,3 +376,97 @@ codex exec -C . -o .ao/consultations/responses/CNS-YYYYMMDD-NNN.codex.response.v - Dokümanlar, planlar, raporlar: Türkçe - Codex istişare soruları: Türkçe - CLAUDE.md, README: Türkçe + +## 17. Branch Discipline — Stale State Engelleme (2026-04-20) + +Bu repo multi-worktree + multi-agent (Claude Code + Codex) çalışıyor. Stale branch'ler session'lar arası drift üretir ve version bump hatalarına yol açar (örn. 2026-04-20'de `claude/faz-c-master-plan` 72 commit behind main iken Codex v3.2.0 → 4.0.0b1 jump yaptı; 11 minor release kaybedildi). + +### Session başlangıç check (ZORUNLU) + +Her yeni kod değişikliği session'ı — Claude Code VEYA Codex — infaza geçmeden önce: + +```bash +bash .claude/scripts/check-branch-sync.sh +``` + +Script exit 1 dönerse DUR, kullanıcı ile karar ver: + +- Main'e rebase: `git rebase origin/main` +- Yeni branch from main: `git checkout -b origin/main` +- Eski branch'i sil: `git branch -D ` + +### Uzun-ömürlü branch YASAK + +- `main` = tek truth +- `release/v*`, `feat/*`, `fix/*`, `docs/*`, `work/*` = **SHORT-LIVED** (günler içinde kapanır) +- `backup/*` = uzun-ömürlü ama **yalnız read-only referans**, üstünde çalışılmaz +- **`claude/*`, `master-plan/*`, `wip/*` = YASAK** — stale üretir, agent'lar yanlış base'de çalışır + +2026-04-20 temizliği: 95 local + 61 remote `claude/*` branch silindi. Bu disiplin geri dönmesin. + +### Worktree-per-branch denkliği + +Her worktree ayrı short-lived branch'te çalışır. Session başlangıç: + +```bash +# Primary worktree (/Users/halilkocoglu/Documents/ao-kernel) +cd /Users/halilkocoglu/Documents/ao-kernel +git checkout main && git pull + +# Feature → ya primary'de short-lived branch'e geç, ya yeni worktree yarat +git worktree add ../ao-kernel-feat-X -b feat/X origin/main + +# Bitince +git worktree remove ../ao-kernel-feat-X +git branch -D feat/X # merge edildikten sonra +``` + +### Version bump — base freshness zorunlu + +`pyproject.toml::version` veya `ao_kernel/__init__.py::__version__` değişecekse: + +- Merge base `origin/main` ile **en fazla 24 saat eski** olmalı +- Pre-commit hook bunu yakalar (Bölüm 18) +- Aksi halde eski base üstünde version bump → 11 release kaybı gibi felaketler + +### Multi-agent koordinasyon + +Farklı worktree'lerde çalışan Claude/Codex session'ları için: + +- Her session **kendi worktree'sinin branch-freshness'ını kontrol eder** (`check-branch-sync.sh`) +- Shared implementation branch yok — her session fresh branch from main +- Backup branch (`backup/*`) sadece kurtarma için, üstünde impl yapılmaz + +## 18. Pre-commit Hook: Stale Base Version Bump Engeli (2026-04-20) + +`.git/hooks/pre-commit` (yerel, gitignored) aktif olmalı. Stale base'de version bump'ı commit time'da yakalar: + +```bash +#!/bin/bash +# Block version bump if branch base is >24h old + +set -e +version_changed=$(git diff --cached --name-only | grep -E "^(pyproject\.toml|ao_kernel/__init__\.py)$" || true) +if [ -z "$version_changed" ]; then exit 0; fi + +git fetch origin main --quiet 2>/dev/null || true +base_ts=$(git log -1 --format=%ct "$(git merge-base HEAD origin/main)" 2>/dev/null || echo 0) +now=$(date +%s) +age_hours=$(( (now - base_ts) / 3600 )) + +if [ $age_hours -gt 24 ]; then + echo "✗ PRE-COMMIT BLOCK: version bump on stale base ($age_hours hours old)" + echo " Rebase first: git rebase origin/main" + echo " Or force (not recommended): git commit --no-verify" + exit 1 +fi +exit 0 +``` + +Kurulum: +```bash +cp .claude/scripts/pre-commit-version-gate.sh .git/hooks/pre-commit +chmod +x .git/hooks/pre-commit +``` + +**Not:** git worktree paylaşılan `.git/` kullanır, hook tüm worktree'lerde aktif olur. Bir kez kurulur, tüm session'lar korunur.