Přeskočit na obsah

Tato stránka byla automaticky přeložena z angličtiny, jediného jazyka, ve kterém se tento web píše. Číst originál.

Jak Majordomus funguje

jak nástroj funguje jako jeden model repozitáře s mnoha projekcemi: stav psaný, objevený, odvozený, pozorovaný a usuzovaný; deklarace schopnosti a každý povrch z ní odvozený, včetně míst, kde se příkazová řádka a Cockpit stále píšou ručně; žebřík důkazů pravidla od deklarovaného po doložené; relace, kontext, předávka, plánování, nástěnka peerů a mesh; publikace a verze; mapy povrchů, governance a meshe; jak se udržují pravdivé trasy, navigace a pořadí; změřený architektonický dluh; a klíč k otázkám, na které by měl umět odpovědět technický čtenář

Vykresleno z docs/HOW_IT_WORKS.md — stejného Markdownu, který zobrazuje GitHub.

Majordomus lze snadno špatně pochopit jako nástroj příkazové řádky, HTTP API, server MCP, dashboard a složku pravidel v Markdownu, které se náhodou dodávají společně. Tento dokument vysvětluje, proč je toto čtení chybné a kde je přesto správné. Sleduje fakt od souboru, kde je zapsán, přes index a typovaný registr, které jej drží, přes kontroly, které rozhodují, zda je pravdivý, až ke každému rozhraní, které jej ukazuje — a pojmenovává každé místo, kde repozitář tomuto tvaru zatím nedostává.

Každé tvrzení zde bylo ověřeno proti kódu v commitu, který tento soubor naposledy změnil, a po jednom tvrzení auditováno druhou relací. Kde se kód a návrhový záznam rozcházejí, vítězí kód a rozpor je uveden pod Architecture debt. Čísla se do tohoto dokumentu nepíší: každé je uvedeno jako příkaz, který je měří, protože číslo zkopírované do prózy je zastaralé den po napsání (project.no-counts-in-prose).

Teze

Majordomus by měl fakt jednou objevit a zmodelovat a pak z této kanonické reprezentace odvodit každé relevantní rozhraní.

Ta věta není preferencí opětovného použití kódu. Je to mechanismus proti driftu. Repozitář, na kterém současně pracuje několik lidí a několik AI pracovníků, hromadí popisy sebe sama: seznam příkazů v README, další v textu nápovědy, třetí ve schématu API, čtvrtý v dashboardu, pátý v seznamu nástrojů agenta. Každý je správný v den, kdy vznikl, a každý udržuje ten, kdo si na něj vzpomene. Víc pracovníků a víc rozhraní kopie násobí a agentní vývoj způsobuje, že se kopie rozcházejí rychleji.

Majordomus jde opačným směrem: jeden model, mnoho projekcí. Projekce smí fakt vykreslit jinak, filtrovat ho nebo spojit s jinými. Nesmí o něm mít druhý názor.

Architektura na jednom obrázku

flowchart TD
  d1_A["Authored canonical state: rules, ADRs, policy, claims, milestones, issues, capability declarations"]
  d1_G["Git and the filesystem"]
  d1_R["Runtime: server leases, MCP sessions, mesh datagrams"]
  d1_A --> d1_D["Discovery: kinds.yaml + sources.yaml + the capability composition"]
  d1_G --> d1_D
  d1_D --> d1_I["Object index: typed objects with canonical identity"]
  d1_D --> d1_CR["Capability registry: one descriptor per operation"]
  d1_I --> d1_CR
  d1_CR --> d1_X["One executor: Context::execute"]
  d1_R --> d1_O["Observed state: peers, standing, mesh nodes"]
  d1_X --> d1_V["Derived state: rule proof, claim evidence, plan status, waves, environment"]
  d1_O --> d1_V
  d1_V --> d1_P{"Projections"}
  d1_P --> d1_CLI["Command line: clap tree checked against the registry"]
  d1_P --> d1_MCP["MCP: tools and resources"]
  d1_P --> d1_HTTP["HTTP under /api/v1"]
  d1_HTTP --> d1_OA["OpenAPI 3.1"]
  d1_OA --> d1_SW["Swagger UI"]
  d1_P --> d1_CK["Cockpit: server-rendered pages"]
  d1_P --> d1_GEN["docs/generated and site data"]
  d1_GEN --> d1_SITE["majordomus.dev"]
  d1_GEN --> d1_CHK["generate --check, derive-check, projection tests"]

Čtěte od shora. Lidé a pracovníci píší malou sadu kanonických souborů. Objevování je nachází přes deklarace místo ručně vedených seznamů, index dává každému typovanou identitu a registr schopností drží každou operaci, kterou spustitelný soubor umí. Každý povrch se ptá stejného executoru. Odvozený stav — zda je pravidlo prokázáno, jaký je stav úkolu, jaké je prostředí checkoutu — se počítá z kanonických a pozorovaných vstupů; kde se drží kopie (commitnuté projekce, cache prostředí), kontroluje se proti těmto vstupům nebo se z nich znovu staví a nikdy se nepovažuje za zdroj. Generované soubory dole jsou commitnuté a kontrolované, takže rozpor mezi modelem a jeho projekcemi shodí build, místo aby se dostal ke čtenáři.

Dva programy sdílejí jedno jméno

Před modelem jeden fakt, který tvaruje vše níže. Existují dva executables a oba odpovídají na majordomus:

ProgramSpouštěčNapsáno vVlastní
nástroj shellbin/majordomus s lib/*.shPOSIX shell a awkživotní cyklus úlohy (start, check, finish), handover, context, zachycení relace, doctor, dispatch doktrín, engine plánu
spustitelný soubor v Rustubin/majordomus-cliRust, apps/majordomus-cli/registr schopností, serve, mcp, HTTP, OpenAPI, Swagger UI, Cockpit, generate, peeři, mesh, prostředí, worktrees, důkaz pravidla, důkazy, release

Shellový nástroj odmítne příkaz, který nezná, a když ho docs/generated/cli.yaml — generovaný popis stromu příkazů v Rustu — vypisuje, jmenuje launcher, který spustit místo něj; nepředává ho dál. Obojí konverguje na straně Rustu (ADR 0047 a ADR 0052 popisují přechod relací; obě jsou stále navržené) a některé domény už mají čtečku v Rustu držené na bajtové shodě se zapisovatelem v shellu — plán je nejjasnější případ. Zde popsaná architektura plně platí o spustitelném souboru v Rustu a částečně o shellovém nástroji; rozdíl je zaznamenán tam, kde záleží.

Šest druhů stavu

Každou hodnotu, kterou Majordomus ukazuje, lze zařadit do jednoho z těchto druhů. Druh rozhoduje, kdo ji smí zapsat a zda může někdy přepsat něco jiného.

DruhPříklady v tomto repozitářiKdo to vytváříKdo to měníAutoritaSmí přepsat kanonický stavZneplatněno
Autorsky kanonicképravidla pod .ai/repo/rules/, ADR pod .ai/repo/adrs/, .ai/repo/policy.yaml, docs/CLAIMS.yaml, milníky a úkoly pod .ai/repo/project/, deklarace capability!, share/design/tokens.yamlčlověk nebo worker, v commitutotéž, v posouzeném commitunejvyšší: je to zdrojnelze použítnový commit
Objevenoindex objektů, složení modulů, výpis worktree gitu, sada sledovaných souborůspustitelný soubor, čtoucí autoritativní strukturynikdo: čte se znovupřesně jako u jeho zdrojenikdyzměna zdroje
Odvozenostav důkazu pravidla, stav důkazů tvrzení, stav a vlny úkolů, snímek prostředí, minimální verze release, vše pod docs/generated/deterministická funkce kanonických a objevených vstupůnikdo ručně; generátor to přepisuježádné vlastní: je to pohlednikdy; generate --check odmítne ruční úpravujakákoli změna vstupu
Pozorovánopřipojení peeři, postavení serveru (ready, outdated, stale), přítomnost uzlu meshe, odpovídající port služby, špinavý pracovní stromsonda v určitém okamžikudalší sondapravda jen v okamžiku své časové značkynikdyčas: TTL, odpojení, další sonda
Odvozenoskóre relevance intent při kompilaci vývojového kontextuheuristikaheuristikaporadní, řazeno pod každou deklarovanou relacinikdyzměna vstupů
Lokální kontinuitapředávky, kontrolní body, aktivní úloha, otevřená epizoda, účetní kniha v .ai/local/shellový nástroj jménem pracovníkapřevážně jen přidávání, pouze přes příkazydůkaz toho, co pracovník udělal, ne toho, co platí nynínikdy; zastaralá předávka se ukazuje jako historiestáří a vzdálenost v gitu

Většinu váhy nesou dvě rozlišení.

Objevování není odvozování. Objevování znamená, že informace už někde autoritativně existuje a Majordomus ji najde: soubor pravidla odpovídající pathspecu, modul pojmenovaný v kompozici, worktree uvedený gitem. Odvozování znamená, že Majordomus navrhne pravděpodobný výklad. Jediné odvozování v kompilátoru kontextu je relevance podle klíčových slov a je omezeno pod přímou deklaraci — drží to test an_inference_is_never_as_confident_as_a_declaration — ne však pod každý vztah dosažený slabými nebo vícekrokovými hranami (viz Kontext pro relaci).

Pozorované není kanonické. To, že je peer online, není deklarace, kterou někdo učinil; je to současná realita a vyprší. Nic z nástěnky peerů ani z registru meshe se neukládá, jako by to byl fakt o repozitáři.

Zjišťování

Majordomus raději hledá fakta o repozitáři ve strukturách, které je už vlastní, než aby držel paralelní registry. Zdroje, které skutečně čte:

ZdrojCo se objevujeKde
share/kinds.yamldruhy dokumentů, které distribuce definuje: formát, identita schématu, pole identity, pole titulkunačteno indexem
kinds.yaml vedle sources.yamldruhy, které repozitář přidává, pokud nějaké má (nesmí předefinovat druhy distribuce)stejné
.ai/repo/knowledge/sources.yamlkteré pathspecy gitu drží objekty kterého druhustejné
.ai/manifest.yamlkterý adresář .ai/ drží kterou sekci a které jsou nesledovanéshellový nástroj a spustitelný soubor
gitsledované soubory, worktrees, větve, HEAD, společný adresář gituapps/majordomus-cli/src/worktree/, lib/common.sh
složení schopnostíkaždá spustitelná operaceapps/majordomus-cli/src/capability/builtin/mod.rs
strom clappříkazová řádka tak, jak je napsánaapps/majordomus-cli/src/cli.rs
share/commands.yaml a výpis receptů justpříkazy nástroje shellu a recepty workflowgraf příkazů
.ai/repo/ci/gates.yamlkontroly, třídy cest a co každá kontrola spouštíscripts/ci-plan, důkaz pravidla
soubory lease pod .ai/local/state/mcp/který checkout má živý server a na jaké URLapps/majordomus-cli/src/lease.rs
UDP multicast, broadcast, rendezvous (ve výchozím stavu vypnuto)další uzly Majordomusapps/majordomus-cli/src/mesh/
index docs/README.mdkteré dokumenty jsou zveřejněny a v jakém pořadíscripts/generate-site-data

Objevování je explicitní tam, kde mohlo být magické. Neexistuje žádný soupis při linkování ani build skript skenující zdrojové soubory: ADR 0004 obojí odmítá, takže složení modulů je obyčejný výraz v Rustu, který si čtenář může otevřít. Ta volba má cenu — přidání modulu znamená úpravu tohoto složení — zaznamenanou pod Architektonický dluh.

Index se v procesu sestaví jednou z těchto deklarací (apps/majordomus-cli/src/index.rs). Co drží v tomto checkoutu, uvidíte:

$ bin/majordomus-cli serve ensure
$ curl -s 'http://127.0.0.1:8741/api/v1/objects?kind=rule' | jq .
$ curl -s http://127.0.0.1:8741/api/v1/repository | jq .

Sdílený server checkoutu naslouchá na výchozím portu, pokud není obsazený, a bin/majordomus-cli serve status vypíše URL, kterou skutečně drží.

Identita

Zobrazované jméno je pro čtenáře. Kanonická identita je pro každou relaci. Majordomus nikdy nespojuje dvě věci podle jejich titulků.

EntitaKanonická identitaPříklad
schopnosttečkované id, s jmenným prostorem podle jeho modulurules.show
indexovaný objektmajordomus://<kind>/<identity>majordomus://rule/majordomus.scope-integrity@1
indexovaný objekt jako schopnost<kind>.<identity>rule.majordomus.scope-integrity@1
pravidloid plus version, nikdy název souboruproject.derived-once ve verzi 1
tvrzeníjeho id v docs/CLAIMS.yamlscope-enforcement
test v knize důkazůjeho runner a název, se zdrojovou cestou vedlesuite:04_start_check (zdroj test/cases/04_start_check.sh)
peer na nástěncepozice, p1, p2, přiřazená znovu při opětovném připojení; checkout, který nese, je trvalá polovinap7 ve worktree prismatic-majordomus-wt/feature/x
uzel meshedigest jeho veřejného klíče Ed25519uchováno v ~/.local/state/majordomus/node.json
worktreeodvozeno z názvu větve: <repository>-wt/<branch>prismatic-majordomus-wt/docs/how-majordomus-is-derived

Identita je to, co činí řetězec pravidlo, validátor, test, provedení, důkaz strojově spojitelným. Pravidlo jmenuje své testy cestou; engine důkazů váže tyto cesty ke kontrolám podle toho, co kontroly spouštějí; kniha důkazů zaznamenává provedení podle identity testu a commitu. Žádný krok neshoduje text.

Schémata

Existují dva řetězce schémat, jeden pro každý druh věci, a žádný se nepíše dvakrát.

Spustitelné operace. Vstup a výstup schopnosti jsou běžné typy Rustu, které odvozují schemars::JsonSchema. CanonicalSchema::of::<T> převede typ na jednu hodnotu JSON Schema 2020-12 (apps/majordomus-cli/src/capability/schema.rs) a ta se vykresluje čtyřmi způsoby: inline pro MCP (for_mcp), jako komponenty OpenAPI (for_openapi), jako formulář runneru Cockpitu a do docs/generated/registry.json. Parametry dotazu HTTP se převádějí přes totéž schéma. Žádné schéma schopnosti není ručně udržovaný dokument — není tu rozhraní TypeScript ani samostatná definice Swagger — přestože jeden typ Rustu, design::Ordered<T> (seřazená mapa), implementuje JsonSchema ručně, ne derivací.

flowchart LR
  d2_T["Rust type with derive JsonSchema"] --> d2_S["CanonicalSchema"]
  d2_S --> d2_M["MCP inputSchema and outputSchema"]
  d2_S --> d2_O["OpenAPI components"]
  d2_S --> d2_F["Cockpit runner form"]
  d2_S --> d2_J["docs/generated/registry.json"]
  d2_S --> d2_Q["HTTP query coercion"]

Dokumenty repozitáře. Každý druh deklarovaný v share/kinds.yaml jmenuje identitu schématu tvaru <vendor>.<name>/v<n>. Schémata žijí pod share/schemas/majordomus/<kind>/. Většina druhů v Markdownu — pravidla, ADR, dovednosti, prompty, kontextové dokumenty a další (ls share/schemas/majordomus/*/*.proto) — se píše jako zprávy protobuf a jejich JSON Schema se z nich odvozuje; ostatní druhy se píší přímo jako JSON Schema. Hlavička pravidla je například uzavřená zpráva v share/schemas/majordomus/rule/rule.v1.proto, a proto se neznámý klíč front-matteru v pravidle odmítne, místo aby se tiše ponechal.

