# Ciclo de vida de rondas y trabajo activo — Documento de requisitos de producto

## Estado del documento

- Estado: propuesto.
- Fecha: 2026-08-11.
- Responsable: mantenedores de Objective Guard.
- Evidencia gobernante: [E-005](../episodes/E-005-new-phase-without-declared-round.es.md), [E-024](../episodes/E-024-transition-blocked-by-accepted-debt.es.md), [E-028](../episodes/E-028-local-contract-blocked-rotation.es.md), [E-033](../episodes/E-033-test-suite-could-not-survive-round-rotation.es.md) y [E-035](../episodes/E-035-long-multi-agent-round-exposed-traceability-gaps.es.md).
- Requisitos relacionados: [contrato de producto](02-product-contract.es.md), [arquitectura técnica](04-technical-architecture.es.md) y [roadmap](06-roadmap-and-criteria.es.md).

## Resumen ejecutivo

Objective Guard actualmente trata un `round-end` exitoso como evidencia, no como una transición terminal del ciclo de vida. El archivo versionado `oguard.contract.json` continúa siendo el contrato activo, su preflight puede volver a quedar listo y un agente que recibe una petición nueva puede seguir atribuyendo trabajo a una ronda completada u obsoleta.

Este PRD separa la gobernanza durable de la ejecución activa. Los objetivos y KRs continúan siendo artefactos deliberados y versionados. El puntero de ronda activa, el estado de ciclo de vida, la autorización y el progreso del agente pasan a ser estado operacional local. Un cierre final exitoso vuelve terminal la ronda e invalida su preflight. El trabajo nuevo exige entonces una sucesora explícita, mientras que el trabajo bloqueado o interrumpido puede pausarse o ser sustituido sin reescribir el plan durable.

La primera entrega debe resolver el fallo observado sin exigir toda la arquitectura de subrondas: después de un cierre terminal, `task-flow` nunca debe devolver `ready` para la ronda cerrada.

## Planteamiento del problema

### Fallo observado

Un agente puede completar la verificación, ejecutar `round-end` y recibir `PASS`. Cuando llega una petición nueva, el repositorio todavía expone el mismo contrato versionado como activo. `task-flow` valida ese contrato y puede devolver `ready`, aunque el trabajo anterior ya haya cerrado y la nueva petición tenga una intención diferente.

Esto crea cuatro fallos:

1. El agente no puede distinguir “continuar la tarea anterior” de “empezar trabajo nuevo”.
2. Los cambios nuevos pueden atribuirse a una ronda y objetivo obsoletos.
3. Rotar el trabajo exige reescribir JSON versionado y frecuentemente un árbol Git limpio.
4. Una ronda bloqueada o interrumpida no tiene una transición liviana y explícita que preserve su evidencia sin mantenerla operacionalmente vigente.

### Evidencia

- [Hecho] E-005 registra una fase nueva implementada antes de declarar una ronda sucesora.
- [Hecho] E-024 registra deuda aceptada que bloqueó la rotación posterior hasta agregar una aceptación especial de baseline.
- [Hecho] E-028 registra al contrato local bloqueando la rotación necesaria para corregir su scope.
- [Hecho] E-033 registra una ronda sucia y fallida que no podía cerrar ni rotar sin una decisión del mantenedor.
- [Hecho] E-035 registra reescrituras repetidas del contrato y acoplamiento entre gobernanza durable e identidad de ronda.
- [Hecho] En el log local de dogfooding, `round-end` es repetible y mucho más frecuente que `round-transition`; un cierre exitoso no elimina el contrato activo.
- [Hecho] Después de que `R-KPI-SEMANTICS` devolviera `PASS`, un `task-flow` posterior para otra petición del usuario todavía devolvió `ready` para `R-KPI-SEMANTICS`.

Los conteos de eventos demuestran comportamiento de ciclo de vida, no prevalencia entre usuarios independientes. No deben interpretarse como una tasa de fallo general del producto.

## Principios de producto

