Dziesięciu deweloperów, jeden folder docs
Superpowers to plugin do Claude Code (286 000 gwiazdek na GitHub), którego skille piszą specy i plany implementacji jako pliki markdown i commitują je do repozytorium. Domyślnie każdy z tych plików trafia do jednego folderu, docs/superpowers/. W czerwcu maintainerzy Okama, biblioteki finansowej w Pythonie, odkryli, że osiem planów implementacji napisanych tam przez agenta, zacommitowanych zgodnie z intencją pluginu, zostało wyrenderowanych jako publiczne strony web na Read the Docs. Zauważyli to po wydaniu.
Teraz przeskaluj to: zespół frontendowy złożony z dziesięciu deweloperów, czterech squadów, jedno repozytorium, i każdy deweloper generujący te pliki. Na biurko lidera trafiają trzy pytania. Co właściwie wersjonujemy? Czy drift jest problemem, gdy spec nazywa ścieżkę usuniętą dwa sprinty temu? I kto rządzi folderem? Wyciek Okama nie był spowodowany commitowaniem. Był spowodowany commitowaniem bez reguły. Ten artykuł daje ci pięć.
Każde narzędzie commituje te pliki
Superpowers nigdy nie pyta, czy commitować. Linia 18 jego skilla do planowania zapisuje każdy plan w docs/superpowers/plans/, z datą, jeden plik na feature. Skill do brainstormingu pisze dokument projektowy i commituje go w tym samym kroku, zanim zobaczyłeś plan.
To nie jest dziwactwo Superpowers. Każde większe narzędzie spec-driven robi ten sam wybór:
| Tool | Publisher | Where specs live |
|---|---|---|
| Superpowers (286 000 gwiazdek) | obra | docs/superpowers/, jeden folder na wszystko |
| Spec Kit (136 000 gwiazdek) | GitHub | jeden numerowany folder na feature, na branchu tego feature'a |
| Kiro | Amazon | .kiro/specs/, jeden folder na feature |
| Playbook AI-native SDLC | Anthropic | jeden zacommitowany artefakt na etap: intent, spec, plan, diff, review findings, incident record |
Kiro sprzedaje foldery per-feature jako sposób, żeby zespół mógł współpracować nad różnymi feature'ami naraz. Playbook Anthropic, opublikowany w sierpniu, idzie dalej: każdy etap commituje artefakt, który następny etap może odczytać. Więc pytanie nigdy nie brzmiało, czy commitować, a gdzie odpowiada każde narzędzie. Kto jest właścicielem pliku i kiedy jest martwy — nie. Ta dziura jest tym, co pokrywa pięć reguł.
Trzy sposoby, w jakie to się psuje
Zacommitowane plany zawodzą w trzech różnych sposobach.
Porażka 1: generator dokumentacji. Build dokumentacji, który renderuje każdy plik markdown pod docs/, niezależnie od tego, czy spis treści go wymienia, wysyła folder z planami razem z podręcznikiem. To właśnie przydarzyło się Okama.
Porażka 2: branch. Issue 1246 w Superpowers zgłasza, że brainstorm commituje plan bezpośrednio na main. Jeden użytkownik liczy 10 do 15 commitów na sesję, nowy co kilka zmian. Prośba z tego wątku mieści się w jednej linii: żadnych planów i speców na branchu main.
Porażka 3: drift. Drift speców to cicha porażka: kod się zmienia, a spec nie. Birgitta Böckeler z Thoughtworks nazywa trzy poziomy spec-driven development:
| Level | Meaning |
|---|---|
| Spec-first | Napisany, użyty raz |
| Spec-anchored | Zachowany i utrzymywany na czas życia feature'a |
| Spec-as-source | Człowiek edytuje tylko spec |
Superpowers pisze dokumenty spec-first i zachowuje je na zawsze. Domyślnie dostajesz storage spec-anchored z utrzymaniem na poziomie pierwszego draftu: nikt nie aktualizuje pliku, a agent czyta go za kwartał jako prawdę. TrueFoundry stawia to jasno: drift jest nieunikniony w praktyce spec-first i zarządzany w praktyce spec-anchored, ale tylko jeśli rozbieżność jest wykrywalna.
Repozytorium z 41 specami i 9 plikami agentów nie ma problemu z porządkiem. Ma 41 niewersjonowanych wejść zachowania. Reakcja samej Böckeler: woli przeczytać kod niż wszystkie te pliki markdown. Plan, którego nikt nie wczytuje ponownie, to bałagan. Plan, który wczytuje agent, to instrukcja, a nieaktualna instrukcja jest błędną instrukcją.
Reguła 1: jeden dom na squad, z właścicielami
Reguła 1: folder ma właściciela, a właścicielem jest squad, nie plugin. Od wersji 5 Superpowers honoruje instrukcje w CLAUDE.md twojego projektu ponad swoje własne domyślne ustawienia. Powiedz, gdzie mają iść plany, i pójdą tam.
Sama tabela ścieżek jednak nie wystarcza. W issue 939 użytkownik napisał tabelę ścieżek wyjściowych, a model poszedł za konkretną ścieżką w skillu i zignorował tabelę. Własna notka pluginu o nadpisaniu jest w nawiasie. Jedna wytłuszczona linia w trybie rozkazującym naprawiła to od pierwszej próby: specy muszą być zapisane tutaj, nie tam, z domyślną ścieżką nazwaną jako coś, czego trzeba unikać.
Układ to jeden folder na squad (checkout, search, accounts, design-system), każdy z własnymi specami i planami. W monorepo umieść tę linię w CLAUDE.md danego pakietu. Claude Code wczytuje plik podfolderu na żądanie, gdy tam czyta, a dokumentacja mówi, że właściciel każdego katalogu zwykle utrzymuje swój plik. Inżynierowie, którzy nigdy nie zainstalowali pluginu, są nietknięci: linia odpala się tylko wtedy, gdy skill pyta, gdzie zapisać.
Potem pozwól platformie wymuszać własność. Jedna linia CODEOWNERS na folder squadu, i każde review speca trafia do ludzi, którzy będą z nim żyć. Jedno zastrzeżenie: nadpisanie jest promptem, nie ustawieniem. Sprawdzaj pierwszy spec po każdym wydaniu pluginu.
Reguła 2: prywatne kontra współdzielone
Reguła 2: nie każdy plan jest artefaktem zespołowym. Pierwsza osoba, która poprosiła Superpowers o konfigurowalną lokalizację (issue 337), ujęła to najlepiej: pliki planów mogą być prywatnymi dokumentami roboczymi, nie artefaktami projektu.
Strona prywatna ma plik stworzony dla siebie. CLAUDE.local.md siedzi obok współdzielonego pliku, wczytuje się po nim, a dokumentacja mówi ci, żebyś sam go dodał do git-ignore. Twoje przekierowanie do prywatnego folderu żyje tam i nikt inny go nie widzi. Dla samego folderu Git ma plik ignorowania, który nigdy nie dotyka współdzielonego drzewa: .git/info/exclude jest per klon, nigdy nie zacommitowany, i nie wymaga pull requestu. Plugin już robi to dla własnej przestrzeni roboczej: od wersji 6.0.3 jego katalog roboczy upuszcza wewnątrz siebie .gitignore zawierający *, więc sam się ignoruje bez dotykania śledzonego pliku.
Strona współdzielona to wszystko, co przeszło przez gate review, który już prowadzi brainstorm: spec napisany, review zamówione, zaakceptowane przez drugą osobę. Zaakceptowane, przenosi się do folderu squadu. Niezaakceptowane, zostaje lokalnie. Obie strony są pisane na branchu, nigdy na main. Dwie linie w współdzielonym CLAUDE.md to robią: traktuj specy i plany jako początek feature'a i twórz worktree przed ich napisaniem.
Jedno ograniczenie: git-ignorowany plan nie podróżuje. Maintainerzy Okama najpierw spróbowali ignorować folder i wycofali się, bo plany przestały się synchronizować między maszynami i agentami. Prywatne znaczy prywatne.
Reguła 3: cykl życia, jak w ADR-ach
Reguła 3: spec ma status, a martwy spec to mówi. Ten pomysł ma 15 lat. Michael Nygard w 2011 zaproponował trzymanie architecture decision records (ADR) w repozytorium, jeden numerowany plik każda. Decyzja jest proposed, potem accepted. Gdy późniejszy rekord ją zmienia, stary jest oznaczony jako deprecated albo superseded z referencją do swojego zamiennika. Jeśli decyzja zostaje odwrócona, stary rekord jest zachowany, ale oznaczony jako superseded.
Zastosowane do speców, każdy współdzielony spec otwiera się nagłówkiem z pięciu linii, który agent już czyta:
| Field | Purpose |
|---|---|
| status | proposed, accepted, superseded |
| superseded-by | spec, który zastępuje |
| owner | squad |
| touches | ścieżki, o których spec robi twierdzenia |
| review date | kiedy był ostatnio sprawdzony |
Nigdy nie edytuj zaakceptowanego speca w inną decyzję. Napisz następny, wskaż go z powrotem, i historia zostaje uczciwa. Jeden wyjątek, wskazany w playbooku Anthropic: gdy implementacja odbiega od planu, aktualizuj plan w tym samym commicie. Plan podróżuje z diffem, który go złamał, i hook może to wymuszać.
Spec Kit nazywa trzy sposoby, w jakie spec może żyć. Flow-forward: nowy folder na feature, stare zachowane jako historia. Living spec: spec jest kontraktem, a resztę się regeneruje. Flow-back: build przekształca spec. Ich reguła to nie zostawiać różnicy w taskach czy kodzie, jeśli spec wciąż mówi coś innego. To wybieranie spec-anchored z rozmysłem.
Ograniczenie: status to metadane, które ustawia człowiek. Agent nie oznaczy własnego speca jako superseded, jeśli twój CLAUDE.md mu tego nie powie, a nawet wtedy review musi to zauważyć.
Reguła 4: drift gate w CI
Reguła 4: spec, który okłamuje drzewo, wywala build. Paper, który nazwał ten problem, opublikowany w czerwcu, nazywa to silent spec-code drift: kod się zmienia, specyfikacja nie, a rozbieżność zostaje niewidoczna, aż jest kosztowna do naprawy. Jego odpowiedź to drift gate, blokujący warunek merge'a.
Check jest mniejszy, niż się wydaje. Dla każdego speca, którego nagłówek mówi accepted, wyciągnij ścieżki, które wymienia, w backtickach albo w linii touches, i sprawdź, że każda istnieje. Brakująca ścieżka, failujący build, z nazwą speca w logu. Pliki superseded i proposed są pomijane: tylko accepted specy robią twierdzenia o drzewie, więc tylko accepted specy są sprawdzane. TrueFoundry ujmuje to jako zaplanowany diff, nie archeologię po incydencie: spec to scaffold, a zmiana speca to zmiana polityki.
Ludzie już uruchamiają ręczną wersję. Jeden komentator ma Claude'a porównującego pliki speców z codebase i zgłaszającego tickety na to, czego brakuje. Skrypt robi to przy każdym pull requeście, za darmo.
Druga zabezpieczenie to to, które wysłał Okama: wyklucz folder z builda dokumentacji. Jedna linia w konfiguracji Sphinx trzyma pliki w Git, ale poza HTML.
Ograniczenie: check ścieżek wykrywa usunięte pliki, nie zmieniony behavior. Spec może wymieniać każdy istniejący plik i wciąż opisywać API, które już nie istnieje. Do tego są review i reguła same-commit.
Reguła 5: budżet rozmiaru i jego koszt
Reguła 5: większość pracy nie zasługuje na speca. Dowody na koszt narzutu spec-driven są konsekwentne:
| Experiment | Result |
|---|---|
| Marmelab, Spec Kit na feature'ze, który pokazuje aktualną datę | 8 plików, 1300 linii tekstu specyfikacji |
| Bake-off OpenSpec, te same wymagania z toolem do speców vs sam Claude Code | 50% więcej kodu, 50% wyższa złożoność cyklomatyczna, dwa razy dłużej, trzy razy większy koszt |
| Zespół prowadzący spec-driven development miesiącami | 2 do 3 razy więcej tokenów, około dwa razy dłużej, duży koszt koordynacji dla zmian, które go nie wymagały; brak dowodu, że kod się poprawił |
Bake-off to jeden eksperyment, nie benchmark, i jego autor to mówi. Ale kierunek się trzyma. Więc reguła: pisz speca, gdy praca przekracza granicę squadu albo będzie odczytana ponownie za 90 dni. Wszystko inne to prompt.
Superpowers już sortuje każdą prośbę na trzy drogi: spike, bounded, architectural. Tylko droga architectural pisze speca. Trzymaj drogę bounded bounded i trzymaj speca blisko 300 linii. Praktycy dodają dwie linie: nie robić speca za dużego i czytać wygenerowane specy.
Ograniczenie działa w obie strony. Ten sam bake-off znalazł trzy dziury, które przegapił zwykły przebieg. Spec kupuje pokrycie, nie szybkość. Płać za niego tam, gdzie pokrycie się liczy.
Werdykt: commituj, potem rządź
Wracając do trzech pytań lidera. Co wersjonujemy: zaakceptowane specy i plany, na branchu, w folderze squadu. Drift: nagłówek statusu i gate w CI. Governance: właściciele i reguła rozmiaru.
Pięć reguł, i żadna z nich nie jest dziś wymuszana przez żaden tool. Issue o nadpisaniu jest otwarty. Issue o branchu main jest otwarty. Pull request, który przełożył instrukcję, został zamknięty bez merge'a. Zespół, który się poparzył, zachował praktykę: 8 planów i 6 speców, zacommitowanych, wykluczonych z builda dokumentacji.
Zarzut Böckeler się broni. Z nagłówkiem statusu i budżetem rozmiaru czytasz tylko accepted specy, i mniej z nich. To, co dostajesz w zamian, to to, co playbook Anthropic nazywa audit trail: kto o co prosił, co agent wyprodukował i kto to zaakceptował.
To proces, nie tooling: plik CLAUDE.md, plik CODEOWNERS, nagłówek i piętnastoliniowy skrypt. A jeśli zespół nie będzie recenzować requestu do CODEOWNERS, nie będzie recenzować speca też. W tym przypadku .gitignore byłby uczciwszym wyborem.
AIDive