ANTHROPIC / TECHNICAL EXPLAINER

Anthropic CCAR-F: Claude Code Plan Mode, Skills, and CI Workflows

Use Claude Code plan mode, skills, hooks, permission boundaries and CI workflows with reliable review controls.

In this article

Claude Code can help a team investigate a codebase, propose a change, run checks, and prepare a patch, but its usefulness depends on how responsibility is divided between the tool and the software delivery process. A developer may accept a suggested refactor during a local session; a production pipeline needs repeatable constraints, known inputs, approvals, and a way to explain every change after it merges. Treating both as the same workflow usually creates either a slow interactive experience or an automation path with insufficient guardrails.

Three capabilities deserve separate design attention: planning before changing files, reusable skills or project rules that provide task-specific guidance, and noninteractive execution within continuous integration. They are complementary but not substitutes for ordinary build, test, review, and authorization controls. The established Claude Code settings should define trusted defaults; each of the patterns below determines how those defaults operate during a particular task.

Use planning when the decision is harder than the edit

A coding assistant should not start modifying production-critical code before it understands the interfaces and risks involved. Planning is particularly useful when a change touches several packages, a database migration, a security boundary, or an unfamiliar repository. In a planning phase the assistant can inspect relevant files, identify dependencies, outline tests, and surface unknowns without treating exploration as permission to change the system.

The plan should contain a narrow statement of the requested behavior, the files or components likely to change, alternatives considered, acceptance criteria, tests, and a rollback boundary. For example, adding a new API field may require changes to server validation, client types, documentation, contract tests, and analytics consumers. A useful plan traces those consequences rather than listing generic “implement, test, deploy” steps. It should also identify assumptions that need user or maintainer confirmation.

Not every edit requires formal planning. Fixing a clear typo in an isolated document usually does not. Overusing a heavyweight approval sequence for trivial, reversible changes slows engineers and encourages them to bypass the process. Choose plan-first behavior based on scope, uncertainty, reversibility, and consequence; choose direct execution for a small, well-understood change only when policy and permissions allow it.

Make plan approval specific to the proposed change

An approval should authorize a defined plan, not an unlimited series of future edits. A useful review includes the affected subsystem, intended files, expected tests, known risks, and any new dependencies. Once approved, material deviations should trigger another review: discovering a need to rewrite authentication logic is not a minor implementation detail of a previously approved UI change.

Implementation can still be iterative. The assistant may learn that a proposed library API does not exist or that a test reveals an overlooked edge case. It should report what changed in the evidence and revise the plan when the deviation affects risk, functionality, or scope. For code with financial or security effects, a human owner should inspect the actual diff, not merely approve a fluent explanation of it.

Keep the requested task and the authority to run tools separate. Even an approved plan does not necessarily authorize deployment, credential access, or modifications outside the repository. Tool permissions and branch protections should enforce these boundaries independently from the natural-language plan.

Separate persistent instructions from task-specific skills

Repositories need durable context such as directory conventions, supported runtime versions, formatting rules, test commands, and ownership boundaries. Project instructions can capture these rules so developers do not repeatedly explain them. A skill is more targeted: it can describe the procedure for a recurring kind of work, such as running accessibility checks, writing a migration review, or generating a release-note summary. Keeping these responsibilities distinct reduces unrelated instructions during a coding task.

For example, a shared project rule might state that database schema changes require compatibility testing across two application versions. A migration skill can then explain how to inspect the current schema, prepare a reversible migration, test old and new application paths, and produce the evidence expected by reviewers. Invoking the skill should not override the project rule or silently elevate permissions.

Instruction scopes can overlap: organization policies, repository-level guidance, directory-specific rules, and personal preferences do not all carry equal authority. Teams should document which controls are centrally managed and which can be customized locally, then test whether the intended rule is actually loaded for the target path. A reviewer should be able to tell whether a behavior came from a product permission, a project instruction, or a task-specific skill. Use the current Claude Code settings to verify file locations and precedence, which may change as the product evolves.

Keep reusable skills small, testable, and owned

A useful skill has a clear trigger, objective, inputs, expected outputs, and failure behavior. A “review API compatibility” skill might require an API diff, impacted clients, a compatibility matrix, and a list of unverified assumptions. This is more dependable than a page of generic instructions telling an assistant to “think carefully.” Reuse should save work without obscuring the actual evidence that supports a conclusion.

Skill maintenance resembles other software maintenance. Assign owners, review changes, test representative cases, and remove obsolete commands. A skill that invokes a tool or scripts must explain what permissions are required and what data it may read or change. Project owners should not automatically trust an unreviewed skill pulled from a public repository, because instructions can affect tool selection and handling of sensitive data.

