@ingeniomaps/cauce 0.70.0 → 0.71.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.
Files changed (127) hide show
  1. package/CHANGELOG.md +127 -0
  2. package/agents/README.md +38 -0
  3. package/agents/roles/system/accounting-specialist/learning/HISTORY.md +2 -0
  4. package/agents/roles/system/ai-governance-lead/learning/HISTORY.md +6 -1
  5. package/agents/roles/system/ai-governance-lead/learning/sources.yaml +4 -4
  6. package/agents/roles/system/ai-governance-lead/references/operating-model.md +2 -2
  7. package/agents/roles/system/ai-product-manager/learning/HISTORY.md +4 -1
  8. package/agents/roles/system/ai-product-manager/learning/sources.yaml +2 -2
  9. package/agents/roles/system/ai-product-manager/references/operating-model.md +2 -2
  10. package/agents/roles/system/analytics-engineer/learning/HISTORY.md +4 -1
  11. package/agents/roles/system/analytics-engineer/learning/sources.yaml +2 -2
  12. package/agents/roles/system/analytics-engineer/references/operating-model.md +2 -2
  13. package/agents/roles/system/backend-engineer/learning/HISTORY.md +2 -0
  14. package/agents/roles/system/business-strategist/learning/HISTORY.md +2 -0
  15. package/agents/roles/system/business-strategist/learning/sources.yaml +1 -1
  16. package/agents/roles/system/business-strategist/references/operating-model.md +2 -2
  17. package/agents/roles/system/cloud-architect/learning/HISTORY.md +1 -1
  18. package/agents/roles/system/cloud-architect/learning/sources.yaml +2 -2
  19. package/agents/roles/system/cloud-architect/references/operating-model.md +2 -2
  20. package/agents/roles/system/community-manager/learning/HISTORY.md +4 -1
  21. package/agents/roles/system/community-manager/learning/sources.yaml +2 -2
  22. package/agents/roles/system/community-manager/references/operating-model.md +1 -1
  23. package/agents/roles/system/content-specialist/learning/HISTORY.md +2 -0
  24. package/agents/roles/system/customer-success-manager/learning/HISTORY.md +2 -0
  25. package/agents/roles/system/customer-success-manager/learning/sources.yaml +4 -4
  26. package/agents/roles/system/customer-success-manager/references/operating-model.md +3 -3
  27. package/agents/roles/system/customer-support-specialist/learning/HISTORY.md +2 -0
  28. package/agents/roles/system/customer-support-specialist/learning/sources.yaml +2 -2
  29. package/agents/roles/system/customer-support-specialist/references/operating-model.md +2 -2
  30. package/agents/roles/system/data-analyst/learning/HISTORY.md +2 -0
  31. package/agents/roles/system/data-engineer/learning/HISTORY.md +4 -1
  32. package/agents/roles/system/data-engineer/learning/sources.yaml +3 -3
  33. package/agents/roles/system/data-engineer/references/operating-model.md +2 -2
  34. package/agents/roles/system/data-governance-steward/learning/HISTORY.md +2 -0
  35. package/agents/roles/system/data-scientist/learning/HISTORY.md +4 -1
  36. package/agents/roles/system/data-scientist/learning/sources.yaml +3 -3
  37. package/agents/roles/system/data-scientist/references/operating-model.md +2 -2
  38. package/agents/roles/system/database-administrator/learning/HISTORY.md +1 -1
  39. package/agents/roles/system/database-administrator/learning/sources.yaml +2 -2
  40. package/agents/roles/system/database-administrator/references/operating-model.md +2 -2
  41. package/agents/roles/system/developer-relations-engineer/learning/HISTORY.md +4 -1
  42. package/agents/roles/system/devops-engineer/learning/HISTORY.md +2 -0
  43. package/agents/roles/system/engineering-manager/learning/HISTORY.md +2 -0
  44. package/agents/roles/system/engineering-manager/learning/sources.yaml +1 -1
  45. package/agents/roles/system/engineering-manager/references/operating-model.md +2 -2
  46. package/agents/roles/system/financial-controller/learning/HISTORY.md +2 -0
  47. package/agents/roles/system/financial-controller/learning/sources.yaml +2 -2
  48. package/agents/roles/system/financial-controller/references/operating-model.md +1 -1
  49. package/agents/roles/system/finops-engineer/learning/HISTORY.md +2 -0
  50. package/agents/roles/system/fraud-risk-analyst/learning/HISTORY.md +2 -0
  51. package/agents/roles/system/frontend-engineer/learning/HISTORY.md +2 -0
  52. package/agents/roles/system/growth-marketer/learning/HISTORY.md +2 -0
  53. package/agents/roles/system/growth-marketer/learning/sources.yaml +1 -1
  54. package/agents/roles/system/implementation-manager/learning/HISTORY.md +1 -1
  55. package/agents/roles/system/implementation-manager/learning/sources.yaml +4 -4
  56. package/agents/roles/system/implementation-manager/references/operating-model.md +3 -3
  57. package/agents/roles/system/integrations-engineer/learning/HISTORY.md +2 -0
  58. package/agents/roles/system/kyc-aml-specialist/learning/HISTORY.md +3 -2
  59. package/agents/roles/system/kyc-aml-specialist/learning/sources.yaml +1 -1
  60. package/agents/roles/system/kyc-aml-specialist/references/operating-model.md +1 -1
  61. package/agents/roles/system/legal-counsel/learning/HISTORY.md +6 -1
  62. package/agents/roles/system/legal-counsel/learning/sources.yaml +1 -1
  63. package/agents/roles/system/legal-counsel/references/operating-model.md +1 -1
  64. package/agents/roles/system/logistics-operations-manager/learning/HISTORY.md +2 -0
  65. package/agents/roles/system/machine-learning-engineer/learning/HISTORY.md +4 -1
  66. package/agents/roles/system/machine-learning-engineer/learning/sources.yaml +6 -6
  67. package/agents/roles/system/machine-learning-engineer/references/operating-model.md +3 -3
  68. package/agents/roles/system/mlops-engineer/learning/HISTORY.md +4 -1
  69. package/agents/roles/system/mlops-engineer/learning/sources.yaml +2 -2
  70. package/agents/roles/system/mlops-engineer/references/operating-model.md +2 -2
  71. package/agents/roles/system/mobile-engineer/learning/HISTORY.md +2 -0
  72. package/agents/roles/system/mobile-engineer/learning/sources.yaml +1 -1
  73. package/agents/roles/system/partnerships-manager/learning/HISTORY.md +4 -1
  74. package/agents/roles/system/partnerships-manager/learning/sources.yaml +2 -2
  75. package/agents/roles/system/partnerships-manager/references/operating-model.md +2 -2
  76. package/agents/roles/system/people-operations-manager/learning/HISTORY.md +4 -1
  77. package/agents/roles/system/people-operations-manager/learning/sources.yaml +2 -2
  78. package/agents/roles/system/people-operations-manager/references/operating-model.md +2 -2
  79. package/agents/roles/system/privacy-compliance-specialist/learning/HISTORY.md +2 -0
  80. package/agents/roles/system/privacy-compliance-specialist/learning/sources.yaml +1 -1
  81. package/agents/roles/system/privacy-compliance-specialist/references/operating-model.md +1 -1
  82. package/agents/roles/system/procurement-manager/learning/HISTORY.md +1 -1
  83. package/agents/roles/system/procurement-manager/learning/sources.yaml +2 -2
  84. package/agents/roles/system/procurement-manager/references/operating-model.md +2 -2
  85. package/agents/roles/system/product-manager/learning/HISTORY.md +1 -1
  86. package/agents/roles/system/product-marketing-manager/learning/HISTORY.md +2 -0
  87. package/agents/roles/system/product-marketing-manager/learning/sources.yaml +1 -1
  88. package/agents/roles/system/project-manager/learning/HISTORY.md +4 -1
  89. package/agents/roles/system/project-manager/learning/sources.yaml +1 -1
  90. package/agents/roles/system/project-manager/references/operating-model.md +2 -2
  91. package/agents/roles/system/qa-engineer/learning/HISTORY.md +2 -0
  92. package/agents/roles/system/qa-engineer/learning/sources.yaml +9 -11
  93. package/agents/roles/system/qa-engineer/references/operating-model.md +2 -2
  94. package/agents/roles/system/release-manager/learning/HISTORY.md +1 -1
  95. package/agents/roles/system/sales-representative/learning/HISTORY.md +2 -0
  96. package/agents/roles/system/sales-representative/learning/sources.yaml +2 -2
  97. package/agents/roles/system/sales-representative/references/operating-model.md +1 -1
  98. package/agents/roles/system/security-engineer/learning/HISTORY.md +2 -0
  99. package/agents/roles/system/security-engineer/learning/sources.yaml +1 -1
  100. package/agents/roles/system/security-engineer/references/operating-model.md +1 -1
  101. package/agents/roles/system/site-reliability-engineer/learning/HISTORY.md +2 -0
  102. package/agents/roles/system/software-architect/learning/HISTORY.md +2 -0
  103. package/agents/roles/system/software-architect/learning/sources.yaml +2 -2
  104. package/agents/roles/system/software-architect/references/operating-model.md +1 -1
  105. package/agents/roles/system/solutions-engineer/learning/HISTORY.md +4 -1
  106. package/agents/roles/system/solutions-engineer/learning/sources.yaml +4 -4
  107. package/agents/roles/system/solutions-engineer/references/operating-model.md +2 -2
  108. package/agents/roles/system/tech-lead/learning/HISTORY.md +2 -0
  109. package/agents/roles/system/technical-program-manager/learning/HISTORY.md +4 -1
  110. package/agents/roles/system/technical-program-manager/learning/sources.yaml +2 -2
  111. package/agents/roles/system/technical-program-manager/references/operating-model.md +3 -3
  112. package/agents/roles/system/technical-writer/learning/HISTORY.md +4 -1
  113. package/agents/roles/system/treasury-analyst/learning/HISTORY.md +2 -0
  114. package/agents/roles/system/ui-designer/learning/HISTORY.md +2 -0
  115. package/agents/roles/system/ui-designer/learning/sources.yaml +2 -2
  116. package/agents/roles/system/user-researcher/learning/HISTORY.md +1 -1
  117. package/agents/roles/system/user-researcher/learning/sources.yaml +1 -1
  118. package/agents/roles/system/ux-designer/learning/HISTORY.md +2 -0
  119. package/agents/roles/system/ux-designer/learning/sources.yaml +1 -1
  120. package/agents/roles/system/ux-designer/references/operating-model.md +1 -1
  121. package/automatization/workflows/autobuild.js +38 -20
  122. package/engine/agents/learning-seal.js +36 -5
  123. package/engine/agents/learning-sources.js +46 -2
  124. package/engine/agents/learning.js +13 -1
  125. package/engine/cli/planning.js +29 -0
  126. package/package.json +1 -1
  127. package/template/planning/PROTOCOL.md +14 -0
