prole/AGENTS.md
chrisfu 2477d23bab Rename prole.sh to knoe.sh and implement start/stop/restart for min mode
Co-authored-by: Junie <junie@jetbrains.com>
2026-04-22 10:02:29 -07:00

4.3 KiB

AGENTS.md — AI coding agent guide for knoe-db / Prole

What this repo is

Knoe is an infrastructure stack for deploying a Supabase-style internal developer platform (PostgreSQL, object storage, secrets, auth, observability) across K3d (local), K3s (on-prem), and GKE (cloud) environments. The Python "Prole" installer (prole/cli.py) drives all cluster setup via milestones.


Architecture overview

Dual-cluster GKE layout (prod)

Two GKE clusters in us-west3:

Cluster Context Purpose
knoe-dev-0 gke_plenary-truck-485623-p7_us-west3_knoe-dev-0 App cluster — Garage, Registry, OpenBao, Kong, GitLab, monitoring
knoe-cnpg-0 gke_plenary-truck-485623-p7_us-west3_knoe-cnpg-0 DB cluster — CNPG/PostgreSQL only

Critical: Garage must NEVER be deployed to knoe-cnpg-0. SSD quota (300 GB) is fully consumed by CNPG — all non-CNPG PVCs must use standard storage class (HDD), not standard-rwo/premium-rwo.

Deployment environments / modes

cluster_env PROLE_MODE Target
dev k3d Local K3d cluster
service k3s On-prem K3s cluster
prod k8s GKE (or other cloud)

_deployment_mode_from_env() in knoe/core/env.py converts env strings to mode strings.

Config file mapping

knoe/prole_conf.py maps environments to config files under conf/:

  • devk3d.cfg
  • servicek3s.cfg
  • prodgke.cfg

Config is layered: env-specific file overrides base. PROLE_CONF env var or conf/service/ subdirs point to the active config.


Key source locations

Path Purpose
knoe/core/env.py Core config/env helpers, secret encryption, kubeconfig resolution
knoe/core/actions.py All installer actions and unattended workflow helpers (~8k lines)
knoe/milestone.py Milestone ABC — all install steps implement this; _get_script_env() builds the env for subprocesses
knoe/prole_conf.py Config path resolution and layered loading
knoe/core/milestones.py Concrete milestone definitions
conf/gke.cfg Production GKE config (must have correct app_cluster_kubecontext / db_cluster_kubecontext)
conf/service/prod.cfg Unattended deploy config for ./deploy.sh
etc/ Shell init scripts (init_*.sh) called by milestones
k8s/ Kubernetes manifests by service
scripts/reset_clusters.sh Full cluster teardown + recreate

Developer workflows

Install dependencies

make requirements        # pip install -r prole_requirements.txt

Run tests

make test                # runs pyconv (black check) then pytest with coverage
# or directly:
PYTHONPATH=. pytest tests/

Build the prole CLI binary

make prole               # PyInstaller one-file binary → dist/prole

Interactive installer (ncurses)

./install.sh             # reads conf/gke.cfg (or PROLE_CONF)
# or via the unified launcher:
./knoe.sh install

Unattended deploy

./deploy.sh              # reads conf/service/prod.cfg

Code style

black .                  # formatter (black --check . is enforced in CI)

Secret handling

Secrets in prole.cfg are AES-GCM encrypted at rest using ${PROLE_SECRET:v1:...} tokens. On macOS, the key is in Keychain (prole-installer service); on Linux, at ~/.prole/secrets/knoe.key. OpenBao references use ${OPENBAO:kv/prole/<ns>/<leaf>#<key>}. Never store plaintext passwords in config files.


Milestone pattern

All installer steps subclass Milestone (knoe/milestone.py). They must:

  • Be UI-agnostic (no tkinter/ncurses imports)
  • Use _run_cmd() for subprocesses (handles env injection)
  • Use _get_script_env(state) to build env dicts for shell scripts — this is where KUBECONTEXT, DB_CLUSTER_KUBECONTEXT, PROLE_CONF, etc. are set

Missing init_cluster.app_cluster_kubecontext in config causes Garage to deploy to the wrong cluster.


CNPG / backup specifics

  • CNPG backups go to GCS (not Garage): gs://knoe-0-backups/ and gs://knoe-0-wal/
  • Workload Identity SA: cnpg-backup@plenary-truck-485623-p7.iam.gserviceaccount.com
  • ObjectStore manifest: k8s/prole/knoe-db-barman-objectstore-gcs.yaml
  • Setup: etc/init_cnpg_gke.sh and etc/init_cnpg_backup.sh