---
name: deterministic-scripts-and-runbooks
description: "Server tasks should produce idempotent scripts with runbooks, secrets go to 1Password"
metadata: 
  node_type: memory
  type: feedback
  originSessionId: 318046c9-35d3-4f60-9e34-90873f580290
---

**When doing server stuff (deployments, orchestration, bots, infrastructure), always produce a deterministic script that a human can run subsequently.**

**Why:** Server changes are high-risk and need to be repeatable, auditable, and separable from ad-hoc CLI decisions. Scripts let team members reproduce your work, reduce manual error, and make deployment reversible.

**How to apply:**

1. **Write scripts, not prose instructions:**
   - Shell scripts (bash/fish) with extensive comments explaining each step
   - Include guard clauses (check prerequisites, fail early on missing env vars)
   - Document what the script does at the top (a usage block)
   - Make scripts idempotent where possible — running twice should be safe

2. **Include warnings for destructive or risky steps:**
   - Comment dangerous operations (`rm`, `reset`, force-push, schema changes)
   - Fail with a clear error if preconditions aren't met (e.g., "DB must have a backup before running this")
   - Prompt for confirmation before irreversible actions (optional, but encouraged)

3. **Maintain a runbook in the relevant README:**
   - Document common procedures (e.g., "How to deploy to production", "How to migrate an instance", "How to mint a new push relay token")
   - Link to or embed the scripts from version control
   - Include when/why you'd run each script, prerequisites, and rollback steps
   - Keep it updated as procedures change — a stale runbook is worse than no runbook

4. **Secrets go to 1Password, documented in work summary:**
   - Any secrets created (tokens, keys, credentials) must be stored in 1Password (Private vault, clearly named)
   - Include the 1Password item name/path in your work summary so the team knows where to find it
   - Document the secret's purpose and which services/instances use it
   - If you share a script that references a secret, explain how to retrieve it from 1Password (don't embed it)

**Example:** A deploy script might:
```bash
#!/bin/bash
set -e

# Deploy a new lchat version to production
# Usage: ./deploy-prod.sh <version>
# Prerequisites: SSH key for root@box, LCHAT_ADMIN_TOKEN in 1Password "lchat admin token (prod)"

VERSION="${1:?Error: must pass version}"
BOX="89.167.122.227"

echo "⚠️  Deploying $VERSION to production ($BOX)"
echo "This will restart all instances. Continue? (yes/no)"
read -r confirm
[[ "$confirm" == "yes" ]] || exit 1

# Copy binary to staging
scp lchat-linux-amd64 root@$BOX:/opt/lchat/incoming

# Stage and deploy with rollback on failure
ssh root@$BOX /opt/lchat/lchat stage --file /opt/lchat/incoming
ssh root@$BOX /opt/lchat/lchat deploy --all --version <ver> || {
  echo "Deploy failed. Rolling back all instances..."
  ssh root@$BOX /opt/lchat/lchat rollback --all
  exit 1
}

echo "✅ Deployed $VERSION successfully"
```

**Work summary pattern:** When you finish server work, include a section like:
```
## Secrets stored in 1Password
- Item: "lchat push relay token (new-instance.example.com)" — relay authentication token, needed for LCHAT_PUSH_RELAY_TOKEN env var
- Item: "lchat admin token (new-instance.example.com)" — admin link at https://new-instance.example.com/admin#token=...

## Scripts to run
- `./deploy-prod.sh v1.2.3` — deploys a new version to all instances (see docs/deploy-runbook.md for full procedure)
```

This transforms ad-hoc work into repeatable, auditable infrastructure code that the team can follow and improve.
