You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
DateKeys-App/docs/HANDOFF.md

13 KiB

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.

Powered by TurnKey Linux.