Skip to content
CCAF Preparation

Task Statement 3.6·Domain 320% of exam

CI/CD Integration

Integrate Claude Code into CI/CD pipelines

Jump to practice →

Official Exam Guide Objectives

Knowledge of

  • The -p (or --print) flag for running Claude Code in non-interactive mode in automated pipelines
  • --output-format json and --json-schema CLI flags for enforcing structured output in CI contexts
  • CLAUDE.md as the mechanism for providing project context (testing standards, fixture conventions, review criteria) to CI-invoked Claude Code
  • Session context isolation: why the same Claude session that generated code is less effective at reviewing its own changes compared to an independent review instance

Skills in

  • Running Claude Code in CI with the -p flag to prevent interactive input hangs
  • Using --output-format json with --json-schema to produce machine-parseable structured findings for automated posting as inline PR comments
  • Including prior review findings in context when re-running reviews after new commits, instructing Claude to report only new or still-unaddressed issues to avoid duplicate comments
  • Providing existing test files in context so test generation avoids suggesting duplicate scenarios already covered by the test suite
  • Documenting testing standards, valuable test criteria, and available fixtures in CLAUDE.md to improve test generation quality and reduce low-value test output

What You Need to Know

Running Claude Code inside a pipeline changes what it is. There is no operator, no conversation, and nothing that can pause for a decision — it becomes an automated review and generation step. Five concepts are tested here, and the -p flag is the most directly examinable single fact in the domain (it is Question 10 in the sample question set).

The -p Flag: Non-Interactive Mode

By default Claude Code opens a conversational interface and waits for you to type. A CI runner has nobody to type, so the process sits there until the job times out — no error, no output, just a job that never finishes.

# WRONG — hangs in CI
claude "Analyse this pull request for security issues"

# CORRECT — runs non-interactively
claude -p "Analyse this pull request for security issues"

-p (equivalently --print) selects print mode: the prompt is processed, the result goes to stdout, the process exits.

There is nothing to reason about here — it is recall. Items describe a stalled job with logs showing Claude waiting on input, and the answer is -p. The distractors are inventions: CLAUDE_HEADLESS=true is not a variable, --batch is not a flag, and redirecting stdin from /dev/null does not change the mode Claude Code is running in.

Structured Output for CI

Output in a pipeline is consumed by software, not read by anyone, so it needs to parse. Two flags cover it:

  • --output-format json — returns the run inside a JSON envelope carrying the result text alongside the session ID and cost/usage figures, rather than prose meant for a terminal
  • --json-schema — checks the agent's final output against a schema you supply, and is available in print mode only
claude -p \
  --output-format json \
  --json-schema '{"type":"object","properties":{"findings":{"type":"array","items":{"type":"object","properties":{"file":{"type":"string"},"line":{"type":"integer"},"severity":{"type":"string"},"message":{"type":"string"}}}}}}' \
  "Review this PR for security issues"

One detail costs people marks: the schema-conforming data sits in the envelope under structured_output, so it is jq '.structured_output' rather than reading the top level. What you get back is validated enough to act on:

  • Parse programmatically
  • Post as inline PR comments at the exact file and line
  • Filter by severity for different notification channels
  • Track across review runs

Session Context Isolation

Asking the session that wrote the code to review the code is weaker than asking a fresh one, and not marginally.

Why self-review is weaker:

Generating code leaves a session holding its own reasoning — the approach it settled on, the alternatives it dismissed, the trade-offs it accepted. Reviewing inside that same session means every one of those decisions arrives already justified, and a decision that has been justified is one the reviewer is disinclined to reopen.

The fix: independent review instances

Invoke a second time, with no access to the first session's reasoning. The reviewer then meets the code as code, with no attachment to why it looks the way it does.

# Session A — writes the code
claude -p "Implement the token refresh middleware"

# Session B — separate invocation, no sight of A's reasoning
claude -p "Audit the token refresh middleware: auth bypasses, unhandled failures, edge cases"

The same principle appears in Domain 4 as multi-instance review architecture and in Domain 5 as context management; here it is tested specifically in a pipeline.

