Sprint 2 cerrado. Documentalmente.

This commit is contained in:
2026-05-20 11:36:05 -03:00
parent 1ff2724735
commit d2746f07d1
7 changed files with 222 additions and 113 deletions

View File

@@ -179,4 +179,23 @@ El cambio puede ser técnicamente correcto y producir un output mejor, pero **de
AP.8 NO es lo mismo que AP.3 (Racionalización de output anómalo). AP.3 es minimizar un problema observado. AP.8 es ejecutar trabajo no autorizado argumentando que es mejora.
AP.8 también difiere del Patrón C.6 mal aplicado. C.6 mal aplicado es clasificar mal el nivel de impacto. AP.8 es específicamente sobre adelantar deuda técnica planificada — un subconjunto que merece nombre propio.
AP.8 también difiere del Patrón C.6 mal aplicado. C.6 mal aplicado es clasificar mal el nivel de impacto. AP.8 es específicamente sobre adelantar deuda técnica planificada — un subconjunto que merece nombre propio.
---
## AP.9 — Resolución unilateral de restricciones contradictorias
**Comportamiento:** el agente enfrenta dos requisitos del prompt que colisionan (ej: "no tocar archivo X" + "build limpio sin errores TypeScript") y resuelve la contradicción actuando mínimamente en lugar de detenerse y reportar el conflicto.
**Daño concreto:** el agente produce código funcionalmente correcto en el área autorizada pero roto en el área restringida, y describe el resultado como "comportamiento esperado" minimizando la severidad real. Caso real (InQ ROI Sprint 2, Etapa 1): el prompt restringía `ActivityPanel.tsx` explícitamente (`❌`), pero también exigía build sin errores TypeScript. Cambiar `types.ts` inevitablemente generaba errores TypeScript en `ActivityPanel.tsx`. El agente lo corrigió mínimamente (clasificó como Nivel 2) en lugar de detenerse. Resultado: slider roto que requirió toda la Etapa 2 para corregir.
**Cómo detectarlo:** el reporte declara build limpio pero hay un archivo restringido en el diff. O el agente menciona "ajuste mínimo para compatibilidad de tipos" en un archivo que debería estar intacto.
**Cómo evitarlo:**
1. En el prompt: cuando haya restricción `❌` sobre un archivo, agregar explícitamente: *"Si este cambio produce errores TypeScript en archivos restringidos, DETENTE, no los corrijas, reportá el conflicto al director antes de continuar."*
2. Control preventivo: `git diff --name-only HEAD` al final — si aparece un archivo restringido, revertir y reportar.
3. No incluir simultáneamente restricciones absolutas (`❌ no tocar X`) y requisitos que inevitablemente afectan X (cambios de tipo transitivos). Si el conflicto es inevitable, resolverlo en el prompt antes de dárselo al agente.
**Relación con otros patrones:**
- Requiere el control preventivo de **C.7** (git diff como control de scope) para detección temprana.
- Distinto de **AP.5** (improvisación sin gobernanza): AP.9 ocurre dentro de un prompt estructurado, no por ausencia de método.

View File

