@ingeniomaps/cauce 0.6.1 → 0.7.1

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
@@ -8,6 +8,29 @@ esa operación sea confiable en vez de sólo cómoda: acá se lee qué cambió a
8
8
  un cambio en el protocolo, en las reglas del sistema o en un guard es visible para el usuario y sube
9
9
  minor aunque no toque una sola línea de código.
10
10
 
11
+ ## [0.7.1] - 2026-08-15
12
+
13
+ ### Corregido
14
+
15
+ - **Los cuatro workflows reventaban en su primera línea y nunca habían corrido.** Resolvían su raíz
16
+ con `process.env`, y el runtime de workflows es un sandbox que no expone `process`: `ReferenceError`
17
+ antes de ejecutar nada. `/team` y `/autobuild` —el centro del producto— estaban muertos, y los tests
18
+ no lo veían porque leían los archivos como texto en vez de ejecutarlos.
19
+
20
+ La raíz ahora viaja escrita en el archivo, que es lo que `automation install` ya sabía completar, y
21
+ es relativa a donde se abre la herramienta.
22
+ - **Y al arreglar eso, `team` y `autobuild` morían en la línea de cierre**: llamaban a un `finish()`
23
+ que el runtime tampoco trae. Peor que el anterior, porque ocurría *después* de gastar cada etapa.
24
+ - Dos tests recorren los workflows: uno prohíbe lo que el sandbox no expone, otro falla si se llama a
25
+ algo que ni el runtime da ni el archivo define.
26
+
27
+ ### Cambiado
28
+
29
+ - Los workflows de integración se invocan con argumentos en vez de variables de entorno, que tampoco
30
+ existen ahí: `/integration-sync jira` y `/integration-promote jira KEY-123`.
31
+ - Un test comprueba que ningún workflow use `process`, `require`, `Date.now` ni `Math.random`. El
32
+ sandbox los prohíbe, y usarlos no falla en una rama rara: impide que el archivo arranque.
33
+
11
34
  ## [0.6.1] - 2026-08-15
12
35
 
13
36
  ### Corregido
@@ -28,8 +28,8 @@ para revisión humana. `integrations/promote.js` exige proveedor, clave y un dra
28
28
  el sistema remoto; Jira es actualmente el primer adaptador del contrato general.
29
29
 
30
30
  ```bash
31
- OPS_INTEGRATION_PROVIDER=jira /integration-sync
32
- OPS_INTEGRATION_PROVIDER=jira OPS_INTEGRATION_KEY=KEY-123 /integration-promote
31
+ /integration-sync jira
32
+ /integration-promote jira KEY-123
33
33
  ```
34
34
 
35
35
  ## Aprendizaje de agentes
@@ -10,10 +10,10 @@ export const meta = {
10
10
  ].map((title) => ({ title, detail: `Fase ${title} del protocolo agnóstico` })),
11
11
  }
12
12
 
13
- // El prefijo lo completa `automation install`: en modo sidecar la herramienta se abre en la carpeta
14
- // de la compañía y la raíz ops es uno de sus hijos, no la carpeta misma.
15
- const ROOT = (process.env.OPS_ROOT
16
- || `${process.env.CLAUDE_PROJECT_DIR || '.'}/{{OPS_DIR}}`).replace(/\/+$/, '')
13
+ // El prefijo lo completa `automation install`. No puede venir del entorno: el runtime de workflows no
14
+ // expone `process`, así que leerlo de ahí reventaba el archivo entero en su primera línea. Viaja
15
+ // escrito, relativo a la carpeta donde se abre la herramienta, que es el cwd de los agentes.
16
+ const ROOT = '{{OPS_DIR}}'.replace(/\/+$/, '') || '.'
17
17
  const CONFIG = `${ROOT}/ops.config.json`
18
18
  const P = `${ROOT}/planning`
19
19
  const BACKLOG = `${P}/BACKLOG.md`
