create-harness-btp 0.0.0-stage → 0.1.0

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.
Files changed (39) hide show
  1. package/AI/.gitignore.fragment +11 -0
  2. package/AI/.opencode/agents/analyst.md +29 -0
  3. package/AI/.opencode/agents/architect.md +28 -0
  4. package/AI/.opencode/agents/backend-cap.md +18 -0
  5. package/AI/.opencode/agents/deploy-cf.md +25 -0
  6. package/AI/.opencode/agents/documentarian.md +19 -0
  7. package/AI/.opencode/agents/e2e-fiori.md +61 -0
  8. package/AI/.opencode/agents/frontend-ui5.md +19 -0
  9. package/AI/.opencode/agents/harness-evolution.md +37 -0
  10. package/AI/.opencode/agents/orchestrator.md +40 -0
  11. package/AI/.opencode/agents/qa-review.md +27 -0
  12. package/AI/.opencode/agents/researcher.md +28 -0
  13. package/AI/.opencode/commands/flow.md +16 -0
  14. package/AI/.opencode/commands/verify.md +18 -0
  15. package/AI/.opencode/skills/cap-cli/SKILL.md +21 -0
  16. package/AI/.opencode/skills/mta-build/SKILL.md +45 -0
  17. package/AI/.opencode/skills/sap-cf-cli/SKILL.md +41 -0
  18. package/AI/.opencode/skills/sap-verify/SKILL.md +27 -0
  19. package/AI/AGENTS.md +263 -0
  20. package/AI/INICIO.md +74 -0
  21. package/AI/docs/cf-safe.md +107 -0
  22. package/AI/docs/flujo-etapas.md +22 -0
  23. package/AI/docs/habilitacion-trial.md +167 -0
  24. package/AI/opencode.fragment.jsonc +17 -0
  25. package/AI/scripts/cdp-chrome.ps1 +146 -0
  26. package/AI/scripts/cf-safe-client.ps1 +61 -0
  27. package/AI/scripts/cf-safe-patterns.ps1 +48 -0
  28. package/AI/scripts/cf-safe.ps1 +209 -0
  29. package/AI/scripts/pre-commit-check.ps1 +49 -0
  30. package/AI/scripts/provision-espacio.template.ps1 +73 -0
  31. package/AI/specs/_template.md +41 -0
  32. package/LICENSE +21 -0
  33. package/README.md +184 -2
  34. package/VERSION +1 -0
  35. package/bin/harness-btp.js +65 -0
  36. package/install.ps1 +60 -0
  37. package/install.sh +48 -0
  38. package/package.json +14 -4
  39. package/templates/AGENTS.pointer.md +3 -0
