I1409 — Odvozená data přestávají hashovat vstupy, které nemohou ovládat
Přimět commitnutou derivaci, aby popisovala něco, čeho může být projekcí, a umístit odmítnutí kvůli zastarání tam, kde se merge skutečně dějí.
HOTOVO vlna 0 · p1 · profil implementation · běží samostatně
Součást derived-data-integrity — Commitnuté odvození popisuje něco, čeho může být projekcí.
Cíl
Přimět commitnutou derivaci, aby popisovala něco, čeho může být projekcí, a umístit odmítnutí kvůli zastarání tam, kde se merge skutečně dějí.
Proč
Čtyři samostatné červené 2026-09-10 sdílely jeden kořen a publikace kvůli tomu hodiny stála. Zapsaný artefakt, který hashuje celý svůj vstupní strom, je zneplatněn dalším merge — ne proto, že je špatný, ale protože se strom posunul; a ten, který hashuje HEAD, nikdy nemůže popsat commit, v němž je. apps/majordomus-cli/src/release/changelog.rs:75 nese tu větu ve vlastním komentáři a kontrola ji přesto přesahuje: komentář není omezení. Druhá polovina je strukturální, ne vada návrhu: odvozený merge driver se záměrně řeší na ours a spoléhá na scripts/pages current v .githooks/pre-commit, který o jeden příkaz později odmítne, a hook pre-commit nemůže běžet pro merge, který vytvoří server. Tři z posledních pěti merge do masteru commitoval GitHub. Pokrytí stráže je tedy opačné než její využití — přítomná na cestě, kterou lidem nedoporučujeme, a chybějící na té, kterou doporučujeme — proto si nikdo nevšiml, že chybí. Poznámka, proč je to vedeno pod novým milníkem, ne pod stávajícím: majordomus plan validate odmítne úkol, který nejmenuje milník, takže oblast stálé práce bez něj nelze v plánu zaznamenat vůbec — tak repozitář přistane na spoustě změn proti plánu, který se nehýbe. Přiřazení k nejméně nesprávnému rodiči by vložilo falešnou hranu do modelu, jehož hodnota je v tom, že stav se odvozuje z grafu.
Aktuální stav
Znovu změřeno 2026-10-14 na masteru c0e3585dc8. (1) Data webu jsou nyní projekcí deklarovaného seznamu vstupů (scripts/generate-site-data --inputs, 1495 cest) otisknutého obsahem, takže derivace commitnutá na jednom commitu popisuje tento commit i poté, co trunk postoupí: případ 3048 mergne vedlejší větev a commit trunku, které se nedotýkají žádného kanonického vstupu, a otisk i `scripts/pages current` (poloviny webu a registru) se nemění, zatímco commit do jednoho kanonického vstupu se čte jako zastaralý (exit 10). (2) Ochrana větve nyní vyžaduje kontrolu `ci` (required_status_checks.contexts = [ci], strict: false) a ci pull requestu běží na merge ref na straně serveru, takže odmítnutí zastaralosti běží na cestě, kterou jde merge GitHubu; strict je false, takže PR posouzený na starší bázi může být mergnut i poté, co se master posunul, a nic zde změřeného to v okamžiku mergu neodmítne. (3) Znovu změřeno 2026-10-15 (I1409-b): fixture exportovaná `git archive` do čerstvého repozitáře, jehož databáze objektů neobsahuje žádný z release commitů, se dříve četla jako zastaralá (exit 10: changelog.* a artifacts.* se liší), protože changelog skládal každou sekci release prázdnou. `majordomus generate` se nyní ptá gitu, která okna release nemůže přečíst (release commit nebo předchozí chybí, nebo mělký repozitář), a jen pro ně ponechává skupiny a rozhodnutí, která committed changelog pro tentýž commit už nese, a říká to (`scripts/pages current` vytiskne oznámení); vše, co záznam nese, se stále skládá a posuzuje. Případ 3055 to drží na exportu testovaného commitu: obě poloviny aktuální, `generate` nepřepíše nic a posunutý zdroj registru končí exit 10. Případ 56 stále klonuje a může se vrátit k exportu. (4) Rozhodnuto 2026-10-15 (I1409-c, doplněk ADR 0101): ochranou při serverovém mergi je gate čerstvosti v době ci, ne přísné povinné kontroly. Působí ve třech bodech: povinné ci na refs/pull/<n>/merge (site: generate-site-data --check, rust: generate --check); vlastní textový merge forge, který nespouští žádný merge driver, a proto konfliktuje na site/data/generated/source.json source_hash, kdykoli obě strany změnily kanonický vstup (merge-tree gitu bez driveru z masteru c0e3585dc8 s #1159 a #1149, oba CONFLICTING na GitHubu, tento soubor uvádí); a mergnutý commit při pushi, kde validate 38635619021 spustil derived site data in sync na merge GitHubu c0e3585dc8 a pages 38635619039 spustil build (scripts/pages build, exit 10 při zastarání) v 21:07:39Z před publikací v 21:09:30Z. docs/CI.md už neříká, že nic na straně serveru nekompenzuje; jmenuje tyto kontroly a říká, že pre-commit hook chrání jen merge, který commituje člověk. Zbytek, uvedený v ADR: odvozené artefakty mimo vstupy webu (oblasti AGENTS.md, .claude/skills) se mohou textově mergnout čistě; první odmítnutí je generate --check v běhu při pushi a web nepublikuje žádný z nich. Žádný řez nezbývá.
Cílový stav
Commitovaný odvozený artefakt je projekce vstupů, které commit vlastní, takže přistání další změny jej nezneplatní a fixtura bez historie jej stále umí vyhodnotit. Odmítnutí pro zastaralost existuje na cestě, kterou merge skutečně jdou, takže první věcí, která řekne ne, je kontrola, ne publikace.
Rozsah
- skripty
- apps/majordomus-cli/src/release
- .ai/repo/ci
- test/cases
Mimo rozsah
- Přimět build Pages, aby znovu odvozoval, místo aby odmítal. Generování tu není deterministické na daném stromu - výstup závislý na stroji, %h zkracující proti lokálnímu úložišti objektů, checkout s hloubkou 1 zapisující degradovaný changelog - takže build, který by znovu odvozoval, by mohl vyrobit třetí odpověď, která neodpovídá žádné straně. Tento východ bude navržen znovu; je zde zaznamenán, aby se důvod, proč selhává, znovu neobjevoval.
- Zapnutí ochrany větve. Která kontrola je povinná a co merge stojí, je nastavení repozitáře a rozhodnutí provozovatele.
- Oslabení odvozeného merge driveru. Vyřešit ve prospěch našeho je správné; chybí odmítnutí za ním na straně serveru.
Závislosti
Žádné. Tento úkol je kořenem grafu.
Kritéria přijetí
- Odvozený artefakt commitnutý na jednom commitu je na tomto commitu stále aktuální poté, co na kmen přistane nesouvisející změna
- test/cases/56_derived_current_gate.sh projde ve fixtuře, jejíž databáze objektů neobsahuje testovaný commit
- Kontrola zastaralosti běží na cestě, kterou jde merge na straně serveru, nebo záznam říká, které rozhodnutí bylo učiněno místo toho a proč
- Žádný dokument netvrdí ochranu, kterou merge vytvořený GitHubem nedosáhne
Validace
- scripts/derive-check
- scripts/pages current
- test/run.sh 56_derived_current_gate
Požadované důkazy
- derivation_survives_an_unrelated_merge
- fixture_without_history_evaluates
- server_merge_guard_decided
Důkazy
| pokrývá | typ | command | výsledek | u commitu |
|---|---|---|---|---|
| derivation_survives_an_unrelated_merge | test | bash test/run.sh 3048_a_derivation_survives_an_unrelated_merge | testy: 1 prošel, 0 selhaly, 0 přeskočeny (2026-10-14 ~23:5xZ na masteru c0e3585dc8, MAJORDOMUS_BIN = binárka masteru; poloviny webu i registru obě aktuální po nesouvisejícím mergi, kontrolní exit 10) | c0e3585 |
| fixture_without_history_evaluates | test | bash test/run.sh 3055_a_derivation_needs_no_history | testy: 1 prošel, 0 selhalo, 0 přeskočeno (2026-10-15 ~04:2xZ na 3b5833692a3, MAJORDOMUS_BIN = sestavení tohoto stromu; export HEAD do čerstvého git init bez release commitu: obě poloviny scripts/pages current projdou s ponechaným changelogem a uvedeným jako neposuzovaný, generate nic nepřepíše, přesunutý zdroj registru skončí s kódem 10; projdou i případy 56, 3048 a 103) | 3b58336 |
| server_merge_guard_decided | artifact | gh api repos/korczis/prismatic-majordomus/branches/master/protection; git merge-tree --write-tree c0e3585dc8 2f759351d0 (bez ovladače merge.derived); gh api .../actions/runs/38635619039/jobs | rozhodnuto 2026-10-15: stráž sloučení na serveru je kontrola čerstvosti ve chvíli ci (požadované ci na merge refu; forge merge bez driveru koliduje na source_hash; validate + build Pages před publikací na merge GitHubu c0e3585dc8, běhy 38635619021 / 38635619039), ne přísné požadované kontroly; dodatek k ADR 0101, docs/CI.md opraveno | 9910ad0 |
Riziko
Střední. Změna hashování zasahuje to, co porovnává každá kontrola, takže chybné zúžení učiní zastarání nezjistitelným, nikoli jen hlučným - selhání by bylo tiché ve směru, na kterém záleží. Zjištění za tímto záznamem změřily čtyři relace 2026-09-10 a křížově je ověřily; dva časové údaje, které tyto relace pro scripts/pages current naměřily, se na jednom stroji s dvacetiminutovým odstupem lišily šestinásobně, a proto zde není žádné číslo nabízeno jako měření výkonu.
Časová osa
- zahájeno
- 2026-10-15T07:54:37Z
- ověřeno
- 2026-10-15T07:54:41Z
- dokončeno
- 2026-10-15T07:54:48Z
Tato tři pole, důkazy výše a stav závislostí jsou vše, z čeho se stav skládá. Neexistuje žádné pole stavu, které by s nimi mohlo být v rozporu.
Kanonický záznam: .ai/repo/project/issues/I1409.yaml. Načtěte ho zpět pomocí majordomus plan show I1409.