/e/{eval}/c/{caso}): arriba la pieza, al lado la evidencia, abajo la barra con el veredicto.La hoja de firma funciona igual: una página por ítem (/firma/{id}/i/{item}), la
recomendación de Fable marcada como recomendado, y una página
de resumen desde la que se firma el acta.
Cualquier markdown con la forma de E1_muestra.md vale: un # con el
título y las instrucciones, y luego un ## <ID> por caso con bullets
- **etiqueta**: valor, una sección ### con el texto que se juzga y otra
con la evidencia.
python3 tools/build_eval_from_md.py ruta/al/fichero.md mi-eval-2026-09-01 "Título" \
--descripcion "Una línea"
# escribe evals/mi-eval-2026-09-01.json y comprueba que NADA del manifiesto
# viene de fuera de ese markdown (la garantía de que una muestra ciega no se filtra)
Después: importarlo en src/content.js y npx wrangler deploy. El
formulario (veredictos, campos, cabecera del CSV) vive dentro del manifiesto.
Un JSON en firmas/ con sections[].items[]; cada ítem lleva
opciones, recomendacion y un grupo. El resumen en una línea
se compone con resumen.formato y esos grupos.
GET /api/e/{evalId}/progress?evaluador=operador
→ {"answered":7,"total":20,"missing":["E1-08",…],"updated_at":"…"}
GET /e/{evalId}/export.csv?evaluador=operador # el CSV del corrector
GET /e/{evalId}/export.json?evaluador=operador
GET /firma/{firmaId}/actas.json # todas las actas
Cualquier página acepta ?evaluador=nombre: fija la cookie y permite marcadores
con identidad.
Con npx wrangler secret put FORM_SECRET, todo envío exige ?k=<secreto>
una vez (queda en cookie). Hoy el sitio está abierto por decisión del operador.