Incremental Review Context

Reviews fire on every push, and a review with no memory re-derives its findings from scratch each time. The issues genuinely fixed drop off by themselves, because the code that triggered them is gone. The ones that persist are those the developer read and decided against — and a context-free scan cannot distinguish a rejected suggestion from a new problem, so it raises them again on every push.

Carrying the previous findings forward, with an instruction to report only what is new or still outstanding, is the fix:

claude -p \
  --output-format json \
  "Review this PR. The previous run reported the following:
  ${PREVIOUS_FINDINGS}

  Return only two categories:
  1. Anything not present in that list
  2. Anything from that list still unresolved in the current diff

  Say nothing about items the developer has evidently seen and chosen to leave."

What is at stake is whether anyone reads the output. Five identical comments arriving on every push teach the team that the comments carry no information, and once that lesson lands the genuinely important finding is skipped with the rest.

CLAUDE.md for CI Context

A CI-invoked run reads the project's CLAUDE.md files exactly as an interactive one does, which makes CLAUDE.md the mechanism for giving an automated run the context it cannot ask for:

  • Testing standards: which patterns the team writes tests in, and which it has decided against
  • Available fixtures: what already exists to build test data from, and what each one contains
  • Review criteria: where the line sits between something worth blocking a merge for and a style preference
  • Existing test coverage: what is already exercised, so suggestions land on the gaps

Absent that, generated tests are plausible and worthless — assertions about behaviour nobody was worried about, duplicating coverage that already exists. With it, they follow the conventions the team already uses and test what is actually uncovered.

# .claude/CLAUDE.md — CI-relevant section
## Testing Standards

- Build test data through the factories in test/factories/, never inline literals
- Integration tests reach the database through test/setup/db.ts
- Assert against public API contracts; private internals are not a test surface
- New code is expected to reach 80% branch coverage
- Fixtures on hand: test/fixtures/users.json, test/fixtures/orders.json

CLI Flags Reference

-p is the flag the exam tests hardest, but a headless run is shaped by several others: what form the output takes, which system prompt is in force, and how far permissions and tools extend. Everything below works with claude -p in CI and equally with the interactive claude.

System prompt flags. Four exist, and the distinction under test is append versus replace:

FlagEffect
--system-prompt "<text>"Substitutes your text for the whole default prompt
--system-prompt-file <path>Same substitution, with the text read from a file
--append-system-prompt "<text>"Leaves the default in place and adds your text after it
--append-system-prompt-file <path>Same addition, with the text read from a file

Append when Claude should remain a coding assistant that additionally follows your rules — the default tool guidance, safety instructions and coding conventions all survive, so you write only the difference. Replace when the role genuinely is not Claude Code's: a non-coding agent running in a pipeline nobody is watching. Replacing discards the whole default prompt, which means anything the task still depends on is now yours to supply.

Headless output and limits (print mode).

