diff --git a/docs/HANDOFF.md b/docs/HANDOFF.md index b470ebb..d15e434 100644 --- a/docs/HANDOFF.md +++ b/docs/HANDOFF.md @@ -1,79 +1,124 @@ # HANDOFF — Vauco OS -**Sist oppdatert:** 2026-06-12 18:01 CEST +**Sist oppdatert:** 2026-06-13 06:46 CEST **Skrevet av:** Perplexity (stand-in) via GitHub MCP -**Sprint:** CG5a · CG5b · CG5c · CG5-onboard · CG6 — levert | OPAX docs-proxy + browser-panel — levert +**Sprint:** CG4-credits — credits-panel levert, IAP-test blokkert --- -## ✅ Gjort denne sesjonen (2026-06-12 — kveld) +## ✅ Gjort denne sesjonen (2026-06-13 — morgen) | Commit | Task | Detalj | |--------|------|--------| -| [`a773ec2`](https://github.com/vauco-saas/OSVauco/commit/a773ec26fcedb2540dc5a04acdf71269d704dc63) | **DOCS PROXY** `main.py` | `GET /docs/{path}` — henter MD-filer fra privat repo via `GITHUB_PAT` (Secret Manager). Feiler pent med `503` hvis token mangler, `504` ved timeout. `DOCS_BRANCH` env-var støtte (default `main`). | - -### Neste steg for OPAX browser-panel (ikke pushet ennå) - -Frontend-kode er klar men **ikke pushet** til `opax.html`. Gjenstår: -- Nav-item `🌐 Browser` i sidebar -- `#panel-browser` med iframe + URL-bar -- MD-fetch byttes fra `GH_RAW` → `/docs/` proxy -- `browserNav()` / `browserFrameLoad()` / `browserFrameError()` JS - -Årsak ikke pushet: vi avventer YTT-bygg av `/docs`-proxyen for å verifisere at Cloud Run bygger ok — deretter pusher vi `opax.html` i neste sesjon. +| [`f58ec09`](https://github.com/vauco-saas/OSVauco/commit/f58ec09d4c076b6e552eb06593e919c385673492) | **CG4-credits** `static/billing-dashboard.html` | Credits-panel lagt til: 4 KPI-kort (brukt/gjenstår/burn/runway), animert progress-bar, advarselsbanner, kreditter-per-type liste. Auto-poll hvert 5 min via `fetchCredits()` i `fetchAll()`. | +| Eksisterende | **CG4-credits** `ml/billing_agent.py` | `get_credits_status(days=90)` allerede implementert — 4 BQ-queries, runway-beregning, `GOOGLE_CREDIT_TOTAL_USD` env-var støtte. | +| Eksisterende | **CG4-credits** `main.py` | `GET /billing/credits` rute allerede registrert og koblet til `BillingAgent.get_credits_status()`. | --- -## ✅ Gjort tidligere i dag (2026-06-12 — formiddag/ettermiddag) +## 🔴 Blokkert — `GET /billing/credits` ikke testet i prod + +### Problem 1: `cloud-run-proxy` ikke installert på dev-VM + +``` +gcloud run services proxy ... → krever cloud-run-proxy component +``` + +**Fix:** +```bash +gcloud components install cloud-run-proxy + +gcloud run services proxy osvauco-agent \ + --region=us-central1 \ + --project=propane-will-491900-m5 \ + --port=8080 +# (kjør i Terminal 1 — ikke bakgrunn) + +# Terminal 2: +curl -s "http://localhost:8080/billing/credits?days=90" | python3 -m json.tool +``` + +### Problem 2: `https://opax.vauco.no/billing/credits` returnerer tom respons + +IAP-token er gyldig, men Cloud Run returnerer HTML-feilside i stedet for JSON. +Sannsynlig årsak: `user:chris.christiansen@vauco.no` mangler `roles/run.invoker`. + +**Diagnose:** +```bash +curl -sv -H "Authorization: Bearer $(gcloud auth print-identity-token)" \ + "https://opax.vauco.no/billing/credits" 2>&1 | head -30 +``` + +**Fix hvis 403:** +```bash +gcloud run services add-iam-policy-binding osvauco-agent \ + --region=us-central1 \ + --project=propane-will-491900-m5 \ + --member="user:chris.christiansen@vauco.no" \ + --role="roles/run.invoker" +``` + +### Problem 3: `GOOGLE_CREDIT_TOTAL_USD` ikke satt + +Inntil denne er satt returnerer `/billing/credits` `"credit_runway_days": null`. + +**Fix (enklest — vanlig env-var er nok for et tall):** +``` +GCP Console → Cloud Run → osvauco-agent → Edit & Deploy +→ Variables & Secrets → Add Variable +→ GOOGLE_CREDIT_TOTAL_USD = 300 +``` + +--- + +## 🔴 NESTE OPPGAVE — for Nemotron + +**Jobb:** Verifiser `GET /billing/credits` end-to-end i prod. + +``` +STEG 1 — Installer proxy + gcloud components install cloud-run-proxy + +STEG 2 — Test via proxy (ingen IAP-styr) + gcloud run services proxy osvauco-agent --region=us-central1 --project=propane-will-491900-m5 --port=8080 + curl -s http://localhost:8080/billing/credits?days=90 | python3 -m json.tool + +STEG 3 — Sjekk om kreditter faktisk finnes i BQ + bq query --use_legacy_sql=false \ + 'SELECT credit_type, SUM(amount) FROM `propane-will-491900-m5.billing_export.gcp_billing_export_v1_*`, UNNEST(credits) AS credit_type, amount GROUP BY 1 LIMIT 10' + +STEG 4 — Sett GOOGLE_CREDIT_TOTAL_USD i Cloud Run env + +STEG 5 — Verifiser runway vises i billing-dashboard.html +``` + +--- + +## ✅ Gjort forrige sesjon (2026-06-12 — kveld) | Commit | Task | Detalj | |--------|------|--------| -| [`c312f4a`](https://github.com/vauco-saas/OSVauco/commit/c312f4a7274f65eb213477956854977df10d7a7a) | MASTERPLAN seksjon 10 | Prismodell v2: Starter $499 / Guard $999 / Shield $1.999 / Enterprise $3.500+ | -| [`7aa7384`](https://github.com/vauco-saas/OSVauco/commit/7aa73842d46b2b65610358c0ff8e456b2189e7f4) | MASTERPLAN seksjon 4 | Korrekt repo-layout dokumentert | -| [`50490b0`](https://github.com/vauco-saas/OSVauco/commit/50490b071d5b80252ea32e8db3226064ac9c80c0) | **CG5-onboard** `static/onboard.html` | 4-stegs onboarding-wizard (mørkt CostGuard-tema) | -| [`c3357d3`](https://github.com/vauco-saas/OSVauco/commit/c3357d38aa71f13dd06726800a2c57425d6bd1ac) | **CG5-onboard** `main.py` | `GET /onboard` (IAP-exempt) + `POST /onboard/complete` (Firestore + varsler) | -| [`5270166`](https://github.com/vauco-saas/OSVauco/commit/5270166ce13bdbea9e6009e5d1ce3529001afba6) | **CG6** `static/costguard-dashboard.html` | Klient-dashboard — billing summary, anomalier, modul-donut, delivery-kanaler | -| [`f7e64fc`](https://github.com/vauco-saas/OSVauco/commit/f7e64fcea07ea2b1f0c3c898bf798da49a7e2993) | **CG5c** `main.py` | `POST /notify/sms` — Twilio REST via httpx, Guard+-tier, 402 ved feil tier | -| [`4a1e23e`](https://github.com/vauco-saas/OSVauco/commit/4a1e23e077f2bcb508854c41c47a4d26f82f0124) | **CG5a+CG5b** `main.py` | `NotificationService` + `POST /notify/webhook` + `POST /notify/email` | -| [`21efdc4`](https://github.com/vauco-saas/OSVauco/commit/21efdc4e9511376393a8731a7db4568ea756fe8c) | **CG4d** `opax.html` | Prisingskalkulator panel — GCP-spend slider, tier-highlight, ROI-estimat | +| [`a773ec2`](https://github.com/vauco-saas/OSVauco/commit/a773ec26fcedb2540dc5a04acdf71269d704dc63) | **DOCS PROXY** `main.py` | `GET /docs/{path}` — henter MD-filer fra privat repo via `GITHUB_PAT` | -### Notification-arkitektur (komplett) +## ✅ Gjort 2026-06-12 — formiddag -| Endepunkt | Metode | Kanal | Tier | -|-----------|--------|-------|------| -| `POST /notify/webhook` | CG5a | Slack / Teams / Chat / Discord / custom | Alle | -| `POST /notify/email` | CG5b | SendGrid digest | Alle | -| `POST /notify/sms` | CG5c | Twilio SMS — spike-varsler | Guard+ | - -**Merk:** `GET /onboard` er IAP-exempt — tilsiktet for nå, skal vurderes ved hardening. +| Commit | Task | +|--------|------| +| [`50490b0`](https://github.com/vauco-saas/OSVauco/commit/50490b071d5b80252ea32e8db3226064ac9c80c0) | **CG5-onboard** `static/onboard.html` | +| [`c3357d3`](https://github.com/vauco-saas/OSVauco/commit/c3357d38aa71f13dd06726800a2c57425d6bd1ac) | **CG5-onboard** `main.py` — `GET /onboard` + `POST /onboard/complete` | +| [`5270166`](https://github.com/vauco-saas/OSVauco/commit/5270166ce13bdbea9e6009e5d1ce3529001afba6) | **CG6** `static/costguard-dashboard.html` | +| [`f7e64fc`](https://github.com/vauco-saas/OSVauco/commit/f7e64fcea07ea2b1f0c3c898bf798da49a7e2993) | **CG5c** `POST /notify/sms` — Twilio | +| [`4a1e23e`](https://github.com/vauco-saas/OSVauco/commit/4a1e23e077f2bcb508854c41c47a4d26f82f0124) | **CG5a+CG5b** `POST /notify/webhook` + `POST /notify/email` | --- -## ✅ Gjort forrige sesjon (2026-06-11) - -| Task | Detalj | -|------|--------| -| **CG4b** | Chart.js donut live — build 2f385fe3 ✅ | -| **Medioteq** | Joint venture presisert — ikke SaaS-kunde | - ---- - -## 🔴 Kjente OQ-er (Open Questions) +## 🔴 Kjente OQ-er | ID | Beskrivelse | Prioritet | |----|-------------|-----------| -| **OQ-29** | `GET /notify/channels` mangler — ingen list-endepunkt for å hente konfigurerte delivery-kanaler per kunde | Lav / neste sprint | -| **OQ-30** | `opax.html` browser-panel + MD-proxy-fix ikke pushet — venter på YTT-bygg-verifisering | Høy — neste sesjon | - ---- - -## 🔴 NOW — Neste oppgaver (prioritert) - -| ID | Oppgave | Status | -|----|---------|--------| -| **OQ-30** | Push `opax.html` med browser-panel + MD→`/docs/` fix | ⏳ Første oppgave neste sesjon | -| **CG7** | Scope defineres av Chris — **ikke start uten direktiv** | ⏳ Venter på MASTERPLAN-definisjon | -| **OQ-29** | `GET /notify/channels` | Backlog | +| **OQ-29** | `GET /notify/channels` mangler | Lav | +| **OQ-30** | `opax.html` browser-panel ikke pushet | Høy | +| **OQ-31** | `GOOGLE_CREDIT_TOTAL_USD` ikke satt i Cloud Run | Høy — blokkerer runway | | **ML-3a** | `docs/gemma/world.md` mangler — blokkerer Emma | Blokkert | --- @@ -85,17 +130,17 @@ Frontend-kode er klar men **ikke pushet** til `opax.html`. Gjenstår: | Cloud Run `osvauco-agent` | ✅ Live `us-central1` | | `opax.vauco.no` | ✅ Live | | `main.py` | ✅ Hovudapp — alle ruter her | -| `static/opax.html` | ✅ Live — browser-panel MANGLER ennå | -| `static/jason.html` | ✅ Live | -| `static/onboard.html` | ✅ Live — CG5-onboard | +| `GET /billing/credits` | ✅ Rute finnes — ⚠️ IKKE testet i prod | +| `ml/billing_agent.py` `get_credits_status()` | ✅ Implementert | +| `static/billing-dashboard.html` | ✅ Credits-panel live (CG4-credits) | | `static/costguard-dashboard.html` | ✅ Live — CG6 | -| `opax-mcp/` | ✅ MCP-server mappe | -| `GET /docs/{path}` | ✅ Levert — venter på YTT-bygg | -| `POST /notify/webhook` | ✅ CG5a — levert | -| `POST /notify/email` | ✅ CG5b — levert | -| `POST /notify/sms` | ✅ CG5c — levert (Guard+) | -| `GET /notify/channels` | 🔴 OQ-29 — mangler | +| `static/opax.html` | ✅ Live — browser-panel MANGLER | +| `POST /notify/webhook` | ✅ CG5a | +| `POST /notify/email` | ✅ CG5b | +| `POST /notify/sms` | ✅ CG5c (Guard+) | +| `GET /notify/channels` | 🔴 OQ-29 | | `docs/gemma/world.md` | ❌ Mangler — blokkerer ML-3a | +| `GOOGLE_CREDIT_TOTAL_USD` | 🔴 Ikke satt — runway vises ikke | --- @@ -111,12 +156,11 @@ Frontend-kode er klar men **ikke pushet** til `opax.html`. Gjenstår: | Hovudapplikasjon | `main.py` (rot i repo) | | MCP-server | `opax-mcp/` | | Static filer | `static/` | -| Jason chat | `https://opax.vauco.no/static/jason.html` | -| Onboarding | `https://opax.vauco.no/onboard` | +| IAP curl | `gcloud auth print-identity-token` — **ingen `--audiences`** | | LB IP | `34.98.77.173` | | Repo | `vauco-saas/OSVauco` | | Eier | `chris.christiansen@vauco.no` | -| Jason | `jason.vauger@vauco.no` | +| Jason | `jason.vauger@vauco.no` · `gemini-2.5-flash` | | Emma | `emma.vauger@vauco.no` — 🔮 ML-3a | --- @@ -124,56 +168,28 @@ Frontend-kode er klar men **ikke pushet** til `opax.html`. Gjenstår: ## Env-vars påkrevd ``` -# CG5c — Twilio SMS +GOOGLE_CREDIT_TOTAL_USD=300 # 🔴 MANGLER — sett i Cloud Run env TWILIO_ACCOUNT_SID=ACxxxx TWILIO_AUTH_TOKEN=xxxx TWILIO_FROM_NUMBER=+47xxxxxxxx - -# DOCS proxy — hent fra Secret Manager -GITHUB_PAT=ghp_xxxx # repo:read scope på vauco-saas/OSVauco -DOCS_BRANCH=main # valgfri, default main +GITHUB_PAT=ghp_xxxx +DOCS_BRANCH=main ``` --- -## CostGuard — prismodell v2 (fasit) - -| Tier | GCP-spend/mnd | Pris | -|------|--------------|------| -| Starter | $0–$3k | $499/mnd | -| Guard | $3k–$15k | $999/mnd | -| Shield | $15k–$50k | $1.999/mnd | -| Enterprise | >$50k | $3.500+/mnd | - -**Push-first:** Jason leverer til webhook/e-post/SMS — kunden setter opp kanal ved onboarding. - ---- - -## ⚠️ Regler +## ⚠️ Regler (uendret) - **Hovudapp er `main.py`** — ikke `agents/core-logic/app.py` - **MCP-server er `opax-mcp/`** — ikke `agents/mcp_server/` - **Absolutte stier i Python** — `Path(__file__).parent / "..."` - **Ikke migrer fra us-central1** +- **IAP curl: ingen `--audiences`** — bare `gcloud auth print-identity-token` - **Ikke rør IAP/OAuth** uten `DEPLOY GODKJENT` - **Ikke opprett repos** uten `REPO APPROVED` - **Medioteq = joint venture** — ikke SaaS-kunde -- **Prismodell låst** — ikke endre uten `PLAN APPROVED` - **CG7 er ikke definert** — ikke start uten direktiv fra Chris -- **Verifiser alltid mappestruktur** via GitHub API før du bygger --- -## 📁 Filer (i prioritert rekkefølge) - -1. `docs/MASTERPLAN.md` — autoritativ sannhet -2. `docs/ROADMAP.md` — hva skjer nå -3. `docs/HANDOFF.md` — denne filen -4. `CLAUDE.md` — kontekst for Claude (rot) -5. `docs/AGENT_RULEBOOK.md` -6. `docs/UNIVERSAL_BOOT_PROMPT.md` v1.4 -7. `docs/gemma/world.md` ❌ mangler - ---- - -*Vauco AS · propane-will-491900-m5 · us-central1 · Sesjon avsluttet 2026-06-12 18:01 CEST* +*Vauco AS · propane-will-491900-m5 · us-central1 · Sesjon avsluttet 2026-06-13 06:46 CEST*