Skip to content

Volúmenes y datos — el plano de datos para un consumidor externo ​

Cómo llegan capacidad (código) y datos (volúmenes) a tu máquina, y qué está prohibido por diseño. Es el puente doctrinal del consenso de mesa D-45 (plan/DECISIONES.md:605-634) mientras sus contrapartes de código terminan de aterrizar — esta página declara su propio estado al final, en Estado de este puente.

Regla de oro, antes de cualquier detalle: el código viaja por npm; los datos viajan por Release e ingresan por import; el entorno apunta siempre a un root tuyo. Ningún camino legítimo apunta el entorno al árbol de dependencias instaladas por npm ni al interior de un pack.

Los tres momentos ​

El consenso de mesa fija tres momentos distintos, con canal propio cada uno (C-4, plan/DECISIONES.md:620-622; segundo acto C-6 registrado en plan/BACKLOG.md:358):

MomentoQué viajaCanalEstado
1 · Instalarcapacidad: kits FOSS ligeros @zeus/*registry npm propiooperativo — catálogo en Kits FOSS
2 · Sembrardatos: start pack con versión + hashtarball adjunto al GitHub Release de la games-library (Z_SDK-games-library) · import-oncecontrato v1 en obra (WP-U201)
3 · Sincronizarréplica continua entre nodosP2Phorizonte — segundo acto por consenso de mesa; sin promesa aquí

Instalar trae solo código: los kits publicados son ligeros y no contienen corpora. Los start packs de datos no están en el registry npm (un npm install de un pack responde E404 — mismo hecho de canal que declara VOLUMES/README.md:28-30).

Sembrar es el único momento que puebla datos, y tiene un solo camino de producto: el contrato de import — verificar → staging → validar → fusionar → sellar, con reimport del mismo Release = no-op (import-once). Ese contrato está materializado: plan/CONTRATO-IMPORT-PACK-v1.md (WP-U201 ✅ — ✎ orquestador: U201 mergeó en paralelo a esta página; los 7 pasos y el pipeline importPack existen). Los comandos de operador llegarán con los drivers de familia (U202–U205) y el CA de canal (U212).

Sincronizar (P2P, réplica continua) no está encolado: es un segundo acto que requiere consenso de mesa. Se nombra para que el lector sepa que existe como horizonte, no como promesa.

El root de volúmenes: tuyo, explícito y cercado ​

Todo el runtime resuelve su root de datos por un resolver (packages/engine/presets-sdk/src/volumes/resolve.mjs:29-44, WP-U200 · consenso ◆5). Sus tres reglas:

  1. ZEUS_VOLUMES_ROOT es obligatoria. Sin la variable, el resolver falla honesto — «volumes root is not operable» — en vez de adivinar (resolve.mjs:32-36). No hay default de producto, no hay búsqueda ascendente por directorio de trabajo.
  2. El env apunta siempre a un root propio del operador. Un root que resuelva dentro del árbol de dependencias instaladas por npm es rechazado aunque el env lo pida: un pack es fuente de import, nunca un root vivo (cerco §10.8; resolve.mjs:38-42). El espejo del mismo contrato vive en packages/engine/linea-kit/src/validate.mjs:164-168.
  3. Un valor relativo se ancla contra la raíz del monorepo, jamás contra el directorio de trabajo (resolve.mjs:37). Fuera del monorepo, usa ruta absoluta — linea-kit la exige (validate.mjs:153-157).

Forma del valor (la misma que documenta VOLUMES/README.md:35):

sh
ZEUS_VOLUMES_ROOT=/ruta/propia/VOLUMES

Comodidad de desarrollo dentro del monorepo: el .env puede apuntar a los fixtures del propio repo (.env.example:59, ZEUS_VOLUMES_ROOT=./VOLUMES) — eso sigue siendo un root del árbol propio, no un pack.

volumesRoot del loader de packs = solo desarrollo ​

El loader de start packs (loadStartPack, del kit startpack-kit) es obra de G y vive en la games-library, no en este monorepo (sincronia/notas/NOTA-Z-2026-07-26-H01-volumes-concepto.md:33). Hoy ese loader devuelve un volumesRoot que apunta dentro del árbol del propio pack (nota H-01 §2.1, :57-73).

El consenso ◆4(a) (plan/DECISIONES.md:623-625) resolvió que ese valor deja de ser un root consumible: es un cambio de banda major cuyo owner es G, todavía en curso. Mientras esa contraparte aterriza, la regla para cualquier consumidor es esta:

El volumesRoot que reporta el loader sirve solo en desarrollo — inspeccionar un pack, tests del propio kit. Nunca se apunta ZEUS_VOLUMES_ROOT a él: el único root vivo es el tuyo, y los datos del pack entran a ese root por el momento «sembrar» (import). El resolver ya rechaza el atajo desde WP-U200 (resolve.mjs:38-42).

Manifiesto sellado y estado regenerable ​

Dentro del root, manifiesto y estado son ficheros distintos con contratos distintos (C-3 → WP-U199):

  • volumes.json — manifiesto sellado. Declara identidad y topología; es solo-lectura para el runtime y su identidad es el sha256 de sus bytes exactos (packages/engine/volumes-ops/src/manifest.mjs:52-58). Solo un import puede (re)escribirlo, sellando un hash nuevo (manifest.mjs:8-10). Un root sin manifiesto no es operable: toda operación aborta y nada se inventa en su lugar (manifest.mjs:14-15).
  • volumes.state.json — estado vivo. Contadores regenerables por medición (files, bytes, missing, measuredAt) más el hash del manifiesto contra el que se midió; es mutable, no viaja en git y jamás entra en el hash del sello (packages/engine/volumes-ops/src/state.mjs:2-15; counters.mjs:2-8). Medir no modifica el manifiesto.

Regla de mesa que ordena todo lo anterior: si se puede regenerar midiendo, es estado, no manifiesto (manifest.mjs:17-18).

Estado de este puente ​

ENTREGADO-PARCIAL · cierre condicionado. Esta página describe el destino acordado y el código ya vigente en esta base, pero su cierre depende de tres piezas que no son suyas:

  1. ◆4(a) — el loader deja de exponer un volumesRoot consumible. Obra externa de G en startpack-kit (games-library), banda major (plan/BACKLOG.md:359). Abierta.
  2. CA de canal limpio (WP-U212). La prueba de que un consumidor limpio instala capacidad por npm y siembra datos por Release sin tocar el árbol (plan/BACKLOG.md:275). Pendiente.
  3. Contrato de import v1 (WP-U201). ✅ materializado (plan/CONTRATO-IMPORT-PACK-v1.md — ✎ orquestador: cerró en paralelo); los comandos de operador esperan a los drivers U202–U205.

Cuando esas piezas cierren, esta página enlazará el contrato de import con sus comandos reales y retirará este aviso.