645 líneas. Los ADR entran porque en este repo SON documentos vivos, no registros inmutables: el 0013 tiene 5 commits, el 0009 dos. Eso se comprobó antes de decidir, no se asumió por convención general. EXCLUIDOS por ser REGISTRO o generado: docs/evidencia/ (6), el HANDOFF de la noche de KDE (1) y docs/state/ (24, se regenera solo). Reescribir un comando dentro de una evidencia la falsifica. Y el ADR 0016 se excluye de todo barrido, con un aviso adentro para el próximo que barra: habla SOBRE el renombre, así que necesita seguir diciendo 'hammer'. El barrido se lo llevó puesto y lo dejó titulado 'Renombre del sistema: takana → takana'; revertido. Congelados, verificados uno por uno con controles: /opt/hammer, /var/lib/hammer, /usr/bin/hammer, /mnt/vvv/hammer, la URL de gitea, hammer-farm.service, hammer-live-install.sh, BRIEFING-hammer.md, hammerd, hammer-recover y HAMMER_LIVE.
14 KiB
ADR 0016 — Renombre del sistema: hammer → takana
- Estado: ACEPTADO (decisión del usuario, 2026-09-09)
- ⚠ Este fichero queda FUERA de todo barrido de renombre. Habla sobre el cambio de nombre, así
que necesita seguir diciendo
hammerdonde corresponde. El barrido de la etapa 5 lo pasó por arriba y lo dejó diciendo «Renombre del sistema: takana → takana»; se revirtió. Si alguien vuelve a barrer docs, excluir este fichero explícitamente. - Reemplaza: nada. Afecta: toda la superficie de CLI (regla 4 de
CLAUDE.md).
Contexto
Los nombres propios del proyecto se reparten por rol, no por estética: khipu registra
(docs/state/build-state*.json), yupana reckona sobre el khipu (scripts/yupana.py), harkaq
guarda (la jaula), qorpa hospeda (imágenes ajenas), churay pone (distribución multi-origen).
Cada uno dice qué hace su pieza. El único nombre que designa el todo es el del constructor.
takana (quechua y aimara: martillo, mazo) es la traducción literal de hammer. Conserva la
metáfora que el proyecto ya usa —forja, yunque, sellar— y mantiene el registro agentivo del resto de
la familia. Es hermana de tawasuyu: el territorio (apps, compositor) × la herramienta (la forja).
Se descartaron: chani (valor/precio — nombra el hash, no el motor; y "valor" es cosa, no rol),
tocapu (la marca inscripta — mismo hueco que chani), anta (cobre — es materia, no rol; y no
suena quechua: sin q, k, h, ll ni ñ).
Decisión
- El sistema se llama takana. La marca vive en
docs/marca/. - El renombre va por etapas con alias, nunca de un saque.
hammersigue funcionando hasta que el último llamador migre. - Se adoptan los dos puntos de la hoja de marca que chocaban con contratos vigentes —el verbo
forjay la extensión.tkn—, implementados sin romper llamadores (ver §La hoja de marca).
Lo medido (2026-09-09)
Nada de esto es estimación; sale de git grep y de leer recipe.rs.
| qué | cuánto | consecuencia |
|---|---|---|
ficheros que nombran hammer |
1242 (5779 ocurrencias) | radio total |
en recipes/, y son comentarios de importación |
692 | gratis: ver abajo |
recetas con .hammer-zig-cc dentro de una fase |
10 | caro: re-hashea |
recetas con cargo_vendor_dir = ".hammer-cargo-vendor" |
5 | congelar: ver abajo |
| ficheros que invocan la CLI | 124 | migración real |
crates hammer-* (+ hammerd) |
12 | renombre de paquetes |
El hallazgo que decide todo: Recipe::hash_inputs (crates/hammer-core/src/recipe.rs:535) no
hashea el fichero crudo — construye una lista de campos: source_id, compiler, target,
link, huella del lab, zig_version/strip_debug si están fijados, los patches, los flags, las
fases (configure/compile/install) y los hashes de las deps.
- ⇒ Los comentarios no entran. Renombrar «hammer» en los 692 comentarios de recetas importadas no mueve ni un ArtifactHash. Es churn de diff, no de build.
- ⇒ Las fases sí entran, con etiqueta (
phase:compile=…). Las 10 recetas que escriben.hammer-zig-cclo hacen dentro de la fase: renombrar ese literal las re-hashea y obliga a reconstruirlas y a todo su cono descendente. El literal es un temporal interno del árbol de build, invisible al usuario. Se congela como está. - ⇒
cargo_vendor_dirno está enhash_inputs. Renombrar.hammer-cargo-vendorsería invisible al hash pero puede cambiar los bytes del artefacto — la misma familia de problema que «el lab está fuera dehash_inputs». Se congela como está.
Y el cron apunta a una ruta absoluta: */30 * * * * /mnt/vvv/hammer/scripts/farm/cosecha-cron.sh.
Renombrar el directorio del repo mata el latido de la granja en silencio — no falla nada,
simplemente deja de cosechar. El directorio es lo último que se toca, y con el cron parado.
Plan por etapas
-
Marca + este ADR. Aditivo, no rompe nada. ← hecho
-
Alias. ← hecho (2026-09-09). El binario canónico es
takana;hammerse sigue emitiendo. Son dos[[bin]]apuntando al mismomain.rs, no un symlink: la siembra de la granja excluye/target, así que un symlink hecho en el hub no existiría en el worker, ycargo cleanlo borra. Cuesta una recompilación delmain.rsy un warning de cargo («present in multiple build targets») que se va solo en la etapa 6. Los dos nombres funcionan; no se tocó ningún llamador. -
Llamadores. ← hecho (2026-09-09), en dos commits y en este orden, que no es cosmético:
- 3a — los
cargo build --release --bin hammerpasan a--bin takana --bin hammer(6 sitios). Va solo y primero: el worker compila desde fuente (farm-worker-loop.sh) y la siembra excluye/target. Si se cambiaran antes las invocaciones, habría una ventana en la que el worker sincroniza scripts nuevos y sólo tiene el binario viejo — y eso no falla ruidosamente: deja de cosechar en silencio. - 3b — las 49 invocaciones de
./target/release/hammer→takana, enscripts/,docs/runbooks/yCLAUDE.md. Verificado conbash -n/py_compilelos 49 (ojo:why-differs-barrido.shes Python con extensión.sh) y, sobre todo, con el ciclo real del cron inmediatamente posterior al cambio:2026-09-09T18:30:00Z → 18:32:21Z, siembra ✓, manifiesto ✓, los 9 JSON del grafo regenerados (los producebuild-state.py, que ahora invocatakana) y estado commiteado+pusheado. Cero errores. Esa es la prueba que importa: la regeneración del khipu pasa por el binario renombrado.
Excluido a propósito de la etapa 3:
- La variable de entorno
HAMMER=. Es interfaz entre scripts y hay llamadores que la fijan; renombrarla va con la etapa 4. docs/evidencia/y losHANDOFF-*: son registro de lo que se corrió ese día. Reescribir un comando dentro de una evidencia la falsifica.docs/state/: generado, se regenera solo.- ADRs y docs de diseño: texto, y
hammersigue funcionando. Van con la etapa 5.
Cómo converge el worker (medido el 2026-09-09, no supuesto). Su checkout vive en
/opt/hammer, no es un clon git —lo pone el rsync de la siembra— yhammer-farm.serviceestáenabledallá, corriendofarm-worker-loop.shcomo servicio largo. En el momento del cambio el worker tenía scripts viejos y binario del 6-sep: coherente. Los dos estados intermedios también lo son, y por eso la 3a iba primero:- Antes de reiniciar el servicio: el loop viejo en memoria sigue llamando
hammery recompilando--bin hammer, que existe. Funciona. - Después de reiniciar: el loop nuevo compila los dos y usa
takana; sitakanatodavía no existe,rebuild_si_hace_faltacompila y devuelve 0 —salta el ciclo, no aborta—.
La unit apunta a la RUTA DEL SCRIPT, no al binario, así que nada de la etapa 3 la toca. El nombre del fichero de unit y
/opt/hammerson etapa 6.Convergido y comprobado (2026-09-09 18:40–18:45Z). Reiniciado
hammer-farm.service, el worker compiló los dos binarios y cerró un ciclo de build real con el nombre nuevo:✓ dunst b3:29a79859…, BUILD-YIELD 1/1, 1 promovido. No es que «no se rompió nada visible»: el camino de construir y sellar se ejercitó entero. - 3a — los
-
Crates. ← hecho parcialmente (2026-09-09). Los 10 de librería + CLI (
hammer-{core,build,bootstrap,overlay,journal,mirror,upgrade,agent,recover,cli}) sontakana-*. Verificado que no mueve el corpus:takana hash recipes/zlib.tomldevuelveb3:dc363f26…, idéntico a antes. 600 tests en verde.Dos binarios congelados, con razón medida:
hammerd— paquete y binario. Es componente de Stage 1 de la distro (musl, busybox, hammerd, arje-zero), arje-zero lo supervisa en el sistema arrancado yPRESEED=hammerdlo nombra enselfhost-verify.sh.hammer-recover— el paquete estakana-recover, el binario sigue siendohammer-recover:hammer-live-install.shlo copia a/usr/sbin/hammer-recoveren sistemas ya instalados y hornea un hook de arranque que lo invoca por ese nombre. Renombrarlo no rompe el repo: rompe máquinas instaladas.
Consecuencia que hay que anotar igual: al renombrar
hammer-core, los bytes dehammerdcambian de todos modos —linkea contra un crate con otro nombre y el nombre va en los símbolos—, así que el baselineof_treedel selfhost hay que rehacerlo. Es efecto de la etapa 4, no de un cambio enhammerd.
4 bis. Variables de entorno: leen las dos, gana la nueva. ← hecho (2026-09-09).
Se midió antes de tocarlas y el problema tenía otra forma que la del plan: no era «la variable
HAMMER=», eran 14, ~260 apariciones en 58 ficheros, y el binario las lee. Con knobs del
instalador entre ellas, el entorno del worker trayéndolas puestas y mirror-env.sh exportándolas
— todo eso vive fuera del repo, en perfiles de shell y units. Un sed no falla ruidosamente:
la variable deja de aparecer, se toma el default y el build se comporta distinto en silencio.
- Rust:
takana_core::env::{var, var_os}recibe el nombre canónico (TAKANA_…) y deriva el viejo cambiando el prefijo. Se le pasa el nuevo a propósito, para que ungrepdel nombre nuevo encuentre todas las lecturas. 5 tests, con dos controles negativos: sin ninguna de las dos no hay valor, y un nombre sin prefijoTAKANA_no inventa una caída. - Migrados los 17 sitios directos y los indirectos que el grep de
env::var("HAMMER_…")no mostraba:bases_de_mirror, las constantes dekernel_cmd,ROOT_ENVde qorpa yenv_pathde recover.takana-recoverlleva la caída inline: es un mini-binario que se copia a/usr/sbiny no vale arrastrarle una dep entera por dos líneas. - Scripts: 30 lecturas pasan a
${TAKANA_X:-${HAMMER_X:-default}}, conservando el nombre interno de la variable para no tocar sus 190 usos. - Donde el script EXPORTA en vez de leer, se ponen las dos (
mirror-env.shy el fragmento in-VM detakana-bootstrap). Ahí el lector puede ser un binario viejo —un worker sin recompilar, el/usr/bin/hammerpinado del baseline— que sólo conoceHAMMER_*. La caída sirve al lector nuevo; al viejo hay que seguirle dejando la suya puesta.
Verificado con el binario, no sólo con unit tests: HAMMER_LAB sigue surtiendo efecto,
TAKANA_LAB hace exactamente lo mismo, y con las dos puestas gana TAKANA_LAB. 605 tests en
verde y hash zlib sigue en b3:dc363f26….
Cambio de comportamiento que va dicho aparte: el hostname por defecto de una instalación
nueva pasa de hammer a takana (sólo si no se fija ninguna de las dos variables).
No se tocan: las rutas /var/lib/hammer de sistemas ya instalados, el -volid HAMMER_LIVE
del ISO (es identidad horneada en el medio) y el namespace HARKAQ_*, que es de otro subsistema.
- Comentarios de recetas (692). Gratis en hash, ruidoso en diff: va en un commit propio y solo.
- Retirar el alias. Y recién entonces, si se quiere, el directorio
/mnt/vvv/hammer— parando el cron y reescribiendo el crontab en el mismo movimiento.
Etapas 2–6 no arrancan hasta que la 1 esté pusheada, y ninguna se mezcla con otra en un commit.
La hoja de marca: los dos puntos que contradecían contratos vigentes
La hoja (docs/marca/README.md) trae dos ejemplos que chocan con contratos ya escritos. Se
plantearon como no adoptables; el usuario los reafirmó el 2026-09-09 y se adoptaron. Se
implementaron de forma que la decisión se cumpla sin romper a los llamadores existentes.
1. forja — verbo de marca en castellano
Choca con la regla 4 de CLAUDE.md («la superficie de CLI va en inglés»). Adoptado como
alias de clap sobre build, no como reemplazo:
takana forja <receta>funciona — la invocación de la hoja de marca es real.takana build <receta>sigue siendo el canónico: es lo que usan los 124 llamadores, el cron y los runbooks, y ninguno se tocó.CLAUDE.md§4 quedó enmendada en el mismo movimiento. Cambiar el comportamiento y dejar escrito el contrato viejo es peor que cualquiera de las dos opciones: el otro agente del repo sigue aplicando lo que lee.- La excepción es cerrada: un alias, el que está. Otro alias es decisión de ADR.
2. .tkn — extensión del paquete
Choca con .swm (266 menciones; Etapa F entera encima). Resultó mucho más barato de lo
estimado, y por una razón medida: la extensión no es lógica, es salida.
- Se escribe en un solo lugar (
crates/hammer-cli/src/main.rs:1800). - El descubrimiento de paquetes va por índice, no por glob:
PackageEntry.file(crates/hammer-core/src/repo.rs:75) guarda el nombre real de cada fichero. - ⇒ Los repos existentes no se rompen y un repo mixto es válido: un índice con entradas
.swmsigue resolviendo, y los paquetes nuevos se escriben.tkn. No hace falta migrar nada. - Cero ficheros
.swmversionados en el repo, así que no hubo qué renombrar. Swm,SwmBuild,swm_path,swm_bridgeNO se tocan. Son nombres de tipo y de módulo, no superficie de usuario; renombrarlos es churn puro dentro de la etapa 4.
Nota sobre los ficheros de marca
Los dos SVG difieren correctamente (chispa #FFF6DE sobre oscuro, #17130E sobre claro) —
verificado por sha256 y por los colores presentes, no por el nombre del fichero. Ambos traen un
manifiesto C2PA de procedencia embebido; se conserva tal cual vino, sin limpiar.