@@ -0,0 +1,103 @@
# Case Study: InQ ROI — Sprint 2
**Proyecto:** InQ ROI — herramienta interna de consultoría de procesos BPMN
**Sprint:** 2 (mayo 2026)
**Duración:** 6 etapas
**Tests al cierre:** 548 (eran 541 al inicio)
**Deploy:** https://process-cost-platform.pages.dev
---
## Objetivo del sprint
Completar y elevar el modelo de recursos con costo por hora: migrar de `utilizationPercent` a `utilizationMinutes + units`, construir la experiencia "wow" encima, y hacer visible el desglose de recursos en el reporte web y en el PDF. Complementado con mejoras de UX para uso en talleres.
---
## Etapas y entregables
| Etapa | Contenido | Resultado |
|---|---|---|
| 1 | Migración modelo + Dexie v3 | `utilizationPercent → utilizationMinutes + units`, migración datos preservada, tests verdes |
| 2 | ActivityPanel "wow" | Inputs numéricos, cálculo en tiempo real, helper contextual, resumen de costos naranja |
| 3 | Reporte web: desglose + TECH_DEBT | Filas expandibles en tabla, payback label fix, badge 20px, CumulativeSavingsChart verificado |
| 4 | UX rápidos | Edición inline de nombre de proceso y cliente en header del workspace |
| 5 | PDF: tabla de recursos | Sección condicional en página 4/5, chips de tipo por recurso, fix truncamiento |
| 6 | Fixes + tests | Acentos corregidos, columna Esp. (USD), 7 tests nuevos (541→548) |
---
## Decisiones de método documentadas en este sprint
### AP.9 — Resolución unilateral de restricciones contradictorias
**Origen:** Etapa 1. El prompt tenía dos requisitos que colisionaban: `❌ no tocar ActivityPanel.tsx` y `build sin errores TypeScript`. Cambiar `ActivityResourceAssignment` en `types.ts` inevitablemente generaba errores TypeScript en `ActivityPanel.tsx`. El agente resolvió la contradicción actuando mínimamente en el archivo restringido en lugar de detenerse.
**Daño:** slider roto (stuck en 1 min), requirió toda la Etapa 2 para corregir.
**Aprendizaje:** cuando haya restricción `❌` absoluta sobre un archivo, el prompt debe incluir explícitamente la instrucción de detenerse ante conflictos, no resolverlos unilateralmente. Si el conflicto es inevitable por dependencias de tipos, resolverlo en el prompt antes de dárselo al agente.
**Documentado en:** `methodology/ANTI_PATTERNS.md` como AP.9.
---
### C.7 — Control preventivo de scope con `git diff`
**Origen:** Etapa 1 (como respuesta a AP.9). Los controles detectivos existentes (grep, build, tests) verifican que el código funciona pero no detectan archivos modificados fuera del scope.
**Solución:** incluir en todo prompt:
```bash
git diff --name-only HEAD
```
Con instrucción explícita: si aparece un archivo no autorizado → revertirlo y reportarlo como conflicto de scope, no incluirlo en el entregable.
**Resultado:** aplicado desde Etapa 2. Ningún conflicto de scope no declarado en Etapas 3-6.
**Documentado en:** `methodology/PATTERNS.md` como C.7.
---
## Hallazgos técnicos reutilizables
### rowSpan en jsPDF-autotable no está soportado en body cells
Intentado en `drawResourcesSection` para agrupar filas por actividad. No funciona en body rows. Solución: repetir el nombre de actividad en cada fila. El prompt lo anticipó correctamente con salida de emergencia — pero el tiempo de investigación fue real.
**Para futuros prompts de PDF con tablas agrupadas:** especificar desde el inicio que se use repetición en lugar de rowSpan, o usar `didParseCell` hook si se necesita estilización diferencial.
### `void resources` como placeholder de deuda técnica
En `exportScenarioPdf`, el parámetro `resources` estaba silenciado con `void resources` desde Sprint 1.5. Al agregar la tabla de recursos en Etapa 5, se eliminó ese placeholder. Patrón a evitar: silenciar parámetros con `void` en lugar de documentar la deuda explícitamente en `TECH_DEBT.md`.
### Modelo `utilizationMinutes + units` más natural para talleres
La pregunta "¿cuántos minutos dedica el analista a esta actividad?" es verificable en una entrevista con el cliente. La pregunta anterior "¿qué porcentaje de utilización tiene?" generaba confusión. El cambio de modelo mejoró la calidad de la elicitación de datos de costos en contexto real.
---
## Proporción web/PDF al cierre
| Componente | Etapas | % real | % comprometido |
|---|---|---|---|
| Web app | 1, 2, 3, 4 | ~65% | 60-70% |
| PDF | 5, 6 | ~30% | 15-25% |
| Tests/fixes | 6 | ~5% | 10-15% |
PDF ligeramente por encima del rango comprometido (tabla de recursos + fixes visuales). Justificado por el valor del entregable para pre-venta.
---
## Estado al cierre del sprint
**TECH_DEBT cerrados en Sprint 2:**
- CumulativeSavingsChart -inversión: verificado (ya estaba correcto)
- Payback label superpuesto: corregido
- Badge ⚡ tamaño: 20×20px, validado visualmente
- Truncamiento notas metodológicas: auditado, 2 líneas corregidas
**Pendientes para Sprint 3:**
- Modelo B (AS-IS/TO-BE con dos BPMNs)
- Catálogo global de recursos compartido
- Recursos en escenario automatizado
- Indicador de simulación desactualizada (alta prioridad, bajo esfuerzo)
- Posicionamiento: primera conversación sobre herramienta interna vs. venta externa

View File

@@ -450,6 +450,32 @@ Patrón típico de violación: el agente dice "el cálculo es numéricamente cor
---
### C.7 Control preventivo de scope — `git diff` antes de reportar
**Estado:** propuesto · **Deriva de:** Principios 3 y 4 · **Origen:** Sprint 2 Etapa 1
Incluir en todo prompt de Claude Code la siguiente verificación como paso obligatorio antes de reportar:
```bash
git diff --name-only HEAD
```
El resultado debe contener únicamente los archivos listados como autorizados en el prompt. Si aparece un archivo no autorizado:
1. Revertirlo: `git checkout HEAD -- <archivo>`
2. Listarlo bajo "Conflictos de scope" en el reporte
3. No incluirlo en el entregable de la etapa
**Por qué es preventivo, no detectivo:** los controles detectivos (grep de tipos, build, tests) verifican que el código resultante funciona, pero no detectan archivos modificados fuera del scope. Un agente puede tocar `ActivityPanel.tsx` y los tests seguir verdes si el cambio no rompe nada. El `git diff` captura el cambio antes de que se declare la etapa terminada.
**Indicador de aplicación correcta:** el reporte del agente incluye explícitamente la salida de `git diff --name-only HEAD` y todos los archivos listados son los autorizados.
**Indicador de violación:** el reporte no incluye la salida del git diff, o el diff contiene archivos no listados sin explicación.
**Relación con otros patrones:**
- Es respuesta directa al daño documentado en **AP.9** (resolución unilateral de restricciones contradictorias).
- Complementa **C.3** (auditoría adversarial) dándole al humano una checklist concreta de qué verificar.
---
## Cómo agregar un patrón nuevo
1. Identificar el patrón durante un proyecto real (no inventarlo en abstracto).