# Configuration Guide JWeBot configuration is a versioned profile package compiled into runtime files. Source checkout paths and Git history never contain a populated profile. ## Storage Defaults: | Purpose | Path | |---|---| | Profiles | `~/.config/jwebot/profiles/` | | Active profile | `~/.config/jwebot/current` | | Generated runtime | `~/.config/jwebot/current/generated/` | | Private state | `~/.local/state/jwebot/profiles//` | Override roots with `JWEBOT_CONFIG_ROOT` and `JWEBOT_CONFIG_STATE_ROOT`. ## Lifecycle Create: ```sh ./tools/jwebot-config.py init personal ``` Validate and activate: ```sh ./tools/jwebot-config.py validate personal ./tools/jwebot-config.py activate personal ``` Import: ```sh ./tools/jwebot-config.py import /protected/profile.tar.gz --activate ``` Redacted export: ```sh ./tools/jwebot-config.py export personal \ --output /tmp/personal-redacted.tar.gz ``` The compiler validates every component, writes a temporary `generated` directory, records SHA-256 digests in `manifest.json`, and renames it atomically. Services never read partially generated config. ## Components ### Bot `components/bot.toml` controls: - `JWEBOT_BOT_MENTION`; - the private identity note written to `JWEBOT_PRIVATE_CONTEXT_FILE`; - cloud agent name; - bounded remote memory path. ### Providers `components/providers.toml` controls: - DeepSeek base URL; - optional cloud host; - Steam owner ID; - mandatory loopback Steam proxy. API keys belong only in `secrets/runtime.env`: ```ini JWEBOT_EDGE_DEEPSEEK_API_KEY= JWEBOT_EDGE_STEAM_API_KEY= ``` Steam uses `JWEBOT_EDGE_STEAM_ID64` and `JWEBOT_EDGE_STEAM_PROXY_URL`. No source file contains a fixed friend roster. ### Runtime `components/runtime.toml` controls: - Edge and local extension enablement; - telemetry and OCR prewarm; - delivery enablement; - extension mode and transport; - publisher principal; - Host timeout and fallback; - GUI sender timeout. The OCR runtime also accepts optional environment overrides for constrained hosts: - `WECHAT_OCR_ONNX_INTRA_OP_THREADS` defaults to `1`; - `WECHAT_OCR_ONNX_INTER_OP_THREADS` defaults to `1`. These values limit RapidOCR's ONNXRuntime CPU thread pools so service restarts do not temporarily saturate the host while the OCR cache is cold. ### Debug `components/debug.toml` generates: - `JWEBOT_DEBUG_ENABLED`; - `JWEBOT_DEBUG_CAPTURE_PAYLOADS`; - `JWEBOT_DEBUG_INCIDENT_RETENTION_DAYS`; - `JWEBOT_DEBUG_SESSION_RETENTION_DAYS`; - `JWEBOT_DEBUG_INCIDENT_ROOT`; - `JWEBOT_DEBUG_SESSION_ROOT`. Message bodies, sender names, raw group identifiers, provider payloads, and environment values remain forbidden in telemetry and public incident records. Schemas live in `config/schemas/`. ### Notification `components/notification.toml` compiles to the file referenced by `JWEBOT_HEALTH_NOTIFICATION_CONFIG`. The adapter is an absolute argv array. JWeBot does not invoke a shell. The notification body is supplied on stdin, and a zero exit status confirms delivery. Provider credentials belong in the secret environment. ### Deployment `components/deployment.toml` generates root-only values: - `JWEBOT_RUNTIME_USER`; - `JWEBOT_RUNTIME_HOME`; - `JWEBOT_RUNTIME_PYTHON`; - `JWEBOT_PRODUCTION_BACKUP_ROOT`. The generated file is `current/generated/root.env`. Root deployment tooling may source only this validated file. ### Private Context `context/people.json` contains person aliases, optional identity facts, display IDs, and clock targets. It compiles to `JWEBOT_PRIVATE_CONTEXT_FILE`. Each person may also define a private `steam_id64` and `steam_aliases`. When at least one mapping is present, Steam status and playtime are strictly scoped to those mapped people and use their group display IDs. With no private mapping, the provider falls back to public friend discovery. This file is local-only PII. Default export removes all entries. ### Overrides `overrides/runtime.env` accepts non-secret `JWEBOT_*` and `WECHAT_*` values. `overrides/root.env` accepts deployment overrides. Secret-shaped keys are rejected from runtime overrides and must live under `secrets/`. ## Legacy Migration ```sh ./tools/jwebot-config.py migrate-legacy personal \ --repository /path/to/old/checkout \ --environment /protected/legacy/environment \ --activate ``` The migration: 1. archives root-level debug, incident, report, and operations material; 2. converts static aliases and bot identity into private context; 3. separates secret environment keys from non-secret overrides; 4. compiles and activates the profile; 5. leaves the source checkout unchanged. ## Runtime Compatibility The Edge CLI still reads the former `~/.config/wechat-health-watch/environment` only as a compatibility fallback. New systemd units use the generated profile directly. ## Validation ```sh ./tools/check-config.sh ./tools/check-secrets.py PATH="$PWD/.venv/bin:$PATH" ./tools/check-local.sh ```