Podsumowanie sesji Codex
Zakres sesji
Materiał obejmuje trzy powiązane ze sobą taski Codex:
- sesję koordynującą, w której przeanalizowano plan testów, przygotowano dwa prompty do pracy równoległej, a po zakończeniu obu strumieni wykonano review i integrację,
- sesję nie-adminową rozwijającą testy użytkowników, odzyskiwania hasła i
traffic logs na
https://awesome.byst.re, - sesję adminową rozwijającą testy zamówień na
https://aitesters.byst.re.
Punktem startowym było 84 przechodzących testów w l14. W folderze istniały
już dwa projekty Playwright: api dla zwykłych użytkowników oraz admin-api
dla administracyjnego stagingu. Celem nie było jedynie rozdzielenie listy
endpointów, ale zorganizowanie pracy tak, aby agenci:
- nie edytowali tych samych klientów, fixture'ów i testów,
- nie modyfikowali cudzych danych ani danych seedowanych,
- wiedzieli o istnieniu drugiej sesji,
- nie uruchamiali pełnych suite'ów równocześnie,
- przekazali koordynatorowi osobne, gotowe do review branche.
Finalny rezultat obu strumieni został po review zintegrowany i zweryfikowany wspólnym uruchomieniem 101 testów.
Sesja 1: przygotowanie pracy równoległej
Prompt użytkownika
Pierwsza sesja rozpoczęła się od prośby o zaprojektowanie bezpiecznej pracy w dwóch oknach Codex. Użytkownik chciał zachować dużą autonomię agentów, ale jednocześnie uczynić ich świadomymi równoległego zadania:
work in l14, use english (i'll speak polish)
Chciałbym zacząć pracować równolegle nad dwoma osobnymi wątkami, czyli
chciałbym część testów napisać do wątku admina, a część napisać do wątku
nie-admina. Zastanów się, co moglibyśmy zrobić, żeby było bezpiecznie.
Napisz mi prompty do Kodeksa, prompty dosyć wysokopoziomowe, żeby dać
autonomię agentom w Kodeksie, ale napisz mi prompty do jednego okna, do
drugiego okna i wspomnij o tym, że będzie też drugi wątek.
Analiza przed przygotowaniem promptów
Codex przeczytał l14/api-test-plan.md, strukturę testów, istniejące fixture'y,
konfigurację dwóch projektów Playwright oraz listę niepokrytych endpointów.
Najważniejsze ryzyko dotyczyło zamówień: testy admina potrzebowały zamówienia
utworzonego przez zwykłego użytkownika, a więc potencjalnie wspólnych klientów,
typów i danych testowych.
Zaproponowany podział odpowiedzialności był celowo oparty na plikach i obszarach domenowych:
- agent nie-adminowy otrzymał użytkowników, auth, email events i traffic,
- agent adminowy otrzymał adminowe zamówienia oraz pierwszą infrastrukturę cart/order potrzebną do utworzenia własnego zamówienia testowego,
- wspólnym plikiem pozostał
api-test-plan.md, ale każdy agent miał zmieniać wyłącznie własną, wyraźnie nazwaną sekcję, - żaden agent nie miał scalać, przełączać ani resetować brancha drugiego agenta.
Codex zalecił dwa osobne worktree utworzone z tego samego czystego commita. Było to ważniejsze niż samo użycie dwóch branchy, ponieważ dwa branche otwarte w tym samym fizycznym checkoutcie nadal współdzielą pliki robocze.
Prompt dla agenta nie-adminowego
Przygotowany prompt dawał agentowi autonomię w wyborze stabilnego pokrycia, ale nie pozwalał zamieniać niezweryfikowanych błędów serwera w oczekiwania regresyjne:
$api-testing-skill
Work only in l14 and communicate in English.
You are the non-admin half of two concurrent Codex tasks. The sibling task is
titled “L14 Admin Order Coverage” and is working on admin order coverage
against the dedicated staging backend. Assume both tasks started from the same
clean commit but use separate Codex worktrees and branches.
Your goal is to autonomously improve non-admin API coverage against the
authoritative course API, https://awesome.byst.re.
Start with the independent items in the Thread A section of
l14/api-test-plan.md:
- GET /api/v1/users/me/email-events
- GET /api/v1/traffic/logs/{correlationId}
- POST /api/v1/users/password/forgot
- POST /api/v1/users/password/reset
Treat these as an ordered investigation backlog, not a requirement to force
all four into regression tests. Explore first and implement only behavior that
is verified, stable, and safe to lock down. If token access, asynchronous
behavior, or missing observability prevents reliable assertions, document the
exact evidence and blocker instead of creating a flaky or speculative test.
You own non-admin users, authentication, email-event, and traffic tests and
their directly related clients, DTOs, and support code. Do not modify admin,
cart, or order-owned paths. Do not merge, rebase, reset, or edit the sibling
branch or worktree.
Stay aware of the sibling task. Prefer Codex task-list/read tools. If those
tools are unavailable, inspect only the relevant sibling session information
under ~/.codex in read-only mode. Never expose secrets from logs.
Run newly added tests first. Then run the complete l14 suite, but never while
the sibling is running a full suite.
Prompt dla agenta adminowego
Drugi prompt wymagał, aby każdy test operował wyłącznie na zamówieniu utworzonym przez własny fixture:
$api-testing-skill
Work only in l14 and communicate in English.
You are the admin half of two concurrent Codex tasks. The sibling task is
titled “L14 Non-Admin Coverage” and is covering users/auth/email-events/traffic
against https://awesome.byst.re. Assume both tasks started from the same clean
commit but use separate Codex worktrees and branches.
Your goal is to autonomously add safe admin order coverage against the
dedicated staging backend, https://aitesters.byst.re, using the existing
admin-api Playwright project and configured admin credentials.
Focus on:
- an endpoint-specific disposable order setup,
- GET /api/v1/orders/admin,
- PUT /api/v1/orders/{id}/status.
Never mutate an arbitrary or pre-existing order returned by the admin list.
Status changes must target an order created by this task's own setup. Use
unique generated data and clean up generated users/products whenever
supported. If safe isolation or cleanup is impossible, document the blocker
instead of altering shared staging data unpredictably.
You own admin order tests, cart/order clients, order DTOs and disposable order
fixtures. Do not modify the sibling's users/password, email-event, or traffic
paths. Do not merge, rebase, reset, or edit the sibling branch or worktree.
Run the changed tests, then the admin project, then the complete l14 suite.
Never run the full suite while the sibling is running it.
Oba prompty wskazywały też wspólne reguły repozytorium: obowiązkowe discovery
przez curl, sprawdzenie api-docs.json i kodu backendu, inicjalizowanie
klientów w beforeEach, sekcje given, when, then, osobny spec dla każdej
operacji i kolejność testów według rosnących kodów odpowiedzi.
Sesja 2: agent nie-adminowy
Discovery i pierwszy ważny blocker
Agent utworzył branch codex/l14-non-admin-coverage i przed zmianami uruchomił
pełny baseline: 84 testy przeszły.
Następnie przygotował jednego tymczasowego użytkownika i rozpoczął obowiązkową
eksplorację live API. Pierwszy skrypt zatrzymał się, gdy okazało się, że
POST /api/v1/users/password/forgot nie udostępnia reset tokenu. Agent nie
próbował zgadywać dalszego scenariusza. Najpierw posprzątał użytkownika, a
następnie sprawdził OpenAPI i dostępne endpointy mail/outbox.
Eksploracja wykazała:
- znany i nieznany użytkownik otrzymują identyczny status
202i komunikat, - właściwość
tokenjest obecna, ale ma wartośćnull, - pusty identifier zwraca
400, - brak publicznego tokenu lub udokumentowanego outboxa blokuje stabilny test poprawnego resetu hasła,
- błędny payload resetu i nieznany token dają stabilne odpowiedzi
400.
Email events
Agent potwierdził, że nowy użytkownik otrzymuje pustą listę email events, a
wywołanie forgot-password tworzy zdarzenie PASSWORD_RESET_REQUESTED.
Ponieważ zapis jest asynchroniczny, test nie zakłada natychmiastowej
dostępności. Używa ograniczonego czasowo pollingu i wyszukuje zdarzenie po
typie.
Test sprawdza sam fakt zapisania i udostępnienia zdarzenia, a nie powodzenie zewnętrznego dostarczenia wiadomości. Dlatego status jest sprawdzany względem udokumentowanego zbioru, a pola czasowe strukturalnie.
Traffic logs i wykryty błąd 500
Agent wysłał kontrolowany request z unikalnym X-Client-Session-Id, odnalazł
go przez GET /api/v1/traffic/logs, a następnie pobrał szczegóły po otrzymanym
correlationId.
Pierwsza analiza ujawniła dodatkową rozbieżność: api-docs.json opisywał
clientSessionId jak query parameter, natomiast kod backendu odczytywał
X-Client-Session-Id z nagłówka. Agent powtórzył całą próbę z właściwym
nagłówkiem. Wynik się nie zmienił:
- lista zwracała dokładnie kontrolowany wpis,
- szczegóły tego samego, świeżo zwróconego
correlationIddawały500 {"message":"Internal server error"}, - losowy, nieistniejący identyfikator dawał poprawne, puste
404.
Agent nie dodał testu oczekującego 500. Pokrył tylko stabilną ścieżkę 404,
a udokumentowane 200 oznaczył jako zablokowane błędem backendu.
Implementacja
Powstały cztery nowe specyfikacje:
tests/api/users/email-events.get.spec.ts,tests/api/users/password-forgot.post.spec.ts,tests/api/users/password-reset.post.spec.ts,tests/api/traffic/logs-correlation-id.get.spec.ts.
Rozszerzono klientów auth, users i traffic oraz odpowiadające im DTO. Zakres pozostał zgodny z ustalonym ownershipem: agent nie dotknął adminowych testów, fixture'ów zamówień ani klientów cart/order.
Pierwsze uruchomienie nowych testów dało 5 zaliczonych i 3 niezaliczone testy.
Nie był to błąd serwera, lecz zbyt luźne podsumowanie wcześniejszej eksploracji:
testy zakładały brak pola token, podczas gdy live API serializowało
token: null. Agent poprawił DTO, asercje i opis discovery, po czym ten sam
zestaw zakończył się wynikiem 8/8.
Po skoordynowaniu okna testowego z agentem adminowym pełny suite tego brancha
zakończył się wynikiem 92/92. Branch został zapisany w commicie 79602c8.
Sesja 3: agent adminowy
Sprawdzenie bezpiecznego cyklu życia zamówienia
Agent adminowy przeanalizował OpenAPI, kontrolery, serwisy, encje i testy backendu. Musiał odpowiedzieć na kluczowe pytanie: jak utworzyć zamówienie do testu i jak je później usunąć, skoro API nie udostępnia endpointu kasowania zamówień.
Potwierdzony cykl setupu wyglądał następująco:
- logowanie admina,
- utworzenie unikalnego klienta stagingowego,
- logowanie tego klienta,
- utworzenie unikalnego produktu przez admina,
- dodanie produktu do koszyka klienta,
- utworzenie zamówienia z koszyka.
Kod backendu i live API potwierdziły, że usunięcie wygenerowanego klienta transakcyjnie usuwa jego koszyk i zamówienia. Dopiero potem można bezpiecznie usunąć produkt. Agent sprawdził ten porządek na danych wygenerowanych wyłącznie na potrzeby własnej eksploracji.
Pierwszy pomocniczy skrypt eksploracyjny nie wykonał scenariusza, ponieważ
została w nim użyta nazwa status, zarezerwowana w zsh jako zmienna read-only.
Cleanup trap nadal wykonał bezpieczną próbę sprzątania. Agent zmienił nazwę
zmiennej i powtórzył cały scenariusz, zamiast pomijać discovery.
Implementacja adminowa
Powstały:
fixtures/disposable-order.ts,generator/order-generator.ts,httpclients/orders-client.ts,types/orders.ts,tests/api/admin/orders/admin.get.spec.ts,tests/api/admin/orders/id-status.put.spec.ts.
Rozszerzono także klienta i typy koszyka. Fixture tworzył pełny, unikalny
łańcuch user → product → cart item → order. Test listy adminowej nie zakładał
określonej zawartości stagingu: wyszukiwał własne zamówienie po dynamicznym id.
Każdy test zmiany statusu, również 401, 403 i 404, używał id zamówienia
utworzonego przez własny fixture.
Pokrycie GET /api/v1/orders/admin objęło 200, 400, 401 i 403.
Pokrycie PUT /api/v1/orders/{id}/status objęło 200, niedozwolone przejście
statusu jako 400, a także 401, 403 i 404.
Agent zauważył dwie niestandardowe obserwacje:
- wysłanie nieznanej wartości enuma statusu z poprawnym tokenem admina zwracało
401, chociaż ten sam token działał bezpośrednio przed i po requestcie; podejrzenie dotyczyło obsługi błędu deserializacji lub zabezpieczonego error dispatchu, updatedAtnie zawsze zmieniał się przy natychmiastowej aktualizacji statusu, dlatego test nie porównuje timestampów na nierówność.
Niepoprawnego 401 dla nieznanego enuma nie zapisano jako oczekiwania
regresyjnego.
Nowe specyfikacje zakończyły się wynikiem 9/9, pełny projekt admin-api
wynikiem 34/34, a pełny suite brancha adminowego wynikiem 93/93. Branch został
zapisany w commicie 49cb383.
Jak agenci komunikowali się podczas pracy?
Prompty zakładały osobne worktree, ale po uruchomieniu okazało się, że oba taski początkowo pracowały w tym samym fizycznym checkoutcie. Agent adminowy zauważył nieśledzony skrypt eksploracyjny utworzony przez agenta nie-adminowego. Nie usunął go ani nie kontynuował pracy w ryzykownym stanie.
Przez mechanizm wiadomości między taskami wysłał ostrzeżenie:
The tasks are not actually isolated despite the prompt assumption. I will not
touch your file. I am moving my admin branch/work into a separate Git worktree.
Please avoid l14/api-test-plan.md until you are on your own branch/worktree,
and re-check git status before edits or test runs.
Agent nie-adminowy natychmiast wstrzymał implementację, sprawdził branch i worktree, a po rozdzieleniu checkoutów potwierdził:
This checkout is now safely on codex/l14-non-admin-coverage with only my
Thread A/non-admin changes. I confirmed your admin branch is isolated. Please
continue there; do not restore or switch this checkout.
Drugi etap komunikacji dotyczył testów. Oba branche tworzyły użytkowników na żywych środowiskach, a plan zawierał wcześniejsze dowody rate limitu przy uruchomieniach wykonywanych zbyt blisko siebie. Agent nie-adminowy zakończył 8 testów celowanych, ale wstrzymał pełny suite. Agent adminowy przekazał wynik 9/9 oraz 34/34 i zarezerwował okno na własny pełny suite.
Po wyniku 93/93 agent adminowy wysłał wiadomość, że okno jest wolne. Dopiero wtedy agent nie-adminowy uruchomił pełny suite i uzyskał 92/92. Na końcu przekazał ten wynik z powrotem agentowi adminowemu. Dzięki temu dwa niezależne taski nie wykonywały równocześnie najcięższego zestawu requestów.
Komunikacja nie służyła do współdzielenia niezatwierdzonych zmian. Agenci przekazywali wyłącznie stan, ownership, wyniki testów i moment zwolnienia wspólnego zasobu.
Review w sesji koordynującej
Prompt do review
Po zakończeniu obu tasków użytkownik wrócił do pierwszej sesji:
check changes from both of these agents and let me know what should I review.
Additionally I'd like to have a bug report ready to investigate the error
returned by one of the agents
Koordynator odczytał oba taski Codex, porównał branche z punktem startowym,
sprawdził historię commitów, komplet zmienionych plików, git diff --check oraz
rzeczywiste komendy testowe agentów. Review potwierdziło poprawny podział
ownershipu, kolejność testów, beforeEach, sekcje given/when/then, brak
sekretów w zmianach oraz używanie wyłącznie wygenerowanych rekordów.
Problemy znalezione w review
Review wykryło trzy konkretne problemy wymagające korekty:
- Fixture zamówienia akceptował
404przy sprzątaniu użytkownika i produktu w każdym teście. Mogło to ukryć nieoczekiwane wcześniejsze usunięcie rekordu. - Jeżeli request usuwający użytkownika rzuciłby wyjątek sieciowy, wykonanie nie doszłoby do cleanupu produktu, co mogło pozostawić dane na stagingu.
- Oba branche poprawnie edytowały własne sekcje
api-test-plan.md, ale po integracji tabela blockerów nadal zawierałaby nieaktualne wpisy o email events i sposobie uzyskania correlation id.
Dodatkowo review wskazało dwa świadome punkty do oceny:
- test email events dopuszcza status
FAILED, ponieważ bada zapis zdarzenia, a nie skuteczne dostarczenie maila, - nieznany enum statusu zamówienia zwracający
401wygląda na osobny błąd backendu, prawdopodobnie w obsłudzeHttpMessageNotReadableExceptionlub error dispatchu chronionym przez security.
Niezależne odtworzenie błędu traffic detail
Koordynator nie poprzestał na opisie agenta. Utworzył nowy, unikalny
X-Client-Session-Id, wywołał /api/v1/traffic/info, odnalazł request na
liście i ponownie pobrał szczegóły z tym samym nagłówkiem. Live API znów
zwróciło 500 {"message":"Internal server error"}.
Na tej podstawie powstał osobny raport
bug-reports/traffic-log-detail-returns-500.md, zawierający środowisko, kroki
reprodukcji, wynik oczekiwany i rzeczywisty, wpływ na użytkownika oraz sugerowane
miejsca dochodzenia w backendzie. Raport wyraźnie zabrania zmiany testu tak, aby
oczekiwał 500.
Korekty po review i integracja
Po poleceniu:
ok, apply the fixes and merge into main
koordynator połączył oba branche. Git nie zgłosił konfliktu tekstowego w planie, ale Codex nadal potraktował go jak konflikt semantyczny i ręcznie zachował oba opisy discovery, usuwając nieaktualne blockery.
Fixture disposableOrder został wzmocniony:
- test, który celowo usuwa właściciela zamówienia, jawnie oznacza ten fakt przez
markDeletedByTest, 404jest akceptowane tylko po takim oznaczeniu,- w pozostałych przypadkach cleanup użytkownika i produktu wymaga
204, - błędy cleanupu są zbierane, a usuwanie produktu jest wykonywane również wtedy, gdy cleanup użytkownika rzuci wyjątek,
- wiele błędów cleanupu jest raportowanych przez
AggregateError.
Po integracji uruchomiono jeden wspólny zestaw wszystkich 17 nowych testów. Wynik: 17/17. Następnie uruchomiono pełny suite obu projektów Playwright. Wynik: 101/101.
Commit integracyjny dc2812b zachował historię obu branchy i zawierał poprawki
z review oraz raport błędu.
Wynik testów
Pełna sekwencja walidacji wyglądała następująco:
- baseline przed równoległą implementacją: 84 testy zaliczone,
- pierwszy target agenta nie-adminowego: 5 zaliczonych, 3 niezaliczone z powodu
błędnego założenia o braku pola
token, - poprawiony target nie-adminowy: 8 testów zaliczonych,
- pełny suite brancha nie-adminowego: 92 testy zaliczone,
- target adminowych zamówień: 9 testów zaliczonych,
- cały projekt
admin-api: 34 testy zaliczone, - pełny suite brancha adminowego: 93 testy zaliczone,
- wspólny target po review i integracji: 17 testów zaliczonych,
- pełny suite po integracji: 101 testów zaliczonych,
git diff --check: bez błędów.
Znalezione błędy i świadome ograniczenia
Sesje pozostawiły dwa podejrzane zachowania backendu i jeden brak obserwowalności:
GET /api/v1/traffic/logs/{correlationId}zwraca500dla istniejącego id otrzymanego chwilę wcześniej z listy. Ścieżka200pozostaje zablokowana.PUT /api/v1/orders/{id}/statusz nieznanym enumem zwraca401mimo poprawnego JWT admina. Zachowanie nie zostało zapisane jako kontrakt testowy.- Produkcyjne forgot-password zwraca
token: nulli nie udostępnia udokumentowanego outboxa. Można pokryć walidację oraz anti-enumeration, ale nie stabilny sukces resetu hasła.
Znaleziono też rozbieżności OpenAPI: clientSessionId jest opisany jako query
parameter zamiast nagłówka, a 404 traffic detail ma w schemacie body, mimo że
live API zwraca pustą odpowiedź.
Finalny efekt trzech sesji
Praca równoległa dostarczyła dwa niezależne zestawy zmian bez nadpisania plików
drugiego agenta. Ścieżka nie-adminowa pokrywa email events, forgot-password,
negatywne przypadki resetu i stabilne 404 traffic detail. Ścieżka adminowa ma
bezpieczny fixture pełnego zamówienia oraz pokrycie listy adminowej i zmiany
statusu.
Najważniejszym rezultatem organizacyjnym jest sprawdzony wzorzec współpracy:
jasny ownership plików, osobne worktree, komunikaty o stanie, serializacja
kosztownych suite'ów, niezależne branche oraz osobna sesja review przed
integracją. Finalny snapshot rozwiązania znajduje się w l15, natomiast l14
zachowuje stan startowy sprzed pracy równoległej.
