diff --git a/.gemini/GEMINI.md b/.gemini/GEMINI.md index a722f3a..9efe79c 100644 --- a/.gemini/GEMINI.md +++ b/.gemini/GEMINI.md @@ -47,7 +47,7 @@ MODEL: gemini-2.5-pro MODEL_NOTE: Midlertidig på Gemini inntil Claude-kvote er innvilget BUDGET_CAP: 2500 NOK — spør Chris om +1000 NOK ved behov OPERATOR: Chris Christiansen (chris.christiansen@vauco.no) -PRIMARY_GIT: http://34.59.131.162:3000/chris/OSVauco ← Gitea (master) +PRIMARY_GIT: http://34.67.252.59:3000/chris/OSVauco ← Gitea (master) GITHUB_LEGACY: https://github.com/vauco-saas/OSVauco ← GitHub (legacy/backup) IAP_CLIENT_ID: 357036551735-kq8nt7ld38hfqlcfb3n52ef7tala4meo.apps.googleusercontent.com ``` @@ -64,7 +64,7 @@ Operatør er **Chris Christiansen** — erfaren DevOps/Cloud-utvikler. Vær dire - Du HAR `gcloud`, `docker`, `git`, `curl`, `grep`, `cat`, `bash` — **bruk dem** - Du er inne i repoet — **les filer direkte** - Chris vet hva `gcloud` er — **ikke over-forklar** -- Gitea (`34.59.131.162:3000`) er primær Git (master) — GitHub er kun en legacy/backup +- Gitea (`34.67.252.59:3000`) er primær Git (master) — GitHub er kun en legacy/backup - Emma rapporterer til Chris (`chris.christiansen@vauco.no`) — ingen andre --- @@ -133,7 +133,7 @@ gcloud auth list && gcloud config get-value project ls -la ~/OSVauco/emma/data/morphic.db ~/OSVauco/emma/emma_flynn_log.jsonl 2>/dev/null || echo 'Emma ikke bootstrappt' # 4. Gitea oppe? -curl -s http://34.59.131.162:3000/api/v1/version | python3 -m json.tool +curl -s http://34.67.252.59:3000/api/v1/version | python3 -m json.tool ``` Print deretter: @@ -254,7 +254,7 @@ gcloud run services add-iam-policy-binding [SERVICE] ```bash bash <(curl -s "http://chris:$(gcloud secrets versions access latest --secret=gitea-api-token --project=propane-will-491900-m5 - )@34.59.131.162:3000/chris/OSVauco/raw/branch/main/emma/setup.sh") + )@34.67.252.59:3000/chris/OSVauco/raw/branch/main/emma/setup.sh") echo 'source ~/.emma_env' >> ~/.bashrc && source ~/.emma_env emma # start CLI @@ -285,7 +285,7 @@ Les og print innhold fra: @docs/HANDOFF.md @docs/AGENT_RULEBOOK.md git -C ~/OSVauco log --oneline -3 gcloud auth list && gcloud config get-value project ls -la ~/OSVauco/emma/data/morphic.db 2>/dev/null || echo 'Emma ikke bootstrappt' - curl -s http://34.59.131.162:3000/api/v1/version | python3 -m json.tool + curl -s http://34.67.252.59:3000/api/v1/version | python3 -m json.tool IKKE utfør noe — vent på PLAN APPROVED. HUSK: internett-søk er forbudt for diagnose. Bruk gcloud/cat/grep/git. diff --git a/dev-start.sh b/dev-start.sh index 318ce1f..c1ad39a 100755 --- a/dev-start.sh +++ b/dev-start.sh @@ -23,7 +23,7 @@ SSH_CONFIG_PATH="/mnt/c/Users/Cvias/.ssh/config" SSH_KEY_PATH="C:\Users\Cvias\.ssh\google_compute_engine" # Git Remotes for Verification on GPU VM -GITEA_REMOTE="http://136.111.198.14:3000/chris/osvauco.git" +GITEA_REMOTE="http://34.67.252.59:3000/chris/OSVauco.git" GITHUB_REMOTE="git@github.com:vauco/osvauco.git" # --- Helper Functions --- diff --git a/docs/DNS-OG-INFRASTRUKTUR.md b/docs/DNS-OG-INFRASTRUKTUR.md index 7c03c20..671ce72 100644 --- a/docs/DNS-OG-INFRASTRUKTUR.md +++ b/docs/DNS-OG-INFRASTRUKTUR.md @@ -33,6 +33,17 @@ > ⚠️ Når du legger til nytt subdomene må du alltid oppdatere `--ssl-certificates` med ALLE eksisterende + nytt. > Eksempel: `--ssl-certificates=osvauco-agent-ssl-cert,opax-vauco-cert,NYTT-cert` +**STATUS (2026-07-07): `git.vauco.no` er BLOKKERT** + +Diagnose avdekket en fundamental feilkonfigurasjon: + +* **OK:** DNS (`git.vauco.no` → `34.144.224.45`), SSL-sertifikat (`git-vauco-cert`), og routing til URL-map er i orden. +* **AVVIK:** Backend-tjenesten `vauco-os-backend` peker til feil mål: en Serverless NEG for Cloud Run-tjenesten `osvauco-agent`, ikke Gitea-VM-en. +* **BLOCKER:** Den forventede Gitea-VM-en (`osvauco-dev-vm`) ble ikke funnet. + +**Konklusjon:** +Gitea-endepunktet via `git.vauco.no` er **ikke-fungerende**. All Fase 2-koding som avhenger av et live Gitea-endepunkt er blokkert. Ingen flere endringer på lastbalanserer eller backends skal gjøres nå. + --- ## REGEL: Nytt subdomene = gjør dette (i denne rekkefølgen) @@ -72,6 +83,16 @@ gcloud compute ssl-certificates describe NAVN-cert \ --- +## DOMENE-ROLLEMODELL (Låst) + +| Domene | Tildelt Rolle | Status | +|-----------|----------|--------| +| `git.vauco.no` | Gitea (kode-repo) | **Planlagt** | +| `opax.vauco.no`| OPAX-MCP (agent-gateway)| **Aktiv** | +| `ops.vauco.no` | Ikke i bruk | **Parkert** | + +--- + ## DAGENS SUBDOMENER — Status | Subdomene | DNS type | Peker til | SSL-cert | IAP | Status | @@ -144,3 +165,69 @@ gcloud dns record-sets create subdomene.vauco.no. \ --- *Opprettet: 2026-05-30 | Oppdatert: 2026-06-10 | OSVauco | propane-will-491900-m5* +--- + +## Ny DNS-strategi: Minimal Live-sone i Cloud DNS (2026-07-07) + +**Beslutning:** Vi speiler ikke ProISP-sonen 1:1. Den behandles som historikk. En ny, minimal sone bygges bevisst opp i Google Cloud DNS (`vaucono`) for å bli den fremtidige autoritative kilden. Ingen nameserver-bytte skjer ennå. + +### Sammenligning og Fremtidig Status for DNS-Records + +#### Gruppe 1: E-post/autentisering (Beholdes og verifiseres) +*Disse er standard for Google Workspace og er kritisk for e-postflyt.* +| Navn | Type | Ønsket Verdi | Planlagt `gcloud`-kommando | +| :--- | :--- | :--- | :--- | +| `vauco.no.` | MX | Standard Google MX-records. | `transaction add --name="vauco.no." --type=MX --ttl=3600 "1 smtp.google.com." "5 alt1.smtp.google.com." ...` | +| `vauco.no.` | TXT | `v=spf1 include:_spf.google.com ~all` | *(Eksisterer allerede i Cloud DNS)* | +| `google._domainkey` | TXT | (DKIM-nøkkel fra Google) | *(Eksisterer allerede i Cloud DNS)* | +| `_dmarc.vauco.no.`| TXT | (DMARC-policy) | *(Eksisterer allerede i Cloud DNS)* | + +#### Gruppe 2: Beholdes til Live (Kjerne-infrastruktur) +*Disse peker til aktiv, strategisk infrastruktur.* +| Navn | Type | Ønsket Verdi | Planlagt `gcloud`-kommando | +| :--- | :--- | :--- | :--- | +| `opax.vauco.no.`| A | `34.98.77.173` (IAP LB IP) | `transaction add --name="opax.vauco.no." --type=A --ttl=300 "34.98.77.173"` | +| `vauco.no.` | A | Fremtidig web-host / statisk side | `...` | +| `www.vauco.no.` | A | Fremtidig web-host / statisk side | `...` | + +#### Gruppe 3: Beslutning Kreves +*Disse er strategiske, men avhenger av eksterne faktorer før de kan låses.* +| Navn | Type | Ønsket Verdi | Status | +| :--- | :--- | :--- | :--- | +| `git.vauco.no.`| A | (Stabil, ekstern IP til dev-VM) | **BLOKKERT:** Venter på at nettverk/brannmur er bekreftet. | + +#### Gruppe 4: Legacy / Eksperiment (Skal ikke migreres nå) +*Disse subdomenene er fra tidligere eksperimenter og skal ikke opprettes i den nye sonen med mindre et konkret behov dokumenteres.* +- `blackbriar.vauco.no` +- `vaultconnection.vauco.no` +- `n8n.vauco.no` +- `scout.vauco.no` +- `stage.vauco.no` +- `costguard.oss.vauco.no` +- `threadstone.vauco.no` (og andre GitHub Pages CNAMEs) + +### Oppsummering av Plan +Cloud DNS-sonen er ufullstendig. For å gjøre den klar, må vi: +1. Legge til korrekte MX-records for Google Workspace. +2. Endre `opax.vauco.no` fra CNAME til en A-record som peker på IAP Load Balancer-IP-en. +3. Klargjøre en midlertidig, statisk host for `vauco.no` og `www` og legge inn A-records for disse. +4. Avklare og sette en stabil, ekstern IP for `git.vauco.no`. +5. **Ikke** migrere noen av de gamle "Legacy/Eksperiment"-subdomenene. + +--- +### Gemini-bekreftelse 2026-07-07 +Jeg bekrefter med dette min forståelse av den nye, minimale DNS-strategien: + +**1. Ønsket sluttmodell for kjerne-domener:** +* **`opax.vauco.no`:** Skal være en A-record som peker direkte til IAP Load Balancer-IP-en (`34.98.77.173`), for å sikre korrekt IAP-flyt. Dette er en endring fra dagens CNAME i Cloud DNS-sonen. +* **`git.vauco.no`:** Skal være en A-record som peker til den stabile, eksterne IP-adressen til Gitea-serveren (dev-VM). Dette er for øyeblikket blokkert til nettverk/IP er avklart. +* **`vauco.no` / `www.vauco.no`:** Er definert som fremtidig hovedinngang/portal. Innholdet er ikke en prioritet nå, men A-records for disse må være en del av den Google-styrte sonen før bytte. + +**2. Forutsetninger før nameserver-bytte:** +Før `vauco.no` kan bytte navnetjenere til Google Cloud DNS, må følgende fem punkter være fullført i `vaucono`-sonen: +1. Alle nødvendige MX-records for Google Workspace må være lagt inn. +2. `opax.vauco.no` må være korrigert fra CNAME til A-record. +3. En midlertidig host for `vauco.no` og `www.vauco.no` er klargjort og tilhørende A-records er lagt inn. +4. En stabil IP for `git.vauco.no` må være satt. +5. Det er bekreftet at ingen "legacy"-domener skal migreres. + diff --git a/docs/HANDOFF.md b/docs/HANDOFF.md index 829ad04..f3193fb 100644 --- a/docs/HANDOFF.md +++ b/docs/HANDOFF.md @@ -4,6 +4,24 @@ **Skrevet av:** Perplexity (for Chris Christiansen) **Status:** Fase D — VM oppgradert, Gitea som primær, Ollama neste +### Gitea + OPAX-MCP status (2026-07-07) + +- Gitea er migrert til CPU-VM `gitea-cpu-vm` og svarer på `http://34.67.252.59:3000` og `/api/v1/version`. +- OSVauco-repoet på dev-VM har remotes: + - `origin` + `gitea`: `http://34.67.252.59:3000/chris/OSVauco.git`. +- Alle tidligere hardkodede Gitea-IP-er er oppdatert til CPU-VM: + - `opax-mcp/server.py` (`GITEA_URL` default), + - `emma/emma_gitea.py` (Emma-klient), + - `.gemini/GEMINI.md` (PRIMARY_GIT, testkommandoer), + - `dev-start.sh` (`GITEA_REMOTE`). +- Ny `opax-mcp/gitea_handler.py` er lagt til og bruker `GITEA_URL`/`GITEA_TOKEN` fra env for Gitea-API-kall. +- Neste steg (ikke utført ennå): + - Verifisere `GITEA_TOKEN` via `gcloud secrets versions access --secret=gitea-token`, + - kjøre enkel `curl` mot `"$GITEA_URL/api/v1/version"` med token, + - deretter koble OPAX-MCP/Gitea-tools til den nye instansen. + +Dette dokumentet er oppdatert til å reflektere at Gitea på CPU-VM er ny primær Git-master; GitHub er fortsatt kun legacy/backup. + --- ## ⚠️ KRITISKE REGLER — les alltid først @@ -21,6 +39,78 @@ --- +## 📈 STRATEGISK FASEPLAN: Gitea som Source of Truth +**Status:** Planlagt + +### Arkitekturbeslutning (Låst) +- **Gitea:** Eneste "Source of Truth" for all kode. +- **OPAX-MCP:** Eneste eksterne agent-gateway (over HTTPS). +- **GitHub:** Kun en potensiell passiv backup/mirror, ikke i operativ flyt. + +### Domene-rollemodell (Låst) +- **`git.vauco.no` → Gitea:** Source of truth for kode. +- **`opax.vauco.no` → OPAX-MCP:** Ekstern agent-gateway. +- **`ops.vauco.no` → Parkert:** Droppes inntil videre for å redusere kompleksitet. + +--- + +### Fase 1: Stabiliser `opax-mcp` konfigurasjon +* **Beslutning (Låst):** Alternativ B er valgt. `opax-mcp.yaml` blir eneste autoritative kilde til sannhet for deploy-konfigurasjon. +* **Filer/Tjenester:** `opax-mcp.yaml`, `cloudbuild.mcp.yaml`, Cloud Run `opax-mcp`. +* **Verifisering:** `gcloud run services describe opax-mcp` viser korrekt konfigurasjon. + +**Fase 1 – TODO:** +* **Mål:** Én autoritativ deploy-kilde for opax-mcp (ikke manuell gcloud run deploy --source .). +* **Ferdig-kriterie:** Live-opax-mcp bygges fra en definert pipeline som matcher opax-mcp.yaml (samme env-sett og image-vei). + +### Fase 2: Etablere Gitea-capability bak OPAX-MCP +* **Mål:** Etablere Gitea-funksjonalitet bak gatewayen, med tydelig skille mellom repo/Gitea og CI/CD. +* **Filer/Tjenester:** `opax-mcp` (som gateway), en ny/dedikert Gitea-agent service. +* **Verifisering:** `curl` til `opax-mcp` ruter et Gitea-kall korrekt til backend-tjenesten og gir HTTP 200. +* **Ferdig-kriterie:** Gitea-funksjonalitet er tilgjengelig via `opax-mcp`, implementert i en separat tjeneste. + +**Fase 2 – Gitea Capabilities (Scope):** + +**Repo-lesing (Read-only):** +* `list_repo_files`: Viser filer og mapper i en gitt bane. +* `get_file_content`: Henter innholdet i en spesifikk fil. +* `list_commits`: Viser de siste commits for en branch. +* `list_open_issues`: Viser åpne issues i repoet. + +**Repo-skriving (Operator-only):** +* `update_file`: Oppdaterer en eksisterende fil (erstatter `push_file`). +* `create_issue`: Oppretter en ny issue. +* `create_branch`: Oppretter en ny branch. +* `create_commit`: Lager en ny commit med endringer. + +**Fase 2 – Implementasjonsretning (B-prime):** + +**Blocker / Prerequisite for Implementasjon:** +* `GITEA_URL` og `GITEA_REPO` **må** legges til som autoritative miljøvariabler i `opax-mcp.yaml` før koding av Gitea-handleren starter. +* Hardkodede fallback-verdier i `server.py` skal ikke lenger være kilde til sannhet for konfigurasjon. +* Logikken i `server.py` kan fortsatt bruke mønsteret `p.get('repo', GITEA_REPO)` for fleksibilitet, men kun etter at `GITEA_REPO` er deklarativt definert i YAML-filen. + +1. **Modul:** Ny fil `opax-mcp/gitea_handler.py` opprettes. Dette blir en **intern modul** i `opax-mcp`-servicen, ikke en egen microservice. +2. **Logikk:** `opax-mcp/server.py` importerer `gitea_handler` og delegerer alle Gitea-relaterte kall (`list_repo_files`, `update_file`, etc.) dit. CICD-kall forblir i `server.py`. +3. **Autentisering:** + * **Ekstern (klient → OPAX-MCP):** Håndteres av IAP, som i dag. Ingen endring. + * **Intern (OPAX-MCP → Gitea):** `gitea_handler.py` bruker et dedikert API-token til å autentisere seg mot Gitea. +4. **Secrets:** `opax-mcp.yaml` må oppdateres med `GITEA_URL` og en referanse til secret `GITEA_API_TOKEN_SECRET`. + +### Fase 3: Gitea-drevet CI/CD +* **Mål:** Sikre at Cloud Build utelukkende trigges av `git push` til Gitea. +* **Filer/Tjenester:** Cloud Build Triggers, Gitea webhooks, `cloudbuild.yaml`. +* **Verifisering:** Et `git push` til Gitea starter en ny kjøring i Cloud Build. +* **Ferdig-kriterie:** CI/CD-pipelinen er 100% Gitea-drevet. + +### Fase 4: Fjerne GitHub fra daglig drift +* **Mål:** Fjerne alle operative bindinger til GitHub. +* **Filer/Tjenester:** `cloudbuild.yaml` (GitHub App-kobling), diverse skript. +* **Verifisering:** Ingen skript eller pipelines feiler etter at GitHub-integrasjoner er fjernet. +* **Ferdig-kriterie:** GitHub er kun en passiv backup. + +--- + ## 🎯 NESTE OPPGAVE (prioritert) ### 1. Installer Ollama på osvauco-dev-vm @@ -43,9 +133,8 @@ ollama pull qwen2.5:7b # 4.7 GB — sterkere curl http://localhost:11434/api/generate -d '{"model":"gemma3:4b","prompt":"hei","stream":false}' ``` -### 4. Oppdater opax-mcp/server.py -- Pek på `http://localhost:11434` istedet for emma-gpu-vm (`34.13.238.133:11434`) -- Deploy til Cloud Run: `cd ~/OSVauco/opax-mcp && gcloud run deploy opax-mcp --source . --region us-central1 --project propane-will-491900-m5 --clear-base-image` +### 4. Oppdater opax-mcp/server.py (PARKERT/ERSTATTET) +- **Note:** Erstattet av Fase 1: `opax-mcp.yaml` som autoritativ deploy-path. Kodeendringer til `opax-mcp` skal følge den nye, stabile deploy-prosessen. ### 5. Oppdater boot.sh — Ollama autostart-sjekk - Legg til seksjon `[ OLLAMA ]` i `scripts/boot.sh` som sjekker at Ollama kjører @@ -126,6 +215,103 @@ emma-gpu-vm (stoppet — start ved behov) --- +## 🔑 TILGANGSMODELL OG PROFILER + +**Beslutning:** +- OPAX-MCP er felles ekstern gateway over HTTPS. +- Repo- og driftsverktøy er kun for operator-profiler. +- Familieprofiler og senere sluttbrukerprofiler skal ikke ha generell repo-oversikt eller generiske kodeverktøy. +- Sluttbrukere får kun oppgavebaserte capabilities med avgrenset scope. +- Nye brukere og nye hjem/oppsett skal på sikt kunne opprettes via blueprints/profiler, ikke via full teknisk tilgang. + +**Operativ tolkning:** +- “Ekstern klient” betyr Perplexity, mobilflater, familieassistenter og andre agenter/VM-er som ikke skal ha direkte tilgang til intern repo/serverstruktur. +- Disse klientene skal gå via OPAX-MCP, ikke direkte mot Gitea eller interne driftstjenester. +- Full repo-innsikt, push/write og driftstools forblir for operatornivå. +- Familie- og sluttbrukerflater skal eksponere trygge, oppgavebaserte funksjoner i stedet for generelle utviklerverktøy. +- Arkitekturen skal støtte én kjerneplattform med ulike profiler: Operator, Family og senere kunde/hjem-blueprints. + +PROFILMODELL – HVEM FÅR HVA VIA OPAX-MCP + +Operator-profil (deg og evt. få betrodde) +- Full tilgang til OPAX-MCP-verktøy for repo, drift og CICD. +- Kan lese og skrive direkte mot Gitea via Gitea-capability (list_commits, get_file, push_file, issues). +- Kan trigge og overvåke Cloud Build / Cloud Run via CICD-capability. +- Kan endre arkitektur, secrets og konfigurasjon når det er nødvendig. +- Krav: sterk auth (MCP_SECRET), bevisst bruk, og commit/push-praksis mot Gitea som sannhet. + +Family-profil (familie og nærmeste) +- Ingen generell repo-innsikt og ingen generiske kodeverktøy. +- Tilgang til oppgavebaserte capabilities (f.eks. familieplan, handleliste, meldinger, status) via OPAX-MCP. +- Kan bruke agenter og assistenter som går via OPAX-MCP, men bare innenfor trygge, avgrensede flows. +- Repo-tilgang for family skjer indirekte, som del av oppgaveverktøy, ikke som “fri coding”. +- Krav: enkel, mobilvennlig auth og minimal risiko for å påvirke drift eller arkitektur. + +Blueprint-/kunde-/hjem-profiler (senere) +- Malbaserte profiler som beskriver hvilket sett med capabilities og hvilke grenser en ny “hjem” eller kunde får. +- Hver blueprint definerer: + - Hvilke moduler som er aktive (Gitea-lesing, meldinger, økonomi, osv.). + - Hvilke verktøy er synlige i OPAX-MCP for den profilen. + - Hvilke ressurser (repoer, prosjekter, noder) er innenfor scope. +- Opprettelse av nye profiler skal skje som en bevisst handling via blueprint, ikke via ad-hoc åpning av hele systemet. + +**Tilgangsmatrise – Gitea Capabilities (Fase 2):** +* **Operator-profil:** + * **Repo-lesing:** Full tilgang. + * **Repo-skriving:** Full tilgang. +* **Family-profil:** + * **Repo-lesing:** Kun tilgang til spesifikke, trygge funksjoner (f.eks. `get_file_content` for en handleliste). Ingen generell fil-listing. + * **Repo-skriving:** Ingen tilgang. +* **Blueprint/Kunde/Hjem-profil:** + * **Repo-lesing:** Ingen tilgang som standard. Må aktiveres eksplisitt i blueprint. + * **Repo-skriving:** Ingen tilgang som standard. + +--- + +## 🔁 LÆRINGSSLØYFE FOR AGENTER OG LLM-DRIFT + +**Mål:** +- Systemet skal forbedres mens vi jobber, ikke bare etterpå. +- Høyere kvalitet skal komme fra bedre dataflyt, bedre seleksjon og bedre feedback, ikke bare større modeller. + +**Prinsipper:** +- Good data beats more data: verifiserte hendelser, faktiske diff-er, reelle feil og ekte outcome-logg er mer verdifulle enn mye støy. +- Bad data compounds: feil antakelser, uverifiserte forklaringer og gamle docs som behandles som sannhet skal ikke mates tilbake ukritisk. +- Scaling laws i praksis: mer kontekst, flere steg og mer historikk gir bare bedre resultater hvis datakvaliteten holdes høy. +- Moore’s law betyr at rå compute over tid blir billigere og mer tilgjengelig, men det løser ikke alene kvalitetsproblemet i agent- og LLM-drift. +- Bedre hardware uten bedre datahygiene gir bare raskere produksjon av de samme feilene. Derfor skal systemet utnytte begge lover samtidig: Moore’s law på compute-siden, og scaling laws på modell/data-siden. +- Arbeidslogg, handoff, learnings og verifiseringsoutput skal brukes som kuratert læringsgrunnlag for neste agent og senere trenings-/finetunegrunnlag. +- Hver økt skal produsere små, høyverdige datapunkter: diagnose, plan, apply, verifisering, avvik, beslutning. +- Praktisk betyr det at mer GPU, mer kontekst og større modeller først gir varig verdi når læringsgrunnlaget er kuratert, verifisert og forankret i reell drift. +- Strategien er: bruk økende compute til å forsterke god læring, ikke til å skalere opp støy. + +**Operativ regel:** +- Agenter skal ikke “lære” av egne antakelser alene. +- De skal lære av dokumentert virkelighet: rå output, godkjente diff-er, bekreftede feil, bekreftede fixes og tydelig markerte blockers. + +**Bruk:** +- Dette gjelder Gemini på VM, OPAX-MCP, fremtidige LLM API-agenter og senere intern eval/finetune/RAG. +- Målet er at neste agent starter klokere enn forrige, uten å arve ukritisk støy. + +--- + +## 🚚 Gitea-migreringsplan + +Diagnose har avdekket at en aktiv Gitea-instans kjører på en midlertidig VM, og at lastbalanserer peker feil. Dette løses ved en kontrollert migrering til en ny, permanent VM, ikke ved å fikse den gamle. + +* **Kilde-VM:** `osvauco-dev-from-snap` (i `us-west4-a`) +* **Kilde-data:** `/opt/gitea/data/` (inneholder `app.ini` med `ROOT_URL=http://34.59.131.162:3000/`) + +* **Mål-VM:** Ny `gitea-cpu-vm` (i `us-central1-b`, som per arkitekturbeslutning) +* **Mål-data:** `/opt/gitea/data/` + +**Nøkkelsteg ved migrering:** +1. Data fra kilde-VM må kopieres til mål-VM. +2. `ROOT_URL` i `app.ini` på mål-VM **må** oppdateres fra `http://34.59.131.162:3000/` til `https://git.vauco.no/`. +3. Lastbalanserer-backend (`vauco-os-backend`) må pekes til den nye `gitea-cpu-vm` **etter** at migreringen er testet og verifisert. + +--- + ## 📚 Relevante docs | Dok | Innhold | diff --git a/docs/LEARNINGS.md b/docs/LEARNINGS.md index 77261b5..4fe4748 100644 --- a/docs/LEARNINGS.md +++ b/docs/LEARNINGS.md @@ -194,3 +194,16 @@ Regel: Alle IAP-kall fra `osvauco-dev-vm` bruker: `curl -s https://opax.vauco.no/health -H "Authorization: Bearer $TOKEN"` Ikke bruk ADC/user-login som primær metode for IAP fra VM. Implementert i: `docs/LEARNINGS.md` (append-only), neste steg `scripts/boot.sh` / testprosedyrer + +### LEARNING-018: Agent-metodikk for Infrastruktur-endringer +Dato: 2026-07-07 +Kontekst: En serie feilkonfigurasjoner i lastbalansering for Gitea ble identifisert og løst ved å følge en strukturert, iterativ prosess. +Lærdom: For å sikre trygge og forutsigbare endringer, må en fast metodikk følges. +Regel: Følgende metode skal brukes for infrastruktur-endringer: + 1. **Diagnose:** Start alltid med read-only-kommandoer (`describe`, `list`, `get`) for å forstå nå-situasjonen. Ikke anta at dokumentasjon er 100% korrekt. + 2. **Målarkitektur:** Definer og bli enige om en klar målarkitektur før løsninger foreslås. + 3. **Planlegg & Dokumenter:** Skriv planen inn i relevant dokument (`HANDOFF.md`, etc.) som en "ikke utført" TODO-liste. Identifiser og dokumenter alle blockere. + 4. **Små Steg:** Utfør planen i de minste, logiske stegene. + 5. **Verifiser:** Verifiser resultatet med en test (`curl`, `gsutil ls`, etc.) umiddelbart etter *hver* endring. + 6. **Oppdater Sannhet:** Oppdater dokumentasjonen med resultatet, slik at neste økt starter fra en korrekt tilstand. +Implementert i: Hele Gitea LB-fiksen (juli 2026). Nå formalisert her for fremtidig bruk. diff --git a/emma/emma_gitea.py b/emma/emma_gitea.py index 485ae9e..7429688 100644 --- a/emma/emma_gitea.py +++ b/emma/emma_gitea.py @@ -8,7 +8,7 @@ class GiteaClient: Token fra GITEA_TOKEN env eller Secret Manager. """ - def __init__(self, base_url: str = "http://34.59.131.162:3000", token: str = None): + def __init__(self, base_url: str = "http://34.67.252.59:3000", token: str = None): self.base_url = base_url.rstrip("/") self.token = token or os.environ.get("GITEA_TOKEN", "") self.headers = {"Authorization": f"token {self.token}", "Content-Type": "application/json"} diff --git a/opax-mcp.yaml b/opax-mcp.yaml index b3996e9..277c033 100644 --- a/opax-mcp.yaml +++ b/opax-mcp.yaml @@ -50,8 +50,11 @@ spec: value: 38423976-91ff-4ff4-859e-1f262344c609 - name: OPAX_IAP_CLIENT_ID value: 357036551735-kq8nt7ld38hfqlcfb3n52ef7tala4meo.apps.googleusercontent.com - - name: GITEA_URL - value: http://136.111.198.14:3000 + - name: MCP_SECRET + valueFrom: + secretKeyRef: + key: latest + name: mcp-server-key - name: GITEA_TOKEN valueFrom: secretKeyRef: diff --git a/opax-mcp/gitea_handler.py b/opax-mcp/gitea_handler.py new file mode 100644 index 0000000..7ce6453 --- /dev/null +++ b/opax-mcp/gitea_handler.py @@ -0,0 +1,50 @@ +import os +import httpx +import logging + +logger = logging.getLogger(__name__) + +def _gitea_headers() -> dict: + """Constructs headers for Gitea API requests.""" + return {"Authorization": f"token {os.environ.get('GITEA_TOKEN')}", "Accept": "application/json"} + +async def handle_get_file_content(p: dict, default_repo: str) -> dict: + """Gets the raw content of a file from the Gitea repository.""" + gitea_url = os.environ.get("GITEA_URL") + if not gitea_url: + raise ValueError("GITEA_URL environment variable is not set.") + + path = p.get("path") + if not path: + raise ValueError("Missing required parameter: 'path' for get_file_content") + + repo_id = p.get("repo", default_repo) + ref = p.get("ref", "main") + + url = f"{gitea_url}/api/v1/repos/{repo_id}/raw/{path}?ref={ref}" + + async with httpx.AsyncClient(timeout=15) as c: + r = await c.get(url, headers=_gitea_headers()) + r.raise_for_status() + return {"path": path, "content": r.text, "encoding": "text"} + +async def handle_list_repo_files(p: dict, default_repo: str) -> dict: + """Lists files and directories in a given path in the Gitea repository.""" + gitea_url = os.environ.get("GITEA_URL") + if not gitea_url: + raise ValueError("GITEA_URL environment variable is not set.") + + path = p.get("path", "") + repo_id = p.get("repo", default_repo) + ref = p.get("ref", "main") + + url = f"{gitea_url}/api/v1/repos/{repo_id}/contents/{path}?ref={ref}" + + async with httpx.AsyncClient(timeout=15) as c: + r = await c.get(url, headers=_gitea_headers()) + r.raise_for_status() + files = r.json() + return { + "path": path, + "files": [{"name": f.get("name"), "type": f.get("type"), "path": f.get("path")} for f in files] + } diff --git a/opax-mcp/server.py b/opax-mcp/server.py index 3717f5b..4751bcc 100644 --- a/opax-mcp/server.py +++ b/opax-mcp/server.py @@ -21,6 +21,10 @@ from datetime import datetime, timezone, timedelta from typing import Any, Optional import logging +# Local handlers +from .gitea_handler import handle_get_file_content, handle_list_repo_files + + logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) @@ -30,7 +34,7 @@ app = FastAPI(title="opax-mcp", version="3.5.0") # BUMPED OSVAUCO_AGENT_URL = os.environ.get("OSVAUCO_AGENT_URL", "") # f.eks. https://osvauco-agent-....run.app MCP_SECRET = os.environ.get("MCP_SECRET", "") INTERNAL_API_KEY = os.environ.get("INTERNAL_API_KEY", "") -GITEA_URL = os.environ.get("GITEA_URL", "http://34.59.131.162:3000") +GITEA_URL = os.environ.get("GITEA_URL", "http://34.67.252.59:3000") GITEA_TOKEN = os.environ.get("GITEA_TOKEN", "") GITEA_REPO = os.environ.get("GITEA_REPO", "chris/OSVauco") GOOGLE_CLOUD_PROJECT = os.environ.get("GOOGLE_CLOUD_PROJECT", "propane-will-491900-m5") @@ -336,6 +340,15 @@ async def get_telemetry(p): return await _agent_get("/telemetry/h async def run_terminal(p): return await _agent_post("/terminal/exec", {"cmd": p.get("command", p.get("cmd", "help"))}) async def tui_command(p): return await _agent_post("/tui-command", p) +# --- Gitea delegators --- +async def get_file_content(p): + """Delegates to the gitea_handler to get file content.""" + return await handle_get_file_content(p, default_repo=GITEA_REPO) + +async def list_repo_files(p): + """Delegates to the gitea_handler to list repo files.""" + return await handle_list_repo_files(p, default_repo=GITEA_REPO) + # --- Uendrede funksjoner --- async def run_jason(p): """Kaller /run på osvauco-agent, som nå har sin egen JASON_BACKEND-logikk.""" @@ -389,6 +402,8 @@ TOOLS = { # Gitea / VCS "list_commits": (list_commits, "List siste commits i Gitea-repo", {}), "get_file": (get_file, "Hent fil fra Gitea-repo", {"type":"object","properties":{"path":{"type":"string"}},"required":["path"]}), + "get_file_content": (get_file_content, "Hent innholdet i en fil fra Gitea (ny handler)", {"type":"object","properties":{"path":{"type":"string"}},"required":["path"]}), + "list_repo_files": (list_repo_files, "List filer og mapper i Gitea (ny handler)", {"type":"object","properties":{"path":{"type":"string"}}}), # Google Workspace "create_email_alias": (create_email_alias, "Opprett et nytt e-postalias", {"type":"object","properties":{"user_key":{"type":"string"},"alias":{"type":"string"}},"required":["user_key","alias"]}), "list_user_aliases": (list_user_aliases, "List en brukers e-postaliaser", {"type":"object","properties":{"user_key":{"type":"string"}},"required":["user_key"]}),