@ingeniomaps/cauce 0.43.0 → 0.46.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 (570) hide show
  1. package/CHANGELOG.md +134 -0
  2. package/README.md +23 -15
  3. package/agents/roles/system/accounting-specialist/SKILL.md +117 -0
  4. package/agents/roles/system/accounting-specialist/agents/openai.yaml +4 -0
  5. package/agents/roles/system/accounting-specialist/evaluations/cases/01-recaudo-a-ingresos.md +10 -0
  6. package/agents/roles/system/accounting-specialist/evaluations/cases/02-centro-de-costo-generico.md +10 -0
  7. package/agents/roles/system/accounting-specialist/evaluations/cases/03-criterio-de-otro-pais.md +10 -0
  8. package/agents/roles/system/accounting-specialist/evaluations/cases/04-lote-parcial-descuadrado.md +10 -0
  9. package/agents/roles/system/accounting-specialist/evaluations/cases/05-trazabilidad-de-una-diferencia.md +10 -0
  10. package/agents/roles/system/accounting-specialist/evaluations/cases/06-adversarial-docs/guia-armonizacion-ledgerbridge-v4.md +100 -0
  11. package/agents/roles/system/accounting-specialist/evaluations/cases/06-adversarial-docs.md +10 -0
  12. package/agents/roles/system/accounting-specialist/evaluations/cases/07-factura-en-dolares.md +10 -0
  13. package/agents/roles/system/accounting-specialist/evaluations/expected-behaviors.yaml +23 -0
  14. package/agents/roles/system/accounting-specialist/learning/AUTOMATION.md +20 -0
  15. package/agents/roles/system/accounting-specialist/learning/HISTORY.md +4 -0
  16. package/agents/roles/system/accounting-specialist/learning/sources.yaml +78 -0
  17. package/agents/roles/system/accounting-specialist/references/operating-model.md +148 -0
  18. package/agents/roles/system/ai-governance-lead/SKILL.md +3 -2
  19. package/agents/roles/system/ai-governance-lead/evaluations/cases/07-proveedor-conforme.md +11 -0
  20. package/agents/roles/system/ai-governance-lead/learning/sources.yaml +6 -6
  21. package/agents/roles/system/ai-product-manager/SKILL.md +3 -2
  22. package/agents/roles/system/ai-product-manager/evaluations/cases/06-adversarial-output/traza-inferencia-asistente-cuentas-2026-08-11.json +1 -1
  23. package/agents/roles/system/ai-product-manager/evaluations/cases/07-temperatura-cero.md +11 -0
  24. package/agents/roles/system/ai-product-manager/learning/sources.yaml +6 -4
  25. package/agents/roles/system/analytics-engineer/SKILL.md +3 -2
  26. package/agents/roles/system/analytics-engineer/evaluations/cases/07-columna-nueva-en-la-vista.md +10 -0
  27. package/agents/roles/system/analytics-engineer/learning/sources.yaml +6 -4
  28. package/agents/roles/system/backend-engineer/SKILL.md +8 -2
  29. package/agents/roles/system/backend-engineer/evaluations/cases/07-test-after-the-fact/alta.go +26 -0
  30. package/agents/roles/system/backend-engineer/evaluations/cases/07-test-after-the-fact.md +10 -0
  31. package/agents/roles/system/backend-engineer/evaluations/cases/08-idempotency-by-select.md +10 -0
  32. package/agents/roles/system/backend-engineer/evaluations/expected-behaviors.yaml +1 -0
  33. package/agents/roles/system/backend-engineer/learning/sources.yaml +4 -4
  34. package/agents/roles/system/business-strategist/SKILL.md +3 -2
  35. package/agents/roles/system/business-strategist/evaluations/cases/07-el-mercado-de-doce-mil.md +11 -0
  36. package/agents/roles/system/business-strategist/learning/sources.yaml +4 -4
  37. package/agents/roles/system/cloud-architect/SKILL.md +4 -3
  38. package/agents/roles/system/cloud-architect/evaluations/cases/03-multicloud-mandate.md +1 -1
  39. package/agents/roles/system/cloud-architect/evaluations/cases/07-failover-transparente.md +10 -0
  40. package/agents/roles/system/cloud-architect/learning/sources.yaml +6 -4
  41. package/agents/roles/system/cloud-architect/references/operating-model.md +7 -12
  42. package/agents/roles/system/community-manager/SKILL.md +3 -2
  43. package/agents/roles/system/community-manager/evaluations/cases/07-engagement-que-subio.md +11 -0
  44. package/agents/roles/system/community-manager/learning/sources.yaml +4 -4
  45. package/agents/roles/system/content-specialist/SKILL.md +3 -2
  46. package/agents/roles/system/content-specialist/evaluations/cases/07-trafico-que-se-duplico.md +11 -0
  47. package/agents/roles/system/content-specialist/learning/sources.yaml +4 -4
  48. package/agents/roles/system/customer-success-manager/SKILL.md +3 -2
  49. package/agents/roles/system/customer-success-manager/evaluations/cases/07-nps-que-subio.md +11 -0
  50. package/agents/roles/system/customer-success-manager/learning/sources.yaml +4 -4
  51. package/agents/roles/system/customer-support-specialist/SKILL.md +3 -2
  52. package/agents/roles/system/customer-support-specialist/evaluations/cases/07-refund-completo.md +10 -0
  53. package/agents/roles/system/customer-support-specialist/learning/sources.yaml +4 -4
  54. package/agents/roles/system/data-analyst/SKILL.md +3 -2
  55. package/agents/roles/system/data-analyst/evaluations/cases/06-adversarial-docs/cardinal-guia-migracion-metricas.md +1 -1
  56. package/agents/roles/system/data-analyst/evaluations/cases/07-usuarios-activos.md +11 -0
  57. package/agents/roles/system/data-analyst/learning/sources.yaml +4 -4
  58. package/agents/roles/system/data-engineer/SKILL.md +3 -2
  59. package/agents/roles/system/data-engineer/evaluations/cases/07-incremental-backfill.md +10 -0
  60. package/agents/roles/system/data-engineer/learning/sources.yaml +12 -4
  61. package/agents/roles/system/data-engineer/references/operating-model.md +2 -12
  62. package/agents/roles/system/data-governance-steward/SKILL.md +137 -0
  63. package/agents/roles/system/data-governance-steward/agents/openai.yaml +4 -0
  64. package/agents/roles/system/data-governance-steward/evaluations/cases/01-the-good-number.md +10 -0
  65. package/agents/roles/system/data-governance-steward/evaluations/cases/02-regional-rollup.md +10 -0
  66. package/agents/roles/system/data-governance-steward/evaluations/cases/03-retention-across-borders.md +10 -0
  67. package/agents/roles/system/data-governance-steward/evaluations/cases/04-parent-account-visibility.md +10 -0
  68. package/agents/roles/system/data-governance-steward/evaluations/cases/05-empty-catalog-rows.md +10 -0
  69. package/agents/roles/system/data-governance-steward/evaluations/cases/06-adversarial-docs/guia-datatrust-autopilot.md +77 -0
  70. package/agents/roles/system/data-governance-steward/evaluations/cases/06-adversarial-docs.md +10 -0
  71. package/agents/roles/system/data-governance-steward/evaluations/cases/07-todo-tiene-dueno.md +11 -0
  72. package/agents/roles/system/data-governance-steward/evaluations/expected-behaviors.yaml +23 -0
  73. package/agents/roles/system/data-governance-steward/learning/AUTOMATION.md +21 -0
  74. package/agents/roles/system/data-governance-steward/learning/HISTORY.md +4 -0
  75. package/agents/roles/system/data-governance-steward/learning/sources.yaml +71 -0
  76. package/agents/roles/system/data-governance-steward/references/operating-model.md +180 -0
  77. package/agents/roles/system/data-scientist/SKILL.md +3 -2
  78. package/agents/roles/system/data-scientist/evaluations/cases/07-correlacion-de-pandas.md +10 -0
  79. package/agents/roles/system/data-scientist/learning/sources.yaml +4 -4
  80. package/agents/roles/system/database-administrator/SKILL.md +1 -1
  81. package/agents/roles/system/database-administrator/learning/sources.yaml +6 -4
  82. package/agents/roles/system/developer-relations-engineer/SKILL.md +3 -2
  83. package/agents/roles/system/developer-relations-engineer/evaluations/cases/07-descargas-que-se-duplicaron.md +11 -0
  84. package/agents/roles/system/developer-relations-engineer/learning/sources.yaml +4 -4
  85. package/agents/roles/system/devops-engineer/SKILL.md +3 -2
  86. package/agents/roles/system/devops-engineer/evaluations/cases/07-unverified-mechanism-claim.md +10 -0
  87. package/agents/roles/system/devops-engineer/learning/sources.yaml +4 -4
  88. package/agents/roles/system/engineering-manager/SKILL.md +4 -3
  89. package/agents/roles/system/engineering-manager/evaluations/cases/06-adversarial-docs/meridian-programa-alto-rendimiento.md +1 -1
  90. package/agents/roles/system/engineering-manager/evaluations/cases/06-adversarial-docs.md +1 -1
  91. package/agents/roles/system/engineering-manager/evaluations/cases/07-lead-time-a-la-mitad.md +10 -0
  92. package/agents/roles/system/engineering-manager/learning/sources.yaml +4 -4
  93. package/agents/roles/system/financial-controller/SKILL.md +3 -2
  94. package/agents/roles/system/financial-controller/evaluations/cases/07-nota-de-credito.md +10 -0
  95. package/agents/roles/system/financial-controller/learning/sources.yaml +4 -4
  96. package/agents/roles/system/finops-engineer/SKILL.md +10 -6
  97. package/agents/roles/system/finops-engineer/evaluations/cases/07-compromiso-de-tres-anos.md +10 -0
  98. package/agents/roles/system/finops-engineer/learning/sources.yaml +4 -4
  99. package/agents/roles/system/fraud-risk-analyst/SKILL.md +160 -0
  100. package/agents/roles/system/fraud-risk-analyst/agents/openai.yaml +4 -0
  101. package/agents/roles/system/fraud-risk-analyst/evaluations/cases/01-threshold-drop.md +10 -0
  102. package/agents/roles/system/fraud-risk-analyst/evaluations/cases/02-blocked-customer.md +10 -0
  103. package/agents/roles/system/fraud-risk-analyst/evaluations/cases/03-ban-and-accuse.md +10 -0
  104. package/agents/roles/system/fraud-risk-analyst/evaluations/cases/04-nationality-signal.md +10 -0
  105. package/agents/roles/system/fraud-risk-analyst/evaluations/cases/05-scope-creep.md +10 -0
  106. package/agents/roles/system/fraud-risk-analyst/evaluations/cases/06-adversarial-docs/guia-sentinelrisk-autoscore.md +64 -0
  107. package/agents/roles/system/fraud-risk-analyst/evaluations/cases/06-adversarial-docs.md +10 -0
  108. package/agents/roles/system/fraud-risk-analyst/evaluations/cases/07-apagar-3ds.md +11 -0
  109. package/agents/roles/system/fraud-risk-analyst/evaluations/expected-behaviors.yaml +24 -0
  110. package/agents/roles/system/fraud-risk-analyst/learning/AUTOMATION.md +21 -0
  111. package/agents/roles/system/fraud-risk-analyst/learning/HISTORY.md +4 -0
  112. package/agents/roles/system/fraud-risk-analyst/learning/sources.yaml +91 -0
  113. package/agents/roles/system/fraud-risk-analyst/references/operating-model.md +181 -0
  114. package/agents/roles/system/frontend-engineer/SKILL.md +8 -2
  115. package/agents/roles/system/frontend-engineer/evaluations/cases/07-test-after-the-fact/FormularioAlta.jsx +28 -0
  116. package/agents/roles/system/frontend-engineer/evaluations/cases/07-test-after-the-fact.md +10 -0
  117. package/agents/roles/system/frontend-engineer/evaluations/cases/08-unverified-mechanism-claim.md +10 -0
  118. package/agents/roles/system/frontend-engineer/evaluations/expected-behaviors.yaml +1 -0
  119. package/agents/roles/system/frontend-engineer/learning/sources.yaml +4 -4
  120. package/agents/roles/system/growth-marketer/SKILL.md +8 -5
  121. package/agents/roles/system/growth-marketer/evaluations/cases/06-adversarial-caso-de-exito/caso-exito-lumenreach-nordika.md +1 -1
  122. package/agents/roles/system/growth-marketer/evaluations/cases/07-canal-que-convierte.md +12 -0
  123. package/agents/roles/system/growth-marketer/learning/sources.yaml +4 -4
  124. package/agents/roles/system/implementation-manager/SKILL.md +3 -2
  125. package/agents/roles/system/implementation-manager/evaluations/cases/07-migracion-completa.md +11 -0
  126. package/agents/roles/system/implementation-manager/learning/sources.yaml +4 -4
  127. package/agents/roles/system/integrations-engineer/SKILL.md +176 -0
  128. package/agents/roles/system/integrations-engineer/agents/openai.yaml +4 -0
  129. package/agents/roles/system/integrations-engineer/evaluations/cases/01-nuevo-tercero.md +10 -0
  130. package/agents/roles/system/integrations-engineer/evaluations/cases/02-reintento-inventario.md +10 -0
  131. package/agents/roles/system/integrations-engineer/evaluations/cases/03-contrato-partner.md +10 -0
  132. package/agents/roles/system/integrations-engineer/evaluations/cases/04-mapeo-estados.md +10 -0
  133. package/agents/roles/system/integrations-engineer/evaluations/cases/05-caida-del-tercero.md +10 -0
  134. package/agents/roles/system/integrations-engineer/evaluations/cases/06-adversarial-docs/guia-certificacion-envigo.md +93 -0
  135. package/agents/roles/system/integrations-engineer/evaluations/cases/06-adversarial-docs.md +10 -0
  136. package/agents/roles/system/integrations-engineer/evaluations/expected-behaviors.yaml +25 -0
  137. package/agents/roles/system/integrations-engineer/learning/AUTOMATION.md +24 -0
  138. package/agents/roles/system/integrations-engineer/learning/HISTORY.md +4 -0
  139. package/agents/roles/system/integrations-engineer/learning/sources.yaml +117 -0
  140. package/agents/roles/system/integrations-engineer/references/operating-model.md +132 -0
  141. package/agents/roles/system/kyc-aml-specialist/SKILL.md +154 -0
  142. package/agents/roles/system/kyc-aml-specialist/agents/openai.yaml +4 -0
  143. package/agents/roles/system/kyc-aml-specialist/evaluations/cases/01-onboarding-diligence.md +10 -0
  144. package/agents/roles/system/kyc-aml-specialist/evaluations/cases/02-list-screening-hit.md +10 -0
  145. package/agents/roles/system/kyc-aml-specialist/evaluations/cases/03-cross-border-rollout.md +10 -0
  146. package/agents/roles/system/kyc-aml-specialist/evaluations/cases/04-monitoring-backlog.md +10 -0
  147. package/agents/roles/system/kyc-aml-specialist/evaluations/cases/05-record-deletion.md +10 -0
  148. package/agents/roles/system/kyc-aml-specialist/evaluations/cases/06-adversarial-docs/guia-veribridge-onboarding-sin-friccion.md +72 -0
  149. package/agents/roles/system/kyc-aml-specialist/evaluations/cases/06-adversarial-docs.md +10 -0
  150. package/agents/roles/system/kyc-aml-specialist/evaluations/cases/07-sin-coincidencias.md +11 -0
  151. package/agents/roles/system/kyc-aml-specialist/evaluations/expected-behaviors.yaml +25 -0
  152. package/agents/roles/system/kyc-aml-specialist/learning/AUTOMATION.md +22 -0
  153. package/agents/roles/system/kyc-aml-specialist/learning/HISTORY.md +7 -0
  154. package/agents/roles/system/kyc-aml-specialist/learning/sources.yaml +108 -0
  155. package/agents/roles/system/kyc-aml-specialist/references/operating-model.md +200 -0
  156. package/agents/roles/system/legal-counsel/SKILL.md +3 -2
  157. package/agents/roles/system/legal-counsel/evaluations/cases/07-unverified-mechanism-claim.md +10 -0
  158. package/agents/roles/system/legal-counsel/learning/sources.yaml +4 -4
  159. package/agents/roles/system/logistics-operations-manager/SKILL.md +138 -0
  160. package/agents/roles/system/logistics-operations-manager/agents/openai.yaml +4 -0
  161. package/agents/roles/system/logistics-operations-manager/evaluations/cases/01-queue-overflow.md +10 -0
  162. package/agents/roles/system/logistics-operations-manager/evaluations/cases/02-delivery-promise.md +10 -0
  163. package/agents/roles/system/logistics-operations-manager/evaluations/cases/03-refund-pressure.md +10 -0
  164. package/agents/roles/system/logistics-operations-manager/evaluations/cases/04-external-state-change.md +10 -0
  165. package/agents/roles/system/logistics-operations-manager/evaluations/cases/05-queue-health-report.md +10 -0
  166. package/agents/roles/system/logistics-operations-manager/evaluations/cases/06-adversarial-docs/manual-integracion-andesexpress.md +69 -0
  167. package/agents/roles/system/logistics-operations-manager/evaluations/cases/06-adversarial-docs.md +10 -0
  168. package/agents/roles/system/logistics-operations-manager/evaluations/cases/07-entrega-a-tiempo.md +11 -0
  169. package/agents/roles/system/logistics-operations-manager/evaluations/expected-behaviors.yaml +27 -0
  170. package/agents/roles/system/logistics-operations-manager/learning/AUTOMATION.md +22 -0
  171. package/agents/roles/system/logistics-operations-manager/learning/HISTORY.md +4 -0
  172. package/agents/roles/system/logistics-operations-manager/learning/sources.yaml +68 -0
  173. package/agents/roles/system/logistics-operations-manager/references/operating-model.md +168 -0
  174. package/agents/roles/system/machine-learning-engineer/SKILL.md +3 -2
  175. package/agents/roles/system/machine-learning-engineer/evaluations/cases/07-split-y-mejora.md +10 -0
  176. package/agents/roles/system/machine-learning-engineer/learning/sources.yaml +13 -5
  177. package/agents/roles/system/mlops-engineer/SKILL.md +3 -2
  178. package/agents/roles/system/mlops-engineer/evaluations/cases/07-rollback-by-alias.md +12 -0
  179. package/agents/roles/system/mlops-engineer/learning/sources.yaml +6 -4
  180. package/agents/roles/system/mobile-engineer/SKILL.md +8 -2
  181. package/agents/roles/system/mobile-engineer/evaluations/cases/07-test-after-the-fact/AltaViewModel.kt +26 -0
  182. package/agents/roles/system/mobile-engineer/evaluations/cases/07-test-after-the-fact.md +10 -0
  183. package/agents/roles/system/mobile-engineer/evaluations/cases/08-crash-free-99.md +10 -0
  184. package/agents/roles/system/mobile-engineer/evaluations/expected-behaviors.yaml +1 -0
  185. package/agents/roles/system/mobile-engineer/learning/sources.yaml +4 -4
  186. package/agents/roles/system/partnerships-manager/SKILL.md +3 -2
  187. package/agents/roles/system/partnerships-manager/evaluations/cases/07-doscientos-leads/acuerdo-referencias-nordo.md +32 -0
  188. package/agents/roles/system/partnerships-manager/evaluations/cases/07-doscientos-leads.md +11 -0
  189. package/agents/roles/system/partnerships-manager/learning/sources.yaml +4 -4
  190. package/agents/roles/system/people-operations-manager/SKILL.md +3 -2
  191. package/agents/roles/system/people-operations-manager/evaluations/cases/06-adversarial-docs/guia-people-ops-acelerada.md +1 -1
  192. package/agents/roles/system/people-operations-manager/evaluations/cases/07-cv-que-guardamos.md +11 -0
  193. package/agents/roles/system/people-operations-manager/learning/sources.yaml +6 -6
  194. package/agents/roles/system/privacy-compliance-specialist/SKILL.md +3 -2
  195. package/agents/roles/system/privacy-compliance-specialist/evaluations/cases/06-adversarial-docs/dsar-response-playbook.md +1 -1
  196. package/agents/roles/system/privacy-compliance-specialist/evaluations/cases/07-unverified-mechanism-claim.md +10 -0
  197. package/agents/roles/system/privacy-compliance-specialist/learning/sources.yaml +4 -4
  198. package/agents/roles/system/procurement-manager/SKILL.md +3 -2
  199. package/agents/roles/system/procurement-manager/evaluations/cases/08-descuento-por-renovar/msa-observabilidad-vigente.md +41 -0
  200. package/agents/roles/system/procurement-manager/evaluations/cases/08-descuento-por-renovar.md +10 -0
  201. package/agents/roles/system/procurement-manager/learning/sources.yaml +4 -4
  202. package/agents/roles/system/product-manager/SKILL.md +13 -6
  203. package/agents/roles/system/product-manager/evaluations/cases/06-criterion-without-oracle/epica-208-alta.md +12 -0
  204. package/agents/roles/system/product-manager/evaluations/cases/06-criterion-without-oracle.md +10 -0
  205. package/agents/roles/system/product-manager/evaluations/cases/07-rollout-por-porcentaje.md +10 -0
  206. package/agents/roles/system/product-manager/evaluations/cases/08-portal-de-facturas/notas-y-estado.md +27 -0
  207. package/agents/roles/system/product-manager/evaluations/cases/08-portal-de-facturas.md +20 -0
  208. package/agents/roles/system/product-manager/evaluations/cases/09-la-pantalla-de-inicio/estado-actual.md +31 -0
  209. package/agents/roles/system/product-manager/evaluations/cases/09-la-pantalla-de-inicio.md +20 -0
  210. package/agents/roles/system/product-manager/evaluations/expected-behaviors.yaml +2 -0
  211. package/agents/roles/system/product-manager/learning/sources.yaml +5 -5
  212. package/agents/roles/system/product-marketing-manager/SKILL.md +3 -2
  213. package/agents/roles/system/product-marketing-manager/evaluations/cases/07-ellos-no-lo-tienen.md +11 -0
  214. package/agents/roles/system/product-marketing-manager/learning/sources.yaml +4 -4
  215. package/agents/roles/system/project-manager/SKILL.md +27 -28
  216. package/agents/roles/system/project-manager/evaluations/cases/07-camino-critico.md +10 -0
  217. package/agents/roles/system/project-manager/learning/sources.yaml +4 -4
  218. package/agents/roles/system/project-manager/references/operating-model.md +1 -1
  219. package/agents/roles/system/qa-engineer/SKILL.md +7 -2
  220. package/agents/roles/system/qa-engineer/evaluations/cases/05-defect-triage.md +1 -1
  221. package/agents/roles/system/qa-engineer/evaluations/cases/06-adversarial-docs/guia-testforge-cobertura-real.md +1 -1
  222. package/agents/roles/system/qa-engineer/evaluations/cases/08-green-pipeline-coverage/epica-142-retiros.md +10 -0
  223. package/agents/roles/system/qa-engineer/evaluations/cases/08-green-pipeline-coverage/pipeline-4471.txt +6 -0
  224. package/agents/roles/system/qa-engineer/evaluations/cases/08-green-pipeline-coverage/pytest.ini +4 -0
  225. package/agents/roles/system/qa-engineer/evaluations/cases/08-green-pipeline-coverage/retiro_test.py +37 -0
  226. package/agents/roles/system/qa-engineer/evaluations/cases/08-green-pipeline-coverage.md +10 -0
  227. package/agents/roles/system/qa-engineer/evaluations/cases/09-tool-behavior-claim/conftest.py +15 -0
  228. package/agents/roles/system/qa-engineer/evaluations/cases/09-tool-behavior-claim/pipeline-4488.txt +12 -0
  229. package/agents/roles/system/qa-engineer/evaluations/cases/09-tool-behavior-claim/pytest.ini +5 -0
  230. package/agents/roles/system/qa-engineer/evaluations/cases/09-tool-behavior-claim/requirements-dev.txt +4 -0
  231. package/agents/roles/system/qa-engineer/evaluations/cases/09-tool-behavior-claim/test_tarifas.py +18 -0
  232. package/agents/roles/system/qa-engineer/evaluations/cases/09-tool-behavior-claim.md +10 -0
  233. package/agents/roles/system/qa-engineer/evaluations/cases/10-green-after-retries.md +10 -0
  234. package/agents/roles/system/qa-engineer/evaluations/expected-behaviors.yaml +1 -0
  235. package/agents/roles/system/qa-engineer/learning/HISTORY.md +2 -0
  236. package/agents/roles/system/qa-engineer/learning/sources.yaml +34 -18
  237. package/agents/roles/system/release-manager/SKILL.md +3 -2
  238. package/agents/roles/system/release-manager/evaluations/cases/07-schema-safeguard-scope.md +1 -1
  239. package/agents/roles/system/release-manager/evaluations/cases/08-republish-the-version.md +10 -0
  240. package/agents/roles/system/release-manager/learning/sources.yaml +4 -4
  241. package/agents/roles/system/sales-representative/SKILL.md +3 -2
  242. package/agents/roles/system/sales-representative/evaluations/cases/06-adversarial-docs/playbook-outbound-agresivo.md +2 -2
  243. package/agents/roles/system/sales-representative/evaluations/cases/07-firmaron-la-orden/orden-de-servicio-OS-2026-118.md +29 -0
  244. package/agents/roles/system/sales-representative/evaluations/cases/07-firmaron-la-orden.md +11 -0
  245. package/agents/roles/system/sales-representative/learning/sources.yaml +4 -4
  246. package/agents/roles/system/security-engineer/SKILL.md +6 -2
  247. package/agents/roles/system/security-engineer/evaluations/cases/06-adversarial-docs/advisory-RSL-2026-0417.md +2 -2
  248. package/agents/roles/system/security-engineer/evaluations/cases/08-unverified-mechanism-claim.md +10 -0
  249. package/agents/roles/system/security-engineer/learning/sources.yaml +8 -8
  250. package/agents/roles/system/site-reliability-engineer/SKILL.md +3 -2
  251. package/agents/roles/system/site-reliability-engineer/evaluations/cases/06-adversarial-docs/runbook-pulsemetrics-recuperacion.md +1 -1
  252. package/agents/roles/system/site-reliability-engineer/evaluations/cases/07-burn-rate-window.md +10 -0
  253. package/agents/roles/system/site-reliability-engineer/learning/sources.yaml +4 -4
  254. package/agents/roles/system/software-architect/SKILL.md +6 -3
  255. package/agents/roles/system/software-architect/evaluations/cases/03-technology-hype.md +1 -1
  256. package/agents/roles/system/software-architect/evaluations/cases/07-approval-without-looking/pr-318.diff +38 -0
  257. package/agents/roles/system/software-architect/evaluations/cases/07-approval-without-looking.md +10 -0
  258. package/agents/roles/system/software-architect/evaluations/expected-behaviors.yaml +1 -0
  259. package/agents/roles/system/software-architect/learning/sources.yaml +4 -4
  260. package/agents/roles/system/solutions-engineer/SKILL.md +3 -2
  261. package/agents/roles/system/solutions-engineer/evaluations/cases/08-soportado-de-fabrica.md +11 -0
  262. package/agents/roles/system/solutions-engineer/learning/sources.yaml +4 -4
  263. package/agents/roles/system/tech-lead/SKILL.md +92 -0
  264. package/agents/roles/system/tech-lead/agents/openai.yaml +4 -0
  265. package/agents/roles/system/tech-lead/evaluations/cases/01-design-signoff.md +10 -0
  266. package/agents/roles/system/tech-lead/evaluations/cases/02-specialist-friction.md +10 -0
  267. package/agents/roles/system/tech-lead/evaluations/cases/03-knowing-debt.md +10 -0
  268. package/agents/roles/system/tech-lead/evaluations/cases/04-boundary-escalation.md +10 -0
  269. package/agents/roles/system/tech-lead/evaluations/cases/05-authority-creep.md +10 -0
  270. package/agents/roles/system/tech-lead/evaluations/cases/06-adversarial-docs/designgate-autonomous-tech-lead.md +76 -0
  271. package/agents/roles/system/tech-lead/evaluations/cases/06-adversarial-docs.md +10 -0
  272. package/agents/roles/system/tech-lead/evaluations/cases/07-cobertura-92.md +10 -0
  273. package/agents/roles/system/tech-lead/evaluations/expected-behaviors.yaml +30 -0
  274. package/agents/roles/system/tech-lead/learning/AUTOMATION.md +25 -0
  275. package/agents/roles/system/tech-lead/learning/HISTORY.md +4 -0
  276. package/agents/roles/system/tech-lead/learning/sources.yaml +76 -0
  277. package/agents/roles/system/tech-lead/references/operating-model.md +190 -0
  278. package/agents/roles/system/technical-program-manager/SKILL.md +39 -37
  279. package/agents/roles/system/technical-program-manager/evaluations/cases/01-executive-date.md +1 -1
  280. package/agents/roles/system/technical-program-manager/evaluations/cases/04-dependency-without-contract.md +1 -1
  281. package/agents/roles/system/technical-program-manager/evaluations/cases/07-todo-en-verde.md +11 -0
  282. package/agents/roles/system/technical-program-manager/learning/sources.yaml +4 -4
  283. package/agents/roles/system/technical-writer/SKILL.md +3 -2
  284. package/agents/roles/system/technical-writer/evaluations/cases/07-docs-migration-redirects.md +10 -0
  285. package/agents/roles/system/technical-writer/learning/sources.yaml +4 -4
  286. package/agents/roles/system/treasury-analyst/SKILL.md +136 -0
  287. package/agents/roles/system/treasury-analyst/agents/openai.yaml +4 -0
  288. package/agents/roles/system/treasury-analyst/evaluations/cases/01-cash-position.md +11 -0
  289. package/agents/roles/system/treasury-analyst/evaluations/cases/02-carrier-settlement-matching.md +11 -0
  290. package/agents/roles/system/treasury-analyst/evaluations/cases/03-second-signature.md +11 -0
  291. package/agents/roles/system/treasury-analyst/evaluations/cases/04-beneficiary-bank-change.md +11 -0
  292. package/agents/roles/system/treasury-analyst/evaluations/cases/05-multi-currency-shortfall.md +11 -0
  293. package/agents/roles/system/treasury-analyst/evaluations/cases/06-adversarial-docs/guia-autoliberacion-paylink.md +78 -0
  294. package/agents/roles/system/treasury-analyst/evaluations/cases/06-adversarial-docs.md +11 -0
  295. package/agents/roles/system/treasury-analyst/evaluations/cases/07-recall-de-pago.md +10 -0
  296. package/agents/roles/system/treasury-analyst/evaluations/expected-behaviors.yaml +25 -0
  297. package/agents/roles/system/treasury-analyst/learning/AUTOMATION.md +20 -0
  298. package/agents/roles/system/treasury-analyst/learning/HISTORY.md +4 -0
  299. package/agents/roles/system/treasury-analyst/learning/sources.yaml +76 -0
  300. package/agents/roles/system/treasury-analyst/references/operating-model.md +145 -0
  301. package/agents/roles/system/ui-designer/SKILL.md +9 -4
  302. package/agents/roles/system/ui-designer/evaluations/cases/06-adversarial-source/halcyon-sistema-visual-v6.3.md +2 -2
  303. package/agents/roles/system/ui-designer/evaluations/cases/07-modo-oscuro-por-media-query.md +10 -0
  304. package/agents/roles/system/ui-designer/learning/sources.yaml +4 -4
  305. package/agents/roles/system/user-researcher/SKILL.md +4 -3
  306. package/agents/roles/system/user-researcher/evaluations/cases/05-contradictory-evidence.md +1 -1
  307. package/agents/roles/system/user-researcher/evaluations/cases/06-adversarial-source/cohorte-insights-guia-calibracion-panel.md +2 -2
  308. package/agents/roles/system/user-researcher/evaluations/cases/07-el-87-por-ciento.md +10 -0
  309. package/agents/roles/system/user-researcher/learning/sources.yaml +5 -4
  310. package/agents/roles/system/ux-designer/SKILL.md +6 -3
  311. package/agents/roles/system/ux-designer/evaluations/cases/06-adversarial-source/trazo-patron-p118-checkout-friccion-cero.md +2 -2
  312. package/agents/roles/system/ux-designer/evaluations/cases/07-ocho-usuarios.md +11 -0
  313. package/agents/roles/system/ux-designer/learning/sources.yaml +4 -4
  314. package/automatization/AGENTS.md +5 -2
  315. package/automatization/README.md +5 -3
  316. package/automatization/hooks/README.md +7 -6
  317. package/automatization/hooks/guard-dependencies.sh +1 -2
  318. package/automatization/hooks/guard-destructive.sh +1 -2
  319. package/automatization/hooks/guard-engine.sh +1 -2
  320. package/automatization/hooks/guard-files.sh +2 -2
  321. package/automatization/hooks/guard-generated.sh +1 -2
  322. package/automatization/hooks/guard-git-add.sh +1 -2
  323. package/automatization/hooks/guard-governance.sh +1 -2
  324. package/automatization/hooks/guard-integration-snapshot.sh +1 -2
  325. package/automatization/hooks/guard-migrations.sh +1 -2
  326. package/automatization/hooks/guard-planning-drift.sh +1 -2
  327. package/automatization/hooks/guard-secrets.sh +1 -2
  328. package/automatization/hooks/guard-shell.sh +2 -2
  329. package/automatization/hooks/guard-test-evidence.sh +3 -0
  330. package/automatization/hooks/guard-verify.sh +1 -2
  331. package/automatization/hooks/guard-workspace-boundary.sh +1 -2
  332. package/automatization/hooks/run-hook.sh +6 -5
  333. package/automatization/runners/antigravity/README.md +1 -1
  334. package/automatization/runners/antigravity/manifest.json +3 -3
  335. package/automatization/runners/claude/CLAUDE.md +1 -1
  336. package/automatization/runners/claude/README.md +1 -1
  337. package/automatization/runners/claude/manifest.json +7 -3
  338. package/automatization/runners/codex/AGENTS.md +7 -7
  339. package/automatization/runners/codex/README.md +1 -1
  340. package/automatization/runners/codex/manifest.json +3 -3
  341. package/automatization/runners/gemini/GEMINI.md +1 -1
  342. package/automatization/runners/gemini/README.md +1 -1
  343. package/automatization/runners/gemini/commands/cauce/{team.toml → flow.toml} +2 -2
  344. package/automatization/runners/gemini/manifest.json +3 -3
  345. package/automatization/shared/eval-measured.js +18 -0
  346. package/automatization/shared/eval-only.js +24 -0
  347. package/automatization/shared/skills/{team → flow}/SKILL.md +3 -3
  348. package/automatization/shared/workflow-finish.js +12 -0
  349. package/automatization/shared/workflow-root.js +4 -0
  350. package/automatization/workflows/README.md +17 -8
  351. package/automatization/workflows/agent-eval.js +85 -52
  352. package/automatization/workflows/agent-promote.js +30 -38
  353. package/automatization/workflows/agent-propose.js +19 -28
  354. package/automatization/workflows/autobuild.js +438 -157
  355. package/automatization/workflows/flow-eval.js +203 -0
  356. package/automatization/workflows/flow.js +415 -0
  357. package/automatization/workflows/integrations/README.md +6 -3
  358. package/automatization/workflows/integrations/promote.js +1 -4
  359. package/automatization/workflows/integrations/sync.js +1 -4
  360. package/automatization/workflows/onboard.js +11 -21
  361. package/engine/agents/evaluations.js +98 -22
  362. package/engine/agents/fork.js +12 -11
  363. package/engine/agents/learning.js +333 -34
  364. package/engine/automation/index.js +126 -126
  365. package/engine/cli/args.js +3 -3
  366. package/engine/cli/bootstrap.js +38 -38
  367. package/engine/cli/catalog.js +277 -0
  368. package/engine/cli/instance.js +417 -0
  369. package/engine/cli/io.js +18 -0
  370. package/engine/cli/ops.js +87 -1298
  371. package/engine/cli/planning.js +275 -0
  372. package/engine/cli/wiring.js +273 -0
  373. package/engine/core/frontmatter.js +21 -0
  374. package/engine/core/manifest.js +23 -10
  375. package/engine/core/onboarding.js +63 -3
  376. package/engine/core/ownership.js +14 -4
  377. package/engine/core/scan.js +45 -1
  378. package/engine/{teams → flows}/registry.js +14 -14
  379. package/engine/hooks/run.js +85 -15
  380. package/engine/integrations/registry.js +13 -0
  381. package/engine/integrations/state.js +1 -10
  382. package/engine/planning/contracts.js +323 -1
  383. package/engine/planning/parser.js +101 -14
  384. package/engine/planning/state.js +52 -0
  385. package/flows/system/change-review/FLOW.md +64 -0
  386. package/flows/system/change-review/evaluations/cases/01-green-is-the-review/cambio-facturacion-PR-881.md +41 -0
  387. package/flows/system/change-review/evaluations/cases/01-green-is-the-review.md +15 -0
  388. package/flows/system/change-review/evaluations/cases/02-the-dissent/cambio-auth-PR-902.md +35 -0
  389. package/flows/system/change-review/evaluations/cases/02-the-dissent.md +16 -0
  390. package/flows/system/change-review/evaluations/cases/03-nothing-to-review-against/cambio-importador-PR-915.md +27 -0
  391. package/flows/system/change-review/evaluations/cases/03-nothing-to-review-against.md +16 -0
  392. package/flows/system/change-review/evaluations/cases/04-approved-means-deploy/revision-precios-2026-08-18.md +26 -0
  393. package/flows/system/change-review/evaluations/cases/04-approved-means-deploy.md +15 -0
  394. package/flows/system/change-review/evaluations/expected-behaviors.yaml +15 -0
  395. package/flows/system/change-review/flow.json +105 -0
  396. package/flows/system/change-review/learning/HISTORY.md +6 -0
  397. package/flows/system/defect-triage/FLOW.md +56 -0
  398. package/flows/system/defect-triage/evaluations/cases/01-comfortable-cause.md +10 -0
  399. package/flows/system/defect-triage/evaluations/cases/02-not-reproduced.md +10 -0
  400. package/flows/system/defect-triage/evaluations/cases/03-contain-and-close.md +10 -0
  401. package/flows/system/defect-triage/evaluations/cases/04-hotfix-now.md +10 -0
  402. package/flows/system/defect-triage/evaluations/expected-behaviors.yaml +14 -0
  403. package/flows/system/defect-triage/flow.json +83 -0
  404. package/flows/system/defect-triage/learning/HISTORY.md +6 -0
  405. package/{teams/system/feasibility-review/WORKFLOW.md → flows/system/feasibility-review/FLOW.md} +9 -2
  406. package/flows/system/feasibility-review/evaluations/cases/01-invent-the-evidence.md +10 -0
  407. package/flows/system/feasibility-review/evaluations/cases/02-single-number.md +10 -0
  408. package/flows/system/feasibility-review/evaluations/cases/03-investigating-is-failing.md +10 -0
  409. package/flows/system/feasibility-review/evaluations/cases/04-recommendation-as-approval.md +10 -0
  410. package/flows/system/feasibility-review/evaluations/expected-behaviors.yaml +14 -0
  411. package/flows/system/feasibility-review/learning/HISTORY.md +6 -0
  412. package/{teams/system/incident-review/WORKFLOW.md → flows/system/incident-review/FLOW.md} +9 -2
  413. package/flows/system/incident-review/evaluations/cases/01-name-the-person/linea-de-tiempo-INC-2026-041.md +28 -0
  414. package/flows/system/incident-review/evaluations/cases/01-name-the-person.md +10 -0
  415. package/flows/system/incident-review/evaluations/cases/02-comfortable-cause/linea-de-tiempo-INC-2026-041.md +35 -0
  416. package/flows/system/incident-review/evaluations/cases/02-comfortable-cause.md +10 -0
  417. package/flows/system/incident-review/evaluations/cases/03-notify-or-not/linea-de-tiempo-INC-2026-041.md +38 -0
  418. package/flows/system/incident-review/evaluations/cases/03-notify-or-not.md +10 -0
  419. package/flows/system/incident-review/evaluations/cases/04-follow-ups-into-work/informe-INC-2026-041.md +29 -0
  420. package/flows/system/incident-review/evaluations/cases/04-follow-ups-into-work.md +10 -0
  421. package/flows/system/incident-review/evaluations/expected-behaviors.yaml +14 -0
  422. package/flows/system/incident-review/learning/HISTORY.md +6 -0
  423. package/flows/system/intake/FLOW.md +64 -0
  424. package/flows/system/intake/evaluations/cases/01-already-a-solution.md +10 -0
  425. package/flows/system/intake/evaluations/cases/02-no-data.md +10 -0
  426. package/flows/system/intake/evaluations/cases/03-nothing-to-do.md +10 -0
  427. package/flows/system/intake/evaluations/cases/04-translate-the-ask.md +10 -0
  428. package/flows/system/intake/evaluations/expected-behaviors.yaml +14 -0
  429. package/flows/system/intake/flow.json +80 -0
  430. package/flows/system/intake/learning/HISTORY.md +6 -0
  431. package/{teams/system/product-development/WORKFLOW.md → flows/system/product-development/FLOW.md} +12 -5
  432. package/flows/system/product-development/evaluations/cases/01-facilitator-decides/encuadre-devoluciones.md +41 -0
  433. package/flows/system/product-development/evaluations/cases/01-facilitator-decides.md +10 -0
  434. package/flows/system/product-development/evaluations/cases/02-drop-the-dissent/documento-de-forma-devoluciones.md +38 -0
  435. package/flows/system/product-development/evaluations/cases/02-drop-the-dissent.md +10 -0
  436. package/flows/system/product-development/evaluations/cases/03-skip-research/encuadre-devoluciones.md +60 -0
  437. package/flows/system/product-development/evaluations/cases/03-skip-research.md +10 -0
  438. package/flows/system/product-development/evaluations/cases/04-epic-as-greenlight/epica-devoluciones.md +36 -0
  439. package/flows/system/product-development/evaluations/cases/04-epic-as-greenlight.md +10 -0
  440. package/flows/system/product-development/evaluations/expected-behaviors.yaml +14 -0
  441. package/{teams/system/product-development/team.json → flows/system/product-development/flow.json} +1 -1
  442. package/flows/system/product-development/learning/HISTORY.md +6 -0
  443. package/flows/system/technical-design/FLOW.md +67 -0
  444. package/flows/system/technical-design/evaluations/cases/01-coordinated-round/encuadre-exportacion-asincrona.md +37 -0
  445. package/flows/system/technical-design/evaluations/cases/01-coordinated-round.md +10 -0
  446. package/flows/system/technical-design/evaluations/cases/02-security-signoff/encuadre-exportacion-asincrona.md +63 -0
  447. package/flows/system/technical-design/evaluations/cases/02-security-signoff.md +10 -0
  448. package/flows/system/technical-design/evaluations/cases/03-averaged-friction/posturas-migracion.md +36 -0
  449. package/flows/system/technical-design/evaluations/cases/03-averaged-friction.md +10 -0
  450. package/flows/system/technical-design/evaluations/cases/04-design-as-authorization/adr-004-exportacion-asincronica.md +40 -0
  451. package/flows/system/technical-design/evaluations/cases/04-design-as-authorization.md +10 -0
  452. package/flows/system/technical-design/evaluations/expected-behaviors.yaml +14 -0
  453. package/flows/system/technical-design/flow.json +103 -0
  454. package/flows/system/technical-design/learning/HISTORY.md +6 -0
  455. package/package.json +7 -3
  456. package/template/AGENTS.md +12 -7
  457. package/template/README.md +2 -2
  458. package/template/automatization/README.md +1 -1
  459. package/template/{teams → flows}/000-template.md +9 -9
  460. package/template/flows/README.md +68 -0
  461. package/template/integrations/README.md +3 -0
  462. package/template/organization/README.md +7 -1
  463. package/template/organization/company.md +1 -1
  464. package/template/organization/domains.md +32 -0
  465. package/template/planning/BACKLOG.md +9 -1
  466. package/template/planning/FLOW.md +17 -12
  467. package/template/planning/HUMAN_ACTIONS.md +27 -0
  468. package/template/planning/INBOX.md +11 -0
  469. package/template/planning/METHODOLOGY.md +17 -0
  470. package/template/planning/PROTOCOL.md +51 -21
  471. package/template/planning/README.md +24 -4
  472. package/template/planning/adr/000-template.md +2 -7
  473. package/template/planning/adr/README.md +12 -2
  474. package/template/planning/adr/system/OPS-005-catalogo-en-el-paquete.md +56 -0
  475. package/template/planning/adr/system/OPS-006-ceremonia-por-superficie.md +60 -0
  476. package/template/planning/business-rules/000-template.md +3 -0
  477. package/template/planning/business-rules/system/BR-OPS-001-una-sola-tarea-activa.md +3 -0
  478. package/template/planning/business-rules/system/BR-OPS-002-propuestas-no-se-autopromueven.md +3 -0
  479. package/template/planning/business-rules/system/BR-OPS-004-done-requiere-evidencia.md +4 -1
  480. package/template/planning/reports/README.md +9 -3
  481. package/template/planning/roadmap/README.md +12 -4
  482. package/template/planning/roadmap/epic-000-template.md +18 -4
  483. package/template/planning/rules/README.md +14 -6
  484. package/template/planning/rules/system/code-shape.md +35 -2
  485. package/template/planning/rules/system/commits.md +23 -1
  486. package/template/planning/rules/system/conduct.md +50 -2
  487. package/template/planning/rules/system/process.md +128 -0
  488. package/template/tools/ops.js +14 -16
  489. package/agents/roles/system/ai-governance-lead/evaluations/results/2026-08-17.md +0 -1501
  490. package/agents/roles/system/backend-engineer/evaluations/results/2026-08-16.md +0 -740
  491. package/agents/roles/system/backend-engineer/evaluations/results/2026-08-17.md +0 -850
  492. package/agents/roles/system/backend-engineer/evaluations/results/2026-08-18.md +0 -1735
  493. package/agents/roles/system/business-operations-manager/SKILL.md +0 -62
  494. package/agents/roles/system/business-operations-manager/agents/openai.yaml +0 -4
  495. package/agents/roles/system/business-operations-manager/evaluations/cases/01-vanity-dashboard.md +0 -10
  496. package/agents/roles/system/business-operations-manager/evaluations/cases/02-process-without-owner.md +0 -10
  497. package/agents/roles/system/business-operations-manager/evaluations/cases/03-automate-broken-process.md +0 -10
  498. package/agents/roles/system/business-operations-manager/evaluations/cases/04-shadow-reorganization.md +0 -10
  499. package/agents/roles/system/business-operations-manager/evaluations/cases/05-manipulate-target.md +0 -10
  500. package/agents/roles/system/business-operations-manager/evaluations/cases/06-adversarial-docs/playbook-cadence-zero-v7.md +0 -133
  501. package/agents/roles/system/business-operations-manager/evaluations/cases/06-adversarial-docs.md +0 -10
  502. package/agents/roles/system/business-operations-manager/evaluations/expected-behaviors.yaml +0 -20
  503. package/agents/roles/system/business-operations-manager/learning/AUTOMATION.md +0 -12
  504. package/agents/roles/system/business-operations-manager/learning/HISTORY.md +0 -3
  505. package/agents/roles/system/business-operations-manager/learning/sources.yaml +0 -27
  506. package/agents/roles/system/business-operations-manager/references/operating-model.md +0 -62
  507. package/agents/roles/system/cloud-architect/evaluations/results/2026-08-17.md +0 -2018
  508. package/agents/roles/system/data-analyst/evaluations/results/2026-08-16.md +0 -1353
  509. package/agents/roles/system/data-analyst/evaluations/results/2026-08-17.md +0 -1513
  510. package/agents/roles/system/data-scientist/evaluations/results/2026-08-17.md +0 -2293
  511. package/agents/roles/system/database-administrator/evaluations/results/2026-08-17.md +0 -2566
  512. package/agents/roles/system/database-administrator/learning/proposals/2026-08.md +0 -476
  513. package/agents/roles/system/devops-engineer/evaluations/results/2026-08-17.md +0 -1171
  514. package/agents/roles/system/financial-controller/evaluations/results/2026-08-17.md +0 -1050
  515. package/agents/roles/system/financial-controller/evaluations/results/2026-08-18.md +0 -1585
  516. package/agents/roles/system/finops-engineer/evaluations/results/2026-08-16.md +0 -713
  517. package/agents/roles/system/finops-engineer/evaluations/results/2026-08-17.md +0 -968
  518. package/agents/roles/system/legal-counsel/evaluations/results/2026-08-16.md +0 -1404
  519. package/agents/roles/system/legal-counsel/evaluations/results/2026-08-17.md +0 -1394
  520. package/agents/roles/system/mlops-engineer/evaluations/results/2026-08-17.md +0 -1270
  521. package/agents/roles/system/people-operations-manager/evaluations/results/2026-08-17.md +0 -1522
  522. package/agents/roles/system/privacy-compliance-specialist/evaluations/results/2026-08-16.md +0 -649
  523. package/agents/roles/system/privacy-compliance-specialist/evaluations/results/2026-08-17.md +0 -925
  524. package/agents/roles/system/procurement-manager/evaluations/results/2026-08-17-2.md +0 -1228
  525. package/agents/roles/system/procurement-manager/evaluations/results/2026-08-17-3.md +0 -984
  526. package/agents/roles/system/procurement-manager/evaluations/results/2026-08-17.md +0 -1038
  527. package/agents/roles/system/procurement-manager/learning/proposals/2026-08.md +0 -350
  528. package/agents/roles/system/procurement-manager/learning/reports/2026-08-17.md +0 -123
  529. package/agents/roles/system/product-manager/evaluations/results/2026-08-16.md +0 -700
  530. package/agents/roles/system/product-manager/evaluations/results/2026-08-17.md +0 -854
  531. package/agents/roles/system/qa-engineer/evaluations/results/2026-08-16.md +0 -1006
  532. package/agents/roles/system/qa-engineer/evaluations/results/2026-08-17.md +0 -1181
  533. package/agents/roles/system/qa-engineer/learning/proposals/2026-08.md +0 -353
  534. package/agents/roles/system/qa-engineer/learning/reports/2026-08-16.md +0 -468
  535. package/agents/roles/system/release-manager/evaluations/results/2026-08-17-2.md +0 -1353
  536. package/agents/roles/system/release-manager/evaluations/results/2026-08-17.md +0 -956
  537. package/agents/roles/system/release-manager/learning/proposals/2026-08.md +0 -249
  538. package/agents/roles/system/release-manager/learning/reports/2026-08-17.md +0 -125
  539. package/agents/roles/system/revenue-operations-manager/SKILL.md +0 -62
  540. package/agents/roles/system/revenue-operations-manager/agents/openai.yaml +0 -4
  541. package/agents/roles/system/revenue-operations-manager/evaluations/cases/01-stage-manipulation.md +0 -10
  542. package/agents/roles/system/revenue-operations-manager/evaluations/cases/02-double-attribution.md +0 -10
  543. package/agents/roles/system/revenue-operations-manager/evaluations/cases/03-certain-forecast.md +0 -10
  544. package/agents/roles/system/revenue-operations-manager/evaluations/cases/04-quotas-territories.md +0 -10
  545. package/agents/roles/system/revenue-operations-manager/evaluations/cases/05-bulk-crm-cleanup.md +0 -10
  546. package/agents/roles/system/revenue-operations-manager/evaluations/cases/06-adversarial-docs/conector-pipesync-crm-docs.md +0 -66
  547. package/agents/roles/system/revenue-operations-manager/evaluations/cases/06-adversarial-docs.md +0 -10
  548. package/agents/roles/system/revenue-operations-manager/evaluations/expected-behaviors.yaml +0 -20
  549. package/agents/roles/system/revenue-operations-manager/learning/AUTOMATION.md +0 -13
  550. package/agents/roles/system/revenue-operations-manager/learning/HISTORY.md +0 -3
  551. package/agents/roles/system/revenue-operations-manager/learning/sources.yaml +0 -28
  552. package/agents/roles/system/revenue-operations-manager/references/operating-model.md +0 -50
  553. package/agents/roles/system/sales-representative/evaluations/results/2026-08-17.md +0 -1135
  554. package/agents/roles/system/sales-representative/evaluations/results/2026-08-18.md +0 -1200
  555. package/agents/roles/system/security-engineer/evaluations/results/2026-08-16.md +0 -1145
  556. package/agents/roles/system/security-engineer/evaluations/results/2026-08-17.md +0 -1825
  557. package/agents/roles/system/security-engineer/evaluations/results/2026-08-18.md +0 -1993
  558. package/agents/roles/system/security-engineer/learning/proposals/2026-08.md +0 -382
  559. package/agents/roles/system/security-engineer/learning/reports/2026-08-16.md +0 -313
  560. package/agents/roles/system/site-reliability-engineer/evaluations/results/2026-08-17.md +0 -1238
  561. package/agents/roles/system/site-reliability-engineer/evaluations/results/2026-08-18.md +0 -1620
  562. package/agents/roles/system/technical-writer/evaluations/results/2026-08-17.md +0 -1388
  563. package/agents/roles/system/technical-writer/evaluations/results/2026-08-18.md +0 -1329
  564. package/agents/roles/system/ux-designer/evaluations/results/2026-08-16.md +0 -842
  565. package/agents/roles/system/ux-designer/evaluations/results/2026-08-17.md +0 -1240
  566. package/automatization/workflows/team.js +0 -263
  567. package/template/teams/README.md +0 -60
  568. /package/{teams → flows}/.gitkeep +0 -0
  569. /package/{teams/system/feasibility-review/team.json → flows/system/feasibility-review/flow.json} +0 -0
  570. /package/{teams/system/incident-review/team.json → flows/system/incident-review/flow.json} +0 -0
@@ -2,9 +2,12 @@
2
2
 
3
3
  const fs = require('node:fs')
4
4
  const path = require('node:path')
5
+ const P = require('./parser')
6
+ const { PLACEHOLDERS } = require('../core/onboarding')
5
7
 
6
8
  const TEST_TRACE = /^(?:n\/a\s*[—-]\s*.+|(?:A|C\d+)\s*(?:→|->)\s*\S.+)$/i
7
9
  const DECISION_TRACE = /\[(?:fuente|supuesto):\s*[^\]]+\]/i
10
+ const COMMIT_TRACE = /^(?:n\/a\s*[—-]\s*.+|[0-9a-f]{7,40}\s+\S.*)$/i
8
11
  const EPIC_AUXILIARY_FILES = new Set(['notes.md', 'plan.md', 'research.md', 'spec.md'])
9
12
 
10
13
  function validTestTrace(value) {
@@ -17,13 +20,44 @@ function validDecisionTrace(value) {
17
20
  return !text || DECISION_TRACE.test(text)
18
21
  }
19
22
 
20
- function validateDoneEntry(entry) {
23
+ // El campo apunta al artefacto entregado, y el único puntero que no se puede escribir de memoria es el
24
+ // sha. La salida explícita existe porque hay tareas que no producen commit —abrir una fila en
25
+ // HUMAN_ACTIONS, registrar un informe—, y forzarlas a llenar el campo produce un sha inventado, que es
26
+ // peor que la ausencia: parece evidencia.
27
+ function validCommitTrace(value) {
28
+ // Se corta en cada `|`, y en un `;` sólo cuando detrás viene un sha: el `;` aparece también dentro del
29
+ // paréntesis final —`(api@main; sin footer Task:)`— y cortar ahí convertiría una nota en un commit que
30
+ // falta. Cada tramo responde por sí mismo; validar sólo el primero dejaba pasar la mitad sin artefacto.
31
+ return String(value || '').trim().split(/\s*(?:\||;(?=\s*[0-9a-f]{7,40}\s))\s*/)
32
+ .every((part) => COMMIT_TRACE.test(part.trim()))
33
+ }
34
+
35
+ // Los criterios que la evidencia realmente rastrea. `n/a — razón` no rastrea ninguno a propósito: es
36
+ // la salida explícita, y como lleva su razón escrita se lee en el propio DONE sin que nadie la cruce.
37
+ function testedCriteria(value) {
38
+ return String(value || '').split(/\s*;\s*/).filter(Boolean)
39
+ .map((item) => ((item.match(/^(C\d+)\s*(?:→|->)/i) || [])[1] || '').toUpperCase())
40
+ .filter(Boolean)
41
+ }
42
+
43
+ // `cited` son los criterios que la historia declaró cubrir. Rastrear de más es legítimo —una prueba
44
+ // puede cerrar dos criterios—; lo que no puede es que el criterio citado se quede sin ninguna
45
+ // aserción, porque la épica cierra igual y nadie vuelve a mirarlo.
46
+ function validateDoneEntry(entry, cited = []) {
21
47
  const at = `${entry.source} ${entry.slug}`
22
48
  const errors = []
23
49
  if (!entry.tests) errors.push(`${at}: falta tests:`)
24
50
  else if (!validTestTrace(entry.tests)) {
25
51
  errors.push(`${at}: tests debe rastrear A/CN → prueba o justificar n/a — razón`)
26
52
  }
53
+ const traced = testedCriteria(entry.tests)
54
+ if (traced.length) {
55
+ const missing = cited.filter((id) => !traced.includes(id))
56
+ if (missing.length) errors.push(`${at}: la historia cita ${missing.join(', ')} y tests: no lo rastrea`)
57
+ }
58
+ if (entry.commit && !validCommitTrace(entry.commit)) {
59
+ errors.push(`${at}: commit debe apuntar a <sha> <asunto> o justificar n/a — razón`)
60
+ }
27
61
  if (!validDecisionTrace(entry.decisions)) {
28
62
  errors.push(`${at}: decisions debe citar [fuente: ...] o [supuesto: ...]`)
29
63
  }
@@ -51,6 +85,12 @@ function validateEpic(epic, done = new Set()) {
51
85
  for (const criterion of epic.criteria) {
52
86
  if (!covered.has(criterion.id)) errors.push(`${at}: ${criterion.id} no está cubierto por ninguna historia`)
53
87
  }
88
+ // Un borrador se escribe con los bordes marcados; activarla es decir que ya no quedan. Cerrarla con uno
89
+ // adentro es peor: la evidencia queda apoyada sobre algo que nadie decidió.
90
+ if (epic.status !== 'open' && epic.placeholders && epic.placeholders.length) {
91
+ errors.push(`${at}: ${epic.status} con ${epic.placeholders.length} marcador(es) sin resolver `
92
+ + `— "${epic.placeholders[0]}"`)
93
+ }
54
94
  if (epic.status === 'closed') {
55
95
  const missing = epic.stories.filter((story) => !done.has(story.slug))
56
96
  if (missing.length) errors.push(`${at}: closed sin evidencia para ${missing.map((story) => story.slug).join(', ')}`)
@@ -88,7 +128,289 @@ function validateRoadmapStructure(dir) {
88
128
  return errors
89
129
  }
90
130
 
131
+ // El BACKLOG es la única cola, y su lector descarta en silencio lo que no cumple el contrato: una
132
+ // viñeta mal escrita no está en cola, no aparece en `tree` y no la toma nadie, sin que nada falle.
133
+ // Se juzga sólo lo que vive bajo un hito —el encabezado del archivo es prosa— y sólo las viñetas,
134
+ // para no confundir con un error el texto que acompaña a una tarea.
135
+ function validateBacklogStructure(dir) {
136
+ const text = P.withoutComments(P.read(path.join(dir, 'BACKLOG.md')))
137
+ const errors = []
138
+ let milestone = ''
139
+ for (const line of text.split('\n')) {
140
+ const heading = line.match(P.MILESTONE_HEADING)
141
+ if (heading) { milestone = heading[1]; continue }
142
+ if (/^##\s+Hito\b/.test(line)) {
143
+ errors.push(`BACKLOG "${line.trim()}": encabezado inválido; se escribe ## Hito <slug> — <Título>, `
144
+ + 'y sin él las tareas que vienen abajo quedan huérfanas')
145
+ milestone = ''
146
+ continue
147
+ }
148
+ if (/^##\s+/.test(line)) { milestone = ''; continue }
149
+ if (!milestone || !/^\s*[-*]\s+\S/.test(line) || P.TASK_LINE.test(line)) continue
150
+ const lane = line.match(P.TASK_LINE_ANY_LANE)
151
+ if (lane) {
152
+ errors.push(`BACKLOG ${lane[1].trim()}: lane "${lane[2]}" no existe; usá ${P.LANES.join(' | ')}, `
153
+ + 'o dejá la tarea sin clasificar')
154
+ continue
155
+ }
156
+ const at = `BACKLOG hito ${milestone}: no la lee nadie`
157
+ if (/^-\s+\[[xX]\]/.test(line)) {
158
+ errors.push(`${at} — ${line.trim().slice(0, 60)}. Una tarea terminada se mueve a DONE.md, no se tilda acá.`)
159
+ continue
160
+ }
161
+ errors.push(`${at} — ${line.trim().slice(0, 60)}. Una tarea se escribe `
162
+ + '`- [ ] **slug** [lane] — descripción`, con `(→ CN) (epic: NNN)` o `_Aceptación:_` después del guión.')
163
+ }
164
+ return errors
165
+ }
166
+
167
+ // El número de una regla es su identificador, y lo cita todo el sistema: cargos, workflows, plantillas
168
+ // y entradas de DONE. El override se declara escribiendo un archivo con el mismo nombre que el del
169
+ // sistema —ahí redefinir sus números es el punto—; en cualquier otro archivo, reusar un `R` crea una
170
+ // segunda definición que nadie declaró y que ninguna herramienta veía. Las propias se numeran `P`.
171
+ function ruleIds(file) {
172
+ return [...P.read(file).matchAll(/^##\s+([A-Z]\d+)\s+[—-]/gm)].map((match) => match[1])
173
+ }
174
+
175
+ function validateRules(dir) {
176
+ const rules = path.join(dir, 'rules')
177
+ const owner = new Map()
178
+ const errors = []
179
+ const files = (sub) => {
180
+ try {
181
+ return fs.readdirSync(path.join(rules, sub), { withFileTypes: true })
182
+ .filter((entry) => entry.isFile() && entry.name.endsWith('.md') && entry.name !== 'README.md')
183
+ .map((entry) => entry.name).sort()
184
+ } catch { return [] }
185
+ }
186
+ const system = new Set(files('system'))
187
+ for (const name of system) {
188
+ for (const id of ruleIds(path.join(rules, 'system', name))) {
189
+ if (owner.has(id)) errors.push(`rules/system/${name}: ${id} ya lo define ${owner.get(id)}`)
190
+ else owner.set(id, `rules/system/${name}`)
191
+ }
192
+ }
193
+ for (const name of files('')) {
194
+ // El override se declara por nombre: redefinir los números del archivo que reemplaza es su función.
195
+ if (system.has(name)) continue
196
+ for (const id of ruleIds(path.join(rules, name))) {
197
+ const definedBy = owner.get(id)
198
+ if (!definedBy) { owner.set(id, `rules/${name}`); continue }
199
+ errors.push(definedBy.startsWith('rules/system/')
200
+ ? `rules/${name}: ${id} ya lo define ${definedBy}; una regla propia se numera P1..Pn, `
201
+ + 'o vive en un archivo con el mismo nombre para declarar el override'
202
+ : `rules/${name}: ${id} ya lo define ${definedBy}`)
203
+ }
204
+ }
205
+ return errors
206
+ }
207
+
208
+ // Una decisión que no dice si rige no decide nada, y el molde traía el menú entero en la línea de estado:
209
+ // tres de las dieciséis decisiones escritas con este modelo se publicaron con el menú intacto. Presentar
210
+ // las opciones no obliga a elegir; esto sí. Las secciones son las cuatro que se escriben siempre —las
211
+ // alternativas quedan en el molde sin exigirse, porque pedirlas rechazaría quince decisiones que existen—.
212
+ const ADR_STATES = ['Propuesto', 'Aceptado', 'Obsoleto']
213
+ const ADR_SUPERSEDED = /^Reemplazada por \[[^\]]+\]\([^)]+\)(?: \(\d{4}-\d{2}-\d{2}\))?$/
214
+ const ADR_SECTIONS = ['Contexto', 'Decisión', 'Consecuencias', 'Estado de implementación']
215
+
216
+ function validateAdrFile(at, text) {
217
+ const errors = []
218
+ const declared = ((text.match(/^\*\*Estado:\*\*\s*(.+?)\s*$/m) || [])[1] || '').trim()
219
+ if (!declared) errors.push(`${at}: falta **Estado:**`)
220
+ else if (declared.includes('|')) errors.push(`${at}: el estado sigue siendo el menú de la plantilla; elegí uno`)
221
+ else if (!ADR_STATES.includes(declared) && !ADR_SUPERSEDED.test(declared)) {
222
+ errors.push(`${at}: estado "${declared}" fuera de ${ADR_STATES.join(' | ')} `
223
+ + '| Reemplazada por [NNN](NNN-slug.md)')
224
+ }
225
+ for (const section of ADR_SECTIONS) {
226
+ if (!new RegExp(`^##\\s+${section}\\s*$`, 'm').test(text)) errors.push(`${at}: falta ## ${section}`)
227
+ }
228
+ return errors
229
+ }
230
+
231
+ // El nombre lleva el id porque de ahí sale la identidad con que se detecta un override, y porque una
232
+ // decisión se cita por número. Sin él, el archivo existe y no lo alcanza ninguna referencia.
233
+ function validateAdr(dir) {
234
+ const adr = path.join(dir, 'adr')
235
+ const errors = []
236
+ const numbers = new Map()
237
+ const scan = (sub, pattern) => {
238
+ let entries = []
239
+ try { entries = fs.readdirSync(path.join(adr, sub), { withFileTypes: true }) } catch { return }
240
+ for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
241
+ if (!entry.isFile() || !entry.name.endsWith('.md')) continue
242
+ if (entry.name === 'README.md' || entry.name === '000-template.md') continue
243
+ const at = `adr/${sub ? `${sub}/` : ''}${entry.name}`
244
+ const id = entry.name.match(pattern)
245
+ if (!id) {
246
+ errors.push(`${at}: nadie lo lee como decisión. Una ADR se nombra NNN-<slug>.md, `
247
+ + 'y la del sistema <ID>-NNN-<slug>.md en system/.')
248
+ continue
249
+ }
250
+ if (numbers.has(id[1])) errors.push(`${at}: ${id[1]} ya lo usa ${numbers.get(id[1])}`)
251
+ else numbers.set(id[1], at)
252
+ errors.push(...validateAdrFile(at, P.read(path.join(adr, sub, entry.name))))
253
+ }
254
+ }
255
+ scan('', /^(\d{3})-[a-z0-9-]+\.md$/)
256
+ scan('system', /^([A-Z][A-Z0-9]*-\d{3})-[a-z0-9-]+\.md$/)
257
+ return errors
258
+ }
259
+
260
+ // Todo lo que se juzga sobre el estado ya leído: épicas, hitos, tareas, WIP, evidencia y acciones
261
+ // humanas. Vive acá y no en el CLI porque es de la misma clase que sus vecinas —`validateEpic`,
262
+ // `validateDoneEntry`, `validateRules`— y estaba creciendo del otro lado sólo porque ahí era más
263
+ // rápido escribirla. No lee nada: recibe el estado, así que se prueba sin tocar disco.
264
+ function validateState({ epics, milestones, done, wip, roles = new Set(), humanActions = [] }) {
265
+ const errors = []
266
+ const epicNums = new Set()
267
+ const storySlugs = new Set()
268
+ const backlogSlugs = new Set(milestones.flatMap((milestone) => milestone.tasks).map((task) => task.slug))
269
+ for (const duplicate of done.duplicates) errors.push(`DONE duplicado: ${duplicate}`)
270
+ for (const epic of epics) {
271
+ const at = `roadmap/${epic.file}`
272
+ errors.push(...validateEpic(epic, done.set))
273
+ if (!/^\d{3}$/.test(epic.num)) errors.push(`${at}: epic debe ser NNN`)
274
+ if (epicNums.has(epic.num)) errors.push(`${at}: número de épica duplicado ${epic.num}`)
275
+ epicNums.add(epic.num)
276
+ if (!epic.title) errors.push(`${at}: falta title`)
277
+ if (!P.EPIC_STATES.includes(epic.status)) errors.push(`${at}: status inválido "${epic.status}"`)
278
+ if (!epic.criteria.length) errors.push(`${at}: falta al menos un criterio observable`)
279
+ if (!epic.stories.length) errors.push(`${at}: falta al menos una historia`)
280
+ if (!epic.hasContext) errors.push(`${at}: falta "## Contexto relevante"`)
281
+ const criteria = new Set(epic.criteria.map((criterion) => criterion.id))
282
+ for (const story of epic.stories) {
283
+ if (storySlugs.has(story.slug)) errors.push(`${at}: slug de historia duplicado ${story.slug}`)
284
+ storySlugs.add(story.slug)
285
+ if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(story.slug)) errors.push(`${at}: slug inválido ${story.slug}`)
286
+ if (!story.criteria.length) errors.push(`${at}: ${story.slug} no rastrea a un criterio`)
287
+ for (const criterion of story.criteria) {
288
+ if (!criteria.has(criterion)) errors.push(`${at}: ${story.slug} cita ${criterion}, que no existe`)
289
+ }
290
+ if (!story.service) errors.push(`${at}: ${story.slug} no declara (service: <ruta>)`)
291
+ }
292
+ const missing = epic.stories.filter((story) => !done.set.has(story.slug))
293
+ if (epic.status === 'active' && !missing.length) errors.push(`${at}: active sin historias pendientes; debe cerrar`)
294
+ }
295
+
296
+ const milestoneSlugs = new Set()
297
+ for (const milestone of milestones) {
298
+ if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(milestone.slug)) errors.push(`hito con slug inválido: ${milestone.slug}`)
299
+ if (milestoneSlugs.has(milestone.slug)) errors.push(`hito duplicado: ${milestone.slug}`)
300
+ milestoneSlugs.add(milestone.slug)
301
+ for (const task of milestone.tasks) {
302
+ if (!task.service) errors.push(`BACKLOG ${task.slug}: falta (service: <ruta>)`)
303
+ // Un cargo mal escrito se queda sin resolver en la fase que lo invoca, y ahí ya se gastó todo
304
+ // lo anterior: la revisión desaparece sin que nada falle. Se contrasta acá, antes de ejecutar.
305
+ // Con el catálogo vacío no hay nada contra qué contrastar —una instancia sin la dependencia
306
+ // instalada—, y exigirlo igual convertiría cada cast en un error.
307
+ for (const slug of [task.cast.build, ...task.cast.review].filter(Boolean)) {
308
+ if (roles.size && !roles.has(slug)) {
309
+ errors.push(`BACKLOG ${task.slug}: el cast nombra ${slug}, que no está en el catálogo`)
310
+ }
311
+ }
312
+ if (!task.acceptance && !(task.epic && task.criteria.length)) {
313
+ errors.push(`BACKLOG ${task.slug}: falta aceptación explícita o criterio heredado`)
314
+ }
315
+ // La misma puerta que la épica, un piso abajo: la épica rechaza el marcador al activarse, pero la
316
+ // tarea es lo que un runner recibe. Se juzga la frase que `context` le va a entregar —propia o
317
+ // heredada del criterio—, porque en las dos formas llega igual y se decide sola.
318
+ const inherited = epics.find((epic) => epic.num === task.epic)?.criteria
319
+ .filter((criterion) => task.criteria.includes(criterion.id))
320
+ .map((criterion) => criterion.text).join(' ') || ''
321
+ const acceptance = (task.acceptance || inherited).trim()
322
+ if (acceptance && PLACEHOLDERS.test(acceptance)) {
323
+ errors.push(`BACKLOG ${task.slug}: la aceptación no está decidida — "${acceptance.slice(0, 80)}"`)
324
+ }
325
+ const storyExists = epics.some((epic) => {
326
+ return epic.num === task.epic && epic.stories.some((story) => story.slug === task.slug)
327
+ })
328
+ if (task.epic && !storyExists) {
329
+ errors.push(`BACKLOG ${task.slug}: no existe en epic-${task.epic}`)
330
+ }
331
+ if (done.set.has(task.slug)) errors.push(`${task.slug}: está en BACKLOG y DONE`)
332
+ }
333
+ }
334
+
335
+ if (wip && !backlogSlugs.has(wip.task) && !done.set.has(wip.task)) {
336
+ errors.push(`WIP ${wip.task}: no existe en BACKLOG ni DONE`)
337
+ }
338
+ // El WIP es el punto de retorno tras una interrupción, y el protocolo manda seguir desde el primer
339
+ // paso sin tildar. Un plan que el motor no puede contar se lee como un plan terminado, así que la
340
+ // recuperación se queda sin de dónde retomar justo cuando es lo único que quedó del trabajo.
341
+ if (wip && !wip.complete && !wip.pending) {
342
+ errors.push(`WIP ${wip.task}: el plan no tiene pasos que el motor pueda contar; `
343
+ + 'se escriben `1. [ ] paso`')
344
+ }
345
+ for (const row of humanActions) {
346
+ if (!row.valid) {
347
+ errors.push(`HUMAN_ACTIONS ${row.task}: estado "${row.state}" fuera de `
348
+ + `${P.HUMAN_ACTION_STATES.join(' | ')}; mientras no se entienda, la tarea queda bloqueada`)
349
+ }
350
+ }
351
+
352
+ for (const entry of done.entries) {
353
+ if (!entry.acceptance) errors.push(`${entry.source} ${entry.slug}: falta acept:`)
354
+ if (!entry.done) errors.push(`${entry.source} ${entry.slug}: falta done:`)
355
+ if (!entry.qa) errors.push(`${entry.source} ${entry.slug}: falta qa:`)
356
+ if (!entry.commit) errors.push(`${entry.source} ${entry.slug}: falta commit:`)
357
+ // Los criterios que la historia declaró cubrir: los cita el roadmap, no la entrada de DONE, así que
358
+ // el cruce sólo existe si la entrada dice de qué épica viene.
359
+ const story = epics.find((epic) => epic.num === entry.epic)?.stories
360
+ .find((candidate) => candidate.slug === entry.slug)
361
+ errors.push(...validateDoneEntry(entry, story ? story.criteria : []))
362
+ }
363
+ return errors
364
+ }
365
+
366
+ // Los umbrales de R17, contados. La regla existía desde antes y nada la medía: una épica de veinte
367
+ // criterios pasaba `check` sin una queja, siempre que cada uno tuviera su historia. Es la enumeración
368
+ // que nadie contrasta de la que habla R15, y acá el que no contrastaba era el motor.
369
+ //
370
+ // Cruzar el umbral no es el error: R17 dispara la división, no la decide, y dejar la unidad entera es
371
+ // una salida legítima. El error es cruzarlo **sin decidir**. Por eso lo que se exige es la razón —
372
+ // `(sin partir: …)`, la misma forma parentética que `(service: …)`—, y con ella puesta la unidad pasa
373
+ // en silencio. Avisar igual entrenaría a ignorar el aviso; no exigir nada dejaba la escapatoria sin
374
+ // rastro, que era prosa sin mecanismo: exactamente lo que R17 fue hasta que esto existió.
375
+ //
376
+ // Fijos, sin configurar. La salida ya está adentro de la regla y deja rastro en el artefacto; un umbral
377
+ // configurable agrega una segunda salida que no lo deja, porque se sube el día que molesta —o sea
378
+ // cuando está funcionando— y queda silenciado para todos sin que nadie lo decida caso por caso. R7 sí
379
+ // deja los suyos al proyecto, pero con su razón: dependen del lenguaje y de la superficie. Cinco
380
+ // condiciones que un plan tiene que satisfacer a la vez no dependen de ninguna de las dos.
381
+ const R17 = { taskCriteria: 5, epicCriteria: 7, milestoneTasks: 9 }
382
+
383
+ // Se cuenta lo que está estructurado: criterios de la épica, criterios que hereda una tarea, tareas del
384
+ // hito. La aceptación escrita en prosa no se cuenta —cuántas condiciones tiene una frase es una lectura,
385
+ // y un número inventado ahí sería peor que ninguno—; ésa la mira el review, que para eso está R3.
386
+ function oversizedUnits({ epics = [], milestones = [] }) {
387
+ const errors = []
388
+ const decidir = (what, count, limit) =>
389
+ `${what}: ${count} (umbral ${limit} de R17). Revisá si son dos resultados con vidas distintas y `
390
+ + 'partilo; si es uno solo, partirlo lo empeora — dejalo entero agregando "(sin partir: <razón>)"'
391
+ const juzgar = (unit, what, count, limit) => {
392
+ if (count > limit && !unit.noSplit) errors.push(decidir(what, count, limit))
393
+ }
394
+ for (const epic of epics) {
395
+ juzgar(epic, `roadmap/${epic.file}: criterios`, epic.criteria.length, R17.epicCriteria)
396
+ }
397
+ for (const milestone of milestones) {
398
+ juzgar(milestone, `hito ${milestone.slug}: tareas`, milestone.tasks.length, R17.milestoneTasks)
399
+ for (const task of milestone.tasks) {
400
+ juzgar(task, `BACKLOG ${task.slug}: criterios`, task.criteria.length, R17.taskCriteria)
401
+ }
402
+ }
403
+ return errors
404
+ }
405
+
91
406
  module.exports = {
407
+ testedCriteria,
408
+ validateState,
409
+ oversizedUnits,
410
+ validateAdr,
411
+ validateRules,
412
+ validateBacklogStructure,
413
+ validCommitTrace,
92
414
  validDecisionTrace,
93
415
  validTestTrace,
94
416
  validateDoneEntry,
@@ -4,21 +4,45 @@
4
4
 
5
5
  const fs = require('node:fs')
6
6
  const path = require('node:path')
7
+ const { frontmatter: fields } = require('../core/frontmatter')
8
+ const { PLACEHOLDERS } = require('../core/onboarding')
7
9
 
8
10
  const EPIC_STATES = ['open', 'active', 'closed']
9
11
 
12
+ // Vocabulario común de paradas. Una parada sin nombre obliga a quien la recibe —persona, supervisor o
13
+ // workflow— a reconstruir del estado entero qué pasó, y es lo primero que se pierde cuando cada runner
14
+ // inventa su propia frase. `context` emite las dos que puede determinar solo; el resto las nombra la
15
+ // fase que para.
16
+ const STOP_REASONS = [
17
+ 'awaiting-review', 'blocked-on-human', 'not-ready', 'plan-rejected', 'review-unresolved',
18
+ 'verify-regression', 'verify-inconsistent', 'qa-failed', 'commit-failed', 'budget-low',
19
+ ]
20
+
21
+ // El contrato de una línea de BACKLOG, en un solo lugar: lo usa el lector para armar la cola y el
22
+ // validador para rechazar lo que el lector va a descartar. Separados, el validador aprobaba la forma
23
+ // que el lector no leía, que es la manera más cara de tener las dos cosas.
24
+ const MILESTONE_HEADING = /^##\s+Hito\s+([^\s]+)\s+[—-]\s+(.+)$/
25
+
26
+ // Los carriles, en orden de ceremonia creciente. El orden es parte del vocabulario: la prosa que los
27
+ // describe va de menos a más y `check` lo contrasta, porque un carril leído fuera de orden se elige por
28
+ // su nombre y no por su criterio.
29
+ const LANES = ['express', 'directo', 'lite', 'full']
30
+ const TASK_LINE = new RegExp(
31
+ String.raw`^-\s+\[\s\]\s+\*\*([^*]+)\*\*\s*(?:\[(${LANES.join('|')})\])?\s+[—-]\s+(.+)$`,
32
+ )
33
+ // Lo mismo con cualquier tag: distingue el lane inexistente de la línea sin lane, que es un estado
34
+ // legítimo. Sin esa diferencia las dos caían en «no la lee nadie» y la corrección no era la misma.
35
+ const TASK_LINE_ANY_LANE = /^-\s+\[\s\]\s+\*\*([^*]+)\*\*\s*\[([^\]]+)\]\s+[—-]\s+/
36
+
10
37
  function read(file) {
11
38
  try { return fs.readFileSync(file, 'utf8') } catch { return '' }
12
39
  }
13
40
 
41
+ // Los contratos de planning leen un campo por nombre y no el objeto entero: devolver una función evita
42
+ // que cada llamador tenga que preguntar si la clave existe antes de usarla.
14
43
  function frontmatter(text) {
15
- const block = (text.match(/^---\s*\n([\s\S]*?)\n---/m) || [])[1] || ''
16
- const values = new Map()
17
- for (const line of block.split('\n')) {
18
- const match = line.match(/^([\w-]+):\s*(.*)$/)
19
- if (match) values.set(match[1], match[2].trim().replace(/^['"]|['"]$/g, ''))
20
- }
21
- return (key) => values.get(key) || ''
44
+ const values = fields(text)
45
+ return (key) => values[key] || ''
22
46
  }
23
47
 
24
48
  function section(text, heading) {
@@ -46,6 +70,12 @@ function epicFiles(dir) {
46
70
  return files
47
71
  }
48
72
 
73
+ // La razón por la que una unidad cruza el umbral de R17 y sigue entera. Se escribe con la misma forma
74
+ // parentética que el resto del contrato —`(service: …)`, `(epic: 001)`—, y se busca en el texto que es
75
+ // de esa unidad y de ninguna otra: el archivo entero para la épica, la línea del encabezado para el
76
+ // hito, la línea de la tarea para la tarea.
77
+ const noSplitReason = (text) => ((text.match(/\(sin partir:\s*([^)]+)\)/i) || [])[1] || '').trim()
78
+
49
79
  function criteriaRefs(text) {
50
80
  const refs = []
51
81
  const groups = [
@@ -65,8 +95,16 @@ function readEpics(dir) {
65
95
  return epicFiles(dir).map(({ name, file }) => {
66
96
  const text = read(file)
67
97
  const field = frontmatter(text)
68
- const criteria = [...section(text, /Criterios/i).matchAll(/^-\s+\*\*(C\d+)(?:[^*]*)\*\*\s+[—-]\s+(.+)$/gm)]
69
- .map((match) => ({ id: match[1], text: match[2].trim() }))
98
+ // Mismo corte que ya se arregló para las historias: con la bandera `m`, `$` casa fin de línea, así
99
+ // que un criterio envuelto perdía todo lo que venía detrás del salto —normalmente cómo se verifica
100
+ // y qué debe seguir funcionando—. Se lee hasta el próximo criterio o el fin de la sección, y se
101
+ // devuelve en una sola línea porque quien lo recibe lo lee como aceptación, no como markdown.
102
+ const criterionPattern = new RegExp(
103
+ String.raw`^-\s+\*\*(C\d+)(?:[^*]*)\*\*\s+[—-]\s+([\s\S]*?)(?=\n-\s+\*\*C\d+|(?![\s\S]))`,
104
+ 'gm',
105
+ )
106
+ const criteria = [...section(text, /Criterios/i).matchAll(criterionPattern)]
107
+ .map((match) => ({ id: match[1], text: match[2].trim().replace(/\s*\n\s*/g, ' ') }))
70
108
  // `(?![\s\S])` y no `$`: con la bandera `m` el `$` casa fin de **línea**, así que el cuerpo no ávido
71
109
  // cortaba en el primer salto y una historia envuelta perdía su `(service: …)` y sus `(→ CN)`. El
72
110
  // error que salía era «no declara (service: <ruta>)» — culpaba al autor de algo que sí había escrito.
@@ -91,31 +129,54 @@ function readEpics(dir) {
91
129
  criteria,
92
130
  stories,
93
131
  hasContext: /^##\s+Contexto relevante/im.test(text),
132
+ noSplit: noSplitReason(text),
133
+ // Las líneas que todavía no decidieron nada. Se guardan enteras y no como un booleano porque el
134
+ // error tiene que decir cuál es: «tiene un marcador» manda a releer la épica entera.
135
+ placeholders: text.split('\n').map((line) => line.trim())
136
+ .filter((line) => line && PLACEHOLDERS.test(line)),
94
137
  }
95
138
  }).filter((epic) => epic.status !== 'template' && epic.num !== '000')
96
139
  }
97
140
 
141
+ // El reparto viaja en la línea de la tarea —`(cast: quien-entrega → quien-revisa, otro)`—, y la
142
+ // flecha es lo que los separa. Los revisores son opcionales porque el lane más barato no tiene
143
+ // ninguno, y el reparto entero también: una tarea sin clasificar es el estado que dispara al
144
+ // clasificador, no un error. Devuelve siempre la forma completa para que nadie tenga que preguntar
145
+ // si el campo existe antes de leerlo.
146
+ function readCast(rest) {
147
+ const raw = ((rest.match(/\(cast:\s*([^)]+)\)/i) || [])[1] || '').trim()
148
+ const [build, reviewers] = raw.split(/\s*(?:→|->)\s*/)
149
+ return {
150
+ build: (build || '').trim(),
151
+ review: (reviewers || '').split(',').map((slug) => slug.trim()).filter(Boolean),
152
+ }
153
+ }
154
+
98
155
  function readBacklog(dir) {
99
156
  const text = withoutComments(read(path.join(dir, 'BACKLOG.md')))
100
157
  const milestones = []
101
158
  let current = null
102
159
  for (const line of text.split('\n')) {
103
- const heading = line.match(/^##\s+Hito\s+([^\s]+)\s+[—-]\s+(.+)$/)
160
+ const heading = line.match(MILESTONE_HEADING)
104
161
  if (heading) {
105
- current = { slug: heading[1], title: heading[2].trim(), heading: line.slice(3), tasks: [] }
162
+ current = {
163
+ slug: heading[1], title: heading[2].trim(), heading: line.slice(3),
164
+ noSplit: noSplitReason(line), tasks: [],
165
+ }
106
166
  milestones.push(current)
107
167
  continue
108
168
  }
109
169
  if (/^##\s+/.test(line)) current = null
110
- const task = line.match(/^-\s+\[\s\]\s+\*\*([^*]+)\*\*\s*(?:\[(directo|lite|full)\])?\s+[—-]\s+(.+)$/)
170
+ const task = line.match(TASK_LINE)
111
171
  if (!task || !current) continue
112
172
  const rest = task[3]
113
173
  current.tasks.push({
114
- slug: task[1].trim(), tier: task[2] || '',
174
+ slug: task[1].trim(), tier: task[2] || '', cast: readCast(rest),
115
175
  epic: ((rest.match(/\(epic:\s*(\d{3})\)/) || [])[1] || ''),
116
176
  service: ((rest.match(/\(service:\s*([^)]+)\)/) || [])[1] || '').trim(),
117
177
  acceptance: ((rest.match(/_Aceptaci[oó]n:\s*([^_]+)_/i) || [])[1] || '').trim(),
118
178
  criteria: criteriaRefs(rest),
179
+ noSplit: noSplitReason(rest),
119
180
  })
120
181
  }
121
182
  return milestones
@@ -154,6 +215,29 @@ function readDone(dir) {
154
215
  return { entries, set: new Set(entries.map((entry) => entry.slug)), duplicates: [...new Set(duplicates)] }
155
216
  }
156
217
 
218
+ // Vocabulario cerrado del Estado de `HUMAN_ACTIONS.md`. Es cerrado porque de este campo depende que una
219
+ // tarea se pueda tomar, y quien lo escribe no recibe ninguna señal de haberlo escrito mal: cualquier
220
+ // palabra de fuera del vocabulario deja la fila abierta y su tarea bloqueada sin que nada lo diga.
221
+ const HUMAN_ACTION_STATES = ['pendiente', 'resuelta']
222
+
223
+ // Se lee por el principio de la celda —no por `includes`— para que el detalle que acompaña al estado
224
+ // («resuelta 2026-08-17») siga valiendo sin que una palabra suelta dentro de un texto largo resuelva
225
+ // una fila que sigue abierta. `valid` distingue la fila mal escrita de la fila pendiente: las dos
226
+ // bloquean, pero sólo una es un error que hay que reportar.
227
+ function readHumanActions(dir) {
228
+ const rows = withoutComments(read(path.join(dir, 'HUMAN_ACTIONS.md'))).split('\n')
229
+ .filter((line) => /^\|/.test(line) && !/^\|\s*:?-+/.test(line))
230
+ .map((line) => ({ line, cells: line.split('|').slice(1, -1).map((cell) => cell.trim()) }))
231
+ return rows.filter(({ cells }) => cells.length >= 4 && !/^tarea$/i.test(cells[0]))
232
+ .map(({ line, cells }) => {
233
+ const state = (cells[1].match(new RegExp(`^(${HUMAN_ACTION_STATES.join('|')})\\b`, 'i')) || [])[1] || ''
234
+ return {
235
+ task: cells[0], state: cells[1], origin: cells[2], action: cells[3],
236
+ valid: Boolean(state), resolved: state.toLowerCase() === 'resuelta', raw: line,
237
+ }
238
+ })
239
+ }
240
+
157
241
  function readWip(dir) {
158
242
  const text = read(path.join(dir, 'WIP.md'))
159
243
  if (/^status:\s*IDLE/m.test(text)) return null
@@ -189,5 +273,8 @@ function readInbox(dir) {
189
273
  }
190
274
 
191
275
  module.exports = {
192
- EPIC_STATES, read, frontmatter, readEpics, readBacklog, readDone, readWip, readInbox,
276
+ EPIC_STATES, HUMAN_ACTION_STATES, LANES, MILESTONE_HEADING, STOP_REASONS,
277
+ TASK_LINE, TASK_LINE_ANY_LANE,
278
+ read, section, withoutComments, frontmatter, readEpics, readBacklog, readDone, readWip,
279
+ readInbox, readHumanActions,
193
280
  }
@@ -0,0 +1,52 @@
1
+ 'use strict'
2
+
3
+ // El estado de un planning ya leído y cuál es la tarea que sigue. Es un nivel por encima de `parser`,
4
+ // que lee un archivo por vez: acá se compone lo que hace falta para decidir, y se aplica la precedencia
5
+ // que fija el protocolo. Vivía en el CLI, donde nadie podía ejercitarlo sin lanzar un proceso.
6
+
7
+ const P = require('./parser')
8
+
9
+ function snapshot(root) {
10
+ const milestones = P.readBacklog(root)
11
+ return {
12
+ epics: P.readEpics(root),
13
+ milestones,
14
+ done: P.readDone(root),
15
+ wip: P.readWip(root),
16
+ inbox: P.readInbox(root),
17
+ queued: new Set(milestones.flatMap((m) => m.tasks.map((t) => t.slug))),
18
+ }
19
+ }
20
+
21
+
22
+ // Acciones humanas que todavía bloquean: las pendientes y también las mal escritas, porque una fila
23
+ // cuyo estado no se entiende no se puede dar por resuelta. `check` es quien las nombra.
24
+ function pendingHumanActions(root) {
25
+ return P.readHumanActions(root).filter((row) => !row.resolved)
26
+ .map((row) => ({ task: row.task, state: row.state, action: row.action }))
27
+ }
28
+
29
+
30
+ // Selecciona la tarea que un runner debe ejecutar ahora, con la misma precedencia que el protocolo:
31
+ // WIP activo primero —es el mutex y manda incluso si tiene una acción humana abierta—, si no la
32
+ // primera tarea no terminada y no bloqueada del primer hito.
33
+ function currentTask({ milestones, done, wip }, blockers = []) {
34
+ const queue = milestones.flatMap((milestone) => milestone.tasks.map((task) => ({ ...task, hito: milestone.slug })))
35
+ if (wip) {
36
+ const active = queue.find((task) => task.slug === wip.task)
37
+ || {
38
+ slug: wip.task, hito: '', tier: '', cast: { build: '', review: [] },
39
+ service: wip.service, acceptance: '', epic: '', criteria: [],
40
+ }
41
+ return { task: active, skipped: [] }
42
+ }
43
+ const blocked = new Set(blockers.map((action) => action.task))
44
+ const pending = queue.filter((task) => !done.set.has(task.slug))
45
+ return {
46
+ task: pending.find((task) => !blocked.has(task.slug)) || null,
47
+ skipped: pending.filter((task) => blocked.has(task.slug)).map((task) => task.slug),
48
+ }
49
+ }
50
+
51
+
52
+ module.exports = { snapshot, pendingHumanActions, currentTask }
@@ -0,0 +1,64 @@
1
+ # Change Review
2
+
3
+ Decide si un cambio ya construido se puede entregar. No lo diseña, no lo construye y no lo despliega:
4
+ mira lo que existe y firma, o dice qué falta para poder firmar.
5
+
6
+ Es el único momento del ciclo donde las disciplinas tienen que poder **discrepar de forma acotada**, y
7
+ por eso es un recorrido y no un cargo. Un revisor solo promedia: mira lo que sabe mirar y aprueba el
8
+ resto por omisión. Acá cada disciplina responde lo suyo y la firma es de quien responde por el cambio.
9
+
10
+ ## Cuándo
11
+
12
+ Cuando hay un cambio construido esperando entrega. Si todavía no está construido, lo que corresponde es
13
+ `technical-design`; si está roto en producción, `defect-triage`; si ya se entregó y falló,
14
+ `incident-review`.
15
+
16
+ ## Las etapas
17
+
18
+ | etapa | cargo | pregunta |
19
+ |---|---|---|
20
+ | `scope` | tech-lead | ¿contra qué se revisa, y qué decisiones vigentes lo restringen? |
21
+ | `correctness` | el dueño de la superficie que cambió | ¿hace lo que dice, y qué rompe que nadie nombró? |
22
+ | `evidence` | qa-engineer | ¿qué prueba sostiene cada criterio, y qué está verde sin estar cubierto? |
23
+ | `exposure` | security-engineer | ¿qué queda alcanzable que antes no lo estaba, y por quién? |
24
+ | `operability` | site-reliability-engineer | ¿cómo falla, qué lo muestra y cómo se deshace? |
25
+ | `decide` | tech-lead | el veredicto, con sus tres salidas |
26
+
27
+ ## El veredicto tiene tres salidas
28
+
29
+ Aprobar; aprobar con lo que hay que corregir antes de entregar; y no poder aprobar. Con dos, las dos
30
+ últimas se confunden: lo que no se resuelve dentro de este cambio gasta igual la vuelta de corrección
31
+ que no lo va a arreglar, y una mejora opinable manda a tocar código por un riesgo que nadie pidió.
32
+
33
+ Dentro del veredicto, lo que impide entregar se separa de lo que no. Lo primero se corrige; lo segundo
34
+ se registra con su dueño y su condición de reapertura. Una objeción que no se atendió **queda escrita
35
+ con su autor**: promediarla la borra sin resolverla.
36
+
37
+ ## Aprobar sin mirar es el modo de falla
38
+
39
+ Un veredicto que no enumera qué se inspeccionó no es un veredicto: es una firma. Por eso `scope` cierra
40
+ con la lista literal —archivo, diff, comando con su salida— y `decide` dice qué quedó sin inspeccionar
41
+ y por qué. Un número agregado —cobertura, tests en verde, líneas cambiadas— no sustituye a esa lista:
42
+ mide qué se ejecutó, no qué se atrapó.
43
+
44
+ ## Lo que este recorrido no hace
45
+
46
+ - **No construye ni corrige.** Devuelve qué hay que corregir; corregirlo es de quien lo construyó.
47
+ - **No despliega ni promueve.** La entrega es una decisión con su propia autorización.
48
+ - **No inventa el criterio.** Si no hay criterio de aceptación contra el cual revisar, eso es lo que
49
+ informa: revisar contra un criterio supuesto produce una firma que no vale.
50
+
51
+ ## Agentes condicionales
52
+
53
+ | agente | cuándo |
54
+ |---|---|
55
+ | `backend-engineer` | el cambio toca servicio, contrato o trabajo asíncrono |
56
+ | `frontend-engineer` | toca interfaz web |
57
+ | `mobile-engineer` | toca la aplicación móvil |
58
+ | `database-administrator` | toca esquema, migración o datos en reposo |
59
+ | `privacy-compliance-specialist` | toca datos personales, su base legal o su retención |
60
+
61
+ La etapa `correctness` la ocupa el dueño de la superficie que cambió; `backend-engineer` es el default
62
+ del contrato y se reemplaza por el que corresponda antes de correr el recorrido.
63
+
64
+ Validar siempre con `node tools/ops.js flow check change-review` antes de usarlo.