CCDV-F · module 7 of 8 · 3.1% of the exam
Claude Code
Weight: 3.1 percent of the exam. Tests working knowledge of Claude Code as a configurable agent: memory files, skills and slash commands, hooks, permissions, subagents, and non-interactive use in CI.
What the exam expects
Six questions, so breadth over depth. The exam does not ask you to recite every hook event or CLI flag. It asks you to pick the right mechanism for a stated goal, which means you need a clear mental model of what each component is for and, just as importantly, what it is not for.
The recurring shape: a team wants some behaviour to be automatic, shared, enforced, or reproducible, and four components could plausibly deliver it. The correct answer is the one whose purpose matches, and the distractors are components misapplied.
One framing helps more than any list. Claude Code has four distinct configuration surfaces with different jobs:
| Surface | Job | Loaded |
|---|---|---|
| Memory (CLAUDE.md) | Standing facts about this project or user | Always, into every session |
| Skills and commands | Procedures, invoked by you or chosen by Claude | On demand, when invoked or judged relevant |
| Hooks | Deterministic code that runs at lifecycle points | Automatically, at the event |
| Settings and permissions | What Claude is allowed to do | Always, enforced by the harness |
Memory: CLAUDE.md
CLAUDE.md holds facts that should be true in every session: this repo uses pnpm, tests run through a wrapper script, migrations are generated rather than hand-edited.
Files are read and merged from several locations:
- Project:
CLAUDE.mdat the repository root, and.claude/CLAUDE.md - User:
~/.claude/CLAUDE.md, applying to all your projects - Enterprise: a managed-settings key, injected organization-wide and not excludable by users
Project memory checked into version control is what makes a convention shared and reviewable. Personal memory gives every teammate a different Claude, which is usually the problem being solved rather than the solution.
The boundary against skills matters: memory is always in context, so it should stay short and factual. When a section of CLAUDE.md grows into a multi-step procedure, that is the signal to move it into a skill, whose body loads only when used.
Skills and slash commands
Custom commands have been merged into skills. A skill at .claude/skills/deploy/SKILL.md and a file at .claude/commands/deploy.md both create /deploy. Skills additionally support a directory of supporting files and richer frontmatter, so they are the recommended form; existing command files keep working.
Locations follow the same project versus personal split: .claude/skills/<name>/SKILL.md for the project, ~/.claude/skills/<name>/SKILL.md for all your projects.
The frontmatter fields that come up:
| Field | Effect |
|---|---|
description | What the skill is for; also what Claude reads when deciding whether to load it |
disable-model-invocation: true | Only a person can invoke it. Use for side-effecting workflows such as deploy, commit, or send-message |
user-invocable: false | Only Claude can invoke it. Use for background knowledge that is not a meaningful user action |
allowed-tools | Pre-approves the listed tools for the turn that invokes the skill, so it runs without prompts |
argument-hint | Autocomplete hint only. It grants nothing |
The pairing to remember is disable-model-invocation plus allowed-tools: the first stops Claude from deciding to deploy on its own, the second lets the deploy run without interruption once a human triggers it. Note that the allowed-tools grant is scoped to the invoking turn and clears when you send your next message, whereas the skill's instructions stay in context.
Hooks
Hooks run your own code at lifecycle points, which makes them the mechanism for anything that must happen deterministically rather than because the model chose to.
The events worth knowing: PreToolUse, PostToolUse, UserPromptSubmit, SessionStart, SessionEnd, Stop, SubagentStop, and PreCompact. Hooks are configured in settings files at user, project, and managed scope.
Exit code semantics are the most examinable part:
- 0: success. Standard output is parsed for JSON on hooks that support it.
- 2: blocking error. Standard error is shown to Claude as the reason. On
PreToolUsethis blocks the tool call; onUserPromptSubmitit blocks the prompt; onStopit prevents stopping. - Anything else: non-blocking error. The action proceeds.
So "block this class of edit automatically and tell Claude why" is a PreToolUse hook exiting 2 with an explanation on standard error. PostToolUse runs after the tool has already executed, which is too late to prevent anything. Hooks can also return structured JSON, including a permissionDecision on PreToolUse, for finer control than exit codes provide.
Settings, permissions, and modes
Settings resolve in a fixed precedence order, highest first:
- Managed settings (organization policy)
- Command line arguments
.claude/settings.local.json(project, not shared).claude/settings.json(project, shared)~/.claude/settings.json(user)
Managed at the top is the answer whenever a scenario says an organization must guarantee something regardless of what individual developers configure. Permission rules merge across scopes rather than replacing each other, and a restrictive managed value cannot be relaxed locally.
Permissions use allow, ask, and deny lists with rules such as Bash(git diff *), Read(./.env), and Write(path). Two details: the space before the asterisk matters for prefix matching, and ** spans directory levels. deny is how you withhold access; there is no way to express a prohibition through the allow list.
Permission modes set the session baseline: default (ask on restricted actions), acceptEdits (write files without prompting, still ask for riskier operations), plan (propose without executing), and bypassPermissions (skip checks entirely).
Subagents
A subagent runs in its own context window with its own system prompt, tool access, and permissions, and returns only its result to the main conversation.
That property is the reason to use one. When an investigation would flood the main conversation with search results, logs, and file contents that will never be referenced again, delegating it keeps the main context clean. The secondary reasons are constraining tools, reusing a configuration, and routing work to a cheaper model.
Subagents are markdown files with YAML frontmatter in .claude/agents/ (project) or ~/.claude/agents/ (user), with fields including name, description, tools, and model. The description is what Claude matches against when deciding to delegate.
Non-interactive and CI use
Run in print mode with a prompt to execute non-interactively. The pieces that matter for CI:
- Bare mode skips auto-discovery of hooks, skills, plugins, MCP servers, and memory files, so a run behaves identically on every machine. This is the answer whenever a scenario stresses reproducibility or "not influenced by anyone's local configuration".
- Output format accepts
text,json(result plus session metadata and cost), andstream-json(newline-delimited events). Parsing structured output beats string-matching prose. - Tool pre-approval via an allowed-tools list, using the same permission rule syntax, keeps the surface minimal. A permission mode can set a session-wide baseline instead, but
bypassPermissionsin CI is the opposite of what an unattended context warrants. - Exit codes: zero on success, non-zero on failure, so scripts can branch on status.
- Session continuation is available for multi-step scripted flows.
How to think through the question
- Extract the requirement verb. Shared, automatic, enforced, reproducible, isolated. Each maps to a surface: shared points to project-scoped files in version control; enforced points to managed settings or permissions; automatic and deterministic points to hooks; isolated points to subagents; reproducible points to bare mode.
- Ask who decides. If the model decides, it is a skill Claude may load or a tool it may call. If a person decides, it is a user-invoked skill. If nobody should decide, it is a hook or a permission rule.
- Check the timing. Before an action or after it. This one question settles most hook questions.
- Eliminate anything that puts an enforcement requirement in prose. A CLAUDE.md line is a strong convention, never a guarantee.
- Eliminate the manual workaround. Options describing copy-paste between sessions or scripting a terminal UI are almost always the distractor.
Worked example. A team wants every proposed edit under the migrations directory blocked automatically, with an explanation returned to Claude so it can pick another approach, without a human having to decline each time.
Step 1: the verbs are "blocked automatically" and "without a human", so this is deterministic enforcement, pointing at hooks or permissions. Step 2: nobody should decide per occurrence, which rules out anything requiring a person. Step 3 is decisive: the edit must be prevented, not undone, so the hook must run before the tool. That eliminates PostToolUse, which fires after the write has already happened and leaves the hook undoing damage. A SessionStart hook that deletes the directory is destructive and explains nothing. A restricted subagent constrains a subagent but does nothing about the main conversation. What remains is a PreToolUse hook exiting with code 2 and writing the reason to standard error, which is exactly the block-with-explanation contract.
Exam traps
- Putting procedures in CLAUDE.md. Memory is always in context, so long procedures there are permanent overhead. Skills load on demand.
- Putting transient output in CLAUDE.md. Search results and investigation notes do not belong in a file loaded into every session.
- Personal configuration for a team requirement. If it must apply to everyone, it belongs in the project or in managed settings.
- CLAUDE.md as a security control. Instructions are conventions; permission rules are enforcement.
PostToolUsefor prevention. It runs after the tool.- Confusing
disable-model-invocationwithuser-invocable: false. They are opposites: the first restricts invocation to humans, the second restricts it to Claude. - Treating
argument-hintas a permission grant. It is autocomplete text. bypassPermissionsin CI. Unattended runs warrant tighter permissions, not looser ones.- Assuming print mode cannot use tools. It can, and it is the intended automation entry point.
- Forgetting bare mode when reproducibility is the stated requirement. Without it, a teammate's personal hook or MCP server can change the result.
Quick reference
- Memory:
CLAUDE.mdat repo root and.claude/,~/.claude/CLAUDE.md, plus enterprise managed memory. Short standing facts only. - Skills:
.claude/skills/<name>/SKILL.mdor~/.claude/skills/...;.claude/commands/<name>.mdstill works. Both create/<name>. - Key frontmatter:
disable-model-invocation(humans only),user-invocable: false(Claude only),allowed-tools(pre-approve for the turn). - Hooks:
PreToolUse,PostToolUse,UserPromptSubmit,SessionStart,Stop,SubagentStop,PreCompact. Exit 2 blocks and shows standard error to Claude. - Settings precedence: managed, CLI args, project local, project, user. Managed cannot be overridden.
- Permissions:
allow,ask,denywith rules likeBash(git diff *). Modes:default,acceptEdits,plan,bypassPermissions. - Subagents:
.claude/agents/or~/.claude/agents/, frontmattername,description,tools,model. Own context window, returns a summary. - CI: print mode plus bare mode, explicit tool pre-approval, structured output, branch on exit code.
Ready to test this domain?
Drill mode gives instant feedback: pick a wrong answer and you immediately see why it is wrong.
Start the drill