# DX-83: 多 Agent 环境下的 Subagent 支持与降级策略

**Status**: Draft
**Created**: 2026-01-04
**Priority**: High
**Type**: Enhancement
**Related**: DX-81 (Multi-Agent Init)

---

## Problem

### 当前状态

#### Subagent 依赖场景

多个 Invar skills 依赖 **isolated subagent** 实现核心价值：

| Skill | Subagent 用途 | 硬编码 Model | 必要性 |
|-------|---------------|--------------|--------|
| `/review` | 每轮 review (fresh eyes) | `model=opus` | **MANDATORY** |
| `/develop` (VALIDATE) | 非平凡实现验证 (>3 函数或 >200 行) | `model=opus` | **MANDATORY** |
| `/acceptance --deep` | 深度验证 (default) | 未指定 | Optional |
| `/security --deep` | 安全审计 (default) | 未指定 | Optional |

**核心问题：**
```markdown
# .claude/skills/review/SKILL.md:14
1. **EVERY round MUST spawn isolated subagent** (Task tool with model=opus)
```

#### Agent 能力差异

DX-81 实现多 agent 支持后，不同 agent 的能力差异暴露：

| Agent | Task Tool | Subagent Support | Model Access |
|-------|-----------|------------------|--------------|
| **Claude Code** | ✅ | ✅ | sonnet, opus, haiku |
| **Windsurf** | ✅ | ✅ | sonnet, opus, haiku |
| **Pi** | ❌ | ❌ | sonnet (via API) |
| **Cursor** | ❌ | ❌ | 各种模型 (via API) |

---

### 问题 1: Skill 文档硬编码 Model

**现状：**
```markdown
# review/SKILL.md
1. **EVERY round MUST spawn isolated subagent** (Task tool with model=opus)

# develop/SKILL.md
2. Spawn Isolated VALIDATOR (Task tool, model=opus):
```

**问题：**
1. **违反配置分离原则** - model 选择应该是配置，不是硬编码
2. **无法尊重用户偏好** - 用户可能想用 sonnet 节省成本
3. **无法适配 agent 环境** - Pi 通过 API 调用，无 opus 访问权限

**影响：**
- 用户无法自定义 model 偏好
- 与全局 model 设置冲突（如 `/model sonnet`）
- 跨 agent 环境时行为不一致

---

### 问题 2: 共享 Skill 无法适配双环境

**现状：**
DX-81 后，`.claude/skills/` 被 Claude Code 和 Pi 共享：

```
.claude/skills/
├── review/SKILL.md     ← 同一份文档
├── develop/SKILL.md    ← 同一份文档
└── ...
```

但 skill 文档只描述了一种执行路径（Task tool required），导致：

**在 Pi 环境中：**
```bash
$ pi /review
[Pi reads review/SKILL.md]
"MUST spawn isolated subagent (Task tool)"
→ Pi 尝试调用 Task tool
→ ❌ Tool not available
→ 💥 Skill execution fails
```

**问题：**
- Skill 文档假设 Task tool 总是可用
- 没有 fallback 策略
- Pi 用户无法使用需要 subagent 的 skills

---

### 问题 3: 无能力检测机制

**现状：**
Skills 没有检测 agent 能力的方法：

```markdown
# review/SKILL.md (伪代码)
1. Spawn subagent with Task tool
   → 但如果 Task tool 不可用？
   → 没有检测逻辑
   → 没有 fallback 说明
```

**缺失功能：**
1. **运行时检测** - 无法在 skill 执行时检测 Task tool 是否可用
2. **环境标记** - `invar init` 不记录 agent 能力信息
3. **配置覆盖** - 用户无法强制使用/禁用 subagent

**影响：**
- Skill 无法优雅降级
- 错误信息不明确
- 用户体验差（silent failure 或 hard crash）

---

### 问题 4: Review 降级的价值争议

**核心矛盾：**
`/review` skill 的设计哲学是 **adversarial review with context isolation**：

```markdown
# review/SKILL.md
Code is GUILTY until proven INNOCENT.
Every round spawns isolated subagent reviewing FULL scope.

**Why isolation?**
- Main agent has context contamination from fixing
- "Fresh eyes" impossible in same context
- Round 2+ drifts to "verify my fixes" not "find problems"
```

