What you will be able to do
- Decide which testing standards and conventions belong in CLAUDE.md for CI-invoked runs
- Explain why a separate review instance beats asking the authoring session to grade its own work
- Carry prior review findings into a re-run so only new or unaddressed issues get reported
- Give test generation the existing tests so it does not propose scenarios that are already covered
1.CLAUDE.md: the standing brief for every CI run
A CI run starts with no conversation history. The repository is the only place project knowledge can come from, and the project-level CLAUDE.md is how you provide it. It is checked in at ./CLAUDE.md or ./.claude/CLAUDE.md, and the docs say it is loaded into every session. The GitLab integration likewise says Claude follows your CLAUDE.md guidelines and existing code patterns. CLAUDE.md is not just for reviews: it is the project's shared instructions for every task, and a review also reads it as project context.
What should go in it? The best-practices guide's Include column lists testing instructions and preferred test runners. It also lists Bash commands Claude can't guess and common gotchas. Its Exclude column lists anything Claude can figure out by reading code. For test generation, this means writing down the knowledge Claude cannot infer:
- Testing standards: which runner to use and how to run a single test. - What makes a test worth writing: for example, "cover error paths, not trivial getters". - Available fixtures: which ones exist and where they live.
The docs do not name fixtures specifically. They fall under the same rule of including what Claude can't guess. The docs' own example is written as short, specific bullets:
# Workflow
- Be sure to typecheck when you're done making a series of code changes
- Prefer running single tests, and not the whole test suite, for performanceKeep it short. CI reads the file on every run, so every line costs tokens on every job, and the memory docs warn that long files reduce adherence. They suggest aiming for under 200 lines per file. Move conventions that apply only to part of the codebase, such as test-file rules, into path-scoped files under .claude/rules/. Those load only when Claude works with matching files.
Checkpoint 1 of 5· Check yourself
Generated tests in CI keep covering trivial getters and building ad-hoc test data instead of using the team's fixtures. Which change targets the cause?
Testing instructions are on the docs' Include list. Project-specific facts such as fixtures can't be inferred from the code, so they belong in CLAUDE.md. Long tutorials are on the Exclude list.
“Testing instructions and preferred test runners”Source: code.claude.com
2.Why the author session should not grade its own work
The session that wrote the code has its own reasoning, failed attempts and assumptions in context. The best-practices guide notes that long sessions with irrelevant context can reduce performance. It recommends a second opinion: a fresh model that tries to refute the result. Its Writer/Reviewer pattern makes this concrete:
| Step | Session | Prompt |
|---|---|---|
| 1 | Session A (Writer) | Implement a rate limiter for our API endpoints |
| 2 | Session B (Reviewer) | Review the rate limiter implementation in @src/middleware/rateLimiter.ts. Look for edge cases, race conditions, and consistency with our existing middleware patterns. |
| 3 | Session A (Writer) | Here's the review feedback: [Session B output]. Address these issues. |
In CI this separation is easy to get. A new claude -p invocation without --continue or --resume does not carry over an earlier conversation. Give it the diff and a reviewer role, and it judges the change on its merits:
gh pr diff "$1" | claude -p \
--append-system-prompt "You are a security engineer. Review for vulnerabilities." \
--output-format jsonCheckpoint 2 of 5· Put it in order
Put the Writer/Reviewer steps in order
- 1.Session A receives Session B's feedback and addresses the issues
- 2.Session B reviews the implementation for edge cases and race conditions
- 3.Session A implements the rate limiter
The writer builds, a separate reviewer critiques, and the writer fixes what the reviewer found.
“Here's the review feedback: [Session B output]. Address these issues.”Source: code.claude.com
Sources4
3.Re-running a review after new commits
A review that runs again on every push has a duplication problem. A reviewer that starts fresh each time knows nothing about what it already posted, so it reports the same open issues again as new comments. The fix is to give the re-run the earlier findings and tell it to report only issues that are new, or that are still present and unaddressed.
The headless docs do not show this exact dedupe prompt, but they do provide two ways to bring earlier review state into a run. One is to resume the reviewer's own session by ID. --output-format json returns the session ID, and --resume continues that conversation:
session_id=$(claude -p "Start a review" --output-format json | jq -r '.session_id')
claude -p "Continue that review" --resume "$session_id"The other is to pass the earlier findings in as input. If you saved the .structured_output from the last run, pipe it in alongside the new diff or load it with --append-system-prompt-file. Then give an explicit instruction, for example: "these were reported previously; report only new issues or ones still unaddressed." Resuming the *reviewer's* session is consistent with the previous section, because the reviewer stays independent of the author.
Checkpoint 3 of 5· Exam question
A CI pipeline needs to parse Claude's response programmatically to decide whether a build step should fail. The team wants the reply to always match a specific JSON shape, for example an object with a boolean `passed` field and an array of `issues` strings, regardless of how Claude phrases its reasoning. Which invocation achieves this?
Correct answer: A — claude -p "review this diff" --output-format json --json-schema '{"type":"object","properties":{"passed":{"type":"boolean"},"issues":{"type":"array","items":{"type":"string"}}},"required":["passed","issues"]}'
- A. Correct. Combining --output-format json with --json-schema validates the model's structured output against the supplied schema and returns it in the structured_output field, giving a guaranteed machine-parseable shape.
- B. Asking nicely in the prompt with plain text output gives no schema enforcement; Claude can vary phrasing or omit fields, and the CI script would need fragile text parsing.
- C. stream-json streams turn-by-turn events for real-time display, it does not validate or constrain the final answer to a specific object schema.
- D. Appending schema instructions to the system prompt is a soft hint with no validation; the model can still drift from the exact shape, unlike an enforced --json-schema.
Checkpoint 4 of 5· Check yourself
A CI reviewer posts the same unaddressed-issue comment again after every push. What most directly stops the duplicates?
Duplicates happen because each run has no record of what it already reported. Supplying the earlier findings, by resuming the review session or passing them in, lets the reviewer filter.
“claude -p "Continue that review" --resume "$session_id"”Source: code.claude.com
4.Feeding existing tests into test generation
Test generation has its own version of the duplication problem. If Claude cannot see the current test suite, it will suggest scenarios the suite already covers. The best-practices guide gives you two ways to supply that context. You can pipe file contents in directly, as with cat file | claude -p "query". Or you can tell Claude to pull context itself using Bash commands, MCP tools, or by reading files. For example: "read tests/auth/ first, then add tests only for scenarios not already covered." The docs give no worked example of this deduplication, but both mechanisms are documented.
This works well alongside the guide's advice to provide verification criteria. Its example prompt lists concrete cases (user@example.com is true, invalid is false, user@.com is false) and asks Claude to run the tests after implementing. In CI, the existing test files show what is already covered, CLAUDE.md says what a valuable test looks like, and running the tests confirms the new ones pass.
Checkpoint 5 of 5· Check yourself
A nightly job asks Claude to "write tests for the auth module". Reviewers keep rejecting tests that duplicate existing ones. Which change addresses this?
Claude can only avoid scenarios it can see. The docs support piping content in or telling Claude to fetch context by reading files.
“Tell Claude to pull context itself using Bash commands, MCP tools, or by reading files.”Source: code.claude.com
Sources4
Exam traps
Each one states something that sounds right. Open it to see what is actually true.
1.A longer, more exhaustive CLAUDE.md always improves CI output.Why is that wrong?
Longer files consume more context on every run and reduce adherence. Keep CLAUDE.md concise and put area-specific rules in path-scoped files.
2.The session that wrote the code is the best reviewer because it already understands the change.Why is that wrong?
The docs recommend a fresh model as a second opinion, so the agent that did the work is not the one grading it.
Covered in Why the author session should not grade its own work
Practise it for real
Build a headless review step that an independent instance runs on a PR diff, with output a script can read
1.Run: gh pr diff <number> | claude -p --append-system-prompt "You are a security engineer. Review for vulnerabilities." --output-format json
Why: Piping only the diff into a fresh -p run gives you a reviewer that has no history with the author session
You should see: A single JSON object is printed and the process exits without waiting for input
2.Pipe the same command into jq -r '.session_id' and save the value
Why: The session ID lets a later run carry this review's findings forward
You should see: A session ID string
3.After a new commit, run claude -p "Report only issues that are new or still unaddressed" --resume "$session_id" --output-format json
Why: Giving the re-run its earlier findings prevents duplicate comments
You should see: Findings limited to new or still-open issues
4.Add --json-schema with a findings schema and extract the result with jq '.structured_output'
Why: A schema gives a posting script a fixed shape to read
You should see: A JSON value matching your schema, separate from the .result text
Stuck? Get a nudge
If the run stalls, check whether it is waiting on a permission prompt and add a matching --allowedTools entry.
Sources
Every claim above is drawn from one of these pages, quoted as it was written on the date shown.
- 1.https://code.claude.com/docs/en/github-actionsOfficial docs
“Keep your CLAUDE.md concise, since Claude reads it on every run”
↩︎ CLAUDE.md: the standing brief for every CI run - 2.https://code.claude.com/docs/en/gitlab-ci-cdOfficial docs
“Project-aware: Claude follows your CLAUDE.md guidelines and existing code patterns”
↩︎ CLAUDE.md: the standing brief for every CI run - 3.https://code.claude.com/docs/en/code-reviewOfficial docs
“CLAUDE.md: shared project instructions that Claude Code uses for all tasks, not just reviews.”
↩︎ CLAUDE.md: the standing brief for every CI run - 4.https://code.claude.com/docs/en/best-practicesOfficial docs
“Anything Claude can figure out by reading code”
↩︎ CLAUDE.md: the standing brief for every CI run“Long sessions with irrelevant context can reduce performance.”
↩︎ Why the author session should not grade its own work“so the agent doing the work isn’t the one grading it”
↩︎ Why the author session should not grade its own work“Tell Claude to pull context itself using Bash commands, MCP tools, or by reading files.”
↩︎ Feeding existing tests into test generation“example test cases: user@example.com is true, invalid is false, user@.com is false”
↩︎ Feeding existing tests into test generation“has a fresh model try to refute the result, so the agent doing the work isn’t the one grading it”
↩︎ Exam trap 2“Testing instructions and preferred test runners”
↩︎ Checkpoint“Here's the review feedback: [Session B output]. Address these issues.”
↩︎ Checkpoint - 5.https://code.claude.com/docs/en/memoryOfficial docs
“Scope rules to specific file types with .claude/rules/”
↩︎ CLAUDE.md: the standing brief for every CI run“Longer files consume more context and reduce adherence”
↩︎ Exam trap 1 - 6.https://code.claude.com/docs/en/cli-referenceOfficial docs
“Resume session by ID or name”
↩︎ Re-running a review after new commits - 7.https://code.claude.com/docs/en/headlessOfficial docs
“System prompt additions | --append-system-prompt, --append-system-prompt-file”
↩︎ Re-running a review after new commits“claude -p "Continue that review" --resume "$session_id"”
↩︎ Checkpoint