1. **Una ronda es una unidad de ejecución; un objetivo es gobernanza durable.** Cerrar una no implica alcanzar el otro.
2. **Terminal significa terminal.** Una ronda cerrada, abandonada o sustituida no puede autorizar ediciones.
3. **La intención nueva debe ser explícita.** El guard puede identificar estado incompatible, pero no puede inventar silenciosamente el próximo objetivo, scope o tipo de tarea.
4. **La evidencia es append-only.** Pausar, abandonar, aceptar deuda o sustituir trabajo preserva los resultados previos.
5. **El estado operacional no es gobernanza durable.** La identidad del agente, el puntero activo, la autorización y el progreso no exigen una reescritura permanente del plan.
6. **El trabajo sucio nunca se adopta silenciosamente.** Una transición debe clasificar o aislar cambios preexistentes antes de atribuir ediciones nuevas.
7. **Un guard aprobado sólo prueba los checks declarados.** El cierre del ciclo de vida no certifica el logro del objetivo.

## Objetivos

- Hacer el cierre de ronda explícito, terminal e idempotente.
- Impedir autorización preflight bajo una ronda terminal.
- Indicar claramente al agente si debe continuar, cerrar, pausar, sustituir o iniciar trabajo nuevo.
- Separar el plan versionado de objetivo/KRs del puntero local de ronda activa.
- Preservar trabajo inconcluso y bloqueado sin obligarlo a continuar activo.
- Soportar transiciones limpias y herencia explícita de superficie sucia.
- Preservar evidencia reproducible append-only y hashes de contrato.
- Proporcionar migración desde el modelo actual de contrato activo versionado.

## No objetivos

- Inferir automáticamente el objetivo real del usuario desde lenguaje natural.
- Declarar automáticamente alcanzado un objetivo padre después de aprobar una ronda.
- Ocultar, hacer stash, commitear, descartar o rebasar trabajo sucio sin autoridad explícita.
- Reemplazar ramas Git, worktrees, CI, issue trackers u orquestadores.
- Implementar scheduling multiagente distribuido en la primera entrega.
- Hacer que una clasificación estadística o de LLM sea autoridad final de transición.

## Actores y trabajos a realizar

### Agente de programación

- Saber qué ronda, si existe, autoriza ediciones actualmente.
- Saber si una petición nueva puede continuar la ronda activa.
- Recibir un remedio preciso cuando el trabajo está cerrado, bloqueado u obsoleto.

### Desarrollador supervisor

- Cerrar, pausar, abandonar o sustituir trabajo sin perder evidencia.
- Decidir cómo se maneja el trabajo sucio antes de iniciar otra ronda.
- Distinguir finalización de ronda de logro del objetivo.

### Integrador de CI y harness

- Leer estados y códigos de razón estables.
- Invalidar preflight cuando cambia el ciclo de vida.
- No depender de prosa mutable ni de juicio de modelo.

### Evaluador

- Reconstruir objetivo → ronda → transición → evidencia sin tratar ejecuciones repetidas de `round-end` como tareas completadas diferentes.

## Modelo de dominio

### Ciclo de vida del objetivo

| Estado | Significado | ¿Puede contener rondas activas? | Terminal |
| --- | --- | --- | --- |
| `active` | El objetivo durable continúa siendo perseguido. | Sí | No |
| `achieved` | Un humano o workflow autorizado aceptó evidencia a nivel objetivo. | No | Sí |
| `abandoned` | El objetivo ya no será perseguido. | No | Sí |
| `superseded` | Una sucesora identificada reemplaza al objetivo. | No | Sí |

Las transiciones de objetivo son explícitas y nunca se infieren de `round-end`.

### Ciclo de vida de la ronda

| Estado | Significado | Autorización de edición |
| --- | --- | --- |
| `draft` | La intención es revisable y no concede autorización. | Denegada |
| `active` | Existen contrato congelado y baseline coincidente. | Elegible |
| `blocked` | El cierre o una política encontró un bloqueo sin resolver. | Según política; denegada por defecto para trabajo no relacionado |
| `parked` | El trabajo se pausó intencionalmente y puede retomarse. | Denegada |
| `closed` | El cierre requerido terminó correctamente. | Denegada permanentemente |
| `abandoned` | El trabajo terminó incompleto, con razón y actor. | Denegada permanentemente |
| `superseded` | Una ronda sucesora reemplazó este trabajo. | Denegada permanentemente |

`closed`, `abandoned` y `superseded` son terminales. Retomar trabajo pausado crea un evento append-only y devuelve la misma ronda a `active`; las rondas terminales no pueden retomarse.

