# Dev-environment values for the bloom chart - the single-node k3s cluster on the dev VM
# (deploy/k8s/README.md, M24-1). Promotion path across values-dev/-staging/-prod: see the
# chart README's "Environment overlays & promotion" section.
#
# Usage (the M24-5 CI deploy runs exactly this, pinning the tag to the pushed commit SHA):
#
#   helm upgrade --install bloom deploy/helm/bloom \
#     --namespace bloom \
#     -f deploy/helm/bloom/values-dev.yaml \
#     --set image.tag=<commit sha>
#
# Roll back to the previously-deployed SHA with `helm rollback bloom -n bloom` - immutable
# SHA tags preserve the build-once/deploy-many + rollback semantics from M15.

# The TypeScript backend (apps/server) - DEV-CUTOVER step 2 (docs/dev-cutover-runbook.md): deploy
# it ALONGSIDE the Python api against the one Postgres, but route NO user traffic to it yet.
# `ingress.server.paths` below stays empty, so server-ingress.yaml renders nothing and Traefik
# forwards nothing here - the pod comes up, /readyz proves DB connectivity, and it idles. The
# first path move (populating ingress.server with one low-risk prefix) is a separate reviewed PR.
# The image is the same-SHA `-server` artifact CI pushes on every main merge (ci-build.yml); the
# `--set image.tag=<sha>` the deploy pins resolves it via server.image.tag="" (follows image.tag).
server:
  enabled: true
  # Non-secret config only; the catalogue of keys lives in .env.example. Without BLOOM_ENV the server's
  # Settings default to "development", so the ported /metrics gate (M38-3) served the registry
  # openly while the Python api - running env=production from api.config - 404'd (#743): the
  # first moved prefix changed behavior for config reasons, not code. The k3s dev deploy is a
  # deployed instance, not a laptop; both backends must read the same environment posture.
  #
  # Runtime-twin config (#747): the side-effect-free runtime keys mirrored from the live
  # bloom-api-config, so the TS server assembles the same orchestrator wiring the Python api
  # runs and its rich GET /health reports at parity. The webhook HMAC secrets
  # (BLOOM_*_WEBHOOK_SECRET) are NOT here by design - they arrive from the shared
  # bloom-api-secrets Secret via envFrom, which is why the flipped /webhooks receiver (#758)
  # verifies signatures at parity without duplicating them in this non-secret block.
  #
  # Worker armed (dev-cutover step 4): BLOOM_JOB_WORKER_ENABLED=true starts the TS JobRunner
  # drain loop so the TS server now DRAINS the shared Postgres job queue (not just enqueues).
  # The Python worker stays running (rollback anchor + it owns the periodic scheduler, which the
  # TS app does not start); both drain concurrently, made safe by at-least-once + the event_key
  # idempotency fence, so no duplicate side effects. The TS scheduler loop is intentionally
  # unstarted, so BLOOM_SCHEDULER_ENABLED is left unset. The pool stays pinned at 4 (the step-4
  # budget assumed the worker active: Python 8 + TS 4 = 12 < ~15 Supavisor dev ceiling).
  config:
    BLOOM_ENV: "production"
    BLOOM_JOB_WORKER_ENABLED: "true"
    BLOOM_LOG_LEVEL: "INFO"
    # HARD coexistence gate (#747): Python pool 8 (api.config above) + TS pool 4 = 12, under
    # the ~15 Supavisor per-role dev ceiling. The TS pool is pinned at 4 in code
    # (apps/server/src/db.ts createDbClient max: 4); this key documents the budget the code
    # enforces and must stay in lockstep with it.
    BLOOM_DB_POOL_MAX_SIZE: "4"
    # LLM surface: openclaw through the tailnet gateway (hostAliases below pin its name).
    BLOOM_LLM_PROVIDER: "openclaw"
    BLOOM_LLM_MODEL: "openclaw/default"
    BLOOM_LLM_FALLBACK_PROVIDER: "anthropic"
    BLOOM_OPENCLAW_BASE_URL: "http://bloom-engine.tail6e7da9.ts.net:18790"
    # Engineer engine: the remote claude_code runner on its dedicated VM (M24-6 ADR).
    BLOOM_ENGINEER_ENGINE: "claude_code"
    BLOOM_ENGINE_RUNNER_URL: "http://100.94.75.123:8700"
    # GitHub App identity (non-secret); the PEM itself arrives at the path below, and the
    # token BLOOM_ENGINE_RUNNER_TOKEN via the shared bloom-api-secrets Secret.
    BLOOM_GITHUB_APP_ID: "4306723"
    BLOOM_GITHUB_APP_SLUG: "bloom-po"
    BLOOM_GITHUB_APP_PRIVATE_KEY_PATH: "/app/secrets/github-app.pem"
    BLOOM_GITHUB_DEFAULT_INSTALLATION_ID: "146785574"
    BLOOM_GITHUB_DEFAULT_ORG: "hidden-claw"
    # Persistence: the shared Supabase Postgres (DSN in the shared Secret).
    BLOOM_STORE_BACKEND: "supabase"
    BLOOM_ENGINEERS: "ada,linus,grace"
    # Collaborator roster (M11): overrides the BLOOM_ENGINEERS engineer-only fallback so the
    # roster also carries a designer. Required for M43 design tickets - the coordinator routes a
    # `kind:design` ticket to a `designer`-role collaborator; with an engineer-only roster the
    # injected design ticket is unroutable and the UI/UX flow deadlocks. Keep the three engineers
    # in sync with BLOOM_ENGINEERS above.
    BLOOM_COLLABORATORS: "ada:engineer,linus:engineer,grace:engineer,iris:designer"
    BLOOM_REVIEW_MODE: "strict"
    BLOOM_ADMIN_DASHBOARD_URL: "https://bloom-admin-bmp.pages.dev"
    BLOOM_DASHBOARD_URL: "https://bloom-dashboard-1y6.pages.dev"
    BLOOM_OAUTH_REDIRECT_BASE_URL: "https://bloom-dashboard-1y6.pages.dev"
    BLOOM_PUBLIC_BASE_URL: "https://bloom-server.exe.xyz"
    # Credential store (M19): URL/org are non-secret; client id/secret come from the Secret.
    BLOOM_INFISICAL_URL: "https://bloom-secrets.exe.xyz"
    BLOOM_INFISICAL_ORG: "949484db-3696-4b2b-b4e8-ebef6d08932e"
    BLOOM_TELEGRAM_BOT_USERNAME: "BloomBuilderBot"
    BLOOM_TELEGRAM_REQUIRE_LINK: "true"
    # UX design surface (M43, #843): the designer renders study mockups into per-project files
    # provisioned inside this Penpot project on bloom-design.exe.xyz. Provider
    # (BLOOM_DESIGN_UX_PROVIDER) defaults to penpot and the base URL defaults to the instance,
    # so only the project id is pinned here; the access token is secret and arrives via the
    # bloom-api-secrets Secret (BLOOM_PENPOT_ACCESS_TOKEN).
    # Project: "Bloom Dashboard" in the default team.
    BLOOM_PENPOT_PROJECT_ID: "15cab2bd-418a-81a7-8008-69cdfa7ccc47"
  # Tailnet peers by MagicDNS name (M17-7, #747): the server resolves the openclaw gateway +
  # engine-runner *.ts.net names through the node's tailscaled; cluster DNS cannot resolve
  # them, so they are pinned here. Tailscale IPs are stable for the life of a node.
  hostAliases:
    - ip: 100.88.252.20
      hostnames:
        - logos-gateway.tail6e7da9.ts.net
    - ip: 100.94.75.123
      hostnames:
        - bloom-engine.tail6e7da9.ts.net
  # GitHub App PEM (#747 follow-up): mount the existing bloom-github-app-key Secret (subPath
  # github-app.pem) at BLOOM_GITHUB_APP_PRIVATE_KEY_PATH so the engineer engine mints per-run
  # installation tokens - closing the last /health field (engine.runner + github_app check) to
  # parity with the Python api. The api reads the same Secret today via an out-of-band volume.
  githubAppKeySecret: "bloom-github-app-key"