@@ -124,6 +124,14 @@ const CONTRACT = {
124
124
  const BASE = `Never invent credentials or decisions; register external blockers in ${HUMAN}. Never execute INBOX ` +
125
125
  `automatically. Never push, deploy, amend, force, or use git add -A. Never edit process governance, and do not ` +
126
126
  `edit planning bookkeeping unless this workflow explicitly requests it.`
127
+ // Cierre del recorrido. El runtime no trae un helper de cierre —el valor devuelto por el script ya
128
+ // es el resultado—, y darlo por sentado hacía reventar el archivo justo al terminar: después de
129
+ // gastar cada etapa, en la línea que las cerraba.
130
+ function finish(result) {
131
+ log(`Fin: ${JSON.stringify(result)}`)
132
+ return result
133
+ }
134
+
127
135
  const stop = (reason, detail = '') => {
128
136
  log(`Checkpoint: ${reason}${detail ? ` — ${detail}` : ''}`)
129
137
  return finish({ stopped: true, reason, detail })
@@ -9,6 +9,6 @@ remoto → sync → staging → revisión humana → promote → planning
9
9
  - `sync.js`: valida y refresca staging sin promover ni escribir remoto.
10
10
  - `promote.js`: materializa localmente un candidato cuyo draft está `ready`.
11
11
 
12
- El proveedor se selecciona con `OPS_INTEGRATION_PROVIDER`; `promote` requiere además
13
- `OPS_INTEGRATION_KEY`. La implementación particular de Jira vive en `engine/integrations/providers/jira.js`,
12
+ El proveedor se pasa como argumento —`/integration-sync jira`—; `promote` requiere además la clave
13
+ remota: `/integration-promote jira KEY-123`. La implementación particular de Jira vive en `engine/integrations/providers/jira.js`,
14
14
  no en estos workflows.
@@ -10,12 +10,15 @@ export const meta = {
10
10
  ],
11
11
  }
12
12
 
13
- // El prefijo lo completa `automation install`: en modo sidecar la herramienta se abre en la carpeta
14
- // de la compañía y la raíz ops es uno de sus hijos, no la carpeta misma.
15
- const ROOT = (process.env.OPS_ROOT
16
- || `${process.env.CLAUDE_PROJECT_DIR || '.'}/{{OPS_DIR}}`).replace(/\/+$/, '')
17
- const PROVIDER = process.env.OPS_INTEGRATION_PROVIDER || ''
18
- const KEY = process.env.OPS_INTEGRATION_KEY || ''
13
+ // El prefijo lo completa `automation install`. No puede venir del entorno: el runtime de workflows no
14
+ // expone `process`, así que leerlo de ahí reventaba el archivo entero en su primera línea. Viaja
15
+ // escrito, relativo a la carpeta donde se abre la herramienta, que es el cwd de los agentes.
16
+ const ROOT = '{{OPS_DIR}}'.replace(/\/+$/, '') || '.'
17
+ // `/integration-promote jira KEY-123` o `{"provider": "jira", "key": "KEY-123"}`.
18
+ const parts = typeof args === 'string' ? args.trim().split(/\s+/) : []
19
+ const input = typeof args === 'string' ? { provider: parts[0], key: parts[1] } : (args || {})
20
+ const PROVIDER = String(input.provider || '').trim()
21
+ const KEY = String(input.key || '').trim()
19
22
  const RESULT = {
20
23
  type: 'object', additionalProperties: false, required: ['passed', 'provider', 'key', 'details'],
21
24
  properties: { passed: { type: 'boolean' }, provider: { type: 'string' }, key: { type: 'string' }, details: { type: 'string' }, kind: { type: 'string' } },
@@ -24,7 +27,7 @@ const RESULT = {
24
27
  phase('Preflight')
25
28
  const result = await agent(
26
29
  `Read ${ROOT}/integrations/README.md, integrations config, the provider contract and planning/PROTOCOL.md. ` +
27
- `Require OPS_INTEGRATION_PROVIDER=${JSON.stringify(PROVIDER)} and OPS_INTEGRATION_KEY=${JSON.stringify(KEY)}. ` +
30
+ `The provider is ${JSON.stringify(PROVIDER)} and the remote key ${JSON.stringify(KEY)}; both are required. ` +
28
31
  `Run integration check. Inspect only that candidate's draft and snapshot; stop unless draft state is ready and ` +
29
32
  `acceptance, hierarchy and service mapping are concrete. Never call or write the remote provider.\n\n` +
30
33
  `If valid, enter Promote and run "node tools/ops.js integration promote ${ROOT} ${PROVIDER} ${KEY}" exactly once. ` +
@@ -10,11 +10,13 @@ export const meta = {
10
10
  ],
11
11
  }
12
12
 
13
- // El prefijo lo completa `automation install`: en modo sidecar la herramienta se abre en la carpeta
14
- // de la compañía y la raíz ops es uno de sus hijos, no la carpeta misma.
15
- const ROOT = (process.env.OPS_ROOT
16
- || `${process.env.CLAUDE_PROJECT_DIR || '.'}/{{OPS_DIR}}`).replace(/\/+$/, '')
17
- const REQUESTED = process.env.OPS_INTEGRATION_PROVIDER || ''
13
+ // El prefijo lo completa `automation install`. No puede venir del entorno: el runtime de workflows no
14
+ // expone `process`, así que leerlo de ahí reventaba el archivo entero en su primera línea. Viaja
15
+ // escrito, relativo a la carpeta donde se abre la herramienta, que es el cwd de los agentes.
16
+ const ROOT = '{{OPS_DIR}}'.replace(/\/+$/, '') || '.'
17
+ // `/integration-sync jira` o `{"provider": "jira"}`: sin entorno, el argumento es la única entrada.
18
+ const input = typeof args === 'string' ? { provider: args } : (args || {})
19
+ const REQUESTED = String(input.provider || '').trim()
18
20
  const RESULT = {
19
21
  type: 'object', additionalProperties: false, required: ['passed', 'provider', 'details'],
20
22
  properties: {
@@ -26,7 +28,7 @@ const RESULT = {
26
28
  phase('Preflight')
27
29
  const result = await agent(
28
30
  `Read ${ROOT}/integrations/README.md, ${ROOT}/integrations/config.json and ${ROOT}/planning/PROTOCOL.md. ` +
29
- `Resolve provider from OPS_INTEGRATION_PROVIDER=${JSON.stringify(REQUESTED)}; if empty, continue only when exactly ` +
31
+ `The requested provider is ${JSON.stringify(REQUESTED)}; if empty, continue only when exactly ` +
30
32
  `one provider is enabled. Run "node tools/ops.js integration check ${ROOT} <provider>" and read its exit code. ` +
31
33
  `Do not edit config and do not call a remote write operation.\n\n` +
32
34
  `If green, enter Sync and run "node tools/ops.js integration sync ${ROOT} <provider>". The registered adapter owns ` +
@@ -15,10 +15,10 @@ export const meta = {
15
15
  ],
16
16
  }
17
17
 
18
- // El prefijo lo completa `automation install`: en modo sidecar la herramienta se abre en la carpeta
19
- // de la compañía y la raíz ops es uno de sus hijos, no la carpeta misma.
20
- const ROOT = (process.env.OPS_ROOT
21
- || `${process.env.CLAUDE_PROJECT_DIR || '.'}/{{OPS_DIR}}`).replace(/\/+$/, '')
18
+ // El prefijo lo completa `automation install`. No puede venir del entorno: el runtime de workflows no
19
+ // expone `process`, así que leerlo de ahí reventaba el archivo entero en su primera línea. Viaja
20
+ // escrito, relativo a la carpeta donde se abre la herramienta, que es el cwd de los agentes.
21
+ const ROOT = '{{OPS_DIR}}'.replace(/\/+$/, '') || '.'
22
22
  const P = `${ROOT}/planning`
23
23
  const ROADMAP = `${P}/roadmap`
24
24
  const HUMAN = `${P}/HUMAN_ACTIONS.md`
@@ -34,9 +34,9 @@ const REPORTS = `${P}/reports`
34
34
  // El prefijo se toma como candidato y se confirma más abajo contra los equipos que existen: si no es
35
35
  // uno, el texto completo era la intención y nadie tuvo que aprenderse una sintaxis.
36
36
  const input = typeof args === 'string' ? { intent: args } : (args || {})
37
- const raw = String(input.intent || process.env.OPS_INTENT || '').trim()
37
+ const raw = String(input.intent || '').trim()
38
38
  const prefix = raw.match(/^([a-z][a-z0-9-]*)\s*:\s*(.+)$/s)
39
- const CANDIDATE = String(input.team || process.env.OPS_TEAM || (prefix ? prefix[1] : '') || 'product-development')
39
+ const CANDIDATE = String(input.team || (prefix ? prefix[1] : '') || 'product-development')
40
40
  const INTENT = (input.team || !prefix ? raw : prefix[2]).trim()
41
41
 
42
42
  const MANIFEST = {
@@ -78,6 +78,14 @@ const EPIC = {
78
78
  },
79
79
  }
80
80
 
81
+ // Cierre del recorrido. El runtime no trae un helper de cierre —el valor devuelto por el script ya
82
+ // es el resultado—, y darlo por sentado hacía reventar el archivo justo al terminar: después de
83
+ // gastar cada etapa, en la línea que las cerraba.
84
+ function finish(result) {
85
+ log(`Fin: ${JSON.stringify(result)}`)
86
+ return result
87
+ }
88
+
81
89
  const stop = (reason, detail = '') => {
82
90
  log(`Checkpoint: ${reason}${detail ? ` — ${detail}` : ''}`)
83
91
  return finish({ stopped: true, reason, detail })
@@ -100,7 +108,7 @@ const resolved = await agent(
100
108
  } }, label: 'team-resolve' },
101
109
  )
102
110
  if (!resolved) return stop('teams-unavailable', 'no se pudo listar los equipos')
103
- if (!resolved.exists && (input.team || process.env.OPS_TEAM)) {
111
+ if (!resolved.exists && input.team) {
104
112
  return stop('equipo-inexistente', `${CANDIDATE} no existe. Disponibles: ${resolved.teams.join(', ')}`)
105
113
  }
106
114
  // El prefijo era parte de la intención, no un equipo: se recompone y sigue con el equipo por defecto.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ingeniomaps/cauce",
3
- "version": "0.6.1",
3
+ "version": "0.7.1",
4
4
  "description": "Sistema portable de planificación y ejecución verificable para cualquier proyecto",
5
5
  "type": "commonjs",
6
6
  "bin": {