Co to znamená
Majordomus vede hranici epizody pod modelem, takže epizoda, na které záleželo — ta, která skončila pádem, kompakcí nebo zavřením okna — je zaznamenána, ať už si model záznam pamatoval, nebo ne. Do ADR 0103 to bylo zapojeno pro jediného providera: Claude Code spouští SessionStart a SessionEnd, shim spouští capture session a repozitář dostane epizodu. Každý další klient nedostal nic.
Klient bez hooků má hranici také a sdílený server na ní stojí. Klient mluví initialize, zavolá majordomus_session_attach se svým vlastním trvalým jménem sezení, pracuje a odejde. Epizoda se otevře při připojení, každá zpráva, kterou pošle, je heartbeat této epizody, ztráta spojení epizodu odpojí, ne uzavře, a klient, který se vrátí pod stejným jménem, dostane svou vlastní epizodu znovu — pod jakýmkoli peer id, které má teď. Záměrné majordomus_session_detach ji uzavře do záznamu relace; klientovi, který prostě zmizí, se epizoda po uplynutí odkladu pro opětovné připojení uzavře jako přerušená a rozdíl mezi těmito dvěma záznamy je jediná věc o skončené epizodě, která mění to, co kdo udělá dál.
Princip
src/episodes.rs je nástěnka: attach, touch, detach, close, reap, close_all, vedená podle externí identity, kterou dodá klient, a nikdy podle id peera. src/capability/builtin/episodes.rs deklaruje episodes.attach, episodes.detach a episodes.list jako typované deskriptory a registr je promítá jako všechny ostatní: nástroje majordomus_session_attach, majordomus_session_detach a majordomus_episodes, POST /api/v1/episodes/attach, POST /api/v1/episodes/detach, GET /api/v1/episodes, operace OpenAPI, referenci.
Nic z toho nezapisuje záznam relace. Nástěnka spouští majordomus capture session --provider generic --event start|end — tentýž příkaz, který spouští shim hooku poskytovatele, se stejným tvarem payloadu, přes stejný čtecí modul v lib/capture.sh — a hlásí, co řekl, doslova, v poli repository epizody. lib/capture.sh připouští poskytovatele, jehož deklarovaný zdroj epizod je connection, bez řádku adaptéru, protože poskytovatel, který nespouští žádnou událost, nemá žádný tvar vendorova payloadu, kterému by se přizpůsobil.
Tři události spojení tu už jsou a spojují se, nevymýšlejí znovu: mcp/protocol.rs se při každé zprávě dotkne epizody vedle peera, http/mcp.rs ji odpojí při DELETE a při odstraněné relaci a při vypnutí zavře každou, commands/mcp.rs ji odpojí, když odejde klient stdio.
Jak to vidět
just build
# a client with no hooks at all: three frames on stdin, a complete episode on the other side
printf '%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"anything","version":"0"}}}' \
'{"jsonrpc":"2.0","method":"notifications/initialized"}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"majordomus_session_attach","arguments":{"external_id":"my-thread"}}}' \
'{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"majordomus_session_detach","arguments":{}}}' \
| bin/majordomus-mcp --http-port 0 | jq -r '.result.structuredContent.episode.repository // empty'
# session … opened at …
# episode closed (closed, reason detach) into .ai/repo/sessions/…
majordomus capture status # generic:session connection verifiedCo nepokrývá
Zachycení surového promptu, a deklarace to říká. Server MCP dostává initialize, volání nástrojů a notifikace; prompt osoby mezi nimi není nikdy, v žádné verzi protokolu. share/providers.yaml zaznamenává generic.offers.prompts: none s tímto zdůvodněním v poli důkazů a pod prompts záměrně neexistuje hodnota connection, po které by někdo mohl sáhnout. Zachycení promptu zůstává specifické pro poskytovatele.
Komprimace. Spojení ji nevidí — nic v protokolu neohlašuje, že klient se chystá zahodit svůj kontext — takže epizoda spojení má start a konec a žádnou třetí událost. Poskytovatel, který spouští PreCompact, si tuto výhodu ponechává.
Epizoda, o kterou nikdo nepožádal. initialize nic neotevírá. Klient, který otevře server, aby přečetl jedno pravidlo, je peer a nezanechává záznam, což je také to, co drží pravdivou záruku test/cases/90_mcp_shared_server.sh: obsluha repozitář nemění vůbec.
Proč existuje
Tvrzení repozitáře, že hranici vede pod modelem, bylo tak, jak bylo zapojeno, tvrzením o jednom dodavateli. Spojení je zdroj událostí, který už vytváří každý klient MCP, nástěnka peerů už sledovala attach, aktivitu a detach a capture session už otevíralo a zavíralo epizody pro providera, který pojmenuje svou relaci; ty tři se musely spojit, ne vymýšlet. test/cases/200_generic_mcp_episode.sh to celé řídí přes bin/majordomus-mcp se skutečnými JSON-RPC rámci — initialize nic neotevírá, attach dosáhne úložiště repozitáře, kill -9 nechá epizodu otevřenou k pokračování, opětovné připojení ji obnoví místo otevření druhé a ztracené spojení odpojí, nezavře — protože životní cyklus, který funguje jen tehdy, když test volá knihovnu, nic nedokazuje o klientovi, kterého někdo skutečně zavřel.