### Puntero de trabajo activo

En la primera entrega, como máximo una ronda por worktree es la autoridad activa de edición. El puntero local contiene:

```json
{
  "schema_version": 1,
  "objective_id": "O-1",
  "round_id": "R-2",
  "round_contract_hash": "...",
  "state": "active",
  "activated_at": "...",
  "baseline_fingerprint": "...",
  "authorization_epoch": 3
}
```

El puntero es local y está ignorado por Git. El hash inmutable del contrato de ronda y cada transición permanecen en eventos append-only e historial.

## Modelo de almacenamiento

### Gobernanza durable versionada

- `oguard.plan.json`: jerarquía de objetivos, KRs y amendments aprobados.
- `oguard.contract.json`: política del repositorio y esquema contractual durante la migración; luego no debe actuar como único puntero de ronda activa.
- `oguard.kpis.json`: política de KPIs versionada.
- Evidencia exportada opcional bajo `evidence/` para revisión y CI.

### Estado operacional local

- `.oguard/active-round.json`: autoridad actual de edición o estado explícito sin ronda activa.
- `.oguard/rounds/<round-id>.json`: snapshot local inmutable de ronda.
- `.oguard/log/events.jsonl`: eventos append-only de ciclo de vida y verificación.
- `.oguard/session-baseline.json`: puntero de baseline activo durante la migración de compatibilidad.
- `.oguard/history/`: snapshots inmutables direccionados por hash.

El estado local puede reconstruirse desde artefactos durables y eventos cuando sea posible, pero la reconstrucción debe fallar visiblemente cuando la evidencia sea incompleta.

## Requisitos funcionales

### RF-01 — Cierre exitoso terminal

`oguard round-end --mode final` con resultado aprobado debe agregar `round-closed`, establecer la ronda activa como `closed`, incrementar el epoch de autorización e invalidar cada preflight de esa ronda.

Un cierre repetido devuelve `already-closed` con el evento original y no agrega otra observación de ronda completada ni vuelve a ejecutar checks salvo que se solicite explícitamente `--verify-again`. La reverificación nunca reactiva la ronda.

### RF-02 — Cumplimiento de ciclo de vida en preflight

`oguard task-flow` debe leer el estado de ciclo de vida antes de evaluar si el contrato está listo.

- Sin ronda activa: `action-required/no-active-round`.
- Ronda terminal cerrada: `action-required/round-closed`.
- Ronda pausada: `action-required/round-parked`.
- Ronda sustituida o abandonada: `action-required/round-terminal`.
- Ronda activa coincidente: continuar la validación contractual existente.
- Estado ilegible: `error/lifecycle-state-unavailable`, nunca `ready`.

El gate pre-edición debe vincular autorización al ID de ronda, hash de contrato, fingerprint de baseline y epoch de autorización.

### RF-03 — Creación explícita de sucesora

`oguard next-round` crea una sucesora desde objetivo, ronda, KR, tipo de tarea, scope, checks y obligaciones explícitos, o desde un borrador local de intención revisado.

Cuando la ronda previa es terminal y el árbol está limpio, la transición debe resolverse con un comando. Archiva el snapshot previo, crea la sucesora, la activa y registra el predecesor causal.

### RF-04 — Pausar y retomar

`oguard round park --reason --actor` pausa una ronda activa o bloqueada sin reescribir gobernanza durable. Registra el fingerprint del diff actual e invalida autorización.

`oguard round resume` exige el mismo snapshot de ronda y un fingerprint de diff compatible. Una diferencia devuelve `action-required/parked-surface-changed`.

### RF-05 — Abandonar y sustituir

`oguard round abandon --reason --actor` vuelve terminal una ronda sin afirmar éxito.

`oguard round supersede --reason --actor --successor <id>` registra una relación terminal con una sucesora. No puede borrar fallos, criterios desconocidos ni evidencia de superficie sucia.

### RF-06 — Decisión de transición con árbol sucio

Iniciar trabajo no relacionado con árbol sucio nunca debe devolver `ready` automáticamente. El guard devuelve la superficie sucia y sólo admite disposiciones explícitas:

- `continue-current`: mantener activa la ronda actual;
- `checkpoint`: el usuario commitea o crea otro checkpoint externo y reintenta;
- `park`: pausar la ronda, sin autorizar otra en el mismo worktree sucio;
- `new-worktree`: crear o seleccionar un worktree aislado fuera del core de Objective Guard;
- `carry-surface`: una sucesora autorizada declara archivos heredados y los preserva como superficie no atribuida o atribuida al predecesor.

`carry-surface` exige razón, actor, ID predecesor, fingerprint exacto y conjunto declarado de archivos. No convierte esos cambios en evidencia para el KR de la sucesora.

### RF-07 — Cierre de objetivo

`oguard objective close --outcome achieved|abandoned|superseded --reason --actor` está separado del cierre de ronda. `achieved` exige criterios de nivel objetivo o aceptación explícita del responsable. El comando rechaza el cierre mientras exista una ronda activa, salvo que se cierre, pause, abandone o sustituya en el mismo workflow auditado.

### RF-08 — Estado y guía para el agente

`oguard status --json` y `task-flow --json` exponen:

- ciclo de vida del objetivo;
- ronda activa o `null`;
- estado y timestamps de ronda;
- último cierre o bloqueo;
- clasificación del árbol sucio;
- vencimiento e invalidadores de autorización;
- acciones exactas disponibles.

La salida humana debe empezar con una de estas acciones: `continue`, `close`, `resume`, `start-successor` o `resolve-dirty-work`.

### RF-09 — Protocolo de incompatibilidad de intención

El harness puede enviar un hash de intención candidato derivado de campos estructurados explícitos. Objective Guard compara IDs y scope declarado; no decide equivalencia semántica desde prosa.

Si llega una petición después de un cierre terminal, el resultado siempre es `start-successor`. Si llega durante una ronda activa y la intención estructurada difiere, el resultado es `action-required/intent-mismatch`, con `continue-current`, `park` o `supersede` como acciones explícitas.

Un modelo opcional puede proponer una transición candidata, pero no activarla.

### RF-10 — Modelo de eventos

Agregar eventos append-only:

- `round-activated`;
- `round-blocked`;
- `round-parked`;
- `round-resumed`;
- `round-closed`;
- `round-abandoned`;
- `round-superseded`;
- `objective-closed`;
- `dirty-surface-carried`.

Cada evento incluye ID de objetivo, ID de ronda, estado previo, estado siguiente, hash de contrato, fingerprint de baseline, timestamp, actor, razón cuando corresponda e IDs predecesor/sucesor cuando apliquen.

### RF-11 — Compatibilidad hacia atrás

Los repositorios con sólo `oguard.contract.json` entran en modo de compatibilidad `legacy-active`.

Reglas de migración:

1. Si el hash del contrato actual tiene un último `round-end` final aprobado, inicializarlo como `closed` y dejar sin ronda activa.
2. Si su último cierre bloquea o está incompleto, inicializarlo como `blocked`.
3. Si no existe cierre y el baseline coincide, inicializarlo como `active`.
4. Si el estado es ambiguo, devolver `action-required/migration-ambiguous`; nunca elegir `active` silenciosamente.

La migración escribe estado local y un evento. No reescribe el plan versionado ni veredictos históricos.

## Superficie CLI

```text
oguard status [--json]
oguard task-flow [--intent <path>] [--json]
oguard round close [--mode final] [--json]
oguard round park --reason <text> --actor <id> [--json]
oguard round resume [--json]
oguard round abandon --reason <text> --actor <id> [--json]
oguard round supersede --successor <id> --reason <text> --actor <id> [--json]
oguard next-round ... [--from-intent] [--carry-surface <manifest>]
oguard objective status [--json]
oguard objective close --outcome <achieved|abandoned|superseded> --reason <text> --actor <id> [--json]
```

`oguard round-end` permanece como alias de compatibilidad de `oguard round close` durante una versión mayor y emite un campo de deprecación en JSON, sin texto ruidoso cuando lo llama automatización.

## Tabla de decisiones

