# How Caveman's Prompt Engineering Layer Works: A Deep Dive into the Three-Component Architecture

> Discover how Caveman's prompt engineering layer works with its three-component architecture. Learn how system prompts, mode tracking, and configuration inject dynamic instructions into Claude.

- Repository: [Julius Brussee/caveman](https://github.com/JuliusBrussee/caveman)
- Tags: deep-dive
- Published: 2026-07-11

---

**Caveman's prompt engineering layer combines a system prompt file (SKILL.md), a mode tracker hook (caveman-mode-tracker.js), and a configuration utility (caveman-config.js) to dynamically inject "caveman" style instructions into Claude's context based on user commands and persist the chosen intensity across session turns.**

Caveman is an open-source Claude Code extension that forces the AI to respond in terse, primitive "caveman" speech. At the heart of this behavior lies a sophisticated **prompt engineering layer** that determines when to activate the persona, how to persist the selected intensity level, and how to safely manage state across conversations. This article examines the exact implementation in the JuliusBrussee/caveman repository, breaking down the three core components that make this stylistic switching possible.

## The Three Core Components of Caveman's Prompt Engineering Layer

### SKILL.md: The Master System Prompt

The foundation of the system resides in [`skills/caveman/SKILL.md`](https://github.com/JuliusBrussee/caveman/blob/main/skills/caveman/SKILL.md), which stores the complete **system prompt** that defines the "caveman" persona. This markdown file contains the core instruction text `Respond terse like smart caveman…` (lines 11-15) and defines intensity levels (lite, full, ultra, wenyan-*) in a structured table (lines 32-41).

The file also implements **Auto-Clarity** rules (lines 58-66) that instruct the model to automatically drop the caveman persona when handling security warnings, irreversible actions, or potentially ambiguous fragmented sentences. When the hook injects the skill, the entire file content is sent as hidden system context, ensuring the model understands both the persona constraints and the safety exceptions.

### caveman-mode-tracker.js: The User Prompt Parser

The dynamic switching logic lives in [`src/hooks/caveman-mode-tracker.js`](https://github.com/JuliusBrussee/caveman/blob/main/src/hooks/caveman-mode-tracker.js), a UserPromptSubmit hook that parses every user prompt to detect mode changes. It normalizes incoming text to lowercase and collapses whitespace (line 32), then checks against **deactivation regexes** (lines 34-46) for phrases like "stop caveman" or "normal mode", and **activation regexes** (lines 59-65) for commands like "/caveman" or natural language "turn on caveman".

When a mode is resolved, the hook calls `safeWriteFlag(flagPath, mode)` (line 68) to persist the selection to `$CLAUDE_CONFIG_DIR/.caveman-active`, and `recordModeChange()` (line 47) for analytics tracking. It also emits a structured reminder `CAVEMAN MODE ACTIVE (<mode>)…` (lines 93-99) that reinforces the current style for that specific turn.

### caveman-config.js: Safe State Management

The persistence layer is handled by [`src/hooks/caveman-config.js`](https://github.com/JuliusBrussee/caveman/blob/main/src/hooks/caveman-config.js), which provides the **resolution order** for default modes and implements **symlink-safe flag handling**. The default mode follows this priority chain: environment variable → repo-local config → user config → `'full'` (lines 4-16).

The module exposes `VALID_MODES` and `getDefaultMode()` for validation, but its critical feature is the `safeWriteFlag` implementation. This function creates a temporary file and renames it atomically (lines 81-92) while explicitly refusing symlinks (lines 43-56), preventing race conditions and path traversal vulnerabilities when writing to the flag file.

## How the Components Interact During a Session

### Session Initialization

When a Claude session begins, the **SessionStart** hook ([`caveman-activate.js`](https://github.com/JuliusBrussee/caveman/blob/main/caveman-activate.js)) writes the default mode to the flag file and injects the full [`SKILL.md`](https://github.com/JuliusBrussee/caveman/blob/main/SKILL.md) content once as hidden context. This ensures the model knows the baseline style before processing any user prompts.

### Per-Turn Processing and Mode Switching

For every subsequent user prompt, [`caveman-mode-tracker.js`](https://github.com/JuliusBrussee/caveman/blob/main/caveman-mode-tracker.js) executes its detection logic. If the user types "/caveman lite" or "less tokens", the hook updates the flag file with the new intensity level. The skill is **re-injected** every turn via the reinforcement block, with `readFlag(flagPath)` determining which intensity rules from the table in [`SKILL.md`](https://github.com/JuliusBrussee/caveman/blob/main/SKILL.md) apply to the current response.

### One-Shot Independent Modes

Commands such as `/caveman-commit`, `/caveman-review`, and `/caveman-compress` are treated as **independent** modes. When invoked, the tracker temporarily saves the current prose mode to `*.caveman-active.prev*` (lines 41-45) before executing the one-shot command, then restores the previous mode after completion (lines 76-90). This allows task-specific caveman styling without losing your session's prose settings.

## Security and Auto-Clarity Features

The **Auto-Clarity** section within [`SKILL.md`](https://github.com/JuliusBrussee/caveman/blob/main/SKILL.md) (lines 58-66) acts as a critical safety guardrail. These rules tell the model to automatically disable the caveman persona for security warnings or irreversible actions. Unlike the mode tracker, which handles explicit user commands, the model obeys these rules directly from the system prompt, ensuring critical information is never obscured by the terse style.

## Practical Usage Examples

Activate caveman with default intensity or a specific level:

```bash

# Activate default (full) intensity

/caveman

# Activate lighter compression

/caveman lite

# Turn off caveman mode

stop caveman

```

Query the current mode programmatically:

```javascript
const { readFlag } = require('./caveman-config');
const path = require('path');

const mode = readFlag(path.join(process.env.CLAUDE_CONFIG_DIR || '~/.claude', '.caveman-active'));
if (mode) {
  console.log(`Current caveman mode: ${mode}`);
}

```

Use one-shot commands for specific tasks:

```bash

# Generate a commit message in caveman style, then return to previous mode

/caveman-commit

```

## Summary

- **Three-component architecture**: [`SKILL.md`](https://github.com/JuliusBrussee/caveman/blob/main/SKILL.md) defines the persona, [`caveman-mode-tracker.js`](https://github.com/JuliusBrussee/caveman/blob/main/caveman-mode-tracker.js) parses user commands, and [`caveman-config.js`](https://github.com/JuliusBrussee/caveman/blob/main/caveman-config.js) manages safe state persistence.
- **Atomic persistence**: Mode state is stored in `$CLAUDE_CONFIG_DIR/.caveman-active` using atomic file writes with symlink protection to prevent security vulnerabilities.
- **Natural language support**: The regex-based parser handles both explicit slash commands and natural phrases like "turn on caveman" or "normal mode".
- **One-shot safety**: Independent commands like `/caveman-commit` save and restore your previous mode, ensuring temporary tasks don't alter your session context.
- **Built-in safety**: Auto-Clarity rules in the system prompt automatically disable the persona for security-critical outputs without requiring explicit user intervention.

## Frequently Asked Questions

### How does Caveman detect when to switch modes?

The [`caveman-mode-tracker.js`](https://github.com/JuliusBrussee/caveman/blob/main/caveman-mode-tracker.js) hook normalizes each user prompt to lowercase and spaces, then checks it against regex patterns for activation phrases (like "/caveman" or "less tokens") and deactivation phrases (like "stop caveman"). When matched, it calls `safeWriteFlag()` to update the state file and emits a structured reminder to the model.

### What intensity levels does Caveman support?

According to [`SKILL.md`](https://github.com/JuliusBrussee/caveman/blob/main/SKILL.md) and [`caveman-config.js`](https://github.com/JuliusBrussee/caveman/blob/main/caveman-config.js), Caveman supports four primary intensity levels: `lite`, `full`, `ultra`, and wenyan variants (`wenyan-lite`, etc.). The `VALID_MODES` constant enforces these values, and the default resolves to `full` unless overridden by environment variables or configuration files.

### Is the mode flag file secure against symlink attacks?

Yes. The `safeWriteFlag()` function in [`caveman-config.js`](https://github.com/JuliusBrussee/caveman/blob/main/caveman-config.js) explicitly refuses symlinks (lines 43-56) and performs atomic writes by creating a temporary file and renaming it (lines 81-92). This prevents race conditions and ensures malicious symlinks cannot redirect writes to sensitive system locations.

### How does Caveman handle one-shot commands like /caveman-commit?

For independent modes, the tracker saves the current prose mode to a `.caveman-active.prev` backup file before executing the one-shot command. After the task completes, it automatically restores the previous mode from that backup, ensuring your session's style settings remain intact.