Generované artefakty mají také schémata, pod share/schemas/generated/. Před zápisem generate zkontroluje každý artefakt na banner původu a každý strukturovaný dokument, který deklaruje kontrakt, proti jeho schématu.

Schopnost: jedna deklarace

Každá operace Rust programu se deklaruje jednou, makrem capability! (apps/majordomus-cli/src/capability/handler.rs). Toto je skutečná deklarace operace, která vysvětluje důkaz jednoho pravidla, z apps/majordomus-cli/src/capability/builtin/rules.rs (popis zkrácen):

capability! {
    id: "rules.show",
    title: "What proves this rule",
    description: "One rule with its full proof: ...",
    input: RuleInput,
    output: RuleDetail,
    stability: Stability::BehaviorallyVerified,
    exposure: Exposure {
        mcp: mcp("majordomus_rule"),
        http: get("/api/v1/rules/rule"),
        cli: Some(CliExposure { path: vec!["rules".into(), "show".into()] }),
    },
    tags: ["rules", "governance", "verification", "evidence"],
    cache: CachePolicy::Disabled,
    handler: show,
},

Co deklarace uvádí a co makro doplní samo:

Deklarováno autoremKlasifikováno nebo označeno, nikdy deklarováno
id, title, descriptionmodule, opatřeno razítkem module! při skládání modulu
kind (ve výchozím stavu Query, nebo Command, Resource)provenance, z module_path!()
typy input a outputavailability, visibility, execution, klasifikováno podle druhu a expozice
stabilitypřípady měření převzaté z implementace BenchmarkCases vstupního typu
exposure pro MCP, HTTP a příkazovou řádkuzda zapisuje do repozitáře: výslovný souhlas přes .writes_repository(), připnuto unit testem the_capabilities_that_write_the_repository_are_these v capability/builtin/mod.rs na množinu, kterou uvádí
tags, cache, benchmark, handler

Dvě vlastnosti vynucuje překladač, nikoli revize: vstupní typ, který neimplementuje BenchmarkCases, se nepřeloží — zda se operace poté měří, určuje její deklarovaná BenchmarkPolicy (vyžadovaná, nebo prominutá s typovaným důvodem), kterou ukazuje report pokrytí; a handler, jehož signatura neodpovídá deklarovaným typům, se nepřeloží.

Registr

Moduly skládají schopnosti pomocí module!; compose_modules! skládá moduly; aplikace sestaví registr pomocí CapabilityRegistry::builder().with_modules(builtin::modules()).with_index(&index). Druhé volání je místo, kde se objevování setkává s rovinou schopností: každý indexovaný objekt se stane schopností Resource (apps/majordomus-cli/src/capability/declarative.rs), čitelnou přes MCP jako majordomus://<kind>/<identity>, takže nový soubor s pravidlem si agent přečte bez jediného řádku v Rustu.

build() validuje celou množinu a sbírá každou chybu místo zastavení u první (apps/majordomus-cli/src/capability/registry.rs): gramatiku id, jmenný prostor shodný s modulem, duplicitní nástroj MCP, duplicitní trasu HTTP, duplicitní cestu příkazu, chybně utvořené vystavení HTTP, neplatnou politiku cache. Registr, který by vystavil dvě operace na jedné trase, nelze sestavit.

Exekutor je jeden. Context::execute (apps/majordomus-cli/src/capability/executor.rs) je jediný volající dispatche registru. Příkazová řádka, HTTP, MCP i Cockpit jdou přes něj, což činí „stejnou operaci na každém povrchu“ vlastností kódu, ne slibem.

Prohlédnout registr tohoto checkoutu:

$ jq '.capabilities | length' docs/generated/registry.json
$ jq -r '.capabilities[] | [.id, .kind, .stability] | @tsv' docs/generated/registry.json
$ bin/majordomus-cli capabilities describe rules.show
$ bin/majordomus-cli capabilities validate

Projekce

HTTP

Neexistuje tabulka tras. Router se ptá registru: Router::capability v apps/majordomus-cli/src/http/router.rs volá registry.by_http(method, path), odpoví 405, když sedí jiná metoda, a 404, když nesedí nic, naváže query parametry GET přes vstupní schéma nebo vezme JSON tělo POST a volá Context::execute. Každá HTTP expozice je vynucena pod /api/v1/ přes HttpExposure::PREFIX. Chyby se mapují na 400, 404, 422 a 500 na jednom místě.

Nekapacitní mounty — obsluhovaná domovská stránka, /openapi.json, /swagger, /cockpit, /mcp, proud událostí, /docs/, /rustdoc — jsou deklarovány jednou v zjišťování webových povrchů (apps/majordomus-cli/src/web/; docs/generated/web.json je vypíše), které popisuje docs/WEB.md. Nová operace nepotřebuje vůbec žádný kód HTTP: rules.show nemá v routeru žádný handler, jen generický dispatch.

Ručně se píše obchodní logika za handlerem — apps/majordomus-cli/src/rules/ pro důkaz pravidla — nikdy metadata trasy.

OpenAPI

apps/majordomus-cli/src/http/openapi.rs projde registr a vytvoří dokument OpenAPI 3.1. operationId je id schopnosti, schémata jsou kanonická schémata jako komponenty, příklady jsou případy měření výkonu a rozšíření x-majordomus-* nesou druh a identitu. Je poskytován živě na /openapi.json ze stejného registru, který obsluhuje požadavky, a commitnut jako docs/generated/openapi.json, aby byla změna kontraktu vidět při review. Jedna odpověď zatím není odvozena věrně: dokument připojuje odpověď 422 refused jen k příkazům, ačkoli některé dotazy mohou také odmítnout a router jim přesto odpovídá 422.

OpenAPI je odvozeno z týchž smluv, které obsluhují skutečné požadavky API. Není to druhá dokumentace, kterou je třeba držet v souladu.

Swagger UI

Swagger UI na /swagger je pouze vykreslovač /openapi.json a nic víc (apps/majordomus-cli/src/http/swagger.rs). Není zdrojem pravdy, nedrží žádné definice a nemůže s API nesouhlasit, protože nemá nic vlastního, s čím by nesouhlasil. Jeho assety pro prohlížeč jsou připnuty na jednu verzi a načítají se z CDN — jediná část lokálního povrchu, která nefunguje offline, a modul to říká.

MCP

MCP je projekce téhož registru pro agenty (apps/majordomus-cli/src/mcp/surface.rs):

  • Nástroje jsou každá schopnost, jejíž expozice jmenuje nástroj. inputSchema a outputSchema pocházejí z kanonického schématu; nápověda read-only pochází z druhu. Nápovědy destructive a idempotent zatím nepocházejí z deklarovaného účinku: jsou jednou zapsány v mcp/protocol.rs pro každý nástroj (viz Architektonický dluh).
  • Zdroje jsou každá schopnost, jejíž expozice jmenuje zdroj, plus každý indexovaný objekt jako majordomus://<kind>/<identity>, čtené stejným řešením objektů, jaké používá HTTP endpoint objektů.
  • Volání nástroje se vyřeší pomocí registry.by_mcp_tool a spustí Context::execute.
  • Instrukce, které klient čte na initialize, jmenují nástroje, jež zapisují do repozitáře, změřené z deklarovaného účinku každé schopnosti, a OpenAPI publikuje stejný účinek jako x-majordomus-effect; every_surface_names_what_writes_the_repository_and_nothing_else v apps/majordomus-cli/tests/shared_units.rs drží obojí na registru.
  • Prompty se neinzerují a šablony zdrojů jsou prázdné — záměrně, ne opomenutím.

Žádný nástroj MCP není psán ručně. majordomus_announce, který vypadá jako zvláštní koordinační nástroj, je běžná schopnost peers.announce. Jediné ručně kódované chování je v mostu MCP (apps/majordomus-cli/src/mcp/bridge.rs), který tento nástroj rozpozná, aby mohl po opětovném připojení přehrát oznámení klienta na nový server.

Příkazová řádka: kontrolovaná druhá deklarace

Tady je model k sobě upřímný. Příkazová řádka není generována z registru. Strom clap v apps/majordomus-cli/src/cli.rs je psán ručně, odesílán ručně psaným matchem a vykreslován textovými funkcemi v každém modulu příkazu. Zdroj to říká: apps/majordomus-cli/src/capability/closure.rs uvádí, že příkazová řádka „je deklarována podruhé, v clap“.

To, co brání tomu, aby se ta druhá deklarace rozešla, je, že se kontroluje v obou směrech:

  1. Od deklarace k přítomnosti. Schopnost, jejíž CliExposure pojmenovává cestu, která ve stromu clap neexistuje nebo existuje, ale nelze ji spustit, selže v closure.rs a v testu projekce.
  2. Přítomné k deklarovanému. Každý příkaz clap, který nevykresluje schopnost, musí figurovat v cli::LOCAL (apps/majordomus-cli/src/cli/local.rs) s typovaným důvodem — vykresluje schopnost, zapisuje repozitář, je alias, je lokální pro relaci, nebo spravuje proces. quality::parity kontroluje seznam proti stromu oběma směry a scripts/ci/projection-check selže u příkazu bez důvodu.
  3. Stejný executor. Příkaz, který vykresluje schopnost, volá ctx.execute(id, input); jeho vlastní kód je jen prezentace (report_text, show_text v apps/majordomus-cli/src/commands/rules.rs) a --format json vypíše hodnotu schopnosti beze změny.

