Files
small-scripts/context/claude-profile-modes.md
Paul O'Reilly 143b32597e Add claude-profile engagement mode picker with statusline and session-start integration
- claude-profile: phase 1-3 picker (profile, mode, launch) with preset support,
  dryrun, WezTerm theming, and --append-system-prompt mode body injection
- 5 mode files (chat/quick/deep/hybrid/orch) with YAML frontmatter + prose body;
  new escalates_to field drives statusline →Opus arrow for deep and hybrid
- statusline.sh reads CLAUDE_CONFIG_DIR/active-mode.env to show
  [Sonnet→Opus] deep · topic format when launched via claude-profile
- Root CLAUDE.md session-start: auto-selects project from cwd or CLAUDE_PROJECT
  in active-mode.env, skipping the interactive picker when context is clear
- Spec, tests (37 assertions, 9 test files, all passing), context docs, and
  preset example included

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 00:36:38 +12:00

6.4 KiB

claude-profile engagement modes

Status

Built and tested via dryrun. NOT yet exercised in a real claude launch.

The feature ships as part of scripts/claude-profile (rewritten this session from 104 to ~280 lines). Spec is at specs/claude-profile.spec.md. All 37 dryrun assertions pass via tests/test-claude-profile.sh. Full test suite (tests/run-all.sh) is green: 8 of 8 test files passing.

What was built

Component Path
Spec specs/claude-profile.spec.md
Picker bash scripts/claude-profile
5 mode files data/claude-profile/modes/{chat,quick,deep,hybrid,orch}.md
Preset example data/claude-profile/presets.yaml.example
Test script tests/test-claude-profile.sh

The five modes:

Mode Driver model Async For
chat Haiku (claude-haiku-4-5-20251001) no No project, conversation only
quick Sonnet (claude-sonnet-4-6) no Single small focused job
deep Sonnet yes Hard design/debugging, plan + spec enforced, Opus via named workflows
hybrid Haiku yes Cheap driver, escalates to Opus/Sonnet subagents on demand
orch Sonnet yes Decompose work, dispatch container agents, auto-fires /loop 2m /orchestrate

What is NOT done

  1. Not symlinked into ~/sbin. The new script lives at ~/dev/claude/small-scripts/scripts/claude-profile but is not yet on PATH. To install:
    ln -sf "$HOME/dev/claude/small-scripts/scripts/claude-profile" "$HOME/sbin/claude-profile"
    
  2. Not exercised against real claude. Dryrun confirms the resolved values; an actual launch (e.g. claude-profile oreillyit --mode quick or --mode chat) is the first thing the next session should try.
  3. Presets file not installed. Example template is at data/claude-profile/presets.yaml.example. To use presets, copy to ~/.claude-oreillyit/presets.yaml and edit.
  4. CLAUDE.md does not yet read active-mode.env. When a real launch happens with --project <name>, the existing CLAUDE.md project picker will still appear and the user has to confirm the same project. This is the first follow-up listed below.

How the runtime contract works

  1. claude-profile resolves the profile, mode, and (for some modes) follow-up answers.
  2. Writes $CLAUDE_CONFIG_DIR/active-mode.env with all resolved values (machine-readable, key=value).
  3. Writes $CLAUDE_CONFIG_DIR/last-mode with the mode name (used as picker default next time).
  4. Reads the mode file's body (everything after the YAML frontmatter), appends it to the context-load output, and passes the combined string via --append-system-prompt.
  5. Resolves the mode's driver field through a hardcoded mapping table to a full Claude model ID.
  6. Executes claude --model "<full-model-id>" --append-system-prompt "<combined>" "${pass-through-args[@]}".

The mode file's prose body is what tells the driver model how to behave (escalation rules, plan-mode triggers, async policy, status-line format, on-/clear behaviour). The frontmatter is parsed by bash for the launcher's own decision-making.

Driver mapping (lives in the script as a constant)

Frontmatter driver --model argument
haiku claude-haiku-4-5-20251001
sonnet claude-sonnet-4-6
opus claude-opus-4-6
opus-1m claude-opus-4-6[1m]

When new model versions ship, update the DRIVER_MAP associative array near the top of scripts/claude-profile.

  1. Install the symlink: ln -sf "$HOME/dev/claude/small-scripts/scripts/claude-profile" "$HOME/sbin/claude-profile"
  2. Real-launch test: claude-profile oreillyit --mode chat first (lowest blast radius — Haiku driver, no project, no async). Verify the mode body actually appears in the system prompt and the model behaves per the chat mode rules.
  3. Then --mode quick with a real project to verify the Sonnet driver and the no-async constraints.
  4. Then --mode deep to verify plan-mode auto-engagement and the named-workflow escalation table.
  5. If anything feels off, tests/test-claude-profile.sh is the fast feedback loop — run it after any picker-bash changes.
  6. Once happy with v1, start picking up follow-ups from FUTURE.md (see "Follow-ups" below).

Follow-ups (sequenced)

All in FUTURE.md. Suggested order:

  1. CLAUDE.md project picker integration — read CLAUDE_PROJECT from active-mode.env, skip the duplicate picker. Quick win.
  2. Status-line script: render the mode tag — the user explicitly asked for this; humans need to see the active mode at a glance. Lives in the claude-foundations repo, not small-scripts.
  3. bg-model-call wrapper — referenced by the deep and hybrid modes but not yet built. Own small-scripts entry with its own spec and tests.
  4. switch mode skill — mid-session re-pick. Lower priority; depends on whether mode switching turns out to be common in practice.
  5. MiniMax-driven inverted architecture — biggest item, real research project. Token-budget sketch is the precondition before any code; if savings <30% it's not worth pursuing.

Files touched this session

  • Created: specs/claude-profile.spec.md, data/claude-profile/modes/{chat,quick,deep,hybrid,orch}.md, data/claude-profile/presets.yaml.example, tests/test-claude-profile.sh, context/claude-profile-modes.md (this file)
  • Modified: scripts/claude-profile (rewritten), README.md, CLAUDE.md, FUTURE.md
  • Pruned: 4 reflected session logs from March (memory/log/2026-03-17.*.md and 2026-03-23.123551.md)

Key gotchas to remember

  • read -rp under set -e exits silently if stdin is not a TTY. Always guard interactive reads with [[ -t 0 ]] and provide a default. Without this, --dryrun hangs or silently exits when run from scripts. See memory/gotchas-bash.md for the broader pattern.
  • context-load is on PATH via ~/sbin, not a sibling of claude-profile. The script uses command -v context-load first, with sibling fallback for testing isolation.
  • Use full model IDs, not aliases. The claude-code-guide agent only confirmed sonnet/opus aliases work; haiku is unverified. The mapping table uses full IDs throughout for safety and unambiguous version selection.
  • claude --model is session-scoped. Switching driver mid-session is impossible — it requires a relaunch. The switch mode follow-up works around this by writing a new active-mode.env for the next /clear to pick up.