Test skills with adversarial or awkward scenarios. What happens when the target files are missing, a repository contains contradictory historical instructions, or a requested command would operate on a production environment? A robust skill reports the limitation or seeks authorization rather than inventing a replacement procedure. Skills should also avoid embedding secrets, hard-coded customer identifiers, or dated vendor instructions that silently go stale.

Integrate Claude Code into CI without creating a privileged bypass

Noninteractive execution needs real CLI boundaries, not a prompt that merely asks for safe JSON. claude -p runs in print mode, --output-format json supplies a machine-readable response envelope and --json-schema specifies the structured final output. --tools restricts which built-in tools are available; --allowedTools permits designated tool operations without individual permission prompts. It is not a substitute for the minimal available-tool set or target-system authorization. Verify supported syntax in the current Claude Code CLI before changing a release job.

For pull-request review, require each finding to identify a file and line span, an observable defect or rule, supporting evidence, impact and uncertainty. Run real tests and compare reviewer findings against a labeled set of clean and defective changes. Excessive false positives make critical warnings easier to miss. Treat external PR descriptions and code comments as untrusted data: neither may grant tool access or request secrets. A schema-valid finding is review evidence, not authorization to merge or deploy; protected branch rules and approved reviewers remain the decision boundary.

Continuous integration is a different operating environment from a developer’s workstation. Jobs should start from a known commit, have bounded execution time, use minimal short-lived credentials, and produce artifacts that are reviewable later. Claude Code may help with static analysis, proposing a patch, drafting tests, or summarizing failures, but the system of record for acceptance remains deterministic checks, code review, and the organization’s protected branch and release policy.

Do not give an AI-assisted job access to deployment credentials merely because it needs to inspect test failures. Use a read-only token for repository analysis, narrow permissions for opening a proposed change, and a separately controlled identity for promotion. External pull requests and issue descriptions can contain malicious instructions. Treat their text as untrusted evidence, not as authority to run commands or send repository secrets to another service.

A sound pipeline keeps distinct stages: gather repository context, ask for the bounded analysis, capture the proposed diff or report, run validation, and require appropriate approval before merge or release. Report whether the proposed patch actually passed tests and which environment ran them. A generated test explanation cannot replace a test runner’s exit code. If an automated fix fails twice for the same cause, stop and return a concise diagnostic rather than repeatedly modifying code until a time budget expires.

Use hooks as guards rather than invisible automation

Hooks can enforce invariants around tool actions or workflow stages. They may reject dangerous commands, validate file paths, run required checks, or collect audit data. Their purpose is not to add a second, opaque automation system behind the assistant. Every hook should have an owner, clear trigger conditions, a bounded runtime, predictable failure semantics, and observable results.

For example, a pre-write guard can reject changes to secret files or deployment manifests outside an authorized task. A post-change check can run a formatter or unit test and record its result. If a critical pre-execution hook fails, the workflow should fail closed. The Agent SDK lifecycle likewise distinguishes a proposed tool call from its verified outcome; hooks, permission checks and target-service authorization enforce different boundaries.

Hooks cannot replace application security. A repository hook can reject a shell command seen by the coding assistant, but downstream APIs should still validate identity and authorization. Nor should hooks indiscriminately collect prompts, file contents, and secrets into logs. Record the minimum information needed to explain decisions and enforce retention limits suitable for the project.

Evaluate changes at the repository and delivery level

The most useful measure is whether the AI-assisted workflow produces a correct, maintainable change with a clear record of evidence and review. Measure build success, tests added or updated, escaped defects, policy denials, unauthorized-file attempts, review effort, and time to an accepted patch. Counting generated lines or assistant messages tells little about engineering quality. A large diff can be worse than a precise two-line change.

Create regression scenarios for large refactors, missing dependencies, permission denials, ambiguous requirements, conflicting project rules, and changes that cannot be safely tested in a local environment. Ensure the assistant reports when a validation step was not run, instead of treating absence of failure as success. CI output and the actual diff should remain inspectable even if an LLM-generated summary is polished.

A team can test this governance chain with a deliberately unsafe change request: plan mode should expose the intended files, path rules should constrain context, hooks and CI should reject prohibited changes, and the review should explain the failed check. If a generated patch passes unit tests but bypasses a protected deployment rule, the workflow has not succeeded. Repository policy and human approval—not a polished assistant summary—must determine what can be merged and shipped.