SDD 26 §7.quinquies: el cable tiene dos puntas en dos repos, y hoy no coinciden
La bóveda se commiteó esta mañana con sus cuatro enchufes en orden y no funciona igual. El motivo no está en ninguno de los cuatro: cada función de atuq es un VERBO del host, el host vive en tawasuyu, y `recipes/puriy-costura.toml` lo pinea por commit. Escribir la extensión y subir el pin son dos unidades distintas y la primera se commitea sin la segunda sin que nada proteste. Queda escrito con las dos mediciones y sus controles: el binario SELLADO y vigente tiene «vault» 0 veces contra «cas» 5 —el hermano que tenía que dar positivo, sin el cual el cero no prueba nada— y el pin es ANCESTRO del commit que agregó los verbos. Más la tabla de las diez extensiones: 13 verbos sobre 8, y los únicos tres sin dueño son los de la bóveda; o sea que «cuándo se tocó la receta» no contestaba esto. También queda la trampa del instrumento, que costó más que el vigía: el extractor buscaba `verb: "…"` y la extensión de IA arma el mensaje con el verbo en una VARIABLE, así que encontraba cero y la declaraba sana. De ahí el control de cobertura. Y por qué el pin no subió en el mismo turno, que es lo que hay que leer antes de intentarlo: el `Cargo.lock` de tawasuyu no cierra para `puriy-costura` —11 deps viejas, sin `pacha-boveda`, y `pacha-boveda-daemon` ausente del lock—. Reproducido en árbol limpio del commit: `cargo metadata --locked` muere con «cannot update the lock file» sin nombrar al culpable, tal como la receta avisaba; y `cargo metadata --offline` lo cierra con 37 líneas sin mover una versión de registry. Pero el fichero está `MM` en el clon compartido —otra sesión lo tiene stageado Y modificado, y su árbol YA trae la reparación sin commitear—, así que no se tocó. Con un repo de juguete quedó medido por qué el `--` no alcanza ahí, que es lo contrario de lo que uno supone: con un fichero en MM, `git commit -- <ruta>` commitea EL ÁRBOL, no lo stageado, y el índice ajeno de esa ruta desaparece. El pathspec aísla de lo que el otro dejó en OTRAS rutas; en la ruta que uno nombra, no. Y la unidad 12 entra al plan con lo que le falta dicho: el lock de allá, el pin, el rebuild y el guardián de metal.
This commit is contained in:
@@ -2699,6 +2699,119 @@ extensión va a poder leer el cuerpo de un script. Lo que NO va a poder es ver l
|
||||
por esa vía —`filterResponseData` entrega el documento, no cada `<script>`—, y eso está bien para v1:
|
||||
el ataque que `sct` nombra es la sustitución en el CDN, que es exactamente el caso `<script src>`.
|
||||
|
||||
### 7.quinquies El cable tiene DOS puntas en DOS repos — y hoy no coinciden (2026-09-15)
|
||||
|
||||
La bóveda se commiteó esta mañana (unidad 12, `6f0ba974`): la extensión, la política, el permiso del
|
||||
host, las preferencias, y un guardián que mira los cuatro. Los cuatro estaban bien. **La bóveda no
|
||||
funciona igual**, y el motivo no está en ninguno de esos cuatro sitios.
|
||||
|
||||
Cada función de `atuq` que no es CSS es un **verbo** del host nativo, y el host vive en OTRO REPO:
|
||||
`recipes/puriy-costura.toml` lo pinea por commit de tawasuyu. O sea que el cable tiene dos puntas en
|
||||
dos repos, y que `vault.match` sea un verbo o una cadena que nadie atiende lo decide un `commit =`
|
||||
de un TOML que la extensión nunca menciona. Escribir la extensión y subir el pin son **dos unidades
|
||||
de trabajo distintas**, y la primera se commitea sin la segunda sin que nada proteste.
|
||||
|
||||
**Cómo se ve el fallo, que es por qué merece vigía.** No falla nada. El manifiesto está, la política
|
||||
instala, `connectNative` **conecta** —el host existe y contesta—, la extensión manda `vault.match` y
|
||||
recibe:
|
||||
|
||||
{"ok": false, "error": "verbo desconocido: vault.match"}
|
||||
|
||||
`fondo.js` lee `r.ok !== true`, borra la insignia y se calla. El usuario ve un navegador sin bóveda;
|
||||
un guardián de ficheros ve todo en orden. Es la misma familia que el §6.10 del subcomando sin driver:
|
||||
sellado, con contenido, reproducible… y la función no está.
|
||||
|
||||
**La medición, con su control al lado.** El artefacto vigente (`hash --check` sobre la receta dice
|
||||
`b3:1eb2b692 SELLADO`) contra su propio binario:
|
||||
|
||||
strings del binario sellado → «vault» 0 veces
|
||||
→ «cas» 5 veces ⇐ EL CONTROL
|
||||
|
||||
El cero solo no probaba nada: un `grep` que devuelve cero puede ser una ausencia o un sitio
|
||||
equivocado, y las dos se ven igual. Lo que lo convierte en evidencia es el hermano que TENÍA que dar
|
||||
positivo en el mismo binario. Y desde la fuente sale lo mismo por otro camino: la receta pinea
|
||||
`e19bb0e5`, que `git merge-base --is-ancestor` confirma **ANCESTRO** de `bc6903f9e`, el commit que
|
||||
agregó los verbos. El host sellado es anterior a la bóveda por construcción.
|
||||
|
||||
**Y no se podía deducir mirando la receta.** Las otras nueve extensiones conviven bien con ese mismo
|
||||
pin viejo: 13 verbos sobre 8 extensiones, y los únicos tres sin dueño son los de la bóveda. «Cuándo
|
||||
se tocó la receta por última vez» no contesta esta pregunta.
|
||||
|
||||
| extensión | verbos | ¿el pin los atiende? |
|
||||
|---|---|---|
|
||||
| `archivo` | `archive.add`, `archive.ask`, `archive.search` | ✓ |
|
||||
| **`boveda`** | **`vault.match`, `vault.fill`, `vault.save`** | **✗ los tres** |
|
||||
| `descargas` | `cas.ingest` | ✓ |
|
||||
| `foco` | `focus.state` | ✓ |
|
||||
| `ia` | `ai.ask`, `archive.ask` | ✓ |
|
||||
| `medios` | `media.open` | ✓ |
|
||||
| `sct` | `sct.observe` | ✓ |
|
||||
| `torrent` | `torrent.add` | ✓ |
|
||||
| `inicio`, `proxy` | — | no le hablan al host, a propósito |
|
||||
|
||||
Queda vigilado por `scripts/vigia-atuq-verbos.py`, que corre en un segundo sin construir nada y
|
||||
pregunta `git grep '"<verbo>" =>' <commit> -- '*.rs'` **leyendo del objeto** —sin checkout: el árbol
|
||||
de tawasuyu es compartido y siempre tiene ficheros en vuelo—. El mismo chequeo quedó además dentro
|
||||
de `test-atuq-boveda-coherente.py`, que pasa a decir **cinco** lugares y no cuatro.
|
||||
|
||||
⚠ **Y lo que costó más que el vigía: el extractor de verbos no veía la mitad.** Buscaba `verb: "…"`,
|
||||
que es como lo escribe la bóveda; pero la extensión de IA arma el mensaje con `postMessage({ id,
|
||||
verb: verbo, … })` —el verbo llega por VARIABLE— así que ese patrón encontraba **cero verbos en
|
||||
`ia`** y la declaraba sana sin haber mirado nada. Cero verbos encontrados y cero verbos faltando son
|
||||
el mismo cero con dos causas. De ahí salió un tercer control que no es ni positivo ni negativo sino
|
||||
de **cobertura**: una extensión de la que no se extrae ningún verbo se REPORTA, y las dos que de
|
||||
verdad no le hablan al host están nombradas en el código para que no se confundan con el extractor
|
||||
mudo.
|
||||
|
||||
#### Por qué el pin NO se subió en el mismo turno, y qué hace falta
|
||||
|
||||
El candidato es `be8710cff` —el más nuevo que toca `puriy-costura`, y trae además «la aplicación de
|
||||
la bóveda y el navegador ya pueden convivir», que pinear `bc6903f9e` se saltearía—. **No se puede
|
||||
todavía, y el muro está medido**, no supuesto: el `Cargo.lock` de tawasuyu no cierra para
|
||||
`puriy-costura`. Su entrada en el lock de `main` todavía lista las **once** deps viejas —sin
|
||||
`pacha-boveda`, sin `pacha-cifrador`— y `pacha-boveda-daemon` no está en el lock en absoluto.
|
||||
|
||||
Reproducido en un árbol LIMPIO del commit (`git archive <sha> | tar -x`, que es el procedimiento que
|
||||
la propia receta dejó escrito y que evita que el lock describa «el escritorio de todos»):
|
||||
|
||||
cargo metadata --locked --offline
|
||||
error: cannot update the lock file … because --locked was passed to prevent this
|
||||
|
||||
—y, como la receta avisaba, **no nombra al crate culpable**. La reparación es barata y quedó
|
||||
comprobada en ese mismo árbol limpio: `cargo metadata --offline` cierra el lock con un diff de **37
|
||||
líneas**, todas de contabilidad de deps por ruta, **sin mover una sola versión de registry**.
|
||||
|
||||
**Pero ese fichero no se commiteó, y la razón es la regla 2 de `CLAUDE.md` vista desde el otro lado.**
|
||||
En el clon compartido, `git status` dice `MM Cargo.lock`: otra sesión lo tiene **stageado Y
|
||||
modificado** ahora mismo. Las tres versiones, medidas:
|
||||
|
||||
| dónde | tamaño | deps de `puriy-costura` |
|
||||
|---|---|---|
|
||||
| `main` (`2c40330e4`) | 672 409 B | 11 — no cierra |
|
||||
| el **índice** (stageado por otro) | 671 160 B | 11 — no cierra, y **no es el de `main`** |
|
||||
| el **árbol** de esa sesión | 673 397 B | **18 — cierra** |
|
||||
|
||||
O sea que la reparación ya existe, sin commitear, en el árbol de otro agente. Tocarla es pisarle el
|
||||
trabajo, y el `--` no protege de eso. **Comprobado en un repo de juguete, porque la intuición es la
|
||||
contraria:**
|
||||
|
||||
```sh
|
||||
# f.txt en estado MM: v2 en el índice (del otro), v3 en el árbol (mío)
|
||||
git commit -m … -- f.txt
|
||||
# ⇒ commitea v3 (EL ÁRBOL, no lo stageado)
|
||||
# ⇒ y el índice queda en v3: lo que el otro tenía stageado ahí DESAPARECE
|
||||
```
|
||||
|
||||
El `--` acota **qué rutas** entran al commit y con eso aísla de lo que el otro dejó en OTRAS rutas
|
||||
—que es lo que la regla 2 dice y sigue siendo cierto—; para la ruta que uno nombra, se lleva el
|
||||
árbol y **borra el índice ajeno**. En un repo compartido, un fichero en `MM` que uno no tocó no se
|
||||
commitea ni con pathspec: se avisa.
|
||||
|
||||
⇒ **Pendiente, y no es de takana:** que tawasuyu publique el lock cerrado. Con eso, subir el pin a
|
||||
`be8710cff`, reconstruir (2,4 G de vendoreo del workspace entero, ver la receta) y recién ahí escribir
|
||||
el guardián de METAL de la bóveda —servidor, navegador real, login real, el diálogo de consentimiento
|
||||
a la vista—, que es lo que el commit de la unidad 12 dejó anunciado.
|
||||
|
||||
## 8. Plan, por unidades de trabajo
|
||||
|
||||
Cada una cierra sola, se commitea y se pushea. El orden no es preferencia: cada una destraba a la
|
||||
@@ -2726,6 +2839,7 @@ siguiente.
|
||||
| 9 | **Medios (6.6) ✅ y torrent (6.9) ✅ — 2026-09-10.** El medio lo abre `mpv`; el torrent lo toma `puriy-costura-torrent`, un daemon **propio, configurable y perezoso** que sobrevive al navegador y cosecha al CAS. Medido antes de decidir: la pila de librqbit compila para musl (226 crates), así que la decisión fue «no ahí» y no «no se puede». **Faltan** el foco (6.5) y la IA local (6.7), ésta bloqueada porque el corpus no tiene modelo ni embeddings | 6.5–6.7, 6.9 | 5 ✅ |
|
||||
| 10 | **Foco (6.5) — 2026-09-10.** Entra al corpus la cadena `nftables` (libmnl + libnftnl + nft 1.1.6), que el grafo pedía y nadie había puesto, con dos arreglos de fábrica: el sello de tiempo que rompía la reproducción y un bashismo. Medido con root: el cgroup en foco no sale y el de al lado sí. Y del lado del navegador, la extensión `foco` MUESTRA el estado y **no tiene verbo para apagarlo**. **Falta** quién pone a `atuq` en un cgroup (delegación, decisión de arje) y quién aplica la política (root) | 6.5 | 6 ✅ |
|
||||
| 11 | **Motor de inferencia local (6.7) — 2026-09-11.** Entra `recipes/llama-cpp.toml` (b10901, estática, 199 M, **REPRODUCE**), que resulta ser **un solo muro para dos pendientes**: el §6.7 y la mitad semántica del §6.3 no eran dos problemas, era que el corpus no tenía con qué correr un modelo (`pluma-llm` sólo tiene backends de nube; `rimay-verbo-fastembed` DESCARGA onnxruntime glibc + el modelo). ⚠ Y dejó medido lo que no se podía deducir: **`SOURCE_DATE_EPOCH` —la variable que nos da reproducibilidad— apagaba las SEIS perillas de ISA de ggml**, y el artefacto sellaba y corría con 0 `%ymm`. Ahora van declaradas y el `install` las comprueba. Guardián `scripts/test-llama-cpp.py` con control negativo vivo. **Faltan** el modelo (fuente pineada, no receta), los verbos del host y quién levanta el servidor | 6.7, y la mitad semántica de 6.3 | 5 ✅ |
|
||||
| 12 | **La bóveda (SDD-BOVEDA §8) — a medias, 2026-09-15.** La décima extensión: ofrece la credencial del sitio abierto y no puede sacar una contraseña por su cuenta —`vault.match` contesta títulos y usuarios; la contraseña sale por `vault.fill`, que **pregunta en el escritorio**—. La dirección la pone el chrome, nunca la página. El gestor de Gecko se aparta como VALOR DE ARRANQUE y no como política. ⚠ **No funciona todavía**: los tres verbos existen en tawasuyu y la receta pinea un commit ANTERIOR (§7.quinquies), y el pin está bloqueado por un `Cargo.lock` que no cierra. **Falta**: el lock de allá, el pin, el rebuild, y el guardián de METAL | el gestor de contraseñas de la suite dentro del navegador | 5 ✅ |
|
||||
| 9.a | **Proxy por contenedor ✅ v0.5** — contenedores por política + extensión con `proxy.onRequest` | 6.8, y NO dependía de 5: es API de Firefox | — |
|
||||
|
||||
Las unidades 2 y 4 son **paralelizables**: la toolchain no toca el chrome y el chrome no toca la
|
||||
|
||||
Reference in New Issue
Block a user