# Factory env-var contract

Every upstream factory script reads these env vars. Consumers (foxhop ecdsa, any future lumbda-driven research repo) set them before sourcing or exec'ing factory scripts. Defaults assume a generic lumbda development setup; consumers override for their domain.

## Path knobs

| Var | Default | Purpose |
|---|---|---|
| `LUMBDA_REPO_DIR` | `$HOME/git/lumbda` | Git repo to `git pull --ff-only origin master` at top of every emit-loop iter. Consumers override to their own repo (e.g. foxhop sets `$HOME/git/www.foxhop.net`). |
| `LUMBDA_FACTORY_DIR` | `$LUMBDA_REPO_DIR/factory` | Where upstream factory scripts live. Used for inter-script `exec`/`source` resolution. |
| `LUMBDA_QUEUE_DIR` | `/tmp/lumbda-queue` | Runtime queue + DLQ + rDLQ + supervisor.config home. One per running factory instance. |
| `LUMBDA_DOMAIN_DIR` | unset | Optional domain root (consumer repo's working subdir). Foxhop sets `$HOME/git/www.foxhop.net/ecdsa`. Scripts that resolve `.lsp` cell paths look here. |

## Backend knobs

| Var | Default | Purpose |
|---|---|---|
| `LUMBDA_BACKEND_CMD` | `bend-cuda` | Command the dispatcher exec's per cell. Receives `--portal <bin-path>` as first arg. Consumers point at their compiled backend binary. |
| `LUMBDA_BACKEND_PROC_PATTERN` | `bend-cuda` | `pgrep -f` pattern to count running backend forks for VRAM accounting. Usually same basename as `LUMBDA_BACKEND_CMD`. |
| `LUMBDA_EMITTER_CMD` | unset | Optional emit-side command run by `bend-emit-pool` per `.lsp` cell. If unset, pool only manages queue lifecycle (no emit). Foxhop sets a full `lumbda --fast .../emit-stream.lsp` invocation. |

## Remote knobs

| Var | Default | Purpose |
|---|---|---|
| `LUMBDA_REMOTE` | unset (local) | SSH target (e.g. `user@host`) for remote factory ops. Empty = run locally. |
| `LUMBDA_REMOTE_SSH_OPTS` | `-o BatchMode=yes -o ConnectTimeout=10` | SSH options for remote calls. |

## Autoscaler V2 knobs (all already env-var-gated in source)

| Var | Default | Purpose |
|---|---|---|
| `AUTOSCALER_V2` | `1` | `0` falls back to V1 controller (legacy). |
| `AUTOSCALER_PEAK_INITIAL` | `4096` | Initial per-worker VRAM estimate (MiB). |
| `AUTOSCALER_CPU_CEILING` | `30` | Total worker hard cap (cores + modest oversub). |
| `AUTOSCALER_DLQ_DAMPING_THRESHOLD` | `10` | DLQ entries-per-poll above which damping fires. |
| `AUTO_PULL_MASTER` | `1` | Auto-pull at top of each emit iter (0 disables). |
| `AUTO_PULL_TIMEOUT` | `30` | Seconds for git pull. |
| `LUMBDA_AUTO_PULL_DIRS` | `$LUMBDA_REPO_DIR` | Colon-separated repo dirs to pull each iter. Consumer with both upstream lumbda + domain repo sets e.g. `$HOME/git/lumbda:$HOME/git/www.foxhop.net`. Both pull `--ff-only origin master`; either failure logged as PULL-FAIL but does not abort emit. |
| `TIER_<NAME>_DISPATCH_CEILING` | 24/16/12/6/1 | Per-tier hard cap (micro/small/medium/large/huge). |
| `TIER_<NAME>_MAX` | varies | Per-tier bin-size ceiling (MiB). See `lib-tier.sh`. |
| `TIER_CONFIG_LIVE_RELOAD` | `1` | Dispatcher re-reads supervisor.config per dispatch (no restart needed). |

## Discipline

- Defaults stay generic. Consumers override via wrapper scripts that `export` then `exec`.
- Scripts NEVER hardcode `/tmp/ecdsa-queue`, `bend-cuda`, host names, or repo paths. Always read from env.
- New knobs land with default + table entry above. CHANGELOG entry on add.
- `LUMBDA_FACTORY_DIR/CONTRACT.md` (this file) stays single source of truth; never duplicate var docs in script comment blocks beyond a one-line pointer.

## Consumer wrapper pattern

```bash
#!/bin/bash
# foxhop ecdsa/scripts/bend-supervisor — wraps upstream lumbda factory
export LUMBDA_REPO_DIR="$HOME/git/www.foxhop.net"
export LUMBDA_DOMAIN_DIR="$HOME/git/www.foxhop.net/ecdsa"
export LUMBDA_QUEUE_DIR="/tmp/ecdsa-queue"
export LUMBDA_BACKEND_CMD="$LUMBDA_DOMAIN_DIR/cuda/bend-cuda"
export LUMBDA_EMITTER_CMD="lumbda --fast $LUMBDA_DOMAIN_DIR/lumbda/emit-stream.lsp"
exec "$HOME/git/lumbda/factory/bend-supervisor.sh" "$@"
```
