# Sanad Package 2 — Premium Communication Superset of P1. Dashboard on **:8012**. **Self-contained** — vendors the SanadV3 engine + the BLE Mask lib under `vendor/`, builds `FROM python:3.10-slim` with no `sanad-base`/`Sanad_Core`/sibling checkout. Full design: **[PLAN.md](PLAN.md)**. P2 = everything P1 does **+** multilingual auto-detect, voice-command **arm gestures**, gestures while speaking, wake-phrases, skills, and a lip-syncing LED "Shining Mask". (Voice-command **locomotion** is deferred to a later pass.) ## Quick start (how to start) On the robot, **from this folder** (`Sanad_Package_2/`): ```bash cp .env.example .env # optional: license / audio / mask MAC docker compose up -d --build # build (vendored engine + mask + chest-audio SDK) + run # Jetson Docker without buildx: DOCKER_BUILDKIT=0 docker compose up -d --build ``` Open **http://<robot-ip>:8012** (ships **keyless**): 1. **Gemini API key** card → paste your key. 2. **Persona** card → who the robot is (the bilingual prompt drives multilingual auto-detect). 3. **Audio** card → chest vs USB/Anker; **Mask** tab → connect the LED face, lip-sync test. 4. **Live-voice** tab → enable voice-command arm gestures (default OFF). Press **Start** and talk. > P2 needs a license that **entitles P2** — the bundled `license/sanad.lic.example` > entitles P1+P2+P3 for demo. The **LED mask** must be paired/in range and **freed > from the phone app**. `bleak` is pinned to **0.22.3** (BlueZ 5.53 compat). Manage it: `docker compose logs -f` · `docker compose down` · `./test_p2.sh :8012`. Auto-start on boot: `sudo systemctl enable docker` (compose runs `restart: unless-stopped`). Brand-new robot (build + sign a P2 license) → **[NEW_ROBOT_SETUP.md](NEW_ROBOT_SETUP.md)**. ## What it ships - `app_p2.py` — launcher: bootstraps `Project.Sanad` + the flat Mask path, constructs the P2 superset (comms + arm + `FaceController` mask), wires lip-sync (Gemini `[[MOUTH:n]]` markers → `mask_face.set_mouth`), gestures-while-speaking, lifelike face state, and the arm motion-block interlock seam (no-op while loco deferred); mounts the P1 + premium routers; serves the SanadV3 SPA (non-P2 tabs hidden) on :8012. - `routes_p2.py` — `/api/p2/*` convenience routes (api-key, persona, say, logs, settings) with live-session restart. - `vendor/Sanad` (SanadV3 engine) · `vendor/sanad_pkg` (license+bus) · `vendor/mask` (flat BLE Shining-Mask lib, own path via `SANAD_MASK_DIR=/app/mask`). - `Dockerfile` (+ BlueZ/D-Bus, `bleak==0.22.3`, Pillow) · `docker-compose.yml` (BLE mounts: `/var/run/dbus`, `NET_ADMIN`, `/dev/bus/usb`) · `entrypoint.sh` (license gate `P2` → resolve env → preflight → launch) · `sync_vendor.sh`. ## Dashboard (:8012) — all P1 tabs **+** Live-voice (commands) · Wake-phrases · Motion/Gestural (arm only) · Skills · **Mask/Lip-sync** (`/api/mask/*`: connect, brightness, face start/stop, speaking, mouth, expressions, status) · Logs · Voice (multilingual). ## License features `multilingual`, `voice_command_motion` (arm gestures), `lipsync`, `mask` (entrypoint checks entitlement **P2**). A future `voice_command_locomotion` feature gates the deferred walking. ## Status Built + structurally validated on the workstation (compile, import resolution, shim-symbol coverage, namespace bootstrap, `license_check P2` entitled, YAML). **Pending:** Docker build + on-robot test (chest audio + arm work; **mask lip-sync needs the physical BLE mask** paired and freed from the phone app). See PLAN.md "Open decisions" for the in-container-BLE confirmation.