**哲学问题：**
没有 isolation 的 review 是否还有意义？

**选项 A: Hard Fail**
```
❌ /review requires isolated subagent support
💡 Use Claude Code or manual code review
```
- ✅ 保证质量
- ❌ Pi 用户无法使用

**选项 B: Degraded Mode**
```
⚠️  Running review without isolation (bias risk)
✅ Applying checklist with persona switch
```
- ✅ Pi 用户可以使用
- ❌ 质量大幅降低（⭐⭐ vs ⭐⭐⭐）
- ❌ 可能给用户虚假安全感

---

## Analysis

### 能力检测策略

#### 方案 A: 环境标记（静态检测）

**实现：**
```markdown
# .invar/context.md (auto-generated by `invar init`)
## Agent Environment

Primary Agent: Claude Code
- Task Tool: ✅ Available
- Model Access: sonnet, opus, haiku
- Subagent Support: ✅ Full

Fallback Agent: Pi
- Task Tool: ❌ Not Available
- Model Access: sonnet (API)
- Subagent Support: ❌ None
```

**Skill 检测逻辑：**
```python
# Pseudo-code in skill
def detect_subagent_support() -> bool:
    context = read(".invar/context.md")
    return "Task Tool: ✅" in context
```

**优点：**
- ✅ 明确，无歧义
- ✅ 在 init 时确定，不依赖运行时
- ✅ 用户可见，可手动编辑

**缺点：**
- ❌ 需要维护 context.md 同步
- ❌ 用户可能误编辑
- ❌ 无法处理动态环境变化

---

#### 方案 B: 配置文件（用户控制）

**实现：**
```toml
# .invar/config.toml (new file)
[agent]
type = "claude-code"  # claude-code | pi | windsurf | cursor
task_tool_available = true

[skills]
# Global subagent model preference
subagent_model = "inherit"  # inherit | sonnet | opus | haiku

[skills.review]
execution_mode = "auto"  # auto | isolated | degraded | disabled
subagent_model = "inherit"
skip_degraded_warning = false

[skills.develop]
subagent_model = "inherit"
validate_isolation_threshold = 200  # lines of code
```

**Skill 检测逻辑：**
```python
# Pseudo-code in skill
def get_execution_mode() -> str:
    config = read_toml(".invar/config.toml")

    # User explicit override
    mode = config["skills"]["review"]["execution_mode"]
    if mode != "auto":
        return mode

    # Auto-detect
    if config["agent"]["task_tool_available"]:
        return "isolated"
    else:
        return "degraded"
```

**优点：**
- ✅ 用户可完全控制
- ✅ 支持显式覆盖（`--no-subagent` flag）
- ✅ 配置即文档

**缺点：**
- ❌ 需要新的配置基础设施
- ❌ 配置可能与实际环境不一致

---

#### 方案 C: 运行时检测（动态探测）

**实现：**
```python
# Pseudo-code in skill entry
def detect_task_tool() -> bool:
    try:
        # Attempt no-op Task call
        Task(
            subagent_type="general-purpose",
            prompt="echo test",
            description="capability probe",
            model="haiku"  # cheap model for probe
        )
        return True
    except ToolNotAvailableError:
        return False
```

**优点：**
- ✅ 总是反映实际能力
- ✅ 无需维护配置
- ✅ 动态适应环境变化

**缺点：**
- ❌ 每次 skill 调用都需要探测（性能开销）
- ❌ 依赖 agent 的错误处理机制
- ❌ 可能产生 API 费用（haiku probe）

---

#### 推荐：混合方案（B + C）

1. **配置优先（方案 B）**
   - `invar init` 时检测并写入 `.invar/config.toml`
   - 用户可手动编辑配置

2. **运行时验证（方案 C 简化版）**
   - Skill 入口处检查 Task tool 是否在 available tools list
   - 不执行实际调用，只检查工具列表

3. **用户覆盖**
   - 支持 `--no-subagent` flag 强制降级
   - 支持环境变量 `INVAR_FORCE_DEGRADED=1`

---

### Model 配置层级

**问题根源：**
```markdown
# Current (hardcoded in SKILL.md)
spawn isolated subagent (Task tool with model=opus)
```

**设计原则：**
1. **配置分离** - Model 选择是配置，不是文档
2. **层级覆盖** - Global → Skill → User flag
3. **默认合理** - `inherit` (使用当前 agent 的 model)

