feat: add Claude domain playbooks for agent reference

This commit is contained in:
Backtalk6858
2026-06-27 01:04:06 -05:00
parent c3944641d3
commit cb65e3d7cf
2 changed files with 273 additions and 0 deletions
+150
View File
@@ -0,0 +1,150 @@
---
name: playbook-background-agent-prompts
description: "REQUIRED before writing any background agent prompt: full template, 5 discipline rules, mandatory wrap-up block, and anti-patterns; read this before drafting any agent prompt"
metadata:
node_type: memory
type: project
originSessionId: 075715ba-4454-464c-ba39-dfbcdefc6590
---
## When to use background agents
Use a background agent when:
- The task is bounded (clear start, clear end, defined output)
- It does not require real-time decisions from the user
- It can run in parallel with other work without file/resource conflicts
- It fits within 15 tool calls
Do NOT use a background agent for:
- Open-ended research or design tasks (those belong in main session)
- Tasks that require human decisions mid-way
- Tasks that share files or DB rows with another running agent
---
## The 5 Prompt Discipline Rules
Every background agent prompt must satisfy all 5. A prompt missing any of these will loop, stall, or silently fail.
### Rule 1 — Hard turn limit
Always include `--max-turns 15` in the prompt (or in the claude -p invocation). Without this, a looping agent runs indefinitely and consumes unbounded SDK credits.
### Rule 2 — Loop detection instruction
Include this verbatim:
> "If you issue the same tool call or command twice with identical arguments, STOP immediately and output the mandatory wrap-up with status=partially_succeeded."
### Rule 3 — Credential map inline
Every credential the agent needs must be provided inline in the prompt — exact Vault path and field name. Never send an agent to search for auth at runtime. Use the infrastructure auth map (`secret/data/claude/infrastructure-auth-map` → yaml field) as the source.
Format:
```
## Credentials you will need
- sudo-bridge (primary): Vault path secret/data/sudo-bridge → api_key
- Gitea token: Vault path secret/data/gitea → admin_token
- AppRole bootstrap: role-id at /opt/appdata/docker/docker-compose/vault/approle/role-id
```
Always include the AppRole bootstrap pattern when Vault access is needed:
```bash
VAULT_IP=$(docker inspect vault-iwaulpoi5hwirdlogshmul40 --format '{{json .NetworkSettings.Networks}}' | python3 -c "import sys,json; nets=json.load(sys.stdin); print(list(nets.values())[0]['IPAddress'])")
ROLE_ID=$(cat /opt/appdata/docker/docker-compose/vault/approle/role-id | tr -d '[:space:]')
SECRET_ID=$(cat /opt/appdata/docker/docker-compose/vault/approle/secret-id | tr -d '[:space:]')
VAULT_TOKEN=$(curl -sf -X POST -H "Content-Type: application/json" \
-d "{\"role_id\":\"$ROLE_ID\",\"secret_id\":\"$SECRET_ID\"}" \
http://$VAULT_IP:8200/v1/auth/approle/login | python3 -c "import sys,json; print(json.load(sys.stdin)['auth']['client_token'])")
# Always revoke after use:
curl -sf -X POST -H "X-Vault-Token: $VAULT_TOKEN" http://$VAULT_IP:8200/v1/auth/token/revoke-self
```
### Rule 4 — Defined output format
Specify the exact output the agent must produce. Never say "report what you did" — always define the schema. Use the mandatory wrap-up block (Rule 5 below) as the minimum output requirement. Add task-specific fields as needed.
### Rule 5 — Mandatory wrap-up block (structural, not instructional)
Add this block verbatim to every prompt, immediately before the loop detection instruction. This is structural — the agent cannot satisfy the prompt without emitting it.
```
## MANDATORY WRAP-UP (required regardless of success or failure)
Before stopping for ANY reason — task complete, error, or approaching turn limit — output this JSON as your final message. Do not stop without it.
{
"status": "succeeded|partially_succeeded|failed",
"actions_taken": ["action 1 — outcome", "action 2 — outcome"],
"actions_failed": ["action — reason it failed"],
"notes": "anything relevant for the next session"
}
If you hit --max-turns before finishing, set status="partially_succeeded" and list what remains in actions_failed.
```
---
## Prompt template
```
You are [one sentence role description]. [One sentence scope — what you will and will not touch.]
## Task
[Clear, bounded description of what to accomplish.]
## Context / pre-fetched data
[Include inline any data the agent needs: DB rows, config values, file contents. Do not make the agent fetch things that can be included here.]
## Credentials you will need
[List exact Vault paths and field names for every secret needed. Include AppRole bootstrap if Vault access required.]
## Step-by-step
[Numbered steps if the task has a defined sequence.]
## MANDATORY WRAP-UP (required regardless of success or failure)
Before stopping for ANY reason — task complete, error, or approaching turn limit — output this JSON as your final message. Do not stop without it.
{
"status": "succeeded|partially_succeeded|failed",
"actions_taken": ["action 1 — outcome", "action 2 — outcome"],
"actions_failed": ["action — reason it failed"],
"notes": "anything relevant for the next session"
}
If you hit --max-turns before finishing, set status="partially_succeeded" and list what remains in actions_failed.
--max-turns 15
If you issue the same tool call or command twice with identical arguments, STOP immediately and output the mandatory wrap-up with status=partially_succeeded.
```
---
## Parallel agent rules
- **Max comfortable parallel:** 4-5 agents (primary server has 18GB available RAM, ~300MB per agent)
- **Max safe parallel:** 8 agents
- **Do not parallelize:** Tasks that write to the same file, the same DB row, or the same Gitea repo
- **Do parallelize:** Tasks that touch independent files, services, or repos
- Token cost is the same whether serial or parallel — parallelism saves wall-clock time only
---
## Anti-patterns
| Anti-pattern | Why it fails | Fix |
|---|---|---|
| "Report what you did when done" | Instructional — skipped under context pressure | Use mandatory wrap-up JSON block |
| Sending agent to find its own credentials | Agent loops searching for auth | Provide all Vault paths inline |
| Open-ended task ("investigate and fix anything wrong") | No defined completion state | Bound the task: specific file, specific check, specific output |
| No --max-turns | Looping agent runs forever | Always include --max-turns 15 |
| Sharing a file between two parallel agents | Race condition, one overwrites the other | Assign non-overlapping files/resources |
| Making design decisions in the agent | Agent guesses wrong, wasted run | Pre-decide everything in main session, send agent only to execute |
| `curl -sf ... \| python3 -c` for API calls | `-sf` suppresses body on error; inline python escaping breaks | Write a /tmp Python script using urllib instead |
| secrets-proxy /shell with target="server-01" | Only accepts target=sandbox or target=production — 400 error | Server-01 ops go through sudo-bridge-server01 at http://192.168.1.90:8082 directly |
| Pre-fetching everything before writing prompts | Burns context; most things agents can discover in 1 tool call | Pre-fetch only what's blocking — include discovery steps inside the agent prompt instead |
| Writing files on server-01 without allowlist entry | 403 — command not in allowlist | Add pattern to allowlist (tier 1 = auto, tier 2 = NTFY approval) first; use base64 python3 -c for file writes |
| Downgrading tier-2 wildcard to tier-1 to bypass NTFY | First-registered wildcard wins — adding tier-1 `python3 -c *` after a tier-2 `python3 -c *` has no effect | Use `docker exec <container> python3 -c` instead (different prefix, not matched by `python3 -c *`) |
| Pre-hashing keys in PROXY_CALLERS env var | secrets-proxy app.py expects raw keys in PROXY_CALLERS and hashes internally — pre-hashing causes double-hash, all auth returns 403 Invalid API key | Store raw keys: `PROXY_CALLERS=json.dumps(callers)` not `json.dumps({n: sha256(k) for n,k in callers.items()})` |
| Relying on NTFY approvals for unattended agents | NTFY notifications may be missed or time out, stalling the agent indefinitely | Design server-01 file writes to use `docker exec` pattern (tier-1) for unattended runs; reserve tier-2 for explicit interactive sessions |
---
## Evolution
Update when: new anti-patterns discovered; AppRole bootstrap pattern changes; parallel agent limits change based on server hardware; new credential types need standard inline format.