# Install **Status:** Stages S0–S7 implemented. ## Stages | Stage | Where | Outcome | Status | |-------|-------|---------|--------| | S0 | Human | Host per [DEPLOYER_HOST.md](DEPLOYER_HOST.md) | ✅ Procedural | | S0b | Host script | Docker installed if missing | ✅ Implemented | | S1 | Host script | Repo env, `.env` from `.env.example` | ✅ Implemented | | S2 | Host script | Main + aux vision config; vision smoke | ✅ Implemented | | S3 | Host script | Stack alignment (compose docs; OpenShell owns sandbox) | ✅ Implemented | | S4 | Host script | Sandbox verify (attach) or onboard (clean host) | ✅ Implemented | | S5 | Host script | Policy overlays + skills sync via nemohermes | ✅ Implemented | | S6 | Host script | Doctor green | ✅ Implemented | | S7 | Owner + operator connect helpers | Name assistant; connect **their** SaaS/channels | ✅ Implemented | ## Platform commands (normative) All mutations: `nemohermes` / `openshell` (see [design/research/platform-notes.md](../design/research/platform-notes.md)). --- ## S0: Host baselining Follow [DEPLOYER_HOST.md](DEPLOYER_HOST.md) to prepare the host: 1. Provision a Linux host (cloud VM, bare metal). 2. Install OS updates. 3. Create a deploy user with sudo access. 4. Install `nemohermes` and `openshell` CLIs. 5. Clone this repository. ## S0b: Docker bootstrap ```bash ./scripts/bootstrap.sh # or make bootstrap ``` **Idempotent:** if Docker is already installed and running, the script exits immediately. **What it checks:** - `docker info` succeeds → skip install. - OS family detection (Debian/Ubuntu or RHEL/Fedora). - Installs Docker, adds user to `docker` group, verifies daemon. ## S1: Repository environment ```bash ./scripts/install/s1-env.sh # or make install-s1 ``` **What it does:** 1. If `.env` does not exist, copies `.env.example` to `.env`. 2. Validates that all required keys are present and non-empty: - `LUMINA_SANDBOX` — sandbox name (default: `hermes`) - `LUMINA_INFERENCE_BASE_URL` — inference endpoint URL - `LUMINA_INFERENCE_MODEL` — model identifier - `LUMINA_VISION_MODEL` — vision model identifier 3. Fails with clear messages if keys are missing or empty. **Edit `.env`** with your actual values before running S2. See `.env.example` for all keys and descriptions. **Never commit `.env` with real secrets.** It is in `.gitignore`. ## S2: Model + vision configuration ```bash ./scripts/install/s2-models.sh # or make install-s2 ``` **What it does:** 1. Loads `.env` and validates required keys. 2. Checks that `nemohermes` and `openshell` CLIs are available. 3. Verifies the inference endpoint is reachable (`/v1/models`). 4. If the OpenShell gateway is connected, configures the inference route via `openshell inference set`. 5. Runs the **vision smoke test**: - Probes `/v1/models` for `multimodal` capability tag. - Falls back to a minimal chat completion if capability tags are not exposed. 6. **Fails loudly** (non-zero exit) if vision capability cannot be confirmed. **If the gateway is not yet connected:** the script validates the endpoint and skips the `openshell` write. S3+ will handle full gateway configuration. ## S3: Stack alignment ```bash ./scripts/install.sh --stage s3 # or make install-s3 ``` **What it does:** - Documents that OpenShell manages the Hermes sandbox container. - The product compose file (`deploy/compose/docker-compose.yml`) is optional — used only for local MCP and webhook services at S7+. - No action needed for UAT attach path. **Key principle:** OpenShell owns the sandbox. The product does NOT define the sandbox in `docker-compose.yml`. ## S4: Sandbox verification or onboard ```bash ./scripts/install/s4-sandbox.sh # attach mode (default) ./scripts/install/s4-sandbox.sh --mode attach ./scripts/install/s4-sandbox.sh --mode onboard ./scripts/install/s4-sandbox.sh --mode onboard --dry-run # or make install-s4 ``` **Attach mode (default):** - Verifies the sandbox exists and is healthy. - Checks that the agent package (`agents/hermes/`) is present. - No destructive operations. **Onboard mode (clean host):** - Creates a new sandbox from the agent package using `nemohermes onboard`. - If a sandbox with the same name already exists, falls back to attach mode for safety. - Use `--dry-run` to preview without executing. ## S5: Policy overlays + skills sync ```bash ./scripts/install/s5-policy-skills.sh # policy + skills ./scripts/install/s5-policy-skills.sh --policy-only ./scripts/install/s5-policy-skills.sh --skills-only # or make install-s5 ``` **What it does:** 1. **Policy:** Applies the inference policy overlay from `policy/openshell/overlays/inference.yaml` via `nemohermes policy-add`. Existing balanced-tier presets (npm, pypi, huggingface, brew) are preserved. 2. **Skills:** Iterates skill directories under `skills/` (skipping `_lib`) and installs each via `nemohermes skill install`. Skills without `SKILL.md` are skipped with a warning. **Additive only:** policy-add never removes existing presets. Skills install is idempotent. ## Run all stages (S0b–S5) ```bash ./scripts/install.sh # or make install ``` ## Run S3–S5 only (attach path) ```bash ./scripts/install.sh --stage s3-s5 # or make install-s3-s5 ``` ## After install (S0–S6) - Verify `.env` values are correct for your environment. - Check policy: `nemohermes policy-list` - Run health checks: `make doctor` - See [SETUP_UX.md](SETUP_UX.md) for owner-facing setup after full install. - See [design/scenarios.md](../design/scenarios.md) (S1–S5) for operational scenarios. - See [OPERATIONS.md](OPERATIONS.md) for day-2 operator commands. ## S7: Owner messaging + operator connect scripts After install stages S0–S6 are complete, the operator connects the owner's SaaS integrations and messaging channels. **Safety model:** `--dry-run` is the default. Use `--apply` to perform mutations. All mutations use `nemohermes` / `openshell`. No parallel control API. ### Connect dispatcher ```bash ./scripts/connect.sh --help ./scripts/connect.sh status ./scripts/connect.sh all --dry-run # preview all targets ./scripts/connect.sh all --apply # execute all targets ``` ### Per-target connect ```bash # Name / profile (sandbox identity) ./scripts/connect.sh name --dry-run ./scripts/connect.sh name --apply # Messaging channels (WhatsApp, Email, Telegram) ./scripts/connect.sh channels --target whatsapp --dry-run ./scripts/connect.sh channels --target whatsapp --apply ./scripts/connect.sh channels --target telegram --apply ./scripts/connect.sh channels --target email --apply # Square (remote MCP — read-only tools) ./scripts/connect.sh square --dry-run ./scripts/connect.sh square --apply # QuickBooks Online (local MCP — read-only tools) ./scripts/connect.sh quickbooks --dry-run ./scripts/connect.sh quickbooks --apply # Vagaro (REST + webhooks) ./scripts/connect.sh vagaro --dry-run ./scripts/connect.sh vagaro --apply ``` ### Make targets ```bash make connect # show connect help make connect-status # show connection status make connect-name # name / profile (--dry-run) make connect-channels # channels (--dry-run) make connect-square # Square (--dry-run) make connect-quickbooks # QuickBooks (--dry-run) make connect-vagaro # Vagaro (--dry-run) make connect-all # all targets (--dry-run) ``` ### Connection state State is stored in `.local/capability_state.json` (gitignored). Status values: | Status | Meaning | |--------|---------| | `connected` | Integration is active and verified | | `skipped` | Operator or owner chose to skip | | `later` | Planned for future setup | | `error` | Connection attempt failed — needs attention | | `offline` | Not yet connected — using fixtures | ### Capability report After connecting, export a capability report compatible with the setup-education skill: ```bash # Via the connect state library (source in a script) source scripts/lib/connect_state.sh export_capability_report > /tmp/capability_report.json ``` ### Owner-safe messaging The owner never receives terminal, Docker, or editor instructions. All connect work is done by the operator using these scripts. The owner interacts with the assistant through connected channels (WhatsApp, Email, Telegram) and completes vendor browser steps (OAuth consent, BotFather, etc.) on their own devices. ## UAT host notes This repository was tested on a live host with: - `nemohermes` v0.0.93, `openshell` v0.0.85 - Sandbox: `hermes` (default) - Gateway: `nemoclaw` at `https://127.0.0.1:8080` - Inference: OpenAI-compatible endpoint with multimodal model - Docker: present and running Scripts are idempotent on this configuration.