Playbook: Role Delegation Architecture
Read this first when starting any session in the p24-infra ecosystem — before the task-specific playbook. It explains who can do what, from where, and how to hand off work that falls outside your role.
Two classes of sessions
Class A — Local p24-infra session
Where: C:\code_2026\p24-infra on the developer workstation
Has: age key (C:\Users\konar\.age\p24-infra-keys.txt), SSH key, full SOPS access
Can be: any technical role — dev-coder, sys-admin, sys-security, secret-manager, dev-reviewer, dev-tester
Cross-role delegation: direct Agent() spawn in the background (see pattern below)
Class B — Worker / non-p24-infra session
Where: bms-4, vps-i1, or local — but working in et-op, brandpilot, Art-Agency, etc.
Has: only the credentials injected into that project (Vercel env vars, .env.local)
Cannot: touch SOPS files, SSH into servers, run Docker commands
Cross-role delegation: issue + worker queue (see queue pattern below)
Golden rule
A session executes its own role to completion. When it hits a role boundary, it delegates and waits — it never crosses the boundary inline.
Role boundaries at a glance
| Role | Can do | Cannot do (delegate to →) |
|---|---|---|
| dev-coder | Code, migrations, PRs, tests | SOPS → secret-manager · SSH/Docker → sys-admin · security audit → sys-security |
| dev-reviewer | PR review, code quality | Implementation → dev-coder · credentials → secret-manager · server ops → sys-admin |
| dev-tester | Test planning, coverage, writing tests | Implementation → dev-coder · credentials → secret-manager · server ops → sys-admin |
| sys-admin | SSH, Docker, Ansible, DNS, monitoring | SOPS writes → secret-manager · security audits → sys-security · feature code → dev-coder |
| sys-security | Security audits, read-only credential verification | SOPS writes/rotation → secret-manager · feature code → dev-coder · server config → sys-admin |
| secret-manager | All SOPS reads/writes, credential distribution | Feature code → dev-coder · server ops → sys-admin |
| creative roles | Brand content, creative output | All credentials → secret-manager · server ops → sys-admin · all code → dev-coder |
sys-admin and sys-security may READ credentials from SOPS for operational verification.
They must never write or edit SOPS files.
Class A delegation — direct background Agent()
Used by: local p24-infra sessions.
Agent(
description: "secret-manager — add NEW_KEY to monitoring.env.sops",
prompt: """
Read C:\\Users\\konar\\.claude\\agent-prompts\\roles\\secret-manager.md
and adopt that persona.
Working directory: C:\\code_2026\\p24-infra
Task: [KEY_NAME, target SOPS file, reason — never the value]
IMPORTANT: do not display any secret values in your response.
Return format:
Secret Manager — done.
Operation: ADD|ROTATE|RETRIEVE KEY_NAME
SOPS file: secrets/<file>.env.sops
Distributed to: Vercel|vps-i1|bms-4|all / N/A
PR: #N
""",
run_in_background: true
)- Replace
secret-managerwithsys-admin,sys-security,dev-coder, etc. as needed - Role files:
C:\Users\konar\.claude\agent-prompts\roles\<role-name>.md(local) or/home/claude-runner/.claude/agent-prompts/roles/<role-name>.md(workers) - Continue all work that does not depend on the delegated result
- The agent’s completion message is the resume signal
Research subagents must NOT decrypt SOPS (#5544)
A spawned subagent inherits every tool the parent has, including sops, so it can leak a secret
exactly the way the main session can. But a research / investigation / design-spec /
consumer-audit task (locating consumers of a credential, auditing which SOPS file holds a key,
mapping a distribution chain) never needs the plaintext value — only key names, file paths,
and consumer inventories. There is no legitimate reason for a research-only subagent to run
sops --decrypt at all, and every SOPS exposure in this repo’s history has been a hand-rolled
decrypt-and-grep during nominal “research,” not an actual credential write (most recently #5538 —
an Explore-type subagent auditing meta-dispatcher printed a live QUEUE_API_KEY into its own
tool-call transcript; rotated via #5539).
Convention (applies to every non-secret-manager Agent() and Workflow agent): include this
clause verbatim in the subagent prompt —
No SOPS decryption. This is a research/investigation task. Do NOT run `sops --decrypt` / `sops -d`
under any circumstances — not even in a "safe" variable-capture pattern. You only need key NAMES
and file paths: grep the repo for the key name as plain text (never touches ciphertext), or list
names only with `sops --decrypt … | ForEach-Object { $_.Split('=')[0] }` (bash: `… | cut -d= -f1`).
If you believe you need a plaintext value to finish this task, STOP and report that instead of
decrypting — the orchestrator will delegate the value-dependent step to a secret-manager agent.The canonical copy of this clause lives in CLAUDE.md §Role Enforcement → Research/investigation subagents must NOT decrypt SOPS, loaded every session. Only a secret-manager-role subagent
performing an add/rotate/retrieve is exempt — and it must still use the safe extraction pattern /
broker, never bare sops -d stdout.
Deferred (issue #5544 item 2): a
PreToolUsehook variant that blockssops --decryptwhenever the invoking agent’s declared role is notsecret-managerwas considered but not shipped here — the hook cannot reliably see the subagent’s role, so this remains a prompting-convention control for now. Revisit if a role signal becomes available to the hook.
Why direct spawn only works from Class A
The age key lives on the local Windows machine. A background agent spawned from a local session inherits the filesystem context. A worker on bms-4 running an et-op session does NOT have this key, so it cannot spawn a secret-manager agent directly.
Class B delegation — issue + worker queue
Used by: et-operational-platform, brandpilot, Art-Agency, radekkonarski-personal-brand sessions (whether local or on VPS workers).
# 1. Create issue in YOUR repo (not p24-infra)
gh issue create \
--title "[SECRET-REQUEST] ADD: KEY_NAME — reason" \
--label "secret-request" \
--body "..."
# 2. Dispatch to queue
curl -sf -X POST "$QUEUE_API_URL/queue-issue" \
-H "Authorization: Bearer $QUEUE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"issue_number": N, "repo": "radieu/YOUR_REPO", "job_type": "secret-manager"}'- Full issue body template:
docs/playbooks/secret-manager-request.md - Worker picks up within ~2 minutes; callback comment on your issue signals completion
- Continue all other work while waiting
Why the queue is required for Class B
bms-4 workers running et-op or brandpilot jobs do NOT have the age key for those project contexts. The queue dispatches the job to a p24-infra secret-manager worker that does have it.
Complete flow examples
Example 1 — Local dev-coder needs a new credential
dev-coder (local, p24-infra context)
implements feature
→ discovers NEW_SERVICE_API_KEY needed in monitoring.env.sops
→ spawns secret-manager agent (Class A direct spawn)
→ continues other work
← agent returns: "ADD NEW_SERVICE_API_KEY. PR #312."
→ dev-coder references NEW_SERVICE_API_KEY in code
→ opens PR
Example 2 — et-op worker needs a new credential
dev-coder (bms-4, et-op context)
implements feature
→ discovers NEW_WEBHOOK_URL needed in et-operational-platform.env.sops
→ creates [SECRET-REQUEST] issue in radieu/et-operational-platform
→ dispatches job_type: secret-manager to queue
→ continues other tasks
← callback comment: "ADD NEW_WEBHOOK_URL. Deployed to Vercel. PR #89 merged."
→ dev-coder references NEW_WEBHOOK_URL via process.env
→ opens PR
Example 3 — sys-admin discovers a security anomaly
sys-admin (local, p24-infra)
checks vps-i1 logs
→ finds suspicious auth attempts from 1.2.3.4
→ spawns sys-security agent (Class A direct spawn)
task: analyse auth.log from 1.2.3.4, assess credential risk
→ continues monitoring other services
← sys-security returns: "IP blocked. 3 failed attempts, no success. KEY_A rotation recommended."
→ sys-admin spawns secret-manager: "rotate KEY_A (precautionary, security incident)"
Where each role reads this document
Every technical role reads CLAUDE.md §Role Enforcement at startup (step 6 for secret-manager,
referenced in escalation tables for all other roles). This playbook is the extended reference —
link to it from any role file when more context is needed.
Related documents
| Document | Purpose |
|---|---|
docs/playbooks/roles-and-skills.md | Full role inventory — skills, file paths, startup sequences |
docs/playbooks/secret-manager-request.md | Full queue request template (Class B) |
docs/playbooks/secret-manager.md | Secret Manager operating manual (SOPS operations, tiers, rotation log) |
docs/playbooks/infra-task-executor.md | Infra task request flow (server ops from non-p24-infra) |
p24-infra/CLAUDE.md §Role Enforcement | Canonical boundary matrix + Agent() template (loaded every session) |
C:\code_2026\CLAUDE.md §Role Enforcement | Ecosystem-wide summary (loaded for all projects) |