V praxi se cesta příkazu píše třikrát: ve strukturách clap, v CliExposure schopnosti a jako doslovná slova, která modul příkazu předá registry.by_cli, aby našel svou schopnost. Výše uvedené kontroly drží tyto tři v souladu; neudělají z nich jedno. Ne každý spustitelný příkaz je projekcí schopnosti — mnoho z nich jsou položky LOCAL, které vykreslují sdílenou doménovou logiku, zapisují do repozitáře, aliasují jiný příkaz nebo spravují proces. Rozdělení změřte, nevěřte zde napsanému číslu:

$ jq '[.. | objects | select(.executable? == true)] | length' docs/generated/cli.json
$ jq '[.capabilities[] | select(.exposure.cli)] | length' docs/generated/registry.json

Vedle ručně vykreslených příkazů existuje generický a je odvozený. majordomus-cli run <capability-id> [--input JSON] (apps/majordomus-cli/src/commands/executions.rs) provede jakoukoli registrovanou schopnost tímtéž executorem a vypíše její hodnotu — protějšek runneru Cockpitu v příkazové řádce. Každá schopnost je tedy dosažitelná z příkazové řádky; vyhrazený příkaz s vlastními slovy a lidským rendererem existuje jen tam, kde pro něj byl napsán příkaz clap. Indexované objekty se čtou stejně, přes entity kinds a entity show (schopnosti entity.kinds a entity.show, také přes HTTP a MCP), nebo přes run objects.list.

$ bin/majordomus-cli run plan.status --format json
$ bin/majordomus-cli run peers.list --format json
$ bin/majordomus-cli entity show <uri>

Text nápovědy je z clap. Doplňování shellu z clap není: majordomus completion odpovídá z grafu příkazů, který skládá strom clap, share/commands.yaml pro nástroj shellu a výpis receptů just (ADR 0027, docs/COMMANDS.md). Reference příkazů na webu, /docs/cli/, se generuje z docs/generated/cli.json, které se samo generuje ze stromu clap — takže reference nemůže uvést příkaz, který program nemá.

flowchart TD
  d3_CAP["capability! declaration with CliExposure"] --> d3_CL["closure check: path exists and runs"]
  d3_CLAP["clap tree in cli.rs"] --> d3_CL
  d3_CLAP --> d3_LOC["cli::LOCAL reasons for non-capability commands"]
  d3_LOC --> d3_PAR["quality::parity both directions"]
  d3_CLAP --> d3_CJ["docs/generated/cli.json"]
  d3_CJ --> d3_REF["/docs/cli/ reference pages"]
  d3_CLAP --> d3_CG["command graph"]
  d3_SC["share/commands.yaml"] --> d3_CG
  d3_JU["just recipes"] --> d3_CG
  d3_CG --> d3_COMP["completion"]

Cockpit

Cockpit není další aplikace, databáze ani doménový model. ADR 0012 jej nazývá projekcí registru pro člověka a kód to na úrovni dat dodržuje: data, která ukazuje každá stránka, procházejí přes Context::execute (ask() v apps/majordomus-cli/src/cockpit/pages.rs) a nedělá žádné vlastní objevování. Stránka mesh vykresluje mesh.status a mesh.nodes a nedrží žádný seznam uzlů (project.mesh-is-observation-not-authority); pohled peers vykresluje peers.list.

Je to server-rendered Rust bez šablonovacího enginu: typovaný strom HTML (apps/majordomus-cli/src/cockpit/html.rs), komponenty v view.rs a prohlížečové knihovny vendorované jako progresivní vylepšení. Jeho barvy, písmo a stavová slova jsou projekcemi share/design/tokens.yaml (ADR 0036), generovanými do stylopisu, který stránky používají.

Co se odvozuje a co se píše:

ČástJak existuje
průzkumník a spouštěč schopností na /cockpit/capabilities/<id>generické: jedna stránka pro každou schopnost; formulář runneru, generovaný ze vstupního schématu s příklady z případů měření výkonu, pro každou schopnost vystavenou přes HTTP, jejíž stabilita spuštění dovoluje; rules.show nemá žádný kód stránky
prohlížeč objektů na /cockpit/objects?kind=<kind> a /cockpit/object?uri=<uri>obecné: každý indexovaný druh, včetně pravidel, ADR a tvrzení
navigační katalogyodvozeno z modulů registru, druhů indexu a odvození grafů, seskupeno podle oblastí produktového modelu a kanonicky seřazeno
oblasti nejvyšší úrovně a jejich trasyručně psáno: match v apps/majordomus-cli/src/cockpit/mod.rs a seznam oblastí v nav.rs
specializované stránky (release, design, mesh, worktrees, kontinuita)ručně psané pohledy nad typovanými odpověďmi schopností

Proto neexistuje trasa /cockpit/rules/<id>. Pravidlo se prohlíží na svém URI objektu a jeho důkaz spuštěním rules.show v runneru. Každá kanonická entita je prohlédnutelná; ne každý druh má vlastní stránku.

Dokumentace a web

Ke čtenáři se dostanou tři vygenerované vrstvy a každá vzniká z kanonického zdroje pojmenovaným generátorem a kontroluje se na drift:

VýstupZdrojGenerátorKontrola driftu
docs/generated/ — registr, OpenAPI, reference příkazů, reference schopností, měření výkonu, changelog, design, manifest artefaktů, grafregistr, index, designové tokeny, záznamy release a historie gitumajordomus generatemajordomus generate --check, bajt po bajtu
projekce site/data/generated/ a site/content/ — stránky dokumentace, záruky, doktríny, příkazy, stránky registru, stav plánudocs/*.md, docs/CLAIMS.yaml, pravidla, share/commands.yaml, .ai/repo/project/, generovaný registrscripts/generate-site-datascripts/generate-site-data --check
site/public/vše výšeZola přes scripts/site-buildscripts/site-check, poté ověření publikace

scripts/derive spustí celý graf popořadě (generování, data webu, generování znovu, protože dokumenty jsou indexované objekty, pak .gitattributes) a scripts/derive-check jmenuje každý zastaralý soubor. Manifest artefaktů docs/generated/artifacts.md vypisuje každý soubor, který majordomus generate zapisuje, s jeho schématem, pokud ho má, a zdrojem, a sám je generován; výstupy generátoru webu v něm nejsou.

Tento dokument je příklad. Píše se jednou, zde. scripts/generate-site-data ho najde přes jeho řádek v docs/README.md — každý Markdown nebo YAML soubor nejvyšší úrovně v docs/ musí mít řádek v jedné z tabulek indexu, jinak generování selže — zapíše site/content/docs/how-it-works.md s generovaným front matter (titul z prvního nadpisu, popis z řádku indexu, pořadí z pozice řádku), přepíše jeho relativní odkazy na routes webu a převede jeho bloky mermaid na vykreslené diagramy. Stránka dokumentace je commitnuta a drží se zdroje stejnou --check.

Porovnané povrchy

PovrchKonzumentÚčelOdvozeno zPsáno ručněFormát
HTTPsoftwareprogramová operaceregistr (trasy, vazba, dispečink)pouze business logikaJSON pod /api/v1
OpenAPIintegrátoři, generátorykontraktregistr a kanonická schématanicOpenAPI 3.1 JSON
Swagger UIčlověk zkoumající APIinteraktivní smlouva/openapi.jsonnicHTML
MCPAI pracovnícinástroje a zdrojeregistr a index objektůpřehrání oznámení po opětovném připojeníJSON-RPC
Příkazová řádkalidé a skriptyinteraktivní operacekontrolováno proti registru; vykresluje hodnoty schopnostístrom clap, textové renderery, cli::LOCALtext terminálu nebo --format json
Cockpitlidéviditelnost a běžící operaceodpovědi schopností; katalogy z registru a indexuseznam oblastí, routes, specializované pohledyHTML
Generované dokumenty a webčtenářireference a vysvětleníregistr, index, docs/vysvětlující prózaMarkdown, JSON, HTML

Jsou to rozhraní nad toutéž skutečností, ne její nezávislé implementace. Rozdíly jsou prezentace a místa, kde je prezentace stále psána ručně, jsou místa, která kontroly sledují.

Generátor a renderer

Generátor rozhoduje, co existuje: které entity, jejich vztahy, jejich pořadí, jejich metadata. Renderer rozhoduje jen o tom, jak to vypadá. Důkaz pravidla ukazuje toto rozdělení:

flowchart TD
  d4_RF["rule files"] --> d4_IDX["object index"]
  d4_GY[".ai/repo/ci/gates.yaml"] --> d4_ENG["rules engine: apps/majordomus-cli/src/rules"]
  d4_IDX --> d4_ENG
  d4_LED[".ai/repo/evidence/ledger.json"] --> d4_ENG
  d4_ENG --> d4_RD["RuleDetail value"]
  d4_RD --> d4_T1["text renderer: rules show"]
  d4_RD --> d4_T2["JSON: rules show --format json and GET /api/v1/rules/rule"]
  d4_RD --> d4_T3["MCP tool majordomus_rule"]
  d4_RD --> d4_T4["Cockpit runner"]

Žádný renderer nepočítá, zda je pravidlo dokázáno. Frontend není autoritou nad sémantikou repozitáře: Cockpit neodvozuje vztahy pravidel, připravenost úkolů ani stav vynucování, protože engine, který každé z nich vlastní, už odpovídá.

Routy, navigace a pořadí

Které trasy a nabídky jsou odvozeny a které jsou deklarovány záměrně:

PovrchTrasyNavigaceJak se udržuje pravdivé
HTTPjedna na expozici schopnosti, nalezená registry.by_http v době požadavku; nic neregistruje trasuGET /api/v1/ vypíše každou vystavenou schopnostregistr odmítne duplicitní trasu
OpenAPIjedna cesta na HTTP expozicitagy z jmenného prostoru schopnostítest projekce porovnává každou expozici s její operací
MCPjeden nástroj nebo zdroj na expozici plus jeden zdroj na indexovaný objekttools/list, resources/listtest projekce; jedinečnost v registru
Cockpitobecné stránky pro každou schopnost a každý objekt; trasy oblastí jsou ručně psaný seznam a shodují seseznam oblastí psaný ručně; katalogy uvnitř každé oblasti odvozené z registru, indexu a modelu produktutesty v cockpit/mod.rs drží seznam oblastí, statické trasy a dispatcher v rovnosti
webjedna stránka na odvozený objekt, který projekce publikuje — funkce, tvrzení (jako záruky), doktríny, pravidla, ADR, příkazy, schopnosti, případy užitísite/data/nav.toml, deklarováno jednou záměrně: navbar je redakční, sitemap nescripts/ci/nav-check a site-check: každý href se vyřeší, žádný href se neopakuje, každá publikovaná sekce je dosažitelná
servírovaná domovská stránkapřipojení runtimu, z webové topologiez vyřešené topologieweb::discover a seznam vyhrazených cest

Pořadí je smlouva, ne náhoda. Generované seznamy se řadí podle klíče crate::order — skupina, pak pořadí, pak štítek, pak kanonická identita (ADR 0025) — takže projekce uvádí tytéž entity ve stejném pořadí při každém běhu a na každém povrchu; shellové generátory řadí pomocí LC_ALL=C. scripts/ci/order-check odmítne ručně napsané řazení podle locale a zpřísňuje zbývající ad hoc místa řazení a testy determinismu generují dvakrát a porovnávají bajty.

Jak se předchází odchylkám

Generování samo drift nezabrání; generátor, který nikdo znovu nespouští, je zastaralá kopie se skriptem vedle. Zabrání mu to, že se každá projekce kontroluje proti svému zdroji.

InvariantMechanismusKde běží
každá deklarovaná projekce existuje a žádná projekce nemá chybějící deklaracievery_declared_projection_exists_and_no_projection_is_an_orphan v apps/majordomus-cli/tests/projections.rs: každý nástroj MCP má id, schéma a popis schopnosti; každé vystavení přes HTTP má operaci OpenAPI se stejným id; každá cesta příkazu existuje a běží; žádný osiřelý nástroj, zdroj ani operace; každé $ref se vyřešísada testů crate v CI
změna kanonického typu dosáhne každé projekcea_change_to_the_canonical_type_or_description_reaches_every_projection: výměna vstupního typu změní vlastnosti MCP, parametry OpenAPI i referenci dohromady; odstranění vystavení HTTP odstraní cestu a ponechá nástrojstejné
generovaný výstup je deterministický a nenese cestu strojegenerated_artifacts_are_byte_identical_twice_and_carry_no_absolute_path a test trasování artefaktůstejné
commitnuté generované soubory se rovnají čerstvé generacimajordomus generate --check, scripts/generate-site-data --check, scripts/derive-checkscripts/rust-check a job site v CI; scripts/pages current v háčku pre-commit
povrchy schopností se shodují od začátku do konce na skutečné binárcetest/cases/76_capabilities_projections.sh: capabilities validate, jedna schopnost porovnaná napříč svými metadaty MCP, operací OpenAPI a generovanou referencí, počty porovnané oběma směry, generate --check selhávající po zásahu, nový druh dokumentu přidaný jen datyshellová sada
každý příkaz má důvod existovat i mimo registrscripts/ci/projection-check, quality::parityCI
graf příkazů je jediný zdroj doplňování a referencíscripts/ci/command-graph, test/cases/101_command_graph.shCI
generovaný soubor se needituje ručněhlavička „GENERATED FILE — DO NOT EDIT DIRECTLY“ plus bytové porovnání; project.derived-files-regeneratedpre-commit a CI

Determinismus je požadavek, ne hezká vlastnost: projekce, která řadí své položky při dvou během různě, dělá z každé regenerace diff a z každé kontroly driftu šum. Generované výstupy se řadí podle kanonické identity v rámci sémantických skupin (crate::order ve spustitelném souboru; řazení v C-locale v shellových generátorech) a testy determinismu generují dvakrát a porovnávají bajty.

Jedna schopnost přes každý povrch

rules.show, od deklarace po důkazy. Poslední sloupec je smysl: téměř nic po deklaraci se nepíše na schopnost zvlášť.

KrokSoubor nebo URLPsaný ručně, nebo odvozený
deklaraceapps/majordomus-cli/src/capability/builtin/rules.rsručně psané
vstupní typ a jeho případy měřeníRuleInput ve stejném souboruručně psané
doménová logikaapps/majordomus-cli/src/rules/ručně psané
kompozicemodul rules v builtin::modules()autorské, dva existující řádky: pub mod a položka compose_modules!
validace registruCapabilityRegistry::buildautomaticky
HTTP routaGET /api/v1/rules/rule?rule=<id> přes generický routerautomaticky
Operace OpenAPI rules.show/openapi.json, docs/generated/openapi.jsonvygenerováno
Vstup do Swagger UI/swaggervykresleno
Nástroj MCP majordomus_rulemcp/surface.rs, obecnéautomaticky
runner Cockpitu/cockpit/capabilities/rules.show, formulář ze schématuautomaticky
příkaz majordomus-cli rules show <id>varianta clap v cli.rs, dispatch a textový renderer v commands/rules.rs, spustitelný příklad v cli.rspsáno ručně, pak kontrolováno uzávěrem a paritou
referenční dokumentacedocs/generated/capabilities.md, docs/generated/modules/rules.md, docs/generated/cli.mdvygenerováno
web/registry/capabilities/rules-show/, /docs/cli/rules/show/vygenerováno
benchmarkspřímé transporty, MCP a HTTP z měřicích případůvygenerováno
teststest projekce pro každý modul, tests/projections.rs, test příkladů CLI, apps/majordomus-cli/tests/rules.rsnapsáno jednou, kde možno generické

Co se stane, když se přidá schopnost

Poctivý vývojářský postup na výchozí větvi dnes:

  1. Doménové chování napište do vlastního modulu pod apps/majordomus-cli/src/.
  2. Deklarujte schopnost pomocí capability! v modulu pod apps/majordomus-cli/src/capability/builtin/, se vstupními a výstupními typy odvozujícími JsonSchema a vstupem implementujícím BenchmarkCases. Pokud je modul nový, přidejte jej do seznamu pub mod a do builtin::modules() — jediný ruční krok skládání.
  3. HTTP, OpenAPI, Swagger UI, MCP a spouštěč Cockpitu se objeví bez dalšího kódu, pro každé vystavení, které deklarace jmenuje; spouštěč potřebuje vystavení přes HTTP a run <id> k němu z příkazové řádky dojde tak či onak.
  4. Je-li schopnost vystavena na příkazové řádce, přidejte variantu clap, dispečujte ji přes ctx.execute, napište textový renderer a přidejte spustitelný příklad. Closure a parity selhávají capabilities validate, projekční test a projection-check, dokud se deklarace a strom neshodují; samotný build uspěje.
  5. Spusťte just derive (scripts/derive: generate, data webu, znovu generate, pak .gitattributes), což přepíše registr, OpenAPI, reference, inventář měření a data webu; samotné majordomus generate data webu nepřepíše. Commitněte je se změnou. Pre-commit hook odmítne commit, jehož data webu jsou zastaralá, a — je-li spustitelný soubor sestaven — takový, jehož projekce registru jsou zastaralé.
  6. Testy. Generické testy projekcí pokrývají novou schopnost automaticky. Vlastní pin test modulu vypisuje jeho schopnosti a jejich vystavení, takže přidání jedné do existujícího modulu znamená rozšířit tu tabulku; poté přidejte behaviorální případ pro to, co dělá.
  7. Tvrzení a důkazy. Je-li schopnost veřejnou zárukou, přidejte do docs/CLAIMS.yaml tvrzení s jeho testem a detailní stránku pod docs/claims/; běh testu zaznamenejte pomocí majordomus-cli evidence record.
  8. Verze. Veřejná plocha se změnila, takže majordomus-cli release analyze nyní dluží bump; release bump jej zapíše (viz Publikace a verze).

Nic se neregistruje zvlášť v HTTP, OpenAPI, Swaggeru, MCP, Cockpitu ani referenci. Příkazová řádka je zbývající druhá deklarace a je kontrolovaná. Cíl nulové registrace — nová kanonická entita, která dosáhne každého relevantního povrchu bez kroku na povrch — je splněn pro každý povrch kromě příkazové řádky a skládání modulů.

Správa: čím je každý druh dokumentu

Taxonomie tak, jak ji implementují schémata a loadery:

DruhCo to jeAutorsky vSchéma
pravidloverzovaný invariant s tvrzením, třídou (blokující nebo poradní), závislostmi a volitelně deklarací, jak se vynucuje.ai/repo/rules/project/ a vendorovaný standard pod .ai/repo/rules/vendor/majordomus/rules/majordomus.rule/v1
doktrínane samostatný druh: pravidlo, jehož blok vynucování jmenuje validátor, který spouští příkazodvozeno z pravidel pomocí lib/doctrine.shschéma pravidla
policykonfigurovatelné chování repozitáře: platné profily, povinné sekce předávky, prahy čerstvosti, zapojení vynucování.ai/repo/policy.yamlmajordomus.policy/v1
ADRarchitektonické rozhodnutí s jeho kontextem, alternativami a důsledky; proposed, dokud je osoba nepřijme.ai/repo/adrs/majordomus.adr/v1
claimveřejné prohlášení o tom, co nástroj zaručuje, se zdrojem, implementací, testem a stavemdocs/CLAIMS.yaml, podrobnosti v docs/claims/majordomus.claim/v1
profilpojmenovaná sada přepínačů politiky pro druh práce.ai/repo/profiles/majordomus.profile/v1
dovednostzabalený postup pro workera.ai/repo/skills/majordomus.skill/v1

Doktrína je část, která se nejčastěji chápe špatně. Doktrína není dokument principů, na který pravidla ukazují; je to pravidlo, které nástroj sám vynucuje pojmenovaným validátorem. Registr doktrín se odvozuje, nikdy nepíše: je to každé pravidlo účinné sady, jehož blok vynucování jmenuje validátor (docs/DOCTRINE.md). Principy, kterým doktrína slouží, jsou samy pravidly — vendorovaná pravidla označená principle (soubory principle-NN-*.v1.md, například majordomus.one-worker-one-scope) — spojená obyčejným depends_on. Neexistuje typované pole doktrína-pravidlo; viz Dluh architektury.

Doktríny pocházejí z balíčku. Standardní pravidla žijí v share/standard/majordomus/ s manifestem nesoucím sha256 každého souboru a do repozitáře se vendorují bajt po bajtu. majordomus doctor porovnává vendorované soubory s manifestem.

Tvar pravidla

Úryvek skutečné hlavičky .ai/repo/rules/project/rule-is-a-doctrine.v1.md (jeho description vynecháno, výrok zkrácen):

id: project.rule-is-a-doctrine
version: 1
kind: rule
title: A new enforced rule is a doctrine, not an inline check
statement: A rule the tool enforces declares an x-majordomus block ...
status: active
class: blocking
depends_on: []
tags: [doctrine]
x-majordomus:
  tests: [test/cases/18_doctrine_wiring.sh, test/cases/125_rule_proof.sh]

Tělo musí nést nadpisy, které rule.v1.proto vyžaduje: Rationale, Required behaviour, Failure behaviour, Verification. Blok x-majordomus nemá pole mode. Režim vynucování se odvozuje z toho, co blok jmenuje (ADR 0048):

Názvy blokůRežimVýznam
a validatorodeslánopříkaz spouští mj_validate_<name> sám: check, finish, doctor, watch — podle toho, co uvádí jeho enforced_by
tests a žádný validátorřízeno kontrolouCI kontrola spouští testy, které ho dokazují
jen reviewed_becausezrevidovánovynucuje ho člověk a pravidlo říká, proč to žádný stroj nedokáže
nicdeklarativníuvedený princip; povoleno jen pro vendorovaná pravidla označená principle — jakékoli jiné pravidlo, které nic nejmenuje, selže rule-proof-check

Shellový nakladač pravidel (lib/rules.sh) odmítne napůl deklarovaný blok; Rustový engine důkazů ho čte jako deklarativní a nahlásí ho.

Životní cyklus pravidla

flowchart TD
  d5_AU["authored: a .vN.md file"] --> d5_PA["parsed against rule.v1"]
  d5_PA --> d5_IX["indexed: majordomus://rule/id@version"]
  d5_IX --> d5_MO["mode derived from x-majordomus"]
  d5_MO --> d5_GB["gates bound: tests matched to what gates.yaml runs"]
  d5_GB --> d5_EX["executed: a gate or a command runs"]
  d5_EX --> d5_RC["recorded: evidence ledger row with commit and digest"]
  d5_RC --> d5_ST["state derived against the current tree"]
  d5_ST --> d5_SF["surfaces: rules report, rules show, MCP, Cockpit, site"]

Existence pravidla neznamená, že se vynucuje

Toto je ústřední myšlenka správy a implementace ji typuje. Pravidlo může stát na kterémkoli z těchto stupňů a každý stupeň je samostatný fakt:

PříčkaCo to zakládá
deklarovánosoubor existuje
zpracováno a platnéloader a schéma pravidla to přijímají
registrovánoindex to drží na jeho URI
důkaz pojmenovánjeho blok x-majordomus jmenuje validátor nebo testy
důkaz se vyřešíkaždá jmenovaná cesta existuje ve stromu — jinak visící, což vždy selže
zapojenovalidátor je vyvolán příkazem (kontroluje doctor kontrola zapojení doktríny), nebo kontrola v .ai/repo/ci/gates.yaml spouští pojmenovaný test
provedenoběh proběhl
zaznamenánoledger důkazů drží ten běh, s jeho commitem, stavem pracovního stromu a digestem
aktuálnívstupy zaznamenaného běhu se ve stromu, na který se ptáme, nezměnily

Rust engine pravidel (apps/majordomus-cli/src/rules/mod.rs) to redukuje na jeden stav z RuleState, nejsilnější první: proven, inputs_unchanged, stale, gated, failing, not_run, reviewed, unrunnable, dangling, unproven. Visící cesta činí pravidlo dangling — převažuje nad vším; jinak selhávající test činí pravidlo failing; jinak je jeho stav nejslabší z testů, které mohou nést důkaz. Za prošlé se počítají jen první tři. Nález se vznáší pro visící důkaz nebo pro blokující pravidlo, které je nedokázané, selhává nebo nejde spustit; not_run, gated a reviewed záměrně nálezy nejsou, protože popisují absenci záznamu, ne vadu.

scripts/ci/rule-proof-check je kontrola: visící (dangling) důkaz selhává a pravidlo jakékoli třídy, které nejmenuje žádný validátor, žádný test a žádné reviewed_because, selhává — třída není výjimka. Jediná výjimka je vendorované pravidlo označené principle. Drží ho ratchet, jehož základní stav, .ai/repo/rule-proof-baseline.txt, je prázdný.

Abyste viděli, kde repozitář stojí — ne abyste věřili slovu tohoto dokumentu:

$ bin/majordomus-cli rules report
$ bin/majordomus-cli rules show majordomus.scope-integrity
$ curl -s http://127.0.0.1:8741/api/v1/rules | jq .summary

V době psaní ten report říká, že každé blokující pravidlo buď jmenuje důkaz, který se vyřeší a je navázán na kontrolu, nebo deklaruje reviewed_because a vynucuje ho člověk (rules report --class blocking uvádí které), a že v ledgeru je zaznamenáno málo běhů, takže většina pravidel stojí na not_run místo proven. To je správné čtení důkazů: kontroly běží v CI při každé změně a CI zaznamenává své běhy do artefaktu na běh (scripts/ci/evidence-collect), ale nic je zatím nepřenáší do sledovaného ledgeru (ADR 0080, navrženo). „Satisfied“ v reportu znamená žádný nález — nic nevisí a žádné blokující pravidlo není nedokázané, selhávající ani nespustitelné; zahrnuje reviewovaná pravidla a poradní pravidla, která žádný důkaz nejmenují. Neznamená, že zaznamenaný běh prošel. Zelený odznak kdekoli v Majordomu musí být projekcí zaznamenaného provedení; kde žádné zaznamenáno není, povrchy říkají not run, gated nebo reviewed — nikdy proven.

Mapa správy

flowchart LR
  g_P["principle: a vendored advisory rule tagged principle"] -->|depends_on| g_R["rule: id@version, class, statement"]
  g_R -->|x-majordomus names a validator| g_V["validator: mj_validate_* in lib/"]
  g_R -->|x-majordomus names tests| g_T["tests: test/cases, crate tests, gate scripts"]
  g_R -->|names only reviewed_because| g_H["a person's review"]
  g_V --> g_D["dispatched by check, finish, doctor, watch"]
  g_T --> g_G["bound to gates in .ai/repo/ci/gates.yaml"]
  g_D --> g_X["execution"]
  g_G --> g_X
  g_X -->|evidence record| g_L["ledger: outcome, commit, tree, digest"]
  g_L --> g_S["proof state, judged against the presented tree"]
  g_S --> g_U["rules report, rules show, MCP, Cockpit runner, site"]

Doktrína je horní cesta — pravidlo, jehož blok jmenuje validátor, který příkaz spouští. Pravidlo s kontrolou je prostřední cesta. Pravidlo s review je dolní a žádný povrch ho nenazývá vynucovaným strojem.

Důkazy

Důkazem je zaznamenané provedení, nikoli cesta k testu, která náhodou existuje (docs/EVIDENCE.md).

flowchart LR
  d6_TR["test run"] --> d6_REC["majordomus-cli evidence record"]
  d6_REC --> d6_LED[".ai/repo/evidence/ledger.json: latest run per test"]
  d6_LED --> d6_JOIN["join: claim or rule to its tests"]
  d6_TREE["git: diff from the recorded commit"] --> d6_JOIN
  d6_JOIN --> d6_STATE["proof state"]
  d6_STATE --> d6_OUT["evidence report, rules show, Cockpit, site guarantees"]

Kniha je commitnutá a drží poslední provedení každého testu: runner, výsledek, sekundy, commit, stav pracovního stromu, digest, původ (local, CI nebo release) a příkaz. Stav důkazu tvrzení se odvozuje na požádání:

StavVýznam
provenzaznamenaný běh prošel, mezi jeho commitem a dotazovaným stromem se nezměnilo nic než ledger a oba stromy byly čisté
inputs_unchangedvlastní zdroj, implementace a test tvrzení se nezměnily, ale změnilo se něco jiného nebo byl jeden ze dvou stromů špinavý
stalejeden z těch vstupů se změnil, předložená revize neobsahuje commit běhu, tvrzení nedeklaruje žádné vstupy, nebo git nemohl odpovědět
failingzaznamenaný běh selhal
not_runžádný běh není zaznamenán
unrunnablepojmenovaný test je druhu, který žádný runner nemůže provést
no_testtvrzení nejmenuje žádný test

Rozhodnutí žije v jedné funkci, freshness() v apps/majordomus-cli/src/evidence/freshness.rs, takže žádný povrch nemůže posoudit běh jinak. Čerstvost proto není časové razítko, ale vztah ke stromu: test, který prošel u jednoho commitu, je u tohoto commitu proven, u pozdějšího commitu, který se jeho vstupů nedotkl, inputs_unchanged a u toho, který se jich dotkl, stale. proven a inputs_unchanged se nikdy nesloučí do jednoho stavu, protože druhé je závěr o relevanci a první ne.

Schopnosti důkazů jsou deklarovány jednou v apps/majordomus-cli/src/capability/builtin/evidence.rs a vypisuje je jq -r '.capabilities[] | select(.id | startswith("evidence.")) | .id' docs/generated/registry.json: report, jedno tvrzení, jeden test, záznam a razítko. evidence.record je jediný zapisovatel a je jen z příkazové řádky, stejně jako evidence.stamp, který čte cestu, již jeho volající jmenuje.

Jedna doktrína vystopovaná: integrita rozsahu

majordomus.scope-integrity je doktrína: převzaté pravidlo, jehož blok jmenuje validátor.

OdkazKde
ručně psanéshare/standard/majordomus/rules/scope-integrity.v1.md, vendorováno do .ai/repo/rules/vendor/majordomus/rules/scope-integrity.v1.md, sha256 v obou manifestech
principdepends_on: majordomus.one-worker-one-scope@1
blok vynucovánívalidator: scope, enforced_by: [check, finish, watch], exit_code: 10, claims: [scope-enforcement, scoped-task], tests: [test/cases/04_start_check.sh]
validátormj_validate_scope v lib/check.sh: selže u souborů změněných od začátku úlohy, které leží mimo rozsah úlohy
dispatchmj_doctrine_dispatch v check, finish a watch; finish --check běží z hooku pre-push
zapojení ověřenomj_validate_doctrine_wiring v lib/doctor.sh, mutačně testováno pomocí test/cases/18_doctrine_wiring.sh
testtest/cases/04_start_check.sh, spouštěno kontrolami shell-suite a macos
claimscope-enforcement v docs/CLAIMS.yaml, podrobnosti na docs/claims/scope-enforcement.md
index a MCPmajordomus://rule/majordomus.scope-integrity@1; nástroj majordomus_rule
HTTPGET /api/v1/rules/rule?rule=majordomus.scope-integrity
Cockpit/cockpit/object?uri=majordomus%3A%2F%2Frule%2Fmajordomus.scope-integrity%401
web/doctrines/scope-integrity/, z site/data/generated/doctrines.json; /guarantees/scope-enforcement/
evidencecokoli ledger drží pro test/cases/04_start_check.sh, čtené pomocí rules show

Jedno pravidlo vystopováno: odvozené soubory se přegenerují

project.derived-files-regenerated je kontrolované pravidlo projektu: žádný validátor, testy pojmenovány.

OdkazKde
ručně psané.ai/repo/rules/project/derived-files-regenerated.v1.md
důkaztests: jmenující test/cases/56_derived_current_gate.sh, test/cases/51_derived_artifacts_committed.sh, test/cases/95_executable_reference.sh a scripts/derive-check
bod vynucováníhook pre-commit spouští scripts/pages current; .ai/repo/policy.yaml deklaruje toto zapojení jako derived-current a doctor selže, pokud ho hook přestane spouštět
kontrolyshell-suite spouští pojmenované případy a macos na požádání; scripts/derive-check engine důkazů klasifikuje jako nespustitelné a ignoruje, protože ostatní se vyřeší
povrchyrules show project.derived-files-regenerated, stránka objektu v Cockpitu, jeho vlastní stránka /rules/project-derived-files-regenerated-1/ a sekce pravidel v /features/declare-once/
evidencečteno pomocí rules show; důkaz je pojmenován a kontrolován

Postup: přidání nového pravidla

Předpokládejme, že správce přidá: každá veřejná schopnost má alespoň jedno spustitelné ověření. Co se dnes děje v každém kroku na výchozí větvi:

  1. Ručně psané. Soubor jménem every-capability-is-verified.v1.md pod .ai/repo/rules/project/, s hlavičkou pravidla a požadovanými nadpisy těla. Ručně: soubor, jeho vztahy a jeho blok vynucování jsou ručně psané části.
  2. Schéma. Loader pravidel validuje hlavičku proti rule.v1; neznámý klíč nebo napůl deklarovaný blok vynucování se odmítne. Automatické.
  3. Discovery. Třída zdrojů rule v .ai/repo/knowledge/sources.yaml už adresáři odpovídá, takže index drží majordomus://rule/project.every-capability-is-verified@1. Automaticky.
  4. Vztahy. depends_on jmenuje princip, kterému slouží, pomocí id@version; DAG validuje doctor. Psáno, pak kontrolováno.
  5. Vynucování. Režim volí autor podle toho, co blok jmenuje. Velká část tohoto pravidla je už pravdivá z konstrukce — vstup bez benchmarkových případů se nepřeloží a testy projekcí spouštějí každou expozici — takže seznam tests: jmenující apps/majordomus-cli/tests/projections.rs a nový případ z něj udělá kontrolovaný. Autorsky.
  6. Navázání na kontrolu. Engine důkazů naváže tyto testy na kontroly v .ai/repo/ci/gates.yaml, které je spouštějí. Automaticky; cesta, která neexistuje, visí a shodí rule-proof-check.
  7. Příkazová řádka. majordomus-cli rules report a rules show ho zahrnují. Automatické.
  8. HTTP. GET /api/v1/rules/rule?rule=project.every-capability-is-verified. Automaticky.
  9. MCP. Zdroj na svém URI a nástroj majordomus_rule. Automaticky.
  10. Cockpit. Jeho stránka objektu a zpráva o pravidlech v runneru. Automaticky.
  11. Web. Pravidlo dostane svou generovanou stránku na /rules/project-every-capability-is-verified-1/; doktrína dostane také stránku /doctrines/ a funkce, která ji jmenuje, ji uvádí. Automaticky.
  12. Provedení. CI spustí kontroly při příští změně, která se dotkne jejich třídy cest. Automaticky.
  13. Důkazy. Běh se dostane do knihy jen přes evidence record. Dnes ručně.
  14. Aktuální stav na každém povrchu. Odvozeno na požádání z knihy a stromu. Automaticky.
  15. Regrese. Kontrola selže u budoucí změny, která poruší invariant; rule-proof-check selže u budoucí úpravy, která odstraní jmenovaný test. Automaticky.

Relace, úlohy a kontinuita

Práce přežije relaci, která ji dělá, díky trvalým záznamům, ne přepisům (docs/CONTINUITY.md). Záznamy zapisuje nástroj shellu:

ZáznamKdeTrvaléPsaný ručně, nebo odvozený
aktivní úloha.ai/local/state/current.yamllokálníúloha, rozsah, profil psané ručně; blok computed from git odvozený
otevřená epizoda.ai/local/state/sessions-open/lokální, do uzavřeníodvozeno z událostí hooků poskytovatele
uzavřená relace.ai/repo/sessions/, když manifest pojmenovává tento oddílcommitnutoodvozeno z knihy při uzavření
kontrolní bod.ai/local/state/checkpoints/lokálníodvozeno pomocí checkpoint --derive, nebo napsáno ručně
handover.ai/local/state/handovers/lokálnítělo napsáno; front matter odvozen
kniha záznamů.ai/local/state/ledger.jsonllokální, připojuje se a rotuje podle ledger.retention_max_lines politikyodvozeno: jedna účtenka na událost

Hooky poskytovatele (pro Claude Code v .claude/hooks/) volají majordomus capture session při startu, compactu a ukončení. Start otevře nebo zachová epizodu, zajistí, že server checkoutu běží, a vypíše briefing; ukončení odvodí checkpoint a předávku a uzavře vlastní relaci poskytovatele. .ai/local/ je ignorováno gitem: kontinuita je lokální pro stroj a commitují se pouze záznamy uzavřených relací. V repozitáři se zapnutou kooperací mesh se předávky navíc replikují do propojených runtime přes žurnál (apps/majordomus-cli/src/mesh/handover.rs).

Životní cyklus úlohy je start s povinným rozsahem, check, které rozesílá doktríny na ni vázané, a finish s výsledkem a, pokud to profil vyžaduje, ověřovacím příkazem, jehož exit kód se zaznamená. Dokončení, které selže v doktríně, je odmítnuto s exitem 10 a seznamem nesplněného.

Kontext pro relaci

Kontext se kompiluje na několika místech a každé je deterministické. Kromě tří níže lib/session_context.sh skládá pracovní kontext otevřené epizody při každém čtení.

majordomus context (lib/context.sh) sestavuje seřazené sekce — git, peery, úlohu, profil, kontextové dokumenty, otevřené otázky, kandidáty znalostí, rozhodnutí, uvažování, checkpoint, předávku, integraci, relevantní soubory, historii, prompt — řízené přepínači profilu a vtěsnané do řádkového rozpočtu politiky. Sekce se zahazují od nejméně spolehlivé — historie, integrace, soubory, dokumenty, znalosti, uvažování, rozhodnutí, pak těla checkpointu a předávky, která před zahozením zkrátí na řádek s ukazatelem, pak peery — a git, úloha, profil a otevřené otázky se nezahazují nikdy. Každé zahození je uvedeno pod EXCLUDED; pokud je výstup stále nad rozpočtem, příkaz skončí exitem 10 místo tichého zkrácení.

majordomus context resolve <path> (lib/context_docs.sh) skládá kontextové dokumenty, které platí pro cestu: každý Markdown soubor context/v1 pod .ai/, jehož rozsah ji pokrývá — přesný adresář, obsahující podstrom nebo explicitní seznam cest — seřazené podle hloubky, pak deklarovaného pořadí, pak cesty, s odstraněnými nahrazenými dokumenty a otiskem nad řetězcem. Každý dokument přidává k svým předkům; nejbližší je nenahrazuje.

devcontext.compile je kompilátor v Rustu pro seřazenou pracovní množinu úlohy (apps/majordomus-cli/src/devcontext/). Prochází složený graf objektů od úlohy po typovaných hranách s pevnými dopřednými a zpětnými vahami, řadí podle úrovně autority — úloha, governance, zdroj, rozhodnutí, znalost, historie — poté podle relevance, poté podle URI a utrácí tokenový rozpočet metodou first fit, přičemž pojmenuje každou přeskočenou položku a její cenu. Jeho jediné odvozování je záměr: slova úlohy porovnaná s titulkem, popisem, identitou a tagy objektu, omezená pod přímým semínkem a pod většinou jednotlivých deklarovaných hran (devcontext/select.rs); stále může předstihnout deklarovaný vztah dosažený slabou nebo vícekrokovou hranou a úroveň autority se řadí před relevancí. Příkaz shellu context jej zatím nepoužívá.

Kontext se generuje, protože musí být znovu sestavitelný. Kontext, který existuje jen uvnitř dřívějšího promptu, se ztratí spolu s ním; kontext zkompilovaný ze stavu repozitáře může příští pracovník zkompilovat znovu a vysvětlit ho položku po položce.

Předávka

majordomus handover bere tělo na stdin se sekcemi, které politika vyžaduje — Objective, Current State, Next Action — nebo ho odvodí pomocí --derive. Tělo je autorské; front matter je odvozený: repozitář, worktree, větev, head, stav pracovního stromu, změněné soubory, časová razítka. Tělo, které nese identitní pole, je odmítnuto, takže worker nemůže tvrdit head, na kterém není.

handover --resolve najde nejrelevantnější záznam: nejprve stejný worktree a větev, pak stejnou větev, nikdy v celém repozitáři. Označí vztah k aktuálnímu HEAD jako exact, advanced, diverged nebo jiný kontext a vypíše verdikt čerstvosti podle prahů z politiky, přičemž zastaralý záznam označí jako historii. Briefing relace používá stejný verdikt a necituje další akci zastaralé předávky, protože pokyn, který platil před několika dny, je kontext, ne rozkaz.

Plánování

Milníky jsou specifikace výsledků; úkoly jsou prováděcí kontrakty (docs/PLANNING.md). Obojí je autorské YAML pod .ai/repo/project/. Úkol deklaruje závislosti, rozsah, akceptační kritéria, validaci, požadované důkazy a časová razítka svých přechodů. Nemá pole status. Status se odvozuje:

flowchart TD
  d7_I["issues: depends_on, timestamps, evidence_required, evidence covers"] --> d7_S["status per issue"]
  d7_S --> d7_W["waves: Kahn layering of the dependency DAG"]
  d7_W --> d7_C["scope_conflict warnings: same wave, shared paths"]
  d7_M["milestones: required issues, milestone dependencies"] --> d7_MS["milestone status"]
  d7_S --> d7_MS
  d7_MS --> d7_N["active milestone and next issue"]
  d7_N --> d7_P["docs/PLAN_STATUS.md, plan capabilities, Cockpit, site"]

Úkol je hotov, když není zrušen, má čas dokončení a každý vyžadovaný token důkazů je pokryt; jinak je prvním z verify, active, blocked nebo ready, který jeho časová razítka a závislosti dovolují. Stav před jeho blokátory se hlásí jako předčasné provedení. Úkoly na cyklu nebo za ním nedostanou žádnou vlnu a hlásí se. Milník blokovaný svou závislostí blokuje své úkoly.

Motorem je lib/project.awk; apps/majordomus-cli/src/plan.rs je druhý čtenář držený na bajtové shodě pomocí test/cases/99_plan_capabilities.sh. Jediná zapisující schopnost, plan.transition, přesune úkol, jen když to odvozený plán dovolí, a odmítne jej označit za hotový, když by simulovaný plán po přesunu hotový neodvodil. Neexistuje žádný zastaralý druhý stav k údržbě: stav je funkcí záznamů.

Nástěnka peerů, překryv a mesh

Tři věci se snadno pletou: kdo jiný právě teď v tomto repozitáři pracuje, zda jeho práce koliduje s mou a které instance Majordomu existují v síti.

Nástěnka: co dělají peeři

Sdílený server každého checkoutu drží v paměti nástěnku peerů (apps/majordomus-cli/src/peers.rs). Klient MCP, který se připojí, se stane peerem s id pozice, jménem klienta, transportem, časem připojení a poslední aktivitou. Pomocí majordomus_announce uvede záměr a rozsah, volitelně pod názvem claimu, a nové oznámení pod stejným názvem tento claim nahradí. Nástěnka se neperzistuje: odešlý peer, který něco oznámil, je uchován jako nepřipojený, až do RETAINED odešlých slotů (apps/majordomus-cli/src/peers.rs), a ten, který nikdy nic neoznámil, zmizí.

majordomus_peers sbírá nástěnku v rámci repozitáře (ADR 0044): čte nástěnku tohoto checkoutu z paměti a ptá se serveru každého sesterského worktree přes HTTP, jedním skokem, a každého peera označí checkoutem, z něhož pochází. complete: false znamená, že nástěnku nešlo přečíst, a boards říká které a proč — krátká nástěnka není důkazem, že tam nikdo není.

Překryv: odvozeno, doporučující

Překryv se odvozuje z tvrzení, nikdy se nedeklaruje. Dva rozsahy se potkají, když jsou stejné nebo když jeden obsahuje druhý na hranici cesty. Počítá se na třech místech:

KdePorovnáváVýsledek
peers.announce a peers.listohlášené rozsahy na nástěnceseznam překryvů; informativní
majordomus start a check --overlap (lib/start.sh)aktivní rozsahy úloh jiných worktreesnálezy INFO; vždy exit 0
majordomus contextnároky na nástěnce vůči rozsahu aktivní úlohyřádek OVERLAP: „claim není zámek“

Žádné z nich nic neodmítá. Překryv v době oznámení porovnává jen vlastní nástěnku oznamujícího checkoutu; porovnání napříč repozitářem se dělá při sběru nástěnky, pomocí peers.list a briefingu context. Na jednom stroji odmítá doktrína rozsahu: soubory, které úloha změnila mimo svůj rozsah, neprojdou check a dokončeným finish, a finish --check běží z pre-push hooku. scripts/collision-check porovnává nesloučené lokální a vzdálené větve na cesty, které obě přidávají s různým obsahem, a kontrola collision-check takovou kolizi u pull requestu odmítne (exit 11), pokud není označena jako přijatá. Napříč stroji je claim převzatý přes mesh.claim ve výchozím stavu exkluzivní a je odmítnut s claim_conflict, když narazí na živý exkluzivní claim jiné relace — mezi claimy ten, který je víc než povědomí (viz Mesh: kdo existuje).

flowchart LR
  d8_A["worker A: task scope, announced claim"] --> d8_B["board in A's server"]
  d8_C["worker B in another worktree"] --> d8_D["board in B's server"]
  d8_B --> d8_G["peers.list gathers every checkout's board"]
  d8_D --> d8_G
  d8_G --> d8_O["overlap: scopes equal or nested"]
  d8_O --> d8_V["CLI context, MCP peers, Cockpit"]
  d8_T["task scope in current.yaml"] --> d8_SC["scope doctrine at check, finish, pre-push"]

Mesh: kdo existuje

Mesh odpovídá na jinou otázku: které uzly Majordomus existují a lze je zastihnout (docs/MESH.md, apps/majordomus-cli/src/mesh/). Uzel má identitu Ed25519 vedenou na uživatele; instance je jeden běh procesu. Poskytovatelé objevování posílají jednu podepsanou, omezenou obálku přes UDP multicast, UDP broadcast nebo HTTP rendezvous endpoint a deklarace může jmenovat statické seedy spolupráce. Registr drží uzly podle identity s presence TTL a retenčním oknem; důvěra je deny-unknown; uzly označuje a rozhoduje, které se smějí propojit a replikovat žurnál, a nedává žádná práva provádění.

PoleDruh stavu
identita uzlu (digest veřejného klíče)trvalé, na uživatele
instance, adresa, naposledy viděnopozorováno; vyprší
štítek důvěryautorská politika aplikovaná na pozorování

Repozitář bez deklarace meshe, nebo s deklarací enabled: false, neotevře žádný objevovací socket a kostra, ze které nový repozitář začíná, žádný nedodává. Vlastní deklarace tohoto repozitáře, .ai/repo/mesh/majordomus.yaml, je zapnutá: multicast na lokálním segmentu, rendezvous huby na soukromé síti vlastníka a tailnetu a důvěryhodné klíče, které vypisuje (docs/MESH.md, „Mesh tohoto repozitáře“). Neexistuje poskytovatel Tailscale ani mDNS; ADR 0050 je uvádí jako budoucí poskytovatele a rendezvous koncový bod dosažitelný přes tailnet je podporovaný způsob, jak spojit stroje. Tok dat je stejný jako u každého jiného povrchu: schopnosti mesh.status a mesh.nodes, obsluhované přes HTTP a MCP a vykreslené na /cockpit/mesh.

Nástěnka se promítá do meshe. Nástěnka stále sbírá checkouty jednoho stroje přes soubory zápůjček a to zůstává pohledem místním ke stroji. Nad objevováním kooperace propojuje runtimy jednoho repozitáře — jeden server na checkout, na tomto stroji nebo jiném — přes ověřená spojení (ADR 0067): při každém tepu se relace nástěnky runtime stávají relacemi meshe a jejich oznámení poradními nároky, v jednom podepsaném žurnálu, který každý propojený runtime replikuje a sloučí stejně. Takže nástěnka peerů a nároky se replikují napříč runtimy; spojení potřebuje povolený mesh a důvěryhodný klíč. Žurnál je podepsaná posloupnost na proud s hodinami Lamport (apps/majordomus-cli/src/mesh/journal.rs) nesoucí události relací, nároků, předávek a review a jeho stav je čisté sloučení (mesh::state::fold): oznámení nástěnky se stane poradním nárokem meshe, zatímco nárok převzatý přes mesh.claim je výhradní a při konfliktu se odmítne. Při rozdělení sítě mohou nárokovat obě strany; sloučení vybere nejnižší hodiny Lamport, pak proud, pak posloupnost a poraženého označí conflicted — nároky nejsou linearizovatelné a docs/MESH.md to říká. Registr uzlů a tabulka spojení žijí v paměti a umírají s procesem; soubor identity a žurnál přetrvávají a znovu načtený žurnál obnoví události, ale ne čerstvost. Stabilita modulu je experimentální. Mesh agenty neorchestruje.

Mapa mesh

flowchart TD
  m_M["machine"] --> m_N["node: Ed25519 identity per user and machine"]
  m_N --> m_R["runtime: one per checkout's shared server"]
  m_R --> m_B["board: attached MCP peers and their announcements, in memory"]
  m_R --> m_S["mesh sessions in the signed journal"]
  m_B -->|every heartbeat| m_AC["advisory mesh claims"]
  m_S --> m_EC["exclusive claims via mesh.claim"]
  m_AC --> m_SC["scopes"]
  m_EC --> m_SC
  m_SC --> m_O["overlap: equal or nested paths, reported"]
  m_EC -->|meets a live exclusive claim| m_CC["claim_conflict: refused"]

Přítomnost, spojení a nástěnka se pozorují a vyprší; identita a žurnál trvají; překryv se odvozuje z tvrzení a hlásí se; odmítne se jedině výhradní mesh tvrzení.

Prostředí repozitáře

RepositoryEnvironment (apps/majordomus-cli/src/environment/mod.rs) je jeden typovaný snímek toho, čím checkout je: projekt, repozitář, správa verzí, toolchainy, vrstva, workflow, projekce poskytovatelů, lokální služby a diagnostika, se záznamem původu u každé hodnoty (docs/ENVIRONMENT.md). Rozřeší se rychle z cache pod .ai/local/ nebo plně z indexu.

Model je architektura; banner je jeden jeho renderer. Stejná hodnota se vykresluje jako banner shellu přes direnv (environment/render.rs), jako text a JSON majordomus-cli env, jako GET /api/v1/environment, jako zdroj MCP majordomus://environment a vysvětluje ji environment.explain. Lokální služba se pozoruje jediným omezeným TCP spojením, které dokazuje, že port odpovídá, a nic víc.

Publikace a verze

Od merge k veřejné stránce

flowchart TD
  d9_M["merge to master"] --> d9_B["scripts/pages build: refuse stale source hash, render without regenerating"]
  d9_B --> d9_K["scripts/pages check: site-check and the never-published check"]
  d9_K --> d9_P["scripts/site-deploy pushes site/public to gh-pages"]
  d9_P --> d9_V["scripts/pages verify --commit SHA: poll majordomus.dev/build.json"]
  d9_V --> d9_G["pages-live gate: served commit is on master, nothing owed past the window"]

Publikační cesta (.github/workflows/pages.yml, modelovaná v .ai/repo/ci/pages.yaml) nic nepřegenerovává: commitnuté projekce jsou už zkontrolovány, takže publikace je vykresluje. Tři fakty se drží zvlášť, protože selhávají zvlášť: build uspěl, nasazení bylo pushnuto a veřejný web servíruje nový commit. Jen poslední se ověřuje proti veřejnému endpointu — build.json na majordomus.dev nese commit, ze kterého byl postaven. V jobu nasazení je toto ověření (scripts/pages verify --commit … --smoke) poradní: krok může selhat, aniž by selhal job, a job hlásí „pushed“ a „serving“ jako samostatné fakty. Rozhoduje kontrola pages-live, spouštěná při finish, která ověřuje, že servírovaný commit je na masteru a že žádná publikace není dlužna déle než okno nasazení (share/standard/majordomus/rules/publication-currency.v1.md).

Verze se píše jednou

Verze se píše na jednom místě, v [package] version manifestu crate, a zapisuje ji jeden příkaz, majordomus-cli release bump (apps/majordomus-cli/src/release/version.rs), který také udržuje v souladu vlastní položku lockfilu a čte obojí zpět. Shellový nástroj žádnou verzi neuvádí: čte share/version.txt, generovanou projekci manifestu, která se dodává vedle něj (ADR 0085), a release::version::diagnose odmítne verzi napsanou ručně kdekoli, kde žijí soubory nástroje — kontrola version-authored-once. Minimální zvýšení se měří, ne volí: release analyze porovnává veřejný povrch schopností — id, expozice a schémata, s kompatibilitou vstupu a výstupu posuzovanou v opačných směrech — s posledním release (ADR 0051). Conventional commity jsou důkaz, ne autorita. Stejná analýza je GET /api/v1/release/analysis, nástroj MCP a /cockpit/release. Po zvýšení just derive přepíše share/version.txt, každé razítko generátoru, changelog, docs/INSTALL.md a data verze webu.

Tag spustí workflow releasu: sestaví matici platforem z docs/generated/distribution-matrix.json, publikuje, zapíše záznam releasu pod .ai/repo/releases/ ze skutečných otisků artefaktů, otevře s ním pull request a po dosažení záznamu na výchozí větvi otestuje veřejný instalátor smoke testem.

Co doctor kontroluje

majordomus doctor je jen pro čtení a dispečuje každou doktrínu, která je na něj navázána (lib/doctor.sh). Mezi nimi: vendorovaný balík pravidel proti hashům manifestu; řetěz zapojení doktríny od validátoru přes dispečink a propagaci selhání po test, tvrzení a CI; instrukční soubory poskytovatelů proti jejich generačním razítkům (bez razítka nebo ručně upravené selže); zapojení každého vynucovacího záznamu v politice, včetně odvozovací kontroly v pre-commitu; integrita schémat, rozložení, rozpočty, retence, DAG pravidel, ADR, dovednosti a prompty. Rustové health.report přidává porovnání commitnutého registru s vykreslením v procesu.

Doctor odhaluje, neopravuje. Regenerace je majordomus generate a just derive; oprava ručně upravené projekce poskytovatele je majordomus update --diff <target> a poté --force — prosté update odmítne přepsat ruční úpravu. Generátor se neopravuje sám jen proto, že existuje: regenerace běží bez dozoru pouze ve workflow verzí a releasů, které otevírají pull requesty, a nic neopravuje na místě.

Kruhový dogfooding

Majordomus je supervizován Majordomem. Pravidla, která zakazují ručně vedené registry, jsou pravidla ve vlastním .ai/ tohoto repozitáře; důkazní engine, který říká, zda jsou vynucována, čte kontroly tohoto repozitáře; generátory, které píšou referenci, jsou kontrolovány kontrolami, které tato pravidla jmenují; ledger důkazů může zaznamenat běhy testů, které dokazují determinismus generátorů (dnes jich žádný nedrží: jq -r '.executions[].test' .ai/repo/evidence/ledger.json); a Cockpit vykresluje tento důkaz ze stejného registru, který dokazuje. Když se generátor rozbije, kontrola, kterou jmenuje pravidlo o generátorech, selže v CI a samo pravidlo se čte failing až poté, co je ten běh zaznamenán. Smyčka je silná jen jako její nejslabší zaznamenaný článek — dnes zaznamenávání provádění — a proto je ten článek níže jmenován.

Co se negeneruje

Majordomus generuje mechanické projekce. Negeneruje lidský úsudek, aby ho pak potichu nazval kanonickou pravdou.

Píší lidé, nikdy se negenerujeOdvozeno strojem z toho
záměr: proč milník existuje, co znamená hotovostav, vlny, připravenost
rozhodnutí a jeho kompromisy v ADRzáznam ADR v indexu, odkazy z pravidel a souborů
přijetí rozhodnutínic: extrahované ADR se nesmí nazývat přijatým
znění pravidla a proč existujejejí režim, kontroly, stav důkazů, povrchy
tvrzení o tom, co nástroj zaručujejeho stav důkazů
vysvětlující próza, včetně tohoto dokumentujeho stránka na webu, odkazy, pořadí a popis
cíl a další akce předávkyjeho repozitář, větev, hlava a změněné soubory

Pokud člověk zaznamená OAuth musí používat PKCE, stroj smí odvodit pravidla, kterých se to dotýká, kontext, který to má nést, odkazy z dokumentace a zda je implementace testována. Nesmí rozhodnutí přepsat proto, že heuristika usoudila, že je nepravděpodobné. Odvození v kompilátoru kontextu je zastropováno pod přímou deklarací právě z toho důvodu.

Matice generování

EntitaNapsánoObjevenoOdvozenoCLIHTTPMCPCockpitWeb
schopnostcapability!skládání modulůdostupnost, viditelnost, provádění, měření výkonukaždý přes run <id>; vyhrazený příkaz tam, kde ho vykresluje příkaz clapano, když je vystavenonástroj nebo zdroj, pokud je vystavenexplorer a runnerstránky /registry/
commandstrom clap, share/commands.yamlrecepty justgraf příkazů, completionanopřes svou schopnostpřes svou schopnost/cockpit/commands/docs/cli/, /commands/
objekt dokumentujakýkoli indexovaný souborsources.yamlURI, druhentity kinds, entity show; shell search; run objects.list/api/v1/objects, /api/v1/entity*zdrojstránka objektujen druhy s projekcí
pravidlosoubor pravidlaindexrežim, kontroly, stav důkazurules report, rules show/api/v1/rulesmajordomus_rules, majordomus_rulestránka objektu, runner/rules/<id>-<version>/ pro každé platné pravidlo; /doctrines/ pro doktríny
doktrínapravidlo s validátoremloader doktrínregistr doktrínshell doctrinepřes pravidlapřes pravidlapřes pravidla/doctrines/
claimdocs/CLAIMS.yaml, docs/claims/indexstav důkazuevidence claimkoncové body důkazůnástroje důkazůstránka objektu, runner/guarantees/
ADRsoubor ADRindexžádnéentity showobjektyzdrojstránka objektu/adrs/adr-NNNN/, jedna generovaná stránka na rozhodnutí
úkol, milníkYAMLindexstatus, waves, nextshell plan; plánovací schopnosti v Rustu pouze přes run plan.<op>/api/v1/plan/*, POST /api/v1/plan/transitionmajordomus_plan*pouze runner, žádná stránka plánu/plan/, plán rozvoje, graf závislostí
peer (pozorováno: připojení a ohlášení)oznámeníPřipojení MCPpřekryvyrun peers.list; sekce shellu context; oznámení vyžaduje relaci MCP/api/v1/peers; POST /api/v1/peers/announce existuje, ale bez relace MCP odmítámajordomus_peers, majordomus_announce/cockpit/peersžádné
uzel meshe (pozorováno: přítomnost), claim meshedeklarace meshe; mesh.claimposkytovatelé, odkazypřítomnost, štítek důvěry, sloučený stav žurnálumajordomus-cli mesh/api/v1/mesh/*majordomus_mesh*/cockpit/meshžádné
prostředípolitika, manifestgit, toolchainy, službysnapshot s provenancíenv/api/v1/environmentmajordomus://environmentne na přehledužádné
design tokenshare/design/tokens.yamlžádnéstylesheety, logo, designová datažádnéreport designudesignové nástroje/cockpit/design, veškeré stylováníveškeré stylování
verze[package] version manifestu crate, zapsané pomocí release bumpposlední záznam o releaseminimální bumprelease analyze/api/v1/release/analysisnástroj pro release/cockpit/releasechangelog, instalace