package/AI/AGENTS.md ADDED
@@ -0,0 +1,263 @@
1
+ # Harness MVP SAP BTP — Reglas del proyecto
2
+ > Nota portabilidad: verificado en Windows, adapta rutas a [TU_PC].
3
+
4
+ > Flujo reutilizable especificación → despliegue en SAP BTP Cloud Foundry,
5
+ > orquestado por OpenCode en este equipo Windows. El `AGENTS.md` global de
6
+ > `[TU_PC]\.config\opencode` sigue cargándose; en caso de conflicto,
7
+ > manda este archivo.
8
+
9
+ ## Herramientas: nombres intocables
10
+
11
+ | Uso | Comando | Notas |
12
+ |---|---|---|
13
+ | Cloud Foundry | `sap_cf` | `sap_cf.cmd` (ruta de instalación de Cloud Foundry CLI en [TU_PC]). |
14
+ | MTA build | `mbt` | Cloud MTA Build Tool (binario recuperado vía su propio `install.js`). |
15
+ | Cloudflare | `cf` | **Prohibido** usar `cf` para Cloud Foundry: ese comando es el CLI de Cloudflare en [TU_PC]. |
16
+
17
+ Ver skill local `sap-cf-cli` antes del primer comando CF del turno;
18
+ ver `mta-build` antes del primer build MTAR.
19
+
20
+ ## Destino Cloud Foundry conocido (sin secretos)
21
+
22
+ - Endpoint verificado: `[TU_ENDPOINT_CF]` (p. ej. `https://api.cf.<region>.hana.ondemand.com`;
23
+ registrar el valor real en la spec del MVP, nunca aquí).
24
+ - Org y espacio objetivo (ver `sap_cf target`;
25
+ no se transcriben aquí por higiene). Antes de **cada despliegue**, el
26
+ orquestador re-verifica endpoint/org/espacio contra la especificación del
27
+ MVP. Si no coinciden o no pueden deducirse, se pide solo el dato
28
+ indispensable y no se despliega.
29
+ - Despliegue MTA (`sap_cf deploy *.mtar`) requiere el plugin **multiapps**.
30
+ Antes de asumir su ausencia o instalarlo, verificar con `sap_cf plugins`
31
+ (lección: verificar siempre antes de asumir su ausencia).
32
+ Instalarlo solo cuando un MVP lo requiera (ver `mta-build`).
33
+ - Placeholders MTA a credenciales: antes de diseñar un placeholder, verificar
34
+ la forma real con una key temporal borrable (se documenta solo
35
+ instancia/key, nunca el secreto; se borra tras extraer lo necesario). Si el
36
+ deploy-service rechaza placeholders a keys anidadas (p. ej.
37
+ `credentials.oauth`), no reintentar el mismo placeholder: fallback =
38
+ binding nativo (`existing-service`) o destino MANUAL en cockpit registrado
39
+ como pendiente conocido con su causa (cero secretos en repo).
40
+ - No-go conocido: una instancia `integration-flow`
41
+ (`it-rt`) NO vale como `TokenServiceInstance` de un destino (`Invalid service
42
+ name [it-rt]...`); no diseñar ni reintentar destino versionado con ella.
43
+
44
+ ## Modelo híbrido MTA + CF CLI (regla irrestricta)
45
+
46
+ > El `.mta` hace lo suyo; los agentes hacen por CLI lo que el MTA no debe
47
+ > poseer. Objetivo: portar un MVP entre espacios/cuentas sin intervención
48
+ > humana salvo decisiones de coste/acceso.
49
+
50
+ | En MTA (`mta.yaml`) | Fuera del MTA (agentes por `sap_cf`, una vez por espacio) |
51
+ |---|---|
52
+ | `managed-service`: xsuaa, destination, html5-repo-host/runtime, todo lo que el deploy puede crear/actualizar | `existing-service`: bindings a instancias pre-existentes (p. ej. DIE trial, `it-rt` integration-flow), espacios, roles `SpaceDeveloper`, entitlements/cuotas |
53
+ | Keys DECLARADAS por nombre (`service-key: name:`); el deploy reutiliza la key existente del espacio, nunca la crea con secretos | Creación idempotente de espacio/instancias/roles vía `scripts/provision-<espacio>.ps1` (ver § Paisajes); cero secretos en repo, solo nombres |
54
+ | Destinos versionados con referencias por nombre (`TokenServiceInstanceName/KeyName`, `~{srv-api/srv-url}`); ninguna credencial literal | Lo que el deploy-service rechace (p. ej. placeholders a keys anidadas `credentials.oauth`) NO se reintenta igual: fallback = binding nativo o destino MANUAL en cockpit registrado como pendiente conocido con su causa |
55
+
56
+ - `sap_cf` siempre; `cf` prohibido (es Cloudflare en [TU_PC]).
57
+ - Keys rotadas por deploy (el deploy-service puede borrar la
58
+ `service-key` en cada deploy): el runtime NUNCA lee keys; solo binding/VCAP.
59
+ Las keys son solo de diseño (temporal borrable, solo nombre documentado).
60
+ - Ante URL aún desconocida en paisaje nuevo (p. ej. URL del iFlow de prd antes de desplegarlo): desplegar con placeholder deja la destination inoperativa en runtime pero NO rompe el deploy; se registra como `TODO(<paisaje>)` y se fija tras conocerla.
61
+ - `scripts/cf-safe.ps1` es el punto de entrada para toda lectura CF con secreto potencial (ver `docs/cf-safe.md`).
62
+
63
+ ## Paisajes .mtaext y pre-provisión idempotente
64
+
65
+ - Cada paisaje = un `<paisaje>.mtaext` en la raíz del MVP (`dev.mtaext`, `prd.mtaext`): `extends: <mta-id>`, overrides SOLO por paisaje (nombres de `existing-service`, `service-key`, URL del iFlow). `mta.yaml` guarda el default (= dev vivo). Cero secretos.
66
+ - Cadena de deploy: `sap_cf target -s <paisaje>` → `sap_cf deploy mta_archives/<mtar> -e <paisaje>.mtaext`. Sin `-e` no hay deploy multi-paisaje.
67
+ - Puerta `/verify` (etapa 7) exige en verde: `mbt mtad-gen -e <paisaje>.mtaext` por cada `.mtaext` afectado + target coincide con spec + instancia/key esperadas existen verificadas (comando o cockpit, nunca heredadas de notas).
68
+ - Persistencia efímera (p. ej. SQLite `:memory:` se vacía en cada redeploy/restart): la spec lo declara; el E2E resiembra tras cada deploy y ningún CA exige datos supervivientes salvo que la spec defina persistencia real.
69
+ - Pre-provisión: `scripts/provision-<espacio>.ps1` por paisaje no-dev, idempotente (cada paso comprueba y emite `SKIP:` si existe), NO despliega nada. Plantilla obligatoria: preflight de target (endpoint+org, aborta si no coinciden) → crea espacio si falta → guardia de marketplace (aborta antes de crear si falta un offering) → crea instancias solo si faltan → asigna rol solo si falta. Allowlist cerrada: `target, spaces, space-users, services, marketplace, create-space, create-service, set-space-role`. PROHIBIDO: `delete-*`, `unbind-*`, `purge-*`, `restage-*`. Usa `sap_cf` (nunca `cf`).
70
+
71
+ ## Flujo por etapas (`/flow <ruta-spec>`)
72
+
73
+ 0. Evaluación de la especificación → 1. Investigación → 2. Plan →
74
+ 3. Preparación → 4. Desarrollo → 5. Pruebas → 6. Correcciones →
75
+ 7. Revisión de despliegue (`/verify`) → 8. Despliegue →
76
+ 9. Git → 10. Documentación (+ cosecha de lecciones: `harness-evolution`
77
+ propone, el orquestador aplica tras revisión).
78
+
79
+ - Cada etapa tiene entregable verificable; el orquestador define el criterio
80
+ de avance en el plan y lo exige antes de continuar.
81
+ - Rigor proporcional al MVP: saltar etapas irrelevantes está permitido y se
82
+ registra; ejecutar builds/despliegues innecesarios, no.
83
+ - **Despliegue continuo en MVPs ya desplegados (ciclo
84
+ desplegar→probar→corregir, sin detenerse):** cuando se cumplan TODAS estas
85
+ condiciones, el orquestador NO se detiene en la etapa 7 a pedir orden de
86
+ despliegue, sino que encadena puerta (`/verify`) → despliegue
87
+ (`deploy-cf`) → E2E (`e2e-fiori`) → correcciones, con un máximo de 3
88
+ vueltas y presupuesto explícito por vuelta:
89
+ 1. El MVP tiene al menos un despliegue anterior con éxito al MISMO
90
+ endpoint/org/espacio, registrado en la spec;
91
+ 2. `sap_cf target` re-verificado coincide con la spec;
92
+ 3. El cambio no puede verificarse por completo en local (integraciones
93
+ que solo existen en SAP: DIE, iFlow, XSUAA, HTML5 Repo…) o el usuario
94
+ ordenó el despliegue.
95
+ Si las 3 se cumplen, desplegar es parte del alcance implícito: pararse
96
+ deja la mejora sin probar. El bucle termina en la
97
+ primera vuelta con E2E en verde; si se agotan las 3 vueltas o el
98
+ presupuesto, se entrega lo conseguido con evidencia y pendientes.
99
+ **El bucle se detiene igual y se pide decisión al usuario si:** el target
100
+ no coincide con la spec, la sesión CF caducó y exige re-login, aparece
101
+ coste/cuota fuera de trial/gratuito, el destino es productivo (no
102
+ trial/dev), o el usuario ordena parar. Primeros despliegues (sin
103
+ antecedente en la spec) siguen exigiendo confirmación explícita del
104
+ destino antes de la etapa 8.
105
+ - **Portar a otro espacio/cuenta (flujo estándar, sin humanos en el camino):**
106
+ `preflight` (target+spec+entitlements/`sap-verify` del plan en el espacio
107
+ nuevo) → `provision-<espacio>.ps1` (solo con orden explícita o antecedente
108
+ de deploy con éxito al mismo endpoint/org registrado en la spec) →
109
+ `/verify` (con `mtad-gen -e` del paisaje) → `deploy-cf`
110
+ (`-e <paisaje>.mtaext`) → `e2e-fiori`. Presupuesto: máx 15 min provision,
111
+ máx 3 vueltas deploy→e2e→fix como el bucle continuo. Parada con decisión
112
+ al usuario si: target no coincide, sesión exige re-login, falta
113
+ offering/entitlement, coste fuera de trial/gratuito, destino productivo, o
114
+ placeholder `TODO(<paisaje>)` bloquea el CA (se entrega con pendiente, no
115
+ se inventa la URL).
116
+ - **Autoridad con efecto:** `deploy-cf` sigue siendo el ÚNICO agente con
117
+ efecto deploy. `provision-<espacio>.ps1` también tiene efecto (crea
118
+ espacio/instancias/roles) y exige orden explícita del usuario O antecedente
119
+ de deploy con éxito al mismo endpoint/org registrado en la spec; sin una de
120
+ las dos, el orquestador solo lo propone, no lo ejecuta. Todo `provision`
121
+ deja evidencia (salida `SKIP:`/`CREATE:`) y registra instancias/keys creadas
122
+ solo por nombre en la spec.
123
+ - Paralelo solo en tareas realmente independientes; el orquestador integra y
124
+ revisa todo. No delega decisiones finales ni acepta cambios sin inspección.
125
+ - Éxito solo con evidencia observable (salida de comandos, app en estado
126
+ `started`, artefacto MTAR existente). Nunca declarar éxito por haber
127
+ lanzado un comando.
128
+ - Nunca imprimir tokens, contraseñas ni secretos en terminal, informes, logs
129
+ o prompts a subagentes. Autenticación por mecanismo interactivo/seguro.
130
+
131
+ ## Local frente a BAS
132
+
133
+ Este harness corre en Windows local ([TU_PC]). No presuponer que una instalación local
134
+ (`sap_cf`, `mbt`, Node, Java, Python) existe en un dev space
135
+ remoto de BAS, ni viceversa. `cds` y `ui5` CLIs no están instalados
136
+ globalmente: se instalan por proyecto cuando la especificación los exija.
137
+
138
+ ## Presupuesto anti-bloqueo (obligatorio para orquestador y subagentes)
139
+
140
+ Ninguna tarea puede consumir tiempo ilimitado. Reglas:
141
+
142
+ - Toda delegación con `subagent` incluye **presupuesto explícito** (minutos
143
+ o nº de acciones) proporcional a la tarea; p. ej. una validación en
144
+ navegador: 15 min.
145
+ - **Prohibido reintentar en bucle**: si la misma acción falla 3 veces, se
146
+ para y se reporta como bloqueo de entorno con evidencia, no se insiste.
147
+ - Al agotar el presupuesto: **entrega parcial + cierre limpio** (matar solo
148
+ procesos propios por PID, borrar perfiles temporales). El orquestador
149
+ sigue con la evidencia parcial; nunca se deja una sesión "trabajando" sin
150
+ entregable.
151
+ - El orquestador que detecte una sesión atascada le envía UNA orden de
152
+ entrega inmediata; si no responde, cierra sus recursos externos por PID y
153
+ continúa sin ella, registrando el incidente.
154
+
155
+ ## Disciplina de shell y CLIs (lecciones 2026-10-29)
156
+
157
+ PowerShell 5.1, no bash. Prohibidos `ver`, `head`, `tail`, `where <args>`,
158
+ `grep` como comando: usar `Get-Command`, `Select-Object -First/-Last`,
159
+ `Select-String`. Todo comando con sintaxis nueva se prueba aislado antes de
160
+ encadenarlo en pipes.
161
+
162
+ - `cds` CLI: solo vía `npx -p @sap/cds-dk cds ...` (el paquete del proyecto
163
+ no trae el CLI). Ver skill `cap-cli`. Nunca adivinar nombres de paquetes
164
+ npm: verificar con `context7` o `npm view` antes de `npx`/`npm i`.
165
+ - Reparación de `mbt` verificada: `node install.js cloud-mta-build-tool`
166
+ en el directorio del paquete (no `mbt` a secas). Ver skill `mta-build`.
167
+ `mbt` exige además `make` en `%PATH%` (si falla `exec: "make": executable
168
+ file not found`, anteponer un `bin` con `make` al `$env:PATH` solo para
169
+ el comando; no persiste entre sesiones).
170
+ - Nunca `npm audit fix --force` sin revisión: reportar vulnerabilidades a
171
+ `qa-review`.
172
+ - Artefactos transitorios (regla de entorno): todo lo que
173
+ un agente genere y sirva solo temporalmente (capturas de pruebas, builds,
174
+ dumps de consola/red, perfiles CDP) va en `temp/<tarea>/`, nunca en la raíz
175
+ ni dentro del repo del MVP (`temp/` está ignorado). El orquestador incluye
176
+ la ruta `temp/<tarea>/` en cada delegación que implique tests, builds o
177
+ navegador; la evidencia que deba conservarse se mueve a `evidencia/` con su
178
+ referencia en docs. Al cerrar la tarea se borra lo transitorio.
179
+ - El target CF puede cambiar entre sesiones: re-verificar `sap_cf target`
180
+ en cada puerta y registrar el cambio en la spec antes de desplegar.
181
+ - Higiene de navegador y CDP (regla irrestricta, ver § Higiene obligatoria de
182
+ navegador y CDP): matar procesos solo por PID con filtro de perfil temporal
183
+ propio (`CommandLine -like '*<perfil>*'`); prohibido `Stop-Process -Name chrome`
184
+ o kills por nombre. Los subagentes llevan time-box explícito y, si lo superan,
185
+ se cierra su navegador y se sigue con su evidencia parcial.
186
+ - Índices de conocimiento: `codebase-memory` local antes que lectura amplia;
187
+ `graphify-code` local tras cambios commiteados si está `connected`. Sin
188
+ reindexación redundante en ambos en el mismo turno.
189
+
190
+ ## Higiene obligatoria de navegador y CDP (regla irrestricta)
191
+
192
+ Toda tarea que use navegador (`playwright` o `chrome-devtools`, en pruebas o
193
+ implementación) cumple este protocolo sin excepciones. Fuente única: esta
194
+ sección + `scripts/cdp-chrome.ps1`. Causa raíz conocida: el MCP
195
+ `playwright` está configurado con `--cdp-endpoint http://localhost:9222` y
196
+ **solo se conecta, no lanza navegador**; nadie levantaba el host CDP, de ahí
197
+ el `ECONNREFUSED`. `chrome-devtools` usa canal propio y no necesita `:9222`.
198
+
199
+ 1. **Antes (verificación previa):** comprobar el puerto con
200
+ `scripts/cdp-chrome.ps1 status`. Para `playwright`, ejecutar `ensure`:
201
+ reutiliza el endpoint si responde; si el puerto lo ocupa un proceso
202
+ ajeno, **detenerse, no matarlo**, e informar; si está libre, lanza Chrome
203
+ headless propio con perfil temporal y verifica `/json/version` con
204
+ reintentos (máx 3: 1 s/2 s/4 s). Sin endpoint verificado no hay prueba
205
+ con navegador que dar por hecha: reportarlo y seguir con el resto.
206
+ 2. **Durante:** trabajar headless por defecto (sin ventana salvo petición
207
+ explícita). No abrir navegadores fuera del protocolo.
208
+ **Excepción — E2E con login de usuario:** si la app exige autenticación
209
+ interactiva (XSUAA/IdP) que solo el usuario puede completar, `e2e-fiori`
210
+ se invoca igual con navegador VISIBLE (`headed`, perfil temporal propio)
211
+ para que el usuario se autentique en su ventana y luego continúa; espera
212
+ acotada al login manual (máximo definido en la delegación, sin reintentos
213
+ en bucle) y el agente nunca pide ni registra credenciales. El orquestador
214
+ avisa al usuario ANTES de abrir el navegador (2026-10-31: avisar tarde
215
+ = 5 min perdidos). Ante muro de
216
+ login, `e2e-fiori` deja veredicto formal `BLOQUEADO`-con-evidencia
217
+ (captura + URL + punto alcanzado) salvo orden contraria del usuario;
218
+ nunca se omite en silencio.
219
+ 3. **Después (limpieza):** al terminar la sesión de navegador o la tarea,
220
+ ejecutar `scripts/cdp-chrome.ps1 cleanup` (mata **solo** procesos propios
221
+ verificados por PID + perfil, borra el perfil temporal) y, con
222
+ `chrome-devtools`, cerrar las páginas abiertas. Verificar puerto libre.
223
+ Sin limpieza verificada no se cierra la tarea.
224
+ 4. **Evidencia:** el cierre informa salida de `ensure`/`cleanup` (o de
225
+ `status` si no se usó navegador) + qué quedó pendiente.
226
+
227
+ ## MCP y skills: selección por fase
228
+
229
+ - `context7` (`resolve-library-id` → `query-docs`): docs de CAP, UI5, CF CLI,
230
+ MTA y cualquier librería antes de suponer APIs. Lo usan `researcher` y los
231
+ especialistas. Ante un error de servicio con código (p. ej. EP003) o un
232
+ payload dudoso, contrastar el payload contra el tutorial oficial vigente +
233
+ el error real antes de asumir; las docs viejas o el scaffold no mandan.
234
+ - `codebase-memory`: contexto del índice cuando el MVP viva en un proyecto
235
+ indexado (`index_status`/`detect_changes` para frescura al arrancar;
236
+ `index_repository` tras cambios si hay novedades); nada que asumir si
237
+ puede recuperarse del grafo. `graphify-code` local como complemento
238
+ cuando esté `connected` (ver `opencode.jsonc`); índice local por defecto,
239
+ sin reindexar redundante en ambos en el mismo turno.
240
+ - `github`: solo si la especificación pide repo remoto/PR. Sin spec que lo
241
+ pida, trabajo local.
242
+ - `eslint`: calidad estática en código JS/TS del MVP.
243
+ - `playwright` / `chrome-devtools`: validación en navegador de UIs Fiori
244
+ cuando el MVP la incluya; `playwright` exige host CDP externo
245
+ (`scripts/cdp-chrome.ps1 ensure` antes, `cleanup` después; nunca dar UI
246
+ por hecha solo porque compila ni sin endpoint verificado).
247
+ - Skills globales en su fase, sin cargar todas: `sapui5` con `frontend-ui5`;
248
+ `systematic-debugging` ante fallos; `verification-before-completion` con
249
+ `qa-review`; `test-driven-development` si la spec exige TDD; `git-workflow`
250
+ con Git. Skills externas SAP (ver `INICIO.md § Skills candidatas`) solo se
251
+ adoptan si la spec las necesita, tras inspección previa.
252
+
253
+ ## Git
254
+
255
+ - Regla permanente: **ningún secreto en Git** (credenciales, tokens,
256
+ `.env`, `default-services` con claves, archivos de auth). Revisar diff y
257
+ estado de ignorados antes de cualquier operación Git.
258
+ - No inicializar repo ni conectar remotos salvo que la especificación lo pida.
259
+ - Commits locales solo cuando correspondan al proyecto. Nunca `push`,
260
+ publicar repos ni abrir PR salvo petición expresa de la especificación o
261
+ del usuario.
262
+ - Si el repo del MVP tiene CI con workflows: ningún merge a `main` se da por
263
+ hecho sin CI en verde verificado en terminal (`gh pr checks <n> --watch`).
package/AI/INICIO.md ADDED
@@ -0,0 +1,74 @@
1
+ # Guía de inicio — Harness MVP SAP BTP
2
+
3
+ > Nota portabilidad: verificado en Windows, adapta rutas a [TU_PC].
4
+
5
+ Entorno local Windows para llevar MVPs SAP de especificación a despliegue en
6
+ Cloud Foundry, con OpenCode como orquestador.
7
+
8
+ ## Estado verificado (Windows, [TU_PC])
9
+
10
+ | Herramienta | Resultado |
11
+ |---|---|
12
+ | `sap_cf --version` | CF CLI, sesión activa contra `[TU_ENDPOINT_CF]` |
13
+ | `mbt --version` | Cloud MTA Build Tool (binario recuperado; el `install.js` del paquete npm pedía `cloud-mta-build-tool`, no `mbt`) |
14
+ | `node` / `npm` | versión instalada en [TU_PC] |
15
+ | `java` | versión instalada en [TU_PC] — sirve para builds MTA Java si la spec los pide |
16
+ | `cf` | CLI de Cloudflare — no usar para Foundry |
17
+ | OpenCode | agente `orchestrator` por defecto (este proyecto) |
18
+ | MCP heredados (global) | `context7`, `codebase-memory`, `github`, `playwright`, `eslint`, `chrome-devtools` |
19
+ | Skill instalada útil | `sapui5` (global) |
20
+ | Pendiente (a propósito) | CLIs `cds`/`ui5`, skills SAP externas — se instalan solo si una spec los exige. Plugin CF `multiapps`: verificar con `sap_cf plugins` antes de asumir |
21
+
22
+ ## Cómo proporcionar una especificación
23
+
24
+ 1. Copia `specs/_template.md` a `specs/<nombre-mvp>.md` y rellénala
25
+ (objetivo, tipo UI5/CAP/MTA, destino BTP, servicios, criterios de
26
+ aceptación, fuera de alcance).
27
+ 2. El destino BTP (endpoint/org/espacio) debe figurar en la spec o
28
+ confirmarse cuando el orquestador lo pida. Sin destino confirmado no hay
29
+ despliegue.
30
+
31
+ ## Cómo iniciar el flujo
32
+
33
+ ```
34
+ /flow specs/<nombre-mvp>.md
35
+ ```
36
+
37
+ El orquestador ejecuta las etapas 0–10 de `AGENTS.md` (evaluación,
38
+ investigación, plan, preparación, desarrollo, pruebas, correcciones,
39
+ revisión de despliegue, despliegue, Git, documentación) con rigor
40
+ proporcional al tamaño del MVP. Comando de apoyo:
41
+
42
+ ```
43
+ /verify — puerta de despliegue: re-verifica target, artefacto y criterios
44
+ sin desplegar
45
+ ```
46
+
47
+ ## Comandos locales de referencia
48
+
49
+ ```
50
+ sap_cf target # endpoint/org/espacio actuales (sin secretos)
51
+ sap_cf apps # estado observable tras desplegar
52
+ sap_cf logs <app> --recent
53
+ mbt build # genera .mtar en mta_archives/ (requiere mta.yaml)
54
+ ```
55
+
56
+ Nunca `cf ...` para Foundry. Nunca pegar tokens en terminal ni en specs.
57
+
58
+ ## Lecturas CF seguras (broker cf-safe)
59
+
60
+ Toda lectura CF con secreto potencial vía `scripts/cf-safe.ps1`
61
+ (nunca `sap_cf` directo en agentes/scripts si la salida puede traer
62
+ credenciales). Detalle: `docs/cf-safe.md`.
63
+
64
+ ## Skills candidatas (no instaladas)
65
+
66
+ Inspeccionadas solo por procedencia; adoptar **únicamente** si
67
+ una spec las necesita, revisando antes su alcance y scripts de instalación:
68
+
69
+ - `sap-cap-capire` (sap-ai-skills.com) — CAP/CDS.
70
+ - `sap-btp-developer-guide` (secondsky) — fundamentos BTP/CAP.
71
+ - AI Skills Library (`skills.cloud.sap`, SAP SE) — CF CLI v8 y despliegue.
72
+ - Repositorio `secondsky/sap-skills` — BTP, CAP, Fiori, ABAP.
73
+
74
+ La skill global `sapui5` ya cubre frontend UI5/Fiori y tiene preferencia.
@@ -0,0 +1,107 @@
1
+ # cf-safe — broker determinista para Cloud Foundry
2
+
3
+ Punto único de salida hacia `sap_cf`. Fail-closed: nada ejecuta sin pasar
4
+ denylist → allowlist → validación de target.
5
+
6
+ Fuentes: `scripts/cf-safe.ps1` (cabecera, líneas 1-34), `scripts/cf-safe-patterns.ps1`,
7
+ `scripts/cf-safe-client.ps1`, `scripts/pre-commit-check.ps1`;
8
+ integración: `doc-extract-lab/scripts/provision-prd.ps1` (líneas 46-50).
9
+ Estado QA citado según brief del turno (no re-ejecutado aquí por restricción
10
+ de no-ejecución de este turno de documentación): sintaxis 5/5, WhatIf/DENY 7/7,
11
+ redacción 24/24. Sin E2E real contra CF todavía (pendiente).
12
+
13
+ ## Qué es
14
+
15
+ - `scripts/cf-safe.ps1`: broker. Recibe `-CfArgs`, valida, ejecuta solo
16
+ `sap_cf` (`sap_cf.cmd`, ruta fija) y devuelve UNA línea JSON
17
+ `{ok, exit, verb, redacted, rawLog, names, output}`.
18
+ - `scripts/cf-safe-patterns.ps1`: tabla central de redacción (6 regex +
19
+ marcador `***REDACTED***`, fail-closed: ante error devuelve el marcador,
20
+ nunca el original). Patrón de referencia: `doc-extract-lab/srv/lib/die-client.js`
21
+ (`redactDieSecrets`).
22
+ - `scripts/cf-safe-client.ps1`: cliente para scripts de provisión
23
+ (`Invoke-SapCfSeguro`; `New-TempServiceKey` es esqueleto BLOQUEADO,
24
+ sin efecto en este turno).
25
+ - `scripts/pre-commit-check.ps1`: chequeo pre-commit, bloquea secretos fuera
26
+ de `temp/` (whitelist: líneas con `***REDACTED***`).
27
+
28
+ ## Por qué (sin LLM ejecutor)
29
+
30
+ Ningún agente/LLM invoca `sap_cf` directamente para lecturas con secreto
31
+ potencial: el broker aplica las reglas de forma determinista (código, no
32
+ criterio del modelo). El LLM solo recibe `output` ya redactado y truncado;
33
+ el crudo nunca llega a stdout ni a prompts.
34
+
35
+ ## Uso
36
+
37
+ Lectura (sin flags):
38
+
39
+ ```powershell
40
+ powershell -ExecutionPolicy Bypass -File scripts/cf-safe.ps1 -CfArgs @('services')
41
+ # Formas equivalentes (sin comas ni @() bajo -File):
42
+ powershell -ExecutionPolicy Bypass -File scripts/cf-safe.ps1 -CfArgs services
43
+ powershell -ExecutionPolicy Bypass -File scripts/cf-safe.ps1 services
44
+ ```
45
+
46
+ Simulación sin ejecutar (omite validación de target):
47
+
48
+ ```powershell
49
+ powershell -ExecutionPolicy Bypass -File scripts/cf-safe.ps1 -CfArgs @('services') -WhatIf
50
+ ```
51
+
52
+ Desde un script de provisión (vía cliente, solo nombres, cero secretos):
53
+
54
+ ```powershell
55
+ . (Join-Path $PSScriptRoot '..\..\scripts\cf-safe-client.ps1')
56
+ Invoke-SapCfSeguro -CfArgs @('services') -ExpectedApi 'https://api.cf.us10-001.hana.ondemand.com'
57
+ ```
58
+
59
+ Regla: **toda lectura CF con secreto potencial vía cf-safe** (nunca
60
+ `sap_cf` directo en agentes/scripts cuando la salida pueda traer
61
+ credenciales: `env`, `service-key` con valores, `logs --recent`).
62
+
63
+ ## Allowlist / denylist y códigos
64
+
65
+ Orden: 1) binario fijo (`cf` de Cloudflare se rechaza) → 2) denylist →
66
+ 3) allowlist → 4) target → 5) ejecución.
67
+
68
+ - Denylist (exit 1): `delete-*`, `unbind-*`, `purge-*`, `restage-*`,
69
+ `set-env` sin `-AllowWrite`, `create-service-key` directo,
70
+ `service-key` con valores sin `-NeedValues` (y sin `-AllowWrite`),
71
+ inyección (`|`, `>`, `;`, backtick, `$()`).
72
+ - Allowlist lectura (sin flags): `target`, `apps`, `app`, `services`,
73
+ `service`, `marketplace`, `spaces`, `space-users`, `service-keys`
74
+ (solo nombres), `env` (redactado), `logs --recent` (redactado,
75
+ 200 líneas), `plugins`.
76
+ - Allowlist escritura (SOLO con `-AllowWrite`): `create-space`,
77
+ `create-service`, `set-space-role`, `target -o/-s`, `set-env`,
78
+ `service-key` con valores (exige además `-NeedValues`).
79
+ - Códigos: `0` ok / `1` deny-denylist / `2` fuera-de-allowlist /
80
+ `3` validación-target (endpoint/org no coinciden; `ExpectedOrg` vacío
81
+ = no valida org) / `4` error-ejecución.
82
+
83
+ ## Dónde van los crudos
84
+
85
+ - `output` (stdout JSON): redactado y truncado a 4000 caracteres.
86
+ - Crudo SOLO en `temp/cf-safe/*.raw.log`, nunca a stdout.
87
+ - `temp/` está ignorado (artefactos transitorios) y `pre-commit-check.ps1`
88
+ ignora todo bajo `temp/`; fuera de `temp/`, cualquier señal de secreto
89
+ sin `***REDACTED***` bloquea el commit (exit 1).
90
+
91
+ ## Integración provision y /verify
92
+
93
+ - `doc-extract-lab/scripts/provision-prd.ps1` importa
94
+ `scripts/cf-safe-client.ps1`: todas sus llamadas CF pasan por
95
+ `Invoke-SapCfSeguro` (denylist primero). Allowlist del provision cerrada
96
+ (ver `AGENTS.md` § Paisajes); `New-TempServiceKey` sigue esqueleto
97
+ bloqueado hasta diseño final de keys temporales.
98
+ - `/verify`: el broker valida `ExpectedApi`
99
+ (default `https://api.cf.us10-001.hana.ondemand.com`) y `ExpectedOrg`
100
+ antes de ejecutar; con `-WhatIf` la validación se omite (solo simulación).
101
+
102
+ ## Pendientes
103
+
104
+ - [ ] E2E real contra CF (veredicto con evidencia, sin secretos en repo).
105
+ - [ ] Instalación del hook pre-commit (`git config core.hooksPath .githooks`;
106
+ copiar `pre-commit-check.ps1` a `.githooks/pre-commit`).
107
+ - [ ] Pasar PSScriptAnalyzer a los 4 scripts.
@@ -0,0 +1,22 @@
1
+ # Flujo por etapas — entregables y criterios de avance
2
+
3
+ > Referencia única del ciclo. `AGENTS.md` manda; este documento lo detalla.
4
+ > El progreso de cada MVP se registra en su spec (§6) y en su informe de cierre.
5
+
6
+ | Etapa | Nombre | Ejecuta | Entregable verificable | Criterio de avance |
7
+ |---|---|---|---|---|
8
+ | 0 | Evaluación | `analyst` | Veredicto + supuestos + CA verificables | Spec completable; bloqueos con dato mínimo pedido |
9
+ | 1 | Investigación | `researcher` | Tabla fuente\|fecha\|evidencia (documentado/pendiente/coste) | Ninguna API/servicio supuesto sin fuente |
10
+ | 2 | Plan/Arquitectura | `architect` | Topología + esqueleto `mta.yaml` + planes verificados | Decisiones y descartes registrados; persistencia fijada |
11
+ | 3 | Preparación | orquestador | Scaffold + facets + deps instaladas + target CF confirmado | `cds version` OK; `sap_cf target` coincide con spec |
12
+ | 4 | Desarrollo | `backend-cap` + `frontend-ui5` | Modelo/servicios CAP + UI + mocks DIE/iFlow corriendo en local | CA1–CA3 observables con `cds watch` |
13
+ | 5 | Pruebas | `qa-review` | Resultado por CA (comando + salida real) | Sin rojo; vulnerabilidades del scaffold dictaminadas |
14
+ | 6 | Correcciones | especialistas | Fixes verificados | Plan de pruebas en verde |
15
+ | 7 | Revisión despliegue | `/verify` | Veredicto apto/no apto (target + artefacto + CA + Git limpio) | Solo "apto" permite etapa 8 |
16
+ | 8 | Despliegue | `deploy-cf` | Apps `started` + logs + evidencia (cockpit/URL) | CA4–CA5 con evidencia observable |
17
+ | 9 | Git | orquestador | Commits locales; remoto solo con autorización expresa | Sin secretos en diff; push/PR solo si la spec lo pide |
18
+ | 10 | Documentación | `documentarian` | Spec, inventario e informe de cierre al día | Hechos con fuente; pendientes marcados |
19
+
20
+ Rigor proporcional: en MVPs pequeños se pueden aligerar 5 (pruebas manuales
21
+ guiadas por CA) y diferir 9; nunca se saltan 0, 2, 7 ni 8. Paralelo solo en
22
+ tareas independientes; el orquestador integra y revisa todo cambio.
@@ -0,0 +1,167 @@
1
+ # Habilitación del trial — guía ordenada con justificación
2
+
3
+ > Paso a paso de todo lo configurado para el laboratorio `doc-extract-lab`
4
+ > el 2026-10-29. Cada sección explica **para qué sirve**, **cómo se
5
+ > configuró**, **casos de uso** y **cuándo usarlo**. Orden cronológico real
6
+ > de ejecución: seguirlo en este orden evita los errores que encontramos
7
+ > (p. ej. suscribir Document AI antes de tener IAS falla con `422`).
8
+
9
+ ## Paso 0. Verificar el entorno Cloud Foundry (lectura, sin cambios)
10
+
11
+ - **Para qué sirve.** Confirma contra qué org/espacio desplegará el MTA.
12
+ - **Cómo.** En el equipo local: `sap_cf target` (endpoint, org, espacio).
13
+ - **Casos de uso / cuándo.** Antes de cada despliegue y siempre que el
14
+ cockpit muestre un espacio con otro nombre (aquí: cockpit `dev` frente a
15
+ la sesión local). Si no coinciden, se ajusta el target en la puerta de
16
+ despliegue; nunca se despliega "a ver qué pasa".
17
+
18
+ ## Paso 1. Instancia HTML5 Application Repository (`HTML5_service`)
19
+
20
+ - **Para qué sirve.** Repositorio central de frontends HTML5 del espacio CF:
21
+ versiona los bundles UI5, los sirve con caché y rutas estables, y los
22
+ publica en la sección **HTML5 Applications** del cockpit.
23
+ - **Cómo se configuró.** Subcuenta `trial` → Services → Service Marketplace
24
+ → `HTML5 Application Repository Service` → Create → Plan **`app-host`** →
25
+ Runtime **Cloud Foundry** → Space **`dev`** → nombre `HTML5_service`.
26
+ - **Casos de uso.** Cualquier frontend Fiori/UI5 que deba vivir en el
27
+ cockpit y servirse vía App Router.
28
+ - **Cuándo usarlo.** Siempre que la app tenga UI propia (este MVP: CA5). Si
29
+ el MVP fuera solo API, se omite.
30
+
31
+ ## Paso 2. Instancia XSUAA (`XSUAA_service`)
32
+
33
+ - **Para qué sirve.** Broker OAuth2 propio de la aplicación: emite los JWT
34
+ con que el App Router crea la sesión de usuario y que el backend CAP
35
+ valida (`xsappname`, scopes).
36
+ - **Cómo se configuró.** Service Marketplace → `Authorization and Trust
37
+ Management Service` → Create → Plan **`application`** → CF → `dev` →
38
+ nombre `XSUAA_service`.
39
+ - **Por qué `application`.** `broker` es para multi-tenant con tenant
40
+ dinámico, `apiaccess` para API sin sesión de usuario, `space` delega en el
41
+ espacio: ninguno sirve al App Router gestionado.
42
+ - **Casos de uso / cuándo.** Toda app con login de usuarios o propagación de
43
+ identidad al backend. Se omite solo en MVPs 100 % anónimos o batch.
44
+
45
+ ## Paso 3. Instancia Document AI (`DAI_service`)
46
+
47
+ - **Para qué sirve.** API REST de extracción de datos desde documentos
48
+ (PDF, imágenes): recibe el archivo y devuelve JSON con los campos del
49
+ esquema entrenado.
50
+ - **Cómo se configuró.** Service Marketplace → `SAP Document AI Trial` →
51
+ Create → Plan **`default`** (gratuito del trial) → CF → `dev` → nombre
52
+ `DAI_service`. Estado final: `Usable`.
53
+ - **Por qué `default` y no `blocks_of_100`.** `blocks_of_100` consume
54
+ créditos de la cuenta; `default` respeta la restricción "solo trial".
55
+ - **Casos de uso.** Facturas, remitos, formularios: cualquier documento
56
+ semiestructurado del que haya que extraer campos.
57
+ - **Cuándo usarlo.** Cuando el volumen o la variabilidad de documentos hacen
58
+ inviable la carga manual o plantillas fijas.
59
+
60
+ ## Paso 4. Suscripción a la app `SAP Document AI`
61
+
62
+ - **Para qué sirve.** UI de gestión: crear/entrenar esquemas de extracción y
63
+ probar con documentos de ejemplo. La **instancia** (paso 3) da la API; la
64
+ **suscripción** da la consola.
65
+ - **Cómo se configuró.** Service Marketplace → `SAP Document AI` →
66
+ suscripción directa (plan `default`). **Falló al inicio** con `422 OIDC
67
+ trust missing` porque no existía tenant IAS → se resolvió tras los pasos
68
+ 6–7 y reintento.
69
+ - **Casos de uso / cuándo.** Siempre que se usen esquemas propios o haya que
70
+ inspeccionar resultados fuera del código. Si solo se consume un esquema
71
+ estándar vía API, es opcional.
72
+
73
+ ## Paso 5. Suscripción a Integration Suite (plan `trial`)
74
+
75
+ - **Para qué sirve.** Plataforma de integración: aquí vive el iFlow que
76
+ recibe el JSON extraído y simula la entrega al S/4HANA inexistente.
77
+ - **Cómo se configuró.** Service Marketplace → `Integration Suite` → plan
78
+ **`trial`** → suscribir. Estado final: `Subscribed`.
79
+ - **Casos de uso.** Conectar el MVP con sistemas SAP/no-SAP, transformar
80
+ mensajes, exponer APIs gestionadas.
81
+ - **Cuándo usarlo.** Cuando el flujo sale del BTP hacia otro sistema. Si el
82
+ MVP fuera autocontenido, se omite (o se deja como mock documentado).
83
+
84
+ ## Paso 6. Suscripción a Cloud Identity Services (tenant IAS)
85
+
86
+ - **Para qué sirve.** Crea el **tenant IAS propio** de la subcuenta: el
87
+ proveedor de identidad de los usuarios de negocio (login, grupos,
88
+ federación). Sin él, ninguna suscripción a aplicación con login funciona.
89
+ - **Cómo se configuró.** Service Marketplace → `Cloud Identity Services` →
90
+ Create → Plan **`default` de la sección Subscriptions**
91
+ (`sap-identity-services-onboarding`, NO `application` de Instances) →
92
+ parámetro **Service type: `TEST`** → Create → **activar la cuenta con el
93
+ email** que llega al admin (definir contraseña) → consola admin abierta.
94
+ - **Casos de uso.** Login de usuarios en Fiori, Work Zone y cualquier app
95
+ suscrita; base para federar con un IdP corporativo más adelante.
96
+ - **Cuándo usarlo.** Antes de suscribir la primera aplicación con usuarios
97
+ (paso 7). Es prerrequisito, no opcional.
98
+
99
+ ## Paso 7. Establecer confianza (Establish Trust) y reintentar
100
+
101
+ - **Para qué sirve.** Vincula la subcuenta con el tenant IAS vía **OpenID
102
+ Connect**, para que las apps deleguen el login en él. (SAML no vale para
103
+ Document AI.)
104
+ - **Cómo.** Subcuenta → Security → Trust Configuration → **Establish
105
+ Trust** → Choose Tenant: ya aparece el tenant creado en el paso 6 →
106
+ completar el wizard → luego Instances and Subscriptions → `SAP Document
107
+ AI` → `...` → **Retry** hasta `Subscribed`.
108
+ - **Cuándo.** Una vez por subcuenta, tras el paso 6 y antes de usar
109
+ cualquier app suscrita.
110
+ - **Estado 2026-10-29: resuelto.** Trust `Active` (origen `sap.custom`,
111
+ dominio `Default`); suscripción `SAP Document AI` en `Subscribed`.
112
+
113
+ ## Concepto clave: usuarios de plataforma frente a usuarios de negocio
114
+
115
+ El trial te da un **usuario de plataforma** (tu login, p. ej. el `HM` del
116
+ cockpit): administra la cuenta global —cockpit, `sap_cf`, crear
117
+ instancias— autenticado por el IdP por defecto de SAP. Ese usuario **no**
118
+ sirve para entrar a las aplicaciones desplegadas.
119
+
120
+ Los **usuarios de negocio** son quienes usan las apps (consola de Document
121
+ AI, tu Fiori vía App Router): se autentican contra un **tenant IAS** en el
122
+ que la subcuenta confía (pasos 6–7). Por eso hizo falta crear el tenant
123
+ aunque ya tuvieras usuario: son dos poblaciones distintas con dos IdP
124
+ distintos.
125
+
126
+ **Cuándo es pertinente crear el tenant IAS y la confianza:**
127
+
128
+ - Siempre que suscribas una **aplicación con login** (Document AI,
129
+ Work Zone, cualquier SaaS del marketplace).
130
+ - Siempre que tu app propia autentique usuarios (App Router + XSUAA con
131
+ `application` delega el login en este trust).
132
+ - Cuando necesites **roles y grupos de negocio** separados de los
133
+ administradores de plataforma.
134
+ - En productiva, además: para **federar tu IdP corporativo** (Azure AD,
135
+ etc.) como fuente de usuarios sin crearlos uno a uno.
136
+
137
+ **Cuándo NO hace falta:** MVPs de solo API con llaves de servicio, jobs
138
+ batch sin usuarios, o pruebas de conectividad máquina a máquina — ahí basta
139
+ con instancias y service keys.
140
+
141
+ ## Paso 8 (siguiente, aún no hecho). Role collections del usuario
142
+
143
+ - **Para qué sirve.** Autorizar a tu usuario en cada servicio (DIE,
144
+ Integration Suite, HTML5 Repo): sin roles, el acceso da 403 aunque todo lo
145
+ anterior esté verde.
146
+ - **Cómo (cuando toque).** Subcuenta → Security → Users → tu usuario →
147
+ asignar las role collections de cada servicio; o crear role collections a
148
+ medida. Se hará durante el `/flow` si algún acceso falla.
149
+ - **Cuándo.** Después del despliegue o al primer 403.
150
+ - **Incidencia 2026-10-29 (Integration Suite):** `Go to Application`
151
+ devuelve página en blanco `.../is-landing/v1.0/unauthorized` → falta
152
+ asignar `Integration_Provisioner` al usuario antes de `Add Capabilities`.
153
+ Si persiste tras asignarlo: (1) esperar 5–10 min por propagación y
154
+ reentrar en incógnito (token viejo en caché); (2) asignar el rol al
155
+ usuario de origen `sap.custom` (IAS), no solo al `sap.default` — la app
156
+ autentica contra el trust IAS; (3) comprobar que el usuario exista en la
157
+ consola IAS.
158
+
159
+ ## Mapa rápido decisión
160
+
161
+ | Mi MVP necesita… | Habilitar |
162
+ |---|---|
163
+ | UI Fiori en el cockpit | Pasos 0, 1 (+ 2 para login) |
164
+ | Login / identidad propagada | Pasos 2, 6, 7 |
165
+ | Extraer datos de documentos | Pasos 3 (+ 4 para consola) |
166
+ | Salir hacia otro sistema | Paso 5 |
167
+ | Solo API sin UI ni usuarios | Solo 0 (+ 3/5 según el caso) |
@@ -0,0 +1,17 @@
1
+ // Fragmento MCP para el proyecto destino. Fusionar en su `opencode.jsonc`.
2
+ // `graphify-code` viene DESHABILITADO por defecto: el índice vive en el
3
+ // proyecto (`AI/graphify-out/graph.json`, ruta relativa) y debe generarse
4
+ // tras instalar. Para activarlo:
5
+ // 1. Generar el índice del proyecto en `AI/graphify-out/graph.json`.
6
+ // 2. Poner `"enabled": true` en el bloque `graphify-code`.
7
+ // 3. Reiniciar OpenCode.
8
+ {
9
+ "mcp": {
10
+ "graphify-code": {
11
+ "type": "local",
12
+ "command": ["graphify-mcp", "--graph", "AI/graphify-out/graph.json"],
13
+ "cwd": ".",
14
+ "enabled": false
15
+ }
16
+ }
17
+ }