autonomous-deployment-mission
Execute multi-phase service deployments autonomously with safety guards, journaling, and a morning report — Phase 0 diagnostics, sequential deployment, anti-gaspillage budgets, escalation policy.
Quand l'utiliser (Trigger)
Déclenchement standard selon le contexte de l'écosystème Hermès.
Mode d'emploi (Usage)
Mode d'emploi standard via l'agent Hermès. Autonomous Deployment Mission
When to Use
You are acting as a senior DevOps engineer in autonomous overnight mode. The user has given you a multi-component deployment mission and expects you to execute it unattended with full safety, tracking, and a morning report.
Use this skill when:
- You are deploying 2+ interconnected services (observability + orchestration + agents, etc.)
- The session is expected to run unattended (user asleep, working other tasks)
- The user has given explicit security constraints and budgets
- There is a deliverable (morning report) expected at the end
Mission Structure
A deployment mission follows an invariant 8-phase structure:
Phase 0 — Diagnostics (system state, prerequisites, constraints)
Phase 1..N — Deploy (one service at a time, verify each)
Phase N+1 — Integrate (wire services together)
Phase N+2 — Operate (test end-to-end, verify traces/propagation)
Phase Final — Report (RAPPORT.md handoff)
Rule: Never skip Phase 0. Never skip Phase Final. Never deploy service N+1 before service N is verified healthy.
Phase 0 — Diagnostics (Mandatory First Step)
Before any action, establish the system baseline:
# OS + resources
cat /etc/os-release | head -3
uname -a
free -h
df -h /
# Docker/Compose availability
docker --version
docker compose version 2>/dev/null || echo "compose plugin missing"
groups $USER | grep docker && echo "user in docker group" || echo "sudo needed"
# Node/nvm/pnpm
node -v 2>/dev/null || echo "node missing"
pnpm -v 2>/dev/null || echo "pnpm missing"
which nvm && nvm ls 2>/dev/null
# Port availability — check if target ports are free
ss -tlnp | grep -E ':(3000|3100|8080|5173)\b' || echo "target ports free"
# Current directory structure
ls ~/agent-stack/ 2>/dev/null || echo "~/agent-stack/ does not exist"
Output the diagnostic summary to the user. Do not proceed beyond Phase 0 without user stepping in to approve or give further direction, unless the user has explicitly stated they are asleep and to proceed independently.
Phase 1..N — Sequential Service Deployment
Core Principle: One Phase at a Time
START → Diagnostics → Deploy Svc 1 → Verify → Deploy Svc 2 → Verify → Integrate → Operate → Report
NEVER deploy two services in parallel. NEVER start deploy of Svc N+1 until Svc N’s health check passes.
Per-Service Template
For each service, follow this sub-pattern:
- Source: Get official Docker Compose file or install docs. Do NOT guess compose structure.
- Secrets: Generate with
openssl rand -hex 32, store in.envwithchmod 600. - Deploy:
docker compose up -d(or equivalent install command). - Health Wait: Loop until all containers healthy (30-60s typical).
- API Verify:
curl -s -o /dev/null -w "%{http_code}" http://localhost:<port>→ expect 200. - Credentials Capture: Admin email/password (auto-provisioned or generated).
- Key Capture: API keys, tokens, OTel endpoints — store paths in PROGRESS.md.
- Patch Config: Any config needed for remote access (Tailscale, etc.).
Safety Contract (Non-Negotiable)
These rules must be in the mission brief and followed without exception:
Absolute Rules
- No destructive commands outside project dir:
rm -rfonly within~/agent-stack/or service directory. Never system paths, never existing data volumes without explicit approval. - Secrets in .env chmod 600: Never displayed in logs, reports, or skill files. Mask as
pk-***,sk-***. - Ports on localhost only: Unless remote access is explicitly needed (Tailscale, reverse proxy), bind to
127.0.0.1. - No unnecessary network access: Don’t install packages not needed for the deployment.
Anti-Gaspillage Budgets
- Max 5 attempts per step: If a step fails 5 times, stop that step, log the blocker, and move to what is achievable.
- Max 3 hours total: If the mission exceeds 3 hours, save state and stop. Do not start new phases.
- Loop detection: If a sub-agent repeats the same error 3 times, kill it and fall back to manual approach.
- Token budget awareness: Before each delegation, ask “can I do this myself in <5 attempts?” If yes, don’t delegate.
Escalation Policy
- Do NOT wake the user for anything short of irrecoverable destruction
- Log every blocker in PROGRESS.md with: what was attempted, what failed, what was tried
- If ALL progress is blocked (no safe alternative path) → secure containers, write final RAPPORT.md, and stop
Progress Journal (PROGRESS.md)
Created at ~/agent-stack/PROGRESS.md at the start of the mission. Updated after every phase completion (not every tool call — keep it to state transitions).
Format
# Agent Stack — Progress Journal
## [YYYY-MM-DD HH:MM] Phase N — Phase Name
- **Action**: What was done
- **Result**: ✅ / ❌ / ⏸
- **Agent**: self / claude / codex / gemini
- **Tokens**: ~N (estimated)
- **Decisions**: Key choices made
- **Blockers**: What stopped or was skipped (if any)
What to log
- Phase boundaries only (start/end of each Phase 0, 1, 2, etc.)
- Blocker entries (what failed + what was attempted)
- Key credentials captured (file paths where they’re stored, not the values)
- Config changes (file paths, what was changed, why)
What NOT to log
- Every
curlordocker pscall - Intermediate debug output
- Versions/dates that are obvious from context
Delegation Rules (Budget-Aware)
Follow the 5-attempt rule for both self-execution and delegation:
Can I do this in <5 attempts myself?
├─ YES → Do it directly (save tokens)
└─ NO → Delegate with a MINIMAL context prompt:
• Only the file paths and error messages needed
• Never the full conversation history
• One task per delegation
| Type | Delegation Target | When |
|---|---|---|
| Debugging complex Docker/networking errors | Claude Code | Unusual compose failures, ClickHouse tuning |
| Script generation, refactoring | Codex CLI | Repetitive code tasks, adapter generation |
| Large doc reading, synthesis | Gemini CLI | Tracking down upstream docs, understanding API surfaces |
Multi-Session Resume Protocol
When the user returns mid-mission with “continue” / “continuer la tâche en cours” / “resume” / “next” — do NOT assume fresh start. Follow this protocol:
Step 1 — State Reconstruction
Run all of these in parallel (they’re independent):
# A — Search conversation history for the last session's state
# (use session_search with the project name or "PROGRESS" as query)
# B — Check service health (services may still be running from last session)
docker ps --format "table {{.Names}}\t{{.Status}}"
curl -s http://localhost:3000/api/public/health 2>/dev/null || echo "Langfuse down"
curl -s http://localhost:3100/api/health 2>/dev/null || echo "Paperclip down"
# C — Read the progress journal
cat ~/agent-stack/PROGRESS.md
# D — Check shared cross-machine log (if applicable on multi-machine setups)
cat ~/shared_log.md 2>/dev/null | tail -20
Step 2 — Compare Expected vs Actual State
Build a picture of what SHOULD be running vs what IS running:
| Service | Should Be | Actually Is | Action |
|---|---|---|---|
| Langfuse (Docker) | 6 containers healthy | ? | Start if down |
| Paperclip (process) | Running on :3100 | ? | Start if down |
Pitfall: A service may appear healthy but its config may have changed. Always re-read the .env and config files to check for required next-step modifications.
Step 3 — Update PROGRESS.md to Reality
The PROGRESS.md from the previous session was written in plan format (future tense, “Phase 1 — Deploy X”). Now transform it into status format (past tense, “Phase 1 ✅ — deployed with 6 containers”). This gives the user accurate context and avoids confusion about what was actually done vs planned.
Step 4 — Identify Decision Points
Multi-phase deployments often have multiple valid next steps. Present a prioritized menu when the user returns mid-mission:
Currently running: Langfuse ✅, Paperclip ✅
Next available steps:
1. Configure provider LLM ← enables agent task execution
2. Connect observability (Paperclip → Langfuse)
3. Add more agents (Codex, Gemini)
4. Test E2E
Ask the user for priority — don’t guess which step they want next.
Morning Report (RAPPORT.md)
Written at ~/agent-stack/RAPPORT.md at mission end (success or stop). It is the single deliverable the user reads over coffee.
Report Template
# Rapport du Matin — Agent Stack
Date: YYYY-MM-DD
## 1. STATUT GLOBAL
✅ / ⏸ / ❌
## 2. Ce qui fonctionne (avec URLs)
- Service A: [URL](http://x.x.x.x:PORT) — description
- Service B: [URL](http://x.x.x.x:PORT) — description
- Intégration: trace E2E visible dans Langfuse ✅
## 3. Ce qui a bloqué
- Blocage 1: Ce qui s'est passé, pourquoi, ce qui a été tenté
- Blocage 2: ...
## 4. Décisions qui t'attendent
- Action irréversible X dont tu n'as pas voulu (ex: drop DB volume)
- Configuration Y à valider
## 5. Coût estimé (tokens)
| Phase | Hermes | Claude | Codex | Gemini |
|-------|--------|--------|-------|--------|
| 0 | ~2K | — | — | — |
| 1 | ~N | ~N | ~N | ~N |
| Total | ~N | ~N | ~N | ~N |
## 6. Prochaines étapes
- Migration VPS sous Coolify
- Ajout service X
- ...
## 7. Runbook
### Démarrer
```bash
cd ~/agent-stack/<service> && docker compose up -d
Arrêter
cd ~/agent-stack/<service> && docker compose down
Vérifier l’état
docker compose -f ~/agent-stack/<service>/docker-compose.yml ps
Sauvegarder
# Which volumes to back up
docker volume ls --filter label=com.docker.compose.project=<project>
Dépanner
- Symptôme X → Cause Y → Solution Z
8. Actions humaines restantes
- Action 1 (à faire par toi)
- Action 2 (à faire par toi)
## Reference Files
This skill ships with detailed deployment references for specific services:
| File | Covers |
|------|--------|
| `references/langfuse-deployment.md` | Full Langfuse Docker Compose flow, API key recovery, OTel endpoint, auth, NEXTAUTH_URL gotcha, port safety, pitfalls |
| `references/paperclip-deployment.md` | Paperclip pnpm-based install, mode switching (local_trusted/authenticated), hostname restriction fix, Better-Auth gotchas, restart sequence, Langfuse integration |
| `references/hermes-credential-pool-keys.md` | How Hermes credential_pool manages API keys at runtime (env: sourcing, HERMES_REDACT_SECRETS masking), discovery protocol when keys are needed for external services, when to ask the user vs keep documenting |
| `references/paperclip-local-adapters.md` | Paperclip built-in adapter types for local CLI subscriptions (claude_local, codex_local, gemini_local, hermes_local), architecture pattern (API key orchestrator + local CLI agents), CLI auth commands, trade-offs vs cloud APIs |
Load these when deploying the respective service.
## Docker Compose Technical Reference
For the low-level Docker Compose mechanics used in deployments — binary installation (sudo-less), secret generation, .env security, health verification, port binding patterns, volume management, and remote access via Tailscale — see `references/docker-compose-deployment.md`. Specific service deployment references are also listed in the table above.
## Service Interdependency Patterns
### Observability Pattern (Langfuse + Orchestrator + Agents)
Langfuse (traces storage) ↑ Paperclip (orchestrator) ←→ Agent A (Claude Code) ↑ Agent B (Codex CLI) ↑ Agent C (Gemini CLI) └── Hermes (meta-orchestrator, writes PROGRESS.md)
**Key integration points:**
- Paperclip project `.env` contains `LANGFUSE_PUBLIC_KEY`, `LANGFUSE_SECRET_KEY`, `LANGFUSE_BASE_URL`
- Agents push OTel traces to Langfuse endpoint at `/api/public/otel/v1/traces`
- Auth: `Authorization: Basic <base64(pk:sk)>`
- Each agent's span should include the Paperclip `trace_id` for cross-service correlation
### Remote Access Pattern (Docker + Tailscale + No Reverse Proxy)
[User Windows] — Tailscale — [Linux Server] │ │ │ http://100.x.x.x:3000 ──────► Langfuse (0.0.0.0:3000) │ http://100.x.x.x:3100 ──────► Paperclip (0.0.0.0:3100)
**No reverse proxy needed** when services bind to `0.0.0.0` and Tailscale routes traffic directly to the server's network interface. The Tailscale IP (`100.x.x.x`) behaves like any other network IP — any service listening on `0.0.0.0` is reachable.
Exception: services that enforce loopback binding (like Paperclip's `local_trusted` mode). These require mode-switching or SSH tunnels.
## Pitfalls
- **Deploying two services at once**: You lose the ability to isolate which failure belongs to which service. One phase at a time, always.
- **Skipping diagnostics**: 80% of "mysterious failures" are uncovered in Phase 0 (wrong node version, port already in use, disk full).
- **Logging secrets in PROGRESS.md**: The journal must contain file paths to secrets, not the secrets themselves. If the journal leaks, keys must be rotated.
- **Running 3+ hours without checkpoint**: If the mission exceeds 3 hours, future-you will thank present-you for saving state. Write RAPPORT.md even mid-mission.
- **Trusting "obvious" error messages**: A `connection refused` on Tailscale IP is usually a loopback bind issue, not a service failure.
- **Forgetting the morning report**: The user doesn't read your terminal history. RAPPORT.md is the only deliverable that matters.
- **Config fix applied but restart blocked by safety**: After patching a config file (`.env`, etc.), the service must reload to pick it up. The `docker compose restart` command is often blocked by terminal safety because it's classified as service-disruption. Don't retry with different syntaxes — present the blocker clearly to the user: state what was changed, confirm the operation is safe (no data loss, no volume drop, clean config reload), and ask for explicit approval. This is a natural human-in-the-loop checkpoint, not a failure.