Claude Code Session Preflight

Table of content

by Ray Svitla


most Claude Code sessions go wrong before the first prompt.

the package is a week stale. the model fell back to whatever the global config said. the working tree has uncommitted changes from yesterday. a .claude/settings.local.json from a sandbox repo still has an open allow rule. an MCP server you forgot about is wired to a third-party system. the agent runs, returns “done”, and the diff lands somewhere you didn’t intend.

a serious agent session deserves a preflight. five minutes of read-only checks beats an hour of cleanup.

below are the ten checks I run before any Claude Code session that’s going to touch real code, real branches, or real MCP-connected systems. unless explicitly noted, every command is read-only.


the 10-point preflight

#checkthe question it answers
1versionis the CLI at a known good version?
2model + effortwhat model and effort level will actually run?
3repo stateis the working tree clean and on the right branch?
4permissionswhat is allow/deny/ask resolving to here?
5MCP serverswhich servers will be live, with what scope?
6context fileswhich CLAUDE.md / AGENTS.md / skills will load?
7sourceswhere is the agent allowed to fetch from?
8output pathwhere will the output land — branch, file, PR?
9rollback planhow do you undo this in one command?
10stop conditionswhen do you kill the run?

if you can answer all ten in under five minutes, you’re ready. if you can’t, you don’t have a preflight problem — you have an unknown-stack problem, and the agent will surface it the loud way.


1. version

# read-only
claude --version
which claude
npm view @anthropic-ai/claude-code version

@anthropic-ai/claude-code ships fast. don’t memorize a number; run the three commands and compare. drift of more than a couple of point releases is a smell — old isn’t broken, but old means you might be reading docs and release notes that describe behavior you don’t have.

what to check:

failure mode: stale package. you read a release note about a fix and assume you have it. you don’t.

2. model and effort

inside a Claude Code session, run /status. it shows you which settings sources are live and which model and effort the session resolved to.

settings precedence in Claude Code, highest to lowest:

  1. managed (org policy)
  2. command-line args
  3. .claude/settings.local.json
  4. .claude/settings.json
  5. ~/.claude/settings.json

a model field in your project local file silently overrides your user file. an effortLevel set high globally will burn budget on a one-line fix you wanted Haiku for. the fields that matter:

fieldpurpose
modeldefault model id
effortLevelpersists effort across runs
availableModelslocks the menu
alwaysThinkingEnabledextended thinking default

failure mode: you think you’re on Sonnet at medium. you’re actually on Opus at the highest tier because a teammate committed .claude/settings.json last sprint.

3. repo state

# read-only
git status -sb
git log --oneline -5
git stash list
git diff --stat HEAD

four lines. they answer: is the tree clean, am I on the branch I think I’m on, are there stashes I forgot, and is there uncommitted work the agent will trample.

then create a session branch so the run is isolated:

# creates a new branch (reversible)
git switch -c session/$(date +%Y-%m-%d)-short-task-name

cheap, reversible, and the branch name tells you in two weeks what the session was for.

failure mode: right repo, wrong branch, dirty tree. the agent’s edits land on top of work you forgot about, the diff looks plausible, and you commit it.

4. permissions

permissions in Claude Code are JSON rules in three buckets — allow, deny, ask — evaluated deny-first, then ask, then allow. arrays merge across scopes, so a project file extends, not replaces, your user file.

read the live state:

# read-only
cat .claude/settings.json 2>/dev/null
cat .claude/settings.local.json 2>/dev/null
cat ~/.claude/settings.json

the rule format is Tool or Tool(specifier). patterns that should never be permanent in allow:

a sane denylist for any project that has secrets:

{
  "permissions": {
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)",
      "Bash(curl * | sh)",
      "Bash(rm -rf *)"
    ],
    "ask": [
      "Bash(git push *)",
      "Bash(npm publish *)"
    ]
  }
}

ask is the underused middle. it lets the agent propose, you approve, no full allow-all required.

failure mode: dangerous permissions inherited. a sandbox repo’s allow-all bash rule lives in ~/.claude/settings.json and follows you into a production repo.

5. MCP servers

# read-only
claude mcp list
claude mcp get <name>

inside a session, /mcp shows live status, including OAuth state for remote servers.

three scopes:

scopeloads insharedstored in
local (default)current projectno~/.claude.json
projectcurrent projectyes (committed).mcp.json at repo root
userall your projectsno~/.claude.json

