# RUNBOOK fáze 0 — mobilní kanál: hranice VM a instalace přepravy

**Datum:** 4. 10. 2026
**Vlastník kroků:** majitel stroje (orchestrátor v této session nemá předaný nástroj
`bash`; tedy musíš spustit ty)
**Kdy spustit:** teď. Fáze 1 je zablokovaná, dokud P0.1 a P0.2 nejsou hotové.

Tento runbook **nepíše nic do repa**. Všechny kroky jsou mimo repozitář
(`~/.config/...`, `~/.config/systemd/user/...`), aby `tests/test_kilo_agent_policy.py`
zůstal zelený — `.kilo/kilo.jsonc` se nedotýkáme vůbec.

---

## P0.1 — Probe hranice VM (read-only, 9 příkazů)

Vlož do terminálu **uvnitř VM** a pošli mi výstup doslova, včetně prázdných řádků.

```bash
systemd-detect-virt
findmnt -t 9p,virtiofs,vboxsf,vboxguest,vmhgfs-fuse,cifs,nfs,sshfs -o TARGET,SOURCE,FSTYPE,OPTIONS
systemctl list-units --type=service --state=running --no-pager | grep -Ei 'vbox|vmware|virtio|spice|9p|guestadditions'
bwrap --unshare-all --share-net --ro-bind /usr /usr --ro-bind /bin /bin --ro-bind /lib /lib \
  --ro-bind /lib64 /lib64 --dev /dev --proc /proc --tmpfs /tmp \
  /bin/sh -c 'echo SANDBOX_OK; echo PID1=$(cat /proc/1/comm); echo NS=$(readlink /proc/1/ns/pid)'
readlink /proc/self/ns/pid
nproc; free -m | head -2; df -h / /home | tail -2
```

**Co z toho čtu:**
- `findmnt` → **je to sdílená složka hostitele?** (rozhodující)
- `NS=` vs `readlink /proc/self/ns/pid` → liší se? to je důkaz, že `--unshare-all` funguje
- `PID1=` → uvnitř sandboxu musí být `sh`, ne `systemd`/`init`
- `bwrap` chybí → sandbox fail-closed, `cyberbrain run` nebude fungovat vůbec

> `cyberbrain doctor` můžeš spustit taky (read-only), ale sandbox **nespouští** —
> je to hlášení dostupnosti, ne důkaz vynucení.

---

## P0.2 — Sdílená složka hostitele: ZŮSTÁVÁ, jen se ohodnotí

**Rozhodnutí vlastníka 4. 10. 2026: sdílená složka je potřebná, neodstraňuje se.**
Doporučení „odstranit“ bylo chybné: bylo vydáno bez znalosti, k čemu složka slouží.
Správná otázka je „co v ní je a zda to Kilo s `bash` čte“, ne „odstranit nebo ne“.

Krok 1 — zjistit, co to je (uvnitř VM, read-only):

```bash
findmnt -t vboxsf,9p,virtiofs -o TARGET,SOURCE,FSTYPE,OPTIONS
ls -la /media/sf_debian-12.12.0-i386-DVD-1 | head -20
```

Krok 2 — zvolit jednu ze tří možností (všechny jsou vratné, žádná nesmaže data):

| Co v ní je | Co udělat |
|---|---|
| Jen instalační ISO / instalační média (pravděpodobné podle názvu) | **Odpojit v hostu:** `umount /media/sf_debian-12.12.0-i386-DVD-1`. Konfigurace zůstává, data zůstávají, Kilo k nim vůbec nesáhne. Kdybys to potřeboval znovu, připojíš zpět. |
| Něco, co opravdu potřebuješ za běhu | **Nepřipojovat to do cesty, kterou Kilo vidí:** buď odpoj a připoj jen když pracuješ (ručně, po dobu práce), nebo host-side nastav share jako read-only (VirtualBox → Shared Folders → Read-only). |
| Něco citlivého | Tohle je jediný případ, kdy je správná rada „odstranit“. |

Doplňková kontrola, jestli se to připojí samo po startu:
`grep vboxsf /etc/fstab` — když tam je řádek, zakomentuje se, a po restartu se nepřipojí.

### Zjištěný stav 4. 10. 2026 (výstup vlastníka)

```
TARGET                                SOURCE                      FSTYPE OPTIONS
/media/sf_debian-12.12.0-i386-DVD-1   debian-12.12.0-i386-DVD-1   vboxsf rw,nodev,relatime,iocharset=utf8,uid=0,g…
ls: adresář '…' nelze otevřít: Operace zamítnuta
```

| Co z toho plyne | Význam |
|---|---|
| `vboxsf`, `rw`, `uid=0` | sdílená složka hostitele, zapisovatelná, soubory jako root |
| `Operace zamítnuta` pro uživatele `em` | **dnešní stav: Kilo jako `em` k ní nemá cestu.** Omezení drží *nepřítomnost práv*, ne zákaz |
| Obsah neověřen | `ls` selhalo, takže co v ní je, se nepotvrdilo (název ukazuje na instalační ISO) |

**Reziduum:** omezení by padlo při běhu s právami root. Pracovní režim má `bash: allow`,
takže bezheslové `sudo` ve VM by bylo jeden příkaz od otevření cesty k hostiteli.

**Proto je rozhodnutí vlastníka formulováno takto: složka v konfiguraci zůstává, ale
v pracovním režimu nesmí být připojená.** Odpojit lze bez ztráty čehokoli a připojit
zpět jedním příkazem.

Proč to vůbec řešíme: sdílená složka vede z hostitele do VM a dál do telefonu —
Kilo v pracovním režimu má `bash`, takže by přes ni šlo číst (při rw i zapisovat) do
souborů hostitele. Bezpečnostní příručka virtualizace to potvrzuje. **Nejde o to, že by
složka byla nebezpečná sama o sobě, ale o to, kdo k ní přistupuje.**

