AIDive

Pakiet do filmu

Governance specyfikacji i planów AI w Git: pięć reguł, drift gate, źródła i checklista

11 min czytania

TL;DR

  • Commituj specyfikacje i plany pisane przez AI. Każde narzędzie robi to domyślnie; otwarte pozostaje pytanie o governance.
  • Daj każdemu zespołowi (squadowi) jeden folder z linią CODEOWNERS, żeby zmiana specyfikacji wymagała review od właścicieli kodu.
  • Dodaj do każdej współdzielonej specyfikacji nagłówek w stylu ADR: status, superseded-by, owner, dotknięte ścieżki, data przeglądu. Nigdy nie przepisuj zaakceptowanej specyfikacji na nową decyzję.
  • Uruchom w CI drift gate: dla każdej zaakceptowanej specyfikacji build ma się wywalać, gdy ścieżka, którą wymienia, już nie istnieje.
  • Przekieruj ścieżkę zapisu jedną pogrubioną linią w trybie rozkazującym w CLAUDE.md, trzymaj osobiste plany w CLAUDE.local.md i .git/info/exclude, a pisz na branchu, nigdy na main.
  • Pisz specyfikację tylko do pracy, która przekracza granicę squadu albo będzie czytana ponownie za 90 dni. Przebiegi spec-driven kosztują około dwa razy więcej czasu i trzy razy więcej tokenów.

Co mówią źródła

Domyślne ustawienia: wszyscy commitują

Skill writing-plans z Superpowers zapisuje plany w docs/superpowers/plans/YYYY-MM-DD-<feature-name>.md, a linia pod spodem mówi, że preferencje użytkownika dotyczące lokalizacji planów mają pierwszeństwo przed tym ustawieniem s1. Skill brainstorming zapisuje zwalidowany projekt w docs/superpowers/specs/YYYY-MM-DD-<topic>-design.md i kończy się słowami "Commit the design document to git" s2. Spec Kit tworzy specs/[branch-name]/ z plikami spec.md, plan.md i tasks.md, numerowanymi 001, 002, oraz constitution w memory/constitution.md s6. Kiro trzyma .kiro/specs/ z jednym folderem na funkcję i zachęca zespoły, by "collaborate with team members on different features simultaneously" s8. Playbook Anthropic jest jednoznaczny: "Every stage commits an artifact the next stage can read", "Commit the approved plan as plan.md" oraz "When implementation departs from the plan, update plan.md in the same commit" s5.

Żaden z tych dokumentów nie mówi, do kogo należy zacommitowana specyfikacja ani kiedy przestaje być prawdziwa. W tej luce mieszczą się trzy udokumentowane porażki.

Porażka 1: publiczny wyciek

Issue 1690, otwarte 2026-06-05, zgłasza, że domyślna lokalizacja docs/superpowers/ może przez Sphinx i Read the Docs wyciec wewnętrzne plany do opublikowanej dokumentacji s15. Dotknięty projekt to okama, biblioteka Pythona z 273 gwiazdkami. Jej commit z poprawką dodał z powrotem 5 planów i 3 specyfikacje, usunął jedną linię z .gitignore i brzmi "track superpowers plans/specs in git, excluded from the Sphinx build" s21. W linii 84 docs/conf.py jest teraz exclude_patterns = ["_build", "Thumbs.db", "superpowers"] s22. Dziś folder zawiera 8 planów i 6 specyfikacji s15. Zespół zachował praktykę i naprawił build.

Porażka 2: plany na main

Issue 1246, otwarte 2026-04-22 i wciąż otwarte, pyta, dlaczego plan jest commitowany, zanim powstanie branch deweloperski. Jeden użytkownik pisze "I'm getting 10 to 15 commits"; inny: "Yes please, no plans and specs on main branch!" s16. Wtyczka nie egzekwuje reguły o branchach; robi to checklista poniżej.

Porażka 3: nadpisania, które model pomija

