Čím tento checkout právě je — projekt a jeho verze, repozitář a jeho vrstva, správa verzí, toolchainy, které repozitář deklaruje, co vrstva drží, workflow, která zde člověk může spustit, projekce poskytovatelů a lokální služby — je jedna typovaná hodnota, environment::RepositoryEnvironment, sestavená jedním resolverem pod apps/majordomus-cli/src/environment/. Každý povrch, který cokoli z toho říká, vykresluje tuto hodnotu: majordomus env v příkazové řádce, HTTP trasa /api/v1/environment, zdroj MCP majordomus://environment a banner, který direnv vykreslí při vstupu do adresáře. Žádný z nich nic sám nezjišťuje. Chování tak, jak je implementováno a testováno; kde se tento dokument a program rozcházejí, dokument se mýlí a mění se ve stejném commitu.
Příkazy a jejich spustitelné příklady jsou v generované referenci (generated/cli.md, pod majordomus env); schopnosti, jejich trasy a jejich benchmarkové případy v generated/capabilities.md, modul environment. Nic z toho se zde nepřepisuje.
Dvě rozlišení, jeden model
Spočítat, co vrstva drží, znamená postavit index, což stojí sekundy; banner běží při každém cd. Snímek se tedy rozřešuje ve dvou režimech a oba vyrábějí stejný typ:
- full čte vše, včetně indexu, a zapisuje cache.
env statusaenv explainse rozliší v plném rozsahu, protože na ně člověk čeká. - fast čte jen to, co je levné — jedno
git status, jednojust --dump, pár čtení souborů — a zbytek bere z cache, kterou zapsalo poslední úplné vyřešení.env banner,env exportaenv enterse vyřeší rychle, protože direnv spouští poslední z nich při každém vstupu.
To, co žádná cache nedodá, se hlásí jako neznámé, nikdy se neuhodne a nikdy nedoplní výchozí hodnotou: každá úroveň snímku nese svůj stav (resolved, cached nebo unavailable) a nedostupná hodnota chybí, místo aby byla nula. Oba režimy se liší v tom, co smějí číst, nikdy v tom, co znamenají; testy crate je k tomu zavazují.
Původ
Každé pole nese, odkud pochází: soubor, příkaz nebo konstantu doby kompilace, která o něm rozhodla, resolver, který ho přečetl, a zda bylo čteno nyní, vzato z cache, nebo vůbec nevyřešeno. env explain to vypíše pro jedno pole, prefix nebo každé pole; schopnost environment.explain odpovídá totéž přes HTTP a MCP.
Cache
Cache žije pod .ai/local/state/environment/, vedle leasu sdíleného serveru a ze stejného důvodu: patří tomuto checkoutu, nikdy se nesleduje a čerstvý klon začíná bez ní. Obsahuje počty, názvy receptů s jejich popisy a řetězce verzí toolchainu — nic načtené z prostředí procesu, žádný obsah souborů, žádnou cestu mimo repozitář. Každá úroveň nese vlastní otisk nad svými vstupy, takže úprava justfile zneplatní workflow a počty nechá být. Cache, kterou nelze přečíst, je minutí, nikdy chyba, a zápisy jsou atomické. Obsloužený požadavek — HTTP nebo MCP — ji nikdy nezapisuje: cache patří příkazové řádce a GET s vedlejším účinkem na repozitář by byl defekt.
Vstupní bod shellu
.envrc je adaptér a nic víc. Dává na cestu bin/, sleduje lease, aby se prostředí a banner přehodnotily, když sdílený server naběhne nebo zmizí, a vyhodnotí jedno volání: bin/majordomus-env enter --shell direnv. Tento jediný proces zapisuje přiřazení — MAJORDOMUS_ROOT, MAJORDOMUS_SHARE a MAJORDOMUS_URL, když server běží — na standardní výstup, kde direnv čte prostředí, které uplatní, a banner na standardní chybový výstup; obnovuje most workflow, když se pohnula deklarace za ním; a zajišťuje, že sdílený server tohoto repozitáře obsluhuje tento checkout. bin/majordomus-env najde spustitelný soubor přes lib/rust_bin.sh a nikdy jej nesestavuje: chybějící spustitelný soubor je jeden řádek na standardním chybovém výstupu jmenující just build a exit 0, protože nenulový exit na cd způsobí, že direnv ohlásí selhání celého prostředí. Spustitelný soubor starší než jeho zdroje dostane týž řádek a žádný runtime — adaptér nastaví MAJORDOMUS_RUNTIME=off — protože server spuštěný ze zastaralého kódu odpovídá stromem, který už neexistuje.
Vstup serveru, který se spouští, se naváže na loopback, pokud prostředí tohoto stroje nejmenuje jiné rozhraní v MAJORDOMUS_HTTP_HOST. Vstup tu proměnnou zdědí a předá dál; nečte ji a .envrc ji nenastavuje. Protože .envrc.local se načítá po výše uvedeném jednom volání, hodnota tam zapsaná dorazí pozdě pro server, který to volání spouští: patří do vlastního startovacího souboru shellu (MCP.md).
Pravidla, která to drží uzavřené, jsou project.envrc-is-an-adapter (.ai/repo/rules/project/envrc-is-an-adapter.v2.md) — soubor, který shell vyhodnocuje při vstupu do repozitáře, rozliší nástroj a provede na něj přesně jedno volání, bootstrap příkaz, a vyhodnotí, co to volání exportuje; nečte nic o repozitáři, nic nesestavuje, nesahá do sítě a nic nerozhoduje — a project.entry-converges, které říká, co to jedno volání musí a nesmí dělat. ADR 0043 je rozhodnutí a docs/ENTRY.md stránka pro operátora.
MAJORDOMUS_BANNER volí auto, full, compact nebo off; MAJORDOMUS_RUNTIME=off vstoupí bez zvednutí runtime; NO_COLOR udělá výstup prostý a pod CI není žádný banner vůbec. Skupina env souboru justfile (.just/env.just) nese recepty, které člověk spouští.
Pod bannerem entry vykreslí epizodu a kompaktní kontroly preflight bez opakování nadpisu repozitáře: co je o tomto checkoutu dokázáno, na rozdíl od toho, čím je. Server a jeho povrchy, briefing, pravidla, zaznamenané běhy testů a nasazení dostávají každé verdikt se svými důkazy. Je to samostatná hodnota, environment::preflight::Preflight, a popisuje ji PREFLIGHT.md. Banner z ní bere jedinou věc: služba se vykreslí jako odpovídající jen tehdy, když preflight ověřil server za ní, nikdy jen na sílu samotného spojení. Server publikuje své URL až po startu svých request workerů, aby je lease-triggered reload mohl oslovit. Zatímco připravuje trasy, jeho lease zůstává ve stavu starting.
Co je kanonické a co odvozené
| Fakt | Kanonický zdroj |
|---|---|
| název projektu, verze, licence, shrnutí | manifest cratu, při kompilaci |
| kořen repozitáře, sekce vrstvy | .ai/manifest.yaml, přes model repozitáře |
| správa verzí | jeden git status --porcelain=v2 --branch |
| toolchainy | manifest, který každý z nich deklaruje |
| co vrstva drží | index, přes registr schopností |
| workflow | just --dump --dump-format json |
| projekce providerů | projections[] z politiky |
| služby | vlastní konstanty tras spustitelného souboru a lease sdíleného serveru |
Nic v modulu nezapisuje mimo .ai/local/ a nic v něm neotevírá socket k ničemu jinému než k loopback adrese, kterou jmenuje lease — a jen na požádání o sondu.