# dsh-agent-teams-fish v0.6.0

**合并上游 v0.1.23 + 完整保留 Fish 自建功能版**：把上游 `NanmiCoder/dsh-agent-teams` v0.1.23（`1094b84`）的 37 个提交合入本 fork，同时**一行未丢**地保留 Fish 的厂商美术系统与队长头像跟随路由。

基线由上游 tag `v0.1.22`（commit `9cba4fe`）推进到 **`v0.1.23`**；版本号走 **minor**：上游是大版本功能更新（新增成员工具策略、工作区审计、lineage 身份链、质量门契约绑定等），不是补丁。

## 一、为什么是 minor 而不是 patch

本 fork 的版本语义是「Fish 自己的发布节奏」，与上游版本号解耦。本次一次带入上游**四个新模块**（`src/tool-policies.ts` / `src/workspace-audit.ts` / `src/lineage.ts` / `src/artifacts.ts`），并改动了质量门、快照、工具参数等既有行为，属功能更新，故 `0.5.1 → 0.6.0`。

## 二、上游 v0.1.23 带来了什么

| 上游改动 | 内容 | 落点 |
|---------|------|------|
| **成员工具策略**（#59） | 部署方在配置里按 id 声明可复用的 `allow` / `deny` 工具列表，成员通过 `tool_policy` 选用；四项协调工具始终保留，队长专属工具永不重开。这管的是**工具可见性**，不是操作系统沙箱 | `src/tool-policies.ts`〔新增〕 · `src/tools.ts` |
| **质量门契约与修订绑定**（#161） | review / verification 的判定绑定到**产物字节**，补齐修复沿革；改动过的文件在被可靠判定覆盖之前**阻断交付** | `src/quality-gates.ts` |
| **修复契约与失效源告警**（#174, #175） | 保留修复契约、暴露失效源告警，并为验证失败自动创建修复 / 复验跟进任务，且不会因依赖失败而死锁 | `src/quality-gates.ts` |
| **越界 findings 升级**（#183） | 落在允许修复范围之外的 finding 带原因升级，而不是造出不可能完成的修复任务 | `src/quality-gates.ts` |
| **lineage 身份沿 fork 链**（#176） | 队长身份在**热 fork 与冷 fork** 之间保持，含多跳沿革与成员唤醒；成员侧仍是精确 id 匹配，父链里出现的队长绝不被误读为队长身份 | `src/lineage.ts`〔新增〕 |
| **会话源元数据与恢复工具**（#160） | 会话源元数据改用当前格式写入，并提供**显式、非破坏性**的历史恢复工具（带源备份） | `src/artifacts.ts`〔新增〕 |
| **工作区审计** | 新增工作区审计，面板与 status 工具据此得出**同一交付结论** | `src/workspace-audit.ts`〔新增〕 · `src/snapshot.ts` |
| **损坏 `team.json` 的边界降级** | `team.json` 损坏时按边界降级处理，不再整体崩掉 | `src/state.ts` |
| **卡片 id 匹配回归修复**（#203） | 修 Unicode 团队卡片与历史事件折叠，成员花名册改用与持久化状态一致的团队身份 | `src/client/agent-teams-card-definition.ts` |
| **finding 行号校验**（#188） | 落库前拒绝非法 finding 行号，可恢复的历史值做归一化 | `src/quality-gates.ts` |
| **成员模型与 provider 同解**（#189） | 成员模型连同其配置的 provider 一起解析，显式 provider 选择被保留 | `src/members.ts` |
| **迟到的成员失败记录**（#205） | 任务结算之后才到达的成员轮次失败，记为持久化的队长备注 | `src/tools.ts` |

## 三、Fish 自建功能：一项未丢

合并的取舍原则是**两侧并存、不删任何一边**。3 处源码冲突的处理：

1. `src/snapshot.ts` **import 块**：本版 `captainRouteOf`（成员路由取值）与上游 `canDeclareDelivery` / `describeQualityLoop` / `verdictAuditNotes` / `auditTeamWorkspace`（质量审计）并存 —— 命名空间与用途不重叠。
2. `src/snapshot.ts` **函数体**：本版「队长 live route 优先于快照」（`liveCaptain` → `captainRouteOf` → `captainProvider` / `captainModel`，实时值优先）与上游「面板要与 status 工具得出同一交付结论」（`audit` / `deliveryCheck` / `staleById` / `verdictStale`）并存 —— 两者写的是不同字段、读的是不同数据源，互不排斥。现在面板**同时**拿到实时队长路由与统一交付结论。
3. `src/tools.ts` **`add_member` 参数**：保留本版详细 `role` 文案（十个岗位桶 + 「不要发明新角色名，否则掉兜底图」——这是 Fish 美术 fallback 行为的线上说明），**同时**保留上游新增的 `tool_policy` 参数。

保留项逐条核对：

- `src/artwork-source.ts` —— 自定义美术目录解析与扩展名 → MIME 表，243 行在位
- `src/client/artwork.ts` —— 十七厂商识别 / 厂商头像命名空间 / 降级链 **`厂商+岗位 → 厂商 → 岗位`** / 商标徽标 / 高清 WebP 族，351 行在位
- `src/members.ts` 的 `captainRouteOf` 与队长头像跟随路由（`captainProvider` / `captainModel`）
- `src/index.ts` 的美术路由与 MIME 按扩展名送达
- `assets/agent-teams/` 随包素材 **286 个文件，零改动**
- `scripts/verify.mjs` 的美术门禁、`custom-artwork.test.mjs` / `artwork-role-match.test.mjs` / `import-vendor-artwork.mjs`
- 角色词表含 10 个岗位桶（`audio` / `video` 在内）
- 身份字段三处同步：`package.json` 的 `name` / `cordis.patch.yml` 的插件行 `name` / `lib/client.js` 里 `__ModuleLoader__.load` 的 `id`，**均为 `dsh-agent-teams-fish`**

## 四、改动文件

| 文件 | 改动 |
|------|------|
| `src/*.ts`（17 个） | 合入上游 v0.1.23；`snapshot.ts` / `tools.ts` 的 3 处冲突按「两侧并存」解 |
| `src/tool-policies.ts` · `src/workspace-audit.ts` · `src/lineage.ts` · `src/artifacts.ts` | 上游新增模块 |
| `lib/**` | 构建产物，由构建链整体重建（非手工编辑） |
| `package.json` | 版本 `0.5.1 → 0.6.0`；身份字段一律取本版；保留上游新增脚本 |
| `README.md` · `README.en.md` | 补 0.6.0 横幅；旧版本横幅全部改为 release-notes 链接形式 |
| `release-notes/v0.1.23.md` | 上游发布说明，直接取用 |

## 五、验证

- 构建链五步全部 exit=0（`clean-build` → `tsc` 服务端 → `tsc` 客户端 → `tsdown` → `git-artifacts --write`），且**构建后无未暂存改动**（幂等，说明 `lib/` 产物与 `src/` 一致）
- `custom-artwork.test.mjs` **21 项全绿**、`artwork-role-match.test.mjs` **41 项全绿**、`quality-gates-amend.test.mjs` **9 项全绿** —— 与合并前基线一致，无回归
- 全仓搜 `^<<<<<<<` 为空，无冲突标记残留
- `compatibility.test.mjs` 仍为既有 **9 pass / 2 fail** 基线（`source candidates pass the peer gate...`、`doctor runs through an installed bin symlink...`）—— 合并前即如此，**非本次引入**；该失败源于本机未开开发者模式的 Windows 无法 `symlinkSync`，属环境限制
