chore(docs): konsolider MASTERPLAN/ROADMAP/HANDOFF til én sannhet (#5)

* chore(docs): konsolider MASTERPLAN/ROADMAP/HANDOFF til én sannhet

Bakgrunn: revisjon 2026-05-31 avdekket at vi hadde to MASTERPLAN-er som
ikke matchet, en deprecated VAUCO_OS_ROADMAP som fortsatt ble brukt, tre
parallelle HANDOFF-filer, AGENT_RULEBOOK med feil region (us-central1)
og feil MCP_SERVICE (opax-mcp-core), og committed Git merge-konflikt-
markører i selve session-loggen.

Endringer:
- Ny docs/MASTERPLAN.md (autoritativ, erstatter både rot-MASTERPLAN.md og
  forrige docs-versjon). Tydeligere hierarki:
    Vauco AS → Vauco OS (plattform) → OPAX (engine) → Moduler
- Ny docs/ROADMAP.md (erstatter docs/VAUCO_OS_ROADMAP.md som var deprecated)
- Ny docs/HANDOFF.md — én fil, overskrives per sesjon (per planregelen)
- Oppdatert docs/AGENT_RULEBOOK.md:
    Region: us-central1 → europe-west1
    AI-modell: gemini-2.5-pro (midlertidig, venter på Claude EU-kvote)
    Vertex AI loc: europe-west1
    MCP_SERVICE: opax-mcp-core → osvauco-agent
- Fjernet Git merge-konfliktmarkører i docs/OSVAUCO_OPAX_SESSION_LOG.md
- Flyttet HANDOFF_20260526/20260531/20260531_claude47 → docs/archive/handoffs/
- Slettet duplikat-filer i docs/archive/ (Cost_Management_Rules,
  GCPBestPractices, OSVAUCO_OPAX_SESSION_LOG — alle dekket av live-filer)
- Slettet rot-MASTERPLAN.md (erstattet av peker-fil), VAUCO_OS_ROADMAP.md,
  Procfile (legacy fra POC, ikke brukt av Cloud Run)
- docs/TODO.md → peker-fil mot ROADMAP

Repo-strategi (fra MASTERPLAN §3):
- 4 aktive repos: OSVauco (mono), vauco-bootstrap, threadstone-landing,
  vauco-saas.github.io
- 3 arkiverte: vauco-os, vauco-gemini-tui-bridge, command-hub
- 2 parkerte (lever videre, ikke aktivt jobb): threadstone-instructions,
  deep-dream — venter på hver sin trigger (Threadstone-app pilot / første
  betalende kunde på CostGuard)

Etter merge: neste oppgave er F8 (browser-end-to-end på opax.vauco.no).

Co-authored-by: Perplexity <noreply@perplexity.ai>

* docs: inkorporer vauco.no salgsportal (apex) i planen

Hovedhull avdekket: vauco.no viser fortsatt Proisp 'Under construction'
placeholder. Planen manglet helt et spor for apex-siden — bedriftens
ansikt utad og portalen som leder besøkende til riktig modul.

MASTERPLAN endringer:
- §1 Plattformhierarki: utvidet fra 3 til 4 nivåer; vauco.no apex
  lagt til som egen kunde-flate (over Vauco OS i hierarkiet)
- §2 Domener: vauco.no/www.vauco.no markert som placeholder (skal
  erstattes), reserverte subdomener (status./docs./careers.)
  dokumentert, email-infra-status notert
- §3 Repos: vauco-site lagt til som 5. aktive repo (public,
  GitHub Pages — eget repo fordi sidens kildekode skal være public
  mens mono-repoet må forbli privat)
- §4b NY: vauco.no salgsportal — full spec for formål, IA,
  visuell retning, salgs-flow, teknisk stack, versjons-evolusjon
  V1 → V4
- §11 Kjente hull: OQ-23..OQ-26 lagt til (apex-placeholder,
  SPF/DKIM/DMARC, personvern/vilkår, statuspage)

ROADMAP endringer:
- NEXT-seksjon utvidet med V-spor: V1a–V1e (vauco.no MVP)
  kan kjøres parallelt med CG3
- KJENTE HULL-seksjon lagt til

HANDOFF oppdatert med oppsummering av nye tillegg.

NY FIL: docs/vauco-site/DESIGN.md
- Klar-til-plukk-opp build-spec for V1 MVP
- Sidekart, copy-utkast, farger, typografi, layout, performance-mål
- DNS-tabell for å flytte vauco.no fra Proisp-parking til GitHub Pages
- SPF/DKIM/DMARC oppskrift
- Bygg-rekkefølge med konkrete gh/git-kommandoer
- Akseptkriterier for V1 APPROVED

Etter merge har vi to parallelle spor:
- Spor A: F8 (OPAX end-to-end) + CG3 (CostGuard frontend)
- Spor B: V1 (vauco.no MVP)

Begge har egne HITL gates.

* chore(scripts): konsolider boot/opax/opax2 + hotkeys + README

- boot.sh: ny daglig VM-starter (rename fra osvauco-opax-boot.sh)
  * auto-fornyer gcloud auth + ADC (>8t)
  * git pull current branch
  * spør: opax (Gemini 2.5 Pro) / opax2 (Claude) / hopp over
  * setter aliaser: pf hc st at ca cl cg costs ms logg mp rl ho rb sl osv sol
  * printer NESTE OPPGAVE fra docs/HANDOFF.md
- opax.sh: region europe-west1, model gemini-2.5-pro, peker på docs/HANDOFF.md
- opax2.sh: peker på docs/HANDOFF.md (ikke arkivert handoff), advarer om kvote
- scripts/README.md: hotkey-tabell + bashrc-snippet + lock-tabell
- Slettet: scripts/archived/ (7 filer i git-historikk), osvauco-health-check.sh

* fix(scripts): OS VAUCO-header, github-status, auto-context, exit-hook

boot.sh:
- Ny header: OS VAUCO (stort) + Vauco OS subtitle
- [ REPO + GITHUB ] viser: fetch, pull, ahead/behind, uncommitted, last commit,
  gh CLI auth-status, åpne PRs på branchen
- 'ghs' alias = gh pr list + gh issue list
- NESTE OPPGAVE regex case-insensitive (matcher 'NESTE OPPGAVE' og 'Neste oppgave')

opax.sh / opax2.sh:
- Ny header: OS VAUCO / OPAX (cyan) og OS VAUCO / OPAX2 (Claude) (magenta)
- Sjekker MASTERPLAN + ROADMAP + RULEBOOK + HANDOFF + gh auth i preflight
- Auto-laster RULEBOOK + MASTERPLAN + ROADMAP + HANDOFF inn i CLI som kontekst
  ved oppstart (gemini -p / claude -p, fallback til stdin)
- Exit-hook: spør 'Vil du logge sesjonen nå?' når TUI avsluttes, kjører sol()
- ABSOLUTT REGEL (ingen handling uten PLAN APPROVED) injiseres i kontekst

* fix(scripts): NESTE OPPGAVE-parsing + gemini sandbox workaround

- Bytt awk(IGNORECASE) → sed-pipeline som funker på både gawk og mawk
  (HANDOFF.md har '## 🔄 Neste oppgave: ...' — emoji + capitalized)
- Flytt auto-context fra /tmp/ → $OSVAUCO_DIR/.gemini/context/ og .claude/context/
  Gemini CLI sandboxer alt utenfor workspace; /tmp er blokkert.
- Send relativ sti (.gemini/context/session-PID.md) til 'gemini -p @...'
- Rydd context-filer eldre enn 1 dag ved oppstart
- .gitignore: ekskluder .gemini/context/ + .claude/context/

* fix(scripts): flytt context til tmp-context/ (Gemini respekterer .gitignore)

Gemini CLI nekter å lese filer som er git-ignored. .gemini/context/ var
ignored, så context-fil ble blokkert.

- Ny mappe: tmp-context/ (innenfor workspace, ikke gitignored som dir)
- Kun session-*.md er gitignored (selve filene), ikke mappen
- tmp-context/README.md beholder mappen i git
- Ny .geminiignore: lar Gemini lese tmp-context/ men ignorerer
  node_modules, .terraform, dist osv.

* fix(scripts): bytt context-filnavn til ctx-*.md (Gemini respekterer .gitignore)

Gemini CLI blokkerer enhver fil som matcher et .gitignore-mønster, selv
om den ikke er i .geminiignore. Vi hadde 'tmp-context/session-*.md' i
.gitignore som blokkerte session-PID.md.

Løsning:
- Fjern session-pattern fra .gitignore helt
- Bytt filnavn: session-$$.md → ctx-$$.md
- Mappen ryddes uansett av find -mtime +1 -delete ved hver opax-oppstart
- Kommentar i .gitignore forklarer hvorfor og hvordan skippe lokalt

* fix(scripts): start gemini/claude TUI uten -p (TUI bombet pga non-interactive mode)

Problem: 'gemini -p "..."' kjører non-interactive (svarer + avslutter) —
det er derfor TUI ikke kom opp etter at vi la til auto-context.

Løsning: Gemini CLI auto-laster .gemini/GEMINI.md ved hver TUI-start.
- Oppdaterte .gemini/GEMINI.md: model=gemini-2.5-pro (var Claude 4.6),
  boot-prompt peker på MASTERPLAN/ROADMAP/HANDOFF (var slettet ROADMAP)
- opax.sh og opax2.sh: fjernet -p flag, kjører bare 'gemini'/'claude' = full TUI
- Slettet tmp-context/ (ikke nødvendig — GEMINI.md gjør jobben)
- Modellen får LOCKED DEFS automatisk fra GEMINI.md
- For full kontekst-load, skriv 'BOOT' i TUI

* chore(session): logg 20260531-153243 — git pull origin chore/consolidate-2026-05-31

* feat(opax): auto-kjør BOOT-prompt ved hver TUI-start

---------

Co-authored-by: Perplexity <noreply@perplexity.ai>
Co-authored-by: Chris Christiansen <chris.christian...@>
This commit is contained in:
chrischristiansen-glitch 2026-05-31 17:57:13 +02:00 committed by GitHub
parent 1fd62f3fc5
commit 70eced385f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
32 changed files with 1600 additions and 2232 deletions

View File

@ -16,9 +16,10 @@ GCP_REGION: europe-west1
GCP_VERTEX_LOC: eu GCP_VERTEX_LOC: eu
CLOUD_RUN_SVC: osvauco-agent CLOUD_RUN_SVC: osvauco-agent
ARTIFACT_REPO: gcr.io/propane-will-491900-m5 ARTIFACT_REPO: gcr.io/propane-will-491900-m5
MODEL: claude-opus-4-6@20260801 MODEL: gemini-2.5-pro
MODEL_PROVIDER: Vertex AI (Anthropic Claude via Google Cloud) MODEL_PROVIDER: Vertex AI (Google) — europe-west1
MODEL_COST: ~2 NOK per 1M tokens (input) 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 BUDGET_CAP: 2500 NOK intern grense — spør Chris om +1000 NOK ved behov
OPERATOR: Chris Christiansen (chris.christiansen@vauco.no) OPERATOR: Chris Christiansen (chris.christiansen@vauco.no)
OPERATOR_ROLE: Eier, arkitekt og primær operatør av OSVauco / OS-Vauco 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: 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. BOOT: Read docs/AGENT_RULEBOOK.md, docs/MASTERPLAN.md, docs/ROADMAP.md, docs/HANDOFF.md.
Print LOCKED DEFINITIONS. Print last NESTE OPPGAVE. Do not take any action until I give a PLAN prompt. Print LOCKED DEFINITIONS. Print NESTE OPPGAVE from HANDOFF.md. Do not take any action until I give a PLAN APPROVED prompt.
``` ```

13
.geminiignore Normal file
View File

@ -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/

2
.gitignore vendored
View File

@ -48,3 +48,5 @@ tfplan.txt
infrastructure/terraform/tfplan infrastructure/terraform/tfplan
**/tfplan **/tfplan
!infrastructure/terraform/customers/**/*.tfvars !infrastructure/terraform/customers/**/*.tfvars

View File

@ -1,307 +1,10 @@
# VAUCO OS — MASTERPLAN RESET # MASTERPLAN
**Versjon:** 2026-05-27 | **Eier:** Chris Christiansen | **Status:** Autoritativ
--- > **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å? Se også:
- [`docs/ROADMAP.md`](docs/ROADMAP.md) — levende roadmap
Du har bygget mye bra, men jobbet utenfra inn i stedet for innenfra ut. Det har skapt: - [`docs/HANDOFF.md`](docs/HANDOFF.md) — gjeldende sesjonsstatus
- [`docs/AGENT_RULEBOOK.md`](docs/AGENT_RULEBOOK.md) — locked definitions for agent-boot
- **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*

View File

@ -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

View File

@ -1,36 +1,44 @@
# VAUCO OS — AGENTRLEBOOK.md # VAUCO OS — AGENT_RULEBOOK.md
# Eier: OPS-Computer-Hub
# Sist oppdatert: 2026-05-21 CEST **Eier:** OPS-Computer-Hub
# Godkjent av: Chris Christiansen **Sist oppdatert:** 2026-05-31 CEST
**Godkjent av:** Chris Christiansen
--- ---
## Hensikt ## 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 | | Parameter | Verdi |
|-------------------|-----------------------------------------------------------------------| |-------------------|-----------------------------------------------------------------------|
| GCP Account | chris.christiansen@vauco.no | | GCP Account | `chris.christiansen@vauco.no` |
| Forbudte kontoer | tinius.vauger, ccv, jason.vauger | | Forbudte kontoer | `tinius.vauger`, `ccv` |
| GCP Project | propane-will-491900-m5 (Jason-v1) | | Agent-konto | `jason.vauger@vauco.no` (kun `billing.viewer` + `run.invoker`) |
| Billing | 0171F6-057E6B-A260BA | | GCP Project | `propane-will-491900-m5` (Jason-v1) |
| Org | vauco.no / 155051211891 | | Billing | `0171F6-057E6B-A260BA` |
| Region | us-central1 — ALDRI us-west1 | | Org | `vauco.no` / `155051211891` |
| SDK | `from google import genai` — ALDRI `vertexai.generative_models` | | **Region** | **`europe-west1`** — ALDRI `us-central1` eller `us-west1` |
| Agent-rammeverk | Google ADK (tillatt) — andre må eksplisitt `ADK_GODKJENT` av Chris | | **Vertex AI loc** | **`europe-west1`** (EU) |
| GitHub user | vauco-saas | | **AI-modell** | **`gemini-2.5-pro`** via Vertex AI (venter på Claude EU-kvote) |
| Canonical repo | OSVauco | | SDK | `from google import genai` (google-genai >=0.3) |
| Canonical branch | main | | Agent-rammeverk | Google ADK (tillatt) — andre må eksplisitt `ADK_GODKJENT` av Chris |
| MCP_NAME | OPAX-MCP | | GitHub org | `vauco-saas` |
| MCP_PROTOCOL | OPAX Protocol | | Canonical repo | `OSVauco` |
| MCP_SERVICE | opax-mcp-core (Cloud Run, us-central1) | | Canonical branch | `main` |
| ROOT_DOMAIN | vauco.no | | MCP_NAME | `OPAX-MCP` |
| HUB_URL | https://opax.vauco.no ✅ LIVE 2026-05-21 | | 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. > `-os` = produksjon. `-oss` = staging. Aldri omvendt.
**Auth-strategi:** **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) - Senere: BankID på `-os`-domener for kliniske kunder (Medioteq først)
**Kjente/planlagte domener:** **Kjente/planlagte domener:**
| Domene | Status | Cloud Run-tjeneste | | Domene | Status | Cloud Run-tjeneste |
|---------------------------|------------------|-----------------------| |------------------------------|------------------|-----------------------|
| `opax.vauco.no` | ✅ LIVE | `opax-mcp-core` | | `opax.vauco.no` | ✅ LIVE | `osvauco-agent` |
| `medioteq-oss.vauco.no` | Planlagt | `medioteq-oss-core` | | `costguard.oss.vauco.no` | ✅ LIVE | (Cloudflare Pages) |
| `medioteq-os.vauco.no` | Planlagt | `medioteq-os-core` | | `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 | Gate | Når kreves |
2. `MERGE APPROVED` — før merge til main |----------------------|----------------------------------------------------------|
3. `DEEP DREAM GODKJENT` — før strategisk vokabular eksponeres | `PLAN APPROVED` | Før noen kode/infra-endring starter |
4. `COST GODKJENT` — før endringer som påvirker billing | `MERGE APPROVED` | Før PR merges til `main` |
5. `IAM_GODKJENT` — før IAM-endringer eller ny service account | `DEPLOY GODKJENT` | Før manuell deploy som rører IAP, OAuth, Secret Manager |
6. `NEWREPO` — før opprettelse av ny repo | `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<N> 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) | Fil | Rolle |
- Hvis 1+ branch er 10+ commits ahead: STOPP og spør Chris |-----|-------|
- Standard: OSVauco/main er canonical for dette prosjektet | `docs/MASTERPLAN.md` | Arkitektur, domener, repos, fasit |
2. Les eid fil + MASTER_HANDOFF_v2 + ROADMAP fra riktig branch | `docs/ROADMAP.md` | Levende roadmap, faser, status |
3. Bekreft i én linje: `Boot OK — branch X, HEAD Y, oppgave Z` | `docs/HANDOFF.md` | Sesjonsstatus — **alltid kun én fil**, overskrives |
| `docs/AGENT_RULEBOOK.md` | Denne filen — locked definitions |
| `protocols/sessions/YYYY-MM-DD_<tema>.md` | Detaljerte sesjonsprotokoller (append-only) |
> **Aldri opprett flere parallelle MASTERPLAN, ROADMAP eller HANDOFF.**
--- ---
## VOCABULARY FIREWALL ## AGENT-OPPFØRSEL — kjerneregler
| Type | Ord | Regel | 1. **Foreslå før du handler.** Print plan. Vent på `PLAN APPROVED`.
|---|---|---| 2. **Self-modifisering av infra/secrets/IAM uten godkjenning = hard stop.**
| Offentlig (OK overalt) | Token Ledger, VVN, Provenance, File signature, Client identity record, Cognitive contribution, The system | Fritt bruk | 3. **Print LOCKED DEFINITIONS ved boot.** Sjekk at de matcher denne filen.
| Strategisk (KUN internt) | Pregeverdi, Deep Dream, Vauco-arv, Pregesignatur, T-konto, Work of Living, Pregeverk | KUN i `deep-dream/`-mappe | 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 <kommando>` 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 BOOT: Les docs/AGENT_RULEBOOK.md, docs/MASTERPLAN.md, docs/HANDOFF.md.
- ALDRI rekursive modell-loops Print LOCKED DEFINITIONS fra Lock List.
- Hvis tråden bruker $1 på én oppgave: STOPP, rapporter, spør Print NESTE OPPGAVE fra docs/HANDOFF.md.
- 80%/95%/100% quota stops aktive Vent på PLAN-prompt før noen handling.
```
--- ---
## FRICTION-REGLER (kodifisert lærdom) *Vauco AS · `propane-will-491900-m5` · `europe-west1`*
### 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 <SERVICE> --ingress internal-and-cloud-load-balancing
```
2. **IAP service account må ha `run.invoker`-rollen**
```bash
gcloud run services add-iam-policy-binding <SERVICE> \
--member=serviceAccount:service-<PROJECT_NUMBER>@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)

