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.
$ 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
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í.
| repo | un directorio con .zar/: objetos por contenido, commits y referencias. |
| hub | un repo compartido con zar share: tiene un código corto y una lista de espacios. No hay un tipo de repo «servidor». |
| espacio | una 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). |
| rama | puntero mutable a un commit. Una rama solo puede estar activa en un espacio. |
| canal | puntero protegido: solo avanza por fast-forward y cada movimiento queda en un log append-only. |
| perfil | identidad y política de un actor (humano o agente): autor, qué ramas puede crear o escribir, qué canales puede promover o seguir. |
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.
Ramas, switch, restore y fusión de tres vías con commits de dos padres, marcadores de conflicto y --abort / --continue.
Tags que no se sobrescriben sin --force, y pins: claves de «listo» por rama para avisar de que un trabajo está terminado.
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.
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.
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.
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.
Sincronización por un contrato Transport: R1 con otro repo en disco, R2 por HTTP con zar serve y tokens zar_. Solo fast-forward.
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.
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.
Á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…"}
}
verify.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
Bearer zar_…; --private exige token para leer.CODE@http://…, sigue stable y sondea; el hub nunca manda comandos.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
ok, caducada, huerfana, sin-ancla, comparando blobs.wiki/decisiones/; promote pasa la wiki por lint.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.
zar whoami, zar wiki hot, zar status, zar update, siempre con --json, decidiendo por ok y error.code.
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.
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.
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.
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.
Repo v2, ramas, perfiles, espacios, merge y tags, canal stable, gates y pins, estrés y empaquetado.
Wiki: páginas, índice determinista y caducidad exacta.
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.
Lo que se calcula del código: fichero, estructura, quien-usa, diff por nombre.
wiki servir, explorado solo humano y rutas de escritura por perfil.
Medida: ¿ayuda lo calculado a un agente? 4 de 4 correctos; no gana, y deja de ser obligatorio en la skill.
El contrato Transport en disco: remote, push, pull, clone.
El mismo contrato por HTTP: zar serve y tokens zar_, sin tocar las órdenes.
Unirse desde otra máquina y recibir lo que se promueve, sondeando.
hot en espacios remotos, informe de vuelta al hub y que .zarignore viaje.
gc.