---
name: "slice-parallel-safety"
version: "1.2.0"
origin: "captured"
generation: 0
parent_skill_ids: []
status: "stable"
description: "切片并行安全矩阵。定义多 Agent 并行工作时的文件锁定、冲突检测和依赖声明规则。借鉴 OpenHarness Team Coordinator 子代理协调机制，确保并行切片不产生文件级冲突。"
trigger_phases: ["all"]
applicable_agents: ["Copilot Orchestrator"]
priority: 5
---

# Slice Parallel Safety — 切片并行安全

> **来源**：OpenHarness `team/` Team Coordinator 子代理并行协调 + `compaction/` Auto-Compaction。
> **实现方式**：Prompt 层声明式冲突矩阵 + Orchestrator 路由时的并行安全检查。

## 何时触发

| 触发条件 | 说明 |
|---|---|
| Orchestrator 准备并行分派 2+ Agent 时 | 路由前检查文件范围冲突 |
| 同一切片内多 Agent 接力时 | 声明依赖，确保产物交接完整 |
| 跨切片并行开发时 | 校验模块边界不重叠 |

## 谁来调用

| Agent | 职责 |
|---|---|
| **Copilot Orchestrator** | 并行分派前检查安全矩阵，分配文件范围锁 |
| **Copilot Planner** | 规划阶段声明切片间依赖关系 |

---

## §1 并行安全等级

### 1.1 并行兼容分类

| 等级 | 标识 | 含义 | 示例 |
|---|---|---|---|
| **P-SAFE** | 🟢 | 完全并行安全，无文件范围重叠 | 前端 Implementation + 后端 Code Gen（不同路径） |
| **P-CAUTION** | 🟡 | 有潜在共享文件，需声明范围锁 | 两个后端模块共享 `blade-common` 工具类 |
| **P-CONFLICT** | 🔴 | 文件范围冲突，必须串行 | 同一 Entity/VO 的两个切片修改 |

### 1.2 Agent 并行兼容矩阵

> 同一切片内两个 Agent 同时活跃时的兼容性。

| Agent A ↓ \ Agent B → | Code Gen | Implementation | Code Review | QA | Schema Guardian | Documentation |
|---|---|---|---|---|---|---|
| **Code Gen** | 🔴 | 🔴 | 🟢 | 🟢 | 🟡 | 🟢 |
| **Implementation** | 🔴 | 🔴 | 🟡 | 🟡 | 🟢 | 🟢 |
| **Code Review** | 🟢 | 🟡 | 🟢 | 🟢 | 🟢 | 🟢 |
| **QA** | 🟢 | 🟡 | 🟢 | 🟢 | 🟢 | 🟢 |
| **Schema Guardian** | 🟡 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 |
| **Documentation** | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 |

**说明**：
- 🔴 表示两者写入范围重叠，必须串行（等前者完成再开始后者）
- 🟡 表示需声明文件范围锁后可并行
- 🟢 表示无冲突，可自由并行

---

## §2 文件范围锁

### 2.1 锁声明格式

Orchestrator 在路由 Agent 时声明文件范围锁：

```
Route to: Copilot Implementation
Slice: EAM-Slice-2
File Scope Lock:
  EXCLUSIVE:
    - blade-service/eam-asset/**
    - blade-service-api/eam-asset-api/**
    - src/views/eam/assetLedger/**
    - src/api/eam/assetLedger.js
    - src/option/eam/assetLedger.js
  SHARED_READ:
    - blade-common/**
    - src/utils/**
    - M-DOC/EAM/**
```

### 2.2 锁类型

| 锁类型 | 含义 | 并行规则 |
|---|---|---|
| **EXCLUSIVE** | 独占写入 | 同一路径只能有一个 Agent 持有 EXCLUSIVE 锁 |
| **SHARED_READ** | 共享只读 | 多个 Agent 可同时持有，但不可写入 |
| **NONE** | 未锁定 | 不在当前切片范围内，不应被访问 |

### 2.3 冲突检测

Orchestrator 在分派第二个 Agent 前检查：

```
if (AgentB.EXCLUSIVE ∩ AgentA.EXCLUSIVE ≠ ∅)
  → P-CONFLICT: 串行等待 AgentA 完成
  
if (AgentB.EXCLUSIVE ∩ AgentA.SHARED_READ ≠ ∅)
  → P-CAUTION: 要求 AgentB 在声明范围外的共享文件上不做写入
  
if (AgentB.SHARED_READ ∩ AgentA.SHARED_READ ≠ ∅)
  → P-SAFE: 无冲突
```

