Skip to content

Commit 5b2584a

Browse files
authored
fix(execute-phase,audit-pr,product-audit): scope-bleed guardrail (#88)
## What Closes a scope-export laziness hatch across three skills via one shared invariant — the **descope amendment**: - **`execute-phase`** — new **descope guard**: before creating any issue, it is classified `discovered work` (files freely) vs. `descope` (overlaps a SPEC acceptance criterion or phase task not fully delivered in this unit). A descope STOPs before the issue is created and requires a user-approved, dated `## Amendments` entry in the governing SPEC first — an issue may never be the first record of a descope. New Forbidden-list entry + turn- contract box. - **`audit-pr`** — new **Scope integrity (descope)** merge-readiness gate: lists issues born since branch divergence that reference the unit; each must have its criterion still met, or a matching `## Amendments` entry (dated, user-approved, linked) — else **BLOCKER**. Applies to feature and fix PRs alike; passes trivially when nothing was exported. New turn- contract box; closing `→ Next:` routes a blocker to the amendment-or- triage decision. - **`product-audit`** — new **scope-export recurrence** signal in the Workflow discipline dimension: ≥ 2 consecutive units exporting scope is a planning-quality finding, routed to the atomicity/split rules (#64). Plus: contract-restatement docs parity (`README.md`/`README.es.md`, `docs/workflow/SKILLS.md`/`SKILLS.es.md`), `bump-skill` registration (`execute-phase` 2.5.0, `audit-pr` 3.3.0, `product-audit` 2.1.0), and a GOLDEN_FIXTURE smoke test with the weakest fleet model (Claude Haiku 4.5). ## Why Finishing a feature sometimes generates a tail of new issues — and some of those are not genuinely new work discovered along the way, but acceptance scope quietly cut in the rush to declare the unit done, then re-imported later as issues. No guardrail caught this before: `execute-phase` could create issues freely, and `audit-pr` never cross-checked issues born during the unit against the SPEC's acceptance criteria. This closes that hole with the same discovered-vs-must-be-recorded shape `fold-findings` (#65) used for review findings. ## Scope Guardrail #4 of the original issue (`workflow-status` envelope exposure of `issues_born`/descope-amendment counts) is deliberately **out of scope** — issue #79 (already postponed) explicitly folds that field in and lists #66 as its own dependency, so it lands once, in its own unit. ## Evidence - `npx skills add . --list` → exit 0, every skill discovered, no YAML breakage (this repo's verification gate — no application build). - GOLDEN_FIXTURE smoke test (`docs/workflow/GOLDEN_FIXTURE.md`, run-log row appended EN+ES): two live runs with Claude Haiku 4.5 (weakest model in this session's fleet) against the descope guard — an issue overlapping an unmet acceptance criterion was correctly classified `descope` (STOP, amendment required before filing); an issue outside every criterion/task was correctly classified `discovered work` (filed immediately, no gate). - All bilingual doc pairs updated in the same commits per this repo's hard bilingual-sync rule. Closes #66
2 parents e57e210 + 5832e5b commit 5b2584a

13 files changed

Lines changed: 605 additions & 18 deletions

File tree

CHANGELOG.es.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ Cómo funciona el pinning realmente, **verificado** contra el CLI `skills`:
142142
#### `execute-phase`
143143
| Versión | Fecha | Tipo | Qué cambió |
144144
|---|---|---|---|
145+
| 2.5.1 | 2026-07-18 | parche | Fix #66: se aclaró el paso de retro-relleno de la enmienda en la guardia de descope — tras crear el issue de seguimiento y enlazarlo en el cuerpo del issue, editar explícitamente la fila `## Amendments` para sustituir el marcador `#<n>` por el número real del issue y commitear ese cambio; una fila que aún lea el marcador literal falla la comprobación simétrica de fila sin enlazar de `audit-pr`. |
146+
| 2.5.0 | 2026-07-17 | menor | Fix #66: nueva **guardia de descope** en la Política de issues — antes de crear cualquier issue, se clasifica como trabajo descubierto (se archiva libremente) o descope (solapa un criterio de aceptación/tarea de la SPEC no entregado del todo); un descope PARA antes de crear el issue, exigiendo primero una entrada `## Amendments` fechada y aprobada por el usuario (formato de fila canónico definido una sola vez aquí). Nueva entrada en la lista de prohibiciones y casilla del contrato de turno que exige que la guardia se aplicase a cada issue creado en el turno. |
145147
| 2.4.1 | 2026-07-17 | parche | Fix #81: el guardia de pre-vuelo de lint de fase (añadido en 2.4.0) gana una salvedad explícita para SPECs legacy — un SPEC sin sección `## Phases` omite el guardia por completo (sin lint, sin DETENCIÓN) y cae directamente al flujo legacy de paso único preexistente, restaurando la promesa de retrocompatibilidad de la propia fix #64. |
146148
| 2.4.0 | 2026-07-17 | menor | Fix #64: nuevo **guardia de pre-vuelo de lint de fase**, ejecutado tras las puertas de dependencias/estado propio y antes de cualquier edición — la fase objetivo debe pasar el lint canónico de 8 casillas (`docs/fix/_TEMPLATE/SPEC.md` `## Phases` "Phase-lint") o execute-phase se DETIENE con un bloque fijo que nombra las casillas fallidas y recomienda recortar de nuevo vía `/plan-feature`/`/plan-fix`; `--force` omite la DETENCIÓN, nunca la comprobación, registrado en `decisions.md`/`progress.md`. Integrado en el contrato de turno y las reglas duras. |
147149
| 2.3.0 | 2026-07-17 | menor | Fix #65: la sección del ciclo de fold ("Folding review / audit findings") ahora nombra la nueva skill independiente `/fold-findings` como la vía preferida e invocable por sí sola (clasificación congelada + lista de prohibiciones, turno/nivel propio); la checklist de esta sección se mantiene como fallback en contexto / de portabilidad. |
@@ -254,6 +256,7 @@ Cómo funciona el pinning realmente, **verificado** contra el CLI `skills`:
254256
#### `audit-pr`
255257
| Versión | Fecha | Tipo | Qué cambió |
256258
|---|---|---|---|
259+
| 3.3.0 | 2026-07-17 | menor | Nueva puerta de **integridad de alcance (descope)** en el contrato de merge-readiness: lista los issues nacidos desde que la rama divergió que hacen referencia a la unidad; cada uno debe tener su criterio de aceptación aún cumplido **o** una entrada `## Amendments` correspondiente, fechada y aprobada por el usuario (con la misma bitácora que escribe la guardia de descope de `execute-phase`) — si no, BLOQUEANTE; aplica tanto a PRs de feature como de fix, y pasa trivialmente cuando no se exportó nada. El contrato de turno gana la casilla correspondiente; el bloque de cierre `→ Next:` enruta un bloqueante de scope-bleed a la decisión de enmienda o triage. Parte de #66. |
257260
| 3.2.0 | 2026-07-17 | menor | Nueva puerta de **integridad de cierre** en el contrato de merge-readiness: grep sobre la SPEC de feature que gobierna en busca de un encabezado `Capability closure` (a cualquier nivel); un bloque presente con una fila en blanco o una fila no-`n/a` sin mapear es bloqueante, `n/a: <razón>` pasa, un bloque ausente produce un warning datado `design-debt: closure absent, SPEC predates the rule` (nunca bloqueante) — los PRs gobernados por fix son siempre n/a. El warning es a la vez el disparador de retrofit, enrutado a `/design-feature <slug>` en el bloque de cierre. El contrato de turno gana la casilla correspondiente. Parte de #78. |
258261
| 3.1.1 | 2026-07-13 | parche | Corrección de referencia cruzada en Guardrails: el comentario MERGE-READY ahora cita correctamente el paso de proceso 6 (seguía apuntando al paso 5 previo a la renumeración de 3.1.0). |
259262
| 3.1.0 | 2026-07-13 | menor | Nuevo paso de proceso 5 (solo en veredicto BLOCKED): cada blocker se persiste en el **mismo** ledger de fold fix-now `review-findings.md` que escribe `review-change` (D4 — un solo ledger para el ciclo de fold), severidad `high` (un blocker bloquea el merge por definición), deduplicado por `file:line`+axis, sin escritura en una unidad mergeada. Pasos de proceso restantes renumerados (6→8). Parte de la feature 17 (`finding-severity-routing`). |
@@ -275,6 +278,7 @@ Cómo funciona el pinning realmente, **verificado** contra el CLI `skills`:
275278
#### `product-audit`
276279
| Versión | Fecha | Tipo | Qué cambió |
277280
|---|---|---|---|
281+
| 2.1.0 | 2026-07-17 | menor | Nueva señal de **recurrencia de exportación de alcance** en la dimensión Disciplina de workflow: ≥ 2 unidades recientes consecutivas, cada una con una bitácora `## Amendments` de descope no vacía o un issue nacido clasificado como descope (puerta de scope-bleed de `audit-pr`), es un hallazgo de calidad de planificación ("features recortadas demasiado grandes para la capacidad real"), enrutado a las reglas de atomicidad/división (#64). El formato de salida gana un ejemplo trabajado bajo Top findings. Parte de #66. |
278282
| 2.0.0 | 2026-07-10 | mayor | **Cambio incompatible:** se elimina la sección `## Machine envelope` y su cláusula de emisión en el contrato de turno — el contrato del envelope se traslada a la capa de orquestación; `workflow-status` sigue siendo el único emisor en línea. Ver `docs/workflow/MIGRATION.md`. |
279283
| 1.8.0 | 2026-07-10 | menor | Nueva dimensión "Installed tooling" + paso de proceso: inventaría las skills instaladas y los servidores MCP conectados, los cruza contra los ejes de revisión aplicables y el roadmap, y añade un cuarto flujo de propuestas ("Tooling: register / re-design") — registrar una herramienta útil no registrada en `CLAUDE.md`, o enrutar un descubrimiento que cambia el alcance a `/design-feature`. Solo propone; nunca registra ni edita `CLAUDE.md`. Se añade `detail.proposed_tooling` al envelope máquina (aditivo). |
280284
| 1.7.0 | 2026-07-05 | menor | Envelope máquina: cada invocación termina ahora con un bloque JSON fijo (state, unit, phase, pr, findings, blockers, dependencies, next + pista de tier de modelo) para orquestación programática — esquema en la skill interna `orchestration-envelope`, protocolo en `docs/workflow/ORCHESTRATION.md`. Estado HALT para hallazgos críticos que paran todo. |
@@ -420,6 +424,32 @@ Cómo funciona el pinning realmente, **verificado** contra el CLI `skills`:
420424

421425
## Registro cronológico (más reciente primero)
422426

427+
- **2026-07-18 — pliegue de revisión del scope-bleed-guardrail (fix 66).**
428+
Bump PARCHE para `execute-phase` (2.5.1): se aclaró el paso de retro-
429+
relleno de la enmienda en la guardia de descope — una vez que el issue de
430+
seguimiento existe y está enlazado, la fila `## Amendments` sustituye
431+
explícitamente el marcador `#<n>` por el número real del issue y ese
432+
cambio se commitea, de modo que nunca falla la comprobación simétrica de
433+
fila sin enlazar de `audit-pr`. Encontrado y corregido durante
434+
`review-change` en el PR #88.
435+
436+
- **2026-07-17 — scope-bleed-guardrail (fix 66).** Bump MENOR para
437+
`execute-phase` (2.5.0): nueva guardia de descope — antes de crear cualquier
438+
issue, se clasifica como trabajo descubierto (se archiva libremente) o
439+
descope (solapa un criterio de aceptación/tarea de la SPEC incumplido); un
440+
descope PARA antes de crear el issue, exigiendo primero una entrada
441+
`## Amendments` fechada y aprobada por el usuario (formato de fila canónico
442+
definido una sola vez aquí). Bump MENOR para `audit-pr` (3.3.0): nueva
443+
puerta de integridad de alcance (descope) en el contrato de merge-readiness
444+
— los issues nacidos desde que la rama divergió que hacen referencia a la
445+
unidad deben tener su criterio aún cumplido o una entrada `## Amendments`
446+
correspondiente, si no BLOQUEANTE; PRs de feature y de fix por igual. Bump
447+
MENOR para `product-audit` (2.1.0): nueva señal de recurrencia de
448+
exportación de alcance — ≥ 2 unidades consecutivas exportando alcance es un
449+
hallazgo de calidad de planificación enrutado a las reglas de
450+
atomicidad/división (#64). El guardarraíl #4 (exposición en el envelope de
451+
`workflow-status`) se pospone a #79.
452+
423453
- **2026-07-17 — audit-pr-closure-integrity (fix 78).** Bump MENOR para
424454
`audit-pr` (3.2.0): nueva puerta de integridad de cierre en el contrato de
425455
merge-readiness — un chequeo puramente mecánico (grep en busca de un

CHANGELOG.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ How pinning actually works, verified against the `skills` CLI:
141141
#### `execute-phase`
142142
| Version | Date | Type | What changed |
143143
|---|---|---|---|
144+
| 2.5.1 | 2026-07-18 | patch | Fix #66: clarified the descope guard's amendment-backfill step — after creating the follow-up issue and linking it in the issue body, explicitly edit the `## Amendments` row to replace the `#<n>` placeholder with the real issue number and commit that edit; a row still reading the literal placeholder fails `audit-pr`'s symmetric unlinked-row check. |
145+
| 2.5.0 | 2026-07-17 | minor | Fix #66: new **descope guard** in the Issue policy — before creating any issue, classify it discovered-work (file freely) vs. descope (overlaps a SPEC acceptance criterion/phase task not fully delivered); a descope STOPs before the issue is created, requiring a user-approved, dated `## Amendments` entry first (canonical row format defined once here). New Forbidden-list entry and turn-contract box asserting the guard ran on every issue created in the turn. |
144146
| 2.4.1 | 2026-07-17 | patch | Fix #81: the Phase-lint pre-flight guard (added in 2.4.0) gains an explicit legacy-SPEC carve-out — a SPEC with no `## Phases` section skips the guard entirely (no lint, no STOP) and falls through to the pre-existing legacy single-pass flow, restoring fix #64's own backward-compatibility promise. |
145147
| 2.4.0 | 2026-07-17 | minor | Fix #64: new **phase-lint pre-flight guard**, run after the dependency/own-status gates and before any edit — the target phase must pass the canonical 8-box phase-lint (`docs/fix/_TEMPLATE/SPEC.md` `## Phases` "Phase-lint") or execute-phase STOPs with a fixed block naming the failed boxes and recommending re-cut via `/plan-feature`/`/plan-fix`; `--force` skips the STOP, never the check, logged in `decisions.md`/`progress.md`. Wired into the Turn contract and Hard rules. |
146148
| 2.3.0 | 2026-07-17 | minor | Fix #65: the fold-cycle section ("Folding review / audit findings") now names the new standalone `/fold-findings` skill as the preferred, independently-invocable path (frozen classification + forbidden list, own turn/tier); the section's own checklist is retained as the in-context / portability fallback. |
@@ -253,6 +255,7 @@ How pinning actually works, verified against the `skills` CLI:
253255
#### `audit-pr`
254256
| Version | Date | Type | What changed |
255257
|---|---|---|---|
258+
| 3.3.0 | 2026-07-17 | minor | New **scope integrity (descope)** gate in the merge-readiness contract: lists issues born since branch divergence that reference the unit; each must have its acceptance criterion still met **or** a matching, user-approved, dated `## Amendments` entry (keyed off the same log `execute-phase`'s descope guard writes) — else BLOCKER; applies to feature and fix PRs alike, passes trivially when nothing was exported. Turn contract gained a matching box; closing `→ Next:` routes a scope-bleed blocker to the amendment-or-triage decision. Part of #66. |
256259
| 3.2.0 | 2026-07-17 | minor | New **closure integrity** gate in the merge-readiness contract: grep the governing feature SPEC for a `Capability closure` heading (any level); a present block with a blank row or an unmapped non-`n/a` row is a blocker, `n/a: <reason>` passes, absent block yields a dated `design-debt: closure absent, SPEC predates the rule` warning (never a blocker) — fix-governed PRs are always n/a. The warning doubles as the retrofit trigger, routed to `/design-feature <slug>` in the closing block. Turn contract gained a matching box. Part of #78. |
257260
| 3.1.1 | 2026-07-13 | patch | Guardrails cross-reference fix: the MERGE-READY comment now correctly cites Process step 6 (was still pointing at the pre-3.1.0 step 5 after the fold-ledger step renumbering). |
258261
| 3.1.0 | 2026-07-13 | minor | New process step 5 (BLOCKED verdict only): every blocker persists to the **same** fix-now fold ledger `review-findings.md` that `review-change` writes (D4 — one ledger for the fold cycle), severity `high` (a blocker gates the merge by definition), deduped by `file:line`+axis, no write on a merged unit. Remaining process steps renumbered (6→8). Part of feature 17 (`finding-severity-routing`). |
@@ -274,6 +277,7 @@ How pinning actually works, verified against the `skills` CLI:
274277
#### `product-audit`
275278
| Version | Date | Type | What changed |
276279
|---|---|---|---|
280+
| 2.1.0 | 2026-07-17 | minor | New **scope-export recurrence** signal in the Workflow discipline dimension: ≥ 2 consecutive recent units each with a non-empty `## Amendments` descope log or a descope-classified born issue (`audit-pr`'s scope-bleed gate) is a planning-quality finding ("features cut too big for real capacity"), routed to the atomicity/split rules (#64). Output format gained a worked example under Top findings. Part of #66. |
277281
| 2.0.0 | 2026-07-10 | major | **Breaking:** dropped the `## Machine envelope` section and its turn-contract emission clause — the envelope contract moved to the orchestration layer; `workflow-status` remains the sole inline emitter. See `docs/workflow/MIGRATION.md`. |
278282
| 1.8.0 | 2026-07-10 | minor | New "Installed tooling" dimension + process step: inventories installed skills and connected MCP servers, cross-references them against the applicable review axes and the roadmap, and adds a fourth proposal stream ("Tooling: register / re-design") — register a useful unregistered tool in `CLAUDE.md`, or route a scope-affecting discovery to `/design-feature`. Proposes only; never registers or edits `CLAUDE.md`. `detail.proposed_tooling` added to the machine envelope (additive). |
279283
| 1.7.0 | 2026-07-05 | minor | Machine envelope: every invocation now ends with a fixed JSON block (state, unit, phase, pr, findings, blockers, dependencies, next + model-tier hint) for programmatic orchestration — schema in the internal `orchestration-envelope` skill, protocol in `docs/workflow/ORCHESTRATION.md`. HALT state for critical, stop-the-world findings. |
@@ -419,6 +423,28 @@ How pinning actually works, verified against the `skills` CLI:
419423

420424
## Release log (chronological, newest first)
421425

426+
- **2026-07-18 — scope-bleed-guardrail review fold (fix 66).** PATCH bump for
427+
`execute-phase` (2.5.1): clarified the descope guard's amendment-backfill
428+
step — after the follow-up issue exists and is linked, the `## Amendments`
429+
row's `#<n>` placeholder is explicitly replaced with the real issue number
430+
and the edit committed, so it never fails `audit-pr`'s symmetric unlinked-
431+
row check. Found and fixed during `review-change` on PR #88.
432+
433+
- **2026-07-17 — scope-bleed-guardrail (fix 66).** MINOR bump for
434+
`execute-phase` (2.5.0): new descope guard — before creating any issue,
435+
classify it discovered-work (file freely) or descope (overlaps an unmet
436+
SPEC acceptance criterion/phase task); a descope STOPs before the issue is
437+
created, requiring a user-approved, dated `## Amendments` entry first
438+
(canonical row format defined once here). MINOR bump for `audit-pr`
439+
(3.3.0): new scope integrity (descope) gate in the merge-readiness
440+
contract — issues born since branch divergence that reference the unit
441+
must have their criterion still met or a matching `## Amendments` entry,
442+
else BLOCKER; feature and fix PRs alike. MINOR bump for `product-audit`
443+
(2.1.0): new scope-export recurrence signal — ≥ 2 consecutive units
444+
exporting scope is a planning-quality finding routed to the atomicity/split
445+
rules (#64). Guardrail #4 (`workflow-status` envelope exposure) deferred to
446+
#79.
447+
422448
- **2026-07-17 — audit-pr-closure-integrity (fix 78).** MINOR bump for
423449
`audit-pr` (3.2.0): new closure-integrity gate in the merge-readiness
424450
contract — a purely mechanical check (grep for a `Capability closure`

0 commit comments

Comments
 (0)