# Bug #9: Agent Spawn Command Missing - Docker Container CLI Issue

## Status: CONFIRMED ROOT CAUSE IDENTIFIED

**Severity:** P0 - BLOCKING - Agent execution never completes
**Confidence:** 0.92
**Impact:** All Docker CFN Loop workflows fail silently
**Date Identified:** 2025-11-14

---

## Executive Summary

The Docker CFN Loop infrastructure successfully spawns agent containers, but agents never complete their work because the spawn-agent.sh script attempts to execute a non-existent CLI command inside containers:

```bash
npx claude-flow-novice agent-spawn --type ${AGENT_TYPE} --task-id ${TASK_ID} --agent-id ${AGENT_ID}
```

**Problem:** The CLI has no `agent-spawn` subcommand registered in the main entry point.

**Result:** Containers start, register in Redis, then silently fail with command-not-found errors. The coordinator's wait loop times out after polling an empty completion counter forever.

---

## Root Cause Analysis

### Issue Location

**File:** `.claude/skills/cfn-docker-agent-spawning/spawn-agent.sh`
**Line:** 408
**Command:** `npx claude-flow-novice agent-spawn --type ${AGENT_TYPE} --task-id ${TASK_ID} --agent-id ${AGENT_ID} ${CONTEXT_ARG}`

### CLI Structure Investigation

#### 1. What CLI Commands Exist (package.json)

```json
"bin": {
  "claude-flow-novice": "dist/cli/index.js",      // Main entry point
  "cfn-spawn": "dist/cli/spawn.js",               // Dedicated spawn binary
  "cfn-loop": "dist/cli/cfn-loop.js",
  "cfn-swarm": "dist/cli/cfn-swarm.js",
  // ... other commands
}
```

**Key Finding:** There are TWO separate entry points:
- `claude-flow-novice` - Main CLI
- `cfn-spawn` - Dedicated spawning CLI

#### 2. Main CLI Entry Point (src/cli/index.ts)

```typescript
// Supported commands:
switch (command) {
  case 'agent':
    await agentCommand(agentType, options);
    break;

  default:
    console.error(`Unknown command: ${command}`);
    process.exit(1);
}
```

**Supported syntax:**
```bash
npx claude-flow-novice agent <type> [options]     // ✅ WORKS
npx claude-flow-novice agent-spawn ...             // ❌ NOT REGISTERED
```

#### 3. Spawning Entry Point (src/cli/spawn.ts)

Routes to `agent-spawn.ts` main function:

```typescript
import { main as agentSpawnMain } from './agent-spawn.js';

async function main() {
  const args = process.argv.slice(2);
  await agentSpawnMain(args);  // Delegates to agent-spawn.ts
}
```

**Supported via separate binary:**
```bash
npx cfn-spawn agent <type> [options]               // ✅ WORKS
npx cfn-spawn <type> [options]                     // ✅ WORKS (agent implied)
```

#### 4. Agent Spawn Implementation (src/cli/agent-spawn.ts)

- **290 lines** of fully implemented agent spawning logic
- Has complete `parseAgentArgs()` and `spawnAgent()` functions
- Supports all required options: `--type`, `--task-id`, `--agent-id`, `--context`
- **BUT** only exposed through `cfn-spawn` binary, not main CLI

### The Mismatch

```
spawn-agent.sh (Docker container)
    ↓
Tries to execute: npx claude-flow-novice agent-spawn ...
    ↓
Main CLI entry point (src/cli/index.ts)
    ↓
switch(command) case: 'agent-spawn'  ❌ NOT HANDLED
    ↓
default case: console.error("Unknown command: agent-spawn")
    ↓
Container exits silently with code 1
    ↓
Coordinator timeout (waits for completion counter that never increments)
```

---

## Evidence

### 1. CLI Registration Proof

**File:** `src/cli/index.ts` (lines 100-110)

```typescript
const { command, agentType, options } = parseArgs(args);

switch (command) {
  case 'agent':
    await agentCommand(agentType, options);
    break;

  default:
    console.error(`Unknown command: ${command}`);
    console.log('Run with --help for usage information');
    process.exit(1);
}
```

**Fact:** Only `case 'agent'` is registered. No `agent-spawn` case.

### 2. Separate Binary Proof

**File:** `src/cli/spawn.ts` (exists and routes correctly)

This file properly handles agent spawning but is exposed through the `cfn-spawn` binary, not `claude-flow-novice`.

### 3. Docker Image Limitation

**File:** `docker/Dockerfile.agent` or base image

The container runs `npx claude-flow-novice agent-spawn ...` which only works if:
1. Main CLI has `agent-spawn` subcommand, OR
2. Container has `cfn-spawn` available in PATH

Neither condition is met in current setup.

---

## Why This Causes Silent Failure

### Container Execution Flow

