safe-self-update — Každý uzel meshe sleduje publikovaný release sám, verze se potkávají bezpečně a původ releasu lze ověřit
Zapojený uzel meshe sleduje stabilní release sám přes jediný instalátor, jen dopředu, aktivuje v pořadí a vrací zpět neúspěšnou aktivaci (ADR 0161); novější klient nahradí starší server v uspořádaném předání a starší klient se dozví, že je starší; změna jakéhokoli schématu na drátě nebo na disku vyžaduje zvýšení verze; vydaný archiv nese atestaci původu, kterou instalátor kontroluje.
AKTIVNÍ 3 of 11 issues done
- připraveno
- 3
- blokováno
- 5
- aktivní
- 0
- verify
- 0
- hotovo
- 3
- zrušeno
- 0
Problém
Balíček předpokládá self-updater a podepsané releasy. Oba předpoklady jsou vyvráceny. `majordomus update` regeneruje projekce poskytovatelů z politiky (lib/update.sh:4); žádný příkaz self-update neexistuje a docs/DISTRIBUTION.md:416-439 to říká; k upgradu člověk znovu spustí install.sh s --version. Artefakty mají kontrolní součty, nejsou podepsány: sha256 a velikost v releases/<tag>.json kontroluje site/static/install.sh:478 (voláno na :706) a docs/DISTRIBUTION.md:151-153 podepisování záměrně odkládá. Existuje riziko kompatibility: kontrola nahrazení (superseded) pokrývá jen binárku nahrazenou na stejné cestě (apps/majordomus-cli/src/lease.rs:695-709), zatímco instalátor používá jeden adresář na verzi, takže nový klient se připojí ke staršímu serveru a zaznamená to jen varování Outdated (apps/majordomus-cli/src/capability/builtin/server.rs:410-424). version-surface oceňuje pouze veřejnou plochu; verze discovery mesh a spojení (apps/majordomus-cli/src/mesh/protocol.rs:36-40, apps/majordomus-cli/src/mesh/link.rs:50-53), schéma lease a události žurnálu jsou mimo ni. Změřeno v auditu základní linie běhu ze dne 2026-10-09 na masteru 1fb8d6be44 (plan/RUNTIME_BASELINE.md).
Výsledek
Zapojený uzel meshe sleduje stabilní release sám přes jediný instalátor, jen dopředu, aktivuje v pořadí a vrací zpět neúspěšnou aktivaci (ADR 0161); novější klient nahradí starší server v uspořádaném předání a starší klient se dozví, že je starší; změna jakéhokoli schématu na drátě nebo na disku vyžaduje zvýšení verze; vydaný archiv nese atestaci původu, kterou instalátor kontroluje.
Aktuální stav
Implementováno: install.sh ověřuje kontrolní součet a velikost, odmítá traversal a ne-HTTPS; release-verdict podmiňuje release na CI; version-surface pokrývá schopnosti, trasy, nástroje, příkazy a schémata; vyjednání protokolu MCP. Chybí: čtečka stabilního ukazatele na libovolném uzlu (každý uzel se aktualizuje ručně), předání verze napříč cestami, ocenění wire schémat, fixture inzerce v1, provenience.
Cílový stav
Matice kompatibility v plan/RUNTIME_BASELINE.md uvádí sousední verze klienta/serveru a mesh s testem pro každou dvojici a docs/DISTRIBUTION.md říká, co každá instalační cesta ověřuje. Vlastník 2026-10-14 rozhodl, že kontrola aktualizací na pozadí je žádoucí (ADR 0161): každý zapsaný uzel sleduje releases/latest.json přes self update, který znovu spustí install.sh, a mesh ukazuje verzi každého uzlu (I2720-I2724).
Rozsah
- apps/majordomus-cli/src/lease.rs
- apps/majordomus-cli/src/capability/builtin/server.rs
- apps/majordomus-cli/src/mcp/protocol.rs
- apps/majordomus-cli/src/release
- apps/majordomus-cli/src/mesh/protocol.rs
- apps/majordomus-cli/src/mesh/link.rs
- scripts/ci/version-matches-surface
- .github/workflows/release.yml
- site/static/install.sh
- test/fixtures
- test/cases
- docs/DISTRIBUTION.md
- docs/MCP.md
- docs/MESH.md
- apps/majordomus-cli/src/mesh
- .ai/repo/mesh/majordomus.yaml
Mimo rozsah
- Druhý instalátor nebo aktualizátor; install.sh zůstává jedinou cestou (balíček M11) a self update jej spouští znovu (ADR 0161).
- Síťové stažení při vstupu do repozitáře.
- Restart serveru klienta, zatímco má rozdělanou práci; předání jde přes přesun relace z I2127.
Kritéria přijetí
- Zapsaný, sledující uzel je na verzi, kterou jmenuje releases/latest.json, do jednoho kontrolního intervalu od release, bez zásahu člověka
- Neúspěšná aktivace se sama vrátí na předchozí verzi a nástěnka jmenuje uzel, verzi a selhavší kontrolu
- Klient verze N+1 vedle serveru verze N na jiné cestě skončí s jedním serverem N+1 a bez ztracené relace
- Změna schématu wire, lease nebo žurnálu bez zvýšení verze selže na version-surface
- Každý archiv releasu nese attestaci, která se pro tento repozitář ověří
Validace
- bin/majordomus plan validate
- cargo test --test serve_lifecycle
- MJ_TEST_JOBS=4 bash test/run.sh 85_installer 743_release_version_answers_with_the_contract
Požadované důkazy
- version_hand_off_test
- wire_versions_gated
- node_follows_stable_pointer_test
- hub_rolls_back_failed_version_test
- release_attestation
Rizika
- Předání mezi verzemi závisí na tom, že starý server ukončí své relace (I2127); přistání I2163 jako prvního by nechalo klienty na starém serveru uvíznout.
- Automatické sledování zvyšuje cenu špatného archivu; I2165 (atestace) se zvyšuje na p1 s ADR 0161.
- Atestace potřebuje oprávnění k repozitáři v publikačním jobu; s tím se mění blok oprávnění release workflow.
Úkoly
Každý z nich je prováděcí kontrakt s vlastními kritérii přijetí, validačním příkazem a požadovanými důkazy. Sloupec wave je vrstva grafu závislostí, v níž úkol leží.
| issue | status | vlna | závisí na | název |
|---|---|---|---|---|
| I2163 | HOTOVO | 1 | I2127 | Klient se nikdy nepřipojí k serveru jiné verze, aniž by to řekl, a novější klient nahradí starší server |
| I2165 | HOTOVO | 0 | — | Vydaný archiv nese atestaci původu, kterou instalátor umí zkontrolovat |
| I2720 | PŘIPRAVENO | 0 | — | majordomus self update znovu spustí publikovaný instalátor a nikdy ho nereimplementuje |
| I2721 | BLOKOVÁNO | 1 | I2720 | Zapsaný uzel meshe sleduje stabilní ukazatel sám |
| I2722 | BLOKOVÁNO | 1 | I2720 | Hub aktivuje novou verzi pod svým správcem služeb, zkontroluje její zdraví a sám provede rollback |
| I2723 | PŘIPRAVENO | 0 | — | Mesh ukazuje verzi každého uzlu a jak daleko se release rozšířil |
| I2724 | BLOKOVÁNO | 1 | I2720, I2165 | Uzel bez cesty k webu převezme archiv od peera a přesto ho sám ověří |
| I2826 | PŘIPRAVENO | 0 | — | GitHub release nese changelog samotného nástroje pro svůj tag, nikdy poznámky generované GitHubem |
| I2829 | HOTOVO | 0 | — | Alfa se publikuje jako pre-release od začátku do konce a nikde se nestane nejnovějším release |
| I3177 | BLOKOVÁNO | 1 | I2723 | Two nodes one release apart keep linking, and what the older cannot answer is shown unavailable |
| I3178 | BLOKOVÁNO | 2 | I2720, I2722 | A self update killed at any stage leaves a usable installation |
Graf
flowchart LR
I2163["I2163<br/>A client never attaches to a server of another version without saying so, and a newer client replaces an older server"]:::done
I2165["I2165<br/>A released archive carries a provenance attestation the installer can check"]:::done
I2720["I2720<br/>majordomus self update re-runs the published installer, and never reimplements it"]:::ready
I2721["I2721<br/>An enrolled mesh node follows the stable pointer by itself"]:::blocked
I2722["I2722<br/>A hub activates a new version under its service manager, checks its health and rolls back by itself"]:::blocked
I2723["I2723<br/>The mesh shows each node's version and how far a release has rolled out"]:::ready
I2724["I2724<br/>A node without a route to the site takes the archive from a peer and still verifies it itself"]:::blocked
I2826["I2826<br/>A GitHub release carries the tool's own changelog for its tag, never GitHub's generated notes"]:::ready
I2829["I2829<br/>An alpha is published as a pre-release end to end, and never becomes the latest release anywhere"]:::done
I3177["I3177<br/>Two nodes one release apart keep linking, and what the older cannot answer is shown unavailable"]:::blocked
I3178["I3178<br/>A self update killed at any stage leaves a usable installation"]:::blocked
I2165 --> I2724
I2720 --> I2721
I2720 --> I2722
I2720 --> I2724
I2720 --> I3178
I2722 --> I3178
I2723 --> I3177
classDef done stroke:#16a34a,fill:#dcfce7,color:#14532d,stroke-width:2px
classDef active stroke:#2563eb,fill:#eff6ff,color:#1e3a8a,stroke-width:2px
classDef verify stroke:#7c3aed,fill:#f5f3ff,color:#4c1d95,stroke-width:2px
classDef ready stroke:#0891b2,fill:#ecfeff,color:#164e63,stroke-width:2px
classDef planned stroke:#0891b2,fill:#ecfeff,color:#164e63,stroke-width:2px
classDef blocked stroke:#b45309,fill:#fffbeb,color:#78350f,stroke-width:2px
classDef cancelled stroke:#6b7280,fill:#f9fafb,color:#374151,stroke-width:2px
classDef superseded stroke:#6b7280,fill:#f9fafb,color:#374151,stroke-width:2pxOdkazuje z tohoto diagramu (11)
- I2163 Klient se nikdy nepřipojí k serveru jiné verze, aniž by to řekl, a novější klient nahradí starší server
- I2165 Vydaný archiv nese atestaci původu, kterou instalátor umí zkontrolovat
- I2720 majordomus self update znovu spouští publikovaný instalátor a nikdy ho nereimplementuje
- I2721 Zapsaný uzel mesh sleduje stabilní ukazatel sám
- I2722 Hub aktivuje novou verzi pod svým správcem služeb, zkontroluje její zdraví a sám se vrátí zpět
- I2723 Mesh ukazuje verzi každého uzlu a jak daleko se release rozšířil
- I2724 Uzel bez cesty k webu převezme archiv od peera a přesto ho ověří sám
- I2826 GitHub release nese vlastní changelog nástroje pro svůj tag, nikdy poznámky generované GitHubem
- I2829 Alfa se publikuje jako pre-release od začátku do konce a nikde se nestane nejnovějším releasem
- I3177 Two nodes one release apart keep linking, and what the older cannot answer is shown unavailable
- I3178 A self update killed at any stage leaves a usable installation
Kanonický záznam: .ai/repo/project/milestones/safe-self-update.yaml. Přečtěte si ho zpět pomocí majordomus plan show safe-self-update.