Co se stane, když člověk nebo agent vstoupí do repozitáře s Majordomus, co konverguje samo, co je záměrně ponecháno k vyžádání a co dělat, když se něco nezvedne. docs/ENTRY_AUDIT.md je forenzní zjištění, z něhož tento dokument vzešel; ADR 0035 rozhodlo o dveřích agenta a ADR 0043 o dveřích shellu; toto je stránka pro operátora.
Stručně: nic z toho není příkaz, který by si někdo musel pamatovat. Stačí vstoupit do adresáře, kteroukoli cestou.
Posloupnost
cd <repository> direnv evaluates .envrc, which makes one call — `majordomus env
enter` — and evaluates what it prints: the variables a shell here
benefits from on stdout, the banner on stderr, the workflow bridge
refreshed when a declaration behind it moved, and the repository's
shared server ensured when nothing is serving this checkout. The
file itself reads nothing about the repository, builds nothing and
starts nothing; the executable does all of it. Nothing is waited
for: a server this entry starts becomes ready beside the shell, and
`watch_file` over the lease brings its address in when it lands.
an agent starts the provider's start event opens the episode, makes sure the
repository's shared server is serving this checkout, and writes a
briefing the provider adds to the context it is about to build:
the episode, the task, what blocks acceptance, the last handover's
next action, and one line naming where the server stands.
an MCP client attaches the client configuration at the root starts the launcher, which
builds the executable when it must and elects: the first process
serves, every later one bridges to it. This has always converged.
the worker announces `majordomus_announce` puts one line of intent and the paths it
expects to touch on the board every other client can read.
Vše výše se děje bez napsání příkazu, kromě posledního, což je žádost, kterou bootstrap klade workeru, a ta, kterou most opakuje za něj, když se pod ním změní jeho server.
Tři příkazy
majordomus serve status [--checkouts this|repository] [--format json]
where this checkout's server stands, and — unless
`--checkouts this` narrows it — every server of
this repository
majordomus serve ensure [--idle S] [--wait S] [--port P]
a ready server for this checkout, started if
there must be one
majordomus serve stop [--wait S] end the server this checkout's lease names
serve ensure je to, co spouští událost startu, a majordomus env enter spouští tutéž funkci — jedna konvergence, tři povrchy, aby agent a člověk nemohli dojít ke dvěma různým odpovědím na to, zda už server běží. Přečte lease a otestuje server, který jmenuje, přesně jako volba, a konverguje: připravený server se nahlásí a nic se nespouští; na server, který se ještě váže, se počká; chybějící nebo zastaralé lease dostane server spuštěný jako samostatný proces a volání čeká, dokud neodpoví. Spuštěno dvakrát, podruhé nespustí nic. Spuštěno třemi shelly najednou, volba nechá jeden navázat a ostatní se připojí. Celé volání je omezeno --wait a server, který se včas nepřipravil, se nahlásí se stavem, kterého dosáhl, a nenulovým návratovým kódem.
Server, který ensure spustí, nemá vlastního klienta, takže skončí, když po --idle sekund není připojen žádný peer. Tím se řádek ADR 0003 — není proces bez klienta — drží pravdivý v čase, ne v každém okamžiku: vstupu agenta se server dluží před jeho prvním připojením a checkout, ve kterém nikdo nepracuje, ho neudržuje.
Co znamenají stavy
| postavení | co říká | co dělat |
|---|---|---|
absent | žádný lease: tento checkout nic neobsluhuje | nic, pokud nechcete: serve ensure |
starting | pronájem bez adresy, dost mladý na to, aby ho jeho vlastník ještě navazoval | čeká; serve ensure čeká na vás |
ready | server, který lease jmenuje, odpovídá za tento checkout, ze souboru na disku, ve verzi tohoto spustitelného souboru | nic |
outdated | odpovídá, ale z jiné verze nebo ze souboru, který byl od spuštění nahrazen | serve stop, potom serve ensure |
stale | lease jmenuje server, který neodpovídá, nebo vůbec není leasem | nic: další start to převezme a řekne, o co šlo |
Vstup jako shell
majordomus env enter [--shell SHELL] [--no-banner] [--no-bridge] [--no-runtime] [--wait S]
Co volá .envrc a jediné volání, které provádí. Soubor nese PATH_add, watch_file a ten řádek; vše ostatní — zda zajistit, na jakém portu, s jakou dobou nečinnosti, kdy mlčet, kdy odmítnout — patří spustitelnému souboru, kde je to typováno, měřeno a testováno.
Tři věci o něm jsou kontrakt, ne implementace:
- Nikdy nečeká. Studený vstup zjistí, že nic neodpovídá, spustí server jako vlastní proces a vrátí se. Naměřeno na stroji se zátěží 136: studený vstup stál 185–217 ms a teplý 134–218 ms: totéž, protože start runtime je fork a exec a nic víc. Rozpočty jsou
benchmark.budget.enter_msabenchmark.budget.enter_cold_msv politice atest/cases/190měří obojí při každém běhu. - Nikdy neselže. Každý výsledek za běhu je nejvýše jeden řádek na standardním chybovém výstupu a návratový kód 0. Nenulový kód zde způsobí, že direnv ohlásí selhání celého prostředí, a člověku zanechá rozbitý shell v repozitáři, který je v pořádku.
- Mlčí, když nemá co říct. Vstup do zdravého repozitáře o runtime nic nevypíše, nezmění žádný soubor pod
.ai/local/a nespustí žádný proces. Člověku, který do tohoto adresáře vstoupí čtyřicetkrát denně, se čtyřicetkrát neřekne nic. - Hlásí jen to, co je prokázáno. Pod bannerem kreslí kompaktní preflight (
PREFLIGHT.md): server a jeho povrchy, brífink, pravidla, zaznamenané běhy testů a nasazení, každé s verdiktem opřeným o důkazy. Služba se nikdy neoznačí jako odpovídající jen proto, že bylo přijato spojení. Označí se, až když server za ní odpovídá jako držitel zápůjčky tohoto checkoutu ve verzi tohoto spustitelného souboru (project.entry-reports-only-evidence).
Přepínače. session.ensure_server_on_start v politice řídí obě vstupní cesty — jedna otázka, jedna odpověď, takže se obě nemohou rozejít. MAJORDOMUS_RUNTIME=off je totéž odmítnutí pro shell jednoho člověka a znamená ho jen přesně tato hodnota: překlep v profilu nesmí tiše zabránit spuštění repozitáře. --no-runtime je totéž jako argument.
Do ADR 0043 to bylo naopak a pravidlo znělo „vstup shellem hlásí a neobsluhuje“. Cena toho byla celý smysl návrhu: člověk, který zde otevřel terminál, dostal banner a žádný runtime — žádný Cockpit, žádné API, žádnou nástěnku peerů, tedy žádný způsob, jak vidět, že na stejném stroji jsou další pracovníci — a nápravou byl příkaz, který si musel pamatovat. Námitka ADR 0003 se týká procesu, který přežije svůj důvod k existenci, a nečinný život na ni odpovídá: server, ke kterému se nikdo nepřipojí, skončí.
Co není automatické a proč
Nic při vstupu nesestavuje spustitelný soubor a nic nezajišťuje ze zastaralého. Chybějící spustitelný soubor, nebo starší než jeho zdroje, je jeden řádek na standardní chybový výstup jmenující recept, který jej sestaví, a vstup stále končí nulou — bez runtime. Vše, co zde člověk vidí — banner, most workflow, doplňování, sdílený server — je projekcí tohoto jediného souboru, takže jdou spolu a řádek to říká. Server spuštěný ze zastaralého kódu by odpovídal stromem, který už neexistuje, Cockpitu, API i každému dalšímu pracovníkovi, který je k němu připojen, a žádný z nich nevidí, že proces je starší než checkout, který údajně obsluhuje. Obě dvířka rozhodují o zastarání týmž mj_rust_stale v lib/rust_bin.sh, takže checkout, kde se rozcházejí, nemůže existovat.
Nikdy vzdálená síť. Jediný socket, který vstup otevře, míří na loopback adresu, kterou server tohoto checkoutu už publikoval.
Briefing je stále věcí agenta. Shell dostane prostředí a banner; epizodu, úlohu a další akci poslední předávky skládá startovní událost poskytovatele, protože bez pracovníka, který ji má, žádná epizoda není.
Když nekonverguje
| co vidíte | co to znamená | co spustit |
|---|---|---|
banner je pryč, just nic nevypíše, doplňování je tiché | spustitelný soubor chybí nebo je starší než jeho zdroje; každý povrch je jeho projekce | just build |
Shared server: not ensured: the executable is not built v briefingu | totéž, vidět z události startu providera | just build, pak začněte novou relaci |
| v prostředí není žádná adresa | žádný server ji pro tento checkout nepublikoval | majordomus serve status, potom serve ensure |
| server odpovídá, ale věcmi, které strom už nemá | proces je starší než kód | majordomus serve status říká outdated; serve stop pak serve ensure |
| linked worktree nehlásí žádný server, zatímco primární checkout jej má | server servíruje checkout, ve kterém byl spuštěn; každý má vlastní lease | serve ensure v tom worktree; serve status vypíše oba |
direnv: error .envrc is blocked | direnv schvaluje podle cesty a obsahu a nový worktree začíná neschválený | majordomus worktree ensure <branch> přenáší schválení primárního |
majordomus: nothing was serving this checkout; a server is starting | očekávaný řádek při prvním vstupu; adresa dorazí o okamžik později, když watch_file uvidí lease | nic |
majordomus: <reason>; a server is starting in its place | lease jmenoval server, který tento checkout už neobsluhuje — ztratil lease, běží kód, který už není na disku, nebo není náš — a vstup jej nahradil; banner nezobrazuje adresu, dokud se nepublikuje nová | nic; proces, který stále drží starý port, pojmenuje majordomus serve status |
tentýž řádek na každém cd | server se spustí a pak selže | přečtěte log, který řádek jmenuje, pak majordomus serve status |
| druhý banner hned po prvním | direnv znovu vyhodnotil vstup, protože se zápůjčka pod watch_file pohnula; příchod nebo odchod serveru vykreslí dvouřádkovou formu, nikdy znovu rámeček | nic |
majordomus: the executable is older than the sources a žádný server se nespustí | vstup odmítá spustit runtime ze zastaralého kódu | just build; příští cd jej zajistí |
server ◐ na vstupním řádku, zatímco se adresy vypisují | odpovídá server z jiné verze nebo vyměněného spustitelného souboru; značky služeb banneru říkají ○, ne ✓ | majordomus serve stop, potom serve ensure |
rules ? nebo enforced ? na vstupním řádku | korpus pravidel se počítá z indexu, který tento vstup nikdy nesestavuje, a žádný plný běh nezacachoval počet | majordomus env preflight --full |
| nástěnka peerů je prázdná, ačkoli pracují jiní | nástěnka je pamětí jednoho serveru a každý checkout má svůj vlastní server | majordomus serve status pojmenovává každý server repozitáře a co každý drží |
Kde každý fakt žije
Nic z výše uvedeného není zapsáno dvakrát. Lease pod lokálním stavem checkoutu je jediné místo, kde adresa běžícího serveru platí, a jeden typovaný čtenář ji parsuje. Port, o který server žádá jako první, je deklarován jednou v deklaraci příkazové řádky. Trasy patří povrchům, které je vlastní, a snapshot prostředí je vykresluje. Co který příkaz dělá, patří grafu příkazů, a tato stránka příkazy jmenuje, neopakuje je.
majordomus serve status --format json the server, its lease and every checkout's
majordomus serve status --checkouts this this checkout's server alone, without reading or
probing any other checkout
majordomus env status the checkout: project, version control, toolchains,
the layer, the workflows, the local services
majordomus context what the next worker needs to know now
majordomus doctor whether Majordomus itself is healthy and wired hereCo to drží zavřené
project.entry-converges je pravidlo a scripts/ci/entry-converges kontrola, která o něm rozhoduje: vstupní soubor sám nic nespouští, dělá právě jedno volání a to volání je bootstrapový příkaz bez --wait; dveře shellu čtou tentýž přepínač, ctí MAJORDOMUS_RUNTIME a konvergují touž funkcí jako serve ensure; adaptér odmítne zajistit ze zastaralého spustitelného souboru; ani jedny dveře nesestavují; přepínač a dva rozpočty vstupu jsou každý deklarovány v politice, kostře, seznamu povolených a schématu společně; startovací shim je zapojen tam, kde to politika říká, aby jej doctor sladil; briefing si netvoří vlastní názor na to, kde server stojí; a server, který nikdo nevlastní, má omezený život. Že lease má jediného čtenáře, je project.the-lease-is-read-once, rozhodnuto pro všechny soubory najednou pomocí scripts/ci/lease-reader-check. Co žádný skript nerozhodne — že vstup skutečně konverguje — je test/cases/108_entry_converges_on_a_server.sh pro dveře agenta, které řídí vlastní shim poskytovatele, a test/cases/190_entry_is_automatic.sh pro dveře shellu; test/cases/191_entry_races.sh a test/cases/192_entry_across_checkouts_and_clients.sh drží konvergenci pod skutečnou souběžností — deset současných vstupů, mrtvý pid v leasu, živý proces, který není náš, opuštěný lease, port držený cizincem, dva worktrees vstupující najednou a deset klientů na runtimu, který vstup spustil. test/cases/118_entry_converges_by_rule.sh dokazuje kontrolu tím, že zasadí vše, co pravidlo zakazuje, a sleduje, jak se to odmítne.
Související
docs/MCP.md má životní cyklus sdíleného serveru a volbu v plném znění; docs/ENVIRONMENT.md snímek a adaptér; docs/CONTINUITY.md epizodu, briefing a záznamy; docs/WORKTREES.md topologii větev–worktree; docs/ENTRY_AUDIT.md co bylo změřeno, než se cokoli z toho stavělo, a co je ještě dlužno.