diff --git a/.gemini/GEMINI.md b/.gemini/GEMINI.md index f880476..5197571 100644 --- a/.gemini/GEMINI.md +++ b/.gemini/GEMINI.md @@ -16,9 +16,10 @@ GCP_REGION: europe-west1 GCP_VERTEX_LOC: eu CLOUD_RUN_SVC: osvauco-agent ARTIFACT_REPO: gcr.io/propane-will-491900-m5 -MODEL: claude-opus-4-6@20260801 -MODEL_PROVIDER: Vertex AI (Anthropic Claude via Google Cloud) -MODEL_COST: ~2 NOK per 1M tokens (input) +MODEL: gemini-2.5-pro +MODEL_PROVIDER: Vertex AI (Google) — europe-west1 +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 @@ -402,6 +403,6 @@ Auth: Google OAuth now. BankID on `-os` later (Medioteq first). Lim inn dette ved start av HVER sesjon: ``` -BOOT: Read docs/AGENT_RULEBOOK.md, docs/VAUCO_OS_ROADMAP.md, docs/OSVAUCO_OPAX_SESSION_LOG.md. -Print LOCKED DEFINITIONS. Print last NESTE OPPGAVE. Do not take any action until I give a PLAN prompt. +BOOT: Read docs/AGENT_RULEBOOK.md, docs/MASTERPLAN.md, docs/ROADMAP.md, docs/HANDOFF.md. +Print LOCKED DEFINITIONS. Print NESTE OPPGAVE from HANDOFF.md. Do not take any action until I give a PLAN APPROVED prompt. ``` diff --git a/.geminiignore b/.geminiignore new file mode 100644 index 0000000..af665e7 --- /dev/null +++ b/.geminiignore @@ -0,0 +1,13 @@ +# .geminiignore — filer Gemini CLI skal ignorere +# (NB: session-context i tmp-context/ er IKKE listet her, så CLI kan lese den) + +node_modules/ +.terraform/ +*.tfstate +*.tfstate.backup +infrastructure/terraform/tfplan +**/tfplan +dist/ +build/ +.next/ +.cache/ diff --git a/.gitignore b/.gitignore index 46a3886..4e85a6e 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,5 @@ tfplan.txt infrastructure/terraform/tfplan **/tfplan !infrastructure/terraform/customers/**/*.tfvars + + diff --git a/MASTERPLAN.md b/MASTERPLAN.md index 399ddd7..fafc9c9 100644 --- a/MASTERPLAN.md +++ b/MASTERPLAN.md @@ -1,307 +1,10 @@ -# VAUCO OS — MASTERPLAN RESET -**Versjon:** 2026-05-27 | **Eier:** Chris Christiansen | **Status:** Autoritativ +# MASTERPLAN ---- +> **Denne filen er flyttet.** Den autoritative versjonen ligger nå i [`docs/MASTERPLAN.md`](docs/MASTERPLAN.md). +> +> Konsolidert 2026-05-31 — én kilde til sannhet. -## 1. SITUASJONSANALYSE — Hvor er vi nå? - -Du har bygget mye bra, men jobbet utenfra inn i stedet for innenfra ut. Det har skapt: - -- **Dobbelt opp:** To CostGuard-implementasjoner, dupliserte MD-filer, overlappende repos -- **Repo-kaos:** 9 repos for det som egentlig er 1 kjerne + 1 produkt -- **Tapt tråd:** TUI-bridge → OPAX → Pages → CostGuard-landing — hvert sprang tok deg vekk fra planen -- **Manglende kryssjekk:** MASTERPLAN, ROADMAP og HANDOFF er ikke synkroniserte - -**Det gode:** Alt ligger nå på `vauco-saas`. Grunnmuren (Cloud Run, RAG, Memory, OAuth) er solid. - ---- - -## 2. SANNHETEN OM HVA DU HAR - -### To separate ting — hold dem adskilt - -``` -Vauco AS -├── VAUCO OS (intern plattform — kun Chris) -│ └── Formål: operere, bygge og selge fra -│ -└── THREADSTONE (eksternt SaaS-produkt — til kunder) - └── Formål: selges til bedrifter -``` - -Og et tredje prosjekt under utvikling: - -``` -└── PROOF OF CURIOSITY (separat merkevare/prosjekt) - └── Domener registrert, ikke lansert ennå -``` - -Disse skal ALDRI blandes i samme repo, samme deploy eller samme domenestruktur. - ---- - -## 3. REGISTRERTE DOMENER - -### Vauco (hos Proisp) - -| Domene | Prosjekt | Status | -|--------|----------|--------| -| `vauco.no` | Vauco OS / alle Vauco-tjenester | ✅ Aktiv, verifisert på GitHub | - -**Aktive subdomener under vauco.no:** - -| Subdomen | Teknologi | Status | -|----------|-----------|--------| -| `opax.vauco.no` | CNAME → Cloud Run | ✅ Live | -| `oss.vauco.no` | Staging-miljø | ✅ Aktiv | -| `os.vauco.no` | Prod-miljø | 🔮 Fase C | -| `costguard.oss.vauco.no` | CNAME → Cloud Run | ⏳ CG3 | -| `costguard.os.vauco.no` | Promoveres fra oss | 🔮 Fase C | -| `threadstone.vauco.no` | GitHub Pages | ✅ Live | -| `app.threadstone.vauco.no` | GitHub Pages | ✅ Live | -| `kunde1.vauco.no` | LB + IAP via Terraform | 🔮 Fase C | - -### Proof of Curiosity (hos Proisp) - -| Domene | Merknad | -|--------|---------| -| `proof-of-curiosity.com` | Registrert — ikke i bruk | -| `proofofcuriosity.com` | Registrert — ikke i bruk | -| `proofofcuriosity.io` | Registrert — ikke i bruk | -| `proof-of-curiosity.no` | Registrert — ikke i bruk | -| `proofofcuriosity.no` | Registrert — ikke i bruk | - -> **Notat:** Proof of Curiosity er et separat prosjekt/merkevare. Ingen repos eller infrastruktur er knyttet til disse domenene ennå. Prioriteres etter CG3 + første Vauco-kunde. - ---- - -## 4. REPO-STRUKTUR — Fasit - -### Behold (4 repos) - -| Repo | Formål | Synlighet | -|------|--------|-----------| -| `OSVauco` | Alt kjerne: Cloud Run, GCP-scripts, ml/, auth/, docs/ | Privat | -| `vauco-bootstrap` | Terraform-modul for kunde-provisjonering | Privat | -| `threadstone-landing` | threadstone.vauco.no landingsside | Public | -| `vauco-saas.github.io` | app.threadstone.vauco.no (Threadstone-app) | Public | - -### Arkiver (5 repos) — flytt innhold først - -| Repo | Innhold flyttes til | Deretter | -|------|---------------------|----------| -| `vauco-os` | `OSVauco/docs/architecture/` | Arkiver | -| `vauco-gemini-tui-bridge` | `OSVauco/tui/` | Arkiver | -| `command-hub` | `OSVauco/static/command-hub.html` | Arkiver | -| `threadstone-instructions` | `OSVauco/docs/threadstone/` | Arkiver | -| `deep-dream` | Rør ikke — arkiver direkte | Arkiver | - ---- - -## 5. OSVauco — INTERN MAPPESTRUKTUR (fasit) - -``` -OSVauco/ -├── infrastructure/ # GCP-scripts (00-11) -├── scripts/ # smoke-test, utils -├── ml/ # billing_agent, anomaly_detector, feedback_loop -├── auth/ # OAuth2-flow -├── tui/ # ← vauco-gemini-tui-bridge flyttes hit -├── static/ # HTML-filer servert av Cloud Run -│ ├── billing-dashboard.html -│ ├── costguard.html ← CG3 (bygges her, ikke GitHub Pages) -│ └── command-hub.html ← fra command-hub repo -├── docs/ -│ ├── MASTERPLAN.md ← autoritativ (denne filen) -│ ├── ROADMAP.md ← én roadmap, ikke to -│ ├── HANDOFF.md ← alltid én fil, overskrives per sesjon -│ ├── architecture/ ← fra vauco-os repo -│ ├── threadstone/ ← fra threadstone-instructions repo -│ └── [alle andre MD-filer] -├── .gemini/ # Gemini TUI konfig -├── .env.example -├── Dockerfile -├── main.py -└── MASTERPLAN.md ← denne filen (rot-nivå) -``` - ---- - -## 6. DOKUMENTHIERARKI — Én kilde til sannhet - -| Fil | Rolle | Oppdateres | -|-----|-------|------------| -| `MASTERPLAN.md` | Arkitektur, domener, agent-identitet, infrastruktur — **aldri slett** | Ved arkitekturendringer | -| `docs/ROADMAP.md` | Fasestatus, neste steg, backlog — **levende dokument** | Hver sesjon | -| `docs/HANDOFF.md` | Alltid kun én fil — hva ble gjort, hva er neste, kjente hull | Overskrives hver sesjon | - -**Regel:** Arkitektur → MASTERPLAN. Oppgave → ROADMAP. Sesjonsstatus → HANDOFF. Aldri dobbelt opp. - ---- - -## 7. ROADMAP — Prioritert rekkefølge - -### 🔴 UMIDDELBART — Rydding (gjør én gang) - -| # | Oppgave | Tid | -|---|---------|-----| -| R1 | Flytt `vauco-os` → `OSVauco/docs/architecture/` | 30 min | -| R2 | Flytt `vauco-gemini-tui-bridge` → `OSVauco/tui/` | 20 min | -| R3 | Flytt `command-hub` → `OSVauco/static/command-hub.html` | 10 min | -| R4 | Arkiver de 5 reposene på GitHub | 10 min | -| R5 | Slett duplikat-MD-filer i `docs/` | 15 min | -| R6 | Synkroniser ROADMAP til faktisk repo-state | 30 min | - -### 🟡 NESTE — CG3 (CostGuard landingsside) - -| # | Oppgave | -|---|---------| -| CG3a | Bygg `static/costguard.html` i OSVauco (OAuth-knapp + billing embed) | -| CG3b | Sett CNAME `costguard.oss.vauco.no` → Cloud Run i Proisp | -| CG3c | Verifiser at `/static/costguard.html` er tilgjengelig via Cloud Run | -| CG3d | Test OAuth-flow fra landingssiden | - -### 🟢 GO-TO-MARKET — CostGuard - -| Fase | Innhold | -|------|---------| -| C4 | Medioteq HITL-møte → `terraform apply` → første betalende kunde | -| C5 | Salgsdemo: costguard.os.vauco.no + demo-video | -| DX5 | Dialogflow Messenger live på costguard-landingssiden | -| ML-2 | Adaptiv intelligens (trigger: >500 telemetri-kall) | - -### 🔵 FREMTID — Proof of Curiosity - -| # | Oppgave | -|---|---------| -| POC-1 | Definer hva Proof of Curiosity er (produkt, merkevare, community?) | -| POC-2 | Velg primærdomene (anbefaling: `proofofcuriosity.io`) | -| POC-3 | Opprett repo under `vauco-saas` eller separat org | -| POC-4 | Bygg landing/MVP | - -> **Trigger:** Ikke start POC før CG3 er live og første Vauco-kunde er onboardet. - ---- - -## 8. AGENT-IDENTITET - -| Identitet | E-post | Rolle | -|-----------|--------|-------| -| Eier / admin | `chris.christiansen@vauco.no` | Full kontroll | -| Agent (OPAX / Jason) | `jason.vauger@vauco.no` | `billing.viewer` — hente og rapportere kostnadsdata | -| Fremtidig gruppe | `billing@vauco.no` | `billing.viewer` (Fase C) | - ---- - -## 9. CLOUD RUN — LIVE ENDEPUNKTER - -**Service:** `osvauco-agent` | **Region:** `europe-west1` -**URL:** `https://osvauco-agent-357036551735.europe-west1.run.app` - -| Endepunkt | Status | -|-----------|--------| -| `GET /health` | ✅ | -| `POST /run` | ✅ | -| `POST /run/dag` | ✅ | -| `GET /billing/summary` | ✅ | -| `GET /billing/forecast` | ✅ | -| `GET /billing/anomalies` | ✅ | -| `GET /auth/login` | ✅ | -| `GET /auth/callback` | ✅ | -| `GET /static/billing-dashboard.html` | ✅ | -| `GET /state` | ✅ | -| `GET /telemetry/history` | ✅ | - ---- - -## 10. TUI-BRIDGE — Status - -Planen var lokal TUI for å kode fra hvor som helst. -Det som skjedde: OPAX + Cloud Shell + Gemini TUI løste behovet. - -**Konklusjon:** Koden bevares i `OSVauco/tui/`. Reaktiveres etter CG3 + første kunde hvis behovet melder seg igjen. - ---- - -## 11. GO-TO-MARKET — Enkel og konkret - -**Produkt #1: CostGuard** -- **Hvem:** Norske bedrifter med GCP-kostnader de ikke kontrollerer -- **Hva:** Autonomt kostnadsovervåkningsverktøy med AI-anomali-deteksjon -- **Pris:** $300-500/mnd per kunde (breakeven ved 1 kunde) -- **Salgskanal:** Chris selv via OPAX → HITL-møte → `terraform apply` - -**Ikke selg Vauco OS. Ikke selg OPAX. De er interne verktøy.** - ---- - -## 12. KJENTE HULL - -| ID | Problem | Løsning | Prioritet | -|----|---------|---------|-----------| -| OQ-15 | BQ billing_export tabell | Venter på aktivering — sjekk neste sesjon | Medium | -| OQ-16 | Duplikat CostGuard-implementasjoner | Slett gammel, behold `ml/billing_agent.py` | Høy | -| OQ-17 | `github-token` secret mangler | Opprett alias fra `github-pat` | Medium | -| OQ-18 | VM alltid-på kostnad | Kjør `03-teardown.sh` hver kveld | Høy | -| OQ-19 | MASTERPLAN/ROADMAP ikke synkronisert | Gjøres som del av R6 | Høy | - ---- - -## 13. OPAX — FREMTIDIG VISJON (parkert, prioriteres etter CG3) - -> Notert 2026-05-28. Ikke bygg dette nå — fokus er CG3 + UI/UX-opprydding. - -### Hva OPAX skal bli - -OPAX (`opax.vauco.no`) er Chris sin **mobile salgssentral**. Ikke en terminal, ikke et dashboard — en stille, tekstbasert assistent han kan snakke MED via AirPods mens han er i møte med en potensiell kunde. - -### Flyt: tale → modul → provisjonering - -``` -Chris snakker (AirPods, Web Speech API / Whisper) - ↓ -OPAX transkriberer tale — aldri lyd ut, kun tekst inn - ↓ -Jason analyserer: "hvem er kunden, hva trenger de" - ↓ -Genererer ferdig kundeskreddersydd modul (HTML + config) - ↓ -Chris reviewer på skjerm — sier "kjør" eller "send" - ↓ -OPAX sender mail fra vauco.no med magic link - ↓ -Kunde logger inn med godkjent e-postadresse (ingen passord) -``` - -### Prinsipper - -- **OPAX snakker aldri** — kun tekst på skjerm, ingen TTS -- **Voice er kun inn** — Web Speech API (gratis, Chrome/Safari) eller Whisper -- **Silent assistant** — OPAX er stille, rask, mørk, monospace -- **Provisjonering on-the-go** — modul lages mens Chris er i møtet, sendes direkte -- **Auth** — magic link til kundens mail, eller forhåndsgodkjent e-postadresse - -### Teknisk stack (når det bygges) - -| Komponent | Teknologi | -|-----------|-----------| -| Voice-input | Web Speech API (fase 1) → Whisper API (fase 2) | -| Module generator | Gemini 2.5 Pro + customer-template | -| Auth/provisjonering | Magic link via SendGrid/Resend fra `vauco.no` | -| UI | Mørk, monospace, minimalistisk — lever i `static/opax.html` | -| Backend | Nytt endepunkt `POST /opax/generate` i `main.py` | - -### Hva som IKKE skal inn i OPAX - -- Ingen TTS / robot-stemme -- Ikke erstatte command-hub.html direkte — de har ulike roller -- Ikke blande med Threadstone-customer-template logikk - -### Når starter vi? - -**Trigger:** CG3 er live OG `static/` UI/UX-opprydding er gjort. -Første steg da: bygg `static/opax-v2.html` med tale-input + chat-display. - ---- - -*OSVauco | propane-will-491900-m5 | europe-west1 | Autoritativ fra 2026-05-27* +Se også: +- [`docs/ROADMAP.md`](docs/ROADMAP.md) — levende roadmap +- [`docs/HANDOFF.md`](docs/HANDOFF.md) — gjeldende sesjonsstatus +- [`docs/AGENT_RULEBOOK.md`](docs/AGENT_RULEBOOK.md) — locked definitions for agent-boot diff --git a/Procfile b/Procfile deleted file mode 100644 index 857555b..0000000 --- a/Procfile +++ /dev/null @@ -1,5 +0,0 @@ -# NOTE: This file is legacy from an early proof-of-concept. -# Cloud Run uses container entrypoint (Dockerfile), not Procfile. -# Kept for reference only — do not use for deployment. -web: uvicorn main:app --host 0.0.0.0 --port $PORT --workers 1 - diff --git a/docs/AGENT_RULEBOOK.md b/docs/AGENT_RULEBOOK.md index 6a8bc26..18fb9ee 100644 --- a/docs/AGENT_RULEBOOK.md +++ b/docs/AGENT_RULEBOOK.md @@ -1,36 +1,44 @@ -# VAUCO OS — AGENTRLEBOOK.md -# Eier: OPS-Computer-Hub -# Sist oppdatert: 2026-05-21 CEST -# Godkjent av: Chris Christiansen +# VAUCO OS — AGENT_RULEBOOK.md + +**Eier:** OPS-Computer-Hub +**Sist oppdatert:** 2026-05-31 CEST +**Godkjent av:** Chris Christiansen --- ## Hensikt -Immutable regler for alle 4 tråder. Ingen tråd kan overstyre disse. -Endringer krever eksplisitt godkjenning fra Chris. + +Immutable regler for alle agent-tråder. Ingen tråd kan overstyre disse. +Endringer krever eksplisitt godkjenning fra Chris (`RULEBOOK APPROVED`). --- -## LOCK LIST — ALDRI ENDRE +## LOCK LIST — ALDRI ENDRE UTEN EKSPLISITT GODKJENNING | Parameter | Verdi | |-------------------|-----------------------------------------------------------------------| -| GCP Account | chris.christiansen@vauco.no | -| Forbudte kontoer | tinius.vauger, ccv, jason.vauger | -| GCP Project | propane-will-491900-m5 (Jason-v1) | -| Billing | 0171F6-057E6B-A260BA | -| Org | vauco.no / 155051211891 | -| Region | us-central1 — ALDRI us-west1 | -| SDK | `from google import genai` — ALDRI `vertexai.generative_models` | -| Agent-rammeverk | Google ADK (tillatt) — andre må eksplisitt `ADK_GODKJENT` av Chris | -| GitHub user | vauco-saas | -| Canonical repo | OSVauco | -| Canonical branch | main | -| MCP_NAME | OPAX-MCP | -| MCP_PROTOCOL | OPAX Protocol | -| MCP_SERVICE | opax-mcp-core (Cloud Run, us-central1) | -| ROOT_DOMAIN | vauco.no | -| HUB_URL | https://opax.vauco.no ✅ LIVE 2026-05-21 | +| GCP Account | `chris.christiansen@vauco.no` | +| Forbudte kontoer | `tinius.vauger`, `ccv` | +| Agent-konto | `jason.vauger@vauco.no` (kun `billing.viewer` + `run.invoker`) | +| GCP Project | `propane-will-491900-m5` (Jason-v1) | +| Billing | `0171F6-057E6B-A260BA` | +| Org | `vauco.no` / `155051211891` | +| **Region** | **`europe-west1`** — ALDRI `us-central1` eller `us-west1` | +| **Vertex AI loc** | **`europe-west1`** (EU) | +| **AI-modell** | **`gemini-2.5-pro`** via Vertex AI (venter på Claude EU-kvote) | +| SDK | `from google import genai` (google-genai >=0.3) | +| Agent-rammeverk | Google ADK (tillatt) — andre må eksplisitt `ADK_GODKJENT` av Chris | +| GitHub org | `vauco-saas` | +| Canonical repo | `OSVauco` | +| Canonical branch | `main` | +| MCP_NAME | `OPAX-MCP` | +| MCP_PROTOCOL | `OPAX Protocol` | +| **MCP_SERVICE** | **`osvauco-agent`** (Cloud Run, `europe-west1`) | +| ROOT_DOMAIN | `vauco.no` | +| HUB_URL | `https://opax.vauco.no` ✅ LIVE 2026-05-21 (LB IP `34.98.77.173`) | + +> **Endringslogg:** +> - 2026-05-31: Region rettet `us-central1` → `europe-west1`. Modell rettet til `gemini-2.5-pro` (midlertidig). MCP_SERVICE rettet `opax-mcp-core` → `osvauco-agent`. Vertex AI loc lagt til. --- @@ -45,133 +53,71 @@ Endringer krever eksplisitt godkjenning fra Chris. > `-os` = produksjon. `-oss` = staging. Aldri omvendt. **Auth-strategi:** -- Nå: Google OAuth på alle miljøer +- Nå: Google OAuth + IAP på alle miljøer - Senere: BankID på `-os`-domener for kliniske kunder (Medioteq først) **Kjente/planlagte domener:** -| Domene | Status | Cloud Run-tjeneste | -|---------------------------|------------------|-----------------------| -| `opax.vauco.no` | ✅ LIVE | `opax-mcp-core` | -| `medioteq-oss.vauco.no` | Planlagt | `medioteq-oss-core` | -| `medioteq-os.vauco.no` | Planlagt | `medioteq-os-core` | +| Domene | Status | Cloud Run-tjeneste | +|------------------------------|------------------|-----------------------| +| `opax.vauco.no` | ✅ LIVE | `osvauco-agent` | +| `costguard.oss.vauco.no` | ✅ LIVE | (Cloudflare Pages) | +| `medioteq-oss.vauco.no` | Planlagt | `medioteq-oss-core` | +| `medioteq-os.vauco.no` | Planlagt | `medioteq-os-core` | +| `threadstone.vauco.no` | ✅ LIVE | (GitHub Pages) | +| `app.threadstone.vauco.no` | ⚠️ CNAME satt | (GitHub Pages — side mangler) | --- -## HITL-GATES — STOPP OG SPØR ALLTID +## HITL GATES — ingen tråd kan hoppe over disse -1. `DEPLOY GODKJENT` — før deploy til Cloud Run -2. `MERGE APPROVED` — før merge til main -3. `DEEP DREAM GODKJENT` — før strategisk vokabular eksponeres -4. `COST GODKJENT` — før endringer som påvirker billing -5. `IAM_GODKJENT` — før IAM-endringer eller ny service account -6. `NEWREPO` — før opprettelse av ny repo +| Gate | Når kreves | +|----------------------|----------------------------------------------------------| +| `PLAN APPROVED` | Før noen kode/infra-endring starter | +| `MERGE APPROVED` | Før PR merges til `main` | +| `DEPLOY GODKJENT` | Før manuell deploy som rører IAP, OAuth, Secret Manager | +| `REPO APPROVED` | Før nye repos opprettes under `vauco-saas` | +| `MODEL APPROVED` | Før AI-modell byttes | +| `RULEBOOK APPROVED` | Før endringer i denne filen | +| `FASE APPROVED` | Når en fase er verifisert komplett | --- -## BOOT-PROTOKOLL — kjøres av ALLE tråder ved oppstart +## DOKUMENTHIERARKI — én kilde til sannhet -1. Branch-discovery: list alle branches, finn mest aktiv (ahead av default) - - Hvis 1+ branch er 10+ commits ahead: STOPP og spør Chris - - Standard: OSVauco/main er canonical for dette prosjektet -2. Les eid fil + MASTER_HANDOFF_v2 + ROADMAP fra riktig branch -3. Bekreft i én linje: `Boot OK — branch X, HEAD Y, oppgave Z` +| Fil | Rolle | +|-----|-------| +| `docs/MASTERPLAN.md` | Arkitektur, domener, repos, fasit | +| `docs/ROADMAP.md` | Levende roadmap, faser, status | +| `docs/HANDOFF.md` | Sesjonsstatus — **alltid kun én fil**, overskrives | +| `docs/AGENT_RULEBOOK.md` | Denne filen — locked definitions | +| `protocols/sessions/YYYY-MM-DD_.md` | Detaljerte sesjonsprotokoller (append-only) | + +> **Aldri opprett flere parallelle MASTERPLAN, ROADMAP eller HANDOFF.** --- -## VOCABULARY FIREWALL +## AGENT-OPPFØRSEL — kjerneregler -| Type | Ord | Regel | -|---|---|---| -| Offentlig (OK overalt) | Token Ledger, VVN, Provenance, File signature, Client identity record, Cognitive contribution, The system | Fritt bruk | -| Strategisk (KUN internt) | Pregeverdi, Deep Dream, Vauco-arv, Pregesignatur, T-konto, Work of Living, Pregeverk | KUN i `deep-dream/`-mappe | +1. **Foreslå før du handler.** Print plan. Vent på `PLAN APPROVED`. +2. **Self-modifisering av infra/secrets/IAM uten godkjenning = hard stop.** +3. **Print LOCKED DEFINITIONS ved boot.** Sjekk at de matcher denne filen. +4. **Sjekk pwd før kommandoer.** Alltid `cd ~/OSVauco` ved start. +5. **Logg sesjonsslutt.** Append til `docs/OSVAUCO_OPAX_SESSION_LOG.md`. +6. **Ikke stol på alias.** Sjekk `which ` ved tvil. +7. **Region-guard.** Kjør `infrastructure/99-region-guard.sh` ved tvil om region. --- -## KOST-DISIPLIN +## BOOT-PROTOKOLL -- $3/dag hard cap per tråd -- `gemini-2.5-flash` for enkle steg, `pro` for komplekse -- ALDRI rekursive modell-loops -- Hvis tråden bruker $1 på én oppgave: STOPP, rapporter, spør -- 80%/95%/100% quota stops aktive +``` +BOOT: Les docs/AGENT_RULEBOOK.md, docs/MASTERPLAN.md, docs/HANDOFF.md. +Print LOCKED DEFINITIONS fra Lock List. +Print NESTE OPPGAVE fra docs/HANDOFF.md. +Vent på PLAN-prompt før noen handling. +``` --- -## FRICTION-REGLER (kodifisert lærdom) - -### TASK-FRICTION-001: Branch-discovery-before-read -Preflight må advare hvis non-default branch er 10+ commits ahead. -Implementer i: `scripts/preflight-check.sh` - -### TASK-FRICTION-002: SYSTEM_STATE_AGENT_BOOT autogenerering -Boot-script skriver fersk state-fil ved hver tråd-oppstart. -Implementer i: `scripts/boot-state.sh` (EXEC eier) - -### TASK-FRICTION-003: Eierskap-matrise håndhevet i pre-commit -Pre-commit hook avviser commit hvis fil endres av feil tråd. -Implementer i: `.githooks/pre-commit` (OPS eier) - ---- - -## KORREKSJONS-REGEL - -Ground truth wins always. -1. Innrøm direkte i én setning -2. Oppdater eid fil med korreksjon -3. Fortsett -ALDRI forsvar gamle posisjoner. - ---- - -## KOMMUNIKASJON MELLOM TRÅDER - -- ML-TRÅD: Chris kopierer melding over -- Filer flyter via GitHub (`OSVauco` + tjeneste-repoer) -- Aldri direkte tråd-til-tråd — alt via committed MD eller Chris - ---- - -## EIERSKAP-MATRISE - -| Fil | Eier | Andre kan | -|---|---|---| -| VAUCO_OS_MASTER_HANDOFF_v2.md | OPS | lese | -| VAUCO_OS_ROADMAP.md | PLAN | lese, foreslå patch via PR | -| SYSTEM_STATE_AGENT_BOOT.md | EXEC | lese | -| docs/AGENTRLEBOOK.md | OPS | lese | -| docs/ARCHITECTURE.md | PLAN | lese, foreslå patch via PR | -| docs/LEARNINGS.md | OPS | lese, foreslå append | -| docs/RISKREGISTER.md | AUDIT | lese | -| docs/PLANBOARD.md | AUDIT | lese | -| CHANGELOG.md | OPS | lese | -| TODO.md | EXEC | lese | - -Regel: én fil — én eier. Andre foreslår via PR, eier merger. - ---- - -## IAP + Cloud Run Setup - -### IAP + Cloud Run — Obligatorisk konfigurasjon - -Når Cloud Run eksponeres via IAP + Load Balancer må følgende tre ting være på plass: - -1. **Cloud Run ingress: `internal-and-cloud-load-balancing`** - ```bash - gcloud run services update --ingress internal-and-cloud-load-balancing - ``` - -2. **IAP service account må ha `run.invoker`-rollen** - ```bash - gcloud run services add-iam-policy-binding \ - --member=serviceAccount:service-@gcp-sa-iap.iam.gserviceaccount.com \ - --role=roles/run.invoker - ``` - -3. **IAP policy: `domain:vauco.no` med `roles/iap.httpsResourceAccessor`** - -Uten punkt 2 får alle brukere 403 selv om IAP-policy er korrekt. - ---- -EOF v1.2 — 2026-05-21 — OPS-Computer-Hub (Phase 2: HUB_URL locked LIVE, domain status updated) +*Vauco AS · `propane-will-491900-m5` · `europe-west1`* diff --git a/docs/HANDOFF.md b/docs/HANDOFF.md new file mode 100644 index 0000000..1e881f8 --- /dev/null +++ b/docs/HANDOFF.md @@ -0,0 +1,175 @@ +# HANDOFF — Vauco OS + +**Sist oppdatert:** 2026-05-31 ~16:30 CEST +**Skrevet av:** Perplexity (Sonnet 4.6) på vegne av Chris Christiansen +**Status:** Repo-konsolidering pågår. Klar for Fase 8 verifisering rett etter merge. + +> **Regel:** Dette er **den eneste** HANDOFF-filen. Overskrives hver sesjon. Tidligere handoffs er flyttet til `docs/archive/handoffs/`. + +--- + +## 🔴 ABSOLUTT REGEL #1 + +**Du gjør ingenting uten at Chris eksplisitt skriver `PLAN APPROVED` eller et tilsvarende godkjenningssignal.** +Du er en assistent, ikke en autonom agent. Foreslå. Vent. Utfør kun etter godkjenning. +Self-modifisering av infrastruktur, secrets, IAM eller produksjonsmiljø uten godkjenning = **hard stop**. + +--- + +## 🏗 Hva er dette prosjektet? + +Se `docs/MASTERPLAN.md` for full sannhet. Kortversjonen: + +``` +Vauco OS (plattform) + └── OPAX (engine på Cloud Run europe-west1) + ├── CostGuard (Modul #1 — live på costguard.oss.vauco.no) + ├── Threadstone (Modul #2 — Q3 2026) + └── [Modul #3+] +``` + +Første betalende produkt: **CostGuard** (GCP-kostnadsanalyse via AI). + +--- + +## ✅ Hva er faktisk ferdig (ikke spør om dette igjen) + +| Komponent | Status | +|---|---| +| Cloud Run `osvauco-agent` | ✅ Live, `europe-west1` | +| `opax.vauco.no` (LB + SSL) | ✅ Live, IP `34.98.77.173` | +| IAP (`@vauco.no` only) | ✅ Aktivert | +| CI/CD Cloud Build → Cloud Run | ✅ Operativt (auto-deploy på push til main) | +| RAG corpus `osvauco-corpus` | ✅ Populert, `europe-west4` | +| OAuth2 (Google) | ✅ I Secret Manager | +| Budget guard (500 NOK/mnd) | ✅ Live | +| AI-modell | ✅ `gemini-2.5-pro` via Vertex AI EU (midlertidig — venter på Claude-kvote) | +| `costguard.oss.vauco.no` | ✅ Live (Cloudflare Pages) | +| Terraform bootstrap-modul | ✅ I `infrastructure/terraform/modules/` | +| BigQuery dataset + sink | ⏳ Oppe, men tabell ikke populert ennå | + +--- + +## 🟡 Denne sesjonen (2026-05-31) — Konsolidering + vauco.no inkorporert + +PR `chore/consolidate-2026-05-31` rydder: + +- ✅ Ny `docs/MASTERPLAN.md` (autoritativ, erstatter både rot-`MASTERPLAN.md` og gammel docs-versjon) + - **Ny seksjon §4b:** `vauco.no` salgsportal — formål, IA, visuell retning, salgs-flow, evolusjon V1→V4 + - **Hierarkiet utvidet til 4 nivåer:** apex (`vauco.no`) lagt til som egen kunde-flate + - **Nye reserverte subdomener** dokumentert: `status.`, `docs.`, `careers.` +- ✅ Ny `docs/ROADMAP.md` (erstatter `docs/VAUCO_OS_ROADMAP.md`) + - **V-spor lagt til:** V1a–V1e (vauco.no MVP) — kan kjøres parallelt med CG3 +- ✅ Ny `docs/HANDOFF.md` (denne filen — eneste handoff fra nå) +- ✅ Ny `docs/vauco-site/DESIGN.md` (klar-til-plukk-opp spec for V1) +- ✅ Oppdatert `docs/AGENT_RULEBOOK.md` (region, modell, MCP_SERVICE rettet) +- ✅ Slettet `docs/archive/{Cost_Management_Rules.md,GCPBestPractices.md,OSVAUCO_OPAX_SESSION_LOG.md}` (duplikater) +- ✅ Fjernet Git merge-konfliktmarkører i `docs/OSVAUCO_OPAX_SESSION_LOG.md` +- ✅ Flyttet `HANDOFF_20260526.md`, `HANDOFF_20260531.md`, `HANDOFF_20260531_claude47.md` → `docs/archive/handoffs/` +- ✅ Slettet `Procfile` (legacy, ikke brukt av Cloud Run) +- ✅ Slettet `docs/VAUCO_OS_ROADMAP.md` (erstattet av ROADMAP.md) +- ✅ Oppdatert `docs/TODO.md` til å peke på ROADMAP + +**Andre hull avdekket og dokumentert i MASTERPLAN §11 + ROADMAP:** +- OQ-23: `vauco.no` viser "Under construction" — fikses i V1 +- OQ-24: Mangler SPF/DKIM/DMARC — salgsmail havner i spam +- OQ-25: Mangler personvern.html/vilkar.html — GDPR-krav før betalende kunde +- OQ-26: Ingen statuspage — trust-signal etter første kunde + +**Etter merge — to spor parallelt:** +- **F8** (end-to-end test av OPAX) +- **V1** (vauco.no MVP) + +--- + +## 🔄 Neste oppgave: Fase 8 — End-to-end test (browser) + +Cloud Run og IAP er allerede verifisert (`/health` OK via Cloud Run, IAP blokkerer uautentisert). + +**Det som gjenstår:** + +### Steg 1 — Verifiser modell-config +```bash +# Sjekk at app bruker gemini-2.5-pro, ikke Claude +gcloud run services describe osvauco-agent --region europe-west1 \ + --format='value(spec.template.spec.containers[0].env[?(@.name=="VERTEX_MODEL")].value)' +# Forventet: gemini-2.5-pro +``` + +### Steg 2 — Test Vertex Gemini direkte +```bash +curl -X POST \ + "https://europe-west1-aiplatform.googleapis.com/v1/projects/propane-will-491900-m5/locations/europe-west1/publishers/google/models/gemini-2.5-pro:generateContent" \ + -H "Authorization: Bearer $(gcloud auth print-access-token)" \ + -H "Content-Type: application/json" \ + -d '{"contents":[{"role":"user","parts":[{"text":"ping"}]}]}' +# Forventet: JSON med tekst-svar +``` + +### Steg 3 — Full end-to-end +Logg inn på `https://opax.vauco.no` med `chris.christiansen@vauco.no` → send en melding → verifiser at agenten svarer. + +**HITL gate:** Skriv `FASE8 APPROVED` i denne filen + i ROADMAP når alle steg er verifisert. + +--- + +## 🔜 Etter Fase 8 — to spor parallelt + +**Spor A — CG3 (CostGuard frontend wiring)** — inntektsmotor +**Spor B — V1 (vauco.no salgsportal)** — ansiktet utad, må være live før første kundeklage om "hvem er Vauco?" + +Se `docs/ROADMAP.md` seksjon NEXT for full sjekkliste og `docs/vauco-site/DESIGN.md` for V1 design-spec. + +--- + +## 📋 Nøkkelinformasjon + +| Nøkkel | Verdi | +|---|---| +| GCP Project | `propane-will-491900-m5` | +| Region | `europe-west1` | +| Vertex AI endpoint | `europe-west1` (EU) | +| Cloud Run service | `osvauco-agent` | +| Cloud Run URL (direkte) | `https://osvauco-agent-357036551735.europe-west1.run.app` | +| Public URL | `https://opax.vauco.no` | +| LB IP | `34.98.77.173` | +| AI-modell | `gemini-2.5-pro` (midlertidig — venter på Claude EU-kvote) | +| Repo | `vauco-saas/OSVauco` | +| Kontakt | `chris.christiansen@vauco.no` | + +--- + +## 📁 Viktige filer å lese (i denne rekkefølgen) + +1. `docs/MASTERPLAN.md` — autoritativ sannhet +2. `docs/ROADMAP.md` — hva som skjer akkurat nå +3. `docs/HANDOFF.md` — denne filen +4. `docs/AGENT_RULEBOOK.md` — regler for hvordan agenter oppfører seg +5. `.gemini/GEMINI.md` — locked definitions og boot-protokoll +6. `docs/ARCHITECTURE.md` — teknisk arkitektur +7. `docs/OSVAUCO_OPAX_SESSION_LOG.md` — append-only sesjonshistorikk + +--- + +## ⚠️ Vanlige feil — ikke gjør disse + +- **Ikke opprett nye HANDOFF_YYYYMMDD-filer.** Det er kun denne. Overskriv den. +- **Ikke gjenopplive `VAUCO_OS_ROADMAP.md`.** Den er slettet 2026-05-31. Bruk `ROADMAP.md`. +- **Ikke bytt til Claude før kvote er bekreftet** av Google Cloud-team + `MODEL APPROVED` fra Chris. +- **Ikke foreslå å migrere fra europe-west1** — regionen er låst. +- **Ikke rør IAP, OAuth, eller Secret Manager** uten eksplisitt `DEPLOY GODKJENT` fra Chris. +- **Ikke opprett nye repos.** Vurder mappe i `OSVauco` først. Krever `REPO APPROVED`. +- **Ikke hopp over HITL gates** — hver fase avsluttes med et godkjenningssignal. + +--- + +## 📜 Tidligere handoffs + +Arkivert i `docs/archive/handoffs/`: +- `HANDOFF_20260526.md` +- `HANDOFF_20260531.md` +- `HANDOFF_20260531_claude47.md` + +--- + +*Vauco AS · propane-will-491900-m5 · `europe-west1`* diff --git a/docs/MASTERPLAN.md b/docs/MASTERPLAN.md index dda8d1f..01ab8c9 100644 --- a/docs/MASTERPLAN.md +++ b/docs/MASTERPLAN.md @@ -1,214 +1,468 @@ -# MASTERPLAN — Vauco OS +# VAUCO OS — MASTERPLAN **Eier:** Chris Christiansen · Vauco AS · Org.nr 935 989 779 **Sist oppdatert:** 2026-05-31 -**Status:** AUTORITATIV — én kilde til sannhet +**Status:** 🟢 AUTORITATIV — én kilde til sannhet for hele Vauco-økosystemet + +> **Regel #1:** Denne filen er sannheten. Hvis en annen fil sier noe annet — denne vinner. +> **Regel #2:** Endringer her krever eksplisitt `PLAN APPROVED` fra Chris. +> **Regel #3:** Roadmap → seksjon 7. Sesjonsstatus → `docs/HANDOFF.md`. Ingen andre handoff-filer. --- -## 1. Plattformhierarki +## 1. Plattformhierarki — sannheten i én modell ``` -Vauco OS (Plattform — visjon, økonomi, token-lag) - └── OPAX (Engine — AI-infrastruktur, Cloud Run, agentic arkitektur) - ├── CostGuard (Modul #1 — live på costguard.oss.vauco.no) - ├── Threadstone (Modul #2 — kreativ AI-assistanse, Q3 2026) - └── [Modul #3+] (TBD basert på CostGuard-læring) +Vauco AS (selskap, eier alle merkevarer) +│ +├── vauco.no (APEX — bedriftens salgs- og portalside; ansiktet utad) +│ └── ruter besøkende videre til riktig modul +│ +└── VAUCO OS (plattform — visjon, økonomi, token-lag, agent-fabrikk) + └── OPAX (engine — Cloud Run, RAG, agentic arkitektur, IAP) + ├── Modul #1 · CostGuard (live på costguard.oss.vauco.no) + ├── Modul #2 · Threadstone (landingsside live, app i bygg) + └── Modul #3 · [navngis senere] + +Separat merkevare under Vauco AS (parkert til etter Modul #1 + #2 lever): +└── Proof of Curiosity (egen identitet, ikke en OPAX-modul) ``` -### Vauco OS -Overordnet plattform og merkevare. Holder VVL (Vauco Value Ledger), token-økonomi ($VCO), og go-to-market-strategi. Ikke et brukervendt produkt — det er infrastrukturen rundt produktene. +**Fire nivåer, fire formål:** -### OPAX -Den tekniske motoren. Cloud Run (`osvauco-agent`) på GCP `europe-west1`. Alle produkt-moduler bygger på OPAX-API-et. OPAX er ikke synlig for sluttkunden — det er plumbing. - -### CostGuard (Modul #1) -Første go-to-market produkt. Hjelper bedrifter å forstå og kontrollere GCP-kostnader via AI-drevet analyse. Live på `costguard.oss.vauco.no` (Cloudflare Pages). Backend via Cloud Run `europe-west1`. - ---- - -## 2. Infrastrukturstatus (per 2026-05-31) - -| Komponent | Status | URL / Detalj | +| Nivå | Hva | Hvem ser det | |---|---|---| -| Cloud Run (`osvauco-agent`) | ✅ Live | GCP europe-west1 | -| `opax.vauco.no` (LB + SSL) | ✅ Live | GCP Load Balancer, IP 34.98.77.173 | -| IAP på `opax.vauco.no` | ✅ Konfigurert | Begrenset til `@vauco.no` Google-kontoer | -| `costguard.oss.vauco.no` | ✅ Live | Cloudflare Pages, docs/ | -| `docs/index.html` iframe | ✅ Fikset | Peker nå på europe-west1 | -| BigQuery (`osvauco_logs`) | ⏳ Venter | Sink oppe, tabell populeres | -| OAuth2 (Google) | ✅ Konfigurert | Secret Manager | -| CI/CD (Cloud Build → Cloud Run) | ✅ Operativt | Auto-deploy på push til main | -| Budget guard (500 NOK/mnd) | ✅ Live | 50/90/100% terskler | -| BQ billing export (`gcp_billing_export_v1_*`) | ⏳ Venter | Første tabell ikke populert ennå | -| Multi-tenant stamp-out | 🔜 Fase C | Onboarding-script + admin-panel | -| RAG corpus (`osvauco-corpus`) | ✅ Populert | europe-west4 | -| **AI-modell** | ✅ Oppdatert | Claude Opus 4.6 via Vertex AI `eu` endpoint | +| **vauco.no (apex)** | **Bedriftens salgsportal — viser hvem Vauco AS er og hvilke moduler vi selger** | **Alle: kunder, partnere, presse, kandidater** | +| Vauco OS | Plattformen Chris bygger og selger fra | Internt (Chris + agenter) | +| OPAX | Engine som driver modulene | Internt + utviklere | +| Modul (CostGuard / Threadstone / …) | Det kundene faktisk kjøper | Kunder | + +**Salgskanal-prinsipp:** +- `vauco.no` = portalen som forteller "hva selger vi" og leder til riktig modul +- Hver modul har sin egen landings-/produktside (`costguard.oss.vauco.no`, `threadstone.vauco.no`, …) +- Vauco OS og OPAX nevnes ikke som produkter på `vauco.no` — de er interne verktøy + +**Ikke selg Vauco OS. Ikke selg OPAX. De er interne verktøy.** --- -## 3. Roadmap +## 2. Registrerte domener — fasit -### ✅ Fullført +### Vauco (hos Proisp) -- **Fase 0** — Baseline: `opax-mcp-core` live, OSVauco repo, `.gemini/` grunnmur, boot-script -- **Fase 1** — MCP_NAME/MCP_PROTOCOL/ROOT_DOMAIN locked; ARCHITECTURE.md opprettet · 2026-05-21 -- **Fase 2** — `opax.vauco.no` live: domain mapping + CNAME + SSL · 2026-05-21 -- **Fase 3** — Nemotron session loop i GEMINI.md; TODO.md; sesjonslogg · 2026-05-21 -- **Fase A (infra)** — Deploy, GitHub PAT, CI/CD-forsøk, webhook, budget guard, GCS bucket, logging sink · 2026-05-24 -- **Fase B (stabilisering)** — Smoke-test 10/10 ✅, BigQuery dataset + sink, Threadstone model-temaer · 2026-05-26 -- **Repos konsolidert** — Alt samlet under `vauco-saas/OSVauco` · 2026-05-27 -- **Fase 4 (infra migrering)** — `opax.vauco.no` migrert fra Cloud Run domain mapping til GCP Load Balancer + SSL-sertifikat · 2026-05-30 -- **Fase 5 (IAP)** — IAP aktivert, OAuth consent Internal, `@vauco.no`-domenet begrenset · 2026-05-30 -- **Fase 6 (CI/CD)** — Cloud Build trigger operativ, auto-deploy på push til main · 2026-05-30 -- **Fase 7 (RAG)** — RAG corpus `osvauco-corpus` populert, agent kobles til corpus · 2026-05-30 -- **AI-modell oppgradering** — Gemini 2.5 Pro → Claude Opus 4.6 via Vertex AI EU endpoint · 2026-05-31 +| Domene | Prosjekt | Status | +|--------|----------|--------| +| `vauco.no` | Rot for alle Vauco-tjenester | ✅ Aktiv, verifisert på GitHub | -### 🔄 Aktiv nå +**Aktive subdomener:** -- **Fase 8 — End-to-end test av agent via opax.vauco.no** - - Aktiver Claude Opus 4.6 i Vertex AI Model Garden - - Verifiser Cloud Run kjører i `europe-west1` - - Test agent via IAP: `curl https://opax.vauco.no/health` - - Test Claude EU endpoint direkte - - Full end-to-end: login → chat → svar via Claude Opus 4.6 - - HITL gate: `FASE8 APPROVED` +| Domene/subdomen | Teknologi | Status | Eier-flate | +|----------|-----------|--------|------------| +| `vauco.no` (apex) | Proisp parking-side (placeholder) | ⚠️ "Under construction" — skal erstattes med ekte salgsportal | Vauco AS apex | +| `www.vauco.no` | Følger apex | ⚠️ Samme placeholder | Vauco AS apex | +| `opax.vauco.no` | LB + IAP → Cloud Run `osvauco-agent` | ✅ Live (IP 34.98.77.173) | OPAX | +| `oss.vauco.no` | Staging-miljø | ✅ Aktiv | OPAX | +| `os.vauco.no` | Prod-miljø | 🔮 Fase C | OPAX | +| `costguard.oss.vauco.no` | Cloudflare Pages | ✅ Live | CostGuard | +| `costguard.os.vauco.no` | Promoteres fra oss | 🔮 Fase C | CostGuard | +| `threadstone.vauco.no` | GitHub Pages (`threadstone-landing`) | ✅ Live | Threadstone | +| `app.threadstone.vauco.no` | GitHub Pages (`vauco-saas.github.io`) | ⚠️ CNAME satt, side mangler | Threadstone | +| `.vauco.no` | LB + IAP via Terraform | 🔮 Fase C2 | OPAX/Multi-tenant | -- **CG3 — CostGuard Frontend Wiring** - - OAuth login flow (`/auth/login?client_id=demo`) kobles til Cloud Run - - BigQuery-data vises når `gcp_billing_export_v1_*` er populert - - HITL gate: `CG3 APPROVED` +**Reservert til senere — ikke opprettet ennå:** -### 🔜 Neste — Fase C (etter Fase 8 + CG3 APPROVED) +| Subdomen | Tiltenkt formål | Trigger | +|----------|------------------|---------| +| `status.vauco.no` | Statuspage for alle moduler (Cloud Run uptime, RAG, IAP) | Etter første kunde — trust-signal | +| `docs.vauco.no` | Offentlig kundedokumentasjon (CostGuard onboarding, API-ref) | CG4 / første kunde | +| `careers.vauco.no` | Stillinger (kan bare være redirect til notion-side) | Når Vauco rekrutterer | -**C1 — Terraform-konvertering** -- Konverter `infrastructure/*.sh` → Terraform-modul i `vauco-bootstrap/` -- LB, IAP, Cloud Run som Terraform-ressurser -- Sett `IAP_ENABLED=true` + `IAP_AUDIENCE` i Cloud Run env-vars +**Email-infra:** +- MX: Google Workspace (`smtp.google.com`) ✅ +- TXT-records (SPF/DKIM/DMARC): ⚠️ Mangler — sett opp som del av V1 for å unngå at salgs-mail havner i spam -**C2 — Multi-tenant Stamp-Out** +### Proof of Curiosity (hos Proisp) — egen merkevare -Målet: Du lager en modul i din admin-view. Kunden får sin egen isolerte instans automatisk. +| Domene | Merknad | +|--------|---------| +| `proof-of-curiosity.com` | Registrert — ikke i bruk | +| `proofofcuriosity.com` | Registrert — ikke i bruk | +| `proofofcuriosity.io` | Registrert — ikke i bruk | +| `proof-of-curiosity.no` | Registrert — ikke i bruk | +| `proofofcuriosity.no` | Registrert — ikke i bruk | -``` -Du (admin, opax.vauco.no) - └── klikker "Opprett klient: Medioteq" - ↓ - onboarding-script provisjonerer: - - medioteq-oss.vauco.no (staging — kunden tester her) - - medioteq-os.vauco.no (prod — live etter godkjenning) - - Eget GCP-prosjekt (isolert, spesielt viktig for Medioteq/helse) - - Kunden logger inn med Google OAuth (BankID for helse-kunder) - - Ingenting av Vauco OS sin interne infrastruktur eksponeres -``` - -Leveranser i C2: -- `scripts/onboard-client.sh ` — provisjonerer DNS + Cloud Run + GCP-prosjekt -- `opax.vauco.no/admin` — admin-panel: liste over klienter, status, knapp for oss → os flip -- ARCHITECTURE.md oppdateres med klient-isolasjonsmodell -- Første testkandidat: CostGuard som mal - -**C3 — BQ-2 / Looker Studio** -- Verifiser sink-SA IAM → Looker Studio dashboard -- Koble live BQ-data til billing-dashboard - -### 📋 Backlog - -- `opax-mcp/` restruktureres som modul-subtree -- Full boot cycle acceptance test (automatisert) -- **Threadstone Fase 1** — `vauco-saas/threadstone-instructions` repo, Master Hub v3.2 (Q3 2026) -- **Dialogflow CX** — Norsk Playbook-agent, webhook mot Cloud Run -- **Medioteq** — kun idéfase, ingenting implementeres før OPAX multi-tenant er operasjonelt -- **VVL Fase 2** — $VCO on-chain (Q3 2026), etter Threadstone Fase 1 er validert +> **Trigger:** Ingen POC-arbeid før Modul #1 (CostGuard) har første betalende kunde og Modul #2 (Threadstone) er i pilot. --- -## 4. OPAX Anti-Chaos Protocol +## 3. Repo-struktur — fasit -> **Status: Proprietær Vauco-arkitektur · Potensielt salgsbart B2B-produkt** +### Aktive repos (5 — hold antallet lavt) -### Problemet +| Repo | Formål | Synlighet | Eier-flate | +|------|--------|-----------|------------| +| `OSVauco` | Mono-repo: OPAX-engine, alle infrastruktur-scripts, Terraform, all dokumentasjon | Privat | OPAX (rot) | +| `vauco-bootstrap` | Terraform-modul for kunde-provisjonering (referert som submodul fra OSVauco) | Privat | OPAX | +| `vauco-site` | `vauco.no` salgsportal (apex + www) — eget public repo for SEO, ikke skjul kildekoden | Public | Vauco AS apex | +| `threadstone-landing` | `threadstone.vauco.no` landingsside | Public | Threadstone | +| `vauco-saas.github.io` | `app.threadstone.vauco.no` — Threadstone-app frontend | Public | Threadstone | -Bedrifter som bruker autonome AI-agenter (GitHub Copilot Workspace, Devin, LangChain-bygg) opplever "AI-ADHD": agenter mister kontekst, hopper over kritiske steg, sletter kode de ikke forstår, og fanges i feilsøkings-loops. Det koster dyrt å rydde opp. +> **Hvorfor `vauco-site` får eget repo (ikke i mono-repoet):** +> 1. Skal være public (mono-repoet er privat og må forbli det — inneholder infra, secrets-referanser, kundedata-mønstre) +> 2. Skal serveres via GitHub Pages eller Cloudflare Pages — egen deploy-pipeline +> 3. Designere/markedsfolk kan jobbe der uten å se OPAX-koden +> 4. Følger samme mønster som `threadstone-landing` -### Protokollen +### Arkiverte repos (ikke gjenåpne uten plan-endring) -OPAX Anti-Chaos Protocol er en **deterministisk prompt-arkitektur** som tvinger LLM-er til å oppføre seg som lineære state-maskiner: +| Repo | Arkivert | Innholdet finnes nå i | +|------|----------|------------------------| +| `vauco-os` | ✅ 2026-05-27 | `OSVauco/docs/architecture/` | +| `vauco-gemini-tui-bridge` | ✅ 2026-05-27 | (kun arkiv; reaktiveres etter Fase 8 om behov) | +| `command-hub` | ✅ 2026-05-27 | `OSVauco/static/command-hub.html` | -``` -REGEL 1 — LINEÆR STATE MACHINE - Agenten opererer strengt trinn-for-trinn. - Trinn N+1 starter ikke før bruker skriver "Step N approved". +### Parkerte repos — leve videre, ikke arkiver, ikke aktivt jobb før trigger -REGEL 2 — INGEN CONTEXT-SWITCHING - Ved blokkering (f.eks. venter på ekstern data): HALT. - Ingen pivoting til andre oppgaver. +| Repo | Trigger for å gjenoppta | Hvor det hører hjemme i hierarkiet | +|------|--------------------------|------------------------------------| +| `threadstone-instructions` | Når Threadstone-app går i pilot (Modul #2 fase 2) | Threadstone-modul — boot-prompter + tema-config | +| `deep-dream` | Når Modul #1 har betalende kunde | Strategisk visjon, klassifisert — egen prosess | -REGEL 3 — CLI-FIRST EXECUTION - All standard utvikling: ready-to-run kommandoer eller kodeblokker. - Manuell filredigering kun for Auth/Security. - -REGEL 4 — PRIME DIRECTIVE - Slett ikke kjernekonsepter. - Syntetiser til ren, enhetlig arkitektur. - Arkiver det som erstattes — slett ingenting. - -REGEL 5 — AUTO-SNAPSHOT VED GH-OPERASJONER - Før enhver GitHub-handling: ta snapshot av tråden. - Lagre til: docs/archive/sessions/[YYYY-MM-DD]_[emne].md -``` - -### Kommersiell potensial - -| Nivå | Produkt | Modell | -|---|---|---| -| **1 — Playbook** | Strukturert bibliotek av system-prompts og arkitektur-regler | Engangslisens / årsabonnement | -| **2 — Middleware API** | OPAX wrapper-API: kundens oppgave inn → Anti-Chaos-pakket prompt ut → svar overvåket | Pay-per-call / SaaS | -| **3 — Enterprise Consulting** | Implementering av Vauco OS-prinsipper i kundens infrastruktur | Prosjektbasert | - -**Målgruppe:** CTO-er og engineering leads i selskaper med 10–500 utviklere som sliter med å få ROI på AI-investeringer. - -> 📁 Detaljert teknisk spec: `docs/architecture/ANTI_CHAOS_PROTOCOL.md` (opprettes i Fase C) +> **Regel:** Hvis du vil opprette et nytt repo — `STOP`. Vurder først om det kan leve som mappe i `OSVauco`. Krever eksplisitt `REPO APPROVED` fra Chris. --- -## 5. Filstruktur — én kilde til sannhet +## 4. OSVauco — intern mappestruktur (fasit) ``` -vauco-saas/OSVauco/ -├── .gemini/ -│ └── GEMINI.md ← agent-kontekst, boot-prompt, locked definitions -├── docs/ -│ ├── MASTERPLAN.md ← denne filen — autoritativ -│ ├── HANDOFF_[dato].md ← siste sesjonshandoff -│ ├── ARCHITECTURE.md ← teknisk arkitektur -│ ├── AGENT_RULEBOOK.md ← agentregler -│ ├── VAUCO_OS_ROADMAP.md ← ⚠️ deprecated, erstattet av seksjon 3 her -│ ├── protocols/ -│ ├── architecture/ -│ └── archive/ -├── static/ +OSVauco/ +├── MASTERPLAN.md → symlink/peker til docs/MASTERPLAN.md (denne filen) +├── README.md +├── AGENTS.md ML-roller, ikke rør uten ML-fase-endring +├── Dockerfile / cloudbuild.yaml CI/CD (auto-deploy på push til main) +│ +├── agents/ Python-agentene +│ ├── core-logic/ OPAX orchestrator + FastAPI app (main.py) +│ ├── rag/ RAG-agent +│ ├── memory/ Memory-agent +│ ├── multi_agent/ Sub-orchestrators +│ ├── eval/ Evaluering +│ ├── tests/ Pytest +│ └── tools/ Hjelpere +│ +├── auth/ OAuth2-flow +├── ml/ CostGuard-engine (billing_agent, anomaly_detector, telemetry) +├── infrastructure/ GCP-scripts (00–12, 99) + terraform/ +│ └── terraform/ IaC (modules, customers, platform.tf) +├── scripts/ smoke-test, cost-audit, opax-boot, sync-gdrive +├── static/ HTML servert av Cloud Run +│ ├── opax.html OPAX operator hub │ ├── billing-dashboard.html -│ └── command-hub.html -└── src/ ← OPAX backend +│ ├── command-hub.html +│ ├── costguard.html ← CG3 bygges her +│ └── admin.html +├── docs/ +│ ├── MASTERPLAN.md ← denne filen, autoritativ +│ ├── ROADMAP.md ← levende, oppdateres hver sesjon +│ ├── HANDOFF.md ← ÉN fil, overskrives per sesjon +│ ├── AGENT_RULEBOOK.md ← immutable regler for agent-boot +│ ├── ARCHITECTURE.md +│ ├── LEARNINGS.md +│ ├── architecture/ fra vauco-os repo +│ ├── threadstone/ (kommer når threadstone-instructions konsolideres) +│ └── [øvrige tema-docs] +├── protocols/ +│ └── sessions/ Detaljerte sesjonsprotokoller (én per dag) +├── data/ RAG-input (threadstone_faq.*) +└── dialogflow/ DX-agent-config ``` --- -## 6. Nøkkelkontakter & secrets +## 4b. vauco.no — salgsportal (Vauco AS apex) -- **GCP Project:** `propane-will-491900-m5` -- **Region:** `europe-west1` -- **Vertex AI endpoint:** `eu` (Claude Opus 4.6) -- **Cloud Run service:** `osvauco-agent` -- **Cloud Run URL:** `https://osvauco-agent-357036551735.europe-west1.run.app` -- **Load Balancer IP:** `34.98.77.173` -- **AI-modell:** `claude-opus-4-7@20260301` via Vertex AI -- **Secret Manager:** Google OAuth2-credentials -- **Billing account:** se Secret Manager -- **Kontakt:** chris.christiansen@vauco.no +> Eget repo: `vauco-saas/vauco-site` — opprettes som del av V1. + +### Formål (én linje) +Vauco AS sin offisielle bedriftsside. Selger Vaucos AI-moduler ved å lede besokende videre til riktig modul-landingsside. Bygger tillit gjennom å vise hvem som står bak. + +### Hvem siden er for (prioritert rekkefølge) +1. **Potensielle CostGuard-kunder** — norske bedrifter med GCP-kostnader de ikke kontrollerer (Chris sin primære salgsmotor) +2. **Threadstone-pilot-kunder** (Q3 2026+) +3. **Partnere og presse** — "hvem er Vauco?" +4. **Fremtidige ansatte** — kandidater som googler firmaet etter et møte + +### Informasjonsarkitektur (sidekart) + +``` +vauco.no (hovedside) +├── #hero "Vauco bygger AI-moduler som leverer målbar verdi" +├── #moduler Grid med levende moduler +│ ├── CostGuard → costguard.oss.vauco.no +│ ├── Threadstone → threadstone.vauco.no +│ └── "Flere kommer" (placeholder med signup) +├── #hvorfor-vauco 3 punkter: norsk eierskap, GCP-ekspertise, AI som ikke er hype +├── #om-oss Chris Christiansen + Vauco AS (org.nr, Oslo) +├── #kontakt chris.christiansen@vauco.no + LinkedIn +└── footer Org.nr, personvern-lenke, status.vauco.no (når live) + +/personvern.html Personvernerklæring (GDPR-krav) +/vilkar.html Standardvilkår for kunder +/sitemap.xml For SEO +/robots.txt +``` + +### Visuell retning (utgangspunkt) + +- **Ankret i Threadstone-stilen** (`threadstone-landing/index.html`) — mørk bakgrunn, monospace-aksenter, Inter/SF Pro som hovedtypo +- **Én hovedfarge per modul:** CostGuard får en, Threadstone en annen — visuelt skille så kundene ikke forveksler +- **Ikke generisk SaaS-look.** Vauco er en operatør, ikke et VC-finansiert startup. Tone: rolig, kompetent, norsk. +- **Mobile-first** — Chris demoer ofte fra telefon +- **Lighthouse ≥0.95** på alle 4 akser +- **Ingen tracking-piksler** ved lansering (kan legges til senere som GA4 om nødvendig) + +### Salgs-flow (hva siden faktisk skal drive) + +``` +Google/LinkedIn → vauco.no + ↓ + #moduler-grid + ↓ + klikk "CostGuard" → costguard.oss.vauco.no + ↓ + Magic-link login + ↓ + (etter CG3-flow): kunden ser sine GCP-kostnader + ↓ + "Bestill" → Chris ringes opp (OPAX HITL) +``` + +### Teknisk stack + +| Lag | Valg | +|-----|------| +| Hosting | GitHub Pages (samme mønster som `threadstone-landing`) eller Cloudflare Pages | +| Bygg | Vanilj HTML/CSS — ingen framework før vi har en grunn | +| Deploy | Push til main → Pages bygger | +| Domene | `vauco.no` + `www.vauco.no` CNAME | +| SSL | Auto via Pages | +| Skjema | Formspark / Netlify Forms eller `mailto:` (V1 = mailto) | + +### Det som IKKE skal være på vauco.no + +- Ingen OPAX, Vauco OS, eller intern arkitektur — dette er kundenes side +- Ingen Deep Dream-innhold +- Ingen Proof of Curiosity (egen merkevare, egen side når tiden er inne) +- Ingen demo-credentials, ingen tekniske dypdykk +- Ingen "vi er det neste OpenAI"-retorikk + +### Designreferanser å inspireres av (ikke kopiere) + +- Linear.app — ren visuell hierarki +- Resend.com — norsk-ish tone, fokus på én ting +- Vercel.com — strukturen på modul-grid (men råere typografi) +- Threadstone-landing.html — vår egen stilreferanse + +### Versjons-evolusjon + +| Versjon | Inneholder | Trigger | +|---------|------------|---------| +| V1 (MVP) | Hero + modul-grid (CostGuard live, Threadstone "coming soon") + om-oss + kontakt + personvern | NOW — etter Fase 8 | +| V2 | Sales-CTA på hver modul (kalkulator-widget for CostGuard ROI), case study #1 | Etter første betalende kunde | +| V3 | Blogg/innsikter, kundereferanser, status-widget fra `status.vauco.no` | Når 3+ kunder | +| V4 | Internasjonalt (`vauco.no/en`), Proof of Curiosity i footer | Etter Modul #3 | --- -*Vauco AS · Org.nr 935 989 779 · Oslo, Norge* -*Powered by OPAX · Crafted by Chris Christiansen* +## 5. Dokumenthierarki — én kilde til sannhet + +| Fil | Rolle | Oppdateres | +|-----|-------|------------| +| `docs/MASTERPLAN.md` | Arkitektur, domener, repos, agent-identitet — **denne filen** | Ved arkitekturendringer | +| `docs/ROADMAP.md` | Faser, status, backlog — **levende dokument** | Hver sesjon | +| `docs/HANDOFF.md` | Hva ble gjort, hva er neste, kjente hull — **alltid kun én fil** | Overskrives hver sesjon | +| `docs/AGENT_RULEBOOK.md` | Locked definitions for agent-boot | Kun ved infrastruktur-låsing | +| `protocols/sessions/YYYY-MM-DD_.md` | Detaljerte protokoller per sesjon | Append-only | + +**Regel:** Arkitektur → MASTERPLAN. Oppgave → ROADMAP. Sesjonsstatus → HANDOFF. **Aldri dobbelt opp.** + +> **VAUCO_OS_ROADMAP.md er deprecated 2026-05-31.** Erstattet av `docs/ROADMAP.md`. + +--- + +## 6. AI-modell — låst (midlertidig) + +| Parameter | Verdi | Merknad | +|-----------|-------|---------| +| **Modell** | `gemini-2.5-pro` | Via Vertex AI | +| **Endpoint** | `europe-west1` (EU) | Bruker Vertex-kreditter | +| **SDK** | `from google import genai` | google-genai >=0.3 | +| **Status Claude Opus 4.6/4.7** | ⏳ Venter på kvote-godkjenning fra Google Cloud-team | Bytt når kvote er innvilget | + +**Bytte til Claude krever:** +1. Bekreftelse fra Google Cloud-team at kvote er innvilget i `europe-west1` eller `eu`-region +2. Eksplisitt `MODEL APPROVED` fra Chris +3. Oppdatering av denne tabellen, `AGENT_RULEBOOK.md` og `.gemini/GEMINI.md` i samme commit + +--- + +## 7. Roadmap — prioritert rekkefølge + +> Denne seksjonen er kortversjonen. Full status og daglig oppdatering ligger i `docs/ROADMAP.md`. + +### 🔴 NÅ — Konsolidering + Fase 8 verifisering + +| # | Oppgave | Eier | Status | +|---|---------|------|--------| +| K1 | Slå sammen MASTERPLAN-er, slett duplikater, fjern merge-markører | Chris + Perplexity | 🟡 In progress (denne sesjonen) | +| K2 | Oppdater AGENT_RULEBOOK med korrekt region + modell | Chris | 🟡 In progress | +| K3 | Fiks nattlig GDrive backup-workflow | Chris | ⏳ Pending | +| F8 | End-to-end test: `opax.vauco.no` → login → chat → svar | Chris | 🟡 Delvis (Cloud Run + IAP OK, browser-flow gjenstår) | + +### 🟠 V — vauco.no salgsportal (parallelt spor) + +| # | Oppgave | +|---|---------| +| V1a | Opprett `vauco-saas/vauco-site` (public repo) | +| V1b | Bygg MVP: hero + modul-grid (CostGuard live, Threadstone "coming soon") + om-oss + kontakt + personvern | +| V1c | Sett CNAME `vauco.no` + `www.vauco.no` → GitHub Pages i Proisp | +| V1d | Erstatt "Under construction" placeholder — deploy MVP | +| V1e | Sett opp SPF + DKIM + DMARC TXT-records på `vauco.no` (e-post fra Workspace) | +| V2 | Sales-CTA + CostGuard ROI-kalkulator (trigger: etter Fase 8 OG første demo) | + +### 🟡 NESTE — CG3 (CostGuard frontend wiring) + +| # | Oppgave | +|---|---------| +| CG3a | Bygg `static/costguard.html` i OSVauco (OAuth-knapp + billing embed) | +| CG3b | Sett CNAME `costguard.oss.vauco.no` → Cloud Run i Proisp | +| CG3c | Verifiser at `/static/costguard.html` er tilgjengelig via Cloud Run | +| CG3d | Test OAuth-flow fra landingssiden | + +### 🟢 GO-TO-MARKET — CostGuard (Modul #1) + +| Fase | Innhold | +|------|---------| +| C4 | Medioteq HITL-møte → `terraform apply` → første betalende kunde | +| C5 | Salgsdemo: `costguard.os.vauco.no` + demo-video | +| DX5 | Dialogflow Messenger live på costguard-landingssiden | +| ML-2 | Adaptiv intelligens (trigger: >500 telemetri-kall) | + +### 🔵 MODUL #2 — Threadstone + +| # | Oppgave | +|---|---------| +| T1 | Konsolider `threadstone-instructions` → `OSVauco/docs/threadstone/` (når app-arbeid starter) | +| T2 | Bygg `app.threadstone.vauco.no` i `vauco-saas.github.io` | +| T3 | Koble til OPAX-engine via `POST /threadstone/generate` | +| T4 | Pilot med første kunde | + +### 🟣 STRATEGISK — Deep Dream (klassifisert) + +> Innholdet i `deep-dream` repo er strategisk visjon. **Røres ikke** før Modul #1 har betalende kunde. Lever som eget repo for å holde tilgang adskilt. + +### 🌐 FREMTID — Proof of Curiosity + +| # | Oppgave | +|---|---------| +| POC-1 | Definer hva Proof of Curiosity er (produkt, merkevare, community?) | +| POC-2 | Velg primærdomene (anbefaling: `proofofcuriosity.io`) | +| POC-3 | Opprett repo (vurder om det skal under `vauco-saas` eller separat org) | +| POC-4 | Bygg landing/MVP | + +> **Trigger:** Ikke start POC før Modul #1 er live med betalende kunde OG Modul #2 er i pilot. + +--- + +## 8. Agent-identitet + +| Identitet | E-post | Rolle | +|-----------|--------|-------| +| Eier / admin | `chris.christiansen@vauco.no` | Full kontroll | +| Agent (OPAX / Jason) | `jason.vauger@vauco.no` | `billing.viewer` + `run.invoker` på `osvauco-agent` | +| Fremtidig gruppe | `billing@vauco.no` | `billing.viewer` (Fase C) | + +**Forbudte kontoer:** `tinius.vauger`, `ccv` — aldri gi tilganger. + +--- + +## 9. Cloud Run — live endepunkter + +**Service:** `osvauco-agent` | **Region:** `europe-west1` | **Project:** `propane-will-491900-m5` +**Direkte URL:** `https://osvauco-agent-357036551735.europe-west1.run.app` +**Public URL:** `https://opax.vauco.no` (via LB 34.98.77.173 + IAP `@vauco.no`) + +| Endepunkt | Status | +|-----------|--------| +| `GET /health` | ✅ | +| `POST /run` | ✅ | +| `POST /run/dag` | ✅ | +| `GET /billing/summary` | ✅ | +| `GET /billing/forecast` | ✅ | +| `GET /billing/anomalies` | ✅ | +| `GET /auth/login` | ✅ | +| `GET /auth/callback` | ✅ | +| `GET /static/billing-dashboard.html` | ✅ | +| `GET /static/opax.html` | ✅ | +| `GET /state` | ✅ | +| `GET /telemetry/history` | ✅ | + +--- + +## 10. Go-to-market — enkelt og konkret + +**Produkt #1: CostGuard** +- **Hvem:** Norske bedrifter med GCP-kostnader de ikke kontrollerer +- **Hva:** Autonomt kostnadsovervåkningsverktøy med AI-anomali-deteksjon +- **Pris:** $300–500/mnd per kunde (breakeven ved 1 kunde) +- **Salgskanal:** Chris selv via OPAX → HITL-møte → `terraform apply` + +**Produkt #2: Threadstone** (Q3 2026) +- Definisjon låses når Modul #1 har første kunde. + +--- + +## 11. Kjente hull + +| ID | Problem | Løsning | Prioritet | +|----|---------|---------|-----------| +| OQ-15 | BQ billing_export tabell | Venter på aktivering — sjekk neste sesjon | Medium | +| OQ-17 | `github-token` secret mangler | Opprett alias fra `github-pat` | Medium | +| OQ-18 | VM alltid-på kostnad | Kjør `03-teardown.sh` hver kveld | Høy | +| OQ-20 | Nattlig GDrive backup feiler hver natt siden 2026-05-25 | Diagnostisere SA-key / folder-ID; fikses i K3 | Høy | +| OQ-21 | `app.threadstone.vauco.no` CNAME satt, men ingen `index.html` | Bygg som del av T2 eller fjern CNAME | Lav | +| OQ-22 | Claude Opus 4.6/4.7 mangler EU-kvote | Vent på Google Cloud-team; midlertidig på Gemini 2.5 Pro | Medium | +| OQ-23 | `vauco.no` viser "Under construction" (Proisp placeholder) | Erstattes av V1-fase | Høy | +| OQ-24 | Ingen SPF/DKIM/DMARC TXT-records på `vauco.no` | Sett opp som del av V1e — salgsmail havner ellers i spam | Høy | +| OQ-25 | Ingen `personvern.html` / `vilkar.html` på vauco.no | GDPR-krav før betalende kunder onboardes — del av V1 | Høy | +| OQ-26 | Ingen statuspage (`status.vauco.no`) | Etter første kunde — trust-signal | Lav | + +--- + +## 12. OPAX — fremtidig visjon (parkert, prioriteres etter CG3 + Fase 8) + +> Notert 2026-05-28. Ikke bygg dette nå — fokus er Fase 8 + CG3. + +OPAX (`opax.vauco.no`) blir Chris sin **mobile salgssentral** — en stille, tekstbasert assistent han kan snakke MED via AirPods mens han er i møte med en potensiell kunde. + +**Flyt:** tale → transkribering → Jason analyserer → genererer kundemodul → Chris reviewer → magic-link til kundens mail. + +**Prinsipper:** +- OPAX snakker aldri — kun tekst på skjerm +- Voice er kun inn (Web Speech API / Whisper) +- Silent assistant — stille, rask, mørk, monospace +- Provisjonering on-the-go + +**Teknisk stack når det bygges:** Web Speech API → Whisper, Gemini 2.5 Pro (eller Claude når kvote kommer), magic link via SendGrid/Resend fra `vauco.no`, ny endepunkt `POST /opax/generate` i `main.py`. + +**Trigger for å starte:** CG3 live OG `static/` UI/UX-opprydding gjort. + +--- + +## 13. TUI-bridge — parkert + +Lokal TUI-plan ble løst av OPAX + Cloud Shell + Gemini TUI. Koden ligger i arkiv (`vauco-gemini-tui-bridge`). Reaktiveres etter Fase 8 + første kunde hvis behovet melder seg igjen — flyttes da til `OSVauco/tui/`. + +--- + +*OSVauco | propane-will-491900-m5 | europe-west1 | Autoritativ fra 2026-05-31* diff --git a/docs/OSVAUCO_OPAX_SESSION_LOG.md b/docs/OSVAUCO_OPAX_SESSION_LOG.md index 338d8ba..c5df8fc 100644 --- a/docs/OSVAUCO_OPAX_SESSION_LOG.md +++ b/docs/OSVAUCO_OPAX_SESSION_LOG.md @@ -111,87 +111,11 @@ Phase 5 — IAP på opax.vauco.no: begrens til @vauco.no Google-kontoer - [x] Threadstone model-temaer dokumentert - [ ] CI/CD Cloud Build trigger — forsøkt, ikke fullfort (ULØST → Phase 6) -<<<<<<< Updated upstream ### Neste sesjon Fase B ferdigstilling + Phase 4 (LB + SSL migrering) -======= -### Neste sesjon — kjør i rekkefølge -```bash -cd ~/OSVauco # HUSK: alltid start her! -source .env -bash infrastructure/08-memorybank-setup.sh # A5 — sjekk om allerede kjørt -# Etter A5: kopier MEMORY_ENGINE_NAME inn i .env og kjør source .env -``` - -### Gjenværende MASTERPLAN-punkter - -| ID | Script | Status | -|----|--------|--------| -| A4 | `07-rag-setup.sh` | Sannsynligvis kjørt (RAG-filer committet) | -| A5 | `08-memorybank-setup.sh` | **Neste — usikkert om kjørt** | -| A7 | `04-observability-setup.sh` | ✅ FERDIG 2026-05-25 | -| A9 | `11-billing-iam-hardening.sh` | ✅ FERDIG 2026-05-25 | -| B1 | Dialogflow CX Playbook-agent | Ikke startet — kr 5 822 kreditt venter | -| B2 | `GITHUB_APP_INSTALLATION_ID` | Ikke satt — CI/CD fase B | - -### Notater -- `gemini-2.0-flash` og `gemini-2.0-flash-001` er **utfaset** for dette prosjektet — bruk aldri igjen -- Artifact Registry cleanup policy: beholder 5 nyeste images automatisk -- Teardown kjøres hver kveld: `bash infrastructure/03-teardown.sh` -- **TODO:** Legg `cd ~/OSVauco` inn i `osvauco-opax-boot.sh` så VM alltid starter i riktig mappe -- Zsh-prompt viser alltid `~/OSVauco` selv om du er i `~` — ikke stol på prompten, sjekk med `pwd` -- `ORG_DOMAIN` ikke satt i `.env` — legg til `export ORG_DOMAIN="vauco.no"` når vauco.no er Google Workspace-org -- Billing: vurder å opprette `billing@vauco.no` som Google Group fremfor enkeltadresser - ---- - -## Tidligere sesjoner - -### 2026-05-24 -- Cloud Run agent oppe for første gang -- IAP / opax.vauco.no load balancer satt opp -- CI/CD auto-deploy på push til main -- gemini-2.5-flash bekreftet fungerende modell - -### 2026-05-23 -- VM bootstrappet på nytt etter serverbytte -- Repo klonet, git config satt opp -- `01-setupenv.sh` kjørt — Vertex AI API aktivert - -### Sesjonsavslutning -- Gjort : GitHub og VM er i sync. Kvelden er ferdig — A7 og A9 i boks, A5 Memory Bank er neste sesjon. God natt! -- Uløst : N -- Slutt : 2026-05-25 21:36 UTC - ---- -## Session: 20260525-213642 -- Tid : 2026-05-25 21:37 UTC -- Bruker : chris.christiansen@vauco.no -- OPAX : OK -- Lokal : 515c1da @ main -- Remote : 515c1da -- Mål : VM ready for jobb - -### Kommandologg - 21:37:24 ✔ opax - 21:37:33 ✘[1] cd OSVauco - 21:38:00 ✔ pwd - 21:47:19 ✔ cost-audit - ---- -## Session: 20260525-221713 -- Tid : 2026-05-25 22:17 UTC -- Bruker : chris.christiansen@vauco.no -- OPAX : OK -- Lokal : 515c1da @ main -- Remote : 868693b -- Mål : RAG - -### Kommandologg - 22:17:33 ✔ opax - 22:17:48 ✘[1] mirror-sync - 22:18:58 ✘[1] git push origin main - 22:20:11 ✘[128] git pull --rebase origin main - 22:21:26 ✘[128] git pull --rebase origin main ->>>>>>> Stashed changes +### Sesjonsavslutning 20260531-153243 +- Start : 2026-05-31 15:32 UTC +- Slutt : 2026-05-31 15:34 UTC +- Gjort : git pull origin chore/consolidate-2026-05-31 +- Uløst : source ~/OSVauco/scripts/boot.sh diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md new file mode 100644 index 0000000..fff8d66 --- /dev/null +++ b/docs/ROADMAP.md @@ -0,0 +1,113 @@ +# VAUCO OS — ROADMAP + +**Eier:** Chris Christiansen +**Sist oppdatert:** 2026-05-31 +**Erstatter:** `docs/VAUCO_OS_ROADMAP.md` (deprecated) + +> Levende dokument. Oppdateres hver sesjon. Arkitektur og fasit ligger i `docs/MASTERPLAN.md`. + +--- + +## NOW — Aktiv akkurat nå + +- [ ] **K1 — Repo-konsolidering** (denne sesjonen) + - Slå sammen MASTERPLAN-er, fjern duplikater, fjern merge-markører i session log + - HITL gate: `MERGE APPROVED` på PR `chore/consolidate-2026-05-31` +- [ ] **K2 — AGENT_RULEBOOK retting** + - Region → `europe-west1`, modell → `gemini-2.5-pro`, MCP_SERVICE → `osvauco-agent` + - Done når: AGENT_RULEBOOK matcher MASTERPLAN §6 og §9 +- [ ] **K3 — Fiks nattlig GDrive backup** + - Workflow `backup-gdrive-nightly.yml` har failet hver natt siden 2026-05-25 + - Diagnostiser: SA-key gyldig? Folder-ID korrekt? `RCLONE_GDRIVE_SA_JSON` secret intakt? +- [ ] **F8 — End-to-end test via opax.vauco.no** + - Cloud Run `/health` ✅, IAP blokk ✅ + - **Gjenstår:** browser-login → chat → svar + - HITL gate: `FASE8 APPROVED` + +--- + +## NEXT — Neste opp (etter NOW) + +### vauco.no salgsportal (V-spor) — kan kjøres parallelt med CG3 +- [ ] **V1a** — Opprett `vauco-saas/vauco-site` (public repo, GitHub Pages) +- [ ] **V1b** — Bygg MVP: hero + modul-grid + om-oss + kontakt + personvern + vilkår +- [ ] **V1c** — Sett CNAME `vauco.no` + `www.vauco.no` → GitHub Pages i Proisp +- [ ] **V1d** — Erstatt "Under construction" — deploy MVP +- [ ] **V1e** — Sett opp SPF + DKIM + DMARC TXT-records på `vauco.no` + +### CostGuard frontend wiring +- [ ] **CG3a** — Bygg `static/costguard.html` (OAuth-knapp + billing embed) +- [ ] **CG3b** — Sett CNAME `costguard.oss.vauco.no` → Cloud Run i Proisp +- [ ] **CG3c** — Verifiser `/static/costguard.html` tilgjengelig via Cloud Run +- [ ] **CG3d** — Test OAuth-flow fra landingssiden +- [ ] **OQ-21** — Bygg `app.threadstone.vauco.no` eller fjern CNAME + +--- + +## LATER — Backlog (vent på trigger) + +### Go-to-market CostGuard +- [ ] **C4** — Medioteq HITL-møte → `terraform apply` → første betalende kunde +- [ ] **C5** — Salgsdemo: `costguard.os.vauco.no` + demo-video +- [ ] **DX5** — Dialogflow Messenger live på costguard-landingssiden +- [ ] **ML-2** — Adaptiv intelligens (trigger: >500 telemetri-kall) + +### Modul #2 — Threadstone +- [ ] **T1** — Konsolider `threadstone-instructions` → `OSVauco/docs/threadstone/` (trigger: T2 starter) +- [ ] **T2** — Bygg `app.threadstone.vauco.no` i `vauco-saas.github.io` +- [ ] **T3** — Koble til OPAX-engine via `POST /threadstone/generate` +- [ ] **T4** — Pilot med første kunde + +### Infrastruktur — Fase C +- [ ] **C1** — Terraform-konvertering (påbegynt: `infrastructure/terraform/modules/`) +- [ ] **C2** — Multi-tenant stamp-out (`scripts/onboard-client.sh`) +- [ ] **C3** — BQ-2 / Looker Studio kobling +- [ ] Full boot cycle acceptance test (automatisert) +- [ ] OPS agent + BigQuery live logging +- [ ] `opax-mcp/` restruktureres som ordentlig modul-subtree + +### OPAX-evolusjon +- [ ] Voice-input på `opax.vauco.no` (Web Speech API → Whisper) +- [ ] Magic-link auth for kunde-onboarding +- [ ] `POST /opax/generate` endpoint + +### Strategisk +- [ ] **Deep Dream** — røres ikke før Modul #1 har betalende kunde +- [ ] **Proof of Curiosity** — defineres etter Modul #1 + Modul #2 lever + +--- + +## BLOCKED + +- ⏳ **OQ-22** — Claude Opus 4.6/4.7 EU-kvote ikke innvilget. Midlertidig på `gemini-2.5-pro` via Vertex AI EU. + +--- + +## KJENTE HULL — ikke i en fase ennu + +- [ ] **OQ-23** — `vauco.no` viser "Under construction" → fikses i V1-fase +- [ ] **OQ-24** — SPF/DKIM/DMARC mangler på `vauco.no` (Google Workspace MX er satt, men autentisering ikke) → V1e +- [ ] **OQ-25** — Personvern/vilkår mangler → GDPR-krav før betalende kunde → V1 +- [ ] **OQ-26** — Ingen statuspage → etter første kunde + +--- + +## ✅ Fullførte faser + +- [x] **Phase 0** — Baseline: repo, `.gemini/`-struktur, boot-script, sesjonslogg +- [x] **Phase 1** — Domain/protocol locking, `ARCHITECTURE.md` +- [x] **Phase 2** — `opax.vauco.no` LIVE: Cloud Run, CNAME, SSL · 2026-05-21 +- [x] **Phase 3** — Nemotron session loop, `docs/TODO.md`, Phase 1+2 rapport · 2026-05-21 +- [x] **Phase 4** — Docs hardening: LEARNINGS 007–009, SECRETS-SETUP, IAP-SETUP kartlegging · 2026-05-25 +- [x] **Phase 5** — Cloud Run IAM-autentisering på `osvauco-agent`: kun Chris + Jason · 2026-05-25 +- [x] **Phase 5 IAP** — IAP migrering til GCP Load Balancer (IP 34.98.77.173) · 2026-05-30 +- [x] **Phase 6** — CI/CD: auto-deploy på push til main · 2026-05-30 +- [x] **Phase 7** — RAG corpus `osvauco-corpus` populert i `europe-west4` · 2026-05-30 +- [x] **GDrive/GitHub paritet** — mirror-script, PS1 prompt, IAM/Secrets · 2026-05-25 +- [x] **Repo-konsolidering trinn 1** — `vauco-os`, `vauco-gemini-tui-bridge`, `command-hub` arkivert · 2026-05-27 +- [x] **Terraform bootstrap-modul** — `infrastructure/terraform/modules/{vauco-bootstrap,vauco-platform}` opprettet · 2026-05-26 +- [x] **OPAX operator hub** — `static/opax.html` deployet · 2026-05-31 + +--- + +*Sjekkliste-logikk: NOW skal være ≤4 oppgaver. Når en NOW er done → flytt til Fullført. Når en NEXT starter → flytt opp til NOW.* diff --git a/docs/TODO.md b/docs/TODO.md index d20ed73..fdf9a9d 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -1,39 +1,9 @@ -# OSVauco / OPAX — TODO +# TODO — Flyttet -> Managed by PLAN thread. Update when phases move between sections. Last updated: 2026-05-25T14:37 CEST +> Denne filen er erstattet av [`docs/ROADMAP.md`](ROADMAP.md) per 2026-05-31. +> +> ROADMAP-filen er nå levende dokument for alle oppgaver. +> Se også [`docs/MASTERPLAN.md`](MASTERPLAN.md) for arkitektur/fasit +> og [`docs/HANDOFF.md`](HANDOFF.md) for gjeldende sesjonsstatus. ---- - -## NOW - -- [x] **⚠️ HASTER** — Roter OAuth client secret `Vauco OS Web App` i [Google Auth Platform](https://console.cloud.google.com/auth/clients/357036551735-ka7t2fv9ue2jp01bs826hpdctlvispuo.apps.googleusercontent.com?project=propane-will-491900-m5) — eksponert i chat 2026-05-25. (Løst) -- [x] Vurder om `jason.vauger@vauco.no` skal beholde `roles/run.invoker` på `osvauco-agent`. (Konklusjon: Ja, nødvendig for feedback_loop.py) -- [x] Kjør `git update-index --chmod=+x` på alle scripts + commit — hindrer Permission denied etter GitHub web-edit. -- [ ] Verifiser første nattlige GDrive backup — kl 03:00 UTC (Actions-logg). - ---- - -## NEXT - -- [ ] **Phase 6** — LEARNING-010 append: Cloud Run domain mapping støtter ikke load balancer IAP. -- [ ] `opax-mcp/` restruktureres som ordentlig modul-subtree. -- [ ] Full boot cycle acceptance test (automatisert). -- [ ] VS Code ↔ Cloud Shell workflow — preflight-script for lokal utvikling. -- [ ] **Gemini TUI-output logging** — `gemini-log` alias, append siste 50 linjer til session log. -- [ ] GDrive nightly workflow — verifiser schedule-trigger fungerer. - ---- - -## DONE ✅ - -- [x] **Phase 0** — Baseline: repo, `.gemini/`-struktur, boot-script, sesjonslogg. -- [x] **Phase 1** — Domain/protocol locking, `ARCHITECTURE.md`, `VAUCO_OS_ROADMAP.md`. -- [x] **Phase 2** — `opax.vauco.no` LIVE: Cloud Run, CNAME, SSL. -- [x] **Phase 3** — Nemotron session loop, `docs/TODO.md`, Phase 1+2 rapport. -- [x] **Phase 4** — Docs hardening: LEARNINGS 007-009, SECRETS-SETUP, IAP-SETUP kartlegging. (2026-05-25) -- [x] **Phase 5** — Cloud Run IAM-autentisering på `osvauco-agent`: kun `chris.christiansen@vauco.no` + `jason.vauger@vauco.no`. DNS urørt. (2026-05-25) -- [x] **GDrive/GitHub paritet** — mirror-script, nattlig backup, PS1 prompt, IAM/Secrets, opax-logg-slutt auto-push. (2026-05-25) -- [x] **GDrive backup IAM** — SA opprettet, JSON-nøkkel, mapper delt. (2026-05-25) -- [x] **GitHub Secrets** — `RCLONE_GDRIVE_SA_JSON` + `GDRIVE_BACKUP_FOLDER_ID` satt. (2026-05-25) -- [x] **Første mirror-sync** — `.gdrive-mirror-state` opprettet, `GDRIVE_MIRROR_BOOT.md` lastet opp. (2026-05-25) -- [x] **PS1 gul-bug** — state-fil skrives nå ETTER push, prompt grønn umiddelbart. (2026-05-25) +**Historisk TODO-innhold** (status per 2026-05-25) er bevart i Git-historikken. diff --git a/docs/VAUCO_OS_ROADMAP.md b/docs/VAUCO_OS_ROADMAP.md deleted file mode 100644 index 3038898..0000000 --- a/docs/VAUCO_OS_ROADMAP.md +++ /dev/null @@ -1,57 +0,0 @@ -# VAUCO OS — ROADMAP.md -# Eier: PLAN-Claude-Architect -# Sist oppdatert: 2026-05-22 CEST -# Godkjent av: Chris Christiansen - ---- - -## NOW — Aktiv nå - -- [ ] **Phase 4** — Docs hardening - - Owner: OPS / Gemini TUI - - HITL gate: `MERGE APPROVED` - - Filer: `LEARNINGS.md`, `SECRETS-SETUP.md`, `IAP-SETUP.md` — oppdater med nåværende state - - Done: alle tre filer har seksjon `## Status 2026-05-22` med verifisert info - ---- - -## NEXT — Neste opp - -- [ ] **Phase 5** — IAP på `opax.vauco.no` - - Begrens til `@vauco.no` Google-kontoer - - Owner: EXEC-Gemini / Chris - - HITL gate: `DEPLOY GODKJENT` - - Done: uautentiserte requests → 403, `chris.christiansen@vauco.no` → 200 - -- [ ] **Phase 6** — VS Code ↔ Cloud Shell workflow - - Preflight-script + dokumentasjon for lokal utvikling mot OSVauco-repoet - - Owner: OPS - - HITL gate: `MERGE APPROVED` - ---- - -## LATER — Backlog - -- [ ] `opax-mcp/` restruktureres som ordentlig modul-subtree -- [ ] Full boot cycle acceptance test (automatisert) -- [ ] OPS agent + BigQuery live logging -- [ ] Multi-klient onboard-mønster -- [ ] **Medioteq** — kun idéfase, ingenting implementeres før OPAX er fullt operasjonelt - ---- - -## BLOCKED - -*(ingen blokkerte punkter)* - ---- - -## ✅ Fullførte faser - -- [x] **Phase 0** — Baseline: `opax-mcp-core` live, OSVauco repo, `.gemini/` grunnmur, boot-script, sessionslogg -- [x] **Phase 1** — MCP_NAME/MCP_PROTOCOL/ROOT_DOMAIN locked; ARCHITECTURE.md + ROADMAP.md opprettet · `6ae1a25` `4a971dd` `c4149e7` · 2026-05-21 -- [x] **Phase 2** — `opax.vauco.no` LIVE: domain mapping + CNAME + SSL + HUB_URL locked · `f3bf419` · 2026-05-21 -- [x] **Phase 3** — Nemotron session loop i GEMINI.md; docs/TODO.md; Phase 1+2 SLUTTRAPPORT i session log · `77ed501` · 2026-05-21 - ---- -EOF v2.0 — 2026-05-22 — synkronisert med faktisk repo-state diff --git a/docs/archive/Cost_Management_Rules.md b/docs/archive/Cost_Management_Rules.md deleted file mode 100644 index 3600091..0000000 --- a/docs/archive/Cost_Management_Rules.md +++ /dev/null @@ -1,85 +0,0 @@ -# Cost Management Rules [ARCHIVED] -> Arkivert 2026-05-27 — erstattet av docs/CostManagementRules.md - -# Cost Management Rules -**OSVauco-NMTMD-GCOS | GCP Agent Master Repo** - -## 1. Budget Alerts - -```bash -gcloud billing budgets create \ - --billing-account="${BILLING_ACCOUNT_ID}" \ - --display-name="Agent Platform Budget" \ - --budget-amount=500USD \ - --threshold-rule=percent=0.5,basis=CURRENT_SPEND \ - --threshold-rule=percent=0.8,basis=CURRENT_SPEND \ - --threshold-rule=percent=1.0,basis=CURRENT_SPEND -``` - -## 2. Resource Labeling - -All GCP resources MUST carry: - -| Label Key | Example | Purpose | -|-----------|---------|--------| -| env | prod/dev/staging | Environment | -| team | osvaucoe | Cost attribution | -| cost-center | ai-platform | Finance | -| agent | orchestrator/rag | Per-agent tracking | - -## 3. Cloud Run Cost Controls - -```bash -gcloud run deploy ${SERVICE} \ - --max-instances=10 \ - --concurrency=80 \ - --timeout=300 -``` - -- CPU throttling on for non-latency-critical agents -- min-instances=1 only for latency-sensitive services - -## 4. Vertex AI Cost Controls - -- Use gemini-2.0-flash for high-volume sub-agent calls -- Context caching for repeated prompts (up to 75% savings) -- max_output_tokens=2048 for most tasks -- Monitor: aiplatform.googleapis.com/prediction/online/token_count - -## 5. RAG Engine Cost Controls - -- Delete stale documents from corpus -- Batch embedding for initial ingestion -- top_k=5 (not higher) -- Archive cold corpora to Cloud Storage lower tier - -## 6. Memory Bank Cost Controls - -- TTL: 7 days for short-lived session memories -- Firestore-backed for most use cases -- Index only user_id and session_id - -## 7. Networking Cost Controls - -- Private Google Access to avoid Vertex AI egress charges -- VPC routing for all agent traffic -- Cloud NAT only where unavoidable - -## 8. Storage Lifecycle - -```json -{ - "rule": [{ - "action": { "type": "Delete" }, - "condition": { "age": 7 } - }] -} -``` -Apply with: `gcloud storage buckets update gs://BUCKET --lifecycle-file=lifecycle.json` - -## 9. End-of-Day Teardown Checklist - -- [ ] Run 03-teardown.sh -- [ ] Verify no active Agent Runtimes: `gcloud ai agent-engines list --region=us-central1` -- [ ] Verify no active Vertex AI endpoints: `gcloud ai endpoints list --region=us-central1` -- [ ] Check billing dashboard for anomalies diff --git a/docs/archive/GCPBestPractices.md b/docs/archive/GCPBestPractices.md deleted file mode 100644 index a7762a2..0000000 --- a/docs/archive/GCPBestPractices.md +++ /dev/null @@ -1,11 +0,0 @@ -# GCP Best Practices [ARCHIVED] -> Arkivert 2026-05-27 — erstattet av docs/GCP_Best_Practices.md - -# GCP Best Practices — propane-will-491900-m5 - -## Platform context (2025–2026) -- **Vertex AI Agent Engine** has been rebranded as **Gemini Enterprise Agent Platform**. - Agent runtimes are fully managed serverless — no VM management required. -- **ADK (Agent Development Kit)** 2.0 is open-source, supports Python/TypeScript/Go/Java/Kotlin. - Agents run locally for dev, then deploy to Agent Runtime, Cloud Run, or GKE. -- Region: **us-central1** for all resources (low latency, widest feature availability). diff --git a/docs/archive/OSVAUCO_OPAX_SESSION_LOG.md b/docs/archive/OSVAUCO_OPAX_SESSION_LOG.md deleted file mode 100644 index 92408ec..0000000 --- a/docs/archive/OSVAUCO_OPAX_SESSION_LOG.md +++ /dev/null @@ -1,2 +0,0 @@ -# OSVAUCO OPAX SESSION LOG [ARCHIVED] -> Arkivert 2026-05-27 — historisk sesjonslogg, erstattet av HANDOFF_20260526.md og fremtidige HANDOFF-filer. diff --git a/docs/HANDOFF_20260526.md b/docs/archive/handoffs/HANDOFF_20260526.md similarity index 100% rename from docs/HANDOFF_20260526.md rename to docs/archive/handoffs/HANDOFF_20260526.md diff --git a/docs/HANDOFF_20260531.md b/docs/archive/handoffs/HANDOFF_20260531.md similarity index 100% rename from docs/HANDOFF_20260531.md rename to docs/archive/handoffs/HANDOFF_20260531.md diff --git a/docs/HANDOFF_20260531_claude47.md b/docs/archive/handoffs/HANDOFF_20260531_claude47.md similarity index 100% rename from docs/HANDOFF_20260531_claude47.md rename to docs/archive/handoffs/HANDOFF_20260531_claude47.md diff --git a/docs/vauco-site/DESIGN.md b/docs/vauco-site/DESIGN.md new file mode 100644 index 0000000..7431e52 --- /dev/null +++ b/docs/vauco-site/DESIGN.md @@ -0,0 +1,252 @@ +# vauco.no — Design & build-spec for V1 (MVP) + +**Eier:** Chris Christiansen +**Sist oppdatert:** 2026-05-31 +**Status:** 🟡 Spec klar — venter på V1a (repo-opprettelse) +**Trigger for å starte build:** Etter Fase 8 approved, eller parallelt hvis Chris vil + +> **Plassering av denne filen:** Mens `vauco-site`-repoet ikke finnes ennå, lever spec'en her i OSVauco. Når `vauco-saas/vauco-site` opprettes (V1a), flyttes denne filen dit som `README.md` eller `DESIGN.md`. + +--- + +## 1. Hva siden er + +Vauco AS sin offisielle bedriftsside på `vauco.no`. Ett formål: **lede besøkende videre til riktig salgs-modul** og samtidig svare på "hvem er Vauco?". + +Det er ikke en produktside. Det er ikke en blogg. Det er en portal. + +--- + +## 2. Sidekart V1 + +``` +vauco.no/ (hovedside — én lang side, ankerlenker) +├── #hero +├── #moduler Grid av salgs-moduler +├── #hvorfor +├── #om +├── #kontakt +└── footer + +vauco.no/personvern.html GDPR personvernerklæring +vauco.no/vilkar.html Standardvilkår for kunder +vauco.no/sitemap.xml +vauco.no/robots.txt +``` + +V1 er **én HTML-fil** + 2 statiske underdokumenter. Ikke noe mer. + +--- + +## 3. Innhold per seksjon (utkast — Chris godkjenner copy) + +### #hero +- **H1:** "Vauco bygger AI-moduler som leverer målbar verdi." +- **Sub:** "Norskutviklet. Drevet på Google Cloud. Lansert av operatører som faktisk har drevet plattformer i produksjon." +- **CTA primær:** "Se CostGuard →" (anchor til #moduler eller direkte til costguard.oss.vauco.no) +- **CTA sekundær:** "Snakk med Chris →" (mailto:chris.christiansen@vauco.no) + +### #moduler (kjernen — grid med kort) +| Kort | Status | Lenke | +|------|--------|-------| +| **CostGuard** — AI-drevet GCP-kostnadsovervåkning. Stopp surprise-regninger før de skjer. | 🟢 Live | costguard.oss.vauco.no | +| **Threadstone** — Generativ AI-assistent for innhold som leverer. | 🟡 I pilot | threadstone.vauco.no | +| **Modul #3** — *Coming soon.* Meld deg på for tidlig tilgang. | ⏳ Q4 2026 | (mailto med subject "Modul 3 interesse") | + +### #hvorfor (3 punkter, ikke flere) +1. **Norsk eierskap, norsk drift.** Data forblir i EU. Vauco AS er norsk-registrert (org.nr 935 989 779). +2. **GCP-ekspertise i bunn.** Vi har bygget og driftet Google Cloud-plattformer profesjonelt. Det er ingen tilfeldighet at CostGuard er første produkt. +3. **AI som ikke er hype.** Hver modul har en konkret jobb og et målbart utfall. Hvis vi ikke kan vise ROI, lanserer vi den ikke. + +### #om +- Bilde av Chris (kan tas opp senere — V1 kan kjøre uten) +- Kort tekst: "Vauco AS er grunnlagt av Chris Christiansen i Oslo, 2026. Vi bygger AI-moduler for nordiske bedrifter." +- LinkedIn-lenke + +### #kontakt +- `chris.christiansen@vauco.no` +- LinkedIn +- Oslo, Norge +- (Telefon kun ved forespørsel — ikke list åpent) + +### footer +- Vauco AS · Org.nr 935 989 779 +- Lenker: Personvern · Vilkår · Status (placeholder, peker til status.vauco.no når live) +- © 2026 Vauco AS + +--- + +## 4. Visuell retning + +### Stil-anker +Bygger videre på `threadstone-landing/index.html` sin estetikk: +- Mørk bakgrunn (`#0a0a0a` eller lignende) +- Lys tekst (`#f5f5f5`) +- Monospace for kodeaksenter / labels / footer (`'JetBrains Mono'`, `'SF Mono'`, fallback `ui-monospace`) +- Sans-serif for body: Inter / SF Pro Display / system-ui + +### Farger +| Rolle | Hex | Bruk | +|-------|-----|------| +| Bakgrunn | `#0a0a0a` | `` | +| Tekst primær | `#f5f5f5` | H1, body | +| Tekst sekundær | `#a0a0a0` | Sub-text, captions | +| Aksent — Vauco | `#e8d4a3` (varm sand/gull, samme som Threadstone) | Lenker, CTA-knapp | +| Aksent — CostGuard | TBD (foreslå grønn/blå, ikke samme som Vauco-aksent) | Kun på CostGuard-kortet | +| Aksent — Threadstone | TBD (foreslå lilla/rose) | Kun på Threadstone-kortet | +| Border | `rgba(255,255,255,0.08)` | Kort-borders | + +### Typografi +- H1: 48–64px, weight 600, line-height 1.1 +- H2: 32–40px, weight 500 +- Body: 16–18px, line-height 1.6 +- Monospace caption: 13px, uppercase letter-spacing 0.1em + +### Layout +- Maks bredde: 1100px, sentrert +- Padding: 24px på mobil, 48px på desktop +- Grid på #moduler: 1 kolonne mobil, 2 kolonner tablet, 3 kolonner desktop +- Vertikal rytme: 96px mellom hovedseksjoner + +### Mobile-first +Chris demoer fra telefon. Side må fungere perfekt på iPhone 13/14/15. Test både portrait og landscape. + +### Performance-mål +- Lighthouse: Performance ≥95, Accessibility ≥95, Best Practices ≥95, SEO ≥95 +- Total page size <100KB (uten bilder) +- Ingen tracking-piksler i V1 +- Ingen tredjepartsfonter — bruk system-stack med fallback (eller selvhostet Inter via woff2) + +--- + +## 5. Teknisk + +### Stack +- **HTML5 + CSS3** (vanilj — ingen framework) +- **Ingen JavaScript** i V1 (eller maks 1 KB for smooth-scroll på ankerlenker) +- **GitHub Pages** for hosting +- **GitHub Actions** for valider-og-deploy (auto-deploy på push til main) + +### Filstruktur i `vauco-site/` repo +``` +vauco-site/ +├── index.html +├── personvern.html +├── vilkar.html +├── style.css (kan inline-es i index.html for V1) +├── assets/ +│ ├── favicon.svg +│ ├── og-image.png (1200x630, Open Graph) +│ └── (evt. Chris-portrett) +├── CNAME (innhold: vauco.no) +├── robots.txt +├── sitemap.xml +└── README.md (denne filen flyttes hit) +``` + +### Meta-tags (kritisk for SEO + sosial deling) +```html +Vauco — AI-moduler som leverer målbar verdi + + + + + + + +``` + +### DNS-endringer (i Proisp) +| Record | Type | Verdi | +|--------|------|-------| +| `@` (apex) | A | `185.199.108.153` (GitHub Pages) | +| `@` (apex) | A | `185.199.109.153` | +| `@` (apex) | A | `185.199.110.153` | +| `@` (apex) | A | `185.199.111.153` | +| `www` | CNAME | `vauco-saas.github.io.` | + +**Eksisterende A-records (Proisp-parking 104.37.38.95, 104.37.39.71) må fjernes.** + +### Email-records (V1e — samme runde) +| Record | Type | Verdi | +|--------|------|-------| +| `@` | TXT | `"v=spf1 include:_spf.google.com ~all"` | +| `google._domainkey` | TXT | (hent fra Google Workspace Admin → Apps → Gmail → Authenticate email) | +| `_dmarc` | TXT | `"v=DMARC1; p=quarantine; rua=mailto:dmarc@vauco.no; pct=100"` | + +--- + +## 6. Akseptkriterier for V1 + +Før V1 kan kalles ferdig: + +- [ ] `https://vauco.no` viser ny side (ikke "Under construction") +- [ ] `https://www.vauco.no` viser samme side (eller redirect til apex) +- [ ] Lighthouse mobil: alle 4 ≥95 +- [ ] OG-bilde rendrer korrekt i LinkedIn-deling (test via [LinkedIn Post Inspector](https://www.linkedin.com/post-inspector/)) +- [ ] CostGuard-kort lenker til `costguard.oss.vauco.no` og kortet åpnes som ny tab +- [ ] Threadstone-kort lenker til `threadstone.vauco.no` +- [ ] `personvern.html` og `vilkar.html` finnes og er lenket fra footer +- [ ] SPF + DKIM + DMARC verifisert via [mxtoolbox.com](https://mxtoolbox.com) — alle grønne +- [ ] Sitemap pinget til Google Search Console +- [ ] Chris signer av visuelt — `V1 APPROVED` + +--- + +## 7. V2 og videre — ikke bygg ennå + +Bare for kontekst: + +- **V2:** CostGuard ROI-kalkulator inline på siden, første case study +- **V3:** Blogg/innsikter (`vauco.no/innsikt/`), kundereferanser, live status-widget +- **V4:** `/en` engelsk versjon, Proof of Curiosity i footer + +--- + +## 8. Bygg-rekkefølge for V1 (når du eller en agent starter) + +```bash +# 1. Opprett repo +gh repo create vauco-saas/vauco-site --public \ + --description "vauco.no — Vauco AS salgsportal" \ + --add-readme + +# 2. Klon, lag struktur +git clone https://github.com/vauco-saas/vauco-site.git +cd vauco-site +# (kopier denne DESIGN.md inn som README.md) +# (bygg index.html, personvern.html, vilkar.html, CNAME, robots.txt, sitemap.xml) + +# 3. Sett CNAME-fil +echo "vauco.no" > CNAME + +# 4. Push +git add -A +git commit -m "feat: Vauco AS apex-side V1 MVP" +git push origin main + +# 5. Aktiver Pages: Settings → Pages → Source: main / root +# 6. Vent på SSL-sertifikat (kan ta 24t første gang) + +# 7. Endre DNS i Proisp (se tabell §5 over) +# 8. Vent på DNS-propagering, verifiser med: +dig +short vauco.no A +# Forventet: 185.199.108-111.153 + +# 9. Sjekk SSL: +curl -sI https://vauco.no | head -5 +# Forventet: HTTP/2 200, server: GitHub.com +``` + +--- + +## 9. Referanser + +- Stilanker: `threadstone-landing/index.html` (samme org) +- Designinspirasjon: [linear.app](https://linear.app), [resend.com](https://resend.com), [vercel.com](https://vercel.com) +- GDPR-guide for personvernerklæring: [Datatilsynet — krav til personvernerklæring](https://www.datatilsynet.no/) +- GitHub Pages custom domain: [docs.github.com/pages/configuring-a-custom-domain](https://docs.github.com/en/pages/configuring-a-custom-domain-for-your-github-pages-site) + +--- + +*Denne spec'en flyttes til `vauco-saas/vauco-site/README.md` så snart V1a er gjennomført.* diff --git a/scripts/README.md b/scripts/README.md new file mode 100644 index 0000000..edf212e --- /dev/null +++ b/scripts/README.md @@ -0,0 +1,78 @@ +# scripts/ — OSVauco operasjons-scripts + +Alle scripts kjøres fra `~/OSVauco`. Etter at du har sourced `boot.sh` har du aliaser klare. + +## Daglig oppstart (én linje) + +Legg dette i `~/.bashrc`: + +```bash +# OSVauco auto-boot ved interaktivt shell-login +[[ $- == *i* && -z "$OSVAUCO_BOOTED" ]] && source ~/OSVauco/scripts/boot.sh +``` + +Ved login får du: + +1. Auto-renewal av `gcloud auth` + ADC +2. `git pull` på current branch +3. Print av NESTE OPPGAVE fra `docs/HANDOFF.md` +4. Valg: `opax` (Gemini 2.5 Pro) / `opax2` (Claude Opus 4.7) / hopp over + +## Hotkeys (etter boot.sh er sourced) + +| Alias | Hva | Script | +|---|---|---| +| `opax` | Start Gemini 2.5 Pro TUI | `opax.sh` | +| `opax2` | Start Claude Opus 4.7 TUI | `opax2.sh` | +| `pf` | Preflight (auth/project/env) | `preflight.sh` | +| `hc` | Health-check (Cloud Run + LB) | `health-check.sh` | +| `st` | Smoke-test | `smoke-test.sh` | +| `at` | Acceptance-test | `acceptance-test.sh` | +| `ca` | Cost-audit | `cost-audit.sh` | +| `cl` / `costs` | Cost-lens | `cost-lens.sh` | +| `cg` | Cost-guard | `cost-guard.sh` | +| `ms` | Mirror-sync til GDrive | `sync-gdrive-mirror.sh` | +| `logg` | Manuell logg-slutt | `opax-logg-slutt.sh` | +| `sol` | Avslutt + commit + push | (funksjon i boot.sh) | +| `mp` | Vis MASTERPLAN | `docs/MASTERPLAN.md` | +| `rl` | Vis ROADMAP | `docs/ROADMAP.md` | +| `ho` | Vis HANDOFF | `docs/HANDOFF.md` | +| `rb` | Vis AGENT_RULEBOOK | `docs/AGENT_RULEBOOK.md` | +| `sl` | Vis SESSION_LOG | `docs/OSVAUCO_OPAX_SESSION_LOG.md` | +| `osv` | `cd ~/OSVauco` | — | +| `reboot-osv` | Re-source boot.sh | — | + +## Modell-valg + +| TUI | Modell | Region | Når | +|---|---|---|---| +| `opax` | `gemini-2.5-pro` | `europe-west1` | Default (alltid OK) | +| `opax2` | `claude-opus-4-7@20260301` | `europe-west1` | Når Claude-kvote er innvilget | + +Verdier er låst i `docs/AGENT_RULEBOOK.md`. Endring krever `RULEBOOK APPROVED` HITL-gate. + +## Locked infrastruktur + +| Felt | Verdi | +|---|---| +| GCP-prosjekt | `propane-will-491900-m5` | +| Region | `europe-west1` | +| Cloud Run-tjeneste | `osvauco-agent` | +| LB IP | `34.98.77.173` | +| Public URL | `https://opax.vauco.no` (IAP) | +| Direct URL | `https://osvauco-agent-357036551735.europe-west1.run.app` | + +## Engangs-fixers + +`scripts/fix/` inneholder engangs-fixers for kjente problemer: + +- `fix-cloudrun.sh` — restart + redeploy ved Cloud Run-feil +- `fix-dns.sh` — re-bind A-record til LB IP +- `fix-iap.sh` — re-aktiver IAP-policy på backend +- `fix-tui.sh` — reinstall gemini CLI + node-deps + +Kjør kun når preflight peker på det konkrete problemet. + +## Endrings-prosess + +Alle endringer i `scripts/` skal gjennom PR med `MERGE APPROVED` HITL-gate. diff --git a/scripts/archived/boot.sh b/scripts/archived/boot.sh deleted file mode 100755 index b4c6f4f..0000000 --- a/scripts/archived/boot.sh +++ /dev/null @@ -1,188 +0,0 @@ -#!/usr/bin/env bash -# ============================================================================= -# boot.sh — OSVauco OPAX Terminal Boot Protocol v3 -# Auto-runs on Cloud Shell startup via ~/.bashrc -# Manual: source ~/OSVauco/scripts/boot.sh -# ============================================================================= - -OSVAUCO_DIR="${HOME}/OSVauco" - -[[ $- != *i* ]] && return -[[ ! -d "$OSVAUCO_DIR" ]] && return - -cd "$OSVAUCO_DIR" || return - -# Colors -CYAN='\033[0;36m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -RED='\033[0;31m' -WHITE='\033[1;37m' -DIM='\033[2m' -BOLD='\033[1m' -NC='\033[0m' - -OK="${GREEN}[OK]${NC}" -WARN="${YELLOW}[!!]${NC}" -FAIL="${RED}[XX]${NC}" -INFO="${CYAN}[>>]${NC}" -DOT="${DIM}[--]${NC}" - -clear - -printf "${CYAN}" -echo " ___ _____ _ _ ___ _ _ ___ _____ " -echo " / _ \| ___| | | | |/ _ \| | | |/ __|| _ | " -echo " | | | | |___ | | | / /_\ \ | | | | | | | | " -echo " | | | |___ | | | | | _ | | | | | | | | | " -echo " | |_| |___| | \ \_/ / | | | |_| | |__ \ \_/ / " -echo " \___/\____/ \___/\_| |_/\___/ \___| \___/ " -printf "${NC}" -printf "${DIM} -------------------------------------------------${NC}\n" -printf " ${CYAN}OPAX${NC} ${DIM}Operator Platform // propane-will-491900-m5${NC}\n" -printf "${DIM} -------------------------------------------------${NC}\n" -printf " ${WHITE}BOOT${NC} ${DIM}$(date '+%Y-%m-%d %H:%M %Z')${NC}\n" -printf "${DIM} -------------------------------------------------${NC}\n" -echo "" - -# ============================================================================= -# SECTION 1: AUTH -# ============================================================================= -printf "${BOLD}${CYAN} [ AUTH ]${NC}\n" - -if [[ -f "$OSVAUCO_DIR/.env" ]]; then - source "$OSVAUCO_DIR/.env" - printf " ${OK} .env loaded ${DIM}PROJECT_ID=${PROJECT_ID}${NC}\n" -else - printf " ${FAIL} .env MISSING ${YELLOW}Run: cp .env.example .env${NC}\n" - return -fi - -gcloud config set project "$PROJECT_ID" --quiet 2>/dev/null -ACTIVE_PROJ=$(gcloud config get-value project 2>/dev/null) -if [[ "$ACTIVE_PROJ" == "$PROJECT_ID" ]]; then - printf " ${OK} gcloud project ${DIM}${ACTIVE_PROJ}${NC}\n" -else - printf " ${FAIL} project MISMATCH ${RED}got: ${ACTIVE_PROJ}${NC}\n" -fi - -ACTIVE_ACCOUNT=$(gcloud config get-value account 2>/dev/null) -if [[ -n "$ACTIVE_ACCOUNT" ]]; then - printf " ${OK} gcloud account ${DIM}${ACTIVE_ACCOUNT}${NC}\n" -else - printf " ${FAIL} NO ACCOUNT ${YELLOW}Run: gcloud auth login${NC}\n" -fi - -if gcloud auth application-default print-access-token >/dev/null 2>&1; then - printf " ${OK} ADC token ${DIM}valid${NC}\n" -else - printf " ${WARN} ADC missing ${YELLOW}Run: gcloud auth application-default login${NC}\n" -fi -echo "" - -# ============================================================================= -# SECTION 2: CLOUD RUN -# ============================================================================= -printf "${BOLD}${CYAN} [ CLOUD RUN ]${NC}\n" -CR_LIST=$(gcloud run services list \ - --project="${PROJECT_ID}" \ - --region="${REGION}" \ - --format="value(name,status.url)" 2>/dev/null || echo "") - -if [[ -z "$CR_LIST" ]]; then - printf " ${DOT} No services deployed ${DIM}(no cost)${NC}\n" -else - while IFS=$'\t' read -r NAME URL; do - printf " ${OK} %-26s ${DIM}%s${NC}\n" "$NAME" "$URL" - done <<< "$CR_LIST" -fi -echo "" - -# ============================================================================= -# SECTION 3: MEMORY BANK -# ============================================================================= -printf "${BOLD}${CYAN} [ MEMORY BANK ]${NC} ${DIM}(\$0.0994/vCPU-hr -- continuous billing)${NC}\n" -ENGINES=$(gcloud ai reasoning-engines list \ - --project="${PROJECT_ID}" \ - --region="${REGION}" \ - --format="value(name,displayName)" 2>/dev/null || echo "") - -if [[ -z "$ENGINES" ]]; then - printf " ${OK} No active instances ${DIM}(no cost)${NC}\n" -else - ENGINE_COUNT=$(echo "$ENGINES" | grep -c . || true) - printf " ${FAIL} ${RED}${BOLD}${ENGINE_COUNT} INSTANCE(S) RUNNING -- COSTS MONEY CONTINUOUSLY${NC}\n" - while IFS=$'\t' read -r ENAME EDISPLAY; do - SHORT=$(echo "$ENAME" | awk -F'/' '{print $NF}') - printf " ${WARN} %-22s ${DIM}id: %s${NC}\n" "${EDISPLAY:-unnamed}" "$SHORT" - done <<< "$ENGINES" - printf " ${INFO} ${DIM}gcloud ai reasoning-engines delete ID --project=$PROJECT_ID --region=$REGION --quiet${NC}\n" -fi -echo "" - -# ============================================================================= -# SECTION 4: AGENT RUNTIMES -# ============================================================================= -printf "${BOLD}${CYAN} [ AGENT RUNTIMES ]${NC}\n" -AGENT_RUNTIMES=$(gcloud ai agent-engines list \ - --project="${PROJECT_ID}" \ - --region="${REGION}" \ - --format="value(name,displayName,state)" 2>/dev/null || echo "") - -if [[ -z "$AGENT_RUNTIMES" ]]; then - printf " ${DOT} No agent runtimes ${DIM}(no cost)${NC}\n" -else - while IFS=$'\t' read -r ANAME ADISPLAY ASTATE; do - SHORT=$(echo "$ANAME" | awk -F'/' '{print $NF}') - if [[ "$ASTATE" == "ACTIVE" ]]; then - printf " ${OK} %-24s ${GREEN}%-8s${NC} ${DIM}id: %s${NC}\n" "${ADISPLAY:-unnamed}" "$ASTATE" "$SHORT" - else - printf " ${WARN} %-24s ${YELLOW}%-8s${NC} ${DIM}id: %s${NC}\n" "${ADISPLAY:-unnamed}" "$ASTATE" "$SHORT" - fi - done <<< "$AGENT_RUNTIMES" -fi -echo "" - -# ============================================================================= -# SECTION 5: RAG CORPORA -# ============================================================================= -printf "${BOLD}${CYAN} [ RAG CORPORA ]${NC} ${DIM}(not deleted by teardown)${NC}\n" -RAG_LIST=$(gcloud ai rag-corpora list \ - --project="${PROJECT_ID}" \ - --region="${REGION}" \ - --format="value(name,displayName)" 2>/dev/null || echo "") - -if [[ -z "$RAG_LIST" ]]; then - printf " ${DOT} No RAG corpora found\n" -else - while IFS=$'\t' read -r RNAME RDISPLAY; do - SHORT=$(echo "$RNAME" | awk -F'/' '{print $NF}') - printf " ${OK} %-28s ${DIM}id: %s${NC}\n" "${RDISPLAY:-unnamed}" "$SHORT" - done <<< "$RAG_LIST" -fi -echo "" - -# ============================================================================= -# SECTION 6: GIT -# ============================================================================= -printf "${BOLD}${CYAN} [ GIT ]${NC}\n" -git pull --quiet 2>/dev/null -GIT_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") -LAST_COMMIT=$(git log --oneline -1 2>/dev/null || echo "unknown") -printf " ${OK} branch: ${WHITE}%-18s${NC} ${DIM}%s${NC}\n" "$GIT_BRANCH" "$LAST_COMMIT" -echo "" - -# ============================================================================= -# QUICK COMMANDS -# ============================================================================= -printf "${DIM} -------------------------------------------------${NC}\n" -printf "${BOLD}${CYAN} QUICK COMMANDS${NC}\n" -printf " ${DIM}authcheck${NC} bash infrastructure/00-authcheck.sh\n" -printf " ${DIM}deploy ${NC} bash infrastructure/05-cloudrun-deploy.sh\n" -printf " ${DIM}rag ${NC} bash infrastructure/07-rag-setup.sh\n" -printf " ${DIM}memory ${NC} bash infrastructure/08-memorybank-setup.sh\n" -printf " ${DIM}cost ${NC} bash infrastructure/09-cost-check.sh\n" -printf " ${DIM}teardown ${NC} bash infrastructure/03-teardown.sh\n" -printf " ${DIM}gemini ${NC} gemini ${DIM}# OPAX-MCP TUI${NC}\n" -printf "${DIM} -------------------------------------------------${NC}\n" -echo "" diff --git a/scripts/archived/bootstrap.sh b/scripts/archived/bootstrap.sh deleted file mode 100644 index e07eb92..0000000 --- a/scripts/archived/bootstrap.sh +++ /dev/null @@ -1,100 +0,0 @@ -#!/bin/bash -# bootstrap.sh — OSVauco VM bootstrap -# Kjøres på ny VM eller etter serverbytte -# Bruk: source .env && bash scripts/bootstrap.sh - -set -euo pipefail - -PROJECT_ID="${PROJECT_ID:-propane-will-491900-m5}" -REGION="${REGION:-us-central1}" -ARTIFACT_REPO="${ARTIFACT_REPO:-osvauco-repo}" -CLOUD_RUN_SERVICE="${CLOUD_RUN_SERVICE:-osvauco-agent}" -CLOUD_RUN_URL="https://osvauco-agent-357036551735.us-central1.run.app" - -echo "" -echo "╔══════════════════════════════════════════════════╗" -echo "║ OSVauco VM Bootstrap ║" -echo "║ Prosjekt: $PROJECT_ID ║" -echo "╚══════════════════════════════════════════════════╝" -echo "" - -# ── Steg 1: Auth-sjekk ───────────────────────────────────── -echo "[1/4] Auth-sjekk..." -bash infrastructure/00-authcheck.sh - -# ── Steg 2: Sjekk at osvauco-base finnes i Artifact Registry ─ -echo "" -echo "[2/4] Sjekker base Docker-image..." - -BASE_IMAGE="${REGION}-docker.pkg.dev/${PROJECT_ID}/${ARTIFACT_REPO}/osvauco-base" - -if gcloud artifacts docker images describe "${BASE_IMAGE}:latest" \ - --project="$PROJECT_ID" >/dev/null 2>&1; then - echo " ✅ osvauco-base:latest finnes — hopper over bygg" -else - echo " ⚠️ osvauco-base:latest mangler — bygger nå (~5-10 min)..." - gcloud builds submit \ - --config=cloudbuild.base.yaml \ - --project="$PROJECT_ID" \ - . - echo " ✅ osvauco-base bygget og pushet" -fi - -# ── Steg 3: Sjekk IAM-bindinger for CI/CD ────────────────── -echo "" -echo "[3/4] Sjekker IAM-bindinger for CI/CD..." - -PROJECT_NUMBER=$(gcloud projects describe "$PROJECT_ID" --format="value(projectNumber)") -CB_SA="${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" -AGENT_SA="osvauco-agent-sa@${PROJECT_ID}.iam.gserviceaccount.com" - -# Cloud Build SA → iam.serviceAccountUser på agent-SA -gcloud iam service-accounts add-iam-policy-binding "$AGENT_SA" \ - --member="serviceAccount:${CB_SA}" \ - --role="roles/iam.serviceAccountUser" \ - --project="$PROJECT_ID" \ - --quiet 2>/dev/null && echo " ✅ Cloud Build SA har actAs på agent-SA" || echo " ℹ️ Cloud Build SA binding allerede på plass" - -# Agent SA → iam.serviceAccountUser på seg selv -gcloud iam service-accounts add-iam-policy-binding "$AGENT_SA" \ - --member="serviceAccount:${AGENT_SA}" \ - --role="roles/iam.serviceAccountUser" \ - --project="$PROJECT_ID" \ - --quiet 2>/dev/null && echo " ✅ Agent SA har actAs på seg selv" || echo " ℹ️ Self-binding allerede på plass" - -# ── Steg 4: Test at Cloud Run-agenten svarer ─────────────── -echo "" -echo "[4/4] Tester Cloud Run-agenten..." - -TOKEN=$(gcloud auth print-identity-token 2>/dev/null || echo "") - -if [[ -z "$TOKEN" ]]; then - echo " ⚠️ Kan ikke hente identity token — er du logget inn med gcloud auth login?" -else - HTTP_CODE=$(curl -s -o /tmp/osvauco-test.json -w "%{http_code}" \ - -X POST \ - -H "Authorization: Bearer $TOKEN" \ - -H "Content-Type: application/json" \ - -d '{"user_id":"bootstrap","session_id":"boot-1","message":"Hei"}' \ - "${CLOUD_RUN_URL}/run") - - if [[ "$HTTP_CODE" == "200" ]]; then - echo " ✅ Agent svarer (HTTP 200)" - cat /tmp/osvauco-test.json | python3 -m json.tool 2>/dev/null | head -5 - else - echo " ⚠️ Agent svarte HTTP $HTTP_CODE" - cat /tmp/osvauco-test.json - echo "" - echo " Vanlige årsaker:" - echo " - gemini-2.0-flash: kjør 'gcloud run services update ...' med ORCHESTRATOR_MODEL=gemini-2.0-flash-001" - echo " - 403: ny revisjon ikke deployet ennå — vent 2 min og prøv igjen" - fi -fi - -echo "" -echo "╔══════════════════════════════════════════════════╗" -echo "║ Bootstrap ferdig! ║" -echo "║ Husk: bash infrastructure/03-teardown.sh ║" -echo "║ ...hver kveld for å unngå 24/7-fakturering ║" -echo "╚══════════════════════════════════════════════════╝" -echo "" diff --git a/scripts/archived/osv-startup.ps1 b/scripts/archived/osv-startup.ps1 deleted file mode 100644 index c8d2280..0000000 --- a/scripts/archived/osv-startup.ps1 +++ /dev/null @@ -1,148 +0,0 @@ -# OSVauco · OPAX — VS Code Windows Startup - -$REPO = "G:\Shared drives\OS-VAUCO-DRIVE\OSVauco" -$PING = "https://opax.vauco.no/ping" -$LOG = "$REPO\docs\OSVAUCO_OPAX_SESSION_LOG.md" -$W = 54 - -[Console]::OutputEncoding = [System.Text.Encoding]::UTF8 -Set-Location $REPO -Clear-Host - -# ---- GCLOUD PATH DETECTION ----------------------------------- -$gcloudCmd = $null -$gcloudPaths = @( - "gcloud", - "$env:LOCALAPPDATA\Google\Cloud SDK\google-cloud-sdk\bin\gcloud.cmd", - "$env:PROGRAMFILES\Google\Cloud SDK\google-cloud-sdk\bin\gcloud.cmd", - "$env:USERPROFILE\AppData\Local\Google\Cloud SDK\google-cloud-sdk\bin\gcloud.cmd" -) -foreach ($p in $gcloudPaths) { - try { $null = & $p version 2>$null; if ($LASTEXITCODE -eq 0 -or $?) { $gcloudCmd = $p; break } } catch {} -} - -# ---- SJEKKER ------------------------------------------------- -$gcOK = $false; $adcOK = $false; $opaxOK = $false; $gitOK = $false -$gcAcc = ""; $gcNotInstalled = ($null -eq $gcloudCmd) - -$gitOut = git pull 2>&1; $gitOK = ($LASTEXITCODE -eq 0) - -if (-not $gcNotInstalled) { - try { - $gcAcc = & $gcloudCmd auth list --filter=status:ACTIVE --format="value(account)" 2>$null - if ($gcAcc) { - $gcOK = $true - & $gcloudCmd config set project propane-will-491900-m5 2>$null | Out-Null - & $gcloudCmd config set compute/region us-central1 2>$null | Out-Null - } - } catch {} - try { $t = & $gcloudCmd auth application-default print-access-token 2>$null; if ($t) { $adcOK = $true } } catch {} -} - -try { if ((Invoke-RestMethod -Uri $PING -TimeoutSec 5).status -eq 'ok') { $opaxOK = $true } } catch {} - -$allOK = $gitOK -and $opaxOK -and $gcOK -$PU = 'Magenta'; $GR = 'Green'; $DG = 'DarkGreen' - -# ---- STATUS STRENGER ----------------------------------------- -$gitTxt = if ($gitOK) { if ($gitOut -match 'Already') { "✅ Git : up to date" } else { "✅ Git : oppdatert" } } else { "❌ Git : FEIL" } -$gcTxt = if ($gcNotInstalled) { "ℹ GCP : ikke funnet — bruk Cloud Shell" } - elseif ($gcOK) { "✅ GCP : " + ($gcAcc -replace '@vauco.no','') } - else { "⚠ GCP : gcloud auth login" } -$adcTxt = if ($gcNotInstalled) { "ℹ ADC : ikke tilgjengelig" } - elseif ($adcOK) { "✅ ADC : OK" } - else { "⚠ ADC : gcloud auth application-default login" } -$opaxTxt = if ($opaxOK) { "✅ OPAX : opax.vauco.no" } else { "❌ OPAX : nede — sjekk Cloud Run" } - -# ---- HJELPEFUNKSJONER ---------------------------------------- -function Pad($text, $width) { - if ($text.Length -gt $width) { return $text.Substring(0, $width - 1) + "…" } - return $text + (" " * ($width - $text.Length)) -} - -function GlowBox($lines) { - $seg = [math]::Floor($W / 3); $r = $W - $seg * 2 - Write-Host " " -NoNewline - Write-Host ("█" * $seg) -NoNewline -ForegroundColor $PU - Write-Host ("█" * $seg) -NoNewline -ForegroundColor $DG - Write-Host ("█" * $r) -ForegroundColor $GR - foreach ($line in $lines) { - $inner = Pad $line ($W - 4) - Write-Host " " -NoNewline - Write-Host "█" -NoNewline -ForegroundColor $PU - Write-Host (" $inner ") -NoNewline -ForegroundColor $GR - Write-Host "█" -ForegroundColor $GR - } - Write-Host " " -NoNewline - Write-Host ("█" * $r) -NoNewline -ForegroundColor $GR - Write-Host ("█" * $seg) -NoNewline -ForegroundColor $DG - Write-Host ("█" * $seg) -ForegroundColor $PU -} - -function DocBox($line) { - $hash = ""; $date = ""; $msg = $line - if ($line -match '^([0-9a-f]{7}) (\d{4}-\d{2}-\d{2}) (.+)$') { - $hash = $matches[1]; $date = $matches[2]; $msg = $matches[3] - } - Write-Host " " -NoNewline; Write-Host "┌─ " -NoNewline -ForegroundColor $PU - Write-Host $hash -NoNewline -ForegroundColor $GR; Write-Host " $date" -ForegroundColor $DG - Write-Host " " -NoNewline; Write-Host "│ " -NoNewline -ForegroundColor $PU - Write-Host (Pad $msg ($W - 4)) -ForegroundColor $GR - Write-Host " " -NoNewline; Write-Host "└" -NoNewline -ForegroundColor $PU - Write-Host ("─" * ($W - 2)) -ForegroundColor $PU -} - -function NesteBox($text) { - Write-Host " " -NoNewline; Write-Host "┌" -NoNewline -ForegroundColor $PU - Write-Host ("─" * ($W - 2)) -ForegroundColor $PU - Write-Host " " -NoNewline; Write-Host "│ " -NoNewline -ForegroundColor $PU - Write-Host (Pad $text ($W - 4)) -ForegroundColor $GR - Write-Host " " -NoNewline; Write-Host "└" -NoNewline -ForegroundColor $PU - Write-Host ("─" * ($W - 2)) -ForegroundColor $PU -} - -function StatusLine($text) { - $col = if ($text -match "^✅") { $GR } elseif ($text -match "^❌") { 'Red' } else { $PU } - Write-Host " " -NoNewline; Write-Host "▒ " -NoNewline -ForegroundColor $col - Write-Host $text -ForegroundColor $col -} - -# ============================================================== -Write-Host "" -GlowBox @("", " O S V A U C O · O P A X", " us-central1 · gemini-2.5-pro", " $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')", "") -Write-Host "" - -Write-Host " ■ NESTE OPPGAVE" -ForegroundColor $PU -$nesteLines = @("Sjekk docs/VAUCO_OS_ROADMAP.md") -if (Test-Path $LOG) { - $m = [regex]::Match((Get-Content $LOG -Raw -Encoding UTF8), '(?s)## NESTE OPPGAVE\r?\n(.*?)(?=\r?\n## |$)') - if ($m.Success) { - $nesteLines = $m.Groups[1].Value.Trim() -split "`n" | - Where-Object { $_.Trim() -and $_.Trim() -ne '---' } | - Select-Object -First 3 | ForEach-Object { $_.Trim() } - } -} -foreach ($nl in $nesteLines) { NesteBox $nl } -Write-Host "" - -Write-Host " ■ SISTE DOCS" -ForegroundColor $PU -$docLines = git -C $REPO log -3 --pretty=format:"%h %cd %s" --date=short -- docs 2>&1 | - ForEach-Object { ($_ -replace '[^\x00-\x7F\u00e6\u00f8\u00e5\u00c6\u00d8\u00c5\u2014\u2013]+', '').Trim() } | Where-Object { $_ } -foreach ($dl in $docLines) { DocBox $dl } -Write-Host "" - -Write-Host " ■ STATUS" -ForegroundColor $PU -StatusLine $gitTxt; StatusLine $gcTxt; StatusLine $adcTxt; StatusLine $opaxTxt -Write-Host "" - -# ============================================================== -# CUSTOM PROMPT — ANSI direkte via [System.Console]::Write -# ============================================================== -function prompt { - # Lilla: \e[35m Hvit: \e[97m Bold bright green: \e[1;92m Reset: \e[0m - [System.Console]::Write("`e[35m G:\Shared-drives\`e[0m") - [System.Console]::Write("`e[97mOS`e[0m") - [System.Console]::Write("`e[1;92mVauco`e[0m") - [System.Console]::Write("`e[1;92m ❯`e[0m") - return " " -} diff --git a/scripts/archived/osvauco-opax-boot.sh b/scripts/archived/osvauco-opax-boot.sh deleted file mode 100755 index 882d20d..0000000 --- a/scripts/archived/osvauco-opax-boot.sh +++ /dev/null @@ -1,184 +0,0 @@ -#!/usr/bin/env bash -# ============================================================================= -# osvauco-opax-boot.sh — OSVauco OPAX session-starter -# Bruk: source ~/OSVauco/scripts/osvauco-opax-boot.sh -# NB: Må sources (ikke bash) for PROMPT_COMMAND + opax_logg_slutt. -# Standalone avslutt: bash ~/OSVauco/scripts/opax-logg-slutt.sh -# ============================================================================= - -OSVAUCO_DIR="$HOME/OSVauco" -ROADMAP="$OSVAUCO_DIR/docs/VAUCO_OS_ROADMAP.md" -TODO="$OSVAUCO_DIR/docs/TODO.md" -SESSION_LOG="$OSVAUCO_DIR/docs/OSVAUCO_OPAX_SESSION_LOG.md" -STATE_FILE="$OSVAUCO_DIR/.gdrive-mirror-state" -BASHRC="$HOME/.bashrc" - -GREEN="$(tput setaf 2 || true)" -RED="$(tput setaf 1 || true)" -YELLOW="$(tput setaf 3 || true)" -CYAN="$(tput setaf 6 || true)" -BOLD="$(tput bold || true)" -DIM="\033[2m" -NC="$(tput sgr0 || true)" - -OK="${GREEN}[OK]${NC}" -WARN="${YELLOW}[!!]${NC}" -FAIL="${RED}[XX]${NC}" - -SESSION_ID="$(date '+%Y%m%d-%H%M%S')" - -# ============================================================================= -# AUTO-AUTH RENEWAL -# ============================================================================= -ADC_SCOPE_FILE="$HOME/.config/gcloud/.osvauco-adc-renewed" - -printf "${BOLD}${CYAN} [ AUTH ]${NC}\n" -if ! gcloud auth print-access-token >/dev/null 2>&1; then - printf " ${YELLOW}⚠ gcloud auth utløpt — logger inn...${NC}\n" - gcloud auth login --no-launch-browser -else - printf " ${DIM}✦ gcloud auth OK${NC}\n" -fi - -# ADC sjekk med 8t cache -NEED_ADC_LOGIN=0 -if ! gcloud auth application-default print-access-token >/dev/null 2>&1; then - NEED_ADC_LOGIN=1 -elif [[ -f "$ADC_SCOPE_FILE" ]]; then - # Sjekk om filen er eldre enn 8 timer (28800 sekunder) - if [[ $(($(date +%s) - $(stat -c %Y "$ADC_SCOPE_FILE"))) -gt 28800 ]]; then - NEED_ADC_LOGIN=1 - fi -else - NEED_ADC_LOGIN=1 -fi - -if [[ $NEED_ADC_LOGIN -eq 1 ]]; then - printf " ${YELLOW}⚠ ADC utløpt eller gammel — fornyer...${NC}\n" - gcloud auth application-default login --scopes="https://www.googleapis.com/auth/cloud-platform" - touch "$ADC_SCOPE_FILE" -else - printf " ${DIM}✦ ADC OK${NC}\n" -fi -printf " ${GREEN}✦ Auth klar${NC}\n\n" - -clear - -# ============================================================================= -# COMPACT BOOT UI -# ============================================================================= -printf "${CYAN}OSVauco · OPAX ❱ %s · %s${NC}\n" "$SESSION_ID" "${PROJECT_ID:-propane-will-491900-m5}" -printf "${DIM}────────────────────────────────────────────────────────────${NC}\n" - -# 1. SERVICES -printf "${BOLD}SERVICES${NC}\n" -# Helper: check_service -check_service() { - printf " %-12s " "$1" - if eval "$2" >/dev/null 2>&1; then printf "${GREEN}✦ OK${NC}\n"; else printf "${RED}✗ FAIL${NC}\n"; fi -} -# Vertex, Cloud Run, GH, Git -check_service "Vertex AI" "curl -s -f -H \"Authorization: Bearer $(gcloud auth application-default print-access-token)\" \"https://us-central1-aiplatform.googleapis.com/v1/projects/propane-will-491900-m5/locations/us-central1/models\"" -check_service "Cloud Run" "curl -s -f -H \"Authorization: Bearer $(gcloud auth print-identity-token)\" https://opax.vauco.no/health" -check_service "GitHub" "gh auth status" -check_service "Git Remote" "git -C $OSVAUCO_DIR ls-remote origin refs/heads/main" - -printf "${DIM}────────────────────────────────────────────────────────────${NC}\n" - -# 2. SYSTEM -printf "${BOLD}SYSTEM${NC}\n" -LOAD=$(cat /proc/loadavg | awk '{print $1}') -MEM=$(free -h | grep Mem | awk '{printf "%s/%s", $3, $2}') -DISK=$(df -h / | tail -1 | awk '{print $5}') -printf " %-12s %s · %s · %s\n" "Resources" "Load: $LOAD" "RAM: $MEM" "/: $DISK" -printf " %-12s %s\n" "Uptime" "$(uptime -p | sed 's/up //')" - -printf "${DIM}────────────────────────────────────────────────────────────${NC}\n" - -# 3. NESTE -printf "${BOLD}NEXT${NC}\n" -NEXT_ROADMAP=$(awk '/^## NEXT/{f=1;next} f && /^## /{f=0} f && /^- \[ \]/{print;exit}' "$ROADMAP") -printf " ${GREEN}▶ %s${NC}\n" "${NEXT_ROADMAP:-Ingen oppgave}" - -printf "${DIM}────────────────────────────────────────────────────────────${NC}\n" -printf "── ready ── SESSION %s ──────────────────\n\n" "$SESSION_ID" - -# ============================================================================= -# Load nvm -# ============================================================================= -export NVM_DIR="$HOME/.nvm" -[[ -s "$NVM_DIR/nvm.sh" ]] && source "$NVM_DIR/nvm.sh" -if ! command -v gemini &>/dev/null && [[ -d "$NVM_DIR" ]]; then - NVM_DEFAULT=$(nvm version default 2>/dev/null || true) - [[ -n "$NVM_DEFAULT" ]] && nvm use "$NVM_DEFAULT" &>/dev/null || true -fi - -# ============================================================================= -# AVSLUTT-FUNKSJON -# ============================================================================= -sol() { - PROMPT_COMMAND="${PROMPT_COMMAND//_opax_log_cmd; /}" - PROMPT_COMMAND="${PROMPT_COMMAND//_opax_log_cmd/}" - printf "\n ${BOLD}${CYAN}Sesjonslogg — avslutt${NC}\n" - printf " Hva ble gjort? (LØST / ULØST)\n > " - read -r DONE_DESC - [[ -z "$DONE_DESC" ]] && DONE_DESC="(ingen notat)" - printf " Uløste problemer? (Enter for ingen)\n > " - read -r UNSOLVED - [[ -z "$UNSOLVED" ]] && UNSOLVED="ingen" - cat >> "$SESSION_LOG" << EOF - -### Sesjonsavslutning -- Gjort : $DONE_DESC -- Uløst : $UNSOLVED -- Slutt : $(date '+%Y-%m-%d %H:%M %Z') -EOF - printf " ${GREEN}[OK]${NC} Logg oppdatert → docs/OSVAUCO_OPAX_SESSION_LOG.md\n\n" - cd "$OSVAUCO_DIR" - git add docs/OSVAUCO_OPAX_SESSION_LOG.md 2>/dev/null || true - if ! git diff --cached --quiet; then - git commit -m "chore(session): logg sesjon $SESSION_ID — $DONE_DESC" - git push origin main - printf " ${GREEN}[OK]${NC} Sesjonslogg pushet → GitHub\n\n" - else - printf " ${DIM}[--]${NC} Ingen ny logg å pushe\n\n" - fi -} -export -f sol 2>/dev/null || true -alias sol='sol' -alias opax-logg-slutt='sol' - - -# ============================================================================= -# VALGFRI GEMINI-START -# ============================================================================= -read -r -p " Starte Gemini-CLI nå? [y/N]: " ANSWER -case "$ANSWER" in - y|Y) - echo - if ! command -v gemini &>/dev/null; then - printf " ${RED}[XX]${NC} gemini ikke funnet.\n" - else - echo " [OSVauco] Starter Gemini-CLI fra ~/OSVauco..." - cd "$OSVAUCO_DIR" - gemini - fi - ;; - *) - echo - echo " [OSVauco] OK — kjør 'gemini' når du vil. God session! 🚀" - ;; -esac - -# ============================================================================= -# QUICK COMMANDS -# ============================================================================= -printf "${BOLD}QUICK COMMANDS${NC}\n" -printf " %-4s %-12s %-4s %-12s\n" "ca" "cost-audit" "cl" "cost-lens" -printf " %-4s %-12s %-4s %-12s\n" "cg" "cost-guard" "hc" "health-check" -printf " %-4s %-12s %-4s %-12s\n" "pf" "preflight" "st" "smoke-test" -printf " %-4s %-12s %-4s %-12s\n" "rl" "roadmap" "sl" "session-log" -printf " %-4s %-12s %-4s %-12s\n" "ms" "mirror-sync" "g" "gemini" -printf " %-4s %-12s %-4s %-12s\n" "l" "ls -la" "ll" "ls -lh" -printf " %-4s %-12s %-4s %-12s\n" "sol" "avslutt" "" "" -printf "\n" diff --git a/scripts/archived/osvauco-startup.sh b/scripts/archived/osvauco-startup.sh deleted file mode 100755 index 19888e9..0000000 --- a/scripts/archived/osvauco-startup.sh +++ /dev/null @@ -1,95 +0,0 @@ -#!/usr/bin/env bash -# OSVauco startup — auth + Gemini bootstrap for OPAX-MCP work - -set -euo pipefail - -GREEN="$(tput setaf 2 || true)" -RED="$(tput setaf 1 || true)" -YELLOW="$(tput setaf 3 || true)" -RESET="$(tput sgr0 || true)" - -clear - -# Guard: stopp hvis gcloud auth er utløpt -if ! gcloud auth print-access-token >/dev/null 2>&1; then - echo "${RED}⚠️ gcloud auth utløpt — kjør: gcloud auth login --no-launch-browser${RESET}" - exit 1 -fi - -cat << 'BANNER' -============================================================ - O S V A U C O -============================================================ -D E V H U B - -Prosjekt: propane-will-491900-m5 · Region: us-central1 -============================================================ - -BANNER - -echo -echo "=== OSVauco Auth Setup ===" -echo - -# Lås til riktig prosjekt og region -gcloud config set project propane-will-491900-m5 >/dev/null 2>&1 || true -gcloud config set compute/region us-central1 >/dev/null 2>&1 || true - -PROJECT=$(gcloud config get-value project 2>/dev/null) -REGION=$(gcloud config get-value compute/region 2>/dev/null) -ACCOUNT=$(gcloud auth list --filter=status:ACTIVE --format="value(account)" 2>/dev/null) - -echo " Project : ${PROJECT}" -echo " Region : ${REGION}" -echo " Account : ${ACCOUNT}" - -# Sjekk ADC (Application Default Credentials) -ADC_OK=0 -if gcloud auth application-default print-access-token >/dev/null 2>&1; then - ADC_OK=1 -fi - -echo -if [ "$ADC_OK" -eq 1 ]; then - echo " ADC : ${GREEN}OK${RESET}" -else - echo " ADC : ${YELLOW}MISSES TOKEN${RESET} (kjør: gcloud auth application-default login)" -fi - -# Sync til .env i prosjektet -ENV_FILE="$HOME/OSVauco/.env" -mkdir -p "$(dirname "$ENV_FILE")" -touch "$ENV_FILE" -grep -q '^GOOGLE_CLOUD_PROJECT=' "$ENV_FILE" || echo "GOOGLE_CLOUD_PROJECT=${PROJECT}" >> "$ENV_FILE" -grep -q '^GOOGLE_CLOUD_LOCATION=' "$ENV_FILE" || echo "GOOGLE_CLOUD_LOCATION=${REGION}" >> "$ENV_FILE" - -echo " .env : ${GREEN}oppdatert${RESET}" -echo - -echo "=== Auth status ===" -echo " Project : ${PROJECT}" -echo " Region : ${REGION}" -echo " Account : ${ACCOUNT}" -if [ "$ADC_OK" -eq 1 ]; then - echo " Status : ${GREEN}GRØNN${RESET} (gcloud + ADC på plass)" -else - echo " Status : ${YELLOW}GUL${RESET} (gcloud OK, men ADC mangler)" -fi -echo - -read -r -p "[OSVauco] Starte Gemini-CLI nå med oppstartsrapport? (y/N): " ANSWER -case "$ANSWER" in - y|Y) - echo - echo "[OSVauco] Starter Gemini-CLI fra ~/OSVauco ..." - echo "[OSVauco] Første melding som sendes inn er @.gemini/GEMINI.md" - echo - cd "$HOME/OSVauco" - ( printf '@.gemini/GEMINI.md -'; cat ) | gemini - ;; - *) - echo - echo "[OSVauco] OK, holder deg i vanlig shell. Kjør 'gemini' når du vil inn i TUI." - ;; -esac diff --git a/scripts/archived/preflight-check.sh b/scripts/archived/preflight-check.sh deleted file mode 100755 index 145b2a3..0000000 --- a/scripts/archived/preflight-check.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env bash -# preflight-check.sh — Verifies the local development environment for OSVauco OPAX. - -set -euo pipefail - -# --- Configuration & Helpers --- -ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/.." -FAIL_COUNT=0 - -step_info() { echo "[INFO] $1"; } -step_ok() { echo " ✅ $1"; } -step_fail() { - echo " ❌ $1" - FAIL_COUNT=$((FAIL_COUNT + 1)) -} - -# --- Preflight Checks --- - -echo "==================================================================" -echo "=> Running OSVauco Preflight Checks" -echo "==================================================================" - -# Check 1: gcloud authentication and project config -step_info "Checking GCP authentication..." -if bash "$ROOT_DIR/infrastructure/00-authcheck.sh" &>/dev/null; then - step_ok "gcloud is authenticated and project is set." -else - step_fail "gcloud authentication or project is not configured. Run 'gcloud auth login' and 'gcloud config set project '." -fi - -# Check 2: .env file existence -step_info "Checking for .env file..." -if [ -f "$ROOT_DIR/.env" ]; then - step_ok ".env file found." - # Source it for the next check - source "$ROOT_DIR/.env" -else - step_fail ".env file not found. Please copy .env.example to .env and fill in the required values." -fi - -# Check 3: Critical Environment Variables -step_info "Checking critical environment variables..." -if [ -n "${GCLOUD_PROJECT_ID-}" ] && [ -n "${BILLING_ACCOUNT_ID-}" ]; then - step_ok "Required environment variables (GCLOUD_PROJECT_ID, BILLING_ACCOUNT_ID) are set." -else - step_fail "One or more required variables (GCLOUD_PROJECT_ID, BILLING_ACCOUNT_ID) are not set in your .env file." -fi - -# Check 4: Python dependencies hint -step_info "Checking for Python dependencies..." -if [ -f "$ROOT_DIR/requirements.txt" ]; then - step_ok "requirements.txt found. Ensure dependencies are installed with 'pip install -r requirements.txt'." -else - step_fail "requirements.txt not found." -fi - -# Check 5: Git working directory status -step_info "Checking Git status..." -if git -C "$ROOT_DIR" diff --quiet && git -C "$ROOT_DIR" diff --cached --quiet; then - step_ok "Git working directory is clean." -else - step_fail "Git working directory has uncommitted changes. Please commit or stash them." -fi - -# --- Summary --- -echo "==================================================================" -if [ $FAIL_COUNT -eq 0 ]; then - echo "✅✅✅ Preflight checks passed successfully! ✅✅✅" - exit 0 -else - echo "❌❌❌ Preflight checks failed with $FAIL_COUNT error(s). Please resolve them and re-run. ❌❌❌" - exit 1 -fi diff --git a/scripts/archived/preflight.sh b/scripts/archived/preflight.sh deleted file mode 100755 index a3b6085..0000000 --- a/scripts/archived/preflight.sh +++ /dev/null @@ -1,161 +0,0 @@ -#!/usr/bin/env bash -# ============================================================================= -# preflight.sh — OSVauco Operator Preflight Dashboard -# Provides immediate situational awareness of the OPAX ecosystem on GCP. -# Usage: bash scripts/preflight.sh -# ============================================================================= - -set -uo pipefail - -# Colors -GREEN='\033[0;32m' -RED='\033[0;31m' -YELLOW='\033[1;33m' -CYAN='\033[0;36m' -DIM='\033[2m' -BOLD='\033[1m' -NC='\033[0m' - -# Icons -OK="${GREEN}\u2713${NC}" -WARN="${YELLOW}\u26a0\ufe0f${NC}" -FAIL="${RED}\u2718${NC}" -INFO="${CYAN}\u2139${NC}" - -# 1. Context Discovery -PROJECT_ID=$(gcloud config get-value project 2>/dev/null | tr -d '\r' || echo "NOT_SET") -ACCOUNT=$(gcloud config get-value account 2>/dev/null | tr -d '\r' || echo "NOT_SET") -# Region fallback if not set in environment -REGION="${RAG_LOCATION:-${REGION:-us-central1}}" -REGION=$(echo "$REGION" | tr -d '\r') - -clear -echo -e "${CYAN}${BOLD}==========================================================${NC}" -echo -e "${CYAN}${BOLD} OSVauco OPAX PREFLIGHT DASHBOARD${NC}" -echo -e "${CYAN}${BOLD}==========================================================${NC}" -echo -e "${DIM}Time : $(date '+%Y-%m-%d %H:%M %Z')${NC}" -echo -e "${DIM}Project : ${PROJECT_ID}${NC}" -echo -e "${DIM}Identity: ${ACCOUNT}${NC}" -echo -e "${CYAN}${BOLD}----------------------------------------------------------${NC}" - -# --- 1. Infrastructure Status (Cloud Run) --- -echo -e "${BOLD}[1] Infrastructure (Cloud Run)${NC}" -SERVICE_NAME="opax-mcp-core" -# Check if service exists and its state -SERVICE_DATA=$(gcloud run services describe "${SERVICE_NAME}" --region="${REGION}" --project="${PROJECT_ID}" --format="value(status.conditions[0].status,status.url)" 2>/dev/null | tr -d '\r' || echo "NOT_FOUND -") -SERVICE_STATUS=$(echo "$SERVICE_DATA" | awk '{print $1}') -SERVICE_URL=$(echo "$SERVICE_DATA" | awk '{print $2}') - -if [ "$SERVICE_STATUS" = "True" ]; then - echo -e " ${OK} ${SERVICE_NAME}: ${GREEN}ACTIVE${NC}" - echo -e " ${DIM}URL: ${SERVICE_URL}${NC}" -elif [ "$SERVICE_STATUS" = "NOT_FOUND" ]; then - echo -e " ${FAIL} ${SERVICE_NAME}: ${RED}NOT DEPLOYED${NC}" - echo -e " ${DIM}Action: bash infrastructure/05-cloudrun-deploy.sh${NC}" -else - echo -e " ${WARN} ${SERVICE_NAME}: ${YELLOW}INACTIVE / UNHEALTHY${NC} (Status: ${SERVICE_STATUS})" - echo -e " ${DIM}Check console for deployment errors${NC}" -fi -echo "" - -# --- 2. Knowledge Base Status (RAG Engine) --- -echo -e "${BOLD}[2] Knowledge Base (RAG Engine)${NC}" -CORPUS_DISPLAY_NAME="osvauco-knowledge-base" - -# Note: gcloud ai rag-corpora might not be available in all SDK versions. -if gcloud ai rag-corpora --help &>/dev/null; then - RAG_DATA=$(gcloud ai rag-corpora list --project="${PROJECT_ID}" --format="value(name,location)" 2>/dev/null | tr -d '\r' | grep "${CORPUS_DISPLAY_NAME}" || true) - if [ -n "$RAG_DATA" ]; then - FULL_NAME=$(echo "$RAG_DATA" | awk '{print $1}') - RAG_LOC=$(echo "$RAG_DATA" | awk '{print $2}') - # Get count of files - FILE_COUNT=$(gcloud ai rag-files list --corpus="${FULL_NAME}" --project="${PROJECT_ID}" --location="${RAG_LOC}" --format="value(name)" 2>/dev/null | wc -l | tr -dc '0-9') - FILE_COUNT=${FILE_COUNT:-0} - echo -e " ${OK} Corpus: ${GREEN}FOUND${NC} in ${RAG_LOC}" - echo -e " ${DIM}Files: ${FILE_COUNT} documents indexed${NC}" - else - echo -e " ${WARN} Corpus: ${YELLOW}NOT FOUND${NC}" - echo -e " ${DIM}Action: python3 agents/rag/setup_corpus.py${NC}" - fi -else - # Fallback: Try a lightweight python check - echo -e " ${INFO} Corpus check: ${DIM}gcloud ai rag commands missing. Checking via SDK...${NC}" - RAG_CHECK=$(python3 -c " -import os -try: - from vertexai import rag - import vertexai - vertexai.init(project='${PROJECT_ID}') - # Check common regions - for loc in ['${REGION}', 'europe-west4']: - vertexai.init(project='${PROJECT_ID}', location=loc) - for c in rag.list_corpora(): - if c.display_name == '${CORPUS_DISPLAY_NAME}': - print(f'FOUND|{loc}|{c.name}') - exit(0) - print('MISSING') -except Exception: - print('ERROR') -" 2>/dev/null | tr -d '\r' || echo "ERROR") - - if [[ "$RAG_CHECK" == FOUND* ]]; then - LOC=$(echo "$RAG_CHECK" | cut -d'|' -f2) - echo -e " ${OK} Corpus: ${GREEN}FOUND${NC} in ${LOC}" - elif [ "$RAG_CHECK" = "MISSING" ]; then - echo -e " ${WARN} Corpus: ${YELLOW}NOT FOUND${NC}" - echo -e " ${DIM}Action: python3 agents/rag/setup_corpus.py${NC}" - else - echo -e " ${WARN} Corpus: ${DIM}Unable to verify (Vertex AI SDK issues)${NC}" - fi -fi -echo "" - -# --- 3. Resource & Cost Risk Audit --- -echo -e "${BOLD}[3] Resource & Cost Risk Audit${NC}" -# Resources that incur cost even when idle -VM_COUNT=$(gcloud compute instances list --project="${PROJECT_ID}" --filter="status=RUNNING" --format="value(name)" 2>/dev/null | wc -l | tr -dc '0-9') -SQL_COUNT=$(gcloud sql instances list --project="${PROJECT_ID}" --filter="state=RUNNABLE" --format="value(name)" 2>/dev/null | wc -l | tr -dc '0-9') -# Reasoning Engines (Memory Bank) are common cost leaks -RB_COUNT=$(gcloud ai reasoning-engines list --project="${PROJECT_ID}" --format="value(name)" 2>/dev/null | wc -l | tr -dc '0-9') - -# Initialize defaults -VM_COUNT=${VM_COUNT:-0} -SQL_COUNT=${SQL_COUNT:-0} -RB_COUNT=${RB_COUNT:-0} - -if [ "$VM_COUNT" -eq 0 ] && [ "$SQL_COUNT" -eq 0 ] && [ "$RB_COUNT" -eq 0 ]; then - echo -e " ${OK} No expensive idle resources detected." -else - if [ "$VM_COUNT" -gt 0 ]; then - echo -e " ${RED}${FAIL} Running VMs: ${VM_COUNT}${NC} (Always-on cost!)" - fi - if [ "$SQL_COUNT" -gt 0 ]; then - echo -e " ${RED}${FAIL} Running SQL: ${SQL_COUNT}${NC} (Always-on cost!)" - fi - if [ "$RB_COUNT" -gt 0 ]; then - echo -e " ${RED}${FAIL} Memory Bank: ${RB_COUNT}${NC} (Idle cost!)" - fi - echo -e " ${DIM}Tip: Run bash infrastructure/03-teardown.sh at end of day.${NC}" -fi -echo "" - -# --- 4. Security & Integrations --- -echo -e "${BOLD}[4] Security & Secrets${NC}" -SECRETS=("github-token" "webhook-url" "rag-corpus-name") -for s in "${SECRETS[@]}"; do - if gcloud secrets describe "$s" --project="${PROJECT_ID}" &>/dev/null; then - echo -e " ${OK} Secret: ${GREEN}${s}${NC}" - else - if [ "$s" = "rag-corpus-name" ]; then - echo -e " ${INFO} Secret: ${DIM}${s}${NC} (Auto-populated by setup_corpus.py)" - else - echo -e " ${WARN} Secret: ${YELLOW}${s}${NC} (MISSING)" - echo -e " ${DIM}Action: gcloud secrets create ${s} --data-file=...${NC}" - fi - fi -done -echo "" - -echo -e "${CYAN}${BOLD}==========================================================${NC}" -echo -e " ${BOLD}Next Step:${NC} Run ${DIM}bash scripts/osvauco-opax-boot.sh${NC} to start OPAX." -echo -e "${CYAN}${BOLD}==========================================================${NC}" diff --git a/scripts/boot.sh b/scripts/boot.sh new file mode 100755 index 0000000..a1c099d --- /dev/null +++ b/scripts/boot.sh @@ -0,0 +1,271 @@ +#!/usr/bin/env bash +# ============================================================================= +# boot.sh — OSVauco daily VM session-starter +# +# Bruk: source ~/OSVauco/scripts/boot.sh +# Eller legg i ~/.bashrc: +# [[ $- == *i* && -z "$OSVAUCO_BOOTED" ]] && source ~/OSVauco/scripts/boot.sh +# ============================================================================= + +export OSVAUCO_BOOTED=1 +OSVAUCO_DIR="${OSVAUCO_DIR:-$HOME/OSVauco}" +HANDOFF="$OSVAUCO_DIR/docs/HANDOFF.md" +ROADMAP="$OSVAUCO_DIR/docs/ROADMAP.md" +MASTERPLAN="$OSVAUCO_DIR/docs/MASTERPLAN.md" +RULEBOOK="$OSVAUCO_DIR/docs/AGENT_RULEBOOK.md" +SESSION_LOG="$OSVAUCO_DIR/docs/OSVAUCO_OPAX_SESSION_LOG.md" + +# Locked values (matcher docs/AGENT_RULEBOOK.md) +export GOOGLE_CLOUD_PROJECT="propane-will-491900-m5" +export GOOGLE_CLOUD_LOCATION="europe-west1" +export VERTEX_AI_LOCATION="europe-west1" +export OSVAUCO_SERVICE="osvauco-agent" +DIRECT_URL="https://osvauco-agent-357036551735.europe-west1.run.app" +DOMAIN_URL="https://opax.vauco.no" + +GREEN="$(tput setaf 2 2>/dev/null || true)" +RED="$(tput setaf 1 2>/dev/null || true)" +YELLOW="$(tput setaf 3 2>/dev/null || true)" +CYAN="$(tput setaf 6 2>/dev/null || true)" +MAGENTA="$(tput setaf 5 2>/dev/null || true)" +WHITE="$(tput setaf 7 2>/dev/null || true)" +BOLD="$(tput bold 2>/dev/null || true)" +DIM="$(tput dim 2>/dev/null || true)" +NC="$(tput sgr0 2>/dev/null || true)" + +SESSION_ID="$(date '+%Y%m%d-%H%M%S')" +export OSVAUCO_SESSION_ID="$SESSION_ID" +export OSVAUCO_SESSION_START="$(date '+%Y-%m-%d %H:%M %Z')" + +ok() { printf " ${GREEN}✦${NC} %s\n" "$1"; } +warn() { printf " ${YELLOW}⚠${NC} %s\n" "$1"; } +fail() { printf " ${RED}✗${NC} %s\n" "$1"; } + +# ============================================================================= +# HEADER — OS VAUCO +# ============================================================================= +clear +printf "${CYAN}${BOLD}" +cat << 'LOGO' + ___ ____ __ __ _ _ _ ____ ___ + / _ \/ ___| \ \ / /_ _| | | | | |/ ___|/ _ \ + | | | \___ \ \ \ / / _` | | | | | | | | | | | + | |_| |___) | \ V / (_| | |__| |_| | |___| |_| | + \___/|____/ \_/ \__,_|____|\___/ \____|\___/ +LOGO +printf "${NC}${DIM} Vauco OS · Operasjonsplatform · %s${NC}\n" "$(date '+%Y-%m-%d %H:%M')" +printf "${DIM} ──────────────────────────────────────────────────────${NC}\n\n" + +# ============================================================================= +# 1. AUTH +# ============================================================================= +printf "${BOLD}${CYAN}[ AUTH ]${NC}\n" +if ! gcloud auth print-access-token >/dev/null 2>&1; then + warn "gcloud auth utløpt — kjører login (no-browser)..." + gcloud auth login --no-launch-browser +else + ACCT=$(gcloud auth list --filter=status:ACTIVE --format='value(account)' 2>/dev/null | head -1) + ok "gcloud auth ($ACCT)" +fi + +ADC_FILE="$HOME/.config/gcloud/.osvauco-adc-renewed" +NEED_ADC=0 +if ! gcloud auth application-default print-access-token >/dev/null 2>&1; then + NEED_ADC=1 +elif [[ ! -f "$ADC_FILE" ]] || [[ $(($(date +%s) - $(stat -c %Y "$ADC_FILE" 2>/dev/null || echo 0))) -gt 28800 ]]; then + NEED_ADC=1 +fi +if [[ $NEED_ADC -eq 1 ]]; then + warn "ADC utløpt eller >8t — fornyer..." + gcloud auth application-default login --no-launch-browser \ + --scopes="https://www.googleapis.com/auth/cloud-platform" && touch "$ADC_FILE" +else + ok "ADC OK" +fi + +# ============================================================================= +# 2. PROJECT +# ============================================================================= +printf "${BOLD}${CYAN}[ PROJECT ]${NC}\n" +CURRENT_PROJ=$(gcloud config get-value project 2>/dev/null) +if [[ "$CURRENT_PROJ" != "$GOOGLE_CLOUD_PROJECT" ]]; then + gcloud config set project "$GOOGLE_CLOUD_PROJECT" >/dev/null 2>&1 + warn "Satt project → $GOOGLE_CLOUD_PROJECT" +else + ok "project = $GOOGLE_CLOUD_PROJECT" +fi +ok "region = $GOOGLE_CLOUD_LOCATION (Vertex EU)" + +# ============================================================================= +# 3. REPO + GITHUB STATUS +# ============================================================================= +printf "${BOLD}${CYAN}[ REPO + GITHUB ]${NC}\n" +if [[ -d "$OSVAUCO_DIR/.git" ]]; then + cd "$OSVAUCO_DIR" + BRANCH=$(git branch --show-current) + git fetch --quiet origin 2>/dev/null && ok "git fetch OK" || warn "git fetch feilet (offline?)" + + # Pull + if git pull --ff-only origin "$BRANCH" >/dev/null 2>&1; then + ok "git pull OK (branch: $BRANCH)" + else + warn "git pull ikke fast-forward — sjekk 'git status'" + fi + + # Ahead/behind + AHEAD=$(git rev-list --count "origin/$BRANCH..HEAD" 2>/dev/null || echo "?") + BEHIND=$(git rev-list --count "HEAD..origin/$BRANCH" 2>/dev/null || echo "?") + if [[ "$AHEAD" == "0" && "$BEHIND" == "0" ]]; then + ok "sync med origin/$BRANCH" + else + warn "ahead=$AHEAD behind=$BEHIND vs origin/$BRANCH" + fi + + # Uncommitted + DIRTY=$(git status --porcelain | wc -l) + if [[ "$DIRTY" == "0" ]]; then + ok "working tree clean" + else + warn "$DIRTY uncommitted endringer ('git status' for liste)" + fi + + # Last commit + LAST=$(git log -1 --format='%h %s (%cr)' 2>/dev/null) + printf " ${DIM}last:${NC} %s\n" "$LAST" + + # gh CLI auth + if command -v gh >/dev/null 2>&1; then + if gh auth status >/dev/null 2>&1; then + GH_USER=$(gh api user --jq '.login' 2>/dev/null || echo "?") + ok "gh CLI auth ($GH_USER)" + # Open PRs på denne branchen + OPEN_PR=$(gh pr list --head "$BRANCH" --json number,title --jq '.[0] | "PR #\(.number): \(.title)"' 2>/dev/null) + [[ -n "$OPEN_PR" ]] && printf " ${DIM}pr:${NC} %s\n" "$OPEN_PR" + else + warn "gh CLI ikke autentisert — kjør: gh auth login" + fi + else + warn "gh CLI ikke installert — installer: sudo apt install gh" + fi +else + fail "Repo ikke funnet på $OSVAUCO_DIR" +fi + +# ============================================================================= +# 4. LOCKED DEFS +# ============================================================================= +printf "${BOLD}${CYAN}[ LOCKED ]${NC}\n" +printf " ${DIM}service=${NC}%s ${DIM}lb=${NC}34.98.77.173\n" "$OSVAUCO_SERVICE" +printf " ${DIM}url=${NC}%s\n" "$DOMAIN_URL" +printf " ${DIM}direct=${NC}%s\n" "$DIRECT_URL" + +# ============================================================================= +# 5. NESTE OPPGAVE (matcher både "NESTE OPPGAVE" og "Neste oppgave") +# ============================================================================= +printf "${BOLD}${CYAN}[ NESTE OPPGAVE ]${NC}\n" +if [[ -f "$HANDOFF" ]]; then + NEXT=$(sed -n '/^##.*[Nn]este [Oo]ppgave/,/^## /p' "$HANDOFF" | sed '1d;$d' | sed '/^$/d' | head -12) + if [[ -n "$NEXT" ]]; then + printf "${GREEN}%s${NC}\n" "$NEXT" + else + warn "Ingen 'Neste oppgave'-seksjon funnet i HANDOFF.md" + fi +else + fail "HANDOFF.md mangler: $HANDOFF" +fi + +# ============================================================================= +# 6. ALIASER / HOTKEYS +# ============================================================================= +alias pf='source $OSVAUCO_DIR/scripts/preflight.sh' +alias hc='bash $OSVAUCO_DIR/scripts/health-check.sh' +alias st='bash $OSVAUCO_DIR/scripts/smoke-test.sh' +alias at='bash $OSVAUCO_DIR/scripts/acceptance-test.sh' +alias opax='source $OSVAUCO_DIR/scripts/opax.sh' +alias opax2='source $OSVAUCO_DIR/scripts/opax2.sh' +alias ca='bash $OSVAUCO_DIR/scripts/cost-audit.sh' +alias cl='bash $OSVAUCO_DIR/scripts/cost-lens.sh' +alias cg='bash $OSVAUCO_DIR/scripts/cost-guard.sh' +alias costs='bash $OSVAUCO_DIR/scripts/cost-lens.sh' +alias ms='bash $OSVAUCO_DIR/scripts/sync-gdrive-mirror.sh' +alias logg='bash $OSVAUCO_DIR/scripts/opax-logg-slutt.sh' +alias rl='${PAGER:-less} $ROADMAP' +alias mp='${PAGER:-less} $MASTERPLAN' +alias ho='${PAGER:-less} $HANDOFF' +alias rb='${PAGER:-less} $RULEBOOK' +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' + +# sol() — avslutt-funksjon +sol() { + printf "\n ${BOLD}${CYAN}Sesjonsavslutning${NC}\n" + printf " Hva ble gjort? (LØST / ULØST)\n > "; read -r DONE_DESC + [[ -z "$DONE_DESC" ]] && DONE_DESC="(ingen notat)" + printf " Uløste problemer? (Enter for ingen)\n > "; read -r UNSOLVED + [[ -z "$UNSOLVED" ]] && UNSOLVED="ingen" + cat >> "$SESSION_LOG" << EOF + +### Sesjonsavslutning $OSVAUCO_SESSION_ID +- Start : $OSVAUCO_SESSION_START +- Slutt : $(date '+%Y-%m-%d %H:%M %Z') +- Gjort : $DONE_DESC +- Uløst : $UNSOLVED +EOF + ok "Logg oppdatert" + cd "$OSVAUCO_DIR" + git add docs/OSVAUCO_OPAX_SESSION_LOG.md 2>/dev/null + if ! git diff --cached --quiet; then + git commit -m "chore(session): logg $OSVAUCO_SESSION_ID — $DONE_DESC" -q + git push origin "$(git branch --show-current)" -q && ok "Pushet → GitHub" + fi +} +export -f sol + +# ============================================================================= +# 7. QUICK COMMANDS-TABELL +# ============================================================================= +printf "${DIM}────────────────────────────────────────────────────────────${NC}\n" +printf "${BOLD}HOTKEYS${NC}\n" +printf " %-8s %-22s %-8s %-22s\n" "opax" "Gemini 2.5 Pro TUI" "opax2" "Claude Opus 4.7 TUI" +printf " %-8s %-22s %-8s %-22s\n" "pf" "preflight" "hc" "health-check" +printf " %-8s %-22s %-8s %-22s\n" "st" "smoke-test" "at" "acceptance-test" +printf " %-8s %-22s %-8s %-22s\n" "ca" "cost-audit" "cl" "cost-lens" +printf " %-8s %-22s %-8s %-22s\n" "cg" "cost-guard" "costs" "cost-lens (alias)" +printf " %-8s %-22s %-8s %-22s\n" "mp" "vis MASTERPLAN" "rl" "vis ROADMAP" +printf " %-8s %-22s %-8s %-22s\n" "ho" "vis HANDOFF" "rb" "vis RULEBOOK" +printf " %-8s %-22s %-8s %-22s\n" "sl" "vis SESSION_LOG" "logg" "manuell logg-slutt" +printf " %-8s %-22s %-8s %-22s\n" "ghs" "gh PRs + issues" "ms" "mirror-sync (GDrive)" +printf " %-8s %-22s %-8s %-22s\n" "osv" "cd ~/OSVauco" "sol" "avslutt + commit" +printf " %-8s %-22s\n" "reboot-osv" "kjør boot.sh på nytt" +printf "${DIM}────────────────────────────────────────────────────────────${NC}\n" + +# ============================================================================= +# 8. NVM +# ============================================================================= +export NVM_DIR="$HOME/.nvm" +[[ -s "$NVM_DIR/nvm.sh" ]] && source "$NVM_DIR/nvm.sh" + +# ============================================================================= +# 9. VALG: opax / opax2 / hopp over +# ============================================================================= +printf "\n${BOLD}Hvilken TUI vil du starte?${NC}\n" +printf " ${CYAN}1${NC}) opax — Gemini 2.5 Pro (Vertex EU) ${DIM}[default]${NC}\n" +printf " ${MAGENTA}2${NC}) opax2 — Claude Opus 4.7 (Vertex EU)\n" +printf " ${DIM}3${NC}) hopp over (jobb i shell)\n" +printf " Velg [1/2/3]: " +read -r CHOICE +case "${CHOICE:-1}" in + 1|"") + printf " ${GREEN}→ starter opax (Gemini 2.5 Pro)${NC}\n\n" + source "$OSVAUCO_DIR/scripts/opax.sh" + ;; + 2) + printf " ${MAGENTA}→ starter opax2 (Claude)${NC}\n\n" + source "$OSVAUCO_DIR/scripts/opax2.sh" + ;; + *) + printf " ${DIM}OK — shell ready. Kjør 'opax' eller 'opax2' når du er klar.${NC}\n\n" + ;; +esac diff --git a/scripts/opax.sh b/scripts/opax.sh old mode 100644 new mode 100755 index d69e587..8939342 --- a/scripts/opax.sh +++ b/scripts/opax.sh @@ -1,18 +1,29 @@ #!/usr/bin/env bash # ============================================================================= -# OPAX.SH — Authoritative OSVauco OPAX Environment Bootstrapper +# opax.sh — Gemini 2.5 Pro TUI starter (Vertex AI europe-west1) # -# Usage: source ~/OSVauco/scripts/opax.sh -# Alias: opax +# Bruk: source ~/OSVauco/scripts/opax.sh +# Alias: opax (settes av scripts/boot.sh) +# +# Modell og region er låst i docs/AGENT_RULEBOOK.md. # ============================================================================= -# --- Pre-computation and Environment --- -OSVAUCO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" -export GOOGLE_CLOUD_PROJECT="propane-will-491900-m5" -export GOOGLE_CLOUD_LOCATION="us-central1" -export GEMINI_MODEL="gemini-2.5-pro" +# Definer boot-promptet som skal sendes til Gemini +read -r -d '''' BOOT_PROMPT << 'EOM' +BOOT: Les @docs/AGENT_RULEBOOK.md, @docs/MASTERPLAN.md, @docs/ROADMAP.md og @docs/HANDOFF.md. Print så LOCKED DEFINITIONS (project, region, model, service, URLs) i en kompakt blokk. Oppsummer NESTE OPPGAVE fra HANDOFF.md i én setning. List så 3 konkrete neste-steg du foreslår, men IKKE utfør noe — vent på at jeg svarer "PLAN APPROVED" eller gir en spesifikk instruksjon. Bekreft til slutt at du forstår ABSOLUTT REGEL #1. +EOM + +OSVAUCO_DIR="${OSVAUCO_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}" +export GOOGLE_CLOUD_PROJECT="propane-will-491900-m5" +export GOOGLE_CLOUD_LOCATION="europe-west1" +export VERTEX_AI_LOCATION="europe-west1" +export GEMINI_MODEL="gemini-2.5-pro" +HANDOFF="$OSVAUCO_DIR/docs/HANDOFF.md" +MASTERPLAN="$OSVAUCO_DIR/docs/MASTERPLAN.md" +ROADMAP="$OSVAUCO_DIR/docs/ROADMAP.md" +RULEBOOK="$OSVAUCO_DIR/docs/AGENT_RULEBOOK.md" +SESSION_LOG="$OSVAUCO_DIR/docs/OSVAUCO_OPAX_SESSION_LOG.md" -# --- UI Colors --- GREEN="$(tput setaf 2 2>/dev/null || printf '\033[0;32m')" RED="$(tput setaf 1 2>/dev/null || printf '\033[0;31m')" YELLOW="$(tput setaf 3 2>/dev/null || printf '\033[1;33m')" @@ -22,108 +33,107 @@ DIM="$(tput dim 2>/dev/null || printf '\033[2m')" BOLD="$(tput bold 2>/dev/null || printf '\033[1m')" NC="$(tput sgr0 2>/dev/null || printf '\033[0m')" -OK="✅" -FAIL="❌" +OK="✔" +FAIL="✗" -if [[ -z "${OPAX_LOADED-}" ]]; then - clear - printf "${CYAN}" - echo " ___ _____ _ _ ___ _ _ ___ _____ " - echo " / _ \| ___| | | | |/ _ \| | | |/ __|| _ | " - echo " | | | | |___ | | | / /_\ \ | | | | | | | | " - echo " | | | |___ | | | | | _ | | | | | | | | | " - echo " | |_| |___| | \ \_/ / | | | |_| | |__ \ \_/ / " - echo " \___/\____/ \___/\_| |_/\___/ \___| \___/ " - printf "${NC}" - printf "${DIM} -------------------------------------------------${NC}\n" - printf " ${CYAN}OPAX${NC} ${DIM}Operator Platform // ${GOOGLE_CLOUD_PROJECT}${NC}\n" - printf "${DIM} -------------------------------------------------${NC}\n\n" - - printf "${BOLD}${WHITE} Preflight Checks...${NC}\n" - - run_check() { - local description="$1" - local command_to_run="$2" - local error_message="$3" - local is_critical="${4:-false}" - - printf " %-40s" "$description" - if eval "$command_to_run" &>/dev/null; then - printf "${GREEN}${OK}${NC}\n" - else - printf "${RED}${FAIL}${NC}\n" - if [[ "$is_critical" == "true" ]]; then - printf "\n ${RED}${BOLD}CRITICAL:${NC} ${error_message}\n" - printf " ${YELLOW}Aborting OPAX startup.${NC}\n\n" - return 1 - else - printf " ${YELLOW}⚠${NC} ${error_message}\n" - fi - fi - } - - run_check "gcloud user authenticated" \ - "gcloud auth list --filter=status:ACTIVE --format='value(account)' | grep -q @" \ - "Run: gcloud auth login" \ - true - - run_check "Application Default Credentials (ADC)" \ - "curl -sf -H 'Metadata-Flavor: Google' 'http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token' | grep -q access_token || gcloud auth application-default print-access-token --quiet" \ - "Run: gcloud auth application-default login" \ - true - - run_check "gcloud project = $GOOGLE_CLOUD_PROJECT" \ - "[[ \$(gcloud config get-value project 2>/dev/null) == '$GOOGLE_CLOUD_PROJECT' ]]" \ - "Run: gcloud config set project $GOOGLE_CLOUD_PROJECT" \ - true - - run_check "GitHub remote reachable" \ - "git -C '$OSVAUCO_DIR' ls-remote --exit-code origin" \ - "Cannot reach git remote origin" \ - true - - run_check "Secret Manager tilgjengelig" \ - "gcloud secrets versions access latest --secret=GEMINI_API_KEY --project=$GOOGLE_CLOUD_PROJECT" \ - "Sjekk IAM-tillatelser for Secret Manager" - - run_check "Git working tree clean" \ - "git -C '$OSVAUCO_DIR' diff --quiet && git -C '$OSVAUCO_DIR' diff --cached --quiet" \ - "Uncommitted changes present" - - # Cloud Run health - SERVICE_URL=$(gcloud run services describe osvauco-agent \ - --region "$GOOGLE_CLOUD_LOCATION" \ - --project "$GOOGLE_CLOUD_PROJECT" \ - --format="value(status.url)" 2>/dev/null || echo "") - - if [[ -n "$SERVICE_URL" ]]; then - TOKEN=$(gcloud auth print-identity-token 2>/dev/null || echo "") - run_check "Cloud Run osvauco-agent healthy" \ - "curl -sf -H 'Authorization: Bearer ${TOKEN}' '${SERVICE_URL}/health'" \ - "Service ikke tilgjengelig — sjekk Cloud Run" +run_check() { + local desc="$1" cmd="$2" err="$3" critical="${4:-false}" + printf " %-42s" "$desc" + if eval "$cmd" &>/dev/null; then + printf "${GREEN}${OK} OK${NC} +" else - printf " %-40s${YELLOW}SKIP${NC}\n" "Cloud Run osvauco-agent healthy" - printf " ${DIM}Service ikke funnet i $GOOGLE_CLOUD_LOCATION${NC}\n" + printf "${RED}${FAIL} FAIL${NC} +" + if [[ "$critical" == "true" ]]; then + printf " + ${RED}${BOLD}KRITISK:${NC} ${err} +" + printf " ${YELLOW}Avbryter opax-oppstart.${NC} + +" + return 1 + else + printf " ${YELLOW}⚠${NC} ${err} +" + fi fi +} - printf "\n${GREEN}${BOLD}✅ OPAX klar.${NC}\n\n" +clear +printf "${CYAN}${BOLD}" +cat << 'LOGO' + ___ ____ __ __ _ _ _ ____ ___ + / _ \/ ___| \ \ / /_ _| | | | | |/ ___|/ _ + | | | \___ \ \ \ / / _` | | | | | | | | | | | + | |_| |___) | \ V / (_| | |__| |_| | |___| |_| | + \___/|____/ \_/ \__,_|____|\___/ \____|\___/ +LOGO +printf "${NC}${BOLD}${CYAN} OS VAUCO / OPAX${NC}${DIM} · Gemini 2.5 Pro${NC} +" +printf "${DIM} ─────────────────────────────────────────────${NC} +" +printf " ${CYAN}project=${NC}%s ${CYAN}region=${NC}%s +" "$GOOGLE_CLOUD_PROJECT" "$GOOGLE_CLOUD_LOCATION" +printf " ${CYAN}model =${NC}%s +" "$GEMINI_MODEL" +printf "${DIM} ─────────────────────────────────────────────${NC} + +" + +printf "${BOLD}${WHITE}Preflight${NC} +" +run_check "gcloud auth" "gcloud auth print-access-token" "Kjør: gcloud auth login --no-launch-browser" true || return 1 +run_check "ADC (application-default)" "gcloud auth application-default print-access-token" "Kjør: gcloud auth application-default login" true || return 1 +run_check "project = $GOOGLE_CLOUD_PROJECT" "[[ "$(gcloud config get-value project 2>/dev/null)" == "$GOOGLE_CLOUD_PROJECT" ]]" "Kjør: gcloud config set project $GOOGLE_CLOUD_PROJECT" false +run_check "HANDOFF.md finnes" "[[ -f '$HANDOFF' ]]" "Mangler: $HANDOFF" false +run_check "MASTERPLAN.md finnes" "[[ -f '$MASTERPLAN' ]]" "Mangler MASTERPLAN" false +run_check "ROADMAP.md finnes" "[[ -f '$ROADMAP' ]]" "Mangler ROADMAP" false +run_check "AGENT_RULEBOOK.md finnes" "[[ -f '$RULEBOOK' ]]" "Mangler RULEBOOK" false +run_check "gemini CLI installert" "command -v gemini" "Installer: npm i -g @google/generative-ai-cli" true || return 1 +run_check "gh CLI auth" "gh auth status" "Kjør: gh auth login" false +run_check "Vertex AI API enabled" "gcloud services list --enabled --filter='aiplatform.googleapis.com' --format='value(name)' | grep -q aiplatform" "Kjør: gcloud services enable aiplatform.googleapis.com" false + +printf " +${BOLD}${CYAN}NESTE OPPGAVE${NC} +" +if [[ -f "$HANDOFF" ]]; then + sed -n '/^##.*[Nn]este [Oo]ppgave/,/^## /p' "$HANDOFF" | sed '1d;$d' | sed '/^$/d' | head -12 fi -# --- Miljø og prompt --- -cd "$OSVAUCO_DIR" 2>/dev/null || true +# ============================================================================= +# AUTO-BOOT: BOOT_PROMPT-variabelen sendes til `gemini --prompt`. +# Dette instruerer agenten til å lese kontekstfiler og foreslå en plan. +# ============================================================================= -export PS1="\[${GREEN}\]┌──(\[${CYAN}\]OPAX:\[${BOLD}\]\w\[${NC}\])\[${NC}\]\n\[${GREEN}\]└─▪\[${NC}\] " +printf " +${DIM}Tips:${NC} 'ho' = HANDOFF · 'sol' = avslutt+commit · 'pf' = re-preflight · 'gh pr list' = aktive PRs +" +printf "${DIM}Auto-booting med prompt-injeksjon...${NC} +" -export OPAX_LOADED=true +cd "$OSVAUCO_DIR" +printf " +${GREEN}${BOLD}→ Starter gemini med boot-prompt...${NC} -if [[ -z "${OPAX_COMMANDS_SHOWN-}" ]]; then - printf "${BOLD}${WHITE}QUICK COMMANDS${NC}\n" - printf " ${GREEN}%-8s${NC} %s\n" "ca" "cost-audit" - printf " ${GREEN}%-8s${NC} %s\n" "cl" "cost-lens" - printf " ${GREEN}%-8s${NC} %s\n" "st" "smoke-test" - printf " ${GREEN}%-8s${NC} %s\n" "hc" "health-check" - printf " ${GREEN}%-8s${NC} %s\n" "g" "gemini" - printf " ${GREEN}%-8s${NC} %s\n" "sol" "avslutt" - printf "\n" - export OPAX_COMMANDS_SHOWN=true -fi +" + +gemini --prompt "$BOOT_PROMPT" +GEMINI_EXIT=$? + +# ============================================================================= +# EXIT-HOOK: spør om sesjons-logg etter at gemini avsluttes +# ============================================================================= +printf " +${DIM}── opax-sesjon avsluttet (exit=$GEMINI_EXIT) ──${NC} +" +printf "${BOLD}${CYAN}Vil du logge sesjonen nå?${NC} [Y/n]: " +read -r LOGG_ANSWER +case "${LOGG_ANSWER:-y}" in + n|N) printf " ${DIM}OK — kjør 'sol' senere når du vil logge + commit.${NC} + +" ;; + *) + if declare -f sol >/dev/null; then sol; else bash "$OSVAUCO_DIR/scripts/opax-logg-slutt.sh"; fi + ;; +esac diff --git a/scripts/opax2.sh b/scripts/opax2.sh old mode 100644 new mode 100755 index 424c19e..1b50655 --- a/scripts/opax2.sh +++ b/scripts/opax2.sh @@ -1,22 +1,24 @@ #!/usr/bin/env bash # ============================================================================= -# OPAX2.SH — Claude 4.7 session starter +# opax2.sh — Claude Opus 4.7 TUI starter (Vertex AI europe-west1) # # Bruk: source ~/OSVauco/scripts/opax2.sh -# Alias: opax2 +# Alias: opax2 (settes av scripts/boot.sh) # -# Forskjell fra opax: -# - Bruker Claude Opus 4.7 via Vertex AI EU endpoint -# - Mater inn handoff til claude automatisk ved oppstart -# - Region: europe-west1 +# Krever Claude-kvote i propane-will-491900-m5 / europe-west1. # ============================================================================= -OSVAUCO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +OSVAUCO_DIR="${OSVAUCO_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}" export GOOGLE_CLOUD_PROJECT="propane-will-491900-m5" export GOOGLE_CLOUD_LOCATION="europe-west1" +export VERTEX_AI_LOCATION="europe-west1" export VERTEX_AI_ENDPOINT="eu" export CLAUDE_MODEL="claude-opus-4-7@20260301" -HANDOFF_FILE="$OSVAUCO_DIR/docs/HANDOFF_20260531_claude47.md" +HANDOFF="$OSVAUCO_DIR/docs/HANDOFF.md" +MASTERPLAN="$OSVAUCO_DIR/docs/MASTERPLAN.md" +ROADMAP="$OSVAUCO_DIR/docs/ROADMAP.md" +RULEBOOK="$OSVAUCO_DIR/docs/AGENT_RULEBOOK.md" +SESSION_LOG="$OSVAUCO_DIR/docs/OSVAUCO_OPAX_SESSION_LOG.md" GREEN="$(tput setaf 2 2>/dev/null || printf '\033[0;32m')" RED="$(tput setaf 1 2>/dev/null || printf '\033[0;31m')" @@ -30,138 +32,77 @@ NC="$(tput sgr0 2>/dev/null || printf '\033[0m')" OK="✔" FAIL="✗" -SKIP="▷" run_check() { - local description="$1" - local command_to_run="$2" - local error_message="$3" - local is_critical="${4:-false}" - printf " %-42s" "$description" - if eval "$command_to_run" &>/dev/null; then + local desc="$1" cmd="$2" err="$3" critical="${4:-false}" + printf " %-42s" "$desc" + if eval "$cmd" &>/dev/null; then printf "${GREEN}${OK} OK${NC}\n" else printf "${RED}${FAIL} FAIL${NC}\n" - if [[ "$is_critical" == "true" ]]; then - printf "\n ${RED}${BOLD}KRITISK:${NC} ${error_message}\n" + if [[ "$critical" == "true" ]]; then + printf "\n ${RED}${BOLD}KRITISK:${NC} ${err}\n" printf " ${YELLOW}Avbryter opax2-oppstart.${NC}\n\n" return 1 else - printf " ${YELLOW}⚠${NC} ${error_message}\n" + printf " ${YELLOW}⚠${NC} ${err}\n" fi fi } clear -printf "${MAGENTA}" +printf "${MAGENTA}${BOLD}" cat << 'LOGO' - ___ _____ _ _ _ _ ___ - / _ \| _ || | | || \ | ||_ | - | | | | |_) || |__| || \| | | | - | | | | __/ | __ || . ` | | | - | |_| | | | | | || |\ | _| |_ - \___/|_| |_| |_||_| \_||_____| + ___ ____ __ __ _ _ _ ____ ___ + / _ \/ ___| \ \ / /_ _| | | | | |/ ___|/ _ \ + | | | \___ \ \ \ / / _` | | | | | | | | | | | + | |_| |___) | \ V / (_| | |__| |_| | |___| |_| | + \___/|____/ \_/ \__,_|____|\___/ \____|\___/ LOGO -printf "${NC}" -printf "${DIM} --------------------------------------------------${NC}\n" -printf " ${MAGENTA}OPAX2${NC} ${DIM}Claude 4.7 · Vertex AI EU · ${GOOGLE_CLOUD_PROJECT}${NC}\n" -printf "${DIM} --------------------------------------------------${NC}\n\n" +printf "${NC}${BOLD}${MAGENTA} OS VAUCO / OPAX2 (Claude)${NC}${DIM} · Claude Opus 4.7${NC}\n" +printf "${DIM} ─────────────────────────────────────────────${NC}\n" +printf " ${MAGENTA}project=${NC}%s ${MAGENTA}region=${NC}%s\n" "$GOOGLE_CLOUD_PROJECT" "$GOOGLE_CLOUD_LOCATION" +printf " ${MAGENTA}model =${NC}%s\n" "$CLAUDE_MODEL" +printf "${DIM} ─────────────────────────────────────────────${NC}\n\n" -printf "${BOLD}${WHITE} Preflight...${NC}\n" +printf "${BOLD}${WHITE}Preflight${NC}\n" +run_check "gcloud auth" "gcloud auth print-access-token" "Kjør: gcloud auth login --no-launch-browser" true || return 1 +run_check "ADC (application-default)" "gcloud auth application-default print-access-token" "Kjør: gcloud auth application-default login" true || return 1 +run_check "project = $GOOGLE_CLOUD_PROJECT" "[[ \"\$(gcloud config get-value project 2>/dev/null)\" == \"$GOOGLE_CLOUD_PROJECT\" ]]" "Kjør: gcloud config set project $GOOGLE_CLOUD_PROJECT" false +run_check "HANDOFF.md finnes" "[[ -f '$HANDOFF' ]]" "Mangler HANDOFF" false +run_check "MASTERPLAN.md finnes" "[[ -f '$MASTERPLAN' ]]" "Mangler MASTERPLAN" false +run_check "ROADMAP.md finnes" "[[ -f '$ROADMAP' ]]" "Mangler ROADMAP" false +run_check "AGENT_RULEBOOK.md finnes" "[[ -f '$RULEBOOK' ]]" "Mangler RULEBOOK" false +run_check "claude CLI installert" "command -v claude" "Claude CLI mangler — installer wrapper for Vertex Claude" true || return 1 +run_check "gh CLI auth" "gh auth status" "Kjør: gh auth login" false +run_check "Vertex AI API enabled" "gcloud services list --enabled --filter='aiplatform.googleapis.com' --format='value(name)' | grep -q aiplatform" "Kjør: gcloud services enable aiplatform.googleapis.com" false -run_check "gcloud user authenticated" \ - "gcloud auth list --filter=status:ACTIVE --format='value(account)' | grep -q @" \ - "Kjør: gcloud auth login" \ - true - -run_check "ADC tilgjengelig" \ - "gcloud auth application-default print-access-token --quiet" \ - "Kjør: gcloud auth application-default login" \ - true - -run_check "GCP project = $GOOGLE_CLOUD_PROJECT" \ - "[[ \$(gcloud config get-value project 2>/dev/null) == '$GOOGLE_CLOUD_PROJECT' ]]" \ - "Kjør: gcloud config set project $GOOGLE_CLOUD_PROJECT" \ - true - -run_check "GitHub remote tilgjengelig" \ - "git -C '$OSVAUCO_DIR' ls-remote --exit-code origin" \ - "Kan ikke nå git remote" \ - true - -# Vertex AI EU endpoint sjekk -TOKEN=$(gcloud auth print-access-token 2>/dev/null || echo "") -run_check "Vertex AI EU endpoint nåbar" \ - "curl -sf -o /dev/null -H 'Authorization: Bearer ${TOKEN}' \ - 'https://eu-aiplatform.googleapis.com/v1/projects/${GOOGLE_CLOUD_PROJECT}/locations/eu/publishers/anthropic/models'" \ - "Sjekk Vertex AI EU tillatelser / Model Garden aktivering" - -# Cloud Run sjekk (europe-west1) -CR_URL="https://osvauco-agent-357036551735.europe-west1.run.app" -IT=$(gcloud auth print-identity-token 2>/dev/null || echo "") -CR_HTTP=$(curl -s -o /dev/null -w "%{http_code}" \ - -H "Authorization: Bearer $IT" \ - "$CR_URL/health" 2>/dev/null || echo "000") -if [[ "$CR_HTTP" == "200" ]]; then - printf " %-42s${GREEN}${OK} OK${NC} (HTTP $CR_HTTP)\n" "Cloud Run osvauco-agent" -else - printf " %-42s${YELLOW}⚠ HTTP $CR_HTTP${NC}\n" "Cloud Run osvauco-agent" - printf " ${DIM}Direkte URL: $CR_URL${NC}\n" +printf "\n${BOLD}${MAGENTA}NESTE OPPGAVE${NC}\n" +if [[ -f "$HANDOFF" ]]; then + sed -n '/^##.*[Nn]este [Oo]ppgave/,/^## /p' "$HANDOFF" | sed '1d;$d' | sed '/^$/d' | head -12 fi -# opax.vauco.no IAP sjekk -DOMAIN_HTTP=$(curl -s -o /dev/null -w "%{http_code}" \ - -H "Authorization: Bearer $IT" \ - "https://opax.vauco.no/health" 2>/dev/null || echo "000") -if [[ "$DOMAIN_HTTP" == "200" ]]; then - printf " %-42s${GREEN}${OK} OK${NC} (HTTP $DOMAIN_HTTP)\n" "opax.vauco.no (IAP)" -else - printf " %-42s${YELLOW}▷ HTTP $DOMAIN_HTTP${NC} ${DIM}(Fase 8: verifiser IAP)${NC}\n" "opax.vauco.no (IAP)" -fi +# ============================================================================= +# AUTO-CONTEXT: CLAUDE.md (hvis finnes) eller .gemini/GEMINI.md som fallback. +# Claude CLI for Vertex leser typisk CLAUDE.md i workspace-rot. +# ============================================================================= -printf "\n${MAGENTA}${BOLD}✦ OPAX2 klar — Claude 4.7 · europe-west1${NC}\n\n" +printf "\n${YELLOW}MERK:${NC} Claude-kvote i europe-west1 må være innvilget for at modellen skal svare.\n" +printf "${DIM}Tips: 'ho' = HANDOFF · 'sol' = avslutt+commit · 'pf' = re-preflight${NC}\n" +printf "${DIM}I Claude TUI, skriv: 'BOOT' for å trigge full kontekst-lesing.${NC}\n\n" -# --- Handoff-prompt --- -printf "${DIM} --------------------------------------------------${NC}\n" -printf "${BOLD} HANDOFF\n${NC}" -if [[ -f "$HANDOFF_FILE" ]]; then - printf " ${GREEN}${OK}${NC} ${DIM}$HANDOFF_FILE${NC}\n" - printf " Sende handoff til Claude nå? [Y/n]: " - read -r ANSWER - case "$ANSWER" in - n|N) - printf " ${DIM}Hopper over — kjør manuelt: claude < $HANDOFF_FILE${NC}\n\n" - ;; - *) - printf " ${DIM}Starter Claude 4.7 med handoff...${NC}\n\n" - if command -v claude &>/dev/null; then - cd "$OSVAUCO_DIR" - # Sender handoff som første melding, så Claude leser kontekst før du skriver noe - BOOT_MSG=$(cat "$HANDOFF_FILE") -cat << EOF | claude -$BOOT_MSG +cd "$OSVAUCO_DIR" +printf "${MAGENTA}${BOLD}→ Starter claude TUI...${NC}\n\n" ---- -Du har nå lest handoff. Print en kort oppsummering (maks 5 linjer) av hva du forstår er status og neste steg. Ikke gjør noe annet. Vent på Chris sin godkjenning. -EOF - else - printf " ${RED}${FAIL}${NC} claude CLI ikke funnet.\n" - printf " ${DIM}Installer: npm install -g @anthropic-ai/claude-code${NC}\n\n" - fi - ;; - esac -else - printf " ${YELLOW}⚠${NC} Handoff ikke funnet: $HANDOFF_FILE\n\n" -fi +claude +CLAUDE_EXIT=$? -# --- Miljø og prompt --- -cd "$OSVAUCO_DIR" 2>/dev/null || true -export PS1="\[${MAGENTA}\]┌──(\[${CYAN}\]OPAX2:\[${BOLD}\]\w\[${NC}\])\[${NC}\]\n\[${MAGENTA}\]└─▪\[${NC}\] " -export OPAX2_LOADED=true - -printf "${BOLD}${WHITE}QUICK COMMANDS${NC}\n" -printf " ${MAGENTA}%-8s${NC} %s\n" "hc" "health-check" -printf " ${MAGENTA}%-8s${NC} %s\n" "st" "smoke-test" -printf " ${MAGENTA}%-8s${NC} %s\n" "ca" "cost-audit" -printf " ${MAGENTA}%-8s${NC} %s\n" "sol" "avslutt + logg" -printf "\n" +printf "\n${DIM}── opax2-sesjon avsluttet (exit=$CLAUDE_EXIT) ──${NC}\n" +printf "${BOLD}${MAGENTA}Vil du logge sesjonen nå?${NC} [Y/n]: " +read -r LOGG_ANSWER +case "${LOGG_ANSWER:-y}" in + n|N) printf " ${DIM}OK — kjør 'sol' senere når du vil logge + commit.${NC}\n\n" ;; + *) + if declare -f sol >/dev/null; then sol; else bash "$OSVAUCO_DIR/scripts/opax-logg-slutt.sh"; fi + ;; +esac diff --git a/scripts/osvauco-health-check.sh b/scripts/osvauco-health-check.sh deleted file mode 100755 index e28ebf9..0000000 --- a/scripts/osvauco-health-check.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash -# osvauco-health-check.sh — alias 'hc' -# Viderekobler til scripts/health-check.sh -exec "$(dirname "$0")/health-check.sh" "$@" diff --git a/scripts/osvauco-opax-boot.sh b/scripts/osvauco-opax-boot.sh deleted file mode 100755 index 6acb5f8..0000000 --- a/scripts/osvauco-opax-boot.sh +++ /dev/null @@ -1,172 +0,0 @@ -#!/usr/bin/env bash -# ============================================================================= -# osvauco-opax-boot.sh — OSVauco OPAX session-starter -# Bruk: source ~/OSVauco/scripts/osvauco-opax-boot.sh -# ============================================================================= - -OSVAUCO_DIR="$HOME/OSVauco" -ROADMAP="$OSVAUCO_DIR/docs/VAUCO_OS_ROADMAP.md" -SESSION_LOG="$OSVAUCO_DIR/docs/OSVAUCO_OPAX_SESSION_LOG.md" -DIRECT_URL="https://osvauco-agent-357036551735.us-central1.run.app" -DOMAIN_URL="https://opax.vauco.no" - -GREEN="$(tput setaf 2 || true)" -RED="$(tput setaf 1 || true)" -YELLOW="$(tput setaf 3 || true)" -CYAN="$(tput setaf 6 || true)" -BOLD="$(tput bold || true)" -DIM="\033[2m" -NC="$(tput sgr0 || true)" - -SESSION_ID="$(date '+%Y%m%d-%H%M%S')" - -# ============================================================================= -# AUTO-AUTH RENEWAL -# ============================================================================= -ADC_SCOPE_FILE="$HOME/.config/gcloud/.osvauco-adc-renewed" - -printf "${BOLD}${CYAN} [ AUTH ]${NC}\n" -if ! gcloud auth print-access-token >/dev/null 2>&1; then - printf " ${YELLOW}⚠ gcloud auth utløpt — logger inn...${NC}\n" - gcloud auth login --no-launch-browser -else - printf " ${DIM}✦ gcloud auth OK${NC}\n" -fi - -NEED_ADC_LOGIN=0 -if ! gcloud auth application-default print-access-token >/dev/null 2>&1; then - NEED_ADC_LOGIN=1 -elif [[ -f "$ADC_SCOPE_FILE" ]]; then - if [[ $(($(date +%s) - $(stat -c %Y "$ADC_SCOPE_FILE"))) -gt 28800 ]]; then - NEED_ADC_LOGIN=1 - fi -else - NEED_ADC_LOGIN=1 -fi - -if [[ $NEED_ADC_LOGIN -eq 1 ]]; then - printf " ${YELLOW}⚠ ADC utløpt — fornyer...${NC}\n" - gcloud auth application-default login --no-launch-browser \ - --scopes="https://www.googleapis.com/auth/cloud-platform" - touch "$ADC_SCOPE_FILE" -else - printf " ${DIM}✦ ADC OK${NC}\n" -fi -printf " ${GREEN}✦ Auth klar${NC}\n\n" - -clear - -# ============================================================================= -# BOOT UI -# ============================================================================= -printf "${CYAN}OSVauco · OPAX ❱ %s · propane-will-491900-m5${NC}\n" "$SESSION_ID" -printf "${DIM}────────────────────────────────────────────────────────────${NC}\n" - -printf "${BOLD}SERVICES${NC}\n" - -# Cloud Run — sjekk direkte URL (den faktiske tjenesten) -TOKEN=$(gcloud auth print-identity-token 2>/dev/null || true) -CR_HTTP=$(curl -s -o /dev/null -w "%{http_code}" \ - -H "Authorization: Bearer $TOKEN" \ - "$DIRECT_URL/health" 2>/dev/null || echo "000") -if [[ "$CR_HTTP" == "200" ]]; then - printf " %-20s ${GREEN}✦ OK${NC} (HTTP $CR_HTTP)\n" "Cloud Run (direkte)" -else - printf " %-20s ${RED}✗ FAIL${NC} (HTTP $CR_HTTP)\n" "Cloud Run (direkte)" -fi - -# opax.vauco.no — domenesjekken — Phase 5 -DOMAIN_HTTP=$(curl -s -o /dev/null -w "%{http_code}" \ - -H "Authorization: Bearer $TOKEN" \ - "$DOMAIN_URL/health" 2>/dev/null || echo "000") -if [[ "$DOMAIN_HTTP" == "200" ]]; then - printf " %-20s ${GREEN}✦ OK${NC} (HTTP $DOMAIN_HTTP)\n" "opax.vauco.no" -else - printf " %-20s ${YELLOW}⚠ VENTER${NC} (HTTP $DOMAIN_HTTP) — Phase 5: IAP + domene ikke konfigurert ennå\n" "opax.vauco.no" -fi - -# GitHub + Git -printf " %-20s " "GitHub" -if gh auth status >/dev/null 2>&1; then printf "${GREEN}✦ OK${NC}\n"; else printf "${RED}✗ FAIL${NC}\n"; fi - -printf " %-20s " "Git Remote" -if git -C "$OSVAUCO_DIR" ls-remote origin refs/heads/main >/dev/null 2>&1; then printf "${GREEN}✦ OK${NC}\n"; else printf "${RED}✗ FAIL${NC}\n"; fi - -printf "${DIM}────────────────────────────────────────────────────────────${NC}\n" - -printf "${BOLD}SYSTEM${NC}\n" -LOAD=$(awk '{print $1}' /proc/loadavg) -MEM=$(free -h | awk '/Mem:/{printf "%s/%s", $3, $2}') -DISK=$(df -h / | awk 'NR==2{print $5}') -printf " %-20s Load: %s · RAM: %s · /: %s\n" "Resources" "$LOAD" "$MEM" "$DISK" -printf " %-20s %s\n" "Uptime" "$(uptime -p | sed 's/up //')" - -printf "${DIM}────────────────────────────────────────────────────────────${NC}\n" - -printf "${BOLD}NEXT${NC}\n" -NEXT_ROADMAP=$(awk '/^## NEXT/{f=1;next} f && /^## /{f=0} f && /^- \[ \]/{print;exit}' "$ROADMAP" 2>/dev/null || true) -printf " ${GREEN}▶ %s${NC}\n" "${NEXT_ROADMAP:-Ingen oppgave i roadmap}" - -printf "${DIM}────────────────────────────────────────────────────────────${NC}\n" -printf "${BOLD}QUICK COMMANDS${NC}\n" -printf " %-4s %-12s %-4s %-12s\n" "ca" "cost-audit" "cl" "cost-lens" -printf " %-4s %-12s %-4s %-12s\n" "cg" "cost-guard" "hc" "health-check" -printf " %-4s %-12s %-4s %-12s\n" "pf" "preflight" "st" "smoke-test" -printf " %-4s %-12s %-4s %-12s\n" "rl" "roadmap" "sl" "session-log" -printf " %-4s %-12s %-4s %-12s\n" "ms" "mirror-sync" "g" "gemini" -printf " %-4s %-12s %-4s %-12s\n" "sol" "session-exit" "" "" -printf "\n── ready ── SESSION %s ──\n\n" "$SESSION_ID" - -# ============================================================================= -# NVM -# ============================================================================= -export NVM_DIR="$HOME/.nvm" -[[ -s "$NVM_DIR/nvm.sh" ]] && source "$NVM_DIR/nvm.sh" - -# ============================================================================= -# AVSLUTT-FUNKSJON -# ============================================================================= -sol() { - printf "\n ${BOLD}${CYAN}Sesjonslogg — avslutt${NC}\n" - printf " Hva ble gjort? (LØST / ULØST)\n > " - read -r DONE_DESC - [[ -z "$DONE_DESC" ]] && DONE_DESC="(ingen notat)" - printf " Uløste problemer? (Enter for ingen)\n > " - read -r UNSOLVED - [[ -z "$UNSOLVED" ]] && UNSOLVED="ingen" - cat >> "$SESSION_LOG" << EOF - -### Sesjonsavslutning -- Gjort : $DONE_DESC -- Uløst : $UNSOLVED -- Slutt : $(date '+%Y-%m-%d %H:%M %Z') -EOF - printf " ${GREEN}[OK]${NC} Logg oppdatert\n" - cd "$OSVAUCO_DIR" - git add docs/OSVAUCO_OPAX_SESSION_LOG.md 2>/dev/null || true - if ! git diff --cached --quiet; then - git commit -m "chore(session): logg sesjon $SESSION_ID — $DONE_DESC" - git push origin main - printf " ${GREEN}[OK]${NC} Pushet → GitHub\n\n" - fi -} -export -f sol 2>/dev/null || true -alias sol='sol' - -# ============================================================================= -# GEMINI-START -# ============================================================================= -read -r -p " Starte Gemini-CLI nå? [y/N]: " ANSWER -case "$ANSWER" in - y|Y) - if ! command -v gemini &>/dev/null; then - printf " ${RED}[XX]${NC} gemini ikke funnet.\n" - else - cd "$OSVAUCO_DIR" - gemini - fi - ;; - *) - echo " OK — kjør 'gemini' når du er klar. 🚀" - ;; -esac