Spec v0.10 draft of delivery 1, its final review, and the handoff

- spec_v0.10/revision_borrador.md records the final review of the
  draft (datekeys-go branch v0.10): one blocking, three major and
  eleven minor corrections, all applied there in 9d1cd2e.
- The design follows the corrections that touch it (annex D): R6c only
  rejects '/', '\', ':' and U+0000 in a best-fit projection, so "¿"
  and "♥" are accepted; the CLI prefixes paths too, redirected or not.
  It also answers the author's question on several signatures: a
  future alg can carry a list without changing the format.
- The handoff records the state and the next steps: the author picks
  the Unicode version of the tables (18.0.0 came out on 16-09-2026)
  and approves the text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
main
dev 1 week ago
parent afd9f769dc
commit fe8d15f1a0

@ -1,6 +1,6 @@
# Handoff DateKeys, 26 de septiembre de 2026 (actualizado el 30 a mediodía: diseño del formato 3 corregido y en tres entregas) # Handoff DateKeys, 26 de septiembre de 2026 (actualizado el 30 por la tarde: borrador del spec v0.10 de la entrega 1, revisado)
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ó; a mediodía se aplicaron al diseño esa revisión y las decisiones del autor, y quedó separado en tres entregas (§2.5, al final). 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ó; a mediodía se aplicaron al diseño esa revisión y las decisiones del autor, y quedó separado en tres entregas; por la tarde, el autor cerró las preguntas de la entrega 1, y se redactó y revisó el borrador del spec v0.10 (§2.5, al final). Sirve para retomar sin contexto previo, sea una persona o una sesión de Claude.
--- ---
@ -37,6 +37,7 @@ Los repos con remoto están en el Gitea privado `g.activething.com` (solo LAN, c
| `datekeys-go` (`go/DateKeys`) | `main` | `7e2d83c` | Spec v0.9 cerrada, con el tag anotado **`spec-v0.9`** en `7e2d83c`; SHA-256 del spec `36189e1e62f0f835b7665219aa63df7200cd89ac4e4e924f2705f970fa7c40a9`. Implementa el formato 2 (`f24a280`): lo escribe y lee los formatos 1 y 2. `scripts/check.sh 60s` limpio. La v0.8.2 sigue en su tag, `spec-v0.8.2` (`9ac9cd9`). | | `datekeys-go` (`go/DateKeys`) | `main` | `7e2d83c` | Spec v0.9 cerrada, con el tag anotado **`spec-v0.9`** en `7e2d83c`; SHA-256 del spec `36189e1e62f0f835b7665219aa63df7200cd89ac4e4e924f2705f970fa7c40a9`. Implementa el formato 2 (`f24a280`): lo escribe y lee los formatos 1 y 2. `scripts/check.sh 60s` limpio. La v0.8.2 sigue en su tag, `spec-v0.8.2` (`9ac9cd9`). |
| | `v0.8.2` | `9ac9cd9` | El commit del tag; ya no hace falta. | | | `v0.8.2` | `9ac9cd9` | El commit del tag; ya no hace falta. |
| | `v0.9` | `7e2d83c` | Igual que `main`; ya no hace falta. | | | `v0.9` | `7e2d83c` | Igual que `main`; ya no hace falta. |
| | `v0.10` | `9d1cd2e` | Borrador del spec v0.10, entrega 1 del formato 3: el spec, el CDDL y `spec/README.md`. Sin aprobar y sin subir; el código sigue en la v0.9. |
| `datekeys-ts`, antes `App` (`go/DateKeys-App`) | `main` | `da26862` | Desde `5ee8813`, sin `docs/` y con el paquete `datekeys-ts` (§0). Versión `0.2.0-dev` desde `8c08c97`, con `v0.1.0` cerrada en `d577283`; implementa el spec 0.9 desde `0118890` (`VERSION` y `SPEC_VERSION`, también en el pie de la página). Escribe el formato 2 y tiene la página `/create` (fase 3, §2.5). Librería TypeScript con la inspección (pasos 1 a 8) y la apertura (pasos 9 a 18) de los formatos 1 y 2, en memoria o desde un `Blob` hacia un stream de salida, como un fichero OPFS. Página `/inspect` con la acción "abrir", que muestra el formato y avisa del 1. `testdata` sincronizado a `7e2d83c` (`spec-v0.9`). Fase 2 completa (pasos 2 a 8), incluidos el cifrado tlock y la interoperabilidad de TypeScript a Go. Los 125 casos del corpus pasan por `open` con el código, el paso y el texto de Go. En `0118890`, 5 425 tests, ninguno saltado; la fase 3 añadió los suyos, con `npm run verify` en verde en cada paso (§2.5). | | `datekeys-ts`, antes `App` (`go/DateKeys-App`) | `main` | `da26862` | Desde `5ee8813`, sin `docs/` y con el paquete `datekeys-ts` (§0). Versión `0.2.0-dev` desde `8c08c97`, con `v0.1.0` cerrada en `d577283`; implementa el spec 0.9 desde `0118890` (`VERSION` y `SPEC_VERSION`, también en el pie de la página). Escribe el formato 2 y tiene la página `/create` (fase 3, §2.5). Librería TypeScript con la inspección (pasos 1 a 8) y la apertura (pasos 9 a 18) de los formatos 1 y 2, en memoria o desde un `Blob` hacia un stream de salida, como un fichero OPFS. Página `/inspect` con la acción "abrir", que muestra el formato y avisa del 1. `testdata` sincronizado a `7e2d83c` (`spec-v0.9`). Fase 2 completa (pasos 2 a 8), incluidos el cifrado tlock y la interoperabilidad de TypeScript a Go. Los 125 casos del corpus pasan por `open` con el código, el paso y el texto de Go. En `0118890`, 5 425 tests, ninguno saltado; la fase 3 añadió los suyos, con `npm run verify` en verde en cada paso (§2.5). |
| `docs` (solo local) | `main` | | Este repo: handoff, planes, revisiones y reglas. | | `docs` (solo local) | `main` | | Este repo: handoff, planes, revisiones y reglas. |
| `web` (solo local) | `main` | `f2b8a38` | Landing de datekeys.com. | | `web` (solo local) | `main` | `f2b8a38` | Landing de datekeys.com. |
@ -90,7 +91,7 @@ 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í) ### 2.5 Sesiones del 29-09: v0.9 del spec y formato 2 en Go (retomar aquí)
**Estado al parar (30-09 a mediodía). Retomar por el formato 3, al final de esta sección:** el diseño ya lleva la revisión de Fable y las decisiones del autor, y está separado en tres entregas. Queda que el autor cierre las diez preguntas de la entrega 1 y, después, redactar su texto del spec v0.10. **Estado al parar (30-09 por la tarde). Retomar por el formato 3, al final de esta sección:** el borrador del spec v0.10 de la entrega 1 está redactado y revisado en `datekeys-go`, rama `v0.10` (`9d1cd2e`, sin subir). Queda que el autor elija la versión de Unicode de las tablas y apruebe el texto.
**Estado al cerrar la fase 3 (29-09 por la noche):** **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`. - 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`.
@ -237,11 +238,17 @@ El vector de GT (`vectors/tlock_ibe.json`) ya está cubierto en `App`. El paso 9
- R3 limita el NFD de cada segmento a 255 unidades UTF-16, por HFS+, y R4 prohíbe U+F000–U+F0FF; - R3 limita el NFD de cada segmento a 255 unidades UTF-16, por HFS+, y R4 prohíbe U+F000–U+F0FF;
- un sello que no verifica se descarta y ya no aborta la cápsula. - un sello que no verifica se descarta y ya no aborta la cápsula.
- **Interpretación que confirmar:** la decisión 3 hablaba de «una versión de `security` con un área fija mayor». El diseño hace que el área la fije la versión del spec y deja el mapa `security` en su versión 1, para que un lector de la entrega 2 siga comprobando la firma en una cápsula de la entrega 3. Es la pregunta 3 de la entrega 1. - **Interpretación que confirmar:** la decisión 3 hablaba de «una versión de `security` con un área fija mayor». El diseño hace que el área la fije la versión del spec y deja el mapa `security` en su versión 1, para que un lector de la entrega 2 siga comprobando la firma en una cápsula de la entrega 3. Es la pregunta 3 de la entrega 1.
- **Hecho el 30-09 por la tarde:**
- El autor cerró las diez preguntas de la entrega 1, todas con la recomendación (`afd9f76`). Los límites quedan como se propusieron y congelados con el formato. Un único fichero dentro de una carpeta se descarga directamente, con el ZIP como opción, y la página ofrece cada fichero del ZIP como un corte suyo.
- El borrador del spec v0.10 de la entrega 1 está en `datekeys-go`, rama `v0.10`, sin subir: `fa7f95e` lo redacta y `9d1cd2e` aplica la revisión final. Lleva el spec, el CDDL y `spec/README.md`. La referencia sigue implementando la v0.9, y su `SpecVersion` no cambia.
- La revisión final, como la de la v0.9, encontró un problema bloqueante, tres mayores y once menores, todos corregidos ([spec_v0.10/revision_borrador.md](spec_v0.10/revision_borrador.md)). El bloqueante: R6c rechazaba «¿», porque bestfit1250 lo lleva a '?'. Ahora solo rechaza '/', '\', ':' y U+0000 en una proyección. El diseño recoge los cambios que le afectan en su anexo D.
- Pregunta del autor: la firma de autor con su clave privada está prevista, en la entrega 2. Varias firmas no hace falta decidirlas ahora: un `alg` futuro puede definir una lista de firmas sin cambiar el formato (pregunta 3 de la entrega 2 del diseño).
- **Siguiente:** - **Siguiente:**
1. El autor cierra las diez preguntas de la entrega 1 (apartado 9 del diseño). Todas traen recomendación salvo los límites de tamaño. 1. El autor elige la versión de Unicode de las tablas. El diseño y el borrador dicen 17.0.0, pero Unicode 18.0.0 salió el 16-09-2026, con 13 007 caracteres nuevos. Las tablas quedan congeladas con el formato 3, así que la recomendación es la 18.0.0; el cambio toca §29.5.1, §73, §75, §76 y §77.
2. Se redacta el texto del spec v0.10 de la entrega 1 para que lo apruebe el autor. 2. El autor aprueba el texto del spec v0.10.
3. La entrega 2 abre la versión siguiente del spec; la 3 espera al documento «Servicio de sellado DateKeys v1». 3. La referencia Go implementa el formato 3 con sus fixtures, vectores y mutaciones, fija los SHA-256 de las tablas y pasa `scripts/check.sh`. Después, con la autorización del autor, el tag `spec-v0.10`, como en la v0.9.
4. Para otra revisión externa, el artefacto hay que volver a publicarlo desde el diseño nuevo. 4. `datekeys-ts` sincroniza `testdata` y lee y escribe el formato 3.
5. La entrega 2 abre la versión siguiente del spec, y la 3 espera al documento «Servicio de sellado DateKeys v1». Para otra revisión externa, el artefacto hay que volver a publicarlo desde el diseño nuevo.
**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.

