OpenSpec: propozycje zmian i żywe specyfikacje
OpenSpec to otwartoźródłowa warstwa specyfikacji od Fission AI dla agentów kodujących, które pracują na istniejącym kodzie. Każda zmiana dostaje propozycję, delty wymagań i listę zadań; gdy agent ją zaimplementuje, archiwizacja scala delty w openspec/specs/, żywy opis tego, jak system działa teraz. Działa w Claude Code, Codex i Cursorze.
Endpoint resetu hasła ma sześć lat, nikt nie spisał, jak się zachowuje, a dział bezpieczeństwa chce w tym sprincie limitu żądań, a w następnym krótszego czasu życia tokenu. Możesz dać agentowi ticket i przejrzeć diff albo uruchomić Spec Kit i wyprodukować specyfikację, plan, notatki z researchu i kontrakty dla dwugodzinnej zmiany. Żadna z tych dróg nie zostawia ci spisanej, aktualnej odpowiedzi na pytanie „co dziś robi reset hasła?”.
Ta strona jest dla programisty, który uruchamia agenta na kodzie z historią. Przeprowadza obie te zmiany przez OpenSpec, pokazuje dokładne pliki i polecenia, a na końcu daje regułę, kiedy lepszym wyborem jest Spec Kit.
Co zyskujesz, uruchamiając OpenSpec na istniejącym kodzie
Dział zatytułowany „Co zyskujesz, uruchamiając OpenSpec na istniejącym kodzie”- Działającą instalację dla Claude Code, Codex i Cursora w jednym repozytorium oraz pisownię poleceń w każdym narzędziu.
- Regułę, która rozstrzyga o pierwszej zmianie w kodzie bez specyfikacji: tylko wymagania
ADDEDmogą utworzyć specyfikację, i dlatego testy charakteryzacyjne są krokiem zerowym. - Dwie prawdziwe delty dla endpointu resetu hasła: jedną, która tworzy specyfikację, i drugą, która modyfikuje i usuwa w niej wymagania.
- Prompty do skopiowania dla explore, propose, apply i pull requesta.
- Job CI, który odrzuca źle sformatowaną zmianę i archiwizację, która zapomniała zaktualizować żywą specyfikację.
- Tabelę decyzyjną: OpenSpec czy Spec Kit, gdy kod już istnieje.
Jak działa model zmian w OpenSpec?
Dział zatytułowany „Jak działa model zmian w OpenSpec?”OpenSpec rozdziela dwie rzeczy: to, co system robi teraz (openspec/specs/), i to, co zmieni jedna zmiana (openspec/changes/<nazwa>/). Tak wygląda drzewo po zarchiwizowaniu pierwszej zmiany z tego tutorialu i zaproponowaniu drugiej:
Folderopenspec/
- config.yaml schemat
spec-driven, opcjonalnecontext:irules: Folderspecs/
- password-reset/spec.md żywa specyfikacja, zapisywana wyłącznie przez archive
Folderchanges/
Foldershorten-reset-token-ttl/ w toku
- proposal.md dlaczego, co się zmienia, których obszarów dotyczy
- specs/password-reset/spec.md delta
- design.md opcjonalny, dla zmian przekrojowych albo ryzykownych
- tasks.md numerowane checkboksy, przez które przechodzi apply
Folderarchive/
Folder2026-09-26-add-reset-rate-limit/ pierwsza zmiana, zachowana jako historia
- …
- config.yaml schemat
Plik delty używa czterech nagłówków sekcji. Krok archive nakłada je na odpowiadający plik w openspec/specs/ i przy każdym jest rygorystyczny:
| Sekcja delty | Do czego służy | Co robi archive | Co ją wykoleja |
|---|---|---|---|
## ADDED Requirements | Nowe zachowanie albo istniejące zachowanie, które spisujesz po raz pierwszy | Dopisuje wymaganie; tworzy plik specyfikacji, jeśli go nie ma | Wymaganie, którego nagłówek już istnieje w specyfikacji z inną treścią (nawet jeśli różni się tylko wielkością liter lub spacjami); do tego służy MODIFIED. ADDED to jedyna operacja, która może utworzyć specyfikację |
## MODIFIED Requirements | Zmienione zachowanie | Zastępuje cały blok wymagania twoim | Odmawia, gdy plik specyfikacji nie istnieje, gdy nagłówek się nie zgadza albo gdy twój blok gubi scenariusz, który ma aktualna specyfikacja |
## REMOVED Requirements | Zachowanie, które wycofujesz, z liniami **Reason** i **Migration** | Usuwa wymaganie | Na specyfikacji, która jeszcze nie istnieje, ignoruje usunięcie z ostrzeżeniem |
## RENAMED Requirements | Sama zmiana nazwy, w formie FROM: / TO: | Zmienia nagłówek | Blok MODIFIED, który używa starej nazwy |
W każdej sekcji wymaganie to ### Requirement: <nazwa> z tekstem normatywnym (SHALL albo MUST), a pod nim co najmniej jeden #### Scenario: <nazwa> z liniami WHEN i THEN. Scenariusz ma dokładnie cztery krzyżyki; kolejne sekcje pokazują, co się dzieje, gdy ich brakuje.
Wartość tego modelu leży w scalaniu. Za pół roku openspec/specs/password-reset/spec.md odpowie na pytanie „co robi reset hasła?”, a każdy zarchiwizowany katalog zmiany na pytanie „kiedy i dlaczego to się zmieniło?”. Narzędzie ze specyfikacją na funkcję daje ci tylko to drugie.
Zainstaluj OpenSpec i podłącz go do agenta
Dział zatytułowany „Zainstaluj OpenSpec i podłącz go do agenta”OpenSpec wymaga Node.js 20.19.0 lub nowszego (engines w pakiecie 1.13.2). Pakiet npm to @fission-ai/openspec, a polecenie to openspec.
-
Zainstaluj CLI raz na maszynę (terminal):
Okno terminala npm install -g @fission-ai/openspec@latestopenspec --version # oczekuj 1.13.2 lub nowszejREADME wymienia też oficjalną formułę Homebrew:
brew install openspec. CLI wysyła anonimowe statystyki użycia (według README nazwy poleceń i wersję) i sam je wyłącza w CI; żeby zrezygnować na swojej maszynie, ustawOPENSPEC_TELEMETRY=0albo uruchomopenspec config set telemetry.enabled false. -
Zainicjuj repozytorium dla agentów, których używa zespół. Jeden
initobsłuży wszystkie trzy:Okno terminala cd twoje-repoopenspec init --tools claude,codex,cursorZapisuje sześć skilli w
.claude/skills/openspec-*/i sześć poleceń w.claude/commands/opsx/:explore,propose,apply,archive,synciupdate. W sesji wpisujesz/opsx:propose. Polecenia mająallowed-tools: Bash(openspec:*), więc agent może wołać CLI bez pytania o zgodę; nic więcej nie jest wstępnie dozwolone.Zapisuje te same sześć skilli w
.agents/skills/openspec-*/i żadnych poleceń, bo Codex wywołuje skille bezpośrednio. W sesji wpisujesz$openspec-propose,$openspec-apply-changealbo$openspec-archive-changelub opisujesz zadanie i pozwalasz Codexowi wybrać skill. Według komunikatuopenspec initw aplikacji desktopowej Codex wybierasz skill z sekcji Skills na pasku bocznym.Zapisuje skille w
.cursor/skills/openspec-*/, a polecenia w.cursor/commands/opsx-*.md. Wyjścieinitpodaje dla Cursora pisownię/opsx-propose, z łącznikiem zamiast dwukropka. Obsługi poleceń po stronie Cursora nie sprawdzono ponownie na potrzeby tej strony, bo cursor.com był niedostępny 2026-09-26. -
Opisz projekt agentowi raz, w
openspec/config.yaml. Polecontext:jest czytane przed każdą propozycją, arules:dodają ograniczenia dla poszczególnych artefaktów:schema: spec-drivencontext: |Express 4 API in TypeScript, Postgres through Knex, Vitest + supertest.Password reset lives in src/routes/auth/password-reset.ts.rules:tasks:- Every task names the test that proves itproposal:- Always include a Non-goals section -
Zacommituj
openspec/, katalogi skilli i katalogi poleceń, żeby każdy członek zespołu i każdy agent czytał ten sam workflow.
Przeprowadź pierwszą zmianę w kodzie bez specyfikacji
Dział zatytułowany „Przeprowadź pierwszą zmianę w kodzie bez specyfikacji”Pierwsza zmiana dotyczy obszaru funkcjonalnego (w OpenSpec: capability), czyli resetu hasła, który nie ma pliku w openspec/specs/. To przesądza o tym, jak ją zapisać: archive odrzuca deltę MODIFIED wobec nieistniejącej specyfikacji, a deltę REMOVED pomija, wypisując jedynie ostrzeżenie. Dlatego pierwsza zmiana opisuje reset hasła wyłącznie jako wymagania ADDED: dodawany limit żądań oraz istniejące zachowanie, które chcesz spisać i chronić.
-
Przypnij obecne zachowanie testami, zanim agent czegokolwiek dotknie. Wszystko, co zapiszesz w specyfikacji jako „istniejące”, potrzebuje testu, który dowodzi, że jest prawdą dziś. Napisz testy charakteryzacyjne dla endpointu resetu: odpowiedź dla nieznanego adresu e-mail, wygasanie tokenu i jednorazowe użycie. Zacommituj je osobno.
-
Explore.
exploreczyta kod i zadaje pytania; jego skill zabrania pisania kodu.Każde zachowanie oznaczone UNTESTED wraca do kroku 1, zanim złożysz propozycję, albo zostaje poza specyfikacją.
-
Propose. Jedno polecenie tworzy katalog zmiany i wszystkie jej artefakty, po czym się zatrzymuje. Skill propose stwierdza, że żądanie „authorizes planning only”, więc agent nie zacznie implementacji w tej samej turze.
-
Recenzuj deltę, nie prozę. Otwórz
openspec/changes/add-reset-rate-limit/specs/password-reset/spec.md. Fragment tego, co powinieneś zaakceptować:## PurposeLets users regain access to their account by email without revealing which addresses have accounts.## ADDED Requirements### Requirement: Reset request rate limitThe system SHALL accept at most 5 reset requests per email address per rolling hour.#### Scenario: Sixth request within an hour- **WHEN** a client sends a 6th reset request for alice@example.com within 60 minutes- **THEN** the system responds 429 with a Retry-After header and sends no email### Requirement: Reset token lifetimeThe system SHALL reject a reset token 24 hours after it was issued.#### Scenario: Token used after 25 hours- **WHEN** a user submits a token issued 25 hours earlier- **THEN** the system rejects it and the password is unchangedZaakceptuj ją, gdy każdy scenariusz ma konkretne wejście i sprawdzalne wyjście, gdy każde „istniejące” wymaganie odpowiada przechodzącemu testowi charakteryzacyjnemu i gdy
tasks.mdprzy każdym zadaniu wskazuje test. W schemaciespec-drivenplikdesign.mdjest opcjonalny; przy limicie żądań, który wymaga wspólnego licznika dla wielu instancji, poproś o niego. -
Zwaliduj strukturę (terminal):
Okno terminala openspec validate add-reset-rate-limit --strictopenspec show add-reset-rate-limit -
Apply.
/opsx:applyprzechodzi przeztasks.mdpo kolei, odhacza każde ukończone zadanie jako- [x]i zatrzymuje się, gdy zadanie jest niejasne albo zablokowane. Prompt w następnej sekcji dokłada bramkę testów. -
Archive.
/opsx:archivesprawdza artefakty i zadania, nakłada deltę i przenosi zmianę doopenspec/changes/archive/2026-09-26-add-reset-rate-limit/. Ponieważ ten obszar nie miał specyfikacji, archive tworzyopenspec/specs/password-reset/spec.mdz wymagańADDEDi sekcji## Purpose. Z terminala ten sam krok toopenspec archive add-reset-rate-limit --yes.
Zmień wyspecyfikowane zachowanie deltami MODIFIED i REMOVED
Dział zatytułowany „Zmień wyspecyfikowane zachowanie deltami MODIFIED i REMOVED”Sprint później dział bezpieczeństwa prosi o 30-minutowy czas życia tokenu i koniec starego linku z tokenem w query stringu. Teraz openspec/specs/password-reset/spec.md istnieje, więc delta może w niej modyfikować i usuwać wymagania.
Delta, którą widzi recenzent:
## MODIFIED Requirements
### Requirement: Reset token lifetimeThe system SHALL reject a reset token 30 minutes after it was issued.
#### Scenario: Token used after 25 hours- **WHEN** a user submits a token issued 25 hours earlier- **THEN** the system rejects it and the password is unchanged
#### Scenario: Token used after 31 minutes- **WHEN** a user submits a token issued 31 minutes earlier- **THEN** the system rejects it and the password is unchanged
## REMOVED Requirements
### Requirement: Legacy reset link**Reason**: Tokens in query strings leak through referrer headers and proxy logs.**Migration**: Emails sent since the 2024 template change use /reset/<token>; users with an older email request a new reset.Scenariusz „25 hours” wciąż tu jest, choć nowy go obejmuje. To celowe: MODIFIED zastępuje cały blok, a w 1.13.2 zarówno openspec validate, jak i archive odrzucają blok MODIFIED, który gubi scenariusz obecny w aktualnej specyfikacji. Jeśli chcesz usunąć scenariusz, zmień żywą specyfikację w osobnej, zrecenzowanej zmianie, a nie pomijając go w delcie.
Zanim uruchomisz apply, obejrzyj zmianę tak, jak zobaczy ją recenzent (terminal):
openspec show shorten-reset-token-ttl --type change --diff--diff wypisuje diff każdej delty względem aktualnej specyfikacji, wymaganie po wymaganiu. To najszybszy sposób, żeby potwierdzić, że zmieniają się tylko linie, o które prosił dział bezpieczeństwa.
Zapętl apply z testami, aż zmiana będzie gotowa
Dział zatytułowany „Zapętl apply z testami, aż zmiana będzie gotowa”Skill apply odhacza zadania; niczego nie dowodzi. Uczyń zestaw testów bramką między zadaniami i nie pozwól agentowi edytować specyfikacji, żeby jego kod przeszedł.
/opsx:apply shorten-reset-token-ttlUruchom to w sesji, która złożyła propozycję, żeby agent zachował kontekst. Jeśli zadanie pójdzie źle, /rewind (albo Esc Esc) przywraca sesję do ostatniego checkpointu. Żeby wymusić zasadę „nigdy nie edytuj specyfikacji”, uruchom sesję implementacyjną z regułą deny dla żywych specyfikacji:
claude --disallowedTools "Edit(/openspec/specs/**)"Reguła Edit obejmuje wszystkie wbudowane narzędzia edytujące pliki, a początkowy / wiąże ścieżkę z katalogiem głównym projektu. Trzymaj regułę na poziomie sesji, nie w .claude/settings.json: /opsx:archive musi zapisywać do openspec/specs/, więc archive uruchamiaj w sesji bez niej. Składnię reguł opisuje strona Uprawnienia, sandboksy i tryby zatwierdzania.
$openspec-apply-change shorten-reset-token-ttlWpisz polecenie testów do AGENTS.md (na przykład npm test -- tests/auth), żeby prompt apply poniżej mógł się do niego odwołać, i uruchom sesję z profilem uprawnień :workspace (-c default_permissions=":workspace", beta), a nie z pełnym dostępem.
Codex nie ma tu sesyjnej reguły deny dla ścieżki openspec/specs/; zasadę „nigdy nie edytuj specyfikacji” egzekwuje reguła CODEOWNERS na openspec/specs/ i job CI z następnej sekcji.
/opsx-apply shorten-reset-token-ttlCommituj po każdym zadaniu, po którym testy przechodzą, żeby nieudane zadanie było o jedno git restore od cofnięcia, a tasks.md miał czystą historię.
Cursor nie ma tu sesyjnej reguły deny dla ścieżki openspec/specs/; zasadę „nigdy nie edytuj specyfikacji” egzekwuje reguła CODEOWNERS na openspec/specs/ i job CI z następnej sekcji.
Archiwizuj dopiero wtedy, gdy wszystkie zadania są odhaczone, a testy zielone. Skill archive ostrzega przed nieodhaczonymi zadaniami, ale po twoim potwierdzeniu i tak archiwizuje, a do tego proponuje opcję „Archive without syncing”, która przenosi zmianę do archiwum bez dotykania openspec/specs/. Przy zmianie zachowania zawsze wybieraj synchronizację.
Jak zweryfikować zmianę w OpenSpec bez czytania każdej linii?
Dział zatytułowany „Jak zweryfikować zmianę w OpenSpec bez czytania każdej linii?”Rozdziel kontrole na deterministyczne i na te, które są oceną:
| Bramka | Czego dowodzi | Czego nie dowiedzie | Kto zatwierdza |
|---|---|---|---|
| Testy charakteryzacyjne przed pierwszą zmianą | Że „istniejące” wymagania są dziś prawdziwe | Niczego o nowym zachowaniu | Programista |
| Recenzja delty przed apply | Że zapisano właściwą zmianę zachowania, z przykładami | Że kod ją realizuje | Właściciel kodu danego obszaru |
openspec validate --strict | Strukturę delty, tekst SHALL/MUST, scenariusz przy każdym wymaganiu, brak zgubionego scenariusza w bloku MODIFIED | Że wymagania są słuszne albo że kod je spełnia | CI |
| Testy napisane z każdego scenariusza | Że kod zachowuje się zgodnie ze specyfikacją dla tych wejść | Zachowania, którego nikt nie wyspecyfikował | CI |
Archive aktualizuje openspec/specs/ | Że żywa specyfikacja odpowiada zmianie | Że kod będzie jej odpowiadał później | Recenzent PR |
Dodaj bramki strukturalne do CI. Ten job waliduje wszystkie zmiany i specyfikacje, odrzuca scenariusz zapisany z trzema krzyżykami i odrzuca pull request, który archiwizuje zmianę z deltami, nie dotykając openspec/specs/:
name: openspecon: pull_requestpermissions: contents: readjobs: validate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 with: fetch-depth: 0 persist-credentials: false - uses: actions/setup-node@v7 with: node-version: 22 - name: Validate changes and specs run: npx -y @fission-ai/openspec@1.13.2 validate --all --strict --no-interactive - name: No three-hash scenarios run: | if grep -rnE '^### Scenario:' openspec/; then echo "Scenarios need four hashes (#### Scenario:)"; exit 1 fi - name: Archived deltas reached the living spec env: BASE_REF: ${{ github.base_ref }} run: | archived=$(git diff --name-only --diff-filter=A "origin/$BASE_REF"...HEAD -- 'openspec/changes/archive/*/specs/*') if [ -n "$archived" ] && git diff --quiet "origin/$BASE_REF"...HEAD -- openspec/specs; then echo "Archived deltas but openspec/specs/ is unchanged:"; echo "$archived"; exit 1 fiKrok z grepem istnieje, bo walidacja nie łapie każdego źle zapisanego scenariusza. W 1.13.2 ### Scenario: pod wymaganiem, które ma też poprawny #### Scenario:, przechodzi validate --strict z samą linią INFO, że nagłówek „is ignored by validation”. Archive przebudowuje potem specyfikację, czyta zabłąkany nagłówek jako wymaganie bez scenariusza i przerywa pracę, czyli dopiero po napisaniu kodu. Grep przenosi ten błąd do pull requesta.
Taki opis to pakiet dowodowy tej zmiany. Recenzent czyta diff specyfikacji i tabelę scenariusz–test, jak opisuje recenzja pull requesta od agenta, a kod otwiera tylko tam, gdzie wiersz mówi UNTESTED albo plik leży poza listą zadań.
OpenSpec czy Spec Kit, gdy kod już istnieje?
Dział zatytułowany „OpenSpec czy Spec Kit, gdy kod już istnieje?”Oba piszą Markdown przed kodem. Różnią się jednostką pracy i tym, co przetrwa zmianę. Spec Kit zapisuje jeden katalog na funkcję, z konstytucją, specyfikacją, planem, researchem, modelem danych, kontraktami i zadaniami, i stawia bramkę na każdym etapie. OpenSpec zapisuje jeden katalog na zmianę, z propozycją, deltą, opcjonalnym designem i zadaniami, i scala deltę w specyfikację całego systemu. Tutorial Spec Kit pokazuje drugą stronę tego porównania.
| Twoja sytuacja | Użyj | Dlaczego |
|---|---|---|
| Mała albo średnia zmiana w działającym systemie, kilka razy w tygodniu | OpenSpec | Jeden punkt recenzji na zmianę, a archive utrzymuje openspec/specs/ w aktualności |
| Musisz odpowiedzieć z repozytorium na pytanie „co ta funkcja systemu robi teraz?” | OpenSpec | Spec Kit zostawia katalogi na funkcję i żadnej scalonej specyfikacji |
| Nowa usługa albo produkt, albo funkcja z kilkoma user stories do zatwierdzenia przez product ownera | Spec Kit | Konstytucja, clarify, analyze i converge dają ślad z bramką na każdym etapie |
| Praca regulowana, która wymaga udokumentowanego planu, researchu i kontraktów dla każdej funkcji | Spec Kit | design.md w OpenSpec jest opcjonalny i nie ma bramek etapów |
Błąd, którego poprawka przywraca zachowanie opisane już w openspec/specs/ | Żaden framework | Nieprzechodzący test powołujący się na wymaganie |
| Refaktoryzacja bez zmiany zachowania | Żaden framework | Testy przed i po; jeśli używasz OpenSpec, ustaw skip_specs: true w .openspec.yaml zmiany |
Rozsądny podział to Spec Kit dla nowej usługi i OpenSpec dla strumienia zmian po jej wdrożeniu. Wybierz jeden framework na repozytorium i zapisz to w CLAUDE.md albo AGENTS.md; dwa frameworki specyfikacji na tym samym kodzie dają agentowi dwa źródła prawdy. Porównanie frameworków spec-driven przeprowadza jedną funkcję przez oba.
Ile OpenSpec kosztuje w kontekście i ceremonii?
Dział zatytułowany „Ile OpenSpec kosztuje w kontekście i ceremonii?”Kontekst. OpenSpec instaluje skille i polecenia w projekcie, nie plugin, więc claude plugin details tu nie działa. Zmierzone 2026-09-26 na plikach, które zapisało openspec init --tools claude (1.13.2): sześć opisów skilli i sześć opisów poleceń dokłada do każdej sesji około 2200 znaków, czyli mniej więcej 550 tokenów przy czterech znakach na token. Każdy skill ładuje pełne instrukcje dopiero przy uruchomieniu: openspec-explore ma 22,8 KB, a openspec-propose 16,3 KB. Przegląd frameworków porównuje to z pakietami pluginów, które kosztują dziesiątki tysięcy tokenów.
Ceremonia. Jedna zmiana to trzy albo cztery pliki, a recenzent czyta deltę, zwykle krótszą niż strona. Prawdziwym kosztem jest dyscyplina: ktoś musi zrecenzować deltę przed apply i ktoś musi potwierdzić, że archive zaktualizował żywą specyfikację. Pomiń którykolwiek krok, a zostaniesz z katalogiem Markdownu, któremu nikt nie ufa.
Co się psuje, gdy uruchamiasz OpenSpec na istniejącym kodzie?
Dział zatytułowany „Co się psuje, gdy uruchamiasz OpenSpec na istniejącym kodzie?”Archive odmawia przy pierwszej zmianie. Objaw: archive zatrzymuje się z komunikatem „target spec does not exist; only ADDED requirements are allowed for new specs”. Agent zapisał MODIFIED dla zachowania, które istnieje w kodzie, ale jeszcze nie w openspec/specs/, a validate --strict tego nie zatrzymał: uznaje zmianę za poprawną i wypisuje tylko linię INFO, że archive odrzuci tę deltę. Naprawa: przepisz deltę na wymagania ADDED z sekcją ## Purpose, podparte testami charakteryzacyjnymi.
Usunięcie po cichu nic nie robi. Objaw: zarchiwizowana zmiana wymienia wymaganie REMOVED, a żywa specyfikacja nigdy o nim nie wspomina. Dla obszaru bez specyfikacji archive ignoruje REMOVED z ostrzeżeniem. Naprawa: w pierwszej zmianie w ogóle nie wpisuj wycofywanego zachowania do specyfikacji, a usunięcie odnotuj w proposal.md.
Archive odrzuca deltę MODIFIED. Objaw: „current spec contains scenario(s) not present in the modified block”. Agent zapisał fragment zamiast całego wymagania. Naprawa: skopiuj pełny blok z openspec/specs/, ze wszystkimi scenariuszami, i dopiero go edytuj.
Scenariusz zostaje zignorowany, a potem archive się wywraca. Objaw: validate --strict jest zielone, testy wygenerowane z delty pomijają jeden scenariusz, a archive przerywa później z komunikatem „Requirement must have at least one scenario”. Scenariusz zapisano jako ### Scenario:, więc walidacja go zignorowała, a archive odczytał go jako wymaganie. Naprawa: zmień nagłówek na #### Scenario:, dopisz test i zostaw krok z grepem w jobie CI powyżej, żeby następny taki błąd wyszedł na recenzji.
Żywa specyfikacja rozjeżdża się z kodem. Objaw: ktoś zarchiwizował zmianę przez „Archive without syncing” albo zmienił zachowanie bez propozycji, i openspec/specs/ opisuje system sprzed kwartału. Naprawa: krok CI sprawdzający, czy zarchiwizowane delty dotarły do żywej specyfikacji, reguła CODEOWNERS na openspec/specs/ i kontrole dryfu opisane w spec-driven development.
Agent edytuje specyfikację, żeby pasowała do jego kodu. Objaw: commit implementacyjny zmienia deltę albo openspec/specs/, a testy przechodzą. Naprawa: zablokuj zapis do openspec/specs/ w sesjach implementacyjnych, wymagaj zgody właściciela obszaru na każdą zmianę w tym katalogu i chroń testy, które kodują scenariusze.
Stare tutoriale prowadzą na manowce. Objaw: npm i -g openspec instaluje wersję 0.0.0 albo /openspec:proposal nic nie robi. Naprawa: zainstaluj @fission-ai/openspec i używaj poleceń /opsx:* w pisowni twojego narzędzia.