# Fermenty — El mentor en el Panel

> Briefing para Claude Code. **v2, escrita después del informe de fase 0**
> (`docs/Mentor_en_Panel_Fase0.md`), que confirmó Camino A y cambió el encargo.
>
> Referencias: `docs/Mentor_en_Panel_Fase0.md`, `docs/Lexico.md` (§4 El motor,
> §6 Congelar/snapshot · Un solo dueño · Definición vs. hecho),
> `docs/Matematica_Motor.md` (§5 la cinética), `docs/Planes.md` (§3, §6),
> `docs/Dominios_Navegacion.md` (§2 autenticación), `docs/Cierre_del_lazo.md`.
>
> Destino: `docs/Mentor_en_Panel.md` · Documento vivo · v2 · 2026-08-03
> (v1 conservada en `docs/Mentor_en_Panel_v1.md`)

---

## 0. Qué cambia respecto a v1

| v1 decía | v2 dice | Por qué |
|---|---|---|
| Fase 0: análisis | **Hecha.** Camino A | `Batch::create` en un solo punto; el Panel ya pasa por el motor |
| Fase 1: extraer el formulador | **Borrada.** No aplica | `BatchService` ya es el dueño único |
| «No se tocan pantallas existentes» | **Se tocan**: creación y seguimiento | El punto de entrada *es* la pantalla de creación |
| «El límite está cableado a 3» | **Falso.** Se lee del plan y es 2 | `config/billing.php` |
| §7a ¿qué es «tanda activa»? | **Resuelta de facto**: `status='active'` | Solo falta ratificarla en `Planes.md` |
| Verificación: «filas idénticas» | Reformulada (§9) | No tenía sentido mientras el Panel no preguntara |

---

## 1. El encargo

**Que el Panel formule preguntando, enseñe la propuesta antes de comprometer, y
acompañe la tanda con la voz del motor.**

El motor ya corre en el Panel. Corre a ciegas y en silencio: no recibe `perfil` ni
`contexto`, y no enseña nada de lo que calcula.

***No es*** cablear el motor. Ya está cableado.

***No es*** el Afinador de cuatro ejes. «Los cuatro ejes» es vocabulario del motor y
está prohibido en la interfaz (`Planes.md` §5).

***No es*** el bucle 1. La ventana **no se mueve todavía** — eso no está construido.
El Panel enseña lo que el motor dijo; no finge que aprende. Es la trampa más fácil de
esta pantalla y §7 la acota.

***No es*** el escalón 3. Lotes propios y trazabilidad no entran: si entran ahora,
entran gratis y ya no salen (`Planes.md` §8).

***No es*** una revisión del reparto gratis/Pro. Las contradicciones que encontró el
informe van a su propio briefing (§11).

---

## 2. El hallazgo que ordena todo

**El Panel no hace las preguntas.** Su formulario no envía `perfil` ni `contexto`, así
que el motor cae a los valores por defecto: perfil de la receta, `tempRef` = 23 °C,
confianza media.

Con Q10 = 2,0 (`Matematica_Motor.md` §5), 23 °C fijos son un factor de ~2,5× entre una
cocina de invierno y una de verano. **El Panel lleva tiempo dando fechas calculadas
para una cocina que no es la del usuario, sin decirlo.**

No es una funcionalidad ausente. Es una predicción mala emitida en silencio, y es la
razón por la que la pantalla sube de prioridad: no es el adorno del final, es la
corrección.

### Y hay un segundo dueño de la ventana

`reschedule()` se ejecuta **después** de crear y reescala los pasos leyendo la guía
viva. No corrompe datos hoy, pero significa que las fechas que ve el usuario del Panel
no son las que dijo el motor.

Por eso **no puede retirarse en un commit posterior a la pantalla**: en el momento en
que el Panel pregunte y el motor responda, ese reescalado contradiría la respuesta
dentro de la misma petición. Sale en el mismo bloque (§7).

---

## 3. Los dos caminos, y hay que sostener los dos

`formularConMotor()` se salta si la guía no tiene ficha. Hoy la única ficha cerrada es
la de kombucha, así que **la mayoría de las guías van por el camino sin motor.**

| | Guía **con** ficha | Guía **sin** ficha |
|---|---|---|
| Preguntas | Perfil + contexto | Como hoy |
| Propuesta | Cantidades, ventana en fechas, trueques, avisos | Horquilla orientativa de la guía |
| `reschedule()` | **Retirado del camino** | **Se mantiene**: es el único que reescala |
| Voz | Del motor | Consejos editoriales (`guide_step_hints`) |

La pantalla es una, y **decide por la existencia de ficha, no por un ajuste manual**.
La formulabilidad se computa, no se marca a mano.