| Ronda actual | Árbol | Trabajo entrante | Decisión |
| --- | --- | --- | --- |
| Ninguna | Limpio | Nuevo | Iniciar sucesora/ronda nueva |
| Cerrada | Limpio | Nuevo | Iniciar sucesora |
| Cerrada | Sucio | Nuevo | Resolver trabajo sucio; nunca reactivar ronda cerrada |
| Activa | Limpio | Misma intención estructurada | Continuar |
| Activa | Limpio | Intención diferente | Continuar, pausar o sustituir explícitamente |
| Activa | Sucio | Intención diferente | Continuar, checkpoint, pausar, worktree nuevo o herencia auditada |
| Pausada | Compatible | Retomar | Retomar explícitamente |
| Pausada | Cambiado | Retomar | Acción requerida; superficie incompatible |
| Bloqueada | Cualquiera | No relacionado | Resolver, pausar, abandonar o sustituir; nunca continuar silenciosamente |

## Requisitos de experiencia de usuario

### Ronda cerrada

```text
[objective-guard] Previous round R-42 is closed.
No round currently authorizes edits.
Next: review intent and open a successor round.
```

### Trabajo diferente durante una ronda activa

```text
[objective-guard] R-42 is still active, but the submitted task identity differs.
Choose: continue R-42, park it, or supersede it with a declared successor.
```

### Trabajo sucio

```text
[objective-guard] New work cannot inherit 4 modified files silently.
Choose a checkpoint, isolated worktree, or audited carry-surface transition.
```

Los diagnósticos deben nombrar raíz del repositorio, ronda actual, estado, invalidator exacto y remedio ejecutable. No deben instruir al agente a commitear, hacer stash, descartar o crear un worktree sin autoridad del usuario.

## Requisitos de seguridad e integridad

- Los archivos de ciclo de vida usan escritura atómica y locking equivalente al estado de findings.
- Las transiciones terminales son idempotentes y comparan el estado previo esperado.
- Los timestamps por sí solos no ordenan escritores concurrentes; los eventos incluyen secuencia monotónica o revisión de estado.
- Un agente obsoleto no puede reactivar ni cerrar una ronda después de que cambie su epoch de autorización.
- Actor y razón son obligatorios para transiciones semánticamente destructivas: abandonar, sustituir, cerrar objetivo, aceptar deuda y heredar superficie sucia.
- El borrado del estado local causa reconstrucción visible o ambigüedad, nunca `ready` implícito.

## Telemetría y métricas de éxito

### Métricas primarias

- `ready_after_terminal_round_rate = 0`.
- `edits_authorized_without_active_round = 0` en hooks estructurados.
- `duplicate_terminal_close_rate = 0`.
- Al menos 95% de las peticiones nuevas después de un cierre reciben `start-successor` en su primer preflight.
- Al menos 90% de las transiciones sucesoras limpias terminan con un comando.

### Métricas de fricción

- Mediana de comandos desde cierre terminal hasta activación de sucesora.
- Tasa de resultados `migration-ambiguous`, superficie sucia e incompatibilidad de intención.
- Cantidad y edad de rondas activas, bloqueadas y pausadas.
- Intervenciones humanas causadas por ambigüedad de ciclo de vida.

### Guardrails de integridad

- Ningún veredicto histórico es reescrito por migración o transición.
- Ningún archivo sucio heredado cuenta como evidencia del KR sucesor por defecto.
- Ninguna ronda terminal recibe un epoch de autorización nuevo.
- El logro de objetivo nunca se infiere de una ronda aprobada.

## Criterios de aceptación

### CA-01 — El cierre exitoso es terminal

Dada una ronda activa con checks finales aprobados, cuando cierra, entonces su estado es `closed`, se invalida autorización y un `task-flow` posterior devuelve `action-required/round-closed` o `no-active-round`.

### CA-02 — El cierre repetido es idempotente

Dada una ronda cerrada, cuando se ejecuta cerrar otra vez, entonces no se registra una segunda finalización terminal y se devuelve el resultado original como `already-closed`.

### CA-03 — El trabajo nuevo limpio tiene una ruta sucesora de un comando

Dada una ronda cerrada y árbol limpio, cuando se entrega intención sucesora revisada, entonces un comando archiva la predecesora, activa la sucesora y habilita elegibilidad para preflight.

### CA-04 — El trabajo sucio no se adopta silenciosamente

Dados archivos modificados de una predecesora, cuando se solicita trabajo no relacionado, entonces preflight se deniega hasta registrar una disposición explícita. La herencia preserva atribución predecesora y no prueba KRs sucesores.

