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

RoleCan doCannot do (delegate to →)
dev-coderCode, migrations, PRs, testsSOPS → secret-manager · SSH/Docker → sys-admin · security audit → sys-security
dev-reviewerPR review, code qualityImplementation → dev-coder · credentials → secret-manager · server ops → sys-admin
dev-testerTest planning, coverage, writing testsImplementation → dev-coder · credentials → secret-manager · server ops → sys-admin
sys-adminSSH, Docker, Ansible, DNS, monitoringSOPS writes → secret-manager · security audits → sys-security · feature code → dev-coder
sys-securitySecurity audits, read-only credential verificationSOPS writes/rotation → secret-manager · feature code → dev-coder · server config → sys-admin
secret-managerAll SOPS reads/writes, credential distributionFeature code → dev-coder · server ops → sys-admin
creative rolesBrand content, creative outputAll 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-manager with sys-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 PreToolUse hook variant that blocks sops --decrypt whenever the invoking agent’s declared role is not secret-manager was 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.


DocumentPurpose
docs/playbooks/roles-and-skills.mdFull role inventory — skills, file paths, startup sequences
docs/playbooks/secret-manager-request.mdFull queue request template (Class B)
docs/playbooks/secret-manager.mdSecret Manager operating manual (SOPS operations, tiers, rotation log)
docs/playbooks/infra-task-executor.mdInfra task request flow (server ops from non-p24-infra)
p24-infra/CLAUDE.md §Role EnforcementCanonical boundary matrix + Agent() template (loaded every session)
C:\code_2026\CLAUDE.md §Role EnforcementEcosystem-wide summary (loaded for all projects)