Skip to content

Commit 84cd212

Browse files
committed
Merge branch 'develop'
2 parents b5a5e4b + 016782b commit 84cd212

5 files changed

Lines changed: 243 additions & 3 deletions

File tree

docs/audit/tracker-gap-reference-catalog.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4012,7 +4012,7 @@ La prueba HTTP del bucle completo pasó a la primera, y al mutar la regla de aut
40124012

40134013
**Title:** Smoke test E2E vivo satélite↔Core como evidencia reproducible de cierre.
40144014

4015-
- **Status:** `IN-PROGRESS` (2026-07-21) — **REACTIVADO y en construcción como RoboSoft (decisión del PO).** RoboSoft realiza y supera esta oportunidad: una **flota de agentes de prueba determinísticos** que conducen el Tracker E2E contra el stack VIVO (`tracker-api` + `tracker-gateway` + Core real), ejercitando REST + las MCP tools del Core + `/converse`, **aseverando** y emitiendo **evidencia reproducible** (JSON + exit code para CI). **Hecho en este incremento:** el harness (`robosoft/`: `run.mjs`, `lib/config|client|report.mjs`) + el primer robot **`core-integration`** (capabilities, rulesets, MCP list+call, `evaluate` con round-trip real al Core, `/converse`). Diseño+uso en `robosoft/README.md`. Harness auto-probado (contra targets caídos: FAIL narrado, evidencia escrita, exit 1). **Pendiente (próximos robots):** `governance-journey` (funnel SDLC completo asertivo, reusando `seed/e2e-governance.mjs`), `provider-connections`, multi-persona, y wiring en CI contra el clúster kind. La verificación contra el clúster VIVO requiere levantar el entorno (port-forward) — documentado en el README. **✅ Validado en vivo 2026-07-21** contra `kind-evolith-cluster` (Core real: `evolith-core-api`+`evolith-mcp`+`evolith-runtime` y `tracker-gateway` desplegados; port-forward gateway :3000): **11/13 checks verde** — capabilities (`schemaVersion 1.0.0`, `supportedConsumers:[evolith_tracker,external]`), rulesets (3), **47 MCP tools**, MCP call (201 + content envelope), y **`evaluate` con veredicto REAL** (`success:true`, gates=1/failed=1, reglas `CLI-RR-*`). El robot se **endureció con lo aprendido en vivo**: desenvolver el `{success,data,meta}` del Core, aceptar `2xx` (NestJS POST → 201), heurística de tool read-only con separador `-`, y payload `evaluationInput.files` inline (el endpoint directo del Core NO usa `repositoryRef`). Los 2 checks rojos son `/converse` — **no hay `tracker-api` en este clúster** (honesto). **🔎 Primer hallazgo real de RoboSoft (señal soft):** el pod del Core no puede leer `rulesets/opa/policy.wasm` (`EACCES` → `FORBIDDEN`/ABAC), un hueco de **despliegue del Core** (cross-product, del board del Core, no del Tracker) que la interfaz surface pero el entorno bloquea.
4015+
- **Status:** `IN-PROGRESS` (2026-07-21) — **REACTIVADO y en construcción como RoboSoft (decisión del PO).** RoboSoft realiza y supera esta oportunidad: una **flota de agentes de prueba determinísticos** que conducen el Tracker E2E contra el stack VIVO (`tracker-api` + `tracker-gateway` + Core real), ejercitando REST + las MCP tools del Core + `/converse`, **aseverando** y emitiendo **evidencia reproducible** (JSON + exit code para CI). **Hecho en este incremento:** el harness (`robosoft/`: `run.mjs`, `lib/config|client|report.mjs`) + el primer robot **`core-integration`** (capabilities, rulesets, MCP list+call, `evaluate` con round-trip real al Core, `/converse`). Diseño+uso en `robosoft/README.md`. Harness auto-probado (contra targets caídos: FAIL narrado, evidencia escrita, exit 1). **Pendiente (próximos robots):** `governance-journey` (funnel SDLC completo asertivo, reusando `seed/e2e-governance.mjs`), `provider-connections`, multi-persona, y wiring en CI contra el clúster kind. La verificación contra el clúster VIVO requiere levantar el entorno (port-forward) — documentado en el README. **✅ Validado en vivo 2026-07-21** contra `kind-evolith-cluster` (Core real: `evolith-core-api`+`evolith-mcp`+`evolith-runtime` y `tracker-gateway` desplegados; port-forward gateway :3000): **11/13 checks verde** — capabilities (`schemaVersion 1.0.0`, `supportedConsumers:[evolith_tracker,external]`), rulesets (3), **47 MCP tools**, MCP call (201 + content envelope), y **`evaluate` con veredicto REAL** (`success:true`, gates=1/failed=1, reglas `CLI-RR-*`). El robot se **endureció con lo aprendido en vivo**: desenvolver el `{success,data,meta}` del Core, aceptar `2xx` (NestJS POST → 201), heurística de tool read-only con separador `-`, y payload `evaluationInput.files` inline (el endpoint directo del Core NO usa `repositoryRef`). Los 2 checks rojos son `/converse` — **no hay `tracker-api` en este clúster** (honesto). **🔎 Primer hallazgo real de RoboSoft (señal soft):** el pod del Core no puede leer `rulesets/opa/policy.wasm` (`EACCES` → `FORBIDDEN`/ABAC), un hueco de **despliegue del Core** (cross-product, del board del Core, no del Tracker) que la interfaz surface pero el entorno bloquea. **Segundo robot `governance-journey` construido y VALIDADO EN VIVO 2026-07-21** (tracker-api local contra `tracker-ci-pg`): conduce una iniciativa de tenant por el **funnel SDLC completo** —gate policies ×5 → product+repo satélite → opportunity → triage → promote → initiative (discovery-detail/scope/submit/approve) → **discovery→design→construction→qa→release**, las 5 compuertas `APPROVED`— **53/53 checks verde**. **Dos hallazgos más de RoboSoft:** (1) **el prefijo del tracker-api es `/api/v1`, no `/api`** — por eso `src/apps/tracker-api/seed/e2e-governance.mjs` está **stale y hoy da 404** (usa `/api/...`); RoboSoft corrigió su `apiPrefix`. (2) **CD-19 en acción:** `POST /core-verdict` registra un veredicto `attested` (auto-declarado) que **NUNCA satisface una compuerta**; solo la ruta probatoria `POST /gate-submissions/{id}/sync-core-verdict` (que pregunta al Core real) produce procedencia `core`. Como el satélite demo falla la evaluación real, una compuerta con `requiresCoreVerdict:true` no puede aprobarse con él — el sistema funcionando. `governance-journey` valida la **máquina de estados** (design `requiresCoreVerdict:false`); el veredicto-Core real lo cubre `core-integration`. **Pendiente:** provider-connections robot, multi-persona, y wiring CI.
40164016
- **Purpose / oportunidad:** El clúster kind vivo ya existe y tiene el Core desplegado. Automatizar un smoke E2E que (1) despliegue `tracker-gateway`+`tracker-api`, (2) ejercite las 6 MCP tools contra el Core real, y (3) llame `/v1/agent/converse` con credencial, daría la **evidencia viva** que hoy falta para `AR-02`/`COH-006`/`COH-007` y para cualquier cierre futuro que dependa de integración real. Hoy la verificación fue manual (`kubectl exec` + `curl`); sin harness, cada cierre "vivo" se repite a mano y no queda en CI.
40174017
- **Component:** `Infra/Quality` · **Module:** live E2E harness · **Type:** OPP
40184018
- **Criticality:** P2 · **Complexity:** M