@ -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`) | | [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 |
| [spec_v0.10/](spec_v0.10/formato3_diseno.md) | Formato de cápsula 3 en diseño, en tres entregas: varios ficheros, firma de autor y sello de tiempo. El diseño, con las dos revisiones incorporadas, y la revisión de Fable | | [spec_v0.10/](spec_v0.10/formato3_diseno.md) | Formato de cápsula 3 en diseño, en tres entregas: varios ficheros, firma de autor y sello de tiempo. El diseño, con sus revisiones incorporadas, la revisión de Fable y la revisión final del borrador del spec |

@ -289,7 +289,7 @@ R1 y R8 son capa 3 sobre todo el array; las demás, capa 4. Así, [«b/..», «a
- la parte posterior mide de 0 a 3. - la parte posterior mide de 0 a 3.
La expresión regular no usa búsquedas anticipadas, que el paquete `regexp` de Go no admite; en JavaScript va con la bandera `u`. «~1» a secas también se rechaza. En NTFS «ABCDEF~1» resuelve a «ABCDEFGHIJ» (comprobado), así que `Root.MkdirAll` y el Explorador fusionarían dos carpetas distintas. La expresión regular no usa búsquedas anticipadas, que el paquete `regexp` de Go no admite; en JavaScript va con la bandera `u`. «~1» a secas también se rechaza. En NTFS «ABCDEF~1» resuelve a «ABCDEFGHIJ» (comprobado), así que `Root.MkdirAll` y el Explorador fusionarían dos carpetas distintas.
- **R6c.** Best-fit. Para cada `bestfit*.txt` de WindowsBestFit, fijadas por digest, se sustituye cada punto no ASCII que la tabla lleva a ASCII por ese byte. Se rechaza si alguna proyección contiene '/' o un carácter ASCII de R4, o incumple R3, R5, R6 o R6b. Cubre ∖, ∶, ¥ (cp932), ₩ (cp949), ´ (cp1253), las formas de ancho completo y «CON.txt». - **R6c.** Best-fit. Para cada `bestfit*.txt` de WindowsBestFit, fijadas por digest, se sustituye cada punto no ASCII que la tabla lleva a ASCII por ese byte. Se rechaza si alguna proyección contiene '/', '\', ':' o U+0000, o incumple R3, R5, R6 o R6b. Cubre ∖, ∶, ¥ (cp932), ₩ (cp949), ´ (cp1253), las formas de ancho completo, «CON.txt» y U+3000 en los extremos, que bestfit1252 lleva a U+0020. Los demás caracteres de R4 que dé una proyección no se rechazan: con la API ANSI de Windows hacen fallar la creación del fichero, pero no cambian su destino. Así se aceptan «¿», que bestfit1250 lleva a '?', y «§», «♥» y las flechas, que bestfit874 lleva a controles C0 (anexo D).
- **R7.** Árbol plegado. - **R7.** Árbol plegado.
- Nodos: las rutas y sus prefijos. - Nodos: las rutas y sus prefijos.
- Clave de cada segmento: NFD(pliegue(NFD(s′))), con s′ el segmento sin los puntos de la lista blanca de R4 y el pliegue C+F de CaseFolding 17.0.0 más ı → i (NTFS). Se quitan antes de normalizar porque los cuatro son starters (ccc 0): entre dos marcas combinantes, cambiarían su orden canónico. Los directorios con casefold de ext4 y f2fs también ignoraban los puntos ignorables al comparar, hasta 2025; no está comprobado aquí. - Clave de cada segmento: NFD(pliegue(NFD(s′))), con s′ el segmento sin los puntos de la lista blanca de R4 y el pliegue C+F de CaseFolding 17.0.0 más ı → i (NTFS). Se quitan antes de normalizar porque los cuatro son starters (ccc 0): entre dos marcas combinantes, cambiarían su orden canónico. Los directorios con casefold de ext4 y f2fs también ignoraban los puntos ignorables al comparar, hasta 2025; no está comprobado aquí.
@ -373,12 +373,12 @@ Con un sello válido, una mtime posterior a t se muestra como incoherencia.
- Primero van los veredictos. - Primero van los veredictos.
- Después, «autor declarado (texto del creador, sin comprobar)» y el comentario, en un recuadro titulado «Comentario del creador (sin comprobar)». - Después, «autor declarado (texto del creador, sin comprobar)» y el comentario, en un recuadro titulado «Comentario del creador (sin comprobar)».
- **En la CLI (hallazgo 7):** - **En la CLI (hallazgo 7), sea o no su salida un terminal:**
- expande cada TAB del comentario a espacios, hasta la siguiente columna múltiplo de 8; - expande cada TAB del comentario a espacios, hasta la siguiente columna múltiplo de 8;
- parte cada línea del autor y del comentario en trozos de ancho visual como mucho W − 3, con W el ancho del terminal, u 80 si la salida no es un terminal, y nunca menos de 20; cada trozo lleva al menos un punto de código; - parte cada línea del autor, del comentario y de cada ruta que muestre en trozos de ancho visual como mucho W − 3, con W el ancho del terminal, u 80 si la salida no es un terminal, y nunca menos de 20; cada trozo lleva al menos un punto de código;
- cuenta el ancho por lo alto: 1 por carácter ASCII imprimible y 2 por cualquier otro punto de código. El prefijo `│ ` cuenta 3, porque U+2502 tiene anchura ambigua y ocupa 2 columnas en un terminal CJK; - cuenta el ancho por lo alto: 1 por carácter ASCII imprimible y 2 por cualquier otro punto de código. El prefijo `│ ` cuenta 3, porque U+2502 tiene anchura ambigua y ocupa 2 columnas en un terminal CJK;
- pone `│ ` delante de cada trozo. Así el terminal nunca parte una línea por su cuenta, y ninguna queda sin prefijo; - pone `│ ` delante de cada trozo. Así el terminal nunca parte una línea por su cuenta, y ninguna queda sin prefijo;
- después del comentario repite los veredictos. - repite los veredictos al final, después del comentario y de las rutas que muestre.
### 5. Escritor y lector ### 5. Escritor y lector
@ -493,7 +493,7 @@ Ejemplos:
- **Fixtures:** `format3_single`, `_tree`, `_comment_only`, `_bloque256`, `_time_and_key_portable`, `_area_1024` (el lector acepta un área mayor), `_security_v2` (veredicto X), `_signature_unsupported`, con alg 1, una clave de 32 bytes y una firma de 64, aleatorias (F1 en la entrega 1 y F2 desde la 2), y `_seal_unsupported`, con esa firma y un sello de `seal_type` 1 con un token aleatorio (F1 y S1 en la entrega 1; S2 desde la 3). - **Fixtures:** `format3_single`, `_tree`, `_comment_only`, `_bloque256`, `_time_and_key_portable`, `_area_1024` (el lector acepta un área mayor), `_security_v2` (veredicto X), `_signature_unsupported`, con alg 1, una clave de 32 bytes y una firma de 64, aleatorias (F1 en la entrega 1 y F2 desde la 2), y `_seal_unsupported`, con esa firma y un sello de `seal_type` 1 con un token aleatorio (F1 y S1 en la entrega 1; S2 desde la 3).
- **Vectores:** - **Vectores:**
- `paths.json` y `head_schema.json`: U+00A0 y U+3000 en los extremos, que se aceptan; best-fit; 8.3 con la expresión regular, «~1» incluido; Cn; [«b/..», «a»]; U+206A–206F, las etiquetas y otros ignorables fuera de la lista blanca; «.» seguido de ZWJ y un segmento hecho solo de ZWJ; 127 veces «ΐ»; U+F03A; «.datekeys-x» en el primer nivel y en otro; el orden de U+FF5E y U+1F600; - `paths.json` y `head_schema.json`: U+00A0 y U+3000 en los extremos, con el veredicto que den las tablas, que para U+3000 es el rechazo por R6c; «¿», «§» y «♥», que se aceptan; best-fit; 8.3 con la expresión regular, «~1» incluido; Cn; [«b/..», «a»]; U+206A–206F, las etiquetas y otros ignorables fuera de la lista blanca; «.» seguido de ZWJ y un segmento hecho solo de ZWJ; 127 veces «ΐ»; U+F03A; «.datekeys-x» en el primer nivel y en otro; el orden de U+FF5E y U+1F600;
- `path_fold.json`, con «ab» con y sin ZWNJ; - `path_fold.json`, con «ab» con y sin ZWNJ;
- `security.json`: el mapa exterior con la clave 2 que no es una cadena de bytes, con una clave 4 o con un byte de más dentro de `SECURITY_LEN` (X); `alg` 0 o una clave vacía dentro de la clave 2 (F1, con el sello intacto); - `security.json`: el mapa exterior con la clave 2 que no es una cadena de bytes, con una clave 4 o con un byte de más dentro de `SECURITY_LEN` (X); `alg` 0 o una clave vacía dentro de la clave 2 (F1, con el sello intacto);
- `zip.json`: mtime 1, 2³¹, 2040 y 253402300799, y 65535 entradas. - `zip.json`: mtime 1, 2³¹, 2040 y 253402300799, y 65535 entradas.
@ -638,6 +638,7 @@ Un tercero recibe un paquete (`datekeys statement export|verify`) con PRELUDE, `
1. ¿Fichero de clave cifrado por defecto? Sí, con logN 16. 1. ¿Fichero de clave cifrado por defecto? Sí, con logN 16.
2. ¿Sin sello, la clave solo se guarda pegándola desde otro canal? Sí: una firma sin sello puede haberse rehecho tras la fecha. 2. ¿Sin sello, la clave solo se guarda pegándola desde otro canal? Sí: una firma sin sello puede haberse rehecho tras la fecha.
3. ¿Varias firmas, de coautores, de un notario o de un testigo? No hace falta decidirlo ahora. Hay un solo hueco de firma, pero su `alg` permite que una versión posterior defina una lista de firmas sin cambiar el formato. Un lector anterior la mostraría como F1, abriría la cápsula igual y seguiría comprobando el sello, porque la clave 3 va aparte.
--- ---
@ -851,3 +852,12 @@ Un revisor comprobó que los arreglos de Fable y las decisiones del autor están
- las referencias al código y las cruzadas. - las referencias al código y las cruzadas.
Quedan sin verificar Unicode 17.0, las tablas WindowsBestFit, HFS+ en una máquina y los mapeos de Cygwin, WSL y el SMB de macOS. Quedan sin verificar Unicode 17.0, las tablas WindowsBestFit, HFS+ en una máquina y los mapeos de Cygwin, WSL y el SMB de macOS.
## Anexo D. Revisión final del borrador del spec v0.10 (30-09)
El borrador del spec de la entrega 1 (`datekeys-go`, rama `v0.10`) pasó una revisión final, como la de la v0.9. Encontró un problema bloqueante, tres mayores y once menores, todos corregidos en el borrador. La lista completa está en [revision_borrador.md](revision_borrador.md). Estos cambian el diseño:
- **R6c (bloqueante).** Rechazaba cualquier carácter ASCII de R4 en una proyección best-fit, y las tablas llevan ahí caracteres corrientes: bestfit1250 convierte «¿» en '?', y bestfit874 convierte «§», «♥» y las flechas en controles C0. «¿Qué es esto.jpg» no se habría podido guardar. Ahora solo rechaza '/', '\', ':' y U+0000, que son los que cambian el destino con la API ANSI de Windows (apartado 3).
- **Rutas en la salida de la CLI.** El prefijo y la repetición de los veredictos valen también para las rutas que muestre, y para una salida que no es un terminal (apartado 4).
- **Precedencia del paso 17.** Los códigos distintos de `ERR_INTEGRITY` se informan después de leer `PAYLOAD_AGE` hasta EOF, no hasta el final del STREAM: los datos tras el chunk final prevalecen, y `filippo.io/age` los señala en la lectura siguiente.
- **Orden de los veredictos.** `alg` y `seal_type` solo se leen de un contenido que cumple su schema: un `seal` con una clave desconocida es S2, no S1.

