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.
- package/AI/.gitignore.fragment +11 -0
- package/AI/.opencode/agents/analyst.md +29 -0
- package/AI/.opencode/agents/architect.md +28 -0
- package/AI/.opencode/agents/backend-cap.md +18 -0
- package/AI/.opencode/agents/deploy-cf.md +25 -0
- package/AI/.opencode/agents/documentarian.md +19 -0
- package/AI/.opencode/agents/e2e-fiori.md +61 -0
- package/AI/.opencode/agents/frontend-ui5.md +19 -0
- package/AI/.opencode/agents/harness-evolution.md +37 -0
- package/AI/.opencode/agents/orchestrator.md +40 -0
- package/AI/.opencode/agents/qa-review.md +27 -0
- package/AI/.opencode/agents/researcher.md +28 -0
- package/AI/.opencode/commands/flow.md +16 -0
- package/AI/.opencode/commands/verify.md +18 -0
- package/AI/.opencode/skills/cap-cli/SKILL.md +21 -0
- package/AI/.opencode/skills/mta-build/SKILL.md +45 -0
- package/AI/.opencode/skills/sap-cf-cli/SKILL.md +41 -0
- package/AI/.opencode/skills/sap-verify/SKILL.md +27 -0
- package/AI/AGENTS.md +263 -0
- package/AI/INICIO.md +74 -0
- package/AI/docs/cf-safe.md +107 -0
- package/AI/docs/flujo-etapas.md +22 -0
- package/AI/docs/habilitacion-trial.md +167 -0
- package/AI/opencode.fragment.jsonc +17 -0
- package/AI/scripts/cdp-chrome.ps1 +146 -0
- package/AI/scripts/cf-safe-client.ps1 +61 -0
- package/AI/scripts/cf-safe-patterns.ps1 +48 -0
- package/AI/scripts/cf-safe.ps1 +209 -0
- package/AI/scripts/pre-commit-check.ps1 +49 -0
- package/AI/scripts/provision-espacio.template.ps1 +73 -0
- package/AI/specs/_template.md +41 -0
- package/LICENSE +21 -0
- package/README.md +184 -2
- package/VERSION +1 -0
- package/bin/harness-btp.js +65 -0
- package/install.ps1 +60 -0
- package/install.sh +48 -0
- package/package.json +14 -4
- 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
|
+
}
|