|
|
|
|
|
# Handoff DateKeys, 26 de septiembre de 2026 (actualizado el 29 por la noche)
|
|
|
|
|
|
|
|
|
|
|
|
Estado al parar la sesión del 26 por el límite semanal de uso, actualizado el 28 de septiembre tras cerrar la v0.8.2 del spec (§2.1) y el 29 tras cerrar la fase 2 (§2.2). Sirve para retomar sin contexto previo, sea una persona o una sesión de Claude.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 1. Repositorios
|
|
|
|
|
|
|
|
|
|
|
|
Los dos repos están en el Gitea privado `g.activething.com` (solo LAN, certificado autofirmado para `git.activething.com`; git funciona, `curl` necesita `-k`). **Ese servidor no es del autor**: no se proponen cambios en él. La integración continua es el gate local.
|
|
|
|
|
|
|
|
|
|
|
|
| Repo | Rama | Commit | Estado |
|
|
|
|
|
|
|---|---|---|---|
|
|
|
|
|
|
| `datekeys-go` (`go/DateKeys`) | `main` | `3e4755e` | Spec v0.8.2 cerrada, con el tag anotado **`spec-v0.8.2`** en `9ac9cd9`. Después, `datekeys.SpecVersion`, `datekeys.Version()` y `datekeys version`, sin cambios en `testdata`. |
|
|
|
|
|
|
| | `v0.8.2` | `9ac9cd9` | El commit del tag; ya no hace falta. |
|
|
|
|
|
|
| `App` (`go/DateKeys-App`) | `main` | `48d6704` | Versión `0.1.0-dev`, que implementa el spec 0.8.2 (`VERSION` y `SPEC_VERSION`, también en el pie de la página). Librería TypeScript con la inspección (pasos 1 a 8) y la apertura (pasos 9 a 18), en memoria o desde un `Blob` hacia un stream de salida, como un fichero OPFS. Página `/inspect` con la acción "abrir". `testdata` sincronizado a `9ac9cd9`. Fase 2 completa (pasos 2 a 8), incluidos el cifrado tlock y la interoperabilidad de TypeScript a Go. Los 65 casos del corpus pasan por `open` con el código y el paso de Go. 2 611 tests, ninguno saltado; `npm run verify` en verde. |
|
|
|
|
|
|
| `AppOld` (solo local) | `master` | `4d2b0a1` | Prototipo antiguo. No se toca. |
|
|
|
|
|
|
|
|
|
|
|
|
Verificación ya hecha sobre `datekeys-go`:
|
|
|
|
|
|
- fuzzing de 30 min en cada uno de los 15 objetivos sobre `3820066`, limpio;
|
|
|
|
|
|
- diferencial Go/TypeScript de 407 196 entradas contra `f6f2e9f`, con cero diferencias, textos de error incluidos;
|
|
|
|
|
|
- `scripts/check.sh 60s` sobre `9ac9cd9`, el commit del tag, limpio (28-09);
|
|
|
|
|
|
- govulncheck no encuentra nada alcanzable. Avisa, sin llamada alcanzable, de dos problemas:
|
|
|
|
|
|
- GO-2026-6443, en `google.golang.org/grpc` 1.84.0, arreglado solo en una versión `-dev`. Hay que subir grpc cuando salga la 1.85.0.
|
|
|
|
|
|
- GO-2026-5932, en `golang.org/x/crypto/openpgp`, sin arreglo. No lo importamos.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 2. Qué queda, en orden
|
|
|
|
|
|
|
|
|
|
|
|
### 2.1 Hecho el 28-09: cierre de la v0.8.2
|
|
|
|
|
|
|
|
|
|
|
|
- Los 9 retoques de la 2.ª revisión están en `9ac9cd9`, un solo commit sobre `c57ed48` que absorbe el WIP `69a3342`. La rama WIP está borrada.
|
|
|
|
|
|
- §76 los recoge como correcciones 4 a 6:
|
|
|
|
|
|
- un encoder MUST NOT escribir una extensión fuera de su registro;
|
|
|
|
|
|
- §17 y §51 dan los códigos del paso 10 solo para un release suministrado directamente;
|
|
|
|
|
|
- en el paso 9, cualquier fallo de la fuente es `ERR_RELEASE_UNAVAILABLE` y ningún otro código.
|
|
|
|
|
|
- La regla del encoder no se comprueba en la librería: `capsule.Encrypt` y `accesskey.Encode` no reciben `Registry`, y la aplica la aplicación. Está documentado en `extension.Placement`.
|
|
|
|
|
|
- El autor aprobó el texto el 28-09. El spec lleva esa fecha, y el SHA-256 de sus bytes LF, `5cfa3203…`, está en `spec/README.md` y en el mensaje del tag.
|
|
|
|
|
|
- `main` avanzó por fast-forward hasta `9ac9cd9` y lleva el tag `spec-v0.8.2`. Los dos están subidos.
|
|
|
|
|
|
- `App` sincronizó `testdata` con `9ac9cd9` en `71ab8fb`. Solo cambia `testdata/README.md`.
|
|
|
|
|
|
|
|
|
|
|
|
Siguen valiendo estas reglas:
|
|
|
|
|
|
- `App/testdata` solo se actualiza desde `datekeys-go`, con `scripts/sync-testdata.mjs`, y nunca se generan fixtures en `App`. Una guarda falla si aparece un fichero de `testdata` que ningún test ejecuta.
|
|
|
|
|
|
- Si cambia un texto de error de Go en los pasos 1 a 8, el TypeScript lo sigue. Hoy coinciden byte a byte.
|
|
|
|
|
|
- Un cambio normativo posterior ya no modifica la v0.8.2: abre una versión nueva, con su caso en §76.
|
|
|
|
|
|
|
|
|
|
|
|
### 2.2 Fase 2: abrir cápsulas en el navegador
|
|
|
|
|
|
|
|
|
|
|
|
Plan: `docs/PLAN_fase2_ibe_noble2.md` v2, con las decisiones confirmadas por el autor. Los pasos 2 a 8 de su sección 10:
|
|
|
|
|
|
- hecho el 28-09 (`74e1215`): `age-encryption` 0.3.1 y noble 2.4.0 como dependencias de ejecución, con sus guardas en `src/lib/dependencies.test.ts` y `check-build.mjs`. El README de `App` recoge el coste medido en el bundle, 73 KB con gzip para todo, y `npm audit`;
|
|
|
|
|
|
- hecho el 28-09 (`35be27c`): `ibe.ts` sobre noble 2, con vectores de Go en `src/lib/dkc/testing/ibe-vectors.json` (`scripts/ibe-go-vectors.go`) y cobertura del 100 % fijada como umbral. Los argumentos del stanza y su paso al `Stanza` de `age-encryption`, que guarda el tipo en `args[0]`, van al paso 7;
|
|
|
|
|
|
- hecho el 28-09 (`076f3db`): `release.ts`, con `verifyRelease` en el orden y con los textos de `provider.Verify`, `ReleaseSource` y `suppliedRelease`. Solo verifica el scheme de Quicknet: otro da `ERR_UNKNOWN_PROFILE`. Reproduce los 7 casos del corpus que fallan en el paso 10;
|
|
|
|
|
|
- hecho el 28-09 (`97827ae`), paso 5a: `open.ts`, los pasos 9 a 18 con el texto en claro en memoria. Las identidades estrictas de `agewrap` se apoyan en `x25519.ts`, que abre los stanzas de uno en uno. Usa `@noble/ciphers` 2.4.0, dependencia directa aprobada ese día: es la copia que ya usa `age-encryption`. Las identidades `AGE-SECRET-KEY-1…` se leen con `bech32.ts`. `index.ts` no reexporta aún la apertura, que metería noble en `/inspect`;
|
|
|
|
|
|
- hecho el 28-09 (`a89bee5`), paso 5b. `open` acepta un `Blob` del que solo lee el prefijo de los pasos 1 a 8 (`prefix.ts`, movido de la página a la librería), calcula el `capsule_digest` en streaming (`digest.ts`) y descifra `PAYLOAD_AGE` en streaming. La salida puede ser un `WritableStream`, que se cierra tras el paso 18 y se aborta ante cualquier fallo. Comprobado en el navegador con OPFS real: un fallo de STREAM deja intacto el fichero;
|
|
|
|
|
|
- el paso 6 está cubierto: la enmienda de canonicidad entró en la v0.8.2;
|
|
|
|
|
|
- hecho el 28-09 (`66970cf`), paso 7: `encryptOnG2RFC9380` y `timeRecipient`. Con sigma fijo, el cifrado reproduce byte a byte los vectores de Go. Go abrió los cuerpos IBE y los ficheros `age` que cifró esta librería, con `tlock.TimeUnlock` y con `agewrap.NewTimeIdentity`. Todo está en `src/lib/dkc/testing/tlock-vectors.json`;
|
|
|
|
|
|
- hecho el 28 y 29-09 (`48d6704`), paso 8: la acción "abrir" en `/inspect`, cargada bajo demanda, con la política aprobada por el autor el 28-09 tras revisar lo que dice el protocolo:
|
|
|
|
|
|
- el release lo pega quien abre, o sale del registro del fixture, y la página nunca lo pide a la red;
|
|
|
|
|
|
- el texto en claro de un fichero propio va a un fichero temporal de OPFS (§56), que se borra;
|
|
|
|
|
|
- los avisos de licencia se publican en `licenses.txt`.
|
|
|
|
|
|
Una revisión adversarial confirmó 15 hallazgos, todos corregidos. Los detalles y las comprobaciones en el navegador están en la fila 8 del plan.
|
|
|
|
|
|
|
|
|
|
|
|
La lectura del protocolo del 28-09 deja dos SHOULD para más adelante: §48 (varios relays) y §49 (obtener el release directamente del proveedor). Los cubrirá una fuente drand opcional del SDK, nunca activa por defecto en la página (sección 12 del plan).
|
|
|
|
|
|
|
|
|
|
|
|
El vector de GT (`vectors/tlock_ibe.json`) ya está cubierto en `App`. El paso 9 de `open.ts` debe seguir la corrección 6: cualquier fallo de una fuente es `ERR_RELEASE_UNAVAILABLE` y ningún otro código.
|
|
|
|
|
|
|
|
|
|
|
|
### 2.5 Sesión del 29-09 por la noche: fase 3 y v0.9 del spec (retomar aquí)
|
|
|
|
|
|
|
|
|
|
|
|
**Estado al parar:**
|
|
|
|
|
|
- `datekeys-go`, rama `v0.9` (`1189f2f`, subida): borrador del spec v0.9, sin aprobar, en `spec/DateKeys_Protocol_Specification_v0.9.md`, con `spec/datekeys.cddl` actualizado. `main` no cambia.
|
|
|
|
|
|
- El repaso final encontró 21 problemas, con su arreglo propuesto (salida del workflow `spec-v0.9-draft`, fichero `scratchpad/v09/review.md` de la sesión, que puede haber desaparecido). Se estaban aplicando cuando se paró el trabajo: **pueden estar a medias**. Lo primero mañana es comprobarlos uno a uno contra el borrador y terminarlos. También falta la entrada v0.9 en `spec/README.md` y ejecutar `go test ./...`, por si algún test lee el CDDL.
|
|
|
|
|
|
- `App`: `docs/PLAN_fase3_escritura.md` (plan del writer TypeScript) y `docs/REVISION_completitud_protocolo.md` (revisión del protocolo). El plan describe aún el writer de la v0.8.2 y hay que replantearlo sobre la v0.9.
|
|
|
|
|
|
|
|
|
|
|
|
**Decisiones del autor del 29-09 para la v0.9:**
|
|
|
|
|
|
- D1: `time_and_key` lleva siempre exactamente 16 stanzas X25519 en `INNER_ACCESS_AGE`. Los que sobran son señuelos, y todos van en orden aleatorio. Como mucho hay 16 credenciales, contando la `.dkk`.
|
|
|
|
|
|
- D2: el contenido se rellena siempre. El código 1 redondea al siguiente múltiplo de 256, con un mínimo de 256. El código 2, "reforzado", es max(bloque256, Padmé) y es el de por defecto. No hay opción sin relleno.
|
|
|
|
|
|
- D3: la longitud real y el código van en `CONTROL_CBOR` versión 2 (claves 6 y 7). El lector entrega solo L bytes y comprueba que el relleno sea todo ceros y que siga la regla.
|
|
|
|
|
|
- D4: el formato pasa a 2 (`VERSION` 2 del PRELUDE), así que un lector v0.8.2 lo rechaza en el paso 2, sin red. Un lector v0.9 sigue abriendo el formato 1.
|
|
|
|
|
|
- D5: `access_policy` sigue visible.
|
|
|
|
|
|
- D6: nueva sección de privacidad, §55.2.
|
|
|
|
|
|
- D7: reglas normativas del escritor, §62.1:
|
|
|
|
|
|
- `I_PAYLOAD` sale de un CSPRNG y no se reutiliza;
|
|
|
|
|
|
- límites;
|
|
|
|
|
|
- la fecha pedida tiene que ser futura;
|
|
|
|
|
|
- el escritor se autocomprueba;
|
|
|
|
|
|
- rechaza claves X25519 no canónicas o de orden bajo.
|
|
|
|
|
|
|
|
|
|
|
|
**Preguntas abiertas del borrador para el autor:**
|
|
|
|
|
|
1. L como `bstr` de 8 bytes, no como `uint`.
|
|
|
|
|
|
2. Si el lector informa del formato con SHOULD o con MAY.
|
|
|
|
|
|
3. Si se mantienen el objetivo 8 de §4 y el no objetivo nuevo de §5.
|
|
|
|
|
|
4. Un generador de pruebas que escriba el formato 1.
|
|
|
|
|
|
5. El prefijo `format2_` en los fixtures.
|
|
|
|
|
|
6. Señuelos como claves públicas aleatorias válidas, sin clave privada.
|
|
|
|
|
|
7. Puntos del twist: MAY o SHOULD.
|
|
|
|
|
|
|
|
|
|
|
|
Hay además reglas añadidas fuera de D1-D7 que confirmar: L_MAX = 2⁵³ − 2⁴⁶, el orden uniforme de los stanzas, y el MUST NOT de §56 sobre entregar el contenido antes de que termine el paso 17.
|
|
|
|
|
|
|
|
|
|
|
|
**Orden de trabajo:**
|
|
|
|
|
|
1. Terminar y verificar las 21 correcciones.
|
|
|
|
|
|
2. El autor aprueba el texto de la v0.9.
|
|
|
|
|
|
3. La referencia Go implementa el formato 2, con fixtures nuevos y mutaciones, y pasa `check.sh`.
|
|
|
|
|
|
4. Se pone el tag `spec-v0.9`.
|
|
|
|
|
|
5. `App` sincroniza `testdata` y el lector TypeScript abre el formato 2.
|
|
|
|
|
|
6. Se replantea el plan de la fase 3 y se escribe el writer TypeScript del formato 2.
|
|
|
|
|
|
|
|
|
|
|
|
**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.
|
|
|
|
|
|
- Un fichero único `.dk` con `.dkc` y `.dkk` juntos no conviene: con `time_and_key` equivaldría a `time_only`. Ya se envía un solo fichero con `time_only` o con destinatarios `age1…`.
|
|
|
|
|
|
- `App` sigue en `0.1.0-dev`; decidir si se cierra `0.1.0`.
|
|
|
|
|
|
|
|
|
|
|
|
### 2.3 Depende del autor
|
|
|
|
|
|
|
|
|
|
|
|
- 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.
|
|
|
|
|
|
- Decidir si `App` pasa de `0.1.0-dev` a `0.1.0`, ahora que la fase 2 está completa.
|
|
|
|
|
|
|
|
|
|
|
|
### 2.4 Más adelante
|
|
|
|
|
|
|
|
|
|
|
|
Fase 3 (writer TypeScript de cápsulas), Release API sobre la librería, traducción del spec al inglés y revisión externa antes de la v1.0.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 3. Reglas del proyecto
|
|
|
|
|
|
|
|
|
|
|
|
- **Dependencias:** en ejecución, solo `age`, `drand`, `tlock` y lo que ellas arrastran. El tooling de desarrollo sale de la lista del README. Nada nuevo sin aprobación escrita. Nunca GitHub como servicio.
|
|
|
|
|
|
- **Spec:** en español, estilo RFC 2119. Todo cambio normativo se registra en §76 con su caso reproducible, y se actualiza el SHA-256 de `spec/README.md`.
|
|
|
|
|
|
- **Código y comentarios:** en inglés. Commits con `Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>`.
|
|
|
|
|
|
- **Precedencia de errores (§69.1):** trama; tipo y versión; perfil CBOR y CDDL; campos con código propio, en orden de clave. Entre objetos decide el orden de pasos de §63.
|
|
|
|
|
|
- **Subagentes:** con `model: "opus"`.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 4. Documentos
|
|
|
|
|
|
|
|
|
|
|
|
- Planes en `App/docs`: `PLAN_libreria_go.md`, `PLAN_codec_cbor_y_pagina_svelte.md` (v2) y `PLAN_fase2_ibe_noble2.md` (v2).
|
|
|
|
|
|
- En `datekeys-go`:
|
|
|
|
|
|
- `spec/DateKeys_Protocol_Specification_v0.8.2.md`, `spec/datekeys.cddl` y `spec/README.md`;
|
|
|
|
|
|
- `testdata/README.md`, que documenta los ficheros compartidos para segundas implementaciones;
|
|
|
|
|
|
- `docs/traceability.md` y `CHANGELOG.md`.
|
|
|
|
|
|
- Las herramientas de verificación de esta sesión (el diferencial Go/TypeScript de `tsreview/` y las copias congeladas `dkgo-ref-<commit>`) están en el scratchpad temporal y pueden haber desaparecido. Su descripción está en los mensajes de los commits de `App` y en el README de `App`.
|