175
docs/HANDOFF.md Normal file
View File

@ -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:** V1aV1e (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`*

View File

@ -1,214 +1,468 @@
# MASTERPLAN — Vauco OS # VAUCO OS — MASTERPLAN
**Eier:** Chris Christiansen · Vauco AS · Org.nr 935 989 779 **Eier:** Chris Christiansen · Vauco AS · Org.nr 935 989 779
**Sist oppdatert:** 2026-05-31 **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) Vauco AS (selskap, eier alle merkevarer)
└── OPAX (Engine — AI-infrastruktur, Cloud Run, agentic arkitektur)
├── CostGuard (Modul #1 — live på costguard.oss.vauco.no) ├── vauco.no (APEX — bedriftens salgs- og portalside; ansiktet utad)
├── Threadstone (Modul #2 — kreativ AI-assistanse, Q3 2026) │ └── ruter besøkende videre til riktig modul
└── [Modul #3+] (TBD basert på CostGuard-læring)
└── 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 **Fire nivåer, fire formål:**
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.
### OPAX | Nivå | Hva | Hvem ser det |
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 |
|---|---|---| |---|---|---|
| Cloud Run (`osvauco-agent`) | ✅ Live | GCP europe-west1 | | **vauco.no (apex)** | **Bedriftens salgsportal — viser hvem Vauco AS er og hvilke moduler vi selger** | **Alle: kunder, partnere, presse, kandidater** |
| `opax.vauco.no` (LB + SSL) | ✅ Live | GCP Load Balancer, IP 34.98.77.173 | | Vauco OS | Plattformen Chris bygger og selger fra | Internt (Chris + agenter) |
| IAP på `opax.vauco.no` | ✅ Konfigurert | Begrenset til `@vauco.no` Google-kontoer | | OPAX | Engine som driver modulene | Internt + utviklere |
| `costguard.oss.vauco.no` | ✅ Live | Cloudflare Pages, docs/ | | Modul (CostGuard / Threadstone / …) | Det kundene faktisk kjøper | Kunder |
| `docs/index.html` iframe | ✅ Fikset | Peker nå på europe-west1 |
| BigQuery (`osvauco_logs`) | ⏳ Venter | Sink oppe, tabell populeres | **Salgskanal-prinsipp:**
| OAuth2 (Google) | ✅ Konfigurert | Secret Manager | - `vauco.no` = portalen som forteller "hva selger vi" og leder til riktig modul
| CI/CD (Cloud Build → Cloud Run) | ✅ Operativt | Auto-deploy på push til main | - Hver modul har sin egen landings-/produktside (`costguard.oss.vauco.no`, `threadstone.vauco.no`, …)
| Budget guard (500 NOK/mnd) | ✅ Live | 50/90/100% terskler | - Vauco OS og OPAX nevnes ikke som produkter på `vauco.no` — de er interne verktøy
| BQ billing export (`gcp_billing_export_v1_*`) | ⏳ Venter | Første tabell ikke populert ennå |
| Multi-tenant stamp-out | 🔜 Fase C | Onboarding-script + admin-panel | **Ikke selg Vauco OS. Ikke selg OPAX. De er interne verktøy.**
| RAG corpus (`osvauco-corpus`) | ✅ Populert | europe-west4 |
| **AI-modell** | ✅ Oppdatert | Claude Opus 4.6 via Vertex AI `eu` endpoint |
--- ---
## 3. Roadmap ## 2. Registrerte domener — fasit
### ✅ Fullført ### Vauco (hos Proisp)
- **Fase 0** — Baseline: `opax-mcp-core` live, OSVauco repo, `.gemini/` grunnmur, boot-script | Domene | Prosjekt | Status |
- **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 | `vauco.no` | Rot for alle Vauco-tjenester | ✅ Aktiv, verifisert på GitHub |
- **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
### 🔄 Aktiv nå **Aktive subdomener:**
- **Fase 8 — End-to-end test av agent via opax.vauco.no** | Domene/subdomen | Teknologi | Status | Eier-flate |
- Aktiver Claude Opus 4.6 i Vertex AI Model Garden |----------|-----------|--------|------------|
- Verifiser Cloud Run kjører i `europe-west1` | `vauco.no` (apex) | Proisp parking-side (placeholder) | ⚠️ "Under construction" — skal erstattes med ekte salgsportal | Vauco AS apex |
- Test agent via IAP: `curl https://opax.vauco.no/health` | `www.vauco.no` | Følger apex | ⚠️ Samme placeholder | Vauco AS apex |
- Test Claude EU endpoint direkte | `opax.vauco.no` | LB + IAP → Cloud Run `osvauco-agent` | ✅ Live (IP 34.98.77.173) | OPAX |
- Full end-to-end: login → chat → svar via Claude Opus 4.6 | `oss.vauco.no` | Staging-miljø | ✅ Aktiv | OPAX |
- HITL gate: `FASE8 APPROVED` | `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 |
| `<kunde>.vauco.no` | LB + IAP via Terraform | 🔮 Fase C2 | OPAX/Multi-tenant |
- **CG3 — CostGuard Frontend Wiring** **Reservert til senere — ikke opprettet ennå:**
- 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`
### 🔜 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** **Email-infra:**
- Konverter `infrastructure/*.sh` → Terraform-modul i `vauco-bootstrap/` - MX: Google Workspace (`smtp.google.com`) ✅
- LB, IAP, Cloud Run som Terraform-ressurser - TXT-records (SPF/DKIM/DMARC): ⚠️ Mangler — sett opp som del av V1 for å unngå at salgs-mail havner i spam
- Sett `IAP_ENABLED=true` + `IAP_AUDIENCE` i Cloud Run env-vars
**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 |
``` > **Trigger:** Ingen POC-arbeid før Modul #1 (CostGuard) har første betalende kunde og Modul #2 (Threadstone) er i pilot.
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 <klientnavn>` — 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
--- ---
## 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` |
``` ### Parkerte repos — leve videre, ikke arkiver, ikke aktivt jobb før trigger
REGEL 1 — LINEÆR STATE MACHINE
Agenten opererer strengt trinn-for-trinn.
Trinn N+1 starter ikke før bruker skriver "Step N approved".
REGEL 2 — INGEN CONTEXT-SWITCHING | Repo | Trigger for å gjenoppta | Hvor det hører hjemme i hierarkiet |
Ved blokkering (f.eks. venter på ekstern data): HALT. |------|--------------------------|------------------------------------|
Ingen pivoting til andre oppgaver. | `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 > **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.
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 10500 utviklere som sliter med å få ROI på AI-investeringer.
> 📁 Detaljert teknisk spec: `docs/architecture/ANTI_CHAOS_PROTOCOL.md` (opprettes i Fase C)
--- ---
## 5. Filstruktur — én kilde til sannhet ## 4. OSVauco — intern mappestruktur (fasit)
``` ```
vauco-saas/OSVauco/ OSVauco/
├── .gemini/ ├── MASTERPLAN.md → symlink/peker til docs/MASTERPLAN.md (denne filen)
│ └── GEMINI.md ← agent-kontekst, boot-prompt, locked definitions ├── README.md
├── docs/ ├── AGENTS.md ML-roller, ikke rør uten ML-fase-endring
│ ├── MASTERPLAN.md ← denne filen — autoritativ ├── Dockerfile / cloudbuild.yaml CI/CD (auto-deploy på push til main)
│ ├── HANDOFF_[dato].md ← siste sesjonshandoff
│ ├── ARCHITECTURE.md ← teknisk arkitektur ├── agents/ Python-agentene
│ ├── AGENT_RULEBOOK.md ← agentregler │ ├── core-logic/ OPAX orchestrator + FastAPI app (main.py)
│ ├── VAUCO_OS_ROADMAP.md ← ⚠️ deprecated, erstattet av seksjon 3 her │ ├── rag/ RAG-agent
│ ├── protocols/ │ ├── memory/ Memory-agent
│ ├── architecture/ │ ├── multi_agent/ Sub-orchestrators
│ └── archive/ │ ├── eval/ Evaluering
├── static/ │ ├── tests/ Pytest
│ └── tools/ Hjelpere
├── auth/ OAuth2-flow
├── ml/ CostGuard-engine (billing_agent, anomaly_detector, telemetry)
├── infrastructure/ GCP-scripts (0012, 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 │ ├── billing-dashboard.html
│ └── command-hub.html │ ├── command-hub.html
└── src/ ← OPAX backend │ ├── 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` > Eget repo: `vauco-saas/vauco-site` — opprettes som del av V1.
- **Region:** `europe-west1`
- **Vertex AI endpoint:** `eu` (Claude Opus 4.6) ### Formål (én linje)
- **Cloud Run service:** `osvauco-agent` 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.
- **Cloud Run URL:** `https://osvauco-agent-357036551735.europe-west1.run.app`
- **Load Balancer IP:** `34.98.77.173` ### Hvem siden er for (prioritert rekkefølge)
- **AI-modell:** `claude-opus-4-7@20260301` via Vertex AI 1. **Potensielle CostGuard-kunder** — norske bedrifter med GCP-kostnader de ikke kontrollerer (Chris sin primære salgsmotor)
- **Secret Manager:** Google OAuth2-credentials 2. **Threadstone-pilot-kunder** (Q3 2026+)
- **Billing account:** se Secret Manager 3. **Partnere og presse** — "hvem er Vauco?"
- **Kontakt:** chris.christiansen@vauco.no 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* ## 5. Dokumenthierarki — én kilde til sannhet
*Powered by OPAX · Crafted by Chris Christiansen*
| 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_<tema>.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``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:** $300500/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*

View File

@ -111,87 +111,11 @@ Phase 5 — IAP på opax.vauco.no: begrens til @vauco.no Google-kontoer
- [x] Threadstone model-temaer dokumentert - [x] Threadstone model-temaer dokumentert
- [ ] CI/CD Cloud Build trigger — forsøkt, ikke fullfort (ULØST → Phase 6) - [ ] CI/CD Cloud Build trigger — forsøkt, ikke fullfort (ULØST → Phase 6)
<<<<<<< Updated upstream
### Neste sesjon ### Neste sesjon
Fase B ferdigstilling + Phase 4 (LB + SSL migrering) Fase B ferdigstilling + Phase 4 (LB + SSL migrering)
=======
### Neste sesjon — kjør i rekkefølge
```bash ### Sesjonsavslutning 20260531-153243
cd ~/OSVauco # HUSK: alltid start her! - Start : 2026-05-31 15:32 UTC
source .env - Slutt : 2026-05-31 15:34 UTC
bash infrastructure/08-memorybank-setup.sh # A5 — sjekk om allerede kjørt - Gjort : git pull origin chore/consolidate-2026-05-31
# Etter A5: kopier MEMORY_ENGINE_NAME inn i .env og kjør source .env - Uløst : source ~/OSVauco/scripts/boot.sh
```
### 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

113
docs/ROADMAP.md Normal file
View File

@ -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 007009, 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.*

View File

@ -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.
--- **Historisk TODO-innhold** (status per 2026-05-25) er bevart i Git-historikken.
## 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``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)

View File

@ -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

View File

@ -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

View File

@ -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 (20252026)
- **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).

View File

@ -1,2 +0,0 @@
# OSVAUCO OPAX SESSION LOG [ARCHIVED]
> Arkivert 2026-05-27 — historisk sesjonslogg, erstattet av HANDOFF_20260526.md og fremtidige HANDOFF-filer.

252
docs/vauco-site/DESIGN.md Normal file
View File

@ -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` | `<body>` |
| 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: 4864px, weight 600, line-height 1.1
- H2: 3240px, weight 500
- Body: 1618px, 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
<title>Vauco — AI-moduler som leverer målbar verdi</title>
<meta name="description" content="Vauco AS bygger AI-moduler for nordiske bedrifter. CostGuard for GCP-kostnader. Threadstone for innhold.">
<meta property="og:title" content="Vauco — AI-moduler som leverer">
<meta property="og:description" content="Norskutviklet. Drevet på Google Cloud. Norsk eierskap.">
<meta property="og:image" content="https://vauco.no/assets/og-image.png">
<meta property="og:url" content="https://vauco.no">
<meta name="twitter:card" content="summary_large_image">
<link rel="canonical" href="https://vauco.no">
```
### 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.*

78
scripts/README.md Normal file
View File

@ -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.

View File

@ -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 ""

View File

@ -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 ""

View File

@ -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 " "
}

