@ingeniomaps/cauce 0.37.0 → 0.39.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 CHANGED
@@ -14,6 +14,40 @@ desde este repositorio no va, porque el que lee no puede actuar sobre eso. Cuand
14
14
  unas pocas líneas casi siempre es porque cuenta cómo se descubrió el problema o por qué se eligió el
15
15
  diseño — eso vive en el commit y en el código.
16
16
 
17
+ ## [0.39.0] - 2026-08-19
18
+
19
+ ### Corregido
20
+
21
+ - **`check` nombra las credenciales que nadie se llevó.** El arranque tiene que dejar una fila por cada
22
+ variable que el proyecto declara, y en cuatro corridas reales se cumplió en proporción a lo que se
23
+ habló: las que sólo estaban en el inventario quedaron afuera —entre ellas el broker por donde entran
24
+ los datos y el servicio al que se le mandan errores—. Ahora `check` nombra las que no aparecen ni en el
25
+ mapa ni en `HUMAN_ACTIONS.md`. Mira sólo cuando la instancia ya tiene contexto escrito, porque antes no
26
+ hay dónde tendrían que estar, y avisa en vez de fallar: una variable sin dueño no rompe nada hoy, rompe
27
+ el día que alguien tiene que desplegar.
28
+
29
+ ## [0.38.0] - 2026-08-19
30
+
31
+ ### Añadido
32
+
33
+ - **Gemini recibe `onboard` y `team`, que sólo tenía como prosa.** Estaban descritos en `GEMINI.md` y no
34
+ existía ningún comando detrás, así que quien venía de otro runner los buscaba en la lista y no
35
+ aparecían.
36
+
37
+ - **`automation install` termina diciendo cómo se invoca lo que acaba de instalar.** Una línea con los
38
+ nombres exactos para ese runner, que es lo que evita buscar en una lista de cincuenta skills el nombre
39
+ que se usó en otro lado.
40
+
41
+ ### Cambiado
42
+
43
+ - **Una convención para el nombre de cada recorrido.** El nombre es el mismo en todos los runners
44
+ —`onboard`, `team`, `autobuild`, `integration-sync`, `integration-promote`—; el prefijo lo pone cada
45
+ uno según su espacio de nombres: `/onboard` en Claude, `/cauce:onboard` en Gemini, `cauce:onboard` en
46
+ Antigravity. Codex no tiene comandos y opera el protocolo desde sus instrucciones.
47
+
48
+ Los comandos de Gemini se mudaron de `/ops:` a `/cauce:`. Si actualizás una instalación anterior,
49
+ `.gemini/commands/ops/` queda huérfano: se borra a mano, `install` no toca lo que ya no declara.
50
+
17
51
  ## [0.37.0] - 2026-08-19
18
52
 
19
53
  ### Cambiado
package/README.md CHANGED
@@ -139,8 +139,20 @@ no puede hacer, así que ese recorrido vive en el runner:
139
139
  /autobuild ejecuta una tarea ya promovida, fase por fase.
