Pisanie dobrych specyfikacji
Rzadko piszesz specyfikację od zera. Opisujesz zmianę w języku naturalnym, /opsx:propose tworzy projekt wymagań i scenariuszy, a następnie ulepszasz je. Ta strona dotyczy właśnie tego ostatniego etapu — tego, jak wygląda „dobra” specyfikacja i jak skierować sztuczną inteligencję w tym kierunku.
Jest to uzupełnienie dokumentu Przeglądanie zmiany: przeglądanie polega na wykrywaniu słabych punktów w projekcie, podczas gdy pisanie polega na wiedzeniu, z czego składa się silna specyfikacja.
Specyfikacja to zachowanie, nie kod
Specyfikacja mówi o tym, co twój system robi, w sposób, który każdy może zweryfikować — a nie o tym, jak jest zbudowany. Składa się z wymagań (stwierdzeń dotyczących zachowania) i scenariuszy (konkretnych przykładów je potwierdzających).
### Wymaganie: Wygaśnięcie sesji
System MUSI wygaszać sesję po 30 minutach bezczynności.
#### Scenariusz: Próg bezczynności
- DANE: uwierzytelniona sesja
- GDY: upłynie 30 minut bez żadnej aktywności
- TO: sesja zostaje unieważniona, a użytkownik musi ponownie się uwierzytelnićZachowaj szczegóły implementacji — kolejkę, bibliotekę, schemat tabeli — w pliku design.md lub w kodzie. Gdy wymagania mieszają zachowanie z implementacją, przestają być testowalne i stają się nieaktualne w momencie wprowadzenia zmian w kodzie.
Czym jest dobre wymaganie
Dobre wymaganie opisuje jedno zachowanie, sformułowane tak prosto, że można je przekazać innej osobie do przetestowania.
Jedno stwierdzenie, jedno
MUSI/SHALL. Jeśli wymaganie zawiera trzy klauzule typu „oraz dodatkowo”, tak naprawdę są to trzy różne wymagania. Podziel je.Obserwowalne. Osoba spoza zespołu programistycznego powinna móc stwierdzić, czy wymaganie jest spełnione. „System POWINIEN wyświetlać baner błędu, gdy przesyłany plik przekracza 10 MB” jest obserwowalne. „System POWINIEN obsłużyć duże przesyłki w sposób elegancki” — nie.
Odpowiednia siła wiążąca. OpenSpec używa słów kluczowych z RFC 2119, które mają różne znaczenia:
Słowo kluczowe Znaczenie MUST/SHALLTwarde wymaganie. Niepodlegające negocjacjom. SHOULDSilna rekomendacja, z możliwością uzasadnionego wyjątku. MAYNaprawdę opcjonalne. Domyślnie wybieraj
MUST/SHALL. UżywajSHOULDtylko wtedy, gdy naprawdę masz na myśli „chyba że istnieje dobry powód, aby tak nie zrobić”.
Testem dla wymagania jest pytanie: czy tester, który nigdy nie widział kodu, mógłby stwierdzić, czy wymaganie zostało spełnione? Jeśli nie, wymaga ono doprecyzowania.
Czym jest dobry scenariusz
Scenariusze są miejscem, w którym wymaganie udowadnia swoją wartość. Każdy z nich to konkretny GIVEN/WHEN/THEN (DANE/GDY/TO), który może stać się automatycznym testem.
- Wykorzystuje swoje wymaganie. Scenariusz, który jedynie parafrazuje wymaganie innymi słowami, niczego nie testuje. Stwórz konkretną sytuację z konkretnym wynikiem.
- Pokryj istotne przypadki, a nie tylko ścieżkę szczęścia. Poprawne logowanie jest łatwe. Puste dane wejściowe, wygaszony token, drugie kliknięcie, rzeczy, które idą źle — tam żyją błędy i tam scenariusz ma największą wartość.
- Nazwij przypadek w tytule. „Scenariusz: Odrzuca wygaszony token” informuje recenzenta o zawartości na pierwszy rzut oka; „Scenariusz: Test 2” — nie.
Przydatną nawyką jest przed zatwierdzeniem zadanie pytania: jaki jeden przypadek najbardziej bym żałował, gdyby został złamany? — i upewnienie się, że scenariusz go obejmuje.
Wybierz odpowiedni rodzaj delta
Zmiana opisuje swoje edycje w specyfikacjach za pomocą trzech typów sekcji. Użycie właściwej z nich zapewnia uczciwość archiwizowanych specyfikacji:
## ADDED Requirements— całkowicie nowe zachowanie, którego wcześniej nie było.## MODIFIED Requirements— istniejące już zachowanie, które ulega zmianie. Dołącz pełną nową wersję; krótka notatka wyjaśniająca zmiany pomaga recenzentowi.## REMOVED Requirements— zachowanie, które znika, wraz z linią wyjaśniającą dlaczego.
Podczas archiwizacji sekcja ADDED jest dołączana do głównej specyfikacji, MODIFIED zastępuje starą wersję, a REMOVED jest usuwana. Usunięcie ostatniego wymagania danej funkcjonalności oznacza jej wycofanie: zamiast pozostawiać pustą specyfikację, archiwizacja usuwa plik openspec/specs/<capability>/spec.md. Ponieważ jest to jedyny krok archiwizacji usuwający plik, musi on być wyraźnie potwierdzony — dodaj retire_capabilities: true do pliku .openspec.yaml zmiany, obok istniejącego tam schema:. Bez tego operacja archiwizacji zostanie przerwana z komunikatem o błędzie. Wycofanie usuwa cały plik, dlatego również jest odrzucane, jeśli specyfikacja zawiera cokolwiek poza tytułem, sekcją ## Purpose oraz blokami wymagań — np. sekcję ## Notes lub komentarz pod wymaganiem. Błąd wskazuje linie powodujące problem; przenieś je do sekcji ## Purpose lub do wymagania, albo usuń specyfikację ręcznie. Dla specyfikacji w katalogu roboczym wywołującego, wyjście archiwizacji zawiera również polecenie git checkout przywracające skommitowany plik; wybrane magazyny otrzymują wskazówki dotyczące odzyskiwania ograniczonego do zakresu checkoutu. Jeśli oznaczysz rzeczywistą zmianę jako ADDED, otrzymasz dwa konkurujące ze sobą wymagania; jeśli opiszesz nowe zachowanie jako MODIFIED, nie będzie czego zastępować. W razie wątpliwości otwórz aktualną specyfikację i sprawdź, czy wymaganie już tam istnieje.
Jeszcze jedna sekcja warta poznania. Gdy twoja delta tworzy funkcjonalność, której jeszcze nie ma, otwórz ją sekcją ## Purpose — zdaniem lub dwoma wyjaśniającymi, do czego służy ta funkcjonalność. Archiwizacja używa jej jako Purpose (Cel) dla tworzonej głównej specyfikacji; pominięcie jej skutkuje koniecznością ręcznego wypełnienia placeholdera TBD. Istniejąca specyfikacja już posiada sekcję Purpose, więc sekcja Purpose w delfcie zostanie tam zignorowana — edytuj bezpośrednio plik openspec/specs/<capability-path>/spec.md, aby zmienić cel. Tutaj <capability-path> to katalog względny w stosunku do specs/, taki jak user-auth w projekcie płaskim lub identity/user-auth w projekcie zorganizowanym według domen.
Dopasuj rozmiar zmiany
Najczęstszym błędem autorstwa nie jest źle sformułowane wymaganie — to zmiana, która próbuje być trzema zmianami.
Dobra zmiana ma jeden intencję, którą możesz wyrazić jednym zdaniem. „Dodaj przełącznik trybu ciemnego.” „Ogranicz częstotliwość żądań dla endpointu logowania.” „Migracja sesji z cookies.” Jeśli opisywanie zmiany wymaga dużo „oraz dodatkowo”, to sygnał, aby ją podzielić.
Objawy, że zmiana jest zbyt duża:
- Zakres propozycji brzmi jak lista niezwiązanych ze sobą funkcji.
- Przeglądanie jej zajęłoby popołudnie, więc nikt tego nie zrobi.
- Dwie osoby nie mogłyby pracować nad nią bez kolizji.
- Połowa zadań mogłaby zostać dostarczona samodzielnie.
Mniejsze zmiany są łatwiejsze do recenzji, łatwiejsze do zrealizowania w jednej skoncentrowanej sesji i łatwiejsze do zrozumienia sześć miesięcy później, gdy archiwum będzie jedynym źródłem prawdy. Możesz zawsze uruchamiać kilka zmian równolegle — zobacz Edycja i iteracja oraz Workflow-y.
Ma miejsce też odwrotna sytuacja: poprawka literówki w jednym wierszu nie wymaga trzech wymagań i dokumentu projektowego. Dopasuj ceremonię do wagi sprawy.
Jak skierować AI ku dobremu projektowi
Ponieważ /opsx:propose wykonuje pierwszy szkic, jakość otrzymanego wyniku zależy od jakości danych wejściowych. Nie musisz pisać wymagań ręcznie — musisz dobrze ukierunkować AI:
- Określ intencję i granice. „Dodaj przełącznik trybu ciemnego, który dostosowuje się do ustawień systemu operacyjnego przy pierwszym uruchomieniu — nie dotykaj istniejącego API motywów.” Poza-zakresowa część jest tak samo ważna jak część w-zakresowa.
- Wymień przypadki, które Cię interesują. „Upewnij się, że istnieje scenariusz dla użytkownika, który już ręcznie wybrał motyw.” AI pokrywa to, na co wskażesz.
- Następnie edytuj. To zwykły Markdown. Zaostrz niejasne
SHALL, usuń scenariusz, który niczego nie testuje, dodaj brakujący przypadek — lub poproś AI o to: „wymaganie dotyczące czasu oczekiwania jest niejasne, precyzyjnie określ je na 30 minut.”
Szkic, dopracowanie, powtarzanie. Kilka rund takiego procesu daje specyfikację, której możesz zaufać — a o to chodzi w całym procesie.
Krótka lista kontrolna
Gdzie dalej?
- Przeglądanie zmiany — dwuminutowe przejście, które wychwytuje to, co umknęło.
- Koncepcje — głębszy model stojący za specyfikacjami, zmianami i deltami.
- Przykłady i przepisy — rzeczywiste zmiany od początku do końca.