Architektonický dluh

Kde repozitář ještě není modelem, který tento dokument popisuje, měřeno na výchozí větvi. Ne všechny povrchy tyto mezery samy zveřejňují; jsou zde vypsány, aby je čtenář nemusel hledat.

Deklarováno dvakrát nebo registrováno ručně

  • Příkazový řádek je druhá deklarace v clap, kontrolovaná uzavřením a paritou, ale negenerovaná; cesta příkazu se také opakuje jako slova, která jeho modul předává by_cli, a pomocná funkce, která to dělá, je zkopírována do několika modulů příkazů. Textové renderery a spustitelné příklady se píší ručně.
  • Přidání modulu schopností upraví seznam pub mod a jediné volání compose_modules!.
  • Oblasti Cockpitu, statické trasy a dispatcher jsou psány ručně a testy je drží shodné, nejsou odvozeny; komentář modulu v cockpit/nav.rs pojmenovává méně oblastí, než servíruje.
  • Seznam cílů příkazové řádky majordomus generate je druhý výčet vedle vlastního výčtu generátoru a chybí mu jeden z jeho cílů, který proto běží jen pod all.
  • Nástroj shellu drží vlastní dispatch tabulku vedle share/commands.yaml a rules, skills, evidence, knowledge a bench existují v obou programech s různými významy.
  • Dva seznamy povolených, share/allow/commands.txt a share/allow/events.txt, jsou psané ručně; žádný generátor je zatím neodvozuje.
  • Můstek MCP má pro nástroj announce zvláštní případ při přehrání po opětovném připojení.
  • docs/HARDCODING_LEDGER.yaml uvádí místa, kde je fakt zapsán dvakrát a která byla založena, s příkazem, který každé reprodukuje; několik otevřených položek zůstává a několik duplikací pojmenovaných v této sekci tam zatím není. Tabulka povrchů v docs/WEB.md je jednou z nich svým duchem: psaná ručně a nekontrolovaná žádným testem.