---

## §3 切片间依赖声明

### 3.1 依赖类型

| 类型 | 标识 | 含义 | 处理 |
|---|---|---|---|
| **HARD** | ⛓️ | 强依赖 — 上游切片必须完成才能开始 | 串行调度 |
| **SOFT** | 🔗 | 弱依赖 — 上游切片的 API 契约确定后即可开始 | P3 阶段后可并行 |
| **NONE** | ✂️ | 无依赖 — 完全独立 | 自由并行 |

### 3.2 依赖声明模板

Planner 在切片规划时使用：

```markdown
## Slice Dependencies

| 切片 | 依赖 | 类型 | 条件 | 共享文件 |
|---|---|---|---|---|
| EAM-Slice-2 | EAM-Slice-1 | SOFT 🔗 | Slice-1 的 AssetLedger Entity 定义完成 | blade-service-api/eam-asset-api/**/entity/** |
| EAM-Slice-3 | EAM-Slice-2 | HARD ⛓️ | Slice-2 的功能位置管理全部完成 | blade-service/eam-asset/**/FunctionalLocation* |
| CRM-Slice-1 | EAM-Slice-1 | NONE ✂️ | — | — |
```

---

## §3.5 Track 级文件锁矩阵（多 Team 并行开发）

> 配合 `devprg-lifecycle-protocol §PT-1 ~ §PT-7`。当多个 Team 同时持有不同 Track 时，使用本矩阵判定每个 Track 的独占/共享/禁写区。

### 3.5.1 Track → 路径归属矩阵

| Track | EXCLUSIVE（本 Track 独占写） | SHARED_READ（全 Track 只读） | 禁写（属他 Track 或 Foundation Gate） |
|---|---|---|---|
| **Foundation** (Wave 0/1/2) | `blade-service/blade-system/**`、`blade-service-api/partner-api/**`、`blade-service-api/product-api/**`、`blade-gateway/**`、`blade-auth/**`、`script/sql/foundation/**` | — | 其他所有业务目录 |
| **CRM** | `blade-service/crm-*/**`、`blade-service-api/crm-*-api/**`、`src/views/crm/**`、`src/api/crm/**`、`src/option/crm/**`、`src/lang/modules/{zh-cn,en-us}/crm.js`、`src/lang/modules/{zh-cn,en-us}/crm/**` | `blade-common/**`、Foundation EXCLUSIVE 路径、`src/utils/**`、`src/styles/tokens/**`、`DevPrg/协同规范/**` | 其他 Track 的 EXCLUSIVE 路径 |
| **PLM** | `blade-service/plm-*/**`、`blade-service-api/plm-*-api/**`、`src/views/plm/**`、`src/api/plm/**`、`src/option/plm/**`、`src/lang/modules/{zh-cn,en-us}/plm.js`、`src/lang/modules/{zh-cn,en-us}/plm/**` | 同上 | 同上 |
| **EAM** | `blade-service/eam-*/**`、`blade-service-api/eam-*-api/**`、`src/views/eam/**`、`src/api/eam/**`、`src/option/eam/**`、`src/lang/modules/{zh-cn,en-us}/eam.js`、`src/lang/modules/{zh-cn,en-us}/eam/**` | 同上 | 同上 |
| **QMS** | `blade-service/qms-*/**`、`blade-service-api/qms-*-api/**`、`src/views/qms/**`、`src/api/qms/**`、`src/option/qms/**`、`src/lang/modules/{zh-cn,en-us}/qms.js`、`src/lang/modules/{zh-cn,en-us}/qms/**` | 同上 | 同上 |
| **SCM / FICO / MOM / PPC / HRMS / AI** | 按同一模式替换前缀 | 同上 | 同上 |
| **共享 i18n `core`** | 仅 Foundation Team 可写 `src/lang/modules/{zh-cn,en-us}/core.js` | 全 Track 只读 | 业务 Team 写 core.js 视为越权 |

### 3.5.2 跨 Track 写入诉求的唯一合法路径

当 Team-X 发现其 Slice 需要修改或新增 Track-Y 代码（接口、Entity、Controller、API 文件、菜单、字典等），唯一合法路径为：

1. Team-X 产出 PT（`<SOURCE>__<TARGET>__*.md`），填齐 `source_track / target_track / stub_strategy / contract_stub`
2. Team-X 仅在本 Track EXCLUSIVE 路径下产出 Stub 代码（命名含 `-stub` / `-fallback` / `.mock`）
3. Team-X 继续推进本 Slice 至 closure（不要求 Track-Y 真接口就绪）
4. Track-Y 进入 `REVIEW` 时，由 Orchestrator 自动生成联调切片，Team-Y 接手 PT 的实施清单

