Co to znamená
Čtení životního cyklu zpět jsou dvě různé otázky se dvěma různými odpověďmi a dokud tohle nevzniklo, měla povrch jen jedna z nich. Pracovník se ptá z čeho navazuji? a odpovídá continuity.state: jedna epizoda — ta, na kterou se .ai/local/state/session-current.yaml překládá — jedna předávka, jeden checkpoint, blokátory. Operátor se ptá funguje tento podsystém? a na to z první otázky odpovědět strukturálně nelze, protože ukazatel je symlink, který nejnovější událost start přesměrovává. lifecycle.episodes, lifecycle.recovery, lifecycle.runtime, lifecycle.providers a lifecycle.closed čtou úložiště místo ukazatele a odpovídají na druhou otázku, přes MCP, přes GET /api/v1/lifecycle/<name> i na stránce Continuity v Cockpitu, která nemá vlastní model relací a je projekcí právě těchto pěti a continuity.state.
Princip
lifecycle.episodes vypisuje .ai/local/state/sessions-open/*.yaml — jeden soubor na relaci poskytovatele — a každému přiřadí postavení rozhodnuté z toho, co repozitář může pozorovat: current, když se na něj ukazatel vyřeší, open, když jmenuje tento worktree a ukazatel jmenuje jinou epizodu, foreign, když jmenuje jiný worktree, stranded, když worktree, v němž se otevřel, z disku zmizel a nic už nemůže sestavit jeho záznam. Každá epizoda nese poznámku, které z toho platí a proč, a ledger se k ní připojuje podle id epizody, kterým je označen každý řádek — nikdy podle časového rozsahu, protože jeden ledger drží několik workerů a žádné časové razítko je neodděluje. Totéž spojení dává vztah k úloze a běží od epizody ven: epizoda jmenuje úlohy, kterých se její řádky dotkly, a žádná úloha nerozhoduje, zda se zapisují záznamy epizody.
lifecycle.recovery hlásí to, co nikdo nespraví běžným použitím nástroje: otevřený záznam, jehož worktree zmizel nebo který hlavní kniha již zaznamenala jako uzavřený, s příkazem, který jej vyčistí; soubory .tmp., které zanechá close zabitý mezi zápisem a přejmenováním, ve sledované sekci relací, kde jsou nesledované, neviditelné pro každého čtenáře sekce a nabízené příštímu git add .; zda je session-current.yaml symlink do úložiště per provider, nebo běžný soubor layoutu, který držel jednu epizodu na checkout; a aritmetiku, kterou žádá ADR 0052 — session.started proti session.closed proti otevřeným záznamům, kde kladný rozdíl jsou epizody, jejichž koncová událost dorazila a nic nevyprodukovala.
lifecycle.runtime porovnává commit, ve kterém byl postaven servírovaný index, s commitem, který git hlásí při volání. Čtou se oba, nic se nepředpokládá. Server, který index postavil jednou a drží ho, odpovídá na každou otázku o commitu tak, jak to bylo při jeho startu, stejně přes HTTP API, MCP i Cockpit, aniž by cokoli v odpovědi říkalo, že obraz je starý, a zevnitř žádné z těch odpovědí si toho nelze všimnout.
lifecycle.providers hlásí pro každého poskytovatele události životního cyklu, které jeho adaptér deklaruje ve slovníku poskytovatele, zda umí archivovat prompty a které položky enforcement tohoto repozitáře jmenují jeho hook v wired_by. Deklarace je share/providers.yaml; test/cases/170 odmítne její rozchod s tabulkou adaptérů, kterou shell skutečně pohání. Obě zřejmé alternativy jsou špatné: čtení adresáře hooků poskytovatele hlásí instalaci jako schopnost a seznam napsaný do stránky je druhý zdroj pravdy, který zastará v den, kdy se adaptér změní.
lifecycle.closed čte sledované záznamy přes index objektů — druh session — a hlásí, kolik jich existuje, kolik se uzavřelo na této větvi a nejnovějších dvacet s odkazem na stránku každého objektu. Je to jediná polovina subsystému, která přežije klon.
Žádný z pěti nedeklaruje příkazovou řádku. Čtou .ai/local/, takže se servírují workerovi před checkoutem a nikdy se nedodávají: příkazová řádka je způsob, jak se hodnota dostane do skriptu, do logu a nakonec do commitu.
Jak to vidět
majordomus serve # then open /cockpit/continuity
curl -s localhost:$PORT/api/v1/lifecycle/episodes | jq '[.episodes[] | {session_id, standing, provider, last_event}]'
curl -s localhost:$PORT/api/v1/lifecycle/recovery | jq '{balance, stranded: [.stranded[].session_id], orphans: [.orphans[].path]}'
curl -s localhost:$PORT/api/v1/lifecycle/runtime | jq '{served_head, repository_head, agree}'
curl -s localhost:$PORT/api/v1/lifecycle/providers | jq '[.providers[] | {id, lifecycle, prompt_capture, wired}]'
curl -s localhost:$PORT/api/v1/lifecycle/closed | jq '{total, on_this_branch}'Co nepokrývá
Nikdy nezapisuje. Životní cyklus má jediného zapisovatele, shellový nástroj, a druhý účet událostí, které účetní kniha už drží, je to, co tento návrh odmítá. Nic zde neuzavře uvízlou epizodu ani nesmaže osiřelý záznam; každý nález nese příkaz, který člověk spustí.
Nerozhoduje o prazích. Nic v lifecycle.* neposuzuje záznam jako starý. Stáří je session.freshness v politice a hlásit je věcí continuity.state; druhý motor pro něj by byl přesně tím zdvojením čísel, kvůli kterému se dva povrchy neshodnou.
Neví, zda je připojen provider. Zda je klient, který otevřel epizodu, stále ve své konverzaci, není fakt tohoto repozitáře: soubor epizody nezaznamenává žádný proces, nástěnka peerů nezaznamenává žádné id epizody a klient, který skončí bez vyvolání události konce, zanechá soubor identický s tím, který používá živý worker. stranded je vyhrazeno pro jediný případ, který repozitář dokáže určit — worktree zmizel — a vše ostatní se hlásí jako to, kde soubor leží a kdy ho ledger naposledy viděl.
Nezobrazuje žádný prompt. Archiv promptů je jediná část lokální poloviny, která je konverzací, a nečte ho žádná zdejší schopnost ani žádná karta na stránce Continuity.
Stránka nesleduje živý kanál. Stránky provádění sledují WebSocket, protože provádění vysílá události; úložiště relací ne, a prohlížeč, který by se každých pár sekund ptal, zda je epizoda ještě otevřená, by celý den slyšel ano. Obnovením je opětovné načtení.
Proč existuje
Dne 2026-09-11 držel tento repozitář v jednom checkoutu pět otevřených epizod a každý povrch, který nástroj má, dokázal jmenovat právě jednu z nich — continuity.state sleduje ukazatel a ukazatel mířil na epizodu, která se otevřela naposled. Ostatní čtyři byly neviditelné a epizoda, kterou nikdo nevidí, je epizoda, kterou nikdo neuzavře: vlastní aritmetika účetní knihy ve stejnou chvíli ukazovala dvacet jedna startů proti patnácti uzavřením. Tentýž týden forenzní audit zjistil, že subsystém šest dní nezapsal žádný checkpoint ani předávku, zatímco doctor po celou dobu hlásil zdraví — ADR 0052, „Životní cyklus relace patří epizodě, ne úloze“ — a dlouho běžící server byl nalezen, jak ze tří povrchů obsluhuje šest hodin starý HEAD, aniž to cokoli říkalo. Tři selhání, jeden tvar: subsystém neměl žádné čtení sebe sama, takže každé z nich objevil člověk, který si všiml něčeho jiného.