134. Další verzi přiděluje při přistání integrační executor z verze trunku a změřeného dopadu změny pod typovanou podlahou politiky
Kontext
Verze má jednoho zapisovatele (ADR 0029, ADR 0085) a její minimum se měří z veřejného kontraktu proti poslednímu release (ADR 0051). Kdo ji zapisuje a kdy, bylo ponecháno tomu, kdo si toho všiml první: version-surface odmítne první pull request po release, který kontrakt posune, dokud tento pull request verzi sám nezvýší.
Dne 2026-10-09 a 2026-10-10 byla tato cena změřena na vlastní práci tohoto repozitáře:
- další číslo se mezi relacemi vyjednávalo zprávami (0.19.1 pro jeden pull request, 0.19.2 pro jiný, 0.20.0 pro „první funkci“);
- každá feature branch pak kolidovala s trunkem na řádku verze v
apps/majordomus-cli/Cargo.toml, autorské cestě, kterou refresh integračního executoru odmítá, takže se každá opravovala ručně (#807, #821, #827, #829); - release mezi tím (v0.20.0) zneplatnil každé nesené zvýšení a každá větev se musela znovu zvýšit na 0.21.0.
Pull request zvolil svou verzi dřív, než věděl, na který master přistane. Volbu nic neserializovalo kromě lidí.
Rozhodnutí
- Verze se přiděluje při přistání. Když politika repozitáře říká
release.allocation: landing, pull request verzi nezvyšuje. Integrační executor (ADR 0101) ji zvýší při obnovení, které už provádí před posledním během CI pull requestu, poté co je master zmergován a před derive, takže head, který posuzuje povinná kontrola, a head, který přistane, nesou stejnou verzi. - Číslo se počítá z trunku, nikdy z branche. Další verze je
trunk_version.raised_to(selected), kdetrunk_versionje to, co master deklaruje v okamžiku refresh. Opakování, druhý refresh po posunu masteru nebo zotavení po pádu přepočítá z nového trunku, takže žádná integrace nemůže zvýšit verzi dvakrát a dva pull requesty nemohou držet totéž číslo: executor obnovuje vždy jeden pull request pod integračním lease a přistání, které posune master, znovu způsobí, že každý jiný head jebehind. - Co se vybírá, je typované.
selected = max(required_by_compatibility, floor):required_by_compatibilityje měření ADR 0051 vlastního posunu veřejného povrchu tohoto pull requestu, master proti kandidátovi, přeložené režimem verze (pod 1.0.0 stojí odebrání minor, od 1.0.0 major);floorjerelease.floorv politice:none,patch,minornebomajor, čteno přes režim verze jako kompatibilita, takže pod 1.0.0 žádá minor spodní hranicemajor; změna, která se nedotkne žádné cesty, není přistání a spodní hranici nedluží;- změněné cesty se vypisují bez detekce přejmenování, takže soubor přesunutý do vyňatého stromu se posuzuje i na cestě, kterou opustil;
- změna, která přidává
.ai/repo/releases/v<trunk>.yaml, záznam release, který trunk již deklaruje, nedluží žádnou spodní mez: záznam následuje svůj tag a může změnit více, než pokrývá třída záznamů (záznam v0.20.0 změnil také.gitattributesadocs/INSTALL.md), a její zvýšení by jej přeneslo za tag, který zaznamenává. Rozhoduje přidání, měřené od místa, kde se head odštěpil: změna, která upravuje již napsaný záznam, mez dluží, takže žádný pull request jí neunikne dotykem záznamu; - neznámý pohyb zůstává tím, čím ho činí ADR 0051, nikdy bezpečnou záplatou.
- Výjimka snižuje jen práh, nic jiného.
release.exemptdeklaruje třídy, každou s id, popisem a cestami, které pokrývá. Pull request je vyňat, když každá cesta, kterou mění, spadá do jedné třídy: pak se práh neuplatní, požadavek kompatibility ano. Záznam release, vlastní obnova executoru a změna záznamů plánu jsou třídy, které tento repozitář deklaruje. Přepínač pro jednotlivý pull request neexistuje. - Alokace není publikace. Zvýšená verze je integrovaný fakt; release se publikuje tagem a ověřuje svým záznamem a smoke testem. Nic v tomto rozhodnutí netaguje ani nepublikuje.
- Repozitář, který neříká nic, se nemění.
release.allocationmá výchozíoffarelease.floorvýchozínone: kontrola a zvýšení fungují přesně jako dříve.
Důsledky
majordomus release next(schopnostrelease.next) jen pro čtení odpovídá, co by executor přidělil pro daný head proti base, a proč: verzi trunku, naměřený posun, spodní mez, případnou výjimku a další verzi.- Tento repozitář nastavuje
allocation: landingafloor: minor: každá způsobilá integrace posune alespoň minor (požadavek vlastníka z 2026-10-10). - Obnovení exekutoru musí před přidělením vyřešit konflikt na řádku verze ve prospěch kmene, protože vlastní číslo větve už není tvrzením autora.
- Model konzistence, řečeno otevřeně: GitHub neslučuje a nepublikuje atomicky. Zaručeno je, že každá přistálá integrace nese právě jednu alokaci spočtenou z masteru, na který přistála, protože head, který přistane, je head, který executor obnovil a CI posoudilo (
--match-head-commit), a executor je jediným zapisovatelem alokace.
Dodávka
- Řez A (tento záznam): typovaný blok politiky, rozhodovací engine,
release.next. - Řez B: přidělení uvnitř refresh executoru (
integration/allocate.rs), řešení konfliktu řádku verze v klasifikaci a v refresh a trailerVersion-Allocated: <next> (<selected> from <trunk>)na commitu, který refresh pushuje. Politika, kterou se přistání řídí, je ta, kterou commituje master, čtená z commitu a nikdy z pracovního stromu executoru: vztah headu k masteru je cachován dvojicí id commitů jako navždy platný fakt, takže vše, na čem závisí, musí být faktem těchto commitů. Opakování nebo refresh po posunu masteru přepočítá z nového masteru (případ 1061). - Řez B2: head, který už obsahuje master, ale nenese číslo, které mu přidělí přistání, přesto dluží obnovu. Jeho vztah zůstává
up_to_datea říká, jakou verzi dluží (owes_version, čtenou ze dvou commitů jako vše, co drží cache vztahů), a kontrola čerstvosti jej odmítne jakoneeds_refreshsversion_unallocated:VERSION, nikdy jakobehind_master, což říká, že chybí master. Dodáno s řezem B.allocationzůstává v tomto repozitářioffaž do řezu C, aby se po pull requestu nežádalo ruční zvýšení verze a pak další obnova kvůli ní. - Řez C:
version-surfacena pull requestu podallocation: landingodmítne ruční zvýšení místo jeho požadování;version.ymlpřestane otevírat pull requesty se zvýšením. - Řez D: životní cyklus release jako jeden typovaný stavový automat nad stávajícím workflow.
- Slice E: cesta k manifestu z politiky, aby nainstalovaný repozitář používal týž engine.