@ingeniomaps/cauce 0.68.0 → 0.70.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +159 -0
- package/README.md +13 -6
- package/automatization/AGENTS.md +1 -1
- package/automatization/runners/antigravity/rules/cauce.md +1 -1
- package/automatization/runners/claude/CLAUDE.md +1 -1
- package/automatization/runners/codex/AGENTS.md +1 -1
- package/automatization/runners/gemini/GEMINI.md +1 -1
- package/automatization/shared/skills/autobuild/SKILL.md +1 -1
- package/automatization/workflows/autobuild.js +44 -8
- package/engine/cli/archive.js +87 -0
- package/engine/cli/args.js +7 -2
- package/engine/cli/catalog.js +9 -1
- package/engine/cli/claims.js +125 -0
- package/engine/cli/ops.js +17 -4
- package/engine/cli/planning.js +158 -102
- package/engine/cli/worktree.js +89 -0
- package/engine/core/ownership.js +16 -5
- package/engine/core/repos.js +67 -0
- package/engine/hooks/files.js +3 -2
- package/engine/planning/adoption.js +1 -1
- package/engine/planning/claims.js +153 -0
- package/engine/planning/contracts.js +43 -202
- package/engine/planning/parser.js +89 -33
- package/engine/planning/recurring.js +148 -0
- package/engine/planning/state.js +39 -6
- package/engine/planning/structure.js +220 -0
- package/package.json +1 -1
- package/template/.gitattributes +19 -0
- package/template/AGENTS.md +54 -5
- package/template/Makefile +4 -1
- package/template/automatization/AGENTS.md +1 -1
- package/template/gitignore +9 -0
- package/template/planning/BACKLOG.md +5 -0
- package/template/planning/FLOW.md +3 -1
- package/template/planning/PROTOCOL.md +25 -8
- package/template/planning/README.md +4 -3
- package/template/planning/RECURRING.md +77 -0
- package/template/planning/adr/system/OPS-001-planificacion-como-fuente-de-verdad.md +3 -2
- package/template/planning/business-rules/system/BR-OPS-001-una-sola-tarea-activa.md +7 -4
- package/template/planning/business-rules/system/BR-OPS-005-una-tarea-un-runner.md +44 -0
- package/template/planning/claims/README.md +70 -0
- package/template/planning/delivery/README.md +1 -0
- package/template/planning/delivery/multi-repo.md +11 -0
- package/template/planning/delivery/teamwork.md +162 -0
- package/template/planning/done/README.md +41 -0
- package/template/planning/wip/README.md +49 -0
- package/template/planning/DONE.md +0 -13
- package/template/planning/WIP.md +0 -22
package/template/AGENTS.md
CHANGED
|
@@ -150,9 +150,12 @@ que hacía falta, apagala después, y que la razón quede escrita donde alguien
|
|
|
150
150
|
Antes de abrir un archivo de `planning/`, preguntarle al CLI: es determinista, no gasta contexto y no
|
|
151
151
|
muta nada.
|
|
152
152
|
|
|
153
|
-
- `node tools/ops.js context planning` — gate, mutex de WIP y la tarea que corresponde
|
|
154
|
-
aceptación y sus criterios. Es la entrada correcta para empezar a trabajar.
|
|
153
|
+
- `node tools/ops.js context planning [--hito <slug>]` — gate, mutex de WIP y la tarea que corresponde
|
|
154
|
+
ahora, con su aceptación y sus criterios. Es la entrada correcta para empezar a trabajar. Con `--hito`
|
|
155
|
+
la cola se acota a ese hito, que es como un equipo se reparte trabajo sin coordinarse.
|
|
155
156
|
- `node tools/ops.js tree planning` — panorama de roadmap, backlog, WIP, inbox y done.
|
|
157
|
+
- `node tools/ops.js recurring planning [--promote <qué>]` — qué trabajo recurrente venció y con
|
|
158
|
+
qué línea se promueve. Emite esa línea; escribirla en `BACKLOG.md` es de una persona.
|
|
156
159
|
- `node tools/ops.js check planning` — validación de contratos y trazabilidad.
|
|
157
160
|
- `node tools/ops.js evidence planning [--task <slug>]` — contrasta la evidencia de una entrada de DONE
|
|
158
161
|
contra lo que no escribió su autor: si el artefacto que `tests:` nombra existe en las raíces de
|
|
@@ -161,8 +164,49 @@ muta nada.
|
|
|
161
164
|
nombrada haya corrido —eso depende del runner, y varios no la nombran al pasar— ni reemplaza a leer
|
|
162
165
|
su fuente, que es lo que R9 pide.
|
|
163
166
|
|
|
164
|
-
Los
|
|
165
|
-
falta editarlos o cuando el CLI no responda la pregunta.
|
|
167
|
+
Los cinco aceptan `--json`. Leer `BACKLOG.md`, tu `wip/<runner>.md`, `HUMAN_ACTIONS.md` o `RECURRING.md`
|
|
168
|
+
completos sólo cuando haga falta editarlos o cuando el CLI no responda la pregunta.
|
|
169
|
+
|
|
170
|
+
## Cómo tomar trabajo
|
|
171
|
+
|
|
172
|
+
Con equipo, la tarea que `context` devuelve puede estar libre o ya ser tuya, y la salida lo dice. Libre
|
|
173
|
+
se toma antes de empezar:
|
|
174
|
+
|
|
175
|
+
- `node tools/ops.js claim planning <tarea>` — la reserva a tu nombre y escribe `planning/claims/<tarea>.md`.
|
|
176
|
+
- `node tools/ops.js release planning <tarea>` — la devuelve a la cola.
|
|
177
|
+
|
|
178
|
+
Una tarea que declara `(depende: slug)` no se ofrece ni se puede tomar hasta que eso esté en DONE, y
|
|
179
|
+
`context` la muestra con una línea `WAIT`. No hay que adelantarse: lo que sigue es trabajo de quien tiene
|
|
180
|
+
la tarea de la que depende.
|
|
181
|
+
|
|
182
|
+
Tomar no es promover: la tarea ya estaba aprobada en `BACKLOG.md` y esto sólo dice quién la hace, así que
|
|
183
|
+
entra en la autonomía del runner. Lo que no entra es tocar el reclamo de otro — ni tomarlo, ni soltarlo—,
|
|
184
|
+
y `context` directamente no ofrece una tarea reclamada.
|
|
185
|
+
|
|
186
|
+
El reclamo hay que **commitearlo y empujarlo**: sin eso el otro runner lee lo que hay en su copia y la
|
|
187
|
+
reserva no existe para nadie más.
|
|
188
|
+
|
|
189
|
+
## Con qué runner arrancás
|
|
190
|
+
|
|
191
|
+
Antes de pedir trabajo hay que saber quién lo tiene. Dos sesiones en la misma máquina resuelven la misma
|
|
192
|
+
identidad de git, así que lo que las distingue es el `CAUCE_RUNNER` de cada una.
|
|
193
|
+
|
|
194
|
+
`node tools/ops.js runners planning [--json]` dice qué runners tienen una tarea abierta, cuál, desde
|
|
195
|
+
cuándo y si su rama avanzó. Según lo que devuelva:
|
|
196
|
+
|
|
197
|
+
- **Ninguno** — arrancá con un id propio y no preguntes nada. No hay trabajo que retomar.
|
|
198
|
+
- **Uno o más** — **preguntale a la persona** cuál retoma o si arranca uno nuevo, nombrando la tarea de
|
|
199
|
+
cada uno, desde cuándo y si avanzó. Retomar el id de un agente que sigue corriendo le saca la tarea, y
|
|
200
|
+
arrancar uno nuevo cuando había trabajo a medias lo deja huérfano: las dos rompen algo, y por eso la
|
|
201
|
+
elección no es tuya.
|
|
202
|
+
|
|
203
|
+
Elegido el id, **exportalo vos** y usalo en cada `ops` de la sesión. **Nunca le pidas a una persona que
|
|
204
|
+
escriba una variable de entorno**: no es el idioma en el que trabaja, y el runner es cómo el toolkit
|
|
205
|
+
distingue dos sesiones, no una decisión de producto. Lo suyo es elegir; la mecánica es tuya.
|
|
206
|
+
|
|
207
|
+
- `node tools/ops.js worktree planning <tarea>` — prepara el árbol de trabajo de esa tarea y te devuelve
|
|
208
|
+
la ruta con el `export CAUCE_RUNNER` hecho. No clona nada: `git worktree` comparte el mismo `.git`, y
|
|
209
|
+
cada árbol queda fijado a su rama, así que ningún agente hace `checkout` sobre el trabajo de otro.
|
|
166
210
|
|
|
167
211
|
## Autonomía
|
|
168
212
|
|
|
@@ -178,6 +222,11 @@ Nunca amplía el alcance, promueve sus propias ideas, reescribe el proceso duran
|
|
|
178
222
|
`git add .`/`git add -A`, reescribe historia con `--force` o `--amend`, ni afirma éxito sin evidencia
|
|
179
223
|
real. Tampoco publica: sin autorización no hay `push`.
|
|
180
224
|
|
|
225
|
+
Una recurrencia vencida tampoco la promueve, y ésta es la que más se parece a una excepción: la
|
|
226
|
+
aceptación ya está escrita, la fecha la calculó el CLI y `context` la nombra sola. Nada de eso es la
|
|
227
|
+
aprobación que pide BR-OPS-002 — `context` la nombra para que la vea una persona, y quien la pega en
|
|
228
|
+
`BACKLOG.md` es esa persona.
|
|
229
|
+
|
|
181
230
|
Publicar es lo único de todo eso que este proyecto puede habilitar, y `runner.allowPush` en
|
|
182
231
|
`ops.config.json` es la autorización que R10 pide. Reescribir historia publicada no entra en el trato:
|
|
183
232
|
un `push --force` se frena con la llave prendida o apagada.
|
|
@@ -193,5 +242,5 @@ publicación tampoco se decide ahí: la decide `allowPush`.
|
|
|
193
242
|
3. QA valida el comportamiento por el camino real, no por un atajo interno.
|
|
194
243
|
4. La deuda residual va a `planning/INBOX.md`.
|
|
195
244
|
5. El cambio se commitea en el repo del servicio —uno por naturaleza del diff, y una tarea suele
|
|
196
|
-
tener una sola— y el hash real queda en `
|
|
245
|
+
tener una sola— y el hash real queda en la evidencia de la tarea, `planning/done/<slug>.md`.
|
|
197
246
|
6. `node tools/ops.js check planning` queda verde.
|
package/template/Makefile
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
.DEFAULT_GOAL := help
|
|
2
2
|
|
|
3
|
-
.PHONY: help check tree context upgrade destroy automation-check
|
|
3
|
+
.PHONY: help check tree context recurring upgrade destroy automation-check
|
|
4
4
|
.PHONY: integration-check integration-sync require-key integration-promote
|
|
5
5
|
.PHONY: require-agent agent-learn agent-propose agent-evaluate require-flow flow-list flow-check flow-show
|
|
6
6
|
.PHONY: install-claude install-codex install-gemini install-antigravity
|
|
@@ -23,6 +23,9 @@ tree: ## Muestra roadmap, backlog, WIP y Done
|
|
|
23
23
|
context: ## Muestra el contexto mínimo de la tarea vigente
|
|
24
24
|
@node tools/ops.js context planning
|
|
25
25
|
|
|
26
|
+
recurring: ## Muestra qué trabajo recurrente vence y con qué línea se promueve
|
|
27
|
+
@node tools/ops.js recurring planning
|
|
28
|
+
|
|
26
29
|
# `init` fija la versión exacta del motor, así que `npm update` no la mueve: hay que pedir @latest.
|
|
27
30
|
# Sin este primer paso `upgrade` compara contra el motor instalado y contesta «al día» para siempre.
|
|
28
31
|
destroy: ## Muestra qué se pierde al borrar esta instancia (borrar exige --force a mano)
|
|
@@ -62,6 +62,6 @@ cambia instalación o materialización, valida `ops init` en un directorio tempo
|
|
|
62
62
|
|
|
63
63
|
## Límites
|
|
64
64
|
|
|
65
|
-
No edites `planning/BACKLOG.md`, `
|
|
65
|
+
No edites `planning/BACKLOG.md`, `planning/wip/` ni `planning/done/` desde hooks o instaladores. No hagas que `ops init` active
|
|
66
66
|
un runner silenciosamente. No agregues lógica de negocio, nombres de servicios de un proyecto, tokens, rutas
|
|
67
67
|
personales ni modelos concretos a esta capa reusable.
|
package/template/gitignore
CHANGED
|
@@ -9,5 +9,14 @@ node_modules/
|
|
|
9
9
|
# máquina. Committearlo sería historia que nadie lee y un conflicto por commit.
|
|
10
10
|
planning/.verify-log
|
|
11
11
|
|
|
12
|
+
# El plan de cada runner. Es de la máquina que lo corre —existe para recuperar una ejecución
|
|
13
|
+
# interrumpida, y nadie más puede retomarla— y cambia en cada paso, así que compartirlo es un conflicto
|
|
14
|
+
# por commit a cambio de nada. Lo que el equipo sí necesita saber vive en `planning/claims/`.
|
|
15
|
+
#
|
|
16
|
+
# Se excluyen los planes y no el directorio: git no puede volver a incluir un archivo cuyo directorio
|
|
17
|
+
# está excluido, y el README de ahí adentro sí tiene que viajar.
|
|
18
|
+
planning/wip/*.md
|
|
19
|
+
!planning/wip/README.md
|
|
20
|
+
|
|
12
21
|
*.tgz
|
|
13
22
|
.DS_Store
|
|
@@ -5,6 +5,10 @@ Solo contiene trabajo aprobado y listo. Las ideas viven en `INBOX.md`.
|
|
|
5
5
|
La aceptación se escribe en la línea o se hereda del criterio que la tarea cita. El lane y el cast son
|
|
6
6
|
opcionales: sin ellos la tarea está sin clasificar, que es el estado que dispara al clasificador.
|
|
7
7
|
|
|
8
|
+
`(depende: slug)` declara qué tiene que estar en DONE antes de que esta tarea se pueda tomar. El orden de
|
|
9
|
+
la lista alcanzaba cuando trabajaba un runner; con dos, el segundo toma la que sigue mientras el primero
|
|
10
|
+
construye aquella de la que depende.
|
|
11
|
+
|
|
8
12
|
Pasando de nueve tareas un hito, o de cinco criterios heredados una tarea, `check` pide decidir (R17):
|
|
9
13
|
o se parte, o lleva `(sin partir: <razón>)` en su línea.
|
|
10
14
|
|
|
@@ -14,4 +18,5 @@ o se parte, o lleva `(sin partir: <razón>)` en su línea.
|
|
|
14
18
|
- [ ] **slug-de-tarea** [full] — Resultado a construir. _Aceptación: conducta observable._ (service: ruta) (cast: quien-entrega → quien-revisa)
|
|
15
19
|
- [ ] **otro-slug** [lite] — Resultado a construir. (→ C1) (epic: 001) (service: ruta) (cast: quien-entrega → quien-revisa, otro-revisor)
|
|
16
20
|
- [ ] **sin-clasificar** — Resultado a construir. _Aceptación: conducta observable._ (service: ruta)
|
|
21
|
+
- [ ] **la-que-sigue** [lite] — Resultado a construir. _Aceptación: conducta observable._ (service: ruta) (depende: slug-de-tarea)
|
|
17
22
|
-->
|
|
@@ -5,7 +5,7 @@ INBOX ──promoción humana──▶ roadmap ──historias listas──▶ B
|
|
|
5
5
|
▲ │
|
|
6
6
|
│ Pick/Plan
|
|
7
7
|
│ ▼
|
|
8
|
-
│
|
|
8
|
+
│ done/<tarea>.md ◀── evidencia ◀── Verify/QA ◀───── WIP
|
|
9
9
|
│ │
|
|
10
10
|
└───────────── deuda adyacente ─────────────────────────────┤
|
|
11
11
|
│
|
|
@@ -15,6 +15,8 @@ INBOX ──promoción humana──▶ roadmap ──historias listas──▶ B
|
|
|
15
15
|
|
|
16
16
|
## Preparar
|
|
17
17
|
|
|
18
|
+
0. Si `ops recurring planning` nombra una recurrencia vencida, decidir si esta vuelta se promueve —el
|
|
19
|
+
comando emite su línea— o se posterga con su razón.
|
|
18
20
|
1. Curar una idea desde INBOX.
|
|
19
21
|
2. Escribir una épica con resultados observables, contexto actual y criterios `C1..CN`.
|
|
20
22
|
3. Descomponerla en historias de máximo cuatro horas, cada una rastreada a uno o más criterios.
|
|
@@ -9,9 +9,12 @@ invariantes.
|
|
|
9
9
|
`(service: ruta)`.
|
|
10
10
|
- Hito: `## Hito slug — Título`.
|
|
11
11
|
- Tarea: `- [ ] **slug** [express|directo|lite|full] — descripción. _Aceptación: observable._ (service: ruta) (cast: quien-entrega → quien-revisa, otro)`;
|
|
12
|
-
puede heredar aceptación usando `(→ CN) (epic: NNN)`. Lane y cast son
|
|
13
|
-
está sin clasificar, que es un estado y no un error.
|
|
14
|
-
|
|
12
|
+
puede heredar aceptación usando `(→ CN) (epic: NNN)` y declarar `(depende: slug, otro)`. Lane y cast son
|
|
13
|
+
opcionales: sin ellos la tarea está sin clasificar, que es un estado y no un error. Una tarea con
|
|
14
|
+
dependencias no se ofrece ni se toma hasta que todas estén en DONE.
|
|
15
|
+
- DONE: un archivo por tarea cerrada, `done/<slug>.md`, con su entrada `[x]` y los campos `acept:`,
|
|
16
|
+
`fecha:` en AAAA-MM-DD, `done:`, `qa:`, `tests:` y `commit:`. La fecha es la del cierre, y es lo que
|
|
17
|
+
ordena una evidencia que ya no depende de su posición dentro de un archivo. `tests:` enlaza cada criterio
|
|
15
18
|
mediante `CN → prueba`; usa `A → prueba` cuando no hay épica o `n/a — razón` si no existe una
|
|
16
19
|
superficie ejecutable. `decisions:` es opcional y, si aparece, cita `[fuente: ...]` o
|
|
17
20
|
`[supuesto: ...]`. `commit:` apunta a `<sha> <asunto>`, o a `n/a — razón` cuando la tarea no
|
|
@@ -20,12 +23,23 @@ invariantes.
|
|
|
20
23
|
en el vocabulario cerrado `pendiente | resuelta` —la fecha puede ir detrás—. Mientras la fila no
|
|
21
24
|
esté resuelta, su tarea no se toma; un estado fuera del vocabulario es un error de `check` y no un
|
|
22
25
|
bloqueo silencioso.
|
|
23
|
-
-
|
|
26
|
+
- Recurrencia: fila `| qué | cada | desde | tarea y aceptación |` bajo `## Recurrencias`, con `cada` en
|
|
27
|
+
el vocabulario cerrado `mensual | trimestral | semestral | anual` y la celda de tarea escrita como la
|
|
28
|
+
cola de su línea de BACKLOG. Vencer no bloquea: cada vuelta se promueve con el período en el slug
|
|
29
|
+
—`<qué>-AAAA-MM`— y esa promoción la escribe una persona. Postergar se registra bajo
|
|
30
|
+
`## Postergaciones` con `- **qué** AAAA-MM-DD — razón`.
|
|
31
|
+
- Reclamo: `claims/<tarea>.md` con frontmatter `task/owner/runner/started/service`; el nombre del
|
|
32
|
+
archivo es el slug que reserva, y por eso un `task` que diga otra cosa es un error. `owner` dice a
|
|
33
|
+
quién preguntarle y `runner` decide de quién es: con varios agentes en una máquina la persona es
|
|
34
|
+
la misma y el árbol de trabajo no.
|
|
35
|
+
- WIP activo: frontmatter y checklist en `wip/<runner>.md`; inactivo cuando el archivo no está. Es
|
|
36
|
+
local y no viaja por git: existe para recuperar la sesión de quien lo escribió, y es uno por runner
|
|
37
|
+
porque una instancia sidecar la comparten todos los agentes de esa máquina.
|
|
24
38
|
|
|
25
39
|
## Gates de arranque
|
|
26
40
|
|
|
27
41
|
1. Si existe `AWAITING_REVIEW.md`, parar y mostrar la acción que contiene.
|
|
28
|
-
2. Si WIP está activo
|
|
42
|
+
2. Si tu WIP está activo, la tarea es ésa: es el mutex del runner, y sólo se lee el propio.
|
|
29
43
|
3. Si WIP está activo tras una interrupción confirmada, verificar los pasos `[x]` en disco y continuar
|
|
30
44
|
desde el primer `[ ]`; no replanear.
|
|
31
45
|
4. Si WIP apunta a una tarea ya en DONE y fuera de BACKLOG, reparar el cierre dejando WIP en IDLE.
|
|
@@ -33,7 +47,8 @@ invariantes.
|
|
|
33
47
|
## Máquina por tarea
|
|
34
48
|
|
|
35
49
|
1. Triage: inspeccionar estado y cambios existentes.
|
|
36
|
-
2. Pick: primera tarea no bloqueada
|
|
50
|
+
2. Pick: primera tarea no bloqueada ni reclamada por otro runner, recorriendo los hitos en orden;
|
|
51
|
+
reclamarla antes de empezar y empujar ese reclamo, que sin empujar no reserva nada.
|
|
37
52
|
3. Classify: si la tarea no declara lane y cast, decidirlos y escribirlos en su línea.
|
|
38
53
|
4. Ready: exigir aceptación concreta y decisiones resueltas.
|
|
39
54
|
5. Decompose: dividir trabajo mayor a `maxTaskHours` o con más de cinco condiciones de aceptación.
|
|
@@ -44,7 +59,8 @@ invariantes.
|
|
|
44
59
|
10. Verify: ejecutar los gates declarados por el servicio y registrar exit codes.
|
|
45
60
|
11. QA: probar la aceptación por el camino que usa un consumidor real.
|
|
46
61
|
12. Commit: stage explícito y commits verificables, uno por naturaleza del diff.
|
|
47
|
-
13. Done:
|
|
62
|
+
13. Done: sacar la tarea de la cola, escribir su evidencia en `done/<slug>.md`, limpiar WIP, soltar
|
|
63
|
+
el reclamo y cerrar la épica si no le queda ninguna historia abierta.
|
|
48
64
|
14. Cierre: check verde, deuda residual al INBOX y checkpoint entre hitos.
|
|
49
65
|
|
|
50
66
|
## Lanes
|
|
@@ -68,7 +84,8 @@ chequeo de permisos es `full`, y un componente entero de presentación puede ser
|
|
|
68
84
|
## Invariantes
|
|
69
85
|
|
|
70
86
|
1. Una tarea tiene un dueño de estado: roadmap → BACKLOG → overlay WIP → DONE.
|
|
71
|
-
2. Un
|
|
87
|
+
2. Un runner lleva una tarea a la vez —WIP, que es local: `business-rules/system/BR-OPS-001`— y una
|
|
88
|
+
tarea la lleva un runner —el reclamo, que es compartido: `business-rules/system/BR-OPS-005`—.
|
|
72
89
|
3. INBOX nunca se ejecuta automáticamente — `business-rules/system/BR-OPS-002`.
|
|
73
90
|
4. No declarar éxito sin comandos, resultados y exit codes reales — `business-rules/system/BR-OPS-004`.
|
|
74
91
|
5. No inventar credenciales ni decisiones; registrar HUMAN_ACTIONS.
|
|
@@ -7,8 +7,8 @@ Se lee y se escribe en cada tarea.
|
|
|
7
7
|
| Pieza | Responsabilidad |
|
|
8
8
|
|---|---|
|
|
9
9
|
| `BACKLOG.md` | Única cola de tareas promovidas y listas. |
|
|
10
|
-
| `
|
|
11
|
-
| `
|
|
10
|
+
| `wip/` | El plan en vuelo de cada runner; recuperación y mutex por runner. No viaja por git. |
|
|
11
|
+
| `claims/` | Qué tarea tomó cada quien; un archivo por tarea. |
|
|
12
12
|
| `HUMAN_ACTIONS.md` | Acciones externas que requieren una persona. |
|
|
13
13
|
| `AWAITING_REVIEW.md` | Gate efímero; mientras existe no inicia trabajo. |
|
|
14
14
|
|
|
@@ -19,6 +19,7 @@ Se decide antes de ejecutar y no cambia dentro de una tarea.
|
|
|
19
19
|
| Pieza | Responsabilidad |
|
|
20
20
|
|---|---|
|
|
21
21
|
| `INBOX.md` | Ideas y deuda sin autorización de ejecución. |
|
|
22
|
+
| `RECURRING.md` | Trabajo que vuelve cada tanto; declarado, nunca encolado solo. |
|
|
22
23
|
| `roadmap/` | Especificaciones de épicas y criterios del QUÉ. |
|
|
23
24
|
| `adr/` | Decisiones arquitectónicas durables. |
|
|
24
25
|
| `business-rules/` | Invariantes observables de negocio y operación. |
|
|
@@ -31,7 +32,7 @@ Evidencia que no se reescribe.
|
|
|
31
32
|
|
|
32
33
|
| Pieza | Responsabilidad |
|
|
33
34
|
|---|---|
|
|
34
|
-
| `done/` |
|
|
35
|
+
| `done/` | Evidencia de lo terminado: una tarea cerrada por archivo, más las acciones humanas resueltas. |
|
|
35
36
|
| `reports/` | Informes de recorridos de equipo. |
|
|
36
37
|
|
|
37
38
|
El protocolo exacto está en `PROTOCOL.md`, la explicación visual en `FLOW.md` y los principios que
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Trabajo que vuelve
|
|
2
|
+
|
|
3
|
+
Lo que hay que hacer cada tanto y no una vez: actualizar dependencias, revisar quién tiene acceso a
|
|
4
|
+
producción, mirar el gasto del mes, recorrer el INBOX entero. No es una categoría de trabajo —puede ser
|
|
5
|
+
cualquier cosa— sino una forma de declararlo: acá vive el enunciado, y cada vuelta se promueve a
|
|
6
|
+
`BACKLOG.md` como una tarea más.
|
|
7
|
+
|
|
8
|
+
**Nada se dispara.** Este archivo no ejecuta ni encola: declara cada cuánto algo debería mirarse, y el
|
|
9
|
+
vencimiento se calcula cuando alguien corre el CLI. Promover sigue siendo un acto humano, igual que en
|
|
10
|
+
`INBOX.md`. Lo que la máquina aporta es que no se te pase, no decidir por vos.
|
|
11
|
+
|
|
12
|
+
## Cada fila
|
|
13
|
+
|
|
14
|
+
- **Qué** — un identificador estable, en minúsculas y sin espacios. No cambia nunca: es lo que ata la
|
|
15
|
+
fila a las vueltas que ya se hicieron.
|
|
16
|
+
- **Cada** — vocabulario cerrado: `mensual`, `trimestral`, `semestral`, `anual`. No hay expresiones de
|
|
17
|
+
cron, y esa ausencia es el enunciado: si hiciera falta una, lo que estarías declarando es otra cosa.
|
|
18
|
+
Tampoco hay `semanal`, porque el slug de cada vuelta tiene grano de mes.
|
|
19
|
+
- **Desde** — `AAAA-MM-DD`. Ancla la primera vuelta y después no se toca.
|
|
20
|
+
- **Tarea y aceptación** — lo que se va a promover, con su aceptación observable escrita una sola vez y
|
|
21
|
+
con calma. Improvisada en cada vuelta, la misma recurrencia termina significando cosas distintas sin
|
|
22
|
+
que nadie lo decida.
|
|
23
|
+
|
|
24
|
+
## Cuándo vence
|
|
25
|
+
|
|
26
|
+
Se cuenta desde la última vez que se cerró, no desde un día fijo del calendario: una recurrencia
|
|
27
|
+
atrasada no debe tres vueltas, debe una, la que no se hizo.
|
|
28
|
+
|
|
29
|
+
La fecha de ese último cierre **no se escribe acá**. Sale de `done/` — la entrada más nueva cuyo slug
|
|
30
|
+
sea `<qué>-AAAA-MM`—, que es la evidencia de que efectivamente se hizo y no la afirmación de que se
|
|
31
|
+
hizo. Una celda que alguien tiene que acordarse de actualizar miente a los tres meses, y el estado no se
|
|
32
|
+
copia para representar progreso.
|
|
33
|
+
|
|
34
|
+
Por eso cada vuelta se promueve con su período en el slug —`deps-2026-10`, después `deps-2026-11`— y no
|
|
35
|
+
con el identificador pelado. Reusarlo tiene además su propio castigo: dos entradas de DONE con el mismo
|
|
36
|
+
slug son un error de `check`, y ese error llega un mes tarde.
|
|
37
|
+
|
|
38
|
+
## Lo que este archivo no es
|
|
39
|
+
|
|
40
|
+
- **No bloquea.** Una recurrencia vencida no frena ninguna tarea. Lo que sí frena vive en
|
|
41
|
+
`HUMAN_ACTIONS.md`; ponerlo acá entrena a ignorar lo que vence, que es lo único que este archivo hace.
|
|
42
|
+
- **No es una cola.** Nada de acá está aprobado para ejecutarse. `BACKLOG.md` sigue siendo la única cola
|
|
43
|
+
y se escribe a mano.
|
|
44
|
+
- **No es el INBOX.** Una idea se promueve una vez y se borra; esto vuelve, y por eso se queda.
|
|
45
|
+
|
|
46
|
+
## Recurrencias
|
|
47
|
+
|
|
48
|
+
| Qué | Cada | Desde | Tarea y aceptación observable |
|
|
49
|
+
|---|---|---|---|
|
|
50
|
+
|
|
51
|
+
<!--
|
|
52
|
+
| deps | mensual | 2026-09-01 | Actualizar dependencias. _Aceptación: `npm outdated` no deja una versión mayor sin decisión escrita y la puerta queda verde._ |
|
|
53
|
+
| accesos | trimestral | 2026-07-01 | Revisar quién tiene acceso a producción. _Aceptación: cada cuenta activa figura en `organization/`, y las demás están dadas de baja._ |
|
|
54
|
+
| costos | mensual | 2026-09-01 | Revisar el gasto de infraestructura del mes. _Aceptación: cada línea que subió más de 20% tiene una razón escrita._ |
|
|
55
|
+
| inbox | trimestral | 2026-08-01 | Recorrer el INBOX entero. _Aceptación: ninguna viñeta queda sin decisión de promover, dejar o borrar._ |
|
|
56
|
+
-->
|
|
57
|
+
|
|
58
|
+
## Postergaciones
|
|
59
|
+
|
|
60
|
+
Saltear una vuelta es legítimo y se escribe. Lo que no puede perderse es la razón: sin ella queda una
|
|
61
|
+
recurrencia atrasada y nadie sabe si fue una decisión o un olvido.
|
|
62
|
+
|
|
63
|
+
Postergar compra **un período**, no una fecha elegida: la vuelta siguiente vuelve a preguntar. Las
|
|
64
|
+
postergaciones se cuentan desde el último cierre y el contador se reinicia al cerrar. Tres seguidas no
|
|
65
|
+
son un atraso — son una recurrencia mal declarada, y lo que hay que revisar es la cadencia o la fila
|
|
66
|
+
entera.
|
|
67
|
+
|
|
68
|
+
La salida definitiva es borrar la fila. «Esto ya no lo hacemos» es un diff que alguien revisa; un estado
|
|
69
|
+
`retirada` es una línea que nadie vuelve a leer.
|
|
70
|
+
|
|
71
|
+
Cada una se escribe con el nombre de su fila en negrita, la fecha y la razón —`- **qué** AAAA-MM-DD —
|
|
72
|
+
razón`—, igual que un ítem del INBOX y por el mismo motivo: el nombre es con lo que se cita la fila.
|
|
73
|
+
Sólo se agrega al final; una línea escrita acá no se edita ni se borra.
|
|
74
|
+
|
|
75
|
+
<!--
|
|
76
|
+
- **deps** 2026-10-02 — Esperando el release de la 2.0; subir dependencias antes lo ensucia.
|
|
77
|
+
-->
|
|
@@ -13,8 +13,9 @@ en conversaciones, tickets y memoria del runner hace imposible saber qué está
|
|
|
13
13
|
## Decisión
|
|
14
14
|
|
|
15
15
|
**La instancia usa `planning/` como fuente de verdad operativa, legible y validable.** `INBOX.md` recibe ideas,
|
|
16
|
-
el roadmap define resultados, `BACKLOG.md` contiene trabajo promovido, `
|
|
17
|
-
`
|
|
16
|
+
el roadmap define resultados, `BACKLOG.md` contiene trabajo promovido, `wip/<runner>.md` conserva la ejecución de cada runner y
|
|
17
|
+
y `done/<slug>.md` registra la evidencia de cada tarea cerrada, un archivo por tarea. El protocolo
|
|
18
|
+
define las transiciones permitidas.
|
|
18
19
|
|
|
19
20
|
## Alternativas consideradas
|
|
20
21
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# Una sola tarea activa
|
|
2
2
|
|
|
3
|
-
> **Dominio:** planning | **Estado:** vigente | **Actualizado:** 2026-
|
|
3
|
+
> **Dominio:** planning | **Estado:** vigente | **Actualizado:** 2026-09-07
|
|
4
4
|
|
|
5
|
-
WIP protege la exclusión mutua y permite recuperar una ejecución interrumpida.
|
|
5
|
+
WIP protege la exclusión mutua dentro de un runner y permite recuperar una ejecución interrumpida.
|
|
6
|
+
Que dos runners no tomen la misma tarea es otra cosa, y la sostiene `BR-OPS-005-una-tarea-un-runner.md`.
|
|
6
7
|
[fuente: ../../adr/system/OPS-001-planificacion-como-fuente-de-verdad.md]
|
|
7
8
|
|
|
8
9
|
Elabora el invariante 2 de `../../PROTOCOL.md`, que lo enuncia en una línea: acá viven sus bordes
|
|
@@ -12,7 +13,7 @@ y su evidencia. Cambiar una sin la otra las separa.
|
|
|
12
13
|
|
|
13
14
|
| ID | Regla | Condición y resultado |
|
|
14
15
|
|---|---|---|
|
|
15
|
-
| BR-OPS-001 | WIP es mutex | Si WIP está activo,
|
|
16
|
+
| BR-OPS-001 | WIP es mutex | Si WIP está activo, ese runner no toma otra tarea hasta continuarlo o resolverlo. |
|
|
16
17
|
|
|
17
18
|
## Por qué existe cada regla
|
|
18
19
|
|
|
@@ -24,7 +25,8 @@ y su evidencia. Cambiar una sin la otra las separa.
|
|
|
24
25
|
|---|---|
|
|
25
26
|
| Sesión interrumpida | Se verifican pasos persistidos y se continúa la misma tarea. |
|
|
26
27
|
| Tarea ya cerrada | Se repara el cierre y WIP vuelve a `IDLE`; no se ejecuta otra vez. |
|
|
27
|
-
|
|
|
28
|
+
| WIP ausente | Se lee como IDLE. El archivo es local y un clon nuevo no lo trae; eso no es un error. |
|
|
29
|
+
| Tarea de otro runner | No la ve: el WIP ajeno no viaja. Lo que la reserva es su reclamo (BR-OPS-005). |
|
|
28
30
|
|
|
29
31
|
## Evidencia
|
|
30
32
|
|
|
@@ -36,3 +38,4 @@ y su evidencia. Cambiar una sin la otra las separa.
|
|
|
36
38
|
| Fecha | Cambio | Origen |
|
|
37
39
|
|---|---|---|
|
|
38
40
|
| 2026-08-14 | Creación | OPS-001 y `PROTOCOL.md`. |
|
|
41
|
+
| 2026-09-07 | El mutex se acota al runner; el WIP pasa a ser local | Trabajo en equipo: `../../delivery/teamwork.md`. |
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Una tarea, un runner
|
|
2
|
+
|
|
3
|
+
> **Dominio:** planning | **Estado:** vigente | **Actualizado:** 2026-09-07
|
|
4
|
+
|
|
5
|
+
El reclamo protege la exclusión mutua entre runners y hace visible quién sostiene cada tarea.
|
|
6
|
+
[fuente: ../../adr/system/OPS-001-planificacion-como-fuente-de-verdad.md]
|
|
7
|
+
|
|
8
|
+
Es la contracara de `BR-OPS-001-una-sola-tarea-activa.md`, y las dos juntas son el invariante 2 de
|
|
9
|
+
`../../PROTOCOL.md`. Se parecen y no son la misma: aquélla impide que un runner lleve dos tareas y vive
|
|
10
|
+
en su `wip/<runner>.md`, que es local; ésta impide que dos runners lleven la misma y vive en `claims/`, que es
|
|
11
|
+
compartido. Con una sola, un equipo trabaja una tarea por vez o duplica trabajo sin enterarse.
|
|
12
|
+
|
|
13
|
+
## Reglas
|
|
14
|
+
|
|
15
|
+
| ID | Regla | Condición y resultado |
|
|
16
|
+
|---|---|---|
|
|
17
|
+
| BR-OPS-005 | El reclamo reserva | Una tarea reclamada no se ofrece a otro runner ni se toma hasta que su reclamo se suelte. |
|
|
18
|
+
|
|
19
|
+
## Por qué existe cada regla
|
|
20
|
+
|
|
21
|
+
- **BR-OPS-005:** sin reserva, dos runners que preguntan a la vez reciben la misma tarea y ninguno lo
|
|
22
|
+
nota: el trabajo se duplica y el conflicto aparece recién al mergear, cuando ya se pagó dos veces.
|
|
23
|
+
|
|
24
|
+
## Casos borde
|
|
25
|
+
|
|
26
|
+
| Caso | Comportamiento esperado |
|
|
27
|
+
|---|---|
|
|
28
|
+
| Reclamo propio | Se continúa esa tarea; es lo que el runner declaró que iba a hacer. |
|
|
29
|
+
| Reclamo de otro | La tarea no se ofrece; se toma la siguiente libre. |
|
|
30
|
+
| Reclamo sin empujar | No protege a nadie: el otro runner lee lo que hay en su copia. |
|
|
31
|
+
| Reclamo abandonado | Se avisa por antigüedad; soltarlo es un acto humano, no un comando. |
|
|
32
|
+
| Tarea ya en DONE | El reclamo sobra y se avisa; la evidencia no depende de él. |
|
|
33
|
+
|
|
34
|
+
## Evidencia
|
|
35
|
+
|
|
36
|
+
- `ops context` no devuelve una tarea con reclamo ajeno y nombra quién la tiene.
|
|
37
|
+
- `ops check` rechaza un reclamo cuya tarea no existe en BACKLOG ni DONE.
|
|
38
|
+
- `ops claim` se niega a pisar el reclamo de otro.
|
|
39
|
+
|
|
40
|
+
## Historial
|
|
41
|
+
|
|
42
|
+
| Fecha | Cambio | Origen |
|
|
43
|
+
|---|---|---|
|
|
44
|
+
| 2026-09-07 | Creación | Trabajo en equipo: `../../delivery/teamwork.md`. |
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Reclamos
|
|
2
|
+
|
|
3
|
+
Un archivo por tarea tomada, con el slug de la tarea como nombre: `dashboard-filtros.md` dice que esa
|
|
4
|
+
tarea la está haciendo alguien. Crearlo es tomarla; borrarlo es soltarla.
|
|
5
|
+
|
|
6
|
+
```bash
|
|
7
|
+
node tools/ops.js claim planning dashboard-filtros
|
|
8
|
+
node tools/ops.js release planning dashboard-filtros
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Los dos escriben acá y sólo acá. `BACKLOG.md` no lo toca ningún comando del motor: la cola es de lo
|
|
12
|
+
aprobado y la escribe una persona.
|
|
13
|
+
|
|
14
|
+
## Por qué un archivo por tarea y no uno por persona
|
|
15
|
+
|
|
16
|
+
Dos personas en tareas distintas no tocan nunca el mismo archivo, así que tomar trabajo no produce
|
|
17
|
+
conflictos. Y dos que toman la misma sí chocan, en git, al mergear — que es exactamente donde el choque
|
|
18
|
+
significa algo y donde alguien lo va a ver.
|
|
19
|
+
|
|
20
|
+
Un archivo por persona invierte las dos propiedades: dos agentes de la misma persona pelean por su
|
|
21
|
+
archivo, y dos personas que tomaron lo mismo no chocan hasta que alguien lo nota a mano.
|
|
22
|
+
|
|
23
|
+
## Quién es «yo»: el runner, no la persona
|
|
24
|
+
|
|
25
|
+
El archivo declara dos cosas distintas. `owner` es la persona —a quién preguntarle— y sale de
|
|
26
|
+
`git config user.email`. `runner` es **el agente que la está haciendo**, y es lo que decide si una tarea
|
|
27
|
+
es tuya.
|
|
28
|
+
|
|
29
|
+
La diferencia sólo se nota con varios agentes en la misma máquina, y ahí es decisiva: dos sesiones tuyas
|
|
30
|
+
resuelven el mismo email, así que si lo que decidiera «esto es mío» fuera la persona, el segundo agente
|
|
31
|
+
tomaría por propia la tarea del primero y los dos construirían lo mismo sin que nada fallara.
|
|
32
|
+
|
|
33
|
+
Cada agente exporta el suyo:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
export CAUCE_RUNNER=/ruta/de/su/arbol-de-trabajo
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Sin la variable se deduce del árbol donde corre el proceso, lo que acierta si el agente invoca desde el
|
|
40
|
+
suyo y devuelve el mismo id para todos si invocan desde una instancia compartida. Eso **no queda en
|
|
41
|
+
silencio**: un runner lleva una tarea a la vez, así que el segundo reclamo choca y el mensaje dice qué
|
|
42
|
+
poner. `ops worktree` la imprime hecha.
|
|
43
|
+
|
|
44
|
+
## Qué no va acá
|
|
45
|
+
|
|
46
|
+
El plan, los pasos tildados y las decisiones en curso viven en `wip/<runner>.md`, que es local y no viaja por
|
|
47
|
+
git: cambian en cada paso y no le sirven a nadie más. Acá va lo poco que el equipo necesita —qué está
|
|
48
|
+
tomado y por quién—, que cambia dos veces por tarea.
|
|
49
|
+
|
|
50
|
+
Son también dos exclusiones distintas: el reclamo evita que dos runners tomen la misma tarea, y el WIP
|
|
51
|
+
evita que un runner lleve dos.
|
|
52
|
+
|
|
53
|
+
## Un reclamo sin empujar no protege
|
|
54
|
+
|
|
55
|
+
El otro runner lee lo que hay en su copia. Tomar una tarea y no commitear el archivo se ve igual que no
|
|
56
|
+
haberla tomado, y por eso `ops claim` lo recuerda al terminar.
|
|
57
|
+
|
|
58
|
+
## Cuando alguien se va
|
|
59
|
+
|
|
60
|
+
Un reclamo abandonado bloquea su tarea para siempre. `ops check` avisa a los tres días **sin señales de
|
|
61
|
+
avance**, que no es lo mismo que tres días desde que se tomó: lo que mira es si la rama `task/<tarea>`
|
|
62
|
+
tiene commits **propios**, los que no están en el tronco. Una rama recién creada hereda la historia
|
|
63
|
+
entera, así que sin esa distinción toda rama parecería haber avanzado el día que se creó. Una tarea larga que sigue recibiendo commits no se apura nunca; una que se detuvo se ve aunque el
|
|
64
|
+
reclamo sea de anteayer.
|
|
65
|
+
|
|
66
|
+
Sin repositorio resoluble —el `service:` no cae en ninguna raíz declarada, o el proyecto nombra sus ramas
|
|
67
|
+
de otra forma— el aviso vuelve a mirar sólo la fecha. Degrada a lo que había antes, no rompe.
|
|
68
|
+
|
|
69
|
+
Soltarlo es borrar el archivo a mano, y `ops release` se niega a hacerlo por vos: liberar el trabajo de
|
|
70
|
+
otro es una decisión, no un comando.
|
|
@@ -12,6 +12,7 @@ declara en `project.md` qué partes existen, cuáles aplican y qué deuda separa
|
|
|
12
12
|
| `environments.md` | Pregunta, datos y ciclo de vida de cada ambiente. | Sistemas desplegables. |
|
|
13
13
|
| `flags.md` | Release toggles temporales. | Productos con activación gradual. |
|
|
14
14
|
| `multi-repo.md` | Versionado y compatibilidad entre repos. | Solo workspaces multi-repo. |
|
|
15
|
+
| `teamwork.md` | Qué comparte el equipo, qué no, y cómo crece. | Más de una persona o más de un agente. |
|
|
15
16
|
| `project.md` | Estado real, decisiones adoptadas y evolución. | Obligatorio personalizar. |
|
|
16
17
|
|
|
17
18
|
Un proyecto puede adoptar una parte sin fingir que adoptó las demás. Una desviación durable se documenta en
|
|
@@ -19,6 +19,17 @@ manifiesto es evidencia del pipeline, no una lista que una persona edita manualm
|
|
|
19
19
|
- Bases de datos y APIs aplican expand/contract durante la ventana de convivencia.
|
|
20
20
|
- Una entrega cross-repo registra qué PR y versión satisface cada lado del contrato.
|
|
21
21
|
|
|
22
|
+
## El `service:` de una tarea tiene que resolver a un solo repositorio
|
|
23
|
+
|
|
24
|
+
Con varias raíces declaradas, un `service:` que existe en más de una es ambiguo: `.` existe en todas, y un
|
|
25
|
+
`src` puede existir en dos. `ops worktree` lo nombra y se niega en vez de elegir la primera, porque elegir
|
|
26
|
+
da una respuesta plausible y equivocada —el árbol de trabajo en el repositorio que no era— sin que nada lo
|
|
27
|
+
diga. El aviso de avance de un reclamo degrada por lo mismo: sin poder resolver el repositorio, mira sólo
|
|
28
|
+
la fecha en que se tomó.
|
|
29
|
+
|
|
30
|
+
La salida es escribir servicios que sólo existan en una raíz. Si dos repositorios tienen un directorio con
|
|
31
|
+
el mismo nombre y los dos son servicios de verdad, conviene una instancia por repositorio.
|
|
32
|
+
|
|
22
33
|
## Cuándo coordinar
|
|
23
34
|
|
|
24
35
|
Coordinar solo cuando una propiedad no puede preservarse mediante compatibilidad temporal, por ejemplo una
|