@@ -90,6 +90,12 @@ function sourceTiers(text) {
90
90
  return [...body.matchAll(/tier:\s*([A-Za-z-]+)/g)].map((hit) => hit[1])
91
91
  }
92
92
 
93
+ // Una entrada escrita en una sola línea: seis cargos del catálogo la escriben así y cuarenta y siete la
94
+ // reparten en varias. Leyendo sólo la segunda forma, esos seis no tenían el chequeo de URL duplicada que
95
+ // hay más abajo, y nada lo decía porque no encontrar duplicados y no mirar se ven igual.
96
+ const FLOW_ENTRY = /^\s*-\s*\{[^}]*\bname:\s*([^,}]+?)\s*,[^}]*\burl:\s*"?([^",}\s]+)/
97
+ const quitar = (value) => value.replace(/^['"]|['"]$/g, '')
98
+
93
99
  // Las fuentes de un cargo, por su URL. La misma URL con dos nombres es una sola fuente contada dos
94
100
  // veces: el catálogo llegó a tener la especificación OpenAPI bajo tres —`OpenAPI Specification`,
95
101
  // `...latest published` y `...3.2.0`— así que arreglarle el `tier` a un cargo no se lo arreglaba a los
@@ -99,14 +105,52 @@ function sourceUrls(text) {
99
105
  const out = []
100
106
  let name = ''
101
107
  for (const line of body.split('\n')) {
108
+ const flow = line.match(FLOW_ENTRY)
109
+ if (flow) { out.push({ name: quitar(flow[1]), url: flow[2].replace(/\/+$/, '') }); continue }
102
110
  const declared = line.match(/^\s*-\s*name:\s*(.+?)\s*$/)
103
- if (declared) { name = declared[1].replace(/^['"]|['"]$/g, ''); continue }
111
+ if (declared) { name = quitar(declared[1]); continue }
104
112
  const url = line.match(/^\s*url:\s*(\S+)/)
105
113
  if (url && name) out.push({ name, url: url[1].replace(/\/+$/, '') })
106
114
  }
107
115
  return out
108
116
  }
109
117
 
118
+ // Todo lo que un cargo cita y alguien va a abrir. `sources.yaml` es lo que investiga; `references/` y
119
+ // `SKILL.md` son el método que sigue, y hasta 0.71.0 nadie las miraba: 29 de las 207 URLs de esos
120
+ // documentos no servían, entre ellas dos 404 de páginas que se habían movido.
121
+ //
122
+ // `evaluations/` queda afuera y no por costo: los casos adversariales **inventan** dominios a propósito
123
+ // —veintiuna URLs bajo `.example` y marcas que no existen— y comprobarlas reportaría rotas las que están
124
+ // bien escritas. `learning/reports` y `learning/proposals` también, por lo contrario: son evidencia
125
+ // fechada de que algo dio 403 el día que se consultó, y eso no se arregla.
126
+ const DOC_URL = /https?:\/\/[^\s)>"`\]]+/g
127
+ function documentUrls(dir) {
128
+ const out = []
129
+ const seen = new Set()
130
+ const add = (raw, origin) => {
131
+ const url = raw.replace(/[.,;:]+$/, '')
132
+ if (seen.has(url)) return
133
+ seen.add(url)
134
+ out.push({ url, origin })
135
+ }
136
+ const below = (base, relative) => {
137
+ let entries = []
138
+ try { entries = fs.readdirSync(path.join(base, relative), { withFileTypes: true }) } catch { return }
139
+ for (const entry of entries) {
140
+ const next = `${relative}/${entry.name}`
141
+ if (entry.isDirectory()) { below(base, next); continue }
142
+ if (!entry.name.endsWith('.md')) continue
143
+ for (const hit of fs.readFileSync(path.join(base, next), 'utf8').match(DOC_URL) || []) add(hit, next)
144
+ }
145
+ }
146
+ below(dir, 'references')
147
+ const skill = path.join(dir, 'SKILL.md')
148
+ if (fs.existsSync(skill)) {
149
+ for (const hit of fs.readFileSync(skill, 'utf8').match(DOC_URL) || []) add(hit, 'SKILL.md')
150
+ }
151
+ return out
152
+ }
153
+
110
154
  function evaluate(root, agent) {
111
155
  const target = catalog.resolve(root, agent)
112
156
  const errors = []
@@ -193,4 +237,4 @@ function evaluate(root, agent) {
193
237
  return { errors, warnings, proposals: proposals.length, pending, cases }
194
238
  }
195
239
 
196
- module.exports = { SOURCE_TIERS, cadence, evaluate, evaluateTeam }
240
+ module.exports = { SOURCE_TIERS, cadence, documentUrls, evaluate, evaluateTeam, sourceUrls }
@@ -40,15 +40,21 @@ function prepareReport(root, agent, now = new Date()) {
40
40
  // Los sellos de estado de este módulo escriben atómico y esto no, y la diferencia es qué se pierde
41
41
  // si la escritura se corta: allá el archivo ya existía y quedaría truncado, acá no había nada. Un
42
42
  // documento nuevo a medio escribir se ve; uno viejo a medio pisar se lee como si estuviera entero.
43
+ // `propone` nace sin contestar y lo completa quien escribe el informe. No se deduce del texto de
44
+ // «Recomendación»: los veinte informes del 2026-09-07 tenían texto ahí y once no proponían ningún
45
+ // cambio —explicaban por qué, que es lo correcto—, así que «sección vacía» no distingue nada. Con
46
+ // el campo, un informe que no cambia ningún contrato se mergea solo en vez de gastar una revisión
47
+ // humana que no puede decidir nada.
43
48
  fs.writeFileSync(file, `---
44
49
  agent: ${agent}
45
50
  date: ${isoDate(now)}
46
51
  status: draft
52
+ propone: por-completar
47
53
  ---
48
54
 
49
55
  # Investigación semanal — ${isoDate(now)}
50
56
 
51
- <!-- Dos convenciones que el ciclo necesita y que nada más sostiene:
57
+ <!-- Tres convenciones que el ciclo necesita y que nada más sostiene:
52
58
 
53
59
  · Etiquetá cada hallazgo H1, H2, … en el orden en que aparecen. «Evidencia» y «Recomendación» se
54
60
  refieren a ellos por esa clave, y la propuesta mensual la cita para decir de qué hallazgo sale
@@ -57,6 +63,12 @@ status: draft
57
63
  · No renombres los títulos. «## Recomendación» se lee con un patrón exacto y es lo único que la
58
64
  propuesta consolida de cada informe: renombrarlo no da error, deja la propuesta vacía.
59
65
 
66
+ · Contestá «propone» en el frontmatter, con «si» o con «no». Es «si» cuando el informe pide tocar
67
+ algún archivo del cargo —SKILL.md, sources.yaml, references/, un caso— y «no» cuando lo hallado
68
+ no cambia ningún contrato, aunque «Recomendación» explique largamente por qué. Un «no» se
69
+ mergea sin revisión humana: no hay nada que decidir. Ante la duda va «si», que sólo cuesta una
70
+ mirada.
71
+
60
72
  Este comentario vive fuera de toda sección a propósito — dentro de «Recomendación» viajaría a cada
61
73
  propuesta consolidada. -->
62
74
 
@@ -266,6 +266,9 @@ function treeJson({ epics, milestones, done, wips, inbox, queued, claims }) {
266
266
 
267
267
  function tree(dir, cli) {
268
268
  const root = path.resolve(dir || '.')
269
+ // Mismo motivo que en `context`, y por eso comparten la comprobación: sin ella un planning ausente
270
+ // dibujaba un árbol vacío, que se lee como un roadmap sin épicas en vez de como una ruta equivocada.
271
+ assertPlanning(root)
269
272
  const state = ST.snapshot(root)
270
273
  if (cli.has('--json')) return treeJson(state)
271
274
  const { epics, milestones, done, wips, inbox, queued, claims } = state
@@ -304,9 +307,29 @@ function tree(dir, cli) {
304
307
  console.log(`${paint('1', 'DONE')} ${done.entries.length} tareas\n`)
305
308
  }
306
309
 
310
+ // Lo que no se pudo leer no contesta como si se hubiera leído: la misma regla que `stagedFiles` aplica
311
+ // sobre el índice de git, y que esta familia ya aplicaba al `--hito` inexistente. Faltaba la raíz, y ahí
312
+ // pesa más, porque el consumidor no siempre es una persona: `autobuild` toma la cola vacía como permiso
313
+ // para expandir una épica, así que un error de ruta promovía trabajo en vez de fallar.
314
+ //
315
+ // La ruta va **resuelta** y no como se escribió, porque el error que ataca es de resolución: en sidecar
316
+ // `<empresa>-ops/planning` desde adentro de la raíz apunta a `<empresa>-ops/<empresa>-ops/planning`.
317
+ function assertPlanning(root) {
318
+ if (!fs.existsSync(root)) {
319
+ return fail(`no existe el planning en ${root} (ruta resuelta). Comprobá desde dónde estás invocando.`, 2)
320
+ }
321
+ // Existir no alcanza: un directorio cualquiera contestaría cola vacía igual. `BACKLOG.md` es el archivo
322
+ // del que sale la cola, así que sin él la respuesta no significa nada.
323
+ if (!fs.existsSync(path.join(root, 'BACKLOG.md'))) {
324
+ return fail(`${root} (ruta resuelta) no es un planning: falta BACKLOG.md.`, 2)
325
+ }
326
+ return null
327
+ }
328
+
307
329
  // Contexto mínimo suficiente para ejecutar una tarea, en lugar de releer roadmap, BACKLOG y WIP enteros.
308
330
  function context(dir, cli) {
309
331
  const root = path.resolve(dir || '.')
332
+ assertPlanning(root)
310
333
  const state = ST.snapshot(root)
311
334
  // Acotar la cola a un hito es como un equipo se reparte trabajo sin coordinarse: dos personas en hitos
312
335
  // distintos casi nunca dependen entre sí ni tocan los mismos archivos. Lo que se acota es qué se
@@ -372,6 +395,10 @@ function context(dir, cli) {
372
395
  // vuelta. Que aparezca es la señal.
373
396
  recurring: RC.status({ ...RC.read(root), done: state.done, today: TODAY() })
374
397
  .filter((one) => one.overdue),
398
+ // La próxima sin promover: se nombra, no se encola, igual que la recurrencia de arriba y por su
399
+ // mismo criterio. Por qué no la encola una máquina está en la fase Pick de `autobuild`.
400
+ nextEpic: (!task && [...state.epics].filter((one) => one.status === 'open')
401
+ .sort((a, b) => String(a.num).localeCompare(String(b.num)))[0]) || null,
375
402
  }
376
403
  if (cli.has('--json')) return console.log(JSON.stringify(report))
377
404
 
@@ -403,6 +430,8 @@ function context(dir, cli) {
403
430
  }
404
431
  if (!report.task) {
405
432
  console.log('TASK (sin tarea disponible)')
433
+ const { nextEpic: next } = report
434
+ if (next) console.log(`EPIC ${next.num}: ${next.title} — sin promover`)
406
435
  // Mismo motivo que `blocked` arriba, con otra causa: acá la cola no la traba una persona, la tiene
407
436
  // el equipo, y lo que corresponde es hablar con quien la tiene.
408
437
  for (const one of report.taken) console.log(`TAKEN ${one.slug} (${dueño(one)})`)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ingeniomaps/cauce",
3
- "version": "0.70.0",
3
+ "version": "0.71.0",
4
4
  "description": "Sistema portable de planificación y ejecución verificable para cualquier proyecto",
5
5
  "keywords": [
6
6
  "planning",
@@ -81,6 +81,20 @@ El lane reduce ceremonia, nunca seguridad, aceptación ni evidencia: Verify y el
81
81
  cuatro. Lo que decide el carril es la superficie del cambio y no su tamaño en líneas — un `if` en el
82
82
  chequeo de permisos es `full`, y un componente entero de presentación puede ser `directo`.
83
83
 
84
+ Escribir la línea es también contrastarla. Declara cuatro cosas —qué hace, en qué carril, quién entrega y
85
+ revisa, con qué se comprueba— y las cuatro salen de la misma mano en el mismo acto, así que nada las cruza
86
+ después. Releerlas no encuentra el hueco: una aceptación incompleta se lee perfecta, porque todo lo que
87
+ dice es cierto.
88
+
89
+ Antes de dar la tarea por escrita se recorre su descripción frase por frase y se contesta, por cada cosa
90
+ que promete, cuál condición de aceptación la comprueba; se lee el carril contra la superficie que toca y
91
+ no contra su tamaño; y se comprueba que el cast entregue a quien construye. Lo que quede sin condición se
92
+ agrega o se declara fuera de alcance en la línea.
93
+
94
+ Es el único momento en que las cuatro se pueden mirar juntas, y por eso la pasada vive acá y no en una
95
+ fase: después el carril ya decide cuáles corren, y la que revisaría es una de las que ese carril puede
96
+ saltar. Una tarea mal marcada `express` es justamente la que se salta la fase donde alguien lo notaría.
97
+
84
98
  ## Invariantes
85
99
 
86
100
  1. Una tarea tiene un dueño de estado: roadmap → BACKLOG → overlay WIP → DONE.