140
140
  ```
141
141
 
142
- Claude y Antigravity lo traen como recorrido ejecutable; Codex y Gemini lo operan siguiendo las
143
- instrucciones que `automation install` les deja. Sin runner, la [tabla de comandos](#comandos) y
142
+ ### Cómo se lo llama en cada runner
143
+
144
+ El nombre del recorrido es el mismo en todos —`onboard`, `team`, `autobuild`, `integration-sync`,
145
+ `integration-promote`—; el prefijo lo pone cada runner según su espacio de nombres:
146
+
147
+ | Runner | Se invoca | |
148
+ |---|---|---|
149
+ | Claude | `/onboard` | workflow ejecutable |
150
+ | Gemini | `/cauce:onboard` | comando |
151
+ | Antigravity | `cauce:onboard` | skill |
152
+ | Codex | — | opera el protocolo desde sus instrucciones |
153
+
154
+ `automation install` termina diciendo la lista exacta para el runner que instalaste, que es lo que
155
+ evita buscar en Gemini el nombre que se usó en Claude. Sin runner, la [tabla de comandos](#comandos) y
144
156
  [FLOW.md](template/planning/FLOW.md) hacen el mismo camino a mano.
145
157
 
146
158
  Dentro del proyecto el CLI se invoca con `node tools/ops.js` —o `npx cauce`, que la dependencia deja
@@ -60,5 +60,15 @@
60
60
  "list"
61
61
  ],
62
62
  "expect": "cauce"
63
+ },
64
+ "commands": {
65
+ "invocation": "cauce:{name}",
66
+ "names": [
67
+ "onboard",
68
+ "team",
69
+ "autobuild",
70
+ "integration-sync",
71
+ "integration-promote"
72
+ ]
63
73
  }
64
74
  }
@@ -53,5 +53,15 @@
53
53
  "checkpointing": false,
54
54
  "nativeSkills": true
55
55
  },
56
- "roleSkills": ".claude/skills"
56
+ "roleSkills": ".claude/skills",
57
+ "commands": {
58
+ "invocation": "/{name}",
59
+ "names": [
60
+ "onboard",
61
+ "team",
62
+ "autobuild",
63
+ "integration-sync",
64
+ "integration-promote"
65
+ ]
66
+ }
57
67
  }
@@ -19,5 +19,9 @@
19
19
  "projectInstructions": true,
20
20
  "checkpointing": false,
21
21
  "nativeSkills": false
22
+ },
23
+ "commands": {
24
+ "invocation": "",
25
+ "names": []
22
26
  }
23
27
  }
@@ -9,8 +9,12 @@ Adaptador mediante configuración de proyecto, `GEMINI.md`, checkpointing y coma
9
9
  node tools/ops.js automation install . gemini
10
10
  ```
11
11
 
12
- Instala `.gemini/settings.json`, el contexto raíz `GEMINI.md` y los comandos `/ops:autobuild`,
13
- `/ops:integration-sync` y `/ops:integration-promote`.
12
+ Instala `.gemini/settings.json`, el contexto raíz `GEMINI.md` y los comandos `/cauce:onboard`,
13
+ `/cauce:team`, `/cauce:autobuild`, `/cauce:integration-sync` y `/cauce:integration-promote`.
14
+
15
+ Antes vivían bajo `/ops:` y eran tres: el arranque y el recorrido de equipo le llegaban sólo como prosa,
16
+ así que alguien que venía de otro runner los buscaba en la lista y no estaban. Si actualizás una
17
+ instalación vieja, `.gemini/commands/ops/` queda huérfano y se borra a mano.
14
18
 
15
19
  Gemini no anuncia hooks nativos en este adaptador: los guards se ejecutan como prechecks indicados por el
16
20
  protocolo y los comandos. Esta degradación está declarada en `manifest.json`, no se simula protección inexistente.
