diff --git a/docs/28-servidor-de-produccion.md b/docs/28-servidor-de-produccion.md index 14126736..c2db5288 100644 --- a/docs/28-servidor-de-produccion.md +++ b/docs/28-servidor-de-produccion.md @@ -1174,16 +1174,53 @@ del store a propósito. Queda anotado para que se **decida**, no para que se des ## 9. Estado y orden -| paso | estado | -|---|---| -| **0.** `perfil.servidor` + este documento + el renombre `hammer-*` de los instaladores | ✅ **2026-09-09** | -| **1a.** caja de sacrificio creada — `cx33` (no había `cx53`), hel1, §3.5 | ✅ **2026-09-10** | -| **1b.** imagen del `perfil.servidor` + rescue → `dd` → arranca takana puro (§3) | ✅ **2026-09-10** — puerta 1 pasada, §3.8 | -| **2a.** clave estable + receta de `takana` + repo firmado servido por la caja (§5.1) | ✅ **2026-09-10** | -| **2b.** que el host se actualice DESDE su propio repo (§5.4) | 🚧 bloqueado por la decisión de [SDD 27 §4](27-perfiles-instalables-y-el-instalador.md): `install` reproduce, y eso exige el lab entero | -| **3.** mudanza con las 8 puertas del §6, y recetas nuevas del §6.2 | pendiente | -| **4.** la utilidad de absorción (§4), estrenándose con esta migración | pendiente | -| **5.** `churay` como instalador centralizado (§8) | ADR propio, sin decidir | +**Decisión del usuario (2026-09-14): la mudanza NO pasa por terceros.** Nada de espejar a GitHub +para «tener copia fuera»: la copia fuera **la da la propia mudanza** — en cuanto el gitea vive en la +caja nueva, los 26 repos dejan de existir sólo en la máquina que se borra. El objetivo es dejar de +pagar dos máquinas, no montar una dependencia más. `scripts/mudanza/espejar-repos.sh` queda como +herramienta disponible, no como paso del plan. -**El volumen del store NO se engancha a la caja nueva hasta que pase la puerta 1.** Una caja de -sacrificio con el store dentro deja de ser de sacrificio. +**Y el worker no necesita credenciales: las fuentes de tawasuyu se sirven por HTTPS público.** +Las 23 recetas que apuntaban a `gitea@git.tawasuyu.net` (SSH) pasaron a `https://git.tawasuyu.net/…` +— la URL es locator y no entra en `hash_inputs` (ADR 0013), así que se cambió **con control y sin +mover un solo ArtifactHash**. Medido en el worker: clona y `git archive` extrae el árbol (155 M) sin +ninguna clave. Un usuario propio en gitea sólo haría falta para un repo PRIVADO, y hoy ninguna +receta usa uno. + +### Lo que YA está, y no hay que volver a tocar + +| | | +|---|---| +| la caja `takana` (`2.29.29.217`) | arranca takana puro, PID 1 `arje-zero` — §3.8 | +| store, grafos, granja, respaldo | puertas 2, 3, 4 y 7 — §6.3, §6.7, §6.8, §6.10 | +| repo firmado servido por la caja | §5.1 | +| **la imagen del perfil `servidor` con gitea** | **arranca y sirve 200, supervisado por arje** — §6.11 | +| **`arjectl` para operar sin reiniciar** | §6.12 | +| **el gitea de gioser corriendo sobre takana, con sus datos** | ensayo completo — §6.13 | + +### Lo que falta para el cutover, en este orden + +1. **Actualizar la caja a la imagen nueva** (gitea + `arjectl` + las cuentas de `[[user]]`). + `takana upgrade` está probado (§6.13 del SDD 27 y §5.4 acá); el `dd` es para provisionar, no para + actualizar — sobrescribe el disco local y re-etiqueta la partición. +2. **Mudar los datos del gitea**: `sqlite3 … ".backup"` (1,5 s, consistente con el servidor vivo) + + `rsync -aH` de `/var/lib/gitea` y `/etc/gitea`. El corte final se hace con el gitea del origen + **parado**, para que el último snapshot no pierda escrituras. +3. **Caddy en la caja**: los **6 dominios vivos** del §6.9, con su TLS. Los otros 13 no se mudan. +4. **DNS**: apuntar esos 6 a la IP nueva. El resto de los clones y remotos no se toca — siguen + resolviendo al mismo nombre. +5. **Verificar desde fuera**: cada dominio vivo responde 200 contra la IP nueva **y** un `git clone` + real contra el gitea mudado. +6. **El resto de servicios vivos** del censo (qdrant, squid, act-runner, php-fpm…), por el plan que + `planear.py` ya emite. +7. **Borrar gioser** — sólo con las 8 puertas en verde, a mano, nunca por automatización (§6). + +### Bloqueantes conocidos, con su tamaño + +- **`git` sellado sin `remote-http`** (§6.13): afecta a clonar POR HTTPS *desde* una caja takana, no + al gitea que sirve. Re-sella `git`, raíz de `perfil.base` ⇒ unidad propia. +- **Puerta 5** sigue a medias: la caja sirve su repo pero no se instala de él (`install` reproduce y + eso exige el lab entero). No bloquea la mudanza; bloquea «el servidor se sirve a sí mismo». + +**El volumen del store NO se engancha a la caja hasta que pase la puerta 1** — ya pasó, y el store +local de 68,7 G alcanza, así que la mudanza no depende de mover el volumen de gioser. diff --git a/docs/29-mudanza.md b/docs/29-mudanza.md index 4ab40441..68c4e329 100644 --- a/docs/29-mudanza.md +++ b/docs/29-mudanza.md @@ -303,6 +303,15 @@ Ninguno de los tres es un log de lo que se hizo: los tres son entradas que se vu ### 4.0 quindecies · ⚠ 26 repositorios existen SÓLO en la máquina que se va a borrar +> **Corrección de rumbo (2026-09-14, decisión del usuario): la copia fuera NO se consigue espejando +> a un tercero, se consigue MUDANDO.** En cuanto el gitea vive en la caja nueva, esos 26 repos dejan +> de existir sólo en la máquina que se borra — que es exactamente lo que este paso pide. El objetivo +> del frente es dejar de pagar dos máquinas, y montar una dependencia con GitHub va en contra. +> `espejar-repos.sh` sigue en el repo como herramienta (redundancia extra el día que se quiera), pero +> **no es el paso 1 del plan**: el paso 1 es mudar el gitea, y el criterio de verificación es el +> mismo de siempre — clonar de verdad desde el destino antes de apagar nada. + + Es el hallazgo más grave de este frente, y va por delante de todo lo demás en el plan. Buscando cómo escribir la receta de `tawasuyu` apareció que **su único remoto es el gitea de gioser** (`ssh://gitea@git.tawasuyu.net:2345/…`, y `git.tawasuyu.net` resuelve a `204.168.193.248`, que es diff --git a/recipes/agora-cli.toml b/recipes/agora-cli.toml index 50f65676..06a16944 100644 --- a/recipes/agora-cli.toml +++ b/recipes/agora-cli.toml @@ -11,7 +11,7 @@ version = "0.0.1" license = "MIT" [source] -repo = "gitea@git.tawasuyu.net:tawasuyu/tawasuyu.git" +repo = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git" commit = "9967b02cf597df6d065edbad8d6669b5653d4928" [build] diff --git a/recipes/arje-absorb.toml b/recipes/arje-absorb.toml index 3512f8c3..8c5b5ba6 100644 --- a/recipes/arje-absorb.toml +++ b/recipes/arje-absorb.toml @@ -10,7 +10,7 @@ version = "0.0.1" license = "MIT" [source] -repo = "gitea@git.tawasuyu.net:tawasuyu/tawasuyu.git" +repo = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git" commit = "9967b02cf597df6d065edbad8d6669b5653d4928" [build] diff --git a/recipes/arje-getty-stub.toml b/recipes/arje-getty-stub.toml index 6007c1a7..d583fe6c 100644 --- a/recipes/arje-getty-stub.toml +++ b/recipes/arje-getty-stub.toml @@ -10,7 +10,7 @@ version = "0.0.1" license = "MIT" [source] -repo = "gitea@git.tawasuyu.net:tawasuyu/tawasuyu.git" +repo = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git" commit = "9967b02cf597df6d065edbad8d6669b5653d4928" [build] diff --git a/recipes/arje-installer.toml b/recipes/arje-installer.toml index 282f998c..e698b353 100644 --- a/recipes/arje-installer.toml +++ b/recipes/arje-installer.toml @@ -14,7 +14,7 @@ version = "0.0.1" license = "MIT" [source] -repo = "gitea@git.tawasuyu.net:tawasuyu/tawasuyu.git" +repo = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git" commit = "9967b02cf597df6d065edbad8d6669b5653d4928" [build] diff --git a/recipes/arje-logind-compat.toml b/recipes/arje-logind-compat.toml index 4c75c24c..5de8c823 100644 --- a/recipes/arje-logind-compat.toml +++ b/recipes/arje-logind-compat.toml @@ -20,16 +20,17 @@ # crates dispersos de `compat/`. `-p arje-compat --bin arje-logind-compat` compila SÓLO este daemon. # Estático zig-cc (zbus sobre socket unix + tokio + nix; sin loader del host, como todo arje). # -# HUB-ONLY: fuente `gitea@git.tawasuyu.net` puerto 22 ⇒ el worker secretless recibe Connection -# refused (la gitea escucha en :2345). Se muele en el hub, no en un worker efímero. Ver -# [[rootfs-laptop-worker-divergen]] y el gotcha de recetas tawasuyu en [[frente-gnome]]. +# YA NO ES HUB-ONLY (2026-09-14): la fuente pasó a `https://git.tawasuyu.net/…`, que el gitea sirve +# PÚBLICO y sin credencial. Antes apuntaba a `gitea@git.tawasuyu.net` por SSH y el worker —que no +# tiene ni debe tener esa clave— moría con «access rights». La URL es locator y NO entra en +# `hash_inputs` (ADR 0013): el cambio se hizo con control y NINGÚN ArtifactHash se movió. name = "arje-logind-compat" version = "0.0.1" license = "MIT" [source] # El `commit` es el identificador inmutable (la URL es sólo locator, no entra al hash). -repo = "gitea@git.tawasuyu.net:tawasuyu/tawasuyu.git" +repo = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git" commit = "2445fa31c1b3d8b7da037d2434ace976e2444df4" # El monorepo COMMITEA su propio `vendor/` — `[patch.crates-io] smithay = { path = "vendor/smithay" }`, # una copia parcheada de smithay que mirada necesita para el tearing. `cargo vendor` de takana escribe diff --git a/recipes/arje-net-bring-up.toml b/recipes/arje-net-bring-up.toml index 2c40d043..c020a1e2 100644 --- a/recipes/arje-net-bring-up.toml +++ b/recipes/arje-net-bring-up.toml @@ -10,7 +10,7 @@ version = "0.0.1" license = "MIT" [source] -repo = "gitea@git.tawasuyu.net:tawasuyu/tawasuyu.git" +repo = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git" commit = "9967b02cf597df6d065edbad8d6669b5653d4928" [build] diff --git a/recipes/arje-packager.toml b/recipes/arje-packager.toml index b0e0de8c..40ef6986 100644 --- a/recipes/arje-packager.toml +++ b/recipes/arje-packager.toml @@ -17,7 +17,7 @@ version = "0.0.1" license = "MIT" [source] -repo = "gitea@git.tawasuyu.net:tawasuyu/tawasuyu.git" +repo = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git" commit = "06184e43a8b3179e41905dc56ba07ec569df1ebb" [build] diff --git a/recipes/arje-polkit-compat.toml b/recipes/arje-polkit-compat.toml index d0931344..dde17c73 100644 --- a/recipes/arje-polkit-compat.toml +++ b/recipes/arje-polkit-compat.toml @@ -29,9 +29,10 @@ # un token al grafo y devuelva el resultado. Mientras eso no exista, **cualquier cliente de polkit en # esta distro está autorizado**, y quien lea esta receta tiene que saberlo. # -# HUB-ONLY, como toda receta con fuente tawasuyu: el clone va a `gitea@git.tawasuyu.net` por el puerto -# 22 y la gitea escucha en :2345; el worker efímero es secretless por diseño y recibe -# `Connection refused`. Se muele en el hub. Ver [[rootfs-laptop-worker-divergen]]. +# YA NO ES HUB-ONLY (2026-09-14): la fuente pasó a `https://git.tawasuyu.net/…`, que el gitea sirve +# PÚBLICO y sin credencial. Antes apuntaba a `gitea@git.tawasuyu.net` por SSH y el worker —que no +# tiene ni debe tener esa clave— moría con «access rights». La URL es locator y NO entra en +# `hash_inputs` (ADR 0013): el cambio se hizo con control y NINGÚN ArtifactHash se movió. name = "arje-polkit-compat" version = "0.0.1" license = "MIT" @@ -39,7 +40,7 @@ license = "MIT" [source] # Mismo commit y misma rama que arje-logind-compat: `selfhost/arje-zero-attest-lockfile` es la única # que versiona el `Cargo.lock` de la raíz, sin el cual el vendoreo `--locked` no es reproducible. -repo = "gitea@git.tawasuyu.net:tawasuyu/tawasuyu.git" +repo = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git" commit = "98db584fd28d9ff2bf34c9cf7d7db2e1de0b3fd0" # El monorepo commitea su propio `vendor/` (la copia parcheada de smithay que mirada necesita) y el # `cargo vendor` de takana lo pisaría. Ver [[takana-cargo-vendor-clobbers-project-vendor]]. diff --git a/recipes/arje-zero-attest.toml b/recipes/arje-zero-attest.toml index 94306fd9..b5b68ac2 100644 --- a/recipes/arje-zero-attest.toml +++ b/recipes/arje-zero-attest.toml @@ -18,7 +18,7 @@ version = "0.0.1" license = "MIT" [source] -repo = "gitea@git.tawasuyu.net:tawasuyu/tawasuyu.git" +repo = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git" commit = "06184e43a8b3179e41905dc56ba07ec569df1ebb" [build] diff --git a/recipes/arje-zero.toml b/recipes/arje-zero.toml index c3c2a0c9..8da1a2a0 100644 --- a/recipes/arje-zero.toml +++ b/recipes/arje-zero.toml @@ -40,7 +40,7 @@ license = "MIT" # El `commit` es el identificador inmutable (la URL es sólo locator, no entra al hash). Sin el # `Cargo.lock` del workspace el monorepo lo gitignora, el fetch vendorea SIN --locked ⇒ las deps # derivan en el tiempo y arje-zero (y of_tree(stage1)) deja de ser reproducible. -repo = "gitea@git.tawasuyu.net:tawasuyu/tawasuyu.git" +repo = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git" commit = "98db584fd28d9ff2bf34c9cf7d7db2e1de0b3fd0" # Este árbol COMMITEA su propio `vendor/` (la copia parcheada de smithay que mirada necesita) y el # `cargo vendor` de takana lo pisaría. Ver [[takana-cargo-vendor-clobbers-project-vendor]]. diff --git a/recipes/arjectl.toml b/recipes/arjectl.toml index dcf67093..4f755466 100644 --- a/recipes/arjectl.toml +++ b/recipes/arjectl.toml @@ -27,7 +27,7 @@ version = "0.0.1" license = "MIT" [source] -repo = "gitea@git.tawasuyu.net:tawasuyu/tawasuyu.git" +repo = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git" commit = "98db584fd28d9ff2bf34c9cf7d7db2e1de0b3fd0" # Este árbol COMMITEA su propio `vendor/` y el `cargo vendor` de takana lo pisaría — igual que en # `arje-zero.toml`. Ver [[takana-cargo-vendor-clobbers-project-vendor]]. diff --git a/recipes/cosmos-cli.toml b/recipes/cosmos-cli.toml index b2add771..cbca4d74 100644 --- a/recipes/cosmos-cli.toml +++ b/recipes/cosmos-cli.toml @@ -11,7 +11,7 @@ version = "0.0.1" license = "MIT" [source] -repo = "gitea@git.tawasuyu.net:tawasuyu/tawasuyu.git" +repo = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git" commit = "9967b02cf597df6d065edbad8d6669b5653d4928" [build] diff --git a/recipes/dominium-cli.toml b/recipes/dominium-cli.toml index f43622ab..7bb16675 100644 --- a/recipes/dominium-cli.toml +++ b/recipes/dominium-cli.toml @@ -14,7 +14,7 @@ version = "0.0.1" license = "MIT" [source] -repo = "gitea@git.tawasuyu.net:tawasuyu/tawasuyu.git" +repo = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git" commit = "9967b02cf597df6d065edbad8d6669b5653d4928" [build] diff --git a/recipes/hammerd.toml b/recipes/hammerd.toml index 38697eda..93e9be94 100644 --- a/recipes/hammerd.toml +++ b/recipes/hammerd.toml @@ -13,7 +13,7 @@ license = "MIT" [source] # El repo del propio takana: el `commit` es el identificador inmutable (la URL es sólo locator y # no entra al hash de la receta). Subir el commit cuando hammerd avance. -repo = "ssh://gitea@git.gioser.net:2345/sergio/takana.git" +repo = "https://git.gioser.net/sergio/takana.git" commit = "e9b055121322d3ef8aef8e75738052d5aff0693a" [build] diff --git a/recipes/libelogind.toml b/recipes/libelogind.toml index fd147b15..a80c8386 100644 --- a/recipes/libelogind.toml +++ b/recipes/libelogind.toml @@ -26,8 +26,10 @@ # C-ABI sd-login… los escritorios consultan login1 en RUNTIME por D-Bus»): es cierto para los # clientes D-Bus y FALSO para mutter, que la enlaza. # -# HUB-ONLY, como toda receta de fuente tawasuyu: la gitea escucha en :2345 y el worker efímero es -# secretless ⇒ recibe Connection refused en :22. Se muele en el hub. +# YA NO ES HUB-ONLY (2026-09-14): la fuente pasó a `https://git.tawasuyu.net/…`, que el gitea sirve +# PÚBLICO y sin credencial. Antes apuntaba al SSH de la gitea (puerto 2345) y el worker —que no +# tiene ni debe tener esa clave— no podía construirla. La URL es locator y NO entra en +# `hash_inputs` (ADR 0013): se cambió con control y NINGÚN ArtifactHash se movió. name = "libelogind" version = "0.0.1" license = "MIT" @@ -37,7 +39,7 @@ license = "MIT" # Rama `selfhost/arje-zero-attest-lockfile`, igual que arje-logind-compat, porque es la única que # versiona el `Cargo.lock` de la raíz: sin él, el vendoreo `--locked` del fetch no es reproducible # (el monorepo lo gitignora en main). -repo = "gitea@git.tawasuyu.net:tawasuyu/tawasuyu.git" +repo = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git" commit = "749edfe41766e098d3eb18561c6a396610c5cd8e" # El monorepo COMMITEA su propio `vendor/` (`[patch.crates-io] smithay = { path = "vendor/smithay" }`, # la copia parcheada que mirada necesita para el tearing) y el `cargo vendor` de takana escribe ahí diff --git a/recipes/mirada-compositor.toml b/recipes/mirada-compositor.toml index c8120caa..cf8496e1 100644 --- a/recipes/mirada-compositor.toml +++ b/recipes/mirada-compositor.toml @@ -17,7 +17,7 @@ version = "0.0.1" license = "MIT" [source] -repo = "gitea@git.tawasuyu.net:tawasuyu/tawasuyu.git" +repo = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git" commit = "9a17fefcbf63ba74f45cfabc4e608e391e397b17" [build] diff --git a/recipes/mirada-ctl.toml b/recipes/mirada-ctl.toml index 82754e10..5f4c1778 100644 --- a/recipes/mirada-ctl.toml +++ b/recipes/mirada-ctl.toml @@ -11,7 +11,7 @@ version = "0.0.1" license = "MIT" [source] -repo = "gitea@git.tawasuyu.net:tawasuyu/tawasuyu.git" +repo = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git" commit = "9a17fefcbf63ba74f45cfabc4e608e391e397b17" [build] diff --git a/recipes/mirada-greeter.toml b/recipes/mirada-greeter.toml index bb204995..5910e165 100644 --- a/recipes/mirada-greeter.toml +++ b/recipes/mirada-greeter.toml @@ -16,7 +16,7 @@ version = "0.0.1" license = "MIT" [source] -repo = "gitea@git.tawasuyu.net:tawasuyu/tawasuyu.git" +repo = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git" commit = "9a17fefcbf63ba74f45cfabc4e608e391e397b17" [build] diff --git a/recipes/netup.toml b/recipes/netup.toml index 33f0aa92..abc58e6d 100644 --- a/recipes/netup.toml +++ b/recipes/netup.toml @@ -14,7 +14,7 @@ license = "MIT" [source] # Repo del propio takana (origin). El commit es el identificador inmutable; subirlo cuando netup avance. -repo = "ssh://gitea@git.tawasuyu.net:2345/sergio/takana.git" +repo = "https://git.tawasuyu.net/sergio/takana.git" commit = "c0545ea40cbf530c9b80fc9a76a20551163574cd" [build] diff --git a/recipes/puriy-costura-torrent.toml b/recipes/puriy-costura-torrent.toml index 73cb51df..041f9b47 100644 --- a/recipes/puriy-costura-torrent.toml +++ b/recipes/puriy-costura-torrent.toml @@ -28,7 +28,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [source] -repo = "gitea@git.tawasuyu.net:tawasuyu/tawasuyu.git" +repo = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git" commit = "3bd1440dcb96cfac085cdc669f1cd9c65b5142e5" # Obligatorio para cualquier receta desde este monorepo: tawasuyu commitea su propio `vendor/` con # un `smithay` parcheado por RUTA, y el `cargo vendor` de takana convertiría ese directorio en uno diff --git a/recipes/puriy-costura.toml b/recipes/puriy-costura.toml index 20610acb..74c3e229 100644 --- a/recipes/puriy-costura.toml +++ b/recipes/puriy-costura.toml @@ -42,7 +42,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [source] -repo = "gitea@git.tawasuyu.net:tawasuyu/tawasuyu.git" +repo = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git" commit = "e19bb0e50bf303d56da3c4cf028439a92551b120" # ⚠ SIN ESTO EL BUILD MUERE EN UN SITIO QUE NO NOMBRA LA CAUSA — medido acá el 2026-09-10. # tawasuyu COMMITEA su propio `vendor/`: adentro tiene un `smithay` parcheado a mano (tearing/flip diff --git a/recipes/takana.toml b/recipes/takana.toml index 3fdb905a..f19d6bdb 100644 --- a/recipes/takana.toml +++ b/recipes/takana.toml @@ -34,7 +34,7 @@ license = "MIT" [source] # El repo del propio takana: el `commit` es el identificador inmutable; la URL es sólo locator y no # entra en `hash_inputs` (ADR 0013 §1). Subirlo cuando el CLI avance. -repo = "ssh://gitea@git.gioser.net:2345/sergio/takana.git" +repo = "https://git.gioser.net/sergio/takana.git" commit = "68d052136c06b74f858a8a33d1963f45cf244fa0" [build] diff --git a/recipes/tinkuy-sim.toml b/recipes/tinkuy-sim.toml index 7b690cd8..9a727ce3 100644 --- a/recipes/tinkuy-sim.toml +++ b/recipes/tinkuy-sim.toml @@ -10,7 +10,7 @@ version = "0.0.1" license = "MIT" [source] -repo = "gitea@git.tawasuyu.net:tawasuyu/tawasuyu.git" +repo = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git" commit = "9967b02cf597df6d065edbad8d6669b5653d4928" [build]