@ingeniomaps/cauce 0.67.0 → 0.68.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,36 @@ 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.68.0] - 2026-09-07
|
|
18
|
+
|
|
19
|
+
### Cambiado
|
|
20
|
+
|
|
21
|
+
- **`upgrade` deja de borrar una ruta retirada cuyo contenido no puede probar suyo.** Retirar una ruta
|
|
22
|
+
nunca volvió al toolkit dueño de lo que hay adentro, y hasta acá se borraba el directorio entero: quien
|
|
23
|
+
tenía sus propios workflows en `automatization/workflows` los perdía sin confirmación y sin vuelta
|
|
24
|
+
atrás. De las seis rutas retiradas, cuatro viven bajo `system/` o son un archivo con nombre del
|
|
25
|
+
toolkit y se siguen retirando igual; las dos que un proyecto también usa para lo suyo
|
|
26
|
+
—`automatization/runners` y `automatization/workflows`— se conservan.
|
|
27
|
+
|
|
28
|
+
**Lo que te pide algo**: esas dos rutas quedan en disco con lo que tengas adentro, la corrida te dice
|
|
29
|
+
cuántos archivos son, y `check` las cuenta en cada corrida hasta que las muevas o las borres. Si lo
|
|
30
|
+
que tenés ahí son restos viejos del toolkit y querés limpiarlos, `--force` las retira.
|
|
31
|
+
|
|
32
|
+
- **La regla R9 dice cómo se prueba una quita.** Una prueba que comprueba que aparece lo nuevo no
|
|
33
|
+
comprueba que desapareció lo viejo, y lo que se quita tiene dependientes que no se anuncian —el
|
|
34
|
+
mensaje que afirmaba la invariante, la condición que la deducía—. Sale de una regresión de 0.67.0 que
|
|
35
|
+
entró exactamente por ahí.
|
|
36
|
+
|
|
37
|
+
### Corregido
|
|
38
|
+
|
|
39
|
+
- **El informe de `upgrade` afirmaba descartes que no ocurrieron.** 0.67.0 pasó a conservar los archivos
|
|
40
|
+
editados y la salida siguió enumerándolos como `− descartado tu cambio en …`, uno por uno, después de
|
|
41
|
+
la línea que anuncia que terminó bien. En una instancia real fueron diecinueve renglones falsos, y
|
|
42
|
+
entre ellos iba la única línea destructiva verdadera de esa corrida, indistinguible. Ahora el informe
|
|
43
|
+
recibe qué pasó —descartado, conservado, pendiente— en vez de deducirlo de una condición que dejó de
|
|
44
|
+
valer, y la línea «planning, organization y todo lo propio quedaron intactos» sale justo cuando es
|
|
45
|
+
cierto, que es cuando se conservó algo.
|
|
46
|
+
|
|
17
47
|
## [0.67.0] - 2026-09-07
|
|
18
48
|
|
|
19
49
|
### Agregado
|
package/engine/cli/instance.js
CHANGED
|
@@ -370,10 +370,19 @@ function upgrade(dir, cli) {
|
|
|
370
370
|
|
|
371
371
|
// Retirar lo que el toolkit ya no distribuye, después de haber actualizado lo que sí.
|
|
372
372
|
const retired = []
|
|
373
|
+
const pendientes = []
|
|
373
374
|
for (const relative of O.RETIRED) {
|
|
374
375
|
const target = path.join(root, relative)
|
|
375
376
|
if (!fs.existsSync(target)) continue
|
|
376
377
|
F.assertNoSymlinkPath(root, target)
|
|
378
|
+
// Retirar una ruta no vuelve al toolkit dueño de lo que hay adentro. En las dos que un proyecto
|
|
379
|
+
// también usa para lo suyo, borrar el directorio entero se llevaba puesto contenido que nadie
|
|
380
|
+
// había entregado —un `autobuild.js` propio, los workflows de una empresa— sin confirmación y sin
|
|
381
|
+
// vuelta atrás. Se conserva y se nombra; `--force` es la salida, igual que para una edición local.
|
|
382
|
+
const contenido = O.RETIRED_COMPARTIDO.includes(relative) && fs.statSync(target).isDirectory()
|
|
383
|
+
? O.treeFiles(target)
|
|
384
|
+
: []
|
|
385
|
+
if (contenido.length && !force) { pendientes.push({ relative, files: contenido }); continue }
|
|
377
386
|
fs.rmSync(target, { recursive: true, force: true })
|
|
378
387
|
retired.push(relative)
|
|
379
388
|
}
|
|
@@ -404,7 +413,13 @@ function upgrade(dir, cli) {
|
|
|
404
413
|
// Acá es donde las tres versiones se saben a la vez, así que es donde pueden quedar diciendo lo mismo.
|
|
405
414
|
const pinned = pinEngine(root, to)
|
|
406
415
|
|
|
407
|
-
|
|
416
|
+
// El informe recibe qué pasó y no una condición de la que deducirlo: `changed` es «lo que estaba
|
|
417
|
+
// editado», y sin `--force` eso se conserva. Deducirlo hizo que 0.67.0 afirmara diecinueve descartes
|
|
418
|
+
// que no ocurrieron (caso 048).
|
|
419
|
+
reportUpgrade({
|
|
420
|
+
root, from, to, system, retired, added, overrides, pinned, droppedBlocks,
|
|
421
|
+
descartados: force ? changed : [], conservados: [...conservados], pendientes,
|
|
422
|
+
})
|
|
408
423
|
}
|
|
409
424
|
|
|
410
425
|
module.exports = { copyTemplate, scaffold, providerNames, upgrade, destroy, PROJECT_ROOT }
|
package/engine/cli/planning.js
CHANGED
|
@@ -144,6 +144,15 @@ function check(dir, cli) {
|
|
|
144
144
|
+ '`upgrade` los conserva y no les trae mejoras')
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
+
// Y lo que `upgrade` no retiró porque no pudo demostrar que fuera suyo: queda ahí, sin colgar de
|
|
148
|
+
// ningún mecanismo, hasta que alguien lo mueva o lo borre. Se cuenta por lo mismo que los congelados
|
|
149
|
+
// — un resto que no se ve se vuelve permanente.
|
|
150
|
+
const restos = O.RETIRED_COMPARTIDO.filter((relative) => fs.existsSync(path.join(root, '..', relative)))
|
|
151
|
+
if (restos.length) {
|
|
152
|
+
warnings.push(`${restos.length} ruta(s) retiradas siguen en disco con contenido tuyo `
|
|
153
|
+
+ `(${restos.join(', ')}); Cauce ya no las distribuye ni las toca`)
|
|
154
|
+
}
|
|
155
|
+
|
|
147
156
|
const integration = I.validate(path.resolve(root, '..'))
|
|
148
157
|
errors.push(...integration.errors)
|
|
149
158
|
warnings.push(...integration.warnings)
|
|
@@ -72,12 +72,23 @@ function adviceFor(changed) {
|
|
|
72
72
|
// propias, agentes editados— queda intacto por construcción, no por comparación.
|
|
73
73
|
// Qué le pasó a la instancia en esta actualización, contado a quien la corrió. Recibe el resultado
|
|
74
74
|
// entero en vez de recalcular nada: lo que se informa es exactamente lo que ocurrió.
|
|
75
|
-
function reportUpgrade({
|
|
75
|
+
function reportUpgrade({
|
|
76
|
+
root, from, to, system, retired, added, overrides, pinned, droppedBlocks,
|
|
77
|
+
descartados, conservados, pendientes,
|
|
78
|
+
}) {
|
|
76
79
|
console.log(`✓ Cauce ${from || '(previa)'} → ${to}`)
|
|
77
80
|
// Descartar con --force es legítimo; hacerlo sin dejar rastro no. Queda en la salida del comando,
|
|
78
|
-
// que es la evidencia que el protocolo pide para cualquier cambio.
|
|
79
|
-
|
|
81
|
+
// que es la evidencia que el protocolo pide para cualquier cambio. Y lo que se conservó no se vuelve
|
|
82
|
+
// a enumerar acá: ya salió con su consejo antes de escribir nada, y repetirlo con el glifo del
|
|
83
|
+
// descarte es lo que volvía ilegible el bloque.
|
|
84
|
+
for (const file of descartados) console.log(`− descartado tu cambio en ${file}`)
|
|
85
|
+
if (conservados.length) console.log(`= ${conservados.length} archivo(s) conservados por tu edición`)
|
|
80
86
|
for (const relative of retired) console.log(`− retirado ${relative}: Cauce ya no lo distribuye`)
|
|
87
|
+
// Sin glifo de acción porque no hubo ninguna: la ruta sigue ahí y el contenido también.
|
|
88
|
+
for (const { relative, files } of pendientes) {
|
|
89
|
+
console.log(` ${relative}: ${files.length} archivo(s) que Cauce no entregó; la ruta se retiró y `
|
|
90
|
+
+ 'el contenido queda. Movelo adonde lo quieras y borrala, o repetí con --force.')
|
|
91
|
+
}
|
|
81
92
|
// Nombrarlos importa tanto como crearlos: existen para que los completes, y uno que aparece sin
|
|
82
93
|
// aviso no lo completa nadie.
|
|
83
94
|
for (const relative of added) console.log(`+ ${relative}: lo agrega esta versión, completalo`)
|
|
@@ -90,9 +101,9 @@ function reportUpgrade({ root, from, to, system, changed, retired, added, overri
|
|
|
90
101
|
for (const override of overrides) {
|
|
91
102
|
console.log(`= conservado ${override.collection}/${override.project}: sobrescribe ${override.system}`)
|
|
92
103
|
}
|
|
93
|
-
// Sólo cuando es cierto
|
|
94
|
-
//
|
|
95
|
-
if (!
|
|
104
|
+
// Sólo cuando es cierto, y ahora lo decide lo que pasó y no una condición: se dice justo cuando no
|
|
105
|
+
// se descartó nada, que incluye la corrida que conservó veinte archivos.
|
|
106
|
+
if (!descartados.length) console.log(' planning, organization y todo lo propio quedaron intactos')
|
|
96
107
|
// No se borra: sin la dependencia declarada, quitarle `.ops/` la dejaría sin motor. Se avisa y
|
|
97
108
|
// decide una persona.
|
|
98
109
|
if (fs.existsSync(path.join(root, '.ops', 'engine'))) {
|
package/engine/core/ownership.js
CHANGED
|
@@ -231,6 +231,14 @@ const RETIRED = [
|
|
|
231
231
|
|
|
232
232
|
// Aprendizaje que quedó dentro de una ruta retirada. Es lo único ahí que no se puede reponer, así
|
|
233
233
|
// que se detecta antes de borrar nada: perderlo en silencio sería peor que dejar el directorio.
|
|
234
|
+
// De las rutas retiradas, las que un proyecto también usa para lo suyo. El resto de la lista vive bajo
|
|
235
|
+
// `system/` o es un archivo con nombre propio del toolkit, y ahí nadie más escribe; éstas dos se llaman
|
|
236
|
+
// como el concepto general, así que quien adoptó Cauce cuando se distribuían tiene los suyos justo ahí.
|
|
237
|
+
//
|
|
238
|
+
// El manifiesto no las puede desempatar: `trackedPaths()` nunca las registró, así que para el toolkit
|
|
239
|
+
// todo su contenido es igual de ajeno. Sin poder demostrar que lo entregó, no lo borra.
|
|
240
|
+
const RETIRED_COMPARTIDO = ['automatization/runners', 'automatization/workflows']
|
|
241
|
+
|
|
234
242
|
function retiredWithLearning(root) {
|
|
235
243
|
const found = []
|
|
236
244
|
for (const relative of RETIRED) {
|
|
@@ -294,6 +302,7 @@ function localChanges(root) {
|
|
|
294
302
|
|
|
295
303
|
module.exports = {
|
|
296
304
|
RETIRED,
|
|
305
|
+
RETIRED_COMPARTIDO,
|
|
297
306
|
TEMPLATE_OWN,
|
|
298
307
|
TEMPLATE_PREFIXES,
|
|
299
308
|
addedPaths,
|
package/package.json
CHANGED
|
@@ -31,6 +31,18 @@ y la cobertura no lo va a decir: mide qué líneas se ejecutan, no qué defectos
|
|
|
31
31
|
La precondición del caso también cuenta. Si el estado en que arranca no puede ocurrir por el camino de
|
|
32
32
|
producción, lo que prueba tampoco: queda verde para siempre sobre algo que nadie va a vivir.
|
|
33
33
|
|
|
34
|
+
**Y quitar un comportamiento se prueba al revés que agregarlo.** Una prueba que comprueba que aparece lo
|
|
35
|
+
nuevo no comprueba que desapareció lo viejo: los dos pueden convivir, y ahí el verde dice que la mitad
|
|
36
|
+
del cambio ocurrió. La aserción que hace falta es de ausencia —que la salida vieja ya no esté, que la
|
|
37
|
+
rama vieja ya no corra—, y es la que no se escribe sola porque nadie la extraña.
|
|
38
|
+
|
|
39
|
+
Lo que se quita, además, tiene dependientes, y no se anuncian. Una invariante que deja de valer se lleva
|
|
40
|
+
puesto a quien la daba por cierta: el mensaje que la afirmaba, la condición que la deducía, el comentario
|
|
41
|
+
que la explicaba. Suelen vivir en otro archivo, que es donde una premisa vieja se pudre sin que nada
|
|
42
|
+
falle. Antes de entregar una quita se busca quién dependía de ella —qué la afirmaba, qué la deducía— y
|
|
43
|
+
cada uno se corrige o se declara. Recorrer la enumeración de la tarea no encuentra esto: la enumeración
|
|
44
|
+
dice qué había que hacer, no qué se apoyaba en lo que había.
|
|
45
|
+
|
|
34
46
|
## R10 — Publicación humana por defecto
|
|
35
47
|
|
|
36
48
|
Push, PR, merge, tags, deploy y rollback requieren la autorización configurada para el proyecto.
|