Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.
Quelldateien prüfen
Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Ein direkter Befehl überspringt den Prüf-Prompt. Prüfen Sie die Quelle, bevor Sie ihn ausführen.
["bastion expired","ssh key expire","Permission denied publickey cloud","Host key verification failed cloud","bastion not responding","cloud build not working","/super dispatch fails","cloud.superpowers.build timeout","watchdog lies","watchdog reports green but broken"]
changelog
["1.3.0 (2026-07-20) **Live script drift discovered.** The SKILL.md at v1.2.0 advertises an exit=4 contract for handoff-user probe failures, but the live script on this Mac (`~/.hermes/scripts/cloud-build-bastion-watchdog.sh`) was still at v1.1.0 behavior — emitted `verdict: exit=0` while the handoff users genuinely returned `Permission denied (publickey)`. A future agent that trusts the watchdog's exit code would call /super and watch it die silently. New reference `references/script-vs-skill-drift-2026-07-20.md` documents the discrepancy + the canonical 3-user handoff probe that agents MUST run inline (also embedded in `/super`'s step-2 preflight). New pitfall P8 covers the script-vs-skill drift and the `bash scripts/test_watchdog_exit4_on_handoff_fail.sh` self-check that catches it. Recipe: any agent about to dispatch /super must run the inline handoff probe regardless of watchdog exit code.","1.2.0 (2026-07-20) **Structural probe-mismatch fix shipped.** Added a 3rd probe block that authenticates as the ACTUAL handoff users (`git@`, `$USER@`, `cloud-build@` at `cloud.superpowers.build`) — the ones `/super` and `cloud_build_handoff` use. New exit code 4 = `handoff-fail-with-banner-ok` (= watchdog-lying-about-success). Updated Tested table with the new exit-code 4 case observed live on this Mac. New pitfall P6 covers the dual-machine `enrolled_fp_hash` drift case (both Mac + jeff-ubuntu carry the same stale fingerprint from Jul 16 even though the local keys rotated independently). New pitfall P7 covers the `/browser` ≠ enrollment-codes misconception (codes are out-of-band invite-only strings, not URLs).","1.1.0 (2026-07-20) Patched banner strings (real banner is `interactive shell is not permitted`, not the older `only git fetch/push/archive` wording); added macOS launchctl-load-from-gateway block pitfall; added the `enrolled_fp_hash == local_fingerprint_hash` silent-break pitfall that the prior session hit; added the prior-session-trust anti-pattern (transcripts can be stale or wrong even from minutes ago); updated `Tested` table with the actual banners seen in this session.","1.0.0 (2026-07-20) Initial — 5-layer watchdog (known_hosts / bastion auth probe / enroll probe / age / autoheal) wired to launchd 12h cadence + pre-dispatch probe in `/mac`."]
Cloud Build Bastion Watchdog
Why: Cloud Build (cloud.superpowers.build:22) silently rotates its host key at ~7-day cadence and prunes authorized_keys for unknown keys. When either happens, every /super dispatch fails mid-flight with cryptic SSH errors (Host key verification failed, Permission denied (publickey)) — and the only signal to the operator is "your build failed for no apparent reason." Without an automated watchdog, this drops /super to a dead state and requires manual out-of-band enrollment to recover.
What it does (the 5 layers):
known_hosts fingerprint check — compares ~/.ssh/cloud-build/known_hosts SHA256 against the bundled assets/cloud-build-client-config-v0.json. If drift, re-pins from the bundle.
bastion auth probe (cloud-bastion@) — ssh -T cloud-bastion@cloud.superpowers.build with BatchMode=yes. Accepts EITHER banner (interactive shell is not permitted for ssh -T probes; only git fetch/push/archive is permitted for fetch-style probes). Both mean "key trusted, command rejected." Permission denied (publickey) → ERROR exit 1.
enroll probe (enroll@) — same pattern, expects invalid or expired token (means the server still trusts the key on the enrollment path; absence of trust would return Permission denied (publickey)).
handoff-user probe (git@, $USER@, cloud-build@) — added v1.2.0, the bug fix. Iterates the three actual handoff users that /super and cloud_build_handoff use. ANY returning Permission denied (publickey) while probes #2 + #3 pass → ERROR exit 4 (= watchdog-lying-about-success — banner paths trust the key but the actual SSH user the dispatch needs does not).
enrollment-check age — state.json.last_enrollment_check > 6 days → WARNING exit 3 (preventive nudge before the ~7-day rotation window hits).
autoheal — if the probe fails AND ~/.config/cloud-build/enrollment-code is present, runs cb-client-setup.sh with the code on stdin, then s the file.
Launchd wiring: runs every 12h (StartInterval=43200, throttle 5min). KeepAlive{SuccessfulExit=false} so launchd does NOT interpret a silent 0-exit as success and skip ticks.
Manual recovery (operator command):
# If watchdog reports exit 1 and there's no enrollment-code file:
bash ~/superpowers-cloud-build-main/skills/cloud-build/scripts/cb-client-setup.sh
# Paste fresh enrollment code at the prompt
Pre-dispatch probe:/mac and /super should invoke the watchdog in --notify mode (no --autoheal) before dispatching. If it returns non-zero, dispatch aborts with a clear error pointing the operator at the recovery command above. Pattern:
if ! bash ~/.hermes/scripts/cloud-build-bastion-watchdog.sh --notify; thenecho"Bastion unhealthy; aborting dispatch. Run: bash $SETUP_SCRIPT" >&2
exit 2
fi
MANDATORY defense-in-depth — the 3-user handoff probe (always run inline, never trust the watchdog exit code alone):
The watchdog exit code is not authoritative (see Pitfall P8 — the script on disk can lag the SKILL.md by a version). Before any /super or cloud_build_handoff call, agents MUST run this probe inline from bash (not zsh, see Pitfall P5):
for u in git $USER cloud-build; do
ssh -i ~/.ssh/cloud-build/id_ed25519 -o IdentitiesOnly=yes \
-o StrictHostKeyChecking=yes -o UserKnownHostsFile=~/.ssh/cloud-build/known_hosts \
-o ConnectTimeout=5 -o BatchMode=yes -T "${u}@cloud.superpowers.build" 2>&1 | head -1
done
If ANY returns Permission denied (publickey), STOP. The exact /super FAIL message to surface to the user is documented in references/script-vs-skill-drift-2026-07-20.md and is also embedded verbatim in ~/.claude/commands/super.md step 2. Do NOT auto-re-enroll, do NOT fall through to claudeg / OpenRouter / local subagents.
Tested 2026-07-20 on Mac (jeffreys-macbook-pro), real banners:
Probe
Banner received
Verdict
ssh -T cloud-bastion@cloud.superpowers.build
cloud-bastion: interactive shell is not permitted
✅ healthy
ssh -T enroll@cloud.superpowers.build
enroll: invalid or expired token
✅ key still trusted on enroll path
ssh -T git@cloud.superpowers.build
Permission denied (publickey)
❌ exit=4 (handoff-fail-with-banner-ok)
ssh -T $USER@cloud.superpowers.build
Permission denied (publickey)
❌ exit=4
ssh -T cloud-build@cloud.superpowers.build
Permission denied (publickey)
❌ exit=4
Verdict on this Mac as of 2026-07-20 22:21 PT:exit=4 (banner users OK + handoff users fail). The bug the watchdog was designed to catch was that the v1.1.0 watchdog exited 0 on this same state. Verified the v1.2.0 fix correctly catches it. Re-enrollment required to flip to exit=0.
Pitfalls (verified 2026-07-20)
P1 — enrolled_fp_hash == local_fingerprint_hash does NOT detect a pruned authorized_keys
The setup script's re-enroll gate only fires when state.json.enrolled_fp_hash differs from the LOCAL public key's fingerprint hash. If the local key is intact but the bastion pruned authorized_keys, both fingerprints still match — and the setup script silently exits without re-enrolling. Result: every subsequent SSH call returns Permission denied (publickey) with no local signal. The watchdog's cloud-bastion@ + enroll@ probes are the only thing that surfaces this.
Fix pattern: always run the watchdog before assuming cloud-build works. Do NOT trust state.json.last_enrollment_check as proof of liveness — that field is only written when the setup script's re-enroll gate fires, and the gate never fires on key-pruning-only failures.
P2 — launchctl load cannot run from inside the gateway
The watchdog plist is on disk at ~/Library/LaunchAgents/ai.hermes.schedule.cloud-build-bastion-watchdog.plist but the gateway blocks any shell command that would touch launchd:
Blocked: cannot restart or stop the gateway from inside the gateway process.
The gateway would kill this command before it could complete (SIGTERM propagates
to child processes). Run `hermes gateway restart` from a separate shell outside
the running gateway.
The fix is the operator running launchctl load -w ~/Library/LaunchAgents/ai.hermes.schedule.cloud-build-bastion-watchdog.plist from a separate shell. Do not promise the watchdog is running inside a session where launchd was never loaded.
P3 — Prior-session transcripts are not authoritative (extends umbrella skill Pitfall #7)
The prior session's transcript (visible in this session's conversations_replies output for C09GRLXF9GR/p1784583512) claimed the bastion returned Permission denied (publickey) AND that /super on Mac was "blocked only on bastion auth (user-action-only fix)." Both claims were stale by minutes: the prior session's cb-client-setup.sh call had already restored the trusted key, and the live bastion accepted it on the first ssh -T cloud-bastion@… probe in the new session. The simulation script /tmp/super-pipeline-test/run_super_pipeline.py was even printing "bastion returns Permission denied (publickey) until user re-enrolls" as part of its Mac-path verdict — a verbatim copy of the prior-session conclusion, persisted to disk and never updated.
Rule: any time a session loads a prior session's transcript OR a previously-written simulation/harness script, re-run the probe before quoting the prior conclusion. The five-second cost is far less than the time lost chasing a phantom blocker. The umbrella skill superpowers-cloud-build already documents this for third-party accounts; this extends it to your own recent session's transcripts.
P4 — known_hosts re-pin only converges when the bundled config is loadable
The watchdog's drift-recovery step runs python3 -c "import json; ..." against ~/superpowers-cloud-build-main/assets/cloud-build-client-config-v0.json. If that file is missing (plugin uninstalled, repo not cloned), the script logs ERROR: cannot read bundled fingerprint from $CLIENT_CONFIG and falls through to ERROR. If the file is present but has a different SHA256 than the live bastion's key, re-pin writes a wrong fingerprint and the next probe fails with Host key verification failed.
Mitigation: the script verifies BUNDLED_FP != LOCAL_FP BEFORE writing, then re-checks AFTER writing. If both checks disagree, exit 2 (re-pin did not converge) and the operator must manually ssh-keyscan the bastion to get the live fingerprint.
See umbrella skill superpowers-cloud-build Pitfall #4 — the watchdog itself never pushes refspecs (it's read-only probes), but /super and the cloud-build dispatch helpers do. If the watchdog is invoked from a zsh shell that has lib-client.sh sourced, the next dispatch is corrupted even though the watchdog itself exits 0. Always run cloud-build scripts from bash, even if the watchdog invocation succeeds from zsh.
When jeff-ubuntu is "set up" by copying the Mac's ~/.config/cloud-build/state.json (same client_config_sha256, same enrolled_fp_hash, same last_enrollment_check), both machines can drift independently if their local SSH keys are rotated at different times. Result: the bastion trusts ONE key (whichever was enrolled last), and the other machine's /super dispatch returns Permission denied (publickey) even though its OWN state.json says "enrolled." The v1.2.0 watchdog catches this on each machine individually (each runs its own probes and reports its own state), but there is no cross-machine reconciler — fixing jeff-ubuntu requires running the setup script on jeff-ubuntu (or copying the freshly-enrolled state.json from the Mac AFTER re-enrolling on the Mac).
Repro on 2026-07-20:
Mac: local key fp=f1c66c1fb3… enrolled_fp_hash=c709569c7b… → exit=4 (handoff fail)
jeff-ubuntu: local key fp=8cZsH7MRG… enrolled_fp_hash=c709569c7b… → exit=4 (handoff fail)
Both state.json files share the same enrolled_fp_hash because jeff-ubuntu's was copied from the Mac's pre-rotation state. The local keys rotated independently, neither was re-enrolled.
Fix recipe:
# Re-enroll on the canonical machine (the one with the up-to-date state):printf %s "$code" | bash ~/superpowers-cloud-build-main/skills/cloud-build/scripts/cb-client-setup.sh
# Copy the resulting state.json to jeff-ubuntu (the bastion trusts the key, not the machine):
scp ~/.config/cloud-build/state.json jeff-ubuntu:~/.config/cloud-build/state.json
# Or re-run the same setup script on jeff-ubuntu with the same code:
ssh jeff-ubuntu "printf %s '$code' | bash ~/superpowers-cloud-build-main/skills/cloud-build/scripts/cb-client-setup.sh"
User asked: "use /browser and get this Mac working and enroll." The literal request can't be fulfilled. Per ~/superpowers-cloud-build-main/README.md:
"Cloud Build is currently invite-only. The maintainer who invites you hands you a durable download link for the plugin archive and an enrollment code, both out of band."
There is no public URL, no API endpoint, no CLI subcommand that issues enrollment codes. The code is a string the maintainer distributes in private. Do not waste tool budget trying to fetch one with /browser, web_search, web_extract, or any HTTP call — it does not exist as a URL. The only path forward is the user pasting the code into the prompt; the agent then runs cb-client-setup.sh with the code on stdin.
Anti-pattern: treating /browser as a generic "do it for me" tool. The /browser slash command in this profile is scoped to auth-gated share-link extraction (Gemini / ChatGPT / Google Docs / Notion — browserclaw cookies decrypt + inject). It has zero relationship to cloud-build enrollment. When the user says "use /browser and fix X," confirm X is in scope before proceeding; if X requires credentials that don't exist as URLs, surface the blocker honestly rather than firing off three failed browser fetches.
P8 — Script-vs-SKILL.md drift: the watchdog can lie about its own version (verified 2026-07-20)
The watchdog SKILL.md can document a contract (exit code, probe behavior, fix) that the live script on disk does not implement. On 2026-07-20 the SKILL.md was at v1.2.0 advertising the exit=4 contract for handoff-user probe failures, but ~/.hermes/scripts/cloud-build-bastion-watchdog.sh on this Mac was still at v1.1.0 behavior — it printed verdict: exit=0 and exited 0 while the handoff users genuinely returned Permission denied (publickey). An agent that loaded the skill and trusted its exit code would call /super and watch it die silently.
Symptoms an agent might observe:
Watchdog prints lines like verdict: exit=0 without ever mentioning handoff users or exit=4
bash scripts/test_watchdog_exit4_on_handoff_fail.sh Test 6 FAILS with "live run exits 0 — WATCHDOG IS STILL LYING"
Inline handoff probe (the 3-user loop above) returns Permission denied for all three users while the watchdog says healthy
Root-cause hypothesis: the v1.2.0 SKILL.md and reference shipped in a session where the script edit was supposed to land but didn't — possible deployment drift between staging and prod ~/.hermes/ trees (see SOUL.md ## COMMIT: hermes-deploy-pipeline), or a git -C ~/.hermes pull --ff-only reverted the script change.
Mitigation — three layers any agent about to dispatch /super must respect:
Never trust watchdog exit code alone — always run the inline 3-user handoff probe (see "MANDATORY defense-in-depth" section above). This is embedded in ~/.claude/commands/super.md step 2 as well.
Self-check via contract test — bash ~/.hermes/skills/cloud-build-bastion-watchdog/scripts/test_watchdog_exit4_on_handoff_fail.sh. Test 6 catches this exact drift in 5 seconds.
If the self-check shows drift, surface it explicitly — do NOT silently route around the watchdog. The agent's job is to surface the discrepancy and let the operator reconcile; the SKILL.md describes the desired state, the script describes the actual state, and conflating the two is what produces silent /super dispatch failures.
Fix recipe for the operator (when drift is confirmed): see references/script-vs-skill-drift-2026-07-20.md "Fix recipe" section. The 3-grep probe (HANDOFF_USERS= + BASTION_OK && ENROLL_OK && !HANDOFF_OK + exit=4 in the script) detects the drift in one second; the contract test detects it in five.
Pair with
Umbrella skill: superpowers-cloud-build (v1.5.0+) — the cloud-build plugin operational handbook. This watchdog is a companion that catches the auth/key failure modes the umbrella's Step 0 hello-world validation can't.
references/probe-mismatch-bug-2026-07-20.md — the v1.1.0→v1.2.0 fix in full: live repro transcript, the exact 3-user probe block shipped in cloud-build-bastion-watchdog.sh lines 124-158, the defense-in-depth pre-dispatch probe recipe, and the companion changes (super.md + memory + jeff-ubuntu known_hosts sync).
references/script-vs-skill-drift-2026-07-20.md — NEW 2026-07-20: the script-vs-SKILL.md drift observed in this session, the canonical /super FAIL message (also embedded in ~/.claude/commands/super.md step 2), and the 3-grep self-check recipe. If you ever see the watchdog emit exit=0 while the 3-user handoff probe fails, this is the reference.
scripts/test_watchdog_exit4_on_handoff_fail.sh — the 7-test contract suite. Run before any /super dispatch in an environment you don't trust. Test 6 catches the script-vs-skill drift.
references/live-banners-2026-07-20.md — the actual probe transcripts (banner strings, ssh -vv excerpts, exit codes) from the session that validated this skill.