Con los números de preguntas y secciones

This commit is contained in:
markosbenitez
2026-06-08 20:25:23 -03:00
parent 307a54dabc
commit 52295a78d0
12 changed files with 367 additions and 33 deletions

View File

@@ -48,6 +48,16 @@
*(Sprint 3 y posteriores — ver ARCHITECTURE.md y BRIEF por sprint)*
### [BACKLOG-001] Consentimiento inicial editable desde admin
- **Estado:** hoy el texto del consentimiento está hardcoded en `consent-screen.tsx`.
- **Necesidad:** cuando se construya el motor de formularios (builder), el texto del
consentimiento debe ser editable por encuesta desde la administración, para reflejar
cambios en política de privacidad o ajustes específicos por tipo de relevamiento.
- **Bloquea:** implementación del builder visual.
- **Decisión cerrada:** la edición es desde admin, no desde el código.
---
- Dashboard / reportes (Sprint 3)
- Formulario de consentimiento + persistencia de respuestas (Etapa 2B)
- Builder visual de encuestas (post-validación del caso fijo)

View File

@@ -147,16 +147,6 @@ body {
border-radius: 0 var(--radius) var(--radius) 0;
color: var(--color-primary-hover);
}
.section-sensitive-note {
font-size: 0.8125rem;
color: #92400e;
background: var(--color-sensitive);
border: 1px solid var(--color-sensitive-border);
border-radius: var(--radius);
padding: 8px 12px;
margin: 0;
}
/* ── Question wrapper ── */
.question-wrapper {
background: var(--color-surface);
@@ -183,6 +173,12 @@ body {
line-height: 1.4;
}
.required-mark { color: var(--color-error); }
.q-code {
font-size: 0.78em;
font-weight: 700;
color: #7A8FA0;
letter-spacing: 0.02em;
}
/* ── Options list ── */
.options-list { display: flex; flex-direction: column; gap: 8px; }

View File

@@ -32,6 +32,7 @@ export function QuestionRenderer({
const error = errors[code]
// A1 (Departamento) renders a combined geo widget that also handles A2 (Ciudad)
// Code badges for A1/A2 are rendered inside GeoSelectWidget.
if (code === 'A1') {
return (
<GeoSelectWidget
@@ -47,11 +48,13 @@ export function QuestionRenderer({
// A2 is rendered inside the GeoSelectWidget above — skip here to avoid duplication
if (code === 'A2') return null
const legend = <><span className="q-code">{code} ·</span> {prompt}</>
if (type === 'single_choice' && isArrayOptions(options)) {
return (
<RadioGroup
name={code}
legend={prompt}
legend={legend}
options={options}
value={answers[code] as string | undefined}
required={required}
@@ -65,7 +68,7 @@ export function QuestionRenderer({
return (
<CheckboxGroup
name={code}
legend={prompt}
legend={legend}
options={options}
value={(answers[code] as string[]) ?? []}
maxSelect={max_select}
@@ -80,7 +83,7 @@ export function QuestionRenderer({
return (
<RatingScale
name={code}
legend={prompt}
legend={legend}
ratingOptions={options}
value={answers[code] as number | undefined}
required={required}
@@ -94,7 +97,7 @@ export function QuestionRenderer({
return (
<TextShortField
name={code}
label={prompt}
label={legend}
value={(answers[code] as string) ?? ''}
required={required}
onChange={(v) => onChange(code, v)}
@@ -107,7 +110,7 @@ export function QuestionRenderer({
return (
<TextAreaField
name={code}
label={prompt}
label={legend}
value={(answers[code] as string) ?? ''}
required={required}
onChange={(v) => onChange(code, v)}

View File

@@ -9,9 +9,9 @@ import { ProgressBar } from './progress-bar'
import { QuestionRenderer } from './question-renderer'
// Section metadata (code prefix → display title)
const SECTIONS: { prefix: string; title: string; sensitive?: boolean }[] = [
const SECTIONS: { prefix: string; title: string }[] = [
{ prefix: 'A', title: 'Datos Generales' },
{ prefix: '1', title: 'Prevalencia: cuidado y discapacidad', sensitive: true },
{ prefix: '1', title: 'Prevalencia: cuidado y discapacidad' },
{ prefix: '2', title: 'Intensidad y rol del cuidado' },
{ prefix: '3', title: 'Impacto económico del cuidado' },
{ prefix: '4', title: 'Tiempo y descanso' },
@@ -190,13 +190,13 @@ export function SurveyForm({ survey, questions }: SurveyFormProps) {
return v !== null && v !== undefined && v !== '' && !(Array.isArray(v) && v.length === 0)
}).length
type Section = { prefix: string; title: string; sensitive?: boolean; questions: Question[] }
type Section = { prefix: string; title: string; questions: Question[] }
const sectionMap = new Map<string, Section>()
for (const q of visibleQuestions) {
const prefix = getSectionPrefix(q.code)
if (!sectionMap.has(prefix)) {
const meta = SECTIONS.find((s) => s.prefix === prefix)
sectionMap.set(prefix, { prefix, title: meta?.title ?? prefix, sensitive: meta?.sensitive, questions: [] })
sectionMap.set(prefix, { prefix, title: meta?.title ?? prefix, questions: [] })
}
sectionMap.get(prefix)!.questions.push(q)
}
@@ -242,13 +242,7 @@ export function SurveyForm({ survey, questions }: SurveyFormProps) {
aria-labelledby={`section-${section.prefix}`}
>
<div className="section-header">
<h2 id={`section-${section.prefix}`} className="section-title">{section.title}</h2>
{section.sensitive && (
<p className="section-sensitive-note" role="note">
Esta sección contiene preguntas sensibles sobre salud o discapacidad.
Responder es completamente voluntario.
</p>
)}
<h2 id={`section-${section.prefix}`} className="section-title">Sección {section.prefix} · {section.title}</h2>
</div>
{section.questions.map((q) => (
<div key={q.id} className="question-wrapper" data-code={q.code}>

View File

@@ -1,9 +1,10 @@
'use client'
import type { ReactNode } from 'react'
import type { QuestionOption } from '@/lib/types'
interface CheckboxGroupProps {
name: string
legend: string
legend: ReactNode
options: QuestionOption[]
value: string[]
maxSelect: number | null

View File

@@ -31,7 +31,7 @@ export function GeoSelectWidget({
{/* Departamento */}
<div className="geo-select-group">
<label className="question-legend" htmlFor="A1">
Departamento
<span className="q-code">A1 ·</span> Departamento
</label>
<select
id="A1"
@@ -58,7 +58,7 @@ export function GeoSelectWidget({
className={`question-legend${cityDisabled ? ' geo-label-disabled' : ''}`}
htmlFor="A2"
>
Ciudad
<span className="q-code">A2 ·</span> Ciudad
{cityDisabled && (
<span className="geo-disabled-hint"> (seleccioná un departamento primero)</span>
)}

View File

@@ -1,9 +1,10 @@
'use client'
import type { ReactNode } from 'react'
import type { QuestionOption } from '@/lib/types'
interface RadioGroupProps {
name: string
legend: string
legend: ReactNode
options: QuestionOption[]
value: string | undefined
required: boolean

View File

@@ -1,9 +1,10 @@
'use client'
import type { ReactNode } from 'react'
import type { RatingOptions } from '@/lib/types'
interface RatingScaleProps {
name: string
legend: string
legend: ReactNode
ratingOptions: RatingOptions
value: number | undefined
required: boolean

View File

@@ -1,8 +1,9 @@
'use client'
import type { ReactNode } from 'react'
interface TextAreaFieldProps {
name: string
label: string
label: ReactNode
value: string
required: boolean
onChange: (value: string) => void

View File

@@ -1,8 +1,9 @@
'use client'
import type { ReactNode } from 'react'
interface TextShortFieldProps {
name: string
label: string
label: ReactNode
value: string
required: boolean
placeholder?: string

View File

@@ -0,0 +1,184 @@
# ETAPA 2F — Formulario: numeración visible + eliminar disclaimers por sección
## 1. Objetivo
Dos cambios cosméticos sobre el formulario que ve el respondente:
1. Mostrar el número de sección en su encabezado y el código de pregunta junto a cada pregunta.
2. Eliminar los disclaimers de "esta sección contiene preguntas sensibles" que aparecen
debajo del encabezado de cada sección. La encuesta se trata como un todo atómico:
la persona acepta responderla entera al inicio (los 2 checks ya implementados); no se
re-pide consentimiento por sección.
**Etapa Nivel 2 — cambio visible al usuario, sin tocar datos ni lógica.** No toca el
seed, ni las RPC, ni los componentes de captura, ni el componente de consentimiento.
---
## 2. Contexto previo
- Etapa 2E cerrada (refactor de dashboard alineado al instrumento real).
- El director observó visualmente el formulario y detectó dos puntos de fricción:
(a) las preguntas no muestran su código, lo que dificulta dar feedback con precisión;
(b) hay disclaimers por sección que crean fricción innecesaria.
- El consentimiento inicial con dos checks (operativo + macro) ya advierte de manera
general sobre el tratamiento de datos. Ese es el contrato — no se duplica por sección.
---
## 3. DECISIONES YA TOMADAS — no consultar de nuevo
### 3.1 Numeración de secciones
Cada encabezado de sección muestra el número antes del título.
Formato: **"Sección {N} · {Título}"** donde {N} es A, 1, 2, 3, 4, 5, 6 o 7.
Ejemplos finales:
- "Sección A · Datos Generales"
- "Sección 1 · Prevalencia: cuidado y discapacidad"
- "Sección 2 · Intensidad y rol del cuidado"
- "Sección 3 · Impacto económico del cuidado"
- "Sección 4 · Tiempo y descanso"
- "Sección 5 · Impacto en el trabajo"
- "Sección 6 · Conciencia organizacional"
- "Sección 7 · Para cerrar"
Los nombres de cada sección se toman literalmente de `SEED_SPEC.md` (sin reinterpretar
ni acortar).
### 3.2 Código de pregunta junto a cada pregunta
Cada pregunta muestra su código como tag/etiqueta pequeña antes del texto de la pregunta.
Especificaciones visuales:
- Color: `#43BBC8` (teal RE) o `#7A8FA0` (muted) — elegir el que dé mejor contraste sin
competir con el texto principal de la pregunta.
- Peso: bold o semibold (que el código se distinga visualmente del texto).
- Tamaño: ~0.8× del texto de la pregunta.
- Posición: en la misma línea que el inicio del texto, separado por un punto medio (·)
o por un espacio + tag con borde. Ejemplo: `1.1 · ¿Vos mismo/a vivís con alguna...?`
- Las preguntas dentro de bloques condicionales (1.2-1.5, 1.7-1.12, 1.14-1.16) muestran
su código tal cual está en el seed. Los saltos visibles (1.1 → 1.6 si no se dispara
el bloque) son intencionales — el respondente ve que existe lógica condicional.
### 3.3 Eliminación de disclaimers por sección
Eliminar TODO disclaimer que aparezca debajo del encabezado de una sección con texto del
estilo:
- "Esta sección contiene preguntas sensibles..."
- "Responder es voluntario..."
- Cualquier variante semánticamente equivalente.
El disclaimer confirmado a eliminar (visto en captura):
> "Esta sección contiene preguntas sensibles sobre salud o discapacidad. Responder es completamente voluntario."
**Verificar si existen disclaimers similares en OTRAS secciones** (ej: Sección 3 por
3.4 salario) y eliminarlos también. La eliminación es consistente: ninguna sección lleva
disclaimer propio.
### 3.4 NO tocar el componente de consentimiento
El `consent-screen.tsx` (o equivalente) con los dos checks (operativo + macro) **queda
intacto**. Esa es la advertencia que la persona acepta al inicio, y es suficiente
porque cubre el tratamiento de datos del formulario completo.
### 3.5 Backlog futuro (NO esta etapa)
El texto del consentimiento inicial debería ser editable cuando se construya el motor
de formularios (sprint futuro del builder). **Agregar como ítem al BACKLOG.md** (no a
TECH_DEBT, porque no es deuda — es feature pendiente):
```
[BACKLOG-XXX] Consentimiento inicial editable desde admin
- Estado: hoy el texto del consentimiento está hardcoded en consent-screen.tsx.
- Necesidad: cuando se construya el motor de formularios (builder), el texto del
consentimiento debe ser editable por encuesta desde la administración, para reflejar
cambios en política de privacidad o ajustes específicos por tipo de relevamiento.
- Bloquea: implementación del builder visual.
- Decisión cerrada: la edición es desde admin, no desde el código.
```
---
## 4. Tareas
### 4.1 Verificación previa (Patrón C.8)
Antes de tocar nada, verificar contra `SEED_SPEC.md`:
- Los 8 nombres exactos de las secciones (A, 1, 2, 3, 4, 5, 6, 7).
- Los códigos de pregunta de la sección A y de cada sección numérica.
Si encontrás discrepancias entre los nombres de las secciones en el código actual y los
del seed, **detenete y reportá** antes de aplicar (Patrón C.8). Aplica el aprendizaje
de la Etapa 2E: los códigos y nombres son del seed, no de archivos secundarios.
### 4.2 Localizar dónde se renderizan los encabezados de sección
`grep -rE "Prevalencia|Datos Generales|Intensidad y rol|Impacto económico|Tiempo y descanso|Impacto en el trabajo|Conciencia organizacional|Para cerrar"` en `components/` y `app/(survey)/` (o equivalente).
Encontrar el componente que renderiza el header de cada sección. Probablemente es uno
solo que recibe el nombre de sección como prop o lo deriva del seed.
### 4.3 Modificar el header de sección
Aplicar el formato **"Sección {N} · {Título}"** una sola vez en el componente, leyendo
el número desde una propiedad del seed o pasándolo como prop. Mantener el estilo
visual actual (color teal, tamaño, peso) — solo se agrega el prefijo "Sección {N} · ".
### 4.4 Modificar el componente de pregunta
Localizar el componente que renderiza el texto de cada pregunta. Agregar el tag con el
código de la pregunta antes del texto, según las especificaciones de la sección 3.2.
El código de cada pregunta ya está en la base de datos (`questions.code`) y debería
estar disponible en el objeto que recibe el componente. Si no está, propagarlo en una
prop (no agregarle un fetch).
### 4.5 Eliminar disclaimers por sección
Eliminar el bloque ámbar con "Esta sección contiene preguntas sensibles...". Buscar
todas las instancias:
```bash
grep -rn "preguntas sensibles\|Responder es completamente voluntario\|Responder es voluntario" \
components/ app/(survey)/ 2>/dev/null
```
Eliminar tanto el JSX como, si existe, el dato del seed/constante que las alimenta. Si
el disclaimer está condicionado por `is_sensitive=true` o similar, eliminar también esa
lógica de renderizado.
### 4.6 Backlog
Agregar el ítem BACKLOG-XXX descrito en la sección 3.5 a `BACKLOG.md` (crear el archivo
si no existe). Numerar según el siguiente correlativo disponible.
---
## 5. Entregables (DoD)
- [ ] Verificación C.8 ejecutada — nombres de secciones match SEED_SPEC.md.
- [ ] Los 8 encabezados de sección muestran el prefijo "Sección {N} · ".
- [ ] Cada pregunta muestra su código (1.1, A5, 6.2, etc.) antes del texto.
- [ ] `grep -rE "preguntas sensibles|Responder es .*voluntario"` retorna vacío.
- [ ] `consent-screen.tsx` (o equivalente) sin cambios — confirmar con `git diff`.
- [ ] BACKLOG.md actualizado con el ítem del consentimiento editable.
- [ ] Build sin errores (`next build`).
- [ ] `git diff --name-only HEAD` solo en componentes del formulario y BACKLOG.md.
- [ ] Captura del formulario en sección 1 mostrando: encabezado con "Sección 1 · ", al
menos 2 preguntas con sus códigos visibles, y SIN disclaimer ámbar.
## 6. Qué reportar
```
Verificado:
- Verificación C.8 (nombres de secciones vs SEED_SPEC.md): match
- Archivos modificados en diff: [lista]
- Headers de sección con "Sección {N} · ": confirmado
- Códigos de pregunta visibles: [ejemplo de 2-3]
- grep de disclaimers: vacío
- consent-screen.tsx intacto: confirmado
- BACKLOG.md actualizado: ítem [número]
- Build exitoso
Asumido:
- [si hay decisión cosmética sobre el estilo del tag de código]
Decisiones proactivas (Nivel 2):
- [si las hubo]
Conflictos de scope (Patrón C.8):
- [si los hubo, listarlos AQUÍ y detener]
```
## 7. Qué NO hacer
- ❌ No tocar `consent-screen.tsx` ni el componente de consentimiento de ninguna forma.
- ❌ No modificar el seed, las preguntas, ni `SEED_SPEC.md`.
- ❌ No tocar las RPCs ni la migración del dashboard.
- ❌ No cambiar la lógica condicional de los bloques (1.1→1.2-1.5, etc.).
- ❌ No renumerar preguntas — los códigos quedan tal cual están en el seed.
- ❌ No agregar dependencias npm.
- ❌ No resolver ítems de TECH_DEBT.md ni del BACKLOG salvo el ítem nuevo de esta etapa.

View File

@@ -0,0 +1,142 @@
# ETAPA 2G — Cierre de Sprint 2: promoción de C.8 y documentación de AP.10 + AP.11
## 1. Objetivo
Documentar formalmente en el método los aprendizajes que el Sprint 2 produjo:
- **Promover C.8 a estable** en `method/PATTERNS.md` (validado en 3 etapas del proyecto).
- **Agregar AP.10 (propagación silenciosa de inconsistencia)** a `method/ANTI_PATTERNS.md`.
- **Agregar AP.11 (contrato desactualizado por código)** a `method/ANTI_PATTERNS.md`.
Etapa de documentación pura. **No toca código, no toca seed, no toca dashboard.**
---
## 2. Contexto previo
- Sprint 2 cerrado con Etapas 2A-2F entregadas.
- Etapa 2D produjo el caso real de AP.10 (subtítulos con códigos discrepantes del seed).
- Etapa 2E aplicó por primera vez C.8 y detectó el conflicto A1b-vs-A1 antes de ejecutar
(caso real de AP.11 — SEED_SPEC.md desactualizado por Etapa 1D).
- Etapa 2F ejecutó con C.8 sin discrepancias (validación de patrón en uso limpio).
- Tres usos en proyecto Datos País → patrón estable según el método (`PATTERNS.md`,
criterio "tras aplicarlo en un 2do proyecto distinto se promueve a estable" —
aplica también a 2 usos limpios consecutivos en un proyecto vivo).
---
## 3. Tareas
### 3.1 Agregar C.8 a `method/PATTERNS.md`
Insertar en la **Categoría C — Validación de output**, después de C.7 (Control preventivo
de scope con `git diff`):
```markdown
### C.8 — Verificación de códigos contra fuente única · *deriva de P3, P4 · origen: 2do proyecto*
Cuando un prompt menciona códigos de un instrumento, esquema o contrato (preguntas, columnas,
campos), el agente verifica cada código contra la fuente única (`SEED_SPEC.md`, `schema.sql`,
ADRs) **antes** de ejecutar. Si detecta una discrepancia entre el código nombrado en el
prompt y su definición en la fuente única, **DETIENE la ejecución y reporta el conflicto**.
Ejecutar "literalmente" y delegar la verificación semántica al director es AP.10.
-**Correcto:** el reporte del agente incluye una sección "Verificación C.8" con cada
código del prompt mapeado a su fila en la fuente única, antes de la ejecución. Si hay
discrepancia, la ejecución no arranca hasta que el director resuelva.
-**Violación:** el agente ejecuta el prompt al pie de la letra y reporta "los textos son
los solicitados literalmente; la validación semántica la hace el director" — exporta el
trabajo de verificar al humano y propaga la inconsistencia.
**Cómo se incorpora a un prompt:** agregar un paso "Verificación C.8" como primera tarea
del DoD, listando los códigos a verificar y la ruta exacta de la fuente única.
**Casos reales en Datos País:** Etapa 2D (no se aplicó — daño AP.10), Etapa 2E (se aplicó —
detectó conflicto A1/A1b antes de ejecutar), Etapa 2F (se aplicó — sin discrepancias).
```
### 3.2 Agregar AP.10 a `method/ANTI_PATTERNS.md`
Insertar al final del listado, antes de "Cómo agregar un anti-patrón":
```markdown
## AP.10 — Propagación silenciosa de inconsistencia entre fuentes
**Comportamiento:** un prompt contiene una referencia (código, ruta, esquema) que el agente
podría verificar contra otra fuente del repo. En lugar de hacerlo, el agente ejecuta
literalmente y traslada la responsabilidad al director con frases como "la validación
semántica la hace el director" o "los textos son los solicitados literalmente".
**Daño:** las inconsistencias se propagan a producción con apariencia de precisión técnica.
*Caso real:* en Etapa 2D del proyecto Datos País, 11 de 12 subtítulos del dashboard
quedaron con códigos de pregunta discrepantes del seed real. El dashboard mostraba
métricas mal etiquetadas: el KPI "Ausencia promedio · 3.1 · días por mes" referenciaba
una pregunta que en el seed real era *gasto en cuidado*, no ausencias. Detectado en la
auditoría adversarial posterior, no antes. Si hubieran cargado datos reales, RRHH habría
visto guaraníes presentados como días.
**Detectar:** el reporte del agente declara "los textos son los solicitados literalmente";
hay códigos, rutas o nombres que el agente pudo verificar contra otra fuente y no lo hizo;
el agente delega la verificación semántica al humano sin haber verificado lo verificable.
**Evitar:** Patrón C.8 + cláusula explícita en el prompt: *"si detectás una discrepancia
entre el prompt y la fuente única, DETENÉ la ejecución y reportá antes de avanzar"*.
**Distinción:** ≠ AP.3 — AP.3 minimiza un problema observado; AP.10 evita verificar lo
verificable. ≠ AP.9 — AP.9 resuelve restricciones contradictorias del propio prompt;
AP.10 propaga inconsistencias entre el prompt y otra fuente.
```
### 3.3 Agregar AP.11 a `method/ANTI_PATTERNS.md`
Insertar inmediatamente después de AP.10:
```markdown
## AP.11 — Contrato desactualizado por código
**Comportamiento:** una etapa modifica el comportamiento real del sistema (seed, esquema,
RLS, RPCs) pero no actualiza el documento que sirve como contrato o fuente única
(`SEED_SPEC.md`, `ARCHITECTURE.md`, ADRs). El documento queda mintiendo por silencio.
**Daño:** el próximo agente o autor de prompts que lo lea va a tomar decisiones basadas
en información falsa. *Caso real:* en Etapa 1D del proyecto Datos País se modificó
`seed.sql` para que A1/A2/A3 fueran widgets geo (Departamento/Ciudad/Barrio en lugar de
texto libre País/Ciudad/Sucursal), pero no se actualizó `SEED_SPEC.md`. Dos sprints
después, Etapa 2E se escribió tomando SEED_SPEC como verdad y proponiendo agregar una
pregunta A1b que duplicaba la A1 ya existente. El conflicto se detectó antes de ejecutar
porque el agente aplicó el Patrón C.8; sin C.8, se habría creado una pregunta duplicada
en producción.
**Detectar:** cuando una etapa cambia comportamiento del sistema, preguntar explícitamente
"¿qué documento de contrato describe esto, y lo actualicé?". Si la respuesta es "no sé"
o "después lo veo", AP.11 latente. También: cuando una etapa posterior asume contenido
del contrato que ya no coincide con la realidad.
**Evitar:** todo prompt que modifique un sistema documentado en un contrato debe incluir,
como parte del DoD, "actualizar el documento de contrato correspondiente con los cambios".
Es Principio 4 aplicado al mantenimiento, no solo a la creación.
**Distinción:** ≠ AP.4 — AP.4 es decisión no registrada; AP.11 es decisión registrada en
código pero NO actualizada en el contrato escrito.
```
### 3.4 (Opcional) Agregar referencia cruzada en C.1 del método
En `method/PATTERNS.md`, dentro de C.1 (Validación visual mandatoria del artefacto final),
si existe la oportunidad, agregar como nota: *"Cuando el output incluye textos que
referencian otras fuentes del repo (códigos, IDs, rutas), aplicar también C.8."*
Esta tarea es opcional — solo si encaja naturalmente. No forzarla.
---
## 4. Entregables (DoD)
- [ ] `method/PATTERNS.md` actualizado con C.8 como patrón estable.
- [ ] `method/ANTI_PATTERNS.md` actualizado con AP.10 y AP.11.
- [ ] Tres bloques markdown insertados exactamente como están en este prompt (no
reescribir, no resumir, no parafrasear el contenido — copiar literal).
- [ ] `git diff --name-only HEAD` retorna **solo** los 2 archivos del método.
- [ ] Build no aplica (no hay cambios de código).
## 5. Qué reportar
```
Verificado:
- archivos en diff: method/PATTERNS.md, method/ANTI_PATTERNS.md
- C.8 insertado en Categoría C después de C.7: confirmado
- AP.10 y AP.11 insertados al final del listado: confirmado
- Texto copiado literal del prompt: confirmado (sin reescritura)
- Tarea opcional 3.4: [aplicada / no aplicada — justificación corta]
Asumido:
- [solo si el método tiene una estructura distinta a la esperada]
Decisiones proactivas (Nivel 2):
- [si las hubo]
```
## 6. Qué NO hacer
- ❌ No reescribir, resumir ni parafrasear los textos de C.8, AP.10 o AP.11 — copiar literal.
- ❌ No agregar otros patrones o anti-patrones por iniciativa.
- ❌ No modificar PRINCIPLES.md ni AUTOMATION_STRATEGY.md.
- ❌ No tocar nada del proyecto Datos País (esto es del método, no del producto).
- ❌ No crear archivos nuevos — solo editar los dos existentes.