Co to znamená
Scénář případu užití deklaruje, kde běží. mode: fixture, výchozí, připraví jednorázový repozitář a spustí nástroj proti němu. mode: live klade své otázky repozitáři, ve kterém byl příkaz vyvolán — a protože je to něčí práce, nástroj drží živý scénář u toho, co smí otázka dělat:
- příkaz každého kroku musí být
class: read-onlyvshare/commands.yaml; - živý scénář nejmenuje žádnou přípravu, protože nic nepřipravuje;
- krok závazku — krok, který tvrdí, že závazek je splněn, místo aby cokoli spouštěl — je platný jen v živém scénáři, protože jednorázová fixtura nic nedluží;
- krok je příkaz, nebo povinnost, nikdy obojí.
Každé z nich se rozhoduje z deklarace, která už existuje, takže bezpečnost je vlastnost deklarace, ne pečlivosti autora. usecase validate odmítne jakýkoli jiný tvar s exit 10 a jmenuje krok, příkaz a třídu, která rozhodla.
Princip
mj_uc_validate v lib/usecase.sh čte scenario.mode, odmítne režim, který není ani fixture, ani live, a větví se: scénář s fixturou musí pojmenovat setup, který v adresáři fixtur existuje, živý scénář žádný pojmenovat nesmí. U každého kroku čte run.0 a obligation. Krok závazku nesmí nést příkaz, musí být v živém scénáři a musí pojmenovat token, který share/obligations.yaml deklaruje. Krok s příkazem v živém scénáři se vyhledá v registru příkazů přes mj_cmdreg_class a cokoli jiného než read-only — včetně nedeklarovaného příkazu — se odmítne.
Zbytek mechanismu z tohoto plyne: protože živý scénář nemůže měnit, mj_uc_run_live nepotřebuje sandbox a měnící polovina workflow zůstává u start, check a finish, které na ni dohlížejí (ADR 38).
Jak to vidět
majordomus usecase validate # exit 10 names the step, the command and its class
majordomus usecase show know-whether-this-work-is-finished
bash test/run.sh 359_live_scenarios
test/cases/359_live_scenarios.sh postupně podstrčí každý odmítaný tvar — živý scénář s přípravou, živý krok spouštějící příkaz state-mutating, krok závazku ve fixture, neznámý token závazku a krok, který zároveň spouští i tvrdí — a vyžaduje kód 10 se zprávou, která pojmenuje příčinu.
Co nepokrývá
Rozhoduje tvar, ne chování. class: read-only v share/commands.yaml je deklarace, takže příkaz deklarovaný jako jen pro čtení, který přesto zapisuje, zde nic neodmítne — pravdivost samotného registru dluží share/commands.yaml a jeho revizoři a 31_command_coverage je místo, kde se deklarace příkazu porovnává s grafem příkazů.
Váže scénář, ne relaci. Živý scénář nemůže měnit repozitář, na který se ptá; pracovník, který drží týž repozitář otevřený, ho může ve stejném okamžiku měnit, a toto tvrzení o tom neříká nic. Tam mluví rozsah úlohy, check --overlap a pre-push hook.
Neříká nic o tom, co pozoruje živý běh. Zda je odpověď aktuální, zda povinnost, kterou tvrdí, byla splněna pro tento strom, a ne pro starší, je předmětem slovníku povinností a live-scenario-evidence-is-local, ne tohoto odmítnutí.
Proč existuje
Scénář uměl spustit jen majordomus, takže žádný případ užití nemohl ukázat, jak nástroj odmítne zatoulanou úpravu, a první pokus o jeho napsání sáhl po kroku, který by spustil mutující příkaz proti autorovu vlastnímu checkoutu. Bezpečná odpověď už ve stromu byla: každý příkaz deklaruje svou třídu a každý závazek deklaruje, co ho zakládá. Rozhodování živého scénáře z těchto dvou deklarací činí nebezpečný tvar nereprezentovatelným místo odrazovaným — autor ho nemůže napsat, takže ho nemusí zachytit žádný recenzent.