Plan: zapisz intent.md
Etap planowania w cyklu AI-native zamienia pomysł, ticket albo sygnał z produkcji w commitowany intent.md: problem, oczekiwany wynik, ograniczenia i otwarte pytania, zapisane słowami zgłaszającego. Agent przeprowadza wywiad ze zgłaszającym i pisze plik, ale zatrzymuje się przed jakimkolwiek projektem i kodem. Product owner akceptuje plik, zatwierdzając pull request, który go dodaje.
Ta strona jest dla dewelopera albo product ownera, który spisuje intencję, i dla tech leada, który odpowiada za kolejną bramkę (akceptację przed designem). Oto sytuacja, którą rozwiązuje. Support przekazuje do zespołu „klienci chcą powiadomień”, deweloper wkleja to agentowi, a w piątek działa funkcja e-mailowa, o którą nikt nie prosił. Klienci chcieli powiadomień w aplikacji i tylko o komentarzach do własnych dokumentów. Nigdzie nie było to zapisane.
Tradycyjnie: pomysł przechodzi przez backlog, user stories i spotkania refinementowe, zanim ktokolwiek zacznie nad nim pracować. Przy każdym przekazaniu zmienia się właściciel, więc to, co dociera do inżynierów, jest oddalone o kilka kroków od tego, co zgłaszający miał na myśli.
AI-native: zgłaszający omawia pomysł z agentem, który zadaje pytania analityka, a wynik trafia do repozytorium jako intent.md w ramach tej samej sesji pracy. Agenci od designu, budowy i review czytają ten jeden plik.
Co daje taki sposób zapisywania intencji
Dział zatytułowany „Co daje taki sposób zapisywania intencji”- Szablon i wypełniony przykład
intent.mdoraz zasadę, co do niego nie wchodzi. - Trzy prompty do skopiowania: wywiad ze zgłaszającym, szkic intencji z ticketu i kodu oraz atak na szkic w świeżej sesji.
- Skill
capture-intentdo commitowania, dzięki któremu każdy zgłaszający przechodzi ten sam wywiad w Claude Code, Codeksie i Cursorze. - Kontrolę kształtu w CI i bramkę w
CODEOWNERS, więc nikt nie sprawdza struktury ręcznie, a żadna intencja nie zostanie przyjęta bez zatwierdzenia product ownera. - Sposób wyjścia z każdej typowej awarii tego etapu.
Zanim zapiszesz intencję
Dział zatytułowany „Zanim zapiszesz intencję”- Miejsce na intencje. Trzymaj katalog
intent/w repozytorium produktu, po jednym podkatalogu na zmianę:intent/notifications/intent.md. Etap designu zapisuje obok niegospec.md. Osobne repozytorium intencji opłaca się dopiero wtedy, gdy jedna intencja obejmuje wiele repozytoriów; ten wybór oraz alternatywy w Jirze czy Linearze opisuje łańcuch artefaktów. - Szablon. Zacommituj
intent/TEMPLATE.mdz następnej sekcji. - Wskazana osoba akceptująca. Jeden product owner na obszar, wpisany do
CODEOWNERS(zobacz sekcję o weryfikacji). - Ścieżka dla osób, które nie używają gita. Product manager albo inżynier supportu może przeprowadzić wywiad w claude.ai lub Claude Cowork, a potem dodać plik jako pull request przez edytor webowy GitHuba. Może też zacommitować go za nich inżynier. Liczy się plik, a nie narzędzie, którego użył zgłaszający.
To pierwszy etap cyklu AI-native, więc nie wymaga żadnego wcześniejszego.
Co zawiera intent.md?
Dział zatytułowany „Co zawiera intent.md?”intent.md mówi, co jest potrzebne i dlaczego. Nigdy nie mówi jak. Nazwy tabel, endpointy, biblioteki i ścieżki plików należą do spec.md i plan.md, gdzie decyduje o nich ktoś, kto przeczytał kod. Szablon jest ten sam, którego używa łańcuch artefaktów:
# Intent: INTENT_TITLEAuthor: AUTHOR_NAME (TEAM). Status: draft | accepted. Ticket: TICKET_ID
## ProblemWHAT_IS_BROKEN_OR_MISSING
## Proposed outcomeWHAT_BETTER_LOOKS_LIKE
## Affected users and systemsUSERS_AND_SYSTEMS
## ConstraintsCONSTRAINTS
## Open questionsOPEN_QUESTIONSTak wygląda przykład z powiadomieniami po 20-minutowym wywiadzie. Zwróć uwagę, o czym agentowi nie wolno było zdecydować:
# Intent: Tell document owners when a teammate commentsAuthor: Maria Nowak (Support). Status: draft. Ticket: SUP-412
## ProblemDocument owners miss comments on their documents. Support gets about tentickets a week that read "I didn't know anyone had replied". Owners onlysee comments when they reopen the document.
## Proposed outcomeAn owner learns about a new comment on their document within a minute,without opening it, and can turn this off. Success: those support ticketsstop.
## Affected users and systemsDocument owners on all plans. The comments feature and the accountsettings screen. Commenters see no change.
## ConstraintsIn-app first. Email is out of scope for this change (originator preference:customers asked for in-app). Must respect the existing "do not disturb"setting. No new third-party service without a security review.
## Open questions- Should owners hear about replies inside a thread they already follow? (Product owner to decide.)- What volume do the largest workspaces generate per hour? (Data team.)| Sekcja | Jest dobra, gdy | Sygnał ostrzegawczy |
|---|---|---|
| Problem | Mówi, kto dziś czego nie może zrobić, słowami zgłaszającego | Opisuje funkcję („dodaj tabelę notifications”) |
| Proposed outcome | Tester mógłby zaobserwować, że to się dzieje | „Lepiej”, „szybciej” albo „usprawnić” bez zdarzenia czy liczby |
| Affected users and systems | Wymienia użytkowników i istniejące systemy, także tych, dla których nic się nie zmienia | Pusta albo „wszyscy” |
| Constraints | Wymienia terminy, regulacje, budżety i systemy, których nie wolno zmieniać | Decyzja projektowa podana jako ograniczenie bez słowa „preference” |
| Open questions | Każde pytanie wskazuje, kto może na nie odpowiedzieć | Pusta przy czymkolwiek większym niż drobna poprawka: agent zgadywał |
intent.md pomijasz tylko przy zmianach, których nikt spoza zespołu nie zauważy: literówka, podbicie zależności, refaktoryzacja bez zmiany zachowania. Wszystko, co może zauważyć użytkownik albo inny system, dostaje intencję, nawet jeśli wydaje się drobne.
Zapisz intencję w pięciu krokach
Dział zatytułowany „Zapisz intencję w pięciu krokach”-
Zacznij od tego, co masz. Wystarczy pomysł, ticket, e-mail od klienta albo zrzut ekranu. Zgłaszający nie musi mówić ustrukturyzowanym językiem; strukturę tworzy wywiad.
-
Przeprowadź wywiad. Agent zadaje jedno pytanie naraz i proponuje odpowiedź, więc zgłaszający reaguje, zamiast pisać od zera. Wszystko, na co nie ma odpowiedzi, trafia do Open questions zamiast do zgadywania.
Gdy inżynier zaczyna od ticketu, agent może najpierw przeczytać ticket i kod, a na wywiad przyjść ze szkicem i krótszą listą pytań.
-
Popraw szkic jako zgłaszający. Zgłaszający czyta plik, który jest krótki, i poprawia wszystko, co agent źle zrozumiał. To przejście należy do zgłaszającego, a nie do inżyniera, który prowadził sesję.
-
Zaatakuj szkic w świeżej sesji. Nowa sesja nie ma założeń z wywiadu, więc czyta plik tak, jak przeczyta go agent od designu.
-
Otwórz pull request i pozwól product ownerowi go zaakceptować. Pull request zawiera tylko
intent/notifications/intent.md. Product owner komentuje, prosi o zmiany albo zatwierdza. Przed zatwierdzeniem product owner (albo autor, na jego prośbę) zmieniaStatus: draftnaStatus: acceptedw tym samym pull requeście. Scalenie po tym zatwierdzeniu jest akceptacją i wysyła intencję do etapu Design: napisz spec.md. Zamknięcie pull requesta to zapisane odrzucenie.
Jak poprowadzić wywiad w Claude Code, Codeksie i Cursorze?
Dział zatytułowany „Jak poprowadzić wywiad w Claude Code, Codeksie i Cursorze?”Wywiad wygląda tak samo w każdym narzędziu. Różni się tylko sposób, w jaki powstrzymujesz agenta przed edycją kodu produktu, gdy zadaje pytania.
- Uruchom sesję w trybie tylko do odczytu poleceniem
claude --permission-mode planalbo przełącz się przez Shift+Tab lub/plan. Od v2.1.283 (kanałlatest) sesje interaktywne startują w trybie auto, więc przełącz się świadomie. - Tryb planowania blokuje wszystkie edycje, także
intent.md. Gdy Claude przedstawi plan zapisaniaintent.md, wybierz Yes, manually approve edits; potem zatwierdź zapis dointent/notifications/intent.mdi odrzuć każdy inny plik. - Product owner bez terminala może uruchomić ten sam prompt w claude.ai lub Claude Cowork, a potem otworzyć pull request w edytorze webowym GitHuba.
- Włącz tryb planowania poleceniem
/planw CLI i wklej prompt z wywiadem. Po wywiadzie wyjdź z trybu planowania i poproś Codeksa o zapisanie wyłącznieintent/notifications/intent.md. - Zrzut ekranu albo zdjęcie tablicy dołączysz do pierwszego promptu przez
codex "$(cat prompt.txt)" -i sketch.png. Prompt podaj przed-i, bo-itraktuje każdy kolejny argument jako ścieżkę obrazu (codex-cli 0.157.1). - Aplikacja desktopowa Codex uruchamia ten sam prompt dla osób, które nie pracują w terminalu.
- Do wywiadu użyj Plan Mode, który „creates detailed implementation plans before writing any code” (dokumentacja Cursora, sprawdzone 2026-08-28).
- Traktuj jego wynik jako szkic
intent.md, a nie plan. Plan Mode nie zapisuje plików produktu, więc po wywiadzie przełącz czat w tryb Agent i poproś o zapisanie wyłącznieintent/notifications/intent.mdna podstawieintent/TEMPLATE.md. Zrób to, zanim zamkniesz czat, żeby sesja designu i pozostałe narzędzia czytały ten sam plik. - Przejrzyj proponowaną zmianę pliku w panelu przeglądu, zanim ją zaakceptujesz, i odrzuć każdy inny plik.
Zrób z wywiadu skill, który dostaje każdy zgłaszający
Dział zatytułowany „Zrób z wywiadu skill, który dostaje każdy zgłaszający”Prompt wklejany z wiki się rozjeżdża: każdy przycina go po swojemu. Skill w repozytorium daje każdemu zgłaszającemu ten sam wywiad i ten sam szablon. Zacommituj go jako capture-intent/SKILL.md w katalogu skilli każdego narzędzia (.claude/skills/ dla Claude Code, .agents/skills/ dla Codeksa i Cursora; etap designu wymienia te lokalizacje i pokazuje, jak trzymać jedną kopię źródłową):
---name: capture-intentdescription: Use when someone describes an idea, ticket, bug report, or incident and wants it written up as intent.md, or asks to capture intent before design. Interviews the originator and writes intent/FEATURE/intent.md from intent/TEMPLATE.md. Never designs or writes code.---
# Capture intent
1. Ask one question at a time and give your recommended answer with each.2. Cover, in order: the problem today and for whom, how often it happens, an observable outcome, constraints, and what is out of scope.3. If the codebase can answer a question, read the code instead of asking. Do not edit any file while reading.4. Stop asking when every template section has content or a named open question.5. Write intent/FEATURE/intent.md from intent/TEMPLATE.md with Status: draft. Keep the originator's words in Problem.6. Never name tables, endpoints, libraries, or files. A design idea the originator insists on goes under Constraints, marked "originator preference".7. Every unanswered question goes under Open questions with who can answer it.Wywołaj go po nazwie, gdy chcesz mieć pewność, że się załaduje: /capture-intent w Claude Code i Cursorze, $capture-intent w Codeksie. Budowanie własnych skilli opisuje, jak przetestować skill, zanim zespół zacznie na nim polegać.
Szkicuj intencję z ticketu bez otwierania sesji
Dział zatytułowany „Szkicuj intencję z ticketu bez otwierania sesji”Gdy tickety przychodzą szybciej, niż ktokolwiek zdąży przepytać ich autorów, niech pierwszy szkic napisze zadanie headless, a pytania z wywiadu trafią do pull requesta. Autor odpowiada tam, a agent poprawia plik.
# Terminal albo zadanie CI. TICKET.md zawiera wyeksportowaną treść ticketu i nigdy nie trafia do commita.FEATURE=notificationsPROMPT="Use the capture-intent skill. Read TICKET.md and the code it refers to. \Write intent/$FEATURE/intent.md with Status: draft. Do not ask questions: \put every question under Open questions with who can answer it."
# Przed startem agenta: pobierz commit bazowy i skrypt kontroli z zaufanej bazy.# Oba zostają w pamięci tej powłoki, gdzie agent nie może ich zmienić.BASE_SHA=$(git rev-parse origin/main) || exit 1CHECK=$(git show "$BASE_SHA:scripts/check-intent.sh") && [ -n "$CHECK" ] || exit 1
# Claude Code: headless, edycje plików akceptowane, bez interaktywnych pytańclaude -p "$PROMPT" --permission-mode acceptEdits
# albo Codex: headless, sandbox ograniczony do workspace'ucodex exec -s workspace-write "$PROMPT"
# Zadanie nie commituje zmian: zaindeksuj je bez ticketu, żeby kontrola kształtu je zobaczyłagit add -A -- . ':!TICKET.md'printf '%s\n' "$CHECK" | REQUIRE_INTENT=1 RANGE="--cached $BASE_SHA" shTreść ticketu pochodzi spoza zespołu, więc traktuj ją jak każde niezaufane wejście: uruchamiaj zadanie bez poświadczeń do wdrożeń i sekretów produkcyjnych, a kontrola kształtu opisana niżej niech oblewa każdy przebieg, który dotknął pliku poza intent/. Uruchamiaj skrypt kontroli w wersji z origin/main, nigdy kopię z workspace’u: agent może edytować każdy plik w workspace’ie, także scripts/check-intent.sh, a skrypt przepisany na exit 0 przepuści wszystko. Dlatego zadanie wczytuje skrypt i commit bazowy, zanim agent wystartuje, i kończy się błędem, gdy w bazie nie ma skryptu kontroli. Zadanie nie commituje zmian, więc przed kontrolą zaindeksuj jego wynik, jak w dwóch ostatnich liniach; kontrola czytająca tylko historię commitów nie zobaczyłaby żadnych zmian i przeszłaby bez błędu. REQUIRE_INTENT=1 sprawia, że w razie wątpliwości kontrola oblewa: przebieg, który nie zapisał intent.md, a zmienił src/ albo .github/, kończy się błędem, zamiast przejść jako zmiana bez intencji, a gdy skrypt nie może porównać zmian z gałęzią bazową, zwraca błąd, a nie sukces. Specyfikacja ścieżki ':!TICKET.md' zostawia wyeksportowany ticket poza indeksem, więc kontrola nie zgłasza go jako zbędnego pliku. Incydent produkcyjny przechodzi tę samą ścieżkę, poprzedzony agentem triażu działającym tylko do odczytu; opisuje to Maintain: zamknij pętlę.
Jak sprawdzić intent.md bez czytania go linijka po linijce?
Dział zatytułowany „Jak sprawdzić intent.md bez czytania go linijka po linijce?”Intencja jest krótka i czytają ją zgłaszający oraz product owner. Nikt więcej nie powinien. Podziel sprawdzanie na trzy części: skrypt sprawdza kształt, przegląd w świeżej sesji sprawdza treść, a product owner podejmuje jedyną decyzję, która wymaga człowieka.
Kontrola kształtu. Zapisz ją jako scripts/check-intent.sh. Uruchamiaj ją w CI przy każdym pull requeście; kończy się od razu, jeśli pull request nie zmienia pliku intent/*/intent.md, więc pull requesty z designu i budowy, które dodają spec.md i plan.md do tego samego katalogu, przechodzą bez przeszkód. Uruchamiaj ją też po zadaniu headless, w wersji z bazy, jak pokazano wyżej, ze zmienną RANGE wskazującą zaindeksowane zmiany i z REQUIRE_INTENT=1, żeby przebieg bez intent.md oblał kontrolę:
# W CI pull requesta porównuje gałąź z jej merge base (domyślnie).# CI: pobierz repozytorium z fetch-depth: 0 (albo git fetch origin main), żeby origin/main...HEAD dało się rozwiązać.# Po zadaniu headless zaindeksuj jego wynik i uruchom:# REQUIRE_INTENT=1 RANGE="--cached $BASE_SHA" sh, z tym plikiem z bazy na stdinBASE=origin/mainRANGE=${RANGE:-"$BASE...HEAD"}status=0
# Bezpieczna porażka: zakres, którego git nie rozwiąże, to błąd, a nie „brak zmian”.changed=$(git diff --name-only $RANGE) || { echo "git diff $RANGE failed"; exit 2; }intents=$(printf '%s\n' "$changed" | grep '^intent/.*/intent\.md$')
if [ -z "$intents" ]; then # Zadanie headless musi wytworzyć intent.md; wszystko inne, co zmieniło, oblewa kontrolę. if [ -n "$REQUIRE_INTENT" ]; then [ -n "$changed" ] && printf '%s\n' "$changed" echo "No intent/*/intent.md changed"; exit 1 fi # Pull requesty bez zmian w intent.md (specyfikacja i budowa) przechodzą. exit 0fi
# Pull request z intencją zmienia wyłącznie pliki intent.md.if printf '%s\n' "$changed" | grep -v -e '^intent/.*/intent\.md$' -e '^$'; then echo "Files above are not intent.md files"; status=1fi
for f in $(git diff --name-only --diff-filter=AM $RANGE -- 'intent/*/intent.md'); do grep -Eq '^Author: .+Status: (draft|accepted)' "$f" || { echo "$f: no Author/Status line"; status=1; } for s in '## Problem' '## Proposed outcome' '## Affected users and systems' '## Constraints' '## Open questions'; do grep -qx "$s" "$f" || { echo "$f: missing section $s"; status=1; } done # Bloki kodu i ścieżki źródeł należą do spec.md albo plan.md. if grep -nE '^`{3}|(src|app|lib)/[A-Za-z0-9_./-]+\.(ts|tsx|js|py|go|rb|php|ex)' "$f"; then echo "$f: code or file paths above belong in spec.md or plan.md"; status=1 fidoneexit $statusKontrola treści. Wklej tabelę z przeglądu w świeżej sesji do pull requesta. Werdykt NOT READY wraca do zgłaszającego, a nie do product ownera.
Bramka ludzka. Nic nie zostanie scalone bez zatwierdzenia product ownera. Wpisz go do CODEOWNERS i włącz „Require review from Code Owners” w regule ochrony gałęzi domyślnej. To czyni zatwierdzenie obowiązkowym, ale po nim scalić może każdy z prawem zapisu; jeśli samo scalenie ma należeć do product ownera, ogranicz też, kto może pushować do gałęzi (ruleset albo opcja „Restrict who can push to matching branches”). Minimalny CODEOWNERS:
# .github/CODEOWNERS/intent/**/intent.md @acme/product-owners/intent/billing/**/intent.md @acme/billing-productWzorce pasują tylko do intent.md, więc spec.md i plan.md z tego samego katalogu przechodzą przez własnych właścicieli, a nie przez product ownerów.
Wskaźniki. Dwie liczby z historii gita pokazują, czy etap działa; obie definiuje strona Metryki AI-native SDLC:
- Wyprzedzający: czas od pierwszego zgłoszenia (daty utworzenia ticketu albo pierwszego commita na gałęzi) do scalonego
intent.md. Gdy etap działa, mierzy się go w godzinach albo dniach, nie w tygodniach. - Opóźniony: odsetek intencji przyjętych do designu zamiast zamkniętych oraz to, jak często
intent.mdzmienia się jeszcze po pierwszym commiciespec.mddla tej samej zmiany. Późne edycje intencji oznaczają, że wywiad coś przeoczył.
Co się psuje, gdy intencję zapisuje agent, i jak to naprawić
Dział zatytułowany „Co się psuje, gdy intencję zapisuje agent, i jak to naprawić”Intencja zawiera rozwiązanie. Problem brzmi „dodaj tabelę notifications”, a Proposed outcome opisuje ekran ustawień. Kontrola kształtu łapie ścieżki plików, a przegląd w świeżej sesji (punkt 1) resztę. Przenieś każdy pomysł projektowy do Constraints jako preferencję zgłaszającego albo go usuń, a wynik przepisz tak, żeby tester mógł go zaobserwować.
Open questions jest puste przy prawdziwej funkcji. Agent zapełnił każdą lukę wiarygodnym domysłem, a domysły wyglądają teraz jak wymagania. Uruchom ponownie przegląd w świeżej sesji i poproś, żeby każde niepoparte stwierdzenie zamienił w pytanie. Jeśli w skillu brakuje zdania „anything I cannot answer goes under Open questions”, dopisz je.
Inżynier napisał intencję sam. Plik czyta się dobrze, ale opisuje to, co zbudowałby inżynier, a nie to, czego potrzebuje zgłaszający. Odeślij pull request do zgłaszającego na krok 3. Autor pull requesta jest widoczny w gicie, więc ten wzorzec widać w historii.
Wywiad się nie kończy. Po czterdziestu pytaniach zgłaszający się poddaje. Każ agentowi skończyć, gdy każda sekcja szablonu ma treść albo nazwane otwarte pytanie, co mówi już krok 4 skilla, a pozostałe pytania przenieś do pliku.
Jedna intencja ukrywa trzy zmiany. „Powiadomienia, podsumowania i usługa push na telefony” w jednym pliku dają specyfikację, której nikt nie zaakceptuje. Przegląd w świeżej sesji (punkt 5) proponuje podział. Akceptuj jedną intencję na każdy wynik, który da się wdrożyć niezależnie.
Intencja żyje poza repozytorium. Leży w wątku na czacie, na slajdzie albo w portalu, którego agent nie przeczyta, a sesja designu startuje od parafrazy. Trzymaj plik w gicie. Jeśli istniejący system, na przykład Jira, musi zostać rejestrem, powiąż oba tak, jak opisuje łańcuch artefaktów.
Claude Code nie może zapisać pliku w trybie planowania. Tryb planowania blokuje każdą edycję. Gdy Claude przedstawi plan, wybierz Yes, manually approve edits; potem każda edycja pyta osobno, więc zatwierdź zapis do intent.md i odrzuć każdy inny plik.
Intencja zmienia się po powstaniu specyfikacji. Ktoś w trakcie budowy edytuje intent.md, żeby pasował do tego, co zbudowano. Zamrażaj zaakceptowane intencje: zmiana intencji to nowy pull request z własną akceptacją, który odsyła specyfikację z powrotem do designu. Te edycje liczy wskaźnik opóźniony opisany wyżej.