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.

Razítko plánu nese pečeť své události, protože ledger nikdy neopouští checkout

Razítko plánu nese pečeť své události, protože ledger nikdy neopouští checkout

majordomus://adr/adr-0097navrženo planživotní cykluseventsintegrita

odkazuje na

odkazuje na něj

Nic ve vrstvě to nejmenuje. Zpětné odkazy se odvozují, takže prázdný seznam je odpověď, ne opomenutí.

97. Razítko plánu nese pečeť své události

Kontext

Stav úkolu se odvozuje z jeho záznamu: started_at, verified_at, completed_at a jeho položek důkazů. Přechod — plan::transition za schopností plan.transition (MCP majordomus_plan_transition, POST /api/v1/plan/transition) a mj_plan_transition za majordomus plan start|verify|done — je střeženou hranicí a po zapsání razítka připojí plan_start, plan_verify nebo plan_done do ledgeru.

Dne 2026-09-15 bylo změřeno, že hranice je nepovinná. ve fixture byly completed_at, started_at, verified_at a jedna položka důkazů ručně připojeny do YAML úkolu a commitnuty. majordomus plan show odvodil DONE, majordomus plan validate vypsal 0 failure(s) a skončil s 0 a ledger neobsahoval žádnou událost plan_*. Žádná kontrola neporovnávala razítka s událostmi. Zvlášť done neměl v žádném z enginů předpoklad na stav, takže úkol READY šlo dokončit, aniž by byl kdy zahájen, a shellový engine zapsal completed_at na úkol CANCELLED.

Samozřejmá kontrola — každé razítko má svou událost v knize — se nedá rozhodnout tam, kde na ní záleží. .ai/local/state/ledger.jsonl je v gitignore a patří jednomu checkoutu: klon, jiný worktree i každá úloha CI začínají bez ní. Vlastní plán repozitáře obsahuje 142 razítek a kniha primárního checkoutu 57 událostí plan_*, protože přechody běžely v mnoha worktree. Kontrola proti knize by byla v CI neznámá a lokálně nepravdivá.

Rozhodnutí

Přechod zapíše pečeť vedle každého razítka, ve stejném zápisu, a plán odmítne razítko bez ní. Pečeť je

sha256:<hex of "majordomus.plan-event/v1\n<event>\n<issue>\n<stamp>\n">

v started_event, verified_event nebo completed_event. Je to sledovaná polovina události: název události, úkol a okamžik, což je přesně to, co řádek ledgeru zaznamenává navíc oproti obálce checkoutu, v němž byl zapsán. Pravda je stále jedna — přechod — a dva záznamy o tom, co udělal, jeden lokální a úplný, druhý sledovaný a minimální, zapsané stejným voláním.

Obě odvození (lib/project.awk, plan.rs) berou razítko jako fakt, jen když jeho pečeť sedí. Nedokázané razítko nehýbe žádným stavem a je selháním FAIL stamp_without_event, které jmenuje úkol, razítko a událost. plan validate na ně končí s 10; scripts/ci/core-check spouští plan validate v každém plánu CI, takže kontrola se rozhoduje ze samotného stromu a nikdy není neznámá. Shellový motor hashuje každé razítko plánu jedním procesem sha256sum/shasum, takže kontrola stojí jeden fork na načtení, ne jeden na razítko.

done nyní vyžaduje ACTIVE nebo VERIFY v obou enginech, po kontrole závislostí a před kontrolou důkazů.

Razítka, která předcházejí pečetím, jsou pojmenována, ne zvýhodněna datem. unsealed_stamps v každém záznamu úkolu uvádí svá vlastní jako <field> <stamp> — v záznamu, protože index project.yaml neobjevuje a oba motory musí číst týž seznam. Položka omlouvá přesně tuto hodnotu a jen tehdy, když je starší než SEALED_FROM (2026-10-01T00:00:00Z, konstanta v obou motorech). Razítko zapsané v tomto okamžiku nebo po něm potřebuje svou pečeť, ať seznam říká cokoli, takže seznam se může zkracovat a nelze jím omlouvat novou práci.

Zamítnuté alternativy

  • Porovnat s ledgerem. V CI neznámé a špatně v každém checkoutu, který neprovedl každý přechod. Zamítnuto měřením, výše.
  • Sledovat ledger, nebo log plánovacích událostí vedle záznamů. Druhá sledovaná historie týchž událostí, s konflikty při merge u každého paralelního přechodu a novým zapisovatelem, který je třeba držet v synchronizaci. Pečeť žije v záznamu, který přechod už přepisuje.
  • Vyjmout každé razítko starší než datum. Zpětně datované razítko by prošlo. Pojmenovaný seznam to uzavírá: zpětně datované razítko by muselo být ve stejném diffu přidáno i do seznamu, do kterého pravidlo přidávat zakazuje.
  • Delegovat přechod v shellu na schopnost v Rustu v této změně. Schopnost řeší úkoly přes index, který vyčísluje jen sledované soubory, stojí asi dvě sekundy za volání a každé odmítnutí hlásí jako exit 10; devět behaviorálních případů pohání přechod v shellu nad nesledovanými fixture a tvrdí exity 12 a 15. To je samostatná změna. Dokud nepřistane, oba enginy nesou stejné ochrany a zapisují stejné bajty, což drží test/cases/133_plan_transition.sh a 582_the_done_guard_holds_in_both_engines.sh.

Důsledky

  • Ručně napsané razítko je vidět: selže plan validate jménem a na žádném povrchu neukazuje žádný pokrok.
  • Pečeť je digest veřejných hodnot, ne podpis. Zfalšovat ji je možné a je to nyní záměrný čin, jehož výstupem je řádek diffu, který nezapsal žádný přechod; znemožnit to by vyžadovalo klíč, který repozitář nemá.
  • Záznamy důkazů jsou stále volný text připojovaný plan evidence; padělaný záznam důkazu může splnit guard done. Zpečetění důkazů je další řez téhož zákona.
  • Větev, která označí úkol starším executable po SEALED_FROM, neprojde validací, dokud se úkol znovu nepřesune aktuálním.

Odkud to pochází

kanonický soubor
.ai/repo/adrs/0097-a-plan-stamp-carries-the-seal-of-its-event.md
identity
adr-0097
dostupné také jako
Zdroj MCP majordomus://adr/adr-0097 · majordomus entity show adr/adr-0097 · GET /api/v1/entity?uri=majordomus://adr/adr-0097
v Cockpitu
/cockpit/objects/adr/adr-0097

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.