Odvozeno, ale ne věrně

  • Anotace MCP nástrojů: nápovědy destructive a idempotent jsou stejné pro každý nástroj, včetně těch, které zapisují do repozitáře; jen nápověda read-only se řídí deklarací.
  • OpenAPI připojuje odpověď 422 refused pouze k příkazům, ačkoli některé dotazy odmítají.
  • Diagram pipeline na stránce architektury webu je pevná posloupnost zapsaná v generátoru a vynechává vlastní generační fáze spustitelného souboru.
  • Vztah doktríny k principu je obyčejné depends_on; žádné typované pole neexistuje. Odkazy pravidlo-tvrzení existují jen u vendorovaných doktrín; tvrzení na pravidla nezpět neodkazují.
  • Členové souboru kolekce (tvrzení, příkazy, taxonomie případů užití) se indexují bez kontroly schématem na člena, jíž prochází každý jiný objekt.

Není zpřístupněno všude

  • Žádné stránky Cockpitu podle druhu pro pravidla, doktríny, ADR nebo tvrzení — obsluhuje je generická stránka objektu. Žádná stránka plánu v Cockpitu a přehled ukazuje preflight, ale ne snapshot prostředí.
  • Nástěnka peerů nemá vlastní příkaz — čte ji run peers.list — a pro oznamování je potřeba relace MCP.
  • Příkazy životního cyklu v shellu (start, check, finish, handover, context) nejsou schopnosti, takže nemají projekci HTTP ani MCP; continuity.state je jejich čtecí model.
  • Hooky relace jsou adaptovány jen pro Claude Code; ostatní poskytovatelé své deklarují a jsou neadaptovaní (share/providers.yaml, lib/capture.sh).
  • Prostředky Swagger UI pocházejí z CDN.