---

## P0.3 — Instalace přepravy v VM (Node běží ve VM)

```bash
npm install -g openclaw@latest
openclaw onboard            # nabídne registraci / dashboard
openclaw security audit     # VÝSTUP mi pošli — je to tvrdý fail-closed nástroj
```

**Token bota vytvoř ty** přes `@BotFather` v Telegramu. **Nikdy** ho nedávej do repa,
do `.env` v pracovním stromu ani do konfigurace, kterou by mohl číst kdokoliv. OpenClaw
pro Telegram podporuje `tokenFile` — musí to být **obyčejný soubor, ne symlink**.

```bash
install -m 600 /dev/null ~/.config/openclaw/telegram.token
# vlož token ručně, bez echo do historie:
read -rs -p "Telegram token: " T; printf '%s' "$T" > ~/.config/openclaw/telegram.token; unset T
```

---

## P0.4 — Konfigurace OpenClaw (návrh k aplikaci, vše z dokumentace nástroje)

Soubor mimo repo: `~/.config/openclaw/openclaw.json`.

```json5
{
  gateway: { mode: "local", bind: "loopback", port: 18789, auth: { mode: "token" } },
  session: { dmScope: "per-channel-peer" },
  channels: { telegram: {
      tokenFile: "~/.config/openclaw/telegram.token",
      dmPolicy: "pairing",       // nejprve párování; po prvním spojení přepni na allowlist
      groupPolicy: "disabled",   // skupiny vypnuté — nejsou v našem rozsahu
      mediaMaxMb: 50 } },
  acp: { allowedAgents: ["kilocode"] },   // KLÍČOVÉ: jinak odpovídá vlastní runtime = 2. orchestrátor
  agents: { entries: {
      safe: { runtime: { type: "acp", acp: { agent: "kilocode" } },
              tools: { profile: "messaging", exec: { security: "deny", ask: "always" },
                       fs: { workspaceOnly: true } } },
      work: { runtime: { type: "acp", acp: { agent: "kilocode" } },
              sandbox: { host: "sandbox" } } } },
  tools: { elevated: { enabled: false }, agentToAgent: { enabled: false },
           sessions: { visibility: "agent" } },
  approvals: { exec: { enabled: true, mode: "session" } }
}
```

**Dvě věci, které nesmíš vynechat:**
1. `acp.allowedAgents: ["kilocode"]` — bez toho by Telegramu odpovídal vestavěný runtime
   OpenClawu a Kilo by přestal být jediným orchestrátorem.
2. `exec.security: "deny"` v bezpečném režimu. **Nespoléhat na výchozí hodnotu**: když je
   sandbox vypnutý, implicitní `host=auto` se vyhodnotí na **gateway host**; `host=sandbox`
   naopak fail-closed.

---

## P0.5 — Služby jako systemd (zpevněné, token přes credential)

```bash
openclaw gateway install      # výchozí služba
systemctl --user cat openclaw-gateway.service   # pošli mi to, nechci psát unit naslepo
mkdir -p ~/.config/systemd/user/openclaw-gateway.service.d
```

Návrh override (aplikuj až po `systemctl --user cat`, aby se nekonfliktovalo s tím, co
vygeneruje `openclaw gateway install`):

```ini
[Service]
LoadCredential=telegram-token:%h/.config/openclaw/telegram.token
DynamicUser=yes
ProtectSystem=strict
ProtectHome=read-only
ReadWritePaths=%S/cyberbrain26 %h/.local/share/openclaw
PrivateTmp=yes
PrivateMounts=yes
NoNewPrivileges=yes
UMask=0077
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6

# Po úpravě:
systemctl --user daemon-reload && systemctl --user restart openclaw-gateway
systemd-analyze --user security openclaw-gateway.service   # skóre 0–10, pošli mi
```

**Proč `LoadCredential` a ne `chmod 600`:** credential je v době běhu neměnný, **nešíří
se do potomků** (na rozdíl od proměnné prostředí) a přístup kontroluje jádro.

---

## P0.6 — Kilo Android appka

`~/.config/kilo/config.json` (mimo repo):

```json5
{ "remote_control": true }
```

Nebo jednorázově `/remote` v TUI relaci. Kilo sám dokumentuje, že kdokoliv s přístupem
k účtu může posílat zprávy na stroj, když je remote režim zapnutý — to je zapsáno jako
revize R3 (evidence odchozí cesty).

---

## Co v této fázi NEUDĚLÁME

| Neděláme | Proč |
|---|---|
| nic v `src/`, `tests/`, `.github/`, `.kilo/kilo.jsonc` | vyžaduje výslovné schválení; navíc Gate 0 by se rozbil |
| zapnutý pracovní režim | hranice VM není prokázaná (revize R5) |
| vlastní Telegram bot v CyberBrain26 | most schválení přijde až v Gate 3 |
| Matrix, hlas, telefonování | později, každý zvlášť |

## Brána pro ukončení fáze 0

| Kritérium | Kdo ověří |
|---|---|
| výstup P0.1 je surový, s `EXIT=` kódy | ty + já |
| `vboxsf` sdílená složka odstraněna, nebo prokazatelně není sdílená složka | ty (VBoxManage) |
| `openclaw security audit` zelený | ty, výstuk sem |
| služba běží na loopbacku, `systemd-analyze security` skóre níž než výchozí | ty, výstup sem |
| revize R1–R5 zapsaná | **hotovo** — `.kilo/plans/CyberBrain26cil-031026-v2.md` |

Po tom jde Gate 1: bezpečný režim v Telegramu, read-only konverzace, pozitivní i
negativní test (cizí ID odmítnuto, text v chatu není schválení).