verify before the session:

useful rule: if an MCP server can spend money, send messages, or delete records, it doesn’t belong in a routine coding session. give it its own session with its own settings file.

failure mode: forgotten MCP. you wired a server six weeks ago, never removed it, and an agent run pulls a wall of irrelevant context — or worse, fires off a side effect you didn’t ask for.

6. context files

the agent reads more than your prompt. it reads context files. before a serious session, know what’s loaded:

quick listing:

# read-only
ls -la .claude/ 2>/dev/null
find . -maxdepth 3 \( -name 'CLAUDE.md' -o -name 'AGENTS.md' \) 2>/dev/null

read the project root file. CLAUDE.md and AGENTS.md drift faster than code — instructions that referenced src/legacy/ still sit there a year after src/legacy/ was deleted. stale instructions are not neutral; they teach the agent to do the wrong thing with confidence.

failure mode: missing context files, or worse, present-but-wrong. the agent follows the file. the file is lying.

related: AGENTS.md vs CLAUDE.md vs INSTRUCTIONS.md , AGENTS.md .

7. sources

what is the agent allowed to read from?

if the task only needs the local repo, deny the rest for the session. it shrinks both the attack surface and the hallucination surface.

failure mode: open-internet fetch in a session that should have been local-only. the agent reads a forum post that contradicts your codebase and “fixes” working code.

8. output path

before you start, write down where the output is going:

if any of those is “I’ll figure it out,” you don’t have an output path; you have an open-ended search. open-ended searches are for exploration sessions, not for serious ones.

failure mode: agent reports success, output is in a different branch, an unexpected file, or a draft PR you never opened.

9. rollback plan

write the rollback before the run, not after.

if the session…rollback
made commits on a session branchgit switch main && git branch -D session/...
made unstaged editsgit restore . (after confirming nothing else is there)
made a stashgit stash drop (the specific one, not clear)
pushed to a remoterevert commit + force-push only if you own the branch and confirmed
sent an external action via MCPmanual reversal in that system; agents don’t auto-undo external state

the cheapest rollback is “throw away the branch.” that’s why step 3’s session branch matters. anything that escaped the branch — pushed commits, MCP-sent messages, deployed artifacts — is no longer a one-command undo.

failure mode: no rollback. you didn’t branch, you didn’t note the pre-run commit, the agent rewrote three files, and now you’re reading diffs to figure out what was yours.

10. stop conditions

decide in advance what makes you kill the run:

a stop condition you didn’t write down is not a stop condition. it’s a vibe.

write them in the prompt or in a scratch note next to the terminal. the point isn’t bureaucracy; it’s that you, not the agent, decide when this is over.


the preflight log

paste this into a scratch file at the start of the session. fill it in as you walk the ten checks. when the run is over, keep the filled log in the repo or a side note — five lines of markdown per session beats trying to remember next week.

session: 2026-mm-dd-<short-task>
head before: <commit sha>

1. version        : claude --version       →
2. model/effort   : /status                →
3. branch/status  : git status -sb         →
4. permissions    : sources + key rules    →
5. MCP servers    : claude mcp list        →
6. context files  : CLAUDE.md / AGENTS.md / skills →
7. output path    : branch + paths + PR    →
8. rollback cmd   :
9. stop conditions:

head after  : <commit sha>
notes       : tokens, elapsed, any tool calls outside scope

if you want the read-only checks in one keystroke, alias the three that are pure shell:

# ~/.zshrc or ~/.bashrc — read-only, no side effects
alias ccpf='claude --version; git status -sb; claude mcp list'

the other six need /status, JSON inspection, or your own judgment. those don’t alias honestly. metadata-only is enough — you don’t need transcripts, you need pointers.


when to skip preflight

short list:

everything else gets the ten checks. a serious agent session is a deploy. nobody deploys on vibes.


AGENTS.md vs CLAUDE.md vs INSTRUCTIONS.md — which instruction file the agent actually reads → AGENTS.md — what to put in the file the agent reads first → best MCP servers for Claude Code — what’s worth wiring, what isn’t → agent failure modes — the wider catalog this preflight prevents → Boris Cherny on Claude Code — the harness perspective → agent verification loop — the post-run companion to this preflight


Topics: claude-code preflight agent-safety mcp permissions