@ -0,0 +1,27 @@
# Revisión final del borrador del spec v0.10 (30-09-2026)
*Revisión del borrador de la entrega 1 del formato 3, en `datekeys-go`, rama `v0.10`, commit `fa7f95e`. La hizo un revisor adversarial, como la revisión final de la v0.9, contra el diseño ([formato3_diseno.md](formato3_diseno.md)) y el spec v0.9. Las quince correcciones están aplicadas en el commit siguiente de la rama.*
**Veredicto:** el traslado del diseño es fiel. Están las diez decisiones del apartado 9 del diseño, nada de las entregas 2 y 3 entra como normativo, y no se pierde nada de la v0.9. Los problemas son una consecuencia no prevista de R6c, que el diseño también tenía, y la redacción de algunos puntos de determinismo.
| # | Gravedad | Sección | Problema | Corrección |
|---|---|---|---|---|
| 1 | Bloqueante | §29.5, R6c; §76, cambio 5 | R6c rechazaba cualquier carácter ASCII de R4 en una proyección best-fit. bestfit1250 lleva «¿» a '?', bestfit874 lleva «§», «¶», «♥» y las flechas a controles C0, bestfit1253 lleva «←» y «→» a '<' y '>', y bestfit1252 lleva U+3000 a U+0020. «¿Qué es esto.jpg» o «Para ti ♥.jpg» se habrían rechazado, y relajarlo después exigiría un formato nuevo. | R6c solo rechaza '/', '\', ':' y U+0000, que cambian el destino con la API ANSI de Windows, y sigue aplicando R3, R5, R6 y R6b a la proyección. Los demás hacen fallar la creación del fichero, pero no cambian su destino. |
| 2 | Mayor | §63, paso 17; §69.1; §76, cambio 8 | «Autenticar los P bytes» dejaba fuera los datos tras el chunk final, que `filippo.io/age` señala en la lectura siguiente; 17.1 incluía la comprobación del relleno, que también es 17.8; y 17.3 y 17.6 contaban como fallos. | Los códigos distintos de `ERR_INTEGRITY` se informan tras leer `PAYLOAD_AGE` hasta EOF; 17.1 excluye el relleno; 17.3 y 17.6 nunca fallan. |
| 3 | Mayor | §29.7 | Faltaba el orden de las filas: un `seal` con una clave desconocida y un `seal_type` desconocido daba S1 o S2 según el lector. | Decide la primera fila que se cumple; `alg` y `seal_type` solo se leen de un contenido que cumple su schema. |
| 4 | Mayor | §58, §70 | Las dos secciones rechazaban toda codificación no canónica y toda versión desconocida, también en `security`, contra la regla de que `security` nunca decide la apertura. | Excepción explícita para `SECURITY_CBOR` y el contenido de sus claves 2 y 3: solo cambian los veredictos. |
| 5 | Menor | §76, cambio 8; §64; §69.1 | El caso era falso: con el chunk siguiente corrupto, las dos librerías entregan antes el del head. Solo divergen con el fichero cortado justo tras un chunk completo. | Caso, mutación y ejemplo nuevos con una ruta «..» y el corte exacto tras el chunk que la contiene. |
| 6 | Menor | §29.7 | Los textos de los veredictos eran solo del SDK oficial, con un MUST imposible de comprobar. | El SDK oficial MUST usar esos textos; otra implementación, esos textos o una traducción que no afirme más. |
| 7 | Menor | §29.7 | No quedaba claro si la presentación valía para una salida redirigida, y una ruta larga podía imitar un veredicto. | La regla vale para toda salida de texto, y cubre también las rutas. |
| 8 | Menor | §70 | Faltaba la regla del diseño para una interfaz que solo entrega un flujo de bytes. | Termina tras el paso 2 con un error del llamador, nunca con `ERR_UNSUPPORTED_VERSION`. |
| 9 | Menor | §62.1, regla 13 | Cuatro fixtures de §67 solo se pueden escribir incumpliendo la regla del área y de `security` vacío. | Excepción para un generador de vectores de prueba. |
| 10 | Menor | §76 | La lista de datos de prueba que cambian estaba incompleta. | Lista completa: dos mutaciones, `cbor.json`, el campo `spec`, `testdata/README.md` y las pruebas de las dos implementaciones. Comprobado que ninguno de los 4 380 casos del diferencial deja `VERSION` 3. |
| 11 | Menor | §64, §67 | Faltaban mutaciones de R1, R5, R7, R9, el autor y la maquetación, y lo que cubren los vectores. | Siete mutaciones más y un párrafo con la cobertura de los vectores. |
| 12 | Menor | §76, cambios 2 y 3 | Las cifras del cambio 2 suponían la mtime sin decirlo, y el cambio 3 citaba un límite de 8192 bytes que el texto no tiene. | Caso con mtime; el límite, atribuido al borrador anterior del diseño, con los tamaños de SLH-DSA. |
| 13 | Menor | §62.1, regla 16 | El MUST de tomar la mtime chocaba con la opción de quitarla. | El MUST vale solo si el escritor la incluye. |
| 14 | Menor | §29.5.1 | El conjunto de tablas no estaba cerrado: faltaba la clase de combinación canónica y la lista exacta de los quince ficheros best-fit. | Lista cerrada. Sus SHA-256 siguen por fijar al implementar. |
| 15 | Menor | §57, §69.1, §70, §73, §74, CDDL | Coherencia editorial. | Seis retoques. |
**Comprobado por el revisor:** las diez decisiones; los tamaños, recalculados con un codificador CBOR propio; las afirmaciones sobre Unicode, Node y Go; varias tablas best-fit de un solo byte; el CDDL frente al texto; y las referencias cruzadas.
**Sin comprobar:** la resolución 8.3 en NTFS, HFS+, los mapeos de Cygwin, WSL y el SMB de macOS, los anchos de un terminal CJK, los datos de UCD 17.0.0, las tablas best-fit de doble byte (932, 936, 949, 950 y 1361) y la sintaxis del CDDL con una herramienta.
Loading…
Cancel
Save

Powered by TurnKey Linux.