v1.0 · formato en disco 2 · Python ≥ 3.10

Zar.

Control de versiones propio para que varios agentes trabajen a la vez sobre el mismo proyecto sin pisarse, y para que un humano vea qué hizo cada uno.

solo biblioteca estándar · sin dependencias · nunca interactivo · --json en todo

$ zar init
inicializado: proyecto/.zar  (formato 2, rama main)

$ zar share --label proyecto
hub compartido: 7QK2-M9XD  (proyecto)

$ zar join 7QK2-M9XD ../espacio-a1 --as agente-a1 --name a1
espacio a1 (work) en ../espacio-a1
  rama agent/a1/a1 desde main · perfil agente-a1

$ zar commit -a -m "añade parser"   # autor: agente-a1 [agent]
$ zar promote stable                 # exit 5: no puede promover

# el humano promueve y propaga
$ zar promote stable agent/a1/a1 --propagate
stable: 9c1e04ab → e7d2b3f1 (seq 4)
  espacio ci    (use, auto)  actualizado
  espacio demo  (use, auto)  saltado: sucio
  espacio a2    (work)       saltado: necesita merge
// qué es

Un control de versiones pensado para agentes

Zar es un sistema de control de versiones escrito en Python, sin dependencias externas. Cada agente tiene su espacio (su carpeta de trabajo), su perfil (quién es y qué puede tocar) y sus ramas. El proyecto publica un canal stable que otros espacios consumen y que se actualizan solos cuando cambia. Se entra a un proyecto compartido con un código corto: zar join 7QK2-M9XD.

Es también un banco de pruebas: se construye hito a hito por un agente autónomo, contra criterios de aceptación escritos de antemano. El README es la especificación; si hay que interpretar algo que no está escrito, es un hueco del README y se corrige allí.

repoun directorio con .zar/: objetos por contenido, commits y referencias.
hubun repo compartido con zar share: tiene un código corto y una lista de espacios. No hay un tipo de repo «servidor».
espaciouna carpeta de trabajo enlazada a un hub, con su HEAD, índice y perfil. No duplica objetos: usa el almacén del hub. Puede ser work (rama propia, hace commits) o use (sigue un canal en solo lectura).
ramapuntero mutable a un commit. Una rama solo puede estar activa en un espacio.
canalpuntero protegido: solo avanza por fast-forward y cada movimiento queda en un log append-only.
perfilidentidad y política de un actor (humano o agente): autor, qué ramas puede crear o escribir, qué canales puede promover o seguir.
// características principales

Lo que hace

commitHistoria íntegra

Almacén por contenido (sha256). El id de un commit es el hash de su JSON canónico, así que siempre se recalcula. Si algo no coincide: corrupt, nombrando el objeto. Nunca un corte silencioso.

branchRamas y fusión

Ramas, switch, restore y fusión de tres vías con commits de dos padres, marcadores de conflicto y --abort / --continue.

tag · pinEtiquetas y marcas

Tags que no se sobrescriben sin --force, y pins: claves de «listo» por rama para avisar de que un trabajo está terminado.

spaceEspacios

Cada agente en su carpeta, compartiendo el almacén del hub: un commit de un agente se ve al instante desde otro espacio del mismo hub.

channelCanales

stable solo avanza por fast-forward, con log de quién movió qué. promote --propagate actualiza los espacios que lo siguen y nunca fusiona trabajo de un agente en silencio.

gateGates

Un comando que debe salir con 0 para que un canal avance. Se ejecuta en una materialización temporal del candidato, sin shell y con tiempo máximo.

profilePerfiles

Política cooperativa y auditoría: cada commit guarda el perfil, su tipo y el digest del perfil con que se hizo. Con schema 2, también qué rutas puede cambiar.

syncpush · pull · clone

Sincronización por un contrato Transport: R1 con otro repo en disco, R2 por HTTP con zar serve y tokens zar_. Solo fast-forward.

wikiWiki integrada

La memoria del proyecto vive en wiki/, dentro del árbol, con un registro de decisiones. La caducidad de cada página se calcula, no se adivina.

// cómo funciona

Commits, sincronización y wiki

Todo fichero se escribe de forma atómica; mover una rama o un canal es un compare-and-swap bajo cerrojo. Si dos procesos compiten, uno entra y el otro recibe moved: no se pierde nada.

01Commits

Árbol plano por commit (ruta → blob), bytes tal cual, sin normalizar finales de línea.