**配置层级（优先级从高到低）：**

```toml
# Level 1: User runtime flag (highest priority)
$ /review --model sonnet

# Level 2: Skill-specific config
[skills.review]
subagent_model = "opus"  # Override for this skill

# Level 3: Global skills config
[skills]
subagent_model = "sonnet"  # All skills default

# Level 4: System default (lowest priority)
# Default: "inherit" (use parent agent's current model)
```

**SKILL.md 改造：**
```markdown
# Before (hardcoded)
1. Spawn isolated subagent (Task tool with model=opus)

# After (config-driven)
1. Spawn isolated subagent (Task tool)
   - Model: Follows config `[skills.review].subagent_model`
   - Default: `inherit` (uses current agent model)
   - Override: `--model <name>` flag
```

---

### Degraded Mode 设计

#### 核心问题：质量 vs 可用性

**Isolated Mode (⭐⭐⭐)**
- ✅ Context isolation → fresh eyes
- ✅ Adversarial mindset → finds more issues
- ✅ No bias from implementation history

**Degraded Mode (⭐⭐)**
- ❌ Same context → contamination risk
- ❌ Persona switch only → limited objectivity
- ⚠️  Checklist applied → better than nothing

**Trade-off：**
- **Hard fail**: 保证质量，但 Pi 用户无法使用
- **Degraded mode**: 可用性优先，但质量降低

---

#### 推荐策略：分级降级

| Skill | Without Subagent | Rationale |
|-------|------------------|-----------|
| **review** | **Warn + Degrade** | 降级有限价值，但总比没有好 |
| **develop VALIDATE** | **Warn + Degrade** | Guard 提供基础保障，降级验证可接受 |
| **acceptance --deep** | **Silent Downgrade** → `--standard` | 用户不需要感知 |
| **security --deep** | **Silent Downgrade** → `--standard` | 用户不需要感知 |

**Review Degraded Workflow：**

```markdown
## Mode B: DEGRADED (Fallback)

**When:** Task tool not available OR `--no-subagent` flag

### Entry Warning

⚠️  REVIEW DEGRADED MODE

Agent doesn't support Task tool. Running best-effort review:

  ✅ Full checklist verification
  ✅ Multi-round fix loop
  ❌ NO context isolation
  ❌ NO fresh-eyes objectivity

Bias Risk: Agent may have implementation history in context.
Quality: ⭐⭐ (vs ⭐⭐⭐ with isolation)

Recommendation:
  • For production: Use Claude Code (`invar init --claude`)
  • For quick checks: Proceed with degraded mode

Proceed? [Y/n]

### Degraded Execution

1. **Persona Switch** (instead of isolation)
   ```
   🔄 Switching to Reviewer Persona

   I am now a CRITICAL code reviewer.
   Acknowledging limitations:
   - I may have seen this code before
   - Context contamination risk exists
   - This is DEGRADED vs isolated review
   ```

2. **Same Checklist, Extra Vigilance**
   - Apply full checklist (A-G)
   - Explicitly note bias risk in each finding
   - Be conservative (flag more issues when uncertain)

3. **Report Tagging**
   ```
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
   📋 REVIEW COMPLETE [DEGRADED MODE]
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

   ⚠️  Reviewed without context isolation
   ⚠️  Bias risk: Agent may have seen code before
   ✅ Checklist applied, objectivity limited

   Recommendation: Re-review with isolated agent before production.
   ```
```

---

## Proposal

### Solution Overview

**3-Tier Architecture:**

```
┌────────────────────────────────────────────────────┐
│ Tier 1: Configuration Layer                       │
├────────────────────────────────────────────────────┤
│ .invar/config.toml                                 │
│ - Agent capabilities                               │
│ - Model preferences (global + per-skill)           │
│ - Execution mode overrides                         │
└────────────────────────────────────────────────────┘
                        ↓
┌────────────────────────────────────────────────────┐
│ Tier 2: Skill Documentation (Dual-Path)           │
├────────────────────────────────────────────────────┤
│ .claude/skills/*/SKILL.md                          │
│ - Mode A: ISOLATED (Task tool available)          │
│ - Mode B: DEGRADED (fallback)                     │
│ - Detection logic                                  │
│ - User warnings                                    │
└────────────────────────────────────────────────────┘
                        ↓
┌────────────────────────────────────────────────────┐
│ Tier 3: Runtime Execution                         │
├────────────────────────────────────────────────────┤
│ Agent detects capabilities → Chooses path         │
│ - Check config override                            │
│ - Detect Task tool                                 │
│ - Show warnings if degraded                        │
│ - Execute with appropriate mode                    │
└────────────────────────────────────────────────────┘
```

