I2137 — Přijatá událost mesh je na disku dřív, než se počítá, a poškozený řádek žurnálu se hlásí, nikdy se tiše nespojí ani nezahodí
Zajistit, aby připojování do žurnálu a přepisy při kompakci byly trvalé a hlásily selhání, a aby opětovné načtení přežilo useknutý konec, aniž by ztratilo nebo slilo úplnou událost.
HOTOVO vlna 0 · p0 · profil implementation · běží samostatně
Cíl
Zajistit, aby připojování do žurnálu a přepisy při kompakci byly trvalé a hlásily selhání, a aby opětovné načtení přežilo useknutý konec, aniž by ztratilo nebo slilo úplnou událost.
Proč
Journal::persist ignoruje chyby zápisu (apps/majordomus-cli/src/mesh/journal.rs:1984, let _ = file.write_all) a nikdy nedělá fsync; reload čte celý soubor přes read_to_string a tiše zahazuje každý neparsovatelný řádek (apps/majordomus-cli/src/mesh/journal.rs:1407-1413); připsání po utrženém konci bez koncového newline slije další událost do poškozeného řádku (apps/majordomus-cli/src/mesh/journal.rs:1969-1984), takže jeden pád ztratí i událost po něm. Přepis komprimace (apps/majordomus-cli/src/mesh/journal.rs:2250-2264) má tytéž vlastnosti a soubor se vytváří s výchozí umask. Jediný test reloadu používá čistý soubor (apps/majordomus-cli/src/mesh/journal.rs:2655, a_reloaded_journal_keeps_events_and_resurrects_no_liveness). Plný disk se na této cestě neřeší nikde; jediné sync_all v crate je apps/majordomus-cli/src/economics/runner.rs:1035. Žurnál drží události a těla předávek jiných runtime (apps/majordomus-cli/src/mesh/journal.rs:1961-1985), takže ztracený řádek je ztracená spolupráce. Základní audit z 2026-10-09 na masteru 1fb8d6be44, mezera selhání 4 a řádky tříd selhání plný disk, useknutý žurnál a částečný zápis.
Aktuální stav
Zápisy jsou best effort a bez hlášení; utržený konec poškodí další událost; nečitelné řádky se při znovunačtení ztratí.
Cílový stav
Připsání zapíše nejdřív chybějící koncový newline (utržený konec zůstane jedním nečitelným řádkem), synchronizuje a započítá selhání do JournalTallies.write_failures, místo aby ho zahodilo; reload počítá nečitelné řádky (JournalTallies.unreadable); komprimace zapíše synchronizovaný soubor a přejmenuje ho přes starý, pak synchronizuje adresář; soubor se vytváří jen pro vlastníka (0600); mesh doctor selže na kontrole žurnálu, dokud je kterýkoli počet nenulový. Odložená část, mez velikosti reloadu a odmítnutí potvrdit vlastní událost, jejíž připsání selhalo, je I2706.
Rozsah
- apps/majordomus-cli/src/mesh/journal.rs
- apps/majordomus-cli/src/mesh/doctor.rs
- apps/majordomus-cli/src/capability/builtin/mesh.rs
- apps/majordomus-cli/tests/mesh_compaction.rs
- test/cases
- docs/MESH.md
Závislosti
Žádné. Tento úkol je kořenem grafu.
Co na tom čeká
Kritéria přijetí
- Deník s utrženým posledním řádkem znovu načte každou úplnou událost, ohlásí jeden nečitelný řádek a další připojení je čitelné při dalším načtení
- Neúspěšný zápis na souborový systém jen pro čtení nebo plný se v testu počítá a hlásí ho mesh doctor
- Kill během kompaktace nechá starý nebo nový žurnál, nikdy směs
- Soubor žurnálu se vytváří s oprávněními jen pro vlastníka
Validace
- bin/majordomus plan validate
- cargo test --lib mesh::journal
- cargo test --test mesh_compaction
- MJ_TEST_JOBS=4 bash test/run.sh 493_mesh_compaction_keeps_what_is_live
Požadované důkazy
- torn_tail_reload_test
- write_failure_reported_test
- compaction_crash_test
Důkazy
| pokrývá | typ | command | výsledek | u commitu |
|---|---|---|---|---|
| torn_tail_reload_test | test | cargo test --locked --manifest-path apps/majordomus-cli/Cargo.toml --lib mesh::journal::tests::a_torn_tail_is_one_unreadable_line_and_the_next_append_reads | test result: ok. 1 passed; 0 failed (run 2026-10-14 10:02Z on master 6f28de9207) | 6f28de9 |
| write_failure_reported_test | test | cargo test --locked --manifest-path apps/majordomus-cli/Cargo.toml --lib mesh::journal::tests::a_failed_append_is_counted_and_the_file_is_the_owners_alone | test result: ok. 1 passed; 0 failed (run 2026-10-14 10:02Z on master 6f28de9207) | 6f28de9 |
| compaction_crash_test | test | cargo test --locked --manifest-path apps/majordomus-cli/Cargo.toml --lib mesh::journal::tests::a_compaction_that_cannot_replace_the_file_leaves_the_old_one_and_no_temporary | test result: ok. 1 passed; 0 failed; selhané přejmenování, ne zabitý proces (běh 2026-10-14 10:02Z na master 6f28de9207) | 6f28de9 |
Časová osa
- zahájeno
- 2026-10-14T10:03:06Z
- ověřeno
- —
- dokončeno
- 2026-10-14T10:03:17Z
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/I2137.yaml. Přečtěte jej zpět pomocí majordomus plan show I2137.