AnthropicClaude Certified Architect – Professional2026-107.1 Configure Claude tools and environments for teams (e.g., Claude Code)
Release the team's configuration together
Completed by the knowledge check
Learning objective
Standardize shared Claude Code configuration — project instructions, settings, permissions, hooks, MCP servers, and Skills — in version control.
Core idea
Project instructions, rules, skills, and MCP definitions already have repository locations. At team scale, the architectural decision is to release them as one compatible configuration, with an owner for each executable dependency and a check that a teammate actually receives the intended behavior.
A commit containing every configuration file can still be incomplete. A hook might call a script present only on its author’s laptop; a skill might assume a server that nobody else can authenticate to. Standardization therefore means reviewing the relationship between the files, not merely collecting them under .claude/. Keep organizational enforcement in managed settings, as covered in 7.1.2.
How it works
Review one configuration change across its surfaces
Use the repository’s configuration review to answer what changes for every contributor:
| Surface | Shared artifact | Release question |
|---|---|---|
| Standing guidance | CLAUDE.md or .claude/CLAUDE.md, plus .claude/rules/ | Does the guidance name the commands and conventions this revision actually supports? |
| Permissions and settings | .claude/settings.json | Which operations become approved, prompted, or denied? |
| Lifecycle automation | hooks in .claude/settings.json, with committed scripts | Can every contributor run the handler from the documented environment? |
| Service integration | Root .mcp.json | Does each developer have a supported authentication path to the approved destination? |
| Reusable procedure | .claude/skills/<name>/SKILL.md, with supporting files | Do its commands and integrations exist in this release? |
This is a review inventory, not a second source of configuration. The files remain authoritative. Give changes to permissions and server destinations explicit reviewers rather than hiding them in a large instruction rewrite. A project maintainer owns conventions; a developer-tools maintainer owns executable automation; the integration owner confirms the endpoint and credential requirements.
Keep personal experiments in .claude/settings.local.json, and do not commit that file. Claude Code keeps it out of Git when it creates it; if you create it yourself, add it to .gitignore. A successful experiment becomes shared behavior only after its dependencies and settings move into the reviewed release.
Choose hook events by the lifecycle being standardized
Shared automation belongs under hooks in .claude/settings.json. Select the event according to what the team needs to observe or control:
| Event | Selection with matcher | Team use and boundary |
|---|---|---|
PreToolUse | Tool name, such as Bash | Check a proposed action before execution. |
PostToolUse | Tool name, such as Edit or Write | Format or inspect a successful file-tool edit; the edit already happened. |
PreCompact | manual or auto | Check readiness before context compaction, with a deliberate decision about blocking it. |
SubagentStart | Agent type | Supply team context when a subagent starts; this event cannot block creation. |
SubagentStop | Agent type | Check completion and, with decision: "block" and reason, keep the subagent working. |
For SubagentStart, return context through hookSpecificOutput.additionalContext with hookEventName: "SubagentStart". Review the size and relevance of this text: an organizational convention needed by all delegated work differs from copying a whole repository manual into each subagent.
PreCompact can block with exit code 2 or decision: "block". Blocking proactive automatic compaction leaves the conversation uncompacted; blocking compaction that is recovering from a context-limit API error surfaces that error and fails the request. A handler that always blocks is therefore an availability decision, not a harmless logging preference.
Narrow a tool hook without suppressing lifecycle hooks
The hook handler’s if field takes one permission-rule pattern. This illustrative excerpt selects a deletion review script only for matching Bash calls:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"if": "Bash(rm *)",
"command": "node",
"args": ["${CLAUDE_PROJECT_DIR}/.claude/hooks/check-delete.js"]
}
]
}
]
}
}The team supplies check-delete.js and Node in its development environment; these are example dependencies. For intentional rejection, a PreToolUse command handler can exit 2 or return hookSpecificOutput.permissionDecision: "deny" with hookEventName: "PreToolUse". An ordinary exit 1 without valid decision JSON is non-blocking. If handler failure itself must block, onFailure: "block" on a command or HTTP hook requires Claude Code v2.1.295 or later. Test that failed-script path before relying on the check.
matcher selects the tool group, and if avoids spawning this handler for nonmatching calls. The field supports PreToolUse, PostToolUse, PostToolUseFailure, PermissionRequest, and PermissionDenied only. On other events, a handler carrying if never runs. Do not copy this filter into PreCompact or either subagent lifecycle event.
if accepts no list, &&, or ||; use separate handlers for separate patterns. Bash filtering is best-effort: when Claude Code cannot determine the commands involved, it runs the handler regardless. Treat this filter as a way to reduce unnecessary process starts, not as a hard authorization rule.
A Bash call reaches the deletion review script when it matches the if pattern or when Claude Code cannot determine its commands; exit 2 or a deny decision rejects it, and an ordinary exit 1 is non-blocking.
${CLAUDE_PROJECT_DIR} identifies the root where the session started. If Claude enters a worktree during the session, that variable stays at the original root; use the hook input’s cwd when the check must inspect the active worktree instead.
Key distinctions and trade-offs
Shared configuration versus enforced policy: A repository release improves reproducibility but remains editable by contributors. CLAUDE.md supplies context rather than deterministic enforcement. A mandatory organizational restriction belongs in the managed tier.
Declared files versus effective behavior: Project permissions.allow rules wait for workspace trust; project deny and ask rules do not. A clean clone is not proof that every declared grant already applies. Verify the interactive launch path the team actually uses.
More automation versus more dependencies: A handler reduces reliance on remembered instructions but adds runtime, latency, failure, and ownership obligations. A formatter on PostToolUse cannot prevent a completed edit or cover files changed through an unrelated process.
Architecture / decision scenario
A retail platform has 36 engineers and a ten-minute onboarding target. In a pilot, 11 of 12 engineers can invoke the review skill, but only 5 can query its inventory server; the hook also calls a script from the lead’s home directory. The proposed shortcut is to commit the lead’s ~/.claude/settings.json hooks as-is, retaining the home-directory script path.
The developer-tools owner instead releases the project instructions, settings, hook scripts, .mcp.json, and skill together. The integration owner supplies individual authentication onboarding without committing tokens. Review verifies the approved build command and the deletion handler separately, and checks PreCompact, SubagentStart, and SubagentStop without the unsupported if filter. A teammate accepts workspace trust and exercises the skill, server connection, and matching hook from a clean clone before the release expands.
Common exam traps
- Calling a collection of files reproducible while its scripts live outside the repository.
- Treating instructions as execution enforcement.
- Adding
ifto a lifecycle event and expecting the handler to run. - Treating a
PostToolUseformatter as a pre-execution prohibition. - Committing local settings or live credentials to simplify onboarding.
What to remember
Release related configuration and its dependencies together. Review every permission expansion, choose hooks by event semantics, and use if only on its supported tool events. Verify the intended behavior through the team’s real launch and authentication path.
Knowledge check
A platform team adds a shared SubagentStop handler that checks a delegated reviewer’s output before it finishes. To avoid unnecessary process starts, the handler carries an if field copied from the team’s PreToolUse deletion check. Its matcher names the reviewer’s agent type, yet in testing the handler never runs. What change makes it run?
if value as a pattern that names the agent typedecision: "block" with a reason from the handlerif field and select the subagent with matcherif is evaluated only on the tool events — PreToolUse , PostToolUse , PostToolUseFailure , PermissionRequest and PermissionDenied . On any other event a handler that carries if never runs, whatever its pattern says, so rewriting the pattern changes nothing. For SubagentStop , matcher is the selection mechanism. What the handler returns only matters once it runs.A team’s PreToolUse command handler runs node on a committed script that rejects risky rm calls with exit code 2. On two laptops Node is not installed, the handler fails to start, and matching deletions proceed. Every machine runs Claude Code v2.1.300. The security owner requires a deletion to be blocked whenever the check cannot run. What should the team change?
"if": "Bash(rm *)" to the handlerPostToolUse handler"onFailure": "block" on the handleronFailure: "block" on a command or HTTP hook, available from v2.1.295, makes a failed handler block the action. Exit 1 is non-blocking anyway, if only narrows which calls spawn the handler, and a PostToolUse handler runs after the deletion has happened.A teammate clones a repository whose committed .claude/settings.json allows Bash(npm test *) and denies Bash(git push *). In their first session, the push is refused as configured, but every npm test call still prompts. The teammate has no local, user or managed settings. What explains the difference?
.claude/settings.local.jsonask rulepermissions.allow rules take effect only after each teammate trusts the folder, while project deny and ask rules apply immediately. A clean clone therefore shows the denial working and the pre-approval missing. Deny-first evaluation only decides between rules that match the same call, and npm test matches no deny rule.A PostToolUse hook lints the files Claude edits by running a script stored in the main checkout against ${CLAUDE_PROJECT_DIR}. Midway through a session, Claude enters a worktree under .claude/worktrees/ and edits files there, but the lint results still describe the main checkout. What should the hook read to find the directory Claude is working in?
cwd field${CLAUDE_PLUGIN_ROOT} placeholder${CLAUDE_PROJECT_DIR} stays at the root where the session started, and the exported environment variable carries the same value. The cwd field in the hook input follows Claude into the worktree. A script stored in the main checkout’s .claude/hooks/ resolves its own repository root to the main checkout as well.A platform team commits its project settings and a review skill, but a shared hook still calls a script in its author’s home directory. The rollout owner needs a setup that works on a teammate’s clean clone. What should happen before expansion?
References
- Anthropic, Settings files and precedence
- Anthropic, How Claude remembers your project
- Anthropic, Hooks reference
- Anthropic, Automate actions with hooks
- Anthropic, Extend Claude with skills
- Anthropic, Connect Claude Code to tools via MCP
- Anthropic, Configure permissions