---

### Phase A: Configuration Infrastructure

**Goal:** 创建配置基础设施，支持 model 偏好和能力标记

#### A1: 创建配置模板

**File:** `src/invar/templates/config.toml` (new)

```toml
# Invar Configuration
# Generated by: invar init
# Version: 5.0

[agent]
# Primary agent type (auto-detected during init)
type = "claude-code"  # claude-code | pi | windsurf | cursor | other

# Task tool availability (auto-detected)
# Set to false to force degraded mode for all skills
task_tool_available = true

[skills]
# ==========================================
# Global Skill Settings
# ==========================================

# Model preference for subagents (when Task tool available)
# Options:
#   "inherit" - Use current agent's active model (default)
#   "sonnet"  - Always use Claude Sonnet 4.5
#   "opus"    - Always use Claude Opus 4.5
#   "haiku"   - Always use Claude Haiku 4
subagent_model = "inherit"

# ==========================================
# Skill-Specific Overrides
# ==========================================

[skills.review]
# Execution mode
# Options:
#   "auto"     - Auto-detect (isolated if available, else degraded)
#   "isolated" - Require Task tool (fail if not available)
#   "degraded" - Force degraded mode even if Task tool available
#   "disabled" - Disable this skill entirely
execution_mode = "auto"

# Model for review subagents (overrides global)
subagent_model = "inherit"

# Skip degraded mode warning
skip_degraded_warning = false

[skills.develop]
# Model for validation subagents
subagent_model = "inherit"

# Threshold for requiring isolated validation (lines of code)
# Below this threshold, degraded mode is acceptable
validate_isolation_threshold = 200

[skills.acceptance]
# Default mode (--quick | --standard | --deep)
default_mode = "deep"

[skills.security]
# Default mode (--quick | --standard | --deep)
default_mode = "deep"
```

**Exit Criteria:**
- ✅ Template file created
- ✅ Schema documented in comments
- ✅ Defaults match current behavior

---

#### A2: 配置读取函数

**File:** `src/invar/shell/config.py` (extend)

```python
from pathlib import Path
from returns import Result, Success, Failure
import tomllib

@pre(lambda project_root: isinstance(project_root, Path))
def get_skill_config(
    project_root: Path,
    skill_name: str
) -> Result[dict[str, Any], str]:
    """
    Read skill-specific configuration.

    Merges global and skill-specific settings with proper precedence.

    Examples:
        >>> config = get_skill_config(Path("."), "review")
        >>> config.unwrap()["execution_mode"]
        'auto'
    """
    config_path = project_root / ".invar" / "config.toml"

    if not config_path.exists():
        # Return defaults if no config
        return Success(get_default_skill_config(skill_name))

    result = _read_toml(config_path)
    if isinstance(result, Failure):
        return result

    data = result.unwrap()

    # Merge global + skill-specific
    global_skills = data.get("skills", {})
    skill_specific = global_skills.get(skill_name, {})

    # Global defaults
    merged = {
        "subagent_model": global_skills.get("subagent_model", "inherit"),
    }

    # Skill-specific overrides
    merged.update(skill_specific)

    return Success(merged)


def get_default_skill_config(skill_name: str) -> dict[str, Any]:
    """Get hardcoded defaults for a skill."""
    defaults = {
        "review": {
            "execution_mode": "auto",
            "subagent_model": "inherit",
            "skip_degraded_warning": False,
        },
        "develop": {
            "subagent_model": "inherit",
            "validate_isolation_threshold": 200,
        },
        "acceptance": {
            "default_mode": "deep",
        },
        "security": {
            "default_mode": "deep",
        },
    }
    return defaults.get(skill_name, {})


@pre(lambda project_root: isinstance(project_root, Path))
def detect_agent_capabilities(project_root: Path) -> dict[str, Any]:
    """
    Detect current agent's capabilities.

    Called during `invar init` to populate config.toml.

    Returns:
        {
            "type": "claude-code" | "pi" | "windsurf" | "cursor" | "other",
            "task_tool_available": bool,
        }
    """
    # Detection heuristics:
    # 1. Check for Claude Code indicators (.claude/ exists and was created by us)
    # 2. Check for Pi indicators (.pi/ exists and was created by us)
    # 3. Check environment variables (INVAR_AGENT_TYPE)
    # 4. Default to "other" with task_tool_available=false

    if (project_root / ".claude").exists():
        return {"type": "claude-code", "task_tool_available": True}
    elif (project_root / ".pi").exists():
        return {"type": "pi", "task_tool_available": False}
    else:
        # Conservative default
        return {"type": "other", "task_tool_available": False}
```