### CA-05 — Pausar y retomar preservan identidad

Dada una ronda pausada con fingerprint de superficie sin cambios, cuando se retoma, entonces la misma ronda pasa a activa con un epoch de autorización nuevo y un evento append-only de reanudación.

### CA-06 — Las rondas terminales no pueden retomarse

Dado trabajo cerrado, abandonado o sustituido, cuando se solicita retomar, entonces el comando falla con razón de estado terminal y sin mutación.

### CA-07 — Los cierres de objetivo y ronda permanecen separados

Dada una ronda aprobada cerrada bajo un objetivo activo, el estado del objetivo continúa `active` hasta una transición explícita a nivel objetivo.

### CA-08 — La migración legacy es conservadora

Dado un contrato legacy con cierre final aprobado, la migración no crea ronda activa. Dado historial ambiguo, devuelve action-required en vez de elegir active.

### CA-09 — El agente concurrente obsoleto es rechazado

Dado un agente autorizado bajo epoch N, cuando otra transición incrementa el epoch, entonces las ediciones y cierres desde N se deniegan indicando estado actual y remedio.

### CA-10 — La evidencia permanece reconstruible

Dadas transiciones de cierre, pausa, reanudación y sustitución, la evidencia exportada reconstruye estados previo/siguiente, hashes, actores, razones y vínculos causales sin leer archivos mutables de estado actual.

## Plan de entrega

### P0 — Cierre terminal y prevención de ronda obsoleta

- Agregar estado de ciclo de vida y epoch de autorización.
- Hacer terminal e idempotente el cierre final aprobado.
- Hacer `task-flow` consciente del ciclo de vida.
- Invalidar preflight en cada transición.
- Agregar migración de estado legacy y regresión que reproduzca el caso `R-KPI-SEMANTICS`.

Gate: después de un cierre aprobado, ninguna edición estructurada puede autorizarse hasta activar una sucesora.

### P1 — Separación gobernanza durable / estado operacional

- Agregar puntero local de ronda activa y snapshots locales inmutables.
- Dejar de tratar el plan versionado como puntero operacional.
- Agregar `status`, activación sucesora limpia de un comando y alias de compatibilidad.
- Exportar evidencia de ciclo de vida sin rutas locales.

Gate: tres rondas consecutivas bajo un objetivo no exigen reescribir `oguard.plan.json` y siguen siendo completamente reconstruibles.

### P2 — Trabajo interrumpido y concurrente

- Agregar pausa/reanudación, abandono, sustitución, herencia sucia y epochs de autorización.
- Agregar cierre a nivel objetivo.
- Agregar subrondas heredadas e IDs genéricos de correlación externa.

Gate: dos agentes pueden operar en worktrees aislados bajo un objetivo; un agente obsoleto no puede editar después de una transición y la evidencia contradictoria permanece preservada.

## Riesgos y mitigaciones

| Riesgo | Mitigación |
| --- | --- |
| Se borra el estado local | Reconstrucción conservadora; la ambigüedad bloquea readiness. |
| Más comandos aumentan fricción | Empezar con una acción recomendada y soportar transiciones limpias de un comando. |
| La herencia sucia oculta atribución | Manifest exacto, vínculo predecesor y sin crédito KR por defecto. |
| Los agentes confunden cierre de ronda con logro del objetivo | Comandos, estados y evidencia de aceptación separados. |
| La división versionado/local debilita revisabilidad | Exportar evidencia inmutable de ciclo de vida y hashes para CI/PR. |
| Agentes concurrentes compiten | Revisión/epoch compare-and-swap y denegación de autorización obsoleta. |

## Decisiones abiertas

1. Si `oguard.contract.json` se convierte en política durable del repositorio o continúa como plantilla versionada para snapshots de ronda.
2. Si los snapshots locales de ronda empiezan como JSON o pasan directamente a SQLite.
3. Si `round-end` permanece indefinidamente como alias o se elimina después de una versión mayor.
4. Qué fuente de identidad provee `actor` en harnesses desatendidos.
5. Si trabajo pausado puede coexistir con una ronda activa en el mismo worktree; la recomendación inicial es no.

Ninguna de estas decisiones bloquea P0.