Issue 337 zamknięto 2026-03-10 z notatką maintainera, że od v5.0 wtyczka przedkłada CLAUDE.md projektu nad własne ustawienia domyślne, przykładowa linia: "Save plans to ~/.superpowers/plans/ instead of docs/plans/" s17. Issue 939, na v5.0.6, pokazuje granicę: tabela "Output Paths" w CLAUDE.md została zignorowana, a specyfikacje dalej lądowały w docs/superpowers/specs/. Obejściem, które zadziałało, jest pogrubiona linia w trybie rozkazującym pod tabelą: design specs MUST be saved to docs/design-docs/, NOT docs/superpowers/specs/ s18. Pull request 1020, który zmieniał kolejność instrukcji, zamknięto bez merge'a s19. Nadpisanie to prompt, nie ustawienie: sprawdzaj je po każdym wydaniu wtyczki. Dla własnych plików roboczych wtyczki issue 1780 zamknięto w v6.0.3 folderem .superpowers/sdd/, który sam siebie ignoruje, zapisując własny .gitignore z * s20.

Osobiste a współdzielone

Claude Code dokumentuje ten podział: "For private per-project preferences that shouldn't be checked into version control, create a CLAUDE.local.md at the project root. It loads alongside CLAUDE.md and is treated the same way. Add CLAUDE.local.md to your .gitignore so it isn't committed" s3. Pliki CLAUDE.md w katalogach ładują się na żądanie, "Commit these files to the repository so teammates inherit them. Each directory's owner typically maintains its file", a ustawienie claudeMdExcludes ukrywa pliki innych zespołów w monorepo s4. Git ma trzy warstwy ignorowania, $XDG_CONFIG_HOME/git/ignore, $GIT_COMMON_DIR/info/exclude i .gitignore s24; środkowa ukrywa osobisty folder z planami bez dotykania współdzielonego pliku. CODEOWNERS załatwia drugą połowę, własność: "Code owners are automatically requested for review when someone opens a pull request that modifies code that they own" s23.

Cykl życia, jak w ADR

Wzorem jest wpis Michaela Nygarda z 2011 roku: decyzja "may be 'proposed' if the project stakeholders haven't agreed with it yet, or 'accepted' once it is agreed. If a later ADR changes or reverses a decision, it may be marked as 'deprecated' or 'superseded' with a reference to its replacement", oraz "If a decision is reversed, we will keep the old one around, but mark it as superseded" s9. Thoughtworks dzieli użycie specyfikacji na spec-first (pisana raz na zadanie), spec-anchored (utrzymywana, by rozwijać funkcję) i spec-as-source (edytuje się tylko specyfikację), a jego autor dodaje: "I'd rather review code than all these markdown files" s10. Superpowers pisze pliki spec-first i trzyma je na zawsze: drift z automatu.

Drift i bramka

Artykuł z arXiv nazywa problem "silent spec-code drift -- code evolves, the specification does not, and the divergence becomes invisible until it is costly to repair" i proponuje "a drift gate that makes spec-code divergence a blocking merge condition" s11. Przewodnik Spec Kit ostrzega: "Do not leave a lower-level change in tasks.md or code if spec.md still says something different" s7. TrueFoundry ujmuje sprawę governance wprost: "forty-one specs and nine agent files aren't a tidiness problem", to "forty-one unversioned behavior inputs and nine competing standing policies", a drift "is unavoidable in spec-first practice and managed in spec-anchored practice, but only if divergence is detectable". Ten sam wpis sugeruje około 300 linii na specyfikację i budżet 150 do 200 stałych instrukcji s13. Jeden praktyk opisuje wersję ręczną: "I've had to have Claude compare the spec files to the codebase and see if anything is missing" s26.

Ile to kosztuje

Eksperyment Wynik Źródło
Spec Kit przy funkcji pokazującej bieżącą datę 8 plików i 1,300 linii tekstu s14
Porównanie OpenSpec, te same wymagania, narzędzie do specyfikacji kontra czysty Claude Code OpenSpec znalazł 3 luki więcej; 50% więcej kodu przy 50% większej złożoności cyklomatycznej; dwa razy dłużej i trzy razy drożej s12
Zespół prowadzący spec-driven development od miesięcy "two to three times as many tokens and take about twice as long"; brak dowodu, że kod się poprawił s25