**Exit Criteria:**
- ✅ `get_skill_config()` with tests
- ✅ `detect_agent_capabilities()` with heuristics
- ✅ Proper merging logic (global → skill-specific)

---

#### A3: 在 init 时生成配置

**File:** `src/invar/shell/commands/init.py` (extend)

```python
def _generate_config_file(project_root: Path, agents: list[str]) -> Result[None, str]:
    """
    Generate .invar/config.toml with auto-detected capabilities.

    Args:
        agents: List of enabled agents (["claude", "pi"])
    """
    capabilities = detect_agent_capabilities(project_root)

    # Load template
    template_path = get_template_path("config.toml")
    template = template_path.read_text(encoding="utf-8")

    # Substitute detected values
    config_content = template.replace(
        'type = "claude-code"',
        f'type = "{capabilities["type"]}"'
    ).replace(
        'task_tool_available = true',
        f'task_tool_available = {str(capabilities["task_tool_available"]).lower()}'
    )

    # Write config
    config_path = project_root / ".invar" / "config.toml"
    config_path.write_text(config_content, encoding="utf-8")

    return Success(None)


# In init_command():
# After creating .invar/ directory:
result = _generate_config_file(project_root, enabled_agents)
if isinstance(result, Failure):
    console.print(f"[yellow]Warning:[/yellow] {result.failure()}")
```

**Exit Criteria:**
- ✅ `invar init` 生成 `.invar/config.toml`
- ✅ 自动检测 agent 类型和能力
- ✅ 支持多 agent 场景（如 `--claude --pi` 选主 agent）

---

### Phase B: Skill Documentation (Dual-Path)

**Goal:** 改造 skill 文档，支持双执行路径（isolated + degraded）

#### B1: Review Skill 改造

**File:** `.claude/skills/review/SKILL.md`

**Changes:**

1. **Frontmatter 更新**
   ```yaml
   ---
   name: review
   description: Adversarial code review with context isolation when available
   _invar:
     version: "8.0"  # DX-83: Multi-agent support
     managed: skill
     capabilities:
       recommended: ["task_tool"]  # Not required, but recommended
   ---
   ```

2. **添加 "Execution Modes" 章节**
   ```markdown
   ## Execution Modes (DX-83)

   This skill adapts to agent capabilities:

   | Mode | Requirements | Quality |
   |------|--------------|---------|
   | **ISOLATED** | Task tool available | ⭐⭐⭐ Full adversarial review |
   | **DEGRADED** | Task tool NOT available | ⭐⭐ Best-effort review |

   **Default:** Auto-detect and use best available mode.
   **Override:** Use `--no-subagent` flag to force degraded mode.
   ```

3. **重构为两个路径**
   - **Mode A: ISOLATED** - 现有的完整 workflow
   - **Mode B: DEGRADED** - 新增的降级 workflow

4. **添加检测逻辑说明**
   ```markdown
   ## Agent Instructions

   **At skill entry, detect execution mode:**

   ```python
   # Step 1: Check user override
   if "--no-subagent" in args:
       mode = "degraded"

   # Step 2: Check config
   config = read_config(".invar/config.toml")
   if config["skills"]["review"]["execution_mode"] != "auto":
       mode = config["skills"]["review"]["execution_mode"]

   # Step 3: Auto-detect
   elif task_tool_available():
       mode = "isolated"
   else:
       mode = "degraded"

   # Execute
   if mode == "isolated":
       execute_isolated_review()
   else:
       show_degraded_warning()
       if user_confirms():
           execute_degraded_review()
   ```

**Full degraded mode workflow:**
```markdown
## Mode B: DEGRADED (Fallback)