# The simulator stays off in dev (as everywhere) unless a coordination-loop exercise explicitly
# enables it with its SWARM_* config + secret in place.
swarm:
  enabled: false

# Dev exposure: the exe.dev edge terminates TLS at https://bloom-server.exe.xyz and forwards
# plain HTTP to the VM. bloom-server owns the URL prefixes on that host; the dashboard SPA is
# served by Cloudflare Pages, which reverse-proxies /api back here (the same same-origin /api
# split the Pages proxy implements today). The edge targets k3s Traefik:80 (M24-5 cutover).
ingress:
  enabled: true
  className: traefik
  # Path moves to the TS -server backend (dev-cutover step 3, docs/dev-cutover-runbook.md),
  # lowest-risk first; the cutover is complete, so -server owns every prefix listed here.
  #   /metrics - read-only prom-client scrape (M38-3), fail-closed 404 in production, no
  #              orchestrator seams (first move, #742).
  #   /health  - read-only readiness payload (#745/#746); certified byte-identical to the
  #              Python api's /health except the runtime-specific `version` field after the
  #              runtime-twin activation (#747/#748) + GitHub App PEM mount (#749) brought all
  #              four runtime fields (llm_provider/engine.mode/engine.runner/correlation_store)
  #              to live parity.
  #   /api/auth/config - first /api read prefix (#752): pure GET of sign-in-method booleans
  #              (authRoutes.ts), no auth, no DB, no orchestrator seams. Traefik routes by
  #              longest-matching prefix, so this exact path moves to -server while the broader
  #              /api prefix stays on -api.
  #   /api/admin - the whole admin surface (audit log, overview, resources, actions, and the
  #              admin OIDC sign-in flow), moved as ONE auth-coherent prefix so the signed
  #              bloom_admin_session cookie is minted AND validated on the same backend (no
  #              cross-backend cookie split-brain). Route-completeness verified against the
  #              Python oracle live (every /api/admin/* route registers TS==PY) after porting
  #              the last missing route GET /api/admin/audit_log/:item_id (#754/#755). Longest
  #              -prefix routing keeps everything else under /api on -api.
  #   /api/auth, /api/projects, /api/credentials, /api/telegram - the whole user-session surface,
  #              moved as ONE auth-coherent unit (same rationale as /api/admin): every route here
  #              is gated by the user session cookie minted at /api/auth/google/callback, so mint
  #              and validate must live on one backend. /api/auth supersedes the earlier
  #              /api/auth/config move. Route-completeness verified live vs the Python oracle
  #              (every route registers TS==PY, no gaps). This includes the orchestrator-coupled
  #              project writes (POST /api/projects/:id/messages, SSE events): safe under
  #              coexistence because the TS job worker stays OFF, so the still-running Python
  #              worker remains the sole consumer draining the shared Postgres job queue that the
  #              TS producer enqueues into (the strangler design). /webhooks stays on -api.
  # Revert any prefix = move its line back under api.paths above.
  server:
    host: bloom-server.exe.xyz
    paths:
      - /metrics
      - /health
      - /api/admin
      - /api/auth
      - /api/projects
      - /api/credentials
      - /api/telegram
      #   /webhooks - the github/gitlab/telegram webhook ingress (the orchestrator entry point).
      #              HMAC-verified against the shared bloom-api-secrets, so signature validation is
      #              at parity; every route registers TS==PY live. The TS receiver enqueues into
      #              the shared Postgres job queue that the still-running Python worker drains (TS
      #              job worker stays off), so real webhook -> enqueue -> drain works cross-backend.
      - /webhooks
      #   /api - the broad catch-all, the final move: -server now owns the ENTIRE /api surface,
      #              so bloom-api receives no HTTP (its ingress is disabled above). This subsumes
      #              the granular /api/* prefixes listed above (kept for the audit trail + granular
      #              revert); Traefik sends every /api/* to -server either way. Only the inert
      #              dev-disabled /api/testing surface (404 on both backends) sat here before.
      - /api
  tls:
    # TLS lives at the exe.dev edge in dev; Traefik serves plain HTTP behind it.
    enabled: false

# No in-cluster certs in dev - the exe.dev edge fronts TLS (see ingress.tls above).
certManager:
  enabled: false
