From 04891081eb0c4b57519513fa96c47fd487cfabca Mon Sep 17 00:00:00 2001 From: Chris Christiansen Date: Wed, 10 Jun 2026 18:17:00 +0000 Subject: [PATCH] =?UTF-8?q?docs:=20OX2=20done=20=E2=80=94=20OPAX=20unified?= =?UTF-8?q?=20cockpit=20live=20=C2=B7=202026-06-10?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gemini/GEMINI.md | 850 +++++++++++++++++++++++++++++++++++++++++++-- docs/MASTERPLAN.md | 4 +- docs/ROADMAP.md | 61 +--- scripts/boot.sh | 1 + 4 files changed, 835 insertions(+), 81 deletions(-) diff --git a/.gemini/GEMINI.md b/.gemini/GEMINI.md index 4e2fdca..607bb3c 100644 --- a/.gemini/GEMINI.md +++ b/.gemini/GEMINI.md @@ -90,8 +90,8 @@ Den er **aldri** i git og eksisterer kun på disk eller i Secret Manager. ```bash # Alternativ 1: Sjekk Secret Manager gcloud secrets list --project=propane-will-491900-m5 | grep -i env -gcloud secrets versions access latest \ - --secret= \ +gcloud secrets versions access latest + --secret= --project=propane-will-491900-m5 > .env # Alternativ 2: Sjekk GCS backup @@ -135,14 +135,14 @@ NÅR noe feiler: NÅR du er usikker på state: ```bash -gcloud run services describe $CLOUD_RUN_SVC \ - --project=$GCP_PROJECT --region=$GCP_REGION \ +gcloud run services describe $CLOUD_RUN_SVC + --project=$GCP_PROJECT --region=$GCP_REGION --format="yaml(status,spec.template.spec.containers)" -gcloud artifacts docker images list \ - us-central1-docker.pkg.dev/$GCP_PROJECT/osvauco-repo \ - --project=$GCP_PROJECT \ - --sort-by=~CREATE_TIME \ +gcloud artifacts docker images list + us-central1-docker.pkg.dev/$GCP_PROJECT/osvauco-repo + --project=$GCP_PROJECT + --sort-by=~CREATE_TIME --limit=3 ``` @@ -165,14 +165,14 @@ gcloud artifacts docker images list \ Etter enhver endring: ```bash -gcloud run revisions list \ - --service=$CLOUD_RUN_SVC \ - --project=$GCP_PROJECT \ - --region=$GCP_REGION \ +gcloud run revisions list + --service=$CLOUD_RUN_SVC + --project=$GCP_PROJECT + --region=$GCP_REGION --limit=3 -curl -s -o /dev/null -w "%{http_code}" \ - -H "Authorization: Bearer $(gcloud auth print-identity-token)" \ +curl -s -o /dev/null -w "%{http_code}" + -H "Authorization: Bearer $(gcloud auth print-identity-token)" https://opax.vauco.no/health ``` @@ -258,12 +258,12 @@ VERIFY: [kommando for å bekrefte fix] ### 🔴 Cloud Build feiler ```bash -BUILD_ID=$(gcloud builds list \ - --project=propane-will-491900-m5 \ - --limit=1 \ +BUILD_ID=$(gcloud builds list + --project=propane-will-491900-m5 + --limit=1 --format="value(id)") -gcloud builds log $BUILD_ID \ +gcloud builds log $BUILD_ID --project=propane-will-491900-m5 2>&1 | tail -100 ``` @@ -276,16 +276,16 @@ Vanlige årsaker: ### 🔴 Cloud Run svarer ikke / returnerer feil ```bash -gcloud run services describe osvauco-agent \ - --project=propane-will-491900-m5 \ - --region=us-central1 \ +gcloud run services describe osvauco-agent + --project=propane-will-491900-m5 + --region=us-central1 --format="value(status.conditions)" -gcloud logging read \ - 'resource.type=cloud_run_revision AND resource.labels.service_name=osvauco-agent' \ - --project=propane-will-491900-m5 \ - --limit=50 \ - --order=desc \ +gcloud logging read + 'resource.type=cloud_run_revision AND resource.labels.service_name=osvauco-agent' + --project=propane-will-491900-m5 + --limit=50 + --order=desc --format="table(timestamp,textPayload,jsonPayload.message)" ``` @@ -296,9 +296,9 @@ gcloud auth list gcloud config get-value project gcloud auth print-identity-token -gcloud iap web get-iam-policy \ - --project=propane-will-491900-m5 \ - --resource-type=cloud-run \ +gcloud iap web get-iam-policy + --project=propane-will-491900-m5 + --resource-type=cloud-run --service=osvauco-agent ``` @@ -338,10 +338,10 @@ IMAGE=us-central1-docker.pkg.dev/propane-will-491900-m5/osvauco-repo/osvauco-age gcloud builds submit --config=cloudbuild.yaml --project=propane-will-491900-m5 -gcloud run deploy osvauco-agent \ - --image=$IMAGE:latest \ - --project=propane-will-491900-m5 \ - --region=us-central1 \ +gcloud run deploy osvauco-agent + --image=$IMAGE:latest + --project=propane-will-491900-m5 + --region=us-central1 --platform=managed ``` @@ -378,3 +378,787 @@ Deretter: NIKT utfør noe — vent på PLAN APPROVED eller eksplisitt instruksjon. Bekreft at du forstår ABSOLUTT REGEL: når Chris spesifiserer region/modell/parameter eksplisitt, bruk ALLTID den verdien — aldri overstyr med LOCKED DEFINITIONS. ``` + + +--- Newly Discovered Project Context --- +--- Context from: /home/chris_christiansen/OSVauco/.gemini/GEMINI.md --- +# GEMINI.md — OSVauco / OPAX + +> Gemini 2.5 Pro · Vertex AI us-central1 endpoint · Nemotron session protocol · HITL-safe + +--- + +## Locked Definitions + +``` +MCP_NAME: OPAX-MCP +MCP_PROTOCOL: OPAX Protocol +ROOT_DOMAIN: vauco.no +HUB_URL: https://opax.vauco.no +GCP_PROJECT: propane-will-491900-m5 +GCP_REGION: us-central1 +GCP_VERTEX_LOC: us-central1 +CLOUD_RUN_SVC: osvauco-agent +ARTIFACT_REPO: us-central1-docker.pkg.dev/propane-will-491900-m5/osvauco-repo +MODEL: gemini-2.5-pro +MODEL_PROVIDER: Vertex AI (Google) — us-central1 +MODEL_COST: Vertex pris (Gemini 2.5 Pro) +MODEL_NOTE: Midlertidig på Gemini inntil Claude-kvote er innvilget. Claude-variant: opax2 (claude-opus-4-7@20260301) +BUDGET_CAP: 2500 NOK intern grense — spør Chris om +1000 NOK ved behov +OPERATOR: Chris Christiansen (chris.christiansen@vauco.no) +OPERATOR_ROLE: Eier, arkitekt og primær operatør av OSVauco / OS-Vauco +``` + +> These values are LOCKED. Do NOT change without explicit human instruction. + +--- + +## Modell: Gemini 2.5 Pro via Vertex AI + +Denne agenten kjøres med **Gemini 2.5 Pro** tilgjengelig via Vertex AI EU endpoint. + +- Data forblir innenfor EU-grensen (GDPR-compliant) +- Billing via eksisterende GCP-konto +- Intern budsjett-cap: **2 500 NOK** — ved behov for mer, spør Chris eksplisitt om +1 000 NOK + +```bash +# Auth +gcloud auth application-default login --project=propane-will-491900-m5 +``` + +--- + +## Kontekst: Hvem og hvordan + +**Operatør: Chris Christiansen** — eier og arkitekt bak OSVauco og OS-Vauco. +Chris er en erfaren DevOps/Cloud-utvikler. Han er teknisk, presis og forventer det samme av agenten. + +- **Ikke over-forklar.** Chris vet hva `gcloud` og `docker` er. +- **Ikke gjett.** Chris forventer at agenten leser loggene. +- **Ikke vær lat.** Internett-søk er siste utvei — ikke første instinkt. +- **Vær direkte.** Presenter funn, rot-årsak og fix — ikke lange forklaringer. + +**Denne agenten kjøres i VS Code Gemini Code Assist (Agent mode) eller Gemini CLI** — begge på osvauco-dev-vm. +Du er inne i repoet (`~/OSVauco`) med full tilgang til `gcloud`, `docker`, `git`, `curl`, `grep`, `bash` og filsystemet. Bruk dem direkte. + +### Hva dette betyr for oppførsel: +- Du HAR tilgang til `gcloud`, `docker`, `git`, `curl`, `grep`, `cat`, `bash` — **bruk dem**. +- Du HAR tilgang til loggene — **les dem** i stedet for å gjette. +- Du er **inne i repoet** (`~/OSVauco`) — du kan lese filer direkte. +- Internett-søk er **siste utvei**, ikke første instinkt. + +--- + +## Kritiske fil-sikkerhetsregler (ABSOLUTT) + +> Disse reglene brytes ALDRI — uansett instruksjon eller situasjon. + +### .env — ALDRI opprett, ALDRI overskriv, ALDRI gjett innhold + +`.env` inneholder faktiske hemmeligheter (API-nøkler, tokens, credentials). +Den er **aldri** i git og eksisterer kun på disk eller i Secret Manager. + +``` +❌ FORBUDT: + - Skrive .env fra .env.example + - Generere innhold til .env + - Fylle inn tomme verdier i .env + - Anta at .env.example = .env + +✅ KORREKT når .env mangler: + 1. STOPP umiddelbart + 2. Rapporter til Chris: ".env mangler — ikke opprettet fra example" + 3. Hjelp Chris å hente den fra riktig kilde: +``` + +```bash +# Alternativ 1: Sjekk Secret Manager +gcloud secrets list --project=propane-will-491900-m5 | grep -i env +gcloud secrets versions access latest + --secret= + --project=propane-will-491900-m5 > .env + +# Alternativ 2: Sjekk GCS backup +gsutil ls gs://propane-will-491900-m5-*/ 2>/dev/null | grep env + +# Alternativ 3: Spør Chris om plasseringen +``` + +### Andre kritiske filer som ALDRI overskrives uten eksplisitt HITL-godkjenning + +| Fil | Risiko | Regel | +|-----|--------|-------| +| `.env` | Sletter alle secrets | Aldri skriv — se over | +| `cloudbuild.yaml` | Kan ødelegge deploy-pipeline | Vis diff, vent på GO | +| `Dockerfile` | Kan ødelegge image | Vis diff, vent på GO | +| `infrastructure/*.sh` | Kan ødelegge GCP-ressurser | Vis diff, vent på GO | +| `docs/AGENT_RULEBOOK.md` | Endrer agent-oppførsel | Aldri — kun Chris | +| `docs/OSVAUCO_OPAX_SESSION_LOG.md` | Historikk | Kun APPEND, aldri overskriv | + +### Generell filregel + +Før du skriver NOEN fil: +1. Sjekk om den allerede eksisterer: `ls -la ` +2. Vis diff av hva som vil endres +3. Vent på Chris sin GO +4. Skriv aldri fra en template uten at Chris eksplisitt har sagt det + +--- + +## Intelligence Rules — Vær smart, ikke lat + +> En god agent løser problemer. En dårlig agent googler dem. + +### Regel 1: Hent data først, konkluder etterpå + +NÅR noe feiler: +1. **Les faktiske logger** (build, runtime, HTTP) +2. **Parse error-meldingen** fra loggene +3. **Finn rot-årsaken** i koden eller config +4. **Presenter en konkret fix** med diff + +NÅR du er usikker på state: +```bash +gcloud run services describe $CLOUD_RUN_SVC + --project=$GCP_PROJECT --region=$GCP_REGION + --format="yaml(status,spec.template.spec.containers)" + +gcloud artifacts docker images list + us-central1-docker.pkg.dev/$GCP_PROJECT/osvauco-repo + --project=$GCP_PROJECT + --sort-by=~CREATE_TIME + --limit=3 +``` + +### Regel 2: Aldri gjett exit codes + +| Exit code | Betyr | Handling | +|-----------|-------|----------| +| `125` | Docker daemon-feil / ukjent flagg | Les build-logg, finn flagget | +| `1` | Generell appfeil | Les stderr i logg | +| `137` | OOM / killed | Sjekk minne-limits i cloudbuild.yaml | +| `2` | Misuse av shell / kommando | Feil argument til gcloud/docker | +| Non-zero fra docker build | Dockerfile-linje feiler | Les `Step X/Y` som feilet i loggen | + +### Regel 3: Aldri fiks symptomer — fiks rot-årsak + +❌ Feil: «build feiler → legg til --no-cache» +✅ Riktig: «build feiler → les logg → Step 3/8 feiler på apt-get → dependency mangler → fiks Dockerfile» + +### Regel 4: Bekreft alltid før du konkluderer at noe virker + +Etter enhver endring: +```bash +gcloud run revisions list + --service=$CLOUD_RUN_SVC + --project=$GCP_PROJECT + --region=$GCP_REGION + --limit=3 + +curl -s -o /dev/null -w "%{http_code}" + -H "Authorization: Bearer $(gcloud auth print-identity-token)" + https://opax.vauco.no/health +``` + +### Regel 5: Bruk strukturerte observasjoner + +Når du rapporterer en feil, skriv alltid: +``` +OBSERVASJON: [hva du faktisk leste i loggene] +ROT-ÅRSAK: [hva som faktisk feilet og hvorfor] +FIX: [konkret endring med diff] +VERIFY: [kommando for å bekrefte fix] +``` + +--- + +## Session Protocol (Nemotron Loop) + +### BOOT +- Les og print innhold fra: `docs/AGENT_RULEBOOK.md`, `docs/MASTERPLAN.md`, `docs/ROADMAP.md`, `docs/HANDOFF.md`. +- Print LOCKED DEFINITIONS (`MCP_NAME`, `MCP_PROTOCOL`, `HUB_URL`, `ROOT_DOMAIN`, `GCP_PROJECT`, `MODEL`, `BUDGET_CAP`, `OPERATOR`) i en kompakt blokk. +- Print siste `## NESTE OPPGAVE`-blokk fra `docs/HANDOFF.md` i én setning. +- Hvis ingen NESTE OPPGAVE → advar og les ROADMAP NOW-seksjon i stedet. +- Sjekk gjeldende GCP auth: `gcloud auth list` og `gcloud config get-value project` +- Sjekk om `.env` eksisterer: `ls -la .env` — hvis IKKE: rapporter til Chris umiddelbart, IKKE opprett den. + +### PLAN +- Før enhver kodeendring, skriv en kort PLAN-blokk i Markdown: + - Filer som berøres + - Forventet resultat + - HITL gate påkrevd +- IKKE gå til EXECUTE uten human bekreftelse. + +### EXECUTE +- Gjennomfør nøyaktig den endringen som er beskrevet i PLAN-blokken — ikke mer, ikke mindre. +- Vis alltid full diff før du skriver noen fil. +- Aldri batch urelaterte endringer i ett EXECUTE-steg. + +### VERIFY +- Kjør relevant verifikasjonskommando (`curl`, `gcloud`, `grep`, `git log`). +- Angi resultatet eksplisitt som `PASS` eller `FAIL`. +- Ved FAIL → **les loggene** → identifiser rot-årsak → rapporter. +- IKKE gå videre til LOG før VERIFY er PASS. + +### LOG +- Append til `docs/OSVAUCO_OPAX_SESSION_LOG.md`: + ``` + ## SLUTTRAPPORT – + - Hva: + - Filer: + - Verifisering: + + ## NESTE OPPGAVE + <én konkret neste oppgave> + ``` + +### NEXT +- Ved neste sesjonstart, les `## NESTE OPPGAVE` fra `docs/HANDOFF.md` før du gjør noe annet. + +--- + +## Hard Rules + +1. **Aldri endre LOCK LIST-verdier** uten eksplisitt human instruksjon. +2. **Vis alltid diff før du skriver** noen fil. +3. **Aldri batch urelaterte endringer** i ett EXECUTE-steg. +4. **OPAX (`opax.vauco.no`) er kun management plane** — den mottar aldri rå pasientdata. +5. **Medioteq kliniske data** forblir i `europe-north1` innenfor Medioteq GCP-prosjektgrensen. +6. **Deploy `clinical-mcp` og `clinical-orchestrator`** til Medioteq-prosjektet, aldri Vauco-prosjektet. +7. **HITL gates**: PLAN godkjenner rekkefølge → AUDIT godkjenner format → OPS bekrefter EST → Human bekrefter før EXEC kjøres. +8. **Aldri søk på nett for å diagnostisere feil du kan lese i loggene.** +9. **Aldri anta at noe virker — verifiser alltid med en faktisk kommando.** +10. **Aldri gjett på koden — les den.** Du er i repoet. Bruk `cat`, `grep`, `git diff`. +11. **Aldri skriv .env fra .env.example** — se Kritiske fil-sikkerhetsregler. +12. **Aldri overskriv en fil du ikke har lest først** — bruk `cat` eller `ls -la` før enhver skriveoperasjon. +13. **Budsjett-cap: 2 500 NOK** — aldri overskrid uten eksplisitt GO fra Chris med beløp. + +--- + +## Diagnostics Playbook (KRITISK) + +> **Grunnregel: Aldri gjett. Alltid hent faktisk data før du konkluderer.** + +### 🔴 Cloud Build feiler + +```bash +BUILD_ID=$(gcloud builds list + --project=propane-will-491900-m5 + --limit=1 + --format="value(id)") + +gcloud builds log $BUILD_ID + --project=propane-will-491900-m5 2>&1 | tail -100 +``` + +Vanlige årsaker: +- `exit 125` → Docker ukjent flagg eller image-pull feil +- `exit 1` på apt-get → dependency ikke funnet +- `exit 1` på COPY → fil eksisterer ikke i build-kontekst +- `exit 1` på pip install → requirements-konflikt + +### 🔴 Cloud Run svarer ikke / returnerer feil + +```bash +gcloud run services describe osvauco-agent + --project=propane-will-491900-m5 + --region=us-central1 + --format="value(status.conditions)" + +gcloud logging read + 'resource.type=cloud_run_revision AND resource.labels.service_name=osvauco-agent' + --project=propane-will-491900-m5 + --limit=50 + --order=desc + --format="table(timestamp,textPayload,jsonPayload.message)" +``` + +### 🔴 Auth / IAP-feil + +```bash +gcloud auth list +gcloud config get-value project +gcloud auth print-identity-token + +gcloud iap web get-iam-policy + --project=propane-will-491900-m5 + --resource-type=cloud-run + --service=osvauco-agent +``` + +### 🔴 .env mangler ved oppstart + +```bash +ls -la .env +gcloud secrets list --project=propane-will-491900-m5 | grep -i env +gsutil ls gs://propane-will-491900-m5-*/ 2>/dev/null | grep -i env +find ~ -name ".env" -not -path "*/OSVauco/*" 2>/dev/null +``` + +**STOPP og rapporter til Chris — opprett IKKE .env fra .env.example.** + +### Diagnoseoversikt + +| Situasjon | Gjør DETTE | IKKE dette | +|-----------|-----------|------------| +| Build exit 125 | `gcloud builds log` → finn Step som feilet | Søk på nett | +| Build exit 1 | `gcloud builds log` → les pip/apt-output | Anta avhengighetsfeil | +| Cloud Run 500 | `gcloud logging read` → les stack trace | Endre kode uten å se feilen | +| Cloud Run 404 | `curl` + les rutekonfig | Anta routing er feil | +| Auth 403 | `gcloud iap get-iam-policy` | Anta token er utløpt | +| .env mangler | Rapporter til Chris, hent fra Secret Manager | Opprett fra .env.example | +| Noe «virker ikke» | `gcloud run services describe` | Anta det er koden sin feil | + +--- + +## GCP-konvensjoner for dette prosjektet + +```bash +--project=propane-will-491900-m5 +--region=us-central1 + +CLOUD_RUN_SVC=osvauco-agent +IMAGE=us-central1-docker.pkg.dev/propane-will-491900-m5/osvauco-repo/osvauco-agent + +gcloud builds submit --config=cloudbuild.yaml --project=propane-will-491900-m5 + +gcloud run deploy osvauco-agent + --image=$IMAGE:latest + --project=propane-will-491900-m5 + --region=us-central1 + --platform=managed +``` + +--- + +## Domain Convention + +| Subdomain | Type | Purpose | +|-----------|------|---------| +| `opax.vauco.no` | Hub / MCP | OPAX kommandosenter + salgsmodul-bygger — Vauco internal only | +| `.os.vauco.no` | Prod | Live produksjon for et prosjekt (klient = prosjekt) | +| `.oss.vauco.no` | Stage | Staging / demo for et prosjekt | + +> OPAX er kommandosenteret som bygger, iscenesetter og publiserer ALLE prosjekter. Et prosjekt = en klient (samme ting). Kanonisk merkevare-label er alltid `*.vauco.no`; klient kan videresende eget domene. +> +> **Medisinsk prosjekt (Medioteq) er et SEPARAT, fremtidig prosjekt — ikke opprettet, ikke prioritert, og påvirker IKKE OPAX sin region.** Når det opprettes velges region (EU/US) der og da, uavhengig av OPAX. Kliniske/`europe-north1`-regler gjelder KUN det prosjektet. + +Auth: Google OAuth now. BankID later (Medioteq-prosjektet først). + +--- + +## Standard Boot Prompt + +> Lim inn dette ord-for-ord ved start av HVER sesjon. `Les og print innhold fra` tvinger faktisk fillesing — ikke bare skumming. + +``` +Les og print innhold fra: @docs/AGENT_RULEBOOK.md @docs/MASTERPLAN.md @docs/ROADMAP.md @docs/HANDOFF.md + +Deretter: +1. Print LOCKED DEFINITIONS (project, region, model, service, URLs) i en kompakt blokk +2. Oppsummer NESTE OPPGAVE fra HANDOFF.md i én setning +3. List 3 konkrete neste-steg du foreslår + +NIKT utfør noe — vent på PLAN APPROVED eller eksplisitt instruksjon. +Bekreft at du forstår ABSOLUTT REGEL: når Chris spesifiserer region/modell/parameter eksplisitt, bruk ALLTID den verdien — aldri overstyr med LOCKED DEFINITIONS. +``` + + +--- Newly Discovered Project Context --- +--- Context from: /home/chris_christiansen/OSVauco/.gemini/GEMINI.md --- +# GEMINI.md — OSVauco / OPAX + +> Gemini 2.5 Pro · Vertex AI us-central1 endpoint · Nemotron session protocol · HITL-safe + +--- + +## Locked Definitions + +``` +MCP_NAME: OPAX-MCP +MCP_PROTOCOL: OPAX Protocol +ROOT_DOMAIN: vauco.no +HUB_URL: https://opax.vauco.no +GCP_PROJECT: propane-will-491900-m5 +GCP_REGION: us-central1 +GCP_VERTEX_LOC: us-central1 +CLOUD_RUN_SVC: osvauco-agent +ARTIFACT_REPO: us-central1-docker.pkg.dev/propane-will-491900-m5/osvauco-repo +MODEL: gemini-2.5-pro +MODEL_PROVIDER: Vertex AI (Google) — us-central1 +MODEL_COST: Vertex pris (Gemini 2.5 Pro) +MODEL_NOTE: Midlertidig på Gemini inntil Claude-kvote er innvilget. Claude-variant: opax2 (claude-opus-4-7@20260301) +BUDGET_CAP: 2500 NOK intern grense — spør Chris om +1000 NOK ved behov +OPERATOR: Chris Christiansen (chris.christiansen@vauco.no) +OPERATOR_ROLE: Eier, arkitekt og primær operatør av OSVauco / OS-Vauco +``` + +> These values are LOCKED. Do NOT change without explicit human instruction. + +--- + +## Modell: Gemini 2.5 Pro via Vertex AI + +Denne agenten kjøres med **Gemini 2.5 Pro** tilgjengelig via Vertex AI EU endpoint. + +- Data forblir innenfor EU-grensen (GDPR-compliant) +- Billing via eksisterende GCP-konto +- Intern budsjett-cap: **2 500 NOK** — ved behov for mer, spør Chris eksplisitt om +1 000 NOK + +```bash +# Auth +gcloud auth application-default login --project=propane-will-491900-m5 +``` + +--- + +## Kontekst: Hvem og hvordan + +**Operatør: Chris Christiansen** — eier og arkitekt bak OSVauco og OS-Vauco. +Chris er en erfaren DevOps/Cloud-utvikler. Han er teknisk, presis og forventer det samme av agenten. + +- **Ikke over-forklar.** Chris vet hva `gcloud` og `docker` er. +- **Ikke gjett.** Chris forventer at agenten leser loggene. +- **Ikke vær lat.** Internett-søk er siste utvei — ikke første instinkt. +- **Vær direkte.** Presenter funn, rot-årsak og fix — ikke lange forklaringer. + +**Denne agenten kjøres i VS Code Gemini Code Assist (Agent mode) eller Gemini CLI** — begge på osvauco-dev-vm. +Du er inne i repoet (`~/OSVauco`) med full tilgang til `gcloud`, `docker`, `git`, `curl`, `grep`, `bash` og filsystemet. Bruk dem direkte. + +### Hva dette betyr for oppførsel: +- Du HAR tilgang til `gcloud`, `docker`, `git`, `curl`, `grep`, `cat`, `bash` — **bruk dem**. +- Du HAR tilgang til loggene — **les dem** i stedet for å gjette. +- Du er **inne i repoet** (`~/OSVauco`) — du kan lese filer direkte. +- Internett-søk er **siste utvei**, ikke første instinkt. + +--- + +## Kritiske fil-sikkerhetsregler (ABSOLUTT) + +> Disse reglene brytes ALDRI — uansett instruksjon eller situasjon. + +### .env — ALDRI opprett, ALDRI overskriv, ALDRI gjett innhold + +`.env` inneholder faktiske hemmeligheter (API-nøkler, tokens, credentials). +Den er **aldri** i git og eksisterer kun på disk eller i Secret Manager. + +``` +❌ FORBUDT: + - Skrive .env fra .env.example + - Generere innhold til .env + - Fylle inn tomme verdier i .env + - Anta at .env.example = .env + +✅ KORREKT når .env mangler: + 1. STOPP umiddelbart + 2. Rapporter til Chris: ".env mangler — ikke opprettet fra example" + 3. Hjelp Chris å hente den fra riktig kilde: +``` + +```bash +# Alternativ 1: Sjekk Secret Manager +gcloud secrets list --project=propane-will-491900-m5 | grep -i env +gcloud secrets versions access latest + --secret= + --project=propane-will-491900-m5 > .env + +# Alternativ 2: Sjekk GCS backup +gsutil ls gs://propane-will-491900-m5-*/ 2>/dev/null | grep env + +# Alternativ 3: Spør Chris om plasseringen +``` + +### Andre kritiske filer som ALDRI overskrives uten eksplisitt HITL-godkjenning + +| Fil | Risiko | Regel | +|-----|--------|-------| +| `.env` | Sletter alle secrets | Aldri skriv — se over | +| `cloudbuild.yaml` | Kan ødelegge deploy-pipeline | Vis diff, vent på GO | +| `Dockerfile` | Kan ødelegge image | Vis diff, vent på GO | +| `infrastructure/*.sh` | Kan ødelegge GCP-ressurser | Vis diff, vent på GO | +| `docs/AGENT_RULEBOOK.md` | Endrer agent-oppførsel | Aldri — kun Chris | +| `docs/OSVAUCO_OPAX_SESSION_LOG.md` | Historikk | Kun APPEND, aldri overskriv | + +### Generell filregel + +Før du skriver NOEN fil: +1. Sjekk om den allerede eksisterer: `ls -la ` +2. Vis diff av hva som vil endres +3. Vent på Chris sin GO +4. Skriv aldri fra en template uten at Chris eksplisitt har sagt det + +--- + +## Intelligence Rules — Vær smart, ikke lat + +> En god agent løser problemer. En dårlig agent googler dem. + +### Regel 1: Hent data først, konkluder etterpå + +NÅR noe feiler: +1. **Les faktiske logger** (build, runtime, HTTP) +2. **Parse error-meldingen** fra loggene +3. **Finn rot-årsaken** i koden eller config +4. **Presenter en konkret fix** med diff + +NÅR du er usikker på state: +```bash +gcloud run services describe $CLOUD_RUN_SVC + --project=$GCP_PROJECT --region=$GCP_REGION + --format="yaml(status,spec.template.spec.containers)" + +gcloud artifacts docker images list + us-central1-docker.pkg.dev/$GCP_PROJECT/osvauco-repo + --project=$GCP_PROJECT + --sort-by=~CREATE_TIME + --limit=3 +``` + +### Regel 2: Aldri gjett exit codes + +| Exit code | Betyr | Handling | +|-----------|-------|----------| +| `125` | Docker daemon-feil / ukjent flagg | Les build-logg, finn flagget | +| `1` | Generell appfeil | Les stderr i logg | +| `137` | OOM / killed | Sjekk minne-limits i cloudbuild.yaml | +| `2` | Misuse av shell / kommando | Feil argument til gcloud/docker | +| Non-zero fra docker build | Dockerfile-linje feiler | Les `Step X/Y` som feilet i loggen | + +### Regel 3: Aldri fiks symptomer — fiks rot-årsak + +❌ Feil: «build feiler → legg til --no-cache» +✅ Riktig: «build feiler → les logg → Step 3/8 feiler på apt-get → dependency mangler → fiks Dockerfile» + +### Regel 4: Bekreft alltid før du konkluderer at noe virker + +Etter enhver endring: +```bash +gcloud run revisions list + --service=$CLOUD_RUN_SVC + --project=$GCP_PROJECT + --region=$GCP_REGION + --limit=3 + +curl -s -o /dev/null -w "%{http_code}" + -H "Authorization: Bearer $(gcloud auth print-identity-token)" + https://opax.vauco.no/health +``` + +### Regel 5: Bruk strukturerte observasjoner + +Når du rapporterer en feil, skriv alltid: +``` +OBSERVASJON: [hva du faktisk leste i loggene] +ROT-ÅRSAK: [hva som faktisk feilet og hvorfor] +FIX: [konkret endring med diff] +VERIFY: [kommando for å bekrefte fix] +``` + +--- + +## Session Protocol (Nemotron Loop) + +### BOOT +- Les og print innhold fra: `docs/AGENT_RULEBOOK.md`, `docs/MASTERPLAN.md`, `docs/ROADMAP.md`, `docs/HANDOFF.md`. +- Print LOCKED DEFINITIONS (`MCP_NAME`, `MCP_PROTOCOL`, `HUB_URL`, `ROOT_DOMAIN`, `GCP_PROJECT`, `MODEL`, `BUDGET_CAP`, `OPERATOR`) i en kompakt blokk. +- Print siste `## NESTE OPPGAVE`-blokk fra `docs/HANDOFF.md` i én setning. +- Hvis ingen NESTE OPPGAVE → advar og les ROADMAP NOW-seksjon i stedet. +- Sjekk gjeldende GCP auth: `gcloud auth list` og `gcloud config get-value project` +- Sjekk om `.env` eksisterer: `ls -la .env` — hvis IKKE: rapporter til Chris umiddelbart, IKKE opprett den. + +### PLAN +- Før enhver kodeendring, skriv en kort PLAN-blokk i Markdown: + - Filer som berøres + - Forventet resultat + - HITL gate påkrevd +- IKKE gå til EXECUTE uten human bekreftelse. + +### EXECUTE +- Gjennomfør nøyaktig den endringen som er beskrevet i PLAN-blokken — ikke mer, ikke mindre. +- Vis alltid full diff før du skriver noen fil. +- Aldri batch urelaterte endringer i ett EXECUTE-steg. + +### VERIFY +- Kjør relevant verifikasjonskommando (`curl`, `gcloud`, `grep`, `git log`). +- Angi resultatet eksplisitt som `PASS` eller `FAIL`. +- Ved FAIL → **les loggene** → identifiser rot-årsak → rapporter. +- IKKE gå videre til LOG før VERIFY er PASS. + +### LOG +- Append til `docs/OSVAUCO_OPAX_SESSION_LOG.md`: + ``` + ## SLUTTRAPPORT – + - Hva: + - Filer: + - Verifisering: + + ## NESTE OPPGAVE + <én konkret neste oppgave> + ``` + +### NEXT +- Ved neste sesjonstart, les `## NESTE OPPGAVE` fra `docs/HANDOFF.md` før du gjør noe annet. + +--- + +## Hard Rules + +1. **Aldri endre LOCK LIST-verdier** uten eksplisitt human instruksjon. +2. **Vis alltid diff før du skriver** noen fil. +3. **Aldri batch urelaterte endringer** i ett EXECUTE-steg. +4. **OPAX (`opax.vauco.no`) er kun management plane** — den mottar aldri rå pasientdata. +5. **Medioteq kliniske data** forblir i `europe-north1` innenfor Medioteq GCP-prosjektgrensen. +6. **Deploy `clinical-mcp` og `clinical-orchestrator`** til Medioteq-prosjektet, aldri Vauco-prosjektet. +7. **HITL gates**: PLAN godkjenner rekkefølge → AUDIT godkjenner format → OPS bekrefter EST → Human bekrefter før EXEC kjøres. +8. **Aldri søk på nett for å diagnostisere feil du kan lese i loggene.** +9. **Aldri anta at noe virker — verifiser alltid med en faktisk kommando.** +10. **Aldri gjett på koden — les den.** Du er i repoet. Bruk `cat`, `grep`, `git diff`. +11. **Aldri skriv .env fra .env.example** — se Kritiske fil-sikkerhetsregler. +12. **Aldri overskriv en fil du ikke har lest først** — bruk `cat` eller `ls -la` før enhver skriveoperasjon. +13. **Budsjett-cap: 2 500 NOK** — aldri overskrid uten eksplisitt GO fra Chris med beløp. + +--- + +## Diagnostics Playbook (KRITISK) + +> **Grunnregel: Aldri gjett. Alltid hent faktisk data før du konkluderer.** + +### 🔴 Cloud Build feiler + +```bash +BUILD_ID=$(gcloud builds list + --project=propane-will-491900-m5 + --limit=1 + --format="value(id)") + +gcloud builds log $BUILD_ID + --project=propane-will-491900-m5 2>&1 | tail -100 +``` + +Vanlige årsaker: +- `exit 125` → Docker ukjent flagg eller image-pull feil +- `exit 1` på apt-get → dependency ikke funnet +- `exit 1` på COPY → fil eksisterer ikke i build-kontekst +- `exit 1` på pip install → requirements-konflikt + +### 🔴 Cloud Run svarer ikke / returnerer feil + +```bash +gcloud run services describe osvauco-agent + --project=propane-will-491900-m5 + --region=us-central1 + --format="value(status.conditions)" + +gcloud logging read + 'resource.type=cloud_run_revision AND resource.labels.service_name=osvauco-agent' + --project=propane-will-491900-m5 + --limit=50 + --order=desc + --format="table(timestamp,textPayload,jsonPayload.message)" +``` + +### 🔴 Auth / IAP-feil + +```bash +gcloud auth list +gcloud config get-value project +gcloud auth print-identity-token + +gcloud iap web get-iam-policy + --project=propane-will-491900-m5 + --resource-type=cloud-run + --service=osvauco-agent +``` + +### 🔴 .env mangler ved oppstart + +```bash +ls -la .env +gcloud secrets list --project=propane-will-491900-m5 | grep -i env +gsutil ls gs://propane-will-491900-m5-*/ 2>/dev/null | grep -i env +find ~ -name ".env" -not -path "*/OSVauco/*" 2>/dev/null +``` + +**STOPP og rapporter til Chris — opprett IKKE .env fra .env.example.** + +### Diagnoseoversikt + +| Situasjon | Gjør DETTE | IKKE dette | +|-----------|-----------|------------| +| Build exit 125 | `gcloud builds log` → finn Step som feilet | Søk på nett | +| Build exit 1 | `gcloud builds log` → les pip/apt-output | Anta avhengighetsfeil | +| Cloud Run 500 | `gcloud logging read` → les stack trace | Endre kode uten å se feilen | +| Cloud Run 404 | `curl` + les rutekonfig | Anta routing er feil | +| Auth 403 | `gcloud iap get-iam-policy` | Anta token er utløpt | +| .env mangler | Rapporter til Chris, hent fra Secret Manager | Opprett fra .env.example | +| Noe «virker ikke» | `gcloud run services describe` | Anta det er koden sin feil | + +--- + +## GCP-konvensjoner for dette prosjektet + +```bash +--project=propane-will-491900-m5 +--region=us-central1 + +CLOUD_RUN_SVC=osvauco-agent +IMAGE=us-central1-docker.pkg.dev/propane-will-491900-m5/osvauco-repo/osvauco-agent + +gcloud builds submit --config=cloudbuild.yaml --project=propane-will-491900-m5 + +gcloud run deploy osvauco-agent + --image=$IMAGE:latest + --project=propane-will-491900-m5 + --region=us-central1 + --platform=managed +``` + +--- + +## Domain Convention + +| Subdomain | Type | Purpose | +|-----------|------|---------| +| `opax.vauco.no` | Hub / MCP | OPAX kommandosenter + salgsmodul-bygger — Vauco internal only | +| `.os.vauco.no` | Prod | Live produksjon for et prosjekt (klient = prosjekt) | +| `.oss.vauco.no` | Stage | Staging / demo for et prosjekt | + +> OPAX er kommandosenteret som bygger, iscenesetter og publiserer ALLE prosjekter. Et prosjekt = en klient (samme ting). Kanonisk merkevare-label er alltid `*.vauco.no`; klient kan videresende eget domene. +> +> **Medisinsk prosjekt (Medioteq) er et SEPARAT, fremtidig prosjekt — ikke opprettet, ikke prioritert, og påvirker IKKE OPAX sin region.** Når det opprettes velges region (EU/US) der og da, uavhengig av OPAX. Kliniske/`europe-north1`-regler gjelder KUN det prosjektet. + +Auth: Google OAuth now. BankID later (Medioteq-prosjektet først). + +--- + +## Standard Boot Prompt + +> Lim inn dette ord-for-ord ved start av HVER sesjon. `Les og print innhold fra` tvinger faktisk fillesing — ikke bare skumming. + +``` +Les og print innhold fra: @docs/AGENT_RULEBOOK.md @docs/MASTERPLAN.md @docs/ROADMAP.md @docs/HANDOFF.md + +Deretter: +1. Print LOCKED DEFINITIONS (project, region, model, service, URLs) i en kompakt blokk +2. Oppsummer NESTE OPPGAVE fra HANDOFF.md i én setning +3. List 3 konkrete neste-steg du foreslår + +NIKT utfør noe — vent på PLAN APPROVED eller eksplisitt instruksjon. +Bekreft at du forstår ABSOLUTT REGEL: når Chris spesifiserer region/modell/parameter eksplisitt, bruk ALLTID den verdien — aldri overstyr med LOCKED DEFINITIONS. +``` +## Cloud Build & CI/CD Rules + +- NEVER use --audiences flag with gcloud auth print-identity-token + for Cloud Run invocation. Use bare: gcloud auth print-identity-token +- Always hardcode BASE_URL to canonical Cloud Run URL in smoke-tests: + https://osvauco-agent-357036551735.us-central1.run.app + Do NOT use $_CLOUD_RUN_URL substitution or gcloud run services describe +- When any Cloud Run service returns 404 to automated callers, + FIRST check IAM (missing roles/run.invoker) before debugging routing +- Every new Cloud Run service needs this immediately after creation: + gcloud run services add-iam-policy-binding [SERVICE] + --region=us-central1 + --member="serviceAccount:357036551735@cloudbuild.gserviceaccount.com" + --role="roles/run.invoker" + --project=propane-will-491900-m5 +- Always keep sleep 30 before smoke-test polling loop diff --git a/docs/MASTERPLAN.md b/docs/MASTERPLAN.md index 921630d..19dcfcb 100644 --- a/docs/MASTERPLAN.md +++ b/docs/MASTERPLAN.md @@ -10,6 +10,9 @@ --- +## Lessons Learned +- Cloud Build smoke-tests require: hardcoded canonical BASE_URL, bare identity token (no --audiences), and explicit run.invoker IAM binding for the Cloud Build service account on every service. + ## 1. Plattformhierarki — sannheten i én modell ``` @@ -264,7 +267,6 @@ Vauco AS sin offisielle bedriftsside. Selger moduler ved å lede besøkende til | Eier / admin | `chris.christiansen@vauco.no` | — | Full kontroll | ✅ Aktiv | | Jason Vauger | `jason.vauger@vauco.no` | `gemini-2.5-flash` via Vertex | Kundevendt agent, `billing.viewer` + `run.invoker` | ✅ Live | | Emma Vauger | `emma.vauger@vauco.no` | `gemma-4-12b-it` (lokal GPU-VM) | Intern agent for Chris — erstatter Perplexity stand-in | 🔮 ML-3a trigger — opprett Google Workspace-konto samtidig | -| Perplexity (stand-in) | — | Sonnet 4.6 via GitHub MCP | Operatør-assistent til Emma er oppe | ✅ Aktiv nå | | Fremtidig gruppe | `billing@vauco.no` | — | `billing.viewer` (Fase C) | 🔮 Fase C | **Forbudte kontoer:** `tinius.vauger`, `ccv` — aldri gi tilganger. diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 6430732..b86b40d 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -21,7 +21,7 @@ - [ ] **CG4b** — Token dashboard breakdown per modul i UI (trigger: 50+ BQ-kall) - [ ] **C4** — Medioteq HITL-møte → første betalende kunde -- [ ] **OX2** — Command Hub: sy sammen jason.html + opax.html + command-hub.html til én arbeidsflate +- [x] **OX2** — Command Hub: sy sammen jason.html + opax.html + command-hub.html til én arbeidsflate --- @@ -100,61 +100,28 @@ - [x] **Emma Vauger** — Registrert som agent `emma.vauger@vauco.no` · 2026-06-10 - [x] **CI5** — OPAX-MCP build + deploy SUCCESS · 2026-06-10 ✅ - [x] **CI6** — Jason kaller OPAX-MCP live, returnerer faktisk build-ID · 2026-06-10 ✅ -- [x] **CI/CD smoke-test pipeline** — BASE_URL hardkodet, IAM run.invoker fikset, --audiences bug løst · 2026-06-10 ✅ +- [x] Fix Cloud Build smoke-test pipeline (BASE_URL, IAM run.invoker, token auth, canonical URL) — June 10 2026 --- -## AUTH-LØSNING (autoritativ) — Cloud Run / IAP +## AUTH-LØSNING (autoritativ) — Cloud Run / IAP fra VM -> Oppdatert 2026-06-10 etter smoke-test debugging. Tidligere versjon var feil. - -### Kanoniske URL-er - -``` -Kanonisk URL: https://osvauco-agent-357036551735.us-central1.run.app ← bruk ALLTID denne -IAP/public URL: https://opax.vauco.no -Cloud Build SA: 357036551735@cloudbuild.gserviceaccount.com -``` - -> ⚠️ `zjbqp3prqq`-URL er den interne Cloud Run URL — den fungerer IKKE som `--audiences` target for identity tokens. Bruk alltid `357036551735`-URL (kanonisk) eller `opax.vauco.no` (public). - -### Fra dev-VM (metadata token) +> Bruk alltid denne metoden for curl-kall mot `osvauco-agent` fra dev-VM: ```bash -# Hent token via GCE metadata (riktig audience = kanonisk URL): -TOKEN=$(curl -s -H "Metadata-Flavor: Google" \ - "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=https://osvauco-agent-357036551735.us-central1.run.app&format=full") +TOKEN=$(curl -s -H "Metadata-Flavor: Google" + "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=https://osvauco-agent-zjbqp3prqq-uc.a.run.app&format=full") -curl -s \ - -H "Authorization: Bearer $TOKEN" \ - -H "x-goog-authenticated-user-email: accounts.google.com:chris.christiansen@vauco.no" \ - -H "Content-Type: application/json" \ - -d '{"user_id": "chris", "session_id": "", "message": ""}' \ - https://osvauco-agent-357036551735.us-central1.run.app/run +curl -s + -H "Authorization: Bearer $TOKEN" + -H "x-goog-authenticated-user-email: accounts.google.com:chris.christiansen@vauco.no" + -H "Content-Type: application/json" + -d '{"user_id": "chris", "session_id": "", "message": ""}' + https://osvauco-agent-zjbqp3prqq-uc.a.run.app/run ``` -### Fra Cloud Build smoke-test - -```bash -# ALDRI --audiences flagg — returnerer tomt token: -# TOKEN=$(gcloud auth print-identity-token --audiences="$URL") ← FEIL - -# RIKTIG: -BASE_URL="https://osvauco-agent-357036551735.us-central1.run.app" -TOKEN=$(gcloud auth print-identity-token) - -curl -s -o /dev/null -w "%{http_code}" \ - -H "Authorization: Bearer $TOKEN" \ - "$BASE_URL/health" -``` - -### Fra gcloud CLI (lokal maskin) - -```bash -TOKEN=$(gcloud auth print-identity-token) -curl -H "Authorization: Bearer $TOKEN" \ - https://osvauco-agent-357036551735.us-central1.run.app/health -``` +**Viktig:** Bruk `zjbqp3prqq`-URL (ikke `357036551735`-URL) som audience og endepunkt. +**Aldri** bruk `gcloud auth print-identity-token` uten `--audiences` — gir feil audience. --- diff --git a/scripts/boot.sh b/scripts/boot.sh index a1c099d..ec49622 100755 --- a/scripts/boot.sh +++ b/scripts/boot.sh @@ -197,6 +197,7 @@ alias sl='${PAGER:-less} $SESSION_LOG' alias osv='cd $OSVAUCO_DIR' alias reboot-osv='unset OSVAUCO_BOOTED; source $OSVAUCO_DIR/scripts/boot.sh' alias ghs='gh pr list && gh issue list' +alias trigger='bash $OSVAUCO_DIR/scripts/watch-build.sh' # sol() — avslutt-funksjon sol() {