Po co dyspozytor, skoro ticket można uruchomić ręcznie?
Jeden ticket uruchamia się jedną komendą. Sprint z dziesięcioma ticketami to już pilnowanie: który jest wolny, który czeka na merge innego, która sesja skończyła, a która stanęła na pytaniu. Dyspozytor przejmuje to pilnowanie i nic poza nim.
Skill sprint-run jest celowo cienki. Nie czyta kodu, nie edytuje plików, nie commituje. Jego praca to start sesji roboczych i księgowość wokół nich.
# zalecane: pętla co 15 minut
/loop 15m /monolynx:sprint-run
# jeden tick ręcznie
/monolynx:sprint-run
# jeden tick z trzema równoległymi sesjami
/monolynx:sprint-run 3Nigdy nie pracujesz nad ticketem sam. Widzisz coś do naprawienia w kodzie - to materiał na ticket, nie na Twoją turę.
Dlaczego zalecamy pętlę co 15 minut?
Jedno uruchomienie skilla to jeden tick. Sesja startuje w jednym ticku, a jej wynik zbiera dopiero któryś z następnych, bo dyspozytor po starcie nie czeka i nie zagląda do logu. Pętla jest więc częścią projektu, tylko trzymaną poza skillem.
/loop 15m /monolynx:sprint-runPiętnaście minut pasuje do tempa, w jakim zmienia się stan sprintu. Praca nad ticketem trwa znacznie dłużej niż jeden interwał, więc częstsze ticki widziałyby głównie to samo: sesje nadal pracują. Rzadsze zostawiałyby wolny slot pusty po zakończonej sesji i odkładały raport o sesji, która czeka na człowieka.
| Sposób | Komenda | Kiedy |
|---|---|---|
| Pętla w sesji | /loop 15m /monolynx:sprint-run |
praca przy komputerze, podgląd raportów na bieżąco |
| Skrypt w tmux | sprint_run.sh --slots 2 |
serwer, sesja ma przeżyć rozłączenie |
| Cron | sprint_run.sh --once co 15 minut |
cron sam jest pętlą, jeden tick na wywołanie |
Dyspozytor dobrze pracuje w parze z drugą pętlą. Sesje robocze kończą się merge requestem, a te przeprowadza do brancha docelowego mr-queue, kolejka merge uruchamiana co 10 minut. Po merge blokera następny tick dyspozytora sam startuje ticket, który na niego czekał.
Co dzieje się w jednym ticku?
- Kontrola wstępna
Skrypt sprawdza klienta, repozytorium, slug projektu i flagi autonomii. Bez kompletu tick nie startuje żadnej sesji.
- Stan sprintu
Skill pobiera aktywny sprint i jego tickety.
- Stan sesji
Skrypt zestawia tickety z żywymi sesjami w tle i z ogonami ich logów, po czym liczy werdykt dla każdego ticketu.
- Zbiór
Zakończone sesje dostają komentarz i są sprzątane, padnięte dostają jedno wznowienie, czekające trafiają do raportu.
- Dispatch
Wolne sloty obsadzają tickety w kolejności priorytetu, z pominięciem zablokowanych.
- Raport i linia statusu
Tabela ticketów, sekcja "Czekają na człowieka" i jedna zamrożona linia dla pętli.
Tick zaczyna od sprawdzenia środowiska, potem czyta sprint i sesje w tle. Skrypt przypisuje każdemu ticketowi werdykt. Zakończone sesje są sprzątane, padnięte wznawiane raz, czekające raportowane, a wolne tickety bez blokerów dostają nowe sesje work w osobnych worktree. Tick kończy się raportem i linią statusu.
flowchart TD
A["Kontrola wstępna"] --> B[Aktywny sprint i tickety]
B --> C[Sesje w tle i ogony logów]
C --> D{Werdykt ticketu}
D -->|done| E[Komentarz i sprzątnięcie sesji]
D -->|needs_human| F[Ogon logu do komentarza, jedno wznowienie]
D -->|waiting| G[Raport: czeka na człowieka]
D -->|running| H[Bez zmian]
D -->|free| I{Bloker albo needs-local?}
I -->|tak| J[Pominięty, zostaje w kolejce]
I -->|nie| K[Start sesji work w worktree]
E --> L[Raport i linia statusu]
F --> L
G --> L
H --> L
J --> L
K --> LJakie werdykty liczy skrypt?
Werdykt daje skrypt z listy sesji, statusów ticketów i ogonów logów. Model nie ocenia stanu sesji z prozy.
| Werdykt | Co oznacza | Co robi tick |
|---|---|---|
free |
brak sesji, ticket do zrobienia | kandydat do startu |
running |
sesja żyje i pracuje | nic, zajmuje slot |
waiting |
sesja żyje, ale nie posuwa pracy | nic nie rusza, raportuje |
done |
ticket w statusie in_review albo done; dla dyspozytora praca sesji jest skończona |
komentarz i sprzątnięcie sesji |
needs_human |
sesja padła bez domknięcia ticketu | ogon logu do komentarza, jedno wznowienie |
Skąd dyspozytor wie, że sesja czeka na człowieka?
Sygnały, które dają werdykt waiting
| Sygnał | Co dokładnie |
|---|---|
| Prompt o zgodę | sesja stoi na pytaniu klienta o uprawnienie |
| Marker STOP | linia SPRINT-RUN STOP: powód w ostatniej odpowiedzi sesji |
| Pytanie | ostatnia odpowiedź kończy się pytajnikiem |
| Numerowane opcje | co najmniej dwie opcje i fraza decyzji, na przykład "wybierz" |
| Fraza oczekiwania | odpowiedź kończy się zdaniem zaczynającym się od "Czekam" |
| Zastój | ogon logu niezmieniony przez kolejne ticki, domyślnie dwa |
Odpowiedź człowieka w sesji zdejmuje waiting: sygnały liczą się tylko z tego, co sesja napisała po ostatnim wejściu użytkownika.
Sesja waiting nie zajmuje slotu, więc jedno pytanie nie blokuje połowy przepustowości na całą noc. Ma za to własny limit: gdy czeka zbyt wiele sesji naraz (domyślnie dwie), tick przestaje startować nowe, zamiast mnożyć worktree czekające na odpowiedź.
Które tickety startują, a które czekają?
Kandydatami są tylko tickety z werdyktem free. Kolejność jest deterministyczna: priorytet malejąco, a przy równym priorytecie rosnąco po kluczu. Dwa ticki pod rząd wybierają to samo.
| Sytuacja ticketu | Zachowanie | Dlaczego |
|---|---|---|
| Bloker w statusie innym niż done | nie startuje, zostaje w kolejce | review to nie merge: sesja wciągnęłaby cudzy, niezmergowany branch |
Etykieta needs-local |
nie startuje w tle | wymaga lokalnego środowiska albo decyzji człowieka |
| Ticket z migracją bazy | startuje solo, gdy nic nie biegnie | dwie równoległe migracje rozjeżdżają łańcuch rewizji |
| Brak przeszkód | sesja w tle, komentarz z identyfikatorem | zwykła ścieżka |
Pominięty ticket nie dostaje komentarza, bo pominięcie powtarza się w każdym ticku. Ślad jest w raporcie, z powodem w rodzaju "czeka na merge MON-166". Po zamknięciu blokera następny tick startuje ticket bez niczyjej interwencji.
Jak wygląda start sesji?
Sesja robocza dostaje nazwę z projektu, klucza ticketu i modelu, na przykład monolynx-MON-167-opus, oraz worktree nazwany kluczem ticketu. Model jest podany jawnie, bo sesja bez niego wzięłaby domyślny model konta, który bywa najdroższy. Po starcie tick dopisuje do ticketu komentarz z identyfikatorem sesji. To jedyny trwały ślad, po którym człowiek trafi do właściwej sesji następnego dnia.
Co dostaję po każdym ticku?
Raport ma tabelę ticketów z werdyktem i działaniem, sekcję "Czekają na człowieka" z powodem i komendą dla każdej pozycji oraz jedną linię statusu na samym końcu:
SPRINT-RUN: remaining=3 running=2 waiting=0 done=1Linia jest kontraktem dla pętli: remaining=0 i running=0 oznacza, że sprint jest przerobiony.
Dane wykresu
| Tick | Do zrobienia | W toku | Gotowe |
|---|---|---|---|
| 1 | 6 | 2 | 0 |
| 4 | 5 | 2 | 1 |
| 8 | 3 | 2 | 3 |
| 12 | 1 | 2 | 5 |
| 16 | 0 | 0 | 8 |
Gdy linia pokaże zero pozostałych, przychodzi pora na sprint-end, który zamyka sprint i aktualizuje wiki.
Najczęstsze pytania
Czy dyspozytor może sam zmienić kod albo status ticketu?
Nie. Statusy przestawia sesja work w swojej turze, a kod zmieniają jej agenci. Dyspozytor czyta, komentuje i startuje sesje. Jedyna zmiana w repozytorium, jaką robi, to przewinięcie głównego checkoutu do aktualnego brancha bazowego, i tylko jako fast-forward.
Co się stanie, jeśli uruchomię tick dwa razy pod rząd?
Nic złego. Przed startem tick sprawdza, czy sesja o tej nazwie już żyje, a przed wznowieniem czyta komentarze ticketu. Drugi tick zobaczy ten sam stan i nie zdubluje sesji.
Ile sesji biegnie jednocześnie?
Tyle, ile slotów podasz jako argument, a bez argumentu tyle, ile wskazuje zmienna MONOLYNX_SPRINT_PARALLEL, domyślnie dwie. Sloty zajmują tylko sesje, które pracują.
Co jeśli sesja padnie w połowie ticketu?
Tick wkleja ogon logu do komentarza ticketu i wznawia sesję jeden raz. Druga porażka zostawia ticket dla człowieka, bo zwykle znaczy, że problem jest w tickecie albo w projekcie, a nie w sesji.
Czy mogę ustawić krótszy interwał niż 15 minut?
Możesz, ale zwykle nic to nie da: większość ticków zobaczy te same pracujące sesje. Krótszy interwał ma sens przy bardzo małych ticketach.
Słownik i następny krok
- Tick
- jedno uruchomienie dyspozytora: odczyt stanu, start i zbiór sesji, raport
- Slot
- miejsce na jedną pracującą sesję roboczą
- Worktree
- osobny katalog roboczy gita dla jednego ticketu
- Werdykt
- stan ticketu policzony przez skrypt z sesji, statusu i ogona logu
- Marker STOP
- linia, którą sesja w tle kończy turę, gdy potrzebuje człowieka
- needs-local
- etykieta ticketu, którego nie wolno uruchamiać w tle
- Dispatch
- obsadzenie wolnych slotów nowymi sesjami
Chcesz, żeby sprint przerabiał się sam, a Ty dostawał tylko pytania, które naprawdę wymagają człowieka?
Zobacz moduł Scrum w Monolynx