> **Lo que no se debe hacer:** inventar una ficha por defecto, ni valores plausibles,
> ni «una estimación» para las guías que no la tienen. Sin ficha no hay predicción, y
> decirlo es parte del producto.

---

## 4. Bloque 1 — Barandillas de código

Va **antes** de la pantalla, porque la pantalla añade una superficie que no pasa por
los Resources.

- **`$hidden` en `Batch` y `FermentationGuide`.** Hoy la no-fuga descansa solo en los
  Resources de la API. Las rutas web no pasan por ahí.
- **Retirar el hash de versión de la ficha de la respuesta en vivo.** Se **queda
  congelado en la tanda** — eso es trazabilidad y el snapshot lo exige. Lo que sale es
  la respuesta de una formulación no guardada: agrupar pares entrada/salida por versión
  es exactamente lo que facilita reconstruir los coeficientes desde fuera
  (`Afinador_Web.md` §5).
- **Reescribir los dos avisos que llevan coeficientes en el texto.** Mismo aviso, misma
  clasificación `duro`/`blando`, sin la cifra del modelo dentro.
- **Capa común de candados.** Hoy cada controlador repite el `if` y
  `BatchPolicy::create` devuelve `true` incondicional. Un solo sitio que lea el plan.
- **Borrar código muerto:** `User::FREE_ACTIVE_BATCH_LIMIT` (cero consumidores),
  `App\Http\Controllers\FermentController` (sin ruta), `RouteServiceProvider`
  (carga un fichero inexistente).

> **Condición dura: extracción mecánica, comportamiento idéntico.** Ni una regla de
> reparto cambia en este bloque. Si se centraliza y se corrige a la vez, no se podrá
> distinguir un fallo del refactor de un cambio de política deliberado.
>
> Los candados existentes se copian **tal cual están**, incluidos los que contradicen
> `Planes.md`. Esa discusión es §11.

---

## 5. Bloque 2 — La pantalla de formulación

**Sustituye el flujo actual de creación.** No convive con él: dos puertas al mismo acto
es el error que el proyecto lleva nombrado.

### Rutas web, no `fetch` a `/v1`

La sesión del Panel no vale contra la API — cookie host-only
(`Dominios_Navegacion.md` §2). La pantalla va por rutas web contra `BatchService`.

### Lo que se pregunta

**Lo mismo que la PWA.** Las mismas cartas de preset, el mismo override si lo tiene.
Cualquier entrada que exista en una superficie y no en la otra es una divergencia del
modelo, no una diferencia de maquetación.

Lo que sí cambia es la disposición: el escritorio tiene sitio para enseñar propuesta y
controles **a la vez**, en vez de en secuencia. Ver la ventana moverse al arrastrar la
temperatura es lo que convence, y aquí cabe.

> **El riesgo concreto:** hay hueco, y el hueco invita a añadir campos. Una entrada
> nueva que no exista en la PWA es un cambio del modelo y se decide en
> `Matematica_Motor.md`, no aquí.

### Lo que se devuelve, y en qué orden

El orden de `Afinador_Web.md` §3, que ya está decidido:

1. **Las cantidades**, en gramos, para su volumen
2. **El calendario**, en fechas — no «día 7 a día 9»
3. **Un trueque, dos como mucho**
4. **Los avisos duros**, si los hay. Máximo dos
5. **Todo lo demás plegado**: pH, alcohol, presión, avisos blandos

### El ciclo de borrador

Existe en la API (`formular` / `arrancar`) y no en el Panel. **Formular hoy y arrancar
el jueves es exactamente el caso del escritorio**, así que aquí es donde más falta hace.

Un borrador no cuenta al límite —está bien así— pero eso hace más urgente el bloque 4.

---

## 6. Bloque 3 — La tanda en curso

La pantalla grande del Panel tiene que reflejar que hubo un cálculo detrás.

**Qué entra:**
- La ventana calculada, en fechas, con su procedencia visible
- Los avisos y barandillas vigentes
- Lo que se pidió frente a lo que va pasando
- Lo que haya en `insights`, que ya existe y es el sitio de la voz del mentor

**Qué sale:**
- `reschedule()` **del camino con ficha**. En el camino sin ficha se queda (§3)

**Dónde está la frontera, y es dura:** el Panel **lee** `insights`, no escribe voz
propia. Si una plantilla de texto acaba en una vista, hay dos mentores. El cierre del
lazo escribe en `insights` desde el servicio, y esto es su lector.

Y: **la ventana no se mueve al catar.** Eso es el bucle 1 y no está construido. La
pantalla no debe sugerir lo contrario ni con copy ni con controles preparados «para
cuando esté».

---

## 7. Bloque 4 — Los borradores dejan de ser invisibles

