Przejdź do głównej zawartości

Build: plan.md, potem implementacja

Etap build zamienia zaakceptowany spec.md w plan.md zapisany w repozytorium, a potem w implementację w izolowanym worktree. Tryb planowania (plan mode) pozwala agentowi czytać kod bez możliwości edycji. Konkretny, wyznaczony inżynier akceptuje plan, zanim zmieni się kod aplikacji, a instrukcje repozytorium, hooki i weryfikator utrzymują wynik sprawdzalnym.

Ta strona jest dla dewelopera, który uruchamia agenta, i dla tech leada, który ustala w zespole bramkę planu. Prosisz o endpoint częściowych zwrotów i dostajesz diff na 900 linii. Agent edytuje zamrożony pakiet v1/, podbija zależność, której właścicielem jest zespół platformowy, i testuje tylko szczęśliwą ścieżkę. Pięć minut lektury planu wyłapałoby wszystkie trzy problemy, ale planu nie było, był tylko diff.

Tradycyjnie: inżynier czyta projekt i zaczyna pisać kod. Sposób wprowadzenia zmiany zostaje w jego głowie, a reviewer widzi dopiero gotowy diff, kiedy poprawki są już kosztowne.

AI-native: agent pisze plan w trybie tylko do odczytu, inżynier poprawia go, dopóki zmiana kierunku oznacza edycję dokumentu, a zaakceptowana wersja trafia do repozytorium jako plan.md. Review sprawdza potem diff względem tego pliku.

  • Kontrakt plan.md: pliki, kolejność, ryzyka, rollback i polecenia weryfikujące, a przy każdej otwartej decyzji jej właściciel.
  • Trzy prompty do skopiowania: szkic planu w trybie tylko do odczytu, atak na plan i wykonanie planu w worktree.
  • Dokładne komendy trybu planowania i worktree dla Claude Code, Codex i Cursora.
  • Regułę, gdzie umieścić wiedzę: w pliku instrukcji, skillu, hooku czy w CI.
  • Kontrole, które dowodzą poprawności implementacji bez czytania każdej linii przez człowieka.
  • Zaakceptowany intent.md z etapu Plan i zaakceptowany spec.md z etapu Design. Przy małej zmianie możesz pominąć oba, ale nie plan.
  • Plik instrukcji projektu, który agent czyta na starcie sesji: CLAUDE.md lub AGENTS.md albo reguła projektu w Cursorze.
  • Jedna komenda, która lokalnie uruchamia testy lub budowanie projektu. Pętlę informacji zwrotnej opisuje strona Test.
  • Czysta gałąź. Łańcuch artefaktów opisuje, gdzie w repozytorium leżą intent.md, spec.md i plan.md.

Plan jest akceptowalny, gdy inżynier, który nie widział rozmowy, mógłby wdrożyć zmianę wyłącznie na jego podstawie. Odrzuć każdy plan, który nie wymienia:

  • problemu i celów wyłączonych (non-goals) przejętych z intent.md i spec.md;
  • plików i symboli do przejrzenia lub zmiany;
  • uporządkowanych kroków implementacji i zależności między nimi;
  • ryzyk migracji danych, kompatybilności, bezpieczeństwa i rollbacku;
  • deterministycznych kontroli, które dowodzą zmiany, oraz ewentualnych kontroli wizualnych lub ręcznych z osobą odpowiedzialną;
  • otwartych decyzji i osoby, która musi podjąć każdą z nich.

Szkielet do przyjęcia bez zmian:

# Plan: PAY-412 partial refunds
Spec: intent/PAY-412/spec.md · Approver: Dana Kowal (routine)
## Non-goals
- No change to the v1/ refund endpoint (frozen).
## Files
- src/main/java/com/acme/payments/v2/RefundController.java (new endpoint)
- src/main/java/com/acme/payments/v2/RefundService.java (partial amount rule)
- src/itest/java/com/acme/payments/v2/RefundIT.java (new)
- src/main/resources/db/migration/V42__refund_amount.sql (new)
## Steps
1. Add the Flyway migration V42__refund_amount.sql (additive column only).
2. Add RefundService.partialRefund: BigDecimal validation, and an
idempotency key on retry so a repeated request refunds once.
3. Expose POST /v2/refunds/{id}/partial.
## Risks and rollback
- Migration is additive; rollback is a code revert, the column stays.
- Double refund on retry: idempotency key checked in step 2.
## Proof
- make test && make itest (exit 0)
- RefundIT covers: full, partial, over-refund rejected, retry is idempotent.
## Open decisions
- Currency rounding mode for JPY: owner Finance (Ola Nowak).

