# Production Deployment Use this runbook only after a target host has passed the zero-to-running bootstrap and staging gate. ## Inputs - clean repository snapshot; - active validated profile for the target runtime user; - configured production Python; - operator-provided SSH alias and local privilege elevation; - ready WeChat main window on display `:1`. Do not place hostnames, addresses, usernames, passwords, private keys, or profile values in the repository or command history. ## Local Gate ```sh PATH="$PWD/.venv/bin:$PATH" ./tools/check-local.sh ./tools/check-secrets.py --history ``` ## Staging Transfer a clean snapshot without `.git`, local profiles, virtualenvs, debug state, captures, databases, or archives. On the target: ```sh JWEBOT_RUNTIME_PYTHON=/opt/jwebot/venv/bin/python \ PATH="/opt/jwebot/venv/bin:$PATH" \ ./tools/check-local.sh ``` Verify the active profile: ```sh /opt/jwebot/venv/bin/python -m jwebot_config status /opt/jwebot/venv/bin/python -m jwebot_config validate ``` ## Pre-Cutover Confirm: 1. WeChat main window is visible and meets minimum geometry. 2. Edge and adaptive recorder are active with stable restart counts. 3. Adaptive and legacy OCR queues are empty. 4. Edge direct/cloud outboxes have no failed backlog. 5. Edge SQLite `quick_check` is `ok`. 6. Legacy OCR services are disabled and inactive. 7. A restorable baseline exists. ## Coordinated Cutover Elevate locally on the target and run: ```sh JWEBOT_RUNTIME_PYTHON=/opt/jwebot/venv/bin/python \ ./deploy/scripts/deploy-jwebot-production.sh \ /path/to/staged/JWeBot \ jwebot ``` The deployer prints an eight-stage progress bar and: - records root and user service topology; - copies root and user runtime files; - backs up generated configuration; - creates a SQLite online backup and runs `quick_check`; - refuses non-empty queues or an unready WeChat window; - installs the runtime; - leaves legacy OCR disabled; - verifies Edge health and adaptive restart stability; - writes and verifies backup SHA-256 checksums; - rolls back files, state, and unit topology on cutover failure; - after rollback is disarmed, grants each existing account 200 Mora, records a version-labelled movement, and sends the guarded group update announcement. The first bullet in the current `CHANGELOG.md` release section is the canonical one-sentence announcement summary. Keep it concise and user-facing. ## Post-Cutover ```sh systemctl --user is-active jwebot-edge.service systemctl --user is-active wechat-ocr-adaptive-recorder.service systemctl --user show wechat-ocr-adaptive-recorder.service \ -p NRestarts --value ``` ```sh printf '%s\n' '{"op":"health"}' | /opt/jwebot/venv/bin/python \ ~/.local/lib/wechat-health-watch/jwebot_edge.py respond ``` ```sh /opt/jwebot/venv/bin/python - <<'PY' import sqlite3 from pathlib import Path path = Path.home() / ".local/state/jwebot-edge/edge.sqlite3" print(sqlite3.connect(f"file:{path}?mode=ro", uri=True) .execute("pragma quick_check").fetchone()[0]) PY ``` Player-visible acceptance must use deliberate synthetic messages in the configured group and confirm exactly one ACK and one final response. The deployer also runs the installed release settlement tool. Its successful JSON result must report the expected account count and announcement delivery. The operation is idempotent by the full release string, so rerunning the same command never grants Mora twice: ```sh /opt/jwebot/venv/bin/python \ ~/.local/lib/wechat-health-watch/jwebot_release_update.py ``` If it reports `AnnouncementUncertainError`, inspect the configured group first. Only when the announcement is confirmed absent may the operator retry: ```sh /opt/jwebot/venv/bin/python \ ~/.local/lib/wechat-health-watch/jwebot_release_update.py \ --retry-uncertain-announcement ``` Do not repeat the full deployment to repair an uncertain announcement. The runtime cutover and version-keyed compensation may already be complete. ## Rollback If any gate fails: 1. stop further cutover attempts; 2. verify the coordinated deployer's rollback result; 3. confirm unit topology and SQLite integrity; 4. archive privacy-safe evidence under the active profile; 5. fix and rerun staging before another production attempt.