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.
- fia_harness-2.0.0/LICENSE +21 -0
- fia_harness-2.0.0/PKG-INFO +244 -0
- fia_harness-2.0.0/README.md +226 -0
- fia_harness-2.0.0/fia_harness/__init__.py +9 -0
- fia_harness-2.0.0/fia_harness/cli.py +154 -0
- fia_harness-2.0.0/fia_harness/data/rag/RAG_VECTOR_EXTENSION.md +84 -0
- fia_harness-2.0.0/fia_harness/data/scripts/bootstrap.py +573 -0
- fia_harness-2.0.0/fia_harness/data/scripts/task_generator.py +787 -0
- fia_harness-2.0.0/fia_harness/data/templates/AEO_GEO_SEO.md +88 -0
- fia_harness-2.0.0/fia_harness/data/templates/INICIO_PROYECTO.md +369 -0
- fia_harness-2.0.0/fia_harness/data/templates/QUICKSTART_LITE.md +147 -0
- fia_harness-2.0.0/fia_harness/data/templates/SECURITY.md +153 -0
- fia_harness-2.0.0/fia_harness/data/templates/SKILLS_MCP.md +155 -0
- fia_harness-2.0.0/fia_harness/data/templates/TASK_LITE_TEMPLATE.md +148 -0
- fia_harness-2.0.0/fia_harness/data/templates/TASK_TEMPLATE.md +319 -0
- fia_harness-2.0.0/fia_harness/data/templates/UI_UX_EXCLUSIVA.md +331 -0
- fia_harness-2.0.0/fia_harness.egg-info/PKG-INFO +244 -0
- fia_harness-2.0.0/fia_harness.egg-info/SOURCES.txt +23 -0
- fia_harness-2.0.0/fia_harness.egg-info/dependency_links.txt +1 -0
- fia_harness-2.0.0/fia_harness.egg-info/entry_points.txt +2 -0
- fia_harness-2.0.0/fia_harness.egg-info/top_level.txt +1 -0
- fia_harness-2.0.0/pyproject.toml +46 -0
- fia_harness-2.0.0/setup.cfg +4 -0
- fia_harness-2.0.0/tests/test_harness.py +576 -0
- fia_harness-2.0.0/tests/test_packaging.py +122 -0
|
@@ -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
|
+
|
|
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())
|