Trzymaj plan obok zmiany, a nie tylko w narzędziu. Plan, który istnieje wyłącznie w czacie albo w prywatnym magazynie planów narzędzia, nie przyda się CI, reviewerom ani kolejnemu agentowi.

Zaplanuj w trybie tylko do odczytu, potem commitnij plan.md

Dział zatytułowany „Zaplanuj w trybie tylko do odczytu, potem commitnij plan.md”
  1. Uruchom sesję w trybie planowania, żeby agent mógł czytać i eksplorować, ale nie mógł edytować plików.

  2. Przekaż agentowi intent.md i spec.md i poproś o plan zgodny z powyższym kontraktem.

  3. Przepytaj plan. Zapytaj, co zmiana może zepsuć, który krok jest najbardziej ryzykowny i jakie alternatywy agent odrzucił i dlaczego.

  4. Uruchom prompt atakujący plan, najlepiej w nowej sesji, żeby na krytykę nie wpływało rozumowanie, z którego plan powstał.

  5. Iteruj, aż plan wskaże prawdziwe pliki, symbole i polecenia weryfikujące. Wtedy go zaakceptuj.

  6. Niech pierwszym zapisem po akceptacji będzie plan.md. Commitnij go przed jakimkolwiek kodem aplikacji.

  7. Implementuj. Gdy implementacja musi odejść od planu, zatrzymaj się, zaktualizuj plan.md z podaniem powodu i uzyskaj od osoby akceptującej zgodę na nowy kierunek. Commitnij zaktualizowany plan razem z kodem, który go wymusił.

Narzędzia różnią się sposobem wejścia w tryb planowania i tym, co agent może w nim robić.

Wejdź w tryb planowania przez Shift+Tab (pasek statusu pokazuje ⏸ plan mode on), albo wpisz /plan i swoją prośbę, co przełącza sesję w tryb planowania. Możesz też uruchomić sesję od razu w tym trybie:

Okno terminala
claude --permission-mode plan

Claude czyta pliki i może uruchamiać eksploracyjne komendy tylko do odczytu. Bez pytania uruchamia je wyłącznie wtedy, gdy auto mode jest dostępny. Nie edytuje kodu, dopóki nie zatwierdzisz planu. Gdy plan jest gotowy, Claude pyta, jak kontynuować: Yes, and use auto mode (gdy auto mode jest dostępny; w przeciwnym razie Yes, auto-accept edits), Yes, manually approve edits albo No, keep planning. Ctrl+G otwiera proponowany plan w edytorze tekstu, zanim odpowiesz.

Ponieważ edycje są zablokowane podczas planowania, Claude nie zapisze plan.md w trybie planowania. Wybierz Yes, manually approve edits i niech pierwszą zatwierdzoną edycją będzie plan.md; na tryb, który rzadziej prosi o zgodę, przełącz się dopiero po commicie planu.

Aby tryb planowania był trybem startowym dla sesji terminalowych w projekcie, ustaw "defaultMode": "plan" w sekcji permissions pliku .claude/settings.json. Sprawdzone na Claude Code 2.1.283.

Worktree daje każdej sesji osobny checkout i gałąź, więc dwie sesje nie nadpiszą sobie plików. Pracę dotykającą różnych plików rozdziel między sesje. Pracę na wspólnych plikach prowadź w jednej sesji, krok po kroku.

Okno terminala
claude -w pay-412-partial-refunds

Worktree powstaje w .claude/worktrees/ na nowej gałęzi. To świeży checkout, więc brakuje w nim plików z .gitignore, takich jak .env; wypisz je w pliku .worktreeinclude w katalogu głównym projektu, a zostaną skopiowane automatycznie. Gdy setup wymaga także osobnych portów albo lokalnego stanu bazy, użyj skryptu pomocniczego repozytorium.