@@ -0,0 +1,21 @@
1
+ description = "Arranca una instancia recién creada: pregunta, escribe el contexto y la primera épica"
2
+ prompt = """
3
+ Seguí la sección «El arranque» de {{OPS_DIR}}AGENTS.md y de este contexto raíz.
4
+
5
+ Empezá por `node {{OPS_DIR}}tools/ops.js onboard`: es instantáneo, y la primera línea que imprime es la
6
+ pregunta con la que tenés que abrir. Hacésela tal cual y esperá la respuesta antes de mirar el
7
+ inventario, sea el workspace vacío, un monolito o diez repos. Según lo que conteste, hasta tres
8
+ preguntas más con las palabras de ese proyecto, una por vez. El inventario ya viene resuelto en esa
9
+ salida —servicios, comandos declarados y las variables que cada uno espera—: no recorras el árbol ni
10
+ corras comandos del proyecto para completarlo.
11
+
12
+ Con eso escribí {{OPS_DIR}}organization/, la sección «Mapa real» de {{OPS_DIR}}AGENTS.md con cada
13
+ comando tal como está declarado y de qué archivo salió, y las raíces reales en workspaceRoots. Las
14
+ credenciales, los sistemas externos y el permiso de push van como filas de
15
+ {{OPS_DIR}}planning/HUMAN_ACTIONS.md, sin proponer ningún valor. Una dimensión que no llegaste a
16
+ preguntar queda «Por definir» con su pregunta en {{OPS_DIR}}planning/INBOX.md, y lo que deducís de otra
17
+ respuesta va marcado «(supuesto)».
18
+
19
+ Cerrá escribiendo la épica como epic-NNN-<slug>.md con status: open —sin slug no la lee nadie— y corré
20
+ `node {{OPS_DIR}}tools/ops.js check planning`. Nunca promuevas al BACKLOG: esa firma es humana.
21
+ """
@@ -0,0 +1,15 @@
1
+ description = "Recorre un equipo y propone una épica candidata, sin promoverla"
2
+ prompt = """
3
+ Obtené el recorrido con `node {{OPS_DIR}}tools/ops.js team show <slug> --json` y ejecutá una etapa a la
4
+ vez, adoptando en cada una el contrato del cargo que la posee. Respetá el dueño de decisión de cada
5
+ dominio: ningún otro cargo resuelve en su lugar.
6
+
7
+ Marcá el exit gate de una etapa como cumplido sólo si se cumple de verdad. Cuando falte evidencia,
8
+ autoridad o una decisión externa, registrá la acción concreta en {{OPS_DIR}}planning/HUMAN_ACTIONS.md y
9
+ detente: una opinión del modelo no es investigación de usuarios ni valida un problema.
10
+
11
+ Si la intención resulta viable, escribí la épica en {{OPS_DIR}}planning/roadmap/ como
12
+ epic-NNN-<slug>.md con criterios observables y cerrá con `node {{OPS_DIR}}tools/ops.js check planning`.
13
+ Si no lo es, registrá en {{OPS_DIR}}planning/INBOX.md por qué y qué la haría viable. **Nunca promuevas
14
+ al BACKLOG**: esa firma es humana.
15
+ """
@@ -18,16 +18,24 @@
18
18
  ],
19
19
  "artifacts": [
20
20
  {
21
- "source": "commands/ops/autobuild.toml",
22
- "target": ".gemini/commands/ops/autobuild.toml"
21
+ "source": "commands/cauce/autobuild.toml",
22
+ "target": ".gemini/commands/cauce/autobuild.toml"
23
23
  },
24
24
  {
25
- "source": "commands/ops/integration-sync.toml",
26
- "target": ".gemini/commands/ops/integration-sync.toml"
25
+ "source": "commands/cauce/integration-sync.toml",
26
+ "target": ".gemini/commands/cauce/integration-sync.toml"
27
27
  },
28
28
  {
29
- "source": "commands/ops/integration-promote.toml",
30
- "target": ".gemini/commands/ops/integration-promote.toml"
29
+ "source": "commands/cauce/integration-promote.toml",
30
+ "target": ".gemini/commands/cauce/integration-promote.toml"
31
+ },
32
+ {
33
+ "source": "commands/cauce/onboard.toml",
34
+ "target": ".gemini/commands/cauce/onboard.toml"
35
+ },
36
+ {
37
+ "source": "commands/cauce/team.toml",
38
+ "target": ".gemini/commands/cauce/team.toml"
31
39
  }
32
40
  ],
33
41
  "capabilities": {
@@ -37,5 +45,15 @@
37
45
  "checkpointing": true,
38
46
  "nativeSkills": true
39
47
  },
40
- "roleSkills": ".gemini/skills"
48
+ "roleSkills": ".gemini/skills",
49
+ "commands": {
50
+ "invocation": "/cauce:{name}",
51
+ "names": [
52
+ "onboard",
53
+ "team",
54
+ "autobuild",
55
+ "integration-sync",
56
+ "integration-promote"
57
+ ]
58
+ }
41
59
  }
