Issue 08 | Hands-on: Sub-Agent Summoning, Authorization, and Permission Pitfall Avoidance
Pitfall: Dependency direction cannot be reversed! In this project,
Task #2 blockedBy Task #1was mistakenly set (Phase B blockedBy Phase A is correct), but the description text contained incorrect dependency IDs, confusing the Agent. The ID inblockedBymust be the ID of the prerequisite task.
8.1 Configure Permission Whitelist
Create .claude/settings.json:
{
"permissions": {
"allow": [
"Bash(ls:*)",
"Bash(cat:*)",
"Bash(head:*)",
"Bash(tail:*)",
"Bash(find:*)",
"Bash(grep:*)",
"Bash(wc:*)",
"Bash(open:*)",
"Bash(which:*)",
"Bash(node:*)",
"Bash(npx:*)",
"Bash(npm:*)",
"Bash(python3:*)",
"Bash(git:*)",
"Bash(mkdir:*)",
"Bash(cp:*)",
"Bash(mv:*)",
"Bash(touch:*)",
"Bash(rm:*)",
"Bash(echo:*)",
"Bash(tmux:*)",
"Bash(bash:*)",
"Edit",
"Write",
"Read",
"WebSearch",
"Skill",
"Agent",
"SendMessage",
"TeamCreate",
"TeamDelete",
"TaskCreate",
"TaskGet",
"TaskList",
"TaskUpdate"
]
}
}
Pitfall: Permission format must use a colon!
Bash(ls:*)is correct,Bash(ls *)(space) is invalid.
Detailed Explanation of Permission Entries:
| Format | Meaning |
|---|---|
Bash(ls:*) |
Allows all bash commands starting with ls |
Edit |
Allows file editing (no parameter restrictions) |
Write |
Allows file writing |
Read |
Allows file reading |
Skill |
Allows calling Skill (Important!) |
SendMessage |
Allows inter-Agent communication |
Agent |
Allows spawning child Agents |
8.1.1 Spawn Agent
ui-dev
Agent({
name: "ui-dev",
mode: "bypassPermissions",
team_name: "calc-dev",
prompt: `You are ui-dev, responsible for HTML and CSS development.
Important Rules:
- Do not call any Skill (do not use /planning-with-files, /brainstorming, etc.)
- Write code directly, do not create plan files
- Planning has been completed in task_plan.md; you are only responsible for implementation.
First, read requirement.md to understand the requirements.
Your first task: Create index.html
- Semantic structure: header (mode toggle) + main (display area + button grid) + aside (history panel)
- Display area: expression-line (id="expression") + result-line (id="result")
- Button grid: 4Γ5 grid, each button has a unique id
- Numbers: btn-0 to btn-9
- Operators: btn-plus, btn-minus, btn-multiply, btn-divide, btn-percent
- Functions: btn-equals, btn-clear, btn-backspace, btn-decimal, btn-toggle-sign
- Parentheses: btn-paren-left, btn-paren-right
- Mode toggle: btn-mode-toggle
- History panel: id="history-panel", containing id="history-list"
- Add aria-label to all buttons
Your second task: Create style.css
- CSS variable system, two sets: [data-theme="senior"] and [data-theme="standard"]
- Senior mode: buttons 28px+, display 36px+, buttons 80Γ80px+, high-contrast black and white
- Standard mode: buttons 18-20px, display 24px, buttons 48Γ48px, modern color scheme
- transition: all 0.3s for animation
- Responsive: @media breakpoints at 1024px and 768px
Upon completion of each task:
1. TaskUpdate to mark completed
2. SendMessage to notify team-lead
Working directory: /Users/eric/work/teamtest`
})
logic-dev
Agent({
name: "logic-dev",
mode: "bypassPermissions",
team_name: "calc-dev",
prompt: `You are logic-dev, responsible for the JavaScript calculation engine and interaction logic.
Important Rules:
- Do not call any Skill
- Write code directly
- In Phase A, only write pure functions, do not manipulate the DOM
First, read requirement.md to understand the requirements.
Your first task: Create app.js calculation engine
- tokenize: lexical analysis
- parseExpression: Shunting-yard algorithm to convert to RPN
- evaluate: RPN evaluation
- Input helpers: appendNumber, appendOperator, appendDecimal, toggleSign, appendParenthesis
- Division by zero protection: return "Error"
- previewResult: real-time preview
- Unit tests (TDD)
Your second task: DOM event binding
- Bind events via IDs in HTML
- Keyboard mapping: 0-9, +-*/, Enter, Backspace, Escape
- Mode toggle: document.documentElement.dataset.theme + localStorage
- History: array, 10-item limit
- aria-live result announcement
Upon completion of each task:
1. TaskUpdate to mark completed
2. SendMessage to notify team-lead
Working directory: /Users/eric/work/teamtest`
})
Pitfall: Why can't child Agents call Skill?
bypassPermissionsonly automatically approves operations listed in theallowlist withinsettings.json. Skill is a tool call independent of TeamCreate/Agent/TaskUpdate and requires a separateSkillentry. However, even with aSkillentry, a child Agent calling Skill may still trigger a permission request pop-up (because Skill's internal operations might include actions not in the allow list).Best practice: Explicitly state "Do not call any Skill" in the Agent prompt. Planning work should be completed by the team-lead; child Agents are only responsible for implementation.
8.1.2 Assign Tasks
TaskUpdate({ taskId: "1", owner: "ui-dev" })
TaskUpdate({ taskId: "2", owner: "ui-dev" })
TaskUpdate({ taskId: "3", owner: "logic-dev" })
TaskUpdate({ taskId: "4", owner: "logic-dev" })
8.2 Pitfall Guide (Core Issues and Solutions)
8.2.1 settings.json Permissions Format
// β Incorrect: space-separated
"Bash(ls *)"
// β
Correct: colon-separated
"Bash(ls:*)"
The colon format is the permission matching syntax recognized by Claude Code. Bash(node:*) means all bash commands starting with node are allowed.
8.2.2 bypassPermissions Is Not a Universal Pass
mode: "bypassPermissions" only skips confirmation pop-ups for tools within the settings.json allow list.
Tool calls not in the allow list will still trigger permission requests. Specifically:
| Tool | Is it within default bypassPermissions scope? | Solution |
|---|---|---|
Bash(node:*) |
β (If in allow) | Ensure settings.json has this entry |
Edit |
β | Add to allow |
Write |
β | Add to allow |
Skill |
β οΈ Even if added to allow, internal operation chain may still trigger pop-up | Prohibit calling Skill in the prompt |
Agent |
β | Add to allow |
8.2.3 Why Child Agents Cannot Call Skill
Root cause: The execution chain of a Skill tool involves multiple steps (read skill definition β parse parameters β execute skill logic β potentially trigger additional tool calls). bypassPermissions only covers single-layer tool calls, not nested operations within Skill.
Agent calls Skill("planning-with-files")
β Skill internally reads .agents/workflows/planning-with-files.md
β Skill internally might call Write (to create plan file)
β Write triggers permission check β Stuck here!
Solutions:
- Best: In the Agent prompt, write "Do not call any Skill, write code directly"
- Alternative: Complete planning work in the team-lead, and the Agent only executes
- Not recommended: Try to add all potentially used tools to allow β too fragile