Po akceptacji planu uruchom sesję w najmniej uprzywilejowanym trybie, który wystarczy do wykonania zatwierdzonego fragmentu. Uprawnienia i sandboksy porównują tryby, a strona Git worktree opisuje sprzątanie i kolizje portów.

Wiedza, która dotąd siedziała w głowach ludzi, staje się plikiem czytanym przez agenta na początku każdej sesji. /init przygotowuje szkic w Claude Code i w Codex; w Cursorze poproś agenta o szkic reguły projektu na podstawie repozytorium.

  1. Wygeneruj plik startowy i przytnij go do tego, czego nowa osoba potrzebuje pierwszego dnia: komend budowania, testów i lintera, istotnych konwencji oraz błędów, które agent popełnia regularnie.

  2. Commitnij go w katalogu głównym repozytorium, żeby cały zespół miał jedną wersję.

  3. Gdy agent dwa razy popełni ten sam błąd, dopisz korektę.

  4. Usuń każdą linię, którą agent i tak by respektował. Przycinanie CLAUDE.md i AGENTS.md pokazuje, jak sprawdzić, które linie są potrzebne.

# Payments service
## Commands
- Build: make build
- Test: make test (unit), make itest (integration, needs Docker)
- Lint: make lint
## Conventions
- Java 21, Spring Boot 3. No new Lombok.
- Money is always BigDecimal, never double.
- Every endpoint needs an integration test in src/itest.
## Things the agent gets wrong
- Do not bump dependency versions; the platform team owns them.
- The v1/ package is frozen; changes go in v2/.

Codex czyta AGENTS.md. Claude Code czyta CLAUDE.md. Od wersji 2.1.277 (kanał latest na dzień 2026-09-26; wersja 2.1.281 na Bedrocku, Google Cloud, Foundry i bramach LLM) Claude Code czyta AGENTS.md, gdy projekt nie ma CLAUDE.md. Cursor czyta swoje Rules. AGENTS.md i CLAUDE.md opisuje utrzymanie jednego pliku dla kilku narzędzi.

Gdzie umieścić regułę: plik instrukcji, skill, hook czy CI?

Dział zatytułowany „Gdzie umieścić regułę: plik instrukcji, skill, hook czy CI?”

Plik instrukcji i skill mają charakter doradczy: agent je czyta i zwykle się stosuje. Hook albo kontrola w CI działają jako kod i obowiązują dla wywołań, które dopasowują. Umieść każdą regułę w najtańszej warstwie, która zapewni jej przestrzeganie.

Reguła to…Umieść ją wPrzykład
Fakt potrzebny agentowi w każdej sesjiCLAUDE.md / AGENTS.md / reguła projektu„Testuj przez make test”
Procedura stosowana tylko przy części zadańSkill (SKILL.md)Format błędów API zespołu; checklista bezpieczeństwa
Ograniczenie, którego nie wolno złamać podczas edycjiHookBrak edycji w v1/; formatowanie po każdej edycji
Ograniczenie dotyczące zmergowanego wynikuCI i ochrona gałęziTesty przechodzą; pokrycie nie spada

Skille działają według otwartego standardu Agent Skills (skill-name/SKILL.md); w Claude Code skill projektu leży w .claude/skills/NAME/. Pisanie i współdzielenie skilli opisuje strona o skillach agentów.

Podczas implementacji hooki blokują edycję chronionych ścieżek, uruchamiają formatter i linter po edycji pliku oraz trzymają sekrety z dala od diffa. Hooki etapu budowy mają być szybkie i ograniczone do zmienionego pliku; cięższe kontrole należą do commita albo do CI. Hook, który prosi człowieka o akceptację, należy do etapu Deploy, bo prośba o akceptację na etapie budowy stawia człowieka na ścieżce krytycznej każdej równoległej sesji.

Hooki konfigurujesz w .claude/settings.json. Ten hook PreToolUse blokuje edycję zamrożonego pakietu:

