diff --git a/docs/CostCheckProtocol.md b/docs/CostCheckProtocol.md new file mode 100644 index 0000000..e015d6c --- /dev/null +++ b/docs/CostCheckProtocol.md @@ -0,0 +1,71 @@ +# OSVauco Cost Check Protocol + +> Implements OSVauco-NMTMD-GCOS § Cost Management — sist oppdatert 2026-05-23 + +## Når skal 09-cost-check.sh kjøres? + +| Situasjon | Handling | +|---|---| +| Før du starter arbeid for dagen | Kjør for se hva som fortsatt kjører fra forrige sesjon | +| Agenten booter og `MEMORY_ENGINE_NAME` er tom | Kjør for sjekke om instans allerede finnes | +| Før teardown | Kjør for bekrefte hva som vil bli slettet | +| Mistanke om uventet kostnad | Kjør umiddelbart | + +## Kjør protokollen + +```bash +cd ~/OSVauco +source .env +bash infrastructure/09-cost-check.sh +``` + +## Hva den sjekker + +| Punkt | Ressurs | Koster løpende? | +|---|---|---| +| [1] | Cloud Run services | Ja, per request + CPU | +| [2] | Reasoning Engines / Memory Bank | **Ja, kontinuerlig** | +| [3] | Artifact Registry | Litt, per GB lagret | +| [4] | RAG Corpora | Minimal | +| [5] | GCS Buckets | Minimal | +| [6] | Budget alerts | Sjekker at varsler er aktive | + +## Memory Bank — spesialregel + +Memory Bank (Vertex AI Reasoning Engine) **slettes ikke av `03-teardown.sh`** og +faktureres kontinuerlig: + +- **$0.0994/vCPU-time** +- **$0.0105/GiB-time** +- Gratis tier: 180 000 vCPU-sekunder/mnd + +Hvis `09-cost-check.sh` punkt [2] viser aktive instanser du ikke trenger: + +```bash +gcloud ai reasoning-engines delete ENGINE_NAME \ + --project=$PROJECT_ID --region=$REGION --quiet +``` + +## Agentprotokoll + +Alle agenter som bruker Memory Bank skal ved boot sjekke: + +```python +import os +if not os.getenv("MEMORY_ENGINE_NAME"): + raise RuntimeError( + "MEMORY_ENGINE_NAME ikke satt i .env. " + "Kjør: source .env && bash infrastructure/09-cost-check.sh " + "for å se eksisterende instanser." + ) +``` + +## Teardown-regel (obligatorisk) + +```bash +# Hver kveld: +source .env +bash infrastructure/09-cost-check.sh # se hva som kjører +bash infrastructure/03-teardown.sh # rydd ned Cloud Run + IAM +# Memory Bank: slett manuelt hvis ikke i bruk +``` diff --git a/infrastructure/09-cost-check.sh b/infrastructure/09-cost-check.sh new file mode 100644 index 0000000..5c73e38 --- /dev/null +++ b/infrastructure/09-cost-check.sh @@ -0,0 +1,96 @@ +#!/usr/bin/env bash +# 09-cost-check.sh — Daily cost and resource audit protocol +# Run before teardown OR when agents boot and MEMORY_ENGINE_NAME is unset +# Usage: source .env && bash infrastructure/09-cost-check.sh +# OSVauco-NMTMD-GCOS — Implements cost protocol from CostManagementRules.md + +set -euo pipefail + +: "${PROJECT_ID:?Set PROJECT_ID in .env}" +: "${REGION:?Set REGION in .env}" + +echo "=== 09: OSVauco Cost & Resource Audit ===" +echo " Project : ${PROJECT_ID}" +echo " Region : ${REGION}" +echo " Time : $(date '+%Y-%m-%d %H:%M %Z')" +echo "==========================================" +echo "" + +# ── 1. Cloud Run services ────────────────────────────────────────────────── +echo "[1] Cloud Run services (active = billing):" +gcloud run services list \ + --project="${PROJECT_ID}" \ + --region="${REGION}" \ + --format="table(name,status.url,status.conditions[0].status)" 2>/dev/null \ + || echo " (none found or API not enabled)" +echo "" + +# ── 2. Vertex AI Reasoning Engines (Memory Bank instances) ──────────────── +echo "[2] Vertex AI Reasoning Engines / Memory Bank instances:" +echo " COST: ~\$0.0994/vCPU-hour + \$0.0105/GiB-hour after free tier" +ENGINES=$(gcloud ai reasoning-engines list \ + --project="${PROJECT_ID}" \ + --region="${REGION}" \ + --format="table(name,displayName,createTime)" 2>/dev/null || echo "") + +if [[ -z "$ENGINES" || "$ENGINES" == *"Listed 0 items"* ]]; then + echo " ✓ No active Reasoning Engine / Memory Bank instances found." +else + echo "$ENGINES" + echo "" + echo " ⚠️ ACTIVE INSTANCES FOUND — these cost money continuously." + echo " To delete manually:" + echo " gcloud ai reasoning-engines delete ENGINE_NAME \\" + echo " --project=${PROJECT_ID} --region=${REGION} --quiet" +fi +echo "" + +# ── 3. Artifact Registry repositories ──────────────────────────────────── +echo "[3] Artifact Registry repositories:" +gcloud artifacts repositories list \ + --project="${PROJECT_ID}" \ + --location="${REGION}" \ + --format="table(name,format,sizeBytes)" 2>/dev/null \ + || echo " (none found)" +echo "" + +# ── 4. RAG Corpora (NOT deleted by teardown) ────────────────────────────── +echo "[4] Vertex AI RAG Corpora (NOT deleted by teardown — manual cleanup only):" +gcloud ai rag-corpora list \ + --project="${PROJECT_ID}" \ + --region="${REGION}" \ + --format="table(name,displayName,createTime)" 2>/dev/null \ + || echo " (none found or API not enabled)" +echo "" + +# ── 5. GCS Buckets ──────────────────────────────────────────────────────── +echo "[5] GCS Buckets (NOT deleted by teardown):" +gcloud storage buckets list \ + --project="${PROJECT_ID}" \ + --format="table(name,location,storageClass)" 2>/dev/null \ + || echo " (none found)" +echo "" + +# ── 6. Budget alert status ──────────────────────────────────────────────── +echo "[6] Billing budget alerts:" +BILLING_ACCOUNT_ID="${BILLING_ACCOUNT_ID:-}" +if [[ -n "$BILLING_ACCOUNT_ID" ]]; then + gcloud billing budgets list \ + --billing-account="${BILLING_ACCOUNT_ID}" \ + --format="table(displayName,amount.specifiedAmount.units,thresholdRules.len())" 2>/dev/null \ + || echo " (none found or billing API not enabled)" +else + echo " (BILLING_ACCOUNT_ID not set in .env — skipping)" +fi +echo "" + +# ── Summary ─────────────────────────────────────────────────────────────── +echo "==========================================" +echo " AUDIT COMPLETE — $(date '+%Y-%m-%d %H:%M %Z')" +echo "" +echo " OBLIGATORISK: Kjør teardown på slutten av arbeidsdagen:" +echo " source .env && bash infrastructure/03-teardown.sh" +echo "" +echo " Reasoning Engines / Memory Bank må slettes MANUELT hvis ikke i bruk." +echo " Se punkt [2] ovenfor." +echo "=========================================="