166. Povrchy plánu se odvozují z dodávky a nic, co plán ukazuje, se vedle něj nepíše
Kontext
Dne 2026-10-16 vlastník přečetl https://majordomus.dev/roadmap/ a https://majordomus.dev/ui/roadmap/ a napsal:
- „tohle je evidentne dost outdated, neni to derived, neni to infered, neni to generic, dynamic, integrated, tested, documented, deployed, verified, validated, eliminuj tento paralellni vesmir“ (toto je evidentně dost zastaralé, není to odvozené, není to inferované, není to generické, dynamické, integrované, testované, zdokumentované, nasazené, ověřené, validované; eliminuj tento paralelní vesmír).
- „make main gh_page + landing page more up-to-date, generic/generated, all of above“.
- „vsechny ascii charts/graphs nahrad v souladu s ostatnimi mermaid.js ci cytoscape, interaktivni proklikatelne, enforcovane, veskery kod unifikovane highlightuj stejnym nejlepsim zpusobem“ (nahraď každý ASCII diagram nebo graf, v souladu s ostatními, mermaid.js nebo cytoscape, interaktivní, proklikatelný, vynucený; zvýrazni veškerý kód jednotně tím nejlepším způsobem).
Změřeno téhož rána na master d1162668036 (v0.27.0):
- Veřejný plán rozvoje uvádí osm z 38 milníků.
site/templates/roadmap.htmlponechává jen milníky, které mají ručně zadanéversion:. Jsou to osm milníků napsaných dříve, než projekt měl releasy: 0.1 až 1.0, dva z nich 0.5, v pořadí 0.1, 0.5, 0.6, 0.2, 0.3, 0.4, 0.5, 1.0. Produkt vydal 27 minor verzí. Třicet milníků, v nichž se práce skutečně odehrává, se neobjeví vůbec. - Stav úkolu je razítko a nic ho neporovnává s tím, co se stalo.
lib/project.awk:156-170aplan.rsodvozují stav jen z razítekplan start|verify|donea grafu závislostí. PR #1097 sloučil celé I2653 a I2653 se stále čte jako PŘIPRAVENO. Totéž platí pro I2417 (#930), I2652 (#1090), I2734 (#1234), I2601 (#1092) a další: sloučený pull request jmenuje úkol a plán o tom neví.trace.issue,delivery.report,scripts/github-sync --checka třídy driftu záměrů čtou každý část pravdy. Žádný ji nestaví proti deklarovanému stavu. - „Poslední release“ v plánu rozvoje v UI zaostává za spustitelným souborem, který jej vykreslil. Snímek načtený v 07:15Z říkal „Latest release 0.26.0“ pod hlavičkou 0.27.0, protože záznam o release byl sloučen v 07:44Z.
- Úvodní stránka vyjadřuje přítomnost ručně psanou prózou. Například
site/data/manifesto.tomlříká „Nothing replans“ a „No command runs this today“ amarketing.tomltvrdí „straight from the repository“ nad čísly, která pocházejí z razítek. - Diagramy a kód se kreslí třemi způsoby.
- Kresba z rámečkových znaků přežívá v ADR, v příručce a na jedné obrazovce UI, což
project.a-diagram-is-drawn-not-typednepokrývá. - Kód zvýrazňuje na webu syntect ze Zola, na
majordomus uihighlight.js 11.9 stažený z CDN a vlastní skripty příručky.
- Kresba z rámečkových znaků přežívá v ADR, v příručce a na jedné obrazovce UI, což
Každé z nich je druhý popis repozitáře, napsaný vedle něj. To je paralelní vesmír.
Rozhodnutí
-
Dodání úkolu se odvozuje jednou, v Rustu. Schopnost
plan.deliveryodpovídá pro každý úkol nejzazší z:nonebranch: jmenuje ho větevpr_open: pojmenovává ho otevřený pull requestmerged: merge na trunku jej jmenuje přes hranu úkolu z I1405released: první tagv*obsahující tento mergedeployed: publikovaný web hlásí tento release nebo pozdější
Každá fáze nese objekt, který ji dokázal: větev, číslo PR, merge commit, tag a
latest.jsonwebu. Nese i čas, kdy byla pozorována. Forge se čte přes stávající cacheserved forgea nepřečtený forge se hlásí jako nepřečtený, nikdy jakonone. Nic z toho se nereimplementuje v awk nebo shellu. Data webu aPLAN_STATUS.mdvolají spustitelný soubor. -
Rozpor mezi deklarovaným a odvozeným je nález a na trunku kontrola.
plan.drifthlásí:merged_not_recorded: PŘIPRAVENO, BLOKOVÁNO nebo AKTIVNÍ, se sloučenou prací a bez otevřeného pull requestu, který ji jmenuje.active_without_work: ACTIVE, bez větve, pull requestu či claimu v meshi uvnitř okna.done_without_trace: HOTOVO, bez mergu, který by ho jmenoval. Tato třída je poradní, protože existují úkoly jen se záznamem.
merged_not_recordedstarší než okno deklarované v.ai/repo/ci/odmítnecitrunku a jmenujemajordomus plan verify|done <id>. Deklarovaný stav zůstává záznamem přijetí proti důkazům. Odvozování nikdy nezapisuje razítko. -
Verze milníku je fakt o releasech, ne pole.
version:opouští schéma milníku a záznam, který ho nese, je odmítnut. „Vydáno ve“ je první záznam release (sledované vyjádření tagu,.ai/repo/releases/v*.yaml), jehož commit obsahuje poslední přijatý úkol milníku, protože odvozená data nesmějí záviset na refech mimo strom. Práce dokončená před prvním záznamem (v0.3.1) se čte jako tento release, nejstarší, který tato vrstva eviduje. Milník HOTOVÝ vlastními důkazy bez úkolu nese commit, který zaznamenal nejnovější z těchto důkazů. Otevřený milník je „nevydaný“. Vendorované pravidloroadmap-integrityje přepsáno, aby odpovídalo. -
Každý plánovací povrch kreslí každý milník z jednoho odvození. To se týká
/roadmap/,/plan/, čísel plánu na úvodní stránce,/ui/roadmapaPLAN_STATUS.md:- Pořadí je pořadí grafu milníků.
- Každý úkol ukazuje svůj deklarovaný stav vedle odvozené fáze a odkazuje na PR, commit a tag, které fázi dokládají.
- Každý povrch uvádí commit a čas, kdy byl pozorován.
- Žádná šablona nefiltruje milníky podle ručně psaného pole.
/ui/roadmapčte release z releasů, ne z pull requestu záznamu, v čase snapshotu.
-
Úvodní stránka netvrdí přítomný čas, který nečte. Věta v
site/data/*.toml, která popisuje aktuální stav, se buď stane vykresleným údajem, nebo zmizí.scripts/ci/homepage-checkv těchto souborech odmítá slovník tvrzení o současném stavu. -
Každý vztah je nakreslen, a to interaktivně.
project.a-diagram-is-drawn-not-typeddosáhne verze 2 a pokrývá.ai/repo/adrs/**,.ai/repo/rules/**,handbook/**i každý markdown řetězec, kterýmajordomus uivykresluje.- Diagramy jsou v Mermaid, nebo v Cytoscape tam, kde je graf daty.
- Každý diagram prochází prohlížečem ADR 0152, s odkazy uzlů odvozenými buildem.
-
Jeden zvýrazňovač. Každý blok kódu na každém povrchu zvýrazňuje syntect s jedním slovníkem tříd a jednou paletou generovanou z design tokenů:
- Na webu, přes Zola.
- V
majordomus uia reportech, přes spustitelný soubor. - V příručce, přes stejný vygenerovaný stylopis.
highlight.js opouští UI a žádný povrch nestahuje zvýrazňovač z CDN. Kontrola odmítne druhý zvýrazňovač.
Důsledky
- Plán rozvoje ukazuje 38 milníků tam, kde ukazoval osm, a ukazuje rozdělanou práci (otevřené pull requesty, claimy meshe), kterou nikdy neukazoval.
- Release se stává součástí vlastního obrazu plánu: úkol čte
released in v0.28.0, takže sloučená, ale nevydaná změna je jako taková viditelná a mluví pro další řez. - Trunk zčervená, když sloučený úkol zůstane po okně nezaznamenán. To je záměr: je to drift, který toto ADR vyvolal.
- Spustitelný soubor získává závislost syntect. Paleta se generuje jednou, takže se web a UI nemohou barevně rozejít.
- Engine awk dál odvozuje stav z razítek. Delivery je jen v Rustu, což případ 99 (enginy se shodují) nepokrývá. Je to záměrné a je to zde zaznamenáno.
Zamítnuté alternativy
- Odvozovat stav a zapisovat razítka automaticky. Zamítnuto, protože merge není akceptace. O HOTOVO stále rozhodují důkazy a odvozování jen činí mezeru viditelnou a hlídanou.
- Ponechat
version:a přidat kontrolu věrohodnosti. To bylo zamítnuto, protože věrohodné ručně psané číslo je stále ručně psané. Záznamy releasů už odpověď drží. - Přijmout Shiki pro zvýrazňování. Zamítnuto, protože Shiki by dal Node na cestu vlastních stránek spustitelného souboru. Syntect je engine, který web už používá, dostupný povrchu v Rustu bez druhého toolchainu.