{
  "id": "e7d2b3f1…",
  "parents": ["9c1e04ab…"],
  "message": "añade parser",
  "author": {"profile": "agente-a1",
             "kind": "agent",
             "profile_digest": "3f9a…"},
  "space": "a1",
  "tree": {"src/parser.py": "b194…"}
}
  • 8 procesos haciendo commit a la vez: ninguno se pierde.
  • Matar el proceso a medias deja un repo que pasa verify.

02Sincronización

El mismo contrato con dos transportes: objetos por hash, commits y refs con compare-and-swap.

# R1: otro repo en disco
zar remote add otro ../otro
zar push otro main
zar pull otro main
zar clone ../otro copia

# R2: el mismo contrato por HTTP
zar serve --port 8078
zar token create …
ZAR_TOKEN=zar_… zar push
  • Lectura pública, escritura con Bearer zar_…; --private exige token para leer.
  • R3: un nodo remoto se une con CODE@http://…, sigue stable y sondea; el hub nunca manda comandos.

03Wiki

Páginas Markdown con cabecera: tipo, fuente, commit, blobs, confianza, explorado.

zar wiki            # catálogo y estado
zar wiki hot        # lo que saber hoy
zar wiki buscar …
zar wiki lint --fix
zar wiki quien-usa a.py:f
zar wiki servir     # visor en 127.0.0.1
  • Estados: ok, caducada, huerfana, sin-ancla, comparando blobs.
  • Decisiones registradas en wiki/decisiones/; promote pasa la wiki por lint.
// el agente y las puertas

El agente propone, la puerta decide

Zar tiene su propia skill de agente: un agente trabaja en su espacio y su rama, y un humano promueve a stable. Nunca al revés. Antes de tocar nada lee la wiki, y mantenerla es parte de la tarea, no algo de después.

El proyecto avanza por fases. Cada fase tiene una puerta: un documento escrito antes del código con el inventario de lo que ya existe, lo que no se construye y «el número que se puede fallar». Al terminar, el resultado se anota en la misma puerta.

Orientarse

zar whoami, zar wiki hot, zar status, zar update, siempre con --json, decidiendo por ok y error.code.

Trabajar en su rama

zar add -A y zar commit con un mensaje que dice qué cambió y por qué. El autor lo pone zar con el perfil del agente.

Mantener la wiki

Si una página está caducada, habla de un fichero que ya cambió: el agente lee el fichero real y la actualiza en el mismo commit.

Avisar de que está listo

zar wiki lint --fix y zar pin set listo --note "…". Promover lo hace el humano.

«¿Puede un agente autónomo barato construir esto, en profundidad, contra criterios que no puede tocar?» Las pruebas de aceptación no las escribe el ejecutor, no se confía en su texto de cierre, y se verifica en disco.

// estado actual

Dónde está hoy

Versión 1.0: todos los hitos, de 0.1.1 a 1.0, con sus criterios de aceptación en verde. El formato en disco 2 está congelado. Probado en Windows el 2026-10-25.

1.0hitos 0.1.1 → 1.0 hechos
188tests verdes tras R3
241pasos de caracterización grabados
0dependencias externas
hecho
0.1.1 – 1.0

Repo v2, ramas, perfiles, espacios, merge y tags, canal stable, gates y pins, estrés y empaquetado.

hecho
W0

Wiki: páginas, índice determinista y caducidad exacta.

hecho
W1

hot, enganche en join/update/promote y la skill del agente: 2 de 2 agentes actualizaron la página caducada sin que se lo pidieran.

hecho
W2

Lo que se calcula del código: fichero, estructura, quien-usa, diff por nombre.

hecho
W3

wiki servir, explorado solo humano y rutas de escritura por perfil.

hecho
W4

Medida: ¿ayuda lo calculado a un agente? 4 de 4 correctos; no gana, y deja de ser obligatorio en la skill.

hecho
R1

El contrato Transport en disco: remote, push, pull, clone.

hecho
R2

El mismo contrato por HTTP: zar serve y tokens zar_, sin tocar las órdenes.

hecho
R3

Unirse desde otra máquina y recibir lo que se promueve, sondeando.

✕No es git ni lo reemplaza: sin compresión de objetos, sin rebase, sin submódulos, sin hooks.
✕No es seguro contra acceso al disco: los perfiles son política cooperativa y auditoría.
✕No escala a repos enormes: cada commit guarda el árbol plano completo y aún no hay gc.
✕No gestiona ficheros grandes ni binarios pesados con cuidado especial.