**禁止**：
- ❌ Team-X 直接修改 Track-Y 的 EXCLUSIVE 路径代码
- ❌ Team-X 在共享只读目录（`blade-common` / `src/utils` / Foundation）写代码绕过 PT
- ❌ Team-X 将联调验收纳入本 Slice closure 条件

### 3.5.3 Track 级并行冲突检测

Orchestrator 路由时按以下顺序判定：

```
1. foundationGateReady == false?
   → BLOCKED（Wave 0/1/2 未冻结，不得开并行 Track）

2. targetFileScope.EXCLUSIVE 是否越过本 Track 归属？
   → BLOCKED（DV-08 跨 Track 直写）

3. 同 Track 是否已有另一 Team 的活跃 EXCLUSIVE 锁？
   → BLOCKED（DV-13 Team 争抢）

4. crossTrackDependencies 中的 PT 是否存在且 frontmatter 完整？
   → BLOCKED（DV-09 PT 字段缺失）

5. Stub 路径命名是否含 -stub / -fallback / .mock？
   → BLOCKED（DV-10 Stub 命名不规范）

6. 全部通过 → P-SAFE / P-CAUTION（按传统 §1 矩阵继续判定）
```

### 3.5.4 共享菜单、字典、路由的治理

以下共享资源为 Foundation Team 独占写，业务 Track 新增诉求必须走 PT 申请：
- 菜单树（`blade_menu`）根节点与一级节点
- 全局字典（`blade_dict`）、跨域业务字典（`blade_dict_biz` 中标记 `shared=true` 的代码）
- 网关路由（`blade-gateway` 配置）
- 租户隔离策略、权限框架、角色/岗位底座
- i18n `core.js`（两语种）
- 设计 tokens（`src/styles/tokens/**`）

业务 Track 自有的字典代码、二级以下菜单节点、本 Track 独占 i18n 子系统文件，不受此限。

---

## §4 上下文压缩协议（Auto-Compaction）

> 对应 OpenHarness Auto-Compaction — 长会话中自动压缩上下文，保持 Agent 工作记忆在有效窗口内。

### 4.1 何时压缩

| 触发条件 | 动作 |
|---|---|
| Agent 交互轮次 > 15 轮 | Orchestrator 建议阶段切换或 Agent 重新加载切片上下文 |
| 切片状态文件超过 200 行 | 压缩历史决策为摘要，保留最近 3 个关键决策 |
| Agent 检测到上下文遗忘迹象 | 重新读取 `/memories/session/slice-{id}-state.md` |

### 4.2 压缩策略

```markdown
## Context Compaction Record
- Compacted at: Turn 16
- Preserved:
  - Current phase: P5 (implementation)
  - Active hooks: PRE-02, PRE-06, POST-02, POST-06
  - File scope lock: [see above]
  - Last 3 decisions: [...] 
  - Open blockers: [...]
- Archived to: /memories/session/slice-{id}-compaction-{turn}.md
```

### 4.3 Agent 恢复协议

Agent 在以下场景重新加载上下文：

1. **新会话恢复**：读取 `/memories/session/slice-{id}-state.md` → 获取当前阶段、门禁进度、延后项
2. **长会话压缩后**：读取最新 compaction 记录 → 恢复活跃钩子、文件锁、决策历史
3. **Agent 切换**：下游 Agent 首先读取 upstream 的 agentLog 产物 + slice state

---

## §5 子代理隔离协议（Subagent Isolation）

> 借鉴 Hermes `delegate_tool.py` 的 `skip_memory=True, skip_context_files=True` 上下文隔离 + `MAX_DEPTH=2` 递归限制。

### 5.1 隔离级别

| 级别 | 标识 | 上下文传递 | 适用场景 |
|---|---|---|---|
| **FULL_ISOLATION** | 🔒 | 仅传递任务描述 + 目标文件路径 | 独立研究、代码搜索、文档生成 |
| **CONTEXT_SHARED** | 🔓 | 传递任务描述 + 当前切片摘要 + 相关文件列表 | 实现相关子任务 |
| **INHERIT** | 🔗 | 继承父代理完整上下文 | 需要完整上下文的继续性工作 |

### 5.2 Orchestrator 隔离声明

Orchestrator 调用 `runSubagent` 时声明隔离级别：

