$npx -y skills add SafeAI-Lab-X/ClawKeeper --skill parallels-discord-roundtripRun the macOS Parallels smoke harness with Discord end-to-end roundtrip verification, including guest send, host verification, host reply, and guest readback.
| 1 | # Parallels Discord Roundtrip |
| 2 | |
| 3 | Use when macOS Parallels smoke must prove Discord two-way delivery end to end. |
| 4 | |
| 5 | ## Goal |
| 6 | |
| 7 | Cover: |
| 8 | |
| 9 | - install on fresh macOS snapshot |
| 10 | - onboard + gateway health |
| 11 | - guest `message send` to Discord |
| 12 | - host sees that message on Discord |
| 13 | - host posts a new Discord message |
| 14 | - guest `message read` sees that new message |
| 15 | |
| 16 | ## Inputs |
| 17 | |
| 18 | - host env var with Discord bot token |
| 19 | - Discord guild ID |
| 20 | - Discord channel ID |
| 21 | - `OPENAI_API_KEY` |
| 22 | |
| 23 | ## Preferred run |
| 24 | |
| 25 | ```bash |
| 26 | export OPENCLAW_PARALLELS_DISCORD_TOKEN="$( |
| 27 | ssh peters-mac-studio-1 'jq -r ".channels.discord.token" ~/.openclaw/openclaw.json' | tr -d '\n' |
| 28 | )" |
| 29 | |
| 30 | pnpm test:parallels:macos \ |
| 31 | --discord-token-env OPENCLAW_PARALLELS_DISCORD_TOKEN \ |
| 32 | --discord-guild-id 1456350064065904867 \ |
| 33 | --discord-channel-id 1456744319972282449 \ |
| 34 | --json |
| 35 | ``` |
| 36 | |
| 37 | ## Notes |
| 38 | |
| 39 | - Snapshot target: closest to `macOS 26.3.1 fresh`. |
| 40 | - Snapshot resolver now prefers matching `*-poweroff*` clones when the base hint also matches. That lets the harness reuse disk-only recovery snapshots without passing a longer hint. |
| 41 | - If Windows/Linux snapshot restore logs show `PET_QUESTION_SNAPSHOT_STATE_INCOMPATIBLE_CPU`, drop the suspended state once, create a `*-poweroff*` replacement snapshot, and rerun. The smoke scripts now auto-start restored power-off snapshots. |
| 42 | - Harness configures Discord inside the guest; no checked-in token/config. |
| 43 | - Use the `openclaw` wrapper for guest `message send/read`; `node openclaw.mjs message ...` does not expose the lazy message subcommands the same way. |
| 44 | - Write `channels.discord.guilds` in one JSON object (`--strict-json`), not dotted `config set channels.discord.guilds.<snowflake>...` paths; numeric snowflakes get treated like array indexes. |
| 45 | - Avoid `prlctl enter` / expect for long Discord setup scripts; it line-wraps/corrupts long commands. Use `prlctl exec --current-user /bin/sh -lc ...` for the Discord config phase. |
| 46 | - Full 3-OS sweeps: the shared build lock is safe in parallel, but snapshot restore is still a Parallels bottleneck. Prefer serialized Windows/Linux restore-heavy reruns if the host is already under load. |
| 47 | - Harness cleanup deletes the temporary Discord smoke messages at exit. |
| 48 | - Per-phase logs: `/tmp/openclaw-parallels-smoke.*` |
| 49 | - Machine summary: pass `--json` |
| 50 | - If roundtrip flakes, inspect `fresh.discord-roundtrip.log` and `discord-last-readback.json` in the run dir first. |
| 51 | |
| 52 | ## Pass criteria |
| 53 | |
| 54 | - fresh lane or upgrade lane requested passes |
| 55 | - summary reports `discord=pass` for that lane |
| 56 | - guest outbound nonce appears in channel history |
| 57 | - host inbound nonce appears in `openclaw message read` output |