Cambios Paralelos y Conflictos
Cambios Paralelos y Conflictos
Escenario real: dos features al mismo tiempo
Hasta ahora hemos trabajado con un cambio a la vez. En la practica, es comun necesitar avanzar en multiples features simultaneamente. Para nuestro Kanban, queremos agregar dos cosas:
- Autenticacion: Login de usuarios para que cada quien tenga su tablero
- Filtros: Filtrar tarjetas por etiqueta, fecha o asignado
Ambas features son independientes, pero tocan partes del sistema que podrian solaparse. Veamos como OpenSpec maneja esto.
Creando cambios simultaneos
Creamos ambos cambios uno despues del otro:
/opsx:propose add-auth
/opsx:propose add-filters
Cada /opsx:propose genera su propia carpeta aislada dentro de openspec/changes/ con todos los artefactos:
openspec/changes/
add-auth/
proposal.md
design.md
tasks.md
delta-specs/
add-filters/
proposal.md
design.md
tasks.md
delta-specs/
Esta separacion por carpetas es intencional. Cada cambio tiene su propio conjunto de artefactos, su propia propuesta y sus propias delta specs. No se mezclan.
Con perfil Expanded puedes usar
/opsx:newpara crear los scaffolds primero y luego/opsx:ffpara generar los artefactos de cada cambio por separado, lo que da mas control sobre el proceso.
Ver todos los cambios activos
Para saber que cambios estan en curso, usa el CLI:
openspec status
Esto muestra el estado de cada cambio activo:
| Cambio | Estado | Artefactos |
|---|---|---|
| add-auth | proposed | 4/4 completos |
| add-filters | proposed | 4/4 completos |
El estado puede ser: proposed, specified, applied o verified. Cada cambio avanza por las fases independientemente.
Cada cambio conoce el contexto existente
Al generar los artefactos de add-auth, la IA lee los specs existentes via openspec instructions y sabe que el modelo de datos ya tiene tarjetas, columnas y drag and drop. La propuesta de autenticacion se construye sobre esa base.
Lo mismo para add-filters: la IA conoce toda la estructura actual y propone filtros que se integran con lo existente.
Delta specs que tocan los mismos dominios
Aqui es donde las cosas se ponen interesantes. Ambos cambios podrian generar delta specs que tocan el mismo dominio. Por ejemplo:
Delta spec de add-auth (MODIFIED):
# MODIFIED: kanban-board.spec.md
Scenario: Tablero asociado a usuario autenticado
Given un usuario autenticado con id "user-1"
When solicita su tablero
Then recibe solo las columnas y tarjetas de "user-1"
Delta spec de add-filters (MODIFIED):
# MODIFIED: kanban-board.spec.md
Scenario: Filtrar tarjetas por etiqueta
Given un tablero con tarjetas etiquetadas
When el usuario aplica filtro por etiqueta "urgente"
Then solo se muestran las tarjetas con etiqueta "urgente"
Ambas delta specs modifican kanban-board.spec.md. Mientras los cambios estan en sus carpetas separadas, no hay conflicto. El conflicto potencial aparece al archivar.
Implementar y archivar independientemente
Cada cambio se aplica por separado:
/opsx:apply add-auth
/opsx:archive add-auth
/opsx:apply add-filters
/opsx:archive add-filters
Con perfil Expanded puedes usar
/opsx:verifyantes de archivar para validacion formal, y/opsx:bulk-archivepara archivar todos los cambios verificados en lote.
El orden importa si hay dependencias funcionales. En nuestro caso, los filtros no dependen de la autenticacion, asi que el orden no afecta. Pero si add-filters necesitara saber quien es el usuario para filtrar “mis tarjetas”, seria mejor aplicar add-auth primero.
Una buena practica es preguntarte: si aplico A antes que B, el resultado seria diferente que al reves? Si la respuesta es si, hay una dependencia implicita.
Como OpenSpec resuelve conflictos de specs
Al archivar multiples cambios que modifican el mismo spec, OpenSpec ejecuta un proceso de fusion de specs:
Caso 1: Sin conflicto real
Si ambos cambios agregan escenarios nuevos al mismo archivo sin contradecirse, la fusion es directa. Los escenarios de autenticacion y los de filtrado se agregan al spec existente sin problemas.
Resultado en kanban-board.spec.md:
Feature: Tablero Kanban
# Escenarios originales (modelo de datos)
# Escenarios de reordenamiento (drag and drop)
# Escenarios de autenticacion (add-auth)
# Escenarios de filtrado (add-filters)
Caso 2: Conflicto de specs
Si dos cambios modifican el mismo escenario de forma contradictoria, OpenSpec lo detecta y lo senala. Por ejemplo:
add-authdice: “el endpoint GET /api/boards requiere token”add-filtersdice: “el endpoint GET /api/boards acepta query paramfilter”
Ambos modifican el mismo endpoint. OpenSpec genera un reporte de conflicto indicando que specs se contradicen y pide intervencion humana para resolver.
La resolucion tipicamente implica:
- Revisar ambas delta specs
- Crear una version unificada que satisfaga ambos requisitos
- Re-verificar que la implementacion cumple la spec unificada
Caso 3: Conflicto de implementacion
Los specs no se contradicen pero el codigo generado si (dos cambios modifican la misma funcion de formas incompatibles). Esto es analogo a un merge conflict en Git, pero OpenSpec lo detecta a nivel de specs antes de que llegue al codigo.
Estrategias para minimizar conflictos
Separar por dominio
Si dos cambios tocan dominios diferentes, los conflictos son raros:
| Cambio | Dominio principal |
|---|---|
| add-auth | Autenticacion, sesiones, middleware |
| add-filters | UI del tablero, queries de busqueda |
Comunicacion explicita
Al crear la propuesta con /opsx:propose, incluye en la descripcion que otros cambios estan en curso:
/opsx:propose add-filters
Agregar filtrado de tarjetas. NOTA: el cambio add-auth esta en
paralelo y puede afectar los endpoints de la API.
Esto le da a la IA contexto adicional para generar specs que eviten colisiones.
Priorizar cambios fundamentales
Si un cambio afecta la base del sistema (como autenticacion), archivalo primero. Los cambios que construyen sobre esa base (como filtros por usuario) se benefician de tener los specs actualizados.
Cambios pequenos y frecuentes
Cuanto mas grande es un cambio, mas probable es que colisione con otros. Prefiere muchos cambios pequenos a pocos cambios grandes.
Ventaja sobre branches de Git
Podrias pensar: “esto es lo mismo que Git branches”. No lo es, y la diferencia es importante.
| Aspecto | Git branches | OpenSpec changes |
|---|---|---|
| Fuente de verdad | Codigo | Especificaciones |
| Conflictos | A nivel de lineas de codigo | A nivel de requisitos |
| Deteccion | Al hacer merge | Al archivar specs |
| Resolucion | Resolver linea por linea | Resolver requisito por requisito |
| Contexto | Diff del codigo | Delta specs con intencion |
En Git, un conflicto te muestra dos versiones de la misma linea de codigo. Tienes que adivinar la intencion de cada cambio. En OpenSpec, el conflicto te muestra dos especificaciones que se contradicen. La intencion esta explicita en los escenarios Gherkin.
Ademas, Git no te dice si dos cambios son semanticamente incompatibles cuando tocan archivos diferentes. OpenSpec si, porque los specs describen comportamiento, no implementacion.
Resumen
- Multiples cambios se crean con
/opsx:proposey viven en carpetas aisladas - Cada cambio avanza por las fases independientemente
openspec statusmuestra todos los cambios activos y su estado/opsx:archivecierra cada cambio; con Expanded,/opsx:bulk-archivearchiva en lote- Los conflictos se detectan a nivel de specs, no de codigo
- Separar dominios y priorizar cambios fundamentales minimiza conflictos
- Los specs capturan intencion, a diferencia de los diffs de Git
Capitulo 8: Iteracion - Drag and Drop | Capitulo 10: Mejores Practicas