# 03 — Los bloques del WD14

## Qué es un bloque

Una línea de tags Danbooru, **en el orden que los soltó el tagger**, a la que se
le quitan solo dos cosas:

- **Identidad**: pelo, ojos, piel, species/furry, rasgos faciales, uñas, tallaje
  de busto y complexión. El LoRA del personaje ya aporta eso.
- **Toda la ropa**: el outfit lo pone la línea del personaje y los wildcards.

Se conservan los conteos (`1girl`, `1boy`, `hetero`) porque el MASTER los
necesita para no pelearse con las poses de dos personas. Y se conserva **todo**
lo NSFW (`pussy`, `cum`, penetración, fluidos) y la pose, que es justo lo que
se quiere trasplantar.

## Los tres pools

La severidad se saca **de los tags**, no de la carpeta de origen. La carpeta no
es fiable: hay imágenes en `NSFW/` que son solo spicy y en `SFW/` que son
explicit.

| Pool | Qué es |
|---|---|
| `bloques_sfw.txt` | ni desnudo ni acto |
| `bloques_spicy.txt` | desnudo o anatomía, **sin acto** |
| `bloques_explicit.txt` | acto: penetración, fellatio o fluido |

Existe además una versión *vestida* de cada uno (`bloques_*_vestidos.txt`), con
la ropa del WD14 **sin color**, solo para cuando los personajes lo permita. Hoy
no se usa: los personajes del catálogo son base y salen desnudos, así que
rotar ropa con ellos es inútil.

## Estado actual

39 imágenes de origen → **33 bloques** en el pool.

| Pool | Bloques |
|---|---|
| sfw | 4 |
| spicy | 7 |
| explicit | 22 |

Fuera del pool: **6 descartados** y **0 pendientes de revisar**. Ambos listados
con motivo en `bloques_descartados.txt`, recuperables quitando su entrada de
`REJECT` en `wd14_blocks.py`.

> Cifras verificadas contra `Archivos/wildcards_harvest/` el 15-10-2026. Antes
> de este update el documento decía 27 bloques (4/8/15), 5 descartados y 16
> pendientes: eran las de antes de reconciliar los descartes por `original_txt`.

### El pool Danbooru va aparte

`Archivos/wildcards_danbooru/` es un segundo pool, **8 bloques** (sfw 1, spicy 2,
explicit 5), de 22 imágenes descargadas. Se curó a mano: se eligieron 9 y se
descartó `12348708_bent_over_s` por ruido Halloween. No se mezclan con el WD14;
se cargan con `--pool dan_*` en `test_blocks.py`.

## Purga aplicada

Además de quitar identidad y ropa, se descartan:

| Qué | Por qué |
|---|---|
| `all_fours` | Empuja la pelvis y la vagina cae por debajo. Se sustituye según contexto |
| `spread_ass` | Es el tag que **realmente** parte la anatomía de la pelvis |
| `solo_focus`, `pov_crotch`, `*_focus` | Tags de encuadre que pelean con la pose |
| `cross-section`, `internal_cumshot` | Vista de corte anatómico, no una pose |
| `?` sueltos | Basura del tagger |

Y se **bajan de peso** los que empujan la cámara sin aportar pose:
`(spread_ass:0.6)`, `(ass_focus:0.7)`, `(pussy_peek:0.5)`.

> **Ojo con `KEEP_COUNTS` y `DROP_CAMERA`.** `solo_focus` estuvo en las dos
> listas y, como el chequeo de conteos va primero, el filtro de encuadre nunca
> se ejecutaba. Sobrevivía en 17 de los 27 bloques que había entonces. Cualquier
> tag nuevo va en **una** lista.

### `doggy` NO existe: se usa `all_fours` (medido 09-10-2026)

`doggy` no está en `Archivos/Danbooru tags.csv`. En el pool Danbooru se
descartó por eso y al regenerar Rem con la etiqueta inválida **solo salía la
silueta**.

`replace_flagged()` en `wd14_blocks.py` lo resuelve por contexto:

| Caso | Salida |
|---|---|
| No hay penetración | `all_fours, from_behind, arched_back` |
| Hay penetración | `doggystyle` |

**A/B medido (mismo personaje, mismo seed 12345, misma pose):** con orden plano la
pose no se dibuja; con `all_fours` **justo tras el primer `BREAK`** sale correcta.
Es la medición que confirma que la estructura de `BREAK` manda sobre el orden del
tagger. Detalle en `DOCUMENTACION/02-estructura-prompt.md`.

## Cómo se prueban

Un bloque se pega **detrás** de la línea de un personaje y se genera. El orden
importa: si el bloque va antes de la identidad, la pose se pierde.

```bash
python Engine/test_blocks.py --pool explicit --block 7      # uno concreto
python Engine/test_blocks.py --pool explicit --all          # todos, en orden
python Engine/test_blocks.py --pool spicy --n 4             # 4 al azar
```

