Gate 08: Spawned Agent Permission Verification
Priority: CRITICAL Type: BLOCKING Enforcement: Pre-Spawn (before spawned agents) Last Updated: 2026-01-15
Purpose
Prevent silent file persistence failures by verifying Write(*) permissions are configured BEFORE spawning spawned agents that need to create or modify files.
Problem Prevented:
- Background agents claim success but files not persisted
- PRDs, ADRs, and other artifacts generated but not saved
- Manual extraction required from agent logs
Production Evidence:
- Harvana PRD: 26KB generated, not persisted (permission failure)
- Harvana ADRs: 6 architecture documents referenced but missing
- Multiple specialist agent failures due to missing Write(*) permission
Reference: TC-BA-005 (Permission Pre-Verification test case)
Gate Rules
Rule 1: Settings File Existence (BLOCKING)
Requirement: .claude/settings.json MUST exist before spawning spawned agents.
Verification:
if [ ! -f .claude/settings.json ]; then
BLOCK with error: "settings.json not found"
REQUIRE: Run setup script OR create manually
STATUS: BLOCKED
fi
```text
**Error Message:**
```text
❌ GATE 08: BACKGROUND AGENT PERMISSIONS - BLOCKED
.claude/settings.json not found
PROBLEM:
Background agents need pre-configured Write(*) permissions.
Without settings.json, agents cannot persist files to repository.
SOLUTIONS:
Option 1: Use ai-pack setup script (Recommended)
python3 .ai-pack/templates/.claude-setup.py
Option 2: Manual setup
mkdir -p .claude
cp .ai-pack/templates/.claude/settings.json .claude/
Verify: python3 tests/tools/verify-background-agent-permissions.py
Option 3: Run agents in FOREGROUND
Use interactive mode
Agents will prompt for permissions interactively
Trade-off: Sequential execution (no parallel)
Cannot spawn spawned agent until fixed.
```text
---
### Rule 2: Write(*) Permission (BLOCKING)
**Requirement:** `Write(*)` MUST be in `permissions.allow` array.
**Verification:**
```bash
if ! grep -q '"Write(\*)"' .claude/settings.json; then
BLOCK with error: "Write(*) not configured"
REQUIRE: Add to permissions.allow
STATUS: BLOCKED
fi
```text
**Error Message:**
```text
❌ GATE 08: BACKGROUND AGENT PERMISSIONS - BLOCKED
Write(*) not in permissions.allow
Current configuration:
{
"permissions": {
"allow": [
"Edit(*)",
"Read(*)",
"Bash(git:*)"
// ❌ Missing: "Write(*)"
]
}
}
PROBLEM:
Background agents need Write(*) to persist files.
Without it:
- Write() calls fail silently
- Files not created
- Agent reports "success" but output missing
REQUIRED FIX:
Add "Write(*)" to permissions.allow array:
{
"permissions": {
"allow": [
"Write(*)", // ← Add this
"Edit(*)",
"Read(*)",
"Bash(git:*)"
],
"defaultMode": "bypassPermissions"
}
}
EVIDENCE:
- Harvana PRD: 26KB generated, not persisted
- Multiple specialist failures from missing permission
Cannot spawn spawned agent until Write(*) configured.
```text
---
### Rule 3: defaultMode Configuration (BLOCKING)
**Requirement:** `permissions.defaultMode` MUST be `"bypassPermissions"`.
**Verification:**
```bash
if ! grep -q '"bypassPermissions"' .claude/settings.json; then
BLOCK with error: "defaultMode not set correctly"
REQUIRE: Set to bypassPermissions
STATUS: BLOCKED
fi
```text
**Error Message:**
```text
❌ GATE 08: BACKGROUND AGENT PERMISSIONS - BLOCKED
defaultMode not set to "bypassPermissions"
Current configuration:
{
"permissions": {
"defaultMode": "acceptEdits" // ❌ WRONG
}
}
PROBLEM:
Background agents run non-interactively and cannot prompt for permissions.
With wrong defaultMode:
- Permission prompts block execution
- Agent hangs waiting for user input
- Timeout or silent failure
REQUIRED FIX:
Set defaultMode to "bypassPermissions":
{
"permissions": {
"allow": [
"Write(*)",
"Edit(*)",
"Read(*)"
],
"defaultMode": "bypassPermissions" // ← Must be this
}
}
WHY: Background agents must have pre-approved permissions.
Cannot spawn spawned agent until defaultMode fixed.
```text
---
### Rule 4: Local Override Detection (WARNING)
**Check:** Detect if `.claude/settings.local.json` exists (may override settings.json).
**Verification:**
```bash
if [ -f .claude/settings.local.json ]; then
WARN: "settings.local.json may override settings.json"
RECOMMEND: Add Write(*) to local file OR remove it
STATUS: WARNING (not blocking)
fi
```text
**Warning Message:**
```text
⚠️ GATE 08: BACKGROUND AGENT PERMISSIONS - WARNING
.claude/settings.local.json detected
This file may override settings.json configuration.
RECOMMENDATION:
Ensure Write(*) is also in settings.local.json:
grep "Write(\*)" .claude/settings.local.json
OR remove settings.local.json:
rm .claude/settings.local.json
Proceeding but verify permissions work correctly...
```text
---
## Enforcement Points
### Point 1: Before Spawning Background Planning Agents
**When:** Before calling `Task(..., spawning agents)` for Product Manager, Architect, Designer, Inspector
**Check:**
```python
# Before spawning background planning agent
run_permission_verification()
def run_permission_verification():
# Check 1: settings.json exists
if not Path(".claude/settings.json").exists():
raise PermissionError("Gate 08 BLOCKED: settings.json not found")
# Check 2: Load settings
with open(".claude/settings.json") as f:
settings = json.load(f)
# Check 3: Write(*) in allow list
allow_list = settings.get("permissions", {}).get("allow", [])
if "Write(*)" not in allow_list:
raise PermissionError("Gate 08 BLOCKED: Write(*) not configured")
# Check 4: defaultMode correct
default_mode = settings.get("permissions", {}).get("defaultMode")
if default_mode != "bypassPermissions":
raise PermissionError("Gate 08 BLOCKED: defaultMode incorrect")
# All checks passed
return True
```text
**Passes:** All checks pass
**Fails:** Any check fails (BLOCKING)
---
### Point 2: Before Spawning Background Worker Agents
**When:** Before calling `Task(..., spawning agents)` for Engineer/Worker roles that create files
**Check:**
```python
# Lighter check for worker agents (may not create as many files)
if will_create_files(task):
run_permission_verification()
```text
**Passes:** Verification passes OR task won't create files
**Fails:** Verification fails and task will create files (BLOCKING)
---
## Verification Utility
**Tool:** `tests/tools/verify-background-agent-permissions.py`
**Usage:**
```bash
# Verify permissions before spawning agents
python3 tests/tools/verify-background-agent-permissions.py
# From specific directory
python3 tests/tools/verify-background-agent-permissions.py --repo-root /path/to/repo
```text
**Output:**
```text
🔍 Checking spawned agent permissions...
✅ .claude/settings.json exists
✅ settings.json is valid JSON
✅ Write(*) permission configured
✅ Edit(*) permission configured
✅ Read(*) permission configured
✅ defaultMode: bypassPermissions
✅ Git permissions configured
============================================================
PERMISSION VERIFICATION RESULTS
============================================================
✅ ALL CHECKS PASSED
Background agents are properly configured for:
- Writing files to repository
- Editing existing files
- Reading project files
- Running git commands
Safe to spawn spawned agents with spawning agents
✅ PERMISSION VERIFICATION PASSED
Safe to spawn spawned agents!
```text
---
## Required Configuration
**Minimum `.claude/settings.json`:**
```json
{
"permissions": {
"allow": [
"Write(*)", // REQUIRED for file creation
"Edit(*)", // RECOMMENDED for file editing
"Read(*)", // RECOMMENDED for reading files
"Bash(git:*)", // RECOMMENDED for git operations
"Bash(npm:install)",
"Bash(npm:test)",
"Bash(dotnet:*)"
],
"defaultMode": "bypassPermissions" // REQUIRED for spawned agents
}
}
```text
**Why Each Permission:**
| Permission | Required? | Purpose |
|------------|-----------|---------|
| `Write(*)` | **REQUIRED** | Create new files (PRDs, ADRs, code, tests) |
| `Edit(*)` | Recommended | Modify existing files |
| `Read(*)` | Recommended | Read project files for context |
| `Bash(git:*)` | Recommended | Commit changes, check status |
| `defaultMode: bypassPermissions` | **REQUIRED** | Non-interactive permission approval |
---
## Bypass Conditions
**This gate CANNOT be bypassed.**
**Alternatives if permissions cannot be configured:**
1. **Run agents interactively:**
```python
Task(
subagent_type="general-purpose",
description="Create PRD",
prompt="..."
)
```text
- Can prompt for permissions interactively
- Sequential execution only
- No configuration needed
2. **Manual artifact creation:**
- Don't spawn agent
- Create artifacts manually
- Update task packet directly
**Rationale:** Spawned agents MUST have Write(*) permission. No workaround exists for spawned execution without permissions.
---
## Recovery Procedures
### Scenario 1: Agent Completed But Files Missing
**Symptoms:**
- Agent reports success
- `ls <expected-file>` → "No such file or directory"
- Agent output contains file content
**Root Cause:** Permission failure (Write(*) not configured)
**Recovery:**
```bash
# Step 1: Verify permissions
python3 tests/tools/verify-background-agent-permissions.py
# Step 2: Extract content from agent output
grep -A 1000 "Write(" <agent-output-file>
# Step 3: Manually create missing files
# (Copy content from agent output)
# Step 4: Fix permissions
# Add Write(*) to .claude/settings.json
# Step 5: Verify fix
python3 tests/tools/verify-background-agent-permissions.py
```text
---
### Scenario 2: Agent Hangs or Times Out
**Symptoms:**
- Agent doesn't complete
- No output after long time
- Process appears stuck
**Root Cause:** Wrong defaultMode (agent waiting for permission prompt)
**Recovery:**
```bash
# Step 1: Kill hung agent
# (Use task manager or kill command)
# Step 2: Fix defaultMode
# Set to "bypassPermissions" in .claude/settings.json
# Step 3: Verify fix
python3 tests/tools/verify-background-agent-permissions.py
# Step 4: Re-spawn agent
# Try again with correct configuration
```text
---
## Integration with Other Gates
**Related Gates:**
- **Gate 10 (Persistence):** Verifies files exist after agent completes
- **Gate 05 (Lean Flow):** Prevents overwhelming verification with too many agents
**Test Cases:**
- **TC-BA-005:** Permission Pre-Verification (validates this gate)
- **TC-BA-001:** File Persistence Verification (detects failures from missing permissions)
- **TC-BA-003:** Working Directory Context (ensures files written to correct location)
**Flow:**
```text
1. Gate 08 (this gate): Verify permissions BEFORE spawning
↓ PASS
2. Spawn spawned agent
↓
3. Agent executes with Write(*) permission
↓
4. Gate 10: Verify files persist after completion
↓ PASS
5. Task complete
```text
---
## Metrics
**Effectiveness Tracking:**
```markdown
## Permission Gate Metrics
**Before Gate 08:**
- Permission failures: ~40% of spawned agents
- Files not persisted: ~40%
- Manual extraction required: ~40%
- Time to discover: 10-30 minutes
**After Gate 08:**
- Permission failures: 0% (blocked before spawn)
- Files not persisted: 0% (permissions verified)
- Manual extraction required: 0%
- Time to discover: Immediate (pre-flight check)
**Improvement:**
- 100% prevention of permission failures
- 100% reduction in manual extraction
- Immediate feedback vs delayed discovery
```text
---
## Examples
### Example 1: Missing Write(*) Permission
**Scenario:** Orchestrator attempts to spawn Product Manager for PRD
```python
# Orchestrator code
Task(
subagent_type="general-purpose",
description="Create PRD",
prompt="""Product Manager role from .ai-pack/roles/product-manager.md
Create Product Requirements Document for user authentication feature.
Persist to: docs/product/2026-01-15-auth/prd.md
""",
spawning agents # Background agent
)
```text
**Gate 08 Response:**
```text
❌ GATE 08: BACKGROUND AGENT PERMISSIONS - BLOCKED
Write(*) not in permissions.allow
Current .claude/settings.json:
{
"permissions": {
"allow": [
"Edit(*)",
"Read(*)"
],
"defaultMode": "bypassPermissions"
}
}
PROBLEM:
Product Manager needs Write(*) to create PRD.
Without it, agent will fail silently and PRD won't be created.
REQUIRED FIX:
Add "Write(*)" to permissions.allow:
{
"permissions": {
"allow": [
"Write(*)", // ← Add this
"Edit(*)",
"Read(*)"
],
"defaultMode": "bypassPermissions"
}
}
Save changes and retry.
Cannot spawn Product Manager until Write(*) configured.
```text
---
### Example 2: Wrong defaultMode
**Scenario:** Background agent for architecture design
```python
Task(
subagent_type="general-purpose",
description="Create architecture design",
prompt="Architect role. Create ADRs...",
spawning agents
)
```text
**Gate 08 Response:**
```text
❌ GATE 08: BACKGROUND AGENT PERMISSIONS - BLOCKED
defaultMode not set to "bypassPermissions"
Current: "defaultMode": "acceptEdits"
PROBLEM:
Background agents run non-interactively.
With "acceptEdits" mode:
- Agent will prompt for Write permission
- No user to respond to prompt
- Agent hangs or times out
REQUIRED FIX:
{
"permissions": {
"allow": ["Write(*)", "Edit(*)", "Read(*)"],
"defaultMode": "bypassPermissions" // ← Change this
}
}
Cannot spawn Architect until defaultMode fixed.
```text
---
### Example 3: All Checks Pass
**Scenario:** Properly configured permissions
```bash
# settings.json correctly configured
{
"permissions": {
"allow": [
"Write(*)",
"Edit(*)",
"Read(*)",
"Bash(git:*)"
],
"defaultMode": "bypassPermissions"
}
}
```text
**Gate 08 Response:**
```text
✅ GATE 08: BACKGROUND AGENT PERMISSIONS - PASSED
All permission checks passed:
✅ .claude/settings.json exists
✅ Write(*) configured
✅ Edit(*) configured
✅ Read(*) configured
✅ defaultMode: bypassPermissions
Safe to spawn spawned agents!
Proceeding with agent spawn...
```text
---
## Troubleshooting
### Issue 1: Permission Check Script Not Found
**Error:** `python3 tests/tools/verify-background-agent-permissions.py: No such file`
**Solution:**
```bash
# Verify ai-pack submodule is initialized
git submodule update --init --recursive
# Or download script directly
curl -O https://raw.githubusercontent.com/.../verify-background-agent-permissions.py
python3 verify-background-agent-permissions.py
```text
---
### Issue 2: JSON Syntax Error in settings.json
**Error:** `settings.json is invalid JSON`
**Solution:**
```bash
# Validate JSON
python3 -m json.tool .claude/settings.json
# Common issues:
# - Trailing commas
# - Missing quotes
# - Unescaped backslashes
# Fix and retry
```text
---
### Issue 3: Permissions Work Locally But Fail in CI/CD
**Problem:** Different settings in CI environment
**Solution:**
```bash
# CI/CD must also have .claude/settings.json
# Option 1: Copy template in CI script
cp .ai-pack/templates/.claude/settings.json .claude/
# Option 2: Use environment variable
export CLAUDE_BYPASS_PERMISSIONS=true
```text
---
## Success Criteria
**This gate is successful when:**
✅ Zero permission failures in spawned agents
✅ 100% of artifacts persist when agents claim success
✅ No manual extraction required
✅ Immediate feedback when permissions missing
✅ Clear remediation guidance provided
**Leading Indicators:**
- Permission verification runs before every background spawn
- Developers proactively configure settings.json
- Permission-related failures drop to zero
- No production failures from missing Write(*) permission
---
## References
**Test Cases:**
- TC-BA-005: Permission Pre-Verification (validates this gate)
- TC-BA-001: File Persistence Verification (detects failures)
**Tools:**
- `tests/tools/verify-background-agent-permissions.py`
**Documentation:**
- `roles/orchestrator.md` - Section 2.14 (Spawned Agent Permission Verification)
- `templates/.claude/settings.json` - Template configuration
- `templates/.claude/PERMISSIONS.md` - Permission documentation
**Production Failures:**
- Harvana PRD: 26KB generated, not persisted
- Harvana ADRs: 6 documents missing
- Multiple specialist agent failures
**Related Gates:**
- Gate 10: Persistence Gate (artifact verification)
- Gate 05: Lean Flow (WIP limits)
---
**Version:** 1.0.0
**Status:** Active - MANDATORY
**Enforcement:** BLOCKING on violations