Step 6 records the page decisions of the author, step 7 the page and
its adversarial review. The handoff resumes at the author's decision on
closing 0.2.0.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Handoff DateKeys, 26 de septiembre de 2026 (actualizado el 29 por la noche, tras el paso 5 de la fase 3)
# Handoff DateKeys, 26 de septiembre de 2026 (actualizado el 29 por la noche, al cerrar la fase 3)
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). Sirve para retomar sin contexto previo, sea una persona o una sesión de Claude.
@ -90,7 +90,7 @@ El vector de GT (`vectors/tlock_ibe.json`) ya está cubierto en `App`. El paso 9
**Estado al parar (29-09 por la noche):**
**Estado al parar (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`.
- 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 en curso: la librería TypeScript ya escribe el formato 2 y Go abre lo que escribe (pasos 0 a 5 del plan de la fase 3, hasta `da0b39f`, subido). Retomar por el paso 6 del plan: las decisiones de la página, que confirma el autor.
- 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).
- 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.
- 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.
- 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.
- El lector MUST NOT presentar el contenido como válido antes de que termine el paso 17.
@ -160,7 +160,7 @@ El vector de GT (`vectors/tlock_ibe.json`) ya está cubierto en `App`. El paso 9
- la página muestra el formato, avisa del 1 y, al abrir una cápsula del formato 2, da la regla y P;
- la página muestra el formato, avisa del 1 y, al abrir una cápsula del formato 2, da la regla y P;
- `ibe-vectors.json` añade los siete fixtures del formato 2, calculados con `scripts/ibe-go-vectors.go`; los valores congelados no cambian;
- `ibe-vectors.json` añade los siete fixtures del formato 2, calculados con `scripts/ibe-go-vectors.go`; los valores congelados no cambian;
- comprobado: los 125 casos del corpus dan en TypeScript el código, el paso y el texto de error de `capsule.Open`, en memoria y desde un `Blob`.
- comprobado: los 125 casos del corpus dan en TypeScript el código, el paso y el texto de error de `capsule.Open`, en memoria y desde un `Blob`.
6. Se replantea el plan de la fase 3 y se escribe el writer TypeScript del formato 2. **En curso.** El 29-09 por la noche, [PLAN_fase3_escritura.md](PLAN_fase3_escritura.md) pasó a su v2, sobre las reglas del §62.1:
6. Se replantea el plan de la fase 3 y se escribe el writer TypeScript del formato 2. **Hecho el 29-09.** El 29-09 por la noche, [PLAN_fase3_escritura.md](PLAN_fase3_escritura.md) pasó a su v2, sobre las reglas del §62.1:
- 16 huecos con señuelos y orden uniforme;
- 16 huecos con señuelos y orden uniforme;
- relleno `reforzado` por defecto;
- relleno `reforzado` por defecto;
- L conocida de antemano;
- L conocida de antemano;
@ -176,7 +176,10 @@ El vector de GT (`vectors/tlock_ibe.json`) ya está cubierto en `App`. El paso 9
- pasos 3 y 4 (`8473fdf`): `encrypt.ts` y `writer.ts`. Reproducen byte a byte las secciones deterministas de los siete fixtures del formato 2 de Go, escriben en streaming y abortan la salida ante cualquier fallo. El bucle de propiedades pasa con 500 semillas;
- pasos 3 y 4 (`8473fdf`): `encrypt.ts` y `writer.ts`. Reproducen byte a byte las secciones deterministas de los siete fixtures del formato 2 de Go, escriben en streaming y abortan la salida ante cualquier fallo. El bucle de propiedades pasa con 500 semillas;
- paso 5 (`da0b39f`): Go abre con cada credencial las trece cápsulas de muestra que escribe TypeScript, y las reencodifica a los mismos bytes. Rechaza cuatro mezclas con el mismo código y paso, codifica igual 500 entradas aleatorias y da los mismos textos en 22 recipients y 21 opciones inválidas. Todo queda congelado en `src/lib/dkc/testing/capsule-vectors.json`.
- paso 5 (`da0b39f`): Go abre con cada credencial las trece cápsulas de muestra que escribe TypeScript, y las reencodifica a los mismos bytes. Rechaza cuatro mezclas con el mismo código y paso, codifica igual 500 entradas aleatorias y da los mismos textos en 22 recipients y 21 opciones inválidas. Todo queda congelado en `src/lib/dkc/testing/capsule-vectors.json`.
**Siguiente:** el paso 6 del plan, las decisiones de la página (sección 9): la ruta, las entradas, los avisos y sus textos, la salida y la privacidad. Las confirma el autor; después, el paso 7, la página.
- paso 6: el autor confirma las decisiones de la página con cada recomendación (sección 9 del plan, «Decidido en el paso 6»): `time_only` por defecto, la zona del dispositivo con un selector, los avisos de §53 y §50 desde 365 días y un aviso de protocolo preliminar;
- paso 7 (`3a9d2b1`): la página `/create`, con `lengths.ts` (el tamaño del `.dkc` antes de escribirlo), `localtime.ts`, `create-input.ts` y `creator.ts`. En la compilación de producción, una cápsula creada para dentro de cuatro minutos se abrió después en `/inspect`, con el release pegado de drand, y con `datekeys decrypt` de Go, con red y su `.dkk`, al mismo contenido. Una revisión adversarial encontró un fallo mayor y ocho menores, todos corregidos. El mayor: la `.dkk` que es la única credencial se podía borrar sin confirmación.
**Siguiente:** que el autor decida si cierra `0.2.0` (tag `v0.2.0` en `datekeys-ts`). Después, lo de §2.4.
**Conclusiones de la conversación, sin decisión pendiente:**
**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.
- 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.
@ -187,11 +190,11 @@ El vector de GT (`vectors/tlock_ibe.json`) ya está cubierto en `App`. El paso 9
- Crear `security@datekeys.com` y, si se quiere, un `security.txt` en la web. Después, actualizar `SECURITY.md`, que hoy dice `info@activething.com`.
- Crear `security@datekeys.com` y, si se quiere, un `security.txt` en la web. Después, actualizar `SECURITY.md`, que hoy dice `info@activething.com`.
- Elegir la ruta pública del módulo Go (propuesta: `datekeys.com/go/datekeys`, en minúsculas) y el espejo público, que no puede ser GitHub (por ejemplo Codeberg). Publicar la página `go-import` en `datekeys.com`. Después: renombrar el módulo y poner el tag `v0.1.0` cuando `go get` funcione desde una máquina limpia.
- Elegir la ruta pública del módulo Go (propuesta: `datekeys.com/go/datekeys`, en minúsculas) y el espejo público, que no puede ser GitHub (por ejemplo Codeberg). Publicar la página `go-import` en `datekeys.com`. Después: renombrar el módulo y poner el tag `v0.1.0` cuando `go get` funcione desde una máquina limpia.
- Confirmar las decisiones de la página de la fase 3 (sección 9 del plan): la ruta, las entradas, los avisos y sus textos, la salida y la privacidad.
- Decidir si `datekeys-ts` cierra `0.2.0`, ahora que la fase 3 está completa.
### 2.4 Más adelante
### 2.4 Más adelante
Release API sobre la librería, traducción del spec al inglés y revisión externa antes de la v1.0. La fase 3 está en curso (§2.5, paso 6).
Release API sobre la librería, traducción del spec al inglés y revisión externa antes de la v1.0. Opcional: escribir en OPFS en trozos de 1 MiB, que ahorra un 10 % al cifrar ficheros grandes en la página (README de `datekeys-ts`, «Crear»).
@ -490,7 +490,7 @@ La cobertura de los módulos nuevos se fija en el 100 %.
## 9. Página
## 9. Página
Propuesta para el paso 6, pendiente de confirmación del autor:
Propuesta para el paso 6, confirmada por el autor el 29-09-2026 con cada recomendación (ver «Decidido en el paso 6», al final de la sección):
- **Ruta y navegación.**
- **Ruta y navegación.**
- `/create`, con el enlace "Crear" junto a "Inspector" en `+layout.svelte`.
- `/create`, con el enlace "Crear" junto a "Inspector" en `+layout.svelte`.
- El writer se carga con `import()`, igual que la apertura. La lista de recipients se valida con `recipient.ts`, que no trae noble.
- El writer se carga con `import()`, igual que la apertura. La lista de recipients se valida con `recipient.ts`, que no trae noble.
@ -549,6 +549,19 @@ Queda para que el autor decida en el paso 6:
- un aviso para fechas muy cercanas;
- un aviso para fechas muy cercanas;
- que las extensiones y el código de relleno no se exponen en esta fase.
- que las extensiones y el código de relleno no se exponen en esta fase.
**Decidido en el paso 6 (29-09-2026).** El autor confirma la propuesta con cada recomendación:
- ruta `/create`, con el enlace "Crear" junto a "Inspector";
- política por defecto "solo fecha" (`time_only`): un único fichero y nada secreto que perder, con "fecha y clave" a un clic;
- zona del dispositivo por defecto, con el selector de todas las zonas y UTC;
- una hora que no existe se rechaza con un mensaje, y de una hora ambigua se toma la más tardía;
- ficheros `capsula-<fecha UTC de apertura>.dkc` y `.dkk`, editables;
- la `.dkk` nunca se muestra como `AGE-SECRET-KEY-1…`;
- los avisos de §53 y §50 desde 365 días hasta el instante efectivo, con los textos de arriba, y el de §7.4 junto a la `.dkk`;
- un aviso breve de protocolo preliminar (v0.9, §74) antes de cifrar;
- sin tamaño máximo propio: manda la cuota de OPFS, y 64 MiB en memoria sin OPFS;
- un aviso informativo cuando el instante efectivo está a menos de una hora;
- relleno siempre `reforzado`, sin extensiones en esta fase.
---
---
## 10. Orden de trabajo y criterios de aceptación
## 10. Orden de trabajo y criterios de aceptación
@ -561,8 +574,8 @@ Queda para que el autor decida en el paso 6:
| 3 | `encrypt.ts` y `writer.ts` con entrada en memoria (sección 4) | La tabla de opciones inválidas da los textos y códigos esperados, sin escribir nada y con la salida abortada.<br>Las secciones deterministas de los siete fixtures de formato 2 salen byte a byte, y cada credencial abre su hueco (sección 8, punto 2).<br>Ida y vuelta con `open` para las dos políticas, de 1 a 16 credenciales y los dos códigos.<br>Claves portables nunca repetidas; caso `now + 1 h`.<br>Los dos módulos al 100 %, fijado como umbral.<br>Hecho el 29-09-2026, junto con el paso 4 (`8473fdf`) |
| 3 | `encrypt.ts` y `writer.ts` con entrada en memoria (sección 4) | La tabla de opciones inválidas da los textos y códigos esperados, sin escribir nada y con la salida abortada.<br>Las secciones deterministas de los siete fixtures de formato 2 salen byte a byte, y cada credencial abre su hueco (sección 8, punto 2).<br>Ida y vuelta con `open` para las dos políticas, de 1 a 16 credenciales y los dos códigos.<br>Claves portables nunca repetidas; caso `now + 1 h`.<br>Los dos módulos al 100 %, fijado como umbral.<br>Hecho el 29-09-2026, junto con el paso 4 (`8473fdf`) |
| 4 | Streaming y salida (sección 6) | `Uint8Array`, `Blob` y `ReadableStream` dan el mismo contenido al abrir y las mismas longitudes, también con un trozo de entrada de varios MiB.<br>Nada se escribe antes del paso 17 del flujo.<br>Una salida o una fuente que fallan, una fuente de L ± 1 bytes y un `progress` que lanza dejan la salida abortada y nunca cerrada.<br>`capsule_digest` es el SHA-256 de lo escrito.<br>El bucle de propiedades pasa con 50 semillas, y con 500 a mano.<br>Las mezclas dan el código y el paso esperados.<br>Medida de rendimiento en Node, anotada en el README.<br>Hecho el 29-09-2026 (`8473fdf`): 500 semillas del bucle de propiedades en 203 s; en Node 24.9, unos 120 ms por cápsula `time_only` y 50 MiB/s desde un `Blob` |
| 4 | Streaming y salida (sección 6) | `Uint8Array`, `Blob` y `ReadableStream` dan el mismo contenido al abrir y las mismas longitudes, también con un trozo de entrada de varios MiB.<br>Nada se escribe antes del paso 17 del flujo.<br>Una salida o una fuente que fallan, una fuente de L ± 1 bytes y un `progress` que lanza dejan la salida abortada y nunca cerrada.<br>`capsule_digest` es el SHA-256 de lo escrito.<br>El bucle de propiedades pasa con 50 semillas, y con 500 a mano.<br>Las mezclas dan el código y el paso esperados.<br>Medida de rendimiento en Node, anotada en el README.<br>Hecho el 29-09-2026 (`8473fdf`): 500 semillas del bucle de propiedades en 203 s; en Node 24.9, unos 120 ms por cápsula `time_only` y 50 MiB/s desde un `Blob` |
| 5 | Interoperabilidad TS → Go a nivel de cápsula (sección 8, punto 9) | Go inspecciona y abre todas las muestras con cada credencial, con el mismo SHA-256 del contenido y los mismos L, código y P.<br>Go recodifica PUBLIC_HEADER, CONTROL_CBOR y `.dkk` a los mismos bytes.<br>El diferencial de encoders no da ninguna diferencia.<br>Las mezclas dan el mismo código y paso en Go y en TypeScript.<br>Los veredictos de recipients y los textos de opciones coinciden, salvo los `TypeError` de la decisión 9.<br>Todo congelado en `capsule-vectors.json`.<br>README con la fila "Equivale en Go" de `encrypt.ts` (`capsule.Encrypt`, `accesskey.Encode`).<br>Hecho el 29-09-2026 (`da0b39f`): trece muestras, cuatro mezclas, 500 entradas de los codificadores, 22 recipients y 21 opciones inválidas, sin ninguna diferencia con Go |
| 5 | Interoperabilidad TS → Go a nivel de cápsula (sección 8, punto 9) | Go inspecciona y abre todas las muestras con cada credencial, con el mismo SHA-256 del contenido y los mismos L, código y P.<br>Go recodifica PUBLIC_HEADER, CONTROL_CBOR y `.dkk` a los mismos bytes.<br>El diferencial de encoders no da ninguna diferencia.<br>Las mezclas dan el mismo código y paso en Go y en TypeScript.<br>Los veredictos de recipients y los textos de opciones coinciden, salvo los `TypeError` de la decisión 9.<br>Todo congelado en `capsule-vectors.json`.<br>README con la fila "Equivale en Go" de `encrypt.ts` (`capsule.Encrypt`, `accesskey.Encode`).<br>Hecho el 29-09-2026 (`da0b39f`): trece muestras, cuatro mezclas, 500 entradas de los codificadores, 22 recipients y 21 opciones inválidas, sin ninguna diferencia con Go |
| 6 | Decisiones de la página (sección 9) | el autor confirma la ruta, las entradas, los avisos y sus textos, la salida y la privacidad |
| 6 | Decisiones de la página (sección 9) | el autor confirma la ruta, las entradas, los avisos y sus textos, la salida y la privacidad.<br>Hecho el 29-09-2026: todas con su recomendación (sección 9, «Decidido en el paso 6») |
| 7 | Página | En la compilación de producción, un fichero propio se cifra a `.dkc` y `.dkk` sin ninguna petición fuera del origen, y el informe de los pasos 1 a 8 del `.dkc` escrito pasa, con formato 2.<br>Una cápsula creada para dentro de dos o tres minutos se abre después en `/inspect` con el release pegado, y a mano con `datekeys decrypt` de Go, con red y con su `.dkk`.<br>El aviso de §53 aparece antes de cifrar, solo pasado el umbral.<br>Cancelar a mitad no deja fichero temporal.<br>Sin OPFS, la escritura va a memoria.<br>375 px de ancho.<br>`check-build` generalizado, en verde.<br>Tamaño del bundle de la página anotado.<br>Módulos nuevos al 100 %.<br>Revisión adversarial con cada hallazgo contrastado |
| 7 | Página | En la compilación de producción, un fichero propio se cifra a `.dkc` y `.dkk` sin ninguna petición fuera del origen, y el informe de los pasos 1 a 8 del `.dkc` escrito pasa, con formato 2.<br>Una cápsula creada para dentro de dos o tres minutos se abre después en `/inspect` con el release pegado, y a mano con `datekeys decrypt` de Go, con red y con su `.dkk`.<br>El aviso de §53 aparece antes de cifrar, solo pasado el umbral.<br>Cancelar a mitad no deja fichero temporal.<br>Sin OPFS, la escritura va a memoria.<br>375 px de ancho.<br>`check-build` generalizado, en verde.<br>Tamaño del bundle de la página anotado.<br>Módulos nuevos al 100 %.<br>Revisión adversarial con cada hallazgo contrastado.<br>Hecho el 29-09-2026 (`3a9d2b1`): todo lo anterior, comprobado en Chromium sobre la compilación de producción; `lengths.ts` da el tamaño antes de escribir. La revisión adversarial encontró un fallo mayor (la `.dkk` única se borraba sin confirmación) y ocho menores, todos contrastados y corregidos |
Cada paso termina con `npm run verify` en verde y un commit en Gitea, y actualiza README, CHANGELOG, HANDOFF y la fila de esta tabla. El paso 6 puede ir en paralelo con los pasos 2 a 5. El script de Go del paso 5 puede empezarse durante el paso 4.
Cada paso termina con `npm run verify` en verde y un commit en Gitea, y actualiza README, CHANGELOG, HANDOFF y la fila de esta tabla. El paso 6 puede ir en paralelo con los pasos 2 a 5. El script de Go del paso 5 puede empezarse durante el paso 4.
@ -42,6 +42,6 @@ Para retomar el trabajo, lee [HANDOFF.md](HANDOFF.md): el estado de cada repo, l
| [PLAN_libreria_go.md](PLAN_libreria_go.md) | Plan de la librería Go, hitos M0 a M5 (hecho) |
| [PLAN_libreria_go.md](PLAN_libreria_go.md) | Plan de la librería Go, hitos M0 a M5 (hecho) |
| [PLAN_codec_cbor_y_pagina_svelte.md](PLAN_codec_cbor_y_pagina_svelte.md) | v2: codec CBOR propio en Go y TypeScript, librería TypeScript y página `/inspect` (hecho) |
| [PLAN_codec_cbor_y_pagina_svelte.md](PLAN_codec_cbor_y_pagina_svelte.md) | v2: codec CBOR propio en Go y TypeScript, librería TypeScript y página `/inspect` (hecho) |
| [PLAN_fase2_ibe_noble2.md](PLAN_fase2_ibe_noble2.md) | v2: fase 2, abrir cápsulas en el navegador (hecho) |
| [PLAN_fase2_ibe_noble2.md](PLAN_fase2_ibe_noble2.md) | v2: fase 2, abrir cápsulas en el navegador (hecho) |
| [PLAN_fase3_escritura.md](PLAN_fase3_escritura.md) | Fase 3, writer TypeScript del formato 2 (v0.9). v3, con las decisiones confirmadas; pasos 0 a 5 hechos (la librería y su interoperabilidad con Go); siguen las decisiones de la página y la página |
| [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 |
| [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.9/](spec_v0.9/README.md) | Papeles de trabajo del borrador v0.9: diseño, revisiones y correcciones pendientes |