**When:** Task tool not available OR `--no-subagent` flag

### Entry Warning

⚠️  REVIEW DEGRADED MODE

Agent doesn't support Task tool. Running best-effort review:

  ✅ Full checklist verification
  ✅ Multi-round fix loop
  ❌ NO context isolation
  ❌ NO fresh-eyes objectivity

Bias Risk: Agent may have seen this code before.
Quality: ⭐⭐ (vs ⭐⭐⭐ with isolation)

Recommendation:
  • For production: Use Claude Code (`invar init --claude`)
  • For quick checks: Proceed with degraded mode

Proceed? [Y/n]

### Workflow

1. **Persona Switch** (instead of isolation)

   Display:
   ```
   🔄 Switching to Reviewer Persona [DEGRADED]

   I am now a CRITICAL code reviewer.
   Acknowledging limitations:
   - May have implementation context
   - Context contamination risk
   - Degraded vs isolated review

   Applying extra vigilance to compensate.
   ```

2. **Review Execution**

   - Apply same scope classification (SMALL/MEDIUM/LARGE)
   - Use same checklist (A-G)
   - Same fix loop (max 5 rounds)
   - **Difference:** No subagent spawn, persona switch only

3. **Report Tagging**

   All output must include degraded mode indicator:

   ```
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
   📋 REVIEW COMPLETE [DEGRADED MODE]
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

   ⚠️  Reviewed without context isolation
   ⚠️  Objectivity limited by context contamination
   ✅ Checklist applied with extra vigilance

   **Rounds:** N / 5
   **Issues Found:** X critical, Y major, Z minor

   💡 Recommendation: Re-review with isolated agent before production.
      Run: `invar init --claude` then `/review`
   ```

### Configuration

Skip warning with:
```toml
[skills.review]
skip_degraded_warning = true
```
```

**Exit Criteria:**
- ✅ Dual-path 文档完整
- ✅ Degraded mode 明确标注
- ✅ 检测逻辑清晰描述

---

#### B2: Develop Skill 改造

**File:** `.claude/skills/develop/SKILL.md`

**Changes:**

1. **VALIDATE 章节改造**

   ```markdown
   ### 4. VALIDATE

   - Run `invar_guard()` (full verification)
   - All TodoWrite items complete
   - Integration works (if applicable)

   #### Isolation Requirement (DX-83 Update)

   **For non-trivial implementations, VALIDATE has two modes:**

   | Mode | When | Quality |
   |------|------|---------|
   | **ISOLATED** | Task tool + threshold exceeded | ⭐⭐⭐ Objective |
   | **DEGRADED** | No Task tool OR below threshold | ⭐⭐ Self-check |

   **Threshold:** Lines of code in changed files (default: 200)
   - Configure: `[skills.develop].validate_isolation_threshold`

   ---

   **Mode A: ISOLATED (>200 lines OR >3 functions)**

   [Existing isolated validator workflow]

   ---

   **Mode B: DEGRADED (<200 lines OR no Task tool)**

   ```
   📍 VALIDATE — Degraded mode (no isolation)

   ⚠️  Context contamination risk (you built this code)

   Fallback: Extended self-verification
   • Running invar_guard (full) ✅
   • Manual checklist walk-through ✅
   • Explicit bias acknowledgment ⚠️

   💡 For isolated validation: Use Claude Code
   ```

   **Degraded Checklist:**
   1. Run `invar_guard()` - must pass
   2. Re-read contracts - do they match implementation?
   3. Re-read tests - do they cover edge cases?
   4. Imagine you're the reviewer - what would you question?
   5. Acknowledge: "I built this, bias exists, extra care applied"

   **Report:**
   ```
   ✓ Final: guard PASS | 0 errors, 2 warnings [SELF-VERIFIED]

   ⚠️  Validated without isolation (builder bias risk)
   ✅ Guard passed, manual checklist applied
   💡 Recommend: Have isolated review before merge
   ```
   ```

**Exit Criteria:**
- ✅ VALIDATE 双路径文档
- ✅ 阈值配置化
- ✅ Degraded mode 明确局限性

---

#### B3: Acceptance & Security 简化

**Files:**
- `.claude/skills/acceptance/SKILL.md`
- `.claude/skills/security/SKILL.md`

**Changes:**

1. **简化降级说明**
   ```markdown
   ## Execution Modes

   | Mode | Isolation | Default |
   |------|-----------|---------|
   | `--deep` | Isolated subagent | ✅ (auto-downgrade to `--standard` if no Task tool) |
   | `--standard` | Same context | |
   | `--quick` | Same context | |

   **Auto-downgrade behavior:**
   - If `--deep` requested but Task tool not available
   - Silent downgrade to `--standard`
   - Note in output: `[AUTO: deep→standard (no isolation)]`
   ```

2. **无需用户确认**
   - Acceptance 和 Security 的降级是可接受的
   - 静默执行，只在输出中标注

**Exit Criteria:**
- ✅ 简化的降级逻辑
- ✅ 静默降级，输出标注

---

### Phase C: Documentation Updates

**Goal:** 更新项目文档，说明 agent 能力差异

#### C1: CLAUDE.md 添加能力矩阵

**File:** `CLAUDE.md`

**Section:** 在 "Multi-Agent Support" 后添加

```markdown
## Agent Capability Matrix (DX-83)