Cada corrida escribe en `Output/test_blocks/<pool>/` un PNG por bloque más un
`manifest_*.json` con el prompt exacto y el `.txt` de origen. Con eso, cada
imagen se puede rastrear hasta su bloque y su foto de referencia.

## El ciclo de curación

```
test_blocks.py genera  →  APROBADO | DESCARTADO | REVISAR PROMPT
        ↓
  se corrige el prompt a mano si hace falta
        ↓
  regen_literal.py con ese prompt  →  se vuelve a mirar
        ↓
  APROBADO entra al pool
```

Estructura actual de `explicit/`:

| Carpeta | Contenido |
|---|---|
| `APROBADO/` | 24 PNG — las buenas, con sus prompts |
| `REGEN/` | 35 PNG — 24 con la estructura actual + 11 pruebas sueltas |
| `DESCARTADO/` | 7 PNG |
| `COMPARATIVA/` | 24 hojas de comparación |
| `REVISAR PROMPT/` | vacía de PNG; queda `prompts_pendientes.txt` (volcado de texto) |

Las 11 extra de `REGEN/` son las pruebas de Raiden (`03_b23`): tres ángulos
(`from side`, `tres_cuartos`, `sobre_hombro`) y dos de fluido (`sincum`,
`solocum`). Los `_v1`/`_v2` son variaciones de `regen_aprobados.py --variations`.
No forman parte del set de 24.

`APROBADO/` y `REGEN/` tienen **los mismos nombres de archivo**, así que se
comparan uno a uno. Las de `APROBADO/` son anteriores a la estructura con
`BREAK`: sirven de referencia, no de referencia de calidad.

## Qué se aprendió audiando

- **El fallo nunca es solo del bloque.** Casi siempre es el LoRA del personaje
  (ropa o complexión horneada) o el seed.
- **La anatomía la rompe el tag de anatomía, no la pose.** `spread_ass` y
  `all_fours` parten la pelvis; `doggy` y `missionary` no.
- **Paizuri, `standing_sex` y `cowgirl_position` funcionan.** Se llegaron a
  flagear por los fallos, pero la hipótesis "el tag es malo" era falsa: lo que
  fallaba era el seed o el LoRA del personaje.
- **Regenerar con otro seed** a veces arregla lo que parecía un bloque malo.
- **Sub-agrupar el bloque por categoría da mejor resultado** que el orden de
  confianza del tagger. Verificado con Raiden (`03_b23`): agrupado sale un solo
  hombre coherente; sin agrupar salían dos, uno detrás y otro delante.
- **El bloque puede necesitar un ángulo explícito.** Sin tag de cámara el modelo
  usa el frontal, y en `sex_from_behind` eso pone al hombre delante de la chica.
  Con `from side`, `three-quarter view` u `over-the-shoulder shot` se mantiene
  detrás. Verificado.
- **Un peso dentro del bloque no llega.** `assemble_prompt()` llama a
  `strip_weights_of()`, que borra los `(x:1.3)`. Un refuerzo que necesite peso
  va en un tramo aparte o en el negative prompt.
- **`no X` en el POSITIVE refuerza X.** Medido con Furina: `no thigh strap:1.3`
  no quitó la banda del muslo *y además* le inventó un collar y dos gemas en el
  pezón que antes no había. El text encoder no procesa la negación, solo lee el
  concepto. La negación va en el **negative prompt**, que es donde sí repele.
- **El NEGATIVE no gana contra la ropa que está en el POSITIVE.** Con 5
  personajes cuya línea aún tenía ropa (`test_accesorios.py --pendientes`),
  **4 de 5 siguieron Fully dressed**: el tag estaba en su propia línea. Solo
  Agnes salió limpia. Limpiar `personajes.txt` no basta si la ropa también está
  horneada en el LoRA; ahí hace falta bajar el LoRA a 0.45-0.5 o aceptarla como
  identidad.
- **El negative también puede inventar ropa.** A Elinalise le salieron
  calcetines blancos altos que no estaban en ningún tag, propulsados por el
  propio negative. Tape solo lo que has visto aparecer, no una lista preventiva.
- **Para auditar un personaje, `--nude` es el escenario bueno, no el outfit.**
  Con ropa, Seed parecía perfecta; forzada a desnudez se vio que
  `clover hair ornament` se colorea en piel y que `thigh cutout`/`black sleeves`
  dibujaban el traje marcado sobre el cuerpo. La ropa persistente **esconde** el
  problema en vez de medirlo. Arnés: `Engine/test_accesorios.py --nude`.
- **`dynamic pose, dynamic shot` son solo para pruebas unitarias de UN
  personaje.** No en series: van al final del bloque y ganan sobre
  `front view, standing`.