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.
160 lines
24 KiB
160 lines
24 KiB
# Handoff DateKeys
|
|
|
|
*Estado al 7 de octubre de 2026 por la tarde. Lo que pasó hasta aquí, sesión a sesión, está en [HANDOFF_historial.md](HANDOFF_historial.md).*
|
|
|
|
Sirve para retomar sin contexto previo, sea una persona o una sesión de Claude.
|
|
|
|
**Antes de empezar:**
|
|
- La sesión se abre en `G:\bussines\datekeys`, la raíz, que es la que tiene la memoria y el `CLAUDE.md`.
|
|
- Comprueba que corre en Opus. Una sesión del 1-10 corrió por descuido con Sonnet 5.5 y hubo que revisarla entera. Los trailers `Co-Authored-By` de los commits dicen qué modelo escribió cada uno.
|
|
- Comprueba cada repo con `git status` y `git log`: todo lo de abajo estaba subido al cerrar.
|
|
|
|
---
|
|
|
|
## Estado
|
|
|
|
| Repo | Rama y commit | Tags | Qué es |
|
|
|---|---|---|---|
|
|
| `datekeys-go` | `v0.15` en `6158be2`; `main` en `fe50885` | `spec-v0.15` en `fe50885`, y los de las versiones anteriores | Spec v0.15 aprobada, implementación de referencia, `testdata` compartido; `c49c67c` añade las palabras al azar, `27a75ee` el alfabeto de cada lista y la fuerza de las palabras, `96d8992` arregla `TestGenerate`, `e671032` añade la lista inglesa de la EFF, `92e7154` los dados y `aefc8f6` lo que dice el SDK al sellar |
|
|
| `App` (`datekeys-ts`) | `v0.10` en `e8b5d35`; `main` en `7650418` | `v0.4.0` en `7650418`, `v0.3.0`, `v0.2.0`, `v0.1.0` | Librería TypeScript `0.5.0-dev`, de la spec 0.15, y páginas `/inspect` y `/create`, con las palabras al azar; la última publicada es la 0.4.0 |
|
|
| `datekeys-dart` | `v0.15` en `e2296b0` | ninguno | Librería Dart completa, de la spec 0.15, con las palabras al azar; las ramas `v0.11` a `v0.14` se quedan atrás |
|
|
| `docs` | `main` | — | Este repo |
|
|
| `web` | `main` en `f2b8a38` | — | Landing de datekeys.com, sin remoto |
|
|
|
|
- **Spec:** la v0.15 está aprobada desde el 7-10, con SHA-256 `45105e693be4187af4dd30f4d254402612587b6427c746f5d29f07a541c1e3f3`. Es la recuperación a largo plazo: el objeto release, los archivos y servicios de caché que guardan todas las rondas, el release en la mano en el paso 9.c (opción B: no se compara con el reloj) y el anexo de recuperación del §79. No cambia ningún formato de `.dkc` ni de `.dkk`. No hay ningún borrador abierto. Las versiones aprobadas y sus SHA-256 están en `datekeys-go/spec/README.md`.
|
|
- **El fichero `.dkr` se descartó** antes de aprobar (7-10). El autor no lo había aprobado conscientemente, y no tiene sentido: al crear la cápsula no hay release que guardar, y cuando llega la ronda la cápsula ya se abre. El objeto release no tiene extensión propia; sale de un archivo o de un servicio de caché. El §76 lo registra.
|
|
- **Las tres implementaciones** coinciden en todos los vectores compartidos de `datekeys-go/testdata` en `fe50885`, 142 ficheros, los mismos que en `aefc8f6`, de donde TypeScript y Dart copian hoy `testdata`, `wordlists` y `annex`. Gates el 7-10:
|
|
- Go: `scripts/check.sh` entero en `fe50885`, con el anexo de recuperación abriendo fixtures sin código de DateKeys, y `scripts/fuzz.sh 20s` en `fe50885` con sus 27 objetivos, sin fallos; `scripts/check.sh` entero otra vez en `27a75ee`, `96d8992`, `e671032`, `92e7154`, `aefc8f6` y `6158be2`;
|
|
- TypeScript: `npm run verify` en `728c3bb`, con 8 132 pruebas;
|
|
- Dart: `tool/check.sh` en `e2296b0`, con 2 250 pruebas en la VM y 716 en Node.
|
|
- **Palabras al azar (7-10, después de cerrar la v0.15):** es el SHOULD de §38.1 de ofrecer palabras generadas; no cambia ningún formato ni la derivación.
|
|
- Go: `c49c67c` añade `wordkey.Generate`, `List` y `CheckList`, y `datekeys encrypt -new-words FICHERO [-dic es] [-word-count 7]`. `27a75ee` hace que `CheckList(lang, words)` compruebe cada palabra contra el alfabeto de su idioma, que da el código y no la lista (para `es`, de la `a` a la `z`, `á`, `é`, `í`, `ó`, `ú`, `ü` y `ñ`, en minúscula y NFC): una letra cirílica que parece latina, una mayúscula, una cifra o el retorno de carro de un fichero CRLF dejarían la cápsula sin abrir. También añade `Bits`, la fuerza de lo sorteado, que `encrypt` muestra (90 bits para 7 de 7 776). `scripts/check.sh` pasa entero en los dos.
|
|
- TypeScript (`0.5.0-dev`, de `012cd74` a `4057607`): `scripts/sync-testdata.mjs` copia del mismo commit de Go `wordkey/lists` en `wordlists/`, con su `SOURCE.json` (`testdata` y `wordlists` en `27a75ee`, cuyo `testdata` es el del tag). `wordlist.ts` hace lo de Go, con sus textos: `readWordList` solo acepta una lista con el SHA-256 fijado para su idioma, `checkWordList`, `generateWords` y `wordBits`. `/create` ofrece palabras al azar por defecto tras una casilla, con su fuerza y «Otras palabras», y deja escribir las propias con el aviso de que son más débiles; `licenses.txt` lleva la licencia de la lista. `npm run verify` pasa con 8 119 pruebas, y el flujo se comprobó en el navegador sobre el build de producción.
|
|
- En `/create` apareció y se corrigió un fallo de la 0.4.0 (`4057607`): el efecto que comprueba las rutas se relanzaba sin fin (`effect_update_depth_exceeded`) en cuanto había un fichero, un comentario o un autor.
|
|
- `wordBits` de TypeScript usa `Math.log2`, que puede diferir del `math.Log2` de Go en el último bit; la página muestra los bits truncados, como la CLI, así que no se nota.
|
|
- Dart (`a770d4d` a `fcc7780`, de un agente Opus en un worktree, revisado contra Go): `tool/sync_testdata.dart` copia también `wordlists/`, y `lib/src/wordlist.dart` hace lo mismo que Go, exportado desde `lib/datekeys.dart`. Sus vectores (`test/vectors/wordlist_vectors.json`) los genera Go con `tool/wordlist_go_vectors.go`: `List`, `CheckList` en 83 listas, el veredicto de cada punto de código de los planos 0, 1 y 14, `Generate` en 51 casos con los mismos bytes que Go, y `Bits` bit a bit (porta el `math.Log2` de Go).
|
|
- El agente de Dart vio que `TestGenerate` de Go no probaba nada: su semilla solo daba dos índices, las dos llamadas acababan en `EOF` y el test comparaba dos resultados vacíos. Está arreglado en `96d8992`.
|
|
- **La lista inglesa** (7-10 por la tarde, con permiso del autor): `wordkey/lists/en.txt` es la lista grande de la EFF (Joseph Bonneau, 2016), 7 776 palabras, CC BY 4.0 según la política de copyright de eff.org, en su orden y sin los números de los dados, así que la posición de cada palabra sigue dando su número. `-dic` la toma por defecto, como decidió el autor. El alfabeto de `en` es de la `a` a la `z` y el guion ASCII de sus cuatro palabras compuestas (`drop-down`, `felt-tip`, `t-shirt` y `yo-yo`), para no quitar ninguna ni romper su numeración. Go `e671032`, TypeScript `13df99b` (la página sigue ofreciendo solo la española, y `check-build.mjs` exige que publique solo esa) y Dart `bf0f3d3`, con sus vectores regenerados con Go.
|
|
- **Los dados** (7-10 por la tarde, decisión del autor «sí, hazlo así»): para quien no se fía del azar del ordenador, cinco dados por palabra dan un número del 11111 al 66666, la posición de la palabra en la lista (7 776 = 6⁵), con el primer dado como cifra más significativa. Go `92e7154`: `wordkey.DiceNumber`, `DiceWord`, `DiceWords` (al menos 6 números y ninguna palabra repetida, que se vuelve a tirar) y `DiceList`, la lista numerada como la publica la EFF (la de `en` es su fichero byte a byte, SHA-256 `addd3553…903e`; la de `es`, `611f779a…fddb`, en `wordkey/lists/README.md`); `encrypt -dice TEXT` y `-dice-file FILE`, que muestran las palabras (las que abren la cápsula, no los números), y `datekeys wordlist [-dic LISTA]`, que escribe la lista numerada y su SHA-256. TypeScript `f5044e3`: lo mismo en `wordlist.ts`, y en `/create` la opción «Con dados» entre «Al azar» y «Las elijo yo», que convierte los números en palabras a medida que se escriben, avisa de un número que no vale o de una palabra repetida y ofrece la lista numerada para imprimirla, con su SHA-256. Comprobado en el navegador sobre el build de producción: la lista descargada tiene el SHA-256 de Go y la cápsula se crea con las palabras de los dados. Dart `00f4ad4`, de un agente Opus revisado contra Go: lo mismo en `wordlist.dart`, con vectores de Go de los dados (`DiceWords` con cada punto de código de los planos 0, 1 y 14 entre dos números, entre otros).
|
|
- La lista española, `wordkey/lists/es.txt` (7 776 palabras, SHA-256 `ff77b487…34fe`), es un **borrador sin revisar**, CC BY-SA 4.0, sacado de las frecuencias de subtítulos de FrequencyWords filtradas con el diccionario de LibreOffice; el método está en `wordkey/lists/README.md` y el script en [wordlists/build_es.py](wordlists/build_es.py). Cumple el alfabeto tal cual.
|
|
- **Lo que dice el SDK oficial al sellar (7-10 por la tarde):** los SHOULD de la v0.14 y la v0.15 que no cumplían ni la CLI ni `/create`.
|
|
- **El anexo junto a la cápsula** (§62.1, regla 27): `annex/recovery.md` en `datekeys-go`, el §79 del spec bajo un título con su versión y el SHA-256 de su texto, igual para toda cápsula. `datekeys.RecoveryAnnex` lo incrusta y `TestRecoveryAnnex` exige que sea el §79 del spec de `SpecVersion`: al aprobar una versión nueva se regenera con `DATEKEYS_WRITE_ANNEX=1 go test -run TestRecoveryAnnex .`. `encrypt` lo escribe como `FICHERO.dkc.recuperacion.txt` (`-no-recovery` lo evita), y `/create` lo ofrece para descargar con ese nombre. TypeScript y Dart lo copian de Go en `annex/`, como las listas.
|
|
- **Qué hará falta para abrirla** (regla 26): `encrypt` y `/create` lo dicen al sellar: el `.dkc`, una credencial si es `time_and_key`, y el release de su ronda, que tendrá que guardar un archivo o un servicio de caché si drand ya no lo sirve (§50). El aviso local opcional para `round_time` (MAY) no se ha hecho.
|
|
- **`time_and_key` para horizontes largos** (§7.6): a más de un año y con `time_only`, la CLI y `/create` la recomiendan.
|
|
- **Las palabras propias** (§38.1): `/create` y la ayuda de la CLI dicen que no bastan para algo valioso y que no se use una contraseña de otro sitio, porque pasada la fecha la cápsula permite probarla.
|
|
- **El estado del perfil** (§71): `profile.Status`/`StatusOf` en Go, `profileStatusOf` en TypeScript, con la tabla de los perfiles fijados que trae cada versión, porque el registro firmado no existe: Quicknet, activo. Con un perfil que no esté activo no se escribe ninguna cápsula, y `decrypt`, `inspect` e `/inspect` avisan si el de una cápsula está comprometido.
|
|
- Go `aefc8f6` y `6158be2`, TypeScript `728c3bb` y `e8b5d35`, Dart `8eed96f` y `e2296b0` (de un agente Opus revisado contra Go: el anexo es una constante generada, `lib/src/recovery_annex.g.dart`, que escribe `tool/recovery_annex_copy.dart` tras cada sincronización que cambie `annex/`).
|
|
- Pendiente menor: el anexo es texto del spec, con licencia CC BY 4.0 (`spec/README.md`), pero ni su cabecera ni el README de Go lo dicen.
|
|
- **La revisión externa:** el paquete de [revision_externa/](revision_externa/NOTA_PARA_EL_AUTOR.md) está al día con la v0.15. Su nota dice qué decidió el autor y qué falta: elegir revisor, alcance y presupuesto, el NDA, los bundles y el envío.
|
|
|
|
---
|
|
|
|
## Qué queda
|
|
|
|
La recuperación a largo plazo quedó hecha con la v0.15, y las palabras al azar en las tres librerías y en `/create` (7-10). **Para empezar mañana**, lo que depende del autor en ellas: la revisión de la lista española por alguien que hable español, o rehacerla con el corpus de Leipzig cuando su web vuelva (el 7-10 por la tarde seguía caída). Sin eso, lo siguiente de «Librerías y clientes» es la página web cuando se publique (§59) o el localizador en las páginas.
|
|
|
|
### Protocolo
|
|
|
|
0. **La revisión de Astra de la v0.15 (7-10), para la v0.16.** Cinco hallazgos, todos comprobados y aceptados; la v0.15 no cambia. Tras su segunda respuesta, la dirección es:
|
|
- **Sello sin `accuracy`** (§29.11): S4 solo con una cota de precisión conocida; sin ella el sello verifica pero no acredita anterioridad, y S5 pasa a «No acredita que se sellara antes de la fecha de apertura», con el motivo. Se descarta el margen fijo que propuso Claude: ningún margen finito es conservador para toda TSA. Astra comprobó la política BTSP de ETSI EN 319 421 V1.3.1 (OID `0.4.0.2023.1.1`, §5.2; cota de un segundo, §5.1 y TIS-7.7.2-03), pero TIS-7.7.1-01 exige el perfil de EN 319 422, cuyo §5.2.2 obliga a llevar `accuracy`: un token BTSP sin ella incumple su perfil y da S5, «falta la precisión que exige su perfil»; aceptarlo con un segundo sería una tolerancia de DateKeys que habría que documentar y probar. Un OID declara conformidad, no la certifica. La propuesta de Claude: S4 solo con `accuracy` presente y válida, y un registro de políticas con cota fuera del token que hoy estaría vacío, así que basta con decir que una versión posterior podrá registrarlas. Hay que comprobar las cláusulas citadas al redactar.
|
|
- **Anexo y llave de palabras** (§79.6): el anexo incluirá la derivación de §38.1 (normalización, PBKDF2 con su sal y sus rondas, vector), con una receta exacta para un subconjunto explícito y comprobado (los alfabetos de las listas de DateKeys) y, para el resto, las tablas de Unicode 18.0.0 en un paquete de recuperación publicado una vez (el spec, esos datos, los vectores y `scripts/recovery`), no junto a cada cápsula: el anexo nombra su versión, su SHA-256 y el de cada fichero, para recuperarlo de cualquier copia y comprobar que es el esperado. `scripts/recovery` abrirá con palabras, con casos que ejerciten la normalización.
|
|
- **Último bloque de `age`** (§79.5): «el último puede ser más corto», y un vector con un último bloque completo. `scripts/recovery` ya lo hace bien.
|
|
- **Evidencias de la firma con certificado** (§29.10, regla 21): guardar la cadena sin la raíz y las respuestas OCSP cuando quepan; si no caben, el escritor dice qué deja fuera, también de la TSA y de los intermedios, y permite exportarlo; §29.10 promete solo lo conservado. Ligado a la medida del área (punto 3).
|
|
- **JSON de drand** (§47.1): regla estricta, con vectores: nombres exactos tras decodificar sus escapes (`"\u0072ound"` es `round`), un nombre repetido es `ERR_RELEASE_INVALID`, la ronda un entero sin fracción ni exponente. Hoy Go y TypeScript leen como `encoding/json`: el último gana y los nombres no distinguen mayúsculas.
|
|
- Pendiente del autor: aprobar esta dirección y cuándo abrir la v0.16 (antes o después del informe de la revisión externa).
|
|
1. **La revisión externa.** El paquete está listo; lo que falta es del autor. Al recibir el informe, se abre la versión siguiente con sus hallazgos, el párrafo de idioma y precedencia del final del §1, las etiquetas del §76 que hoy llaman independientes a revisiones de IA, y el registro de la revisión (§75, punto 10). Todo eso lo aprobó el autor el 6-10; ver [revision_externa/precedence_and_language.md](revision_externa/precedence_and_language.md).
|
|
Con ellos, dos retoques editoriales que el texto no puede llevar tras su tag: los de K17 del paquete (la cabecera «prevista», el §1 con la Release API y la Release Cache, el punto y coma del §74), y el §79, que nombra solo `drand/kyber-bls12381` cuando `scripts/recovery` usa también las interfaces de `drand/kyber`.
|
|
2. **Un archivo o servicio de caché de releases** (§50). El protocolo ya lo admite y las librerías leen un archivo local, pero nadie aloja uno todavía. Es decisión del autor: dónde, quién lo mantiene y si DateKeys ofrece el suyo.
|
|
3. **Medir el área de 32 KiB y cerrar el perfil CMS** (§74; §75, punto 13), con firmas reales con certificado de varios países y sellos de autoridades reales. Necesita firmas del autor o permiso para pedir sellos a una autoridad pública.
|
|
4. **Lo que el §74 aún llama provisional:** los esquemas de bytes de la cabecera, el control y la `.dkk`, los límites de los campos y los vectores definitivos del perfil. Conviene congelarlo con el informe de la revisión delante.
|
|
5. **El registro de perfiles firmado** (§71), que no existe.
|
|
6. **Más adelante:** un tipo de acceso post-cuántico, y quizá una derivación más dura que PBKDF2 para la llave de palabras.
|
|
|
|
### Librerías y clientes
|
|
|
|
- **Las palabras al azar** (§38.1) están en Go, TypeScript, `/create` y Dart, con el SHA-256 fijado de cada lista, el alfabeto de su idioma y la fuerza calculada con la lista cargada (ver «Estado»). Ninguna lista se da por buena, tampoco las de DateKeys (el autor, 7-10: un empleado malicioso podría servir una lista con las mismas 6 palabras). Falta:
|
|
- la lista española definitiva: el autor espera a que vuelva la web de la Universidad de Leipzig (el 7-10 daba un error de servidor), cuyos corpus de unos 256 idiomas se descargan con CC BY. El script sirve cambiando la fuente de frecuencias. Su web bloquea a los agentes (Anubis): descarga el autor. Cada lista la revisa alguien que hable el idioma antes de fijar su hash. En el borrador hay nombres propios, préstamos y palabras malsonantes, como «claudia», «green», «sport» o «cojonudo»: que los mire quien la revise, con `descartes.txt` delante;
|
|
- los dados protegen de un generador trucado, no de una app que se quede con las palabras: eso solo lo cubre una app auditable (§59);
|
|
- el servicio `words.datekeys.com`, cuando haya sitio propio: ver las decisiones;
|
|
- quizá el alfabeto por idioma como regla del SDK en la versión siguiente del spec (§38.1). El riesgo de fondo es la app misma, que puede cambiar el generador: §59, builds reproducibles y releases firmadas.
|
|
- **Lo que queda de las recomendaciones al SDK:** el aviso local para `round_time` (§62.1, regla 26, MAY).
|
|
- **La página web, cuando se publique** (§59): builds reproducibles con sus hashes, Subresource Integrity y un cliente sin conexión.
|
|
- **El localizador en las páginas:** las tres librerías lo tienen, pero `/create` no crea sobres e `/inspect` no descarga el resto.
|
|
- **Go no tiene ninguna release del módulo**; la primera, cuando haya un repo accesible desde fuera para `go get`. govulncheck avisa de GO-2026-6443 en grpc, que el código no alcanza: subir grpc cuando salga la 1.85.0.
|
|
- **Dart:** sin versión ni tag. Medir los tiempos en un móvil espera a la app.
|
|
|
|
### Espacio de trabajo
|
|
|
|
- **Del autor:** renombrar la carpeta `App` a `datekeys-ts` y borrar `enquiry.php` de la raíz, pendientes desde el 29-09.
|
|
- **`web` sigue sin remoto.**
|
|
|
|
---
|
|
|
|
## Decisiones del autor que siguen vigentes
|
|
|
|
- **La app Flutter está archivada** «para un futuro» (6-10). No se empieza sin que lo pida.
|
|
- **La revisión externa** (6-10):
|
|
- primero, buscar un revisor que lea español; si no lo hay, traducir solo el núcleo normativo;
|
|
- dos niveles de alcance, con presupuesto cerrado por nivel;
|
|
- código entero en bundles de git cifrados con `age`;
|
|
- un NDA mutuo;
|
|
- la versión siguiente, después del informe. La v0.15 se adelantó a petición del autor (7-10).
|
|
- **Las palabras al azar** (7-10):
|
|
- listas de 7 776 palabras por idioma y 7 palabras por defecto; BIP-39 (2 048) se le queda pequeña al autor;
|
|
- la app descarga la lista del idioma del usuario; la CLI las lleva dentro, inglés por defecto, y otra con `-dic es`, `-dic fr`;
|
|
- **las palabras se sortean siempre en el dispositivo y nunca viajan**: el servidor no las genera ni las ve, ni cifradas. El autor propuso un servicio que las mandara cifradas con la clave de DateKeys y aceptó esto en su lugar;
|
|
- `words.datekeys.com` solo servirá las listas públicas: ficheros estáticos con el hash en la URL, el SHA-256 fijado en la app o un índice firmado por DateKeys. La clave de DateKeys firma; no cifra nada.
|
|
- **La app será auditable** (7-10): código publicado de todo lo que toca las llaves, builds reproducibles, releases firmadas y una auditoría externa (§59). Con eso, las palabras generadas por la app son la opción por defecto; los dados (diceware, lista numerada del 11111 al 66666 y publicada con su hash) quedan como opción para quien desconfíe, y las palabras propias con su aviso. Límite: en iOS la App Store vuelve a firmar y cifrar, y no se puede comprobar el binario; en Android sí (F-Droid). Dónde se publica el código está por decidir: ni GitHub ni el Gitea.
|
|
- **Sin fichero `.dkr`** (7-10): el objeto release no se guarda junto a la cápsula ni tiene extensión propia.
|
|
- **`locator.Open` sigue leyendo como mucho 1 MiB** del localizador (6-10).
|
|
- **El cifrado tlock queda en `BigInt`, sin tiempo constante**, documentado en Dart y TypeScript («continúa», 6-10).
|
|
- **El reporte del posible fallo de dart2js** al equipo de Dart, solo con permiso del autor. Está documentado en el README de `datekeys-dart`.
|
|
- **Mostrar Q1 y Q10 de la revisión al equipo de drand** antes de pagar una revisión es decisión del autor, porque supone enseñar el proyecto fuera.
|
|
- **El diseño de las páginas:** nunca un fondo oscuro, nada del estilo de la landing, usar la skill `frontend-design` sobre la página real y no gastar en maquetas. Ver la memoria.
|
|
|
|
---
|
|
|
|
## Para trabajar
|
|
|
|
- **Subir al Gitea.** El nombre `g.activething.com` a veces resuelve a 89.46.247.16, que no responde. Entonces se sube a la IP de la red local, sin tocar el remoto:
|
|
|
|
```bash
|
|
git -C <repo> push https://192.168.18.112/go/<repo-remoto>.git <rama>
|
|
```
|
|
|
|
y después `git -C <repo> update-ref refs/remotes/origin/<rama> <rama>`. Los remotos son `go/DateKeys`, `go/DateKeys-App`, `go/dateKeys-dart` y `go/datekeys-doc`. El servidor no es del autor: no se propone ningún cambio en él.
|
|
- **Cerrar una versión del spec**, como la v0.12 a la v0.15:
|
|
1. en Go, la cabecera del spec con «aprobado por su autor ese día» y nada más del texto;
|
|
2. `SpecVersion`;
|
|
3. `go run ./internal/testkit/genfixtures -out testdata`, y el campo `spec` a mano en los dos congelados, `security_cms.json` y `locator.json`;
|
|
4. el SHA-256 en `spec/README.md`, y los README, `SECURITY.md`, la trazabilidad, `testdata/README.md` y el CHANGELOG;
|
|
5. `scripts/check.sh`, con el árbol limpio tras el commit;
|
|
6. el tag anotado `spec-vX.Y` y `main` avanzado sin fusión (`git fetch . <rama>:main`);
|
|
7. en TypeScript y Dart, la versión del spec, `testdata` sincronizado con sus scripts, `mutation-texts.json` regenerado con Go en un módulo temporal (`G:\tmp\mutgo`), y el campo `spec` de los vectores propios que salen de Go.
|
|
|
|
Tras aprobar no se añade texto normativo sin enseñarlo: fue el fallo E1 de la v0.11.
|
|
- **Encargos a agentes:**
|
|
- con `model: "opus"`;
|
|
- en worktrees junto a los repos, para que `../datekeys-go` resuelva;
|
|
- nunca dos agentes en los mismos ficheros;
|
|
- solo ficheros nuevos, y los comunes en un último commit;
|
|
- la sesión revisa contra Go antes de integrar.
|
|
- **Herramientas de esta máquina:**
|
|
- los heredocs de Bash rompen las barras invertidas, `\n` incluido;
|
|
- la herramienta Write quita los espacios de final de línea (los saltos de Markdown del §77) y convierte `\uXXXX` en caracteres;
|
|
- para cambios con barras o espacios exactos, un script de Python escrito con Write que use `chr(92)`, o la herramienta Edit;
|
|
- en Windows, `write_text` de Python escribe CRLF: abre con `newline=''` o escribe bytes, o `gofmt` y los hashes fallan;
|
|
- `cd` en Bash mueve el directorio de la sesión: usa `( cd … )` o `git -C`.
|
|
- **Vista previa de la página:** la configuración `inspector-dev-app` de `.claude/launch.json` arranca `App`, mientras la carpeta no se renombre, e `inspector-preview-app` sirve su build de producción (`npm run build` antes, y reiniciarla tras cada build: si no, los chunks nuevos dan 404 y la página no se hidrata). No pares el servidor mientras el autor lo usa. `vite.config.ts` prepara las dependencias que se cargan bajo demanda (`optimizeDeps.include`), para que la primera apertura no recargue la página.
|
|
- **Fuzzing:** usa `FUZZ_PARALLEL=4`. Un «context deadline exceeded» sin entrada que falle es del motor de Go, no del código; se vuelve a pasar.
|
|
- **Disco:** C: está casi lleno con las cachés de Go y Dart; los temporales van en `G:\tmp`, y nunca se borra con comodines.
|
|
|
|
---
|
|
|
|
## Documentos
|
|
|
|
El [README](README.md#documentos) los lista. Para retomar, lo principal es:
|
|
- [revision_externa/](revision_externa/NOTA_PARA_EL_AUTOR.md): el paquete y su nota;
|
|
- [REVISION_completitud_v0.13.md](REVISION_completitud_v0.13.md): qué falta antes de la v1.0;
|
|
- [spec_v0.15/decisiones.md](spec_v0.15/decisiones.md): las decisiones de la última versión, y [diseno_recuperacion.md](diseno_recuperacion.md), su diseño.
|