OSVauco/docs/runbook/CI6-post-mortem.md
Chris Christiansen 9fcb9c354a
Some checks are pending
Check Python Version Consistency / Check Python Version (push) Waiting to run
feat(core): Fresh initialization - Deploy v3.6.1 Singularity Architecture
2026-09-03 04:03:09 +00:00

120 lines
4.2 KiB
Markdown

# CI6 Post-Mortem — Jason bruker live MCP
**Dato:** 2026-06-10
**Løst av:** Chris + Perplexity
**Varighet:** ~2.5 timer
---
## Problemet
Jason-agenten skulle bruke live MCP-verktøy (`get_build_status` etc.) i stedet for RAG/gjetting.
CI6 gikk ikke igjennom på første forsøk — tok mange iterasjoner å debugge.
---
## Rotårsaker (5 stk)
### 1. Feil Cloud Run URL
`osvauco-agent` har **to** URLs:
- `https://osvauco-agent-357036551735.us-central1.run.app` — generert URL (ikke bak IAP)
- `https://osvauco-agent-zjbqp3prqq-uc.a.run.app` — faktisk URL (bak IAP)
**Lærdom:** Bruk alltid `gcloud run services describe ... --format="value(status.url)"` for å hente riktig URL.
---
### 2. IAP-middleware blokkerte alle kall unntatt /health
`main.py` har en `require_iap` middleware som krever `x-goog-authenticated-user-email`-header.
Kall fra VM uten denne headeren → `401 Unauthorized` før FastAPI prosesserer requesten.
**Lærdom:** For API-kall fra ikke-browser-klienter (scripts, agenter, CI), legg til ruten i `IAP_EXEMPT_PATHS` eller send headeren manuelt:
```
-H "x-goog-authenticated-user-email: accounts.google.com:user@vauco.no"
```
---
### 3. RAG blokkerte AFC (Automatic Function Calling)
RAG-verktøyet (`VertexAiRagRetrieval`) er ikke en Python callable — det er en ADK-spesifikk tool-type.
Når den kombineres med `FunctionTool`-er i samme agent, deaktiveres AFC:
```
Tools at indices [1] are not compatible with automatic function calling (AFC).
```
Dette betyr at agenten aldri kaller MCP-verktøyene.
**Lærdom:** Bland ALDRI `VertexAiRagRetrieval` og `FunctionTool` i samme agent.
RAG må isoleres i en dedikert sub-agent.
**Fix:** Fjernet RAG fra `root_agent` (commit `3bb95c8`). TODO: RAG som sub-agent når korpuset er oppdatert.
---
### 4. `_opax_headers()` brukte access token, ikke identity token
`google.auth.default()` gir et **OAuth2 access token** — ikke et **identity token**.
Cloud Run krever identity token med riktig `aud`-claim for å autorisere kall.
**Symptom:** `401 Unauthorized` fra `opax-mcp` selv om IAM var riktig.
**Fix:** Bytt til GCE metadata server for å hente identity token med riktig audience (commit `8013bd8`):
```python
resp = httpx.get(
f"http://metadata.google.internal/.../identity?audience={OPAX_MCP_URL}",
headers={"Metadata-Flavor": "Google"},
)
```
---
### 5. MCP_SECRET ikke mountet på osvauco-agent
`mcp-server-key` var i Secret Manager, men ikke eksponert som env-var på `osvauco-agent`.
Agenten sendte `X-MCP-Key: ""``opax-mcp` avviste alle kall.
**Fix:**
```bash
gcloud run services update osvauco-agent \
--update-secrets="MCP_SECRET=mcp-server-key:latest"
```
**Lærdom:** Dokumenter ALLE required secrets i `.env.example` og i Cloud Run deploy-scriptet.
---
## IAM som måtte settes
```bash
# VM-SA må kunne kalle begge Cloud Run-tjenester
gcloud run services add-iam-policy-binding osvauco-agent \
--member="serviceAccount:357036551735-compute@developer.gserviceaccount.com" \
--role="roles/run.invoker"
gcloud run services add-iam-policy-binding opax-mcp \
--member="serviceAccount:357036551735-compute@developer.gserviceaccount.com" \
--role="roles/run.invoker"
```
---
## Tidslinje
| Tid (CEST) | Hendelse |
|---|---|
| 06:20 | CI5 lukket, build SUCCESS |
| 06:25 | Første `/chat`-kall — 404 (feil endepunkt) |
| 06:30 | Oppdaget endepunkt heter `/run` |
| 06:34 | Feil URL brukt (`357036551735` vs `zjbqp3prqq`) |
| 06:45 | IAP-middleware identifisert i `main.py` |
| 06:51 | Riktig token-type identifisert (audience-problem) |
| 07:00 | VM-SA fikk `run.invoker``osvauco-agent` |
| 07:14 | AFC-feil identifisert — RAG blokkerer FunctionTools |
| 07:17 | RAG fjernet fra `root_agent` (commit `3bb95c8`) |
| 07:39 | `_opax_headers()` fikset til identity token (commit `8013bd8`) |
| 07:47 | VM-SA fikk `run.invoker``opax-mcp` |
| 07:52 | `MCP_SECRET` mountet på `osvauco-agent` |
| 07:53 | ✅ Jason svarer med live build-data |
---
## Forebyggende tiltak
- [ ] `IAP_EXEMPT_PATHS` dokumentert i `main.py`
- [ ] `.env.example` oppdatert med `MCP_SECRET`
- [ ] RAG som sub-agent (OQ-RAG backlog)
- [ ] Deploy-script skal verifisere alle required secrets er mountet
- [ ] CI-test for MCP-kall skal kjøres automatisk etter hver deploy