| Feature | Claude Code | Pi | Windsurf | Cursor |
|---------|-------------|-----|----------|--------|
| **Task Tool** | ✅ | ❌ | ✅ | ❌ |
| **Subagent Support** | ✅ Full | ❌ None | ✅ Full | ❌ None |
| **Model Access** | sonnet, opus, haiku | sonnet (API) | sonnet, opus | Various (API) |

### Skill Execution Quality

| Skill | With Subagent | Without Subagent |
|-------|---------------|------------------|
| `/review` | ⭐⭐⭐ Isolated, adversarial | ⭐⭐ Degraded, persona switch |
| `/develop` VALIDATE | ⭐⭐⭐ Isolated validator | ⭐⭐ Self-verification |
| `/acceptance` | ⭐⭐⭐ Deep mode | ⭐⭐ Standard mode (auto) |
| `/security` | ⭐⭐⭐ Deep mode | ⭐⭐ Standard mode (auto) |

### Recommendations

**For production code:**
- Use agents with Task tool support (Claude Code, Windsurf)
- Skills will use isolated subagents for maximum objectivity

**For development/quick checks:**
- Pi and Cursor work with degraded mode
- Quality reduced but still valuable for iteration

**Configuration:**
- Edit `.invar/config.toml` to customize behavior
- Force degraded mode: `execution_mode = "degraded"`
- Change model preference: `subagent_model = "sonnet"`
```

**Exit Criteria:**
- ✅ 能力矩阵清晰展示
- ✅ 质量对比明确
- ✅ 使用建议实用

---

#### C2: Skill CONFIG.md 更新

**每个 skill 的 CONFIG.md 添加:**

```markdown
## Agent Requirements (DX-83)

**Recommended Capabilities:**
- Task Tool: ✅ For isolated execution
- Model Access: Any (follows config)

**Degraded Mode:**
- Available when Task tool not supported
- Quality: ⭐⭐ (vs ⭐⭐⭐ with isolation)
- See SKILL.md → "Mode B: DEGRADED" for details

**Configuration:**
```toml
[skills.review]
execution_mode = "auto"  # auto | isolated | degraded
subagent_model = "inherit"  # inherit | sonnet | opus | haiku
```
```

**Exit Criteria:**
- ✅ 所有 subagent-dependent skills 文档更新
- ✅ 配置示例准确

---

## Implementation Plan

### Phase A: Configuration Infrastructure (1-2 days)
- [ ] A1: 创建 `config.toml` 模板
- [ ] A2: 实现配置读取函数
- [ ] A3: 在 `init` 时生成配置

**Validation:**
```bash
invar init --claude
cat .invar/config.toml  # Should show task_tool_available=true

invar init --pi
cat .invar/config.toml  # Should show task_tool_available=false
```

---

### Phase B: Skill Documentation (2-3 days)
- [ ] B1: Review skill 双路径改造
- [ ] B2: Develop skill VALIDATE 改造
- [ ] B3: Acceptance & Security 简化

**Validation:**
```bash
# Claude Code (isolated)
claude /review
# → Should use isolated subagents

