{"id":17342,"date":"2026-07-29T03:45:01","date_gmt":"2026-07-29T07:45:01","guid":{"rendered":"https:\/\/wp.glbgpt.com\/?p=17342"},"modified":"2026-07-29T03:45:12","modified_gmt":"2026-07-29T07:45:12","slug":"codex-vs-claude-code","status":"publish","type":"post","link":"https:\/\/wp.glbgpt.com\/es\/hub\/codex-vs-claude-code","title":{"rendered":"Codex frente al c\u00f3digo Claude: \u00bfqu\u00e9 agente de codificaci\u00f3n se adapta mejor a tu flujo de trabajo?"},"content":{"rendered":"<p class=\"wp-block-paragraph\"><strong>Codex vs Claude: en este c\u00f3digo no se trata tanto de encontrar un ganador universal como de elegir el estilo de trabajo en el que puedas confiar cada d\u00eda.<\/strong> Ambos productos permiten inspeccionar un repositorio, editar varios archivos, ejecutar comandos, realizar pruebas y explicar un parche. Las diferencias significativas residen en c\u00f3mo se delega el trabajo, con qu\u00e9 frecuencia se supervisa al agente, cu\u00e1nta informaci\u00f3n se puede examinar y c\u00f3mo se adapta cada herramienta al entorno de desarrollo existente.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">En nuestra prueba controlada con el repositorio de cuatro tareas, Codex obtuvo una puntuaci\u00f3n de 98\/100 y Claude Code, de 99\/100. Ambos completaron el trabajo principal. Claude Code mostr\u00f3 una revisi\u00f3n m\u00e1s amplia y una mayor cobertura de casos extremos, mientras que Codex a menudo alcanz\u00f3 el resultado requerido con un alcance menor y gener\u00f3 pruebas de ejecuci\u00f3n m\u00e1s s\u00f3lidas en nuestra configuraci\u00f3n. Una diferencia de un punto en un peque\u00f1o programa de prueba en Python no es motivo para declarar un ganador absoluto.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Los desarrolladores que no quieran que el resto de su flujo de trabajo quede limitado a un \u00fanico agente de programaci\u00f3n pueden a\u00f1adir GlobalGPT como una capa independiente multimodelo y multimodal. GlobalGPT integra m\u00e1s de 100 modelos destacados, como GPT 5.6, Claude Opus 5 y GPT Image 2, en un \u00fanico panel de control. Adem\u00e1s, el <a href=\"https:\/\/www.glbgpt.com\/home\/cli?inviter=hub_content_cli&amp;login=1\">GlobalGPT CLI<\/a>, Las rutas MCP y Skill pueden utilizarse desde Codex o Claude Code para obtener segundas opiniones, realizar la planificaci\u00f3n, elaborar la documentaci\u00f3n o utilizar otros modelos compatibles, mientras que el host de programaci\u00f3n nativo mantiene el control sobre las modificaciones y las pruebas del repositorio.<\/p>\n\n\n\n<div class=\"wp-block-group is-layout-constrained wp-block-group-is-layout-constrained\">\n<figure class=\"wp-block-image size-large\"><img fetchpriority=\"high\" decoding=\"async\" width=\"1024\" height=\"645\" src=\"https:\/\/wp.glbgpt.com\/wp-content\/uploads\/2026\/07\/glb-1024x645.png\" alt=\"Panel de control de GlobalGPT\" class=\"wp-image-19280\" srcset=\"https:\/\/wp.glbgpt.com\/wp-content\/uploads\/2026\/07\/glb-1024x645.png 1024w, https:\/\/wp.glbgpt.com\/wp-content\/uploads\/2026\/07\/glb-300x189.png 300w, https:\/\/wp.glbgpt.com\/wp-content\/uploads\/2026\/07\/glb-18x11.png 18w, https:\/\/wp.glbgpt.com\/wp-content\/uploads\/2026\/07\/glb-767x483.png 767w, https:\/\/wp.glbgpt.com\/wp-content\/uploads\/2026\/07\/glb-1536x967.png 1536w, https:\/\/wp.glbgpt.com\/wp-content\/uploads\/2026\/07\/glb-2048x1289.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-buttons is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-3e41869c wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link has-black-color has-text-color has-background has-link-color wp-element-button\" href=\"https:\/\/www.glbgpt.com\/home?inviter=hub_popup&amp;login=1\" style=\"background:linear-gradient(135deg,rgba(250,183,0,0.55) 0%,rgba(255,106,0,0.66) 96%)\"><strong>Prueba m\u00e1s de 100 modelos destacados en GlobalGPT<\/strong><\/a><\/div>\n<\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\">La comparaci\u00f3n combina informaci\u00f3n oficial sobre los planes, trabajo pr\u00e1ctico con el repositorio, resultados completos y ampliables, y experiencias de la comunidad claramente descritas. El objetivo es ayudar a un desarrollador independiente a elegir un lenguaje de programaci\u00f3n principal sin que le resulten confusos los accesos por suscripci\u00f3n, los cr\u00e9ditos adicionales y la facturaci\u00f3n de la API.<\/p>\n\n\n\n<style>\n.cvc-toc{margin:28px 0;padding:22px;border:1px solid #e2e6ec;border-radius:8px;background:linear-gradient(145deg,#fff 0%,#f7f9fc 100%);color:#18202b;font:14px\/1.4 Inter,-apple-system,BlinkMacSystemFont,\"Segoe UI\",sans-serif}.cvc-toc *{box-sizing:border-box}.cvc-toc .head{display:flex;align-items:end;justify-content:space-between;gap:16px;margin-bottom:16px}.cvc-toc h2{margin:0;font-size:20px}.cvc-toc .hint{color:#667085;font-size:12px}.cvc-toc ol{display:grid;grid-template-columns:1fr 1fr;gap:8px 18px;margin:0;padding:0;list-style:none;counter-reset:toc}.cvc-toc li{counter-increment:toc}.cvc-toc a{display:flex;align-items:center;gap:10px;padding:9px 10px;border-radius:6px;color:#344054;text-decoration:none;transition:background .15s ease,color .15s ease}.cvc-toc a:before{content:counter(toc,decimal-leading-zero);min-width:24px;color:#2563eb;font-size:11px;font-weight:800;letter-spacing:.04em}.cvc-toc a:hover{background:#eef4ff;color:#174ea6}@media(max-width:720px){.cvc-toc ol{grid-template-columns:1fr}.cvc-toc .head{align-items:start;flex-direction:column}.cvc-toc{padding:18px}}\n<\/style>\n<nav class=\"cvc-toc\" aria-label=\"\u00cdndice\">\n  <div class=\"head\"><h2>En esta comparaci\u00f3n<\/h2><span class=\"hint\">Ir a una secci\u00f3n<\/span><\/div>\n  <ol>\n    <li><a href=\"#quick-comparison\">Comparaci\u00f3n r\u00e1pida<\/a><\/li><li><a href=\"#what-they-are\">Qu\u00e9 son estas herramientas<\/a><\/li><li><a href=\"#workflow-control\">Flujo de trabajo y control<\/a><\/li><li><a href=\"#repository-understanding\">Conocimiento del repositorio<\/a><\/li><li><a href=\"#implementation\">Implementaci\u00f3n y correcci\u00f3n de errores<\/a><\/li><li><a href=\"#code-review\">Calidad de la revisi\u00f3n de c\u00f3digo<\/a><\/li><li><a href=\"#safety\">Permisos y seguridad<\/a><\/li><li><a href=\"#customization\">MCP, habilidades y personalizaci\u00f3n<\/a><\/li><li><a href=\"#pricing\">Precios y l\u00edmites<\/a><\/li><li><a href=\"#controlled-test\">Prueba controlada<\/a><\/li><li><a href=\"#user-experience\">Informes de los usuarios<\/a><\/li><li><a href=\"#globalgpt\">Capa de extensi\u00f3n GlobalGPT<\/a><\/li><li><a href=\"#which-one\">\u00bfCu\u00e1l elegir?<\/a><\/li><li><a href=\"#faq\">PREGUNTAS FRECUENTES<\/a><\/li>\n  <\/ol>\n<\/nav>\n\n\n\n<h2 id=\"quick-comparison\" class=\"wp-block-heading\">Codex frente a Claude: resumen del c\u00f3digo<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Factor decisivo<\/th><th>C\u00f3dice<\/th><th>C\u00f3digo Claude<\/th><\/tr><\/thead><tbody><tr><td>Trabajo relacionado con el repositorio principal<\/td><td>Lee, edita, ejecuta comandos y verifica los cambios en todas las superficies Codex compatibles<\/td><td>Agente de terminal conversacional para leer, editar, ejecutar comandos y verificar cambios<\/td><\/tr><tr><td>Estilo observado en nuestra prueba<\/td><td>M\u00e1s compacto en algunos aspectos de la implementaci\u00f3n y la correcci\u00f3n de errores<\/td><td>M\u00e1s exhaustivo en cuanto al an\u00e1lisis de los repositorios, las pruebas y el alcance de la revisi\u00f3n<\/td><\/tr><tr><td>Conocimiento del repositorio<\/td><td colspan=\"2\">V\u00ednculo funcional en la tarea congelada<\/td><\/tr><tr><td>Revisi\u00f3n del c\u00f3digo<\/td><td>Se han detectado y corregido dos defectos v\u00e1lidos de mayor gravedad<\/td><td>Se notificaron m\u00e1s problemas reproducibles y se pas\u00f3 de 19\/20 a 18\/20.<\/td><\/tr><tr><td>Velocidad observada<\/td><td colspan=\"2\">Resultados dispares; los entornos no eran lo suficientemente equivalentes como para que hubiera un ganador claro.<\/td><\/tr><tr><td>Gama b\u00e1sica para el consumidor<\/td><td>$20 al mes a trav\u00e9s del plan ChatGPT correspondiente<\/td><td>Claude Pro: $20 al mes en EE. UU.<\/td><\/tr><tr><td>Niveles de mayor consumo<\/td><td>Niveles $100 y $200<\/td><td>M\u00e1ximo 5x en $100 y m\u00e1ximo 20x en $200<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">La tabla describe una decisi\u00f3n de compra, no una clasificaci\u00f3n de modelos. Un cambio en la configuraci\u00f3n del modelo, el repositorio, los permisos o la especificaci\u00f3n de la tarea puede alterar el resultado. Si ya utilizas un producto, la mejor comparaci\u00f3n es una tarea delimitada de tu propio c\u00f3digo fuente con el mismo comando de \u00e9xito y sin repeticiones por motivos de calidad.<\/p>\n\n\n\n<style>\n.cvc-profile{--ink:#18202b;--muted:#667085;--line:#e5e8ee;--codex:#2563eb;--claude:#d97706;margin:28px 0;padding:22px;border:1px solid var(--line);border-radius:8px;background:linear-gradient(145deg,#fff 0%,#f8fafc 100%);color:var(--ink);font:14px\/1.45 Inter,-apple-system,BlinkMacSystemFont,\"Segoe UI\",sans-serif}.cvc-profile *{box-sizing:border-box}.cvc-profile h3{margin:0 0 4px;font-size:20px}.cvc-profile .sub{margin:0 0 20px;color:var(--muted)}.cvc-profile .legend{display:flex;gap:18px;margin-bottom:18px;font-weight:700}.cvc-profile .dot{display:inline-block;width:9px;height:9px;margin-right:7px;border-radius:2px}.cvc-profile .task{display:grid;grid-template-columns:190px 1fr 52px;gap:12px;align-items:center;margin:13px 0}.cvc-profile .task strong{font-size:13px}.cvc-profile .tracks{display:grid;gap:5px}.cvc-profile .track{height:9px;overflow:hidden;border-radius:5px;background:#e9edf3}.cvc-profile .fill{height:100%;border-radius:5px}.cvc-profile .codex{background:var(--codex)}.cvc-profile .claude{background:var(--claude)}.cvc-profile .score{text-align:right;font-variant-numeric:tabular-nums;font-weight:800}.cvc-profile .note{margin:18px 0 0;padding-top:14px;border-top:1px solid var(--line);color:var(--muted);font-size:12px}@media(max-width:650px){.cvc-profile .task{grid-template-columns:1fr 46px}.cvc-profile .task>strong{grid-column:1\/-1}.cvc-profile{padding:18px}}\n<\/style>\n<section class=\"cvc-profile\" aria-label=\"Perfil de notas en las pruebas controladas\">\n  <h3>Perfil de prueba controlado<\/h3>\n  <p class=\"sub\">Primer resultado v\u00e1lido, con la misma r\u00fabrica fija. Las barras se han normalizado en funci\u00f3n de la puntuaci\u00f3n m\u00e1xima de cada tarea.<\/p>\n  <div class=\"legend\"><span><i class=\"dot\" style=\"background:#2563eb\"><\/i>C\u00f3dice<\/span><span><i class=\"dot\" style=\"background:#d97706\"><\/i>C\u00f3digo Claude<\/span><\/div>\n  <div class=\"task\"><strong>T1 \u00b7 Comprensi\u00f3n del repositorio<\/strong><div class=\"tracks\"><div class=\"track\"><div class=\"fill codex\" style=\"width:100%\"><\/div><\/div><div class=\"track\"><div class=\"fill claude\" style=\"width:100%\"><\/div><\/div><\/div><span class=\"score\">20 \/ 20<\/span><\/div>\n  <div class=\"task\"><strong>T2 \u00b7 Funci\u00f3n de m\u00faltiples archivos<\/strong><div class=\"tracks\"><div class=\"track\"><div class=\"fill codex\" style=\"width:100%\"><\/div><\/div><div class=\"track\"><div class=\"fill claude\" style=\"width:100%\"><\/div><\/div><\/div><span class=\"score\">30 \/ 30<\/span><\/div>\n  <div class=\"task\"><strong>T3 \u00b7 Correcci\u00f3n de un error relacionado con el horario de verano<\/strong><div class=\"tracks\"><div class=\"track\"><div class=\"fill codex\" style=\"width:100%\"><\/div><\/div><div class=\"track\"><div class=\"fill claude\" style=\"width:100%\"><\/div><\/div><\/div><span class=\"score\">30 \/ 30<\/span><\/div>\n  <div class=\"task\"><strong>T4 \u00b7 Revisi\u00f3n y reparaci\u00f3n<\/strong><div class=\"tracks\"><div class=\"track\"><div class=\"fill codex\" style=\"width:90%\"><\/div><\/div><div class=\"track\"><div class=\"fill claude\" style=\"width:95%\"><\/div><\/div><\/div><span class=\"score\">18 \/ 19<\/span><\/div>\n  <p class=\"note\">La imagen muestra de d\u00f3nde proviene esa diferencia de un punto; no convierte un partido concreto en una clasificaci\u00f3n general.<\/p>\n<\/section>\n\n\n\n<h2 id=\"what-they-are\" class=\"wp-block-heading\">Qu\u00e9 son realmente el Codex y el c\u00f3digo Claude<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u00abCodex\u00bb y \u00abClaude Code\u00bb son productos de la marca, no simples nombres de modelos. El concepto subyacente <a href=\"https:\/\/www.glbgpt.com\/hub\/best-ai-model-for-coding\/\">Modelo de IA para la programaci\u00f3n<\/a> es importante, pero el entorno que lo rodea tambi\u00e9n determina qu\u00e9 archivos puede ver el agente, qu\u00e9 comandos puede ejecutar, c\u00f3mo funcionan las autorizaciones, c\u00f3mo se conserva el contexto y qu\u00e9 pruebas quedan tras la tarea. Si solo se compara la reputaci\u00f3n del modelo, se pasa por alto gran parte de la experiencia que el desarrollador est\u00e1 adquiriendo.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Codex abarca flujos de trabajo en l\u00ednea de comandos, IDE, de escritorio y orientados a la nube. Esa versatilidad lo hace adecuado tanto para la colaboraci\u00f3n local directa como para una delegaci\u00f3n m\u00e1s delimitada. Claude Code se centra en un flujo de trabajo conversacional en terminal con integraciones compatibles y amplias posibilidades de personalizaci\u00f3n; esto <a href=\"https:\/\/www.glbgpt.com\/hub\/how-to-use-claude-ai-for-coding\/\">Gu\u00eda para el uso de Claude en la codificaci\u00f3n<\/a> ofrece una introducci\u00f3n m\u00e1s amplia a ese flujo de trabajo. Para algunos desarrolladores, ver c\u00f3mo trabaja un agente en la terminal resulta tranquilizador. Para otros, lo importante es el diff final, las pruebas y el registro de auditor\u00eda, m\u00e1s que una conversaci\u00f3n continua.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Esta distinci\u00f3n tambi\u00e9n explica por qu\u00e9 dos pruebas que utilizan modelos nominalmente s\u00f3lidos pueden comportarse de forma diferente. El anfitri\u00f3n decide c\u00f3mo se presentan las instrucciones, c\u00f3mo se invocan las herramientas y cu\u00e1ndo debe un ser humano aprobar una acci\u00f3n. Las comparaciones entre comunidades que ignoran el entorno de pruebas pueden confundir un comportamiento a nivel de producto con una verdad a nivel de modelo.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>El modelo<\/strong> proporciona capacidad de razonamiento y de generaci\u00f3n.<\/li>\n\n\n\n<li><strong>El arn\u00e9s del agente<\/strong> gestiona archivos, comandos, contexto, autorizaciones y recuperaci\u00f3n.<\/li>\n\n\n\n<li><strong>El contrato de tareas del usuario<\/strong> determina el alcance, las comprobaciones de \u00e9xito y cu\u00e1ndo debe detenerse el agente.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"1280\" height=\"800\" src=\"https:\/\/wp.glbgpt.com\/wp-content\/uploads\/2026\/07\/x-harness-vs-model-caveat-annotated.webp\" alt=\"Publicaci\u00f3n en X con comentarios en la que se se\u00f1ala que un \u00abagent harness\u00bb puede afectar a las comparaciones entre el c\u00f3digo y el agente\" class=\"wp-image-17390\" srcset=\"https:\/\/wp.glbgpt.com\/wp-content\/uploads\/2026\/07\/x-harness-vs-model-caveat-annotated.webp 1280w, https:\/\/wp.glbgpt.com\/wp-content\/uploads\/2026\/07\/x-harness-vs-model-caveat-annotated-300x188.webp 300w, https:\/\/wp.glbgpt.com\/wp-content\/uploads\/2026\/07\/x-harness-vs-model-caveat-annotated-1024x640.webp 1024w, https:\/\/wp.glbgpt.com\/wp-content\/uploads\/2026\/07\/x-harness-vs-model-caveat-annotated-768x480.webp 768w, https:\/\/wp.glbgpt.com\/wp-content\/uploads\/2026\/07\/x-harness-vs-model-caveat-annotated-18x12.webp 18w\" sizes=\"(max-width: 1280px) 100vw, 1280px\" \/><figcaption class=\"wp-element-caption\">Un comentario de un tal X pone de relieve una salvedad importante a la hora de comparar: el sistema de control del agente puede influir en los resultados. Se trata de un dato contextual \u00fatil, no de una prueba contrastada de que uno de los productos sea mejor que el otro.<\/figcaption><\/figure>\n\n\n\n<h2 id=\"workflow-control\" class=\"wp-block-heading\">Flujo de trabajo y control: \u00bfdelegaci\u00f3n o direcci\u00f3n continua?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">La pregunta m\u00e1s \u00fatil sobre el C\u00f3digo Codex frente al Claude no suele ser \u201c\u00bfCu\u00e1l permite escribir mejor c\u00f3digo?\u201d, sino \u201c\u00bfC\u00f3mo quiero trabajar con \u00e9l?\u201d. Una tarea clara y delimitada puede delegarse con un objetivo exacto, un alcance permitido y una orden de verificaci\u00f3n. Una refactorizaci\u00f3n ambigua se beneficia del debate, la inspecci\u00f3n intermedia y la oportunidad de reorientar al agente antes de que introduzca demasiados cambios.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La orientaci\u00f3n continua resulta \u00fatil cuando los requisitos est\u00e1n en constante evoluci\u00f3n o cuando a\u00fan se est\u00e1 negociando el dise\u00f1o arquitect\u00f3nico. Se convierte en un coste cuando el agente solicita repetidamente decisiones que podr\u00edan haberse resuelto a partir de las instrucciones del repositorio. La ejecuci\u00f3n aut\u00f3noma resulta \u00fatil cuando el contrato de la tarea es estable. Se vuelve arriesgada cuando el agente hace suposiciones sin contrastar o ampl\u00eda el alcance sin una v\u00eda clara de reversi\u00f3n.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Un informe detallado publicado en Reddit con fecha del 13 de abril de 2026 describ\u00eda unas 100 horas de trabajo con Claude Code y 20 horas con Codex en un proyecto de Python y TypeScript de aproximadamente 80 000 l\u00edneas con unas 2 800 pruebas. El autor describi\u00f3 Claude como m\u00e1s r\u00e1pido y m\u00e1s interactivo, aunque requiere m\u00e1s supervisi\u00f3n, y Codex como m\u00e1s lento y m\u00e1s met\u00f3dico. Ese informe resulta especialmente \u00fatil porque incluye el contexto del proyecto y la experiencia, pero sigue representando el flujo de trabajo de un solo desarrollador.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"1280\" height=\"800\" src=\"https:\/\/wp.glbgpt.com\/wp-content\/uploads\/2026\/07\/reddit-claude-code-vs-codex-experience-annotated.webp\" alt=\"Experiencia comentada en Reddit en la que se comparan Claude Code y Codex en un proyecto de 80 000 l\u00edneas de c\u00f3digo\" class=\"wp-image-17391\" srcset=\"https:\/\/wp.glbgpt.com\/wp-content\/uploads\/2026\/07\/reddit-claude-code-vs-codex-experience-annotated.webp 1280w, https:\/\/wp.glbgpt.com\/wp-content\/uploads\/2026\/07\/reddit-claude-code-vs-codex-experience-annotated-300x188.webp 300w, https:\/\/wp.glbgpt.com\/wp-content\/uploads\/2026\/07\/reddit-claude-code-vs-codex-experience-annotated-1024x640.webp 1024w, https:\/\/wp.glbgpt.com\/wp-content\/uploads\/2026\/07\/reddit-claude-code-vs-codex-experience-annotated-768x480.webp 768w, https:\/\/wp.glbgpt.com\/wp-content\/uploads\/2026\/07\/reddit-claude-code-vs-codex-experience-annotated-18x12.webp 18w\" sizes=\"(max-width: 1280px) 100vw, 1280px\" \/><figcaption class=\"wp-element-caption\">Experiencia espec\u00edfica de un desarrollador con Claude Code y Codex en un proyecto concreto. Las observaciones destacadas deben considerarse hip\u00f3tesis que hay que comprobar, y no datos de rendimiento aplicables a todo el producto.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Nuestros propios tiempos de ejecuci\u00f3n no permitieron determinar un ganador claro. Claude complet\u00f3 las dos primeras tareas m\u00e1s r\u00e1pido, mientras que Codex complet\u00f3 las dos \u00faltimas m\u00e1s r\u00e1pido. Adem\u00e1s, Claude recurri\u00f3 a un subagente de reserva cuando su ruta de autenticaci\u00f3n CLI no estaba disponible, por lo que las rutas de ejecuci\u00f3n no eran equivalentes a las del laboratorio. La conclusi\u00f3n m\u00e1s acertada es que la velocidad depende de la tarea, el modelo seleccionado, la configuraci\u00f3n del esfuerzo, el contexto y el host, y no que uno de los dos productos sea siempre m\u00e1s r\u00e1pido.<\/p>\n\n\n\n<h2 id=\"repository-understanding\" class=\"wp-block-heading\">Comprensi\u00f3n del repositorio y gesti\u00f3n del contexto<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Comprender el repositorio es algo m\u00e1s que nombrar carpetas. Un agente \u00fatil debe rastrear c\u00f3mo se mueven los datos entre los archivos, identificar los contratos que limitan un cambio, localizar las pruebas, distinguir un s\u00edntoma de su posible origen y explicar el riesgo que supone modificar la capa equivocada. Un mapa exhaustivo puede revelar incoherencias ocultas; un mapa conciso puede llevar a un desarrollador a tomar una decisi\u00f3n de implementaci\u00f3n segura con mayor rapidez.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">En nuestra tarea T1 de solo lectura, ambos agentes obtuvieron una puntuaci\u00f3n de 20\/20 y basaron sus respuestas en el repositorio. El c\u00f3digo Claude fue m\u00e1s exhaustivo y puso de manifiesto inconsistencias adicionales en el contrato. Codex fue m\u00e1s conciso, aunque identific\u00f3 los archivos relevantes, los riesgos y el plan de implementaci\u00f3n. Ninguno de los dos estilos es autom\u00e1ticamente superior. La exhaustividad resulta \u00fatil en migraciones y auditor\u00edas con las que no se est\u00e1 familiarizado; la concisi\u00f3n ayuda cuando el desarrollador ya conoce la arquitectura y desea un plan de cambios espec\u00edfico.<\/p>\n\n\n\n<style>\n.evidence-t1-repository-understanding{--ink:#111318;--body:#414753;--muted:#707784;--line:#e4e7ec;--soft:#f6f7f9;--blue:#315efb;--violet:#7257e8;--green:#087a55;--greenSoft:#eaf8f2;--red:#a23131;--redSoft:#fff0f0;color:var(--ink);font-family:Inter,ui-sans-serif,-apple-system,BlinkMacSystemFont,\"Segoe UI\",sans-serif;line-height:1.5;border:1px solid var(--line);border-radius:8px;background:#fff;overflow:hidden;box-shadow:0 16px 42px rgba(24,32,56,.08)}\n.evidence-t1-repository-understanding *{box-sizing:border-box}.evidence-t1-repository-understanding .d-head{display:flex;align-items:flex-start;justify-content:space-between;gap:22px;padding:24px 26px 20px;border-bottom:1px solid var(--line)}\n.evidence-t1-repository-understanding .d-kicker{margin:0 0 6px;color:var(--muted);font:750 11px\/1.4 ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.08em;text-transform:uppercase}.evidence-t1-repository-understanding .d-title{margin:0;font-size:22px;line-height:1.2;letter-spacing:-.025em}.evidence-t1-repository-understanding .d-sub{margin:7px 0 0;color:var(--body);font-size:13px}.evidence-t1-repository-understanding .d-pill{flex:0 0 auto;padding:6px 10px;border:1px solid #ccd6ff;border-radius:999px;color:#2448ca;background:#f0f3ff;font-size:11px;font-weight:800}.evidence-t1-repository-understanding .d-grid{display:grid;grid-template-columns:1fr 1fr}.evidence-t1-repository-understanding .d-side{min-width:0;padding:24px 26px}.evidence-t1-repository-understanding .d-side+.d-side{border-left:1px solid var(--line)}.evidence-t1-repository-understanding .d-product{display:flex;align-items:baseline;justify-content:space-between;gap:14px;font-weight:800}.evidence-t1-repository-understanding .d-score{font-size:34px;line-height:1;letter-spacing:-.05em}.evidence-t1-repository-understanding .d-score small{color:var(--muted);font-size:12px;letter-spacing:0}.evidence-t1-repository-understanding .d-metrics{display:grid;grid-template-columns:repeat(3,1fr);gap:7px;margin:18px 0}.evidence-t1-repository-understanding .d-metric{padding:10px;border:1px solid var(--line);border-radius:6px;background:var(--soft)}.evidence-t1-repository-understanding .d-metric span{display:block;color:var(--muted);font-size:9px;font-weight:800;letter-spacing:.06em;text-transform:uppercase}.evidence-t1-repository-understanding .d-metric strong{display:block;margin-top:3px;font-size:13px}.evidence-t1-repository-understanding .d-preview{position:relative;height:192px;overflow:hidden;border:1px solid #29313f;border-radius:6px;background:#11151d;color:#edf0f5}.evidence-t1-repository-understanding .d-preview-label{padding:11px 13px;border-bottom:1px solid rgba(255,255,255,.1);color:#aeb7c7;font:750 9px\/1 ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.06em;text-transform:uppercase}.evidence-t1-repository-understanding .d-preview pre,.evidence-t1-repository-understanding .d-full pre{margin:0;white-space:pre-wrap;font:11px\/1.6 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.evidence-t1-repository-understanding .d-preview pre{padding:13px}.evidence-t1-repository-understanding .d-preview:after{content:\"\";position:absolute;left:0;right:0;bottom:0;height:55px;background:linear-gradient(transparent,#11151d)}.evidence-t1-repository-understanding .d-take{margin:14px 0 0;color:var(--body);font-size:12px}.evidence-t1-repository-understanding .d-fulls{padding:0 26px 22px}.evidence-t1-repository-understanding .d-full{margin-top:10px;border:1px solid var(--line);border-radius:6px}.evidence-t1-repository-understanding .d-full summary{cursor:pointer;padding:13px 14px;font-size:12px;font-weight:800;list-style:none}.evidence-t1-repository-understanding .d-full summary::-webkit-details-marker{display:none}.evidence-t1-repository-understanding .d-full summary:after{content:\"+\";float:right;color:var(--blue);font-size:17px}.evidence-t1-repository-understanding .d-full[open] summary:after{content:\"\u2212\"}.evidence-t1-repository-understanding .d-full-pane{padding:0 14px 14px}.evidence-t1-repository-understanding .d-full-note{margin:0 0 9px;color:var(--muted);font-size:10px}.evidence-t1-repository-understanding .d-full pre{max-height:620px;overflow:auto;padding:15px;border-radius:5px;background:#f5f6f8;color:#222936;border:1px solid #e0e3e8}.evidence-t1-repository-understanding .d-limit{margin:0;padding:12px 26px;border-top:1px solid var(--line);color:#5a6270;background:#fafbfc;font-size:11px}\n@media(max-width:760px){.evidence-t1-repository-understanding .d-head{display:block}.evidence-t1-repository-understanding .d-pill{display:inline-block;margin-top:12px}.evidence-t1-repository-understanding .d-grid{grid-template-columns:1fr}.evidence-t1-repository-understanding .d-side+.d-side{border-left:0;border-top:1px solid var(--line)}}@media(max-width:480px){.evidence-t1-repository-understanding .d-head,.evidence-t1-repository-understanding .d-side{padding:20px}.evidence-t1-repository-understanding .d-fulls{padding:0 20px 20px}.evidence-t1-repository-understanding .d-metrics{grid-template-columns:1fr}}\n<\/style><article class=\"evidence-t1-repository-understanding\"><header class=\"d-head\"><div><p class=\"d-kicker\">T1 \u00b7 Prueba del repositorio controlado<\/p><h3 class=\"d-title\">Familiar\u00edzate con un repositorio que no conozcas antes de modificarlo<\/h3><p class=\"d-sub\">Analizar la arquitectura, rastrear el flujo de datos, identificar los riesgos relacionados con las funciones prioritarias y no realizar cambios en los archivos.<\/p><\/div><span class=\"d-pill\">Corbata<\/span><\/header><div class=\"d-grid\"><section class=\"d-side\" aria-label=\"Resultado del Codex\"><div class=\"d-product\"><span>C\u00f3dice<\/span><span class=\"d-score\">20<small>\/20<\/small><\/span><\/div><div class=\"d-metrics\"><div class=\"d-metric\"><span>Duraci\u00f3n<\/span><strong>108 s<\/strong><\/div><div class=\"d-metric\"><span>Cheques<\/span><strong>2: valor de referencia<\/strong><\/div><div class=\"d-metric\"><span>Alcance<\/span><strong>S\u00f3lo lectura<\/strong><\/div><\/div><div class=\"d-preview\"><div class=\"d-preview-label\">Primer fragmento v\u00e1lido de la salida<\/div><pre>Arquitectura: modelo, repositorio, servicio y una utilidad de tiempo sin cablear.\n\nPrincipales riesgos: sem\u00e1ntica de prioridades indefinida, compatibilidad, ordenaci\u00f3n, validaci\u00f3n y discrepancia de \u00e1mbito.<\/pre><\/div><p class=\"d-take\"><strong>Opini\u00f3n del cr\u00edtico:<\/strong> Compacto, basado en los expedientes y suficiente para la resoluci\u00f3n suspendida.<\/p><\/section><section class=\"d-side\" aria-label=\"Resultado del c\u00f3digo Claude\"><div class=\"d-product\"><span>C\u00f3digo Claude<\/span><span class=\"d-score\">20<small>\/20<\/small><\/span><\/div><div class=\"d-metrics\"><div class=\"d-metric\"><span>Duraci\u00f3n<\/span><strong>61 s<\/strong><\/div><div class=\"d-metric\"><span>Cheques<\/span><strong>2: valor de referencia<\/strong><\/div><div class=\"d-metric\"><span>Alcance<\/span><strong>S\u00f3lo lectura<\/strong><\/div><\/div><div class=\"d-preview\"><div class=\"d-preview-label\">Primer fragmento v\u00e1lido de la salida<\/div><pre>Tres capas m\u00e1s un m\u00f3dulo independiente. Sin ciclos; inyecci\u00f3n de dependencias m\u00ednima.\n\nTambi\u00e9n puso de manifiesto la asignaci\u00f3n de identificadores, los contratos de error asim\u00e9tricos y una cobertura de pruebas escasa.<\/pre><\/div><p class=\"d-take\"><strong>Opini\u00f3n del cr\u00edtico:<\/strong> M\u00e1s exhaustivo, sin dejar de cumplir el mismo contrato de solo lectura.<\/p><\/section><\/div><div class=\"d-fulls\"><details class=\"d-full\"><summary>Ver el resultado completo de Codex<\/summary><div class=\"d-full-pane\"><p class=\"d-full-note\">Salida completa, desinfectada y v\u00e1lida por primera vez<\/p><pre>Arquitectura ##\n\nSe trata de un peque\u00f1o paquete de Python que utiliza \u00fanicamente la biblioteca est\u00e1ndar y que cuenta con cuatro capas funcionales:\n\n- **Modelo de datos:** [`Job`]() es una clase de datos inmutable que contiene `identifier`, `name` y `owner`. `Job.to_dict()` la serializa mediante `dataclasses.asdict()`.\n- **Repositorio:** [`JobRepository`]() almacena los trabajos en un diccionario en memoria cuyas claves son los identificadores. No hay base de datos ni persistencia duradera.\n- **Servicio:** [`SchedulerService`]() se encarga de la asignaci\u00f3n de identificadores, la normalizaci\u00f3n de entradas, la creaci\u00f3n, la visualizaci\u00f3n en la lista y la eliminaci\u00f3n.\n- **Utilidad de tiempo:** [`next_daily_run()`]() calcula la hora de la siguiente ejecuci\u00f3n, pero no hay nada que la importe ni la conecte con `Job`, `SchedulerService` o `JobRepository`.\n- **API p\u00fablica:** [`scheduler.__init__`]() solo exporta `SchedulerService`.\n\nA pesar del nombre del repositorio, los trabajos no contienen actualmente informaci\u00f3n de programaci\u00f3n, y no existe una cola de ejecuci\u00f3n. Por lo tanto, la prioridad puede afectar a los metadatos almacenados y al orden de aparici\u00f3n en la lista, pero no puede influir en la ejecuci\u00f3n real de los trabajos sin ampliar considerablemente el sistema.\n\n## Flujo de datos de creaci\u00f3n y listado\n\nCreaci\u00f3n mediante `SchedulerService.create_job(name, owner)`:\n\n1. [`create_job()`]() rechaza un nombre compuesto \u00fanicamente por espacios en blanco.\n2. Recorta `name` y `owner` y, a continuaci\u00f3n, construye un objeto `Job` inmutable utilizando el `_next_identifier` del servicio.\n3. [`JobRepository.save()`]() guarda el objeto en `_jobs[job.identifier]`.\n4. El servicio incrementa `_next_identifier` y devuelve el mismo `Job`.\n\nListado mediante `SchedulerService.list_jobs()`:\n\n1. [`list_jobs()`]() delega directamente en `repository.all()`.\n2. [`JobRepository.all()`]() ordena num\u00e9ricamente las claves del diccionario.\n3. Por lo tanto, los trabajos se devuelven en orden ascendente por identificador o fecha de creaci\u00f3n, no por orden de programaci\u00f3n o prioridad.\n\n## Archivos que probablemente se vean afectados por las prioridades de los trabajos\n\nRequerido:\n\n- [`scheduler\/models.py`](): a\u00f1adir el campo de prioridad y cualquier valor por defecto. `to_dict()` lo incluir\u00e1 autom\u00e1ticamente, ya que utiliza `asdict()`.\n- [`scheduler\/service.py`](): aceptar, validar y pasar la prioridad a `Job`.\n- [`tests\/test_scheduler.py`](): cubrir el comportamiento por defecto, expl\u00edcito, no v\u00e1lido, serializado y de ordenaci\u00f3n.\n\nCondicional:\n\n- [`scheduler\/repository.py`](): modificar `all()` solo si se pretende que las prioridades controlen el orden de la lista. Una clave secundaria determinista, como `identifier`, deber\u00eda gestionar los empates.\n- [`scheduler\/__init__.py`](): actualizar solo si la prioridad se convierte en una enumeraci\u00f3n p\u00fablica o en un objeto de valor.\n- [`README.md`](): documentar los valores aceptados, el valor por defecto y la sem\u00e1ntica de ordenaci\u00f3n.\n\nProbablemente no se vea afectado:\n\n- `scheduler\/time_rules.py`, ya que su \u00fanico s\u00edmbolo opera sobre una fecha y hora proporcionadas y no tiene relaci\u00f3n alguna con los trabajos ni con la lista.\n\n## Riesgos principales\n\n- **Sem\u00e1ntica indefinida:** El c\u00f3digo no ofrece ning\u00fan precedente sobre si los valores m\u00e1s grandes o m\u00e1s peque\u00f1os significan una mayor prioridad, qu\u00e9 valores son v\u00e1lidos o si la prioridad afecta en absoluto al orden de la lista.\n- **Compatibilidad:** A\u00f1adir un argumento obligatorio a `Job` o a `create_job()` romper\u00eda las llamadas existentes, como `create_job(\"Daily report\", \"Alex\")` en la prueba actual. Un valor por defecto preservar\u00eda esa llamada.\n- **Rotura del constructor posicional:** Actualmente, `Job` se construye de forma posicional en `SchedulerService.create_job()`. La ubicaci\u00f3n de los campos y futuras llamadas posicionales podr\u00edan asignar valores err\u00f3neos de forma silenciosa; la construcci\u00f3n mediante palabras clave ser\u00eda m\u00e1s segura.\n- **Cambio en el orden:** Cambiar el orden de los identificadores en `JobRepository.all()` altera el comportamiento establecido. Las prioridades iguales necesitan un criterio de desempate estable.\n- **Ambiguidad en la validaci\u00f3n:** Un valor de Python sin restricciones podr\u00eda admitir cadenas, valores booleanos o enteros arbitrarios que son dif\u00edciles de comparar de forma coherente.\n- **Discrepancia en el \u00e1mbito de ejecuci\u00f3n:** No hay ning\u00fan distribuidor ni cola de ejecuci\u00f3n. Afirmar que la prioridad determina qu\u00e9 trabajo se ejecuta primero no estar\u00eda respaldado por ning\u00fan s\u00edmbolo actual.\n- **Limitaciones en memoria:** La prioridad, al igual que cualquier otro campo del trabajo, desaparece cuando finaliza el proceso, ya que `_jobs` es solo un diccionario de instancia.\n\n## Plan de implementaci\u00f3n y validaci\u00f3n\n\n1. Definir primero el contrato: representaci\u00f3n, valores permitidos, valor por defecto, direcci\u00f3n de la prioridad, desempate y si cambia el orden de la lista.\n2. A\u00f1adir `priority` a `Job`, preferiblemente con un valor por defecto compatible con versiones anteriores.\n3. Ampliar `SchedulerService.create_job()` con un par\u00e1metro de prioridad por defecto, validarlo y construir `Job` con argumentos clave.\n4. Si la lista tiene en cuenta la prioridad, cambiar `JobRepository.all()` para ordenar primero por prioridad y luego por identificador. De lo contrario, dejar el orden del repositorio sin cambios.\n5. A\u00f1adir pruebas para:\n   - La creaci\u00f3n existente con dos argumentos.\n   - La conservaci\u00f3n expl\u00edcita de la prioridad.\n   - La prioridad por defecto.\n   - Tipos no v\u00e1lidos y valores fuera de rango.\n   - Salida de `Job.to_dict()`.\n   - Orden de la lista con prioridades m\u00faltiples.\n   - Orden estable para prioridades iguales.\n   - Comportamiento actual ante nombres en blanco.\n6. Actualiza el README con el contrato p\u00fablico exacto.\n7. Ejecutar el conjunto completo de pruebas sin conexi\u00f3n con `python3 -m unittest discover -s tests -v`.\n\n## Verificaci\u00f3n realizada\n\n- Conjunto de pruebas de referencia: **2 pruebas superadas**.\n- La b\u00fasqueda de s\u00edmbolos en todo el repositorio ha confirmado que `next_daily_run()` est\u00e1 desconectado y que no hay s\u00edmbolos de prioridad existentes.\n- Archivos modificados: **ninguno**.\n- Implementaci\u00f3n de la funcionalidad: **no realizada**, tal y como se requer\u00eda.\n\n&gt; **Conclusi\u00f3n + decisi\u00f3n**\n&gt;\n&gt; El cambio es m\u00ednimo si la prioridad es solo metadatos o el orden de la lista: principalmente `models.py`, `service.py`, `repository.py` y las pruebas. Antes de la implementaci\u00f3n, hay que decidir si la prioridad simplemente describe un trabajo o si cambia el orden de `list_jobs()`, adem\u00e1s de la escala de valores, el valor por defecto, la direcci\u00f3n y la regla de desempate.<\/pre><\/div><\/details><details class=\"d-full\"><summary>Ver el c\u00f3digo Claude completo<\/summary><div class=\"d-full-pane\"><p class=\"d-full-note\">Registro completo de la transferencia, incluida la salida v\u00e1lida inicial tal y como se ha registrado.<\/p><pre>Registro de ejecuci\u00f3n de # T1 \u2014 Comprensi\u00f3n de un repositorio desconocido\n\nPar\u00e1metros de ejecuci\u00f3n de ##\n\n| Campo | Valor |\n| --- | --- |\n| Tarea | `T1` |\n| Prompt congelado | `01-prompts\/T1.md` |\n| SHA-256 del prompt congelado | `a571ff15c2502ec29b172ae2e77dd9ab0caca2869b91f9468d47571434d16c17` |\n| Unidad de ejecuci\u00f3n | subagente aislado Claude, \"uso general\", contexto nuevo |\n| M\u00e9todo de aislamiento | **recurso de reserva del subagente** (rebaja documentada \u2014 v\u00e9ase `results\/isolation-decision.md`) |\n| Copia limpia asignada | `runtime\/workspaces\/T1` |\n| Versi\u00f3n del c\u00f3digo Claude | `2.1.220` |\n| Configuraci\u00f3n del modelo | `claude-opus-5` |\n| start_utc | `2026-07-28T10:27:31Z` |\n| end_utc | `2026-07-28T10:28:32Z` |\n| Duraci\u00f3n | 61 s (simult\u00e1neo con T2\u2013T4; no es una medici\u00f3n de latencia precisa) |\n| N\u00famero de intento | 1 |\n| Estado | `v\u00e1lido` |\n| Intervenci\u00f3n humana | ninguna |\n\n## Resumen de la herramienta segura\n\n`date`, `find`, `ls`, `wc`, `stat`, `grep`, `Read` en 7 archivos del espacio de trabajo, `python3 -V`,\n`python3 -m unittest discover -s tests -v`. Todas las lecturas se limitan al espacio de trabajo asignado.\nSin red, sin instalaciones, sin escrituras.\n\n## Resultado de la comprobaci\u00f3n sin conexi\u00f3n\n\n`python3 -m unittest discover -s tests -v` \u2192 2 pruebas, OK (salida 0). Revisado de nuevo por el\ncoordinador desde fuera del espacio de trabajo: v\u00e9ase `results\/checks\/T1-public.txt`.\n\n## Parche\n\nNinguno. `results\/T1\/patch.diff` est\u00e1 vac\u00edo, y `diff -ru 02-fixture runtime\/workspaces\/T1`\nno devuelve diferencias. La tarea requer\u00eda una inspecci\u00f3n sin modificar archivos; esto se\nha confirmado, no se ha afirmado.\n\n## Errores corregidos\n\nUn error recuperable del shell: un `grep` inicial utilizaba patrones `--include=*.py` sin comillas que\nel shell intent\u00f3 expandir; al volver a ejecutarlo con los patrones entre comillas, se complet\u00f3 con \u00e9xito. No afect\u00f3 a los resultados.\n\n## Salida visible (textual)\n\n### 1. Qu\u00e9 es este repositorio\n\nUn fixture aut\u00f3nomo de la biblioteca est\u00e1ndar de Python denominado `local-scheduler-1.0.0` (`fixture-manifest.json`), con licencia MIT, sin dependencias de red ni de producci\u00f3n (`README.md`, `\"network_required\": false`). Es muy peque\u00f1o: 8 archivos de c\u00f3digo fuente y documentaci\u00f3n, m\u00e1s el manifiesto, con un total de 103 l\u00edneas. El int\u00e9rprete utilizado es **Python 3.9.6**. No hay ning\u00fan `pyproject.toml`, `setup.py`, configuraci\u00f3n de CI, linter ni configuraci\u00f3n de verificador de tipos; el \u00fanico flujo de trabajo declarado es `python3 -m unittest discover -s tests -v` (`README.md`).\n\n### 2. Arquitectura\n\nTres capas m\u00e1s un m\u00f3dulo independiente, todo bajo `scheduler\/`:\n\n| Capa | Archivo | S\u00edmbolo | Responsabilidad |\n|---|---|---|---|\n| Fachada del paquete | `scheduler\/__init__.py` | `__all__ = ['SchedulerService\"]` | Solo reexporta `SchedulerService`; `Job`, `JobRepository` y `time_rules` no forman parte de la superficie p\u00fablica |\n| Modelo de dominio | `scheduler\/models.py` | `Job` (`@dataclass(frozen=True)`) | Objeto de valor inmutable con los campos `identifier: int`, `name: str`, `owner: str`, adem\u00e1s de `to_dict()` implementado como `asdict(self)` |\n| Persistencia | `scheduler\/repository.py` | `JobRepository` | `dict` en memoria con el identificador como clave; `save`, `get`, `all`, `delete` |\n| Servicio de aplicaci\u00f3n | `scheduler\/service.py` | `SchedulerService` | Validaci\u00f3n, asignaci\u00f3n de identificadores, orquestaci\u00f3n: `create_job`, `list_jobs`, `delete_job` |\n| Hu\u00e9rfano | `scheduler\/time_rules.py` | `next_daily_run` | C\u00e1lculos de recurrencia \u2014 **no es importado por ning\u00fan otro archivo** |\n\nLa direcci\u00f3n de las dependencias es clara y unidireccional: `service.py` importa desde `.models` y `.repository`; `repository.py` importa desde `.models`; `models.py` solo importa `dataclasses`. No hay ciclos. La inyecci\u00f3n de dependencias est\u00e1 presente, pero es m\u00ednima: `SchedulerService.__init__(self, repository=None)` ejecuta `self.repository = repository or JobRepository()`, por lo que se puede sustituir por un repositorio ficticio en las pruebas.\n\nTen en cuenta que `scheduler\/time_rules.py` es c\u00f3digo obsoleto a d\u00eda de hoy. He buscado con grep en todo el \u00e1rbol las cadenas `time_rules` y `next_daily_run`; los \u00fanicos resultados son su propia definici\u00f3n y su aparici\u00f3n en `expected_files` de `fixture-manifest.json`. Se incluye en la distribuci\u00f3n, pero no est\u00e1 conectado.\n\n### 3. Flujo de datos\n\n**Creaci\u00f3n de un trabajo** \u2014 `SchedulerService.create_job(name, owner)`:\n1. Condici\u00f3n de seguridad: `if not name.strip(): raise ValueError(\"name is required')`. Esta es la *\u00fanica* validaci\u00f3n del sistema: nunca se comprueba `owner`, por lo que se acepta un propietario en blanco.\n2. Construcci\u00f3n: `Job(self._next_identifier, name.strip(), owner.strip())` \u2014 construcci\u00f3n posicional, y ambas cadenas se normalizan mediante la eliminaci\u00f3n de espacios.\n3. Persistencia: `self.repository.save(job)`, que realiza `self._jobs[job.identifier] = job` y devuelve el trabajo.\n4. Avanzar el contador: `self._next_identifier += 1` \u2014 *despu\u00e9s* de guardar, de modo que si se produce una excepci\u00f3n, el contador queda sin consumir.\n5. Devolver la instancia de `Job` (el servicio devuelve su propio `job` local, no el valor de retorno del repositorio).\n\nLa asignaci\u00f3n de identificadores se realiza en el **servicio**, no en el repositorio (`self._next_identifier = 1` en `SchedulerService.__init__`). Este es un punto de uni\u00f3n importante: inyectar un repositorio que ya contenga trabajos los sobrescribir\u00e1 de forma silenciosa, ya que el nuevo servicio reinicia la numeraci\u00f3n desde 1.\n\n**Listado de trabajos** \u2014 `SchedulerService.list_jobs()` es un simple reenv\u00edo a `JobRepository.all()`, que devuelve `[self._jobs[key] for key in sorted(self._jobs)]`. Por lo tanto, el orden es **ascendente por identificador entero**, lo que actualmente coincide con el orden de inserci\u00f3n. Se crea una nueva lista en cada llamada, pero los objetos `Job` son referencias compartidas \u2014lo cual es seguro \u00fanicamente porque `Job` est\u00e1 congelado\u2014.\n\n**Eliminaci\u00f3n** \u2014 `SchedulerService.delete_job(identifier)` delega en `JobRepository.delete`, que es `self._jobs.pop(identifier)` sin valor por defecto, por lo que lanza un `KeyError` si falta el identificador. Esto es inconsistente con `JobRepository.get`, que devuelve `None` en la misma condici\u00f3n.\n\n**Cobertura de pruebas de estas rutas** \u2014 `tests\/test_scheduler.py` tiene exactamente dos casos: `test_create_and_list_jobs` (verifica que `job.identifier == 1` y `[job] == service.list_jobs()`) y `test_blank_name_is_rejected`. Ambos se superan en el \u00e1rbol actual.\n\n### 4. Archivos que probablemente se vean afectados por la incorporaci\u00f3n de prioridades de trabajos\n\nPor orden descendente de certeza:\n\n1. **`scheduler\/models.py`** \u2014 seguro. `Job` necesita un campo `priority`. Dado que la clase de datos tiene `frozen=True` y los campos son posicionales, un nuevo campo debe llevar un valor por defecto (p. ej., `priority: int = 0`) o debe colocarse despu\u00e9s de los tres existentes; de lo contrario, se romper\u00e1 toda la construcci\u00f3n posicional existente. `to_dict()` no necesita modificaci\u00f3n: `asdict(self)` recoge el campo autom\u00e1ticamente, lo que supone un cambio silencioso en el contrato de serializaci\u00f3n m\u00e1s que un cambio en el c\u00f3digo.\n2. **`scheduler\/service.py`** \u2014 seguro. `create_job` necesita un par\u00e1metro `priority` y debe pasarlo al constructor posicional `Job(...)` en la l\u00ednea 13. Si se valida la prioridad (rango, pertenencia a una enumeraci\u00f3n), la condici\u00f3n debe ir junto a la comprobaci\u00f3n existente `name.strip()`. Si la lista debe ordenarse por prioridad, `list_jobs` es donde se aplicar\u00eda una pol\u00edtica de ordenaci\u00f3n si se desea que el repositorio siga siendo un almac\u00e9n \"tonto\".\n3. **`scheduler\/repository.py`** \u2014 probable. El m\u00e9todo `sorted(self._jobs)` de `JobRepository.all()` ordena las *claves* del diccionario, es decir, los identificadores. Para obtener una lista ordenada por prioridad, es necesario cambiar esto para ordenar los valores mediante una clave como `(-job.priority, job.identifier)`, o a\u00f1adir un accesor ordenado independiente. No dejes el desempate impl\u00edcito: el orden de inserci\u00f3n en el diccionario no es un contrato estable en el que se pueda confiar.\n4. **`tests\/test_scheduler.py`** \u2014 seguro. Nuevos casos para la prioridad por defecto, la prioridad expl\u00edcita, el orden y el rechazo por prioridad no v\u00e1lida. Ten en cuenta que el `assertEqual([job], service.list_jobs())` existente compara el *mismo* objeto, por lo que se mantiene tras la adici\u00f3n de un campo; no se mantendr\u00eda si comparara un literal `Job` reci\u00e9n creado.\n5. **`README.md`** \u2014 Probable, si es necesario indicar en alg\u00fan lugar la sem\u00e1ntica de la prioridad (qu\u00e9 extremo del rango prevalece, valor por defecto).\n6. **`scheduler\/__init__.py`** \u2014 solo si es necesario exportar una enumeraci\u00f3n de prioridades o constantes junto con `SchedulerService`.\n7. **`fixture-manifest.json`** \u2014 solo si a\u00f1ades un nuevo archivo de m\u00f3dulo; su matriz `expected_files` es un inventario expl\u00edcito y se desajustar\u00eda.\n8. **`scheduler\/time_rules.py`** \u2014 *no* debe modificarse. La prioridad es ortogonal a la recurrencia, y este m\u00f3dulo no est\u00e1 conectado.\n\n### 5. Riesgos principales\n\n- **La sem\u00e1ntica de ordenaci\u00f3n supone un cambio de comportamiento silencioso.** `JobRepository.all()` garantiza actualmente un orden ascendente por identificador y `list_jobs` lo hereda. Cualquier consumidor que conf\u00ede en esa garant\u00eda se ver\u00e1 afectado por la reordenaci\u00f3n. Dec\u00eddase expl\u00edcitamente: \u00bfcambia de significado `list_jobs()`, o aparece junto a ella una nueva funci\u00f3n `list_jobs_by_priority()`? La primera opci\u00f3n es la de mayor riesgo y la prueba existente `test_create_and_list_jobs` es demasiado d\u00e9bil para detectar una regresi\u00f3n (lista de un solo elemento).\n- **La direcci\u00f3n de ordenaci\u00f3n es realmente ambigua.** 'Prioridad 1\" significa convencionalmente *la m\u00e1s alta* en algunos sistemas y *la m\u00e1s baja* en otros. No hay nada en este repositorio \u2014ni comentarios, ni cadenas de documentaci\u00f3n, ni l\u00edneas en el README\u2014 que lo aclare. Elige una convenci\u00f3n, docum\u00e9ntala en `models.py` e incorp\u00f3rala en una prueba con al menos tres prioridades distintas para que la direcci\u00f3n quede fijada.\n- **Empates inestables en la ordenaci\u00f3n.** Si dos trabajos comparten una prioridad, el resultado debe seguir siendo determinista. La funci\u00f3n `sorted` de Python es estable, pero la estabilidad solo es \u00fatil si el orden de entrada est\u00e1 definido. Incluye siempre `identifier` como clave secundaria expl\u00edcita.\n- **Orden de los campos de una dataclass congelada.** `Job` es `@dataclass(frozen=True)` con tres campos posicionales, y `service.py:13` lo construye de forma posicional. Insertar `priority` en cualquier lugar que no sea el \u00faltimo, o sin un valor por defecto, supone un cambio que rompe la compatibilidad y que las dos pruebas existentes podr\u00edan no detectar de forma evidente.\n- **Ampliaci\u00f3n del contrato de `to_dict()`.** `asdict(self)` refleja todos los campos. A\u00f1adir `priority` modifica todas las cargas \u00fatiles serializadas sin que se aprecie ning\u00fan cambio en el cuerpo del m\u00e9todo de `models.py`. Cualquier afirmaci\u00f3n sobre la forma exacta del diccionario dejar\u00e1 de funcionar.\n- **Restricciones de Python 3.9.6.** No se admite `@dataclass(slots=True)` (3.10+), ni `kw_only=True` (3.10+), y las anotaciones PEP 604 `int | None` fallan en tiempo de ejecuci\u00f3n sin `from __future__ import annotations`. Si \"priority' se modela como una enumeraci\u00f3n, `enum.StrEnum` es a partir de la versi\u00f3n 3.11 y no est\u00e1 disponible. Cualquiera de estos casos provocar\u00eda un error en el fixture con este int\u00e9rprete.\n- **La asignaci\u00f3n de identificadores se encuentra en la capa equivocada.** `SchedulerService._next_identifier` implica que el servicio se encarga de la generaci\u00f3n de identificadores, mientras que el repositorio se encarga del almacenamiento. Si el trabajo sobre prioridades da lugar a una segunda implementaci\u00f3n del repositorio o a fixtures precargados, esta separaci\u00f3n provocar\u00e1 colisiones de identificadores y trabajos sobrescritos.\n- **Contratos de error asim\u00e9tricos.** `JobRepository.get` devuelve `None` en caso de no encontrar el elemento, mientras que `JobRepository.delete` lanza un `KeyError`. Cualquier nueva consulta relacionada con la prioridad deber\u00eda adoptar una convenci\u00f3n de forma deliberada, en lugar de heredar la inconsistencia por accidente.\n- **Precedente de laguna en la validaci\u00f3n.** `create_job` valida `name` pero no `owner`. No se debe copiar esa laxitud para `priority`: una prioridad no validada se propaga a la clave de ordenaci\u00f3n y puede lanzar un `TypeError` en lo m\u00e1s profundo de `sorted` (por ejemplo, al comparar un `int` con `None`) en lugar de en el punto de llamada.\n- **Trampa del c\u00f3digo muerto.** `scheduler\/time_rules.py` parece contener l\u00f3gica de programaci\u00f3n y atraer\u00e1 modificaciones. No lo importa ning\u00fan otro archivo, y su propia cadena de documentaci\u00f3n admite el error: a\u00f1ade 24 horas transcurridas en UTC y 'desplaza la hora local del reloj de pared durante los cambios de horario de verano\u00bb. Modificarlo no produce ning\u00fan efecto observable en el sistema probado, por lo que el esfuerzo dedicado a ello es en vano y cualquier prueba escrita al respecto no valida nada de lo que se lanza.\n- **Red de seguridad escasa.** Dos pruebas, sin CI, sin linter, sin comprobaci\u00f3n de tipos. No hay nada que detecte una regresi\u00f3n, salvo lo que uno mismo escriba. Considera el conjunto de pruebas existente como una cobertura b\u00e1sica insuficiente, no como un filtro de acceso.\n\n### 6. Plan de implementaci\u00f3n (no ejecutado)\n\n1. **Establece primero la sem\u00e1ntica, por escrito.** Tipo de prioridad (`int` frente a enum), rango v\u00e1lido, valor por defecto para trabajos existentes o no especificados, y direcci\u00f3n de ordenaci\u00f3n. Reg\u00edstralo como una cadena de documentaci\u00f3n en `Job`, en `scheduler\/models.py`; ese es el \u00fanico lugar del que ya dependen todas las capas.\n2. **Ampl\u00eda el modelo.** A\u00f1ade `priority: int = 0` como el *\u00faltimo* campo de `Job` en `scheduler\/models.py`, conservando la compatibilidad posicional con `service.py:13` y sin modificar `to_dict()`.\n3. **Incorp\u00f3ralo en el servicio.** A\u00f1ade un par\u00e1metro `priority` con valor por defecto a `SchedulerService.create_job`, val\u00eddalo junto al filtro existente `name.strip()` (genera un `ValueError`, coincidiendo con el tipo de error establecido) y p\u00e1salo al constructor de `Job`.\n4. **Establece expl\u00edcitamente el contrato de listado.** Opci\u00f3n preferida de bajo riesgo: deja `JobRepository.all()` tal cual como la primitiva ordenada por identificador y a\u00f1ade un accesor independiente ordenado por prioridad. Si, por el contrario, `list_jobs()` debe cambiar de significado, modifica la comprensi\u00f3n de `JobRepository.all()` para ordenar los valores mediante una clave compuesta expl\u00edcita que incluya `identifier` como criterio de desempate, y anota el cambio en `README.md`.\n5. **Mant\u00e9n `scheduler\/__init__.py` sincronizado** solo si se ha introducido una enumeraci\u00f3n o constante p\u00fablica.\n6. **No modifiques `scheduler\/time_rules.py`**, y no a\u00f1adas archivos a menos que se actualice `expected_files` de `fixture-manifest.json` en el mismo cambio.\n\n### 7. Plan de validaci\u00f3n\n\n- **Primero, la l\u00ednea de base.** Ejecuta `python3 -m unittest discover -s tests -v` antes de cualquier modificaci\u00f3n y confirma que las dos pruebas se superan. Ya lo he hecho: se superan sin problemas.\n- **Control de regresi\u00f3n.** Ambas pruebas existentes deben seguir pasando sin modificaciones. Si es necesario editar `test_create_and_list_jobs`, eso es una se\u00f1al de que el cambio est\u00e1 causando un fallo, no una raz\u00f3n para editar la prueba.\n- **Nuevos casos en `tests\/test_scheduler.py`:**\n  - Prioridad por defecto cuando se llama a `create_job` con la antigua firma de dos argumentos (demuestra la compatibilidad con versiones anteriores).\n  - Recorridos de ida y vuelta de la prioridad expl\u00edcita a trav\u00e9s de `create_job` \u2192 `list_jobs`.\n  - Ordenaci\u00f3n con **tres o m\u00e1s** prioridades distintas, verificando la lista completa; esto es lo que determina la direcci\u00f3n de la ordenaci\u00f3n.\n  - Desempate: dos trabajos con la misma prioridad se ordenan por identificador ascendente.\n  - Una prioridad no v\u00e1lida genera un `ValueError`, al igual que en el caso de un nombre en blanco.\n  - `to_dict()` incluye `priority` con el valor esperado.\n  - Ruta de repositorio inyectada: `SchedulerService(repository=fake)` sigue asignando la prioridad correctamente, poniendo a prueba la integraci\u00f3n entre `repository` y `JobRepository()`.\n- **Comprobaci\u00f3n de compatibilidad.** Confirma que todo funciona espec\u00edficamente en Python 3.9.6: sin `slots=`, sin `kw_only=`, sin uniones PEP 604 sin calificaciones, sin `StrEnum`.\n- **Comprobaci\u00f3n de inventario.** Vuelve a leer `fixture-manifest.json` y confirma que el conjunto de archivos en disco sigue coincidiendo con `expected_files`.\n- **Determinismo.** Ejecuta la suite dos o tres veces; los errores de ordenaci\u00f3n relacionados con el orden de iteraci\u00f3n de los diccionarios pueden aparecer de forma intermitente.\n- **Limpieza.** Ejecuta con `PYTHONDONTWRITEBYTECODE=1` para que los directorios `__pycache__` no aparezcan como desviaciones no rastreadas respecto al manifiesto.\n<\/pre><\/div><\/details><\/div><p class=\"d-limit\">Limitaci\u00f3n del entorno de pruebas: se trataba de un peque\u00f1o repositorio de Python fuera de l\u00ednea. Claude utilizaba un subagente de reserva tras la caducidad del OAuth de la CLI, por lo que el aislamiento y la visibilidad de los tokens no eran id\u00e9nticos.<\/p><\/article>\n\n\n\n<p class=\"wp-block-paragraph\">Este resultado no refleja el rendimiento en un monorepo de gran tama\u00f1o ni en una sesi\u00f3n aut\u00f3noma de una semana de duraci\u00f3n. El entorno de prueba se dise\u00f1\u00f3 deliberadamente para ser peque\u00f1o y controlado. Para realizar una evaluaci\u00f3n real, empieza con una solicitud de solo lectura: pide a cada herramienta que trace la ruta de llamadas, indique los archivos que modificar\u00eda, identifique las pruebas y enumere las suposiciones sin resolver antes de permitir la edici\u00f3n.<\/p>\n\n\n\n<h2 id=\"implementation\" class=\"wp-block-heading\">Estilo de implementaci\u00f3n, alcance de los parches y correcci\u00f3n de errores<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Trabajo con m\u00faltiples archivos<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Un mismo comportamiento de superaci\u00f3n de pruebas puede deberse a diferentes decisiones de ingenier\u00eda. En T2, ambos productos obtuvieron una puntuaci\u00f3n de 30\/30 y superaron el validador oculto congelado. El c\u00f3digo Claude situ\u00f3 la validaci\u00f3n en m\u00e1s de un l\u00edmite e incorpor\u00f3 pruebas m\u00e1s amplias de modelo directo y de umbral. Codex utiliz\u00f3 una implementaci\u00f3n m\u00e1s reducida, centrada en los servicios, que tambi\u00e9n cumpli\u00f3 con el contrato.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Para un desarrollador independiente, se trata de una aut\u00e9ntica disyuntiva. Una validaci\u00f3n m\u00e1s amplia puede proteger las invariantes cuando los objetos se crean a trav\u00e9s de m\u00faltiples rutas. Un parche m\u00e1s peque\u00f1o puede reducir la superficie de regresi\u00f3n y el tiempo de revisi\u00f3n cuando un servicio es el punto de entrada previsto. La respuesta correcta depende de las normas de propiedad del repositorio, no de contar las l\u00edneas modificadas o las pruebas de forma aislada.<\/p>\n\n\n\n<style>\n.evidence-t2-multifile-feature{--ink:#111318;--body:#414753;--muted:#707784;--line:#e4e7ec;--soft:#f6f7f9;--blue:#315efb;--violet:#7257e8;--green:#087a55;--greenSoft:#eaf8f2;--red:#a23131;--redSoft:#fff0f0;color:var(--ink);font-family:Inter,ui-sans-serif,-apple-system,BlinkMacSystemFont,\"Segoe UI\",sans-serif;line-height:1.5;border:1px solid var(--line);border-radius:8px;background:#fff;overflow:hidden;box-shadow:0 16px 42px rgba(24,32,56,.08)}\n.evidence-t2-multifile-feature *{box-sizing:border-box}.evidence-t2-multifile-feature .d-head{display:flex;align-items:flex-start;justify-content:space-between;gap:22px;padding:24px 26px 20px;border-bottom:1px solid var(--line)}\n.evidence-t2-multifile-feature .d-kicker{margin:0 0 6px;color:var(--muted);font:750 11px\/1.4 ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.08em;text-transform:uppercase}.evidence-t2-multifile-feature .d-title{margin:0;font-size:22px;line-height:1.2;letter-spacing:-.025em}.evidence-t2-multifile-feature .d-sub{margin:7px 0 0;color:var(--body);font-size:13px}.evidence-t2-multifile-feature .d-pill{flex:0 0 auto;padding:6px 10px;border:1px solid #ccd6ff;border-radius:999px;color:#2448ca;background:#f0f3ff;font-size:11px;font-weight:800}.evidence-t2-multifile-feature .d-grid{display:grid;grid-template-columns:1fr 1fr}.evidence-t2-multifile-feature .d-side{min-width:0;padding:24px 26px}.evidence-t2-multifile-feature .d-side+.d-side{border-left:1px solid var(--line)}.evidence-t2-multifile-feature .d-product{display:flex;align-items:baseline;justify-content:space-between;gap:14px;font-weight:800}.evidence-t2-multifile-feature .d-score{font-size:34px;line-height:1;letter-spacing:-.05em}.evidence-t2-multifile-feature .d-score small{color:var(--muted);font-size:12px;letter-spacing:0}.evidence-t2-multifile-feature .d-metrics{display:grid;grid-template-columns:repeat(3,1fr);gap:7px;margin:18px 0}.evidence-t2-multifile-feature .d-metric{padding:10px;border:1px solid var(--line);border-radius:6px;background:var(--soft)}.evidence-t2-multifile-feature .d-metric span{display:block;color:var(--muted);font-size:9px;font-weight:800;letter-spacing:.06em;text-transform:uppercase}.evidence-t2-multifile-feature .d-metric strong{display:block;margin-top:3px;font-size:13px}.evidence-t2-multifile-feature .d-preview{position:relative;height:192px;overflow:hidden;border:1px solid #29313f;border-radius:6px;background:#11151d;color:#edf0f5}.evidence-t2-multifile-feature .d-preview-label{padding:11px 13px;border-bottom:1px solid rgba(255,255,255,.1);color:#aeb7c7;font:750 9px\/1 ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.06em;text-transform:uppercase}.evidence-t2-multifile-feature .d-preview pre,.evidence-t2-multifile-feature .d-full pre{margin:0;white-space:pre-wrap;font:11px\/1.6 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.evidence-t2-multifile-feature .d-preview pre{padding:13px}.evidence-t2-multifile-feature .d-preview:after{content:\"\";position:absolute;left:0;right:0;bottom:0;height:55px;background:linear-gradient(transparent,#11151d)}.evidence-t2-multifile-feature .d-take{margin:14px 0 0;color:var(--body);font-size:12px}.evidence-t2-multifile-feature .d-fulls{padding:0 26px 22px}.evidence-t2-multifile-feature .d-full{margin-top:10px;border:1px solid var(--line);border-radius:6px}.evidence-t2-multifile-feature .d-full summary{cursor:pointer;padding:13px 14px;font-size:12px;font-weight:800;list-style:none}.evidence-t2-multifile-feature .d-full summary::-webkit-details-marker{display:none}.evidence-t2-multifile-feature .d-full summary:after{content:\"+\";float:right;color:var(--blue);font-size:17px}.evidence-t2-multifile-feature .d-full[open] summary:after{content:\"\u2212\"}.evidence-t2-multifile-feature .d-full-pane{padding:0 14px 14px}.evidence-t2-multifile-feature .d-full-note{margin:0 0 9px;color:var(--muted);font-size:10px}.evidence-t2-multifile-feature .d-full pre{max-height:620px;overflow:auto;padding:15px;border-radius:5px;background:#f5f6f8;color:#222936;border:1px solid #e0e3e8}.evidence-t2-multifile-feature .d-limit{margin:0;padding:12px 26px;border-top:1px solid var(--line);color:#5a6270;background:#fafbfc;font-size:11px}\n@media(max-width:760px){.evidence-t2-multifile-feature .d-head{display:block}.evidence-t2-multifile-feature .d-pill{display:inline-block;margin-top:12px}.evidence-t2-multifile-feature .d-grid{grid-template-columns:1fr}.evidence-t2-multifile-feature .d-side+.d-side{border-left:0;border-top:1px solid var(--line)}}@media(max-width:480px){.evidence-t2-multifile-feature .d-head,.evidence-t2-multifile-feature .d-side{padding:20px}.evidence-t2-multifile-feature .d-fulls{padding:0 20px 20px}.evidence-t2-multifile-feature .d-metrics{grid-template-columns:1fr}}\n<\/style><article class=\"evidence-t2-multifile-feature\"><header class=\"d-head\"><div><p class=\"d-kicker\">T2 \u00b7 Prueba del repositorio controlado<\/p><h3 class=\"d-title\">Implementar una funci\u00f3n prioritaria en varios archivos<\/h3><p class=\"d-sub\">A\u00f1adir el comportamiento congelado, mantener la compatibilidad y superar las comprobaciones tanto p\u00fablicas como ocultas.<\/p><\/div><span class=\"d-pill\">Corbata funcional<\/span><\/header><div class=\"d-grid\"><section class=\"d-side\" aria-label=\"Resultado del Codex\"><div class=\"d-product\"><span>C\u00f3dice<\/span><span class=\"d-score\">30<small>\/30<\/small><\/span><\/div><div class=\"d-metrics\"><div class=\"d-metric\"><span>Duraci\u00f3n<\/span><strong>115 s<\/strong><\/div><div class=\"d-metric\"><span>Cheques<\/span><strong>7 + ocultos<\/strong><\/div><div class=\"d-metric\"><span>Alcance<\/span><strong>Parche m\u00e1s peque\u00f1o<\/strong><\/div><\/div><div class=\"d-preview\"><div class=\"d-preview-label\">Primer fragmento v\u00e1lido de la salida<\/div><pre>Se ha a\u00f1adido prioridad al modelo inmutable, se ha validado en el l\u00edmite del servicio y se ha mantenido el orden en el repositorio.\n\nLas siete pruebas p\u00fablicas y el validador oculto congelado han superado las pruebas.<\/pre><\/div><p class=\"d-take\"><strong>Opini\u00f3n del cr\u00edtico:<\/strong> Una implementaci\u00f3n m\u00e1s reducida y centrada en los servicios que cubr\u00eda todos los comportamientos congelados.<\/p><\/section><section class=\"d-side\" aria-label=\"Resultado del c\u00f3digo Claude\"><div class=\"d-product\"><span>C\u00f3digo Claude<\/span><span class=\"d-score\">30<small>\/30<\/small><\/span><\/div><div class=\"d-metrics\"><div class=\"d-metric\"><span>Duraci\u00f3n<\/span><strong>101 s<\/strong><\/div><div class=\"d-metric\"><span>Cheques<\/span><strong>14 + ocultos<\/strong><\/div><div class=\"d-metric\"><span>Alcance<\/span><strong>Pruebas m\u00e1s exhaustivas<\/strong><\/div><\/div><div class=\"d-preview\"><div class=\"d-preview-label\">Primer fragmento v\u00e1lido de la salida<\/div><pre>Se ha validado la prioridad tanto en el l\u00edmite del servicio como en el modelo inmutable, se ha conservado el filtrado del repositorio y se ha a\u00f1adido la cobertura de umbrales.\n\nSe han superado catorce pruebas p\u00fablicas y el validador oculto.<\/pre><\/div><p class=\"d-take\"><strong>Opini\u00f3n del cr\u00edtico:<\/strong> Una cobertura m\u00e1s amplia del modelo directo y del umbral, sin que ello suponga una ventaja en cuanto a la puntuaci\u00f3n funcional.<\/p><\/section><\/div><div class=\"d-fulls\"><details class=\"d-full\"><summary>Ver el resultado completo de Codex<\/summary><div class=\"d-full-pane\"><p class=\"d-full-note\">Salida completa, desinfectada y v\u00e1lida por primera vez<\/p><pre>Se ha implementado la funci\u00f3n de prioridad de los trabajos programados.\n\nArchivos modificados:\n\n- [scheduler\/models.py](.\/scheduler\/models.py:5) \u2014 se ha a\u00f1adido el par\u00e1metro serializado `priority`, cuyo valor por defecto es `0`.\n- [scheduler\/service.py](.\/scheduler\/service.py:11): se ha a\u00f1adido la validaci\u00f3n, el almacenamiento y el filtrado `list_jobs(min_priority=0)`, conservando el orden de los identificadores.\n- [tests\/test_scheduler.py](.\/tests\/test_scheduler.py:16) \u2014 Se ha a\u00f1adido cobertura para valores por defecto, serializaci\u00f3n, almacenamiento, l\u00edmites, valores no v\u00e1lidos y filtrado.\n\nPruebas ejecutadas:\n\n```text\npython3 -m unittest discover -s tests -v\nSe han ejecutado 7 pruebas \u2014 OK\n```\n\n**Conclusi\u00f3n:** La tarea congelada est\u00e1 completada y verificada.  \n**Decisi\u00f3n necesaria:** Ninguna.<\/pre><\/div><\/details><details class=\"d-full\"><summary>Ver el c\u00f3digo Claude completo<\/summary><div class=\"d-full-pane\"><p class=\"d-full-note\">Registro completo de la transferencia, incluida la salida v\u00e1lida inicial tal y como se ha registrado.<\/p><pre>Registro de ejecuci\u00f3n de # T2 \u2014 Funci\u00f3n de prioridad de varios archivos\n\nPar\u00e1metros de ejecuci\u00f3n de ##\n\n| Campo | Valor |\n| --- | --- |\n| Tarea | `T2` |\n| Mensaje congelado | `01-prompts\/T2.md` |\n| SHA-256 del prompt congelado | `8476a56034c4e719b97ee4081b32b4c73efd45feafe1bda9d477c83cb8fdb698` |\n| Unidad de ejecuci\u00f3n | subagente aislado Claude, \"uso general\", contexto nuevo |\n| M\u00e9todo de aislamiento | **recurso de reserva del subagente** (rebaja documentada \u2014 v\u00e9ase `results\/isolation-decision.md`) |\n| Copia limpia asignada | `runtime\/workspaces\/T2` |\n| Versi\u00f3n del c\u00f3digo Claude | `2.1.220` |\n| Configuraci\u00f3n del modelo | `claude-opus-5` |\n| start_utc | `2026-07-28T10:27:52Z` |\n| end_utc | `2026-07-28T10:29:33Z` |\n| Duraci\u00f3n | 101 s (simult\u00e1neo con T1, T3 y T4; no es una medici\u00f3n de latencia precisa) |\n| N\u00famero de intento | 1 |\n| Estado | `v\u00e1lido` |\n| Intervenci\u00f3n humana | ninguna |\n\n## Resumen de la herramienta segura\n\n`date`, `Read`\/`Edit`\/`Write` \u00fanicamente dentro del espacio de trabajo asignado, `grep`,\n`python3 -m unittest discover`, `python3 -m compileall`, comprobaciones de funcionamiento `python3 -c` en l\u00ednea.\nSin red, sin instalaciones, solo biblioteca est\u00e1ndar.\n\n## Archivos modificados\n\n`scheduler\/models.py`, `scheduler\/repository.py`, `scheduler\/service.py`,\n`tests\/test_scheduler.py`. No se han a\u00f1adido ni eliminado archivos, por lo que `fixture-manifest.json` sigue siendo\ncorrecto. Parche completo: `results\/T2\/patch.diff`.\n\n## Resultados de la comprobaci\u00f3n sin conexi\u00f3n\n\nInformado por el ejecutor de tareas:\n\n| Comprobaci\u00f3n | Resultado |\n| --- | --- |\n| `python3 -m unittest discover -s tests -v` (referencia, antes del cambio) | 2 superadas, 0 fallidas |\n| `python3 -m compileall -q scheduler tests` | sin errores |\n| comprobaciones r\u00e1pidas en l\u00ednea (construcci\u00f3n heredada de 3 argumentos, umbral de palabra clave\/posicional, `to_dict`) | superada |\n| `python3 -m unittest discover -s tests -v` (final) | **14 superadas, 0 fallidas** |\n\nRevisado de forma independiente por el coordinador desde fuera del espacio de trabajo:\n\n| Comprobaci\u00f3n | Salida | Resultado |\n| --- | --- | --- |\n| conjunto de pruebas p\u00fablico (`results\/checks\/T2-public.txt`) | 0 | 14 pruebas, OK |\n| validador oculto `03-checks\/test_t2_hidden.py` (`results\/checks\/T2-hidden.txt`) | 0 | 2 pruebas, OK |\n\nEl validador oculto falla (salida 1) con una copia pr\u00edstina del fixture, lo que confirma que la superaci\u00f3n es\nsignificativa. V\u00e9ase `results\/checks\/validator-controls.md`.\n\n## Cobertura del comportamiento del mapa de referencia\n\nSe cumplen los cinco comportamientos requeridos en `03-checks\/gold-map.json`:\n\n| Comportamiento requerido | Evidencia |\n| --- | --- |\n| prioridad por defecto 0 | `Job.priority: int = MIN_PRIORITY`; `create_job(..., priority=MIN_PRIORITY)`; `test_priority_defaults_to_zero` |\n| rango de enteros del 0 al 9 | `validate_priority` rechaza valores que no sean enteros y que est\u00e9n fuera de rango; `test_out_of_range_priority_is_rejected`, `test_non_integer_priority_is_rejected` |\n| prioridad serializada | `to_dict()` mediante `asdict`; `test_priority_appears_in_serialized_output` verifica que el diccionario sea exactamente el mismo |\n| filtrado por prioridad m\u00ednima | `list_jobs(min_priority=0)` \u2192 `JobRepository.all(min_priority)`; `test_filter_is_inclusive_of_the_threshold` |\n| orden de identificadores | filtro aplicado dentro de la comprensi\u00f3n existente `sorted(self._jobs)`; `test_filter_preserves_ascending_identifier_order` |\n\n## Errores corregidos\n\nNinguno. El ejecutor de tareas elimin\u00f3 los artefactos `__pycache__` de las ejecuciones de pruebas; una\nrevisi\u00f3n del coordinador confirm\u00f3 que el espacio de trabajo est\u00e1 limpio.\n\n## Salida visible (textual)\n\nSe ha a\u00f1adido un campo entero `priority` a los trabajos programados en las capas de modelo, repositorio y servicio del fixture del programador local, adem\u00e1s de la lista filtrada.\n\n**`scheduler\/models.py`** \u2014 Se han a\u00f1adido las constantes del m\u00f3dulo `MIN_PRIORITY = 0` \/ `MAX_PRIORITY = 9` y una funci\u00f3n reutilizable `validate_priority(priority)` que lanza un `ValueError` para valores que no sean enteros y para valores fuera del rango 0\u20139, ambos inclusive. Se rechaza expl\u00edcitamente `bool` a pesar de ser una subclase de `int`, por lo que `True` no puede pasar como prioridad 1. La clase de datos congelada `Job` incorpora `priority: int = MIN_PRIORITY` como campo final con un valor por defecto, lo que mantiene el funcionamiento de la construcci\u00f3n existente de tres argumentos, y un `__post_init__` que llama al validador para que no se puedan construir prioridades no v\u00e1lidas por ninguna v\u00eda. `to_dict()` se ha dejado como `asdict(self)`, por lo que la prioridad aparece autom\u00e1ticamente en la salida serializada y en el orden de los campos.\n\n**`scheduler\/repository.py`** \u2014 `JobRepository.all()` admite un `min_priority` opcional y filtra dentro de la comprensi\u00f3n existente `sorted(self._jobs)`, de modo que el orden ascendente de los identificadores queda garantizado por la misma ruta de c\u00f3digo \u00fanica que ya lo proporcionaba, en lugar de tener que restablecerse tras el filtrado. El argumento por defecto conserva el comportamiento anterior sin argumentos para las llamadas existentes. El almacenamiento en s\u00ed no requiri\u00f3 ning\u00fan cambio: el repositorio almacena instancias completas de `Job`, por lo que la prioridad se mantiene y se conserva en las operaciones `save`\/`get`\/`all`.\n\n**`scheduler\/service.py`** \u2014 `create_job` acepta un argumento opcional `priority` al final (por defecto 0) y lo valida antes de construir el `Job`, de modo que el error se genera en el l\u00edmite del servicio con el mismo contrato `ValueError` que la comprobaci\u00f3n existente de nombre en blanco. `list_jobs(min_priority=0)` delega en el repositorio. La ordenaci\u00f3n y el filtrado se realizan en un \u00fanico lugar, en lugar de duplicarse.\n\n**Nota de dise\u00f1o sobre la validaci\u00f3n de `min_priority`:** se comprueba el tipo como un entero, pero deliberadamente *no* se restringe el rango a 0\u20139. La regla de 0\u20139 limita lo que un trabajo puede almacenar; un umbral es un par\u00e1metro de consulta, y rechazar, por ejemplo, `min_priority=10` convertir\u00eda una consulta leg\u00edtima de \"sin coincidencias\" en un error. El hecho de que `list_jobs(min_priority=9)` devuelva `[]` cuando ning\u00fan trabajo tiene prioridad 9 est\u00e1 cubierto por una prueba.\n\nSe ley\u00f3 `scheduler\/time_rules.py`, pero no se modific\u00f3: su cambio de horario de verano documentado es un comportamiento predefinido ya existente, fuera del alcance de esta tarea, y modificarlo habr\u00eda supuesto un cambio de comportamiento no relacionado. No se ha a\u00f1adido ni eliminado ning\u00fan archivo, por lo que `fixture-manifest.json` sigue siendo correcto (verificado mediante programaci\u00f3n).\n\n### Cobertura de pruebas a\u00f1adida\n\nValor predeterminado 0; recorrido de ida y vuelta por el almacenamiento a trav\u00e9s de `JobRepository`; prioridad en la salida de `to_dict()`; se aceptan los valores l\u00edmite 0 y 9; se rechazan los valores fuera de rango \u22121\/10\/100; se rechazan los valores no enteros `\"3\"`\/`3.5`\/`None`\/`True`; validaci\u00f3n directa a nivel de modelo; orden de listado sin filtrar; listado filtrado que conserva el orden ascendente de los identificadores; umbral inclusivo; resultado vac\u00edo; se rechaza un `min_priority` no entero.\n<\/pre><\/div><\/details><\/div><p class=\"d-limit\">Limitaci\u00f3n del entorno de pruebas: se trataba de un peque\u00f1o repositorio de Python fuera de l\u00ednea. Claude utilizaba un subagente de reserva tras la caducidad del OAuth de la CLI, por lo que el aislamiento y la visibilidad de los tokens no eran id\u00e9nticos.<\/p><\/article>\n\n\n\n<h3 class=\"wp-block-heading\">Correcci\u00f3n de errores en casos extremos<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">T3 prob\u00f3 un fallo en la programaci\u00f3n del horario de verano. Ambos agentes obtuvieron una puntuaci\u00f3n de 30\/30 y superaron las mismas comprobaciones ocultas de primavera y oto\u00f1o. El c\u00f3digo Claude a\u00f1adi\u00f3 una cobertura expl\u00edcita para horas locales ambiguas y omitidas, entradas simplistas y cambios de varios d\u00edas. Codex realiz\u00f3 un cambio m\u00e1s limitado en los d\u00edas naturales y super\u00f3 el contrato congelado.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Las pruebas m\u00e1s amplias de casos extremos generan confianza cuando la biblioteca se reutiliza ampliamente o cuando el coste de un error de programaci\u00f3n es elevado. Un cambio limitado resulta atractivo cuando el defecto est\u00e1 bien aislado y el equipo desea minimizar los cambios de comportamiento. La pregunta pr\u00e1ctica que hay que plantearse no es \u201c\u00bfQui\u00e9n ha escrito m\u00e1s?\u201d, sino si el parche corrige la causa ra\u00edz indicada, preserva los contratos circundantes y comprueba los l\u00edmites de riesgo.<\/p>\n\n\n\n<style>\n.evidence-t3-dst-bug-fix{--ink:#111318;--body:#414753;--muted:#707784;--line:#e4e7ec;--soft:#f6f7f9;--blue:#315efb;--violet:#7257e8;--green:#087a55;--greenSoft:#eaf8f2;--red:#a23131;--redSoft:#fff0f0;color:var(--ink);font-family:Inter,ui-sans-serif,-apple-system,BlinkMacSystemFont,\"Segoe UI\",sans-serif;line-height:1.5;border:1px solid var(--line);border-radius:8px;background:#fff;overflow:hidden;box-shadow:0 16px 42px rgba(24,32,56,.08)}\n.evidence-t3-dst-bug-fix *{box-sizing:border-box}.evidence-t3-dst-bug-fix .d-head{display:flex;align-items:flex-start;justify-content:space-between;gap:22px;padding:24px 26px 20px;border-bottom:1px solid var(--line)}\n.evidence-t3-dst-bug-fix .d-kicker{margin:0 0 6px;color:var(--muted);font:750 11px\/1.4 ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.08em;text-transform:uppercase}.evidence-t3-dst-bug-fix .d-title{margin:0;font-size:22px;line-height:1.2;letter-spacing:-.025em}.evidence-t3-dst-bug-fix .d-sub{margin:7px 0 0;color:var(--body);font-size:13px}.evidence-t3-dst-bug-fix .d-pill{flex:0 0 auto;padding:6px 10px;border:1px solid #ccd6ff;border-radius:999px;color:#2448ca;background:#f0f3ff;font-size:11px;font-weight:800}.evidence-t3-dst-bug-fix .d-grid{display:grid;grid-template-columns:1fr 1fr}.evidence-t3-dst-bug-fix .d-side{min-width:0;padding:24px 26px}.evidence-t3-dst-bug-fix .d-side+.d-side{border-left:1px solid var(--line)}.evidence-t3-dst-bug-fix .d-product{display:flex;align-items:baseline;justify-content:space-between;gap:14px;font-weight:800}.evidence-t3-dst-bug-fix .d-score{font-size:34px;line-height:1;letter-spacing:-.05em}.evidence-t3-dst-bug-fix .d-score small{color:var(--muted);font-size:12px;letter-spacing:0}.evidence-t3-dst-bug-fix .d-metrics{display:grid;grid-template-columns:repeat(3,1fr);gap:7px;margin:18px 0}.evidence-t3-dst-bug-fix .d-metric{padding:10px;border:1px solid var(--line);border-radius:6px;background:var(--soft)}.evidence-t3-dst-bug-fix .d-metric span{display:block;color:var(--muted);font-size:9px;font-weight:800;letter-spacing:.06em;text-transform:uppercase}.evidence-t3-dst-bug-fix .d-metric strong{display:block;margin-top:3px;font-size:13px}.evidence-t3-dst-bug-fix .d-preview{position:relative;height:192px;overflow:hidden;border:1px solid #29313f;border-radius:6px;background:#11151d;color:#edf0f5}.evidence-t3-dst-bug-fix .d-preview-label{padding:11px 13px;border-bottom:1px solid rgba(255,255,255,.1);color:#aeb7c7;font:750 9px\/1 ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.06em;text-transform:uppercase}.evidence-t3-dst-bug-fix .d-preview pre,.evidence-t3-dst-bug-fix .d-full pre{margin:0;white-space:pre-wrap;font:11px\/1.6 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.evidence-t3-dst-bug-fix .d-preview pre{padding:13px}.evidence-t3-dst-bug-fix .d-preview:after{content:\"\";position:absolute;left:0;right:0;bottom:0;height:55px;background:linear-gradient(transparent,#11151d)}.evidence-t3-dst-bug-fix .d-take{margin:14px 0 0;color:var(--body);font-size:12px}.evidence-t3-dst-bug-fix .d-fulls{padding:0 26px 22px}.evidence-t3-dst-bug-fix .d-full{margin-top:10px;border:1px solid var(--line);border-radius:6px}.evidence-t3-dst-bug-fix .d-full summary{cursor:pointer;padding:13px 14px;font-size:12px;font-weight:800;list-style:none}.evidence-t3-dst-bug-fix .d-full summary::-webkit-details-marker{display:none}.evidence-t3-dst-bug-fix .d-full summary:after{content:\"+\";float:right;color:var(--blue);font-size:17px}.evidence-t3-dst-bug-fix .d-full[open] summary:after{content:\"\u2212\"}.evidence-t3-dst-bug-fix .d-full-pane{padding:0 14px 14px}.evidence-t3-dst-bug-fix .d-full-note{margin:0 0 9px;color:var(--muted);font-size:10px}.evidence-t3-dst-bug-fix .d-full pre{max-height:620px;overflow:auto;padding:15px;border-radius:5px;background:#f5f6f8;color:#222936;border:1px solid #e0e3e8}.evidence-t3-dst-bug-fix .d-limit{margin:0;padding:12px 26px;border-top:1px solid var(--line);color:#5a6270;background:#fafbfc;font-size:11px}\n@media(max-width:760px){.evidence-t3-dst-bug-fix .d-head{display:block}.evidence-t3-dst-bug-fix .d-pill{display:inline-block;margin-top:12px}.evidence-t3-dst-bug-fix .d-grid{grid-template-columns:1fr}.evidence-t3-dst-bug-fix .d-side+.d-side{border-left:0;border-top:1px solid var(--line)}}@media(max-width:480px){.evidence-t3-dst-bug-fix .d-head,.evidence-t3-dst-bug-fix .d-side{padding:20px}.evidence-t3-dst-bug-fix .d-fulls{padding:0 20px 20px}.evidence-t3-dst-bug-fix .d-metrics{grid-template-columns:1fr}}\n<\/style><article class=\"evidence-t3-dst-bug-fix\"><header class=\"d-head\"><div><p class=\"d-kicker\">T3 \u00b7 Prueba de repositorio controlado<\/p><h3 class=\"d-title\">Corregir la programaci\u00f3n diaria durante los cambios de horario de verano<\/h3><p class=\"d-sub\">Mantener la hora de reloj de pared de Nueva York solicitada durante los cambios de estaci\u00f3n de primavera y oto\u00f1o.<\/p><\/div><span class=\"d-pill\">Empate \u00b7 diferentes niveles de intensidad<\/span><\/header><div class=\"d-grid\"><section class=\"d-side\" aria-label=\"Resultado del Codex\"><div class=\"d-product\"><span>C\u00f3dice<\/span><span class=\"d-score\">30<small>\/30<\/small><\/span><\/div><div class=\"d-metrics\"><div class=\"d-metric\"><span>Duraci\u00f3n<\/span><strong>99 s<\/strong><\/div><div class=\"d-metric\"><span>Cheques<\/span><strong>4 + 2 ocultos<\/strong><\/div><div class=\"d-metric\"><span>Alcance<\/span><strong>Soluci\u00f3n parcial<\/strong><\/div><\/div><div class=\"d-preview\"><div class=\"d-preview-label\">Primer fragmento v\u00e1lido de la salida<\/div><pre>Causa principal: la implementaci\u00f3n a\u00f1adi\u00f3 24 horas UTC transcurridas.\n\nSoluci\u00f3n: avanzar un d\u00eda natural seg\u00fan el calendario local. Se superaron ambas comprobaciones de \u00abspring\u00bb y \u00abfall\u00bb congeladas.<\/pre><\/div><p class=\"d-take\"><strong>Opini\u00f3n del cr\u00edtico:<\/strong> El grupo m\u00e1s reducido aprob\u00f3 el contrato en su totalidad.<\/p><\/section><section class=\"d-side\" aria-label=\"Resultado del c\u00f3digo Claude\"><div class=\"d-product\"><span>C\u00f3digo Claude<\/span><span class=\"d-score\">30<small>\/30<\/small><\/span><\/div><div class=\"d-metrics\"><div class=\"d-metric\"><span>Duraci\u00f3n<\/span><strong>118 s<\/strong><\/div><div class=\"d-metric\"><span>Cheques<\/span><strong>10 + 2 ocultos<\/strong><\/div><div class=\"d-metric\"><span>Alcance<\/span><strong>Cobertura de los bordes<\/strong><\/div><\/div><div class=\"d-preview\"><div class=\"d-preview-label\">Primer fragmento v\u00e1lido de la salida<\/div><pre>Se han tenido en cuenta la primavera y el oto\u00f1o, los horarios locales omitidos y ambiguos, las entradas simplistas y los rollos de varios d\u00edas.\n\nAmbas comprobaciones ocultas \u00abcongeladas\u00bb se han superado tras ampliar la cobertura de la regresi\u00f3n.<\/pre><\/div><p class=\"d-take\"><strong>Opini\u00f3n del cr\u00edtico:<\/strong> Mayor cobertura de los casos extremos; la misma puntuaci\u00f3n funcional seg\u00fan la r\u00fabrica \u00abcongelada\u00bb.<\/p><\/section><\/div><div class=\"d-fulls\"><details class=\"d-full\"><summary>Ver el resultado completo de Codex<\/summary><div class=\"d-full-pane\"><p class=\"d-full-note\">Salida completa, desinfectada y v\u00e1lida por primera vez<\/p><pre>Se ha implementado la correcci\u00f3n del horario de verano.\n\nArchivos modificados:\n\n- [scheduler\/time_rules.py](.\/scheduler\/time_rules.py)\n- [tests\/test_time_rules.py](.\/tests\/test_time_rules.py)\n\nCambios:\n\n- Avanza un d\u00eda natural local en lugar de 24 horas UTC.\n- Se han a\u00f1adido pruebas de regresi\u00f3n para el cambio horario de primavera y oto\u00f1o en Nueva York.\n- Se ha comprobado que los intervalos transcurridos en UTC son de 23 y 25 horas, respectivamente.\n\nComprobaciones:\n\n- Pruebas unitarias: 4 superadas.\n- Comprobaci\u00f3n sint\u00e1ctica en memoria: han pasado 7 archivos de Python.\n- Se bloque\u00f3 la compilaci\u00f3n del c\u00f3digo de bytes porque Python redirige su cach\u00e9 fuera del espacio de trabajo asignado; no se escribieron archivos externos.\n\n**Conclusi\u00f3n:** `next_daily_run` ahora conserva la hora real solicitada durante las transiciones del horario de verano. No es necesario tomar ninguna decisi\u00f3n.<\/pre><\/div><\/details><details class=\"d-full\"><summary>Ver el c\u00f3digo Claude completo<\/summary><div class=\"d-full-pane\"><p class=\"d-full-note\">Registro completo de la transferencia, incluida la salida v\u00e1lida inicial tal y como se ha registrado.<\/p><pre>Registro de ejecuci\u00f3n de # T3 \u2014 Correcci\u00f3n de un error de DST\n\nPar\u00e1metros de ejecuci\u00f3n de ##\n\n| Campo | Valor |\n| --- | --- |\n| Tarea | `T3` |\n| Mensaje congelado | `01-prompts\/T3.md` |\n| SHA-256 del prompt congelado | `3fee50d0230f27f8d6dd7f12e050fa3f0b7f5fb77d9559361fee96e5f1a47307` |\n| Unidad de ejecuci\u00f3n | subagente aislado Claude, \"de uso general\", contexto nuevo |\n| M\u00e9todo de aislamiento | **recurso de reserva del subagente** (rebaja documentada \u2014 v\u00e9ase `results\/isolation-decision.md`) |\n| Copia limpia asignada | `runtime\/workspaces\/T3` |\n| Versi\u00f3n del c\u00f3digo Claude | `2.1.220` |\n| Configuraci\u00f3n del modelo | `claude-opus-5` |\n| start_utc | `2026-07-28T10:28:05Z` |\n| end_utc | `2026-07-28T10:30:03Z` |\n| Duraci\u00f3n | 118 s (simult\u00e1neo con T1, T2 y T4; no es una medici\u00f3n de latencia precisa) |\n| N\u00famero de intento | 1 |\n| Estado | `v\u00e1lido` |\n| Intervenci\u00f3n humana | ninguna |\n\nResumen de la herramienta segura ##\n\n`date`, `Read`\/`Edit` \u00fanicamente dentro del espacio de trabajo asignado, `python3 -m unittest discover`,\n`python3 -m compileall`, una ejecuci\u00f3n de control negativo en memoria, una comprobaci\u00f3n de integridad del manifiesto.\nSolo biblioteca est\u00e1ndar (`datetime`, `zoneinfo`, `unittest`). Sin red, sin instalaciones.\n\n## Archivos modificados\n\n`scheduler\/time_rules.py` (la correcci\u00f3n: solo el cuerpo y la cadena de documentaci\u00f3n de `next_daily_run`),\n`tests\/test_scheduler.py` (se ha a\u00f1adido `NextDailyRunTests`, 8 pruebas, adem\u00e1s de una funci\u00f3n auxiliar `_elapsed`;\nlas pruebas existentes no se han modificado). No se ha modificado ning\u00fan otro m\u00f3dulo, ni se han a\u00f1adido archivos. Parche completo:\n`results\/T3\/patch.diff`.\n\n## Resultados de la comprobaci\u00f3n sin conexi\u00f3n\n\nInformado por el ejecutor de tareas:\n\n| Comprobaci\u00f3n | Resultado |\n| --- | --- |\n| `python3 -m unittest discover -s tests -v` | **10 superadas, 0 fallidas** (2 preexistentes + 8 nuevas) |\n| `python3 -m compileall -q scheduler tests` | sin errores |\n| Integridad del manifiesto frente a `fixture-manifest.json` | 0 faltantes, 0 inesperados |\n| Control negativo: implementaci\u00f3n inicial parcheada en memoria, solo `NextDailyRunTests` | Se ejecutaron 8, **5 fallaron seg\u00fan lo previsto**, incluidas ambas pruebas de horario de verano |\n\nRevisado de forma independiente por el coordinador desde fuera del espacio de trabajo:\n\n| Comprobaci\u00f3n | Salida | Resultado |\n| --- | --- | --- |\n| conjunto de pruebas p\u00fablico (`results\/checks\/T3-public.txt`) | 0 | 10 pruebas, OK |\n| validador oculto `03-checks\/test_t3_hidden.py` (`results\/checks\/T3-hidden.txt`) | 0 | 2 pruebas, OK |\n\nEl validador oculto falla (salida 1) con una copia pr\u00edstina del fixture. V\u00e9ase\n`results\/checks\/validator-controls.md`.\n\n## Cobertura del comportamiento del mapa de referencia\n\nSe cumplen los cuatro comportamientos requeridos en `03-checks\/gold-map.json`:\n\n| Comportamiento requerido | Evidencia |\n| --- | --- |\n| hora del reloj de pared conservada | incremento aplicado al reloj de pared local sin ajustes, zona reasignada; verificado en todas las pruebas de horario de verano |\n| Transici\u00f3n de primavera cubierta | `test_spring_forward_keeps_requested_hour`: se mantiene la hora 09:30, desfase `-04:00`, tiempo transcurrido 23 h |\n| Transici\u00f3n de oto\u00f1o cubierta | `test_fall_back_keeps_requested_hour`: se mantiene la hora 09:30, desfase `-05:00`, tiempo transcurrido: 25 h |\n| Zona horaria de la IANA utilizada | `ZoneInfo(\"America\/New_York\")` de la biblioteca est\u00e1ndar |\n\nM\u00e1s all\u00e1 del conjunto requerido, el ejecutor tambi\u00e9n cubri\u00f3 los dos casos l\u00edmite de la PEP 495 \u2014una hora real\nomitida por el cambio horario de primavera y una hora real ambigua durante el cambio horario de oto\u00f1o\u2014, adem\u00e1s de los ciclos de siete d\u00edas\nque abarcan cada transici\u00f3n y el comportamiento de entrada ingenua.\n\n## Errores corregidos\n\nDos fallos autoinfligidos en las aserciones de prueba: `siguiente - anterior` en dos fechas y horas que comparten un\n`tzinfo` resta los relojes de pared \u00abna\u00efve\u00bb, por lo que las aserciones de tiempo transcurrido indicaban 1 d\u00eda y fallaron.\nLa implementaci\u00f3n era correcta y las aserciones eran err\u00f3neas; se corrigi\u00f3 con un auxiliar `_elapsed`\nque convierte primero ambos operandos a UTC. No hubo errores de herramientas, importaciones ni de entorno.\nLos artefactos de `__pycache__` se eliminaron tras la ejecuci\u00f3n.\n\n## Salida visible (textual)\n\n**Reproducci\u00f3n**\n\nSe llam\u00f3 a `scheduler\/time_rules.py::next_daily_run` con una fecha y hora `America\/New_York` a cada lado de una transici\u00f3n al horario de verano de 2024:\n\n```\n2024-03-09T09:30:00-05:00 -&gt; 2024-03-10T10:30:00-04:00   #: la hora se desvi\u00f3 +1\n2024-11-02T09:30:00-04:00 -&gt; 2024-11-03T08:30:00-05:00   #: la hora se desvi\u00f3 -1\n```\n\nUn trabajo programado para las 09:30 hora local se ejecut\u00f3 a las 10:30 tras el cambio horario de verano y a las 08:30 tras el cambio horario de invierno.\n\n**Causa principal**\n\nLa implementaci\u00f3n inicial trataba \u00abdaily\u00bb como una duraci\u00f3n absoluta fija:\n\n```python\nelapsed = previous_run.astimezone(timezone.utc) + timedelta(hours=24)\nreturn elapsed.astimezone(previous_run.tzinfo)\n```\n\nAl convertir primero a UTC, `timedelta(hours=24)` equivale exactamente a 24 horas transcurridas. Sin embargo, un d\u00eda natural local en una zona IANA dura 23 h el d\u00eda del cambio horario de primavera y 25 h el d\u00eda del cambio horario de oto\u00f1o, por lo que un desfase constante de 24 h se aleja necesariamente una hora de la hora real solicitada.\n\n**La soluci\u00f3n** (`scheduler\/time_rules.py`)\n\nLa recurrencia diaria es una regla de calendario, por lo que el incremento se aplica ahora al reloj local \u00abingenuo\u00bb, y la zona se vuelve a asociar posteriormente:\n\n```python\ntzinfo = previous_run.tzinfo\nnaive_next = previous_run.replace(tzinfo=None) + timedelta(days=1)\nif tzinfo is None:\n    return naive_next\ncandidate = naive_next.replace(tzinfo=tzinfo, fold=0)\nreturn candidate.astimezone(timezone.utc).astimezone(tzinfo)\n```\n\nPor qu\u00e9 es correcto:\n- La aritm\u00e9tica del reloj de pared sobre el valor \u00abnaive\u00bb es independiente del desfase, por lo que la hora y los minutos solicitados se conservan por definici\u00f3n; A continuaci\u00f3n, `zoneinfo` proporciona el desfase UTC vigente en la nueva fecha (verificado: `-04:00` tras el cambio horario de primavera, `-05:00` tras el cambio horario de oto\u00f1o; tiempo real transcurrido de 23 h y 25 h, respectivamente).\n- `fold=0`, junto con el ciclo de ida y vuelta UTC, gestiona los dos casos extremos que la aritm\u00e9tica pura del reloj de pared deja mal definidos. Seg\u00fan la PEP 495, una hora de pared *omitida* (02:30 del 10 de marzo de 2024) tiene el desfase anterior a la transici\u00f3n en `fold=0`, por lo que el \u00abround-trip\u00bb lo normaliza al instante real 03:30 EDT en lugar de devolver una fecha y hora que no designa ning\u00fan instante. Una hora real *ambigua* (01:30 del 3 de noviembre de 2024) se resuelve de forma determinista como su primera aparici\u00f3n (EDT), en lugar de ser arbitraria.\n- La entrada \u00abnaive\u00bb conserva su significado anterior (simplemente +1 d\u00eda natural); no se impone ning\u00fan nuevo requisito de `tzinfo` a los usuarios que la invocan.\n\nEl alcance se ha mantenido limitado: solo ha cambiado el cuerpo y la cadena de documentaci\u00f3n de `next_daily_run`. `service.py`, `models.py`, `repository.py` y `__init__.py` no se han modificado, no se han a\u00f1adido archivos nuevos y el manifiesto de fixtures sigue coincidiendo exactamente (sin archivos que falten o inesperados). Solo se ha utilizado la biblioteca est\u00e1ndar (`datetime`, `zoneinfo`, `unittest`).\n\n**Pruebas de regresi\u00f3n** (`tests\/test_scheduler.py`, nuevo `NextDailyRunTests`, 8 pruebas) cubren: estabilidad en d\u00edas normales, cambio horario de primavera (hora + desfase + 23 h transcurridas), cambio horario de oto\u00f1o (hora + desfase + 25 h transcurridas), ciclos de siete d\u00edas que abarcan cada transici\u00f3n, tiempo real omitido, tiempo real ambiguo y entradas simplistas.\n\nHay dos observaciones que vale la pena se\u00f1alar. En primer lugar, mis aserciones iniciales sobre el tiempo transcurrido utilizaban \u00absiguiente - anterior\u00bb; Python ignora un `tzinfo` compartido y resta los relojes de pared ingenuos, por lo que ambas devolv\u00edan 1 d\u00eda y fallaban. La implementaci\u00f3n era correcta y las aserciones eran err\u00f3neas; se corrigi\u00f3 con un auxiliar `_elapsed` que convierte ambos operandos a UTC. En segundo lugar, verifiqu\u00e9 que las pruebas detectaran realmente el defecto original volviendo a ejecutar `NextDailyRunTests` sobre una copia en memoria de la implementaci\u00f3n inicializada: fallaron 5 de 8, incluidas ambas pruebas de horario de verano. Las tres que pasan en la versi\u00f3n con errores (d\u00eda normal, omitido, ambiguo) documentan el comportamiento m\u00e1s que detectar regresiones; los casos omitidos\/ambiguos coinciden por casualidad porque un desplazamiento absoluto de +24 h resulta caer en el mismo instante normalizado.\n<\/pre><\/div><\/details><\/div><p class=\"d-limit\">Limitaci\u00f3n del entorno de pruebas: se trataba de un peque\u00f1o repositorio de Python fuera de l\u00ednea. Claude utilizaba un subagente de reserva tras la caducidad del OAuth de la CLI, por lo que el aislamiento y la visibilidad de los tokens no eran id\u00e9nticos.<\/p><\/article>\n\n\n\n<h2 id=\"code-review\" class=\"wp-block-heading\">Calidad de la revisi\u00f3n de c\u00f3digo y verificaci\u00f3n humana<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Las tareas de revisi\u00f3n de c\u00f3digo requieren una habilidad distinta a la de la implementaci\u00f3n de funcionalidades. Un revisor competente debe detectar errores reproducibles, evaluar su impacto, indicar la ruta exacta del c\u00f3digo y distinguir entre un defecto real y una advertencia especulativa. La correcci\u00f3n de un error supone una prueba adicional: el parche no debe introducir una nueva regresi\u00f3n.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">El c\u00f3digo Claude fue el que obtuvo la ventaja m\u00e1s clara en T4. Inform\u00f3 de cinco hallazgos reproducibles de forma independiente, incluidos los dos objetivos de revisi\u00f3n preestablecidos, y obtuvo una puntuaci\u00f3n de 19\/20. Codex inform\u00f3 y corrigi\u00f3 dos defectos v\u00e1lidos de mayor gravedad, pero no mencion\u00f3 el par preestablecido, por lo que obtuvo una puntuaci\u00f3n de 18\/20. Los hallazgos de Codex no fueron falsos positivos; la diferencia observada radicaba en la amplitud, m\u00e1s que en la correcci\u00f3n b\u00e1sica.<\/p>\n\n\n\n<style>\n.evidence-t4-review-and-repair{--ink:#111318;--body:#414753;--muted:#707784;--line:#e4e7ec;--soft:#f6f7f9;--blue:#315efb;--violet:#7257e8;--green:#087a55;--greenSoft:#eaf8f2;--red:#a23131;--redSoft:#fff0f0;color:var(--ink);font-family:Inter,ui-sans-serif,-apple-system,BlinkMacSystemFont,\"Segoe UI\",sans-serif;line-height:1.5;border:1px solid var(--line);border-radius:8px;background:#fff;overflow:hidden;box-shadow:0 16px 42px rgba(24,32,56,.08)}\n.evidence-t4-review-and-repair *{box-sizing:border-box}.evidence-t4-review-and-repair .d-head{display:flex;align-items:flex-start;justify-content:space-between;gap:22px;padding:24px 26px 20px;border-bottom:1px solid var(--line)}\n.evidence-t4-review-and-repair .d-kicker{margin:0 0 6px;color:var(--muted);font:750 11px\/1.4 ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.08em;text-transform:uppercase}.evidence-t4-review-and-repair .d-title{margin:0;font-size:22px;line-height:1.2;letter-spacing:-.025em}.evidence-t4-review-and-repair .d-sub{margin:7px 0 0;color:var(--body);font-size:13px}.evidence-t4-review-and-repair .d-pill{flex:0 0 auto;padding:6px 10px;border:1px solid #ccd6ff;border-radius:999px;color:#2448ca;background:#f0f3ff;font-size:11px;font-weight:800}.evidence-t4-review-and-repair .d-grid{display:grid;grid-template-columns:1fr 1fr}.evidence-t4-review-and-repair .d-side{min-width:0;padding:24px 26px}.evidence-t4-review-and-repair .d-side+.d-side{border-left:1px solid var(--line)}.evidence-t4-review-and-repair .d-product{display:flex;align-items:baseline;justify-content:space-between;gap:14px;font-weight:800}.evidence-t4-review-and-repair .d-score{font-size:34px;line-height:1;letter-spacing:-.05em}.evidence-t4-review-and-repair .d-score small{color:var(--muted);font-size:12px;letter-spacing:0}.evidence-t4-review-and-repair .d-metrics{display:grid;grid-template-columns:repeat(3,1fr);gap:7px;margin:18px 0}.evidence-t4-review-and-repair .d-metric{padding:10px;border:1px solid var(--line);border-radius:6px;background:var(--soft)}.evidence-t4-review-and-repair .d-metric span{display:block;color:var(--muted);font-size:9px;font-weight:800;letter-spacing:.06em;text-transform:uppercase}.evidence-t4-review-and-repair .d-metric strong{display:block;margin-top:3px;font-size:13px}.evidence-t4-review-and-repair .d-preview{position:relative;height:192px;overflow:hidden;border:1px solid #29313f;border-radius:6px;background:#11151d;color:#edf0f5}.evidence-t4-review-and-repair .d-preview-label{padding:11px 13px;border-bottom:1px solid rgba(255,255,255,.1);color:#aeb7c7;font:750 9px\/1 ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.06em;text-transform:uppercase}.evidence-t4-review-and-repair .d-preview pre,.evidence-t4-review-and-repair .d-full pre{margin:0;white-space:pre-wrap;font:11px\/1.6 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.evidence-t4-review-and-repair .d-preview pre{padding:13px}.evidence-t4-review-and-repair .d-preview:after{content:\"\";position:absolute;left:0;right:0;bottom:0;height:55px;background:linear-gradient(transparent,#11151d)}.evidence-t4-review-and-repair .d-take{margin:14px 0 0;color:var(--body);font-size:12px}.evidence-t4-review-and-repair .d-fulls{padding:0 26px 22px}.evidence-t4-review-and-repair .d-full{margin-top:10px;border:1px solid var(--line);border-radius:6px}.evidence-t4-review-and-repair .d-full summary{cursor:pointer;padding:13px 14px;font-size:12px;font-weight:800;list-style:none}.evidence-t4-review-and-repair .d-full summary::-webkit-details-marker{display:none}.evidence-t4-review-and-repair .d-full summary:after{content:\"+\";float:right;color:var(--blue);font-size:17px}.evidence-t4-review-and-repair .d-full[open] summary:after{content:\"\u2212\"}.evidence-t4-review-and-repair .d-full-pane{padding:0 14px 14px}.evidence-t4-review-and-repair .d-full-note{margin:0 0 9px;color:var(--muted);font-size:10px}.evidence-t4-review-and-repair .d-full pre{max-height:620px;overflow:auto;padding:15px;border-radius:5px;background:#f5f6f8;color:#222936;border:1px solid #e0e3e8}.evidence-t4-review-and-repair .d-limit{margin:0;padding:12px 26px;border-top:1px solid var(--line);color:#5a6270;background:#fafbfc;font-size:11px}\n@media(max-width:760px){.evidence-t4-review-and-repair .d-head{display:block}.evidence-t4-review-and-repair .d-pill{display:inline-block;margin-top:12px}.evidence-t4-review-and-repair .d-grid{grid-template-columns:1fr}.evidence-t4-review-and-repair .d-side+.d-side{border-left:0;border-top:1px solid var(--line)}}@media(max-width:480px){.evidence-t4-review-and-repair .d-head,.evidence-t4-review-and-repair .d-side{padding:20px}.evidence-t4-review-and-repair .d-fulls{padding:0 20px 20px}.evidence-t4-review-and-repair .d-metrics{grid-template-columns:1fr}}\n<\/style><article class=\"evidence-t4-review-and-repair\"><header class=\"d-head\"><div><p class=\"d-kicker\">T4 \u00b7 Prueba de repositorio controlado<\/p><h3 class=\"d-title\">Identifica los defectos reproducibles y soluciona los problemas que presenten mayor fiabilidad<\/h3><p class=\"d-sub\">Revisa el caso de prueba, reproduce los defectos reales, aplica las correcciones permitidas y comprueba que las pruebas de regresi\u00f3n verifican el comportamiento.<\/p><\/div><span class=\"d-pill\">Borde de cobertura Claude<\/span><\/header><div class=\"d-grid\"><section class=\"d-side\" aria-label=\"Resultado del Codex\"><div class=\"d-product\"><span>C\u00f3dice<\/span><span class=\"d-score\">18<small>\/20<\/small><\/span><\/div><div class=\"d-metrics\"><div class=\"d-metric\"><span>Duraci\u00f3n<\/span><strong>223 s<\/strong><\/div><div class=\"d-metric\"><span>Cheques<\/span><strong>4 aprobados<\/strong><\/div><div class=\"d-metric\"><span>Alcance<\/span><strong>2 corregidos<\/strong><\/div><\/div><div class=\"d-preview\"><div class=\"d-preview-label\">Primer fragmento v\u00e1lido de la salida<\/div><pre>1. Alto: los trabajos existentes podr\u00edan sobrescribirse sin previo aviso.\n\n2. Medio: las ejecuciones diarias se desfasaron durante los cambios de horario de verano.\n\nVerificaci\u00f3n: cuatro pruebas superadas, cero fallos.<\/pre><\/div><p class=\"d-take\"><strong>Opini\u00f3n del cr\u00edtico:<\/strong> Se han detectado fallos \u00fatiles de mayor gravedad y se han aplicado correcciones espec\u00edficas, pero no se han alcanzado los dos objetivos de revisi\u00f3n fijados.<\/p><\/section><section class=\"d-side\" aria-label=\"Resultado del c\u00f3digo Claude\"><div class=\"d-product\"><span>C\u00f3digo Claude<\/span><span class=\"d-score\">19<small>\/20<\/small><\/span><\/div><div class=\"d-metrics\"><div class=\"d-metric\"><span>Duraci\u00f3n<\/span><strong>235 s<\/strong><\/div><div class=\"d-metric\"><span>Cheques<\/span><strong>9 aprobados<\/strong><\/div><div class=\"d-metric\"><span>Alcance<\/span><strong>5 casos notificados<\/strong><\/div><\/div><div class=\"d-preview\"><div class=\"d-preview-label\">Primer fragmento v\u00e1lido de la salida<\/div><pre>D1 Desviaci\u00f3n del horario de verano (DST) \u00b7 Alta\nD2 Adquisici\u00f3n ingenua de la zona horaria \u00b7 Media\nD3 Colisi\u00f3n de identificadores \u00b7 Alta\nD4 La eliminaci\u00f3n de un elemento que no existe provoca un KeyError \u00b7 Media\nD5 Propietario no validado \u00b7 Baja<\/pre><\/div><p class=\"d-take\"><strong>Opini\u00f3n del cr\u00edtico:<\/strong> Mayor cobertura de la revisi\u00f3n sin falsos positivos reproducidos; no se corrigieron dos hallazgos dependientes del contrato.<\/p><\/section><\/div><div class=\"d-fulls\"><details class=\"d-full\"><summary>Ver el resultado completo de Codex<\/summary><div class=\"d-full-pane\"><p class=\"d-full-note\">Salida completa, desinfectada y v\u00e1lida por primera vez<\/p><pre>## Hallazgos que requieren acci\u00f3n\n\n1. **Alto \u2014 Los trabajos existentes podr\u00edan sobrescribirse sin previo aviso**\n\n   - Evidencia: inicializaci\u00f3n del identificador en [service.py](.\/scheduler\/service.py:8), combinada con la sustituci\u00f3n del diccionario en [repository.py](.\/scheduler\/repository.py:9).\n   - Impacto: al crear un servicio con un repositorio ya existente, se podr\u00eda reutilizar el identificador `1`, lo que sustituir\u00eda el trabajo almacenado y provocar\u00eda una p\u00e9rdida de datos.\n   - Reproducci\u00f3n m\u00ednima: guarda `Job(1, ...)`, crea `SchedulerService(repository)` y, a continuaci\u00f3n, crea otro trabajo. Antes de la correcci\u00f3n, solo quedaba el nuevo trabajo.\n   - Soluci\u00f3n: inicializar el siguiente identificador a partir del identificador m\u00e1s alto existente en el repositorio.\n   - Prueba de regresi\u00f3n: [test_scheduler.py](.\/tests\/test_scheduler.py:22).\n\n2. **Medio \u2014 Las ejecuciones diarias se desfasaban con los cambios de horario de verano**\n\n   - Evidencia: c\u00e1lculo corregido en [time_rules.py](.\/scheduler\/time_rules.py:4).\n   - Impacto: una tarea diaria programada para las 09:00 se ejecut\u00f3 a las 10:00 tras el cambio al horario de verano en primavera.\n   - Reproducci\u00f3n m\u00ednima: calcular la siguiente ejecuci\u00f3n despu\u00e9s de `2026-03-07 09:00 America\/New_York`. Antes de la correcci\u00f3n, el resultado era `2026-03-08 10:00`.\n   - Soluci\u00f3n: a\u00f1adir un d\u00eda natural local en lugar de 24 horas UTC transcurridas.\n   - Prueba de regresi\u00f3n: [test_scheduler.py](.\/tests\/test_scheduler.py:33).\n\n## Archivos modificados\n\n- [scheduler\/service.py](.\/scheduler\/service.py)\n- [scheduler\/time_rules.py](.\/scheduler\/time_rules.py)\n- [tests\/test_scheduler.py](.\/tests\/test_scheduler.py)\n\n## Verificaci\u00f3n\n\n- Se observ\u00f3 que ambas pruebas de regresi\u00f3n fallaban antes de sus correcciones.\n- Cada una de ellas super\u00f3 la prueba tras su correspondiente correcci\u00f3n.\n- `PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -s tests -v`\n- Resultado: **4 pruebas superadas, 0 fallos**.\n- No quedan artefactos de cach\u00e9 de Python generados.\n\n## Conclusi\u00f3n y decisi\u00f3n\n\n- **Conclusi\u00f3n:** Ambos defectos confirmados est\u00e1n corregidos y cubiertos por pruebas de regresi\u00f3n espec\u00edficas.\n- **Decisi\u00f3n necesaria:** Ninguna.<\/pre><\/div><\/details><details class=\"d-full\"><summary>Ver el c\u00f3digo Claude completo<\/summary><div class=\"d-full-pane\"><p class=\"d-full-note\">Registro completo de la transferencia, incluida la salida v\u00e1lida inicial tal y como se ha registrado.<\/p><pre>Registro de ejecuci\u00f3n de # T4 \u2014 Prueba y revisi\u00f3n del c\u00f3digo\n\nPar\u00e1metros de ejecuci\u00f3n de ##\n\n| Campo | Valor |\n| --- | --- |\n| Tarea | `T4` |\n| Prompt congelado | `01-prompts\/T4.md` |\n| SHA-256 del prompt congelado | `5e69546007ea776f40b3d334ddb75671ff684c151c77551bad27de3b0fdce640` |\n| Unidad de ejecuci\u00f3n | subagente aislado Claude, \"de uso general\", contexto nuevo |\n| M\u00e9todo de aislamiento | **recurso de reserva del subagente** (regresi\u00f3n documentada \u2014 v\u00e9ase `results\/isolation-decision.md`) |\n| Copia limpia asignada | `runtime\/workspaces\/T4` |\n| Versi\u00f3n del c\u00f3digo Claude | `2.1.220` |\n| Configuraci\u00f3n del modelo | `claude-opus-5` |\n| start_utc | `2026-07-28T10:28:22Z` |\n| end_utc | `2026-07-28T10:32:17Z` |\n| Duraci\u00f3n | 235 s (simult\u00e1neo con T1\u2013T3; no es una medici\u00f3n de latencia limpia) |\n| N\u00famero de intento | 1 |\n| Estado | `v\u00e1lido` |\n| Intervenci\u00f3n humana | ninguna |\n\nLa condici\u00f3n de la indicaci\u00f3n congelada \u2014\"corr\u00edgelas si la configuraci\u00f3n de ejecuci\u00f3n congelada permite\ncorrecciones\"\u2014 fue resuelta por el coordinador a partir de `00-control\/run-config.json` y\n`00-control\/safety-policy.json`, que permiten escribir copias aisladas de los fixtures. Se indic\u00f3 al ejecutor\nque se permiten las correcciones. No se le mostr\u00f3 ning\u00fan archivo de control.\n\n## Resumen de herramientas seguras\n\n`date`, `Read`\/`Edit`\/`Write` \u00fanicamente dentro del espacio de trabajo asignado, `grep`,\n`python3 -m unittest discover`, `python3 -m compileall`, una ejecuci\u00f3n de vacuidad con copia temporal, una\ncomprobaci\u00f3n de presencia del manifiesto. Sin red, sin instalaciones, solo biblioteca est\u00e1ndar.\n\n## Archivos modificados\n\n`scheduler\/time_rules.py` (modificado), `scheduler\/service.py` (modificado),\n`tests\/test_scheduler.py` (modificado, +2 pruebas), `tests\/test_time_rules.py` (a\u00f1adido, 5 pruebas).\nParche completo: `results\/T4\/patch.diff`.\n\n## Resultados de la comprobaci\u00f3n sin conexi\u00f3n\n\nInformado por el ejecutor de tareas:\n\n| Comprobaci\u00f3n | Resultado |\n| --- | --- |\n| `python3 -m unittest discover -s tests -v` | **9 superadas, 0 fallidas, 0 omitidas** (l\u00ednea de base 2) |\n| `python3 -m compileall -q scheduler tests` | superada |\n| Comprobaci\u00f3n de presencia del manifiesto frente a `expected_files` | los 8 presentes |\n| Ejecuci\u00f3n de vacuity con las implementaciones originales restauradas | 5 fallos, 4 superadas, seg\u00fan lo previsto |\n\nRevisado de forma independiente por el coordinador desde fuera del espacio de trabajo:\n\n| Comprobaci\u00f3n | Salida | Resultado |\n| --- | --- | --- |\n| conjunto de pruebas p\u00fablico (`results\/checks\/T4-public.txt`) | 0 | 9 pruebas, OK |\n\nComprobaci\u00f3n cruzada informativa, sin puntuaci\u00f3n: el validador oculto de T3 tambi\u00e9n supera la prueba en este\nespacio de trabajo (salida 0), ya que T4 corrigi\u00f3 de forma independiente el mismo defecto `next_daily_run`. V\u00e9ase\n`results\/checks\/validator-controls.md`.\n\n## Cobertura de defectos del mapa de referencia\n\n`03-checks\/gold-map.json` introduce dos defectos para la puntuaci\u00f3n de T4. Ambos se han detectado:\n\n| Defecto introducido | Detectado | Notificado como |\n| --- | --- | --- |\n| propietario en blanco aceptado | s\u00ed | **D5**, `scheduler\/service.py:11,13`, gravedad Baja, notificado y no corregido deliberadamente |\n| La eliminaci\u00f3n de un identificador que falta genera un `KeyError` | s\u00ed | **D4**, `scheduler\/repository.py:19` \u2192 `service.py:22`, gravedad media, notificado y no corregido deliberadamente |\n\nSe notificaron tres hallazgos adicionales m\u00e1s all\u00e1 del conjunto inicial. Ninguno es un falso positivo:\n\n- **D1** \u2014 Desviaci\u00f3n del horario de verano en `next_daily_run`. Este es el tercer defecto que figura en\n  `03-checks\/seeded-defects.md` (est\u00e1 clasificado como T3, no como T4, pero se trata de un error simulado aut\u00e9ntico).\n- **D2** \u2014 Una entrada ingenua en `next_daily_run` adquiere silenciosamente la zona horaria del host y devuelve una\n  fecha y hora que la tiene en cuenta. Real y dependiente del host; verificado por el coordinador compar\u00e1ndolo con el c\u00f3digo fuente del fixture.\n- **D3** \u2014 Colisi\u00f3n de identificadores entre un servicio y un repositorio inyectado o compartido, lo que provoca\n  una sobrescritura silenciosa. Real: `SchedulerService._next_identifier` siempre comienza en 1, mientras que\n  `JobRepository.save` es una asignaci\u00f3n de diccionario sin protecci\u00f3n. T1 identific\u00f3 de forma independiente la misma\n  falla a partir del fixture original.\n\nRecuento de falsos positivos: **0**. El ejecutor tambi\u00e9n inform\u00f3 correctamente de que no hab\u00eda hallazgos de seguridad, se\u00f1alando\nque el fixture no presenta vulnerabilidades de red, E\/S, deserializaci\u00f3n, subprocesos ni credenciales.\n\n## Desviaci\u00f3n digna de menci\u00f3n\n\nLa indicaci\u00f3n fija solicitaba pruebas y correcciones sobre \"los dos defectos con mayor nivel de confianza\". El\nejecutor seleccion\u00f3 D1\/D2 (una correcci\u00f3n, misma funci\u00f3n) y D3, en lugar de los dos defectos introducidos en el mapa de referencia\nD4 y D5. Su raz\u00f3n expuesta es defendible: tanto D4 como D5 dependen de un contrato de API\nno especificado, por lo que corregirlos ser\u00eda una conjetura. El cr\u00e9dito por detecci\u00f3n no se ve afectado: se detectaron ambos defectos preestablecidos,\ncon indicaci\u00f3n de archivo, l\u00ednea, gravedad, impacto y reproducci\u00f3n. Las correcciones aplicadas correspond\u00edan a defectos reales\ny est\u00e1n respaldadas por una comprobaci\u00f3n de vacuidad.\n\n## Errores saneados\n\nDos fallos de prueba autoinducidos debidos a la sustracci\u00f3n del tiempo real frente al tiempo absoluto en fechas y horas\nque comparten un `tzinfo`; corregidos y verificados de nuevo. No se produjeron errores de herramientas ni de entorno. Los artefactos `__pycache__`\nse eliminaron tras la ejecuci\u00f3n.\n\n## Salida visible (textual)\n\n### Informe de defectos\n\n**D1 \u2014 `scheduler\/time_rules.py:10-11` \u2014 La programaci\u00f3n diaria se desv\u00eda una hora durante el horario de verano \u2014 Gravedad: Alta**\n\n`next_daily_run` suma 24 horas *transcurridas* mediante un ciclo de ida y vuelta en UTC en lugar de avanzar el d\u00eda natural. Una tarea diaria se define seg\u00fan la hora real, por lo que todas las tareas en una zona que aplica el horario de verano se ejecutan silenciosamente una hora antes o despu\u00e9s a partir del d\u00eda de cambio de hora, y el error persiste (cada ejecuci\u00f3n se reinicia a partir de la hora desplazada). La propia cadena de documentaci\u00f3n admit\u00eda este comportamiento.\n\n```\nprev = datetime(2024, 3, 9, 9, 0, tzinfo=ZoneInfo(\"America\/New_York\"))\nnext_daily_run(prev)   # -&gt; 2024-03-10 10:00:00-04:00, esperado 09:00-04:00\nprev = datetime(2024, 11, 2, 9, 0, tzinfo=ZoneInfo('America\/New_York'))\nnext_daily_run(prev)   # -&gt; 3 de noviembre de 2024 a las 08:00:00-05:00, previsto a las 09:00-05:00\n```\n\n**D2 \u2014 `scheduler\/time_rules.py:10-11` \u2014 Una entrada \"naiva\" adquiere silenciosamente la zona horaria local del equipo \u2014 Gravedad: Media**\n\nLas mismas dos l\u00edneas. `.astimezone(timezone.utc)` sobre un objeto `datetime` \"naive\" asume la hora local del sistema, y `.astimezone(None)` devuelve un objeto `datetime` \"aware\". Una llamada con entrada \"naive\" devuelve una salida 'aware', por lo que el resultado no es comparable con los dem\u00e1s valores 'naive' del llamante (`TypeError` al compararlos) y la respuesta depende de la `TZ` del host.\n\n```\nnext_daily_run(datetime(2024, 1, 1, 9, 0))\n# -&gt; datetime(2024, 1, 2, 9, 0, tzinfo=timezone(timedelta(hours=8), \"CST\"))  # dependiente del host\n```\n\n**D3 \u2014 `scheduler\/service.py:8,13,15` (prefijo) \u2014 La colisi\u00f3n de identificadores destruye silenciosamente los trabajos almacenados \u2014 Gravedad: Alta**\n\nEl contador de identificadores era espec\u00edfico de cada `SchedulerService` y siempre comenzaba en 1, ignorando el contenido del repositorio inyectado. Cualquier segundo servicio que utilizara un repositorio compartido, o cualquier servicio que utilizara un repositorio prellenado, reasignaba el identificador 1; `JobRepository.save` es una asignaci\u00f3n a un diccionario, por lo que el trabajo existente se sobrescrib\u00eda sin generar ning\u00fan error. P\u00e9rdida de datos.\n\n```\nrepo = JobRepository()\nSchedulerService(repo).create_job(\"Copia de seguridad nocturna\", 'Alex')    # id 1\nSchedulerService(repo).create_job('Exportaci\u00f3n de n\u00f3minas', 'Blake')   # id 1 de nuevo\nrepo.all()   # -&gt; [Job(1, 'Exportaci\u00f3n de n\u00f3minas', 'Blake')]  \u2014 El trabajo de Alex ha desaparecido\n```\n\n**D4 \u2014 `scheduler\/repository.py:19` \u2192 `scheduler\/service.py:22` \u2014 `delete_job` genera un `KeyError` por un id desconocido \u2014 Gravedad: Media**\n\n`delete` utiliza `dict.pop` sin un valor por defecto, mientras que su hom\u00f3logo `get` (l\u00ednea 13) devuelve `None` si no encuentra el elemento. Esta inconsistencia provoca un `KeyError` sin tratar a trav\u00e9s de `SchedulerService.delete_job`, que es poco probable que los usuarios que lo llaman detecten. Reproducci\u00f3n: `SchedulerService().delete_job(999)` \u2192 `KeyError: 999`. La soluci\u00f3n ser\u00eda `pop(identifier, None)` o una excepci\u00f3n de dominio expl\u00edcita; se ha dejado deliberadamente sin corregir, ya que el contrato correcto (operaci\u00f3n nula silenciosa frente a error tipificado) es una decisi\u00f3n de la API que corresponde al propietario.\n\n**D5 \u2014 `scheduler\/service.py:11,13` \u2014 El campo \u00abowner\u00bb no se valida \u2014 Gravedad: Baja**\n\nSe comprueba que `name` no est\u00e9 vac\u00edo, pero no se comprueba `owner`: `create_job(\"ok\", \"   \")` almacena `owner=''`. Ambos par\u00e1metros tambi\u00e9n llaman a `.strip()` sin protecci\u00f3n, por lo que `None` se muestra como `AttributeError: el objeto 'NoneType' no tiene el atributo 'strip'` en lugar del `ValueError` que la API utiliza normalmente para entradas incorrectas. Se ha dejado sin corregir: el contrato previsto para `owner` no se especifica en ninguna parte del fixture.\n\n**Seguridad:** sin hallazgos. El fixture no presenta vulnerabilidades de red, E\/S, deserializaci\u00f3n, subprocesos ni credenciales; el almacenamiento es un diccionario dentro del proceso.\n\n**Laguna de cobertura:** `scheduler\/time_rules.py` y `scheduler\/repository.py` ten\u00edan una cobertura de pruebas nula antes de esta ejecuci\u00f3n; las dos pruebas predefinidas solo ejecutaban la ruta normal del servicio.\n\n### Pruebas y correcciones aplicadas\n\nLos dos defectos con mayor nivel de confianza fueron **D1\/D2** (misma funci\u00f3n, una correcci\u00f3n) y **D3**.\n\n**Correcci\u00f3n 1 \u2014 `scheduler\/time_rules.py`:** se sustituy\u00f3 el c\u00e1lculo de ida y vuelta en UTC por `previous_run + timedelta(days=1)`. Python realiza operaciones aritm\u00e9ticas con tiempo real sobre fechas y horas conscientes, y `zoneinfo` vuelve a resolver el desfase UTC de forma diferida a partir del nuevo tiempo real; as\u00ed, las 09:00 siguen siendo las 09:00, mientras que el desfase se desplaza correctamente de `-05:00 \u2192 -04:00`. Esto corrige D1 y D2 a la vez: las entradas \u00abna\u00efve\u00bb ahora se mantienen como tales y nunca se deduce la zona horaria local. El caso de la hora de transici\u00f3n entre \u00abinaccesible\u00bb y \u00abambigua\u00bb se documenta como un caso en el que se recurre a las reglas de redondeo de `tzinfo`.\n\n**Correcci\u00f3n 2 \u2014 `scheduler\/service.py`:** se ha eliminado el contador `_next_identifier` por instancia; ahora los identificadores se asignan a partir del estado del repositorio como `max(ids existentes, por defecto=0) + 1` en el momento de la creaci\u00f3n. Esto es correcto tanto para repositorios compartidos como para los prellenados. Compensaci\u00f3n: O(n) por creaci\u00f3n en lugar de O(1), lo cual es aceptable para un almac\u00e9n en memoria respaldado por un diccionario, y garantiza la correcci\u00f3n frente a un contador que no puede ver el almac\u00e9n en el que escribe.\n\n**Pruebas \u2014 `tests\/test_time_rules.py` (nuevo, 5 pruebas):** Conservaci\u00f3n del reloj real en el cambio al horario de verano y al horario de invierno, tiempo transcurrido absoluto de 23 h\/25 h durante esas transiciones, resoluci\u00f3n de la diferencia horaria con respecto al UTC, \u00abnaive-stays-naive\u00bb y un simple avance de un d\u00eda en el UTC. Se omite correctamente si no hay ninguna base de datos de la IANA disponible.\n\n**Pruebas \u2014 `tests\/test_scheduler.py` (ampliado, +2 pruebas):** dos servicios que comparten un repositorio deben emitir identificadores distintos y conservar ambos trabajos; un servicio sobre un repositorio prellenado con los identificadores 1 y 7 debe emitir el 8 y dejar intactos los trabajos existentes.\n\n**Comprobaci\u00f3n de vacuidad:** he restaurado ambas implementaciones originales en una copia temporal y he vuelto a ejecutar el conjunto de pruebas: las 5 pruebas nuevas fallaron (`FAILED (failures=5)`), y todas pasan con el c\u00f3digo corregido. Las pruebas identifican realmente los defectos.\n\nUna correcci\u00f3n durante la ejecuci\u00f3n: en mi primer borrador, la aserci\u00f3n del tiempo transcurrido en horario de verano se realizaba como `resultado - anterior`, lo que Python eval\u00faa como aritm\u00e9tica de reloj real cuando ambos operandos comparten un `tzinfo`, por lo que se interpretaba como `24 h` y las pruebas fallaban. Ahora las aserciones se convierten a UTC antes de la resta. El fallo estaba en mi prueba, no en la correcci\u00f3n.\n\n### Notas para el responsable\n\nEl archivo `fixture-manifest.json` no se modific\u00f3, por lo que `tests\/test_time_rules.py` es un archivo nuevo v\u00e1lido que no aparece en `expected_files` \u2014 actualiza el manifiesto si una comprobaci\u00f3n exige un conjunto exacto de archivos. Y los errores D4 y D5 se notificaron, pero no se corrigieron deliberadamente: ambos dependen de una decisi\u00f3n sobre el contrato de la API (sem\u00e1ntica de \u00abmiss-on-delete\u00bb, reglas de validaci\u00f3n del propietario) que no se especifica en ninguna parte del fixture, por lo que elegir una opci\u00f3n habr\u00eda sido una suposici\u00f3n m\u00e1s que una correcci\u00f3n.\n<\/pre><\/div><\/details><\/div><p class=\"d-limit\">Limitaci\u00f3n del entorno de pruebas: se trataba de un peque\u00f1o repositorio de Python fuera de l\u00ednea. Claude utilizaba un subagente de reserva tras la caducidad del OAuth de la CLI, por lo que el aislamiento y la visibilidad de los tokens no eran id\u00e9nticos.<\/p><\/article>\n\n\n\n<p class=\"wp-block-paragraph\">Ninguna de estas puntuaciones elimina la necesidad de una revisi\u00f3n humana. Una vez que cualquiera de los agentes haya completado una reparaci\u00f3n, comprueba las interfaces modificadas, el \u00e1mbito de los archivos inesperados, la falta de pruebas negativas, el historial de permisos o comandos y la ruta de reversi\u00f3n. Una explicaci\u00f3n convincente no sustituye a una prueba reproducible.<\/p>\n\n\n\n<h2 id=\"safety\" class=\"wp-block-heading\">Permisos, entornos aislados y seguridad operativa<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Un agente de programaci\u00f3n puede leer c\u00f3digo privado, ejecutar comandos de shell, modificar numerosos archivos y llamar a herramientas externas. Por ello, el dise\u00f1o de los permisos forma parte de la calidad del producto. Las cuestiones relevantes son: qu\u00e9 operaciones requieren autorizaci\u00f3n, a qu\u00e9 puede acceder el agente por defecto, con qu\u00e9 claridad advierte de las acciones de riesgo y si un desarrollador puede revisar los cambios resultantes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">No hay que dar por sentado que un menor n\u00famero de solicitudes de aprobaci\u00f3n sea autom\u00e1ticamente mejor. Una baja fricci\u00f3n resulta \u00fatil en un entorno aislado sin credenciales ni conexiones de producci\u00f3n. Sin embargo, ese mismo comportamiento puede resultar peligroso en un repositorio conectado a scripts de implementaci\u00f3n, datos reales de clientes o permisos amplios en la nube. Por el contrario, un n\u00famero excesivo de aprobaciones puede hacer que la automatizaci\u00f3n segura resulte poco pr\u00e1ctica y animar a los usuarios a aprobar solicitudes sin leerlas.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Nuestra prueba se realiz\u00f3 con copias locales recientes, sin sistemas de producci\u00f3n, sin implementaci\u00f3n y sin intervenci\u00f3n humana en la ejecuci\u00f3n efectiva. Por lo tanto, eval\u00faa la realizaci\u00f3n de las tareas en condiciones seguras, no la seguridad relativa de los dos productos. Antes de utilizar cualquiera de estas herramientas en trabajos importantes, empieza con acceso de solo lectura, define los directorios y comandos permitidos, revisa las diferencias y realiza comprobaciones objetivas en un entorno recuperable.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Empieza con una arquitectura de solo lectura o asume el riesgo.<\/li>\n\n\n\n<li>Acepta \u00fanicamente aquellos comandos cuyo alcance y consecuencias comprendas.<\/li>\n\n\n\n<li>Mant\u00e9n las credenciales, los datos de producci\u00f3n y el acceso a la implementaci\u00f3n fuera del entorno de prueba.<\/li>\n\n\n\n<li>Exige un archivo \u00abdiff\u00bb, pruebas y una v\u00eda clara para revertir los cambios antes de aceptar el resultado.<\/li>\n<\/ul>\n\n\n\n<h2 id=\"customization\" class=\"wp-block-heading\">MCP, habilidades, instrucciones del proyecto y personalizaci\u00f3n<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Ambos ecosistemas pueden ampliarse, pero los t\u00e9rminos de \u00abampliaci\u00f3n\u00bb no deben considerarse sin\u00f3nimos. Las instrucciones de proyecto indican a un agente c\u00f3mo comportarse en un repositorio. Las \u00abskills\u00bb reutilizables agrupan un flujo de trabajo repetible o conocimientos especializados. MCP conecta un host con herramientas o datos externos. Los \u00abhooks\u00bb y los comandos pueden automatizar momentos concretos de un ciclo de desarrollo. Un producto puede destacar en una capa sin que ello implique que tenga que igualar otra caracter\u00edstica punto por punto.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La cuesti\u00f3n a la hora de comprar no es si existe un logotipo de integraci\u00f3n, sino si la conexi\u00f3n se puede instalar, autenticar, aprobar y poner en pr\u00e1ctica en el servidor que realmente utilizas. Adem\u00e1s, debe contar con un modo de fallo comprensible. Un servidor MCP que funcione de forma interactiva pero que espere a recibir la aprobaci\u00f3n en una sesi\u00f3n desatendida sigue siendo \u00fatil, pero no deber\u00eda describirse como una automatizaci\u00f3n sin fricciones.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Las instrucciones reutilizables tienen una salvedad similar. Los archivos de instrucciones extensos no garantizan el cumplimiento, y un conjunto de reglas demasiado complicado puede restar contexto o generar contradicciones. Las directrices del repositorio deben ser breves, comprobables y estar estrechamente relacionadas con el c\u00f3digo. Indica los comandos de verificaci\u00f3n obligatorios, las \u00e1reas protegidas, las normas de estilo y cu\u00e1ndo el agente debe detenerse para solicitar autorizaci\u00f3n.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Instrucciones del proyecto:<\/strong> normas espec\u00edficas del repositorio y comandos de verificaci\u00f3n.<\/li>\n\n\n\n<li><strong>Competencias:<\/strong> procedimientos reutilizables o paquetes de conocimientos especializados.<\/li>\n\n\n\n<li><strong>MCP:<\/strong> conexiones con herramientas y datos externos.<\/li>\n\n\n\n<li><strong>Ganchos y comandos:<\/strong> automatizaci\u00f3n en torno a eventos definidos del flujo de trabajo.<\/li>\n<\/ul>\n\n\n\n<h2 id=\"pricing\" class=\"wp-block-heading\">Codex frente a Claude: precios y l\u00edmites de uso<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">La comparaci\u00f3n de tarifas b\u00e1sicas para consumidores comienza en $20 al mes. El acceso a Codex est\u00e1 incluido en el plan correspondiente $20 ChatGPT, mientras que Claude Pro cuesta $20 al mes en Estados Unidos e incluye Claude Code. Ambos ofrecen niveles de consumo m\u00e1s elevados, de $100 y $200. Que los precios de cat\u00e1logo sean similares no significa que la capacidad sea id\u00e9ntica.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">El plan \u201cClaude Max 5x\u201d cuesta $100 al mes y el plan \u201cMax 20x\u201d cuesta $200 al mes. Las denominaciones \u00ab5x\u00bb y \u00ab20x\u00bb describen el uso por sesi\u00f3n en comparaci\u00f3n con la versi\u00f3n Pro, y no un n\u00famero garantizado de tareas de codificaci\u00f3n. Claude y Claude Code comparten los l\u00edmites por sesi\u00f3n y semanales. La longitud del contexto, los archivos adjuntos, la elecci\u00f3n del modelo y el uso de funciones pueden influir en la rapidez con la que se agota la asignaci\u00f3n.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1280\" height=\"800\" src=\"https:\/\/wp.glbgpt.com\/wp-content\/uploads\/2026\/07\/claude-max-plan.webp\" alt=\"P\u00e1gina del plan Claude Max en la que se describe la capacidad de uso de Max 5x y Max 20x\" class=\"wp-image-17388\" srcset=\"https:\/\/wp.glbgpt.com\/wp-content\/uploads\/2026\/07\/claude-max-plan.webp 1280w, https:\/\/wp.glbgpt.com\/wp-content\/uploads\/2026\/07\/claude-max-plan-300x188.webp 300w, https:\/\/wp.glbgpt.com\/wp-content\/uploads\/2026\/07\/claude-max-plan-1024x640.webp 1024w, https:\/\/wp.glbgpt.com\/wp-content\/uploads\/2026\/07\/claude-max-plan-768x480.webp 768w, https:\/\/wp.glbgpt.com\/wp-content\/uploads\/2026\/07\/claude-max-plan-18x12.webp 18w\" sizes=\"(max-width: 1280px) 100vw, 1280px\" \/><figcaption class=\"wp-element-caption\">La p\u00e1gina oficial del plan Max de Claude describe las opciones de capacidad de uso de 5x y 20x. Los precios mensuales figuran en ese mismo art\u00edculo oficial; los detalles del plan se comprobaron en julio de 2026.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Los cr\u00e9ditos de uso opcionales de Claude permiten continuar con el trabajo elegible una vez agotado el uso incluido, siempre que est\u00e9n activados, y dichos cr\u00e9ditos se facturan por separado seg\u00fan las tarifas est\u00e1ndar de la API. La autenticaci\u00f3n mediante clave API constituye otra v\u00eda de facturaci\u00f3n independiente. Calificar cualquiera de estas v\u00edas como \u201cilimitada\u201d ocultar\u00eda el coste marginal real.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1280\" height=\"800\" src=\"https:\/\/wp.glbgpt.com\/wp-content\/uploads\/2026\/07\/claude-code-plan-limits.webp\" alt=\"Documentaci\u00f3n del plan \u00abClaude\u00bb en la que se explican las sesiones compartidas y los l\u00edmites de uso semanales\" class=\"wp-image-17389\" srcset=\"https:\/\/wp.glbgpt.com\/wp-content\/uploads\/2026\/07\/claude-code-plan-limits.webp 1280w, https:\/\/wp.glbgpt.com\/wp-content\/uploads\/2026\/07\/claude-code-plan-limits-300x188.webp 300w, https:\/\/wp.glbgpt.com\/wp-content\/uploads\/2026\/07\/claude-code-plan-limits-1024x640.webp 1024w, https:\/\/wp.glbgpt.com\/wp-content\/uploads\/2026\/07\/claude-code-plan-limits-768x480.webp 768w, https:\/\/wp.glbgpt.com\/wp-content\/uploads\/2026\/07\/claude-code-plan-limits-18x12.webp 18w\" sizes=\"(max-width: 1280px) 100vw, 1280px\" \/><figcaption class=\"wp-element-caption\">El c\u00f3digo Claude utiliza la asignaci\u00f3n de la suscripci\u00f3n Pro o Max asociada, incluidos los l\u00edmites de sesiones compartidas y los l\u00edmites semanales. La capacidad exacta var\u00eda en funci\u00f3n de la carga de trabajo.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Codex distingue asimismo entre el uso incluido en el plan de consumidor, los cr\u00e9ditos adquiridos v\u00e1lidos y la facturaci\u00f3n de la API. Los mensajes locales y los chats en la nube comparten un intervalo de cinco horas, y tambi\u00e9n pueden aplicarse l\u00edmites semanales. Un campo de token en un registro de la CLI no se puede convertir directamente en un porcentaje de cinco horas, en un importe de cr\u00e9dito de suscripci\u00f3n ni en una factura de la API.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Para tareas ocasionales de programaci\u00f3n en solitario, el nivel $20 en cualquiera de los dos lados es el punto de partida m\u00e1s sensato. El trabajo diario con repositorios que impliquen contextos largos puede justificar un nivel de uso superior, pero solo tras observar los reinicios reales y el consumo de tareas. El trabajo paralelo intensivo requiere a\u00fan m\u00e1s cuidado: pagar por un nivel superior no elimina la necesidad de controlar el contexto, dividir las tareas y reservar el razonamiento m\u00e1s costoso para el trabajo que requiera un alto nivel de juicio.<\/p>\n\n\n\n<h2 id=\"controlled-test\" class=\"wp-block-heading\">Resultados de nuestra prueba comparativa controlada entre el c\u00f3digo Codex y el c\u00f3digo Claude<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Antes de que se ejecutara ninguno de los agentes, fijamos cuatro instrucciones en ingl\u00e9s, un programa est\u00e1ndar p\u00fablico en Python, comprobaciones objetivas, una r\u00fabrica de puntuaci\u00f3n y una regla de \u00abprimer resultado v\u00e1lido\u00bb. Las tareas abarcaban la comprensi\u00f3n de un repositorio desconocido, una caracter\u00edstica de varios archivos, la correcci\u00f3n de un error en el horario de verano y la revisi\u00f3n de c\u00f3digo con correcciones. Los resultados v\u00e1lidos no fueron objeto de intervenci\u00f3n humana, y los resultados v\u00e1lidos pero deficientes no pudieron volver a ejecutarse para obtener una puntuaci\u00f3n mejor.<\/p>\n\n\n\n<style>.comparison-setup-card{--ink:#111318;--body:#414753;--muted:#707784;--line:#e4e7ec;--soft:#f6f7f9;--blue:#315efb;--violet:#7257e8;--green:#087a55;--greenSoft:#eaf8f2;--red:#a23131;--redSoft:#fff0f0;color:var(--ink);font-family:Inter,ui-sans-serif,-apple-system,BlinkMacSystemFont,\"Segoe UI\",sans-serif;line-height:1.5;border:1px solid var(--line);border-radius:8px;background:#fff;overflow:hidden;box-shadow:0 16px 42px rgba(24,32,56,.08)}.comparison-setup-card *{box-sizing:border-box}.comparison-setup-card .s-head{padding:24px 26px 20px;border-bottom:1px solid var(--line)}.comparison-setup-card .s-kicker{margin:0 0 6px;color:var(--muted);font:750 11px\/1.4 ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.08em;text-transform:uppercase}.comparison-setup-card h3{margin:0;font-size:22px;line-height:1.2;letter-spacing:-.025em}.comparison-setup-card .s-sub{margin:7px 0 0;color:var(--body);font-size:13px}.comparison-setup-card .s-body{padding:24px 26px}.comparison-setup-card .s-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:10px}.comparison-setup-card .s-stat{padding:15px;border:1px solid var(--line);border-radius:6px;background:var(--soft)}.comparison-setup-card .s-stat span{display:block;color:var(--muted);font-size:10px;font-weight:800;text-transform:uppercase;letter-spacing:.06em}.comparison-setup-card .s-stat strong{display:block;margin-top:5px;font-size:20px}.comparison-setup-card table{width:100%;border-collapse:collapse;font-size:12px}.comparison-setup-card th,.comparison-setup-card td{padding:11px 12px;border:1px solid var(--line);text-align:left;vertical-align:top}.comparison-setup-card th{background:var(--soft)}.comparison-setup-card .s-note{margin:16px 0 0;padding:12px 14px;border-left:3px solid var(--blue);background:#f3f5ff;color:#38466c;font-size:12px}.comparison-setup-card details{margin-top:12px;border:1px solid var(--line);border-radius:6px}.comparison-setup-card summary{cursor:pointer;padding:12px 14px;font-size:12px;font-weight:800}.comparison-setup-card pre{max-height:560px;overflow:auto;margin:0;padding:14px;white-space:pre-wrap;background:#f5f6f8;color:#222936;font:11px\/1.6 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}@media(max-width:680px){.comparison-setup-card .s-grid{grid-template-columns:1fr}.comparison-setup-card .s-head,.comparison-setup-card .s-body{padding:20px}}<\/style><aside class=\"comparison-setup-card\"><header class=\"s-head\"><p class=\"s-kicker\">C\u00f3mo se llev\u00f3 a cabo la prueba<\/p><h3>Las mismas tareas, reglas fijas, primeros resultados v\u00e1lidos<\/h3><\/header><div class=\"s-body\"><div class=\"s-grid\"><div class=\"s-stat\"><span>C\u00f3dice<\/span><strong>gpt-5.6-sol<\/strong><small>Medio T1\u2013T3 \u00b7 Alto T4<\/small><\/div><div class=\"s-stat\"><span>C\u00f3digo Claude<\/span><strong>claude-opus-5<\/strong><small>Se ha revelado la opci\u00f3n de reserva del subagente<\/small><\/div><\/div><table><tbody><tr><th>Calendario<\/th><td>Repositorio peque\u00f1o de Python, solo con bibliotecas est\u00e1ndar<\/td><\/tr><tr><th>Regla de ejecuci\u00f3n<\/th><td>Se conserva el primer resultado v\u00e1lido; no se permiten repeticiones de calidad<\/td><\/tr><tr><th>Seguridad<\/th><td>Copias recientes, tareas sin conexi\u00f3n, sin acceso a la producci\u00f3n, sin actualizaciones ni implementaciones<\/td><\/tr><tr><th>Puntuaci\u00f3n<\/th><td>R\u00fabrica fija de 100 puntos, adem\u00e1s de comprobaciones independientes p\u00fablicas y ocultas<\/td><\/tr><\/tbody><\/table><\/div><\/aside>\n\n\n\n<p class=\"wp-block-paragraph\">Codex ejecut\u00f3 procesos CLI aislados con JSONL sin procesar, conservando los campos de tokens emitidos por la CLI. La sesi\u00f3n OAuth de la CLI de Claude de nuestro compa\u00f1ero hab\u00eda caducado, por lo que Claude Code utiliz\u00f3 un coordinador con contextos de subagentes nuevos. Reconstruimos los parches de Claude en copias de auditor\u00eda limpias y volvimos a ejecutar las comprobaciones p\u00fablicas y ocultas. Esto gener\u00f3 pruebas pr\u00e1cticas cre\u00edbles, pero no se obtuvieron superficies de aislamiento ni de control de modelos id\u00e9nticas.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Tarea<\/th><th>C\u00f3dice<\/th><th>C\u00f3digo Claude<\/th><th>Interpretaci\u00f3n acotada<\/th><\/tr><\/thead><tbody><tr><td>T1: comprensi\u00f3n del repositorio<\/td><td>20\/20<\/td><td>20\/20<\/td><td>Empate: \u00abcompacto\u00bb frente a \u00abexhaustivo\u00bb<\/td><\/tr><tr><td>T2: funci\u00f3n de m\u00faltiples archivos<\/td><td>30\/30<\/td><td>30\/30<\/td><td>Conexi\u00f3n funcional; alcance diferente de la validaci\u00f3n y las pruebas<\/td><\/tr><tr><td>T3: Reparaci\u00f3n del DST<\/td><td>30\/30<\/td><td>30\/30<\/td><td>Ambas opciones fueron aprobadas: una cobertura m\u00e1s reducida frente a una cobertura m\u00e1s amplia de los bordes<\/td><\/tr><tr><td>T4: revisi\u00f3n y reparaci\u00f3n<\/td><td>18\/20<\/td><td>19\/20<\/td><td>El c\u00f3digo Claude mostr\u00f3 una mayor amplitud de revisi\u00f3n<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<style>.aggregate-verdict-card{--ink:#111318;--body:#414753;--muted:#707784;--line:#e4e7ec;--soft:#f6f7f9;--blue:#315efb;--violet:#7257e8;--green:#087a55;--greenSoft:#eaf8f2;--red:#a23131;--redSoft:#fff0f0;color:var(--ink);font-family:Inter,ui-sans-serif,-apple-system,BlinkMacSystemFont,\"Segoe UI\",sans-serif;line-height:1.5;border:1px solid var(--line);border-radius:8px;background:#fff;overflow:hidden;box-shadow:0 16px 42px rgba(24,32,56,.08)}.aggregate-verdict-card *{box-sizing:border-box}.aggregate-verdict-card .s-head{padding:24px 26px 20px;border-bottom:1px solid var(--line)}.aggregate-verdict-card .s-kicker{margin:0 0 6px;color:var(--muted);font:750 11px\/1.4 ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.08em;text-transform:uppercase}.aggregate-verdict-card h3{margin:0;font-size:22px;line-height:1.2;letter-spacing:-.025em}.aggregate-verdict-card .s-sub{margin:7px 0 0;color:var(--body);font-size:13px}.aggregate-verdict-card .s-body{padding:24px 26px}.aggregate-verdict-card .s-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:10px}.aggregate-verdict-card .s-stat{padding:15px;border:1px solid var(--line);border-radius:6px;background:var(--soft)}.aggregate-verdict-card .s-stat span{display:block;color:var(--muted);font-size:10px;font-weight:800;text-transform:uppercase;letter-spacing:.06em}.aggregate-verdict-card .s-stat strong{display:block;margin-top:5px;font-size:20px}.aggregate-verdict-card table{width:100%;border-collapse:collapse;font-size:12px}.aggregate-verdict-card th,.aggregate-verdict-card td{padding:11px 12px;border:1px solid var(--line);text-align:left;vertical-align:top}.aggregate-verdict-card th{background:var(--soft)}.aggregate-verdict-card .s-note{margin:16px 0 0;padding:12px 14px;border-left:3px solid var(--blue);background:#f3f5ff;color:#38466c;font-size:12px}.aggregate-verdict-card details{margin-top:12px;border:1px solid var(--line);border-radius:6px}.aggregate-verdict-card summary{cursor:pointer;padding:12px 14px;font-size:12px;font-weight:800}.aggregate-verdict-card pre{max-height:560px;overflow:auto;margin:0;padding:14px;white-space:pre-wrap;background:#f5f6f8;color:#222936;font:11px\/1.6 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}@media(max-width:680px){.aggregate-verdict-card .s-grid{grid-template-columns:1fr}.aggregate-verdict-card .s-head,.aggregate-verdict-card .s-body{padding:20px}}<\/style><article class=\"aggregate-verdict-card\"><header class=\"s-head\"><p class=\"s-kicker\">Prueba supervisada \u00b7 R\u00fabrica de \u00abFrozen\u00bb<\/p><h3>Codex 98\/100 frente a Claude C\u00f3digo 99\/100<\/h3><p class=\"s-sub\">La diferencia de un punto no es una se\u00f1al inequ\u00edvoca de victoria. Las diferencias que resultan \u00fatiles dependen de cada tarea concreta.<\/p><\/header><div class=\"s-body\"><div class=\"s-grid\"><div class=\"s-stat\"><span>C\u00f3dice<\/span><strong>98\/100<\/strong><\/div><div class=\"s-stat\"><span>C\u00f3digo Claude<\/span><strong>99\/100<\/strong><\/div><\/div><table><thead><tr><th>\u00c1mbito de decisi\u00f3n<\/th><th>Resultado observado<\/th><th>Lectura pr\u00e1ctica<\/th><\/tr><\/thead><tbody><tr><td>Conocimiento del repositorio<\/td><td>Empate \u00b7 20\/20 cada uno<\/td><td>Claude era m\u00e1s exhaustivo; Codex era m\u00e1s conciso.<\/td><\/tr><tr><td>Funci\u00f3n de m\u00faltiples archivos<\/td><td>Empate \u00b7 30\/30 cada uno<\/td><td>Ambos superaron las comprobaciones ocultas; Claude a\u00f1adi\u00f3 pruebas m\u00e1s exhaustivas.<\/td><\/tr><tr><td>Correcci\u00f3n de un error relacionado con el horario de verano<\/td><td>Empate \u00b7 30\/30 cada uno<\/td><td>Claude cubr\u00eda m\u00e1s bordes; Codex utiliz\u00f3 el parche m\u00e1s estrecho.<\/td><\/tr><tr><td>Revisi\u00f3n y reparaci\u00f3n<\/td><td>Claude 19\/20; Codex 18\/20<\/td><td>Claude detect\u00f3 m\u00e1s defectos reproducibles.<\/td><\/tr><tr><td>Velocidad observada<\/td><td>Mixto<\/td><td>Claude lider\u00f3 T1\/T2; Codex lider\u00f3 T3\/T4.<\/td><\/tr><\/tbody><\/table><p class=\"s-note\"><strong>Aviso:<\/strong> Las mismas instrucciones y el mismo entorno, pero con rutas de aislamiento diferentes. No generalices esta peque\u00f1a prueba a todos los repositorios, niveles de modelo o sesiones aut\u00f3nomas.<\/p><\/div><\/article>\n\n\n\n<p class=\"wp-block-paragraph\">La prueba es demasiado limitada para evaluar el rendimiento en repositorios de gran tama\u00f1o, en todos los lenguajes, en todos los niveles de modelos o en sesiones aut\u00f3nomas prolongadas. La diferencia total de un punto debe interpretarse como \u201cambos tuvieron \u00e9xito, con una diferencia en el alcance de la revisi\u00f3n\u201d, y no como una clasificaci\u00f3n universal.<\/p>\n\n\n\n<h2 id=\"user-experience\" class=\"wp-block-heading\">Lo que cuentan los usuarios reales\u2026 y hasta qu\u00e9 punto hay que fiarse de ello<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Los comentarios de la comunidad son valiosos cuando incluyen un proyecto, una tarea, un modelo, el contexto de la iniciativa y el plazo previsto. Son poco \u00fatiles cuando una publicaci\u00f3n solo se\u00f1ala que un producto \u201cparece m\u00e1s inteligente\u201d o \u201ces mucho m\u00e1s r\u00e1pido\u201d. Los distintos usuarios comparan diferentes repositorios, niveles de suscripci\u00f3n, indicaciones, extensiones y grados de supervisi\u00f3n.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">El ejemplo contextual de Reddit anterior sugiere una disyuntiva en cuanto a la interacci\u00f3n: un estilo r\u00e1pido y coloquial puede exigir m\u00e1s atenci\u00f3n, mientras que una ejecuci\u00f3n deliberada puede parecer m\u00e1s lenta, pero requiere menos correcciones. Nuestra prueba controlada solo coincide parcialmente con ese relato. En las ejecuciones v\u00e1lidas se observ\u00f3 una velocidad variable y ninguna intervenci\u00f3n humana, por lo que no puede validar la afirmaci\u00f3n sobre la \u00absupervisi\u00f3n\u00bb. Precisamente por eso, las pruebas de la comunidad y las pruebas controladas deben presentarse conjuntamente, sin fusionarlas.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">El comentario sobre el arn\u00e9s X plantea una segunda cuesti\u00f3n \u00fatil: el resultado de la codificaci\u00f3n pertenece al sistema en su conjunto, no solo a la etiqueta del modelo. Ninguna de las dos publicaciones debe considerarse como datos de una encuesta. \u00dasalas para identificar cuestiones para tu propio ensayo: n\u00famero de intervenciones, magnitud de la diferencia, calidad de la prueba y recuperaci\u00f3n tras una suposici\u00f3n err\u00f3nea.<\/p>\n\n\n\n<h2 id=\"globalgpt\" class=\"wp-block-heading\">Ampliaci\u00f3n de Codex y del c\u00f3digo Claude con GlobalGPT<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">GlobalGPT es un <a href=\"https:\/\/www.glbgpt.com\/hub\/best-all-in-one-ai-tools-and-platforms-11-options-compared\/\">espacio de trabajo multimodelo y multimodal<\/a>, no sustituye a los agentes nativos del repositorio. Su funci\u00f3n pr\u00e1ctica consiste en ampliar las capacidades de un host ya existente: utilizar otro modelo de agente disponible para obtener una segunda opini\u00f3n, revisar un plan, realizar una comprobaci\u00f3n de la documentaci\u00f3n o generar resultados especializados, mientras que Codex o Claude Code siguen siendo responsables del acceso al repositorio, los comandos de shell, las pruebas y las aprobaciones.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">GlobalGPT publica gu\u00edas oficiales de la interfaz de l\u00ednea de comandos (CLI) para <a href=\"https:\/\/www.glbgpt.com\/hub\/how-to-use-globalgpt-cli-in-codex\/\">C\u00f3dice<\/a> y <a href=\"https:\/\/www.glbgpt.com\/hub\/how-to-use-globalgpt-cli-in-claude-code\/\">C\u00f3digo Claude<\/a>, as\u00ed como Cursor. En nuestra prueba de integraci\u00f3n segura de T5, la CLI complet\u00f3 la misma tarea \u00abcongelada\u00bb en ambos entornos comparados. En Codex, tambi\u00e9n verificamos una llamada de solo lectura a la lista de modelos del MCP e instalamos, cargamos y utilizamos la skill GlobalGPT.<\/p>\n\n\n\n<style>.globalgpt-integration-card{--ink:#111318;--body:#414753;--muted:#707784;--line:#e4e7ec;--soft:#f6f7f9;--blue:#315efb;--violet:#7257e8;--green:#087a55;--greenSoft:#eaf8f2;--red:#a23131;--redSoft:#fff0f0;color:var(--ink);font-family:Inter,ui-sans-serif,-apple-system,BlinkMacSystemFont,\"Segoe UI\",sans-serif;line-height:1.5;border:1px solid var(--line);border-radius:8px;background:#fff;overflow:hidden;box-shadow:0 16px 42px rgba(24,32,56,.08)}.globalgpt-integration-card *{box-sizing:border-box}.globalgpt-integration-card .s-head{padding:24px 26px 20px;border-bottom:1px solid var(--line)}.globalgpt-integration-card .s-kicker{margin:0 0 6px;color:var(--muted);font:750 11px\/1.4 ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.08em;text-transform:uppercase}.globalgpt-integration-card h3{margin:0;font-size:22px;line-height:1.2;letter-spacing:-.025em}.globalgpt-integration-card .s-sub{margin:7px 0 0;color:var(--body);font-size:13px}.globalgpt-integration-card .s-body{padding:24px 26px}.globalgpt-integration-card .s-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:10px}.globalgpt-integration-card .s-stat{padding:15px;border:1px solid var(--line);border-radius:6px;background:var(--soft)}.globalgpt-integration-card .s-stat span{display:block;color:var(--muted);font-size:10px;font-weight:800;text-transform:uppercase;letter-spacing:.06em}.globalgpt-integration-card .s-stat strong{display:block;margin-top:5px;font-size:20px}.globalgpt-integration-card table{width:100%;border-collapse:collapse;font-size:12px}.globalgpt-integration-card th,.globalgpt-integration-card td{padding:11px 12px;border:1px solid var(--line);text-align:left;vertical-align:top}.globalgpt-integration-card th{background:var(--soft)}.globalgpt-integration-card .s-note{margin:16px 0 0;padding:12px 14px;border-left:3px solid var(--blue);background:#f3f5ff;color:#38466c;font-size:12px}.globalgpt-integration-card details{margin-top:12px;border:1px solid var(--line);border-radius:6px}.globalgpt-integration-card summary{cursor:pointer;padding:12px 14px;font-size:12px;font-weight:800}.globalgpt-integration-card pre{max-height:560px;overflow:auto;margin:0;padding:14px;white-space:pre-wrap;background:#f5f6f8;color:#222936;font:11px\/1.6 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}@media(max-width:680px){.globalgpt-integration-card .s-grid{grid-template-columns:1fr}.globalgpt-integration-card .s-head,.globalgpt-integration-card .s-body{padding:20px}}<\/style><article class=\"globalgpt-integration-card\"><header class=\"s-head\"><p class=\"s-kicker\">Integraci\u00f3n GlobalGPT \u00b7 Excluida de la puntuaci\u00f3n de codificaci\u00f3n<\/p><h3>CLI verificado en ambos flujos de trabajo; MCP y Skill verificados en Codex<\/h3><p class=\"s-sub\">Esto mide las v\u00edas de integraci\u00f3n, no si GlobalGPT sustituye a alguno de los agentes de codificaci\u00f3n nativos.<\/p><\/header><div class=\"s-body\"><table><thead><tr><th>Ruta<\/th><th>Entorno de Codex<\/th><th>Carrera de los compa\u00f1eros de Claude<\/th><\/tr><\/thead><tbody><tr><td>GlobalGPT CLI<\/td><td>Verificado con gpt-5.6-sol y gpt-5.6-luna<\/td><td>Verificado con las mismas tareas congeladas<\/td><\/tr><tr><td>MCP<\/td><td>Lista interactiva de modelos de solo lectura verificada<\/td><td>No conectado durante la carrera<\/td><\/tr><tr><td>Habilidad<\/td><td>Instalado, cargado y probado<\/td><td>Instalado, pero no se utiliza para llamadas en espera<\/td><\/tr><tr><td>MCP sin supervisi\u00f3n<\/td><td>Se ha observado una limitaci\u00f3n en la autorizaci\u00f3n<\/td><td>No se ha probado<\/td><\/tr><\/tbody><\/table><details><summary>Ver toda la documentaci\u00f3n sobre la integraci\u00f3n<\/summary><pre>Resumen de la prueba de integraci\u00f3n # GlobalGPT\n\n\u00c1mbito de aplicaci\u00f3n de # #\n\nLa medida T5 eval\u00faa la integraci\u00f3n de GlobalGPT y queda excluida de la puntuaci\u00f3n de codificaci\u00f3n nativa de Codex. No se utiliz\u00f3 Yukie.\n\n## Bloqueo y disponibilidad de los modelos\n\n- Modelo A: `gpt-5.6-sol`\n- Modelo B: `gpt-5.6-luna`\n- Ambos modelos aparecieron en la lista de modelos activos.\n- Ambas pruebas de disponibilidad ligeras devolvieron texto v\u00e1lido y analizable.\n- Los modelos se bloquearon antes de las llamadas formales de salida de T5A y T5B.\n\n## Resultados formales de la CLI\n\n| Tarea | Modelo | Estado | Duraci\u00f3n | Tokens de la indicaci\u00f3n | Tokens de finalizaci\u00f3n | Encabezados requeridos |\n|---|---|---|---:|---:|---:|---:|\n| T5A | gpt-5.6-sol | V\u00e1lido | 27 s | 2.116 | 1.207 | 6\/6 |\n| T5B | gpt-5.6-luna | V\u00e1lido | 14 s | 2.116 | 1.441 | 6\/6 |\n\nAmbas llamadas formales utilizaron la misma tarea congelada de planificaci\u00f3n de productos en ingl\u00e9s a trav\u00e9s de `glbgpt exec`, devolvieron resultados visibles \u00fanicamente en ingl\u00e9s y no expusieron ninguna credencial. No se produjo ninguna repetici\u00f3n de la prueba de calidad.\n\n## Resultado de MCP\n\n- `codex mcp list` mostr\u00f3 que `globalgpt` estaba habilitado.\n- Una sesi\u00f3n no interactiva de Codex detect\u00f3 e intent\u00f3 ejecutar `mcp__globalgpt__glbgpt_list_models`, pero la llamada se cancel\u00f3 porque no se dispon\u00eda de la aprobaci\u00f3n autom\u00e1tica de MCP. No se relaj\u00f3 ning\u00fan ajuste de seguridad.\n- La sesi\u00f3n interactiva activa de Codex invoc\u00f3 con \u00e9xito la misma herramienta MCP GlobalGPT de solo lectura y recibi\u00f3 nueve modelos de chat.\n- Resultado: se ha verificado el acceso interactivo a MCP; la ejecuci\u00f3n no interactiva y desatendida de MCP sigue sujeta a una limitaci\u00f3n de aprobaci\u00f3n.\n\nResultado de la habilidad ##\n\n- Las habilidades GlobalGPT y GlobalGPT Coding est\u00e1n instaladas en el directorio de habilidades de Codex a trav\u00e9s de enlaces al paquete de habilidades CLI incluido.\n- Se carg\u00f3 la habilidad GlobalGPT y se sigui\u00f3 para la comprobaci\u00f3n de la sesi\u00f3n configurada, la selecci\u00f3n de modelos en tiempo real, la disponibilidad, las opciones de seguridad de cr\u00e9dito y la gesti\u00f3n de fallos.\n- Resultado: instalada y puesta en pr\u00e1ctica en el flujo de trabajo activo de Codex.\n\n## Conclusi\u00f3n limitada\n\nEsta ejecuci\u00f3n verifica el funcionamiento de las llamadas CLI de GlobalGPT, una llamada interactiva de solo lectura a MCP de GlobalGPT desde Codex y una ruta de la habilidad GlobalGPT instalada y utilizada. No demuestra que todos los modelos, herramientas multimedia, hosts, cuentas o configuraciones MCP desatendidas funcionen. No prueba Yukie ni respalda la afirmaci\u00f3n de que GlobalGPT sustituya a Codex o a Claude Code.\n<\/pre><\/details><p class=\"s-note\">\u00c1mbito verificado: llamadas espec\u00edficas a la CLI, una lectura interactiva de MCP y una ruta de Skill instalada\/utilizada. Esto no garantiza todos los modelos, herramientas multimedia, hosts o configuraciones autom\u00e1ticas.<\/p><\/div><\/article>\n\n\n\n<p class=\"wp-block-paragraph\">El l\u00edmite es importante. La ejecuci\u00f3n de Claude realizada por el compa\u00f1ero verific\u00f3 la ruta CLI, no el MCP del lado de Claude. La Skill estaba instalada all\u00ed, pero no se utiliz\u00f3 para las llamadas congeladas. Un intento de Codex MCP sin supervisi\u00f3n segu\u00eda requiriendo aprobaci\u00f3n manual. La disponibilidad de los modelos y los cr\u00e9ditos tambi\u00e9n dependen del plan GlobalGPT actual, por lo que los desarrolladores deber\u00edan consultar la lista activa en lugar de dar por sentado que todos los modelos est\u00e1n incluidos.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">GlobalGPT tambi\u00e9n abarca im\u00e1genes, v\u00eddeos, audio y flujos de trabajo guiados para agentes. Las entradas de Yukie para diapositivas, documentos e im\u00e1genes constituyen una categor\u00eda diferente: ofrecen plantillas expl\u00edcitas y una gu\u00eda paso a paso en el navegador para tareas que no requieren c\u00f3digo. Esto puede resultar m\u00e1s sencillo que abrir una CLI de programaci\u00f3n para crear una presentaci\u00f3n o un documento estructurado, pero no sustituye a la lectura del repositorio, la ejecuci\u00f3n de pruebas ni la revisi\u00f3n del c\u00f3digo.<\/p>\n\n\n\n<style>.yukie-workflow-summary-card{--ink:#111318;--body:#414753;--muted:#707784;--line:#e4e7ec;--soft:#f6f7f9;--blue:#315efb;--violet:#7257e8;--green:#087a55;--greenSoft:#eaf8f2;--red:#a23131;--redSoft:#fff0f0;color:var(--ink);font-family:Inter,ui-sans-serif,-apple-system,BlinkMacSystemFont,\"Segoe UI\",sans-serif;line-height:1.5;border:1px solid var(--line);border-radius:8px;background:#fff;overflow:hidden;box-shadow:0 16px 42px rgba(24,32,56,.08)}.yukie-workflow-summary-card *{box-sizing:border-box}.yukie-workflow-summary-card .s-head{padding:24px 26px 20px;border-bottom:1px solid var(--line)}.yukie-workflow-summary-card .s-kicker{margin:0 0 6px;color:var(--muted);font:750 11px\/1.4 ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.08em;text-transform:uppercase}.yukie-workflow-summary-card h3{margin:0;font-size:22px;line-height:1.2;letter-spacing:-.025em}.yukie-workflow-summary-card .s-sub{margin:7px 0 0;color:var(--body);font-size:13px}.yukie-workflow-summary-card .s-body{padding:24px 26px}.yukie-workflow-summary-card .s-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:10px}.yukie-workflow-summary-card .s-stat{padding:15px;border:1px solid var(--line);border-radius:6px;background:var(--soft)}.yukie-workflow-summary-card .s-stat span{display:block;color:var(--muted);font-size:10px;font-weight:800;text-transform:uppercase;letter-spacing:.06em}.yukie-workflow-summary-card .s-stat strong{display:block;margin-top:5px;font-size:20px}.yukie-workflow-summary-card table{width:100%;border-collapse:collapse;font-size:12px}.yukie-workflow-summary-card th,.yukie-workflow-summary-card td{padding:11px 12px;border:1px solid var(--line);text-align:left;vertical-align:top}.yukie-workflow-summary-card th{background:var(--soft)}.yukie-workflow-summary-card .s-note{margin:16px 0 0;padding:12px 14px;border-left:3px solid var(--blue);background:#f3f5ff;color:#38466c;font-size:12px}.yukie-workflow-summary-card details{margin-top:12px;border:1px solid var(--line);border-radius:6px}.yukie-workflow-summary-card summary{cursor:pointer;padding:12px 14px;font-size:12px;font-weight:800}.yukie-workflow-summary-card pre{max-height:560px;overflow:auto;margin:0;padding:14px;white-space:pre-wrap;background:#f5f6f8;color:#222936;font:11px\/1.6 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}@media(max-width:680px){.yukie-workflow-summary-card .s-grid{grid-template-columns:1fr}.yukie-workflow-summary-card .s-head,.yukie-workflow-summary-card .s-body{padding:20px}}<\/style><article class=\"yukie-workflow-summary-card\"><header class=\"s-head\"><p class=\"s-kicker\">Categor\u00eda de flujo de trabajo diferente<\/p><h3>Pruebas de agente del navegador guiadas por Yukie<\/h3><p class=\"s-sub\">\u00datil para flujos de trabajo web espec\u00edficos; no se ha probado como sustituto de un agente de codificaci\u00f3n de repositorios.<\/p><\/header><div class=\"s-body\"><table><thead><tr><th>Flujo de trabajo<\/th><th>Criterios cumplidos<\/th><th>Primer resultado v\u00e1lido<\/th><\/tr><\/thead><tbody><tr><td>Diapositivas<\/td><td>5\/6<\/td><td>Se ha generado una presentaci\u00f3n de cinco diapositivas; no se han podido verificar las notas del ponente.<\/td><\/tr><tr><td>Documento<\/td><td>6\/6<\/td><td>Resumen de investigaci\u00f3n estructurado con historial de exportaciones y versiones.<\/td><\/tr><tr><td>Imagen + pie de foto<\/td><td>5\/6<\/td><td>Imagen llamativa de formato cuadrado; faltaba el pie de foto obligatorio.<\/td><\/tr><\/tbody><\/table><p class=\"s-note\">Conclusi\u00f3n fundamentada: puntos de entrada claros y flujos de trabajo multimodales guiados. Conclusiones sin fundamento: uso ilimitado, precio exacto o sustituci\u00f3n total del c\u00f3digo Codex\/Claude.<\/p><\/div><\/article>\n\n\n\n<h2 id=\"which-one\" class=\"wp-block-heading\">\u00bfQu\u00e9 lenguaje de programaci\u00f3n deber\u00eda elegir un desarrollador independiente?<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Elige Codex<\/strong> cuando la ejecuci\u00f3n compacta y acotada, la combinaci\u00f3n de superficies disponibles o los datos de ejecuci\u00f3n disponibles en tu configuraci\u00f3n se adapten a tu forma de trabajar.<\/li>\n\n\n\n<li><strong>Selecciona el c\u00f3digo Claude<\/strong> cuando lo que m\u00e1s importa es un bucle de terminal conversacional, las funciones de personalizaci\u00f3n que has comprobado o un comportamiento de revisi\u00f3n m\u00e1s amplio, como el observado en nuestro dispositivo de prueba.<\/li>\n\n\n\n<li><strong>Utiliza cualquiera de las dos opciones para un repositorio que no conozcas<\/strong> solo tras superar una prueba de arquitectura de solo lectura y de riesgos. Ambas herramientas llevaron a cabo esa tarea correctamente.<\/li>\n\n\n\n<li><strong>Util\u00edzalas ambas de forma selectiva<\/strong> cuando la revisi\u00f3n por parte de un segundo agente justifica el coste adicional de la suscripci\u00f3n y la coordinaci\u00f3n. Pide a la segunda herramienta que cuestione una diferencia o un plan, en lugar de repetir la tarea a ciegas.<\/li>\n\n\n\n<li><strong>A\u00f1adir GlobalGPT<\/strong> cuando el enrutamiento multimodelo o el trabajo multimodal es el eslab\u00f3n que falta. Mant\u00e9n las operaciones nativas del repositorio en el servidor de programaci\u00f3n.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Una prueba de siete d\u00edas ofrece m\u00e1s informaci\u00f3n que una tabla de clasificaci\u00f3n. Elige una funci\u00f3n real, pero que no sea de producci\u00f3n, un error y rev\u00edsalos. Congela la indicaci\u00f3n y el comando de \u00e9xito. Registra la primera diferencia v\u00e1lida, las pruebas superadas, el tiempo transcurrido, las intervenciones humanas, el alcance inesperado y c\u00f3mo el trabajo ha afectado a tu uso disponible. El mejor producto es aquel cuyos errores puedes detectar y cuyo flujo de trabajo puedes mantener.<\/p>\n\n\n\n<h2 id=\"faq\" class=\"wp-block-heading\">Preguntas frecuentes sobre el c\u00f3digo Codex frente al Claude<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">\u00bfEs Codex mejor que el c\u00f3digo Claude?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">No en todos los casos. Ambos completaron las cuatro tareas de nuestro programa de pruebas. Claude Code destac\u00f3 por la amplitud de su revisi\u00f3n, mientras que Codex result\u00f3 m\u00e1s conciso en algunos aspectos de la implementaci\u00f3n y la correcci\u00f3n de errores.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u00bfCu\u00e1l es la mejor opci\u00f3n para repositorios de gran tama\u00f1o?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Nuestra peque\u00f1a herramienta no puede responder a eso. Eval\u00faa ambas opciones en una tarea de arquitectura de solo lectura desde tu propio repositorio antes de permitir cambios.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u00bfQu\u00e9 agente de codificaci\u00f3n requiere menos supervisi\u00f3n?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Depende de la claridad de la tarea, la configuraci\u00f3n del modelo, las instrucciones del repositorio y el estilo de interacci\u00f3n deseado. Un usuario de Reddit mencion\u00f3 diferentes patrones de supervisi\u00f3n, pero esa experiencia individual no constituye una regla v\u00e1lida para todo el producto.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u00bfCu\u00e1l es m\u00e1s barato?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Los principales niveles de consumo se sit\u00faan en $20, $100 y $200 al mes, pero la capacidad incluida y las condiciones de l\u00edmite var\u00edan. Los cr\u00e9ditos opcionales y la facturaci\u00f3n por API se gestionan por separado.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u00bfComparten los planes Claude y Claude los mismos l\u00edmites de uso?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">S\u00ed. Claude y Claude Code utilizan una sesi\u00f3n compartida y l\u00edmites semanales en los planes Pro o Max asociados.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u00bfComparten los l\u00edmites las tareas locales y en la nube de Codex?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Los mensajes locales y los chats en la nube comparten un margen de cinco horas, y tambi\u00e9n pueden aplicarse l\u00edmites semanales.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u00bfPuede el GlobalGPT sustituir al Codex o al Claude Code?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">No. Puede ampliar cualquiera de los dos flujos de trabajo con modelos adicionales, la interfaz de l\u00ednea de comandos (CLI), MCP, Skills y herramientas multimodales, pero el acceso al repositorio y el comportamiento del agente de programaci\u00f3n siguen estando en el servidor anfitri\u00f3n.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u00bfPuedo utilizar el c\u00f3digo GlobalGPT de ambos productos?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">GlobalGPT ofrece tutoriales oficiales sobre la interfaz de l\u00ednea de comandos (CLI) para ambos. Hemos comprobado el uso de la CLI en ambos entornos y el uso de MCP junto con Skill en Codex, con una limitaci\u00f3n de autorizaci\u00f3n para el MCP sin supervisi\u00f3n.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Los precios, las condiciones de los planes, las integraciones y las fuentes de informaci\u00f3n se verificaron en julio de 2026. Los detalles del producto pueden sufrir cambios.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.glbgpt.com\/home?inviter=hub_content_home&amp;login=1\">Abierto GlobalGPT<\/a> si quieres incorporar una capa multimodelo y multimodal a tu flujo de trabajo de codificaci\u00f3n actual.<\/p>\n\n\n<\/article>","protected":false},"excerpt":{"rendered":"<p>Codex vs Claude Code is less about finding one universal winner and more about choosing the working style you can trust every day. Both products can inspect a repository, edit multiple files, run commands, execute tests, and explain a patch. The meaningful differences appear in how you delegate work, how often you steer the agent, [&hellip;]<\/p>","protected":false},"author":7,"featured_media":17361,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_seopress_robots_primary_cat":"","_seopress_titles_title":" Codex vs Claude Code: Features, Pricing & Hands-On Tests","_seopress_titles_desc":"A neutral Codex vs Claude Code comparison covering features, pricing, limits, real repository tests, user experience, and GlobalGPT integrations.","_seopress_robots_index":"","footnotes":""},"categories":[7],"tags":[],"class_list":["post-17342","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ai-chat"],"_links":{"self":[{"href":"https:\/\/wp.glbgpt.com\/es\/wp-json\/wp\/v2\/posts\/17342","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wp.glbgpt.com\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wp.glbgpt.com\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wp.glbgpt.com\/es\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/wp.glbgpt.com\/es\/wp-json\/wp\/v2\/comments?post=17342"}],"version-history":[{"count":2,"href":"https:\/\/wp.glbgpt.com\/es\/wp-json\/wp\/v2\/posts\/17342\/revisions"}],"predecessor-version":[{"id":17393,"href":"https:\/\/wp.glbgpt.com\/es\/wp-json\/wp\/v2\/posts\/17342\/revisions\/17393"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wp.glbgpt.com\/es\/wp-json\/wp\/v2\/media\/17361"}],"wp:attachment":[{"href":"https:\/\/wp.glbgpt.com\/es\/wp-json\/wp\/v2\/media?parent=17342"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wp.glbgpt.com\/es\/wp-json\/wp\/v2\/categories?post=17342"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wp.glbgpt.com\/es\/wp-json\/wp\/v2\/tags?post=17342"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}