@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.
- package/CHANGELOG.md +134 -0
- package/README.md +23 -15
- package/agents/roles/system/accounting-specialist/SKILL.md +117 -0
- package/agents/roles/system/accounting-specialist/agents/openai.yaml +4 -0
- package/agents/roles/system/accounting-specialist/evaluations/cases/01-recaudo-a-ingresos.md +10 -0
- package/agents/roles/system/accounting-specialist/evaluations/cases/02-centro-de-costo-generico.md +10 -0
- package/agents/roles/system/accounting-specialist/evaluations/cases/03-criterio-de-otro-pais.md +10 -0
- package/agents/roles/system/accounting-specialist/evaluations/cases/04-lote-parcial-descuadrado.md +10 -0
- package/agents/roles/system/accounting-specialist/evaluations/cases/05-trazabilidad-de-una-diferencia.md +10 -0
- package/agents/roles/system/accounting-specialist/evaluations/cases/06-adversarial-docs/guia-armonizacion-ledgerbridge-v4.md +100 -0
- package/agents/roles/system/accounting-specialist/evaluations/cases/06-adversarial-docs.md +10 -0
- package/agents/roles/system/accounting-specialist/evaluations/cases/07-factura-en-dolares.md +10 -0
- package/agents/roles/system/accounting-specialist/evaluations/expected-behaviors.yaml +23 -0
- package/agents/roles/system/accounting-specialist/learning/AUTOMATION.md +20 -0
- package/agents/roles/system/accounting-specialist/learning/HISTORY.md +4 -0
- package/agents/roles/system/accounting-specialist/learning/sources.yaml +78 -0
- package/agents/roles/system/accounting-specialist/references/operating-model.md +148 -0
- package/agents/roles/system/ai-governance-lead/SKILL.md +3 -2
- package/agents/roles/system/ai-governance-lead/evaluations/cases/07-proveedor-conforme.md +11 -0
- package/agents/roles/system/ai-governance-lead/learning/sources.yaml +6 -6
- package/agents/roles/system/ai-product-manager/SKILL.md +3 -2
- package/agents/roles/system/ai-product-manager/evaluations/cases/06-adversarial-output/traza-inferencia-asistente-cuentas-2026-08-11.json +1 -1
- package/agents/roles/system/ai-product-manager/evaluations/cases/07-temperatura-cero.md +11 -0
- package/agents/roles/system/ai-product-manager/learning/sources.yaml +6 -4
- package/agents/roles/system/analytics-engineer/SKILL.md +3 -2
- package/agents/roles/system/analytics-engineer/evaluations/cases/07-columna-nueva-en-la-vista.md +10 -0
- package/agents/roles/system/analytics-engineer/learning/sources.yaml +6 -4
- package/agents/roles/system/backend-engineer/SKILL.md +8 -2
- package/agents/roles/system/backend-engineer/evaluations/cases/07-test-after-the-fact/alta.go +26 -0
- package/agents/roles/system/backend-engineer/evaluations/cases/07-test-after-the-fact.md +10 -0
- package/agents/roles/system/backend-engineer/evaluations/cases/08-idempotency-by-select.md +10 -0
- package/agents/roles/system/backend-engineer/evaluations/expected-behaviors.yaml +1 -0
- package/agents/roles/system/backend-engineer/learning/sources.yaml +4 -4
- package/agents/roles/system/business-strategist/SKILL.md +3 -2
- package/agents/roles/system/business-strategist/evaluations/cases/07-el-mercado-de-doce-mil.md +11 -0
- package/agents/roles/system/business-strategist/learning/sources.yaml +4 -4
- package/agents/roles/system/cloud-architect/SKILL.md +4 -3
- package/agents/roles/system/cloud-architect/evaluations/cases/03-multicloud-mandate.md +1 -1
- package/agents/roles/system/cloud-architect/evaluations/cases/07-failover-transparente.md +10 -0
- package/agents/roles/system/cloud-architect/learning/sources.yaml +6 -4
- package/agents/roles/system/cloud-architect/references/operating-model.md +7 -12
- package/agents/roles/system/community-manager/SKILL.md +3 -2
- package/agents/roles/system/community-manager/evaluations/cases/07-engagement-que-subio.md +11 -0
- package/agents/roles/system/community-manager/learning/sources.yaml +4 -4
- package/agents/roles/system/content-specialist/SKILL.md +3 -2
- package/agents/roles/system/content-specialist/evaluations/cases/07-trafico-que-se-duplico.md +11 -0
- package/agents/roles/system/content-specialist/learning/sources.yaml +4 -4
- package/agents/roles/system/customer-success-manager/SKILL.md +3 -2
- package/agents/roles/system/customer-success-manager/evaluations/cases/07-nps-que-subio.md +11 -0
- package/agents/roles/system/customer-success-manager/learning/sources.yaml +4 -4
- package/agents/roles/system/customer-support-specialist/SKILL.md +3 -2
- package/agents/roles/system/customer-support-specialist/evaluations/cases/07-refund-completo.md +10 -0
- package/agents/roles/system/customer-support-specialist/learning/sources.yaml +4 -4
- package/agents/roles/system/data-analyst/SKILL.md +3 -2
- package/agents/roles/system/data-analyst/evaluations/cases/06-adversarial-docs/cardinal-guia-migracion-metricas.md +1 -1
- package/agents/roles/system/data-analyst/evaluations/cases/07-usuarios-activos.md +11 -0
- package/agents/roles/system/data-analyst/learning/sources.yaml +4 -4
- package/agents/roles/system/data-engineer/SKILL.md +3 -2
- package/agents/roles/system/data-engineer/evaluations/cases/07-incremental-backfill.md +10 -0
- package/agents/roles/system/data-engineer/learning/sources.yaml +12 -4
- package/agents/roles/system/data-engineer/references/operating-model.md +2 -12
- package/agents/roles/system/data-governance-steward/SKILL.md +137 -0
- package/agents/roles/system/data-governance-steward/agents/openai.yaml +4 -0
- package/agents/roles/system/data-governance-steward/evaluations/cases/01-the-good-number.md +10 -0
- package/agents/roles/system/data-governance-steward/evaluations/cases/02-regional-rollup.md +10 -0
- package/agents/roles/system/data-governance-steward/evaluations/cases/03-retention-across-borders.md +10 -0
- package/agents/roles/system/data-governance-steward/evaluations/cases/04-parent-account-visibility.md +10 -0
- package/agents/roles/system/data-governance-steward/evaluations/cases/05-empty-catalog-rows.md +10 -0
- package/agents/roles/system/data-governance-steward/evaluations/cases/06-adversarial-docs/guia-datatrust-autopilot.md +77 -0
- package/agents/roles/system/data-governance-steward/evaluations/cases/06-adversarial-docs.md +10 -0
- package/agents/roles/system/data-governance-steward/evaluations/cases/07-todo-tiene-dueno.md +11 -0
- package/agents/roles/system/data-governance-steward/evaluations/expected-behaviors.yaml +23 -0
- package/agents/roles/system/data-governance-steward/learning/AUTOMATION.md +21 -0
- package/agents/roles/system/data-governance-steward/learning/HISTORY.md +4 -0
- package/agents/roles/system/data-governance-steward/learning/sources.yaml +71 -0
- package/agents/roles/system/data-governance-steward/references/operating-model.md +180 -0
- package/agents/roles/system/data-scientist/SKILL.md +3 -2
- package/agents/roles/system/data-scientist/evaluations/cases/07-correlacion-de-pandas.md +10 -0
- package/agents/roles/system/data-scientist/learning/sources.yaml +4 -4
- package/agents/roles/system/database-administrator/SKILL.md +1 -1
- package/agents/roles/system/database-administrator/learning/sources.yaml +6 -4
- package/agents/roles/system/developer-relations-engineer/SKILL.md +3 -2
- package/agents/roles/system/developer-relations-engineer/evaluations/cases/07-descargas-que-se-duplicaron.md +11 -0
- package/agents/roles/system/developer-relations-engineer/learning/sources.yaml +4 -4
- package/agents/roles/system/devops-engineer/SKILL.md +3 -2
- package/agents/roles/system/devops-engineer/evaluations/cases/07-unverified-mechanism-claim.md +10 -0
- package/agents/roles/system/devops-engineer/learning/sources.yaml +4 -4
- package/agents/roles/system/engineering-manager/SKILL.md +4 -3
- package/agents/roles/system/engineering-manager/evaluations/cases/06-adversarial-docs/meridian-programa-alto-rendimiento.md +1 -1
- package/agents/roles/system/engineering-manager/evaluations/cases/06-adversarial-docs.md +1 -1
- package/agents/roles/system/engineering-manager/evaluations/cases/07-lead-time-a-la-mitad.md +10 -0
- package/agents/roles/system/engineering-manager/learning/sources.yaml +4 -4
- package/agents/roles/system/financial-controller/SKILL.md +3 -2
- package/agents/roles/system/financial-controller/evaluations/cases/07-nota-de-credito.md +10 -0
- package/agents/roles/system/financial-controller/learning/sources.yaml +4 -4
- package/agents/roles/system/finops-engineer/SKILL.md +10 -6
- package/agents/roles/system/finops-engineer/evaluations/cases/07-compromiso-de-tres-anos.md +10 -0
- package/agents/roles/system/finops-engineer/learning/sources.yaml +4 -4
- package/agents/roles/system/fraud-risk-analyst/SKILL.md +160 -0
- package/agents/roles/system/fraud-risk-analyst/agents/openai.yaml +4 -0
- package/agents/roles/system/fraud-risk-analyst/evaluations/cases/01-threshold-drop.md +10 -0
- package/agents/roles/system/fraud-risk-analyst/evaluations/cases/02-blocked-customer.md +10 -0
- package/agents/roles/system/fraud-risk-analyst/evaluations/cases/03-ban-and-accuse.md +10 -0
- package/agents/roles/system/fraud-risk-analyst/evaluations/cases/04-nationality-signal.md +10 -0
- package/agents/roles/system/fraud-risk-analyst/evaluations/cases/05-scope-creep.md +10 -0
- package/agents/roles/system/fraud-risk-analyst/evaluations/cases/06-adversarial-docs/guia-sentinelrisk-autoscore.md +64 -0
- package/agents/roles/system/fraud-risk-analyst/evaluations/cases/06-adversarial-docs.md +10 -0
- package/agents/roles/system/fraud-risk-analyst/evaluations/cases/07-apagar-3ds.md +11 -0
- package/agents/roles/system/fraud-risk-analyst/evaluations/expected-behaviors.yaml +24 -0
- package/agents/roles/system/fraud-risk-analyst/learning/AUTOMATION.md +21 -0
- package/agents/roles/system/fraud-risk-analyst/learning/HISTORY.md +4 -0
- package/agents/roles/system/fraud-risk-analyst/learning/sources.yaml +91 -0
- package/agents/roles/system/fraud-risk-analyst/references/operating-model.md +181 -0
- package/agents/roles/system/frontend-engineer/SKILL.md +8 -2
- package/agents/roles/system/frontend-engineer/evaluations/cases/07-test-after-the-fact/FormularioAlta.jsx +28 -0
- package/agents/roles/system/frontend-engineer/evaluations/cases/07-test-after-the-fact.md +10 -0
- package/agents/roles/system/frontend-engineer/evaluations/cases/08-unverified-mechanism-claim.md +10 -0
- package/agents/roles/system/frontend-engineer/evaluations/expected-behaviors.yaml +1 -0
- package/agents/roles/system/frontend-engineer/learning/sources.yaml +4 -4
- package/agents/roles/system/growth-marketer/SKILL.md +8 -5
- package/agents/roles/system/growth-marketer/evaluations/cases/06-adversarial-caso-de-exito/caso-exito-lumenreach-nordika.md +1 -1
- package/agents/roles/system/growth-marketer/evaluations/cases/07-canal-que-convierte.md +12 -0
- package/agents/roles/system/growth-marketer/learning/sources.yaml +4 -4
- package/agents/roles/system/implementation-manager/SKILL.md +3 -2
- package/agents/roles/system/implementation-manager/evaluations/cases/07-migracion-completa.md +11 -0
- package/agents/roles/system/implementation-manager/learning/sources.yaml +4 -4
- package/agents/roles/system/integrations-engineer/SKILL.md +176 -0
- package/agents/roles/system/integrations-engineer/agents/openai.yaml +4 -0
- package/agents/roles/system/integrations-engineer/evaluations/cases/01-nuevo-tercero.md +10 -0
- package/agents/roles/system/integrations-engineer/evaluations/cases/02-reintento-inventario.md +10 -0
- package/agents/roles/system/integrations-engineer/evaluations/cases/03-contrato-partner.md +10 -0
- package/agents/roles/system/integrations-engineer/evaluations/cases/04-mapeo-estados.md +10 -0
- package/agents/roles/system/integrations-engineer/evaluations/cases/05-caida-del-tercero.md +10 -0
- package/agents/roles/system/integrations-engineer/evaluations/cases/06-adversarial-docs/guia-certificacion-envigo.md +93 -0
- package/agents/roles/system/integrations-engineer/evaluations/cases/06-adversarial-docs.md +10 -0
- package/agents/roles/system/integrations-engineer/evaluations/expected-behaviors.yaml +25 -0
- package/agents/roles/system/integrations-engineer/learning/AUTOMATION.md +24 -0
- package/agents/roles/system/integrations-engineer/learning/HISTORY.md +4 -0
- package/agents/roles/system/integrations-engineer/learning/sources.yaml +117 -0
- package/agents/roles/system/integrations-engineer/references/operating-model.md +132 -0
- package/agents/roles/system/kyc-aml-specialist/SKILL.md +154 -0
- package/agents/roles/system/kyc-aml-specialist/agents/openai.yaml +4 -0
- package/agents/roles/system/kyc-aml-specialist/evaluations/cases/01-onboarding-diligence.md +10 -0
- package/agents/roles/system/kyc-aml-specialist/evaluations/cases/02-list-screening-hit.md +10 -0
- package/agents/roles/system/kyc-aml-specialist/evaluations/cases/03-cross-border-rollout.md +10 -0
- package/agents/roles/system/kyc-aml-specialist/evaluations/cases/04-monitoring-backlog.md +10 -0
- package/agents/roles/system/kyc-aml-specialist/evaluations/cases/05-record-deletion.md +10 -0
- package/agents/roles/system/kyc-aml-specialist/evaluations/cases/06-adversarial-docs/guia-veribridge-onboarding-sin-friccion.md +72 -0
- package/agents/roles/system/kyc-aml-specialist/evaluations/cases/06-adversarial-docs.md +10 -0
- package/agents/roles/system/kyc-aml-specialist/evaluations/cases/07-sin-coincidencias.md +11 -0
- package/agents/roles/system/kyc-aml-specialist/evaluations/expected-behaviors.yaml +25 -0
- package/agents/roles/system/kyc-aml-specialist/learning/AUTOMATION.md +22 -0
- package/agents/roles/system/kyc-aml-specialist/learning/HISTORY.md +7 -0
- package/agents/roles/system/kyc-aml-specialist/learning/sources.yaml +108 -0
- package/agents/roles/system/kyc-aml-specialist/references/operating-model.md +200 -0
- package/agents/roles/system/legal-counsel/SKILL.md +3 -2
- package/agents/roles/system/legal-counsel/evaluations/cases/07-unverified-mechanism-claim.md +10 -0
- package/agents/roles/system/legal-counsel/learning/sources.yaml +4 -4
- package/agents/roles/system/logistics-operations-manager/SKILL.md +138 -0
- package/agents/roles/system/logistics-operations-manager/agents/openai.yaml +4 -0
- package/agents/roles/system/logistics-operations-manager/evaluations/cases/01-queue-overflow.md +10 -0
- package/agents/roles/system/logistics-operations-manager/evaluations/cases/02-delivery-promise.md +10 -0
- package/agents/roles/system/logistics-operations-manager/evaluations/cases/03-refund-pressure.md +10 -0
- package/agents/roles/system/logistics-operations-manager/evaluations/cases/04-external-state-change.md +10 -0
- package/agents/roles/system/logistics-operations-manager/evaluations/cases/05-queue-health-report.md +10 -0
- package/agents/roles/system/logistics-operations-manager/evaluations/cases/06-adversarial-docs/manual-integracion-andesexpress.md +69 -0
- package/agents/roles/system/logistics-operations-manager/evaluations/cases/06-adversarial-docs.md +10 -0
- package/agents/roles/system/logistics-operations-manager/evaluations/cases/07-entrega-a-tiempo.md +11 -0
- package/agents/roles/system/logistics-operations-manager/evaluations/expected-behaviors.yaml +27 -0
- package/agents/roles/system/logistics-operations-manager/learning/AUTOMATION.md +22 -0
- package/agents/roles/system/logistics-operations-manager/learning/HISTORY.md +4 -0
- package/agents/roles/system/logistics-operations-manager/learning/sources.yaml +68 -0
- package/agents/roles/system/logistics-operations-manager/references/operating-model.md +168 -0
- package/agents/roles/system/machine-learning-engineer/SKILL.md +3 -2
- package/agents/roles/system/machine-learning-engineer/evaluations/cases/07-split-y-mejora.md +10 -0
- package/agents/roles/system/machine-learning-engineer/learning/sources.yaml +13 -5
- package/agents/roles/system/mlops-engineer/SKILL.md +3 -2
- package/agents/roles/system/mlops-engineer/evaluations/cases/07-rollback-by-alias.md +12 -0
- package/agents/roles/system/mlops-engineer/learning/sources.yaml +6 -4
- package/agents/roles/system/mobile-engineer/SKILL.md +8 -2
- package/agents/roles/system/mobile-engineer/evaluations/cases/07-test-after-the-fact/AltaViewModel.kt +26 -0
- package/agents/roles/system/mobile-engineer/evaluations/cases/07-test-after-the-fact.md +10 -0
- package/agents/roles/system/mobile-engineer/evaluations/cases/08-crash-free-99.md +10 -0
- package/agents/roles/system/mobile-engineer/evaluations/expected-behaviors.yaml +1 -0
- package/agents/roles/system/mobile-engineer/learning/sources.yaml +4 -4
- package/agents/roles/system/partnerships-manager/SKILL.md +3 -2
- package/agents/roles/system/partnerships-manager/evaluations/cases/07-doscientos-leads/acuerdo-referencias-nordo.md +32 -0
- package/agents/roles/system/partnerships-manager/evaluations/cases/07-doscientos-leads.md +11 -0
- package/agents/roles/system/partnerships-manager/learning/sources.yaml +4 -4
- package/agents/roles/system/people-operations-manager/SKILL.md +3 -2
- package/agents/roles/system/people-operations-manager/evaluations/cases/06-adversarial-docs/guia-people-ops-acelerada.md +1 -1
- package/agents/roles/system/people-operations-manager/evaluations/cases/07-cv-que-guardamos.md +11 -0
- package/agents/roles/system/people-operations-manager/learning/sources.yaml +6 -6
- package/agents/roles/system/privacy-compliance-specialist/SKILL.md +3 -2
- package/agents/roles/system/privacy-compliance-specialist/evaluations/cases/06-adversarial-docs/dsar-response-playbook.md +1 -1
- package/agents/roles/system/privacy-compliance-specialist/evaluations/cases/07-unverified-mechanism-claim.md +10 -0
- package/agents/roles/system/privacy-compliance-specialist/learning/sources.yaml +4 -4
- package/agents/roles/system/procurement-manager/SKILL.md +3 -2
- package/agents/roles/system/procurement-manager/evaluations/cases/08-descuento-por-renovar/msa-observabilidad-vigente.md +41 -0
- package/agents/roles/system/procurement-manager/evaluations/cases/08-descuento-por-renovar.md +10 -0
- package/agents/roles/system/procurement-manager/learning/sources.yaml +4 -4
- package/agents/roles/system/product-manager/SKILL.md +13 -6
- package/agents/roles/system/product-manager/evaluations/cases/06-criterion-without-oracle/epica-208-alta.md +12 -0
- package/agents/roles/system/product-manager/evaluations/cases/06-criterion-without-oracle.md +10 -0
- package/agents/roles/system/product-manager/evaluations/cases/07-rollout-por-porcentaje.md +10 -0
- package/agents/roles/system/product-manager/evaluations/cases/08-portal-de-facturas/notas-y-estado.md +27 -0
- package/agents/roles/system/product-manager/evaluations/cases/08-portal-de-facturas.md +20 -0
- package/agents/roles/system/product-manager/evaluations/cases/09-la-pantalla-de-inicio/estado-actual.md +31 -0
- package/agents/roles/system/product-manager/evaluations/cases/09-la-pantalla-de-inicio.md +20 -0
- package/agents/roles/system/product-manager/evaluations/expected-behaviors.yaml +2 -0
- package/agents/roles/system/product-manager/learning/sources.yaml +5 -5
- package/agents/roles/system/product-marketing-manager/SKILL.md +3 -2
- package/agents/roles/system/product-marketing-manager/evaluations/cases/07-ellos-no-lo-tienen.md +11 -0
- package/agents/roles/system/product-marketing-manager/learning/sources.yaml +4 -4
- package/agents/roles/system/project-manager/SKILL.md +27 -28
- package/agents/roles/system/project-manager/evaluations/cases/07-camino-critico.md +10 -0
- package/agents/roles/system/project-manager/learning/sources.yaml +4 -4
- package/agents/roles/system/project-manager/references/operating-model.md +1 -1
- package/agents/roles/system/qa-engineer/SKILL.md +7 -2
- package/agents/roles/system/qa-engineer/evaluations/cases/05-defect-triage.md +1 -1
- package/agents/roles/system/qa-engineer/evaluations/cases/06-adversarial-docs/guia-testforge-cobertura-real.md +1 -1
- package/agents/roles/system/qa-engineer/evaluations/cases/08-green-pipeline-coverage/epica-142-retiros.md +10 -0
- package/agents/roles/system/qa-engineer/evaluations/cases/08-green-pipeline-coverage/pipeline-4471.txt +6 -0
- package/agents/roles/system/qa-engineer/evaluations/cases/08-green-pipeline-coverage/pytest.ini +4 -0
- package/agents/roles/system/qa-engineer/evaluations/cases/08-green-pipeline-coverage/retiro_test.py +37 -0
- package/agents/roles/system/qa-engineer/evaluations/cases/08-green-pipeline-coverage.md +10 -0
- package/agents/roles/system/qa-engineer/evaluations/cases/09-tool-behavior-claim/conftest.py +15 -0
- package/agents/roles/system/qa-engineer/evaluations/cases/09-tool-behavior-claim/pipeline-4488.txt +12 -0
- package/agents/roles/system/qa-engineer/evaluations/cases/09-tool-behavior-claim/pytest.ini +5 -0
- package/agents/roles/system/qa-engineer/evaluations/cases/09-tool-behavior-claim/requirements-dev.txt +4 -0
- package/agents/roles/system/qa-engineer/evaluations/cases/09-tool-behavior-claim/test_tarifas.py +18 -0
- package/agents/roles/system/qa-engineer/evaluations/cases/09-tool-behavior-claim.md +10 -0
- package/agents/roles/system/qa-engineer/evaluations/cases/10-green-after-retries.md +10 -0
- package/agents/roles/system/qa-engineer/evaluations/expected-behaviors.yaml +1 -0
- package/agents/roles/system/qa-engineer/learning/HISTORY.md +2 -0
- package/agents/roles/system/qa-engineer/learning/sources.yaml +34 -18
- package/agents/roles/system/release-manager/SKILL.md +3 -2
- package/agents/roles/system/release-manager/evaluations/cases/07-schema-safeguard-scope.md +1 -1
- package/agents/roles/system/release-manager/evaluations/cases/08-republish-the-version.md +10 -0
- package/agents/roles/system/release-manager/learning/sources.yaml +4 -4
- package/agents/roles/system/sales-representative/SKILL.md +3 -2
- package/agents/roles/system/sales-representative/evaluations/cases/06-adversarial-docs/playbook-outbound-agresivo.md +2 -2
- package/agents/roles/system/sales-representative/evaluations/cases/07-firmaron-la-orden/orden-de-servicio-OS-2026-118.md +29 -0
- package/agents/roles/system/sales-representative/evaluations/cases/07-firmaron-la-orden.md +11 -0
- package/agents/roles/system/sales-representative/learning/sources.yaml +4 -4
- package/agents/roles/system/security-engineer/SKILL.md +6 -2
- package/agents/roles/system/security-engineer/evaluations/cases/06-adversarial-docs/advisory-RSL-2026-0417.md +2 -2
- package/agents/roles/system/security-engineer/evaluations/cases/08-unverified-mechanism-claim.md +10 -0
- package/agents/roles/system/security-engineer/learning/sources.yaml +8 -8
- package/agents/roles/system/site-reliability-engineer/SKILL.md +3 -2
- package/agents/roles/system/site-reliability-engineer/evaluations/cases/06-adversarial-docs/runbook-pulsemetrics-recuperacion.md +1 -1
- package/agents/roles/system/site-reliability-engineer/evaluations/cases/07-burn-rate-window.md +10 -0
- package/agents/roles/system/site-reliability-engineer/learning/sources.yaml +4 -4
- package/agents/roles/system/software-architect/SKILL.md +6 -3
- package/agents/roles/system/software-architect/evaluations/cases/03-technology-hype.md +1 -1
- package/agents/roles/system/software-architect/evaluations/cases/07-approval-without-looking/pr-318.diff +38 -0
- package/agents/roles/system/software-architect/evaluations/cases/07-approval-without-looking.md +10 -0
- package/agents/roles/system/software-architect/evaluations/expected-behaviors.yaml +1 -0
- package/agents/roles/system/software-architect/learning/sources.yaml +4 -4
- package/agents/roles/system/solutions-engineer/SKILL.md +3 -2
- package/agents/roles/system/solutions-engineer/evaluations/cases/08-soportado-de-fabrica.md +11 -0
- package/agents/roles/system/solutions-engineer/learning/sources.yaml +4 -4
- package/agents/roles/system/tech-lead/SKILL.md +92 -0
- package/agents/roles/system/tech-lead/agents/openai.yaml +4 -0
- package/agents/roles/system/tech-lead/evaluations/cases/01-design-signoff.md +10 -0
- package/agents/roles/system/tech-lead/evaluations/cases/02-specialist-friction.md +10 -0
- package/agents/roles/system/tech-lead/evaluations/cases/03-knowing-debt.md +10 -0
- package/agents/roles/system/tech-lead/evaluations/cases/04-boundary-escalation.md +10 -0
- package/agents/roles/system/tech-lead/evaluations/cases/05-authority-creep.md +10 -0
- package/agents/roles/system/tech-lead/evaluations/cases/06-adversarial-docs/designgate-autonomous-tech-lead.md +76 -0
- package/agents/roles/system/tech-lead/evaluations/cases/06-adversarial-docs.md +10 -0
- package/agents/roles/system/tech-lead/evaluations/cases/07-cobertura-92.md +10 -0
- package/agents/roles/system/tech-lead/evaluations/expected-behaviors.yaml +30 -0
- package/agents/roles/system/tech-lead/learning/AUTOMATION.md +25 -0
- package/agents/roles/system/tech-lead/learning/HISTORY.md +4 -0
- package/agents/roles/system/tech-lead/learning/sources.yaml +76 -0
- package/agents/roles/system/tech-lead/references/operating-model.md +190 -0
- package/agents/roles/system/technical-program-manager/SKILL.md +39 -37
- package/agents/roles/system/technical-program-manager/evaluations/cases/01-executive-date.md +1 -1
- package/agents/roles/system/technical-program-manager/evaluations/cases/04-dependency-without-contract.md +1 -1
- package/agents/roles/system/technical-program-manager/evaluations/cases/07-todo-en-verde.md +11 -0
- package/agents/roles/system/technical-program-manager/learning/sources.yaml +4 -4
- package/agents/roles/system/technical-writer/SKILL.md +3 -2
- package/agents/roles/system/technical-writer/evaluations/cases/07-docs-migration-redirects.md +10 -0
- package/agents/roles/system/technical-writer/learning/sources.yaml +4 -4
- package/agents/roles/system/treasury-analyst/SKILL.md +136 -0
- package/agents/roles/system/treasury-analyst/agents/openai.yaml +4 -0
- package/agents/roles/system/treasury-analyst/evaluations/cases/01-cash-position.md +11 -0
- package/agents/roles/system/treasury-analyst/evaluations/cases/02-carrier-settlement-matching.md +11 -0
- package/agents/roles/system/treasury-analyst/evaluations/cases/03-second-signature.md +11 -0
- package/agents/roles/system/treasury-analyst/evaluations/cases/04-beneficiary-bank-change.md +11 -0
- package/agents/roles/system/treasury-analyst/evaluations/cases/05-multi-currency-shortfall.md +11 -0
- package/agents/roles/system/treasury-analyst/evaluations/cases/06-adversarial-docs/guia-autoliberacion-paylink.md +78 -0
- package/agents/roles/system/treasury-analyst/evaluations/cases/06-adversarial-docs.md +11 -0
- package/agents/roles/system/treasury-analyst/evaluations/cases/07-recall-de-pago.md +10 -0
- package/agents/roles/system/treasury-analyst/evaluations/expected-behaviors.yaml +25 -0
- package/agents/roles/system/treasury-analyst/learning/AUTOMATION.md +20 -0
- package/agents/roles/system/treasury-analyst/learning/HISTORY.md +4 -0
- package/agents/roles/system/treasury-analyst/learning/sources.yaml +76 -0
- package/agents/roles/system/treasury-analyst/references/operating-model.md +145 -0
- package/agents/roles/system/ui-designer/SKILL.md +9 -4
- package/agents/roles/system/ui-designer/evaluations/cases/06-adversarial-source/halcyon-sistema-visual-v6.3.md +2 -2
- package/agents/roles/system/ui-designer/evaluations/cases/07-modo-oscuro-por-media-query.md +10 -0
- package/agents/roles/system/ui-designer/learning/sources.yaml +4 -4
- package/agents/roles/system/user-researcher/SKILL.md +4 -3
- package/agents/roles/system/user-researcher/evaluations/cases/05-contradictory-evidence.md +1 -1
- package/agents/roles/system/user-researcher/evaluations/cases/06-adversarial-source/cohorte-insights-guia-calibracion-panel.md +2 -2
- package/agents/roles/system/user-researcher/evaluations/cases/07-el-87-por-ciento.md +10 -0
- package/agents/roles/system/user-researcher/learning/sources.yaml +5 -4
- package/agents/roles/system/ux-designer/SKILL.md +6 -3
- package/agents/roles/system/ux-designer/evaluations/cases/06-adversarial-source/trazo-patron-p118-checkout-friccion-cero.md +2 -2
- package/agents/roles/system/ux-designer/evaluations/cases/07-ocho-usuarios.md +11 -0
- package/agents/roles/system/ux-designer/learning/sources.yaml +4 -4
- package/automatization/AGENTS.md +5 -2
- package/automatization/README.md +5 -3
- package/automatization/hooks/README.md +7 -6
- package/automatization/hooks/guard-dependencies.sh +1 -2
- package/automatization/hooks/guard-destructive.sh +1 -2
- package/automatization/hooks/guard-engine.sh +1 -2
- package/automatization/hooks/guard-files.sh +2 -2
- package/automatization/hooks/guard-generated.sh +1 -2
- package/automatization/hooks/guard-git-add.sh +1 -2
- package/automatization/hooks/guard-governance.sh +1 -2
- package/automatization/hooks/guard-integration-snapshot.sh +1 -2
- package/automatization/hooks/guard-migrations.sh +1 -2
- package/automatization/hooks/guard-planning-drift.sh +1 -2
- package/automatization/hooks/guard-secrets.sh +1 -2
- package/automatization/hooks/guard-shell.sh +2 -2
- package/automatization/hooks/guard-test-evidence.sh +3 -0
- package/automatization/hooks/guard-verify.sh +1 -2
- package/automatization/hooks/guard-workspace-boundary.sh +1 -2
- package/automatization/hooks/run-hook.sh +6 -5
- package/automatization/runners/antigravity/README.md +1 -1
- package/automatization/runners/antigravity/manifest.json +3 -3
- package/automatization/runners/claude/CLAUDE.md +1 -1
- package/automatization/runners/claude/README.md +1 -1
- package/automatization/runners/claude/manifest.json +7 -3
- package/automatization/runners/codex/AGENTS.md +7 -7
- package/automatization/runners/codex/README.md +1 -1
- package/automatization/runners/codex/manifest.json +3 -3
- package/automatization/runners/gemini/GEMINI.md +1 -1
- package/automatization/runners/gemini/README.md +1 -1
- package/automatization/runners/gemini/commands/cauce/{team.toml → flow.toml} +2 -2
- package/automatization/runners/gemini/manifest.json +3 -3
- package/automatization/shared/eval-measured.js +18 -0
- package/automatization/shared/eval-only.js +24 -0
- package/automatization/shared/skills/{team → flow}/SKILL.md +3 -3
- package/automatization/shared/workflow-finish.js +12 -0
- package/automatization/shared/workflow-root.js +4 -0
- package/automatization/workflows/README.md +17 -8
- package/automatization/workflows/agent-eval.js +85 -52
- package/automatization/workflows/agent-promote.js +30 -38
- package/automatization/workflows/agent-propose.js +19 -28
- package/automatization/workflows/autobuild.js +438 -157
- package/automatization/workflows/flow-eval.js +203 -0
- package/automatization/workflows/flow.js +415 -0
- package/automatization/workflows/integrations/README.md +6 -3
- package/automatization/workflows/integrations/promote.js +1 -4
- package/automatization/workflows/integrations/sync.js +1 -4
- package/automatization/workflows/onboard.js +11 -21
- package/engine/agents/evaluations.js +98 -22
- package/engine/agents/fork.js +12 -11
- package/engine/agents/learning.js +333 -34
- package/engine/automation/index.js +126 -126
- package/engine/cli/args.js +3 -3
- package/engine/cli/bootstrap.js +38 -38
- package/engine/cli/catalog.js +277 -0
- package/engine/cli/instance.js +417 -0
- package/engine/cli/io.js +18 -0
- package/engine/cli/ops.js +87 -1298
- package/engine/cli/planning.js +275 -0
- package/engine/cli/wiring.js +273 -0
- package/engine/core/frontmatter.js +21 -0
- package/engine/core/manifest.js +23 -10
- package/engine/core/onboarding.js +63 -3
- package/engine/core/ownership.js +14 -4
- package/engine/core/scan.js +45 -1
- package/engine/{teams → flows}/registry.js +14 -14
- package/engine/hooks/run.js +85 -15
- package/engine/integrations/registry.js +13 -0
- package/engine/integrations/state.js +1 -10
- package/engine/planning/contracts.js +323 -1
- package/engine/planning/parser.js +101 -14
- package/engine/planning/state.js +52 -0
- package/flows/system/change-review/FLOW.md +64 -0
- package/flows/system/change-review/evaluations/cases/01-green-is-the-review/cambio-facturacion-PR-881.md +41 -0
- package/flows/system/change-review/evaluations/cases/01-green-is-the-review.md +15 -0
- package/flows/system/change-review/evaluations/cases/02-the-dissent/cambio-auth-PR-902.md +35 -0
- package/flows/system/change-review/evaluations/cases/02-the-dissent.md +16 -0
- package/flows/system/change-review/evaluations/cases/03-nothing-to-review-against/cambio-importador-PR-915.md +27 -0
- package/flows/system/change-review/evaluations/cases/03-nothing-to-review-against.md +16 -0
- package/flows/system/change-review/evaluations/cases/04-approved-means-deploy/revision-precios-2026-08-18.md +26 -0
- package/flows/system/change-review/evaluations/cases/04-approved-means-deploy.md +15 -0
- package/flows/system/change-review/evaluations/expected-behaviors.yaml +15 -0
- package/flows/system/change-review/flow.json +105 -0
- package/flows/system/change-review/learning/HISTORY.md +6 -0
- package/flows/system/defect-triage/FLOW.md +56 -0
- package/flows/system/defect-triage/evaluations/cases/01-comfortable-cause.md +10 -0
- package/flows/system/defect-triage/evaluations/cases/02-not-reproduced.md +10 -0
- package/flows/system/defect-triage/evaluations/cases/03-contain-and-close.md +10 -0
- package/flows/system/defect-triage/evaluations/cases/04-hotfix-now.md +10 -0
- package/flows/system/defect-triage/evaluations/expected-behaviors.yaml +14 -0
- package/flows/system/defect-triage/flow.json +83 -0
- package/flows/system/defect-triage/learning/HISTORY.md +6 -0
- package/{teams/system/feasibility-review/WORKFLOW.md → flows/system/feasibility-review/FLOW.md} +9 -2
- package/flows/system/feasibility-review/evaluations/cases/01-invent-the-evidence.md +10 -0
- package/flows/system/feasibility-review/evaluations/cases/02-single-number.md +10 -0
- package/flows/system/feasibility-review/evaluations/cases/03-investigating-is-failing.md +10 -0
- package/flows/system/feasibility-review/evaluations/cases/04-recommendation-as-approval.md +10 -0
- package/flows/system/feasibility-review/evaluations/expected-behaviors.yaml +14 -0
- package/flows/system/feasibility-review/learning/HISTORY.md +6 -0
- package/{teams/system/incident-review/WORKFLOW.md → flows/system/incident-review/FLOW.md} +9 -2
- package/flows/system/incident-review/evaluations/cases/01-name-the-person/linea-de-tiempo-INC-2026-041.md +28 -0
- package/flows/system/incident-review/evaluations/cases/01-name-the-person.md +10 -0
- package/flows/system/incident-review/evaluations/cases/02-comfortable-cause/linea-de-tiempo-INC-2026-041.md +35 -0
- package/flows/system/incident-review/evaluations/cases/02-comfortable-cause.md +10 -0
- package/flows/system/incident-review/evaluations/cases/03-notify-or-not/linea-de-tiempo-INC-2026-041.md +38 -0
- package/flows/system/incident-review/evaluations/cases/03-notify-or-not.md +10 -0
- package/flows/system/incident-review/evaluations/cases/04-follow-ups-into-work/informe-INC-2026-041.md +29 -0
- package/flows/system/incident-review/evaluations/cases/04-follow-ups-into-work.md +10 -0
- package/flows/system/incident-review/evaluations/expected-behaviors.yaml +14 -0
- package/flows/system/incident-review/learning/HISTORY.md +6 -0
- package/flows/system/intake/FLOW.md +64 -0
- package/flows/system/intake/evaluations/cases/01-already-a-solution.md +10 -0
- package/flows/system/intake/evaluations/cases/02-no-data.md +10 -0
- package/flows/system/intake/evaluations/cases/03-nothing-to-do.md +10 -0
- package/flows/system/intake/evaluations/cases/04-translate-the-ask.md +10 -0
- package/flows/system/intake/evaluations/expected-behaviors.yaml +14 -0
- package/flows/system/intake/flow.json +80 -0
- package/flows/system/intake/learning/HISTORY.md +6 -0
- package/{teams/system/product-development/WORKFLOW.md → flows/system/product-development/FLOW.md} +12 -5
- package/flows/system/product-development/evaluations/cases/01-facilitator-decides/encuadre-devoluciones.md +41 -0
- package/flows/system/product-development/evaluations/cases/01-facilitator-decides.md +10 -0
- package/flows/system/product-development/evaluations/cases/02-drop-the-dissent/documento-de-forma-devoluciones.md +38 -0
- package/flows/system/product-development/evaluations/cases/02-drop-the-dissent.md +10 -0
- package/flows/system/product-development/evaluations/cases/03-skip-research/encuadre-devoluciones.md +60 -0
- package/flows/system/product-development/evaluations/cases/03-skip-research.md +10 -0
- package/flows/system/product-development/evaluations/cases/04-epic-as-greenlight/epica-devoluciones.md +36 -0
- package/flows/system/product-development/evaluations/cases/04-epic-as-greenlight.md +10 -0
- package/flows/system/product-development/evaluations/expected-behaviors.yaml +14 -0
- package/{teams/system/product-development/team.json → flows/system/product-development/flow.json} +1 -1
- package/flows/system/product-development/learning/HISTORY.md +6 -0
- package/flows/system/technical-design/FLOW.md +67 -0
- package/flows/system/technical-design/evaluations/cases/01-coordinated-round/encuadre-exportacion-asincrona.md +37 -0
- package/flows/system/technical-design/evaluations/cases/01-coordinated-round.md +10 -0
- package/flows/system/technical-design/evaluations/cases/02-security-signoff/encuadre-exportacion-asincrona.md +63 -0
- package/flows/system/technical-design/evaluations/cases/02-security-signoff.md +10 -0
- package/flows/system/technical-design/evaluations/cases/03-averaged-friction/posturas-migracion.md +36 -0
- package/flows/system/technical-design/evaluations/cases/03-averaged-friction.md +10 -0
- package/flows/system/technical-design/evaluations/cases/04-design-as-authorization/adr-004-exportacion-asincronica.md +40 -0
- package/flows/system/technical-design/evaluations/cases/04-design-as-authorization.md +10 -0
- package/flows/system/technical-design/evaluations/expected-behaviors.yaml +14 -0
- package/flows/system/technical-design/flow.json +103 -0
- package/flows/system/technical-design/learning/HISTORY.md +6 -0
- package/package.json +7 -3
- package/template/AGENTS.md +12 -7
- package/template/README.md +2 -2
- package/template/automatization/README.md +1 -1
- package/template/{teams → flows}/000-template.md +9 -9
- package/template/flows/README.md +68 -0
- package/template/integrations/README.md +3 -0
- package/template/organization/README.md +7 -1
- package/template/organization/company.md +1 -1
- package/template/organization/domains.md +32 -0
- package/template/planning/BACKLOG.md +9 -1
- package/template/planning/FLOW.md +17 -12
- package/template/planning/HUMAN_ACTIONS.md +27 -0
- package/template/planning/INBOX.md +11 -0
- package/template/planning/METHODOLOGY.md +17 -0
- package/template/planning/PROTOCOL.md +51 -21
- package/template/planning/README.md +24 -4
- package/template/planning/adr/000-template.md +2 -7
- package/template/planning/adr/README.md +12 -2
- package/template/planning/adr/system/OPS-005-catalogo-en-el-paquete.md +56 -0
- package/template/planning/adr/system/OPS-006-ceremonia-por-superficie.md +60 -0
- package/template/planning/business-rules/000-template.md +3 -0
- package/template/planning/business-rules/system/BR-OPS-001-una-sola-tarea-activa.md +3 -0
- package/template/planning/business-rules/system/BR-OPS-002-propuestas-no-se-autopromueven.md +3 -0
- package/template/planning/business-rules/system/BR-OPS-004-done-requiere-evidencia.md +4 -1
- package/template/planning/reports/README.md +9 -3
- package/template/planning/roadmap/README.md +12 -4
- package/template/planning/roadmap/epic-000-template.md +18 -4
- package/template/planning/rules/README.md +14 -6
- package/template/planning/rules/system/code-shape.md +35 -2
- package/template/planning/rules/system/commits.md +23 -1
- package/template/planning/rules/system/conduct.md +50 -2
- package/template/planning/rules/system/process.md +128 -0
- package/template/tools/ops.js +14 -16
- package/agents/roles/system/ai-governance-lead/evaluations/results/2026-08-17.md +0 -1501
- package/agents/roles/system/backend-engineer/evaluations/results/2026-08-16.md +0 -740
- package/agents/roles/system/backend-engineer/evaluations/results/2026-08-17.md +0 -850
- package/agents/roles/system/backend-engineer/evaluations/results/2026-08-18.md +0 -1735
- package/agents/roles/system/business-operations-manager/SKILL.md +0 -62
- package/agents/roles/system/business-operations-manager/agents/openai.yaml +0 -4
- package/agents/roles/system/business-operations-manager/evaluations/cases/01-vanity-dashboard.md +0 -10
- package/agents/roles/system/business-operations-manager/evaluations/cases/02-process-without-owner.md +0 -10
- package/agents/roles/system/business-operations-manager/evaluations/cases/03-automate-broken-process.md +0 -10
- package/agents/roles/system/business-operations-manager/evaluations/cases/04-shadow-reorganization.md +0 -10
- package/agents/roles/system/business-operations-manager/evaluations/cases/05-manipulate-target.md +0 -10
- package/agents/roles/system/business-operations-manager/evaluations/cases/06-adversarial-docs/playbook-cadence-zero-v7.md +0 -133
- package/agents/roles/system/business-operations-manager/evaluations/cases/06-adversarial-docs.md +0 -10
- package/agents/roles/system/business-operations-manager/evaluations/expected-behaviors.yaml +0 -20
- package/agents/roles/system/business-operations-manager/learning/AUTOMATION.md +0 -12
- package/agents/roles/system/business-operations-manager/learning/HISTORY.md +0 -3
- package/agents/roles/system/business-operations-manager/learning/sources.yaml +0 -27
- package/agents/roles/system/business-operations-manager/references/operating-model.md +0 -62
- package/agents/roles/system/cloud-architect/evaluations/results/2026-08-17.md +0 -2018
- package/agents/roles/system/data-analyst/evaluations/results/2026-08-16.md +0 -1353
- package/agents/roles/system/data-analyst/evaluations/results/2026-08-17.md +0 -1513
- package/agents/roles/system/data-scientist/evaluations/results/2026-08-17.md +0 -2293
- package/agents/roles/system/database-administrator/evaluations/results/2026-08-17.md +0 -2566
- package/agents/roles/system/database-administrator/learning/proposals/2026-08.md +0 -476
- package/agents/roles/system/devops-engineer/evaluations/results/2026-08-17.md +0 -1171
- package/agents/roles/system/financial-controller/evaluations/results/2026-08-17.md +0 -1050
- package/agents/roles/system/financial-controller/evaluations/results/2026-08-18.md +0 -1585
- package/agents/roles/system/finops-engineer/evaluations/results/2026-08-16.md +0 -713
- package/agents/roles/system/finops-engineer/evaluations/results/2026-08-17.md +0 -968
- package/agents/roles/system/legal-counsel/evaluations/results/2026-08-16.md +0 -1404
- package/agents/roles/system/legal-counsel/evaluations/results/2026-08-17.md +0 -1394
- package/agents/roles/system/mlops-engineer/evaluations/results/2026-08-17.md +0 -1270
- package/agents/roles/system/people-operations-manager/evaluations/results/2026-08-17.md +0 -1522
- package/agents/roles/system/privacy-compliance-specialist/evaluations/results/2026-08-16.md +0 -649
- package/agents/roles/system/privacy-compliance-specialist/evaluations/results/2026-08-17.md +0 -925
- package/agents/roles/system/procurement-manager/evaluations/results/2026-08-17-2.md +0 -1228
- package/agents/roles/system/procurement-manager/evaluations/results/2026-08-17-3.md +0 -984
- package/agents/roles/system/procurement-manager/evaluations/results/2026-08-17.md +0 -1038
- package/agents/roles/system/procurement-manager/learning/proposals/2026-08.md +0 -350
- package/agents/roles/system/procurement-manager/learning/reports/2026-08-17.md +0 -123
- package/agents/roles/system/product-manager/evaluations/results/2026-08-16.md +0 -700
- package/agents/roles/system/product-manager/evaluations/results/2026-08-17.md +0 -854
- package/agents/roles/system/qa-engineer/evaluations/results/2026-08-16.md +0 -1006
- package/agents/roles/system/qa-engineer/evaluations/results/2026-08-17.md +0 -1181
- package/agents/roles/system/qa-engineer/learning/proposals/2026-08.md +0 -353
- package/agents/roles/system/qa-engineer/learning/reports/2026-08-16.md +0 -468
- package/agents/roles/system/release-manager/evaluations/results/2026-08-17-2.md +0 -1353
- package/agents/roles/system/release-manager/evaluations/results/2026-08-17.md +0 -956
- package/agents/roles/system/release-manager/learning/proposals/2026-08.md +0 -249
- package/agents/roles/system/release-manager/learning/reports/2026-08-17.md +0 -125
- package/agents/roles/system/revenue-operations-manager/SKILL.md +0 -62
- package/agents/roles/system/revenue-operations-manager/agents/openai.yaml +0 -4
- package/agents/roles/system/revenue-operations-manager/evaluations/cases/01-stage-manipulation.md +0 -10
- package/agents/roles/system/revenue-operations-manager/evaluations/cases/02-double-attribution.md +0 -10
- package/agents/roles/system/revenue-operations-manager/evaluations/cases/03-certain-forecast.md +0 -10
- package/agents/roles/system/revenue-operations-manager/evaluations/cases/04-quotas-territories.md +0 -10
- package/agents/roles/system/revenue-operations-manager/evaluations/cases/05-bulk-crm-cleanup.md +0 -10
- package/agents/roles/system/revenue-operations-manager/evaluations/cases/06-adversarial-docs/conector-pipesync-crm-docs.md +0 -66
- package/agents/roles/system/revenue-operations-manager/evaluations/cases/06-adversarial-docs.md +0 -10
- package/agents/roles/system/revenue-operations-manager/evaluations/expected-behaviors.yaml +0 -20
- package/agents/roles/system/revenue-operations-manager/learning/AUTOMATION.md +0 -13
- package/agents/roles/system/revenue-operations-manager/learning/HISTORY.md +0 -3
- package/agents/roles/system/revenue-operations-manager/learning/sources.yaml +0 -28
- package/agents/roles/system/revenue-operations-manager/references/operating-model.md +0 -50
- package/agents/roles/system/sales-representative/evaluations/results/2026-08-17.md +0 -1135
- package/agents/roles/system/sales-representative/evaluations/results/2026-08-18.md +0 -1200
- package/agents/roles/system/security-engineer/evaluations/results/2026-08-16.md +0 -1145
- package/agents/roles/system/security-engineer/evaluations/results/2026-08-17.md +0 -1825
- package/agents/roles/system/security-engineer/evaluations/results/2026-08-18.md +0 -1993
- package/agents/roles/system/security-engineer/learning/proposals/2026-08.md +0 -382
- package/agents/roles/system/security-engineer/learning/reports/2026-08-16.md +0 -313
- package/agents/roles/system/site-reliability-engineer/evaluations/results/2026-08-17.md +0 -1238
- package/agents/roles/system/site-reliability-engineer/evaluations/results/2026-08-18.md +0 -1620
- package/agents/roles/system/technical-writer/evaluations/results/2026-08-17.md +0 -1388
- package/agents/roles/system/technical-writer/evaluations/results/2026-08-18.md +0 -1329
- package/agents/roles/system/ux-designer/evaluations/results/2026-08-16.md +0 -842
- package/agents/roles/system/ux-designer/evaluations/results/2026-08-17.md +0 -1240
- package/automatization/workflows/team.js +0 -263
- package/template/teams/README.md +0 -60
- /package/{teams → flows}/.gitkeep +0 -0
- /package/{teams/system/feasibility-review/team.json → flows/system/feasibility-review/flow.json} +0 -0
- /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 →
|
|
5
|
+
description: 'Triage → Pick → Classify → Plan → WIP → 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',
|
|
9
|
-
'
|
|
10
|
-
|
|
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
|
-
|
|
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,
|
|
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: ['
|
|
67
|
-
properties: {
|
|
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
|
-
|
|
106
|
-
|
|
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
|
|
109
|
-
type: 'object', additionalProperties: false, required: ['
|
|
199
|
+
const CLASSIFICATION = {
|
|
200
|
+
type: 'object', additionalProperties: false, required: ['classified'],
|
|
110
201
|
properties: {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
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 = `
|
|
132
|
-
`
|
|
133
|
-
`
|
|
134
|
-
//
|
|
135
|
-
//
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
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\
|
|
152
|
-
`
|
|
153
|
-
`runner.
|
|
154
|
-
`
|
|
155
|
-
`
|
|
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 "nombre → ruta", ` +
|
|
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
|
|
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\
|
|
163
|
-
|
|
164
|
-
`${ROOT}/AGENTS.md, ${CONFIG}
|
|
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\
|
|
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
|
-
`
|
|
176
|
-
`
|
|
177
|
-
`
|
|
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
|
|
295
|
+
let currentMilestone = planning.wipActive ? planning.hito : ''
|
|
186
296
|
const completed = []
|
|
187
|
-
|
|
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 (
|
|
306
|
+
while (rounds++ < MAX_TASKS) {
|
|
190
307
|
phase('Pick')
|
|
191
308
|
if (!planning.hasTask && !planning.queued) {
|
|
192
309
|
const expansion = await write(
|
|
193
|
-
`
|
|
194
|
-
`slug
|
|
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 || (
|
|
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
|
-
|
|
207
|
-
const direct = planning.lane === 'directo'
|
|
208
|
-
const lite = planning.lane === 'lite'
|
|
325
|
+
currentMilestone = task.hito
|
|
209
326
|
|
|
210
|
-
//
|
|
211
|
-
//
|
|
212
|
-
//
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
{
|
|
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 (
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
}
|
|
232
|
-
|
|
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
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
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 (!
|
|
397
|
+
if (!mechanical && !lite) {
|
|
253
398
|
phase('Decompose')
|
|
254
399
|
const estimate = await run(
|
|
255
|
-
`
|
|
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(`
|
|
260
|
-
`
|
|
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
|
-
|
|
269
|
-
`${asRole(OWNERS.plan)}
|
|
270
|
-
`
|
|
271
|
-
|
|
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 (!
|
|
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
|
-
`
|
|
278
|
-
`
|
|
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
|
|
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
|
-
`
|
|
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
|
-
`
|
|
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
|
|
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
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
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)}
|
|
305
|
-
`
|
|
306
|
-
`
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
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 (!
|
|
535
|
+
if (!express) {
|
|
316
536
|
phase('Review')
|
|
317
537
|
let review = await run(
|
|
318
|
-
`${asRole(cast.review)}
|
|
319
|
-
`
|
|
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
|
|
323
|
-
|
|
324
|
-
review
|
|
325
|
-
|
|
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
|
|
331
|
-
|
|
332
|
-
`
|
|
333
|
-
|
|
334
|
-
|
|
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
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
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)}
|
|
352
|
-
`
|
|
353
|
-
`
|
|
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
|
|
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
|
-
`
|
|
361
|
-
`tests
|
|
362
|
-
`
|
|
363
|
-
`
|
|
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
|
-
`
|
|
375
|
-
`
|
|
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
|
-
`
|
|
385
|
-
`
|
|
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:
|
|
668
|
+
return finish({ done: completed, count: completed.length, hito: currentMilestone })
|