# Handoff DateKeys, 26 de septiembre de 2026 (actualizado el 29 por la noche, al cerrar la fase 3)
# Handoff DateKeys, 26 de septiembre de 2026 (actualizado el 30 de madrugada: formato 3 en diseño, revisado por Fable)
Estado al parar la sesión del 26 por el límite semanal de uso. Se actualizó el 28 de septiembre tras cerrar la v0.8.2 del spec (§2.1), el 29 de madrugada tras cerrar la fase 2 (§2.2), el 29 a mediodía tras reorganizar el espacio de trabajo (§0) y el 29 por la noche tras implementar el formato 2 de la v0.9 en Go y en TypeScript, poner el tag `spec-v0.9` y escribir el writer TypeScript con su interoperabilidad con Go (§2.5). Sirve para retomar sin contexto previo, sea una persona o una sesión de Claude.
Estado al parar la sesión del 26 por el límite semanal de uso. Se actualizó el 28 de septiembre tras cerrar la v0.8.2 del spec (§2.1), el 29 de madrugada tras cerrar la fase 2 (§2.2), el 29 a mediodía tras reorganizar el espacio de trabajo (§0) y el 29 por la noche tras implementar el formato 2 de la v0.9 en Go y en TypeScript, poner el tag `spec-v0.9` y escribir el writer TypeScript con su interoperabilidad con Go (§2.5). El 30 de madrugada se diseñó el formato de cápsula 3 y Fable lo revisó (§2.5, al final). Sirve para retomar sin contexto previo, sea una persona o una sesión de Claude.
---
@ -88,9 +88,11 @@ El vector de GT (`vectors/tlock_ibe.json`) ya está cubierto en `App`. El paso 9
### 2.5 Sesiones del 29-09: v0.9 del spec y formato 2 en Go (retomar aquí)
**Estado al parar (29-09 por la noche):**
**Estado al parar (30-09 de madrugada). Retomar por el formato 3, al final de esta sección:** contestar las cuatro decisiones pendientes y aplicar la revisión de Fable.
**Estado al cerrar la fase 3 (29-09 por la noche):**
- Pasos 1 a 5 hechos. El spec v0.9 está cerrado con el tag `spec-v0.9` (`7e2d83c`, en `main` de `datekeys-go`), y las dos implementaciones leen el formato 2: Go desde `f24a280`, que también lo escribe, y TypeScript desde `0118890`.
- Paso 6 hecho: la fase 3 está completa en `datekeys-ts` (pasos 0 a 7 del plan, hasta `3a9d2b1`, subido). La librería escribe el formato 2, Go abre lo que escribe y la página `/create` cifra en el navegador. La versión `0.2.0` sigue sin publicar: cerrarla es decisión del autor (§2.3).
- Paso 6 hecho: la fase 3 está completa en `datekeys-ts` (pasos 0 a 7 del plan, hasta `3a9d2b1`, subido). La librería escribe el formato 2, Go abre lo que escribe y la página `/create` cifra en el navegador. La versión `0.2.0` sigue sin publicar: cerrarla es decisión del autor (§2.3). Después, a petición del autor, `/inspect` muestra el contenido al abrir, debajo del veredicto, y nombra la descarga por su tipo. Las páginas explican las claves de `age`, y la vista previa sirve las páginas sin caché (`da2000a`, `da26862`, subidos).
- Las 22 correcciones del repaso final ([spec_v0.9/review.md](spec_v0.9/review.md)) se aplicaron en `4a025d1`, más cuatro sitios que repetían los mismos problemas: las reglas 1 y 4 del §62.1 y los cambios 4 y 10 del §76. Los números de la corrección 1 se recalcularon con un Padmé en BigInt.
- La corrección 2 la decidió el autor el 29-09: se suaviza el §56.
- El lector MUST NOT presentar el contenido como válido antes de que termine el paso 17.
@ -194,7 +196,25 @@ El vector de GT (`vectors/tlock_ibe.json`) ya está cubierto en `App`. El paso 9
- firma Ed25519 y sello de DateKeys, con registro anclado en OpenTimestamps.
- Un flujo de diseño con revisión adversarial produjo [spec_v0.10/formato3_diseno.md](spec_v0.10/formato3_diseno.md): 28 problemas encontrados y corregidos.
- El paquete para la revisión de seguridad externa, con el contexto del protocolo, el modelo de amenazas y las preguntas, es [spec_v0.10/formato3_para_revision.md](spec_v0.10/formato3_para_revision.md). También está publicado como artefacto privado: https://claude.ai/artifact/5NY9YxBjZA6DCadZ1aT5Ln.
- **Siguiente:** el autor se lo pasa a Fable para buscar vulnerabilidades. Con sus hallazgos se corrige el diseño, y después se redacta el texto del spec v0.10 para que lo apruebe el autor. Quedan las preguntas abiertas de la sección 11 del diseño.
- **Revisión de Fable (30-09),** guardada en [spec_v0.10/revision_fable.md](spec_v0.10/revision_fable.md).
- **Veredicto:** la parte criptográfica aguanta, y confirma la aritmética de tamaños y la necesidad del verificador Ed25519 propio. Los problemas están en los bordes.
- **Diez hallazgos**, cuatro mayores y seis menores; también hay observaciones sobre el documento.
- **Valoración:** coincido con todos. Comprobados de memoria: el 2 (la lista de git en `core.protectHFS` incluye ZWJ, ZWNJ y U+206A–206F) y el 6 (JavaScript compara en UTF-16: U+FF5E y un emoji quedan al revés que en Go).
- **Arreglos que no necesitan decisión:**
- **2.** R4 por la propiedad `Default_Ignorable_Code_Point`, con lista blanca corta (ZWJ, ZWNJ, VS15, VS16); la clave de R7 descarta lo permitido; tags U+E0000 a U+E007F prohibidos.
- **5.** El tamaño del área de `security` va en la trama, fijo por versión y reservado siempre.
- **6.** TypeScript compara bytes UTF-8, con un vector en `paths.json`.
- **7.** En la CLI, prefijo en cada línea visual del comentario, y los veredictos repetidos al final.
- **8.** Se declara como fuga aceptada que el POST al servicio delata el sello.
- **9.** Tabla de verdad firma/sello, expresión regular de R6b y regla para una mtime negativa.
- **10.** Prefijos de dominio en `control_commit` y `head_digest`, y el nombre `.datekeys-*` reservado.
- **El documento:** 24 objeciones en vez de 28, marcadas «corregida» o «aceptada»; un glosario (capas 2 a 4, L_MAX, la sal); un texto para un sello que el lector no sabe verificar; una sola fuente en vez de tres ficheros que repiten el texto.
- **Decisiones pendientes del autor**, con mi recomendación:
1. **Tres entregas,** con el formato congelado desde la primera y `security` vacío: primero contenedor y rutas, luego la firma, luego el sello. Recomendado: sí.
2. **Origen del servicio (hallazgo 1).** Recomendado: subdominio aparte, `seal.datekeys.com`, que solo sirve la API, con cabeceras `nosniff` y `CSP: sandbox` de todos modos; la CSP de `/create` lo añade a `connect-src`. La alternativa es el mismo origen con cabeceras forzadas por el proxy.
3. **Vida del sello a décadas (hallazgo 3).** Recomendado: el token lleva dentro la prueba de inclusión y el checkpoint firmado, y una raíz offline fijada desde ya certifica las claves anuales. Así el sello se verifica sin red para siempre, y la auditoría del anclaje queda como comprobación online opcional. Las alternativas son un fichero de prueba aparte (la opción de Fable) o depender del registro.
4. **Abuso sin guardar IP (hallazgo 4).** Recomendado: prueba de trabajo SHA-256 en cada petición, de un segundo en el navegador, sin estado. La alternativa es un límite por IP solo en memoria.
- **Siguiente:** con las respuestas, un flujo aplica los arreglos y las decisiones al diseño con revisión adversarial. Después se redacta el texto del spec v0.10 para que lo apruebe el autor, y siguen abiertas las preguntas de la sección 11 del diseño. Si se aceptan las tres entregas, la primera (contenedor y rutas) puede empezar sin esperar al servicio.
**Conclusiones de la conversación, sin decisión pendiente:**
- El protocolo no contempla un sello de tiempo de creación (§5, §55.1). Si se quiere, lo recomendado es un sello RFC 3161 u OpenTimestamps sobre el SHA-256 del `.dkc` completo, guardado aparte.
@ -45,4 +45,4 @@ Para retomar el trabajo, lee [HANDOFF.md](HANDOFF.md): el estado de cada repo, l
| [PLAN_fase3_escritura.md](PLAN_fase3_escritura.md) | Fase 3, writer TypeScript del formato 2 (v0.9). v3, hecha: la librería, su interoperabilidad con Go y la página `/create` (hasta `3a9d2b1` de `datekeys-ts`) |
| [REVISION_completitud_protocolo.md](REVISION_completitud_protocolo.md) | Qué le falta al protocolo antes de la v1.0 |
| [spec_v0.9/](spec_v0.9/README.md) | Papeles de trabajo del borrador v0.9: diseño, revisiones y correcciones pendientes |
| [spec_v0.10/](spec_v0.10/formato3_para_revision.md) | Formato de cápsula 3 en diseño: varios ficheros, firma y sello. El paquete para la revisión de seguridad y el diseño |
| [spec_v0.10/](spec_v0.10/formato3_para_revision.md) | Formato de cápsula 3 en diseño: varios ficheros, firma y sello. El paquete para la revisión de seguridad, el diseño y la revisión de Fable |
*Revisión externa del paquete [formato3_para_revision.md](formato3_para_revision.md), copiada tal como la pasó el autor.*
He leído [formato3_para_revision.md](../docs/spec_v0.10/formato3_para_revision.md) entero y contrastado algunas afirmaciones con el código. Mi opinión:
## Veredicto
**El formato está bien diseñado; el servicio de sellado aún no es revisable.** La parte criptográfica (qué se firma, qué se sella, los compromisos) no le encuentro ataque. Los problemas están en los bordes: el origen del servicio, los caracteres invisibles y la vida del sello a décadas.
Comprobado por mí:
- Toda la aritmética de tamaños cuadra (22/128/175/281, 53, 45, 146, L = 573 → P = 768, L = 1637 → P = 1792).
- noble 2.4.0 usa la ecuación con cofactor siempre (`edwards.js:659`), así que el verificador propio es necesario, no un capricho.
- Go trae Unicode 15.0.0 y Node 24.9 el 16.0, como dice el documento.
## Hallazgos, por gravedad
| # | Gravedad | Problema | Arreglo |
|---|---|---|---|
| 1 | Mayor | **Mismo origen (decisión 5).** Hoy el sitio es estático y el CSP va en `<meta>`. Un documento servido bajo `/seal/*` no lleva CSP y corre en el origen que maneja plaintexts, `.dkk` y claves de autor | Origen aparte (`seal.…`), o cabeceras forzadas en el proxy: `nosniff`, `octet-stream`, `CSP: sandbox` |
| 2 | Mayor | **Caracteres invisibles en rutas.** R4 deja pasar U+206A–206F, y ZWJ/ZWNJ están permitidos: HFS+ los ignora al comparar, así que «ab» y «ab» colisionan. Los tags U+E0020–E007F permiten nombres visualmente idénticos | R4 por propiedad (`Default_Ignorable_Code_Point`) con lista blanca; la clave de R7 descarta lo permitido |
| 3 | Mayor | **El sello no sobrevive a DateKeys.** La auditoría depende de que el registro siga publicado dentro de décadas, y el perfil anual obliga a actualizar cada lector cada año | Fichero aparte con prueba de inclusión, checkpoint y `.ots`; raíz offline ahora, no «más adelante» |
| 4 | Mayor | **Abuso frente a «sin registros».** El registro solo crece y el POST es anónimo; limitar por IP exige guardar IPs | Definirlo: estado solo en memoria, o prueba de trabajo con SHA-256 |
| 5 | Menor | **El área depende de `SECURITY_LEN`.** Un sello futuro de más de 512 bytes cambia L y delata su presencia por P | Área fija mayor, o longitud propia en la trama |
| 6 | Menor | **Orden de rutas en TypeScript.** Comparar strings ordena por UTF-16, no por bytes: U+FF5E y un emoji salen al revés que en Go | Vector en `paths.json` |
| 7 | Menor | **Suplantación en la CLI.** Una línea de comentario rellena de espacios salta de renglón y el falso veredicto aparece sin el prefijo `│ ` | Repetir los veredictos al final, o partir líneas en la CLI |
| 8 | Menor | **A1 y el tráfico.** La página no hace ninguna petición hoy; un POST delata el sello | Declararlo como fuga aceptada |
| 9 | Menor | **Ambigüedades:** si una firma ilegible invalida también el sello; R6b con «~1» a secas y qué cuenta como carácter; mtime negativa | Tabla de verdad, expresión regular, regla de omisión |
| 10 | Menor | `control_commit` y `head_digest` sin prefijo de dominio; el directorio `.datekeys-*` puede coincidir con una entrada | Prefijo; reservar ese nombre |
## Sobre el documento
- **Las 28 objeciones son 24:** la 12, 16, 18 y 24 repiten otras. Y varias no están «corregidas» sino aceptadas (2, 9, 23). Un revisor agradece la distinción.
- **Faltan definiciones para alguien de fuera:** «capa 2/3/4», las referencias a § del spec, el valor de L_MAX (2⁵³ − 2⁴⁶) y para qué sirve la sal del head.
- **Hay tres ficheros con el mismo texto.**`para_revision` es la suma exacta de los otros dos; cualquier corrección hay que hacerla dos veces.
- **El sello sin perfil conocido no muestra nada.** Mejor un texto que diga que hay un sello y que el lector es antiguo.
## Recomendación
Separar en tres entregas, con el formato congelado desde la primera y `security` vacío:
1. Contenedor y rutas.
2. Firma y claves de autor.
3. Sello, cuando exista su documento propio («Servicio de sellado v1»), con custodia de clave, monitores y hosting.
Los hallazgos 1, 3 y 4 son del servicio, no del formato, y no deberían frenar lo demás. El 2 y el 6 sí conviene cerrarlos antes de escribir el texto del spec.
No he revisado aún a fondo el ZIP byte a byte ni he probado el comportamiento de HFS+ en una máquina; lo de HFS+ lo afirmo por la lista que usa git en `core.protectHFS`.