Bez důkazů

  • Běhy se do registru zapisují jen pomocí evidence record; CI spouští každou kontrolu, ale své běhy zpět nezapisuje, takže většina pravidel a tvrzení se čte jako not_run místo proven a web publikuje deklarované a podporované počty vedle sebe, aby to řekl.
  • Deklarativní pravidla nejmenují žádný důkaz a stojí na unproven; jsou poradní, takže nejsou zjištěními. Revidovaná pravidla vynucuje člověk a nepočítají se jako strojově vynucená.

Nevynucováno, jak je zdokumentováno

  • project.derived-files-regenerated říká, že scripts/derive-check běží v CI a ve workflow Pages; běží jen ve workflow zvýšení verze a release, zatímco kontrola pull requestu spouští své poloviny odděleně. Polovina pre-commit porovnává hash vstupu a porovnání registru přeskočí, není-li sestaven spustitelný soubor.
  • Sonda obsluhy nasazení je uvnitř jobu nasazení jen poradní; jakmile uvidí commit, publikovaná dokumentace a rustdoc se ověří a job selže, stejně jako při chybě sestavení GitHub Pages, a kontrola pages-live při dokončení posoudí, zda je publikace aktuální.
  • project.no-counts-in-prose je mechanizováno pro vždy načítaný kontext poskytovatele (doctor) a pás důkazů na domovské stránce (homepage-check); u dokumentů se vynucuje revizí.
  • evidence.record zapisuje commitnutý ledger, ale deklaruje efekt process_state, takže seznam zapisovatelů do repozitáře odvozený z efektů (instrukce MCP, x-majordomus-effect) ho vynechává.