{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{ "type": "command", "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/protect-frozen.sh" }
]
}
]
}
}
#!/bin/bash
# .claude/hooks/protect-frozen.sh (chmod +x; needs jq)
FILE=$(jq -r '.tool_input.file_path // empty')
case "$FILE" in
*/com/acme/payments/v1/*)
echo "v1/ is frozen; put the change in v2/ (see plan.md)" >&2
exit 2 ;;
esac
exit 0

Kod wyjścia 2 blokuje wywołanie narzędzia i pokazuje komunikat Claude’owi, więc agent zmienia kurs zamiast się zatrzymać. Matcher Edit|Write nie widzi zapisów z powłoki: wywołanie Bash z sed -i albo cp do v1/ przejdzie. Wzmocnij regułę kontrolą w CI opisaną niżej albo regułą sandboksa, która zabrania zapisu w tej ścieżce.

Hook pilnuje sesji, a CI pilnuje merge’a. Ta kontrola odrzuca każdy pull request, który zmienia zamrożony pakiet, niezależnie od tego, które narzędzie zapisało zmianę:

Okno terminala
git diff --name-only origin/main...HEAD | grep -q 'com/acme/payments/v1/' \
&& { echo "v1/ is frozen; put the change in v2/"; exit 1; }
exit 0

Checkout rób z fetch-depth: 0, żeby origin/main...HEAD dało się rozwiązać; płytki klon nie ma bazy merge’a, więc ta kontrola i opisana niżej kontrola plan.md kończą się błędem.

Więcej handlerów i wdrożenie w zespole opisuje strona o hookach jako deterministycznych zabezpieczeniach.

Równoległa sesja to kolejny pełny agent we własnym worktree. Subagent działa wewnątrz jednej sesji z własnym oknem kontekstu i ograniczonymi narzędziami: weryfikator, researcher, agent upraszczający kod. Zacznij od dwóch lub trzech równoległych sesji; limitem jest liczba strumieni, dla których jedna osoba zdąży zaakceptować plany i zrobić review. Narzędzia do nadzorowania wielu agentów naraz opisuje strona o równoległych agentach, a porównanie frameworków spec-driven pokazuje, jak Spec Kit i OpenSpec formalizują kontrakt plan.md.

Powtarzalne zadania zamieniaj w subagentów trzymanych w Gicie. W Claude Code to pliki Markdown w .claude/agents/, a Explore i Plan są wbudowane; Codex ma /subagents; Cursor ma Subagents. Przykładowy weryfikator dla Claude Code:

---
name: verifier
description: Runs the app and checks the change against plan.md before the session reports done
tools: Bash, Read
---
Start the app with make run. Exercise the behaviour plan.md describes
and the two nearest neighbouring flows. Report what you ran, what you
saw, and any behaviour that does not match plan.md. Do not fix
anything; report only.

Bash pozwala weryfikatorowi zapisywać pliki, więc „tylko raportuj” to instrukcja, a nie gwarancja. Twardy limit daje uruchomienie go w sandboksie, który zabrania zapisu; zobacz Uprawnienia i sandboksy.

Weryfikator nie jest pętlą informacji zwrotnej. Pętla działa przez całe zadanie; weryfikator to świeży kontekst na końcu, więc jego werdykt nie jest skażony założeniami, które wyprodukowały kod. Własni subagenci opisują ograniczanie narzędzi i wybór modelu.

Jak udowodnić poprawność implementacji bez czytania każdej linii?

Dział zatytułowany „Jak udowodnić poprawność implementacji bez czytania każdej linii?”

To plan sprawia, że diff da się sprawdzić: każde twierdzenie, które reviewer musi przetestować, jest zapisane, zanim powstanie kod.

  • Plan przed kodem. plan.md pojawia się w historii Gita przed pierwszą zmianą w kodzie aplikacji albo w tym samym commicie. Krok CI może sprawdzić, czy pull request zmienia jakiś plan.md. Uruchamiaj go tylko wtedy, gdy pull request ma twoją etykietę zmiany nietrywialnej. Kolejność commitów nadal sprawdza review:

    Okno terminala
    git diff --name-only origin/main...HEAD | grep -q 'plan\.md$' \
    || { echo "Non-trivial change without a committed plan.md"; exit 1; }
  • Polecenia weryfikujące uruchomiono w sesji. Raport z wykonania wymienia każde polecenie weryfikujące z plan.md z jej kodem wyjścia. Brak polecenia oznacza brak dowodu, a nie zaliczone testy.

  • Świeży weryfikator się zgodził. Raport subagenta weryfikującego jest dołączony do pull requestu.

  • Diff zgadza się z planem. Agent review porównuje zmienione pliki z sekcją Files planu i oznacza wszystko, czego tam nie ma. Odstępstwa muszą być opisane w plan.md z podaniem powodu.

Kto zatwierdza. Inżynier akceptuje rutynowe plany. Praca o wyższym ryzyku (migracje, uwierzytelnianie, pieniądze, wspólne interfejsy) trafia do tech leada lub architekta, zanim ruszy implementacja. Akceptacja planu nie daje prawa do merge ani wdrożenia; te pozostają za ochroną gałęzi i bramką produkcyjną opisaną w zarządzaniu i autonomii. Wszystko, co robi sesja, jest przypisane inżynierowi, który ją uruchomił.

Wskaźniki wyprzedzające: odsetek zmian mergowanych po pierwszym przejściu implementacji i czas od akceptacji planu do zmergowanego pull requestu. Wskaźniki opóźnione: liczba cykli poprawek na zmianę i to, jak często zmergowany diff wciąż zgadza się z plan.md. Oba definiuje strona Metryki SDLC opartego na AI.

Co psuje się, gdy implementacja zaczyna się od planu, i jak to naprawić

Dział zatytułowany „Co psuje się, gdy implementacja zaczyna się od planu, i jak to naprawić”

Plan jest ogólnikowy. Mówi „zaktualizuj warstwę serwisów” zamiast wskazać pliki. Odrzuć go i uruchom ponownie prompt szkicujący; planu bez ścieżek i symboli nie da się porównać z diffem.

Claude Code nie zapisze plan.md podczas planowania. Tryb planowania blokuje edycje, także pliku planu. Zatwierdź przez Yes, manually approve edits, najpierw zapisz plan.md i commitnij go przed jakąkolwiek inną edycją.

Plan żyje tylko w narzędziu. Plan w czacie albo we własnym magazynie planów narzędzia jest niewidoczny dla CI i reviewerów. Zapisz go w repozytorium jako plan.md przed pierwszym commitem z kodem aplikacji.

Plan dezaktualizuje się w trakcie implementacji. Agent odkrywa drugie wywołanie albo brakujący indeks. Zatrzymaj sesję, zaktualizuj plan.md z podaniem powodu, uzyskaj zgodę osoby akceptującej i dopiero wtedy kontynuuj. Prompt wykonawczy powyżej każe agentowi się zatrzymać zamiast improwizować.

Tryb planowania traktuje się jak kontrolę uprawnień. Tryb planowania decyduje, kiedy agent może edytować; nie reguluje komend po akceptacji, sekretów, merge ani wdrożenia. Sandbox, akceptacje, ochronę gałęzi i bramki produkcyjne konfiguruj osobno.

Nowy worktree się nie buduje. Świeży checkout nie ma .env ani lokalnego stanu. W Claude Code dopisz pliki do .worktreeinclude albo użyj skryptu setupu repozytorium, który je kopiuje i przydziela porty.

Równoległe sesje kolidują. Dwie sesje edytowały ten sam plik i jeden merge cofa drugi. Podziel pracę w plan.md według własności plików, a kroki na wspólnych plikach wykonuj w jednej sesji.

Hook etapu budowy spowalnia każdą edycję. Pełny zestaw testów przy każdej edycji pliku dławi pętlę. Ogranicz hook do zmienionego pliku, a kontrole całego zestawu przenieś do commita albo CI.

Narzędzie nie ma trybu planowania w bieżącym kontekście. Niektóre powierzchnie i uruchomienia headless go nie oferują. Użyj promptu szkicującego z sandboksem tylko do odczytu, na przykład codex exec -s read-only (odpowiednik w profilach uprawnień podaje zakładka Codex powyżej).