Porównanie to jeden eksperyment i jego autor sam to mówi, ale kierunek jest ten sam we wszystkich trzech. Zatem: pisz specyfikację dla ścieżki architektonicznej, ograniczoną ścieżkę trzymaj ograniczoną i stosuj dwie rady, które powtarzają praktycy: "don t spec too big / read the generated specs" s26.

Do zrobienia w poniedziałek

  • Utwórz docs/specs/<squad>/ dla każdego squadu i dodaj po jednej linii CODEOWNERS na folder, wskazującej reviewerów tego squadu.
  • Dodaj do CLAUDE.md projektu jedną pogrubioną linię w trybie rozkazującym: plans and specs MUST be saved under docs/specs/<squad>/, NOT docs/superpowers/. Uruchom jeden brainstorm i sprawdź, gdzie wylądował plik.
  • Przenieś osobiste plany do folderu wpisanego w .git/info/exclude i trzymaj preferencje poszczególnych deweloperów w CLAUDE.local.md, który sam jest ignorowany.
  • Dodaj nagłówek do każdej współdzielonej specyfikacji: status (proposed, accepted, superseded), superseded-by, owner, paths, review-by.
  • Napisz drift gate: dla każdej specyfikacji z status: accepted wyciągnij wymienione ścieżki i zablokuj pull request, gdy którejś brakuje. Około piętnastu linii shella lub Pythona.
  • Dodaj regułę o branchach: żaden commit ze specyfikacją lub planem nie trafia na main poza pull requestem.
  • Jeśli repo publikuje dokumentację przez Sphinx lub podobne narzędzie, dodaj dziś folder ze specyfikacjami do exclude_patterns.
  • Ustaw budżet rozmiaru: specyfikacja trzyma się około 300 linii, a dostaje ją tylko praca przekraczająca granicę squadu albo czytana ponownie za 90 dni.

Czytaj dalej

  • Przeczytaj trzy kategorie użycia specyfikacji (spec-first, spec-anchored, spec-as-source), zanim wybierzesz schemat nagłówka; cykl życia ma znaczenie tylko dla plików spec-anchored s10.
  • Artykuł z arXiv idzie dalej niż sprawdzanie ścieżek, aż do pełnej architektury z wymuszonym driftem; przydatny, gdy piętnastoliniowa bramka zacznie wydawać się zbyt zgrubna s11.
  • Przewodnik Spec Kit wymienia trzy przepływy ewolucji (Flow-Forward, Living Spec, Flow-Back), które odpowiadają regule tego samego commita s7.
  • Playbook proponuje hook wymuszający synchronizację planu i diffu; wątek na Reddicie o nim ma 43 punkty i 27 komentarzy z relacjami z praktyki s5, s27.
  • Argument TrueFoundry, że zmiana specyfikacji to zmiana polityki, więc należy ją umieścić za bramką eval z metadanymi przebiegu, to kolejny krok po sprawdzaniu ścieżek w CI s13.
  • Śledź dwa otwarte issues, 1246 (plany na main) i 939 (ignorowane nadpisania); gdy któreś się zamknie, jedna reguła z tego pakietu stanie się domyślnym ustawieniem wtyczki s16, s18.
  • Pełny tekst Marmelab wyjaśnia, skąd wzięło się 1,300 linii i gdzie Spec Kit się opłaca s14.

Źródła

FAQ

Czy potrzebuję wszystkich pięciu reguł od pierwszego dnia?

Nie. Przekierowanie w CLAUDE.md i wykluczenie Sphinx zajmują dziesięć minut. Dodaj CODEOWNERS i nagłówek, gdy specyfikacja po raz pierwszy przekroczy granicę squadów, a drift gate, gdy zaakceptowana specyfikacja będzie miała sprint.

Czego drift gate nie widzi?

Zmienionego zachowania. Sprawdza tylko, czy wymieniona ścieżka wciąż istnieje, więc odwrócony warunek przejdzie. Połącz go z regułą tego samego commita i z review.

Czemu po prostu nie dodać folderu do gitignore?

Bo agent, który później czyta specyfikację, jej potrzebuje, a audit trail działa tylko wtedy, gdy elementy pośrednie są wersjonowane. Zespół okama spróbował gitignore i wrócił do commitowania z wykluczeniem z builda.