How the `/caveman` Command Persists Mode Across Session Turns
TLDR: The /caveman command persists its intensity mode across Claude session turns by atomically writing the selected mode to a hidden flag file at ~/.claude/.caveman-active and restoring it via the mode-tracker hook on every subsequent request.
The JuliusBrussee/caveman repository implements a file-based persistence layer that allows the caveman intensity level to survive across multiple turns of a Claude conversation. Unlike ephemeral in-memory storage, this mechanism ensures your selected mode—whether lite, full, or ultra—remains active until explicitly changed.
Where the Mode Is Stored
The Flag File Location and Format
Persistence relies on a single hidden flag file located at $CLAUDE_CONFIG_DIR/.caveman-active, which typically resolves to ~/.claude/.caveman-active on Unix systems. This file contains only the raw mode string (for example, full or wenyan-ultra) with no additional metadata or JSON wrapping.
Core I/O Functions in caveman-config.js
All read and write operations are centralized in src/hooks/caveman-config.js. The safeWriteFlag function handles atomic writes with restrictive permissions, while readFlag performs symlink-safe reads with validation.
// From src/hooks/caveman-config.js
function safeWriteFlag(flagPath, content) {
// Writes atomically, refuses symlinks, sets 0600 permissions
}
function readFlag(flagPath) {
// Symlink-safe, size-capped at 64 bytes, validates against VALID_MODES
}
The write operation uses atomic file operations to prevent corruption during concurrent access, and the read operation enforces a 64-byte size limit—sufficient for the longest valid mode string (wenyan-ultra) while preventing buffer overflow attacks.
How /caveman Updates the Persisted State
When you issue /caveman <mode> in the Claude interface, the caveman skill (documented in skills/caveman/README.md) invokes safeWriteFlag with the requested mode. If you omit the argument, the system calls getDefaultMode() to resolve the default from environment variables, repository configuration, or user settings, ultimately falling back to 'full'.
// Internally triggered by: /caveman ultra
safeWriteFlag(path.join(claudeDir, '.caveman-active'), 'ultra');
This write occurs immediately upon command execution, ensuring the flag file always reflects the most recent user preference regardless of how the session terminates.
Restoring Mode Across Session Turns
The Mode-Tracker Hook Implementation
Every request flowing through the Claude tooling passes through the mode-tracker hook defined in src/hooks/caveman-mode-tracker.js. This hook executes automatically at the start of each turn, reading the flag file and injecting the mode into the request object.
// From src/hooks/caveman-mode-tracker.js
const flagPath = path.join(claudeDir, '.caveman-active');
const mode = readFlag(flagPath);
if (mode) {
request.cavemanMode = mode; // Accessible to downstream hooks
}
// If changed during this turn, log the transition
recordModeChange(claudeDir, newMode);
Because the flag file lives on the local filesystem, the same value persists across process restarts, containerized environments, and multi-day sessions. The hook essentially rehydrates the session state from disk on every interaction.
Security Safeguards for File-Based Persistence
The persistence mechanism implements multiple hardening measures to prevent privilege escalation or data exfiltration:
- Symlink protection: Both
safeWriteFlagandreadFlagreject symbolic links, preventing attackers from redirecting reads to sensitive files like/etc/shadowor writes to system directories. - Size enforcement: The 64-byte cap in
readFlagprevents reading arbitrary large files if a symlink bypass were ever successful. - Ownership verification: When the parent directory is a symlink, the code verifies the real path's ownership matches the current user (via Unix uid or Windows home-directory checks).
- Permission restrictions:
safeWriteFlagcreates files with0600permissions, ensuring only the owner can read the current mode setting.
These safeguards ensure that caveman command persistence cannot be hijacked to access unauthorized system resources.
Statistics and Mode Change Tracking
The system maintains an audit trail of mode transitions. Whenever recordModeChange detects a mode switch, it appends a JSON line to $CLAUDE_CONFIG_DIR/.caveman-mode-log.jsonl. The stats hook (src/hooks/caveman-stats.js) later consumes this log to attribute token usage statistics to the correct mode, even if the active flag has been overwritten multiple times during the session.
// Mode changes are logged for analytics
recordModeChange(claudeDir, newMode); // Writes to .caveman-mode-log.jsonl
This separation of concerns—current state in .caveman-active and historical data in .caveman-mode-log.jsonl—allows accurate reporting without interfering with the lightweight persistence mechanism.
Summary
- The
/cavemancommand writes the selected mode to$CLAUDE_CONFIG_DIR/.caveman-activeusing the atomicsafeWriteFlagfunction. - Each session turn restores the mode via
readFlaginsrc/hooks/caveman-mode-tracker.js, injecting the value intorequest.cavemanMode. - Security measures include symlink rejection, 64-byte size caps, and
0600file permissions. - Mode transitions are logged to
.caveman-mode-log.jsonlfor statistical analysis bysrc/hooks/caveman-stats.js. - The persistence works across process restarts because state is maintained on the filesystem, not in memory.
Frequently Asked Questions
Where is the caveman mode stored between session turns?
The mode is stored in a hidden flag file at $CLAUDE_CONFIG_DIR/.caveman-active (typically ~/.claude/.caveman-active). This file contains only the raw mode string and is read by the mode-tracker hook at the start of every turn to restore the previous session state.
How does the mode-tracker hook restore the caveman setting?
The hook located in src/hooks/caveman-mode-tracker.js calls readFlag to check the flag file on disk. If a valid mode is present, it assigns the value to request.cavemanMode, making it available to downstream processing hooks like compression and statistics.
What happens if I switch modes mid-session?
When you issue a new /caveman command, safeWriteFlag immediately overwrites .caveman-active with the new mode. The recordModeChange function also appends the transition to .caveman-mode-log.jsonl, allowing the stats hook to accurately attribute token usage to the correct mode for that specific turn.
Is the persistence mechanism secure against symlink attacks?
Yes. Both safeWriteFlag and readFlag in src/hooks/caveman-config.js explicitly reject symbolic links. Additionally, the read operation enforces a 64-byte size limit and verifies directory ownership when symlinks are present in the path, preventing unauthorized file access or data exfiltration.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →