Reeve
Plugins & Extensions

Role Enforcer Plugin

Role Enforcer: Unified three-tier enforcement for Coordinator → Manager → Worker

Role Enforcer Plugin

Code = Law. Each tier has enforced boundaries.

The Role Enforcer is a unified policy plugin that enforces the three-tier architecture (Coordinator → Manager → Worker). It supersedes the older Coordinator Enforcer by adding manager-tier enforcement and more granular file-path rules for coordinators.

Three-Tier Enforcement Model

┌──────────────────────────────────────────────────────────────────┐
│  COORDINATOR (CEO) — agent:main:main                             │
│                                                                   │
│  ✅ Read files, web_search, web_fetch, browser, sessions_spawn   │
│  ✅ Edit/Write own config: MEMORY.md, AGENTS.md, SOUL.md, etc.  │
│  🚫 Edit/Write code files (.ts, .py, .js, package.json, etc.)   │
│  🚫 exec: git, npm, python, rm, mv, cp                          │
│  ✅ exec: ls, cat, head, grep, find, pwd, echo (read-only)      │
│  ⚠️  Read large repo files: context bloat warning                │
└──────────────────────────┬───────────────────────────────────────┘

            Routes to domain managers

     ┌─────────────────────┼─────────────────────┐
     ▼                     ▼                     ▼
┌──────────────┐  ┌──────────────┐  ┌──────────────┐
│  MANAGER (VP)│  │  MANAGER (VP)│  │  MANAGER (VP)│
│  agentpik    │  │  freya       │  │  textlands   │
│              │  │              │  │              │
│ ✅ Read      │  │ ✅ Read      │  │ ✅ Read      │
│ ✅ Spawn     │  │ ✅ Spawn     │  │ ✅ Spawn     │
│ ✅ Investigate│ │ ✅ Investigate│ │ ✅ Investigate│
│ 🚫 ALL Edit  │  │ 🚫 ALL Edit  │  │ 🚫 ALL Edit  │
│ 🚫 ALL Write │  │ 🚫 ALL Write │  │ 🚫 ALL Write │
│ 🚫 impl exec │  │ 🚫 impl exec │  │ 🚫 impl exec │
└──────┬───────┘  └──────┬───────┘  └──────┬───────┘
       │                 │                 │
       ▼                 ▼                 ▼
┌──────────────────────────────────────────────────┐
│  WORKERS (IC) — sub-agent sessions               │
│  ✅ Everything. No restrictions. Do the work.    │
└──────────────────────────────────────────────────┘

Role Detection

The plugin identifies agent roles from the session key:

PatternDetected Role
agent:main:main or mainCoordinator
agent:agentpik:main, agent:freya:main, etc.Manager
Any session containing :subagent:Worker
Unknown / unmatchedWorker (safe default)

Sub-agent sessions are always workers, regardless of which agent spawned them.

Tier Rules in Detail

Coordinator (CEO)

The coordinator interfaces with the user, plans work, and delegates. It should never touch code directly.