# Pi (degraded)
pi /review
# → Should show degraded warning
# → Should use persona switch instead of subagent
```

---

### Phase C: Documentation (1 day)
- [ ] C1: CLAUDE.md 能力矩阵
- [ ] C2: Skill CONFIG.md 更新

**Validation:**
- [ ] 文档清晰说明差异
- [ ] 用户能理解何时用哪个 agent

---

### Total Effort: ~5 days

---

## Success Criteria

### Functional

1. **Multi-Agent Compatibility**
   - ✅ 同一份 skill 在 Claude Code 和 Pi 都能运行
   - ✅ Claude Code 使用 isolated mode
   - ✅ Pi 使用 degraded mode

2. **Configuration**
   - ✅ `invar init` 自动检测并生成配置
   - ✅ 用户可手动编辑配置覆盖
   - ✅ Model 选择支持 inherit/sonnet/opus/haiku

3. **Quality Transparency**
   - ✅ Degraded mode 明确标注 `[DEGRADED MODE]`
   - ✅ 质量差异在文档中说明
   - ✅ 用户有明确预期

### User Experience

1. **Claude Code 用户**
   - ✅ 无感知，自动使用最佳模式
   - ✅ 可自定义 model 偏好

2. **Pi 用户**
   - ✅ 可使用所有 skills（降级）
   - ✅ 清楚了解质量限制
   - ✅ 收到 Claude Code 推荐（但不强制）

3. **配置灵活性**
   - ✅ 可强制降级（测试、成本控制）
   - ✅ 可覆盖 model 选择
   - ✅ 可跳过降级警告（CI 场景）

---

## Risks & Mitigations

### Risk 1: 降级质量不可接受

**Risk:**
Degraded mode 可能给用户虚假安全感，实际质量不足。

**Mitigation:**
1. 明确标注 `[DEGRADED MODE]` 在所有输出
2. 质量评级 ⭐⭐ vs ⭐⭐⭐ 在文档中显著展示
3. 每次降级都推荐切换到 Claude Code
4. 报告中包含 "Re-review with isolated agent" 建议

---

### Risk 2: 配置维护负担

**Risk:**
新增配置文件增加用户学习成本。

**Mitigation:**
1. 配置文件有详细注释
2. `invar init` 自动生成，大多数用户不需要手动编辑
3. 默认值 (`inherit`, `auto`) 适用 90% 场景
4. 文档提供常见配置示例

---

### Risk 3: 检测逻辑失效

**Risk:**
Agent 能力检测可能不准确（如环境变化）。

**Mitigation:**
1. 用户可手动覆盖配置
2. Skill 入口处二次检查（尝试列出 available tools）
3. 如果检测失败，默认降级（保守策略）
4. 环境变量支持：`INVAR_FORCE_DEGRADED=1`

---

## Future Work

### DX-84: Runtime Capability Probing

当前检测依赖静态配置和启发式，未来可实现运行时探测：

```python
def probe_task_tool() -> bool:
    """Runtime probe for Task tool availability."""
    # Check if Task in available_tools list
    # Or attempt no-op call with error handling
```

### DX-85: Cross-Agent Quality Benchmarking

收集数据对比 isolated vs degraded 的实际质量差异：
- Issues found ratio
- False positive rate
- User satisfaction

### DX-86: Partial Isolation Strategies

探索中间方案：
- Conversation forking (if agent supports)
- External review service (API call to isolated environment)
- Hybrid: automated checks degraded, manual review isolated

---

## References

- DX-81: Multi-Agent Init Support
- DX-75: Attention-Aware Review Framework (scope classification)
- Claude Code Task Tool Documentation
- Pi Custom Tools API Documentation

---

## Discussion Points

1. **Review 降级的最小可行质量** - ⭐⭐ 是否足够？还是应该 hard fail？
2. **Model 配置默认值** - `inherit` vs `sonnet` vs skill-specific？
3. **检测时机** - Init-time 配置 vs Runtime 探测的权衡？
4. **用户教育** - 如何让用户理解 isolated vs degraded 的差异？

---

**Next Steps:**
1. Review proposal with team
2. Decide on degraded mode quality threshold
3. Prioritize implementation phases
4. Create implementation tasks in backlog
