Zdůvodnění
Vygenerovaný strom, který je jen JSON, je strom, který přečte jen program; vygenerovaný strom, jehož soubory o sobě nic neříkají, je strom, který člověk upraví omylem. Toto repozitář mělo obě selhání najednou: některé artefakty nesly banner „neupravuj“ a jiné ne, registry.json pojmenovával schéma, které splňuje, a cli.json ne, matice měření existovala pro čtenáře, a ne pro program, žádný artefakt nebyl psán v YAML a nikde žádný soubor neříkal, co množina vygenerovaných souborů je — jediná cesta, jak to zjistit, bylo přečíst generátor.
Každá z těch věcí je stejná vada: generátor o svém výstupu věděl věci, které jeho výstup nenesl. Typování artefaktu ji uzavírá. Kódování je vlastnost souboru, kontrakt je vlastnost dokumentu a obojí patří do deklarace, ne do hlavy čtenáře.
Druhá polovina pravidla je důvod, proč se kódování nemohou rozejít. Dokument je jedna hodnota. JSON, YAML a — kde je publikem čtenář — Markdown jsou její vykreslení. Dva renderery nad dvěma hodnotami jsou způsob, jak se matice v Markdownu dostane do rozporu s toutéž maticí v JSON, a tento repozitář takový tvar odmítá všude jinde (project.interfaces-are-projections@1).
Požadované chování
Každý artefakt majordomus generate deklaruje:
- dokument, který promítá, sdílený každým kódováním tohoto dokumentu;
- kódování, ve kterém je zapsán —
json,yaml,markdownnebotext— odpovídající příponě jeho vlastního souboru; - schéma, které jeho obsah splňuje, podle id schématu, když má dokument kontrakt;
- zdroj, ze kterého byl odvozen, v jednom řádku.
Každý artefakt nese hlavičku původu ve formě, kterou jeho kódování dovoluje: členy (schema, generated, generator) v JSON, rozšíření x-majordomus-, kde specifikace samotného dokumentu pevně určuje názvy členů, banner komentáře # v YAML a v textu orientovaném na řádky, komentář HTML v Markdownu. Jedinou výjimkou je bootstrap providera, který nese razítko majordomus update politiky, z níž byl vykreslen, a kontroluje jej tento příkaz.
Strukturovaný dokument se zapisuje v každém kódování, v němž ho tento repozitář commituje, z jedné hodnoty: JSON a YAML dokumentu jsou dvě vykreslení téže generate::Document, nikdy dva výpočty. Dokument, jehož publikum zahrnuje čtenáře, má také vykreslení v Markdownu téže hodnoty.
Dokument, který uvádí id schématu, má pod share/schemas/generated/<name>.schema.json zveřejněnou smlouvu, připnutou k dokumentu členem const jeho schema, a splňuje ji.
Celou sadu indexuje docs/generated/artifacts.{json,yaml,md}, který je sám generovaný: uvádí každý artefakt plánu s jeho kódováním, kontraktem, zdrojem, velikostí a hashem. Jeho vlastní tři kódování hash nenesou — dokument, který by hashoval sám sebe, by neměl pevný bod — a místo toho je bajt po bajtu porovnává generate --check.
Chování při selhání
majordomus generate a majordomus generate --check ověří plán dřív, než se zapíše nebo porovná jediný bajt, a odmítnou s exit 10 se jmenováním každého artefaktu a každého důvodu. Plán, který porušuje kteroukoli klauzuli výše, se nikdy nezapíše: generate nevytvoří napůl otypovaný strom a pak to nenahlásí.
Ověření
majordomus generate --check, který CI a scripts/derive-check spouštějí při každém pushi a kterého dosáhnou i capabilities validate a health.report. apps/majordomus-cli/tests/generated_documents.rs dokazuje každou klauzuli nad skutečným plánem a dokazuje odmítnutí každé porušené klauzule, takže žádná nemůže projít naprázdno; apps/majordomus-cli/tests/cockpit.rs dokazuje čtecí polovinu — artifacts.list, GET /api/v1/artifacts, nástroj MCP majordomus_artifacts a stránka Cockpitu — hlásí stejnou množinu a označí upravený soubor jako zastaralý; test/cases/52_generated_artifact_typing.sh dokazuje, že commitnutý strom tohoto repozitáře pravidlo splňuje a že kódování YAML se zparsují jako YAML a rovnají se svým sourozencům v JSON.