@ingeniomaps/cauce 0.99.1 → 0.99.2

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,18 @@ 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.99.2] - 2026-09-28
18
+
19
+ ### Corregido
20
+
21
+ - **Cada límite de `### Límites` llega una sola vez.** Si la primera viñeta empezaba con «El runner»,
22
+ «Debe» o «Nunca», la lista entera llegaba otra vez a cada agente, pegada en un límite más. Si reordenaste
23
+ tus viñetas para esquivarlo, ya podés dejarlas como quieras.
24
+ - **`check` deja de avisar que una fila resuelta de `HUMAN_ACTIONS.md` no está commiteada cuando sí lo
25
+ está.** Pasaba con filas largas: la búsqueda de git que usaba no encuentra algunas de más de 256 bytes.
26
+ Ahora se compara contra el archivo commiteado, y una fila que pasó a resuelta sólo en tu árbol se sigue
27
+ avisando.
28
+
17
29
  ## [0.99.1] - 2026-09-25
18
30
 
19
31
  ### Cambiado
@@ -119,17 +119,21 @@ function marked(raw) {
119
119
  return { bullets, intros, own }
120
120
  }
121
121
 
122
- const declared = (raw) => marked(raw).bullets
123
-
122
+ // La pasada de prosa descuenta las líneas que ya son viñetas declaradas. Para ella un bloque de viñetas
123
+ // seguidas es un solo párrafo, así que si la primera empezaba con «El runner» la lista entera entraba otra
124
+ // vez, pegada en un límite: cada uno llegaba dos veces al preámbulo (caso 203). Es el mismo descuento por
125
+ // línea que hace `warnings`, y por la misma razón.
124
126
  function limits(text) {
127
+ const { bullets, own } = marked(text)
128
+ const taken = new Set(own)
125
129
  const prose = text.split(/\n\s*\n/)
126
130
  .map((block) => block.split('\n')
127
131
  .map((line) => line.replace(/^[-*]\s+/, '').trim())
128
- .filter((line) => line && !line.startsWith('#') && !line.startsWith('|'))
132
+ .filter((line) => line && !line.startsWith('#') && !line.startsWith('|') && !taken.has(line))
129
133
  .join(' ')
130
134
  .trim())
131
135
  .filter((block) => ENUNCIA.test(block))
132
- return [...declared(text), ...prose]
136
+ return [...bullets, ...prose]
133
137
  }
134
138
 
135
139
  // Lo que el proyecto escribió en su sección de excepciones y **no** llegó a `boundaries`. Existe porque
@@ -163,7 +167,7 @@ function warnings(root) {
163
167
  ))
164
168
  // Se descuenta por línea y no por párrafo, que es donde estaba el defecto: `paragraphs` saca el `- ` y
165
169
  // une las viñetas seguidas en un párrafo solo, así que una lista declarada no era igual a ninguna
166
- // entrada de `declared()` y se contaba entera como un límite perdido (caso 159).
170
+ // viñeta de `marked()` y se contaba entera como un límite perdido (caso 159).
167
171
  const { own, intros } = marked(mine)
168
172
  const suyo = new Set([...own, ...intros])
169
173
  const outside = P.withoutComments(mine).split('\n')
@@ -132,7 +132,7 @@ function check(dir, cli) {
132
132
  warnings.push(...RC.warnings(RC.status({ ...recurring, done, today: TODAY() })))
133
133
  warnings.push(...IB.warnings(root, done, config))
134
134
  warnings.push(...AD.sealWarnings(root))
135
- warnings.push(...R.unrecordedHumanActions(path.resolve(root, '..'), P.readHumanActions(root)))
135
+ warnings.push(...R.unrecordedHumanActions(path.resolve(root, '..'), P.readHumanActions(root), P.withoutComments))
136
136
  warnings.push(...AP.warnings(path.resolve(root, '..')))
137
137
  warnings.push(...TR.warnings(path.resolve(root, '..')))
138
138
  warnings.push(...CT.warnings(path.resolve(root, '..')))
@@ -130,26 +130,30 @@ function coverageWarnings(opsRoot, done) {
130
130
  // defecto se descubría en la fase 4 de un recorrido: 1,21 M de tokens en tres paradas, con la puerta en
131
131
  // verde las tres veces (caso 121).
132
132
  //
133
- // Se pregunta con el pickaxe sobre la línea entera y no por la palabra `resuelta`: lo que hay que
134
- // establecer es que **esa** fila, con ese estado, existió alguna vez en un commit. Una que pasó a resuelta
135
- // sólo en el árbol de trabajo no aparece en ninguno.
133
+ // Se pregunta si **esa** fila, con ese estado, está en el archivo de `HEAD`, línea por línea, y no por la
134
+ // palabra `resuelta`. Una que pasó a resuelta sólo en el árbol de trabajo no está ahí.
135
+ //
136
+ // No se pregunta con el pickaxe, que era la primera forma: `git log -S` busca con una tabla de saltos de
137
+ // un byte (`kwset.c`), que con una aguja de más de 256 bytes se desborda y salta por encima de una fila que
138
+ // sí está en el commit. Una fila resuelta de verdad es justo la larga, porque lleva la decisión adentro
139
+ // (caso 204).
140
+ //
141
+ // `clean` es la limpieza que ya sufrieron las filas: el parser las lee sin comentarios, así que el archivo
142
+ // commiteado tiene que pasar por la misma o una fila con un `<!-- -->` adentro no coincide con su línea.
136
143
  //
137
144
  // Sin repositorio, o con el archivo todavía sin commitear, no dice nada: no hay historia contra la cual
138
145
  // preguntar y el aviso sería inventado. Degrada como el 086 con las migraciones — antes callar de más que
139
146
  // avisar de más, porque un aviso que salta siempre se termina apagando.
140
- function unrecordedHumanActions(opsRoot, rows) {
147
+ function unrecordedHumanActions(opsRoot, rows, clean) {
141
148
  const file = path.join(opsRoot, 'planning', 'HUMAN_ACTIONS.md')
142
149
  const top = git(path.dirname(file), 'rev-parse', '--show-toplevel')
143
150
  if (top.status !== 0) return []
144
151
  const repo = top.stdout.trim()
145
- const relative = path.relative(repo, file)
146
- const history = git(repo, 'log', '--format=%h', '--', relative)
147
- if (history.status !== 0 || !history.stdout.trim()) return []
148
- return rows.filter((row) => row.resolved)
149
- .filter((row) => {
150
- const found = git(repo, 'log', '--format=%h', `-S${row.raw}`, '--', relative)
151
- return found.status === 0 && !found.stdout.trim()
152
- })
152
+ const relative = path.relative(repo, file).split(path.sep).join('/')
153
+ const committed = git(repo, 'show', `HEAD:${relative}`)
154
+ if (committed.status !== 0) return []
155
+ const lines = new Set(clean(committed.stdout).split('\n'))
156
+ return rows.filter((row) => row.resolved && !lines.has(row.raw))
153
157
  .map((row) => `HUMAN_ACTIONS.md: ${row.task} figura resuelta y ningún commit la registró`)
154
158
  }
155
159
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ingeniomaps/cauce",
3
- "version": "0.99.1",
3
+ "version": "0.99.2",
4
4
  "description": "Sistema portable de planificación y ejecución verificable para cualquier proyecto",
5
5
  "keywords": [
6
6
  "planning",