20. Graf schopností se skládá, ne centralizuje, a promítá se dvakrát
Kontext
ADR 0012 rozhodlo, jak Cockpit vykresluje: je projekcí registru, rozvržen z toho, co schopnost odpověděla, a nedrží žádný vlastní inventář. ADR 0013 rozhodlo, jak se povrchy servírují: každý se objevuje u producenta, který ho vlastní, a řeší se jednou. Obě rozhodnutí jsou o strojovně. Žádné neříká, čeho je obraz obrazem.
Ta otázka zůstala s odpovědí, kterou nikdo nezvolil. Program zná schopnosti z registru a objekty z indexu a každé odvození grafu čte jednu stranu: graf registru kreslí moduly a jejich schopnosti, graf vrstvy kreslí adresáře a druhy, graf pravidel kreslí závislosti pravidel, graf rozhodnutí kreslí, co rozhodnutí uvedlo v platnost. Všechno, co vrstva drží a co není schopnost — pravidla, dovednosti, rozhodnutí, dokumenty, případy užití, měření výkonu a po práci na nasazení nasazení — stojí vedle schopností a je s nimi spojeno jen v hlavě čtenáře.
Selháním, které to vyvolá, není, že stránka vypadá řídce. Je to, že schopnost bez dokumentace, bez testu a bez vynucování je na každém povrchu nerozlišitelná od schopnosti, která má všechno tři, protože nic nerozhoduje vztah mezi nimi. Repozitář už umí říct, co existuje. Neumí říct, co je dokončeno.
Samotné odkazy nikdy nechyběly. Pravidlo jmenuje, na čem závisí, rozhodnutí jmenuje, co uvedlo v platnost a co zastupuje, případ užití jmenuje příkazy, které spouští, a tvrzení, která dokládá, kontextový dokument jmenuje, co sleduje. Každé z toho je front matter se schématem a validátorem. Chyběl model, který by je četl jako jeden druh věci, a verdikt, když některý z nich jmenoval něco, co tam není.
Okamžitě se nabízejí dvě opravy a obě mají tvar, který tento repozitář už dříve odmítl. První je manifest: jeden soubor se seznamem každé schopnosti s její dokumentací, testy a pravidlem, které ji řídí. Druhá je prohlížečová aplikace, která stáhne API a obraz složí na klientovi. Ta druhá navíc náhodou rozhoduje i těžší polovinu problému, protože publikovaný web nemá za sebou žádný server: obraz složený z běžícího procesu je na statické stránce buď nepřítomný, nebo smyšlený, a čtenář nepozná který.
Rozhodnutí
Graf skládá, co každý registr vlastní; nic necentralizuje. Odvození composed čte registr schopností a index, z nichž každý zůstává autoritativní přesně pro to, pro co byl autoritativní dřív, a spojuje je do jednoho typovaného modelu. Nejmenuje žádný vlastní druh: druhy uzlů se čtou z toho, co bylo skutečně indexováno, takže druh, který vrstva získá, se v grafu objeví bez úpravy tohoto odvození. Identita objektu v grafu je jeho URI, které přežije přejmenování; popisek nikdy.
Konvence odkazů vrstvy žijí v jedné tabulce a čtou se dvakrát. RELATIONS říká, co znamená pole front matter, když ho objekt nějakého druhu deklaruje, a je to jediné místo, kde je to zapsáno. Kompozice ji čte, aby kreslila hrany; unresolved_relations čte totéž řešení jako verdikt. Neexistuje druhý názor na to, co odkaz znamená, ani způsob, jak by se kresba a kontrola mohly rozejít.
Odvozování je nad stabilními identitami a ničím jiným. Odkaz se rozlišuje přes identitu, deklarované id nebo cestu relativní k repozitáři. Nikdy se nerozlišuje přes název nebo podřetězec, protože název se upravuje pro srozumitelnost a podřetězec se shoduje náhodou. Verzovaná identita se rozlišuje svým kmenem, protože odkaz jmenuje pravidlo, ne verzi, proti níž byl napsán. Kde konvenci nelze bezpečně odvodit, odkaz se deklaruje — a tabulka následuje konvenci vrstvy, místo aby ji opravovala: první dvě zjištění, která tato kontrola na tomto repozitáři vytvořila, byla obě vady v tabulce, ne ve vrstvě, protože dovednosti jmenují své sourozence holou identitou.
Hranice a defekt jsou různé věci. Odkaz file: nebo test:, který vede z vrstvy ven, nakreslí externí uzel, což je podoba hrany ven z vrstvy. Odkaz, který jmenuje druh, který tento repozitář drží, a nevyřeší se na nic, je zjištění nesoucí soubor, klíč, odkaz a nápravu — a nekreslí se. Hrana k přízraku se vykreslí jako prázdný oddíl a prázdný oddíl se čte jako odpověď.
Definice a stav za běhu jsou oddělené typy. Graph drží definice. RuntimeState je překryv indexovaný id uzlu, který nanáší konzument, jenž má proces, na který se může zeptat. Záměrně není polem Node: uzel schopný nést stav za běhu by ho přenesl do statické projekce, kde ho nikdo nemůže obnovit a čtenář ho nerozliší od aktuální hodnoty.
Obě projekce čtou tento jeden model. Statická projekce je graf tak, jak byl generován; runtime projekce je tentýž graf s překryvem navrch. To umožňuje publikovanému webu vykreslit celou architekturu bez backendu a činí paritu mezi nimi testem místo nadějí — odeberte pole jen pro runtime a reprezentace se musí rovnat.
Dostupnost jsou metadata, ne podmínka uvnitř stránky. Zda něco znamená bez běžícího backendu, je pole modelu. Žádná projekce o tom nesmí rozhodovat podle hostname, adresy ani příznaku buildu, protože pravidlo zapsané v šabloně je pravidlo, které nikdo nenajde, když je špatně, a selhání, které způsobí, je odkaz na publikované stránce, za kterým nic není.
Prohlížeč zůstává vylepšením, přesně jak už vyžaduje ADR 0012. JavaScript přidává filtrování, pohled na relace, živý stav a vyhledávání. Není potřeba k přečtení odkazu na dokumentaci a relace jsou v servírovaném HTML dříve, než se spustí.
Zamítnuté alternativy
Jeden centrální manifest schopností, jejich dokumentace, jejich testů a jejich pravidel. Je to nejrychlejší věc k sestavení a nejsnáze čitelná a je to druhý registr, který tento repozitář pro pravidla, druhy a schopnosti už odmítá. V den napsání je správný a při prvním přejmenování, které nikdo nepropagoval, špatný, a drift je tichý, protože manifest nemůže zaznamenat, že pravidlo, které jmenuje, bylo smazáno.
Klientská aplikace, která načítá API a graf sestavuje v prohlížeči. Drží model na druhém místě, za běhu potřebuje build toolchain a první vykreslení činí závislým na JavaScriptu — to vše ADR 0012 pro Cockpit zamítlo a nic z toho se nezlepšilo. Rozhodující námitkou je publikovaný web: bez serveru, ze kterého by se dalo načítat, musí stejný kód buď nevykreslit nic, nebo vykreslit něco, co získat nemohl, a to druhé je horší než to první.
Samostatný generátor pro statickou projekci. Bylo by to rychlé a je to druhý vesmír, který tento repozitář už jednou rozebral. Generování patří do kanonické sady cílů, kde ho vidí kontrola driftu; generátor mimo ni je projekce, kterou nikdo neověřuje.
Odvozovat vztahy z titulků nebo podřetězců, aby přispěvatelé nemuseli nic deklarovat. Funguje to, dokud dva subsystémy nepojmenují něco stejně, a pak to nakreslí hranu, která je špatná, v obrázku, který vypadá autoritativně. Nejednoznačnost je deklarace, ne heuristika.
Kreslit nevyřešený odkaz jako uzel, aby graf zůstal úplný. Fantomový uzel činí nefunkční odkaz podobným hranici, což je jediný rozdíl, který tento model existuje, aby činil.
Nechat uzel nést vlastní runtime stav, přičemž statický build ho prostě nechá prázdný. Prázdné pole a zastaralé pole jsou pro čtenáře nerozlišitelné a typ by zlé jednání usnadnil.
Důsledky
Subsystém, který chce být vidět, má dvě povinnosti a žádnou třetí. Zaregistruje se v registru, který už vlastní jeho druh — schopnost v capability!, objekt pod svým kanonickým adresářem — a pojmenuje své relace ve vlastním front matteru, v polích, která schéma už deklaruje. Nic dalšího se neupravuje: ani navigace, ani přehled, ani vyhledávací index, ani graf, ani matice pokrytí.
Cena za to, že se to nedělá, je přesná a stojí za zmínku, protože to není selhání. Subsystém, který se sám zaregistruje, ale nejmenuje žádné vztahy, se objeví jako uzel bez hran: je vypsán, lze v něm hledat a matice pokrytí jej hlásí jako nedokumentovaný a netestovaný, protože nic se neřeší tak, aby říkalo opak. To je poctivá odpověď a je to důvod, proč se odvozování nerozšiřuje o hádání vztahu z názvu. Subsystém, který jmenuje vztah, jenž se neřeší, je odmítnut: generování se zastaví se souborem, klíčem a opravou, místo aby se publikovala stránka se sekcí, která nikam nevede.
Přísnost má cenu, kterou zaplatí někdo ve spěchu. Překlep v odkazu ve front matter nyní shodí build, který by dříve vykreslil mírně chybnou stránku. To je kompromis, který toto rozhodnutí činí záměrně, a zpráva je část, která musí zůstat dobrá: jmenuje deklaraci, chybějící konec a nápravu, takže selhání je oprava, ne vyšetřování.
Skládání čte index jednou do vyhledávacích tabulek, které potřebuje každý odkaz, protože řešit odkazy vrstvy skenováním objektů na odkaz je tvar, který project.hot-path-reads-once existuje zakázat. Graf roste s repozitářem, takže jeho odvození je cíl měření výkonu jako každá jiná operace a jeho cena je měřena, ne předpokládána; majordomus bench uvádí číslo, které tato próza záměrně neuvádí.
Matice pokrytí, která z těchto hran vyplyne, se při prvním běhu bude číst jako obžaloba, a není jí: je to základní měření repozitáře, který dosud nikdy neměl tento vztah vyřešen. Říct to je součástí jejího dodání.
Nic zde nezužuje ADR 0012 ani ADR 0013. Cockpit zůstává projekcí a nedrží žádný inventář; webové povrchy se dál objevují od svých producentů a rozpoznávají se jednou. Změnil se subjekt: to, co tyto povrchy promítají, je nyní jeden složený model všeho, co repozitář ví, místo několika jednostranných odvození, z nichž každé vidělo polovinu.