Nesestaveno, nebo sestaveno částečně

  • Poskytovatelé discovery Tailscale a mDNS; NAT traversal a spoje širokého dosahu. Spolupráce mezi stroji existuje přes rendezvous endpointy a důvěryhodné klíče, je experimentální a její provoz na více strojích se opírá o zaznamenaný ruční běh (docs/MESH.md).
  • Rustová strana životního cyklu relace je čtecí model; přechod je navržen.
  • Záznam záměru je částečně adoptován (ADR 0070): .ai/repo/project/intents/ drží záznamy, které čtou intent validate a intent preflight; úloha se k nim váže při start a je z nich briefována (ADR 0111) a žádná politika dokončení je nespotřebovává.
  • Verzi lze deklarovat dříve, než je vydána: verze crate a nejnovější záznam o release jsou samostatné skutečnosti; navigační lišta uvádí release a changelog zobrazuje nevydanou verzi nad ním.
  • Mnohá ADR, která kód už dodržuje, zůstávají proposed, protože přijetí je aktem člověka.

Audit tvrzení

Každé silné tvrzení v tomto dokumentu s tím, jak ho ověřit.

VýrokKontrola
HTTP, OpenAPI, MCP a runner Cockpitu nepotřebují žádný kód na schopnostčtěte Router::capability v apps/majordomus-cli/src/http/router.rs a mcp/surface.rs; grep -rn '"rules.show"' apps/majordomus-cli/src najde jen deklaraci a testy
OpenAPI se odvozuje z registru, který obsluhuje požadavkyapps/majordomus-cli/src/http/openapi.rs; bin/majordomus-cli generate --check
každá projekce má deklaraci a naopakcargo test --test projections v apps/majordomus-cli
příkazová řádka je kontrolovaná druhá deklaraceapps/majordomus-cli/src/capability/closure.rs, apps/majordomus-cli/src/cli/local.rs, scripts/ci/projection-check
doktrína je pravidlo s validátoremlib/doctrine.sh; bin/majordomus doctrine list
režim vynucování se odvozuje, nedeklarujeADR 0048; rule.v1.proto nemá pole mode
selhávající test činí pravidlo selhávajícím; jinak je jeho stav nejslabší z testů, které mohou nést důkazapps/majordomus-cli/src/rules/mod.rs, apps/majordomus-cli/src/evidence/freshness.rs; bin/majordomus-cli rules report
stav úkolu se odvozuje bez uloženého stavuYAML úkolu nemá klíč status; lib/project.awk; bin/majordomus plan status
překryv je jen poradnílib/check.sh vrací 0 po --overlap; peers.rs dokumentuje informativní překryvy
mesh je ve výchozím stavu vypnutý a nemá poskytovatele Tailscalels share/skeleton/ai/repo nemá mesh/; ls apps/majordomus-cli/src/mesh
tento repozitář provozuje vlastní mesh a důvěřuje klíčům, které jeho deklarace vypisuje.ai/repo/mesh/majordomus.yaml; test/cases/491_the_mesh_is_on_here.sh
nástěnka je jen v pamětikomentář modulu apps/majordomus-cli/src/peers.rs
publikace se ověřuje proti veřejnému endpointuscripts/pages verify; curl -s https://majordomus.dev/build.json
verze se píše na jednom místě a promítá se pro shellový nástrojapps/majordomus-cli/src/release/version.rs; share/version.txt; scripts/ci/release-check; kontrola version-authored-once

Pětadvacet otázek, zodpovězeno

Otázky, na které by měl technický čtenář po přečtení tohoto dokumentu umět odpovědět, každá s místem, které odpovídá.

OtázkaOdpověď
Odkud se bere příkaz?Varianta clap v apps/majordomus-cli/src/cli.rs (Rust) nebo případ v bin/majordomus s jeho řádkem v share/commands.yaml (shell); a pro každou schopnost generický majordomus-cli run <id>. Příkazová řádka
Registruje se ručně, nebo se odvozuje?Vyhrazený příkaz ručně, jako kontrolovaná druhá deklarace — uzavřenost a parita selžou na stromu, který s registrem nesouhlasí; run <id> je odvozeno. Stejná sekce
Odkud pochází trasa HTTP?HttpExposure schopnosti; router se ptá registru při každém požadavku. HTTP
Jak se OpenAPI vytváří?Projito z registru přes http/openapi.rs, schémata z Rustových typů. OpenAPI
Jak souvisí Swagger UI s API?Vykresluje /openapi.json a nedrží nic vlastního. Swagger UI
Jak získá stejnou schopnost AI pracovník?Jako nástroj nebo zdroj MCP, který jeho expozice jmenuje, přes téhož executora. MCP
Jak to člověk uvidí v Cockpitu?Generická stránka schopnosti a runner, formulář ze vstupního schématu. Cockpit
Jak se dělá navigace Cockpitu?Oblasti a trasy se píší; katalogy v nich se odvozují. Trasy, navigace a pořadí
Odkud pocházejí stránky pravidel a doktrín?Index a registr doktríny přes scripts/generate-site-data: /rules/, /doctrines/, /adrs/; stránka objektu v Cockpitu. Dokumentace a web
Jak souvisí doktrína s pravidly?Doktrína je pravidlo, jehož blok jmenuje validátor; principy jsou pravidla, na nichž závisí. Správa
Jak souvisí pravidlo se svým validátorem?Jmenuje ho její blok x-majordomus a režim se odvozuje z toho, co je jmenováno. Správa, pod „Tvar pravidla“
Jak se validátor vztahuje k důkazům?Běh se zaznamenává do knihy s commitem a digestem a posuzuje se proti stromu. Důkazy
Jak poznáte, že je pravidlo vynucováno?Jeho příčka na žebříku důkazů a jeho stav v rules report. Existence pravidla neznamená, že se vynucuje
Jak se detekuje drift mezi projekcemi?Bajtové porovnání commitnutého a znovu vygenerovaného výstupu a testy projekcí oběma směry. Jak se předchází driftu
Jak funguje objevování?Druhy a zdrojové třídy jsou deklarace; sledované soubory gitu se vůči nim porovnávají. Objevování
Jak fungují typované registry?Index objektů pro dokumenty, registr schopností pro operace, validované celé. Registr
Co je kanonické, odvozené, pozorované, vyvozené?Šest druhů stavu
Jak vzniká kontext relace?Seřazené oddíly vměstnané do rozpočtu, každé zahození pojmenováno. Kontext pro relaci
Jak se dělá předávka?Psané tělo s odvozeným front matterem, vyřešené podle worktree a větve. Předávka
Jak se odvozují vlny provádění?Kahnovo vrstvení grafu závislostí úkolů. Plánování
Jak funguje objevování peerů a meshe?Nástěnka přes připojení MCP a soubory lease; uzly přes podepsané datagramy a rendezvous. Nástěnka peerů, překryv a mesh
Jak se data meshe dostávají na povrchy?Přes schopnosti mesh.* a peers.* přes HTTP, MCP, Cockpit a run, jako všechno ostatní. Mesh: kdo existuje
Jak se odvozuje kolize rozsahů?Rozsahy porovnané jako shodné nebo vnořené cesty; hlásí se a odmítají jen pro výlučný claim mesh. Překryv
Jak se nová schopnost dostane na povrchy?Co se stane, když se přidá schopnost
Kde jsou výjimky?Architektonický dluh

Proč na tom záleží

flowchart LR
  d10_W["more workers"] --> d10_D["more descriptions of the repository"]
  d10_S["more interfaces"] --> d10_D
  d10_MD["more metadata"] --> d10_D
  d10_D --> d10_X["more drift, faster"]
  d10_ONE["one model"] --> d10_P1["command line"]
  d10_ONE --> d10_P2["MCP"]
  d10_ONE --> d10_P3["HTTP and OpenAPI"]
  d10_ONE --> d10_P4["Cockpit"]
  d10_ONE --> d10_P5["docs and site"]

Majordomus není sbírka příkazů, dashboardů a integrací agentů. Je to model nativní pro repozitář, z něhož se tyto povrchy odvozují.

Příkazová řádka, HTTP API, MCP, OpenAPI, Swagger UI, Cockpit a dokumentace mají být projekcemi jedné typované reality repozitáře — a tam, kde je některé z nich stále psáno ručně, ho k té realitě drží kontrola a tento dokument jej jmenuje.

Pravidla a doktríny nejsou cenné proto, že jsou napsané. Cennými se stanou, když je jejich vztah k validátorům, kontrolám, provedením a důkazům strojově zkoumatelný — a když povrchy říkají not run místo zeleného odznaku, dokud není zaznamenán běh.

Nástěnka peerů a mesh nejsou orchestrace agentů. Činí workery, jejich přítomnost a jejich claimy dostatečně viditelnými, aby o nich mohli uvažovat lidé a koordinační mechanismy.

Generování a odvozování jsou způsob, jímž se Majordomus snaží zabránit tomu, aby repozitář pomalu nashromáždil sedm neslučitelných popisů sebe sama.

Prohledává názvy a popisy všech stránek, které tento web publikuje.