atuq v0.5: proxy por contenedor — el primer diferenciador del §6 que se paga entero
Es el único de la lista del SDD 26 §6 que no pasa por el host de native
messaging del §7: es API de Firefox y nada más. Cada contenedor —Personal,
Trabajo, Banco, Compras— puede salir por su propio proxy.
Tres piezas y ninguna alcanza sola: `atuq.cfg` prende los contenedores (vienen
apagados), `policies.json` los CREA con `Containers.Default` —el único
mecanismo que los pone en un perfil NUEVO— y deja la config de fábrica en
`3rdparty.Extensions`, y `extensions/proxy/` los enruta con `proxy.onRequest`,
que es lo único que ve el `cookieStoreId` de la petición.
Las cuatro se comprobaron DENTRO del artefacto de firefox antes de escribir una
línea, no en la documentación de Mozilla: `Containers` y `3rdparty` en el
`policies-schema.json` de browser/omni.ja, `cookieStoreId` en el
`schemas/proxy.json` de omni.ja, y `storage.managed` leyendo
`getExtensionPolicy(id)` en ext-storage.js. Es la regla del §2.sexies: la
pregunta no es si Mozilla lo tiene, es si NUESTRO build lo tiene.
Tres decisiones que valen más que el código:
1. La config se indexa por NOMBRE de contenedor y no por `cookieStoreId`: el id
depende del orden en que se crearon, así que la misma configuración aplicada
a otro perfil apuntaría a otro contenedor.
2. FAIL CLOSED. Un contenedor con proxy configurado que no se pudo honrar no
sale directo: va a un destino cerrado y el navegador muestra el error. Salir
directo sería una fuga silenciosa — la misma familia que el artefacto vacío
de la regla 3, el fallo que llega hasta el final diciendo que todo fue bien.
3. `proxyDNS` PRENDIDO por defecto: sin él la consulta DNS sale por la línea que
se quería evitar. Es la fuga clásica de esta configuración.
Y lo que no promete está arriba de todo en la página de opciones, no en un pie:
separación de tráfico, NO anonimato; para anonimato, Tor Browser. El §4 cumplido
donde el usuario lo lee.
De paso, una verdad que estaba escrita en dos sitios pasa a tener un dueño: el
id de cada extensión sale ahora del `manifest.json` y no de una constante de
rebrand.py, el nombre del XPI se deriva de él, y el `install_url` de la política
se cruza contra la ruta donde el fichero quedó escrito de verdad. El icono se
inyecta desde branding/icons/ en vez de estar copiado byte a byte dentro de cada
extensión. Agregar una tercera extensión es ahora un directorio.
PROBADO, corriendo el árbol en la misma jaula que atuq-nested.sh:
· captura de about:preferences#containers con los cuatro contenedores y sus
iconos, más el containers.json del perfil;
· extensions.json del perfil nombra las dos extensiones;
· `console.info: "atuq/proxy: 4 contenedor(es) enrutado(s)"` — leyó la config
de fábrica por storage.managed Y la casó con los contenedores de la política;
· scripts/test-atuq-politica.py: cinco formas de desincronizar política y XPI,
las cinco matan el build, y el control con la política intacta pasa.
NO probado y dicho por su nombre: que una petición hecha en «Banco» salga por el
proxy de «Banco». Pide automatizar la UI y queda pendiente.
Dos obstáculos del método, que valen para la próxima. La consola de una
extensión es CONTENIDO: `devtools.console.stdout.chrome` (que viene en true) no
la incluye, hace falta `...stdout.content`. Y un `moz-extension://` NO se abre
desde la línea de comandos —muere con `NS_NOINTERFACE [nsIFileURL.file]` y abre
la home en su lugar—, además de que `--screenshot` dispara al `load`, que puede
ocurrir antes de que arranquen las extensiones. Eso último destapó un fallo real
y arreglado: la página de opciones confundía «no hay contenedores» con «la API
no está» y mostraba un mensaje FALSO.
Verificado contra firefox b3:352d7880; se reconstruye contra el firefox con
RLBox cuando selle. La otra mitad de esta unidad —el rename de
recipes/atuq/extension/ a extensions/inicio/— entró sin querer en ff0b556, que
es de otro frente.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UgNtJEFetMYbXax5dVUjZZ
This commit is contained in:
@@ -269,7 +269,7 @@ La columna «quién más lo tiene» es lo que evita que nos contemos un cuento.
|
||||
| 6.5 | **Foco por `cortafuegos`, no por extensión** | nadie (nadie es dueño del navegador *y* del sistema) | `cortafuegos`, `pacha` | bajo |
|
||||
| 6.6 | **Medios por fuera del navegador** | extensiones sueltas; de fábrica no | `foreign-ytdlp`, `-platform`, `-dlna` | bajo |
|
||||
| 6.7 | **IA local en la barra lateral** | Chrome/Edge son nube; Zen no tiene | `rimay`, `iniy` | bajo |
|
||||
| 6.8 | **Proxy por contenedor** | nadie de fábrica | — (API de Firefox) | bajo |
|
||||
| 6.8 | **Proxy por contenedor** ✅ **v0.5** | nadie de fábrica | — (API de Firefox) | bajo |
|
||||
| 6.9 | **Torrent adentro** | **Vivaldi lo trae; Brave tuvo WebTorrent** | `shared/foreign-torrent` (SDD propio, sobre librqbit) | bajo |
|
||||
|
||||
### 6.1 `sct` es la joya
|
||||
@@ -309,6 +309,74 @@ eso; el modo incógnito es teatro. ⚠ Con la advertencia que el propio SDD de `
|
||||
**hay que repetir acá, no esconder**: en una máquina con swap sin cifrar, el documento no aplica.
|
||||
Se promete lo que se puede probar.
|
||||
|
||||
### 6.8 Proxy por contenedor — HECHO (v0.5, 2026-09-06)
|
||||
|
||||
**Es el primer diferenciador del §6 que se paga entero**, y se pudo pagar ahora porque es el único
|
||||
de la lista que no pasa por el host del §7: es API de Firefox y nada más. Cada contenedor
|
||||
—Personal, Trabajo, Banco, Compras— puede salir por su propio proxy.
|
||||
|
||||
Tres piezas, en tres ficheros, y **ninguna alcanza sola**:
|
||||
|
||||
| Pieza | Dónde | Qué aporta |
|
||||
|---|---|---|
|
||||
| `privacy.userContext.enabled` | `atuq.cfg` | prende los contenedores, que Firefox trae apagados |
|
||||
| `Containers.Default` | `distribution/policies.json` | los CREA — es el único mecanismo que los pone en un perfil NUEVO |
|
||||
| `3rdparty.Extensions` | `distribution/policies.json` | la config de fábrica, que la extensión lee como `storage.managed` |
|
||||
| `proxy.onRequest` | `extensions/proxy/fondo.js` | lo único que ve el `cookieStoreId` de cada petición |
|
||||
|
||||
**Las cuatro se comprobaron DENTRO del artefacto antes de escribir una línea**, que es la regla que
|
||||
dejó el §2.sexies: `Containers` y `3rdparty` están en el `policies-schema.json` de `browser/omni.ja`,
|
||||
`cookieStoreId` en el `schemas/proxy.json` de `omni.ja`, y `storage.managed` lee
|
||||
`Services.policies.getExtensionPolicy(id)` en `ext-storage.js`. Ninguna de las cuatro se leyó de la
|
||||
documentación de Mozilla: se leyeron de **nuestro** build, que es el que las tiene que traer.
|
||||
|
||||
**Tres decisiones de diseño que valen más que el código:**
|
||||
|
||||
1. **La configuración se indexa por NOMBRE de contenedor, no por `cookieStoreId`.** El id
|
||||
(`firefox-container-3`) depende del ORDEN en que se crearon, así que la misma configuración
|
||||
aplicada a otro perfil apuntaría a otro contenedor. Un identificador que cambia de significado
|
||||
entre máquinas no sirve para configurar una distro.
|
||||
2. **Fail closed.** Un contenedor que TIENE proxy configurado y no se pudo honrar —entrada
|
||||
inválida, API que falla, mapa a medio construir— **no sale directo**: va a un destino cerrado y
|
||||
el navegador muestra el error. Salir directo sería una fuga silenciosa, y es la misma familia
|
||||
que el artefacto vacío de la regla 3: el fallo que llega hasta el final diciendo que todo fue
|
||||
bien. Un usuario que pidió que «Banco» no salga por su línea tiene que ver un error, no navegar.
|
||||
3. **`proxyDNS` viene PRENDIDO.** Sin él, Gecko resuelve el nombre por su cuenta antes de hablar
|
||||
con el proxy: la consulta DNS sale justo por la línea que se quería evitar. Es la fuga clásica de
|
||||
esta configuración, así que el default es el seguro y hay que apagarlo a mano.
|
||||
|
||||
**Y lo que NO promete está en la propia página de opciones, arriba de todo y no en un pie**:
|
||||
separación de tráfico, no anonimato; no toca la huella del navegador; para anonimato, Tor Browser.
|
||||
Es el §4 cumplido en el sitio donde el usuario lo va a leer.
|
||||
|
||||
#### Lo que quedó PROBADO, y con qué
|
||||
|
||||
Corriendo el árbol de atuq en la misma jaula que usa `scripts/atuq-nested.sh`:
|
||||
|
||||
| Afirmación | Prueba |
|
||||
|---|---|
|
||||
| La política CREA los cuatro contenedores | captura de `about:preferences#containers` con Personal/Trabajo/Banco/Compras y sus iconos, más el `containers.json` del perfil |
|
||||
| Las dos extensiones se INSTALAN | `extensions.json` del perfil nombra `inicio@atuq.tawasuyu` y `proxy@atuq.tawasuyu` |
|
||||
| El ruteo se arma contra los contenedores reales | `console.info: "atuq/proxy: 4 contenedor(es) enrutado(s)"` — o sea que leyó la config de fábrica por `storage.managed` Y la casó con los contenedores que creó la política |
|
||||
| Los guardianes del cruce política↔XPI FALLAN cuando deben | `scripts/test-atuq-politica.py`: 5 formas de romperlo, las 5 matan el build, y el control con la política intacta pasa |
|
||||
|
||||
**Lo que NO está probado, dicho por su nombre:** que una petición hecha en el contenedor «Banco»
|
||||
salga por el proxy de «Banco». Eso pide automatizar la UI —una pestaña de contenedor no se abre
|
||||
desde la línea de comandos— y queda pendiente en vez de darse por hecho.
|
||||
|
||||
**Dos obstáculos del método, que valen para la próxima:**
|
||||
|
||||
- **La consola de una extensión es CONTENIDO, no chrome.** `devtools.console.stdout.chrome` viene
|
||||
en `true` de fábrica y NO la incluye; hace falta `devtools.console.stdout.content`. Sin esa pref
|
||||
los mensajes de la extensión sólo viven en la consola del navegador, que en headless no mira
|
||||
nadie.
|
||||
- **Un `moz-extension://` NO se puede abrir desde la línea de comandos.** El manejador intenta
|
||||
resolverlo como fichero y muere con `NS_NOINTERFACE [nsIFileURL.file]`, abriendo la home en su
|
||||
lugar — o sea que la captura sale de otra página y parece que la tuya no funciona. Y `--screenshot`
|
||||
dispara al `load`, que puede ocurrir ANTES de que termine el arranque de las extensiones: ahí el
|
||||
global `browser` todavía no está inyectado. Eso destapó un fallo real y se arregló: la página de
|
||||
opciones distinguía mal «no hay contenedores» de «la API no está» y mostraba un mensaje FALSO.
|
||||
|
||||
### 2.ter Dónde vive la fuente de `atuq` — hizo falta un modo de `[source]` nuevo
|
||||
|
||||
Escribir la receta destapó un muro que este documento no había visto: `[source]` era
|
||||
@@ -461,7 +529,8 @@ siguiente.
|
||||
| 6 | `sct` v1 (extensión + testigo) | el diferenciador que nadie tiene | 5 |
|
||||
| 7 | Descargas al CAS | 6.2, y alimenta 6.9 | 5 |
|
||||
| 8 | Archivo + RAG | 6.3 | 5, 7 |
|
||||
| 9 | Proxy por contenedor, torrent, medios, foco | 6.5–6.9 | 5 |
|
||||
| 9 | Torrent, medios, foco | 6.5–6.7, 6.9 | 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
|
||||
toolchain. Si hay dos frentes, van juntas.
|
||||
|
||||
Reference in New Issue
Block a user