sitio: menos prosa, un selector de variante, y las descargas fuera del HTML
Tres cosas pedidas por el usuario, y la de fondo es la primera: **sobraba texto**. La página pesa 5,8 KB MENOS con una sección más adentro. **La intro deja de explicar.** Era una frase que contaba el diseño; ahora es una presentación sin verbos conjugados y sin jerga: «Una distribución de Linux de dos pisos. Abajo, una fábrica cerrada: todo desde su código fuente, siempre idéntico, con su origen comprobable. Arriba, un sistema corriente: tuyo, modificable, reversible.» Lo que explicaba ya está en la sección 02, que es donde toca. **Descargar pasa a ser la sección 01**, con título pelado y sin un párrafo: un selector de las cuatro variantes —cada una con nombre, qué es, y entre llaves lo que trae— y los comandos. `mirada` por defecto. `full` no tiene archivo único y el bloque simplemente no está, en vez de una fila explicando la física de la RAM. **Ninguna URL de descarga queda en el HTML.** Las compone el JS al pulsar el selector, con el path armado por trozos; `grep -c "descargas/takana-instalador" index.html` ⇒ **0**, y no hay un solo `<a>` a `/descargas/`. Son ficheros de 138 MiB a 3,4 GiB: no son para que se los baje un rastreador. El precio, dicho en el README: sin JS no hay descargas, y el `<noscript>` lleva la ruta en TEXTO, no como enlace — un enlace ahí devolvería el problema que esto evita. Probado de verdad, no a ojo: el script corre bajo node con un DOM de juguete y emite las siete URLs reales, `full` ocultando su bloque. Las siete responden 200. **Los pesos se corrigen solos.** La tabla en JS es el valor medido al publicar y un `HEAD` la pisa al pintar cada variante. Ya hacía falta: la tabla anterior decía 3,2 y 3,5 GiB cuando los ficheros son 3,1 y 3,4. **Botón de copiar** en cada bloque, puesto por el JS (uno por `.codigo`), copiando sin el `$` del prompt. Y la URL del `curl` es clickable. **Se van las secciones «el código» y «los paquetes».** Sus direcciones quedan en **05 · los repositorios** y sus comandos en **06 · cómo se llama**, que es el minitutorial que faltaba: el laboratorio (`hash`/`build`/`why-differs`), los paquetes (`repo list`/`verify`/`install`) y el sistema vivo (`try`/`journal`/ `commit`). El `git clone` sube a la sección de descargas, que es donde alguien busca cómo conseguirlo. ⚠ La prosa del instalador —kexec, Secure Boot, las dos confirmaciones, el doble sha256, `--check`/`--survey`— **no se perdió: se dejó de repetir.** Vive donde se ejecuta, y el README del sitio dice fichero y línea de cada cosa. La página la estaba duplicando, que es como dos copias empiezan a divergir. 162 pares es/en emparejados, etiquetas balanceadas, cero anclas rotas, JS validado con `node --check`, y lo servido coincide con el disco.
Delta semántico
Ninguna definición cambió: el cambio es de texto, documentación o datos.
2 archivos · +230 −160
- web/takana-os.net/README.md +28 −0
- web/takana-os.net/index.html +202 −160
diff --git a/web/takana-os.net/README.md b/web/takana-os.net/README.md
index 6995e26d..c90decfb 100644
--- a/web/takana-os.net/README.md
+++ b/web/takana-os.net/README.md
@@ -67,6 +67,34 @@ el tipo (hoy no manda ningún `Content-Type` para estos ficheros).
⚠ `/descargas` queda **fuera del `encode`** del vhost: el `.sh` ya viene comprimido, y volver a
comprimirlo por HTTP gasta CPU en cada descarga sin ahorrar un byte.
+### En la página: los enlaces NO están en el HTML
+
+⚠ **Ninguna URL de descarga aparece en `index.html`** (a pedido del usuario, 2026-09-23): el
+selector de variante las compone en JavaScript al pulsarlo, y el path se arma por trozos
+(`'/de'+'scargas/'`). Un rastreador que lee el documento no encuentra una sola, y estos ficheros
+pesan de 138 MiB a 3,4 GiB — no son para que se los baje un bot. Se comprueba con
+`grep -c "descargas/takana-instalador" index.html` ⇒ **0**.
+
+El precio: **sin JavaScript no hay descargas**. Por eso hay un `<noscript>` con la ruta en TEXTO
+PLANO, no como enlace — un enlace ahí devolvería el problema que esto evita.
+
+**Los pesos se corrigen solos.** La tabla en JS (`PESO`) es el valor medido al publicar; al pintar
+cada variante se dispara un `HEAD` y, si responde, el peso real lo pisa. Así una reconstrucción del
+instalador no deja la página mintiendo — que ya pasó: la tabla anterior decía 3,2 y 3,5 GiB cuando
+los ficheros eran 3,1 y 3,4. Si el `HEAD` falla, queda el medido; nunca en blanco.
+
+**El botón de copiar lo pone el JS**, uno por cada `.codigo`, y copia sin el `$` del prompt. No hay
+que escribirlo diez veces en el HTML.
+
+### La prosa del instalador salió de la página, a propósito
+
+El usuario pidió quitar la sobreexplicación (2026-09-23): la sección de descargas es ahora el
+selector, los comandos y nada más. Lo que se quitó **no se perdió** — vive donde se ejecuta:
+`--check`/`--survey`/`--extraer` y el sha256 del payload en `scripts/instalador-autoextraible.sh`,
+`takana.console` en `scripts/instalador-initramfs.sh`, el kexec y las dos confirmaciones en
+`docs/32-instalador-de-usuario.md`, y «el medio desde el que arrancaste no se ofrece» en
+`scripts/takana-install-partition.sh:291`. La página lo estaba repitiendo, no guardando.
+
### Las variantes: qué sistema se instala
`scripts/instalador-variantes.sh [servidor|mirada|full]` arma las tres, en sus dos medios.
diff --git a/web/takana-os.net/index.html b/web/takana-os.net/index.html
index 2ad6beaf..c7132158 100644
--- a/web/takana-os.net/index.html
+++ b/web/takana-os.net/index.html
@@ -48,15 +48,32 @@ body{background:var(--fondo);color:var(--texto);font:17px/1.62 var(--sans);
p{margin:0 0 1rem}
a{color:inherit;text-decoration:none}
h1,h2,h3{font-weight:600;letter-spacing:-.01em;line-height:1.15}
-.variantes{width:100%;border-collapse:collapse;margin:1rem 0;font-size:.92rem}
-.variantes th{text-align:left;font-weight:600;font-size:.78rem;letter-spacing:.06em;text-transform:uppercase;color:var(--tenue);padding:.4rem .6rem;border-bottom:1px solid var(--linea)}
-.variantes td{padding:.55rem .6rem;border-bottom:1px solid var(--linea);vertical-align:top}
-.variantes td:first-child{white-space:nowrap}
-.variantes td:nth-child(3),.variantes td:nth-child(4){white-space:nowrap}
-.baja{display:block;font-family:var(--mono);font-size:.82rem;line-height:1.4;text-decoration:none;border-bottom:0}
-.baja:hover{text-decoration:underline}
-.baja em{display:block;font-family:var(--sans);font-style:normal;font-size:.76rem;color:var(--tenue)}
-.sinmedio{display:block;font-size:.8rem;color:var(--debil)}
+/* el selector de variante: nombre, qué es, y entre llaves lo que trae */
+.selector{display:grid;grid-template-columns:repeat(auto-fit,minmax(176px,1fr));gap:.5rem;
+ margin:1.5rem 0 1.7rem}
+.opcion{text-align:left;background:var(--papel);border:1px solid var(--linea2);border-radius:12px;
+ padding:.72rem .85rem;cursor:pointer;font:inherit;color:var(--texto);
+ transition:border-color .15s,box-shadow .15s}
+.opcion:hover{border-color:var(--acento)}
+.opcion.on{border-color:var(--acento);box-shadow:inset 0 0 0 1px var(--acento)}
+.opcion .nom{display:block;font:500 .95rem/1.2 var(--mono)}
+.opcion.on .nom{color:var(--acento)}
+.opcion .que{display:block;font-size:.8rem;color:var(--tenue);margin-top:.18rem}
+.opcion .trae{display:block;font:.72rem/1.35 var(--mono);color:var(--debil);margin-top:.32rem}
+
+/* cada bloque de comandos: rótulo, peso a la derecha, y su botón de copiar */
+.bloque{margin:0 0 1.2rem}
+.rotulo{display:flex;align-items:baseline;gap:.5rem;margin:0 0 .38rem;
+ font:.7rem/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;color:var(--debil)}
+.rotulo .peso{margin-left:auto;letter-spacing:0;text-transform:none;color:var(--tenue)}
+.codigo{position:relative}
+.codigo pre{margin:0;padding-right:5.4rem}
+.copiar{position:absolute;top:.5rem;right:.5rem;font:500 .7rem/1 var(--sans);color:var(--tenue);
+ background:var(--papel);border:1px solid var(--linea2);border-radius:8px;padding:.35rem .58rem;
+ cursor:pointer;transition:color .15s,border-color .15s}
+.copiar:hover,.copiar.ok{color:var(--acento);border-color:var(--acento)}
+pre a{color:var(--acento);text-decoration:underline;text-underline-offset:2px}
+.solousb{font:.8rem/1.4 var(--sans);color:var(--debil);margin:0 0 1.2rem}
code{font:.86em/1.5 var(--mono);background:var(--papel2);border:1px solid var(--linea);
border-radius:5px;padding:.08em .38em}
:root[data-lang="es"] [data-l="en"],:root[data-lang="en"] [data-l="es"]{display:none!important}
@@ -207,11 +224,11 @@ footer.pie{border-top:1px solid var(--linea);background:var(--papel);padding:2.6
<header class="barra"><div class="envoltura">
<a class="marca" href="/"><svg class="simbolo" viewBox="0 0 748 748"><use href="#tocapu"/></svg>takana</a>
<nav class="enlaces">
+ <a href="#descargar"><span data-l="es">Descargar</span><span data-l="en">Download</span></a>
<a href="#pisos"><span data-l="es">Los dos pisos</span><span data-l="en">The two floors</span></a>
<a href="#decisiones"><span data-l="es">Las decisiones</span><span data-l="en">The decisions</span></a>
- <a href="#codigo"><span data-l="es">El código</span><span data-l="en">The code</span></a>
<a href="#estado"><span data-l="es">El estado</span><span data-l="en">State</span></a>
- <a href="#paquetes"><span data-l="es">Paquetes</span><span data-l="en">Packages</span></a>
+ <a href="#repositorios"><span data-l="es">Repositorios</span><span data-l="en">Repositories</span></a>
</nav>
<div class="perillas">
<button class="perilla" data-poner-lang="es">ES</button>
@@ -227,113 +244,66 @@ footer.pie{border-top:1px solid var(--linea);background:var(--papel);padding:2.6
<h1>takana</h1>
</div>
<p class="lema">
- <span data-l="es">Una distribución de Linux con dos pisos: abajo un laboratorio hermético que compila todo desde fuente y guarda cada artefacto por su hash; arriba un Linux clásico y mutable donde se pueden romper cosas y volver atrás.</span>
- <span data-l="en">A Linux distribution with two floors: downstairs a hermetic laboratory that compiles everything from source and keeps every artefact by its hash; upstairs a classic, mutable Linux where you can break things and go back.</span>
+ <span data-l="es">Una distribución de Linux de dos pisos. Abajo, una fábrica cerrada: todo desde su código fuente, siempre idéntico, con su origen comprobable. Arriba, un sistema corriente: tuyo, modificable, reversible.</span>
+ <span data-l="en">A Linux distribution with two floors. Downstairs, a closed factory: everything from its own source code, always identical, its origin checkable. Upstairs, an ordinary system: yours, changeable, reversible.</span>
</p>
<div class="botones">
- <a class="boton lleno" href="#instalar"><span data-l="es">Instalar</span><span data-l="en">Install</span></a>
- <a class="boton" href="https://git.gioser.net/sergio/takana"><span data-l="es">El repositorio</span><span data-l="en">The repository</span> ↗</a>
- <a class="boton" href="#paquetes"><span data-l="es">Paquetes</span><span data-l="en">Packages</span></a>
+ <a class="boton lleno" href="#descargar"><span data-l="es">Descargar</span><span data-l="en">Download</span></a>
+ <a class="boton" href="#repositorios"><span data-l="es">El repositorio</span><span data-l="en">The repository</span></a>
<a class="boton" href="https://tawasuyu.net">tawasuyu.net ↗</a>
</div>
</div></section>
-<section class="franja" id="instalar"><div class="envoltura">
- <p class="sello"><svg class="simbolo" viewBox="0 0 748 748"><use href="#tocapu"/></svg><span data-l="es">descargar · un archivo</span><span data-l="en">download · one file</span></p>
- <h2><span data-l="es">Un archivo, y sabe hacer todo</span><span data-l="en">One file, and it knows how to do everything</span></h2>
- <p>
- <span data-l="es">No hay un ISO que grabar ni un árbol que copiar: se baja <strong>un fichero</strong>, se le da permiso y se corre. Adentro viene todo —el programa, el instalador que corre en RAM y su propio kernel— así que <strong>no baja nada de internet mientras instala</strong>. Un instalador de sistema que necesita red falla justo donde más caro sale: en la máquina que todavía no tiene sistema.</span>
- <span data-l="en">There is no ISO to burn and no tree to copy: you download <strong>one file</strong>, make it executable and run it. Everything travels inside — the program, the installer that runs in RAM and its own kernel — so it <strong>downloads nothing from the internet while installing</strong>. A system installer that needs the network fails exactly where it costs most: on the machine that has no system yet.</span>
- </p>
-
-<pre><span class="p">$</span> curl -LO https://takana-os.net/descargas/takana-instalador-mirada.sh
-<span class="p">$</span> chmod +x takana-instalador-mirada.sh
-<span class="p">$</span> sudo ./takana-instalador-mirada.sh</pre>
-
- <p>
- <span data-l="es">Eso hace las tres cosas por orden: comprueba si esta máquina puede instalarse <em>sin USB</em>, muestra el terreno —cada partición, su tamaño, qué hay dentro y si se puede usar— y recién entonces pregunta. Lo cifrado, lo de Windows, la swap, las particiones de arranque y lo que está montado <strong>no se ofrecen</strong>, y se muestran igual con el motivo escrito al lado.</span>
- <span data-l="en">It does three things in order: it checks whether this machine can be installed <em>without a USB</em>, it shows the terrain — every partition, its size, what is inside it and whether it can be used — and only then it asks. Encrypted volumes, Windows volumes, swap, boot partitions and anything mounted are <strong>never offered</strong>, and are shown anyway with the reason written next to them.</span>
- </p>
-
- <p class="nota">
- <span data-l="es"><strong>Sin USB</strong> quiere decir que el Linux que estás usando salta al instalador en memoria y suelta su propio disco. Si el kernel de esa máquina no lo permite, el instalador lo dice y explica por qué en vez de fallar a mitad. Antes de escribir nada pide un «si» escrito, y después del salto vuelve a mostrar el terreno y a preguntar: son dos consentimientos para dos cosas distintas.</span>
- <span data-l="en"><strong>Without a USB</strong> means the Linux you are using jumps into the in-memory installer and releases its own disk. If that machine's kernel does not allow it, the installer says so and explains why instead of failing halfway. It asks for a typed «si» before writing anything, and after the jump it shows the terrain and asks again: two consents for two different things.</span>
- </p>
-
- <h3><span data-l="es">Tres variantes</span><span data-l="en">Three variants</span></h3>
- <p>
- <span data-l="es">La diferencia es <strong>qué sistema se instala</strong>, no cómo. Las cuatro traen el mismo instalador y el mismo censo; cambia el tamaño de lo que copian al disco.</span>
- <span data-l="en">The difference is <strong>which system gets installed</strong>, not how. All four carry the same installer and the same survey; what changes is the size of what they copy to the disk.</span>
- </p>
-
- <table class="variantes">
- <tr>
- <th><span data-l="es">variante</span><span data-l="en">variant</span></th>
- <th><span data-l="es">qué trae</span><span data-l="en">what it carries</span></th>
- <th><span data-l="es">un archivo</span><span data-l="en">one file</span></th>
- <th><span data-l="es">imagen USB</span><span data-l="en">USB image</span></th>
- </tr>
- <tr>
- <td><code>base</code></td>
- <td><span data-l="es">el piso de arranque y nada más: arranca a una consola</span><span data-l="en">the boot floor and nothing else: it boots to a console</span></td>
- <td><a class="baja" href="/descargas/takana-instalador-base.sh">takana-instalador-base.sh<em>137 MiB</em></a></td>
- <td><a class="baja" href="/descargas/takana-instalador-usb-base.img">takana-instalador-usb-base.img<em>519 MiB</em></a></td>
- </tr>
- <tr>
- <td><code>mirada</code></td>
- <td><span data-l="es">+ el userland completo + el escritorio propio de la suite</span><span data-l="en">+ the full userland + the suite's own desktop</span></td>
- <td><a class="baja" href="/descargas/takana-instalador-mirada.sh">takana-instalador-mirada.sh<em>524 MiB</em></a></td>
- <td><a class="baja" href="/descargas/takana-instalador-usb-mirada.img">takana-instalador-usb-mirada.img<em>1,6 GiB</em></a></td>
- </tr>
- <tr>
- <td><code>servidor</code></td>
- <td><span data-l="es">+ el userland completo + los servicios. <strong>El archivo único trae el servidor mínimo</strong> —los mismos servicios, sin compilador ni toolbox— porque carga el sistema en memoria; <strong>el USB trae el servidor entero</strong>, que no tiene ese límite.</span><span data-l="en">+ the full userland + the services. <strong>The single file carries the minimal server</strong> — same services, no compiler and no toolbox — because it loads the system into memory; <strong>the USB carries the full server</strong>, which has no such limit.</span></td>
- <td><a class="baja" href="/descargas/takana-instalador-servidor.sh">takana-instalador-servidor.sh<em>580 MiB</em></a></td>
- <td><a class="baja" href="/descargas/takana-instalador-usb-servidor.img">takana-instalador-usb-servidor.img<em>3,2 GiB</em></a></td>
- </tr>
- <tr>
- <td><code>full</code></td>
- <td><span data-l="es">todo lo anterior junto, más el toolbox de línea de comandos</span><span data-l="en">all of the above together, plus the command-line toolbox</span></td>
- <td><span class="sinmedio" data-l="es">no entra en memoria: sólo USB</span><span class="sinmedio" data-l="en">does not fit in memory: USB only</span></td>
- <td><a class="baja" href="/descargas/takana-instalador-usb-full.img">takana-instalador-usb-full.img<em>3,5 GiB</em></a></td>
- </tr>
- </table>
-
- <p class="nota">
- <span data-l="es">⚠ <strong>El archivo único carga el instalador ENTERO en memoria</strong> para poder soltar el disco, así que las variantes grandes piden bastante RAM — y si no entra, el instalador lo dice y no lo intenta. El USB no tiene ese límite: corre desde el propio pendrive. Se llama <code>.sh</code> porque <em>es</em> un guion de shell: una cabecera con el sistema pegado detrás, que se puede leer con <code>head</code> antes de correrlo.</span>
- <span data-l="en">⚠ <strong>The single file loads the WHOLE installer into memory</strong> so it can release the disk, so the larger variants need a fair amount of RAM — and if it does not fit, the installer says so instead of trying. The USB has no such limit: it runs from the stick itself. It is called <code>.sh</code> because it <em>is</em> a shell script: a header with the system appended to it, readable with <code>head</code> before you run it.</span>
- </p>
-
-<pre><span class="p">$</span> curl -sO https://takana-os.net/descargas/takana-instalador-mirada.sh.sha256
-<span class="p">$</span> sha256sum -c takana-instalador-mirada.sh.sha256</pre>
-
- <p class="nota">
- <span data-l="es">Cada descarga publica su <code>.sha256</code> al lado, con el mismo nombre. Ése comprueba que la bajada llegó entera; el que el fichero lleva <em>adentro</em> comprueba su propio contenido antes de desempaquetarlo, y son dos cosas distintas a propósito.</span>
- <span data-l="en">Every download publishes its <code>.sha256</code> next to it, under the same name. That one checks the download arrived whole; the one the file carries <em>inside</em> checks its own contents before unpacking, and they are deliberately two different things.</span>
- </p>
+<section class="franja" id="descargar"><div class="envoltura">
+ <p class="sello"><svg class="simbolo" viewBox="0 0 748 748"><use href="#tocapu"/></svg><span data-l="es">01 · descargar</span><span data-l="en">01 · download</span></p>
+ <h2><span data-l="es">Descargar</span><span data-l="en">Download</span></h2>
+
+ <div class="selector" id="variantes" role="group" aria-label="variante">
+ <button class="opcion" data-v="base" type="button">
+ <span class="nom">base</span>
+ <span class="que"><span data-l="es">sólo el arranque</span><span data-l="en">boot only</span></span>
+ <span class="trae">{<span data-l="es">consola</span><span data-l="en">console</span>}</span>
+ </button>
+ <button class="opcion" data-v="mirada" type="button">
+ <span class="nom">mirada</span>
+ <span class="que"><span data-l="es">el escritorio de la suite</span><span data-l="en">the suite's desktop</span></span>
+ <span class="trae">{userland + mirada}</span>
+ </button>
+ <button class="opcion" data-v="servidor" type="button">
+ <span class="nom">servidor</span>
+ <span class="que"><span data-l="es">la máquina que sirve</span><span data-l="en">the serving machine</span></span>
+ <span class="trae">{userland + <span data-l="es">servicios</span><span data-l="en">services</span>}</span>
+ </button>
+ <button class="opcion" data-v="full" type="button">
+ <span class="nom">full</span>
+ <span class="que"><span data-l="es">todo junto</span><span data-l="en">everything at once</span></span>
+ <span class="trae">{userland + cli + mirada, sway, cosmic, kde + <span data-l="es">servicios</span><span data-l="en">services</span>}</span>
+ </button>
+ </div>
- <h3><span data-l="es">Y si esta máquina no puede saltar: el USB</span><span data-l="en">And if this machine cannot jump: the USB</span></h3>
- <p>
- <span data-l="es">El salto pide tres cosas del kernel que ya está corriendo, y cualquiera puede faltar: soporte de <code>kexec</code>, ser root, y que Secure Boot no esté bloqueando. Cuando falta alguna, el instalador lo dice y explica cuál. Para ese caso está la <strong>imagen USB</strong>, que es el mismo instalador llegando por otro camino — el mismo censo y las mismas guardas.</span>
- <span data-l="en">The jump asks three things of the kernel already running, and any of them can be missing: <code>kexec</code> support, being root, and Secure Boot not getting in the way. When one is missing the installer says so and explains which. For that case there is the <strong>USB image</strong>, which is the same installer arriving by another route — the same survey and the same guards.</span>
- </p>
+ <div class="bloque" id="bloque-sh">
+ <p class="rotulo"><span data-l="es">un archivo</span><span data-l="en">one file</span><span class="peso" id="peso-sh"></span></p>
+ <div class="codigo"><pre id="cmd-sh"></pre></div>
+ </div>
+ <p class="solousb" id="solo-usb" hidden><span data-l="es">sin archivo único — sólo USB</span><span data-l="en">no single file — USB only</span></p>
-<pre><span class="p">$</span> curl -LO https://takana-os.net/descargas/takana-instalador-usb-mirada.img
-<span class="p">$</span> sudo dd if=takana-instalador-usb-mirada.img of=/dev/sdX bs=4M oflag=sync status=progress</pre>
+ <div class="bloque">
+ <p class="rotulo"><span data-l="es">imagen USB</span><span data-l="en">USB image</span><span class="peso" id="peso-img"></span></p>
+ <div class="codigo"><pre id="cmd-img"></pre></div>
+ </div>
- <p class="nota">
- <span data-l="es">Arranca por la ruta de medios removibles del firmware: no hay nada que registrar y no toca la NVRAM hasta que vos elegís instalar. El medio desde el que arrancaste <strong>nunca se ofrece como destino</strong>. Si la máquina no tiene pantalla y la estás administrando por puerto serie, arrancá con <code>takana.console=/dev/ttyS0</code>.</span>
- <span data-l="en">It boots through the firmware's removable-media path: there is nothing to register and it does not touch NVRAM until you choose to install. The medium you booted from is <strong>never offered as a target</strong>. If the machine has no screen and you are driving it over a serial port, boot with <code>takana.console=/dev/ttyS0</code>.</span>
- </p>
+ <div class="bloque">
+ <p class="rotulo"><span data-l="es">desde el código</span><span data-l="en">from source</span></p>
+ <div class="codigo"><pre>$ git clone https://git.gioser.net/sergio/takana.git
+<span class="p">$</span> cd takana && cargo build --release
+<span class="p">$</span> ./target/release/takana --help</pre></div>
+ </div>
- <p class="nota">
- <span data-l="es">El fichero verifica su propio contenido antes de desempaquetarlo, y si la máquina no tiene con qué calcular un sha256 lo <em>dice</em> en vez de saltárselo en silencio. Con <code>--check</code> y <code>--survey</code> mira y no toca nada; con <code>--extraer DIR</code> sólo se desempaqueta, para leer antes de correr. Hace falta un firmware UEFI y una partición de al menos 2 GiB que se pueda perder; nada más se modifica.</span>
- <span data-l="en">The file verifies its own contents before unpacking them, and if the machine has no way to compute a sha256 it <em>says so</em> instead of skipping it silently. With <code>--check</code> and <code>--survey</code> it looks and touches nothing; with <code>--extraer DIR</code> it only unpacks, so you can read before running. It needs UEFI firmware and one partition of at least 2 GiB that you can afford to lose; nothing else is modified.</span>
- </p>
+ <noscript><p class="nota"><span data-l="es">Las descargas se arman con JavaScript. Sin él: takana-os.net/descargas/</span><span data-l="en">Downloads are assembled with JavaScript. Without it: takana-os.net/descargas/</span></p></noscript>
</div></section>
<section class="franja" id="pisos"><div class="envoltura">
- <p class="sello"><svg class="simbolo" viewBox="0 0 748 748"><use href="#tocapu"/></svg><span data-l="es">01 · los dos pisos</span><span data-l="en">01 · the two floors</span></p>
+ <p class="sello"><svg class="simbolo" viewBox="0 0 748 748"><use href="#tocapu"/></svg><span data-l="es">02 · los dos pisos</span><span data-l="en">02 · the two floors</span></p>
<h2><span data-l="es">Por qué dos pisos y no uno</span><span data-l="en">Why two floors and not one</span></h2>
<p>
<span data-l="es">Una distribución inmutable da reproducibilidad y quita la máquina: no se puede tocar nada sin aprender antes un lenguaje declarativo. Una clásica deja tocar todo y no sabe decir de dónde salió un binario. <strong>takana pone las dos, en pisos separados.</strong></span>
@@ -354,11 +324,11 @@ footer.pie{border-top:1px solid var(--linea);background:var(--papel);padding:2.6
</div></section>
<section class="franja" id="decisiones"><div class="envoltura">
- <p class="sello"><svg class="simbolo" viewBox="0 0 748 748"><use href="#tocapu"/></svg><span data-l="es">02 · las decisiones</span><span data-l="en">02 · the decisions</span></p>
+ <p class="sello"><svg class="simbolo" viewBox="0 0 748 748"><use href="#tocapu"/></svg><span data-l="es">03 · las decisiones</span><span data-l="en">03 · the decisions</span></p>
<h2><span data-l="es">Diez decisiones, y contra qué se tomaron</span><span data-l="en">Ten decisions, and what they were taken against</span></h2>
<p>
- <span data-l="es">La primera es la de arriba —los dos pisos— y de ella cuelga todo lo demás. Estas son las otras diez. De cada una: <strong>en qué se aparta de lo que hace una distro tradicional</strong>, <strong>qué implica por dentro</strong> y <strong>qué quiere decir sin jerga</strong>. Ninguna es gratis; todas se pagan en algún lado, y acá está dicho dónde.</span>
- <span data-l="en">The first one is above — the two floors — and everything else hangs off it. These are the other ten. For each: <strong>how it departs from what a traditional distro does</strong>, <strong>what it involves under the hood</strong> and <strong>what it means without jargon</strong>. None is free; each is paid for somewhere, and that is said here.</span>
+ <span data-l="es">La primera es la de arriba, los dos pisos. Estas son las otras diez.</span>
+ <span data-l="en">The first one is above: the two floors. These are the other ten.</span>
</p>
<div class="decisiones">
<article class="decision">
@@ -483,43 +453,6 @@ footer.pie{border-top:1px solid var(--linea);background:var(--papel);padding:2.6
</div>
</div></section>
-<section class="franja" id="codigo"><div class="envoltura">
- <p class="sello"><svg class="simbolo" viewBox="0 0 748 748"><use href="#tocapu"/></svg><span data-l="es">03 · el código</span><span data-l="en">03 · the code</span></p>
- <h2><span data-l="es">Dónde vive el repositorio</span><span data-l="en">Where the repository lives</span></h2>
- <p>
- <span data-l="es">Todo —el CLI, el laboratorio, el catálogo de recetas y el diseño completo— está en un solo repositorio, bajo licencia MIT.</span>
- <span data-l="en">Everything — the CLI, the laboratory, the recipe catalogue and the full design — lives in a single repository, under the MIT licence.</span>
- </p>
-
- <div class="direccion">
- <p class="etiqueta"><span data-l="es">repositorio de código</span><span data-l="en">code repository</span></p>
- <a class="url" href="https://git.gioser.net/sergio/takana">https://git.gioser.net/sergio/takana</a>
- </div>
-
-<pre><span class="p">$</span> git clone https://git.gioser.net/sergio/takana.git
-<span class="p">$</span> cd takana && cargo build --release
-<span class="p">$</span> ./target/release/takana --help</pre>
-
- <p>
- <span data-l="es">El repositorio no trae binarios: trae <strong>recetas</strong>. Cada una fija la fuente upstream por commit o por sha256, y el hash del artefacto sale de la receta entera —fuente, compilador, banderas, fases y los hashes de sus dependencias—, así que se puede saber qué va a salir <em>antes</em> de compilar:</span>
- <span data-l="en">The repository ships no binaries: it ships <strong>recipes</strong>. Each one pins the upstream source by commit or sha256, and the artefact hash is derived from the whole recipe — source, compiler, flags, phases and the hashes of its dependencies — so you can know what will come out <em>before</em> building it:</span>
- </p>
-
-<pre><span class="p">$</span> takana hash ripgrep <span class="c"># el ArtifactHash vigente, sin construir</span>
-<span class="p">$</span> takana build ripgrep <span class="c"># compila aislado y sella en el store</span>
-<span class="p">$</span> takana why-differs a/ b/ <span class="c"># si dos builds no coinciden, NOMBRA la causa</span></pre>
-
- <div class="marco">
- <h3><span data-l="es">Cómo está repartido</span><span data-l="en">How it is laid out</span></h3>
- <ul class="limpia">
- <li><code>crates/</code> — <span data-l="es">el CLI, el laboratorio de build, el demonio, el diario y el overlay.</span><span data-l="en">the CLI, the build lab, the daemon, the journal and the overlay.</span></li>
- <li><code>recipes/</code> — <span data-l="es">el catálogo: una receta <code>.toml</code> por paquete.</span><span data-l="en">the catalogue: one <code>.toml</code> recipe per package.</span></li>
- <li><code>docs/</code> — <span data-l="es">el diseño entero (SDD y ADR). Empieza por <code>00-vision.md</code>.</span><span data-l="en">the entire design (SDDs and ADRs). Start at <code>00-vision.md</code>.</span></li>
- <li><code>scripts/</code> — <span data-l="es">la granja de compilación, la cosecha y los arneses de verificación.</span><span data-l="en">the build farm, the harvest and the verification harnesses.</span></li>
- </ul>
- </div>
-</div></section>
-
<section class="franja" id="estado"><div class="envoltura">
<p class="sello"><svg class="simbolo" viewBox="0 0 748 748"><use href="#tocapu"/></svg><span data-l="es">04 · el estado, medido</span><span data-l="en">04 · the state, measured</span></p>
<h2><span data-l="es">Qué anda y qué no</span><span data-l="en">What works and what doesn't</span></h2>
@@ -552,31 +485,59 @@ footer.pie{border-top:1px solid var(--linea);background:var(--papel);padding:2.6
</p>
</div></section>
-<section class="franja" id="paquetes"><div class="envoltura">
- <p class="sello"><svg class="simbolo" viewBox="0 0 748 748"><use href="#tocapu"/></svg><span data-l="es">05 · los paquetes</span><span data-l="en">05 · the packages</span></p>
- <h2><span data-l="es">El repositorio de paquetes</span><span data-l="en">The package repository</span></h2>
- <p>
- <span data-l="es">El índice está firmado y cada paquete trae la <em>receta</em> de su contenido, no el binario cocinado: <code>install</code> resuelve el nombre, verifica la firma del índice y <strong>reconstruye desde fuente</strong> antes de hidratar. Un origen de descarga no necesita ser de confianza — lo que se verifica es el contenido.</span>
- <span data-l="en">The index is signed and each package carries the <em>recipe</em> for its content, not the cooked binary: <code>install</code> resolves the name, verifies the index signature and <strong>rebuilds from source</strong> before hydrating. A download origin does not need to be trusted — what gets verified is the content.</span>
- </p>
+<section class="franja" id="repositorios"><div class="envoltura">
+ <p class="sello"><svg class="simbolo" viewBox="0 0 748 748"><use href="#tocapu"/></svg><span data-l="es">05 · los repositorios</span><span data-l="en">05 · the repositories</span></p>
+ <h2><span data-l="es">Los repositorios</span><span data-l="en">The repositories</span></h2>
+
+ <div class="direccion">
+ <p class="etiqueta"><span data-l="es">código · licencia MIT</span><span data-l="en">code · MIT licence</span></p>
+ <a class="url" href="https://git.gioser.net/sergio/takana">https://git.gioser.net/sergio/takana</a>
+ </div>
<div class="direccion">
- <p class="etiqueta"><span data-l="es">repositorio de paquetes</span><span data-l="en">package repository</span></p>
+ <p class="etiqueta"><span data-l="es">paquetes · índice firmado</span><span data-l="en">packages · signed index</span></p>
<a class="url" href="/repo/">https://takana-os.net/repo/</a>
</div>
-<pre><span class="p">$</span> takana repo list --repo https://takana-os.net/repo
+ <div class="marco">
+ <h3><span data-l="es">Cómo está repartido</span><span data-l="en">How it is laid out</span></h3>
+ <ul class="limpia">
+ <li><code>crates/</code> — <span data-l="es">el CLI, el laboratorio de build, el demonio, el diario y el overlay.</span><span data-l="en">the CLI, the build lab, the daemon, the journal and the overlay.</span></li>
+ <li><code>recipes/</code> — <span data-l="es">el catálogo: una receta <code>.toml</code> por paquete.</span><span data-l="en">the catalogue: one <code>.toml</code> recipe per package.</span></li>
+ <li><code>docs/</code> — <span data-l="es">el diseño entero (SDD y ADR). Empieza por <code>00-vision.md</code>.</span><span data-l="en">the entire design (SDDs and ADRs). Start at <code>00-vision.md</code>.</span></li>
+ <li><code>scripts/</code> — <span data-l="es">la granja de compilación, la cosecha y los arneses de verificación.</span><span data-l="en">the build farm, the harvest and the verification harnesses.</span></li>
+ </ul>
+ </div>
+</div></section>
+
+<section class="franja" id="llamar"><div class="envoltura">
+ <p class="sello"><svg class="simbolo" viewBox="0 0 748 748"><use href="#tocapu"/></svg><span data-l="es">06 · cómo se llama</span><span data-l="en">06 · how it is called</span></p>
+ <h2><span data-l="es">Cómo se llama</span><span data-l="en">How it is called</span></h2>
+
+ <div class="bloque">
+ <p class="rotulo"><span data-l="es">el laboratorio</span><span data-l="en">the laboratory</span></p>
+ <div class="codigo"><pre>$ takana hash ripgrep <span class="c"># <span data-l="es">el hash vigente, sin construir</span><span data-l="en">the current hash, without building</span></span>
+<span class="p">$</span> takana build ripgrep <span class="c"># <span data-l="es">compila aislado y sella en el almacén</span><span data-l="en">builds sandboxed and seals into the store</span></span>
+<span class="p">$</span> takana why-differs a/ b/ <span class="c"># <span data-l="es">nombra la causa de una diferencia</span><span data-l="en">names the cause of a difference</span></span></pre></div>
+ </div>
+
+ <div class="bloque">
+ <p class="rotulo"><span data-l="es">los paquetes</span><span data-l="en">packages</span></p>
+ <div class="codigo"><pre>$ takana repo list --repo https://takana-os.net/repo
<span class="p">$</span> takana repo verify --repo https://takana-os.net/repo --trust ./trust
-<span class="p">$</span> takana install age --repo https://takana-os.net/repo --trust ./trust</pre>
+<span class="p">$</span> takana install age --repo https://takana-os.net/repo --trust ./trust</pre></div>
+ </div>
- <p class="nota">
- <span data-l="es">Hoy publica la clausura del perfil <code>servidor</code>. El mismo repo se sirve también en <a href="https://repo.gioser.net/">repo.gioser.net</a>; <code>--repo</code> acepta varios orígenes separados por coma y los prueba en orden.</span>
- <span data-l="en">It currently publishes the closure of the <code>servidor</code> profile. The same repo is also served at <a href="https://repo.gioser.net/">repo.gioser.net</a>; <code>--repo</code> takes several comma-separated origins and tries them in order.</span>
- </p>
+ <div class="bloque">
+ <p class="rotulo"><span data-l="es">el sistema vivo</span><span data-l="en">the live system</span></p>
+ <div class="codigo"><pre>$ takana try <span class="c"># <span data-l="es">abre el overlay sobre el sistema real</span><span data-l="en">opens the overlay over the real system</span></span>
+<span class="p">$</span> takana journal <span class="c"># <span data-l="es">lo que cambiaste a mano, registrado</span><span data-l="en">what you changed by hand, recorded</span></span>
+<span class="p">$</span> takana commit <span class="c"># <span data-l="es">promueve · <code>discard</code> lo descarta</span><span data-l="en">promotes · <code>discard</code> throws it away</span></span></pre></div>
+ </div>
</div></section>
<section class="franja"><div class="envoltura">
- <p class="sello"><svg class="simbolo" viewBox="0 0 748 748"><use href="#tocapu"/></svg><span data-l="es">06 · la frontera</span><span data-l="en">06 · the border</span></p>
+ <p class="sello"><svg class="simbolo" viewBox="0 0 748 748"><use href="#tocapu"/></svg><span data-l="es">07 · la frontera</span><span data-l="en">07 · the border</span></p>
<h2><span data-l="es">Qué tiene que ver con tawasuyu</span><span data-l="en">How it relates to tawasuyu</span></h2>
<p>
<span data-l="es"><strong>takana es el suelo; tawasuyu es lo que se para encima.</strong> No son dos mundos sueltos: comparten el almacén direccionado por contenido (BLAKE3), un bus entre el init de tawasuyu y el demonio de takana con contrato por bytes, el grafo de arranque, y <code>arje</code> —el proceso número uno de tawasuyu— como init de las imágenes, estático contra musl.</span>
@@ -630,9 +591,90 @@ footer.pie{border-top:1px solid var(--linea);background:var(--papel);padding:2.6
document.querySelectorAll('[data-poner-lang]').forEach(function(b){
b.addEventListener('click', function(){
r.dataset.lang=b.dataset.ponerLang; pintar();
+ if(SEL) pinta(vAhora); // la coma decimal del peso cambia con el idioma
try{ localStorage.setItem('takana-lang', r.dataset.lang); }catch(e){}
});
});
+
+ /* ── las descargas se arman ACÁ, no en el HTML ──────────────────────────────────
+ Ninguna URL de instalador está en el documento: se compone al pulsar el
+ selector. Un rastreador que lee el HTML no encuentra ninguna, y estos ficheros
+ pesan de 138 MiB a 3,4 GiB — no son para que se los baje un bot. */
+ var SEL = document.getElementById('variantes'), vAhora = 'mirada', pinta;
+ if (SEL) {
+ var DIR = '/de'+'scargas/', PRE = 'takana-'+'instalador-';
+ var PESO = { base: {sh:144662539, img:544210944},
+ mirada: {sh:549945194, img:1680867328},
+ servidor: {sh:608553087, img:3334471680},
+ full: {sh:0, img:3647995904} };
+ var bSh=document.getElementById('bloque-sh'), soloUsb=document.getElementById('solo-usb'),
+ preSh=document.getElementById('cmd-sh'), preImg=document.getElementById('cmd-img'),
+ pSh=document.getElementById('peso-sh'), pImg=document.getElementById('peso-img');
+
+ function tam(b){
+ if(!b) return '';
+ var coma = r.dataset.lang==='es' ? ',' : '.';
+ return b>=1073741824 ? (b/1073741824).toFixed(1).replace('.',coma)+' GiB'
+ : Math.round(b/1048576)+' MiB';
+ }
+ function esc(t){ return t.replace(/&/g,'&').replace(/</g,'<'); }
+ function cmd(t,u){ return '<span class="p">$</span> '+esc(t)+(u?'<a href="'+u+'">'+esc(u)+'</a>':''); }
+ /* el peso REAL, por si el instalador se reconstruyó: un HEAD lo corrige solo.
+ Si falla, se queda el medido — nunca en blanco. */
+ function pesar(u,donde){ try{
+ fetch(u,{method:'HEAD'}).then(function(res){
+ var n=parseInt(res.headers.get('content-length'),10);
+ if(n>0) donde.textContent=tam(n);
+ })['catch'](function(){});
+ }catch(e){} }
+
+ pinta = function(v){
+ vAhora = v;
+ var raiz=location.protocol+'//'+location.host, sh=PRE+v+'.sh', img=PRE+'usb-'+v+'.img';
+ var hay = !!PESO[v].sh;
+ bSh.hidden = !hay; soloUsb.hidden = hay;
+ if(hay) preSh.innerHTML = [cmd('curl -LO ', raiz+DIR+sh),
+ cmd('chmod +x '+sh),
+ cmd('sudo ./'+sh)].join('\n');
+ preImg.innerHTML = [cmd('curl -LO ', raiz+DIR+img),
+ cmd('sudo dd if='+img+' of=/dev/sdX bs=4M oflag=sync status=progress')].join('\n');
+ pSh.textContent = tam(PESO[v].sh); pImg.textContent = tam(PESO[v].img);
+ if(hay) pesar(DIR+sh,pSh);
+ pesar(DIR+img,pImg);
+ SEL.querySelectorAll('.opcion').forEach(function(b){ b.classList.toggle('on', b.dataset.v===v); });
+ };
+ SEL.querySelectorAll('.opcion').forEach(function(b){
+ b.addEventListener('click', function(){ pinta(b.dataset.v); });
+ });
+ pinta(vAhora);
+ }
+
+ /* un botón de copiar por bloque de comandos, puesto desde acá para no repetirlo
+ diez veces en el HTML. Copia sin el `$` del prompt. */
+ function rotulo(txt_es, txt_en){
+ return '<span data-l="es">'+txt_es+'</span><span data-l="en">'+txt_en+'</span>';
+ }
+ document.querySelectorAll('.codigo').forEach(function(c){
+ var b=document.createElement('button');
+ b.className='copiar'; b.type='button';
+ b.innerHTML=rotulo('copiar','copy');
+ b.addEventListener('click', function(){
+ var t=c.querySelector('pre').innerText.replace(/^\$ /gm,'');
+ var ok=function(){
+ b.classList.add('ok'); b.innerHTML=rotulo('copiado ✓','copied ✓');
+ setTimeout(function(){ b.classList.remove('ok'); b.innerHTML=rotulo('copiar','copy'); },1600);
+ };
+ if(navigator.clipboard && navigator.clipboard.writeText){
+ navigator.clipboard.writeText(t).then(ok,function(){});
+ } else {
+ var ta=document.createElement('textarea'); ta.value=t; document.body.appendChild(ta);
+ ta.select(); try{ document.execCommand('copy'); ok(); }catch(e){}
+ document.body.removeChild(ta);
+ }
+ });
+ c.appendChild(b);
+ });
+
document.getElementById('tema').addEventListener('click', function(){
var oscuro = r.dataset.theme ? r.dataset.theme==='dark'
: matchMedia('(prefers-color-scheme:dark)').matches;