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.

Schopnost smí být skriptovaná a automatizace repozitáře jsou skriptované schopnosti, ne shell

Schopnost smí být skriptovaná a automatizace repozitáře jsou skriptované schopnosti, ne shell

majordomus://adr/adr-0069navrženo automatizacecapabilitiesarchitekturapřenositelnostbezpečnost

odkazuje na

odkazuje na něj

69. Schopnost smí být skriptovaná a automatizace repozitáře jsou skriptované schopnosti, ne shell

Kontext

Automatizace repozitáře žije v shellu: 122 souborů pod scripts/ (80 z nich shell, 43 ze 44 v scripts/ci/), 45 pod lib/ (38 shell), čtyři pod bin/ a 216 shellových testovacích případů. Každá opakující se třída vad, kterou si tento repozitář o sobě zaznamenal, má shellovou instanci: příznak BSD/GNU, který se na runneru chová jinak, pipeline, jejíž počet se ztratí v subshellu, kontrola, která nepřečte vlastní vzor a hlásí čisto, řazení, jehož pořadí závisí na locale stroje, soubor, který odvození neviděla, protože ještě nebyl v indexu gitu. Spustitelný soubor v Rustu mezitím už vlastní jeden registr, z něhož se odvozují příkazová řádka, API HTTP, OpenAPI, MCP a Cockpit.

Vlastník repozitáře 2026-09-15 rozhodl, že shell se má postupně nahrazovat Rhai, skriptovacím jazykem vloženým do Rustu, a že Perl nepřichází nikdy v úvahu. Tento záznam říká, čím se to stane ve slovníku tohoto repozitáře, protože zjevné čtení — „automatizační subsystém s automatizačním registrem“ — je druhý registr vedle toho, který slovník už má, a project.no-new-nouns ho odmítá.

Rozhodnutí

Schopnost může být skriptovaná. Nic dalšího se nepřidává.

docs/CONCEPTS.md už říká, že registr schopností „indexes the tool's own surface … and is derived from the layer and the code on every start“ a že schopnost, která průběžně hlásí, zavolaná jednou, je provedení. Skriptovaná schopnost je schopnost deklarovaná v souboru vrstvy místo v kódu Rustu, jejíž handler je skript Rhai místo zkompilované funkce. Index ji objeví jako každý jiný objekt vrstvy, stane se schopností v jednom registru a odtud dosáhne každého povrchu existujícími projekcemi — příkazová řádka, trasa HTTP, operace OpenAPI, nástroj MCP, generovaný formulář spouštěče v Cockpitu, generovaná reference. Přidání jedné ji nikde neregistruje.

Definice je druh. Nový druh v share/kinds.yaml s verzovaným schématem pod share/schemas/majordomus/ deklaruje skriptovanou schopnost: její id, název a popis, vstup a výstup jako JSON Schema, její efekt (read, process state, repository mutation), zda ji lze zrušit, a skript vedle ní. Skriptované schopnosti samotného repozitáře žijí pod .ai/repo/; ty, které distribuce dodává, žijí pod share/ a cestují v archivu release beze změny. Identita, validace neznámých klíčů, URI majordomus:// a zdroj MCP pocházejí z indexu, ne z vlastního loaderu.

Infrastruktura zůstává typovaný Rust. Skript se k repozitáři dostane jen přes schopnosti, jednou hostitelskou funkcí, která volá Context::execute — takže validace schématu, redakce, cache, čítače a rovina provádění platí pro každé volání skriptu přesně tak, jako platí pro volání z HTTP nebo MCP. Kde skript potřebuje něco, co žádná schopnost nenabízí (git status stromu, glob nad sledovanými soubory, spuštění programu s argumenty), odpovědí je typovaná schopnost v Rustu, ne větší skript. Žádná funkce nebere řetězec shellového příkazu. Program se spouští jménem se seznamem argumentů, pracovním adresářem, deltou prostředí a mezí.

Co smí skript dělat, je deklarováno a vynuceno. Skriptovaná schopnost deklaruje svůj efekt a hostitel za běhu odmítne volání jakékoli schopnosti, jejíž efekt jej přesahuje. Strop expozice, který dnes existuje jen v grafu příkazů, se přesouvá do CapabilityRegistry::build, kde drží každou schopnost — zkompilovanou i skriptovanou — pod stejným pravidlem: efekt nad stropem se nepromítá do HTTP ani MCP. Tím se uzavírá i mezera nalezená při psaní tohoto záznamu: plan.transition a recover.orphans zapisují do repozitáře a dnes se servírují přes obojí, zatímco jejich vlastní komentáře říkají, že je strop vylučuje.

