fia-harness 2.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 PGMIA (Pedro D. García Miranda)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,244 @@
1
+ Metadata-Version: 2.4
2
+ Name: fia-harness
3
+ Version: 2.0.0
4
+ Summary: FIA Harness: spec-driven development kit for AI agents with machine-validated state and CI enforcement. Stdlib-only, no cloud, no telemetry.
5
+ Author: PGMIA (Pedro D. García Miranda)
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/mcpedrogm-art/fia-harness
8
+ Project-URL: Repository, https://github.com/mcpedrogm-art/fia-harness
9
+ Project-URL: Demo, https://github.com/mcpedrogm-art/fia-harness-demo
10
+ Keywords: spec-driven-development,ai-agents,sdd,harness,governance,enforcement,local-first
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Topic :: Software Development
14
+ Requires-Python: >=3.8
15
+ Description-Content-Type: text/markdown
16
+ License-File: LICENSE
17
+ Dynamic: license-file
18
+
19
+ # 🧬 FIA HARNESS COMPLETO
20
+
21
+ > **El sistema operativo para construir software con agentes de IA.**
22
+ > Especificación antes que código · Seguridad por diseño · Contexto mínimo en cada fase · Cero asunciones en silencio
23
+
24
+  
25
+
26
+ `Python 3.8+` · `Sin dependencias externas` · `Mono o multi-agente` · `2 modos de trabajo` · `Reglas verificadas en CI` · `LLM-agnóstico` *(funciona con DeepSeek, OpenCode, Claude, GPT o el agente que uses)*
27
+
28
+ ---
29
+
30
+ ## 🗺️ El sistema en un vistazo
31
+
32
+ ```mermaid
33
+ graph TD
34
+ PRD["📄 PRD.md<br/>documento de negocio"] --> BOOT["⚙️ bootstrap.py<br/>(Fase M0)"]
35
+ BOOT --> CTX["CONTEXT.md<br/>resumen vivo del negocio"]
36
+ BOOT --> PROG["PROGRESS.md<br/>fases M0-M3"]
37
+ CTX --> INT["🧠 Agente de IA<br/>Entrevista técnica (M1)"]
38
+ INT --> SEC["SECURITY.md<br/>AEO_GEO_SEO.md<br/>decisiones en CONTEXT.md"]
39
+ SEC --> SPEC["SPEC.md<br/>especificación aprobada<br/>por el humano (M2)"]
40
+ SPEC --> PLAN["Tabla F0-Fn<br/>en PROGRESS.md (M3)"]
41
+ PLAN --> GEN["🤖 task_generator.py"]
42
+ GEN --> TASK["TASK-F1.md<br/>checklists de seguridad,<br/>visibilidad y UX inyectados"]
43
+ TASK --> RUN["🛠️ Agente ejecuta<br/>auditoría → diseño → código"]
44
+ RUN --> VAL["✅ Fase K<br/>tests · typecheck · lint · build"]
45
+ VAL -- falla --> RUN
46
+ VAL -- pasa --> NEXT["PROGRESS.md actualizado<br/>siguiente fase pendiente"]
47
+ NEXT --> GEN
48
+ ```
49
+
50
+ **La idea central:** el PRD se lee una vez. A partir de ahí, cada fase del agente solo carga 4 archivos comprimidos (`CONTEXT.md` + sección de `SPEC.md` + `PROGRESS.md` + `TASK-Fx.md`). Nunca se reenvía el histórico completo. Contexto pequeño = respuestas más baratas, más rápidas y con menos deriva.
51
+
52
+ ---
53
+
54
+ ## ⚙️ Cómo funciona: tres motores
55
+
56
+ ### 1️⃣ Fases de proceso (M0–M3) — *pensar antes de construir*
57
+
58
+ | Fase | Qué pasa | Entregable |
59
+ |:---:|---|---|
60
+ | **M0** | `bootstrap.py` lee el PRD y activa el harness | `CONTEXT.md` + `PROGRESS.md` + plantillas |
61
+ | **M1** | El agente te entrevista: stack, BBDD, seguridad, visibilidad, UI/UX, Skills/MCP | `SECURITY.md` y `AEO_GEO_SEO.md` completos |
62
+ | **M2** | El agente redacta la especificación técnica (SDD) | `SPEC.md` **aprobado por un humano** |
63
+ | **M3** | El plan se trocea en fases pequeñas y verificables | Tabla `F0-Fn` pegada en `PROGRESS.md` |
64
+
65
+ > 🚫 Hasta que M3 cierra, **no se escribe una sola línea de código de producción.**
66
+
67
+ ### 2️⃣ Fases de ejecución (F0–Fn) — *construir fase a fase*
68
+
69
+ Cada fase del plan = **una tarea** = un ciclo completo y cerrado. Ejemplo de plan típico:
70
+
71
+ | Fase | Objetivo | Entregable |
72
+ |:---:|---|---|
73
+ | F0 | Bootstrap del repo, tooling, CI | Repo funcionando |
74
+ | F1 | Modelo de datos + migraciones | BBDD versionada |
75
+ | F2 | Backend core | API mínima |
76
+ | F3 | Frontend core | UI navegable |
77
+ | F4 | Auth y permisos | Login/roles |
78
+ | ... | ... | ... |
79
+
80
+ `task_generator.py` **detecta automáticamente la primera fase pendiente** y genera su tarea. Tú decides cuándo arrancar la siguiente; el agente nunca encadena fases solo.
81
+
82
+ ### 3️⃣ El ciclo de tarea (A–L) — *disciplina en cada fase*
83
+
84
+ ```
85
+ A. Auditoría → inspeccionar antes de tocar
86
+ B. Diseño → mapa mínimo alineado con SPEC.md
87
+ C. Hipótesis → declarar decisiones, no asumirlas
88
+ E. Implementación → cambio mínimo necesario
89
+ F. Edge cases → idempotencia, carreras, validación
90
+ I. Tests → escenarios mínimos obligatorios
91
+ J. No hacer / J2 → scope cerrado + checklist de seguridad
92
+ H2. Visibilidad → SEO/AEO/GEO si hay superficie pública
93
+ H3. UI/UX → Design DNA aprobado si hay interfaz
94
+ K. Validación → tests · typecheck · lint · build
95
+ L. Informe final → qué se hizo, qué no, y resultado verificado
96
+ ```
97
+
98
+ Las fases H2 (Visibilidad) y J2 (Seguridad) **se inyectan automáticamente solo si la fase las necesita**, con el contenido *real y vivo* de tus `AEO_GEO_SEO.md`, `SECURITY.md` y `UI_UX_EXCLUSIVA.md`. Si no aplican, el generador lo deja escrito con su motivo — nunca se omite en silencio.
99
+
100
+ ---
101
+
102
+ ## 🚀 Arranque en 4 pasos
103
+
104
+ > ⚡ **O en un solo comando (PyPI):** `uvx fia-harness init` (o `pipx run fia-harness init`) monta el proyecto nuevo automáticamente — plantillas en `/docs`, scripts en la raíz y `PRD.md` de partida. Salta al paso 2.
105
+
106
+ ```text
107
+ 1. Prepara el proyecto nuevo
108
+ ├── bootstrap.py + task_generator.py en la raíz
109
+ ├── /docs con las 8 plantillas maestras
110
+ ├── (opcional) RAG_VECTOR_EXTENSION.md dentro de /docs si habrá búsqueda semántica
111
+ └── PRD.md en la raíz
112
+
113
+ 2. python bootstrap.py → Fase M0 automática
114
+ Genera CONTEXT.md, PROGRESS.md, progress.json, DECISIONS.md,
115
+ activa las plantillas y emite .github/workflows/harness.yml
116
+
117
+ 3. Abre tu agente con la carpeta → inicia la entrevista (M1)
118
+ El agente lee CONTEXT.md y NO programa nada todavía.
119
+
120
+ 4. Aprueba SPEC.md, pega la tabla F0-Fn en PROGRESS.md y compila:
121
+ python task_generator.py --sync → valida el estado en progress.json
122
+ python task_generator.py → genera la tarea de la fase pendiente
123
+ ```
124
+
125
+ > 📖 Guía detallada paso a paso: **[INSTRUCCIONES DE APLICACION.txt](INSTRUCCIONES%20DE%20APLICACION.txt)** · Protocolo completo: **[INICIO_PROYECTO.md](INICIO_PROYECTO.md)**
126
+
127
+ ---
128
+
129
+ ## 📁 Mapa de archivos
130
+
131
+ | Archivo | Qué es |
132
+ |---|---|
133
+ | 🧭 `INICIO_PROYECTO.md` | **Fuente de verdad del protocolo**: rol del agente, fases, entrevista técnica, reglas de oro |
134
+ | ⚙️ `bootstrap.py` | Inicializador (M0): lee el PRD, genera `CONTEXT.md`/`PROGRESS.md`/`progress.json`/`DECISIONS.md`, activa plantillas y RAG si procede, y emite el CI de reglas de oro |
135
+ | 🤖 `task_generator.py` | Genera cada `TASK-Fx.md`, compila/valida el estado (`--sync`, `--check`) y registra aprobaciones (`--approval`) |
136
+ | 📦 `fia_harness/` + `pyproject.toml` | Paquete PyPI: `fia-harness init` (CLI instalador). Las copias de scripts/plantillas del paquete están vigiladas por tests de sincronización |
137
+ | 🗃️ `progress.json` | Estado compilado y validado del proyecto: la máquina de verdad que lee el CI |
138
+ | 📋 `TASK_TEMPLATE.md` | Plantilla maestra de tarea (ciclo completo A–L, 20 puntos de informe) |
139
+ | ⚡ `TASK_LITE_TEMPLATE.md` | Plantilla de tarea rápida para el Modo Lite |
140
+ | 🛡️ `SECURITY.md` | Checklist de seguridad **obligatorio en todo proyecto**: auth/2FA, RLS, secretos, firewall, Skills/MCP, prompt injection |
141
+ | 🔎 `AEO_GEO_SEO.md` | Visibilidad en tres motores: SEO (buscadores), AEO (asistentes) y GEO (LLMs) — solo si hay superficie pública |
142
+ | 🎨 `UI_UX_EXCLUSIVA.md` | Design DNA, arquetipos, motion system y auditoría anti-clon |
143
+ | 🔌 `SKILLS_MCP.md` | Gobernanza de capacidades: nada se busca/instala/conecta sin **aprobación humana explícita** |
144
+ | ⚡ `QUICKSTART_LITE.md` | Protocolo reducido para prototipos, con promoción obligatoria si aparece riesgo |
145
+ | 🧩 `PROYECTOS RAG Y VECTORIALES/` | Módulo de extensión: stack vectorial (pgvector/Pinecone/Qdrant), chunking, recuperación híbrida + reranking, `llms.txt` |
146
+ | 🧪 `tests/test_harness.py` | Tests automatizados de los parsers y del ciclo completo |
147
+ | 📜 `CHANGELOG_FIXES.md` | Historial de correcciones aplicadas y cómo se verificaron |
148
+
149
+ ---
150
+
151
+ ## ⚡ Dos modos de trabajo
152
+
153
+ | | 🔵 **Completo** | ⚡ **Lite** |
154
+ |---|---|---|
155
+ | Para | MVPs, productos reales | Prototipos, vertical slices, cambios acotados |
156
+ | Documentación | `CONTEXT` + `SPEC` + `PROGRESS` + `DECISIONS` | Solo `QUICK_CONTEXT.md` |
157
+ | Tareas | `TASK-Fx.md` desde `TASK_TEMPLATE.md` | `TASK-QUICK.md` desde `TASK_LITE_TEMPLATE.md` |
158
+ | Seguridad, aprobación humana, Context7 | ✅ Siempre | ✅ Siempre (no se negocian) |
159
+
160
+ **Promoción automática a Completo** si aparece cualquiera de estos: auth/roles, pagos, PII/salud, migraciones críticas, escritura en servicios externos, deploy/secretos, alcance incierto. La promoción **conserva** el trabajo ya validado.
161
+
162
+ > Para activar Lite: declara `Modo de trabajo: Lite` en `CONTEXT.md` (lo detecta `task_generator.py` solo) o fuerza con `--lite`.
163
+
164
+ ---
165
+
166
+ ## 🧩 Módulos condicionales
167
+
168
+ El harness base es común; estas capas se activan solo cuando el proyecto las necesita:
169
+
170
+ | Condición | Módulo que se activa |
171
+ |---|---|
172
+ | El PRD menciona RAG, embeddings, búsqueda semántica o memoria vectorial | `RAG_VECTOR_EXTENSION.md` — *bootstrap.py lo detecta y copia solo* |
173
+ | Hay páginas públicas indexables (landing, blog, docs) | `AEO_GEO_SEO.md` + Fase H2 en las tareas de contenido |
174
+ | Hay interfaz de usuario | `UI_UX_EXCLUSIVA.md` + Design DNA aprobado antes de implementar |
175
+ | El proyecto es multi-agente | `AGENTS.md` con roles y protocolo de handoff |
176
+
177
+ ---
178
+
179
+ ## 🚨 Enforcement: las reglas tienen dientes *(nuevo en v2)*
180
+
181
+ Un harness de documentos obliga por convención; este kit desde la v2 obliga también por infraestructura. `bootstrap.py` emite un workflow de GitHub Actions (`.github/workflows/harness.yml`) que se ejecuta en cada push y PR:
182
+
183
+ | Regla de oro | Cómo se hace cumplir mecánicamente |
184
+ |---|---|
185
+ | Nunca cerrar fases con dependencias abiertas (nº4) | `progress.json` validado: cerrar F2 con F1 abierta **rompe el build** |
186
+ | Nunca cerrar una fase sin Definition of Done (nº5) | Toda fase `done` exige su checkpoint de contexto en `PROGRESS.md` |
187
+ | Nunca ejecutar una fase sin su `TASK-Fx.md` (nº7) | El validador comprueba que `TASK-F<N>.md` exista para cada fase F cerrada |
188
+ | Nunca hacer commit con secretos (nº8) | **gitleaks** escanea todo el historial en cada push |
189
+ | Dependencias sin vulnerabilidades conocidas | `npm audit` / `pip-audit` según el stack detectado |
190
+ | Tests obligatorios antes de dar una fase por cerrada | Job de CI con pytest/unittest o `npm test`, según lo que detecte |
191
+ | Aprobaciones humanas rastreables | Toda `APPROVAL-NNN` citada en una TASK debe existir en `DECISIONS.md` |
192
+
193
+ El flujo de estado: `PROGRESS.md` sigue siendo la superficie de edición (humano o agente), y `task_generator.py --sync` lo compila y valida en `progress.json`. Si editas el Markdown a mano y no compila, el CI se pone rojo hasta que hagas `--sync`. Y `--sync` es *fail-closed*: si el estado viola una regla, **no escribe nada**.
194
+
195
+ ```bash
196
+ python task_generator.py --sync # compila y valida PROGRESS.md -> progress.json
197
+ python task_generator.py --check # valida sin modificar nada (lo ejecuta el CI)
198
+ python task_generator.py --approval "instalar Skill X v1.2" --phase F2 --ref "chat 5-sep"
199
+ ```
200
+
201
+ ---
202
+
203
+ ## 🛡️ Las reglas que nunca se rompen
204
+
205
+ 1. 🚫 **Nunca codificar sin spec aprobada** — ni una línea antes del M3.
206
+ 2. 🗣️ **Nunca asumir en silencio** — toda asunción se declara y se confirma.
207
+ 3. 📦 **Nunca reenviar contexto innecesario** — los archivos de control son la fuente comprimida.
208
+ 4. ✅ **Nunca cerrar una fase sin su Definition of Done** — ni mezclar fases.
209
+ 5. 🔐 **Nunca cerrar una fase de seguridad sin su checklist** — la seguridad no se pospone a un audit final.
210
+ 6. 🙋 **Nunca instalar/buscar/conectar una Skill, MCP o librería sin aprobación humana** — el silencio no es permiso.
211
+ 7. 🧪 **Nunca inventar resultados** — los tests que no se ejecutaron no existen.
212
+ 8. 🛑 **Nunca hacer commit/push/deploy sin autorización explícita.**
213
+
214
+ > 🚨 Desde la v2, las reglas 4, 5, 7 y 8 además se **verifican automáticamente en CI** en cada proyecto que arranca con `bootstrap.py` (sección anterior).
215
+
216
+ ---
217
+
218
+ ## ✅ Verificar el kit
219
+
220
+ ```bash
221
+ python -m unittest discover tests -v
222
+ ```
223
+
224
+ Los tests cubren el parser de `PROGRESS.md` (tablas múltiples, negritas, columnas combinadas), la extracción de secciones con tablas reales, los inyectores por marcadores, la heurística de palabras clave (incluido el falso positivo clásico de *"entre**vista**"*), el recorte de plantilla, la detección de Modo Lite, la **máquina de estado** (dependencias, checkpoints, TASKs, aprobaciones, drift y fail-closed) y un **ciclo completo e2e** (`bootstrap.py` → `task_generator.py`) en carpeta temporal.
225
+
226
+ En un proyecto ya arrancado, puedes comprobar su estado en cualquier momento:
227
+
228
+ ```bash
229
+ python task_generator.py --check
230
+ ```
231
+
232
+ ---
233
+
234
+ ## 📜 Documentación y fuentes de verdad
235
+
236
+ | Documento | Rol |
237
+ |---|---|
238
+ | `README.md` *(este archivo)* | Índice y visión general del sistema |
239
+ | `INICIO_PROYECTO.md` | **Fuente de verdad del protocolo** — si algo diverge, manda este |
240
+ | `INSTRUCCIONES DE APLICACION.txt` | Guía rápida de arranque paso a paso |
241
+ | `guia-automatizacion-tareas.md` | Guía del generador de tareas |
242
+ | `PROTOCOLO DE GESTION....txt` | Síntesis ejecutiva (lectura rápida, no se actualiza con cada cambio) |
243
+ | `Guia_arranque_del_proyecto.pdf` | Snapshot estático de la guía para lectura cómoda |
244
+ | `CHANGELOG_FIXES.md` | Qué se corrigió, por qué y cómo se verificó |
@@ -0,0 +1,226 @@
1
+ # 🧬 FIA HARNESS COMPLETO
2
+
3
+ > **El sistema operativo para construir software con agentes de IA.**
4
+ > Especificación antes que código · Seguridad por diseño · Contexto mínimo en cada fase · Cero asunciones en silencio
5
+
6
+ &nbsp;
7
+
8
+ `Python 3.8+` · `Sin dependencias externas` · `Mono o multi-agente` · `2 modos de trabajo` · `Reglas verificadas en CI` · `LLM-agnóstico` *(funciona con DeepSeek, OpenCode, Claude, GPT o el agente que uses)*
9
+
10
+ ---
11
+
12
+ ## 🗺️ El sistema en un vistazo
13
+
14
+ ```mermaid
15
+ graph TD
16
+ PRD["📄 PRD.md<br/>documento de negocio"] --> BOOT["⚙️ bootstrap.py<br/>(Fase M0)"]
17
+ BOOT --> CTX["CONTEXT.md<br/>resumen vivo del negocio"]
18
+ BOOT --> PROG["PROGRESS.md<br/>fases M0-M3"]
19
+ CTX --> INT["🧠 Agente de IA<br/>Entrevista técnica (M1)"]
20
+ INT --> SEC["SECURITY.md<br/>AEO_GEO_SEO.md<br/>decisiones en CONTEXT.md"]
21
+ SEC --> SPEC["SPEC.md<br/>especificación aprobada<br/>por el humano (M2)"]
22
+ SPEC --> PLAN["Tabla F0-Fn<br/>en PROGRESS.md (M3)"]
23
+ PLAN --> GEN["🤖 task_generator.py"]
24
+ GEN --> TASK["TASK-F1.md<br/>checklists de seguridad,<br/>visibilidad y UX inyectados"]
25
+ TASK --> RUN["🛠️ Agente ejecuta<br/>auditoría → diseño → código"]
26
+ RUN --> VAL["✅ Fase K<br/>tests · typecheck · lint · build"]
27
+ VAL -- falla --> RUN
28
+ VAL -- pasa --> NEXT["PROGRESS.md actualizado<br/>siguiente fase pendiente"]
29
+ NEXT --> GEN
30
+ ```
31
+
32
+ **La idea central:** el PRD se lee una vez. A partir de ahí, cada fase del agente solo carga 4 archivos comprimidos (`CONTEXT.md` + sección de `SPEC.md` + `PROGRESS.md` + `TASK-Fx.md`). Nunca se reenvía el histórico completo. Contexto pequeño = respuestas más baratas, más rápidas y con menos deriva.
33
+
34
+ ---
35
+
36
+ ## ⚙️ Cómo funciona: tres motores
37
+
38
+ ### 1️⃣ Fases de proceso (M0–M3) — *pensar antes de construir*
39
+
40
+ | Fase | Qué pasa | Entregable |
41
+ |:---:|---|---|
42
+ | **M0** | `bootstrap.py` lee el PRD y activa el harness | `CONTEXT.md` + `PROGRESS.md` + plantillas |
43
+ | **M1** | El agente te entrevista: stack, BBDD, seguridad, visibilidad, UI/UX, Skills/MCP | `SECURITY.md` y `AEO_GEO_SEO.md` completos |
44
+ | **M2** | El agente redacta la especificación técnica (SDD) | `SPEC.md` **aprobado por un humano** |
45
+ | **M3** | El plan se trocea en fases pequeñas y verificables | Tabla `F0-Fn` pegada en `PROGRESS.md` |
46
+
47
+ > 🚫 Hasta que M3 cierra, **no se escribe una sola línea de código de producción.**
48
+
49
+ ### 2️⃣ Fases de ejecución (F0–Fn) — *construir fase a fase*
50
+
51
+ Cada fase del plan = **una tarea** = un ciclo completo y cerrado. Ejemplo de plan típico:
52
+
53
+ | Fase | Objetivo | Entregable |
54
+ |:---:|---|---|
55
+ | F0 | Bootstrap del repo, tooling, CI | Repo funcionando |
56
+ | F1 | Modelo de datos + migraciones | BBDD versionada |
57
+ | F2 | Backend core | API mínima |
58
+ | F3 | Frontend core | UI navegable |
59
+ | F4 | Auth y permisos | Login/roles |
60
+ | ... | ... | ... |
61
+
62
+ `task_generator.py` **detecta automáticamente la primera fase pendiente** y genera su tarea. Tú decides cuándo arrancar la siguiente; el agente nunca encadena fases solo.
63
+
64
+ ### 3️⃣ El ciclo de tarea (A–L) — *disciplina en cada fase*
65
+
66
+ ```
67
+ A. Auditoría → inspeccionar antes de tocar
68
+ B. Diseño → mapa mínimo alineado con SPEC.md
69
+ C. Hipótesis → declarar decisiones, no asumirlas
70
+ E. Implementación → cambio mínimo necesario
71
+ F. Edge cases → idempotencia, carreras, validación
72
+ I. Tests → escenarios mínimos obligatorios
73
+ J. No hacer / J2 → scope cerrado + checklist de seguridad
74
+ H2. Visibilidad → SEO/AEO/GEO si hay superficie pública
75
+ H3. UI/UX → Design DNA aprobado si hay interfaz
76
+ K. Validación → tests · typecheck · lint · build
77
+ L. Informe final → qué se hizo, qué no, y resultado verificado
78
+ ```
79
+
80
+ Las fases H2 (Visibilidad) y J2 (Seguridad) **se inyectan automáticamente solo si la fase las necesita**, con el contenido *real y vivo* de tus `AEO_GEO_SEO.md`, `SECURITY.md` y `UI_UX_EXCLUSIVA.md`. Si no aplican, el generador lo deja escrito con su motivo — nunca se omite en silencio.
81
+
82
+ ---
83
+
84
+ ## 🚀 Arranque en 4 pasos
85
+
86
+ > ⚡ **O en un solo comando (PyPI):** `uvx fia-harness init` (o `pipx run fia-harness init`) monta el proyecto nuevo automáticamente — plantillas en `/docs`, scripts en la raíz y `PRD.md` de partida. Salta al paso 2.
87
+
88
+ ```text
89
+ 1. Prepara el proyecto nuevo
90
+ ├── bootstrap.py + task_generator.py en la raíz
91
+ ├── /docs con las 8 plantillas maestras
92
+ ├── (opcional) RAG_VECTOR_EXTENSION.md dentro de /docs si habrá búsqueda semántica
93
+ └── PRD.md en la raíz
94
+
95
+ 2. python bootstrap.py → Fase M0 automática
96
+ Genera CONTEXT.md, PROGRESS.md, progress.json, DECISIONS.md,
97
+ activa las plantillas y emite .github/workflows/harness.yml
98
+
99
+ 3. Abre tu agente con la carpeta → inicia la entrevista (M1)
100
+ El agente lee CONTEXT.md y NO programa nada todavía.
101
+
102
+ 4. Aprueba SPEC.md, pega la tabla F0-Fn en PROGRESS.md y compila:
103
+ python task_generator.py --sync → valida el estado en progress.json
104
+ python task_generator.py → genera la tarea de la fase pendiente
105
+ ```
106
+
107
+ > 📖 Guía detallada paso a paso: **[INSTRUCCIONES DE APLICACION.txt](INSTRUCCIONES%20DE%20APLICACION.txt)** · Protocolo completo: **[INICIO_PROYECTO.md](INICIO_PROYECTO.md)**
108
+
109
+ ---
110
+
111
+ ## 📁 Mapa de archivos
112
+
113
+ | Archivo | Qué es |
114
+ |---|---|
115
+ | 🧭 `INICIO_PROYECTO.md` | **Fuente de verdad del protocolo**: rol del agente, fases, entrevista técnica, reglas de oro |
116
+ | ⚙️ `bootstrap.py` | Inicializador (M0): lee el PRD, genera `CONTEXT.md`/`PROGRESS.md`/`progress.json`/`DECISIONS.md`, activa plantillas y RAG si procede, y emite el CI de reglas de oro |
117
+ | 🤖 `task_generator.py` | Genera cada `TASK-Fx.md`, compila/valida el estado (`--sync`, `--check`) y registra aprobaciones (`--approval`) |
118
+ | 📦 `fia_harness/` + `pyproject.toml` | Paquete PyPI: `fia-harness init` (CLI instalador). Las copias de scripts/plantillas del paquete están vigiladas por tests de sincronización |
119
+ | 🗃️ `progress.json` | Estado compilado y validado del proyecto: la máquina de verdad que lee el CI |
120
+ | 📋 `TASK_TEMPLATE.md` | Plantilla maestra de tarea (ciclo completo A–L, 20 puntos de informe) |
121
+ | ⚡ `TASK_LITE_TEMPLATE.md` | Plantilla de tarea rápida para el Modo Lite |
122
+ | 🛡️ `SECURITY.md` | Checklist de seguridad **obligatorio en todo proyecto**: auth/2FA, RLS, secretos, firewall, Skills/MCP, prompt injection |
123
+ | 🔎 `AEO_GEO_SEO.md` | Visibilidad en tres motores: SEO (buscadores), AEO (asistentes) y GEO (LLMs) — solo si hay superficie pública |
124
+ | 🎨 `UI_UX_EXCLUSIVA.md` | Design DNA, arquetipos, motion system y auditoría anti-clon |
125
+ | 🔌 `SKILLS_MCP.md` | Gobernanza de capacidades: nada se busca/instala/conecta sin **aprobación humana explícita** |
126
+ | ⚡ `QUICKSTART_LITE.md` | Protocolo reducido para prototipos, con promoción obligatoria si aparece riesgo |
127
+ | 🧩 `PROYECTOS RAG Y VECTORIALES/` | Módulo de extensión: stack vectorial (pgvector/Pinecone/Qdrant), chunking, recuperación híbrida + reranking, `llms.txt` |
128
+ | 🧪 `tests/test_harness.py` | Tests automatizados de los parsers y del ciclo completo |
129
+ | 📜 `CHANGELOG_FIXES.md` | Historial de correcciones aplicadas y cómo se verificaron |
130
+
131
+ ---
132
+
133
+ ## ⚡ Dos modos de trabajo
134
+
135
+ | | 🔵 **Completo** | ⚡ **Lite** |
136
+ |---|---|---|
137
+ | Para | MVPs, productos reales | Prototipos, vertical slices, cambios acotados |
138
+ | Documentación | `CONTEXT` + `SPEC` + `PROGRESS` + `DECISIONS` | Solo `QUICK_CONTEXT.md` |
139
+ | Tareas | `TASK-Fx.md` desde `TASK_TEMPLATE.md` | `TASK-QUICK.md` desde `TASK_LITE_TEMPLATE.md` |
140
+ | Seguridad, aprobación humana, Context7 | ✅ Siempre | ✅ Siempre (no se negocian) |
141
+
142
+ **Promoción automática a Completo** si aparece cualquiera de estos: auth/roles, pagos, PII/salud, migraciones críticas, escritura en servicios externos, deploy/secretos, alcance incierto. La promoción **conserva** el trabajo ya validado.
143
+
144
+ > Para activar Lite: declara `Modo de trabajo: Lite` en `CONTEXT.md` (lo detecta `task_generator.py` solo) o fuerza con `--lite`.
145
+
146
+ ---
147
+
148
+ ## 🧩 Módulos condicionales
149
+
150
+ El harness base es común; estas capas se activan solo cuando el proyecto las necesita:
151
+
152
+ | Condición | Módulo que se activa |
153
+ |---|---|
154
+ | El PRD menciona RAG, embeddings, búsqueda semántica o memoria vectorial | `RAG_VECTOR_EXTENSION.md` — *bootstrap.py lo detecta y copia solo* |
155
+ | Hay páginas públicas indexables (landing, blog, docs) | `AEO_GEO_SEO.md` + Fase H2 en las tareas de contenido |
156
+ | Hay interfaz de usuario | `UI_UX_EXCLUSIVA.md` + Design DNA aprobado antes de implementar |
157
+ | El proyecto es multi-agente | `AGENTS.md` con roles y protocolo de handoff |
158
+
159
+ ---
160
+
161
+ ## 🚨 Enforcement: las reglas tienen dientes *(nuevo en v2)*
162
+
163
+ Un harness de documentos obliga por convención; este kit desde la v2 obliga también por infraestructura. `bootstrap.py` emite un workflow de GitHub Actions (`.github/workflows/harness.yml`) que se ejecuta en cada push y PR:
164
+
165
+ | Regla de oro | Cómo se hace cumplir mecánicamente |
166
+ |---|---|
167
+ | Nunca cerrar fases con dependencias abiertas (nº4) | `progress.json` validado: cerrar F2 con F1 abierta **rompe el build** |
168
+ | Nunca cerrar una fase sin Definition of Done (nº5) | Toda fase `done` exige su checkpoint de contexto en `PROGRESS.md` |
169
+ | Nunca ejecutar una fase sin su `TASK-Fx.md` (nº7) | El validador comprueba que `TASK-F<N>.md` exista para cada fase F cerrada |
170
+ | Nunca hacer commit con secretos (nº8) | **gitleaks** escanea todo el historial en cada push |
171
+ | Dependencias sin vulnerabilidades conocidas | `npm audit` / `pip-audit` según el stack detectado |
172
+ | Tests obligatorios antes de dar una fase por cerrada | Job de CI con pytest/unittest o `npm test`, según lo que detecte |
173
+ | Aprobaciones humanas rastreables | Toda `APPROVAL-NNN` citada en una TASK debe existir en `DECISIONS.md` |
174
+
175
+ El flujo de estado: `PROGRESS.md` sigue siendo la superficie de edición (humano o agente), y `task_generator.py --sync` lo compila y valida en `progress.json`. Si editas el Markdown a mano y no compila, el CI se pone rojo hasta que hagas `--sync`. Y `--sync` es *fail-closed*: si el estado viola una regla, **no escribe nada**.
176
+
177
+ ```bash
178
+ python task_generator.py --sync # compila y valida PROGRESS.md -> progress.json
179
+ python task_generator.py --check # valida sin modificar nada (lo ejecuta el CI)
180
+ python task_generator.py --approval "instalar Skill X v1.2" --phase F2 --ref "chat 5-sep"
181
+ ```
182
+
183
+ ---
184
+
185
+ ## 🛡️ Las reglas que nunca se rompen
186
+
187
+ 1. 🚫 **Nunca codificar sin spec aprobada** — ni una línea antes del M3.
188
+ 2. 🗣️ **Nunca asumir en silencio** — toda asunción se declara y se confirma.
189
+ 3. 📦 **Nunca reenviar contexto innecesario** — los archivos de control son la fuente comprimida.
190
+ 4. ✅ **Nunca cerrar una fase sin su Definition of Done** — ni mezclar fases.
191
+ 5. 🔐 **Nunca cerrar una fase de seguridad sin su checklist** — la seguridad no se pospone a un audit final.
192
+ 6. 🙋 **Nunca instalar/buscar/conectar una Skill, MCP o librería sin aprobación humana** — el silencio no es permiso.
193
+ 7. 🧪 **Nunca inventar resultados** — los tests que no se ejecutaron no existen.
194
+ 8. 🛑 **Nunca hacer commit/push/deploy sin autorización explícita.**
195
+
196
+ > 🚨 Desde la v2, las reglas 4, 5, 7 y 8 además se **verifican automáticamente en CI** en cada proyecto que arranca con `bootstrap.py` (sección anterior).
197
+
198
+ ---
199
+
200
+ ## ✅ Verificar el kit
201
+
202
+ ```bash
203
+ python -m unittest discover tests -v
204
+ ```
205
+
206
+ Los tests cubren el parser de `PROGRESS.md` (tablas múltiples, negritas, columnas combinadas), la extracción de secciones con tablas reales, los inyectores por marcadores, la heurística de palabras clave (incluido el falso positivo clásico de *"entre**vista**"*), el recorte de plantilla, la detección de Modo Lite, la **máquina de estado** (dependencias, checkpoints, TASKs, aprobaciones, drift y fail-closed) y un **ciclo completo e2e** (`bootstrap.py` → `task_generator.py`) en carpeta temporal.
207
+
208
+ En un proyecto ya arrancado, puedes comprobar su estado en cualquier momento:
209
+
210
+ ```bash
211
+ python task_generator.py --check
212
+ ```
213
+
214
+ ---
215
+
216
+ ## 📜 Documentación y fuentes de verdad
217
+
218
+ | Documento | Rol |
219
+ |---|---|
220
+ | `README.md` *(este archivo)* | Índice y visión general del sistema |
221
+ | `INICIO_PROYECTO.md` | **Fuente de verdad del protocolo** — si algo diverge, manda este |
222
+ | `INSTRUCCIONES DE APLICACION.txt` | Guía rápida de arranque paso a paso |
223
+ | `guia-automatizacion-tareas.md` | Guía del generador de tareas |
224
+ | `PROTOCOLO DE GESTION....txt` | Síntesis ejecutiva (lectura rápida, no se actualiza con cada cambio) |
225
+ | `Guia_arranque_del_proyecto.pdf` | Snapshot estático de la guía para lectura cómoda |
226
+ | `CHANGELOG_FIXES.md` | Qué se corrigió, por qué y cómo se verificó |
@@ -0,0 +1,9 @@
1
+ """FIA Harness — kit local de especificación, control de fases y enforcement
2
+ para desarrollo con agentes de IA.
3
+
4
+ Paquete de instalación (PyPI): `uvx fia-harness init` monta un proyecto nuevo
5
+ con las plantillas del kit en /docs, los scripts en la raíz y un PRD.md de
6
+ partida. Cero dependencias, Python 3.8+.
7
+ """
8
+
9
+ __version__ = "2.0.0"
@@ -0,0 +1,154 @@
1
+ """fia-harness CLI — instalador del kit (PyPI).
2
+
3
+ `fia-harness init` monta un proyecto nuevo con la misma estructura que describe
4
+ `INSTRUCCIONES DE APLICACION.txt`: plantillas del kit en /docs, los dos scripts
5
+ en la raíz y un `PRD.md` de partida. Igual que el resto del kit: solo librería
6
+ estándar, idempotente (nunca sobrescribe lo que ya existe) y sin telemetría.
7
+ """
8
+
9
+ import argparse
10
+ import shutil
11
+ import sys
12
+ from pathlib import Path
13
+
14
+ from fia_harness import __version__
15
+
16
+ PACKAGE_DIR = Path(__file__).resolve().parent
17
+ DATA_DIR = PACKAGE_DIR / "data"
18
+ TEMPLATES_DIR = DATA_DIR / "templates"
19
+ SCRIPTS_DIR = DATA_DIR / "scripts"
20
+ RAG_DIR = DATA_DIR / "rag"
21
+
22
+ TEMPLATE_NAMES = [
23
+ "INICIO_PROYECTO.md",
24
+ "SECURITY.md",
25
+ "AEO_GEO_SEO.md",
26
+ "UI_UX_EXCLUSIVA.md",
27
+ "SKILLS_MCP.md",
28
+ "TASK_TEMPLATE.md",
29
+ "TASK_LITE_TEMPLATE.md",
30
+ "QUICKSTART_LITE.md",
31
+ ]
32
+
33
+ SCRIPT_NAMES = ["bootstrap.py", "task_generator.py"]
34
+
35
+ RAG_NAME = "RAG_VECTOR_EXTENSION.md"
36
+
37
+ DEFAULT_FOLDERS = ["src", "tests", "docs", "infra"]
38
+
39
+ PRD_STUB = """# <Nombre del Proyecto>
40
+
41
+ > ✏️ **PRD de partida generado por `fia-harness init`.** Completa cada sección
42
+ > antes de aprobar la Fase 1 (entrevista técnica). Si dejas esta plantilla tal
43
+ > cual, el bootstrap te avisará de los campos sin confirmar.
44
+
45
+ ## Problema
46
+
47
+ ✏️ Describe el problema de negocio que resuelve tu producto.
48
+
49
+ ## Usuarios
50
+
51
+ ✏️ ¿Quiénes son los usuarios finales? ¿Qué perfil, cuántos, qué frecuencia?
52
+
53
+ ## Funcionalidades (Must Have)
54
+
55
+ * ✏️ Funcionalidad imprescindible nº1.
56
+ * ✏️ Funcionalidad imprescindible nº2.
57
+
58
+ ## Fuera de alcance (Out of Scope)
59
+
60
+ * ✏️ Lo que explícitamente NO entra en esta versión.
61
+ """
62
+
63
+
64
+ def _print_banner():
65
+ print(f"======================================================================")
66
+ print(f" 🚀 FIA HARNESS v{__version__} — INSTALADOR DE PROYECTOS (init)")
67
+ print(f"======================================================================")
68
+
69
+
70
+ def copy_if_absent(source: Path, target: Path, label: str) -> None:
71
+ """Copia `source` a `target` si no existe: el kit nunca pisa lo tuyo."""
72
+ if target.exists():
73
+ print(f" [.] Ya existe (no sobrescrito): {label}")
74
+ return
75
+ shutil.copy2(source, target)
76
+ print(f" [+] {label}")
77
+
78
+
79
+ def run_init(target_dir: Path) -> int:
80
+ _print_banner()
81
+
82
+ for folder in DEFAULT_FOLDERS:
83
+ folder_path = target_dir / folder
84
+ if not folder_path.exists():
85
+ folder_path.mkdir(parents=True, exist_ok=True)
86
+ print(f" [+] Creada carpeta: /{folder}")
87
+ else:
88
+ print(f" [.] Ya existe carpeta: /{folder}")
89
+
90
+ print("\n-> Copiando plantillas del kit a /docs ...")
91
+ for name in TEMPLATE_NAMES:
92
+ copy_if_absent(TEMPLATES_DIR / name, target_dir / "docs" / name, f"docs/{name}")
93
+ copy_if_absent(RAG_DIR / RAG_NAME, target_dir / "docs" / RAG_NAME,
94
+ f"docs/{RAG_NAME} (módulo RAG/vectorial opcional)")
95
+
96
+ print("\n-> Copiando los dos scripts del kit a la raíz ...")
97
+ for name in SCRIPT_NAMES:
98
+ copy_if_absent(SCRIPTS_DIR / name, target_dir / name, name)
99
+
100
+ print("\n-> Preparando PRD.md de partida ...")
101
+ prd_path = target_dir / "PRD.md"
102
+ if prd_path.exists():
103
+ print(" [.] PRD.md ya existe (no sobrescrito).")
104
+ else:
105
+ prd_path.write_text(PRD_STUB, encoding="utf-8")
106
+ print(" [+] PRD.md generado (complétalo antes de la Fase 1).")
107
+
108
+ print()
109
+ print("✅ Proyecto montado. Siguientes pasos:")
110
+ print(f" 1. Completa {target_dir / 'PRD.md'}")
111
+ print(f" 2. cd {target_dir} && python bootstrap.py (Fase M0)")
112
+ print(" 3. Abre tu agente con la carpeta: leerá CONTEXT.md y empezará la entrevista (M1).")
113
+ return 0
114
+
115
+
116
+ def _fix_windows_console_encoding():
117
+ """Evita UnicodeEncodeError (🚀/✅) en consolas Windows con codificación cp1252."""
118
+ for stream in (sys.stdout, sys.stderr):
119
+ if stream is None:
120
+ continue
121
+ try:
122
+ stream.reconfigure(encoding="utf-8", errors="replace")
123
+ except (AttributeError, ValueError, OSError):
124
+ pass
125
+
126
+
127
+ def main(argv=None) -> int:
128
+ _fix_windows_console_encoding()
129
+ parser = argparse.ArgumentParser(
130
+ prog="fia-harness",
131
+ description="FIA Harness: kit local de especificación y enforcement para agentes de IA.",
132
+ )
133
+ subparsers = parser.add_subparsers(dest="command", required=True)
134
+
135
+ init_parser = subparsers.add_parser(
136
+ "init",
137
+ help="Monta un proyecto nuevo: plantillas en /docs, scripts en la raíz y PRD.md.",
138
+ )
139
+ init_parser.add_argument(
140
+ "-d", "--dir", default=".",
141
+ help="Directorio de destino del proyecto (por defecto: el actual).",
142
+ )
143
+
144
+ args = parser.parse_args(argv)
145
+
146
+ if args.command == "init":
147
+ return run_init(Path(args.dir))
148
+
149
+ parser.print_help()
150
+ return 2
151
+
152
+
153
+ if __name__ == "__main__":
154
+ raise SystemExit(main())