@@ -694,6 +694,15 @@ function install(root, name, output = console, options = {}) {
694
694
  }
695
695
  }
696
696
  installRoleSkills(root, runner, output)
697
+ // Cómo se lo llama acá. El nombre del recorrido es el mismo en todos los runners —`onboard`, `team`,
698
+ // `autobuild`—; el prefijo lo pone cada uno según su espacio de nombres, y esa diferencia es la que
699
+ // hace que alguien no encuentre en Gemini lo que usó en Claude. Decirlo al instalar cuesta una línea
700
+ // y ahorra buscarlo en una lista de cincuenta skills.
701
+ const invocacion = runner.commands && runner.commands.invocation
702
+ if (invocacion && (runner.commands.names || []).length) {
703
+ const lista = runner.commands.names.map((nombre) => invocacion.replace('{name}', nombre))
704
+ output.log(` ${name}: se invocan como ${lista.join(', ')}`)
705
+ }
697
706
  if (runner.activation && activated(runner) !== true) {
698
707
  output.log(` ${name}: falta registrarlo para que corra. Desde ${paths.install}:`)
699
708
  output.log(` ${runner.activation.hint}`)
package/engine/cli/ops.js CHANGED
@@ -465,6 +465,31 @@ function seccionesPerdidas(root) {
465
465
  return avisos
466
466
  }
467
467
 
468
+ // Credenciales que el proyecto declara y que no aparecen en ningún contrato. El arranque tiene que
469
+ // dejar una fila por cada una —quién la carga y dónde— y en la práctica cubre las que se hablaron en la
470
+ // conversación: las que sólo estaban en el inventario se pierden, y con ellas el servicio externo que
471
+ // hay detrás. Una variable sin dueño no rompe nada hoy; rompe el día que alguien tiene que desplegar.
472
+ //
473
+ // Sólo cuando la instancia ya tiene contexto escrito: antes del arranque no hay dónde estuvieran.
474
+ function credencialesSinDueño(root) {
475
+ if (OB.guide(root).fresh) return []
476
+ const contratos = ['AGENTS.md', path.join('planning', 'HUMAN_ACTIONS.md')]
477
+ .map((file) => { try { return fs.readFileSync(path.join(root, file), 'utf8') } catch { return '' } })
478
+ .join('\n')
479
+ if (!contratos) return []
480
+ const huerfanas = []
481
+ for (const service of inventory(root)) {
482
+ for (const nombre of (service.env || {}).names || []) {
483
+ if (!contratos.includes(nombre)) huerfanas.push(`${nombre} (${service.path})`)
484
+ }
485
+ }
486
+ if (!huerfanas.length) return []
487
+ const lista = huerfanas.length > 4
488
+ ? `${huerfanas.slice(0, 4).join(', ')} y ${huerfanas.length - 4} más`
489
+ : huerfanas.join(', ')
490
+ return [`el proyecto declara ${lista} y no aparecen en el mapa ni en HUMAN_ACTIONS: nadie las carga`]
491
+ }
492
+
468
493
  function check(dir, cli) {
469
494
  const root = path.resolve(dir || '.')
470
495
  const errors = []
@@ -578,6 +603,7 @@ function check(dir, cli) {
578
603
  for (const entry of FK.drift(path.resolve(root, '..'))) warnings.push(FK.driftLine(entry))
579
604
 
580
605
  warnings.push(...seccionesPerdidas(path.resolve(root, '..')))
606
+ warnings.push(...credencialesSinDueño(path.resolve(root, '..')))
581
607
 
582
608
  if (cli.has('--json')) {
583
609
  console.log(JSON.stringify({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ingeniomaps/cauce",
3
- "version": "0.37.0",
3
+ "version": "0.39.0",
4
4
  "description": "Sistema portable de planificación y ejecución verificable para cualquier proyecto",
5
5
  "keywords": [
6
6
  "planning",