```bash
# Inside container, spawn-agent.sh executes:
npx claude-flow-novice agent-spawn --type react-frontend-engineer --task-id batch-1 --agent-id agent-1

# What happens:
1. NPX resolves 'claude-flow-novice' binary
2. Runs dist/cli/index.ts with args: ['agent-spawn', '--type', 'react-frontend-engineer', ...]
3. parseArgs() sets command = 'agent-spawn'
4. switch(command) finds NO matching case
5. default case: console.error("Unknown command: agent-spawn")
6. process.exit(1)
7. Container exits silently

# Coordinator sees:
- Container exited (exit code 1)
- task:completed counter never incremented
- Continues waiting indefinitely (or until timeout)
```

### Coordinator Timeout Behavior

```javascript
// From docker/coordinator/src/coordinator.js or similar
while (completed < total) {
  const completed = await redis.get('task:completed');
  console.log(`Progress: ${completed}/${total}`);

  if (completed >= total) break;

  await sleep(5000);  // Poll every 5 seconds
}
// If agent exits silently, completed stays at 0 forever → timeout
```

---

## Testing Impact

### Why Integration Tests Fail

**Test:** Spawning agents with `spawn-agent.sh`

```bash
docker run ... \
  --name agent-batch-1 \
  claude-flow-novice-agent:latest \
  -c "npx claude-flow-novice agent-spawn --type react-frontend-engineer ..."
```

**Result:**
1. Container starts (visible in `docker ps`)
2. Container exits immediately (command fails)
3. No task completion reported
4. Test times out waiting for completion counter

**Observation:** The only reason tests might appear to work is if they use test mode:

```bash
if [[ "${TASK_ID}" =~ test-.* ]]; then
  # Test mode: fake task completion without actual CLI
  docker run ... -c 'sleep 3 && echo "done"'
else
  # Production: try real agent-spawn (FAILS)
  docker run ... -c 'npx claude-flow-novice agent-spawn ...'
fi
```

---

## Solution Approaches

### Option A: Add agent-spawn Subcommand to Main CLI (RECOMMENDED)

**Why:** Mirrors existing `agent` subcommand, minimal changes

**Changes:**

1. **src/cli/index.ts** - Add case handler:

```typescript
case 'agent-spawn':
case 'agent':
  await agentCommand(agentType, options);
  break;
```

2. Update help text to include `agent-spawn` as alias

3. Update Docker command:

```bash
# Current (broken):
npx claude-flow-novice agent-spawn --type ${AGENT_TYPE} ...

# Already works with agent subcommand:
npx claude-flow-novice agent ${AGENT_TYPE} --type ${AGENT_TYPE} ...
```

**Implementation effort:** 5 minutes (2 lines of code)

### Option B: Create CLI Wrapper Script (ALTERNATIVE)

**Why:** Minimal code changes, shell-based

**Changes:**

1. Create `/usr/local/bin/agent-spawn` wrapper in Docker image:

```bash
#!/bin/bash
# Route to cfn-spawn binary which already works
exec npx cfn-spawn "$@"
```

2. Add to Dockerfile:

```dockerfile
RUN echo '#!/bin/bash' > /usr/local/bin/agent-spawn && \
    echo 'exec npx cfn-spawn "$@"' >> /usr/local/bin/agent-spawn && \
    chmod +x /usr/local/bin/agent-spawn
```

3. Update spawn-agent.sh:

```bash
# Current:
npx claude-flow-novice agent-spawn ...

# New:
agent-spawn ...  # Uses wrapper, routes to cfn-spawn
```

**Implementation effort:** 10 minutes (shell wrapper)

### Option C: Update spawn-agent.sh to Use cfn-spawn (QUICKEST)

**Why:** No code changes to CLI, just update calling script

**Changes:**

1. **File:** `.claude/skills/cfn-docker-agent-spawning/spawn-agent.sh` (line 408)

**Current:**
```bash
DOCKER_CMD="$DOCKER_CMD -c 'cd /app && npx claude-flow-novice agent-spawn --type ${AGENT_TYPE} --task-id ${TASK_ID} --agent-id ${AGENT_ID} ${CONTEXT_ARG}'"
```

**New:**
```bash
DOCKER_CMD="$DOCKER_CMD -c 'cd /app && npx cfn-spawn --type ${AGENT_TYPE} --task-id ${TASK_ID} --agent-id ${AGENT_ID} ${CONTEXT_ARG}'"
```

