¿Qué hace todo (núcleo)?
El repositorio es una máquina de estados de bucle cerrado construida a partir de archivos que ya existen. Nada más almacena el estado.
| Capa | Archivo(s) | Rol | Política de escritura |
|---|---|---|---|
| Requisitos | README.md, docs/*.md | Verdad fundamental: contratos, especificaciones, configuración, planes largos | Mayormente lectura. Editado bajo "Deriva de documentación" en todo-continue; documentos de plan (docs/plans/) por todo-init/todo-plan/todo-add/todo-update; la línea Tests: del README por todo-init si se confirma; el RTM opcional (reference/rtm.md) por todo-plan/todo-add/todo-continue solo si ya existe; docs/status.html por todo-report |
| Cola activa | TODO.md | Un árbol de tareas. Un rastreador de elementos de trabajo, no un lugar para diseño | Editado solo por las habilidades todo-* |
| Validación | Código fuente + suites de prueba | Verdad fundamental para "hecho" | Cambiado solo para la tarea en cuestión |
| Archivo | CHANGELOG.md | Permanente, solo anexión (Keep a Changelog + Conventional Commits) | Solo se toca ## [Unreleased] (al lanzar: renombrado a la versión, uno nuevo vacío arriba, y las líneas de enlace al final), por un drenaje raíz y el /todo-release confirmado; todo-init crea el archivo o agrega un [Unreleased] faltante |
| Verificaciones (opcional) | .todo/check.sh, .todo/todo-lint.sh, trabajo de CI | Lint + pruebas, ejecutado por CI, un hook pre-push y /todo-continue | check.sh escrito por /todo-init --ci si se confirma; todo-lint.sh copiado por el usuario; confirmado por el usuario |
| Almacén de versiones | git | Rama o worktree por tarea. Nada llega a la rama base sin verificar | Ver "Modo Git" |
Prefiere herramientas de archivo nativas (Lectura/Edición/Escritura) para ediciones de archivos; sin importar cómo edites, cambia solo las líneas previstas y mantén la nueva línea final del archivo. Usa el shell solo para git, comandos de prueba y Done when, los scripts opcionales, y los comandos de archivo que nombra una habilidad (cp, chmod, mkdir -p, date, grep, cmp, mv y rm del archivo temporal propio de una habilidad).
Los archivos de backlog son TODO.md, CHANGELOG.md, docs/plans/PROJECT.md, docs/plans/<ROOT-ID>-*.md nombrados por un Ref:, y las líneas Tests: y Base: del README escritas por una habilidad todo-*. README.md se prepara para una confirmación de backlog solo mientras git diff README.md agrega exactamente esas líneas, opcionalmente después de una línea en blanco; las ediciones del README que hace un nodo bajo "Deriva de documentación" son archivos de ese nodo y se confirman con él; cualquier otro cambio en README es del usuario: cuenta para la verificación de árbol limpio y nunca se prepara en una confirmación de backlog. Las ediciones del backlog permanecen sin confirmar hasta la próxima confirmación que haga una habilidad en una rama todo/ (la reclamación del árbol, generalmente), que las prepara por ruta explícita. Las nuevas raíces, y cualquier cambio en un nodo de un árbol no reclamado, se realizan solo en la rama base; en una rama todo/ las habilidades los rechazan y nombran la base. La verificación de árbol limpio (reference/git-flow.md) los ignora.
Uso directo
/todo solo es de solo lectura: lista los comandos, ejecuta la verificación de invariantes en TODO.md si existe, informa. No cambia nada.
| Comando | Propósito |
|---|---|
/todo-init | Inicializar archivos, detectar comando de prueba y git, planificación previa opcional y configuración de CI, migrar el formato antiguo |
/todo-plan | Planificar el trabajo en carriles y un árbol; revisar el plan en cualquier momento |
/todo-add | Agregar una tarea, o descomponer una solicitud en un árbol |
/todo-continue | Ejecutar el siguiente nodo de tarea, verificarlo, fusionarlo en su padre |
/todo-update | Cambios manuales de estado y campo |
/todo-status | Árbol de solo lectura, carriles, historial y búsqueda |
/todo-report | Escribir una página de estado HTML interactiva en docs/status.html |
/todo-release | Convertir [Unreleased] en una versión después de que el usuario lo confirme |
Cada habilidad ejecuta solo su propio comando y nunca se encadena a otro sin que se solicite.
Modo Git
Al inicio de cada comando ejecuta git rev-parse --is-inside-work-tree.
- Repositorio Git: cada nodo trabaja en su propia rama o worktree (
reference/git-flow.md). La rama base es la que el usuario nombra, de lo contrario la líneaBase:del README, de lo contrario la primera que exista demain,master,trunk,develop; si no hay ninguna, preguntar una vez. Cuando el usuario nombra una base diferente de ese valor predeterminado, ofrecer agregarBase: <rama>al README (escrito si se confirma; un archivo de backlog como la líneaTests:). Cada paso que verifica o fusiona en la base (reclamación de árbol, liberación de reclamación, fusión base, lanzamiento) se ejecuta en el checkout principal (la primera entrada degit worktree list): desde un worktree vinculado,cdallí primero; si está en otra rama con cambios, detenerse e imprimir los comandos. - No es un repositorio git: advertir una vez por comando: "Esto no es un repositorio git. Las habilidades todo aún funcionan, pero sin ramas, worktrees, confirmaciones ni fusiones, por lo que no hay aislamiento ni historial. Ejecuta
git initpara habilitarlos." Luego usar modo sin git: omitir cada paso de git, rastrear el progreso enState:(incluyendofiles:tocados), aún actualizar marcadores y drenar a CHANGELOG.md. La verificación no cambia.
Nunca etiquetar, forzar push, hacer reset duro o clean. La única eliminación forzada de rama es de una rama que contiene solo la confirmación de reclamación no publicada de la propia habilidad (reference/git-flow.md, pasos 2 y 5 de reclamación de árbol). Los comandos git propios de las habilidades nunca tocan la red: sin fetch, pull ni push. Compartir confirmaciones es trabajo de git y tuyo. Un comando de prueba puede descargar dependencias; si falla por falta de red, bloquear con esa razón en lugar de reintentar.
Esquema de TODO.md
# Active Backlog
## 🌳 Task Tree
Exactamente este encabezado y una sección. Sin secciones In Progress, Ready o Blocked: el marcador en cada tarea es su estado. Un árbol vacío son los dos encabezados y ninguna tarea.
Una tarea tiene de 2 a 4 líneas: qué hacer, cómo se valida, enlaces opcionales y estado.
- [ ] **FEAT-002** · P1 · mid · XL · Agregar actualización de token al servicio de autenticación
- Done when: token antiguo rechazado después de actualizar; `npx jest tests/auth`; regression: `npm test`
- Links: Ref: docs/auth.md#refresh · Depends: TASK-001 · From: FIX-001
- State: branch todo/FEAT-002-add-token-refresh-auth from main; next: build children
- [ ] **FEAT-002.1** · mid · Punto final de actualización
- Done when: punto final cubierto por una prueba de integración; `npx jest tests/auth/refresh.test.ts`
- [/] **FEAT-002.1.1** · high · Interfaz de almacenamiento de tokens
- Done when: almacenamiento realiza un viaje redondo de token; `npx jest tests/auth/store.test.ts`
- State: attempts 1/3; baseline 42 passing; branch todo/FEAT-002.1.1-token-store-interface from todo/FEAT-002.1-refresh-endpoint; next: build
| Parte | Regla |
|---|---|
| Encabezado | - [m] **ID** · [P0-P2, solo raíces ·] COMPLEJIDAD [· TAMAÑO] · qué hacer, una oración: complejidad low, mid o high (obligatorio); tamaño S, M, L o XL (opcional) |
Done when: | Obligatorio. Criterios, luego ; y al menos un comando exacto entre comillas invertidas. Opcional ; regression: \comando``; sin él la regresión es la suite completa del proyecto |
Links: | Opcional. Ref: <ruta#ancla>, Depends: <IDs>, From: <ID>, Lane: <nombre> (solo raíces), separados por · |
State: | Opcional, sobrevive a un reinicio de contexto. Elementos separados por ; , cada uno como máximo una vez, en este orden: attempts n/3, baseline <n> passing (o none, o red: <ids de pruebas fallidas, separadas por comas>), `tier: <low |
Blocked: | En tareas [!], en lugar de State y en su lugar (la última línea de campo): <razón> → <comando entre comillas invertidas> <error, como máximo 5 líneas unidas con " / "> → <acción requerida>. Un bloqueo manual escribe n/a (manual) en el medio |
Solo existen estos cuatro campos; una tarea nunca tiene State y Blocked. Más de 4 líneas es prosa de diseño y pertenece a docs/ (enlazarlo con Ref:). Si una tarea necesita más, dividirla.
Indicadores: [ ] abierto, [/] activo (como máximo uno en el archivo), [!] bloqueado, [x] verificado y fusionado (o fusionándose) en su padre, esperando que su raíz drene.
Árbol, niveles y complejidad
Un nodo en el nivel L tiene su encabezado con sangría de 2L espacios y sus campos con 2L+2. Máximo 3 niveles.
Regla de alcance. Cada hoja es un cambio que cabe en una ventana de contexto y toca como máximo 5 archivos; el trabajo más grande se divide en hijos (/todo-add). Un nodo demasiado grande para dividir aún mantiene State: next: decompose hasta que /todo-continue lo descomponga.
Tamaño (opcional, después de la complejidad) registra el alcance cuando ayuda al lector; cuando está presente, debe coincidir con el árbol, y agregar o eliminar un nodo actualiza el tamaño de cada ancestro:
| Tamaño | Significado | Dónde |
|---|---|---|
S | Un cambio, como máximo 2 archivos | Hoja |
M | Una ventana de contexto, como máximo 5 archivos | Hoja |
L | Tiene hijos, todas hojas | Padre |
XL | Tiene nietos | Padre |
Una hoja con State: next: decompose puede llevar L/XL.
Complejidad dice qué tan difícil es el razonamiento, no qué tan grande es el cambio, para que un agente pueda elegir un modelo adecuado:
| Complejidad | Significado | Ejemplos |
|---|---|---|
low | Mecánico: la causa y el cambio ya se conocen, sin investigación | Renombrar, documentación, configuración, un guard o función pequeña cuya solución establece la línea de tarea |
mid | Trabajo ordinario que necesita algo de investigación o diseño (el predeterminado) | Un nuevo punto final, un error cuya causa debe encontrarse |
high | Razonamiento difícil o alto riesgo | Concurrencia, seguridad, migración de datos, especificación poco clara, diseño entre módulos, algoritmos complicados |
Un padre se califica solo por su paso de integración (generalmente low o mid); sus hijos llevan sus propios niveles. Las raíces llevan la prioridad y el carril; los hijos heredan ambos.
Enrutamiento de modelos (opcional)
Un proyecto asigna niveles a modelos con una línea de README, por ejemplo Models: low=haiku, mid=sonnet, high=opus (cualquier nombre que el agente entienda). Sin esa línea, o sin una herramienta de subagente, la complejidad es solo una pista y el trabajo se ejecuta en el modelo actual. Con ambas:
/todo-continue --delegatey las ejecuciones de carril le dan a cada nodo (o raíz de carril, en su complejidad más alta) un subagente en el modelo asignado.- El revisor se ejecuta en el nivel del nodo o superior.
- Escalación: después de un intento de verificación fallido, el siguiente intento se ejecuta un nivel más arriba (
low→mid→high), registrado enState:comotier:. Una etiquetalowincorrecta cuesta un intento barato, no un nodo bloqueado.
IDs
- Las raíces
<PREFIX>-<NNN>, una secuencia global, 3 dígitos. Los hijos agregan.n:FEAT-002.1,FEAT-002.1.2. Los puntos equivalen al nivel. - Los IDs nunca se reutilizan. Siguiente número de raíz = el número FEAT-/FIX-/TASK- más alto encontrado en
TODO.md,CHANGELOG.md(incluyendo IDs después deIncludes:),docs/plans/*.mdy, en modo git, asuntos de confirmación (git log --all --format=%s, que nombran IDs eliminados), más 1. Siguiente número de hijo = el número de hijo más alto bajo ese padre encontrado en los mismos lugares, más 1.
| Prefijo | Significado | Encabezado de CHANGELOG | Tipo de confirmación |
|---|---|---|---|
FEAT | Nueva capacidad | ### Added | feat |
FIX | Error o regresión | ### Fixed | fix |
TASK | Refactor, tarea, documentación, prueba, rendimiento, construcción | ### Changed | el que corresponda |
Los hijos usan el prefijo de su raíz.
Qué nodo sigue
Un nodo es trabajable cuando: está [ ]; todos los hijos están [x]; cada ID de Depends: está satisfecho (en CHANGELOG.md como ID de entrada o después de Includes:, también en git show <base>:CHANGELOG.md en modo git, o [x] en TODO.md; cuando solo el CHANGELOG de la base lo satisface, /todo-continue fusiona la base en la rama desde la que el nodo comenzará antes de iniciarlo, paso 3; los comandos de solo lectura informan "espera una fusión base"); ningún ancestro está [!]; y, en modo git, su raíz no está reclamada por otra rama. Una raíz está reclamada cuando su State: en el TODO.md de la rama base (git show <base>:TODO.md) nombra una rama; su árbol es trabajable solo desde una rama de esa familia (todo/<ROOT-ID>-… o todo/<ROOT-ID>.…). Un árbol reclamado omitido se informa como reclamado por <rama>; cuando esa rama existe en este clon, agregue "si este es tu trabajo: git switch <rama> (o cd a su worktree) y vuelve a ejecutar para reanudar". Una rama en este clon puede pertenecer a otra sesión, por lo que nunca se reanuda desde la base automáticamente. Si los archivos de backlog contienen ediciones sin confirmar en la base, git switch a esa rama falla: dilo y ofrece git stash push -- <rutas de backlog> primero y git stash pop de vuelta en la base.
El trabajo interrumpido va primero (modo git). En una rama de árbol (cualquier rama todo/), lista las ramas del árbol (git branch --list 'todo/<ROOT-ID>-*' 'todo/<ROOT-ID>.*') y lee el nodo de cada una en git show <rama>:TODO.md. Un nodo que está [x] en una rama aún no fusionada en la rama de su padre (git merge-base --is-ancestor <rama> <rama padre> falla) se detuvo antes de su fusión: completa esa fusión y no hagas nada más (paso 2 de /todo-continue). Un nodo que está [/] se reanuda, primero el más profundo. Un nodo que está [!] en cualquiera de las ramas del árbol cuenta como [!] en todas partes (no trabajable; sus ancestros esperan), incluso donde otra rama aún lo muestra como [ ]; una rama cuyo nodo ya no está en el TODO.md de su rama padre (eliminado) se ignora; una rama ya fusionada en la rama de su padre se elimina con git branch -d. Omite esto en la rama base.
Carriles
Un carril es una pista nombrada de árboles raíz que un contexto de agente trabaja solo, en orden. Lane: <nombre> (una letra minúscula, luego letras minúsculas, dígitos o guiones) en una raíz pone todo su árbol en ese carril; los hijos lo heredan y una raíz sin él está en el carril main (por lo que --lane main selecciona esas raíces). Los carriles son contexto, no tareas: un carril puede contener una tarea o muchas, los carriles se ejecutan en paralelo entre sí (/todo-continue --lane <nombre> reanuda el siguiente nodo trabajable en el carril).
Invariantes
/todo y cada comando verifican:
Done when:existe, no está vacío y contiene al menos un comando entre comillas invertidas.- El número de
[x]no supera al de[ ](el árbol nunca termina antes de que todas las hojas estén hechas). - El árbol no está vacío después de los encabezados.
- Ningún elemento de la lista entre los encabezados está en un nivel diferente al de su contexto (cada anidamiento de sangría
[-*]es un nivel, los campos están dos niveles por debajo). - Un elemento
[/]no es[x](un nodo activo nunca está hecho). - El árbol es un bosque: ningún nodo tiene dos padres (IDs de
Depends:no cuentan; los ID dentro del árbol cuentan). - Cada
Ref:apunta a un archivo existente (y, en modo git, confirmado) o a una sección dentro de él (una etiqueta de anclaje HTML/PDF o un encabezado Markdown que difumina el ancla de la línea); ignorar referencias muertas (sin archivo en el FS ni en el commit HEAD). - Todos los hijos
[x](sin[ ]ni[/]debajo; los[!]están bien; los padres pueden estar en cualquier estado).
/todo-continue también verifica:
- El nodo
[/]coincide con el objetivo (que el pasonext:dicestart <ID>y ese ID está[ ]; obuild: el nodo objetivo está[/]). - El árbol no tiene añadidos extraños (nuevos nodos o cambios de campo en nodos no objetivo).
- El
Done when:no esn/a(a menos que se llame con--nocheck).
Definición de Hecho
Un nodo de tarea está hecho cuando:
- Su
Done when:se cumple: todos los criterios se verifican manual o automáticamente, y todos los comandos entre comillas invertidas se ejecutan y salen con código 0. - La regresión del proyecto (su propio
regression:o la suite completa) pasa. - No quedan cambios sin confirmar fuera de los archivos de backlog.
- En modo git, el nodo está confirmado en su rama.
Barreras de seguridad
- Sin eliminación forzada, reset duro, ni push a remoto.
- Sin modificar archivos fuera del alcance de la tarea.
- Sin cambiar el esquema de TODO.md (encabezados, campos, formato).
- Sin fusionar sin verificar (el nodo debe estar
[x]antes de fusionar a su padre). - Sin reutilizar IDs.
- Sin tocar la red en comandos git propios de la habilidad.
- Sin ejecutar comandos de prueba que modifiquen el estado del sistema (ej., migraciones de base de datos) sin confirmación explícita.
Ayuda de línea de comandos
/todo
Muestra esta ayuda y las invariantes.
/todo-init [--ci] [--plan]
Inicializa TODO.md, detecta el comando de prueba y git.
--ci: Escribe .todo/check.sh para CI.
--plan: Inicia el modo de planificación.
/todo-plan [--revise]
Planifica o revisa el árbol de tareas.
/todo-add [--delegate]
Agrega tareas desde la solicitud.
/todo-continue [--delegate] [--lane <nombre>] [--nocheck]
Ejecuta la siguiente tarea.
--delegate: Usa subagentes para nodos.
--lane: Especifica el carril.
--nocheck: Omite la verificación de invariantes.
/todo-update <ID> [--state <nuevo estado>] [--priority <P0-P2>] ...
Actualiza manualmente el estado o campos.
/todo-status [--tree] [--lanes] [--search <término>]
Muestra el estado actual.
/todo-report
Genera docs/status.html.
/todo-release <versión>
Libera [Unreleased] como <versión>.