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.
majordomus recover
Uzavřete epizody, které nikdo neukončil, sloučte duplicitní záznamy a roztřiďte zatoulané soubory úložišť.
Uzavřete epizody, které nikdo neukončil, sloučte duplicitní záznamy a roztřiďte zatoulané soubory úložišť.
mění stav
systém
Opakovaná údržba, na rozdíl od migrate, což je jednorázový přesun z rozvržení před .ai. Každý subjekt je idempotentní a každý má --check, který nic nezapisuje. Nic se nemaže jen proto, že je to neznámé — kandidát, jehož důkazy nelze přečíst, se ohlásí, spočítá a nechá být.
Jen kódy, které tento příkaz může vrátit. Úplný kontrakt je na indexu příkazů.
0ok
2použití
10kontrakt nesplněn
12chybějící artefakt
Epizodu uzavírají důkazy, nebo nikdo
Poskytovatel, který je zabit, neposílá závěrečnou událost a epizoda, kterou otevřel, zůstane otevřená navždy. Obnova ji uzavře — ale jen když důkazy říkají, že její klient je pryč, a nikdy hádáním. Každý subjekt má --check, který nic nezapisuje, a měření, které rozhodlo o každém verdiktu, se vypíše dřív, než se s ním cokoli udělá.
Plán a měření za ním
jedna epizoda uvízlá a jedna živá
ano
Pro tento repozitář platí
# Installed, with two episodes open: one whose client is gone and one that is live.
#
# Both halves of the stranded episode's trail are aged, not only its open record. The last
# sign of life is the later of started_at and the newest ledger line the episode stamped, so
# an episode whose ledger is fresh is young however old its file claims to be — a fixture
# that moved one half would demonstrate the command passing for the wrong reason.
. "$FIXTURE_SETUP/installed.sh"
"$MJ" session start --provider-session gone-client >/dev/null
"$MJ" session start --provider-session this-client >/dev/null
_S=.ai/local/state
_dead="$(sed -n 's/^session_id: //p' "$_S/sessions-open/gone-client.yaml" | head -n 1)"
sed -i.bak 's/^started_at: .*/started_at: 2020-01-01T00:00:00Z/' "$_S/sessions-open/gone-client.yaml"
rm -f "$_S/sessions-open/gone-client.yaml.bak"
awk -v s="$_dead" '{ if (index($0, "\"session\":\"" s "\"") > 0) sub(/"ts":"[^"]*"/, "\"ts\":\"2020-01-01T00:00:00Z\""); print }' \
"$_S/ledger.jsonl" > "$_S/ledger.mj-tmp" && mv "$_S/ledger.mj-tmp" "$_S/ledger.jsonl"
Spustit
$ majordomus recover episodes --check
Výstup obsahuje
naposledy viděno 2020-01-01T00:00:00Z
stranded:
živé: tento proces je uvnitř
check: 1 akce
ukončení0
Poslední známka života každého kandidáta se vypíše, včetně těch, se kterými se nic nestane, takže chybný predikát je vidět ve výstupu, ne až v jeho důsledcích. Dry run nezapíše vůbec nic.
Uzavření té, jejíž klient zmizel
jedna epizoda uvízlá a jedna živá
ano
Pro tento repozitář platí
# Installed, with two episodes open: one whose client is gone and one that is live.
#
# Both halves of the stranded episode's trail are aged, not only its open record. The last
# sign of life is the later of started_at and the newest ledger line the episode stamped, so
# an episode whose ledger is fresh is young however old its file claims to be — a fixture
# that moved one half would demonstrate the command passing for the wrong reason.
. "$FIXTURE_SETUP/installed.sh"
"$MJ" session start --provider-session gone-client >/dev/null
"$MJ" session start --provider-session this-client >/dev/null
_S=.ai/local/state
_dead="$(sed -n 's/^session_id: //p' "$_S/sessions-open/gone-client.yaml" | head -n 1)"
sed -i.bak 's/^started_at: .*/started_at: 2020-01-01T00:00:00Z/' "$_S/sessions-open/gone-client.yaml"
rm -f "$_S/sessions-open/gone-client.yaml.bak"
awk -v s="$_dead" '{ if (index($0, "\"session\":\"" s "\"") > 0) sub(/"ts":"[^"]*"/, "\"ts\":\"2020-01-01T00:00:00Z\""); print }' \
"$_S/ledger.jsonl" > "$_S/ledger.mj-tmp" && mv "$_S/ledger.mj-tmp" "$_S/ledger.jsonl"
Spustit
$ majordomus recover episodes
Výstup obsahuje
.ai/repo/sessions/
obnoveno: 1 akce
ukončení0
Záznam nese to, co dokazují otevřený záznam a vlastní řádky ledgeru epizody. Jeho commits a changed_files jsou explicitní prázdný seznam a neuvádí žádný head: pracovní strom v době obnovy patří tomu, kdo právě pracuje, a otisknout ho na epizodu, která skončila před dny, by byl záznam vypadající přesně jako pravdivý.
Bez jakékoli degradace
jedna epizoda uvízlá a jedna živá
ne
Pro tento repozitář platí
# A repository with Majordomus installed and projections generated, and one commit of work.
"$MJ" init >/dev/null
"$MJ" update >/dev/null
mkdir -p lib docs
echo a > lib/a
echo d > docs/d
git add . && git commit -qm base
Spustit
$ majordomus recover
Výstup obsahuje
není co obnovovat
ukončení0
Nepřítomnost je odpověď. Čisté úložiště skončí s 0 a řekne to, místo aby nemít co dělat bralo jako selhání.
Předmět, který tento příkaz nemá
jedna epizoda uvízlá a jedna živá
ne
Pro tento repozitář platí
# A repository with Majordomus installed and projections generated, and one commit of work.
"$MJ" init >/dev/null
"$MJ" update >/dev/null
mkdir -p lib docs
echo a > lib/a
echo d > docs/d
git add . && git commit -qm base
Spustit
$ majordomus recover everything
Výstup obsahuje
neznámý subjekt
ukončení2
Chybně napsaný předmět je odmítnut, ne složen do výchozího. Příkaz obnovy, který by tiše udělal něco jiného, než bylo požádáno, je ten, který nesmí existovat.
Reference
Vrátit úložiště záznamů tohoto checkoutu do stavu, který popisuje kontrakt: zavřít epizody, které nikdo neukončil, sloučit duplicitní záznamy jedné epizody do jednoho a roztřídit zbloudilé soubory, které se v úložištích hromadí. Opakovaná, idempotentní údržba — na rozdíl od migrate, což je jednorázový přesun z rozvržení před .ai, který odmítne běžet dvakrát.
Subjekty:status (výchozí, pouze čtení), episodes, records, orphans, all.
Čte:.ai/local/state/sessions-open/, .ai/local/state/ledger.jsonl, úložiště uzavřených záznamů a úložiště checkpointů a předávek. Zapisuje: uzavřený záznam pro každou obnovenou epizodu pod .ai/repo/sessions/, sloučený záznam tam, kde existovaly duplicity, řádek knihy session.recovered pro každou akci a odstraňuje otevřené záznamy a zatoulané dočasné soubory, na kterých zasáhl.
Behaviour:
--check vypíše plán a důkazy za ním a nic nezapíše. Totéž měření řídí skutečný běh, takže plán je akce.
Zbloudilý soubor se posuzuje podle stáří dřív než podle obsahu: dočasný soubor publikace starý vteřiny patří session close, které právě běží, a .mj-stage.XXXXXX staré minuty scripts/derive, které právě běží. Obojí se hlásí jako live a ani jedno se nedotkne; soubor, jehož stáří nelze přečíst, se přeskočí a započítá.
Zastaralý staging adresář se hlásí a nikdy neodstraňuje. Tento příkaz nemaže žádný strom adresářů — SECURITY.md uvádí „žádné rekurzivní mazání“ — takže .mj-stage.XXXXXX za prahem se jmenuje, počítá se jako přeskočený a nechá se člověku k odstranění.
Epizoda je uvízlá, když je její poslední známka života — pozdější z jejího vlastního started_at a nejnovějšího řádku knihy, který označila — starší než session.stranded_after. --older-than <duration> pro jeden běh přepíše politiku.
Mezi živou epizodou a úklidem stojí dvě pojistky a ani jedna není zálohou té druhé. Epizoda, na kterou se tento proces překládá, je vyloučena dříve, než se spustí jakýkoli predikát; a kandidát, jehož důkaz nelze přečíst jako časové razítko, se přeskočí a započítá, nikdy se nepovažuje za nejstarší v množině (project.destructive-sweeps-fail-closed). Epizoda patřící jinému worktree se ohlásí a tady se nikdy nezavře.
Obnovený záznam nese to, co dokazují otevřený záznam a vlastní řádky knihy epizody. commits a changed_files jsou explicitní prázdný seznam a head a working_tree chybí: popisují uzavření, které se nikdy nestalo, a pracovní strom v okamžiku obnovy patří tomu, kdo právě pracuje. outcome je interrupted, čím také bylo.
Duplicitní záznamy se sloučí do nejstaršího podle created_at s sjednocením seznamů, které ostatní dokládají, a názvy nahrazených souborů se zapíší do těla přeživšího. Záznamy, které se neshodují v identitě nebo časech epizody, se ohlásí a nic se neslučuje.
Nic se nemaže jen proto, že to nebylo rozpoznáno. Dočasný soubor publikace po prahu, který drží jedinou kopii záznamu, se publikuje; ten, jehož epizoda je už publikována, nebo prázdný, se odstraní; ten, který drží obsah, jejž tato verze neumí klasifikovat, zůstane přesně tam, kde je, a započítá se. Adresář, který někdo vložil do úložiště kontrolních bodů, se pojmenuje, změří a ponechá.
Idempotentní. Dvojí spuštění nad jedním předmětem provede jeho akce jednou a spuštění po pádu uprostřed běhu provede ty, které se nestaly: záznam se zapíše dřív, než se odstraní otevřený soubor, takže přerušení mezi nimi nic nestojí.
$ majordomus recover episodes --checkepisodes — open episodes in .ai/local/state/sessions-open s-20260910194205-72ea key=187c9e1e-… last seen 2026-09-10T19:42:05Z (ledger, 13h ago) stranded: 13h ago, over the 12h threshold; close with outcome interrupted s-20260911063532-b41b key=c93d195f-… last seen 2026-09-11T08:31:02Z (ledger, 0m ago) live: this process is inside it; never a candidatecheck: 1 action(s) would be taken and nothing was written (run: majordomus recover all)
Důkazy
Každý případ níže běží v CI na Linuxu i macOS. Web se odmítne sestavit, pokud veřejný příkaz nemá behaviorální případ, negativní případ nebo ukázku.