**Verification:** Check if `cfn-spawn` is available in container (should be, since it's in package.json bin section)

**Implementation effort:** 1 minute (one-line change)

---

## Recommended Fix: Option A + Option C

Implement both to ensure robustness:

### Part 1: Add agent-spawn to Main CLI (Option A)

**File:** `src/cli/index.ts`

```typescript
// Before:
switch (command) {
  case 'agent':
    await agentCommand(agentType, options);
    break;
  default:
    // error...
}

// After:
switch (command) {
  case 'agent':
  case 'agent-spawn':  // Add this line
    await agentCommand(agentType, options);
    break;
  default:
    // error...
}
```

### Part 2: Update spawn-agent.sh (Option C)

**File:** `.claude/skills/cfn-docker-agent-spawning/spawn-agent.sh`

```bash
# Line 408 - Change from:
DOCKER_CMD="$DOCKER_CMD -c 'cd /app && npx claude-flow-novice agent-spawn --type ${AGENT_TYPE} --task-id ${TASK_ID} --agent-id ${AGENT_ID} ${CONTEXT_ARG}'"

# To:
DOCKER_CMD="$DOCKER_CMD -c 'cd /app && npx cfn-spawn --type ${AGENT_TYPE} --task-id ${TASK_ID} --agent-id ${AGENT_ID} ${CONTEXT_ARG}'"
```

### Why Both?

- **Part 1:** Future-proofs the CLI (subcommand aliases are standard UX)
- **Part 2:** Ensures immediate fix in current containers
- **Fallback:** If cfn-spawn isn't in PATH, agent-spawn subcommand still works

---

## Verification Plan

### 1. Build and Test CLI Changes

```bash
npm run build
npx claude-flow-novice agent-spawn --help  # Should work after Part 1
npx cfn-spawn --help                        # Already works (Part 2 check)
```

### 2. Test Container Execution

```bash
docker run --rm \
  -e ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY \
  claude-flow-novice-agent:latest \
  -c 'npx claude-flow-novice agent-spawn --type backend-developer --task-id test-1 --agent-id agent-1' \
  # OR
  -c 'npx cfn-spawn --type backend-developer --task-id test-1 --agent-id agent-1'
```

### 3. Integration Test

```bash
# With spawn-agent.sh fix:
./.claude/skills/cfn-docker-agent-spawning/spawn-agent.sh \
  react-frontend-engineer test-1 agent-1 \
  --memory-limit 512m

# Verify:
# - Container starts (docker ps)
# - Container completes with exit code 0
# - No "Unknown command" in logs
```

### 4. Full Coordinator Test

```bash
# Run coordinator with modified spawn-agent.sh
docker run --rm \
  --name cfn-coordinator \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /path/to/workspace:/workspace:rw \
  -e REDIS_HOST=cfn-redis \
  --network cfn-network \
  cfn-intelligent-coordinator:latest

# Monitor:
# - Agents start and complete
# - task:completed counter increments
# - No timeout after reasonable time
```

---

## Impact Assessment

### Services Affected

- Docker CFN Loop agent execution
- Wave-based coordinator spawning
- Any container using `spawn-agent.sh`

### Data Integrity

- **No data loss risk** (no files modified yet)
- Redis coordination unaffected (issue is CLI not completing)
- Coordinator logic sound (issue is command not found)

### Performance

- **Expected improvement:** From infinite timeout to 5-10 minute completion time
- No negative impact

### Testing

- All integration tests that spawn real agents
- Docker-based CFN Loop tests
- Coordinator orchestration tests

---

## Implementation Checklist

- [ ] Add `agent-spawn` case to main CLI switch statement (src/cli/index.ts)
- [ ] Update help text to document `agent-spawn` as alias
- [ ] Update spawn-agent.sh to use `cfn-spawn` binary
- [ ] Build and test CLI changes locally
- [ ] Test container execution (single agent spawn)
- [ ] Test full coordinator run (end-to-end)
- [ ] Update docker/CLAUDE.md with corrected CLI usage
- [ ] Document in this bug report: completion date and test results

---

## References

**CLI Implementation Files:**
- Main entry: `/mnt/.../src/cli/index.ts` (lines 35-120)
- Agent command: `/mnt/.../src/cli/agent-command.ts`
- Agent spawn: `/mnt/.../src/cli/agent-spawn.ts` (290 lines, fully implemented)
- Spawn binary: `/mnt/.../src/cli/spawn.ts`

**Spawning Script:**
- `/mnt/.../`.claude/skills/cfn-docker-agent-spawning/spawn-agent.sh` (line 408)

**Docker Configuration:**
- `/mnt/.../docker/CLAUDE.md` (comprehensive CFN Loop guide)
- `/mnt/.../docker/Dockerfile.agent`

**Package Configuration:**
- `/mnt/.../package.json` (bin section, lines 7-16)

---

## Conclusion

The agent spawn command is **not missing from the codebase** - it exists as fully-implemented `agent-spawn.ts` with all required logic. The issue is purely **CLI registration**:

1. The `cfn-spawn` binary correctly routes to agent spawning
2. The main `claude-flow-novice` CLI is missing the `agent-spawn` subcommand
3. Containers fail silently when trying the non-existent subcommand
4. Coordinator timeouts waiting for completion that never comes

**Fix is trivial:** 1 line in index.ts + 1 line in spawn-agent.sh = agents execute properly.

**Confidence in diagnosis:** 0.92 (based on code inspection showing missing case statement, separate working binary proving logic is sound, and pattern of silent container failures)
