@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,18 +2,31 @@
2
2
  // Descubre proyecto, servicios y límites desde ops.config.json; no codifica rutas ni proveedores.
3
3
  export const meta = {
4
4
  name: 'autobuild',
5
- description: 'Triage → Pick → CastReadyPlan → Build → Review → Verify → QA → Commit → Done',
5
+ description: 'Triage → Pick → ClassifyPlanWIP → Build → Review → Verify → QA → Commit → Done',
6
6
  whenToUse: 'Ejecutar un hito aprobado con recuperación por WIP y checkpoint humano entre hitos.',
7
+ // Escritas una por una y no derivadas de una lista: el runtime exige que `meta` sea un literal puro
8
+ // —sin llamadas, variables ni interpolación— y con un `.map` acá rechazaba el archivo entero antes de
9
+ // la primera fase. Escribirlas también les da un detalle propio, que es lo que se lee al autorizar.
7
10
  phases: [
8
- 'Triage', 'Pick', 'Cast', 'Ready', 'Decompose', 'Plan', 'Critique', 'Build', 'Review',
9
- 'Verify', 'QA', 'Commit', 'Done', 'Closing',
10
- ].map((title) => ({ title, detail: `Fase ${title} del protocolo agnóstico` })),
11
+ { title: 'Triage', detail: 'Contrato del proyecto y estado de planning' },
12
+ { title: 'Pick', detail: 'La próxima tarea, o la épica que falta expandir' },
13
+ { title: 'Classify', detail: 'Carril y reparto de la tarea que no los declara' },
14
+ { title: 'Ready', detail: 'Aceptación concreta y sin decisiones pendientes' },
15
+ { title: 'Decompose', detail: 'Partir la tarea que no entra en el tope de horas' },
16
+ { title: 'Plan', detail: 'El cambio más chico que satisface la aceptación' },
17
+ { title: 'Critique', detail: 'El plan atacado antes de escribir código' },
18
+ { title: 'WIP', detail: 'El plan aprobado persistido antes del primer cambio' },
19
+ { title: 'Build', detail: 'Implementación con la prueba en rojo primero' },
20
+ { title: 'Review', detail: 'El diff real revisado por el dueño de cada dominio' },
21
+ { title: 'Verify', detail: 'Los gates del servicio y la aceptación que ninguna prueba codifica' },
22
+ { title: 'QA', detail: 'El comportamiento ejercitado como lo ve quien lo usa' },
23
+ { title: 'Commit', detail: 'Conventional Commits, uno por naturaleza del diff, sin push' },
24
+ { title: 'Done', detail: 'Cierre atómico en DONE con el WIP en IDLE' },
25
+ { title: 'Closing', detail: 'Check de planning y checkpoint humano del hito' },
26
+ ],
11
27
  }
12
28
 
13
- // El prefijo lo completa `automation install`. No puede venir del entorno: el runtime de workflows no
14
- // expone `process`, así que leerlo de ahí reventaba el archivo entero en su primera línea. Viaja
15
- // escrito, relativo a la carpeta donde se abre la herramienta, que es el cwd de los agentes.
16
- const ROOT = '{{OPS_DIR}}'.replace(/\/+$/, '') || '.'
29
+ {{INCLUDE:shared/workflow-root.js}}
17
30
  const CONFIG = `${ROOT}/ops.config.json`
18
31
  const P = `${ROOT}/planning`
19
32
  const BACKLOG = `${P}/BACKLOG.md`
@@ -25,12 +38,20 @@ const ROADMAP = `${P}/roadmap`
25
38
 
26
39
  // Estado de planning tal como lo emite `ops context --json`; ningún modelo parsea BACKLOG ni WIP.
27
40
  const CONTEXT = {
28
- type: 'object', additionalProperties: false, required: ['blocked', 'hasTask', 'wipActive', 'queued'],
41
+ type: 'object', additionalProperties: false,
42
+ required: ['blocked', 'hasTask', 'wipActive', 'queued', 'cast'],
29
43
  properties: {
30
44
  blocked: { type: 'string' }, hasTask: { type: 'boolean' }, wipActive: { type: 'boolean' },
31
45
  queued: { type: 'integer' }, slug: { type: 'string' }, hito: { type: 'string' },
32
46
  service: { type: 'string' }, acceptance: { type: 'string' }, epic: { type: 'string' },
33
- lane: { type: 'string', enum: ['', 'directo', 'lite', 'full'] },
47
+ lane: { type: 'string', enum: ['', 'express', 'directo', 'lite', 'full'] },
48
+ // Quién entrega y quiénes miran, decidido al clasificar la tarea y escrito en su línea. Viene
49
+ // siempre, aunque venga vacío: preguntar si el campo existe antes de leerlo es la clase de borde
50
+ // que se olvida en una rama y revienta en la otra.
51
+ cast: {
52
+ type: 'object', additionalProperties: false, required: ['build', 'review'],
53
+ properties: { build: { type: 'string' }, review: { type: 'array', items: { type: 'string' } } },
54
+ },
34
55
  blockedTasks: { type: 'array', items: { type: 'string' } },
35
56
  },
36
57
  }
@@ -62,16 +83,45 @@ const PLAN = {
62
83
  testStrategy: { type: 'string' },
63
84
  },
64
85
  }
86
+ // Un veredicto sin manifiesto no se puede contrastar: `consulted` enumera lo que quien revisó abrió de
87
+ // verdad, y es lo único que separa al que miró del que aprobó de memoria. No prueba que lo haya leído bien
88
+ // —para eso habría que releerlo—, y esa asimetría es la que lo deja barato (R14).
89
+ // Tres estados porque hay tres cosas distintas que decir, y con un booleano dos se pisan: «no puedo
90
+ // aprobar esto» y «apruebo con algo que hay que corregir antes de entregar» caían las dos en el mismo
91
+ // `false`, así que la primera gastaba igual una vuelta de corrección sobre algo que la corrección no
92
+ // arregla. Y `blocking` separa lo que impide entregar de la mejora opinable, que hasta ahora mandaba a
93
+ // tocar código con la misma fuerza que un defecto.
65
94
  const DECISION = {
66
- type: 'object', additionalProperties: false, required: ['approved', 'concerns'],
67
- properties: { approved: { type: 'boolean' }, concerns: { type: 'array', items: { type: 'string' } } },
95
+ type: 'object', additionalProperties: false, required: ['verdict', 'concerns', 'consulted'],
96
+ properties: {
97
+ verdict: { type: 'string', enum: ['aprobado', 'con-condiciones', 'bloqueado'] },
98
+ concerns: { type: 'array', items: { type: 'object', additionalProperties: false,
99
+ required: ['detail', 'blocking'],
100
+ properties: { detail: { type: 'string' }, blocking: { type: 'boolean' } },
101
+ } },
102
+ consulted: { type: 'array', items: { type: 'string' } },
103
+ },
68
104
  }