Allowed:

  • Read — any file (with context bloat warnings for large repo files)
  • sessions_spawn — how it delegates work
  • sessions_list, sessions_poll — monitoring sub-agents
  • web_search, web_fetch, browser — research
  • image, tts, message, nodes, canvas, process — platform tools
  • memory_search, memory_get — memory access
  • Edit/Write to config files only: MEMORY.md, memory/*.md, memory/*.json, AGENTS.md, SOUL.md, USER.md, TOOLS.md, HEARTBEAT.md, BOOTSTRAP.md

Blocked:

  • Edit/Write to code files: .ts, .py, .js, .go, .rs, .java, .swift, .rb, .php, .vue, .svelte, package.json, Dockerfile, Makefile, .sh, and many more
  • exec for mutations: git, npm, pnpm, yarn, cargo, make, python *.py, node *.js, rm, mv, cp

Allowed exec (read-only):

  • ls, cat, head, tail, grep, find, which, pwd, echo, wc, date, whoami

Context bloat warning (non-blocking): triggered when reading files under src/, lib/, dist/, node_modules/, or packages/ without a limit parameter or with limit > 50.

Manager (VP)

Managers understand their domain deeply and delegate implementation. They investigate but never implement.

Allowed:

  • Read — any file (with context bloat warnings for repo files without limit)
  • sessions_spawn — how they delegate to workers
  • memory_search, memory_get — memory access
  • web_search, web_fetch — research
  • message, browser, process, etc. — platform tools

Allowed exec (investigation only):

  • File inspection: ls, cat, head, tail, grep, find, wc, file, du
  • Git read-only: git log, git status, git branch, git diff --stat, git diff --name, git show --stat, git show --name, git remote -v, git stash list
  • Shell basics: echo, pwd, which, date, whoami
  • Process inspection: ps, top -l 1, df
  • Reeve read-only: reeve gateway status, reeve help

Blocked (ALL):

  • Edit — all files, no exceptions
  • Write — all files, no exceptions
  • Git mutations: git commit, git push, git merge, git rebase, git checkout -b, git reset, git cherry-pick, git add, git rm, git mv, git tag, git stash save/push/pop/drop/apply
  • Package managers: npm, npx, pnpm, yarn, pip, pip3, pipenv, poetry, cargo, go build/install/get
  • Build tools: make, cmake, gradle, mvn
  • Script execution: python, python3, node, deno, bun, ruby, perl, bash, sh, zsh
  • File mutations: cp, mv, rm, mkdir, touch, chmod, chown, ln
  • Editors: vi, vim, nano, sed
  • Deploy/services: docker, kubectl, systemctl, service
  • Reeve mutations: reeve gateway start/stop/restart

Context bloat warning (non-blocking): triggered when reading files under src/, lib/, dist/, app/, api/, services/, components/, pages/, modules/, cmd/, pkg/, internal/ without a limit or with limit > 100.

Worker (IC)

Workers do the actual implementation. No restrictions whatsoever.

All tools, all files, all exec commands. Workers are spawned with fresh context and a focused task — they need full freedom to get it done.

Installation

  1. Copy the plugin to your Reeve plugins location:
# User plugins (recommended)
cp -r extensions/role-enforcer ~/.reeve/plugins/

# Or system-wide (already included in Reeve repo)
ls extensions/role-enforcer/index.ts
  1. Enable in reeve.json:
{
  "plugins": {
    "role-enforcer": {
      "enabled": true
    }
  }
}
  1. Restart Reeve gateway:
reeve gateway restart

Configuration

Minimal Config

{
  "plugins": {
    "role-enforcer": {
      "enabled": true,
      "logBlocks": true
    }
  }
}

Full Config

{
  "plugins": {
    "role-enforcer": {
      "enabled": true,
      "logBlocks": true,

      "coordinatorSessionPatterns": ["^agent:main:main$", "^main$"],
      "coordinatorBlockMessage": "🚫 Coordinator cannot do direct work. Use sessions_spawn.",
      "coordinatorAllowedFilePatterns": [
        "MEMORY\\.md$", "/memory/.*\\.md$", "AGENTS\\.md$",
        "SOUL\\.md$", "USER\\.md$", "TOOLS\\.md$", "HEARTBEAT\\.md$"
      ],
      "coordinatorBlockedFilePatterns": [
        "\\.py$", "\\.ts$", "\\.tsx$", "\\.js$", "\\.jsx$",
        "package\\.json$", "Dockerfile$", "\\.sh$"
      ],
      "coordinatorExecAllowPatterns": [
        "^ls(\\s|$)", "^cat\\s+", "^grep\\s+", "^find\\s+"
      ],
      "coordinatorExecBlockPatterns": [
        "^git\\s+", "^npm\\s+", "^rm\\s+", "^mv\\s+"
      ],
      "strictMode": false,

      "managerAgentIds": ["agentpik", "freya", "textlands", "reeve-backend"],
      "managerSessionPatterns": [
        "^agent:agentpik:main$",
        "^agent:freya:main$",
        "^agent:textlands:main$",
        "^agent:reeve-backend:main$"
      ],
      "managerBlockMessage": "🚫 Manager cannot implement directly. Spawn a worker.",
      "managerExecAllowPatterns": [
        "^ls(\\s|$)", "^cat\\s+", "^git\\s+log", "^git\\s+status"
      ],
      "managerExecBlockPatterns": [
        "^git\\s+commit", "^npm\\s+", "^python\\s+"
      ],
      "managerReadWarnLines": 100
    }
  }
}

Options Reference

OptionTypeDefaultDescription
enabledbooleantrueEnable/disable enforcement
logBlocksbooleantrueLog blocked attempts to gateway log
Coordinator
coordinatorSessionPatternsstring[]["^agent:main:main$", "^main$"]Regex patterns for coordinator sessions
coordinatorBlockMessagestring(see defaults)Message shown when coordinator is blocked
coordinatorAllowedFilePatternsstring[](14 patterns)File paths coordinator CAN edit/write
coordinatorBlockedFilePatternsstring[](38 patterns)File paths coordinator CANNOT edit/write
coordinatorExecAllowPatternsstring[](12 patterns)Exec commands coordinator can run
coordinatorExecBlockPatternsstring[](10 patterns)Exec commands blocked for coordinator
strictModebooleanfalseBlock ALL tools except explicit allowlist
Manager
managerAgentIdsstring[]["agentpik", "freya", "textlands", "reeve-backend"]Agent IDs treated as managers
managerSessionPatternsstring[](4 patterns)Regex patterns for manager sessions
managerBlockMessagestring(see defaults)Message shown when manager is blocked
managerExecAllowPatternsstring[](22 patterns)Exec commands managers can run
managerExecBlockPatternsstring[](36 patterns)Exec commands blocked for managers
managerReadWarnLinesnumber100Warn if Read has no limit or limit > this

Error Messages

When blocked, agents receive actionable guidance:

Coordinator blocked from editing code:

🚫 Coordinator cannot do direct work. Use sessions_spawn to delegate to a manager or worker.

Blocked tool: Edit
File: src/api/auth.ts
Reason: Blocked: code file (\.ts$)
Session: agent:main:main

Coordinator CAN edit: MEMORY.md, memory/*.md, AGENTS.md, SOUL.md, USER.md, TOOLS.md

To edit code files, spawn a sub-agent:
  sessions_spawn(task="Edit src/api/auth.ts to ...", label="edit-task")

Manager blocked from writing:

🚫 Manager cannot implement directly. Spawn a worker sub-agent via sessions_spawn.

Blocked tool: Write
File: src/components/Login.tsx
Session: agent:agentpik:main

As a MANAGER, you understand and delegate — you don't implement.
Spawn a worker to make this change:
  sessions_spawn(task="Create/update src/components/Login.tsx to ...", label="impl-task")

Strict Mode

For maximum coordinator enforcement, enable strict mode. Only explicitly listed tools are permitted:

{
  "plugins": {
    "role-enforcer": {
      "enabled": true,
      "strictMode": true
    }
  }
}

In strict mode, the coordinator can only use: Read, memory_search, memory_get, sessions_spawn, sessions_list, sessions_poll, web_search, web_fetch, browser, image, tts, message, nodes, canvas, process.

Everything else is blocked. Manager and worker rules are unaffected by strict mode.

Gateway API

Check Status

reeve gateway call role-enforcer.status

Returns:

{
  "ok": true,
  "enabled": true,
  "coordinatorPatterns": ["^agent:main:main$", "^main$"],
  "managerAgents": ["agentpik", "freya", "textlands", "reeve-backend"],
  "stats": {
    "blockedCalls": 42,
    "allowedCalls": 1337,
    "warnings": 8,
    "lastBlockedTool": "Edit",
    "lastBlockedAt": "2026-02-15T10:30:00.000Z",
    "blocksByRole": { "coordinator": 30, "manager": 12 },
    "blocksByTool": { "Edit": 25, "Write": 5, "exec": 12 }
  }
}

Detect Role

reeve gateway call role-enforcer.detect-role \
  '{"sessionKey": "agent:agentpik:main"}'

Simulate Tool Call

reeve gateway call role-enforcer.simulate '{
  "sessionKey": "agent:main:main",
  "toolName": "Edit",
  "filePath": "src/index.ts"
}'
# → { "wouldBlock": true, "role": "coordinator", "reason": "Blocked: code file" }

reeve gateway call role-enforcer.simulate '{
  "sessionKey": "agent:freya:main",
  "toolName": "exec",
  "command": "git log --oneline -5"
}'
# → { "wouldBlock": false, "role": "manager", "reason": "exec command allowed (investigation)" }

Reset Stats

reeve gateway call role-enforcer.reset-stats

Relationship to Coordinator Enforcer

The Role Enforcer supersedes the Coordinator Enforcer:

FeatureCoordinator EnforcerRole Enforcer
Coordinator enforcement✅ (enhanced)
Manager enforcement
Worker detection
File-path aware blocking❌ (blocks all Edit/Write)✅ (allows config files)
Context bloat warnings
Per-role exec patterns❌ (one set)✅ (separate coordinator/manager)
Read warnings

Migration: Replace coordinator-enforcer with role-enforcer in your reeve.json. The coordinator rules are a superset — everything that was blocked before is still blocked, plus coordinators can now edit their own config files (MEMORY.md, AGENTS.md, etc.).

{
  "plugins": {
    "coordinator-enforcer": { "enabled": false },
    "role-enforcer": { "enabled": true }
  }
}

Hook Priority

The role-enforcer registers its before_tool_call hook with priority 1000 (high), ensuring it runs before other plugins. This means enforcement happens first, before any other tool-call hooks can modify behavior.

Troubleshooting

Plugin not blocking?

  1. Check enabled: true in config
  2. Verify session key matches the expected patterns
  3. Check logs: grep "role-enforcer" ~/.reeve/logs/gateway.log
  4. Use the simulate API to test: reeve gateway call role-enforcer.simulate '{...}'

Manager agent not being enforced?

Ensure the agent ID is in managerAgentIds and its main session pattern is in managerSessionPatterns:

{
  "managerAgentIds": ["my-agent"],
  "managerSessionPatterns": ["^agent:my-agent:main$"]
}

Need to disable temporarily?

# Via config
# Set "enabled": false in reeve.json and restart gateway

# Or via gateway call
reeve gateway call role-enforcer.reset-stats  # (no disable endpoint — edit config)

See Also

On this page