---
title: "Doctor"
description: "OrchestKit doctor for health diagnostics across manifest integrity, hook configuration, skill validation, agent frontmatter, MCP server connectivity, CC version compatibility, and permission rules. Reports issues with severity levels and auto-remediation suggestions. Validates component counts, detects orphaned entries, and checks CC version matrix compliance. Use when diagnosing plugin health, troubleshooting configuration issues, or running pre-release checks."
---

<span className="badge badge-blue">Command</span> <span className="badge badge-green">low</span>

```bash title="Invoke"
/ork:doctor
```

<ContextualSkillSidebar slug="doctor" />


# OrchestKit Health Diagnostics

## Argument Resolution

```python
FLAGS = "$ARGUMENTS"         # Full argument string, e.g., "--verbose" or "--json"
FLAG = "$ARGUMENTS[0]"       # First token: -v, --verbose, --json, --category=X
# $ARGUMENTS[0], $ARGUMENTS[1] for indexed access (CC 2.1.59)
```

## STEP 0: Choose Scope (AskUserQuestion — M118 #1464)

A full doctor run takes ~20s. Most invocations only need one slice. Ask the user up-front so voice-flow shortcuts ("just the MCPs") map cleanly:

```python
# Skip the prompt when an explicit scope arg or env override is present:
#   /ork:doctor cc      → skip, use cc-only
#   /ork:doctor mcp     → skip, use mcp-only
#   /ork:doctor plugin  → skip, use plugin-only
#   ORK_DOCTOR_SCOPE=all (or any of the above) → skip, use the env value
#
# Otherwise, ask:
AskUserQuestion(questions=[{
  "question": "What should doctor check?",
  "header": "Scope",
  "options": [
    {"label": "Everything (default)", "description": "Full system health — ~20s; runs all 14 categories"},
    {"label": "CC version & features only", "description": "Categories 10 + 13 + 14; ~3s — for 'is my CC up to date?'"},
    {"label": "MCP servers only", "description": "Category 12 (incl. pinning sub-check); ~5s — for 'are MCPs working?'"},
    {"label": "Plugin health only", "description": "Categories 0-3 + 5 (skills, agents, hooks, build); ~8s — for 'after npm run build'"}
  ]
}])
```

Skip the prompt entirely when the scope is unambiguous from the invocation. The fast scopes (3-8s) are 3-7× faster than the full run — voice users say "just the MCPs" and get a 5s answer.

## Overview

The `/ork:doctor` command performs comprehensive health checks on your OrchestKit installation. It auto-detects installed plugins and validates 14 categories:

1. **Installed Plugins** - Detects ork plugin
2. **Skills Validation** - Frontmatter, references, token budget (dynamic count)
3. **Agents Validation** - Frontmatter, tool refs, skill refs (dynamic count)
4. **Hook Health** - Registration, bundles, async patterns
5. **Permission Rules** - Detects unreachable rules
6. **Schema Compliance** - Validates JSON files against schemas
7. **Coordination System** - Checks lock health and registry integrity
8. **Context Budget** - Monitors token usage against budget
9. **Memory System** - Graph memory health
10. **Claude Code Version & Channel** - Validates CC >= 2.1.111, detects release channel (stable/beta/alpha), recommends 2.1.111+ for `xhigh` effort, `/ultrareview`, stream-json `plugin_errors`
11. **External Dependencies** - Checks optional tool availability (agent-browser)
12. **MCP Status** - Active vs disabled vs misconfigured, API key presence for paid MCPs. CC 2.1.110: detects duplicate definitions across config scopes. Sub-check warns when HIGH-tier servers resolve to `@latest` in `.mcp.json` (closes #1462)
13. **Plugin Validate** - Runs `claude plugin validate` for official CC frontmatter + hooks.json validation (CC >= 2.1.77)
14. **Effort/Model Compatibility** - Warns when `xhigh` effort is requested without Opus 4.7 (silent fallback otherwise)

## When to Use

- After installing or updating OrchestKit
- When hooks aren't firing as expected
- Before deploying to a team environment
- When debugging coordination issues
- After running `npm run build`

## Quick Start

```bash
/ork:doctor           # Standard health check
/ork:doctor -v        # Verbose output
/ork:doctor --json    # Machine-readable for CI
```

## CLI Options

| Flag | Description |
|------|-------------|
| `-v`, `--verbose` | Detailed output per check |
| `--json` | JSON output for CI integration |
| `--category=X` | Run only specific category |

## Health Check Categories

> **Detailed check procedures**: Load `Read("$\{CLAUDE_SKILL_DIR\}/rules/diagnostic-checks.md")` for bash commands and validation logic per category.
>
> **MCP-specific checks**: Load `Read("$\{CLAUDE_SKILL_DIR\}/rules/mcp-status-checks.md")` for credential validation and misconfiguration detection.
>
> **Output examples**: Load `Read("$\{CLAUDE_SKILL_DIR\}/references/health-check-outputs.md")` for sample output per category.

### Categories 0-3: Core Validation

| Category | What It Checks | Reference |
|----------|---------------|-----------|
| **0. Installed Plugins** | Auto-detects ork plugin, counts skills/agents | load `$\{CLAUDE_SKILL_DIR\}/rules/diagnostic-checks.md` |
| **1. Skills** | Frontmatter, context field, token budget, links | load `$\{CLAUDE_SKILL_DIR\}/references/skills-validation.md` |
| **2. Agents** | Frontmatter, model, skill refs, tool refs | load `$\{CLAUDE_SKILL_DIR\}/references/agents-validation.md` |
| **3. Hooks** | hooks.json schema, bundles, async patterns | load `$\{CLAUDE_SKILL_DIR\}/references/hook-validation.md` |

### Categories 4-5: System Health

| Category | What It Checks | Reference |
|----------|---------------|-----------|
| **4. Memory** | .claude/memory/ exists, decisions.jsonl integrity, queue depth | load `$\{CLAUDE_SKILL_DIR\}/references/memory-health.md` |
| **5. Build** | plugins/ sync with src/, manifest counts, orphans | load `$\{CLAUDE_SKILL_DIR\}/rules/diagnostic-checks.md` |

### Categories 6-9: Infrastructure

| Category | What It Checks |
|----------|---------------|
| **6. Permission Rules** | Unreachable rules detection |
| **7. Schema Compliance** | JSON files against schemas |
| **8. Coordination** | Multi-worktree lock health, stale locks, sparse paths config |
| **9. Context Budget** | Token usage against budget |

### Categories 10-14: Environment

| Category | What It Checks | Reference |
|----------|---------------|-----------|
| **10. CC Version & Channel** | Runtime version against minimum required, release channel (stable/beta/alpha) | load `$\{CLAUDE_SKILL_DIR\}/references/version-compatibility.md` |
| **11. External Deps** | Optional tools (agent-browser, portless) | load `$\{CLAUDE_SKILL_DIR\}/rules/diagnostic-checks.md` |
| **12. MCP Status** | Enabled/disabled state, credential checks, **HIGH-tier `@latest` pinning warn** | load `$\{CLAUDE_SKILL_DIR\}/rules/mcp-status-checks.md` + `$\{CLAUDE_SKILL_DIR\}/references/mcp-pinning-check.md` |
| **13. Plugin Validate** | Official CC frontmatter + hooks.json validation (CC >= 2.1.77) | load `$\{CLAUDE_SKILL_DIR\}/rules/diagnostic-checks.md` |
| **14. Effort/Model** | Detects `xhigh` effort configured without Opus 4.7 — see below | inline |

### Category 14: Effort/Model Compatibility (CC 2.1.111+)

CC 2.1.111 added `xhigh` effort (Opus 4.7 only). Using it with any other model silently falls back to `high` — producing no error but losing the extra deepening pass documented in the affected skills.

**Detection**:
- If the active model is NOT Opus 4.7, check whether `/effort` is set to `xhigh`:
  - Read `.claude/settings.json` → `effort` field
  - Read `$ORCHESTKIT_EFFORT` env var (populated by the effort-detector hook)
- Check for any skill invocation under `.claude/chain/*.json` that explicitly set `effort: xhigh` with a non-4.7 model in scope

**Warning format**:
```
WARNING: xhigh effort requires Opus 4.7.
  Current model: <model-id>
  Configured effort: xhigh
  Impact: Skills fall back to high — xhigh's extra deepening pass is lost silently.
  Fix: Either switch to Opus 4.7 (`claude --model opus-4.7`) or lower effort to `high`.
```

**Exit code**: Non-zero in `--json` mode; soft warning in interactive mode.

## Report Format

> Load `Read("$\{CLAUDE_SKILL_DIR\}/references/report-format.md")` for ASCII report templates, JSON CI output schema, and exit codes.

## Interpreting Results & Troubleshooting

> Load `Read("$\{CLAUDE_SKILL_DIR\}/references/remediation-guide.md")` for the full results interpretation table and troubleshooting steps for common failures (skills validation, build sync, memory).

### After you fix an issue

> **CC 2.1.69+**: Run `/reload-plugins` to activate plugin changes in the current session without restarting.
>
> **CC 2.1.116+**: `/reload-plugins` and background plugin auto-update now **auto-install missing plugin dependencies** from marketplaces you've already added. If `ork:doctor` flagged a plugin-load failure due to a missing dep, `/reload-plugins` resolves it in place — no manual `plugin install` step needed.

## Related Skills

- `ork:configure` - Configure plugin settings
- `ork:quality-gates` - CI/CD integration
- `security-scanning` - Comprehensive audits

## References

Load on demand with `Read("$\{CLAUDE_SKILL_DIR\}/references/&lt;file&gt;")` or `Read("$\{CLAUDE_SKILL_DIR\}/rules/&lt;file&gt;")`:
| File | Content |
|------|---------|
| `rules/diagnostic-checks.md` | Bash commands and validation logic per category |
| `rules/mcp-status-checks.md` | Credential validation and misconfiguration detection |
| `references/remediation-guide.md` | Results interpretation and troubleshooting steps |
| `references/health-check-outputs.md` | Sample output per category |
| `references/skills-validation.md` | Skills frontmatter and structure checks |
| `references/agents-validation.md` | Agents frontmatter and tool ref checks |
| `references/hook-validation.md` | Hook registration and bundle checks |
| `references/memory-health.md` | Memory system integrity checks |
| `references/permission-rules.md` | Permission rule detection |
| `references/schema-validation.md` | JSON schema compliance |
| `references/report-format.md` | ASCII report templates and JSON CI output |
| `references/version-compatibility.md` | CC version and channel validation |
| `references/mcp-pinning-check.md` | HIGH-tier MCP `@latest` warning logic + tier source-of-truth |


---

## Rules (2)

### Diagnostic Checks — CRITICAL


# Diagnostic Check Procedures

Detailed procedures for each health check category in `/ork:doctor`.

---

**Incorrect:**
```
✓ Plugins OK    (no actual validation — just assumed healthy)
```

**Correct:**
```
✓ Skills: 69/69 valid (frontmatter, token budget, links)
✗ Hooks: dist/memory-writer.mjs missing — run: cd src/hooks && npm run build
✓ Agents: 38/38 CC 2.1.6 compliant
```

## 0. Installed Plugins Detection

Auto-detects which OrchestKit plugins are installed:

```bash
# Detection logic:
# - Scans for .claude-plugin/plugin.json in plugin paths
# - Identifies ork plugin
# - Counts skills/agents per installed plugin
```

---

## 1. Skills Validation

Validates skills in installed plugins (count varies by installation):

```bash
# Checks performed:
# - SKILL.md frontmatter (name, description, user-invocable)
# - context: fork field (required for CC 2.1.0+)
# - Token budget compliance (300-5000 tokens)
# - Internal link validation (references/ paths)
# - Related Skills references exist
```

---

## 2. Agents Validation

Validates agents in installed plugins:

```bash
# Checks performed:
# - Frontmatter fields (name, description, model, tools, skills)
# - Model validation (opus, sonnet, haiku only)
# - Skills references exist in src/skills/
# - Tools are valid CC tools
```

---

## 3. Hook Health

Verifies hooks are properly configured:

```bash
# Checks performed:
# - hooks.json schema valid
# - Bundle files exist (12 .mjs bundles)
# - Async hooks use fire-and-forget pattern (9 async)
# - Background hook metrics health (Issue #243)
# - Windows-safe spawning (PR #645)
```

---

## 4. Memory System

Validates graph memory with file-level integrity checks:

```bash
# Automated checks:
# - Graph: .claude/memory/ exists, decisions.jsonl valid JSONL, queue depth

# Run these commands to gather memory health data:
wc -l .claude/memory/decisions.jsonl 2>/dev/null || echo "No decisions yet"
wc -l .claude/memory/graph-queue.jsonl 2>/dev/null || echo "No graph queue"
ls -la .claude/memory/ 2>/dev/null || echo "Memory directory missing"
```

Read `.claude/memory/decisions.jsonl` directly to validate JSONL integrity (each line must parse as valid JSON). Count total lines, corrupt lines, and report per-category breakdown.

See [Memory Health](../references/memory-health.md) for details.

---

## 5. Build System

Verifies plugins/ sync with src/:

```bash
# Checks performed:
# - plugins/ generated from src/
# - Manifest counts match actual files
# - No orphaned skills/agents
```

---

## 6. Permission Rules

Leverages CC 2.1.3's unreachable permission rules detection.

---

## 7. Schema Compliance

Validates JSON files against schemas.

---

## 8. Coordination System

Checks multi-worktree coordination health (active instances, stale locks).

---

## 9. Context Budget

Monitors token usage against budget.

---

## 10. Claude Code Version

Validates runtime version against the [Version Compatibility Matrix](../references/version-compatibility.md).

---

## 11. External Dependencies

Checks optional tool availability:

```bash
# agent-browser (vercel-labs/agent-browser)
# Prefer the structured `agent-browser doctor --json` from 0.26.0+ (CC 2.1.121+).
# Falls back to the fuzzy "is the binary on PATH + symlink present?" probe on older versions.
if command -v agent-browser >/dev/null 2>&1; then
  if agent-browser doctor --json >/tmp/ab-doctor.json 2>/dev/null; then
    # Structured snapshot: surface only high-severity issues + a one-line health summary.
    jq -r '
      "agent-browser: " +
      (if (.daemon.status // "unknown") == "running" then "OK" else "DEGRADED" end) +
      " (chrome=" + (.chrome.version // "?") +
      ", net=" + (if .network.reachable then "✓" else "✗" end) + ")"
    ' /tmp/ab-doctor.json
    # Promote any high-severity issue into doctor's findings stream.
    jq -r '.issues[]? | select(.severity == "high") | "  ↳ HIGH: " + .message' /tmp/ab-doctor.json
  else
    # Fallback for agent-browser < 0.26 (no `doctor` subcommand)
    test -L "$HOME/.claude/skills/agent-browser" \
      && echo "agent-browser: installed (legacy probe — upgrade to 0.26+ for structured doctor)" \
      || echo "agent-browser: SYMLINK MISSING at ~/.claude/skills/agent-browser"
  fi
else
  echo "agent-browser: NOT INSTALLED (optional — install via vercel-labs/agent-browser ≥ 0.26)"
fi

# portless: stable named localhost URLs for local dev
#   which portless 2>/dev/null && portless list 2>/dev/null
#   If missing: RECOMMEND "npm i -g portless" for stable local dev URLs
#   If installed but not running: WARN "portless is installed but no services registered"

# tailscale (M127 #1561): only relevant if user has used /ork:dev --share / --funnel / --live.
# Detected by inspecting .claude/state/dev-stack.json for share != null.
#   if [[ -f .claude/state/dev-stack.json ]] && jq -e '.share != null' .claude/state/dev-stack.json >/dev/null 2>&1; then
#     command -v tailscale >/dev/null 2>&1 \
#       && echo "tailscale: OK (share mode in use: $(jq -r '.share.mode' .claude/state/dev-stack.json))" \
#       || echo "tailscale: SHARE MODE ACTIVE BUT TAILSCALE CLI MISSING (Install: brew install tailscale)"
#   fi

# Live demos older than 24h (M127 #1565): warns about sprawl from /ork:dev --live.
#   live_log=".claude/state/live-demos.jsonl"
#   if [[ -f "$live_log" ]]; then
#     now_ts=$(date -u +%s)
#     while IFS= read -r line; do
#       expires=$(printf '%s' "$line" | jq -r '.expiresAt // empty')
#       [[ -z "$expires" ]] && continue
#       expires_ts=$(date -j -u -f '%Y-%m-%dT%H:%M:%SZ' "$expires" +%s 2>/dev/null \
#                  || date -u -d "$expires" +%s 2>/dev/null)
#       if [[ -n "$expires_ts" && "$expires_ts" -lt "$now_ts" ]]; then
#         age_h=$(( (now_ts - expires_ts) / 3600 ))
#         echo "live demo: EXPIRED ${age_h}h ago — branch=$(printf '%s' "$line" | jq -r '.branch')"
#       fi
#     done < "$live_log"
#   fi
```

**Why structured doctor**: agent-browser 0.26.0 added `doctor --json` returning a snapshot of `chrome`, `daemon`, `network`, `config`, `security`, and `providers`. Wiring it in turns the previous "agent-browser broken" failure into actionable per-subsystem findings (Chrome version, daemon status, network reachability, high-severity issues), unblocking debug sessions where the user can't tell us what's wrong.

---

## 13. Plugin Validate (CC >= 2.1.77)

Runs `claude plugin validate` for official CC validation of frontmatter and hooks.json. This complements OrchestKit's custom checks (categories 1-3) with CC's built-in validator.

```bash
# Check CC version supports plugin validate (>= 2.1.77)
# If CC < 2.1.77, skip with: "Plugin validate: SKIPPED (requires CC >= 2.1.77)"

# Run official validation from plugin root
claude plugin validate

# Checks performed by CC:
# - SKILL.md frontmatter schema (required fields, types, allowed values)
# - hooks.json schema (event types, matchers, command paths)
# - Agent frontmatter schema (model, tools, skills fields)
# - File path resolution (command paths in hooks exist)
```

**Relationship to OrchestKit checks:** `claude plugin validate` performs structural/schema validation at the CC level. OrchestKit's categories 1-3 perform deeper semantic checks (token budgets, cross-references, async patterns) that CC does not cover. Both should pass for a fully healthy plugin.

---

## 14. Stale Project State (CC >= 2.1.126, #1582, fixed in #1587)

CC 2.1.126 added `claude project purge [path]` — deletes all CC state (transcripts, tasks, file history, config entry) for a project. Surface this as an info-severity diagnostic when canonical project paths no longer exist on disk.

```bash
# Check CC version supports project purge (>= 2.1.126)
# If CC < 2.1.126, skip silently (suggestion would be unactionable)

# Detect stale project state via the authoritative source.
# Use `claude project purge --dry-run --all` because the directory-name encoding
# under ~/.claude/projects/ is lossy (both `/` and `.` collapse to `-`, so the
# original path cannot be reconstructed deterministically — `my-project` is
# indistinguishable from `my.project` or `my/project`). The CLI's dry-run
# output emits canonical paths from ~/.claude.json which IS lossless.
#
#   claude project purge --dry-run --all 2>/dev/null \
#     | grep -oE 'projects\["[^"]+"\]' \
#     | sed -E 's/^projects\["//; s/"\]$//' \
#     | while IFS= read -r p; do
#         [ -n "$p" ] && [ ! -d "$p" ] && echo "$p"
#       done
#
# Example output (info severity, never blocking):
# ℹ Stale project state: 3 canonical paths reference directories that no longer exist on disk.
#    Suggested cleanup (always preview first):
#      claude project purge --dry-run --all
#      claude project purge --interactive    # confirm each project
```

**Why info, never warn or fail:** the user may have moved a project rather than deleted it; aggressive removal would lose transcript history. Always recommend `--dry-run` first. Mirrors the pattern from `claude plugin prune` (Category 13b).

**Why not parse `~/.claude/projects/` directly:** the directory naming is a lossy collapse of the original path (`/` and `.` both become `-`). A naive `sed 's|-|/|g'` decode produces ambiguous results — `~/.claude/projects/Users-me-my-project` could be `/Users/me/my-project`, `/Users/me/my/project`, `/Users/me/my.project`, or other combinations. The dry-run output above is the canonical source.


### MCP Status Checks — HIGH


# MCP Status Checks

Validates `.mcp.json` entries for enabled/disabled state and required credentials.

## Check Procedure

```bash
# Checks performed:
# - Parse .mcp.json, list each server with enabled/disabled state
# - For tavily: check TAVILY_API_KEY env var OR op CLI availability
# - For memory: check MEMORY_FILE path is writable
# - For agentation: check agentation-mcp package is installed (npx --yes dry-run)
# - Flag any enabled MCP whose process would likely fail at startup
# - HIGH-tier @latest pinning: see references/mcp-pinning-check.md
#   (script: scripts/check-mcp-pinning.sh — exit 1 on HIGH-tier @latest)
# - alwaysLoad audit (CC 2.1.121+, #1541): warn when memory, context7, or
#   sequential-thinking lack `"alwaysLoad": true` — these are universally
#   used and per-skill ToolSearch probes are wasted work without it.
#   Skip the warning on CC < 2.1.121 (key would be silently ignored).
# - claude plugin orphans (CC 2.1.121+, #1544): suggest `claude plugin prune`
#   when `claude plugin list --json` shows orphaned auto-installed deps.
```

**Incorrect:**
```
MCP Servers: all OK
```

**Correct:**
```
MCP Servers:
- context7:  enabled  ✓
- tavily:    enabled  ✗  TAVILY_API_KEY not set — will fail at startup
```

## Output Examples

**Healthy:**
```
MCP Servers:
- context7:           enabled  ✓
- memory:             enabled  ✓
- sequential-thinking: disabled ○
- tavily:             disabled ○  (enable: set TAVILY_API_KEY, see /ork:configure)
- agentation:         disabled ○
```

**Misconfigured (Tavily enabled but no key):**
```
MCP Servers:
- context7:           enabled  ✓
- memory:             enabled  ✓
- tavily:             enabled  ✗  TAVILY_API_KEY not set — MCP will fail at startup
                                  Fix: set TAVILY_API_KEY or set "disabled": true in .mcp.json
```

**Misconfigured (agentation enabled but not installed):**
```
MCP Servers:
- agentation:         enabled  ✗  agentation-mcp package not found
                                  Fix: npm install -D agentation-mcp  or  set "disabled": true
```



---

## References (11)

### Agents Validation

# Agents Validation

## Overview

OrchestKit includes 30 specialized agents validated against CC 2.1.69 frontmatter format.

## Agent Structure

```
src/agents/
├── backend-system-architect.md
├── code-quality-reviewer.md
├── frontend-ui-developer.md
└── ... (38 total)
```

## Validation Checks

### 1. Frontmatter Fields

Required fields:
- `name` - Agent identifier (used in Task subagent_type)
- `description` - Purpose and auto-mode keywords
- `model` - opus, sonnet, or haiku
- `tools` - Array of allowed CC tools
- `skills` - Array of skill names to auto-inject

Optional fields:
- `context` - fork or inherit
- `color` - Display color
- `hooks` - Agent-specific hooks

### 2. Model Validation

Only valid models:

```bash
# Check model values
grep "^model:" src/agents/*.md | sort | uniq -c
```

Expected: opus, sonnet, haiku

### 3. Skills References

All skills in agent frontmatter must exist:

```bash
# Check skill references
for agent in src/agents/*.md; do
  grep -A100 "^skills:" "$agent" | grep "^  - " | \
    sed 's/.*- //' | while read skill; do
      [ -d "src/skills/$skill" ] || echo "Missing: $agent -> $skill"
    done
done
```

### 4. Tools Validation

Valid CC tools:
- Bash, Read, Write, Edit, MultiEdit
- Grep, Glob
- Task, Skill
- WebFetch, WebSearch
- NotebookEdit
- AskUserQuestion
- TaskCreate, TaskUpdate, TaskGet, TaskList

## Quick Validation

```bash
# Run full agent validation
npm run test:agents

# Or directly
./tests/agents/test-agent-frontmatter.sh
```

## Common Issues

### Invalid model

```yaml
model: sonnet  # Valid: opus, sonnet, haiku
```

### Missing skill reference

Ensure skill exists in `src/skills/` directory.

### Invalid tool name

Check tool spelling matches CC tool names exactly.

## Agent Registration Check (CC 2.1.50+)

Run `claude agents` to list all registered agents and compare against the expected count from manifests.

**Gate:** Only run if CC >= 2.1.50 (feature: `claude_agents_cli`). Skip with a note if version is older.

```bash
# Check registered agent count matches expected
expected_count=$(grep -c '"agents/' manifests/ork.json 2>/dev/null || echo 0)
registered_count=$(claude agents 2>/dev/null | wc -l | tr -d ' ')

if [ "$registered_count" -ne "$expected_count" ]; then
  echo "WARN: Agent count mismatch — expected $expected_count, got $registered_count"
  # List missing agents for investigation
  claude agents 2>/dev/null | sort > /tmp/ork-registered.txt
  ls src/agents/*.md 2>/dev/null | xargs -I{} basename {} .md | sort > /tmp/ork-expected.txt
  echo "Missing agents:"
  comm -23 /tmp/ork-expected.txt /tmp/ork-registered.txt
fi
```

**Check:** `claude agents | wc -l` should match expected agent count (38).

## Model Routing

See [docs/model-routing.md](../../../../docs/model-routing.md) for per-agent model assignment rationale and version history.

**Fail action:** List missing agents for manual investigation. Common causes:
- Plugin not installed or not rebuilt after adding agents
- Agent frontmatter parse error preventing registration
- CC version too old (&lt; 2.1.50) to support `claude agents` CLI


### Health Check Outputs

# Health Check Output Examples

Reference output examples for each `/ork:doctor` check category.

## Channel Detection

**Stable:**
```
Channel: stable (v7.0.0)
```

**Beta:**
```
Channel: beta (v7.0.0-beta.3)
⚠ You are on the beta channel. Report issues at github.com/yonatangross/orchestkit/issues
```

**Alpha:**
```
Channel: alpha (v7.0.0-alpha.1)
⚠ You are on the alpha channel. Expect breaking changes. Report issues at github.com/yonatangross/orchestkit/issues
```

**Detection logic:**
1. Read version from `.claude-plugin/plugin.json` (`version` field) or `version.txt`
2. If version contains `-alpha` → alpha channel
3. If version contains `-beta` → beta channel
4. Otherwise → stable channel

## Installed Plugins

```
Installed Plugins: 1
- ork: 103 skills, 36 agents, 173 hook entries
```

## Skills Validation

```
Skills: 79/79 valid
- User-invocable: 18 commands
- Reference skills: 61
```

## Agents Validation

```
Agents: 38/38 valid
- Models: 12 sonnet, 15 haiku, 8 opus
- All skill references valid
```

## Hook Health

```
Hooks: 95/95 entries valid (12 bundles)
- Global: 34, Agent-scoped: 54, Skill-scoped: 7
- Async hooks: 9 (native async)
- Error Rate: 0.3%
```

## Memory System

```
Memory System: healthy
- Graph Memory: 42 decisions, 0 corrupt, queue depth 3
```

## Build System

```
Build System: in sync
- Skills: 69 src/ = 69 plugins/
- Agents: 38 src/ = 38 plugins/
- Last build: 2 minutes ago
```

## Permission Rules

```
Permission Rules: 12/12 reachable
```

## Schema Compliance

```
Schemas: 15/15 compliant
```

## Coordination System

```
Coordination: healthy
- Active instances: 1
- Stale locks: 0
```

## Context Budget

```
Context Budget: 1850/2200 tokens (84%)
```

## Claude Code Version

**OK:**
```
Claude Code: 2.1.47 (OK)
- Minimum required: 2.1.47
- All 15 features available
```

**Degraded:**
```
Claude Code: 2.1.44 (DEGRADED)
- Minimum required: 2.1.47
- Missing: last_assistant_message, added_dirs, Windows hooks, worktree discovery
- Upgrade: npm install -g @anthropic-ai/claude-code@latest
```

## External Dependencies

**Installed (agent-browser ≥ 0.26 — structured doctor):**
```
External Dependencies:
agent-browser: OK (chrome=128.0.6613.137, net=✓)
```

**Installed but degraded:**
```
External Dependencies:
agent-browser: DEGRADED (chrome=128.0.6613.137, net=✗)
  ↳ HIGH: daemon not reachable on port 9222 — try `agent-browser daemon restart`
```

**Installed (agent-browser &lt; 0.26 — legacy fuzzy probe):**
```
External Dependencies:
agent-browser: installed (legacy probe — upgrade to 0.26+ for structured doctor)
```

**Not installed:**
```
External Dependencies:
agent-browser: NOT INSTALLED (optional — install via vercel-labs/agent-browser ≥ 0.26)
```

## Plugin Validate

**Pass (CC >= 2.1.77):**
```
Plugin Validate: PASSED
- claude plugin validate: 0 errors, 0 warnings
```

**Fail (CC >= 2.1.77):**
```
Plugin Validate: FAILED
- claude plugin validate: 2 errors
  - src/skills/broken/SKILL.md: missing required field "description"
  - src/hooks/hooks.json: invalid matcher pattern at hooks[3]
- Fix errors and re-run: npm run build && claude plugin validate
```

**Skipped (CC &lt; 2.1.77):**
```
Plugin Validate: SKIPPED (requires CC >= 2.1.77)
- Falling back to OrchestKit custom validation only
```

## Managed Settings Policy (CC >= 2.1.92)

**OK — forceRemoteSettingsRefresh with endpoint:**
```
Managed Settings: OK
- forceRemoteSettingsRefresh: enabled
- Remote endpoint configured
```

**Warning — forceRemoteSettingsRefresh without endpoint:**
```
Managed Settings: WARNING
- forceRemoteSettingsRefresh: enabled but no remote settings endpoint detected
- This will block startup if network is unavailable
- Configure a remote endpoint or remove forceRemoteSettingsRefresh
```

**Info — not set:**
```
Managed Settings: OK (default)
- forceRemoteSettingsRefresh: not set (falls back to cached settings)
```

**MCP connector conflict (CC >= 2.1.92 fix):**
```
MCP Servers: WARNING
- Plugin MCP server "{name}" duplicates a claude.ai connector
- Prior to CC 2.1.92 this caused stuck "connecting" state
- Consider setting ENABLE_CLAUDEAI_MCP_SERVERS=false or renaming the plugin server
```


### Hook Validation

# Hook Validation

## Overview

OrchestKit uses 134 global hook entries across 15 event types, compiled into 12 bundles. This reference explains how to validate and troubleshoot hooks.

## Hook Architecture

```
hooks.json (63 global + 22 agent-scoped + 1 skill-scoped entries)
    ↓
12 TypeScript bundles (dist/*.mjs)
    ↓
9 async hooks use fire-and-forget pattern
```

## Platform Support

| Platform | Hook Status | Notes |
|----------|------------|-------|
| macOS | Full support | Native execution |
| Linux | Full support | Native execution |
| Windows | Full support (CC 2.1.47+) | Uses Git Bash instead of cmd.exe |

**Windows support history:**
- **Before CC 2.1.47**: All hooks silently failed on Windows (cmd.exe incompatible)
- **CC 2.1.47**: Fixed by executing hooks via Git Bash instead of cmd.exe
- **PR #645**: OrchestKit added Windows-safe spawning (no console flashing, no ENAMETOOLONG)

**Cross-platform safety measures in OrchestKit hooks:**
- `paths.ts` provides cross-platform path handling (`os.homedir()`, `os.tmpdir()`, `path.join()`)
- CRLF normalization (`\r\n` → `\n`) in subagent-validator, decision-history, common.ts
- Windows backslash path normalization in structure-location-validator
- Windows-specific test cases for paths, CRLF, and permission handling

## Hook Categories

| Event Type | Count | Purpose |
|------------|-------|---------|
| PreToolUse | 14 | Before tool execution |
| SubagentStart | 7 | Before agent spawn |
| SubagentStop | 7 | After agent completes |
| PostToolUse | 6 | After tool execution |
| Setup | 6 | Plugin initialization |
| SessionStart | 5 | Session initialization |
| UserPromptSubmit | 5 | Prompt enhancement |
| PermissionRequest | 3 | Auto-approval logic |
| SessionEnd | 3 | Session cleanup |
| TeammateIdle | 3 | Teammate idle handling |
| Stop | 2 | Conversation end |
| Notification | 2 | Desktop/sound alerts |
| PostToolUseFailure | 1 | Failed tool handling |
| PreCompact | 1 | Before context compaction |
| TaskCompleted | 1 | Task completion handling |
| **Total Global** | **66** | |

## Bundle Structure

| Bundle | Handlers | Async |
|--------|----------|-------|
| agent.mjs | Agent hooks | No |
| hooks.mjs | Core dispatching | No |
| lifecycle.mjs | Session lifecycle | Yes |
| notification.mjs | Alerts | Yes |
| permission.mjs | Auto-approve | No |
| posttool.mjs | Post-execution | Yes |
| pretool.mjs | Pre-execution | No |
| prompt.mjs | Prompt enhancement | Yes |
| setup.mjs | Initialization | Yes |
| skill.mjs | Skill-scoped hooks | No |
| stop.mjs | Conversation end | Yes |
| subagent.mjs | Agent lifecycle | No |

## Validation Checks

### 1. hooks.json Schema

```bash
# Validate hooks.json structure
cat src/hooks/hooks.json | jq '.hooks | keys'
```

### 2. Bundle Existence

```bash
# Check all bundles exist
ls -la src/hooks/dist/*.mjs
```

### 3. Async Hook Pattern

Async hooks use fire-and-forget scripts:

```bash
# 9 fire-and-forget scripts required (updated CC 2.1.47)
ls src/hooks/bin/*-fire-and-forget.mjs
```

### 4. Matcher Syntax

Valid matcher patterns:

```json
{
  "matcher": "Bash",           // Exact tool name
  "matcher": "Write|Edit",     // Multiple tools
  "matcher": "*",              // All tools
  "matcher": "mcp__*"          // Wildcard prefix
}
```

## Debug Mode (Issue #243)

Silent hooks run in detached background processes. Enable debug mode to monitor them.

### Enable Debug Logging

Create `.claude/hooks/debug.json`:

```json
{
  "enabled": true,
  "verbose": false,
  "includeInput": false,
  "hookFilters": []
}
```

### View Debug Logs

```bash
# Recent background hook activity
tail -f .claude/logs/background-hooks.log

# Filter by hook name
grep "unified-dispatcher" .claude/logs/background-hooks.log
```

### Hook Metrics

Execution metrics tracked in `.claude/hooks/metrics.json`:

```json
{
  "hooks": {
    "posttool/unified-dispatcher": {
      "totalRuns": 42,
      "successCount": 41,
      "errorCount": 1,
      "avgDurationMs": 150
    }
  }
}
```

### PID Tracking

```bash
# Check for orphaned processes
for f in .claude/hooks/pids/*.pid; do
  pid=$(jq -r '.pid' "$f" 2>/dev/null)
  if [ -n "$pid" ] && ! kill -0 "$pid" 2>/dev/null; then
    echo "Orphaned: $f"
    rm "$f"
  fi
done
```

## Troubleshooting

### Hook not firing

1. Check matcher pattern matches tool name
2. Verify bundle exists in dist/
3. Check hooks.json registration

### Hook timing out

Default timeout: 120s (bash), 600s (CC 2.1.3+)

### Exit Codes

| Code | Meaning |
|------|---------|
| 0 | Success / Allow |
| 1 | Error (logged, continues) |
| 2 | Block (stops execution) |


### Mcp Pinning Check

# MCP Pinning Check (Category 12 sub-check)

Warns when `.mcp.json` resolves HIGH-tier MCP servers to `@latest`. HIGH-tier
upstream packages are pre-1.0 or beta-surface — a breaking change can land on
any `npx -y` fetch with no signal.

**Closes:** #1462. Split from #1446 (MCP audit).

## Tier Source-of-Truth

`src/skills/mcp-patterns/references/mcp-version-matrix.md`

| Tier | Criteria | Packages |
|---|---|---|
| **HIGH** | Pre-1.0 upstream, API may change without notice | `@21st-dev/magic`, `agentation-mcp` |
| **MEDIUM** | Active upstream, semver, used in many skills | `@upstash/context7-mcp`, `tavily-mcp`, `fal-ai-mcp` |
| **LOW** | Stable API, calendar-versioned | `@modelcontextprotocol/server-sequential-thinking`, `@modelcontextprotocol/server-memory` |

## Detection

The check parses `.mcp.json` and for each non-disabled entry extracts the npm
package + version specifier from `args` (handles both `npx -y pkg@x` and
`sh -c "... npx -y pkg@x"` shapes). Local servers (e.g., `node ./server.mjs`)
are skipped.

For each enabled remote server:

| Spec | Tier | Behavior |
|---|---|---|
| `pkg@&lt;concrete&gt;` | any | OK |
| `pkg` or `pkg@latest` | HIGH | **WARN** (exit 1) |
| `pkg` or `pkg@latest` | MEDIUM | informational only (exit 0) |
| `pkg` or `pkg@latest` | LOW | silent (exit 0) |

## Output

**HIGH-tier @latest detected:**
```
MCP pinning: 2 HIGH-tier server(s) resolve to @latest
    ⚠ 21st-dev-magic (@21st-dev/magic)
    ⚠ agentation (agentation-mcp)
    → Consider pinning to concrete versions in .mcp.json
    → See src/skills/mcp-patterns/references/mcp-version-matrix.md
```

**MEDIUM-tier only:**
```
MCP pinning: 3 MEDIUM-tier server(s) at @latest (informational)
    ℹ context7 (@upstash/context7-mcp)
    ℹ tavily (tavily-mcp)
    ℹ fal (fal-ai-mcp)
```

**OK:**
```
MCP pinning: OK (no HIGH-tier @latest entries)
```

## Script

`src/skills/doctor/scripts/check-mcp-pinning.sh` — invokable standalone or via
`/ork:doctor` Category 12.

```bash
# Standalone
src/skills/doctor/scripts/check-mcp-pinning.sh

# JSON for CI
src/skills/doctor/scripts/check-mcp-pinning.sh --json

# Test fixture
src/skills/doctor/scripts/check-mcp-pinning.sh --mcp-json /tmp/test.json
```

Exit codes: `0` = OK or absent, `1` = HIGH-tier @latest found, `2` = usage error.

## Tests

`tests/skills/test-mcp-pinning-check.sh` — 18 assertions across 7 fixtures
covering HIGH/MEDIUM/LOW tier classification, disabled entries, local servers,
JSON output shape, and missing-file handling.


### Memory Health

# Memory Health

## Overview

OrchestKit uses graph memory for knowledge persistence. Doctor validates it with automated checks.

## Automated Health Check

The `memory-health.ts` library provides `checkMemoryHealth()` which returns a `MemoryHealthReport`:

```typescript
interface MemoryHealthReport {
  overall: 'healthy' | 'degraded' | 'unavailable';
  timestamp: string;
  graph: {
    status: TierStatus;
    memoryDir: boolean;        // .claude/memory/ exists
    decisions: FileHealth;     // decisions.jsonl analysis
    graphQueue: FileHealth;    // graph-queue.jsonl depth
  };
}
```

Each `FileHealth` includes: `exists`, `lineCount`, `corruptLines`, `sizeBytes`, `lastModified`.

## Status Meanings

| Status | Meaning |
|--------|---------|
| `healthy` | Graph memory operational, no issues |
| `degraded` | Working but with issues (corrupt data, high queue depth) |
| `unavailable` | Not configured or missing critical components |

## Graph Memory

Local knowledge graph stored in `.claude/memory/`.

### Validation Commands

```bash
# Check directory exists
ls -la .claude/memory/

# Count decisions
wc -l .claude/memory/decisions.jsonl

# Check graph queue depth
wc -l .claude/memory/graph-queue.jsonl 2>/dev/null

# Validate JSONL integrity (each line must be valid JSON)
while IFS= read -r line; do
  echo "$line" | python3 -m json.tool > /dev/null 2>&1 || echo "CORRUPT: $line"
done < .claude/memory/decisions.jsonl
```

### Health Indicators

- Directory exists: `.claude/memory/`
- `decisions.jsonl`: Valid JSONL, no corrupt lines
- `graph-queue.jsonl`: Queue depth &lt; 50 (high depth = sync backlog)
- No corruption: every line parses as valid JSON

### Degraded Conditions

- **Corrupt lines**: One or more JSONL lines fail to parse
- **High queue depth**: >50 pending graph operations (sync backlog)
- **Missing directory**: Graph memory never initialized

## Troubleshooting

### Graph memory missing

```bash
# Initialize graph
mkdir -p .claude/memory
```

The first `/ork:remember` call will create `decisions.jsonl`.

### Corrupt JSONL lines

```bash
# Find corrupt lines
python3 -c "
import json, sys
with open('.claude/memory/decisions.jsonl') as f:
    for i, line in enumerate(f, 1):
        try: json.loads(line)
        except: print(f'Line {i}: {line.strip()[:80]}')
"
```

### High queue depth

Queue items accumulate if the stop dispatcher doesn't run (e.g., session crash). The queue-recovery hook processes orphaned queues on the next session start.


### Permission Rules

# Permission Rules Analysis

## Overview

CC 2.1.3 added detection for unreachable permission rules. This reference explains how to diagnose and fix permission issues.

## Common Issues

### 1. Unreachable Rules

A rule is unreachable when a more general rule already matches:

```json
// PROBLEM: Second rule never matches
{
  "permissions": [
    { "path": "**/*.md", "action": "allow" },
    { "path": "README.md", "action": "deny" }  // Unreachable!
  ]
}
```

**Fix:** Order rules from specific to general:

```json
{
  "permissions": [
    { "path": "README.md", "action": "deny" },
    { "path": "**/*.md", "action": "allow" }
  ]
}
```

### 2. Shadowed Rules

When two rules match the same pattern with different actions:

```json
// PROBLEM: Both match, but first wins
{
  "permissions": [
    { "matcher": "Bash", "action": "allow" },
    { "matcher": "Bash", "commands": ["rm"], "action": "deny" }
  ]
}
```

**Fix:** Use more specific matchers:

```json
{
  "permissions": [
    { "matcher": "Bash", "commands": ["rm", "rm -rf"], "action": "deny" },
    { "matcher": "Bash", "action": "allow" }
  ]
}
```

### 3. Invalid Patterns

Glob patterns that will never match:

```json
// PROBLEM: Typo in pattern
{
  "permissions": [
    { "path": "**.md", "action": "allow" }  // Should be **/*.md
  ]
}
```

## Validation Commands

```bash
# Check for unreachable rules
jq '.permissions // [] | to_entries | map(select(.value.action == "allow"))' \
  .claude/settings.json

# List all permission matchers
jq '.permissions // [] | map(.matcher) | unique' .claude/settings.json
```

## Best Practices

1. Order rules from most specific to least specific
2. Use explicit deny rules before catch-all allow rules
3. Test rules with actual tool invocations
4. Review rules after plugin updates

### Remediation Guide

# Remediation Guide

Quick remediation steps for common `/ork:doctor` findings.

## Interpreting Results

| Status | Meaning | Action |
|--------|---------|--------|
| All checks pass | Plugin healthy | None required |
| Skills warning | Invalid frontmatter | Run `npm run test:skills` |
| Agents warning | Invalid frontmatter | Run `npm run test:agents` |
| Hook error | Missing/broken hook | Check hooks.json and bundles |
| Memory warning | Graph unavailable | Check .claude/memory/ directory |
| Build warning | Out of sync | Run `npm run build` |
| Permission warning | Unreachable rules | Review `.claude/settings.json` |
| Plugin validate error | CC frontmatter/hooks.json invalid | Run `claude plugin validate` and fix reported errors |

## Troubleshooting

### "Skills validation failed"

```bash
# Run skill structure tests
npm run test:skills
./tests/skills/structure/test-skill-md.sh
```

### "Build out of sync"

```bash
# Rebuild plugins from source
npm run build
```

### "Memory unavailable"

```bash
# Check graph memory
ls -la .claude/memory/
```

### "Plugin validate failed"

```bash
# Run CC's official validator (requires CC >= 2.1.77)
claude plugin validate

# Fix reported errors, then rebuild and re-validate
npm run build
claude plugin validate
```

### "Stale plugin paths in PATH"

CC ≤ 2.1.127 occasionally left `installed_plugins.json` entries pointing at deleted cache directories, polluting `PATH` for subprocesses. CC 2.1.128+ scrubs those automatically — no maintenance needed at our floor (2.1.138). If you see plugin commands failing with `command not found` after uninstalling a plugin on CC &lt; 2.1.128, upgrade.

### "Auto mode unable to evaluate"

CC 2.1.128+ adds a hint to the auto-mode classifier failure path. When you see:

```
Auto mode could not evaluate this action.
  hint: retry, use /compact, or run with --debug
```

Pick whichever applies — `/compact` if context is full, `--debug` to see the classifier's reasoning, retry if it was transient.

### "Logged out after laptop wake"

If multiple CC sessions all logged themselves out at the same moment after the laptop woke from sleep, that is the pre-2.1.129 OAuth refresh race — concurrent wake-time refreshes invalidated the active token across every running session.

**Fix**: upgrade to CC ≥ 2.1.129 (our floor is 2.1.138, so anyone on the supported window is already fixed). Recover the session with:

```bash
claude /login
```

Then `claude --resume` the affected session(s). Checkpoint state in `.claude/pipeline-state.json` survives — see `checkpoint-resume` skill for resume semantics.

If logouts after wake persist on CC ≥ 2.1.129, the cause is no longer the race — investigate the refresh token (expired, keychain ACL changed, 1Password locked) instead.

### "All concurrent sessions 401 simultaneously"

If you had multiple CC sessions open (worktree-isolated agents, parallel `/ork:implement` chains, multi-tab work) and every one of them dead-ended at `401 Unauthorized` at the same instant — that is the pre-2.1.133 parallel-session refresh-token race. A refresh-token rotation fired in one session, the other sessions raced against it, and they all wound up holding the now-invalidated old token.

**Fix**: upgrade to CC ≥ 2.1.133 (our floor is 2.1.138, so the supported window is already past this). Recover the stuck sessions with:

```bash
claude /login
```

Then `claude --resume` the affected sessions. Worktree state in each agent's branch is unaffected.

If "all sessions 401 at once" still reproduces on CC ≥ 2.1.133, the cause is no longer this race — check the refresh token itself (expired, revoked by the IdP, keychain ACL changed, 1Password locked). See also the "Logged out after laptop wake" entry above for the related 2.1.129 wake-from-sleep race.

### "EnterWorktree drops my unpushed commits"

If a worktree spawned via `EnterWorktree`, `--worktree`, or an agent run with `isolation: "worktree"` is missing commits you made locally but never pushed — and `git log` in the new worktree starts from `origin/&lt;default-branch&gt;` instead of your current `HEAD` — that is CC 2.1.133's new `worktree.baseRef` default at work. CC 2.1.133 added the setting with default `"fresh"`, which branches new worktrees from `origin/&lt;default&gt;` rather than local `HEAD` (the 2.1.128–2.1.132 behavior).

**Fix**: set `worktree.baseRef: "head"` in `.claude/settings.json` (project) or `~/.claude/settings.json` (user):

```json
{
  "worktree": {
    "baseRef": "head"
  }
}
```

After adding the setting, spawn a fresh worktree — the new one will branch from local `HEAD` and include your unpushed commits. Existing worktrees that were created without the setting need to be recreated; you can recover their work by cherry-picking commits from the original branch first.

See `$\{CLAUDE_SKILL_DIR\}/../chain-patterns/references/worktree-agent-pattern.md` for the full agent-isolation context, and `$\{CLAUDE_SKILL_DIR\}/../configure/references/cc-version-settings.md` (CC 2.1.133 section) for the upstream change description.


### Report Format

# Doctor Report Format

## ASCII Report

**Full ork plugin:**
```
+===================================================================+
|                    OrchestKit Health Report                        |
+===================================================================+
| Version: {version}  |  CC: {cc_version}  |  Plugins: ork          |
+===================================================================+
| Skills           | 67/67 valid                                    |
| Agents           | 37/37 valid                                    |
| Hooks            | 87/87 entries (12 bundles)                     |
| Memory           | Graph memory healthy                           |
| MCP              | context7 ✓  memory ✓  tavily ○  agentation ○  |
| Permissions      | 12/12 reachable                                |
| Schemas          | 15/15 compliant                                |
| Context          | 1850/2200 tokens (84%)                         |
| Coordination     | 0 stale locks                                  |
| CC Version       | {cc_version} (OK)                              |
| Plugin Validate  | PASSED (0 errors)                                |
+===================================================================+
| Status: HEALTHY (11/11 checks passed)                             |
+===================================================================+
```

> **Note:** `\{version\}` is read from `package.json` at runtime. `\{cc_version\}` is detected from Claude Code. Counts reflect installed plugin — dynamic, not hardcoded.


## JSON Output (CI Integration)

```bash
/ork:doctor --json
```

```json
{
  "version": "{version}",
  "claudeCode": "{cc_version}",
  "status": "healthy",
  "plugins": {
    "installed": ["ork"],
    "count": 1
  },
  "checks": {
    "skills": {"passed": true, "count": 67, "perPlugin": {"ork": 67}},
    "agents": {"passed": true, "count": 37, "perPlugin": {"ork": 37}},
    "hooks": {"passed": true, "entries": 87, "bundles": 12, "source": "ork"},
    "memory": {"passed": true, "available": ["graph"]},
    "mcp": {"passed": true, "servers": {"context7": "enabled", "memory": "enabled", "sequential-thinking": "disabled", "tavily": "disabled", "agentation": "disabled"}},
    "permissions": {"passed": true, "count": 12},
    "schemas": {"passed": true, "count": 15},
    "context": {"passed": true, "usage": 0.84},
    "coordination": {"passed": true, "staleLocks": 0},
    "ccVersion": {"passed": true, "version": "2.1.47"},
    "pluginValidate": {"passed": true, "errors": 0, "warnings": 0, "skipped": false}
  },
  "exitCode": 0
}
```

## Exit Codes

| Code | Meaning |
|------|---------|
| 0 | All checks pass |
| 1 | One or more checks failed |


### Schema Validation

# Schema Validation

## Overview

OrchestKit uses JSON schemas to validate configuration files. This reference explains how to validate and fix schema issues.

## Schemas

Located in `.claude/schemas/`:

| Schema | Validates |
|--------|-----------|
| `plugin.schema.json` | `plugin.json` |
| `skill files` | All `SKILL.md` files |
| `context.schema.json` | Context protocol files |
| `coordination.schema.json` | Work registry and decision log |

## Validation Commands

### Validate All

```bash
./tests/schemas/validate-all.sh
```

### Validate Specific File

```bash
# Using ajv
npx ajv validate \
  -s .claude/schemas/skill files \
  -d .claude/skills/doctor/SKILL.md

# Using jq for basic structure check
jq empty .claude/skills/doctor/SKILL.md
```

## Common Schema Errors

### Missing Required Field

```json
// ERROR: Missing "description"
{
  "name": "my-skill",
  "version": "1.0.0"
}
```

**Fix:** Add all required fields:

```json
{
  "$schema": "../../schemas/skill files",
  "name": "my-skill",
  "version": "1.0.0",
  "description": "Description of the skill",
  "capabilities": ["capability-1"]
}
```

### Invalid Type

```json
// ERROR: capabilities must be array
{
  "capabilities": "single-capability"
}
```

**Fix:** Use correct type:

```json
{
  "capabilities": ["single-capability"]
}
```

### Pattern Mismatch

```json
// ERROR: version must match semver
{
  "version": "1.0"
}
```

**Fix:** Use proper semver:

```json
{
  "version": "1.0.0"
}
```

## Batch Validation

```bash
# Validate all SKILL.md files
for category in skills/*/.claude/skills; do for f in "$category"/*/SKILL.md; do
  npx ajv validate \
    -s .claude/schemas/skill files \
    -d "$f" || echo "INVALID: $f"
done
```

## Creating Valid Files

Use schema as a template:

```bash
# View required fields
jq '.required' .claude/schemas/skill files

# View property types
jq '.properties | to_entries | map({key: .key, type: .value.type})' \
  .claude/schemas/skill files
```

### Skills Validation

# Skills Validation

## Overview

OrchestKit includes 103 skills validated against frontmatter requirements and content standards.

## Skill Types

| Type | Count | Frontmatter |
|------|-------|-------------|
| User-invocable | 18 | `user-invocable: true` |
| Internal | 61 | `user-invocable: false` |

## Validation Checks

### 1. Frontmatter Fields

Required fields:
- `name` - Skill identifier
- `description` - Brief description with triggers
- `user-invocable` - Boolean for command availability

Optional fields:
- `context` - fork (recommended), inherit
- `agent` - Associated agent name
- `tags` - Keywords for discovery
- `version` - Semver version
- `allowedTools` - Tool whitelist

### 2. Token Budget

Skills must stay within token limits:
- Minimum: 300 tokens
- Maximum: 5000 tokens

```bash
# Check skill size
wc -c src/skills/*/SKILL.md | sort -n
```

### 3. Reference Links

All internal links must resolve:

```bash
# Check for broken references
for skill in src/skills/*/SKILL.md; do
  grep -o 'references/[^)]*' "$skill" | while read ref; do
    dir=$(dirname "$skill")
    [ -f "$dir/$ref" ] || echo "Broken: $skill -> $ref"
  done
done
```

### 4. Related Skills

All skills in "Related Skills" section must exist:

```bash
# Validate related skill references
grep -h "^- " src/skills/*/SKILL.md | grep -v "http" | \
  sed 's/.*`\([^`]*\)`.*/\1/' | sort -u
```

## Quick Validation

```bash
# Run full skill validation
npm run test:skills

# Or directly
./tests/skills/structure/test-skill-md.sh
```

## Common Issues

### Missing frontmatter

```yaml
---
name: my-skill
description: Does something useful
user-invocable: false
---
```

### Token budget exceeded

Split into SKILL.md + references/ directory.

### Broken reference link

Ensure file exists at `references/filename.md`.


### Version Compatibility

# CC Version Compatibility Matrix

## Overview

OrchestKit requires Claude Code >= 2.1.139. This matrix documents which CC features OrchestKit depends on and their minimum version requirements.

## Experimental skills

Skills that depend on a Claude Code Research Preview feature are marked with an
`experimental:` frontmatter block declaring the reason, expected GA window, and
exit criteria. Doctor should compute this list dynamically by scanning
`src/skills/*/SKILL.md` for frontmatter containing `experimental:` and report
any skills whose `exit-criteria` is missing or empty as a warning.

Current experimental skills (M139, snapshot — verify via dynamic scan):

_None._ `ork:agents-view` was removed in favor of the native `claude agents`
CLI (CC 2.1.139+) plus the parallel-primitives doc at
`docs/parallel-primitives.md`.

When a future skill depends on an unreleased CC feature, add it to this table
with its `exit-criteria` so doctor can warn about Research Preview surface
area. Remove the entry once the underlying CLI feature reaches GA and the
skill is no longer marked `experimental:` in its frontmatter.

## Feature Matrix

| Feature | Min CC Version | OrchestKit Usage | Degradation if Missing |
|---------|---------------|-----------------|----------------------|
| `subagent_type` in SubagentStart | 2.1.7 | Agent type detection in all SubagentStart hooks | Hooks fall back to prompt scanning (removed in v6.0) |
| `session_id` guaranteed | 2.1.9 | Session tracking in all hooks | Session-scoped features fail |
| Hook `continue` field | 2.1.7 | All hook responses | Hooks silently ignored |
| Permission rules detection | 2.1.3 | Doctor unreachable rules check | Permission check skipped |
| `sonnet-4-6` model | 2.1.45 | Agent model field in frontmatter | Falls back to older sonnet |
| Plugin hot reload | 2.1.45 | Live plugin updates without restart | Must restart CC after changes |
| `last_assistant_message` | 2.1.47 | Stop/SubagentStop context capture | Missing assistant context |
| `added_dirs` statusline field | 2.1.47 | Multi-directory project support | Single-dir only in statusline |
| Deferred SessionStart (500ms) | 2.1.47 | Hooks fire after env is ready | Race conditions on cold start |
| Agent model in Teams | 2.1.47 | Model field respected in team spawns | Model ignored, uses default |
| Worktree discovery | 2.1.47 | Skills/agents found from worktrees | Worktree sessions miss plugins |
| Background tasks in worktrees | 2.1.47 | Task tool from worktrees | Background agents fail silently |
| Windows hook execution | 2.1.47 | All hooks on Windows | Hooks silently fail on Windows |
| Windows worktree sessions | 2.1.47 | Drive letter casing match | Worktree sessions not matched |
| Improved agent memory | 2.1.47 | Higher context limits | Conservative limits apply |
| `Ctrl+F` find in output | 2.1.47 | Search through session output | No search capability |
| `Shift+Down` multi-line input | 2.1.47 | Multi-line prompt entry | Single-line input only |
| Memory leak fixes (8 leaks) | 2.1.50 | Stable long-running sessions | Memory grows unbounded over time |
| `claude_agents_cli` | 2.1.50 | Doctor agent registration check | Agent registration check skipped |
| ConfigChange hook event | 2.1.50 | Detect mid-session settings changes | Stale config until restart |
| Auto-memory | 2.1.59 | Claude saves learnings across sessions | Manual CLAUDE.md only |
| `@import` in CLAUDE.md | 2.1.59 | Modular instruction files | Single monolithic CLAUDE.md |
| `.claude/rules/` with `paths:` | 2.1.59 | Path-scoped rules per directory | All rules loaded always |
| HTTP hooks (`type: "http"`) | 2.1.63 | Observability hooks POST to remote endpoints | Falls back to command hooks (local JSONL) |
| Worktree config sharing | 2.1.63 | Project configs shared across worktrees | Manual config copy needed |
| `/clear` resets skills | 2.1.63 | Fixes stale skill content after edits | Native since 2.1.63; no workaround needed |
| Teammate memory fix | 2.1.63 | Safe for 5+ teammate swarms | Memory grows in long team sessions |
| `/simplify`, `/batch` built-in | 2.1.63 | Bundled CC slash commands | Not available |
| `ENABLE_CLAUDEAI_MCP_SERVERS` | 2.1.63 | Opt out of claude.ai MCP servers | All claude.ai MCPs always loaded |
| InstructionsLoaded hook event | 2.1.69 | Rules materialization timing, context injection | Rules written too late, stale context |
| `once: true` hooks | 2.1.69 | 13 skill context loaders fire once then auto-remove | Loaders fire every prompt (wasted tokens) |
| `permissionDecision: 'ask'` | 2.1.69 | Gray-zone command escalation to user | Binary allow/deny only |
| `tool_use_id` correlation | 2.1.69 | Pre/PostToolUse pair tracking | No correlation between pre/post |
| `$\{ENV_VAR\}` in HTTP hooks | 2.1.69 | `$TOKEN` in headers works; `$\{VAR\}` in URLs broken since 2.1.71 (validated before expansion) — use `generate-http-hooks` CLI with real URLs instead | Must use command hooks for env vars |
| Path-scoped rules (`paths:`) | 2.1.69 | 10 conditional rules scoped to file paths | All rules always loaded |
| Worktree dedup fixes | 2.1.70 | Prevents duplicate hook fires in worktrees | Hooks may fire twice |
| 74% prompt re-render reduction | 2.1.70 | CC-internal perf (no action needed) | Higher latency on re-renders |
| ~600 token skill listing savings | 2.1.70 | CC-internal (frees headroom for hook injection) | Tighter token budget |
| MCP cache invalidation | 2.1.70 | MCP tools refresh on reconnect | Stale MCP tool definitions |
| `/loop` command | 2.1.71 | Recurring prompts on intervals (deploy watch, health monitor) | Manual re-invocation |
| Cron scheduling tools | 2.1.71 | Session-scoped cron for recurring tasks | No in-session scheduling |
| Expanded bash auto-approval | 2.1.71 | `fmt`, `comm`, `cmp`, `seq`, `printf`, `test`, etc. auto-approved | Manual approval for POSIX utils |
| `/debug` toggle mid-session | 2.1.71 | Toggle debug logging without restart | Must restart to change log level |
| `settings.local.json` uninstall | 2.1.71 | `/plugin uninstall` writes to local settings, not shared | Uninstall modifies committed settings.json |
| `voice:pushToTalk` rebindable | 2.1.71 | Custom keybinding for push-to-talk in voice mode | Fixed keybinding |
| Background agent output path | 2.1.71 | Completion notifications include output file path | Missing output path in notifications |
| Plugin multi-instance fix | 2.1.71 | Concurrent CC instances preserve plugin installs | Plugin state lost with multiple instances |
| ToolSearch cleanup | 2.1.71 | "Tool loaded." message removed from output | Noisy ToolSearch output |
| Plugin marketplace fixes | 2.1.71 | `@ref` parsing and merge conflict resolution | Marketplace update/add failures |
| Skill listing skip on `--resume` | 2.1.71 | ~600 tokens saved on session resume (no re-injection) | Skill listing re-injected on every resume |
| ExitWorktree tool | 2.1.72 | Agents can leave worktree sessions programmatically | Agents stuck in worktree until session ends |
| Agent `model` parameter restored | 2.1.72 | Per-invocation model override via Agent tool | Model override silently ignored |
| Team agents inherit leader model | 2.1.72 | Teammates use leader's model when unspecified | Teammates fall back to default model |
| `/plan` accepts description arg | 2.1.72 | `/plan fix auth bug` starts plan with context | Must type description after `/plan` prompt |
| Effort levels simplified | 2.1.72 | Three levels: low/medium/high (was 5-level) | Five-level effort scale |
| `CLAUDE_CODE_DISABLE_CRON` env var | 2.1.72 | Disable cron scheduling via environment | No way to disable cron |
| Skill hooks double-fire fix | 2.1.72 | Skill-scoped hooks fire exactly once | Skill hooks may fire twice per invocation |
| `/clear` preserves bg agents | 2.1.72 | Background agents survive `/clear` | `/clear` kills background agents |
| Agent prompt persistence fix | 2.1.72 | Agent prompt no longer deleted from settings.json | Agent prompts lost on restart |
| AlwaysAllow rule matching fix | 2.1.72 | Permission rules match commands correctly | AlwaysAllow rules may not match |
| Worktree task resume fixes | 2.1.72 | cwd restore + bg notification metadata on resume | Worktree tasks resume in wrong dir, missing metadata |
| Prompt cache fix | 2.1.72 | Up to 12x token cost reduction via improved caching | Higher token costs from cache misses |
| Expanded bash auto-approval | 2.1.72 | `lsof`, `pgrep`, `tput`, `ss`, `fd`, `fdfind` auto-approved | Manual approval for system inspection tools |
| `vscode://anthropic.claude-code/open` | 2.1.72 | URI handler to open CC from VS Code links | No deep-link integration with VS Code |
| `/output-style` deprecated → `/config` | 2.1.73 | No OrchestKit references to /output-style | None — already using /config |
| Skill-file deadlock fix on `git pull` | 2.1.73 | Fixes hang with 89-skill plugin after `git pull` | CC hangs during/after git pull |
| SessionStart hooks double-fire fix | 2.1.73 | ~15 SessionStart hooks fire exactly once on resume | Hooks fire twice on --resume/--continue |
| No-op system reminder injection fix | 2.1.73 | ~2K tokens/turn recovered across 99 hooks | Empty system-reminder tags waste context |
| Opus 4.6 default on Bedrock/Vertex/Foundry | 2.1.73 | 6 opus-tier agents auto-upgrade on cloud providers | Older Opus model on cloud providers |
| `/context` optimization hints | 2.1.74 | Actionable suggestions for context-heavy tools, memory bloat, capacity | No optimization guidance |
| `autoMemoryDirectory` setting | 2.1.74 | Custom auto-memory storage path via settings.json | Default path only |
| SessionEnd `hook.timeout` respected | 2.1.74 | SessionEnd hooks run to configured timeout (was hardcoded 1.5s) | SessionEnd hooks killed at 1.5s regardless of config |
| `CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS` | 2.1.74 | Env var override for SessionEnd hook timeout | No env var control |
| `--plugin-dir` precedence | 2.1.74 | Local dev plugins override marketplace installs | Marketplace takes precedence |
| Full model IDs in agent frontmatter | 2.1.74 | `claude-opus-4-6` etc. accepted (not just `opus`) | Only symbolic names (`opus`, `sonnet`, `haiku`) |
| Managed policy precedence fix | 2.1.74 | Managed policy `ask` overrides user `allow` + `allowed-tools` | User rules could bypass managed policy |
| Streaming + bash prefix memory fixes | 2.1.74 | Two memory leaks fixed (streaming buffers, bash prefix cache) | RSS growth in long sessions |
| 1M context default for Opus 4.6 | 2.1.75 | No extra usage needed on Max/Team/Enterprise | Must opt-in to 1M context |
| Memory file timestamps | 2.1.75 | Last-modified timestamps for memory freshness reasoning | No staleness signal on memories |
| Hook source in permission prompts | 2.1.75 | Shows settings/plugin/skill origin when hook asks for confirmation | Opaque hook origin |
| Token estimation fix | 2.1.75 | Prevents premature compaction from thinking/tool_use over-counting | Compaction triggers too early |
| Async hook messages suppressed | 2.1.75 | Hook completion messages hidden by default (visible with --verbose) | Noisy async hook output |
| MCP elicitation support | 2.1.76 | Servers request structured input mid-task via form/URL dialog | No MCP input dialogs |
| Elicitation/ElicitationResult hooks | 2.1.76 | Intercept and override MCP elicitation requests/responses | No elicitation interception |
| `-n`/`--name` CLI flag | 2.1.76 | Set display name for session at startup | No session naming at launch |
| `worktree.sparsePaths` setting | 2.1.76 | Selective sparse-checkout for large monorepos | Full checkout in worktrees |
| PostCompact hook | 2.1.76 | Fires after compaction completes for context recovery | Only PreCompact (before) exists |
| `/effort` slash command | 2.1.76 | Set model effort level mid-session | No effort control |
| `feedbackSurveyRate` setting | 2.1.76 | Enterprise session quality survey sample rate | No quality feedback loop |
| Deferred tools compaction fix | 2.1.76 | ToolSearch schemas retained after compaction | Array/number params rejected post-compaction |
| Background agent partial results | 2.1.76 | Killed agents preserve partial results in context | Killed agents lose all output |
| Compaction circuit breaker | 2.1.76 | Auto-compaction stops after 3 consecutive failures | Compaction retries indefinitely |
| Stale worktree cleanup | 2.1.76 | Worktrees from interrupted parallel runs auto-cleaned | Stale worktrees accumulate |
| Worktree startup performance | 2.1.76 | Direct ref reads, skip redundant fetch | Slower worktree startup |
| Opus 4.6 64k default output | 2.1.77 | 64k default, 128k upper bound for Opus+Sonnet | 32k output limit |
| `allowRead` sandbox setting | 2.1.77 | Re-allow read access within denyRead regions | No granular read exceptions |
| `claude plugin validate` | 2.1.77 | Official frontmatter + hooks.json validation | Manual/custom validation only |
| SendMessage auto-resume | 2.1.77 | Stopped agents auto-resume on SendMessage | SendMessage returns error for stopped agents |
| Agent `resume` param removed | 2.1.77 | Must use SendMessage(\{to: id\}) to continue agents | Agent(resume=...) silently ignored |
| Background bash 5GB limit | 2.1.77 | Tasks killed at 5GB output to prevent disk fill | Unbounded background output |
| `/fork` renamed to `/branch` | 2.1.77 | `/fork` still works as alias | Only `/fork` available |
| PreToolUse allow/deny fix | 2.1.77 | "allow" no longer bypasses deny rules (security fix) | allow hooks could bypass deny rules |
| Worktree race condition fix | 2.1.77 | Stale cleanup no longer deletes resumed agent worktrees | Race between cleanup and agent resume |
| --resume performance | 2.1.77 | 45% faster loading, ~100-150MB less peak memory | Slower fork-heavy session resume |
| Progress message memory fix | 2.1.77 | Progress messages cleaned up during compaction | Memory growth from accumulated progress messages |
| `StopFailure` hook event | 2.1.78 | Hooks fire on API errors (rate limit, auth failure) | No hook on API errors |
| `$\{CLAUDE_PLUGIN_DATA\}` | 2.1.78 | Plugin persistent state survives plugin updates | State lost on plugin update |
| Agent `effort`/`maxTurns`/`disallowedTools` frontmatter | 2.1.78 | Plugin agents support effort, turn limits, tool restrictions | No agent-level frontmatter controls |
| PreToolUse allow bypass fix | 2.1.78 | "allow" hooks no longer bypass deny permission rules | allow hooks could bypass deny rules |
| `claude plugin validate` enhanced | 2.1.78 | Validates skill, agent, command frontmatter + hooks.json | Basic validation only |
| Worktree skills/hooks loading fix | 2.1.78 | --worktree flag loads skills and hooks from worktree dir | Skills/hooks loaded from original dir |
| `--console` auth flag | 2.1.79 | `claude auth login --console` for API billing auth | Only OAuth/API key auth |
| "Show turn duration" toggle | 2.1.79 | Turn duration visible in /config menu | No turn duration display |
| `/remote-control` (VSCode) | 2.1.79 | Bridge session to claude.ai/code from browser/phone | VSCode-only sessions |
| Multi-dir `PLUGIN_SEED_DIR` | 2.1.79 | Multiple seed dirs separated by platform path delimiter | Single seed directory only |
| `-p` mode Ctrl+C fix | 2.1.79 | Ctrl+C works in print mode | Ctrl+C ignored in -p mode |
| Startup memory reduction | 2.1.79 | ~18MB less memory on startup | Higher startup memory |
| `rate_limits` statusline field | 2.1.80 | Statusline scripts receive rate limit usage (5h/7d windows, `used_percentage`, `resets_at`) | No rate limit visibility |
| `source: 'settings'` marketplace | 2.1.80 | Declare plugin entries inline in settings.json | Marketplace JSON files only |
| CLI tool usage detection for tips | 2.1.80 | Plugin tips detect CLI tool usage, not just file patterns | File pattern matching only |
| `effort` frontmatter for skills | 2.1.80 | Skills declare effort level (low/high) to override model effort | No per-skill effort control |
| `--channels` (research preview) | 2.1.80 | MCP servers push messages into active session | Pull-only MCP communication |
| `--resume` parallel tool fix | 2.1.80 | Sessions with parallel tool calls restore all tool_use/tool_result pairs | `[Tool result missing]` on resume |
| Voice mode WebSocket fix | 2.1.80 | Fixes Cloudflare bot detection on non-browser TLS fingerprints | Voice mode connection failures |
| Fine-grained tool streaming fix | 2.1.80 | Fixes 400 errors through API proxies, Bedrock, or Vertex | Streaming failures on proxied deployments |
| `/effort` shows auto resolution | 2.1.80 | Shows what "auto" resolves to, matching status bar | Opaque auto effort |
| Simplified plugin install tips | 2.1.80 | Single `/plugin install` command instead of two-step flow | Two-step marketplace add + install |
| Startup memory reduction (250k repos) | 2.1.80 | ~80 MB saved on startup in large repositories | Higher startup memory on large repos |
| Managed settings cache fix | 2.1.80 | `enabledPlugins`, `permissions.defaultMode`, policy env vars applied at startup | Stale remote-settings.json from prior session |
| `--bare` flag for `-p` mode | 2.1.81 | Eval pipeline uses `--bare` to skip hooks/LSP/plugin sync for faster scripted grading | Full plugin/hook overhead on every `-p` call |
| `--channels` permission relay | 2.1.81 | Channel servers forward tool approval prompts to phone for long-running agents | Must be at terminal for every permission prompt |
| Plugin freshness re-clone | 2.1.81 | Ref-tracked plugins re-clone on every load for latest upstream | Stale plugins until manual reinstall |
| Background agent task output race fix | 2.1.81 | Background agent output no longer hangs between polling intervals | Task output could hang indefinitely |
| Worktree session resume | 2.1.81 | `--resume` of a worktree session switches back to that worktree | Resumed worktree sessions start in main tree |
| Plugin hooks deleted-dir fix | 2.1.81 | Hooks no longer block prompt submission if plugin directory deleted mid-session | Hook deadlock during `npm run build` |
| Invisible hook attachment fix | 2.1.81 | Hook attachments no longer inflate message count in transcript mode | Inflated session analytics from hook overhead |
| MCP tool call collapse | 2.1.81 | MCP read/search calls collapse to single "Queried \{server\}" line (Ctrl+O to expand) | Verbose MCP tool output |
| `showClearContextOnPlanAccept` | 2.1.81 | Plan mode hides "clear context" by default; restorable via setting | "Clear context" shown on every plan accept |
| Concurrent session re-auth fix | 2.1.81 | Multiple CC sessions no longer require repeated re-authentication | Re-auth when one session refreshes OAuth |
| Dashed-string permission fix | 2.1.81 | Bash commands with dashes in strings no longer trigger false permission prompts | False positives on dashed strings |
| `! bash` mode discoverability | 2.1.81 | Claude suggests `!` prefix for interactive commands automatically | Must know about `!` prefix |
| MCP OAuth CIMD/SEP-991 | 2.1.81 | MCP OAuth supports Client ID Metadata Document for servers without DCR | Limited MCP OAuth compatibility |
| Node.js 18 crash fix | 2.1.81 | Fixed crash on Node.js 18 | Crash on Node.js 18 |
| Windows line-by-line streaming disabled | 2.1.81 | Disabled line-by-line streaming on Windows/WSL due to rendering issues | Rendering glitches on Windows |
| Remote Control fixes (4) | 2.1.81 | Session titles, /rename sync, /exit archiving, first-prompt titles fixed | Generic titles, unreliable archiving |
| Voice mode fixes (2) | 2.1.81 | Retry failure messages and WebSocket recovery fixed | Misleading errors, dropped audio |
| `managed-settings.d/` drop-in directory | 2.1.83 | Separate teams deploy independent policy fragments, merged alphabetically | Single monolithic managed-settings.json |
| `CwdChanged` hook event | 2.1.83 | Reactive hooks on working directory change (direnv-like) | No cwd change detection |
| `FileChanged` hook event | 2.1.83 | Reactive hooks on file changes (cache invalidation, tamper detection) | No file change detection |
| `sandbox.failIfUnavailable` | 2.1.83 | Fail-fast when sandbox unavailable instead of running unsandboxed | Silently falls back to unsandboxed |
| `CLAUDE_CODE_SUBPROCESS_ENV_SCRUB` | 2.1.83 | Strip Anthropic/cloud creds from subprocess environments | Creds inherited by subprocesses |
| Agent `initialPrompt` frontmatter | 2.1.83 | Auto-submit first turn on agent spawn, zero-wasted-turn bootstrap | Agents idle on spawn until first interaction |
| Plugin `userConfig` with `sensitive:true` | 2.1.83 | Plugin config at enable time, keychain storage for sensitive values | Plain env vars for all secrets |
| `TaskOutput` deprecated | 2.1.83 | Use `Read` on background task output file instead | `TaskOutput` still functional but deprecated |
| `--bare -p` 14% faster | 2.1.83 | Faster eval pipeline startup | Slower `--bare` startup |
| Background agent compaction fix | 2.1.83 | Background agents no longer become invisible after compaction | Duplicate agents spawned post-compaction |
| Background agent stuck state fix | 2.1.83 | Background tasks no longer stuck "running" when git/API hangs | Stuck tasks require manual cleanup |
| Uninstalled plugin hooks fix | 2.1.83 | Hooks stop firing immediately after plugin uninstall | Stale hooks fire until next session |
| Transcript search (`/` in Ctrl+O) | 2.1.83 | Search through transcript with n/N stepping | No transcript search |
| Plugin disk cache startup | 2.1.83 | Commands/skills/agents load from cache without re-fetching | Slower startup from disk walks |
| Plugin MCP dedup | 2.1.83 | Plugin MCP servers duplicating org connectors are suppressed | Duplicate MCP connections |
| `TaskCreated` hook event | 2.1.84 | Task initialization tracking, metadata injection, dependency validation | No hook on task creation |
| WorktreeCreate `type: "http"` | 2.1.84 | Return worktree path via `hookSpecificOutput.worktreePath` for API-driven orchestration | Command hooks only |
| `paths:` YAML glob list (skills/rules) | 2.1.84 | Auto-load relevant files when skill activates; 15+ skills use this | Manual Read calls for context |
| `ANTHROPIC_DEFAULT_\{OPUS,SONNET,HAIKU\}_MODEL_SUPPORTS` | 2.1.84 | Override effort/thinking capability detection for Bedrock/Vertex/Foundry | Incorrect capability detection on 3P |
| `ANTHROPIC_DEFAULT_*_MODEL_NAME/_DESCRIPTION` | 2.1.84 | Customize /model picker labels for custom deployments | Generic model labels |
| `CLAUDE_STREAM_IDLE_TIMEOUT_MS` | 2.1.84 | Configurable streaming idle watchdog (default 90s, OrchestKit sets 180s) | Fixed 90s timeout kills long agents |
| `allowedChannelPlugins` managed setting | 2.1.84 | Enterprise admin plugin allowlist for channel plugins | No channel plugin governance |
| `x-client-request-id` header | 2.1.84 | API request correlation ID for debugging timeouts | No request-level tracing |
| PowerShell tool (Windows opt-in) | 2.1.84 | Native PowerShell as alternative to Git Bash on Windows | Git Bash only on Windows |
| MCP tool description 2KB cap | 2.1.84 | Prevents OpenAPI-generated servers from bloating context | Unbounded MCP tool descriptions |
| MCP server deduplication | 2.1.84 | Local MCP config wins over claude.ai connectors | Duplicate MCP connections |
| Workflow subagent `json-schema` fix | 2.1.84 | Outer session + subagent both specifying schema no longer 400s | API 400 on nested json-schema |
| System-prompt caching + ToolSearch | 2.1.84 | Global caching works when ToolSearch enabled (incl. MCP users) | Cache misses with ToolSearch |
| Idle-return prompt (75+ min) | 2.1.84 | Nudges `/clear` after 75+ minutes idle, reduces stale token re-caching | No idle session detection |
| `owner/repo#123` link format | 2.1.84 | Bare `#123` no longer auto-linked; must use `owner/repo#123` | Bare `#123` was auto-linked |
| Improved startup parallelism (30ms) | 2.1.84 | `setup()` runs in parallel with slash command and agent loading | Sequential startup |
| MCP startup non-blocking | 2.1.84 | REPL renders immediately, MCP servers connect in background | REPL blocked until all MCP servers connect |
| Background bash stuck notification | 2.1.84 | Tasks stuck on interactive prompt surface notification after ~45s | Stuck tasks hang silently |
| MCP cache leak fix on reconnect | 2.1.84 | Tool/resource cache properly cleaned on server reconnect | Memory leak on MCP reconnect |
| `p90` prompt cache rate improvement | 2.1.84 | Better prompt caching across sessions | Lower cache hit rate |
| PreToolUse for AskUserQuestion | 2.1.85 | Headless AskUserQuestion responder hooks | No hook on AskUserQuestion |
| Config disk write fix | 2.1.86 | Eliminates unnecessary config writes on every skill invocation | Unnecessary disk I/O per skill |
| Write/Edit outside project root | 2.1.86 | Write/Edit fix for files outside project root | Write/Edit fails for external files |
| `PermissionDenied` hook event | 2.1.88 | Fires after auto mode classifier denials, supports `\{retry: true\}` | No hook on permission denials |
| `permissionMode: "auto"` | 2.1.88 | Classifier-based approval replaces interactive prompts | Interactive permission prompts |
| `file_path` always absolute | 2.1.88 | PreToolUse/PostToolUse file_path always absolute for Write/Edit/Read | Relative paths possible |
| Compound `if` matching | 2.1.88 | Hook `if` conditions match compound commands and env-var prefixes | Only simple command matching |
| `CLAUDE_CODE_NO_FLICKER=1` | 2.1.88 | Flicker-free alt-screen rendering with virtualized scrollback | Default rendering |
| `"defer"` permission decision | 2.1.89 | PreToolUse hooks return `decision:"defer"` to pause headless sessions | Only allow/deny/ask |
| `TaskCreated` hook blocking | 2.1.89 | TaskCreated hook fires with documented blocking behavior | TaskCreated (2.1.84) without blocking docs |
| `MCP_CONNECTION_NONBLOCKING=true` | 2.1.89 | Skip MCP connection wait in `-p` mode, bounded at 5s | Blocks on slowest MCP server |
| Named subagent typeahead | 2.1.89 | Named subagents appear in `@` mention typeahead | Only file names in typeahead |
| Hook output disk spill | 2.1.89 | Hook output >50K chars saved to disk with file path + preview | Full output injected into context |
| Edit after Bash view | 2.1.89 | Edit works on files viewed via `sed -n`/`cat` without Read | Must Read before Edit |
| Symlink permission check | 2.1.89 | Edit/Read allow rules check resolved symlink target | Only requested path checked |
| `/powerup` interactive lessons | 2.1.90 | Interactive feature tutorials with animated demos | No built-in learning tools |
| `CLAUDE_CODE_PLUGIN_KEEP_MARKETPLACE_ON_FAILURE` | 2.1.90 | Keep marketplace cache when `git pull` fails (offline support) | Marketplace cache lost on git failure |
| `.husky` protected directory | 2.1.90 | `.husky` added to protected dirs in acceptEdits mode | .husky writable in acceptEdits |
| PreToolUse exit code 2 JSON fix | 2.1.90 | Hooks emitting JSON to stdout with exit code 2 now correctly block | Exit code 2 JSON silently ignored |
| Format-on-save hook fix | 2.1.90 | Edit/Write no longer fail when PostToolUse format-on-save rewrites file | "File content has changed" error |
| `--resume` prompt cache fix | 2.1.90 | `--resume` no longer causes full prompt-cache miss with deferred tools/MCP | Full cache miss on resume |
| MCP schema cache perf | 2.1.90 | Eliminated per-turn JSON.stringify of MCP tool schemas | Redundant serialization per turn |
| SSE linear transport perf | 2.1.90 | SSE transport handles large frames in linear time (was quadratic) | Quadratic SSE processing |
| Transcript write perf | 2.1.90 | Long conversations no longer slow down quadratically on transcript writes | Quadratic transcript slowdown |
| `--resume` hides `-p` sessions | 2.1.90 | Resume picker no longer shows `claude -p` or SDK sessions | `-p` sessions in resume picker |
| DNS cache auto-allow removed | 2.1.90 | `Get-DnsClientCache` and `ipconfig /displaydns` removed from auto-allow | DNS cache commands auto-allowed |
| MCP `_meta` result size override | 2.1.91 | `_meta["anthropic/maxResultSizeChars"]` annotation (up to 500K) — mcp-output-transform respects it | Large MCP results always truncated at 2000 chars |
| `disableSkillShellExecution` | 2.1.91 | Setting disables inline shell in skills/commands/plugins | Shell execution always enabled |
| Plugin `bin/` executables | 2.1.91 | Plugins ship executables under `bin/` invokable as bare Bash commands | Must use full paths to plugin scripts |
| Deep link multiline prompts | 2.1.91 | `claude-cli://open?q=` supports `%0A` encoded newlines | Multi-line deep links rejected |
| Edit tool shorter anchors | 2.1.91 | Edit uses shorter `old_string` anchors, reducing output tokens | Longer anchors, more output tokens |
| `--resume` transcript chain fix | 2.1.91 | Async transcript write failures no longer lose conversation history | History loss on async write failure |
| `permissions.defaultMode:"auto"` validation | 2.1.91 | JSON schema validates `auto` as permission mode | `auto` accepted but could cause issues |
| Plan mode remote session fix | 2.1.91 | Plan file retained after container restart in remote sessions | Plan lost after container restart |
| `forceRemoteSettingsRefresh` policy | 2.1.92 | Fail-closed startup: blocks until remote managed settings fetched, exits on failure | Stale managed settings on startup |
| Stop hook `preventContinuation` fix | 2.1.92 | prompt-type Stop hooks no longer fail when small fast model returns `ok:false`; `preventContinuation:true` restored | Stop hooks could incorrectly fail |
| Tool input JSON-string streaming fix | 2.1.92 | Array/object `tool_input` fields no longer emitted as JSON-encoded strings during streaming | PreToolUse hooks receive malformed tool_input |
| Plugin MCP stuck "connecting" fix | 2.1.92 | Plugin MCP servers no longer stuck connecting when duplicating unauthenticated claude.ai connectors | MCP servers hang on session start |
| Write tool diff perf | 2.1.92 | 60% faster diff computation for large files with tabs/&/$ characters | Slower Write tool on large files |
| Remote Control hostname prefix | 2.1.92 | Session names default to hostname prefix, overridable with `--remote-control-session-name-prefix` | Generic session names |
| Per-model `/cost` breakdown | 2.1.92 | `/cost` shows per-model and cache-hit breakdown for subscription users | Aggregate cost only |
| `/tag` command removed | 2.1.92 | Removed — no OrchestKit references | N/A |
| `/vim` command removed | 2.1.92 | Removed — toggle via `/config` → Editor mode | N/A |
| Subagent tmux pane fix | 2.1.92 | Subagent spawning no longer fails after tmux windows killed/renumbered | "Could not determine pane count" error |
| Prompt cache expiry hint | 2.1.92 | Pro users see uncached token count when returning after cache expires | No cache expiry visibility |
| **Skill frontmatter hooks fix** | **2.1.94** | **20 OrchestKit skill context loaders (assess, implement, verify, brainstorm, review-pr, fix-issue, doctor, explore, cover, setup, commit, quality-gates, visualize-plan, release-checklist, code-review-playbook) declared via `hooks:` in SKILL.md frontmatter now fire — previously silently ignored** | **All 20 skill context loaders dead — skills run without their primed context (much worse UX)** |
| `hookSpecificOutput.sessionTitle` | 2.1.94 | unified-dispatcher sets session title from branch/effort/skill context — visible in prompt bar and remote sessions | Sessions use auto-generated names |
| `keep-coding-instructions` frontmatter | 2.1.94 | Plugin output styles preserve coding instructions when set true | Output styles may strip coding guidance |
| Plugin skill name stability | 2.1.94 | `"skills": ["./"]` uses frontmatter `name` for invocation, stable across install methods | Invocation name depends on directory basename |
| `$\{CLAUDE_PLUGIN_ROOT\}` local-marketplace fix | 2.1.94 | Resolves to installed cache (not marketplace source) for local-marketplace plugins | File lookups point at wrong directory |
| Plugin hooks CLAUDE_PLUGIN_ROOT fix | 2.1.94 | Plugin hooks no longer fail with "No such file or directory" when env var unset | Hooks fail cold-start on some platforms |
| Default effort `high` | 2.1.94 | Default effort level is `high` for API-key/Bedrock/Vertex/Foundry/Team/Enterprise users (use `/effort low` or `/effort medium` to reduce) | Default `medium` — token budgets scaled conservatively |
| 429 rate-limit surface | 2.1.94 | Agents no longer stuck after 429 with long Retry-After — error surfaces immediately | Agents appear stuck, silent wait |
| SDK/print mode partial response fix | 2.1.94 | Preserves partial assistant response on interrupt mid-stream | Partial responses lost, breaks bare-eval/eval-runner |
| `--resume` across worktrees | 2.1.94 | Resume sessions from other worktrees of the same repo directly (was: print `cd` command) | Must cd manually to resume worktree session |
| CJK/multibyte stream-json fix | 2.1.94 | No U+FFFD corruption when chunk boundaries split UTF-8 sequences | International content corrupted in stream-json |
| Amazon Bedrock via Mantle | 2.1.94 | Opt in with `CLAUDE_CODE_USE_MANTLE=1` | Standard Bedrock only |
| Bedrock bearer token 403 fix | 2.1.96 | Fixed 403 "Authorization header is missing" regression when using `AWS_BEARER_TOKEN_BEDROCK` or `CLAUDE_CODE_SKIP_BEDROCK_AUTH` (regression in 2.1.94) | Bedrock bearer-token auth broken on 2.1.94 |
| MCP tool description 2KB cap | 2.1.95 | Tool descriptions and server instructions capped at 2KB — prevents OpenAPI-generated MCP servers from bloating context | Verbose MCP descriptions consume unbounded context |
| MCP local config dedup | 2.1.95 | MCP servers configured both locally and via claude.ai connectors are deduplicated, local config wins | Duplicate MCP tools from both sources |
| Focus view toggle (`/focus`) | 2.1.97 (2.1.110: moved from `Ctrl+O` to `/focus` command) | Condensed view in NO_FLICKER mode: prompt, one-line tool summary with edit diffstats, final response | No condensed view option |
| `refreshInterval` status line | 2.1.97 | New setting re-runs the status line command every N seconds automatically | Status line only updates per turn |
| `workspace.git_worktree` | 2.1.97 | Boolean in status line JSON input, set when cwd is inside a linked git worktree | Must shell out to detect worktree |
| `● N running` in `/agents` | 2.1.97 | Live subagent instance count next to each agent type | No live agent count |
| Stop/SubagentStop long-session fix | 2.1.97 | prompt-type Stop/SubagentStop hooks no longer fail on long sessions; hook evaluator shows actual error | Hooks fail silently on long sessions |
| Subagent worktree/cwd leak fix | 2.1.97 | Subagents with worktree isolation or `cwd:` override no longer leak working directory back to parent Bash tool | Parent inherits child's cwd |
| `claude plugin update` fix | 2.1.97 | No longer reports "already at latest" for git-based marketplace plugins when remote has newer commits | Users stuck on stale plugin versions |
| YAML boolean skill name fix | 2.1.97 | Slash command picker no longer breaks when plugin frontmatter `name` is a YAML boolean keyword | Skills named true/false/yes/no break picker |
| Bash permissions hardened | 2.1.97 | Tighter env-var prefix checks and network redirect validation, fewer false prompts on common commands | Looser Bash permission checks |
| Accept Edits env-prefix auto-approve | 2.1.97 | Auto-approves filesystem commands prefixed with safe env vars or process wrappers (e.g. `LANG=C rm foo`) | Env-prefixed commands always prompt |
| `sandbox.network.allowMachLookup` macOS | 2.1.97 | Now actually takes effect on macOS | Setting ignored on macOS |
| MCP HTTP/SSE memory leak fix | 2.1.97 | Connections no longer accumulate ~50 MB/hr of unreleased buffers on reconnect | Memory leak on MCP reconnect |
| MCP OAuth metadata URL fix | 2.1.97 | `oauth.authServerMetadataUrl` honored on token refresh after restart (fixes ADFS) | Token refresh ignores custom auth URL |
| 429 retry exponential backoff | 2.1.97 | Exponential backoff applied as minimum instead of burning all attempts in ~13s | Retries exhaust quickly |
| `/resume` picker fixes | 2.1.97 | `--resume &lt;name&gt;` editable, Ctrl+A reload preserves search, task-status text fixed, cross-project staleness | Multiple resume UX bugs |
| Resume large file diff fix | 2.1.97 | File-edit diffs no longer disappear on `--resume` for files >10KB | Diffs lost for large files |
| Compaction subagent transcript dedup | 2.1.97 | No longer writes duplicate multi-MB subagent transcripts on prompt-too-long retries | Transcript bloat on long sessions |
| Prototype property settings.json fix | 2.1.97 | Permission rules with names matching JS prototype properties (toString, constructor) no longer cause settings.json to be silently ignored | Named rules can break entire config |
| Image compression parity | 2.1.97 | Pasted/attached images compressed to same token budget as Read tool images | Pasted images use more tokens than Read |
| Bash OTEL TRACEPARENT | 2.1.97 | Subprocesses inherit W3C `TRACEPARENT` env var when OTEL tracing is enabled | No trace propagation to subprocesses |
| Managed-settings removal fix | 2.1.97 | Allow rules removed by admin take effect without process restart | Stale rules until restart |
| `additionalDirectories` mid-session | 2.1.97 | `permissions.additionalDirectories` changes in settings apply mid-session | Changes require restart |
| Bridge session git info | 2.1.97 | Bridge sessions show local git repo, branch, and working directory on claude.ai session card | No git context on bridge card |
| Transcript size optimization | 2.1.97 | Skip empty hook entries and cap stored pre-edit file copies | Larger transcripts |
| `/team-onboarding` command | 2.1.101 | Generate teammate ramp-up guide from local CC usage | No onboarding automation |
| OS CA certificate store trust | 2.1.101 | Enterprise TLS proxies work OOTB (set `CLAUDE_CODE_CERT_STORE=bundled` for only bundled CAs) | Must configure CA certs manually |
| `deny` overrides `ask` | 2.1.101 | `permissions.deny` rules override PreToolUse hook `permissionDecision:"ask"` | deny and ask conflict silently |
| Subagent dynamic MCP inheritance | 2.1.101 | Subagents inherit MCP tools from dynamically-injected servers | Subagents miss dynamic MCP tools |
| Worktree agent file access | 2.1.101 | Worktree-isolated agents can Read/Edit files inside their own worktree | Worktree agents denied file access |
| Focus mode self-contained summaries | 2.1.101 | Claude writes self-contained summaries knowing user only sees final message | Summaries reference invisible tool output |
| Settings resilience | 2.1.101 | Unrecognized hook event name no longer causes entire settings.json to be ignored | Typo in event name breaks all hooks |
| `EnterWorktree` path param | 2.1.105 | Switch into existing worktrees via `path` parameter (previously only created new) | Must create new worktree every time |
| `PreCompact` blocking | 2.1.105 | Hooks can block compaction via exit code 2 or `\{"decision":"block"\}` JSON | PreCompact observe-only |
| Plugin `monitors` manifest key | 2.1.105 | Background monitor support for plugins via top-level `monitors` manifest key | No declarative background monitoring |
| Skill description cap 1,536 chars | 2.1.105 | Skill descriptions up to 1,536 chars (was 250) — better discovery and selection | Descriptions truncated at 250 chars |
| `WebFetch` script stripping | 2.1.105 | Strips `&lt;style&gt;` and `&lt;script&gt;` content before returning markdown | CSS/JS waste context budget |
| Stale worktree squash cleanup | 2.1.105 | Worktrees from squash-merged PRs auto-cleaned | Orphaned worktrees accumulate |
| `ENABLE_PROMPT_CACHING_1H` | 2.1.108 | 1-hour prompt cache TTL across API key, Bedrock, Vertex, Foundry — **major cost savings for long sessions** | 5-minute cache TTL (default) |
| `/recap` session context | 2.1.108 | Auto-recap on return + manual `/recap` command for session context restoration | No context restoration after idle |
| Skill builtin discovery | 2.1.108 | Model auto-discovers `/init`, `/review`, `/security-review` via Skill tool | Must explicitly invoke built-in commands |
| Model switch warning | 2.1.108 | `/model` warns before switching mid-conversation to prevent cache invalidation | Silent model switch loses cache |
| Lazy language grammars | 2.1.108 | Grammars loaded on demand — reduced memory for file operations | All grammars loaded at startup |
| Thinking progress rotation | 2.1.109 | Extended thinking indicator with rotating progress hint | Static thinking indicator |
| `/tui` command | 2.1.110 | Switch to flicker-free fullscreen TUI rendering mid-conversation via `/tui fullscreen` | Must restart with `--tui` flag |
| `PushNotification` tool | 2.1.110 | Built-in tool for mobile push notifications when Remote Control enabled | No programmatic push notifications |
| `/focus` command | 2.1.110 | Dedicated command for focus view (previously `Ctrl+O` since 2.1.97) | Focus view via `Ctrl+O` |
| `Ctrl+O` transcript toggle | 2.1.110 | Now only toggles between normal and verbose transcript view | Also toggled focus view |
| Bash max timeout enforced | 2.1.110 | Bash tool enforces documented max timeout — values exceeding limit hard-fail | Accepted arbitrarily large values |
| Write user-edit signal | 2.1.110 | Write tool tells model when user edits proposed diff before accepting | No user-edit feedback |
| Session recap default-on | 2.1.110 | Session recap enabled even with telemetry disabled — opt out via `/config` | Required `CLAUDE_CODE_ENABLE_AWAY_SUMMARY=1` |
| `--resume` scheduled tasks | 2.1.110 | `--resume`/`--continue` resurrects unexpired scheduled tasks | Only restored session history |
| Remote Control commands | 2.1.110 | `/autocompact`, `/context`, `/exit`, `/reload-plugins` work from Remote Control | Limited remote command set |
| SDK TRACEPARENT/TRACESTATE | 2.1.110 | Auto-read in SDK/headless for OpenTelemetry distributed trace propagation | Manual trace propagation |
| `/doctor` MCP duplicate | 2.1.110 | Warns when same MCP server defined in multiple config scopes with different endpoints | Silent duplicate MCP |
| Opus 4.7 + `xhigh` effort | 2.1.111 | New effort tier between `high` and `max` for Opus 4.7 — used by `brainstorm`, `implement`, `assess`, `cover`, `verify`, `fix-issue`, `audit-full` | Silent fallback to `high` |
| `/ultrareview` skill | 2.1.111 | Built-in parallel multi-agent review; composed (gated) by `ork:review-pr` when triggers fire | Manual multi-agent review via `ork:review-pr` only |
| `/less-permission-prompts` | 2.1.111 | Built-in skill that prunes overbroad permission rules by scanning transcripts | Manual permission audit |
| Stream-json `plugin_errors` | 2.1.111 | Headless `--output-format stream-json` includes `plugin_errors` on init event | Silent plugin load failures — degraded evals |
| `OTEL_LOG_RAW_API_BODIES` | 2.1.111 | Env var for debugging raw API request/response bodies | No raw-body debug path (secret leak risk if enabled carelessly) |
| `CLAUDE_CODE_USE_POWERSHELL_TOOL` | 2.1.111 | Windows PowerShell tool opt-in (progressively rolling out) | CMD tool on Windows |
| Opus 4.7 vision 2,576px | 2.1.111 | Images up to 2,576 px on long edge (~3.75 MP, 3× Opus 4.6) | Must downscale large screenshots |
| Opus 4.7 filesystem memory | 2.1.111 | Model "substantially better" at reading `.claude/chain/*.json` and `memory/*.md` across sessions | Filesystem memory less reliable |
| Auto mode on Max + Opus 4.7 | 2.1.111 | No `--enable-auto-mode` flag required | Flag required |
| Plan filename after prompt | 2.1.111 | Plan-mode files named after the prompt (was: random words) | Generic plan filenames |
| Readonly bash+glob no prompt | 2.1.111 | Read-only Bash with glob patterns no longer prompts | Permission prompt per read-only command |
| `/skills` menu token sort | 2.1.111 | Press `t` to toggle sort by token count | Alpha only |
| Native binary spawn | 2.1.113 | CLI spawns per-platform native binary via optional dep instead of bundled JS — affects hooks that inspect `process.argv0`, `__dirname`, `node_modules` paths | Hooks assume bundled-JS layout |
| `sandbox.network.deniedDomains` | 2.1.113 | Block specific domains even when broader `allowedDomains` wildcard would permit them | Wildcard allow has no exceptions |
| `/loop` Esc cancels wakeup | 2.1.113 | Pending `/loop` wakeups cancellable via Esc; transcript marker `"Claude resuming /loop wakeup"` enables analytics | Wakeup uninterruptible |
| Bash deny wrappers match | 2.1.113 | Deny rules match commands wrapped in `env`/`sudo`/`watch`/`ionice`/`setsid` | Previous wrapper bypass |
| Bash multiline comments in transcript | 2.1.113 | Multi-line Bash commands with leading `#` comments now show full command in transcript — enables `/recap` grep on intent comments | Heredocs/pipe chains opaque in transcript |
| `Bash(find:*)` tightened | 2.1.113 | Auto-approve no longer covers `-exec`/`-delete` — explicit allowlist or manual approval required | `find -delete` auto-approved |
| macOS `/private/*` dangerous | 2.1.113 | `/private/\{etc,var,tmp,home\}` treated as dangerous under `Bash(rm:*)` deny rules (symlink targets) | Symlink escape via `/private/etc` |
| MCP concurrent timeout fix | 2.1.113 | Hanging MCP calls error cleanly instead of blocking queue | MCP calls could silently hang siblings |
| Subagent stall error | 2.1.113 | Subagent timeouts produce clear error after 10 min instead of hanging indefinitely | Silent hang on stalled subagent |
| Remote Control `/extra-usage` | 2.1.113 | `/extra-usage` and `@`-file autocomplete work from mobile/web Remote Control clients | Desktop-only `/extra-usage` |
| Agent teams permission fix | 2.1.114 | Fixed permission dialog crash when agent-teams teammate requests tool approval | Dialog crash on teammate approval |
| Agent hooks main-thread | 2.1.116 | Agent frontmatter `hooks:` fire when agent runs as `--agent` main thread — previously subagent-only | Main-thread agent has no PreToolUse/PostToolUse blockers |
| `/reload-plugins` auto-deps | 2.1.116 | Auto-installs missing plugin dependencies from known marketplaces | Plugin silently fails to load |
| `/doctor` mid-turn | 2.1.116 | `/doctor` runs while Claude is responding (was queued) — enables mid-session diagnostics | Must wait for turn to finish |
| Sandbox `rm` dangerous-path | 2.1.116 | Sandbox auto-allow no longer bypasses dangerous-path check for `rm`/`rmdir` targeting `/`, `$HOME`, critical system dirs | Prior auto-allow escape hatch |
| `/config` search option values | 2.1.116 | Search matches option values, not just keys (e.g. `vim` finds Editor mode) | Keys-only search |
| Slash empty-state | 2.1.116 | Slash command menu shows "No commands match" when filter has zero results | Menu disappeared |
| Bash `gh` rate-limit hint | 2.1.116 | Bash surfaces a hint when `gh` hits GitHub API rate limit — helps agents back off | Blind retry on 403 |
| Usage tab immediate | 2.1.116 | Settings Usage tab renders 5-hour/weekly usage immediately, with fallback when `/usage` endpoint is rate-limited | Blank Usage tab during rate-limit |
| `/terminal-setup` scroll | 2.1.116 | Configures VS Code/Cursor/Windsurf editor scroll sensitivity for smoother fullscreen scrolling | Default terminal scroll feels stuttery in IDE terminals |
| `/resume` fast on large sessions | 2.1.116 | Up to 67% faster on 40 MB+ sessions; MCP stdio startup parallelized, `resources/templates/list` deferred to first `@`-mention | Long `/resume` wait on big sessions |
| Agent `mcpServers:` main-thread | 2.1.117 | Agent frontmatter `mcpServers:` loads for `--agent` main-thread sessions — parallels 2.1.116 agent hooks main-thread behavior | Main-thread agent missing its declared MCPs |
| `CLAUDE_CODE_FORK_SUBAGENT=1` | 2.1.117 | External builds can opt into forked subagents via env var | Full subagent spawn on external builds |
| `plugin install` auto-deps | 2.1.117 | Re-install on already-installed plugin fetches missing dependencies instead of short-circuiting | Manual dep fetch after partial install |
| Marketplace auto-deps | 2.1.117 | `claude plugin marketplace add` auto-resolves missing dependencies from configured marketplaces | Manual resolution of marketplace deps |
| Managed marketplace enforcement | 2.1.117 | `blockedMarketplaces`/`strictKnownMarketplaces` enforced on plugin install/update/refresh/autoupdate | Policy bypass on later operations |
| `/model` persists across restarts | 2.1.117 | Selections persist even when project pins a different model; startup header shows pin source | Pin lost on restart |
| `/resume` large-session summary | 2.1.117 | `/resume` offers to summarize stale large sessions before re-reading | Full re-read of stale sessions |
| OTEL `command_name`/`command_source` | 2.1.117 | `user_prompt` OTEL events distinguish user-typed slash commands from model-invoked ones | No slash-command attribution in analytics |
| OTEL `effort` attr | 2.1.117 | `cost.usage`, `token.usage`, `api_request`, `api_error` include effort attribute | No per-effort cost breakdown |
| Opus/Sonnet 4.6 default effort | 2.1.117 | **Pro/Max subscribers on Opus 4.6 + Sonnet 4.6 now default to `high` (was `medium`)** — skills assuming medium-default get wrong cost expectations | Medium-default cost assumptions off by ~2-3× |
| Advisor Tool (experimental) | 2.1.117 | New experimental tool; dialog has experimental label + learn-more link | Previous stuck-session errors on Advisor tool |
| `cleanupPeriodDays` expansion | 2.1.117 | Retention sweep now covers `~/.claude/tasks/`, `~/.claude/shell-snapshots/`, `~/.claude/backups/` | Tasks/snapshots/backups retained indefinitely |
| Native `bfs`/`ugrep` | 2.1.117 | Native builds replace Glob/Grep tools with embedded `bfs` and `ugrep` via Bash | Slower tree-traversal on native builds |
| Opus 4.7 `/context` fix | 2.1.117 | `/context` correctly computes against 1M window (was showing inflated 200K percentage) | Early autocompact on Opus 4.7 1M sessions |

## Prompt Caching Recommendation

For API-key, Bedrock, Vertex, or Foundry users running long OrchestKit sessions (brainstorm, implement, cover chains), enable 1-hour prompt caching:

```bash
export ENABLE_PROMPT_CACHING_1H=1
```

This extends the prompt cache TTL from 5 minutes to 1 hour, significantly reducing token costs when:
- Returning to a session after brief breaks
- Running multi-phase skills that exceed the 5-minute cache window
- Using `/loop` or scheduled tasks with intervals > 5 minutes

**Note:** Since CC 2.1.110, session recap is enabled by default even with telemetry disabled. Opt out via `/config` or `CLAUDE_CODE_ENABLE_AWAY_SUMMARY=0`. On CC 2.1.108-2.1.109, users with `DISABLE_TELEMETRY=1` must set `CLAUDE_CODE_ENABLE_AWAY_SUMMARY=1` manually.

Doctor should check for this env var and recommend it when:
- User is on API key / Bedrock / Vertex / Foundry (not subscription)
- Session has been active for > 30 minutes
- `ENABLE_PROMPT_CACHING_1H` is not set

## Version Detection

The doctor skill checks the CC version at runtime:

```bash
# CC reports version via environment or CLI
claude --version  # Returns e.g. "2.1.47"
```

## Compatibility Levels

| CC Version | Support Level | Description |
|-----------|--------------|-------------|
| &lt; 2.1.7 | Unsupported | Core hook protocol missing |
| 2.1.7 - 2.1.44 | Degraded | Missing memory improvements, worktree fixes, Windows support |
| 2.1.45 - 2.1.46 | Partial | Missing 2.1.47 features but functional |
| 2.1.47 - 2.1.49 | Partial | All hook features, memory leak risk in long sessions |
| 2.1.50 - 2.1.58 | Partial | Memory leaks fixed, missing auto-memory and @imports |
| 2.1.59 - 2.1.62 | Partial | Auto-memory, @imports, missing HTTP hooks and 2.1.69 features |
| 2.1.63 - 2.1.68 | Partial | HTTP hooks, worktree config sharing, missing InstructionsLoaded/once:true/ask |
| >= 2.1.69 | Full | InstructionsLoaded, once:true, outputAsk, path-scoped rules |
| >= 2.1.72 | Full | ExitWorktree, agent model override, effort simplification, prompt cache 12x |
| >= 2.1.76 | Full | MCP elicitation, PostCompact hook, /effort command |
| >= 2.1.78 | Full | StopFailure event, CLAUDE_PLUGIN_DATA, agent effort/maxTurns frontmatter |
| >= 2.1.80 | Full | rate_limits in StatusLine, skill effort frontmatter, --channels preview |
| >= 2.1.83 | Full | CwdChanged/FileChanged events, managed-settings.d/, sandbox.failIfUnavailable |
| >= 2.1.84 | Full | TaskCreated event, paths: glob, CLAUDE_STREAM_IDLE_TIMEOUT_MS, MCP non-blocking startup |
| >= 2.1.85 | Full | PreToolUse for AskUserQuestion, headless responder hooks |
| >= 2.1.86 | Full | Config disk write fix, Write/Edit outside project root |
| >= 2.1.75 | Full++++++ | 1M context default, memory timestamps, hook source display, token estimation fix |
| >= 2.1.76 | Full+++++++ | PostCompact hook, Elicitation hooks, worktree.sparsePaths, /effort, bg agent partial results |
| >= 2.1.77 | Full++++++++ | 64k/128k output, allowRead sandbox, plugin validate, SendMessage auto-resume, PreToolUse deny fix |
| >= 2.1.78 | Full+++++++++ | StopFailure hooks, CLAUDE_PLUGIN_DATA, agent frontmatter, plugin validate, worktree skills fix |
| >= 2.1.79 | Full++++++++++ | --console auth, /remote-control, multi-dir PLUGIN_SEED_DIR, turn duration toggle |
| >= 2.1.80 | Full+++++++++++ | rate_limits statusline, effort frontmatter, --channels, source:settings marketplace, --resume parallel fix |
| >= 2.1.81 | Full++++++++++++ | --bare eval mode, --channels permission relay, plugin re-clone freshness, worktree resume, bg agent race fix |
| >= 2.1.83 | Full+++++++++++++ | managed-settings.d/, CwdChanged/FileChanged hooks, sandbox.failIfUnavailable, initialPrompt, userConfig, env scrub |
| >= 2.1.84 | Full++++++++++++++ | TaskCreated hook, WorktreeCreate HTTP, paths: globs, ANTHROPIC_DEFAULT_*, stream timeout, MCP 2KB cap, json-schema fix |
| >= 2.1.88 | Full+++++++++++++++ | PermissionDenied hook, auto permission mode, absolute file_path, compound if matching, NO_FLICKER |
| >= 2.1.89 | Full++++++++++++++++ | defer permission, TaskCreated blocking, MCP_CONNECTION_NONBLOCKING, named subagent typeahead, hook disk spill |
| >= 2.1.90 | Full+++++++++++++++++ | /powerup, PLUGIN_KEEP_MARKETPLACE, .husky protected, exit code 2 fix, format-on-save fix, 3x perf |
| >= 2.1.91 | Full | MCP result size override, disableSkillShellExecution, plugin bin/, Edit shorter anchors, transcript fix |
| >= 2.1.92 | Full | forceRemoteSettingsRefresh, Stop hook preventContinuation fix, tool input JSON-string fix, Write perf, tmux pane fix |
| >= 2.1.94 | Minimum | **Skill frontmatter hooks fix (unlocks 20 context loaders), sessionTitle hook output, keep-coding-instructions, default effort high, rate-limit 429 surface, --resume across worktrees, CJK stream-json fix — current minimum** |
| >= 2.1.95 | Full | MCP tool description 2KB cap, local MCP config dedup (npm-only release) |
| >= 2.1.96 | Full | Bedrock bearer token 403 hotfix (2.1.94 regression) |
| >= 2.1.97 | Full | refreshInterval status line, workspace.git_worktree, Stop/SubagentStop long-session fix, subagent cwd leak fix, plugin update fix, Bash permissions hardened, TRACEPARENT OTEL, image compression parity, 429 exponential backoff, MCP memory leak fix, transcript optimization |
| >= 2.1.101 | Full | /team-onboarding, OS CA cert trust, deny-overrides-ask, subagent dynamic MCP, worktree agent file access, focus mode summaries, settings resilience |
| >= 2.1.105 | Full | EnterWorktree path param, PreCompact blocking (exit code 2 / decision:block), plugin monitors manifest, skill description cap 1536 chars, WebFetch script stripping, stale worktree squash cleanup |
| >= 2.1.108 | Full | ENABLE_PROMPT_CACHING_1H for 1-hour cache TTL (major cost savings), /recap session context restoration, Skill tool auto-discovery of built-in commands, model switch warning, lazy language grammars (lower memory), rate limit distinction, agent auto-classifier fix |
| >= 2.1.110 | **Recommended** | **/tui fullscreen rendering, PushNotification tool for long sessions, /focus command (replaces Ctrl+O), Bash max timeout enforced, Write user-edit signal, session recap default-on (no env var needed), --resume resurrects scheduled tasks, /doctor MCP duplicate warning, Remote Control commands (/autocompact, /context, /exit, /reload-plugins), SDK TRACEPARENT/TRACESTATE auto-propagation** |

## Doctor Check Implementation

The doctor skill validates CC version in category 10:

```
Claude Code: 2.1.47 (OK)
- Minimum required: 2.1.47
```

When CC version is below 2.1.47, doctor should show:

```
Claude Code: 2.1.44 (DEGRADED)
- Minimum required: 2.1.47
- Missing features:
  - last_assistant_message (Stop/SubagentStop context)
  - added_dirs (multi-directory support)
  - Windows hook execution
  - Worktree discovery
  - Deferred SessionStart
- Upgrade: npm install -g @anthropic-ai/claude-code@latest
```

## Memory Leak Warning (CC &lt; 2.1.50)

CC 2.1.50 fixed 8 memory leaks affecting long-running sessions:
- Agent teams: completed teammate tasks never garbage collected
- Task state objects never removed from AppState
- TaskOutput retained data after cleanup
- CircularBuffer cleared items retained in backing array
- Shell execution: ChildProcess/AbortController refs retained after cleanup
- LSP diagnostic data never cleaned up after delivery
- File history snapshots: unbounded growth
- Internal caches not cleared after compaction (fixed in 2.1.63)

**Recommendation:** If CC version &lt; 2.1.50, warn user to upgrade for long sessions.

Doctor should display when CC &lt; 2.1.50:

```
Claude Code: 2.1.4x (MEMORY LEAK RISK)
- 8 memory leaks fixed in 2.1.50 affect long-running sessions
- Symptoms: increasing memory usage, slower responses over time
- Upgrade: npm install -g @anthropic-ai/claude-code@latest
```

## Release Channel Detection

Doctor should detect and display the release channel alongside the CC version check. The version is read from `.claude-plugin/plugin.json` or `version.txt`.

| Version Pattern | Channel | Stability |
|----------------|---------|-----------|
| `X.Y.Z` (no suffix) | stable | Production-ready |
| `X.Y.Z-beta.N` | beta | Feature-complete, may have bugs |
| `X.Y.Z-alpha.N` | alpha | Experimental, expect breaking changes |

When on beta or alpha, doctor should append a pre-release reminder to the compatibility output:

```
Claude Code: 2.1.56 (OK)
- Minimum required: 2.1.56
- OrchestKit channel: beta (v7.0.0-beta.3)
  ⚠ Pre-release version — some features may be unstable. Report issues at github.com/yonatangross/orchestkit/issues
```

On stable, no extra warning is needed — just include the channel line:

```
Claude Code: 2.1.56 (OK)
- Minimum required: 2.1.56
- OrchestKit channel: stable (v7.0.0)
```

## OrchestKit Version History

| OrchestKit | Min CC | Key Changes |
|-----------|--------|-------------|
| v7.83.x | 2.1.125 | **M131 — CC 2.1.128 adoption (1 PR): floor 2.1.122 → 2.1.125, latest 2.1.126 → 2.1.128, 7 new matrix entries (`enter_worktree_branch_from_head`, `workspace_reserved_mcp_name`, `plugin_dir_zip_archives`, `channels_console_auth`, `init_plugin_errors_plugin_dir`, `subagent_idle_summary_capped`, `plugin_update_npm_detection_fix`); release-engineer agent documents `.zip` plugin distribution path; setup skill documents `channelsEnabled: true` for `--channels` + console auth; eval-runner agent picks up expanded `init.plugin_errors` covering `--plugin-dir` failures (was marketplace-only since 2.1.111); EnterWorktree branch-from-HEAD audit confirmed no stale "commit before worktree" guidance across 38 skill/agent mentions; M128 backfill of 2.1.122/2.1.126 matrix entries deferred (features adopted in skills/docs without runtime gates)** |
| v7.80.x | 2.1.122 | **M128 — CC 2.1.122 + 2.1.126 adoption (5 issues, 1 PR): floor 2.1.118 → 2.1.122, OTEL `invocation_trigger` attribute on `claude_code.skill_activated` (CC 2.1.126) surfaced in `/ork:analytics` skill-trigger breakdown, `claude project purge --dry-run` wired into `/ork:doctor` stale-project diagnostic + `/ork:dream` summary hint, `--dangerously-skip-permissions` scope expansion (`.git/`, `.vscode/`, shell rcs) documented in security-patterns/setup/hooks-README, OTEL numeric-attr type-safe ingestion verified for CC 2.1.122+, `claude_code.at_mention` event ingestion decision recorded** |
| v7.70.x | 2.1.118 | **M122 — CC 2.1.118 + 2.1.119 adoption (8 issues, 1 PR): floor 2.1.117 → 2.1.118, 17 new matrix entries, PostToolUse `duration_ms` threaded through posttool hooks, OTEL `tool_use_id` + `tool_input_size_bytes` documented, `--from-pr` multi-host (GitLab/Bitbucket/GHE) in review-pr/create-pr/fix-issue, `--print` honors agent `tools:`/`disallowedTools:` in bare-eval, pilot adoption of `type: "mcp_tool"` hook type, `claude plugin tag` wired into release-please workflow, three new chain-patterns refs (mcp-tool-hooks.md, pr-from-platform.md, plugin-tag.md)** |
| v7.69.x | 2.1.117 | **M117 closeout (2 issues, 1 PR): `/ork:doctor` warns on HIGH-tier MCP `@latest` pinning (closes #1462), fast-check property tests for 9 hook handlers + input validator (closes #1452), defensive-input hardening tracked separately as #1497 in M119** |
| v7.50.x | 2.1.111 | **CC 2.1.111 + Opus 4.7 adoption (23 issues, 1 PR): MIN_CC_VERSION 2.1.108 → 2.1.111, 17 new matrix entries (311 total), `xhigh` effort tier across 7 phase-based skills, token budgets converted to %-of-context via new `lib/context-window.ts`, `ork:review-pr` composes `/ultrareview` gated by sensitive-path/diff-size triggers via `AskUserQuestion`, eval preflight catches `plugin_errors` on stream-json init, 2,576px vision ceiling in design/UI skills, doctor Category 14 detects xhigh-without-Opus-4.7, retry-policy audit with rationale comments** |
| v7.44.x | 2.1.108 | **CC 2.1.108 adoption: 25 new matrix entries (278 total), ENABLE_PROMPT_CACHING_1H env var, /recap session context, Skill tool auto-discovery, model switch warning, lazy language grammars, EnterWorktree path param, PreCompact blocking, plugin monitors manifest key, skill description cap 1536 chars, expanded 11 user-invocable skill descriptions** |
| v7.38.x | 2.1.101 | **CC 2.1.101 adoption + frontmatter audit: 26 skill frontmatter fixes (context/agent fields now enforced), deny-overrides-ask behavior, subagent dynamic MCP inheritance, worktree agent file access, /team-onboarding command, OS CA cert trust, focus mode self-contained summaries, RemoteTrigger run fix, settings resilience, 18 new matrix entries (253 total)** |
| v7.37.x | 2.1.98 | **CC 2.1.98 adoption: Monitor tool for streaming background events, SCRIPT_CAPS env var, partial progress from failed bg subagents, hook stderr in transcript, /agents tabbed layout, /reload-plugins skill discovery, Bash permission hardening (backslash escape fix, compound cmd fix), stale worktree cleanup fix, team permission inheritance, Vertex AI wizard, Perforce mode** |
| v7.33.x | 2.1.97 | **CC 2.1.97 full utilization: refreshInterval status line, workspace.git_worktree awareness, TRACEPARENT OTEL tracing to HQ, Stop/SubagentStop long-session fix, subagent cwd leak fix, MCP 2KB cap guardrail, image compression parity, Bash permissions hardened, Accept Edits env-prefix, plugin update fix, prototype settings.json fix** |
| v7.30.x | 2.1.94 | **Skill frontmatter hooks unlock (20 context loaders activated), sessionTitle on UserPromptSubmit, keep-coding-instructions, default effort high adaptation, --resume across worktrees, CJK stream-json fix, Bedrock bearer token 2.1.96 hotfix** |
| v7.29.x | 2.1.92 | forceRemoteSettingsRefresh policy, Stop hook preventContinuation fix, tool input JSON-string fix, plugin MCP dedup fix, Write perf 60%, /tag + /vim removed, MCP result size override, disableSkillShellExecution, plugin bin/, Edit shorter anchors |
| v7.27.x | 2.1.90 | /powerup, PLUGIN_KEEP_MARKETPLACE, .husky protected, exit code 2 fix, format-on-save fix, 3x perf improvements |
| v7.24.x | 2.1.84 | TaskCreated hook, WorktreeCreate HTTP, paths: glob lists, ANTHROPIC_DEFAULT_* env vars, stream idle timeout, json-schema fix |
| v7.23.x | 2.1.83 | managed-settings.d/, CwdChanged/FileChanged hooks, sandbox.failIfUnavailable, initialPrompt, userConfig sensitive, env scrub |
| v7.15.x | 2.1.80 | effort frontmatter, rate_limits statusline, --channels, source:settings, simplified plugin tips |
| v7.14.x | 2.1.79 | --console auth, /remote-control, multi-dir PLUGIN_SEED_DIR, turn duration toggle |
| v7.14.x | 2.1.78 | StopFailure hooks, CLAUDE_PLUGIN_DATA, agent frontmatter, plugin validate, worktree skills fix |
| v7.12.x | 2.1.77 | 64k/128k output, allowRead sandbox, plugin validate, SendMessage auto-resume, PreToolUse deny fix |
| v7.8.x | 2.1.76 | PostCompact hook, Elicitation hooks, sparse paths, /effort, bg agent partial results |
| v7.7.x | 2.1.75 | 1M context default, memory timestamps, hook source display, token estimation fix |
| v7.5.x | 2.1.74 | SessionEnd timeout fix, managed policy precedence, full model IDs, memory fixes |
| v7.4.x | 2.1.73 | Deadlock fix, SessionStart fix, no-op fix, Opus 4.6 cloud default |
| v7.1.x | 2.1.69 | InstructionsLoaded, once:true loaders, outputAsk, env var HTTP hooks, worktree dedup |
| v7.0.x | 2.1.59 | Auto-memory, @imports, ConfigChange, HTTP hooks (2.1.63+), unified plugin |
| v6.0.x | 2.1.47 | Full CC 2.1.47 adoption, relaxed context limits |
| v5.x | 2.1.34 | Agent Teams support, unified dispatchers |
| v4.x | 2.1.9 | Session tracking, TypeScript hooks |