105
+ // Un exit code dice que el test corrió, no que pruebe lo que la tarea prometió: un test que asercia de
106
+ // menos —o que ni existe— sale verde igual, y el guard de verify tampoco lo ve porque también mira exit
107
+ // codes. Por eso `uncovered` se contrasta contra la aceptación leyendo el fuente, no la salida (R9).
69
108
  const VERIFY = {
70
- type: 'object', additionalProperties: false, required: ['passed', 'commands', 'details'],
109
+ type: 'object', additionalProperties: false, required: ['passed', 'commands', 'details', 'uncovered'],
71
110
  properties: {
72
111
  passed: { type: 'boolean' }, details: { type: 'string' },
112
+ // Dos causas que se leen igual en el resultado y piden cosas opuestas: a una le falta trabajo que
113
+ // el propio recorrido puede hacer, a la otra le falta una decisión que no es suya. Sin separarlas,
114
+ // la corrida frena por las dos y una persona termina resolviendo lo que se resolvía solo.
115
+ uncovered: { type: 'array', items: { type: 'object', additionalProperties: false,
116
+ required: ['criterion', 'cause'],
117
+ properties: {
118
+ criterion: { type: 'string' },
119
+ cause: { type: 'string', enum: ['missing-test', 'ambiguous'] },
120
+ },
121
+ } },
73
122
  commands: { type: 'array', items: { type: 'object', required: ['cmd', 'exitCode'], properties: {
74
123
  cmd: { type: 'string' }, exitCode: { type: 'integer' }, note: { type: 'string' },
124
+ ranTests: { type: 'boolean' },
75
125
  } } },
76
126
  regressions: { type: 'array', items: { type: 'string' } },
77
127
  preExisting: { type: 'array', items: { type: 'string' } },
@@ -84,6 +134,33 @@ const QA = {
84
134
  bugs: { type: 'array', items: { type: 'string' } },
85
135
  },
86
136
  }
137
+ // RED/GREEN sin registro es una intención: después nadie distingue el test que se vio fallar del que se
138
+ // escribió cuando el código ya andaba, y ese segundo no prueba su aserción, sólo que corre. Por eso
139
+ // `redFirst` trae el fallo literal de la corrida roja y no la afirmación de que la hubo (R14).
140
+ const BUILD = {
141
+ type: 'object', additionalProperties: false,
142
+ required: ['completed', 'summary', 'redFirst', 'discovered', 'closedTask'],
143
+ properties: {
144
+ completed: { type: 'boolean' }, summary: { type: 'string' }, closedTask: { type: 'boolean' },
145
+ redFirst: { type: 'array', items: { type: 'object', additionalProperties: false,
146
+ required: ['test', 'failure'],
147
+ properties: { test: { type: 'string' }, failure: { type: 'string' } },
148
+ } },
149
+ blockers: { type: 'array', items: { type: 'string' } },
150
+ // Estricto en el cómo, flexible en el qué: lo que aparece y el plan no previó tiene dos destinos y
151
+ // ninguno es el silencio. Un caso que esta tarea puede fijar entra con la prueba que lo fija —por eso
152
+ // su `test` tiene que estar en `redFirst`—; una decisión que no le toca queda registrada con quién
153
+ // puede tomarla. Implementarlo sin prueba lo vuelve invisible y descartarlo lo pierde: en los dos
154
+ // casos el próximo que lo encuentre empieza de cero.
155
+ discovered: { type: 'array', items: { type: 'object', additionalProperties: false,
156
+ required: ['kind', 'detail'],
157
+ properties: {
158
+ kind: { type: 'string', enum: ['edge', 'open'] },
159
+ detail: { type: 'string' }, test: { type: 'string' },
160
+ },
161
+ } },
162
+ },
163
+ }
87
164
  const COMMIT = {
88
165
  type: 'object', additionalProperties: false, required: ['committed'],
89
166
  properties: {
@@ -102,17 +179,34 @@ const OWNERS = {
102
179
  commit: 'release-manager',
103
180
  }
104
181
 
105
- const CAST_RULES = 'Elegís quién trabaja, no qué se hace. No inventes slugs: usá sólo los que ' +
106
- 'devuelve el CLI. Un cargo se suma por riesgo, plataforma o alcance, nunca por rutina.'
182
+ // Clasificar decide dos cosas de una: cuántas perspectivas merece la tarea —el lane— y cuáles —el
183
+ // cast—. El criterio va escrito porque sin él la clasificación es intuición, y la intuición se
184
+ // infla hacia arriba: toda tarea termina pareciendo `full`, que es el carril que no hay que
185
+ // justificar. Lo que decide es la superficie del cambio, no su tamaño en líneas: un `if` en el
186
+ // chequeo de permisos es `full`, y un componente entero de presentación puede ser `directo`.
187
+ const CLASSIFY_RULES = 'Clasificás quién trabaja y cuánta ceremonia merece la tarea; no decidís qué ' +
188
+ 'se hace ni lo hacés. Lane: `express` si la aceptación nombra un valor literal y el resultado no ' +
189
+ 'lo mira nadie —un typo, un umbral interno, un renombre—; `directo` si es igual de mecánico pero ' +
190
+ 'cambia una superficie que alguien ve; `lite` si es comportamiento nuevo ' +
191
+ 'dentro de un servicio con superficie conocida; `full` si cruza contratos entre servicios, datos, ' +
192
+ 'autenticación o permisos, o si la aceptación tiene un borde sin decidir. Cast: quien implementa ' +
193
+ 'según la plataforma del servicio, y los revisores que la superficie realmente justifica ' +
194
+ '—seguridad si toca autenticación, permisos, criptografía o datos sensibles; privacidad si toca ' +
195
+ 'datos personales; sre si toca disponibilidad, límites o despliegue; ux si cambia una superficie ' +
196
+ 'que usa una persona; el de datos o modelos si los toca—. Sumar un cargo que no aporta es ruido ' +
197
+ 'que diluye la revisión. No inventes slugs: usá sólo los que devuelve el CLI.'
107
198
 
108
- const CAST = {
109
- type: 'object', additionalProperties: false, required: ['build'],
199
+ const CLASSIFICATION = {
200
+ type: 'object', additionalProperties: false, required: ['classified'],
110
201
  properties: {
111
- build: { type: 'string' },
112
- review: { type: 'array', items: { type: 'string' } },
113
- verify: { type: 'array', items: { type: 'string' } },
114
- qa: { type: 'array', items: { type: 'string' } },
115
- reason: { type: 'string' },
202
+ classified: { type: 'array', items: { type: 'object', additionalProperties: false,
203
+ required: ['slug', 'lane', 'build'],
204
+ properties: {
205
+ slug: { type: 'string' }, lane: { type: 'string', enum: ['express', 'directo', 'lite', 'full'] },
206
+ build: { type: 'string' }, review: { type: 'array', items: { type: 'string' } },
207
+ reason: { type: 'string' },
208
+ },
209
+ } },
116
210
  },
117
211
  }
118
212
 
@@ -128,43 +222,59 @@ const CONTRACT = {
128
222
  }
129
223
 
130
224
  // Preámbulo invariante: no depende del proyecto y nunca obliga a leer un archivo.
131
- const BASE = `Never invent credentials or decisions; register external blockers in ${HUMAN}. Never execute INBOX ` +
132
- `automatically. Never push, deploy, amend, force, or use git add -A. Never edit process governance, and do not ` +
133
- `edit planning bookkeeping unless this workflow explicitly requests it.`
134
- // Cierre del recorrido. El runtime no trae un helper de cierre —el valor devuelto por el script ya
135
- // es el resultado—, y darlo por sentado hacía reventar el archivo justo al terminar: después de
136
- // gastar cada etapa, en la línea que las cerraba.
137
- function finish(result) {
138
- log(`Fin: ${JSON.stringify(result)}`)
139
- return result
140
- }
141
-
142
- const stop = (reason, detail = '') => {
143
- log(`Checkpoint: ${reason}${detail ? ` ${detail}` : ''}`)
144
- return finish({ stopped: true, reason, detail })
145
- }
225
+ const BASE = `Nunca inventes credenciales ni decisiones; registrá los bloqueos externos en ${HUMAN}. Nunca ` +
226
+ `ejecutes INBOX por tu cuenta. Nunca hagas push, deploy, amend, force ni git add -A. No edites la gobernanza ` +
227
+ `del proceso, y no toques la contabilidad de planning salvo que este recorrido te lo pida explícitamente.`
228
+ // Acompaña a todo prompt con schema DECISION: el schema obliga a llenar `consulted`, y esto obliga a
229
+ // llenarlo con lo que se abrió en vez de con lo que se pensaba mirar.
230
+ const MANIFEST = ' Enumerá en consulted cada archivo, diff o comando que hayas abierto de verdad, con su ruta.'
231
+ // Acompaña a todo prompt con schema DECISION. El criterio va escrito porque tres estados sin criterio son
232
+ // tres nombres, y el del medio —el que evita gastar una corrección en lo que no se corrige— es el que se
233
+ // pierde primero.
234
+ const VERDICT = ' Cerrá con verdict=aprobado si no queda nada por corregir antes de entregar; ' +
235
+ 'verdict=con-condiciones si lo que falta se corrige dentro de este mismo cambio; y verdict=bloqueado ' +
236
+ 'si algo no se resuelve acá —el diseño no lo cubre, falta una decisión ajena, o la corrección excede el ' +
237
+ 'alcance—. Marcá blocking=true sólo en el hallazgo que impide entregar: el resto queda registrado y no ' +
238
+ 'manda a tocar código.'
239
+ // Atajo para reconocer un gate que corrió pruebas sin preguntarle a nadie. No alcanza solo y no
240
+ // pretende hacerlo: `mvn verify`, `gradle build`, `tox`, `bin/rails t` y cualquier `make` con nombre
241
+ // propio corren pruebas y no se parecen a esto, así que el que corrió el comando además lo declara en
242
+ // `ranTests` y vale cualquiera de los dos. Una lista de nombres siempre le va a faltar el siguiente;
243
+ // lo que no puede es frenar una corrida legítima por no conocerlo.
244
+ // El borde izquierdo va explícito en vez de `\b` porque `\b(?:` se lee igual que una llamada a `b()`
245
+ // y la comprobación de identificadores del paquete de pruebas la marca como función inexistente.
246
+ // Lo que hay que corregir antes de entregar. El resto de los hallazgos no desaparece: se registra.
247
+ const blockers = (verdict) => verdict.concerns.filter((one) => one.blocking).map((one) => one.detail)
248
+ const RUNS_TESTS = /(?:^|[\s/:=-])(?:tests?|specs?|pytest|jest|vitest|mocha|rspec|phpunit|ci|check)\b/i
249
+ {{INCLUDE:shared/workflow-finish.js}}
146
250
 
147
251
  phase('Triage')
148
252
  // El contrato se lee una sola vez por corrida y viaja como texto: ningún subagente relee AGENTS.md,
149
253
  // ops.config.json ni PROTOCOL.md. `ops check` y el guard planning-drift siguen validando el resultado.
150
254
  const contract = await agent(
151
- `${BASE}\n\nRead ${ROOT}/AGENTS.md, ${CONFIG} and ${P}/PROTOCOL.md exactly once and read nothing else. Report the ` +
152
- `config values verbatim: project, workspaceRoots as "namepath" entries, runner.maxTaskHours, ` +
153
- `runner.commitPerTask, and runner.humanCheckpointBetweenMilestones as humanCheckpoint. Copy the "## Contratos" ` +
154
- `section of PROTOCOL.md into contracts literally, without rewording, summarising or reordering it. ` +
155
- `In boundaries list only limits stated in AGENTS.md that constrain autonomous execution.`,
255
+ `${BASE}\n\nLeé ${ROOT}/AGENTS.md, ${CONFIG} y ${P}/PROTOCOL.md una sola vez y no leas nada más. Reportá los ` +
256
+ `valores de configuración textualmente: project, workspaceRoots como entradas "nombreruta", ` +
257
+ `runner.maxTaskHours, runner.commitPerTask y runner.humanCheckpointBetweenMilestones como humanCheckpoint. ` +
258
+ `Copiá la sección "## Contratos" de PROTOCOL.md dentro de contracts tal cual, sin reformular, resumir ni ` +
259
+ `reordenar. En boundaries listá sólo los límites que AGENTS.md enuncia y que restringen la ejecución autónoma.`,
156
260
  { schema: CONTRACT, label: 'contract-digest' },
157
261
  )
158
262
  if (!contract) return stop('contract-unavailable', `no se pudo leer ${CONFIG} ni ${P}/PROTOCOL.md`)
159
263
 
160
- const limits = (contract.boundaries || []).length ? ` Project limits: ${contract.boundaries.join('; ')}.` : ''
264
+ const bounds = contract.boundaries || []
265
+ const limits = bounds.length ? ` Límites del proyecto: ${bounds.join('; ')}.` : ''
161
266
  // Alcance de escritura: para subagentes que tocan código o ejecutan gates del producto.
162
- const SCOPE = `${BASE}\n\nProject ${contract.project}. workspaceRoots is the complete writable product boundary: ` +
163
- `${contract.workspaceRoots.join('; ')}.${limits} This preamble already carries the contract; do not re-read ` +
164
- `${ROOT}/AGENTS.md, ${CONFIG} or ${P}/PROTOCOL.md.`
267
+ const SCOPE = `${BASE}\n\nProyecto ${contract.project}. workspaceRoots es el límite completo de escritura del ` +
268
+ `producto: ${contract.workspaceRoots.join('; ')}.${limits} Este preámbulo ya trae el contrato; no vuelvas a leer ` +
269
+ `${ROOT}/AGENTS.md, ${CONFIG} ni ${P}/PROTOCOL.md.`
165
270
  // Formatos de planning: sólo para subagentes que escriben roadmap, BACKLOG, WIP, DONE o gates.
166
- const LEDGER = `${SCOPE}\n\nPlanning contracts, verbatim from ${P}/PROTOCOL.md:\n${contract.contracts}`
271
+ const LEDGER = `${SCOPE}\n\nContratos de planning, textuales de ${P}/PROTOCOL.md:\n${contract.contracts}`
167
272
 
273
+ // Un subagente puede morir —error terminal tras reintentos, o alguien que lo saltea— y entonces el
274
+ // runtime devuelve `null`. Sin comprobarlo, la primera propiedad que se le pide revienta el recorrido
275
+ // con un TypeError en la fase que sea, y lo que quedó a medias es una tarea con WIP escrito y código
276
+ // sin revisar. Cada llamada corta con su etapa puesta: «no contestó» no es lo mismo que «dijo que no»,
277
+ // y sólo la segunda significa que alguien juzgó algo.
168
278
  const read = (prompt, options = {}) => agent(`${BASE}\n\n${prompt}`, options)
169
279
  const run = (prompt, options = {}) => agent(`${SCOPE}\n\n${prompt}`, options)
170
280
  const write = (prompt, options = {}) => agent(`${LEDGER}\n\n${prompt}`, options)
@@ -172,9 +282,9 @@ const write = (prompt, options = {}) => agent(`${LEDGER}\n\n${prompt}`, options)
172
282
  // Gate, mutex de WIP y selección de tarea salen de un comando determinista: AWAITING_REVIEW, BACKLOG,
173
283
  // WIP y HUMAN_ACTIONS nunca entran al contexto de un modelo, y su tamaño deja de costar tokens.
174
284
  const readContext = () => read(
175
- `Run "node tools/ops.js context ${P} --json" from ${ROOT} and report only what it printed. Derive hasTask from ` +
176
- `whether task is null, wipActive from whether wip is null, and lane from task.tier; copy slug, hito, service, ` +
177
- `acceptance and epic from task. The command is the source of truth: do not open planning files to complete it.`,
285
+ `Corré "node tools/ops.js context ${P} --json" desde ${ROOT} y reportá sólo lo que imprimió. Derivá hasTask ` +
286
+ `de si task es null, wipActive de si wip es null y lane de task.tier; copiá slug, hito, service, acceptance, ` +
287
+ `epic y cast de task. El comando es la fuente de verdad: no abras archivos de planning para completarlo.`,
178
288
  { schema: CONTEXT, label: 'planning-context' },
179
289
  )
180
290
 
@@ -182,206 +292,377 @@ let planning = await readContext()
182
292
  if (!planning) return stop('context-unavailable', `no se pudo leer el estado de ${P}`)
183
293
  if (planning.blocked) return stop('awaiting-human-review', `${GATE} tiene un checkpoint humano sin resolver`)
184
294
 
185
- let currentHito = planning.wipActive ? planning.hito : ''
295
+ let currentMilestone = planning.wipActive ? planning.hito : ''
186
296
  const completed = []
187
- let safety = 0
297
+ // Tope de tareas por corrida. No protege de un hito grande —cincuenta tareas en un hito es un problema
298
+ // de planificación, no de ejecución— sino de un ciclo: una tarea que vuelve a quedar elegible corre
299
+ // para siempre. Se corta con motivo porque agotarlo en silencio se lee igual que haber terminado.
300
+ const MAX_TASKS = 50
301
+ let rounds = 0
302
+ // Tareas que ya pasaron por el clasificador en esta corrida. Sin esto, una que vuelve sin lane
303
+ // —porque la escritura falló o el modelo la salteó— se reclasifica en cada vuelta del bucle.
304
+ const classified = new Set()
188
305
 
189
- while (safety++ < 50) {
306
+ while (rounds++ < MAX_TASKS) {
190
307
  phase('Pick')
191
308
  if (!planning.hasTask && !planning.queued) {
192
309
  const expansion = await write(
193
- `Read ${ROADMAP}. Expand only the next approved open epic into a new hito of ${BACKLOG}, preserving each story ` +
194
- `slug, its criteria references and its service. Never promote ${P}/INBOX.md. Report whether you wrote anything.`,
310
+ `Leé ${ROADMAP}. Expandí sólo la próxima épica abierta y aprobada en un hito nuevo de ${BACKLOG}, ` +
311
+ `conservando el slug de cada historia, sus referencias a criterios y su servicio. Nunca promuevas ` +
312
+ `${P}/INBOX.md. Reportá si escribiste algo.`,
195
313
  { schema: EXPANSION },
196
314
  )
315
+ if (!expansion) return stop('agent-unavailable', 'Pick no devolvió resultado')
197
316
  if (!expansion.expanded) break
198
317
  planning = await readContext()
199
318
  if (!planning) return stop('context-unavailable', `no se pudo releer el estado de ${P}`)
200
319
  }
201
- if (!planning.hasTask || (currentHito && planning.hito !== currentHito)) break
320
+ if (!planning.hasTask || (currentMilestone && planning.hito !== currentMilestone)) break
202
321
  const task = {
203
322
  id: planning.slug, hito: planning.hito, service: planning.service,
204
323
  acceptance: planning.acceptance, epic: planning.epic,
205
324
  }
206
- currentHito = task.hito
207
- const direct = planning.lane === 'directo'
208
- const lite = planning.lane === 'lite'
325
+ currentMilestone = task.hito
209
326
 
210
- // Quién ejecuta cada fase. Los dueños por defecto son fijos y no gastan una llamada; los
211
- // condicionales entran por riesgo, plataforma y alcance —nunca por rutina—, que es la misma
212
- // regla que ya usa el team. En `directo` no hay condicionales: el lane baja ceremonia.
213
- const cast = { ...OWNERS, build: '' }
214
- if (!direct) {
215
- phase('Cast')
216
- const chosen = await read(
217
- `${CAST_RULES}\n\nTarea ${task.id} en ${task.service}. Aceptación: ${task.acceptance}.\n` +
218
- `Run "node tools/ops.js agents list ${ROOT} --json" and choose only from the slugs it lists.\n` +
219
- `Elegí el cargo que implementa según la plataforma del servicio${lite ? '.' : ', y los cargos ' +
220
- 'condicionales que la superficie realmente justifica: seguridad si toca autenticación, permisos, ' +
221
- 'criptografía o datos sensibles; privacidad si toca datos personales; sre si toca disponibilidad, ' +
222
- 'límites o despliegue; ux si cambia una superficie que usa una persona; y el que corresponda a ' +
223
- 'datos o modelos si los toca. Dejá vacío lo que no aplique: sumar un cargo que no aporta es ruido ' +
224
- 'que diluye la revisión.'}`,
225
- { schema: CAST, label: 'cast' },
327
+ // Ver la tarea y, si no está clasificada, clasificarla antes de ejecutarla. Se hace una vez por
328
+ // tarea y se escribe en su línea, así que la decisión sobrevive a la corrida y la puede corregir
329
+ // una persona antes de que se ejecute nada al revés que la fase Cast, que la tomaba en caliente,
330
+ // costaba una llamada por tarea y la tiraba al terminar. Clasifica el hito entero de una sola
331
+ // llamada: lo que cuesta una vez no debería costar una vez por tarea.
332
+ //
333
+ // Un WIP activo no se reclasifica: la tarea ya está en vuelo con las fases que le tocaron, y
334
+ // cambiárselas a mitad de camino la deja con un plan aprobado bajo otro carril.
335
+ const unclassified = !planning.lane || !planning.cast.build
336
+ if (unclassified && !planning.wipActive && !classified.has(task.id)) {
337
+ phase('Classify')
338
+ classified.add(task.id)
339
+ const classification = await write(
340
+ `${CLASSIFY_RULES}\n\nRun "node tools/ops.js agents list ${ROOT} --json" and choose only from the slugs ` +
341
+ `it lists.\nClasificá en ${BACKLOG} todas las tareas en cola que no declaren lane o no declaren cast, ` +
342
+ `empezando por ${task.id} en ${task.service} —aceptación: ${task.acceptance}—. El lane va entre ` +
343
+ `corchetes después del slug y el reparto al final de la línea, con la forma ` +
344
+ `"(cast: quien-entrega → quien-revisa, otro)". No toques nada más de la línea, ni el orden del hito, ` +
345
+ `ni las tareas que ya declaran las dos cosas. Reportá lo que escribiste.`,
346
+ { schema: CLASSIFICATION },
226
347
  )
227
- if (chosen) {
228
- cast.build = chosen.build || ''
229
- for (const key of ['review', 'verify', 'qa']) {
230
- cast[key] = [OWNERS[key], ...(lite ? [] : chosen[key] || [])].filter(Boolean).join(', ')
231
- }
232
- log(`Cargos: build=${cast.build || '(sin asignar)'} · review=${cast.review} · qa=${cast.qa}`)
348
+ if (classification && classification.classified.length) {
349
+ log(`Clasificadas: ${classification.classified
350
+ .map((one) => `${one.slug} [${one.lane}] ${one.build}`).join(' · ')}`)
351
+ planning = await readContext()
352
+ if (!planning) return stop('context-unavailable', `no se pudo releer el estado de ${P}`)
353
+ continue
233
354
  }
355
+ // Sin clasificación no se frena la tarea: `full` es el carril que no saltea nada, así que lo que
356
+ // se pierde es tiempo y no evidencia. Frenar acá cobraría una interrupción por lo único que el
357
+ // recorrido puede resolver solo.
358
+ log(`${task.id} sigue sin clasificar: corre por el carril completo`)
234
359
  }
360
+
361
+ const express = planning.lane === 'express'
362
+ const direct = planning.lane === 'directo'
363
+ const lite = planning.lane === 'lite'
364
+ // Lo mecánico no se planifica ni se pregunta si está listo: el clasificador ya leyó la aceptación y
365
+ // dijo que nombra un valor literal. Volver a preguntarlo son dos llamadas para llegar al mismo lado.
366
+ const mechanical = express || direct
367
+
368
+ // Quién ejecuta cada fase. Los dueños por defecto son fijos y no gastan una llamada; quien
369
+ // implementa y quiénes revisan por riesgo salen de la línea de la tarea. Los revisores valen en
370
+ // todos los carriles: los nombró quien ya sabía cuál era el carril, y descartarlos acá sería un
371
+ // segundo filtro que contradice al primero.
372
+ const cast = { ...OWNERS, build: planning.cast.build }
373
+ cast.review = [OWNERS.review, ...planning.cast.review].filter(Boolean).join(', ')
374
+ log(`Cargos: build=${cast.build || '(sin asignar)'} · review=${cast.review} · qa=${cast.qa}`)
235
375
  const asRole = (slugs) => (slugs
236
376
  ? `Actuá como ${slugs}, respetando el contrato de cada uno en su SKILL.md bajo agents/ y sus ` +
237
377
  `límites: un cargo que no puede decidir solo, no decide solo.\n\n`
238
378
  : '')
239
379
 
240
380
  if (!planning.wipActive) {
241
- phase('Ready')
242
- const ready = await read(
243
- `${asRole(OWNERS.ready)}Check concrete acceptance, dependencies and unresolved decisions for ${task.id}: ` +
244
- `${task.acceptance}. Clarify wording only; never expand scope.`, { schema: READY },
245
- )
246
- if (!ready.ready) {
247
- await write(`Register ${task.id} in ${HUMAN} with reason and an exact human action: ${ready.reason}.`)
248
- return stop('not-ready', ready.reason)
381
+ if (!mechanical) {
382
+ phase('Ready')
383
+ const ready = await read(
384
+ `${asRole(OWNERS.ready)}Revisá que ${task.id} tenga aceptación concreta, dependencias resueltas y ` +
385
+ `ninguna decisión pendiente: ${task.acceptance}. Aclará la redacción y nada más; nunca amplíes el ` +
386
+ `alcance.`,
387
+ { schema: READY },
388
+ )
389
+ if (!ready) return stop('agent-unavailable', 'Ready no devolvió resultado')
390
+ if (!ready.ready) {
391
+ await write(`Registrá ${task.id} en ${HUMAN} con el motivo y una acción humana exacta: ${ready.reason}.`)
392
+ return stop('not-ready', ready.reason)
393
+ }
394
+ if (ready.refinedAcceptance) task.acceptance = ready.refinedAcceptance
249
395
  }
250
- if (ready.refinedAcceptance) task.acceptance = ready.refinedAcceptance
251
396
 
252
- if (!direct && !lite) {
397
+ if (!mechanical && !lite) {
253
398
  phase('Decompose')
254
399
  const estimate = await run(
255
- `Inspect ${task.service} and estimate ${task.id}. Split it only if it exceeds ${contract.maxTaskHours} hours.`,
400
+ `Inspeccioná ${task.service} y estimá ${task.id}. Partila sólo si supera ${contract.maxTaskHours} horas.`,
256
401
  { schema: ESTIMATE },
257
402
  )
403
+ if (!estimate) return stop('agent-unavailable', 'Decompose no devolvió resultado')
258
404
  if (estimate.needsSplit) {
259
- await write(`Replace only ${task.id} in ${BACKLOG} with ordered, ` +
260
- `independently verifiable subtasks: ${JSON.stringify(estimate.subtasks)}.`)
405
+ await write(`Reemplazá sólo ${task.id} en ${BACKLOG} por subtareas ordenadas y verificables de forma ` +
406
+ `independiente: ${JSON.stringify(estimate.subtasks)}.`)
261
407
  planning = await readContext()
262
408
  if (!planning) return stop('context-unavailable', `no se pudo releer el estado de ${P}`)
263
409
  continue
264
410
  }
265
411
  }
266
412
 
413
+ // El plan de un cambio mecánico es el cambio, y la aceptación ya lo nombra. Pedirlo igual costaba
414
+ // dos llamadas —planificar y criticar el plan— para llegar a lo que la línea de la tarea ya decía.
415
+ let plan = { steps: [`Aplicar en ${task.service} lo que nombra la aceptación: ${task.acceptance}`] }
416
+ if (!mechanical) {
267
417
  phase('Plan')
268
- let plan = await run(
269
- `${asRole(OWNERS.plan)}Inspect real code, repository instructions, neighbouring conventions, epic context ` +
270
- `and git status for ${task.id}. ` +
271
- `Produce the smallest plan satisfying ${task.acceptance}. Planning files cannot be implementation files.`,
418
+ plan = await run(
419
+ `${asRole(OWNERS.plan)}Inspeccioná el código real, las instrucciones del repositorio, las convenciones ` +
420
+ `vecinas, el contexto de la épica y el git status de ${task.id}. Producí el plan más chico que satisfaga ` +
421
+ `${task.acceptance}. Un archivo de planning no puede ser un archivo de implementación. El plan cubre ` +
422
+ `sólo el cambio dentro de ${task.service}: correr los gates del repositorio, hacer QA, commitear y ` +
423
+ `cerrar la tarea son fases posteriores de este recorrido, cada una con su dueño, así que no van como ` +
424
+ `pasos.`,
272
425
  { schema: PLAN },
273
426
  )
274
- if (!direct && !lite) {
427
+ if (!plan) return stop('agent-unavailable', 'Plan no devolvió resultado')
428
+ if (!lite) {
275
429
  phase('Critique')
276
430
  let critique = await read(
277
- `Attack this plan for correctness, scope, security, tests and conflicts with existing ` +
278
- `code: ${JSON.stringify(plan)}`,
431
+ `Atacá este plan por correctitud, alcance, seguridad, pruebas y conflictos con el código ` +
432
+ `existente.${MANIFEST}${VERDICT} Plan: ${JSON.stringify(plan)}`,
279
433
  { schema: DECISION },
280
434
  )
281
- if (!critique.approved) {
435
+ if (!critique) return stop('agent-unavailable', 'Critique no devolvió resultado')
436
+ // Un plan bloqueado no se corrige: lo que lo bloquea está fuera de lo que una segunda pasada puede
437
+ // tocar, así que insistir gasta dos llamadas para llegar al mismo lugar.
438
+ if (critique.verdict === 'bloqueado') {
439
+ return stop('plan-blocked', blockers(critique).join('; ') || 'sin condiciones nombradas')
440
+ }
441
+ if (blockers(critique).length) {
282
442
  plan = await read(
283
- `Revise the plan once for: ${critique.concerns.join('; ')}. Plan: ${JSON.stringify(plan)}`,
443
+ `Corregí el plan una vez por: ${blockers(critique).join('; ')}. Plan: ${JSON.stringify(plan)}`,
284
444
  { schema: PLAN },
285
445
  )
286
446
  critique = await read(
287
- `Re-critique the revised plan against ${task.acceptance}: ${JSON.stringify(plan)}`,
447
+ `Volvé a criticar el plan corregido contra ${task.acceptance}.${MANIFEST}${VERDICT} ` +
448
+ `Plan: ${JSON.stringify(plan)}`,
288
449
  { schema: DECISION },
289
450
  )
290
- if (!critique.approved) return stop('plan-rejected', critique.concerns.join('; '))
451
+ if (!plan || !critique) return stop('agent-unavailable', 'la revisión del plan no devolvió resultado')
452
+ if (critique.verdict === 'bloqueado' || blockers(critique).length) {
453
+ return stop('plan-rejected', blockers(critique).join('; ') || 'sin condiciones nombradas')
454
+ }
291
455
  }
456
+ // Acá el plan ya está aprobado por los dos caminos posibles, así que el contraste va una sola vez.
457
+ if (!critique.consulted.length) return stop('critique-unbacked', 'aprobó el plan sin declarar qué inspeccionó')
458
+ }
292
459
  }
293
- await write(
294
- `Persist active WIP before code: task=${task.id}, hito=${JSON.stringify(task.hito)}, ` +
295
- `phase=Build, service=${task.service}, ` +
296
- `acceptance=${JSON.stringify(task.acceptance)}, unchecked steps=${JSON.stringify(plan.steps)}. ` +
297
- `Registrá además el reparto de cargos ${JSON.stringify(cast)} en las decisiones del WIP, para que ` +
298
- `después se pueda auditar quién revisó qué. Follow the WIP contract exactly.`,
460
+ phase('WIP')
461
+ // Esta llamada escribe un archivo y nada más, y hay que decirlo con todas las letras. En una corrida
462
+ // real hizo el trabajo entero: leyó los pasos del plan como una orden, implementó, corrió RED/GREEN,
463
+ // cerró la tarea en DONE y dejó el WIP en IDLE. Build encontró todo hecho y lo atribuyó a «una corrida
464
+ // anterior», así que Review, Verify y QA nunca vieron ese código y el recorrido terminó reportando algo
465
+ // distinto de lo que decía planning. El permiso venía del preámbulo de escritura; lo que faltaba era el
466
+ // límite. `wipActive` es el contraste: si el WIP no quedó activo, esta fase hizo otra cosa.
467
+ const persisted = await write(
468
+ `Escribí el WIP y nada más: no toques código, no corras pruebas, no cierres la tarea y no escribas ` +
469
+ `en DONE. Los pasos van sin tildar porque todavía no ocurrieron. task=${task.id}, ` +
470
+ `hito=${JSON.stringify(task.hito)}, phase=Build, service=${task.service}, ` +
471
+ `acceptance=${JSON.stringify(task.acceptance)}, pasos sin tildar=${JSON.stringify(plan.steps)}. ` +
472
+ `Registrá el reparto de cargos ${JSON.stringify(cast)} en las decisiones del WIP, para que después se ` +
473
+ `pueda auditar quién revisó qué. Seguí el contrato de WIP exactamente y reportá con qué status quedó.`,
474
+ { schema: {
475
+ type: 'object', additionalProperties: false, required: ['wipActive'],
476
+ properties: { wipActive: { type: 'boolean' }, note: { type: 'string' } },
477
+ } },
299
478
  )
479
+ if (!persisted) return stop('agent-unavailable', 'la persistencia del WIP no devolvió resultado')
480
+ if (!persisted.wipActive) {
481
+ return stop('wip-not-persisted', `${task.id} entra a Build sin WIP activo: ${persisted.note || ''}`)
482
+ }
300
483
  }
301
484
 
302
485
  phase('Build')
303
486
  const build = await run(
304
- `${asRole(cast.build)}Implement only ${task.id} inside ${task.service}. Resume at the first pending WIP ` +
305
- `step; verify completed steps on disk ` +
306
- `and tick each successful step. Use RED/GREEN for behavior. Acceptance: ${task.acceptance}.`, {
307
- schema: { type: 'object', required: ['completed', 'summary'], properties: {
308
- completed: { type: 'boolean' }, summary: { type: 'string' },
309
- blockers: { type: 'array', items: { type: 'string' } },
310
- } },
311
- },
487
+ `${asRole(cast.build)}Implementá sólo ${task.id} dentro de ${task.service}. Retomá en el primer paso ` +
488
+ `pendiente del WIP; comprobá en el disco los pasos ya hechos y tildá cada uno que salga bien. Para cada ` +
489
+ `comportamiento escribí primero la prueba, corréla y anotá en redFirst el test y el fallo literal que ` +
490
+ `dio; recién después implementá. Un test que pasa antes de que exista el código no asercia lo que dice ` +
491
+ `aserciar: endurecelo y volvé a correr hasta verlo fallar. Corré las pruebas que necesites para ver ese ` +
492
+ `rojo y ese verde, y nada más: los gates completos, el QA, el commit y el cierre son fases posteriores, ` +
493
+ `así que no toques ${DONE} ni ${BACKLOG} ni el status del WIP. Lo que el plan no previó va en discovered y ` +
494
+ `no en el código a secas: kind=edge si esta tarea lo puede fijar —y entonces entra con su prueba, que ` +
495
+ `nombrás en test y anotás en redFirst—, kind=open si lo notaste y no impide entregar la aceptación: se ` +
496
+ `registra para que lo decida quien corresponde y el recorrido sigue. Si de verdad no podés entregar sin ` +
497
+ `esa decisión, eso no va en discovered: es completed=false con su blocker. ` +
498
+ `Aceptación: ${task.acceptance}.`,
499
+ { schema: BUILD },
312
500
  )
501
+ if (!build) return stop('agent-unavailable', 'Build no devolvió resultado')
313
502
  if (!build.completed) return stop('build-blocked', (build.blockers || []).join('; ') || build.summary)
503
+ // Construir no es cerrar. Pasó en una corrida real: el plan traía «VERIFY», «QA» y «Cierre — commit» como
504
+ // pasos, quien construyó los ejecutó, y la tarea salió del BACKLOG y entró a DONE sin que Review, Verify
505
+ // ni QA la miraran. El plan ya no los pide; esto detecta que igual hayan ocurrido.
506
+ if (build.closedTask) {
507
+ return stop('build-closed-task', `${task.id} se cerró en Build, sin pasar por Review, Verify ni QA`)
508
+ }
509
+ // Nombrar el test sin traer su fallo es volver a afirmar que hubo rojo, que es lo que el campo evita.
510
+ const unproven = build.redFirst.find((entry) => !entry.failure.trim())
511
+ if (unproven) return stop('build-unproven', `${unproven.test} se declara en rojo sin el fallo que lo muestra`)
512
+ // Lo que queda abierto no lo cierra quien lo encuentra, pero tampoco frena lo que sí se pudo entregar.
513
+ // Tres corridas reales terminaron acá y las tres traían `completed: true`: el hueco nunca fue «no puedo»
514
+ // sino «hay un borde que alguien tiene que decidir», y una aceptación escrita en prosa siempre tiene uno.
515
+ // Frenar por eso frenaba siempre, y un freno que salta siempre se termina apagando. Lo que de verdad
516
+ // bloquea ya tiene camino —`completed: false` con su blocker—; esto se registra y sigue.
517
+ const openDecisions = build.discovered.filter((entry) => entry.kind === 'open')
518
+ if (openDecisions.length) {
519
+ await write(`Registrá en ${HUMAN} una fila por cada decisión que ${task.id} dejó abierta, con qué la ` +
520
+ `cierra y quién puede tomarla. No inventes responsables ni fechas: ` +
521
+ `${JSON.stringify(openDecisions.map((entry) => entry.detail))}`)
522
+ }
523
+ // Y un caso que sí se fijó acá entra con su prueba o no entró: sin ella el comportamiento nuevo queda
524
+ // sin nada que lo sostenga, y nadie sabe después que debía existir.
525
+ // Los dos campos salen de la misma respuesta pero se escriben por separado, así que pedirles la misma
526
+ // cadena exacta frena una tarea correcta por haber nombrado el test de dos formas —`TestAlta` acá y
527
+ // `users_test.go::TestAlta` allá—. Alcanza con que uno nombre al otro; lo que sigue frenando, que es de
528
+ // lo que se trata, es el caso que no aparece en ningún rojo.
529
+ const namesTest = (red, item) => Boolean(item.test)
530
+ && (red.test.includes(item.test) || item.test.includes(red.test))
531
+ const loose = build.discovered.find((entry) => entry.kind === 'edge'
532
+ && !build.redFirst.some((red) => namesTest(red, entry)))
533
+ if (loose) return stop('edge-unproven', `${loose.detail} entró sin la prueba que lo fija`)
314
534
 
315
- if (!direct) {
535
+ if (!express) {
316
536
  phase('Review')
317
537
  let review = await run(
318
- `${asRole(cast.review)}Review the actual diff for acceptance, regressions, security, architecture, ` +
319
- `generated code, migrations and accidental scope. Cada cargo revisa su dominio, no el ajeno.`,
538
+ `${asRole(cast.review)}Revisá el diff real por aceptación, regresiones, seguridad, arquitectura, código ` +
539
+ `generado, migraciones y alcance accidental. Cada cargo revisa su dominio, no el ajeno.${MANIFEST}` +
540
+ `${VERDICT}`,
320
541
  { schema: DECISION },
321
542
  )
322
- if (!review.approved) {
323
- await write(`Fix only these evidence-backed findings and update WIP: ${review.concerns.join('; ')}`)
324
- review = await run(`Re-review the corrected diff for ${task.id}.`, { schema: DECISION })
325
- if (!review.approved) return stop('review-failed', review.concerns.join('; '))
543
+ if (!review) return stop('agent-unavailable', 'Review no devolvió resultado')
544
+ if (review.verdict === 'bloqueado') {
545
+ return stop('review-blocked', blockers(review).join('; ') || 'sin condiciones nombradas')
546
+ }
547
+ if (blockers(review).length) {
548
+ await write(`Corregí sólo estos hallazgos con evidencia y actualizá el WIP: ${blockers(review).join('; ')}`)
549
+ review = await run(`Volvé a revisar el diff corregido de ${task.id}.${MANIFEST}${VERDICT}`,
550
+ { schema: DECISION })
551
+ if (!review) return stop('agent-unavailable', 'la re-revisión no devolvió resultado')
552
+ if (review.verdict === 'bloqueado' || blockers(review).length) {
553
+ return stop('review-failed', blockers(review).join('; ') || 'sin condiciones nombradas')
554
+ }
555
+ }
556
+ // Aprobar sin declarar qué se abrió no se arregla mandando a tocar código: falló quien revisó.
557
+ if (!review.consulted.length) return stop('review-unbacked', 'aprobó el diff sin declarar qué inspeccionó')
558
+ // Lo que no impide entregar no manda a tocar código, y tampoco desaparece: la mejora opinable que se
559
+ // corrige a las apuradas cuesta una vuelta y un riesgo que nadie pidió. Va a Propuestas y no a
560
+ // Lecciones porque lo que la revisión anotó es un cambio del producto con su evidencia; Lecciones es
561
+ // sobre cómo trabajamos, y ahí el hallazgo queda esperando una promoción que nadie va a hacer.
562
+ const noted = review.concerns.filter((one) => !one.blocking).map((one) => one.detail)
563
+ if (noted.length) {
564
+ await write(`Registrá en la sección Propuestas de ${P}/INBOX.md lo que la revisión de ${task.id} dejó ` +
565
+ `anotado sin frenar la entrega, sin promover ninguna: ${JSON.stringify(noted)}`)
326
566
  }
327
567
  }
328
568
 
329
569
  phase('Verify')
330
- const verified = await run(
331
- `${asRole(cast.verify)}Discover and run the real gates for ${task.service}: repository instructions first, ` +
332
- `then applicable test, lint, ` +
333
- `typecheck and build. Read actual exit codes. passed=true needs commands and no task-caused regression.`,
334
- { schema: VERIFY },
335
- )
570
+ const VERIFY_ASK = `${asRole(cast.verify)}Abrí el fuente de los tests que la tarea agregó o cambió y ` +
571
+ `contrastá cada criterio ` +
572
+ `de aceptación contra sus aserciones: en uncovered va el criterio que ningún test codifica, con su causa ` +
573
+ `—missing-test si el test falta o no asercia la propiedad, ambiguous si el criterio no dice qué habría ` +
574
+ `que aserciar—. Un test que pasa sin aserciarla no la cubre. Después descubrí y corré los gates reales ` +
575
+ `de ${task.service}: primero las instrucciones del ` +
576
+ `repositorio, después el test, lint, typecheck y build que apliquen. Leé los exit codes de verdad. ` +
577
+ `passed=true exige comandos corridos y ninguna regresión causada por la tarea. Marcá ranTests en el ` +
578
+ `comando que haya corrido las pruebas, sea cual sea su nombre. ` +
579
+ `Aceptación: ${task.acceptance}.`
580
+ let verified = await run(VERIFY_ASK, { schema: VERIFY })
581
+ if (!verified) return stop('agent-unavailable', 'Verify no devolvió resultado')
582
+ // Un criterio que nadie sabe cómo aserciar no es trabajo que falta sino una definición que falta, y
583
+ // definirla acá sería inventarla. Escribir la prueba que falta, en cambio, es trabajo del recorrido:
584
+ // hacer parar a una persona por eso le cobra una interrupción por algo que se resolvía solo.
585
+ const ambiguous = verified.uncovered.find((entry) => entry.cause === 'ambiguous')
586
+ if (ambiguous) {
587
+ await write(`Registrá ${task.id} en ${HUMAN}: el criterio "${ambiguous.criterion}" no dice qué habría ` +
588
+ `que aserciar, y hace falta la decisión que lo fija.`)
589
+ return stop('acceptance-ambiguous', ambiguous.criterion)
590
+ }
591
+ if (verified.uncovered.length) {
592
+ await run(`${asRole(cast.build)}Escribí sólo las pruebas que faltan en ${task.id}, con el mismo rojo ` +
593
+ `previo, y no toques el código de producción: ${verified.uncovered.map((e) => e.criterion).join('; ')}`)
594
+ verified = await run(VERIFY_ASK, { schema: VERIFY })
595
+ if (!verified) return stop('agent-unavailable', 'la segunda pasada de Verify no devolvió resultado')
596
+ }
336
597
  if (!verified.passed || !verified.commands.length) return stop('verify-failed', verified.details)
598
+ // Verde por ausencia: los gates pasaron y ninguno corrió las pruebas que esta tarea escribió. El exit
599
+ // code de lint o de build no dice nada del comportamiento, y la corrida cerraba igual.
600
+ const ranTests = verified.commands.some((entry) => entry.ranTests || RUNS_TESTS.test(entry.cmd))
601
+ if (build.redFirst.length && !ranTests) {
602
+ return stop('verify-untested', `${task.id} escribió pruebas y ningún gate corrió una`)
603
+ }
604
+ if (verified.uncovered.length) {
605
+ return stop('verify-hollow', `sin test que lo codifique: ${verified.uncovered.map((e) => e.criterion).join('; ')}`)
606
+ }
337
607
 
338
- phase('QA')
339
- const qa = await run(
340
- `${asRole(cast.qa)}${direct || lite
341
- ? 'Perform the cheapest real acceptance check'
342
- : 'Exercise real consumer-visible behavior'} for ` +
343
- `${task.id}. Unit tests alone are not QA. Start only minimum runtime and tear it down. ` +
344
- `Acceptance: ${task.acceptance}.`,
345
- { schema: QA },
346
- )
347
- if (!qa.passed) return stop('qa-failed', qa.evidence)
608
+ // QA ejercita comportamiento, y lo mecánico no lo cambia: el valor literal que la aceptación nombra
609
+ // ya lo comprobó Verify contra el test, y en `directo` además lo mira el revisor que nombra el cast.
610
+ let qa = { passed: true, evidence: 'carril mecánico: la aceptación queda comprobada en Verify' }
611
+ if (!mechanical) {
612
+ phase('QA')
613
+ qa = await run(
614
+ `${asRole(cast.qa)}${lite
615
+ ? 'Hacé la comprobación de aceptación real más barata'
616
+ : 'Ejercitá el comportamiento real que ve quien lo usa'} para ` +
617
+ `${task.id}. Las pruebas unitarias solas no son QA. Levantá el mínimo runtime necesario y bajalo ` +
618
+ `después. Aceptación: ${task.acceptance}.`,
619
+ { schema: QA },
620
+ )
621
+ if (!qa) return stop('agent-unavailable', 'QA no devolvió resultado')
622
+ if (!qa.passed) return stop('qa-failed', qa.evidence)
623
+ }
348
624
 
349
625
  phase('Commit')
350
626
  const commit = contract.commitPerTask ? await run(
351
- `${asRole(OWNERS.commit)}Find the git repo owning ${task.service}, inspect status/diff, stage explicit task ` +
352
- `files, create one Conventional ` +
353
- `Commit with footer "Task: ${task.id}", then verify log/status. Never amend or push; report unrelated leftovers.`,
627
+ `${asRole(OWNERS.commit)}Encontrá el repositorio git dueño de ${task.service}, inspeccioná status y diff, ` +
628
+ `stageá por nombre los archivos de la tarea, creá un solo Conventional Commit con el footer ` +
629
+ `"Task: ${task.id}" y después verificá log y status. Nunca amend ni push; reportá lo que quedó suelto ` +
630
+ `y no era de la tarea.`,
354
631
  { schema: COMMIT },
355
- ) : { committed: true, reason: 'runner.commitPerTask is disabled' }
632
+ ) : { committed: true, reason: 'runner.commitPerTask está apagado' }
633
+ if (!commit) return stop('agent-unavailable', 'Commit no devolvió resultado')
356
634
  if (!commit.committed) return stop('commit-failed', commit.reason)
357
635
 
358
636
  phase('Done')
359
637
  await write(
360
- `Atomically close ${task.id}: append it under its hito in ${DONE} with acept, done, qa, ` +
361
- `tests and commit evidence; ` +
362
- `remove it and its indented notes from ${BACKLOG}; close its epic only if no tagged task remains; ` +
363
- `reset ${WIP} to ` +
364
- `status IDLE. Facts: build=${build.summary}; verify=${JSON.stringify(verified.commands)}; qa=${qa.evidence}; ` +
365
- `commit=${commit.hash || commit.reason}.`,
638
+ `Cerrá ${task.id} de forma atómica: agregala bajo su hito en ${DONE} con evidencia de acept, done, qa, ` +
639
+ `tests y commit; sacala junto con sus notas indentadas de ${BACKLOG}; cerrá su épica sólo si no queda ` +
640
+ `ninguna tarea etiquetada; y dejá ${WIP} en status IDLE. Hechos: build=${build.summary}; ` +
641
+ `verify=${JSON.stringify(verified.commands)}; qa=${qa.evidence}; commit=${commit.hash || commit.reason}.`,
366
642
  )
367
643
  completed.push(task.id)
368
644
  planning = await readContext()
369
645
  if (!planning) return stop('context-unavailable', `no se pudo releer el estado de ${P}`)
370
646
  }
371
647
 
648
+ if (rounds > MAX_TASKS) {
649
+ return stop('milestone-too-long', `la corrida agotó el tope de ${MAX_TASKS} tareas sin cerrar el hito`)
650
+ }
651
+
372
652
  phase('Closing')
373
653
  const closing = await write(
374
- `Run "node tools/ops.js check ${P}" from ${ROOT}. If red, repair only deterministic derived state; never rewrite ` +
375
- `acceptance or decisions to force green.`, {
654
+ `Corré "node tools/ops.js check ${P}" desde ${ROOT}. Si sale en rojo, reparás sólo estado derivado ` +
655
+ `determinista; nunca reescribas aceptación ni decisiones para forzar el verde.`, {
376
656
  schema: {
377
657
  type: 'object', required: ['passed', 'details'],
378
658
  properties: { passed: { type: 'boolean' }, details: { type: 'string' } },
379
659
  },
380
660
  },
381
661
  )
662
+ if (!closing) return stop('agent-unavailable', 'Closing no devolvió resultado')
382
663
  if (!closing.passed) return stop('planning-check-failed', closing.details)
383
664
  if (completed.length && contract.humanCheckpoint) await write(
384
- `Create ${GATE} with the completed hito, tasks ${completed.join(', ')}, evidence, pending human actions and exact ` +
385
- `continuation instructions. Never push or deploy.`,
665
+ `Creá ${GATE} con el hito terminado, las tareas ${completed.join(', ')}, la evidencia, las acciones humanas ` +
666
+ `pendientes y las instrucciones exactas para continuar. Nunca hagas push ni deploy.`,
386
667
  )
387
- return finish({ done: completed, count: completed.length, hito: currentHito })
668
+ return finish({ done: completed, count: completed.length, hito: currentMilestone })