CCA-F Study Day 27: Cross-Domain Scenario — CI/CD Multi-Agent Pipelines
CCA-F Study Day 27: Cross-Domain Scenario — CI/CD Multi-Agent Pipelines
Today's Focus
Welcome to Review Day 7. Today we tackle a high-value cross-domain scenario that blends Domain 1 (multi-agent orchestration), Domain 2 (tool design + MCP), and Domain 3 (Claude Code CI/CD). The exam's "Claude Code for CI/CD" scenario (Scenario 5) and "Multi-Agent Research" scenario (Scenario 3) both test your ability to compose these concepts together. If you get either of these scenarios on exam day, this session prepares you to answer confidently.
Core Concepts: The CI/CD Multi-Agent Architecture
1. The Generator-Reviewer Pipeline Pattern
The most exam-relevant CI/CD pattern combines three concepts:
- Non-interactive mode (
-pflag) for headless execution in pipelines - Separate sessions for generator vs. reviewer (Domain 1: avoiding reasoning context bias)
- Structured output (
--output-format json) for machine-parseable results
Here is the complete pattern the exam tests:
# Step 1: Generator agent produces code (Session A)
GENERATION=$(claude -p "Implement the user auth module per spec.md" \
--output-format json \
--session-id "gen-$(date +%s)")
# Step 2: SEPARATE SESSION — Reviewer agent validates (Session B)
# This is the critical anti-pattern check. Same-session review = WRONG.
REVIEW=$(claude -p "Review this code for security vulnerabilities.
Output JSON with {pass: bool, issues: [{severity, line, description}]}" \
--output-format json \
--session-id "review-$(date +%s)" \
--input "$GENERATION")
# Step 3: Parse structured output for CI gate
PASS=$(echo "$REVIEW" | jq '.pass')
if [ "$PASS" != "true" ]; then
echo "Review failed" && exit 1
fi
2. Why Separate Sessions Matter (Exam Trap)
The exam presents this scenario: "An agent generates code, then in the same conversation reviews it and says it looks good." Why is this wrong?
- Reasoning context bias: The model remembers WHY it made each decision. When asked to review its own output in the same context, it rationalizes those decisions rather than evaluating objectively.
- Correct approach: The reviewer runs in a fresh session. It sees ONLY the output artifact, not the reasoning that produced it.
- Analogy: This is like having the author of a paper also be the sole peer reviewer. They'll defend their choices, not catch their errors.
3. Fan-Out Pattern for Batch CI/CD
When migrating a codebase (e.g., JS to TypeScript), the exam tests whether you know to use fan-out:
# Fan-out: parallel processing with isolated agents
find src -name "*.js" | xargs -P 4 -I {} \
claude -p "Convert {} from JavaScript to TypeScript. Preserve all functionality." \
--output-format json
# Each file gets its own agent instance (separate context)
# -P 4 runs 4 agents in parallel
# Each agent sees ONLY its assigned file (context isolation)
Exam trap: An answer suggesting you pass ALL files into a single prompt. This fails because: (a) context window overflow, (b) no parallelism, (c) errors in one file can cascade to others.
4. Hooks in CI/CD Context
Hooks enforce deterministic behavior that prompts cannot guarantee:
# .claude/settings.json — CI/CD pipeline hooks
{
"hooks": {
"PreToolUse": [{
"matcher": "Bash",
"command": "node .claude/hooks/block-destructive.js"
}],
"PostToolUse": [{
"matcher": "Write|Edit",
"command": "node .claude/hooks/validate-no-secrets.js"
}]
}
}
// .claude/hooks/block-destructive.js
// Deterministic: blocks rm -rf, DROP TABLE, etc. regardless of prompt
const input = JSON.parse(process.argv[2]);
const cmd = input.tool_input?.command || "";
const BLOCKED = [/rm\s+-rf/, /DROP\s+TABLE/i, /DELETE\s+FROM/i];
if (BLOCKED.some(pattern => pattern.test(cmd))) {
console.log(JSON.stringify({
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "deny",
permissionDecisionReason: `Blocked destructive command: ${cmd}`
}
}));
} else {
console.log("{}"); // Allow
}
5. MCP Integration in CI/CD
MCP servers extend Claude Code's capabilities in pipelines. The exam tests whether you know the boundary between built-in tools and MCP tools:
| Need | Built-in Tool | MCP Server |
|---|---|---|
| Read a file | Read ✓ | — |
| Search codebase | Grep / Glob ✓ | — |
| Run tests | Bash ✓ | — |
| Query Jira tickets | — | mcp__jira__search_issues ✓ |
| Check deployment status | — | mcp__deploy__get_status ✓ |
| Browser testing | — | mcp__playwright__navigate ✓ |
Key insight: Built-in tools handle local filesystem + shell. MCP servers handle external service integrations. The exam will present scenarios where you need to identify which category a capability falls into.
6. Structured Output for Pipeline Gates
In CI/CD, you need machine-parseable output. Two approaches:
# Approach 1: --output-format json (Claude Code native)
claude -p "Analyze test coverage" --output-format json
# Approach 2: Forced tool_use for strict schema compliance
# Define a "report" tool whose schema IS your desired output format
tools = [{
"name": "report_review_result",
"description": "Submit the code review result",
"input_schema": {
"type": "object",
"properties": {
"pass": {"type": "boolean"},
"severity": {"type": "string", "enum": ["critical", "warning", "info"]},
"issues": {
"type": "array",
"items": {
"type": "object",
"properties": {
"file": {"type": "string"},
"line": {"type": "integer"},
"description": {"type": "string"}
},
"required": ["file", "line", "description"]
}
}
},
"required": ["pass", "severity", "issues"]
}
}]
response = client.messages.create(
model="claude-sonnet-4-20250514",
tools=tools,
tool_choice={"type": "tool", "name": "report_review_result"},
messages=[{"role": "user", "content": f"Review this code:\n{code}"}]
)
Anti-Patterns & Exam Traps
| ❌ Wrong Answer | ✅ Correct Answer | Why |
|---|---|---|
| Same-session code generation + review | Separate sessions for generator and reviewer | Reasoning context bias makes self-review unreliable |
| Parsing Claude's text output with regex in CI | Use --output-format json or forced tool_use | Text parsing is brittle; structured output is deterministic |
| Using prompt instructions to block dangerous commands | Use PreToolUse hooks with deny decisions | Prompts are advisory; hooks are deterministic enforcement |
| Single agent processing all files in a migration | Fan-out pattern with parallel isolated agents | Context overflow, no parallelism, error cascading |
| Loading all MCP tools upfront in a large pipeline | Use ToolSearch to dynamically discover tools on-demand | Tool overload degrades selection accuracy past 18+ tools |
🎬 Video to Watch
Claude Code Advanced Patterns: Subagents, MCP, and Scaling to Real Codebases (Anthropic Official Webinar, March 2026)
Covers the exact patterns tested in the CI/CD scenario: subagent orchestration, MCP integration at scale, and the fan-out pattern for codebase-wide operations. Focus on the "scaling patterns" section starting around the middle of the talk.
📖 Reading
- Claude Code CI/CD Documentation — The authoritative reference for
-pflag, batch processing, and pipeline patterns - Building Effective Agents — Re-read the "orchestration patterns" section with CI/CD in mind
🛠️ Hands-On Exercise (25 minutes)
Design a complete CI/CD pipeline (write it as a GitHub Actions YAML) that does the following:
- Step 1 (Generate): Claude Code generates unit tests for all changed files in a PR, using
-pflag with a unique session ID - Step 2 (Review): A SEPARATE Claude Code session reviews the generated tests for correctness, with structured JSON output
- Step 3 (Validate): A PreToolUse hook blocks any Bash commands that include
rmorsudo - Step 4 (Gate): Parse the JSON review output to pass/fail the PR check
Bonus: Add a fan-out step where multiple files are reviewed in parallel using xargs -P.
Quick Quiz
Q1. A CI/CD pipeline uses Claude Code to generate code and then review it. Both steps run in the same session. What architectural flaw does this introduce?
A) Token budget overflow B) Reasoning context bias causing unreliable reviews C) Permission conflicts between write and read operations D) MCP server connection timeouts
Q2. You need to enforce that Claude Code cannot execute DROP TABLE commands in your CI pipeline. The approach that provides deterministic enforcement is:
A) Add "Never run DROP TABLE commands" to CLAUDE.md B) Set the effort level to "low" to prevent complex operations C) Implement a PreToolUse hook that pattern-matches Bash commands and returns a deny decision D) Use tool_choice to prevent Bash tool selection
Q3. A team needs to migrate 500 JavaScript files to TypeScript using Claude Code in CI. Which pattern is architecturally correct?
A) Pass all 500 file paths in a single prompt with max_tokens set high
B) Use fan-out: find src -name "*.js" | xargs -P 8 -I {} claude -p "Convert {}"
C) Create a CLAUDE.md that lists all files and run a single session
D) Use a pipeline pattern where each file's output feeds into the next file's input
Answers: Q1: B — Reasoning context bias. The model rationalizes its own decisions rather than evaluating objectively. Q2: C — PreToolUse hooks provide deterministic enforcement. CLAUDE.md instructions (A) are advisory only. Q3: B — Fan-out with xargs provides parallelism and context isolation. A single prompt (A) overflows context. Pipeline (D) creates unnecessary sequential dependencies between unrelated files.
Tomorrow's Preview
Day 28 will cover a full-length practice scenario: the Structured Data Extraction exam scenario (Scenario 6), combining tool_use schemas, validation-retry loops, multi-pass review, and few-shot prompting into one integrated exercise.