Playbook: Executing Infra Task Requests
Audience: p24-infra admin Claude (and human admins) processing incoming
infra-task-requestissues. For how to submit a request from another repo, seedocs/playbooks/cross-project-infra-requests.md.
System architecture
Infra task requests flow through three layers:
- GH Actions
infra-task-intake.yml— fires onissuesevent, inserts a row into Supabasedev_r_infra_task_requestswithstatus=queued, addswaiting-infrato the Return-To issue. - n8n workflow
infra-task-queue-processoron bms-4 — polls Supabase every 2 minutes, picks upstatus=queuedrows, callsspawn-infra-task-worker.shvia SSH. - claude-runner worker on bms-4 — executes the task, commits changes, opens PRs, posts callback comment on the Return-To issue.
Worker: bms-4 (OVH ns3101999, 54.36.123.110)
Spawn script: /opt/p24-infra/scripts/spawn-infra-task-worker.sh <issue_num>
Worker logs: /var/log/p24-infra-workers/infra-task-<N>.log
Supabase table: dev_r_infra_task_requests in project mwkqmgadqnkkihjdeqsi
Full request lifecycle
| Time | Event |
|---|---|
| T+0 | Issue created in radieu/p24-infra with label infra-task-request |
| T+0 | infra-task-intake.yml fires, inserts Supabase row status=queued, adds waiting-infra to Return-To issue |
| T+0 to T+2 min | n8n infra-task-queue-processor polls, picks up status=queued row |
| T+2 min | n8n calls spawn-infra-task-worker.sh <issue_num> on bms-4 via SSH; row → status=in_progress |
| T+2 to T+30 min | claude-runner worker on bms-4 executes, commits, opens PRs |
| T+done | Worker posts callback comment on Return-To issue, removes waiting-infra, sets p24-infra issue → infra-done, Supabase row → status=done |
How to process a received request
When you (the executor worker) receive an infra task request, follow these steps in order.
Step 1 — Parse the issue body
Read the issue and extract the header fields:
Return-To: <repo>#<issue-number> ← where to post the callback comment
Priority: normal|urgent ← already handled by dispatcher ordering
E2E/Browser: yes|no ← affects your timeout and available tools
E2E/Browser handling:
| Value | Meaning | Your constraints |
|---|---|---|
no | CLI/API-only task | Standard 30-min timeout · no display needed |
yes | Needs browser or E2E tests | Up to 60-min timeout · Playwright/headed Chrome available · needs display/GPU resources |
| missing | Treat as no | Note the missing field in your callback comment |
Step 2 — Detect task type
Simple task — ## Task description present, no ## Dependency graph section → execute directly, skip to Step 3.
Orchestrator task — ## Dependency graph section present → execute waves:
- Parse each wave block. Items listed as parallel within a wave run concurrently; waves are sequential.
- Execute wave 1 — run all parallel items, wait for all to complete.
- If any item in the wave fails: stop, post failure callback (see Step 5), add
human-actionlabel. Do not proceed to the next wave. - Proceed to wave 2, repeat until all waves complete.
- Post success callback when the last wave is done.
Step 3 — Execute the task
Read the task description carefully. Apply all rules from p24-infra CLAUDE.md.
Key rules:
- Never display secret values — read from SOPS or
.env.bak - Every script/action failure → Discord webhook + GH issue in
radieu/p24-infrabefore continuing - No direct commits to
main— all changes via PR tomainfrom a feature/fix branch - SSH commands that modify server files require
# PLAYBOOK: infra-task-executor.mdannotation
Step 4 — Post callback comment on the Return-To issue
Success:
gh issue comment <N> --repo <repo> --body "$(cat <<'EOF'
## Infra task complete
**Request:** radieu/p24-infra#<issue_number>
**Status:** done
### What was done
- <bullet per action taken>
### Next steps
<what the requesting session should do now, or "none">
EOF
)"
Failure / partial:
gh issue comment <N> --repo <repo> --body "$(cat <<'EOF'
## Infra task failed
**Request:** radieu/p24-infra#<issue_number>
**Status:** failed
### What failed
<description of what went wrong and why>
### What completed (if partial)
- <steps that succeeded before failure, or "none">
### Action required
<what a human needs to do to resolve>
EOF
)"
Step 5 — Close out the request
After posting the callback:
# Remove waiting-infra from the Return-To issue
gh issue edit <N> --repo <repo> --remove-label "waiting-infra"
# Mark the p24-infra issue done (success or failure — "done" means processing complete)
gh issue edit <infra_issue_number> --repo radieu/p24-infra \
--remove-label "wip" --add-label "infra-done"Monitoring
GH issue labels:
| Label | Meaning |
|---|---|
infra-task-request | Queued, awaiting pickup |
wip | Worker spawned and running |
human-action | Worker paused — destructive op or ambiguous task; human must unblock |
infra-done | Complete, callback posted |
Supabase — queue state:
SELECT id, issue_number, status, created_at, updated_at
FROM dev_r_infra_task_requests
ORDER BY created_at DESC
LIMIT 10;Status values: queued → in_progress → done | failed | blocked_human_action
Worker logs on bms-4:
ssh root@54.36.123.110 "tail -100 /var/log/p24-infra-workers/infra-task-<N>.log"
# List recent worker log files:
ssh root@54.36.123.110 "ls -lt /var/log/p24-infra-workers/infra-task-*.log | head -5"Escalation
n8n not picking up the task (>10 min after submission)
-
Check n8n is running and workflow is active:
- Open
https://n8n.bms-4.infra.zintegrowana.online→ Workflows →infra-task-queue-processor - Confirm status is Active; if inactive, activate it.
- Open
-
Check Supabase row status:
SELECT status, created_at FROM dev_r_infra_task_requests WHERE issue_number = <issue_number>;If
status=queuedand >10 min elapsed, n8n is the bottleneck. -
If n8n is down: the hourly triage on bms-4 runs a Phase 2 sweep that picks up stale
queuedrows as fallback. Wait up to 1 hour or trigger manually. -
Manual trigger (emergency):
ssh root@54.36.123.110 "sudo -u claude-runner /opt/p24-infra/scripts/spawn-infra-task-worker.sh <issue_num>"
Worker spawned but no result after 30 min
-
Check worker logs:
ssh root@54.36.123.110 "tail -100 /var/log/p24-infra-workers/infra-task-<N>.log" -
If
status=in_progressfor >2 hours: the hourly triage Phase 2B automatically resets it toqueuedfor retry. -
If the p24-infra issue has
human-actionlabel: see section below. -
If issue has
infra-donebut no callback comment on Return-To issue: thegh issue commentcall failed. Check worker logs for the error. Post a manual comment on the Return-To issue referencing the p24-infra issue number.
human-action label added
The worker detected a potential problem and paused:
- Destructive keywords (
delete,drop,wipe,truncate,reset) in the task description Return-To: noneon a task that looks like it should have a callback- Ambiguous task description requiring clarification
To unblock:
- Read the comment the worker posted — it explains what triggered the gate.
- If safe to proceed: add a comment
Approved — proceed, removehuman-action, re-addinfra-task-requestto re-queue. - If task needs clarification: contact the requester (via the Return-To issue), then edit the
p24-infra issue body, remove
human-action, re-addinfra-task-request.
Related
- Requester playbook:
docs/playbooks/cross-project-infra-requests.md - Hourly triage:
docs/playbooks/hourly-triage-outage.md - Spawn script on bms-4:
/opt/p24-infra/scripts/spawn-infra-task-worker.sh - Supabase table:
dev_r_infra_task_requests