ADR 0007 — Remote DVC en Cloudflare R2 y manejo de credenciales
- Estado: aceptado (pendiente de que el usuario cree el bucket y el token; se confirma con el primer
dvc pushverificado) - Fecha: 2026-10-16
Contexto
Los bytes crudos no entran a git (ADR 0002/0003). Hace falta un almacenamiento de trabajo en la nube, direccionable por hash, con egreso barato para que mirrors y usuarios hagan dvc pull. El usuario eligió Cloudflare R2 en la Fase 0.2 entre R2, Backblaze B2, OneDrive institucional vía rclone y “solo Zenodo”.
Decisión
- Remote por defecto de DVC:
s3://tinkuy-qhali-rawconendpointurl https://<ACCOUNT_ID>.r2.cloudflarestorage.com, regiónauto. R2 es S3-compatible (DVC lo soporta condvc[s3]), tiene 10 GB gratis y egreso sin costo, lo que favorece mirrors. - Credenciales nunca en git ni en manos del agente:
.dvc/config(versionado) solo contiene URL y endpoint;.dvc/config.local(gitignored) contieneaccess_key_idysecret_access_key, y lo escribe el usuario. El agente no lee ni escribe ese archivo; solo ejecutadvc status -c/dvc pushy verifica el resultado. - Convención de rutas en
raw/:raw/<source>/<edition>/<module>/<filename>conmanifest.jsonal lado ymanifest.sha256parasha256sum -c. - Caché DVC en el volumen nombrado
dvc-cache(fuera de NTFS);dvc config cache.type reflink,hardlink,copy. - Puntero en
tinkuy-qhali-registry/pointers/por cada archivo, conlocations[kind=dvc-remote]apuntando al remote yfreeze_levelprovisional hasta aplicar la matriz de la Fase 1.
Alternativas descartadas
- OneDrive EduCorpPERU vía rclone: sin remote nativo, sin direccionamiento por hash, dependencia de una cuenta institucional.
- Solo Zenodo: sin caché de trabajo, límite de 50 GB por registro, no apto para iterar.
- Backblaze B2: equivalente; R2 elegido por egreso gratuito y porque el usuario lo prefirió.
Pasos que hace el usuario (una vez)
Crear cuenta en https://dash.cloudflare.com → R2 Object Storage → Create bucket
tinkuy-qhali-raw(ubicación automática).R2 → Manage R2 API Tokens → Create API token: permiso Object Read & Write, limitado al bucket; copiar Access Key ID, Secret Access Key y el Account ID (visible en la URL del endpoint).
En el repo, crear
.dvc/config.local(gitignored) con:['remote "r2"'] access_key_id = <ACCESS_KEY_ID> secret_access_key = <SECRET_ACCESS_KEY>y decirle al agente el Account ID (no es secreto) para que fije
endpointurlen.dvc/config.
Addendum 2026-10-16 (implementación)
dvc init --no-scm: la libgit2 embebida de DVC falla al renombrar objetos de git sobre el bind-mount de Windows (PermissionErroren.git/objects/...lock), mientras que el CLI de git funciona. DVC no toca git; los archivos.dvc,manifest.jsonymanifest.sha256dentro deraw/se versionan explícitamente (excepciones en.gitignore) y se confirman congitdesde el host o desde el contenedor.- Caché DVC en
/dvc-cache(volumen nombrado) en lugar de.dvc/cache:dvc initrechaza un.dvc/preexistente y Docker crea el punto de montaje antes. - Account ID de R2 registrado en
.dvc/config(no es secreto):5cd9171e5332beff49a1752f57985f6a. - El puntero del registry añade
dvc_md5y una ubicacióndvc+r2://files/md5/<2>/<30>(DVC 3 direcciona la caché por MD5; la identidad del archivo sigue siendo el SHA-256).
Consecuencias
dvc pullfunciona para quien tenga credenciales del remote correspondiente. Addendum 2026-10-16 (ADR 0014): ningún bucket que contenga nivel 3 se expone con dominio público ni se comparte por token; el acceso público canónico de niveles 1–2 es Zenodo o el remoter2-open.- Si R2 dejara de ser viable, el remote cambia sin tocar punteros: la identidad es el hash, no la URL.