View File

@ -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 <name> <cmd>
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"

View File

@ -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

View File

@ -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 <project_id>'."
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

View File

@ -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}"

271
scripts/boot.sh Executable file
View File

@ -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

220
scripts/opax.sh Normal file → Executable file
View File

@ -1,18 +1,29 @@
#!/usr/bin/env bash #!/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 # Bruk: source ~/OSVauco/scripts/opax.sh
# Alias: opax # Alias: opax (settes av scripts/boot.sh)
#
# Modell og region er låst i docs/AGENT_RULEBOOK.md.
# ============================================================================= # =============================================================================
# --- Pre-computation and Environment --- # Definer boot-promptet som skal sendes til Gemini
OSVAUCO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" read -r -d '''' BOOT_PROMPT << 'EOM'
export GOOGLE_CLOUD_PROJECT="propane-will-491900-m5" 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.
export GOOGLE_CLOUD_LOCATION="us-central1" EOM
export GEMINI_MODEL="gemini-2.5-pro"
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')" GREEN="$(tput setaf 2 2>/dev/null || printf '\033[0;32m')"
RED="$(tput setaf 1 2>/dev/null || printf '\033[0;31m')" RED="$(tput setaf 1 2>/dev/null || printf '\033[0;31m')"
YELLOW="$(tput setaf 3 2>/dev/null || printf '\033[1;33m')" 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')" BOLD="$(tput bold 2>/dev/null || printf '\033[1m')"
NC="$(tput sgr0 2>/dev/null || printf '\033[0m')" NC="$(tput sgr0 2>/dev/null || printf '\033[0m')"
OK="" OK=""
FAIL="" FAIL=""
if [[ -z "${OPAX_LOADED-}" ]]; then run_check() {
clear local desc="$1" cmd="$2" err="$3" critical="${4:-false}"
printf "${CYAN}" printf " %-42s" "$desc"
echo " ___ _____ _ _ ___ _ _ ___ _____ " if eval "$cmd" &>/dev/null; then
echo " / _ \| ___| | | | |/ _ \| | | |/ __|| _ | " printf "${GREEN}${OK} OK${NC}
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"
else else
printf " %-40s${YELLOW}SKIP${NC}\n" "Cloud Run osvauco-agent healthy" printf "${RED}${FAIL} FAIL${NC}
printf " ${DIM}Service ikke funnet i $GOOGLE_CLOUD_LOCATION${NC}\n" "
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 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 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" gemini --prompt "$BOOT_PROMPT"
printf " ${GREEN}%-8s${NC} %s\n" "cl" "cost-lens" GEMINI_EXIT=$?
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" # EXIT-HOOK: spør om sesjons-logg etter at gemini avsluttes
printf " ${GREEN}%-8s${NC} %s\n" "sol" "avslutt" # =============================================================================
printf "\n" printf "
export OPAX_COMMANDS_SHOWN=true ${DIM}── opax-sesjon avsluttet (exit=$GEMINI_EXIT) ──${NC}
fi "
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

181
scripts/opax2.sh Normal file → Executable file
View File

@ -1,22 +1,24 @@
#!/usr/bin/env bash #!/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 # Bruk: source ~/OSVauco/scripts/opax2.sh
# Alias: opax2 # Alias: opax2 (settes av scripts/boot.sh)
# #
# Forskjell fra opax: # Krever Claude-kvote i propane-will-491900-m5 / europe-west1.
# - Bruker Claude Opus 4.7 via Vertex AI EU endpoint
# - Mater inn handoff til claude automatisk ved oppstart
# - Region: 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_PROJECT="propane-will-491900-m5"
export GOOGLE_CLOUD_LOCATION="europe-west1" export GOOGLE_CLOUD_LOCATION="europe-west1"
export VERTEX_AI_LOCATION="europe-west1"
export VERTEX_AI_ENDPOINT="eu" export VERTEX_AI_ENDPOINT="eu"
export CLAUDE_MODEL="claude-opus-4-7@20260301" 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')" GREEN="$(tput setaf 2 2>/dev/null || printf '\033[0;32m')"
RED="$(tput setaf 1 2>/dev/null || printf '\033[0;31m')" 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="✔" OK="✔"
FAIL="✗" FAIL="✗"
SKIP="▷"
run_check() { run_check() {
local description="$1" local desc="$1" cmd="$2" err="$3" critical="${4:-false}"
local command_to_run="$2" printf " %-42s" "$desc"
local error_message="$3" if eval "$cmd" &>/dev/null; then
local is_critical="${4:-false}"
printf " %-42s" "$description"
if eval "$command_to_run" &>/dev/null; then
printf "${GREEN}${OK} OK${NC}\n" printf "${GREEN}${OK} OK${NC}\n"
else else
printf "${RED}${FAIL} FAIL${NC}\n" printf "${RED}${FAIL} FAIL${NC}\n"
if [[ "$is_critical" == "true" ]]; then if [[ "$critical" == "true" ]]; then
printf "\n ${RED}${BOLD}KRITISK:${NC} ${error_message}\n" printf "\n ${RED}${BOLD}KRITISK:${NC} ${err}\n"
printf " ${YELLOW}Avbryter opax2-oppstart.${NC}\n\n" printf " ${YELLOW}Avbryter opax2-oppstart.${NC}\n\n"
return 1 return 1
else else
printf " ${YELLOW}${NC} ${error_message}\n" printf " ${YELLOW}${NC} ${err}\n"
fi fi
fi fi
} }
clear clear
printf "${MAGENTA}" printf "${MAGENTA}${BOLD}"
cat << 'LOGO' cat << 'LOGO'
___ _____ _ _ _ _ ___ ___ ____ __ __ _ _ _ ____ ___
/ _ \| _ || | | || \ | ||_ | / _ \/ ___| \ \ / /_ _| | | | | |/ ___|/ _ \
| | | | |_) || |__| || \| | | | | | | \___ \ \ \ / / _` | | | | | | | | | | |
| | | | __/ | __ || . ` | | | | |_| |___) | \ V / (_| | |__| |_| | |___| |_| |
| |_| | | | | | || |\ | _| |_ \___/|____/ \_/ \__,_|____|\___/ \____|\___/
\___/|_| |_| |_||_| \_||_____|
LOGO LOGO
printf "${NC}" printf "${NC}${BOLD}${MAGENTA} OS VAUCO / OPAX2 (Claude)${NC}${DIM} · Claude Opus 4.7${NC}\n"
printf "${DIM} --------------------------------------------------${NC}\n" printf "${DIM} ─────────────────────────────────────────────${NC}\n"
printf " ${MAGENTA}OPAX2${NC} ${DIM}Claude 4.7 · Vertex AI EU · ${GOOGLE_CLOUD_PROJECT}${NC}\n" printf " ${MAGENTA}project=${NC}%s ${MAGENTA}region=${NC}%s\n" "$GOOGLE_CLOUD_PROJECT" "$GOOGLE_CLOUD_LOCATION"
printf "${DIM} --------------------------------------------------${NC}\n\n" 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" \ printf "\n${BOLD}${MAGENTA}NESTE OPPGAVE${NC}\n"
"gcloud auth list --filter=status:ACTIVE --format='value(account)' | grep -q @" \ if [[ -f "$HANDOFF" ]]; then
"Kjør: gcloud auth login" \ sed -n '/^##.*[Nn]este [Oo]ppgave/,/^## /p' "$HANDOFF" | sed '1d;$d' | sed '/^$/d' | head -12
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"
fi fi
# opax.vauco.no IAP sjekk # =============================================================================
DOMAIN_HTTP=$(curl -s -o /dev/null -w "%{http_code}" \ # AUTO-CONTEXT: CLAUDE.md (hvis finnes) eller .gemini/GEMINI.md som fallback.
-H "Authorization: Bearer $IT" \ # Claude CLI for Vertex leser typisk CLAUDE.md i workspace-rot.
"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
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 --- cd "$OSVAUCO_DIR"
printf "${DIM} --------------------------------------------------${NC}\n" printf "${MAGENTA}${BOLD}→ Starter claude TUI...${NC}\n\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
--- claude
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. CLAUDE_EXIT=$?
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
# --- Miljø og prompt --- printf "\n${DIM}── opax2-sesjon avsluttet (exit=$CLAUDE_EXIT) ──${NC}\n"
cd "$OSVAUCO_DIR" 2>/dev/null || true printf "${BOLD}${MAGENTA}Vil du logge sesjonen nå?${NC} [Y/n]: "
export PS1="\[${MAGENTA}\]┌──(\[${CYAN}\]OPAX2:\[${BOLD}\]\w\[${NC}\])\[${NC}\]\n\[${MAGENTA}\]└─▪\[${NC}\] " read -r LOGG_ANSWER
export OPAX2_LOADED=true case "${LOGG_ANSWER:-y}" in
n|N) printf " ${DIM}OK — kjør 'sol' senere når du vil logge + commit.${NC}\n\n" ;;
printf "${BOLD}${WHITE}QUICK COMMANDS${NC}\n" *)
printf " ${MAGENTA}%-8s${NC} %s\n" "hc" "health-check" if declare -f sol >/dev/null; then sol; else bash "$OSVAUCO_DIR/scripts/opax-logg-slutt.sh"; fi
printf " ${MAGENTA}%-8s${NC} %s\n" "st" "smoke-test" ;;
printf " ${MAGENTA}%-8s${NC} %s\n" "ca" "cost-audit" esac
printf " ${MAGENTA}%-8s${NC} %s\n" "sol" "avslutt + logg"
printf "\n"

View File

@ -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" "$@"

View File

@ -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