FlagEffect
`--output-format textjson
`--input-format textstream-json`
--json-schema '<schema>'Validates the final output against your schema; paired with --output-format json the result appears under structured_output
--max-turns <n>Stops the run once this many agentic turns have elapsed
--verboseEmits every turn rather than the final result alone

Permissions, tools, and context.

FlagEffect
--permission-mode <mode>Chooses the starting mode: default, acceptEdits, plan, auto, dontAsk, or bypassPermissions
--allowedTools "<rules>"Names what may run unprompted, e.g. "Bash(git diff *)" "Read"
--disallowedTools "<rules>"Denies matching calls; give a bare tool name and the tool disappears from context altogether
--tools "Bash,Edit,Read"Narrows the built-in tools available in the first place
--add-dir <path>Extends read and edit access to another directory — file access only, not configuration discovery
`--model <aliasname>`

Session and start-up. -c / --continue picks the most recent conversation in the current directory back up, while -r / --resume <id|name> targets a specific one. --bare is the minimal mode: auto-discovery is skipped entirely — hooks, skills, plugins, MCP servers, auto memory and CLAUDE.md are all left unloaded — so a scripted call starts quickly with only the Bash and file read/edit tools in hand. It suits scripted runs where speed and predictability matter more than having project configuration present.

Providing Existing Tests to Avoid Duplication

Test generation in CI needs the existing tests in context, and for a reason that only shows up in review: without them Claude Code has no way to know what is already covered, so it proposes tests that duplicate ones already in the suite. Every duplicate costs a developer the time to read it and reject it. Supplied with the current tests, the same run identifies gaps instead.

Batch API vs Real-Time for CI Workflows

The Message Batches API costs 50% less and takes up to 24 hours, with no guaranteed latency SLA. Those two facts together draw a sharp line:

Workflow typeAPI choiceReason
Pre-merge checks (blocking)Real-time (synchronous)Someone is sitting waiting on the answer
Overnight technical debt reportsBatch APINobody is blocked, and it costs 50% less
Weekly code auditBatch APIRuns to a schedule, so latency is irrelevant
Nightly test generationBatch APIFinishes overnight and is read the next morning

The distinguishing question is whether anybody is blocked. A pre-merge check holds up both a developer and a merge, and "up to 24 hours, no guarantee" is not a wait a review gate can absorb — so those go to the real-time API however attractive the saving looks. Work that runs on a schedule and is read whenever someone gets to it is exactly what the 50% discount is for. The exam tests this distinction directly (Sample Question 11).

Deep Dive

--bare mode for reproducible CI runs

--bare reduces startup time by skipping auto-discovery of hooks, skills, plugins, MCP servers, auto memory, and CLAUDE.md — useful for CI and scripts that need the same result on every machine, independent of what happens to be installed locally. Anthropic states --bare is "the recommended mode for scripted and SDK calls, and will become the default for -p in a future release." This trades away exactly the CLAUDE.md context this lesson otherwise relies on — reach for --bare only when reproducibility matters more than project context.

Sourcecode.claude.com › headlessfetched 2026-07-30

JSON output fields: cost tracking and structured_output

With --output-format json, the response payload includes total_cost_usd and a per-model cost breakdown, letting scripted callers track spend per invocation. Combining --output-format json with --json-schema puts the schema-conforming data specifically in the structured_output field, alongside session ID and usage metadata — extract it with jq -r '.structured_output', not from the top level of the envelope. As of v2.1.205, an invalid JSON Schema makes claude exit with an explicit error rather than silently falling back to unstructured text.

Sourcecode.claude.com › headlessfetched 2026-07-30

dontAsk mode for locked-down CI runs

The dontAsk permission mode denies anything not already in your permissions.allow rules or the built-in read-only command set — recommended specifically for locked-down CI runs where nothing should be improvised. In non-interactive -p runs generally, auto mode aborts the session when the classifier repeatedly blocks actions, because there's no user available to prompt.

Sources: https://code.claude.com/docs/en/headless (dontAsk for CI) · https://code.claude.com/docs/en/permission-modes (repeated blocks abort a -p session) (fetched 2026-07-30)

Operational limits worth knowing for CI

Piped stdin into claude -p is capped at 10MB (as of v2.1.128); exceeding it produces a clear error and non-zero exit status. Stopping a claude -p run with SIGTERM aborts the in-progress turn, terminates the process tree of any running Bash command, runs SessionEnd hooks, and exits with code 143. The stream-json output format's last line is always a result message carrying the final response text, cost, and session metadata.

Sourcecode.claude.com › headlessfetched 2026-07-30

GitHub Actions integration

A simple @claude mention in any PR or issue lets Claude analyse code, create PRs, implement features, and fix bugs while following the project's standards; the integration is built on the Claude Agent SDK. Quick setup runs /install-github-app interactively; manual setup installs the Claude GitHub app, adds ANTHROPIC_API_KEY as a repository secret, and copies the example workflow into .github/workflows/. The app needs read & write on Contents, Issues, and Pull requests. The v1 action auto-detects interactive mode (responding to @claude mentions) versus automation mode (running immediately with a prompt), exposes a unified prompt input plus claude_args for CLI passthrough, defaults its trigger_phrase to "@claude", and defaults --max-turns to 10 inside claude_args.

Sourcecode.claude.com › github-actionsfetched 2026-07-30

CI gate on MCP/plugin load errors

The stream-json format's system/init event carries plugin_errors and mcp_server_errors fields whose keys are omitted entirely when there are no errors — so a CI gate can simply fail the job when either array is non-empty, without needing to distinguish "no errors" from "empty array."

Sourcecode.claude.com › headlessfetched 2026-07-30

Quick Reference

ItemValue / behaviour
Non-interactive mode-p / --print — the single most tested fact in Domain 3
--output-format valuestext (default), json (structured, with cost fields), stream-json (NDJSON, real-time)
--json-schemavalidated JSON in print mode only; lands in structured_output field with --output-format json
Cost tracking--output-format json includes total_cost_usd + per-model breakdown
--bareskips hooks/skills/plugins/MCP/auto-memory/CLAUDE.md; reproducible; future -p default
dontAsk modedenies anything not pre-approved — for locked-down CI
stdin cap10MB piped into claude -p; over the cap = error, non-zero exit
SIGTERM on -paborts turn, runs SessionEnd hooks, exits 143
GitHub Actions trigger@claude mention (default trigger_phrase)
GitHub App permissionsContents, Issues, Pull requests — all read & write
Action --max-turns default10
CI gate signalnon-empty plugin_errors / mcp_server_errors in system/init
Session isolationindependent review instance beats same-session self-review
Batch API for CIonly for non-blocking workloads (up to 24h, no latency SLA) — never pre-merge checks
CLAUDE.md in CIread identically to interactive mode — the way to supply testing/review standards

Exam Traps

Practice Scenario

A CI pipeline script runs claude with a prompt but the job hangs indefinitely. Logs show Claude Code is waiting for interactive input. What is the correct fix?

Build Exercise

Set Up a CI/CD Pipeline with Claude Code

Difficulty: Advanced (3/4)

45 minutes

  1. Write a CI script that runs Claude Code with the -p flag for non-interactive PR analysis

Why: The -p flag is the single most directly testable fact in Domain 3. Without it, the CI job hangs indefinitely waiting for interactive input. This is Question 10 in the official sample questions.

You should see: A CI script (GitHub Actions YAML, GitLab CI, or similar) that invokes claude -p with a review prompt. The job completes successfully without hanging. The output is printed to stdout and captured by the CI system.

  1. Add --output-format json and --json-schema to produce structured findings with file, line, severity, and message fields

Why: CI output must be machine-parseable. Automated systems need structured JSON to post inline PR comments, filter by severity, and track findings across runs. Human-readable text output cannot be reliably parsed by downstream tools.

You should see: The Claude Code output is a JSON envelope whose structured_output field conforms to the specified schema. Each finding has file, line, severity, and message fields. Piping the output to jq .structured_output extracts the validated data without errors.

  1. Configure the pipeline to parse the JSON output and post findings as inline PR comments

Why: Inline PR comments at exact file and line numbers provide actionable feedback. Generic PR-level comments are ignored. Structured JSON output makes precise inline commenting possible.

You should see: Each finding from the JSON output appears as an inline comment on the PR at the exact file and line number. Severity levels are visible. Developers can see the finding in context alongside the code it references.

  1. Add a section to CLAUDE.md documenting testing standards, available fixtures, and review criteria for CI-invoked Claude Code

Why: Claude Code reads CLAUDE.md in CI just as in interactive mode. Without project context, CI-invoked test generation produces low-value boilerplate. With testing standards and fixture documentation, generated tests follow team patterns.

You should see: The CLAUDE.md file contains a clearly marked CI-relevant section with testing standards, available fixture paths, and review severity criteria. CI-invoked Claude Code produces tests using the documented factories and fixtures rather than generic boilerplate.

  1. Set up two separate Claude Code invocations: one for code generation and an independent one for review (no shared session context)

Why: The same session that generated code is less effective at reviewing it because it retains reasoning context that biases it toward its own decisions. Independent review instances evaluate code on its own merits without prior justification bias.

You should see: Two distinct claude -p invocations in the CI script: one for generation and one for review. They share no session context. The review invocation analyses the generated code independently. The review findings are more thorough than self-review in the same session.

  1. Implement incremental review: store previous findings, include them in the next review run, and instruct Claude to report only new or still-unaddressed issues

Why: Without incremental context, each review run analyses the entire PR from scratch and produces duplicate comments. Duplicate comments erode developer trust — when the same five issues appear on every push regardless of fixes, developers stop reading them.

You should see: The first review run produces findings and stores them (as a JSON artifact or file). Subsequent runs include the previous findings in context. The output contains only new issues or issues that remain unaddressed. Previously fixed issues do not reappear as comments.

Sources


Appendix A — Build Exercise Step Hints

Progressive hints revealed by the "Stuck? Get a nudge" control on each step.

Step 1. Write a CI script that runs Claude Code with the -p flag for non-interactive PR analysis

Why: The -p flag is the single most directly testable fact in Domain 3. Without it, the CI job hangs indefinitely waiting for interactive input. This is Question 10 in the official sample questions.

You should see: A CI script (GitHub Actions YAML, GitLab CI, or similar) that invokes claude -p with a review prompt. The job completes successfully without hanging. The output is printed to stdout and captured by the CI system.

Stuck? Get a nudge

Step 2. Add --output-format json and --json-schema to produce structured findings with file, line, severity, and message fields

Why: CI output must be machine-parseable. Automated systems need structured JSON to post inline PR comments, filter by severity, and track findings across runs. Human-readable text output cannot be reliably parsed by downstream tools.

You should see: The Claude Code output is a JSON envelope whose structured_output field conforms to the specified schema. Each finding has file, line, severity, and message fields. Piping the output to jq .structured_output extracts the validated data without errors.

Stuck? Get a nudge

Step 3. Configure the pipeline to parse the JSON output and post findings as inline PR comments

Why: Inline PR comments at exact file and line numbers provide actionable feedback. Generic PR-level comments are ignored. Structured JSON output makes precise inline commenting possible.

You should see: Each finding from the JSON output appears as an inline comment on the PR at the exact file and line number. Severity levels are visible. Developers can see the finding in context alongside the code it references.

Stuck? Get a nudge

Step 4. Add a section to CLAUDE.md documenting testing standards, available fixtures, and review criteria for CI-invoked Claude Code

Why: Claude Code reads CLAUDE.md in CI just as in interactive mode. Without project context, CI-invoked test generation produces low-value boilerplate. With testing standards and fixture documentation, generated tests follow team patterns.

You should see: The CLAUDE.md file contains a clearly marked CI-relevant section with testing standards, available fixture paths, and review severity criteria. CI-invoked Claude Code produces tests using the documented factories and fixtures rather than generic boilerplate.

Stuck? Get a nudge

Step 5. Set up two separate Claude Code invocations: one for code generation and an independent one for review (no shared session context)

Why: The same session that generated code is less effective at reviewing it because it retains reasoning context that biases it toward its own decisions. Independent review instances evaluate code on its own merits without prior justification bias.

You should see: Two distinct claude -p invocations in the CI script: one for generation and one for review. They share no session context. The review invocation analyses the generated code independently. The review findings are more thorough than self-review in the same session.

Stuck? Get a nudge

Step 6. Implement incremental review: store previous findings, include them in the next review run, and instruct Claude to report only new or still-unaddressed issues

Why: Without incremental context, each review run analyses the entire PR from scratch and produces duplicate comments. Duplicate comments erode developer trust — when the same five issues appear on every push regardless of fixes, developers stop reading them.

You should see: The first review run produces findings and stores them (as a JSON artifact or file). Subsequent runs include the previous findings in context. The output contains only new issues or issues that remain unaddressed. Previously fixed issues do not reappear as comments.

Stuck? Get a nudge

Appendix B — Interactive Study Prompts

Two prompts to paste into Claude. B1 drills the judgement the exam actually measures; B3 reviews the pipeline you wrote for the Build Exercise above. The exam simulator between them is the interactive quiz on this page.

B1. Concept Check — Discrimination Drill

Prompt — paste into Claude

You are examining me for the Claude Certified Architect – Foundations (CCAR-F) exam, Domain 3: Claude Code Configuration & Workflows (20% of the exam), Task Statement 3.6: CI/CD Integration. Use British English throughout.

What this exam actually measures. Not one item on the official exam asks what something is. Every item drops you into a production system that is already misbehaving, offers four defensible engineering responses, and asks which is best. The skill being tested is proportionality: fix the root cause with the cheapest instrument that gives the guarantee the situation demands. So do not quiz me on definitions. Make me choose between options that are both defensible, then attack whatever I chose.

How to run this session.

  • One question at a time. Stop and wait. Never answer your own question, and never move on until I have committed.
  • Never reveal which option is right before I commit to one.
  • Do not praise me. A correct answer earns "Yes" and the next question. If I am right for the wrong reason, say so — that is the failure that costs marks on exam day.
  • When I am wrong, quote the exact phrase in my answer that gave it away, correct it in one sentence, and move on. One correction at a time.
  • If I write something fluent but empty, name it: "That is a restatement, not a reason."
  • Set every scenario inside one of the exam's production contexts: Code Generation with Claude Code (a team leaning on custom slash commands, CLAUDE.md configuration, and plan mode versus direct execution), Claude Code for Continuous Integration (automated review, test generation and PR feedback in a pipeline that has to keep false positives down), or Developer Productivity with Claude (an agent over an unfamiliar codebase using the built-in Read, Write, Bash, Grep, Glob tools).

Session plan — about twelve questions.

Round 1 — Anchor (1 question). One concrete question to check I have actually read the material. If I cannot answer it, stop the session and tell me to read the lesson before continuing.

Round 2 — Discrimination (5 questions). Each one: describe a symptom in one of the contexts above, with a number or a log observation in it — a job that has sat at the same step for forty minutes, five identical comments arriving on the fourth push, a parse that returns nothing from an output that clearly contains findings. Offer exactly two responses, both defensible. Ask me to pick one and justify it in a single sentence. Then argue the case for the option I rejected as strongly as you can, and ask whether I am holding or changing my answer. Only after I answer that, tell me which is right and why the other one is the more tempting trap.

Round 3 — Proportionality (2 questions). Take one symptom and run it twice with different stakes: once where the cost of the wrong call is a noisy comment on a draft pull request, once where it is a blocking pre-merge check that never returns and holds a release. The right answer must change between the two. If I answer the same way both times without noticing the stakes moved, that is the finding — tell me.

Round 4 — Code review (3 questions). Present a colleague's confident proposal containing one of the trap errors listed below, written the way a teammate would write it in a pull request. Ask me what is wrong with it. Do not signal that anything is wrong.

Round 5 — Verdict. Rate me green, amber or red on each concept below. Name the single weakness most likely to cost me marks, and give me one specific next action: a section of this lesson to re-read, or a step of the Build Exercise to redo. If I am not ready for this task statement, say so plainly.

Concepts in scope

  1. Non-interactive mode-p (also --print) processes the prompt, writes the result to stdout and exits. Without it a CI job waits forever for keyboard input that will never arrive. CLAUDE_HEADLESS=true and --batch are not real flags, and redirecting stdin does not address the mode.
  2. Structured output--output-format json wraps the run in a JSON envelope; --json-schema validates the final output against a schema in print mode, and the conforming data lands in the envelope's structured_output field, not at the top level. That is what makes inline comments at an exact file and line possible.
  3. Session context isolation — the session that generated the code carries its own justifications for every decision in it, and is measurably weaker at reviewing that code. An independent invocation judges the change on its merits.
  4. Incremental review context — feed the previous run's findings in and instruct Claude to report only new or still-unaddressed issues. Without it every push re-derives the same comments, and duplicate comments are what makes developers stop reading them.
  5. CLAUDE.md as CI context — a CI-invoked run reads CLAUDE.md exactly as an interactive one does, so testing standards, available fixtures, review severity criteria and existing coverage belong there. Without them, generated tests are low-value boilerplate.
  6. Batch API versus real-time — the Message Batches API halves cost but can take up to 24 hours with no latency guarantee, which suits overnight reports and weekly audits and rules it out for anything a developer is waiting on.

Trap errors to plant in Round 4

  • Fixing a hanging CI job with an invented environment variable, a --batch flag or a stdin redirect, rather than with print mode.
  • Reviewing generated code in the same session that generated it, and treating that as equivalent to an independent review.
  • Routing a blocking pre-merge check through the Message Batches API for the cost saving.
  • Re-running the review without the previous findings in context, so the same comments land on every push.

Stay inside the material above. If I raise something outside it, tell me it is out of scope for this task statement and return to the drill. Begin with Round 1.

B2. Exam Simulator

Exam simulator

Question 1 of 11

Scenario · Claude Code for Continuous Integration

Your pipeline step runs claude "Analyse this PR for security issues" and the job runs until the runner's 60-minute timeout kills it, producing no findings. The step's log shows Claude Code sitting at a prompt, waiting for interactive input. What's the correct approach to running it in the pipeline?

B3. Build Coach — Pipeline Review

The Build Exercise and its hint ladder are already on this page. This prompt is for the one thing the page cannot do: review the pipeline you actually wrote.

Prompt — paste into Claude

You are a staff engineer reviewing my implementation of a build exercise for the Claude Certified Architect – Foundations exam, Domain 3, Task Statement 3.6: CI/CD Integration. Use British English throughout.

I am building a CI pipeline that runs Claude Code headlessly over a pull request: a non-interactive invocation, schema-validated JSON findings extracted and posted back as inline comments, a CLAUDE.md section supplying the project's testing and review standards, generation and review split across two independent invocations, and an incremental review that carries the previous run's findings forward.

It has to satisfy all of the following:

  • The review job invokes Claude Code non-interactively, completes instead of hanging, and has its output captured by the pipeline.
  • Findings come back as a schema-validated JSON envelope, each carrying file, line, severity and message, read out of the structured field rather than the top level of the envelope.
  • Each finding is posted back as an inline comment at the file and line it refers to, with its severity visible to the reviewer.
  • A CI-relevant CLAUDE.md section documents the testing standards, the fixture paths and what counts as a critical finding versus a minor one, and the generated tests visibly use the documented factories rather than inventing their own.
  • Generation and review run as two distinct invocations that share no session context.
  • The second review run carries the first run's findings and emits only new or still-unaddressed issues.

How to review.

  • Ask me to paste the pipeline definition, the CLAUDE.md section and the command lines exactly as they run. If I have not pasted them, ask for that and nothing else. Do not write the pipeline for me, do not offer a reference version, and do not fill in a step I have skipped.
  • Work through the criteria above in order. For each one, quote the line of my pipeline that satisfies it, or say plainly that nothing does.
  • Then hunt for the failure modes below. Each is a real production bug, not a style preference.
  • Rank everything you find: (1) would fail or hang in the pipeline, (2) would lose marks on the exam, (3) style. Give me the first item under (1) and then stop — wait for my fix before giving me the next one.
  • If my pipeline satisfies everything, do not congratulate me. Change the requirements — the same workflow now also has to run as an overnight technical-debt report over the whole repository — and make me say what changes and what must not.
  • If I ask you to just write it for me, refuse once and give me the smallest nudge that would unblock me instead.

Failure modes to probe

  • The job hanging because the invocation is still interactive, or because the flag has been swapped for one that does not exist.
  • Findings read from the top level of the JSON envelope rather than from the structured field, so the parse silently yields nothing and the pipeline reports a clean review.
  • The review invocation continuing the generation session, which reinstates exactly the self-review bias the split exists to remove.
  • Previous findings dropped between runs, so the same comments arrive on every push and the developers who were meant to act on them stop reading.
  • Startup shortened by skipping project configuration discovery in the same pipeline whose review quality depends on CLAUDE.md being loaded.

Start by asking me for my pipeline definition and the command lines as they actually run.