Interpret je sandbox a není to eval. project.no-network-no-eval zakazuje eval, protože řetězec sestavený za běhu a spuštěný s plnou autoritou nástroje je program, který nikdo neprověřil. Skriptovaná schopnost je v každém ohledu opakem: skript je sledovaný soubor, prověřovaný jako každý jiný; kompiluje se jednou z toho souboru, nikdy z řetězce dodaného volajícím; vlastní funkce eval Rhai je zakázána; engine nemá vlastní přístup k souborům, procesům ani síti a ke světu se dostane jen přes schopnosti, jejichž efekty deklaroval; a engine vynucuje limity na operace, hloubku volání, hloubku výrazu a velikosti řetězců, polí a map, se zrušením a termínem kontrolovanými při každé operaci. SECURITY.md to uvádí jako deklarovanou výjimku v termínech samotného pravidla a sken pravidla je naučen rozlišit soubor skriptu od volání eval.

Konfigurace. rhai 1.26 s sync (sdílený server spouští handlery na vláknech), serde (typované hodnoty překračují hranici přes schémata, která je už popisují), metadata (hostitelské funkce, které smí skript volat, jsou introspektovatelné) a no_time (čas se ke skriptu dostává přes jeho kontext, nikdy skrytými hodinami). unchecked, internals a debugging zůstávají vypnuty. Moduly se rozkládají jen mezi objevenými skripty, nikdy z celého souborového systému.

Zamítnuté alternativy

Automatizační subsystém s vlastním registrem, runtime a API. Byl by to druhý registr, který project.no-new-nouns zakazuje, a každý povrch by se ho musel naučit; stávající registr už se promítá do všech.

Doslovný přepis každého shellového skriptu do Rhai. Většina skriptů je doménová logika — parsování YAML, klasifikace stavu gitu, procházení registru — která patří do typovaného Rustu. Soubor Rhai, který znovu implementuje parsování git status, je stejná vada v jiné syntaxi.

Obecná schopnost shell nebo exec. Udělala by ze skládání řetězců příkazů nejsnazší cestu a za každý povrch by postavila nerecenzovaný program. Pokud by se kompatibilní únik někdy nedal vyhnout, je to samostatně pojmenovaná schopnost s nejvyšším možným efektem, nikdy neprojektovaná mimo příkazový řádek, a každé její použití se hlásí.

Perl, Python nebo Node jako přenosná vrstva. Každý je runtime, který by uživatel musel nainstalovat; Rust executable je již nainstalován všude, kde je Majordomus.

Důsledky

  • Shellový nástroj se zmenšuje migrací, ne přepisem: každý skript se klasifikuje — doménová logika do schopnosti v Rustu, orchestrace do skriptované schopnosti, nevyhnutelný bootstrap se ponechá s deklarovanou výjimkou, mrtvý kód se smaže — a kontrola odmítne nový shell pod řízenými cestami bez položky ve strojově čitelném seznamu výjimek.
  • Skriptované schopnosti se posuzují jako ty kompilované: definice platná podle schématu, test, případy měření výkonu, generovaná dokumentace a kontrola pokrytí Rustu, který je spouští.
  • Diagnostika získává pozici ve zdroji jednou, ve sdíleném typu diagnostiky, takže chyba skriptu pojmenuje soubor, řádek a sloupec na každém povrchu.
  • Uživatel spouští automatizaci repozitáře samotným nainstalovaným spustitelným souborem: bez Bash, bez toolchainu Rust, bez samostatné instalace Rhai.
  • Práce přistává jako řezy milníku automation, každý mergnutý samostatně.

Odkud to pochází

kanonický soubor
.ai/repo/adrs/0069-a-capability-may-be-scripted.md
identity
adr-0069
dostupné také jako
Zdroj MCP majordomus://adr/adr-0069 · majordomus entity show adr/adr-0069 · GET /api/v1/entity?uri=majordomus://adr/adr-0069
v Cockpitu
/cockpit/objects/adr/adr-0069

Tato stránka je generována z výše uvedeného souboru pomocí scripts/generate-site-data; úprava stránky nic nemění, úprava souboru změní všechna rozhraní. Výše uvedené vztahy jsou hrany docs/generated/graph.json, které spustitelný program zapisuje ze stejného indexu.

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