```
Route to: Copilot Implementation (subagent)
Isolation: FULL_ISOLATION
Task: "搜索所有 EAM 模块中使用 TenantEntity 的 Entity 类"
Scope: blade-service-api/eam-*-api/**/entity/**
Expected Output: 文件路径列表 + 继承关系
MAX_DEPTH: 1 (不允许嵌套子代理)
```

### 5.3 子代理约束

| 约束 | 说明 |
|---|---|
| 文件锁继承 | 子代理不得修改父代理 EXCLUSIVE 锁定的文件（除非显式委托） |
| 递归深度 ≤ 2 | 子代理的 `runSubagent` 调用最多再嵌套 1 层，防止递归爆炸 |
| 结果回传精简 | 子代理完成后仅返回最终结果摘要（≤ 2000 tokens），控制 token 回传量 |
| Memory 写入隔离 | FULL_ISOLATION 级别的子代理不得写入 `/memories/`，仅 CONTEXT_SHARED 和 INHERIT 可写 |

---

## §6 并行结果合并协议（Parallel Result Merge）

### 6.1 合并策略

| 场景 | 策略 | 说明 |
|---|---|---|
| 多个只读研究子代理 | **MERGE_ALL** | 合并全部结果，去重 |
| 多个写入子代理（不同文件） | **SEQUENTIAL_APPLY** | 按依赖序应用，无冲突 |
| 多个写入子代理（共享文件） | **CONFLICT → SERIAL** | 检测冲突 → 回退为串行 |

### 6.2 冲突检测

Orchestrator 在收到多个子代理结果后检查：

1. **Scope 越界**：子代理修改了超出其声明 Scope 的文件 → 警告 + 放弃越界变更
2. **同文件冲突**：两个子代理修改了同一文件 → 保留先完成者 + 通知后完成者调整
3. **决策矛盾**：子代理的输出与父代理的 Key Decisions 矛盾 → Orchestrator 仲裁（必要时升级用户）

### 6.3 合并执行格式

```markdown
### Parallel Merge Report
| Subagent | Status | Files Changed | Conflicts |
|---|---|---|---|
| Implementation-A | ✅ DONE | 5 files | None |
| Implementation-B | ✅ DONE | 3 files | 1 (src/utils/shared.js) |

Conflict Resolution:
- src/utils/shared.js: Kept A's version (completed first), B to rebase.
```

---

## §7 超时与恢复协议（Timeout & Recovery）

### 7.1 子代理超时规则

| 任务类型 | 建议超时 | 超时处理 |
|---|---|---|
| 代码搜索/研究 | 60s | 返回已获取的部分结果 |
| 代码生成 | 120s | 保留已生成文件 + 标记未完成项 |
| 测试执行 | 300s | 收集已完成测试结果 + 标记超时测试 |

### 7.2 恢复策略

子代理超时或失败时：

```
1. 记录失败原因到 trajectory.md
2. 评估失败影响：
   ├─ 部分结果可用 → 合并部分结果 + 标记缺失项
   └─ 完全失败 → 串行重试一次
       ├─ 重试成功 → 正常合并
       └─ 仍失败 → BLOCKED，报告用户
3. 更新 Slice Snapshot 中的子代理状态
```

### 7.3 心跳机制说明

> VS Code `runSubagent` 为同步调用，Agent 在等待子代理结果时不主动执行心跳。超时由 `runSubagent` 的 `timeout` 参数控制。
> 此处心跳规则主要用于 Orchestrator 的调度决策：对于预计耗时 > 60s 的子代理任务，Orchestrator 应拆分为更小的子任务以降低超时风险。

---

## §8 Orchestrator 并行调度决策树

```
Is this a multi-agent dispatch?
├── NO → 直接路由，无并行检查
└── YES → 检查 §1.2 Agent 兼容矩阵
    ├── 🟢 P-SAFE → 分配独立文件范围锁，并行分派
    ├── 🟡 P-CAUTION → 声明 SHARED_READ 范围，附加不写入约束，并行分派
    └── 🔴 P-CONFLICT → 串行调度，等待前者完成
        └── 是否可拆分为不冲突的子任务？
            ├── YES → 拆分后按 P-SAFE/P-CAUTION 处理
            └── NO → 严格串行
```

## §9 扩展规则

1. 新增 Agent 必须在 §1.2 兼容矩阵中注册。
2. 切片依赖类型的判定由 Planner 负责，Architect 审核。
3. 文件范围锁在切片完成后自动释放，不跨切片持有。
4. 本 Skill 与 `agent-execution-governance` 协同 — Governance 定义"我能做什么"，本 Skill 定义"我和谁能同时做"。
