CertSafari
    CLAUDE-CERTIFIED-ARCHITECT-FOUNDATIONS-CCAR-F · Lessons

    Domain 3 · Lesson 18/30

    Context for CI Claude Code Runs: CLAUDE.md, Existing Tests and Re-Reviews

    Integrate Claude Code into CI/CD pipelines

    8 min read
    3.33% of exam
    5 sources
    Published 28 Sep 2026
    Docs as of 26 Sep 2026

    What you will be able to do

    • Use CLAUDE.md and .claude/rules/ to give CI-invoked Claude Code your testing standards, fixtures and review criteria
    • Put existing test files in context so generated tests don't duplicate scenarios the suite already covers
    • Explain why an independent session should review generated code, and how to carry earlier findings into a re-review

    1.CLAUDE.md travels with the repository into CI

    A headless run in a pipeline starts from nothing. It doesn't know your conventions and nobody is there to correct it, so any project knowledge it needs has to come from files. That job belongs to CLAUDE.md. Project instructions live at ./CLAUDE.md or ./.claude/CLAUDE.md and are team-shared through source control. Any CI job that checks out the repository therefore gets the same instructions a developer's session does.

    The CI integrations rely on this directly. The GitLab integration's feature list says Claude follows your CLAUDE.md guidelines and existing code patterns. The Code Review docs describe CLAUDE.md as instructions used for every task, not just reviews. The review agents read it as project context and flag newly introduced violations of it. For review-only guidance, such as what to flag, at what severity and how to report it, Code Review also reads a separate REVIEW.md.

    Sources123

    2.Writing testing standards that improve generated tests

    Low-value generated tests usually trace back to missing context. Claude doesn't know which behaviours your team considers worth testing, which fixtures already exist or which scenarios are noise. The FAQ's rule for CLAUDE.md fits here well: record what tooling can't enforce and a new teammate would get wrong on day one. Your test criteria, fixture names and "don't bother testing X" rules are exactly that kind of knowledge.

    Write them as concrete instructions. The memory docs contrast “Run npm test before committing” with “Test your changes”. The first can be acted on and the second cannot. The same applies to test guidance. Name the fixture module, the helper to use, and the kinds of assertions that count as valuable. Length matters too: the FAQ warns that a CLAUDE.md that is too long or too vague gets skimmed.

    You don't have to put all of this in one file. The .claude/rules/ directory holds modular rule files, including a testing.md for testing conventions:

    Project layout with testing conventions split into their own rules filetext
    your-project/
    ├── .claude/
    │   ├── CLAUDE.md           # Main project instructions
    │   └── rules/
    │       ├── code-style.md   # Code style guidelines
    │       ├── testing.md      # Testing conventions
    │       └── security.md     # Security requirements

    A rules file can be scoped with paths frontmatter, which takes glob patterns. The rule then applies only when Claude works with matching files, for example test files:

    paths frontmatter that limits a rule to matching files, including test filesyaml
    ---
    paths:
      - "src/**/*.{ts,tsx}"
      - "lib/**/*.ts"
      - "tests/**/*.test.ts"
    ---

    Sources43

    3.Show the suite before asking for more tests

    Standards tell Claude what a good test looks like. They don't tell it which tests you already have. If a test-generation run can't see the existing suite, it will propose scenarios you already cover. The exam guide's remedy is to put the existing test files in context. The sources give two ways to do that. In a prompt, typing @ followed by a path makes Claude read that file before responding. In a pipeline, you can pipe content into claude -p the same way the build log was piped in earlier.

    The sources show the mechanism but not the instruction. Asking for "only scenarios not already covered by these tests" is the exam guide's recommendation, not something the documentation here spells out.

    Sources4

    4.Why a separate session should review generated code

    The exam guide makes a claim about isolation: the session that generated some code is less effective at reviewing it than an independent review instance. The sources here don't argue the reasoning behind that claim. What they do show is how to get the isolation.

    Every new claude -p invocation is its own session. A session is only carried forward when you ask for it with --continue (most recent conversation) or --resume <session_id>. A generate job and a review job are independent as long as the review job doesn't continue the generate job's session. Inside a terminal session, /code-review gets the same effect by running the review as a forked subagent. The FAQ also lists reviewing a diff along separate dimensions as a use for subagents.

    Sources15

    5.Re-running a review after new commits

    A review bot that runs on every push has a problem that a one-off review doesn't: it posts the same findings again each time. The exam guide's fix is to include the earlier findings in the new run's context and tell Claude to report only issues that are new or still not addressed.

    The sources give one way to carry that context. With --output-format json, you capture the session_id from the first review and pass it to --resume on the next run, so the follow-up happens inside the conversation that produced the original findings. You can also feed a saved list of earlier findings into the prompt. Either way, the dedupe instruction goes in your prompt; the sources don't provide it as a built-in behaviour.

    Capturing a review's session ID and resuming that session in a later runbash
    session_id=$(claude -p "Start a review" --output-format json | jq -r '.session_id')
    claude -p "Continue that review" --resume "$session_id"

    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?

    Sources5

    Exam traps

    Each one states something that sounds right. Open it to see what is actually true.

    1. 1.CLAUDE.md only affects interactive sessions, so CI runs need all project conventions restated in the prompt.Why is that wrong?

      Project CLAUDE.md is shared through source control and is used for all tasks. CI integrations such as GitLab and Code Review read it as project context.

      Covered in CLAUDE.md travels with the repository into CI

    2. 2.The most effective review is the generating session continued with --continue, because it already has all the context about the change.Why is that wrong?

      The exam guide says the generating session is the less effective reviewer. Use a fresh claude -p run or a forked subagent instead. Only --continue or --resume carries a session forward.

      Covered in Why a separate session should review generated code

    Practise it for real

    Turn a headless Claude Code run into output a CI script can parse, then carry its session into a follow-up run.

    1. 1.In a repository, run: claude -p "Summarize this project" --output-format json | jq -r '.result'

      Why: This shows the JSON envelope, with the free-text answer in the result field.

      You should see: A plain-text summary printed by jq.

    2. 2.Run the headless docs' schema example: claude -p "Extract function names from auth.py" --output-format json --json-schema '<the functions schema>' | jq '.structured_output' (use a file that exists in your repo)

      Why: With --json-schema, the data that matches the schema appears in structured_output, which is what a comment-posting script would read.

      You should see: A JSON object with a functions array of strings.

    3. 3.Run: session_id=$(claude -p "Start a review" --output-format json | jq -r '.session_id'), then claude -p "Continue that review" --resume "$session_id"

      Why: This carries a review's context into a later run, which is how a re-review can see the earlier findings.

      You should see: The second run continues the first review instead of starting from nothing.

    Stuck? Get a nudge

    If a step stalls, check whether Claude wanted a tool you didn't pre-approve. Add --permission-mode dontAsk with an explicit --allowedTools list.

    Sources

    Every claim above is drawn from one of these pages, quoted as it was written on the date shown.

    1. 1.
      “Code Review reads it as project context and flags newly introduced violations as nits.”
      ↩︎ CLAUDE.md travels with the repository into CI
      “In a terminal session, where /code-review runs the review as a forked subagent”
      ↩︎ Why a separate session should review generated code
      “CLAUDE.md: shared project instructions that Claude Code uses for all tasks, not just reviews.”
      ↩︎ Exam trap 1
      “In a terminal session, where /code-review runs the review as a forked subagent”
      ↩︎ Exam trap 2
    2. 2.
      “Project-aware: Claude follows your CLAUDE.md guidelines and existing code patterns”
      ↩︎ CLAUDE.md travels with the repository into CI
    3. 3.
      “Team-shared instructions for the project”
      ↩︎ CLAUDE.md travels with the repository into CI
      ““Run npm test before committing” instead of “Test your changes””
      ↩︎ Writing testing standards that improve generated tests
    4. 4.
      “Things tooling can’t enforce that a new teammate would get wrong on day one”
      ↩︎ Writing testing standards that improve generated tests
      “Too long or too vague: trim to the rules that actually matter”
      ↩︎ Writing testing standards that improve generated tests
      “Type @ then the path (tab-completes). The mentioned file is read before Claude responds.”
      ↩︎ Show the suite before asking for more tests
    5. 5.
      “Continue the most recent conversation”
      ↩︎ Why a separate session should review generated code
      “session_id=$(claude -p "Start a review" --output-format json | jq -r '.session_id')”
      ↩︎ Re-running a review after new commits

    Ready to test yourself?

    Practise the 16 questions on this subdomain.