A platform team wants Claude Code to draft a short explanation of every failing nightly build. The step runs inside the continuous integration pipeline with no engineer at the terminal, finance has set a fixed spend ceiling per pipeline run, and the pipeline must fail cleanly rather than wait forever if the step stalls. Which way of invoking Claude Code fits those constraints?
- ARun Claude Code interactively on a shared build machine and have the pipeline job attach to that terminal session, so an engineer can approve each step when one happens to be online.
- BInvoke Claude Code headlessly but leave permissions and run length unset, relying on a clearly worded instruction in the repository's CLAUDE.md telling the agent to stop early and stay within the budget.
- CInvoke Claude Code in its non-interactive headless mode from the pipeline script, with an explicit ceiling on turns or spend for the run and tool permissions defined in the repository's checked-in settings.json. Correct
- DHave the pipeline post the failing build log to a hosted chat assistant through an ad hoc script, then poll that conversation until a reply arrives and paste the reply into the build comment.
Why A is wrong: Attaching to an interactive session is tempting because approvals feel safer, but the stem states nobody is at the terminal, so the job would block on prompts and the pipeline could never fail cleanly.
Why B is wrong: This looks right because headless invocation is correct, but a written instruction is advice the agent may not follow, so neither the spend ceiling nor the clean failure is actually enforced by anything.
Why C is correct: Headless invocation needs no terminal, the explicit run ceiling gives the pipeline a bounded failure instead of an open-ended wait, and committed settings.json makes the permission surface identical on every build agent and reviewable in a pull request.
Why D is wrong: Polling a chat surface seems to avoid the terminal problem, but it discards the repository context that makes the explanation useful and reintroduces the unbounded wait the team must avoid.