Skip to content
Back to skills

Feedback

ASecurity

Capture developer testing feedback as structured evidence and GitHub issues. Use when the user says "report feedback", "found a bug", "this doesn't work", "feedback on feature", "AC-XX is wrong", or reports an issue found during manual testing. Links feedback to acceptance criteria and blocks merge if unresolved.

  • 16 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added June 1, 2026
developmentbashvuenodetestinggitapibackend

Works with

  • cli
  • api
  • mcp

Security analysis

A100/100

Scanned June 1, 2026

npx -y skills add EmbedBuild/specbox-engine --skill feedback --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Feedback?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Feedback
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/embedbuild-feedback/badge)](https://www.skillsdirectory.com/skills/embedbuild-feedback)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: developer-feedback
description: >
  Capture developer testing feedback as structured evidence and GitHub issues.
  Use when the user says "report feedback", "found a bug", "this doesn't work",
  "feedback on feature", "AC-XX is wrong", or reports an issue found during
  manual testing. Links feedback to acceptance criteria and blocks merge if unresolved.
context: direct
allowed-tools: Read, Grep, Glob, Bash(*), Write, Edit, mcp__github__create_issue, mcp__SpecBox-MCP__update_uc, mcp__SpecBox-MCP__mark_ac, mcp__SpecBox-MCP__move_uc
---

# /feedback (Global)

Captura feedback de testing manual del desarrollador, genera evidencia local y crea GitHub issue vinculado a acceptance criteria.

## Uso

```
/feedback [feature] [--ac AC-XX] [--severity critical|major|minor]
```

**Modos de invocacion:**
- `/feedback invoice-detail` → Feedback para feature "invoice-detail"
- `/feedback` → Sin argumento: auto-detecta feature desde la rama actual
- `/feedback invoice-detail --ac AC-03 --severity critical` → Con metadata inline
- `/feedback resolve FB-NNN` → Marcar feedback como resuelto
- `/feedback list [feature]` → Listar feedback del feature

---

## Paso 0.0 — Política de Autopilot v5.29.0

Antes de cada pregunta, llama a `evaluateDecision(decision_key, context)` desde `.claude/hooks/lib/autopilot.mjs`.

| Pregunta del skill | decision_key | Default si auto |
|--------------------|--------------|------------------|
| Recopilación de campos del feedback (Paso 2) | `feedback_field_classification` | siempre `ask` (calidad de spec) |
| Crear GitHub issue | `destructive_action` | siempre `ask` (acción visible externa) |
| Marcar AC como inválido (puede invalidar AG-09) | `destructive_action` | siempre `ask` |

**Regla**: la calidad del feedback no se compromete con autopilot. Esta skill captura información del usuario sobre bugs detectados — la información debe ser completa o se corrompe la trazabilidad.

---

## Paso 0: Detectar Contexto del Feature

### 0.1 Resolver feature name

```
¿Que recibi?
├── nombre_de_feature → Usar directamente
├── "resolve FB-NNN" → Ir a sub-comando Resolve (Paso R)
├── "list [feature]" → Ir a sub-comando List (Paso L)
├── sin argumento → Detectar desde rama actual
│   ├── feature/invoice-detail → feature = "invoice-detail"
│   ├── main/master → Preguntar: "¿Para que feature es el feedback?"
│   └── otro → Extraer nombre de la rama
└── Argumento no reconocido → Preguntar al usuario
```

```bash
git branch --show-current
```

### 0.2 Verificar directorio de evidencia

```bash
ls .quality/evidence/${feature}/ 2>/dev/null
```

Si no existe:
- Crear directorio: `mkdir -p .quality/evidence/${feature}/feedback/`
- INFO: "Directorio de evidencia creado para '{feature}'."

Si existe pero no tiene subdirectorio feedback:
- Crear: `mkdir -p .quality/evidence/${feature}/feedback/`

### 0.3 Detectar repositorio GitHub

```bash
git remote get-url origin 2>/dev/null
```

Extraer owner/repo del URL para la creacion del GitHub issue.
Si no hay remote → WARNING: "No se detecto repositorio remoto. Solo se creara evidencia local."

---

## Paso 1: Localizar PRD y Acceptance Criteria

### 1.1 Buscar PRD

```
¿Donde esta el PRD?
├── .quality/evidence/${feature}/acceptance-report.json existe
│   └── Extraer criteria de ahi (ya parseados por AG-09b)
├── doc/prd/${feature}.md existe
│   └── Parsear seccion "Criterios de Aceptacion > Funcionales"
├── Plan referencia work item (PROYECTO-XX)
│   └── Obtener via doc/plans/${feature}_plan.md
└── No se encuentra PRD
    └── Continuar SIN AC-XX linkage (campo ac_ids sera [])
    └── WARNING: "No PRD found. Feedback will be created without AC-XX linkage."
```

### 1.2 Mostrar AC-XX disponibles

Si se encontro PRD, listar los AC-XX con sus descripciones para que el usuario pueda seleccionar.

Si ya existe `acceptance-report.json`, mostrar tambien el status actual de cada AC-XX:

```
AC-XX disponibles:
  AC-01: Usuario puede crear propiedad [PASS]
  AC-02: Validacion inline al perder foco [PASS]
  AC-03: Preview de factura con zoom [PASS]
```

---

## Paso 2: Recopilar Feedback del Desarrollador

### 2.1 Informacion requerida

Preguntar interactivamente (a menos que se proporcione inline con --ac y --severity):

| Campo | Obligatorio | Ejemplo |
|-------|:-----------:|---------|
| **description** | Si | "El boton de factura abre un PDF en vez de mostrar preview inline con zoom" |
| **expected** | Si | "Preview inline del PDF con controles de zoom y pan, embebido en la pagina" |
| **actual** | Si | "Se abre una nueva pestana con el PDF raw sin controles de zoom" |
| **severity** | Si | `critical` / `major` / `minor` |
| **ac_ids** | No | `["AC-03", "AC-05"]` (seleccionar de la lista del Paso 1) |
| **screenshot_path** | No | `./screenshots/invoice-bug.png` (path relativo o absoluto) |
| **steps_to_reproduce** | No | Lista de pasos para reproducir |

### 2.2 Validar severity

| Severity | Criterio | Efecto en merge |
|----------|----------|-----------------|
| `critical` | Funcionalidad principal rota, crash, data loss | **BLOQUEA** merge |
| `major` | Funcionalidad secundaria rota, UX grave | **BLOQUEA** merge |
| `minor` | Cosmetico, texto incorrecto, mejora visual | NO bloquea (warning) |

### 2.3 Validar AC-XX

Si el usuario proporciono --ac AC-XX:
- Verificar que el AC-XX existe en el PRD o acceptance-report.json
- Si no existe → WARNING y preguntar si continuar sin linkage

---

## Paso 3: Asignar ID al Feedback

### 3.1 Calcular siguiente FB-NNN

```bash
existing=$(ls .quality/evidence/${feature}/feedback/FB-*.json 2>/dev/null | wc -l | tr -d ' ')
next_id=$(printf "FB-%03d" $((existing + 1)))
```

### 3.2 Timestamp

```bash
timestamp=$(date -u +%Y-%m-%dT%H:%M:%SZ)
```

---

## Paso 4: Crear Archivo de Feedback Local

### 4.1 Guardar JSON

Archivo: `.quality/evidence/${feature}/feedback/${next_id}.json`

```json
{
  "id": "FB-001",
  "feature": "{feature}",
  "timestamp": "2026-03-01T14:30:00Z",
  "reporter": "developer",
  "severity": "critical",
  "status": "open",
  "ac_ids": ["AC-03"],
  "description": "Invoice detail shows PDF open button instead of inline preview",
  "expected": "Inline PDF preview with zoom and pan controls embedded in the page",
  "actual": "Opens a new tab with raw PDF without zoom controls",
  "steps_to_reproduce": [
    "Navigate to Invoices list",
    "Click on any invoice",
    "Click 'View PDF' button"
  ],
  "screenshot": "feedback/FB-001-screenshot.png",
  "github_issue": null,
  "invalidates_acceptance": true,
  "resolution": null,
  "resolved_at": null
}
```

### 4.2 Copiar screenshot (si se proporciono)

Si `screenshot_path` fue proporcionado:
```bash
cp "${screenshot_path}" ".quality/evidence/${feature}/feedback/${next_id}-screenshot.png"
```

Si no se proporciono screenshot → `"screenshot": null`

### 4.3 Determinar `invalidates_acceptance`

```
SI ac_ids no esta vacio:
  SI acceptance-report.json existe:
    SI algun AC-XX referenciado tiene status "PASS":
      invalidates_acceptance = true
      WARNING: "Este feedback invalida un criterio previamente ACCEPTED."
    SI todos los AC-XX referenciados ya tienen status "FAIL":
      invalidates_acceptance = false
      INFO: "Los criterios referenciados ya estaban en FAIL."
  ELSE:
    invalidates_acceptance = true (precaucion)
ELSE (sin AC-XX linkage):
  invalidates_acceptance = false
  SI severity == "critical":
    invalidates_acceptance = true (un critical sin AC-XX linkage aun bloquea)
```

---

## Paso 5: Crear GitHub Issue

### 5.1 Pre-condicion

Si no se detecto remote en Paso 0.3 → saltar este paso. `"github_issue": null`.

### 5.2 Construir titulo y body

**Titulo**: `[FB-{NNN}] [{severity}] {description_short} ({feature})`
Max 100 caracteres. Truncar description si necesario.

**Body**:
```markdown
## Developer Feedback: FB-{NNN}

**Feature**: {feature}
**Severity**: {severity}
**Date**: {timestamp}
**Acceptance Criteria**: {ac_ids o "N/A"}

### Expected Behavior
{expected}

### Actual Behavior
{actual}

### Steps to Reproduce
{steps_to_reproduce o "Not provided"}

### Screenshot
{Si hay screenshot: adjuntar referencia. Si no: "Not provided"}

### Impact on Acceptance
{Si invalidates_acceptance: "⚠️ This feedback invalidates previously ACCEPTED criteria: {ac_ids}. Merge is blocked until resolved."}
{Si no: "No direct impact on acceptance criteria."}

---
Filed by [SpecBox Engine](https://github.com/jesusperezdeveloper/specbox-engine) `/feedback`
```

### 5.3 Labels

```
labels: ["feedback", "{severity}"]
```

### 5.4 Crear issue via MCP

Usar `mcp__github__create_issue` con owner, repo, title, body, labels.

### 5.5 Actualizar JSON local

Tras crear el issue, actualizar `${next_id}.json`:
```json
"github_issue": {"number": N, "url": "https://github.com/{owner}/{repo}/issues/{N}"}
```

Si falla la creacion del issue:
- WARNING: "No se pudo crear GitHub issue. Evidencia local guardada."
- `"github_issue": null`
- NO bloquear el flujo

---

## Paso 6: Actualizar Estado del Pipeline

### 6.1 Actualizar acceptance-report.json (si aplica)

Solo si `invalidates_acceptance == true` Y `acceptance-report.json` existe:

Para cada AC-XX referenciado en ac_ids con status "PASS":
- Cambiar `"status": "PASS"` → `"status": "INVALIDATED"`
- Agregar campo `"invalidated_by": "FB-{NNN}"`
- Agregar campo `"invalidated_at": "{timestamp}"`

Recalcular summary:
- Si antes era ACCEPTED y ahora hay criterios INVALIDATED → cambiar verdict a `"INVALIDATED"`
- Actualizar `blocking_criteria` con los criterios invalidados

### 6.1a Reflejar la invalidación en el board (FreeForm + MCP remoto)

> **Contrato de tracking I/O (UC-660/661)**: cuando el backend del proyecto es
> FreeForm **y** el MCP server es remoto (`SPECBOX_ENGINE_MCP_URL` definido), el
> server NO puede leer ni escribir `doc/tracking/items.json` del cliente. Toda
> mutación del board debe ir por el **bridge** `.claude/hooks/lib/mcp-client-io.mjs`
> con content-passing — nunca pasando `project_path` como ruta de filesystem del
> server. Este es el patrón canónico que `/feedback`, `/prd` e `/implement` deben
> seguir al mutar FreeForm.

Aplica **solo** si `invalidates_acceptance == true`, el backend es FreeForm, y
hay un UC asociado al feature en el board. Si el backend es Trello/Plane/Native,
o el MCP es local, usar las tools directamente sin el bundle (el server resuelve
el almacenamiento). Si no hay UC en el board para el feature, omitir este paso.

Procedimiento (round-trip de 3 pasos):

```bash
# 1) Leer el items.json local como string vía el bridge (resuelve la raíz del
#    repo con git rev-parse, aplica el guard de path-traversal).
ITEMS=$(node -e "
  import('./.claude/hooks/lib/mcp-client-io.mjs').then(m =>
    process.stdout.write(m.readTrackingBundle())
  );
")
```

```
# 2) Llamar la tool de mutación con content-passing. Por cada AC-XX invalidado,
#    marcarlo no-completado en el board para que el estado refleje el feedback;
#    opcionalmente mover el UC a un estado bloqueado si el feedback es
#    critical/major. Pasar items_content=<ITEMS> y capturar el items_content
#    mutado que la tool devuelve.
mark_ac(uc_id=<UC>, ac_id="AC-03", completed=false, items_content=<ITEMS>)
   → devuelve { ..., items_content: "<items.json mutado>" }
```

```bash
# 3) Persistir el string mutado de vuelta al disco del cliente vía el bridge.
node -e "
  const mutated = process.env.MUTATED_ITEMS;
  import('./.claude/hooks/lib/mcp-client-io.mjs').then(m =>
    m.writeTrackingBundle(mutated)
  );
"
# (pasar el items_content devuelto por env MUTATED_ITEMS para evitar quoting)
```

Reglas:
- **Nunca** llamar la tool con `project_path` apuntando a una ruta del cliente:
  en remoto el server resolvería contra su propio FS (bug raíz de v6.7.0 #82).
- El bridge es la **única** puerta: no hacer `Read`/`Write` directos sobre
  `doc/tracking/items.json` desde la skill.
- Fire-and-forget defensivo: si el round-trip falla, la evidencia local
  (`acceptance-report.json`, `FB-*.json`) ya está guardada y es la fuente de
  verdad del gate de merge; reportar WARNING y continuar sin bloquear el flujo.

### 6.2 Crear/actualizar feedback-summary.json

Archivo: `.quality/evidence/${feature}/feedback-summary.json`

Leer todos los `FB-*.json` del directorio y agregar:

```json
{
  "feature": "{feature}",
  "last_updated": "ISO",
  "total": 3,
  "open": 2,
  "resolved": 1,
  "by_severity": {
    "critical": 1,
    "major": 1,
    "minor": 0
  },
  "blocking": true,
  "blocking_ids": ["FB-001", "FB-002"],
  "invalidated_criteria": ["AC-03"]
}
```

Campo `blocking`: `true` si hay algun feedback open con severity "critical" o "major".
Campo `blocking_ids`: lista de FB-NNN que son open + critical/major.
Campo `invalidated_criteria`: union de ac_ids de todos los FB-NNN con invalidates_acceptance=true y status=open.

---

## Output Final

```
## Feedback Registrado

**ID**: FB-{NNN}
**Feature**: {feature}
**Severity**: {severity}
**AC-XX afectados**: {ac_ids o "Ninguno"}

### Evidencia local
`.quality/evidence/{feature}/feedback/FB-{NNN}.json`

### GitHub Issue
{url del issue o "No creado (sin remote)"}

### Impacto en Acceptance
{Si invalidates_acceptance: "⚠️ El veredicto de AG-09b ha sido INVALIDATED. AC-XX cambiados a INVALIDATED. El merge esta bloqueado hasta resolver este feedback."}
{Si no: "Sin impacto directo en acceptance gate."}

### Siguiente paso
- Corregir el problema y ejecutar `/feedback resolve FB-{NNN}`
- O re-ejecutar `/implement` que re-evaluara los criterios
```

---

## Sub-comando: /feedback resolve FB-{NNN}

### Paso R.1: Localizar feedback

```bash
cat .quality/evidence/${feature}/feedback/FB-{NNN}.json
```

Si no se proporciono feature → buscar FB-{NNN}.json en todos los features:
```bash
find .quality/evidence/ -name "FB-{NNN}.json" 2>/dev/null
```

### Paso R.2: Validar resolucion

Preguntar al desarrollador:
- "¿El problema fue corregido? Describe brevemente la resolucion."

### Paso R.3: Actualizar feedback JSON

Modificar `FB-{NNN}.json`:
```json
{
  "status": "resolved",
  "resolution": "{descripcion de la resolucion}",
  "resolved_at": "ISO timestamp"
}
```

### Paso R.4: Actualizar acceptance-report.json

Si el feedback tenia `invalidates_acceptance: true` y AC-XX fue INVALIDATED por este feedback:
- Cambiar status del AC-XX de "INVALIDATED" a "NEEDS_REVALIDATION"
- Esto indica que AG-09b debe re-ejecutarse para confirmar

**IMPORTANTE**: NEEDS_REVALIDATION no es PASS. El merge sigue bloqueado hasta que AG-09b re-valide.

### Paso R.5: Actualizar feedback-summary.json

Recalcular contadores (total, open, resolved, blocking, blocking_ids, invalidated_criteria).

### Paso R.6: Cerrar GitHub issue

Si `github_issue` no es null:

```bash
gh issue comment {number} --body "✅ Resolved: {resolution}

Marked as resolved by SpecBox Engine \`/feedback resolve\`"

gh issue close {number}
```

### Paso R.7: Output

```
## Feedback Resuelto

**ID**: FB-{NNN}
**Resolucion**: {resolution}
**GitHub Issue**: Cerrado ({url})

### Estado del pipeline
{Si quedan feedback blocking: "Aun hay {N} feedback abiertos bloqueando merge: {blocking_ids}"}
{Si no quedan blocking: "No hay feedback bloqueante. AC-XX en NEEDS_REVALIDATION — ejecutar /implement para re-validar."}
```

---

## Sub-comando: /feedback list [feature]

### Paso L.1: Resolver feature

Si se proporciona feature → usar ese.
Si no → detectar desde rama actual (misma logica que Paso 0.1).

### Paso L.2: Listar feedback

Leer `feedback-summary.json` y todos los `FB-*.json`:

```
## Feedback: {feature}

| ID | Severity | AC-XX | Status | GitHub | Descripcion |
|----|----------|-------|--------|--------|-------------|
| FB-001 | critical | AC-03 | open | #42 | Preview PDF no funciona |
| FB-002 | major | AC-01 | resolved | #43 | Error en creacion |
| FB-003 | minor | — | open | #44 | Typo en label |

**Bloqueantes**: FB-001 (critical)
**Criterios invalidados**: AC-03
```

Si no hay feedback → "No hay feedback registrado para '{feature}'."

---

## Checklist

- [ ] Feature detectado (de argumento o rama)
- [ ] PRD localizado (si existe) y AC-XX listados
- [ ] Feedback recopilado (description, expected, actual, severity)
- [ ] FB-NNN ID asignado secuencialmente
- [ ] JSON guardado en .quality/evidence/{feature}/feedback/
- [ ] Screenshot copiado (si proporcionado)
- [ ] GitHub issue creado con labels correctos
- [ ] JSON actualizado con github_issue URL
- [ ] acceptance-report.json actualizado si invalidates_acceptance
- [ ] board reflejado vía bridge si FreeForm+remoto e invalidates_acceptance (Paso 6.1a)
- [ ] feedback-summary.json creado/actualizado
- [ ] Output final con impacto en acceptance reportado

---

## Referencia rapida

| Accion | Comando |
|--------|---------|
| Nuevo feedback | `/feedback [feature]` |
| Con metadata | `/feedback feature --ac AC-03 --severity critical` |
| Resolver | `/feedback resolve FB-001` |
| Listar | `/feedback list [feature]` |
| Severity que bloquea | critical, major |
| Severity que no bloquea | minor |
| Evidencia local | `.quality/evidence/{feature}/feedback/` |
| Resumen agregado | `.quality/evidence/{feature}/feedback-summary.json` |

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.