El listado filtra por `['active','paused','completed']`. Un borrador hecho en el móvil
**no existe para el escritorio**: no es una funcionalidad que falte, es una tanda que
desaparece al cambiar de pantalla.

Va aquí y no antes porque enseñar un borrador sin poder arrancarlo desde el Panel es
enseñar algo con lo que no se puede hacer nada. Depende del ciclo del bloque 2.

Decidir también qué se hace con `discarded`, que tampoco aparece.

---

## 8. Las tandas ya creadas no se tocan

Están congeladas a 23 °C y **son hechos**. No se corrige un hecho editando una
definición (`Lexico.md` §6).

**No hay backfill, no hay recálculo, no hay migración de datos.** Arreglar el bug
invita justo a eso, y sería reescribir el pasado de gente que fermentó de verdad.

---

## 9. Cómo se verifica

«Filas idénticas» solo tiene sentido ahora que el Panel pregunta. La prueba:

**Formular con las mismas respuestas desde PWA y Panel, y comparar las filas.**
Snapshot de pasos, ingredientes, cantidades, ventanas previstas, ficha congelada y
versión del motor: idénticos salvo `id` y marcas de tiempo.

Además:
- La misma formulación por el camino sin ficha se comporta como hoy
- El límite se comporta igual en las dos superficies
- Ninguna respuesta web lleva coeficientes ni hash de ficha
- Una tanda creada en el Panel se abre y se sigue desde la PWA, y al revés. **Es la
  misma tanda; no hay tandas «de escritorio»**
- Un borrador creado en la PWA aparece en el Panel y se puede arrancar desde allí

---

## 10. 🔴 Decisiones abiertas

**a) Qué pasa con `batches/create.blade.php`.** Se sustituye. Queda anotado por si
alguna ruta o correo apunta a ese flujo concreto.

**b) La canónica de tanda.** `Encaminamiento.md` §2 dice `/tandas/{id}`; el código
sirve `/panel/batches/{batch}`. Afecta a los enlaces de los correos, **no a esto**. No
se resuelve aquí y no se toca de paso.

**c) `pro` vs `premium`.** Config llama al plan `pro`, `users.plan` guarda `premium`.
El puente lo hace `BillingService`. Es un pie de rastrillo, no un bug. **No se toca
billing ahora.**

**d) Pausar** *(añadida 2026-08-03)*. Pausar no cambia nada: apaga los avisos y hace
muda la tanda, sin exigir catas ni controles. Se deja como está; queda por averiguar
si tiene sentido como gesto. En pantalla, «activas» = en marcha **o** en pausa (la
lista de la home de la PWA las enseña juntas; el Panel mantiene sus tabs); el
**candado** del plan sigue contando solo `status='active'` — cambiarlo sería regla
de reparto (§11).

**e) `discarded` en el listado del Panel** *(añadida 2026-08-03)*. Los borradores ya
tienen su pestaña; las descartadas siguen sin aparecer. Pendiente de decidir.

**f) Borradores sin techo** *(añadida 2026-08-03)*. «Guardar sin empezar» no muerde
el límite — correcto: el candado es al activar y un borrador no cuenta. Pero eso
significa que un usuario gratis puede acumular borradores sin freno. Que ahora sean
visibles resuelve la mitad del problema; la otra mitad —si alguien llena la pestaña,
nada lo para— es reparto (§11) y no se toca aquí. Queda vigilado.

---

## 11. Fuera de alcance

- **Las contradicciones con `Planes.md`** — `fermentation_guides.plan_required` contra
  «formular cualquier fermento ✓ ✓», y el ajuste fino tras `isPremium()` contra §3.3.
  Son de reparto, no de superficie. **Briefing aparte.**
- **`calibracion` y `ejes`** en `config/billing.php`: declarados, sin lectores. Se
  dejan como están.
- El enlace roto de `routes/mobile.php:25` a suscripción — commit propio.
- El bucle 1 y las vistas de agregado (panorama de ventanas, comparar formulaciones).
- Lotes, trazabilidad y recetas propias — escalón 3.
- Billing, precios y Stripe.

---

## 12. No debe inventarse

- **Ni fichas ni coeficientes por defecto** para guías que no los tienen.
- **Ni el criterio de «receta especial»**: no existe como dato, y la vista de `/pro` lo
  bloquea a conciencia. No se representa en ninguna pantalla.
- **Ni el número del límite**: se lee del plan.
- **Ni textos de aviso nuevos**: son los del motor, con su clasificación existente.
- **Ni voz del mentor en las vistas**: se lee de `insights`.
- **Ni la sensación de que la ventana se mueve al catar.** No se mueve todavía.

---

*Documento vivo. La v1 y el informe de fase 0 se conservan: la v1 porque explica por
qué se empezó preguntando, y el informe porque es la única fuente de varias cosas que
el repositorio no documenta.*