docs/audit/tracker-gap-tracking.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ This board is the single source of truth for Tracker technical debt, gaps, oppor
7575
| [`LV-18`](./tracker-gap-reference-catalog.md#lv-18) | Tres de las seis MCP tools llaman rutas del Core que devuelven 404 en el servicio vivo | Aun corrigiendo despliegue y URLs, la mitad del catálogo choca con endpoints que el Core no expone: el contrato nunca se verificó contra el Core real | `/api/v1/gates`, `/api/v1/architecture` y `/api/v1/reference` → HTTP 404 en vivo; sólo `/api/v1/capabilities` responde (401, existe) | `Contracts/Integration` | Cross | P1 | M | `DONE` |
7676
| [`LV-19`](./tracker-gap-reference-catalog.md#lv-19) | ⚠️ **Premisa falsa (corregido 2026-07-21)** — el Tracker SÍ tiene cliente del runtime: `AgentRuntimeGateway` (BFF) llama `POST /v1/agent/converse` vía `/api/v1/assistant/converse`, tenant-scoped y engine-agnóstico, más el puerto gobernado `IAgentExecutionPort` (EAG-16) | El cliente vive en el BFF (correcto per T-051), no en el gateway MCP; el `rg` original miró sólo el `tracker-gateway`, no el `tracker-api` | El residual real —ejercitarlo contra el runtime vivo— es `AR-02`, no un cliente faltante | `Integration` | Cross | P2 | M | `DONE` |
7777
| [`LV-20`](./tracker-gap-reference-catalog.md#lv-20) | `COH-006` y `COH-007` siguen `BLOCKED` pese a que su bloqueante `EAG-16` está `DONE` y su código ya existe | El estado del board no refleja la realidad: ni "bloqueado" (el bloqueante cerró) ni "hecho" (sin verificar en vivo); el estado honesto es code-complete-unverified | `COH-006/007` ya no están `BLOCKED` ni pendientes: cerrados `DONE` por [ADR T-052] (la superficie de agentes es el MCP del Core, que el Tracker consume) | `Docs` | Cross | P3 | XS | `DONE` |
78-
| [`OPP-003`](./tracker-gap-reference-catalog.md#opp-003) | RoboSoft: flota de agentes de prueba E2E determinísticos contra el stack vivo (Core real) como evidencia reproducible | El entorno vivo ya existe; RoboSoft ejercita REST + MCP tools + `/converse` con round-trips reales al Core, asevera y emite evidencia JSON + exit code para CI | Harness (`robosoft/`) + robot `core-integration` construidos y auto-probados; pendientes `governance-journey`, provider-connections, multi-persona y wiring CI | `Infra/Quality` | Cross | P2 | M | `IN-PROGRESS` |
78+
| [`OPP-003`](./tracker-gap-reference-catalog.md#opp-003) | RoboSoft: flota de agentes de prueba E2E determinísticos contra el stack vivo (Core real) como evidencia reproducible | El entorno vivo ya existe; RoboSoft ejercita REST + MCP tools + `/converse` con round-trips reales al Core, asevera y emite evidencia JSON + exit code para CI | Harness + robots `core-integration` (11/13 vs Core real) y `governance-journey` (funnel SDLC completo, 53/53 vs tracker-api vivo) VALIDADOS en vivo; pendientes provider-connections, multi-persona y wiring CI | `Infra/Quality` | Cross | P2 | M | `IN-PROGRESS` |
7979
| [`LV-21`](./tracker-gap-reference-catalog.md#lv-21) | `AgentRuntimeOptions.BaseUrl` por defecto es `http://localhost:3003/v1`, dirección de dev que no resuelve el runtime en k8s | El cliente del runtime existe pero su default apunta a un puerto de portátil; en cualquier otro entorno hay que fijar la variable o falla en silencio (MockFallback) | Igual patrón que la base del Core (`LV-18`): el runtime vivo está en `evolith-runtime-...evolith-local:80`, no en `localhost:3003` | `Integration/Config` | Cross | P3 | XS | `DONE` |
8080
| [`OPP-004`](./tracker-gap-reference-catalog.md#opp-004) | Oportunidad: el gateway MCP no expone `converse` — si un agente BMAD debe conversar vía MCP, falta una 7ª tool que llame a `/api/v1/assistant/converse` del BFF | Los agentes pueden leer/entregar/consultar por MCP, pero no iniciar una conversación con el asistente del Tracker | Moot por [ADR T-052]: el gateway ya no tiene servidor MCP. Si un agente debe conversar vía MCP, es federación en el MCP del Core (`EAG-16`), no una tool del Tracker | `Integration` | Cross | P3 | S | `DEFERRED` |
8181
| [`LV-22`](./tracker-gap-reference-catalog.md#lv-22) | El seed `seed-e2e.mjs` golpea la superficie **pre-CD-32** (`/api/tenants`, no `/api/v1/tenants`): 22 llamadas a `/api/…`, 0 a `/api/v1/…` | Nadie puede sembrar datos de demo en un arranque local: el script falla entero y no hay flujos que revisar | Arreglado normalizando en el helper `api()` (`/api/``/api/v1/`); verificado en vivo: **`ok=0 failed=28``ok=347 failed=4`** (12 productos, 27 iniciativas). Los 4 residuales son bugs distintos → `LV-24` | `Tooling` | Cross | P2 | S | `DONE` |

robosoft/lib/client.mjs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ export function makeClient(baseUrl) {
2626
headers: {
2727
'content-type': 'application/json',
2828
accept: 'application/json',
29+
// dev-bypass reads the tenant from x-tenant-id; bearer mode gets it from
30+
// the JWT, so only send the header when there is no token.
31+
...(config.auth.mode === 'dev-bypass' ? { 'x-tenant-id': config.tenantId } : {}),
2932
...authHeaders(),
3033
},
3134
body: body === undefined ? undefined : JSON.stringify(body),
@@ -58,5 +61,6 @@ export function makeClient(baseUrl) {
5861
base: baseUrl,
5962
get: (path) => request('GET', path, undefined),
6063
post: (path, body) => request('POST', path, body),
64+
put: (path, body) => request('PUT', path, body),
6165
};
6266
}

robosoft/lib/config.mjs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ export const config = {
2222

2323
// Path prefixes (the gateway mounts controllers under /api; the tracker-api
2424
// mounts its surface under /api too). Overridable if a deployment differs.
25+
// The gateway mounts its controllers under /api; the tracker-api mounts its
26+
// domain surface under the VERSIONED prefix /api/v1 (TrackerApiSurface).
2527
gatewayPrefix: process.env.ROBOSOFT_GATEWAY_PREFIX || '/api',
26-
apiPrefix: process.env.ROBOSOFT_API_PREFIX || '/api',
28+
apiPrefix: process.env.ROBOSOFT_API_PREFIX || '/api/v1',
2729

2830
// Auth. `dev-bypass` sends no Authorization header (the local-dev scheme
2931
// authenticates every request as a full-permission admin). `bearer` attaches

0 commit comments

Comments
 (0)