Skip to content
dsh.fish
Bundle

dsh-agent-contract

多智能体契约工作流引擎:契约注入 / 每角色委派通道 / 产出契约三工具 / 台账三领域 / 元数据自动派生器 / 图书管理员(按需唤醒)/ 审计(警告制)。

Source
t2094308-star
License
MIT
Updated
Updated 7 days ago

Readme

# dsh-agent-contract · 多智能体协作契约

**一句话**:它让你派出去干活的 AI 子代理(下称"子代理",就是你派出去跑腿的那个 AI)**守规矩**——按统一格式交作业、进度随时可查、干完有人复核、文档有人维护。

**为什么需要它**:子代理一多就会散。交上来的东西格式各异;说了要交三档文档只交了一档;谁在干什么、谁改了哪篇、哪一步卡住了,全靠人问。这个插件把这些口头约定变成**机器自动检查**,不用人盯。

**它不做什么**:不改你的代码、不替你写内容、不拦截任何操作。它只做两件事——**把规矩递给每个子代理**,**把不合规的地方指出来**。

---

## 它替你做什么

| 能力 | 说得再直白点 |
|---|---|
| 派活自动带规矩 | 子代理一启动就收到一份工作约定(插件里叫"契约"):该交什么、写到哪、有哪些红线 |
| 交作业有固定格式 | 产出文档自带一段头部信息(任务号、角色、档级、关键词、相关文件),机器和人都能一眼看懂 |
| 有账本 | 谁在干什么、哪篇文档是谁交的、任务结没结,都能查 |
| 自动审计(自动审计) | 检查"该交的没交""进度没更新""改了正文没更新关键词"这类问题——**只提醒,不拦截** |
| 专职图书管理员 | 一个固定角色负责整理文档、补齐头部信息、归档旧档、维护一份“哪篇讲什么”的目录 |
| 一个面板 | 右侧栏的「契约」页:人员树、待办、审计结果 |

---

## 架构一目了然

### 图一:谁跟谁说话

```
                        你(在会话里说话)
                              │
                              ▼
                    ┌──────────────────┐
                    │      主代理       │   你直接对话的那个 AI
                    └────────┬─────────┘
                             │  派活
        ┌──────────┬─────────┼─────────┬──────────┐
        ▼          ▼         ▼         ▼          ▼
   ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌──────────┐
   │ 研究员  │ │ 实现者  │ │ 审查者  │ │对抗审查 │ │ 图书管理员│
   └────┬───┘ └────┬───┘ └────┬───┘ └────┬───┘ └─────┬────┘
        │          │          │          │           │
        └──────────┴──────────┴──────────┴───────────┘
                             │  交作业:三档文档 / 进度 / 修复总结
                             ▼
                    项目目录(真正的文件都在这儿)
```

- 子代理**还能再往下派**(层数不超过 4 层、总数不超过 20 个),派下去的每个子代理同样会拿到"工作约定"。
- 审查者与对抗审查者是**平行的两道检查**:一道按常规审,一道换一个不同来源的模型来"找茬"。

### 图二:插件在哪一层

插件不参与干活,它是一层**横向的服务**,在你和其他 AI 之间提供规矩、记账与检查:

```
        你 ──▶ 主代理 ──▶ 子代理们 ──▶ 项目目录
                 ▲            ▲            ▲
                 │            │            │
        ┌────────┴────────────┴────────────┴─────────┐
        │              插件(横向服务层)              │
        │  ① 派活那一刻:现场拼"工作约定"+ 按角色发工具   │
        │  ② 交作业那一刻:写档自动补头部 / 记账 / 提醒   │
        │  ③ 全程:谁在干什么、哪篇是谁交的,都有记录     │
        │  ④ 随时:体检(红黄清单,只提醒不拦)           │
        │  ⑤ 面板:人员树 / 待办 / 审计结果               │
        │  ⑥ 图书管理员:整理、补信息、归档、维护目录     │
        └─────────────────────────────────────────────┘
```

### 一个大任务的全流程(你做什么 / 插件同时做什么)

| # | 主代理在做什么 | 插件同时在做什么 | 你会看到 |
|---|---|---|---|
| 1 | 判断该派谁,把活儿派下去 | 现场拼出一份"工作约定"(规矩 + 角色说明 + 任务信息 + 相关资料线索),按角色发对应的工具,把子代理挂到你的会话树下 | 回执:已派出某某(角色),约定共 N 字 |
| 2 | 子代理开工:读任务、查资料 | 记下它是谁、在第几层、什么状态 | 面板人员树多出一个节点 |
| 3 | 子代理交作业:写三档文档、更新进度 | 自动补齐文档头部(任务号 / 角色 / 档级 / 关键词),写进产出目录;进度超过 400 字会提醒 | 面板上「文档 / 进度」徽章变 ✓ |
| 4 | 该改代码了:派实现者 | 同样带上工作约定和工具白名单 | 面板新节点(后台,可续派) |
| 5 | 改完要复核:派审查者;必要时再派对抗审查者 | 若对抗审查用了**不同来源的模型**,「异源」徽章显示 ✓ | 从徽章就能看出"是不是真的换了个模型来查" |
| 6 | 发现问题→派修复 | 把修复总结落盘、记账 | — |
| 7 | 你或主代理**跑一次体检** | 扫全项目:该交的没交 / 名字不对 / 文档放错目录 / 进度超长……出红黄清单,**只提醒、不改文件** | 面板顶部「审计:红 N / 黄 M」可展开看清单 |
| 8 | 让图书管理员整理一轮 | 补头部信息、归档旧档、维护"哪篇讲什么"的目录;**写前留备份** | 面板待办与成员树自动更新(不用手动刷新) |

**一句话记住**:你只管说人话和看面板;**规矩由插件递给每个子代理,账由插件记,问题由插件指出来**。

### 提示词是怎么拼出来的(派活那一刻的装配流程)

主代理调 `contract_delegate_<角色>` 时,插件**现场装配**一份完整提示词交给子代理。装配顺序固定,六段:

| # | 段落 | 里面是什么 | 来源 | 字数上限(软 / 硬) |
|---|---|---|---|---|
| 1 | **总纲本体** | 「[1] 总纲」+「[2] 状态信息」;方括号槽位**就地替换**成实际值(进度目录 / 任务文件 / 产出目录 / 上级 / 层数 / 总 Agent 数) | 插件内置模板 | 1500 / 2400,**永不裁剪** |
| 2 | **角色卡** | 该角色的 `persona`(工作方式、纪律、产出要求) | 插件角色表 | 角色自带(默认 800 / 1600) |
| 3 | **任务切面** | 任务号 · 任务文件**绝对路径**(只给路径,绝不搬运任务文件正文)· **上级补充指令原文**(不计长度)· 同任务的 debug / 产出文件清单 · 项目简介(若配了) | 现场定位 + 上级口述 | 机器搬运部分 300 |
| 4 | **文档切片** | 检索关键词 + 每篇候选的「路径 + 命中原因 + 该怎么读」;**默认不给正文**,仅高相关例外才附 ≤200 字引文 | 按任务号与补充指令检索文档库 | 整段 1200(超了就把引文全丢掉) |
| 5 | **能力配置** | 角色 · 运行模式(后台可续派 / 前台跑完即释放)· 工具白名单 · 模型路由 + **产出契约** + **禁止事项** | 插件角色表 + 现场计算 | 800 / 1300 |

(原先还有第六段「状态槽汇总」,已删除——槽位在第 1 段就地替换过了,再列一遍纯属重复。)

**预算与裁剪**(只做字符级软/硬闸,不做 token 精算):

```
· 总软上限 6000 / 总硬上限 9000 字(可在配置里改)
· 超软限但没超 30%  → 只提醒,保留全文
· 单段超硬限        → 截断到该段硬限
· 总体超硬限        → 按优先级裁:先 文档切片,再 任务切面
· 总纲永不裁        → 宁可只给一条警告,也要逐字完整下发(传递性要求)
· 任务切片          → 上级给子代理口述的那段补充指令:软 1000 / 硬 2000 字(可配 `budgets.briefSoft/briefHard`),
                    超硬限会被裁并提示「细节写进任务卡/文档,切片只留指针(路径 + 要看哪一节)」
· 机器搬运不限      → 总纲/角色卡/能力配置/切片都是**插件自己生成**的(可控)⇒ 只给一条「总量提示」(不告警、不记 over_budget)
```

```
主代理 ──调用派单工具──▶ 插件现场装配
                            ├─ 1 总纲本体(槽位替换)
                            ├─ 2 角色卡
                            ├─ 3 任务切面(任务路径 + 上级指令原文)
                            ├─ 4 文档切片(检索:路径 + 怎么读,不搬正文)
                            └─ 5 能力配置(工具白名单 + 模型路由 + 产出/禁止)
                                    │
                        ┌───────────┴────────────┐
                        ▼                        ▼
              子代理的初始提示词            主代理只收到一张短回执
              (契约全文,N 千字)         (已派出谁 / 契约 N 字 / 模型+来源 / 警告)
```

**两条值得注意的设计**:

- **主代理的上下文不会被契约正文污染**:它调用时只传任务号与口述指令,装配出来的几千字**只进子代理**;回执里只有一行摘要(契约多少字、有没有裁剪警告)。
- **"上级补充指令"不做长度门控**:那段是**人手写的**,写多长都原样透传;受预算约束的只是"机器搬过来的部分"。这也是为什么同一段契约里,上级指令可以很长而整体仍然可控。
- **续派只发增量**:第一次派给某人时发**完整契约**;之后同一会话里再派给它,**只发这一轮的任务切片**
  (任务号 + 你的补充指令 + 「角色卡/纪律/规范沿用本会话开头那份契约」),**不重复总纲与角色卡**。
  只有契约本身变了(插件升级、角色或规范段变了 —— 插件算得出"指纹")才会补发一段「契约已更新 + 变化段」。
  回执里会写明「本次为续派:只发任务切片 N 字(未重复契约)」。
- **建索引、核对引用、数数这类活不要读全文**:先用只读工具 `doc_census` 一次拿到全部档的机读信息
  (路径 / 类别 / 档级 / 任务号 / 标题 / 字数 / 关键词 / 相关文件 / 是否 legacy / 是否已归档),
  确实需要正文时优先读**头部与速览**;连续整篇读超过 5 篇要先回报。

## 装上它

它是本地开发的插件,通过“链接”方式挂进应用:

```sh
# 第一步:先给插件目录装依赖(这步不能省)
cd "D:\DSH插件\dsh-agent-contract"
npm install --omit=dev --legacy-peer-deps   # 装依赖(插件运行需要的库)

# 第二步:链进应用
dsh plugin --profile desktop add link:D:\DSH插件\dsh-agent-contract
```

装完在桌面应用里**完整退出再打开**(托盘图标 → Quit,不是关窗口)才会生效。

> 第一步漏了的症状:应用里弹“组件启用失败 … failed to import”。
> 想确认依赖是否齐:`node --input-type=module -e "await import('file:///D:/DSH插件/dsh-agent-contract/index.js')"`——报 `schemastery` 是缺依赖;报 `dsh-tools` 属正常(那是应用本身提供的库)。

---

## 怎么配置(**默认不用配**)

**换项目不用改配置**:插件默认**跟着你的工作区走**——你开哪个文件夹,它就把那个文件夹当成项目。

它会自己认路:

- **先看有没有老结构**:按候选清单找既有的目录(`任务`/`tasks`、`[Agent进度]`/`progress`、
  `docs/{研究,坑,修改,核心数据库}` 以及 `仓库/docs/…` 这种变体)。找到就用,**一个字都不改**。
- **都没有就自己建**:在项目根下建一套默认目录和 `待办.md`(**只新建、绝不覆盖**),并在回执里告诉你建了什么。
  想先看看会建什么,就让主代理调一次 `project_init`(默认只预览,确认后再落地)。
  **建目录只有 `project_init` 这一个入口**(显式动作);缺结构时**回执和面板会主动提示你**「本工作区尚未初始化:缺少 … —— 调 `project_init` 可预览并建齐」,不用自己记着去叫它。
- **项目名取文件夹名**:账本按项目分开存,两个项目来回切也不会串。
- **记在项目自己身上**:推导结果写在 `<项目根>/.agent-contract/project.json`(删了会自动重探)。

只有想**把某个项目锁死**(不让它跟着工作区跑)时,才需要动配置文件 `cordis.patch.yml`:

| 配置项 | 意思 | 例子 |
|---|---|---|
| `project.root` | 锁死项目根(**留空 = 跟着工作区自适应**) | `D:\Blockdustry` |
| `project.name` | 锁死项目名(留空 = 用文件夹名;账本按它分域) | `Blockdustry` |
| `paths.*` | 自己指定目录约定(**留空 = 自动探测/按需新建**) | `deliverablesDir: 仓库/docs/子agent` |
| `paths.docKinds` | 类别→目录(审计按它判"文档放错没有")。**要么六类全给,要么一个都别给** | 研究 / 坑 / 修改 / 核心数据库 / 产出档 / 归档 |
| `panel.todoFile` | 面板上“大方向待办”读哪个文件(**仍归配置文件**) | `待办.md` |
| `roles` | 角色设定(不填就用内置的五个角色) | 研究员 / 实现者 / 审查者 / 对抗审查 / 图书管理员 |
| `modelRoutes` | 每个角色用哪个模型(**现在由设置页管**,文件里只作示例) | 对抗审查默认 `adversary: glm-5.3-flash`(设置页里可改) |
| `budgets` | 派活时那份约定的字数上限(超了只提醒) | 软上限 6000 / 硬上限 9000 |
| `audit.checks` | 开启哪些审计项 | 见第 6 节 |
| `audit.archiveAfterDays` | 超过多少天的旧档建议归档 | `90` |
| `git.autoCommit` | 要不要让插件自动提交(默认关)。开了之后:只提交本次动到的文件,若工作区还有**别的**未提交改动就**中止**,绝不 `push` | `false` |

**优先级**:显式配置 > 当前工作区 > 会话所在目录。配了 `project.root` 就以配置为准(工作区推导不会覆盖它)。

---

## 日常怎么用

**① 派活**:跟主代理说人话就行,例如“派一个研究员去查 X”。它会自动带上工作约定,子代理按约定干活。

**② 交作业**:子代理通过三个固定动作交付——
- 写产出文档(自动填好头部信息、返回文件的完整路径)
- 更新进度文件(一句话进度,不超过 400 字)
- 记一次修复总结(修完 bug 时写)

**③ 查看与治理**:随时让主代理“跑一次审计”看有没有问题;需要整理文档时,让图书管理员做一轮。

**④ 走契约是默认,绕过要留痕**:所有子代理派活都应当走契约工具。确实派不出去(宿主限制等)而要走普通派活时,
先调 `contract_request_escalation` **说明理由**(写进台账,面板与体检里都看得到);
**没提权就绕过**的会被体检报出来(`uncontracted_dispatch`),报告里会指出是哪个会话、什么时候、建议怎么做。
契约工具报错时也会给出**原因 + 替代路径**(重试 / 自动新建 / 看版本漂移并完整重启 / 先提权再绕过),
不会让主代理自己瞎试到偷偷绕过。

**⑤ 新仓库**:开一个新文件夹当工作区,直接干活就行——插件会自己认路;想先看它打算建什么,让主代理调一次 `project_init`(默认只预览不落地)。

---

## 面板上看什么

右侧栏的「契约」页分几块:

- **待办任务(大方向)**:读你维护的待办文件,给你看的路线图。可以直接**勾选完成**,也可以点「编辑」改内容。
- **agent 待办(执行队列)**:机器算出来的“还没干完的活”——未结任务、缺的产出、审计提醒。可以点条目跳到对应文件。
- **审计**:一行红/黄计数 + 可展开的清单。这行是**项目级**的:同一个工作区里所有会话看到的是同一份。
- **人员树**:谁派了谁、现在什么状态;每个人身上有五枚小徽章——

| 徽章 | 看什么 |
|---|---|
| 契约 | 派活时有没有带上工作约定 |
| 文档 | 该交的产出交了没 |
| 进度 | 进度文件更新了没 |
| 预算 | 约定文本有没有超字数 |
| 异源 | 对抗审查有没有真的换了另一个模型 |

徽章取值:`✓ 正常` / `⚠ 警告` / `✗ 缺失` / `? 未知` / `— 不适用`。

面板会**自己刷新**:常态每 5 秒重读一次数据,窗口切回来时立刻刷一次;成员树这类较重的部分每 30 秒同步一次。

面板顶部那两个按钮分工不同,别弄混:

- **「↻ 刷新」= 只重读**(不动任何数据):重新读取会话血缘与面板快照。快照本身陈旧/是占位时,点多少次都救不回来。
- **「强制刷新」= 跑一次审计 + 重写面板数据**(等同让主代理跑一次 `audit_scan`,**会改磁盘上的快照**):跑完自动重读,并回一句「审计完成:红 N / 黄 M;面板数据已重写」。进行中按钮会禁用、3 秒内不能连点,失败会在面板上写明原因。

**面板卡在「尚无审计结论」时,点「强制刷新」就能恢复** —— 不必再等主代理。

面板显示的数据放在 `<项目根>/.agent-contract/panel.json`。这份文件是**自动生成**的,删了会自动重建。

**它只在「有动作」时才被重算** —— 派单、跑审计、让馆员治理一轮、编辑待办……这些动作发生后面板才更新。所以「我重启了怎么还是空的/还是旧数字」属于正常现象,不是坏了:**让主代理跑一次审计(或派一次活)即可恢复**,点「↻ 刷新」是次选(它只重读文件,不会重算结论)。

一个例外:**快照是旧版插件写的**时,重启会自动补写一次(把写入方版本对上新版)—— 只补写,不重算结论。审计区在还没有结论时会**明写「尚无结论」+ 下一步怎么做**(不会给你一片空白,也不会拿 `0 红 0 黄` 冒充全绿)。

---

## 文档放哪、怎么命名

> 这一节是**硬要求**:写错时工具会**直接拒绝**并告诉你正确路径(少数几条目前以体检提醒的形式出现,已在各条标注)。

### 目录怎么分(每类一个文件夹,禁止混放)

| 类别 | 目录 | 文件名 |
|---|---|---|
| 研究 | `仓库/docs/研究/` | `<任务号>_<标题>_研究.md` |
| 审查 | `仓库/docs/审查/` | `<任务号>_<标题>_审查.md` |
| 整合清单 | `仓库/docs/整合清单/` | `<任务号>_<标题>_整合清单.md` |
| 产出(三档) | `仓库/docs/产出/L1/`、`产出/L2/`、`产出/L3/` | `<任务号>_<标题>_L1.md`(L2、L3 同理) |
| 坑 | `仓库/docs/坑/` | 坑的主题名 + 索引在坑库 README |
| 修改 | `仓库/docs/修改/` | 重构、迁移记录 |
| 核心数据库 | `仓库/docs/核心数据库/` | 项目总地图(真身在 `docs/核心数据库.md`) |
| 归档 | `仓库/docs/archive/<YYYY-MM>/` | 按月份分片 |
| 临时文件 | `仓库/docs/_临时/` | json / tmp / bak 之类**不进**上面任何一栏(体检排除,不会被当成文档类别) |

几条硬规则:

- **审查报告不许出现在研究或产出目录**(类型和目录必须对得上)。「已强制」(体检项 `doc_kind_mismatch` 必报)
- **产出区是硬限制**:往产出区写非 `.md`、落错档级目录、文件名不符合规范 → 工具**拒绝**并给出正确路径。「已强制」
- **三档按档级分文件夹**:L1 详细归纳、L2 扩充细节、L3 高度概括,各放各的。「已强制」(写档工具直接落到对应档级子目录)
- **归档不靠文件名**:以前用文件名前缀 `^` 表示归档,现在归档写进**文档开头的属性**(`archived: true`),文件名不再带 `^`。「已强制」(让图书管理员跑一轮治理会自动去前缀 + 写属性,只改名不改正文;残留的 `^` 文件体检项 `legacy_caret` 会报)
- 命名规则(`<任务号>_<标题>_L<n>.md`)工具生成时已按规范来。「已强制」
- **每一类都有自己的索引**:每个类别目录下有一份 `索引.md`(**机器自动生成**,只在该文件的标记区块内增删,内容没变就不重写)——
  里面是这一类所有档的路径 + 档级/主题 + 关键词 + 字数 + 更新时间。体检发现「缺索引 / 条目数与磁盘不符」会报出来,
  让馆员跑一次索引重建即可。「已强制」(工具 `librarian_indexes`,治理时也会顺手重建)

### 规范和路径不用猜(契约里都写着)

派活时给子代理的契约里,**直接写着这一轮要用的东西**,所以它不需要去翻插件源码(源码不是规范来源,读了反而容易被实现细节带偏):

- **文档规范**:类别 → 目录 → 命名后缀 → 必备头部字段 → 硬限制 —— 与面板/体检用的是**同一份**(不会两处说法不一样)
- **本轮解析结果**:各类目录的**绝对路径**、临时文件目录、归档分片规则、**全局共享文件清单**
  (全局共享文件 = 一个项目只该有一份的那些:坑库索引 / 派生态索引 / 核心数据库 changelog / 归档目录 / 面板数据)
- **权威顺序**:① 契约里的本轮解析结果 → ② 显式配置 → ③ 自动探测。`project.json` 只是**派生物**,
  过期或与规范冲突时**以契约里的为准**;遇到不一致**按①执行并在报告里标注**即可,不必去源码求证
- **目标路径**:凡是"搬到哪 / 归到哪"的活,工具预演里直接给出**目标绝对路径**(不让它从候选清单里猜)

### 文档开头的属性(AI 速览那一块)

每份产出档开头有一小段属性,机器读它来检索、体检和指路。里面包括:任务号、角色、档级、关键词、相关文件、是否已归档。

- **渐进式披露**:想从概括看到细节,有一条**指路链** —— L3(高度概括)→ L2(扩充细节)→ L1(详细归纳);L3 和 L2 的属性里**直接给出 L1 的路径**,所以**最终都能落到 L1**。「已强制」(写档时工具自动填指针,缺指针体检会报)
- 这条链由工具写档时**自动填**,不需要人记。
- 正文第一屏给不超过 3 行的**速览**:这份给谁看、要细节去哪儿。

### 任务文件(`任务/` 目录里那些)

任务文件**不是**给人写的需求单,它是**子代理自己的作业登记卡**,由子代理自己写、自己维护:

```
- 上级:
- 占用文件或资源:   ← 逐条标注 只读 / 写(新文件) / 禁止改动
- 状态:
- 阶段产出:
- 异常:
(推荐再加:结论摘要、风险)
```

人和助手只给**一句需求**;派活靠派单时自动装配的提示词。缺必备字段会在交付时进体检观察项(不刷噪音)。「已强制」

### 冲突与验收(自动,不用你盯)

- **占用冲突**:两个还在跑的代理都声明"写"同一个文件 → 体检会报出来(写写=红、一写一读=黄、写了"禁止改动"=黄),并建议串行或改分工。「已强制」
- **治理验收报告**:整理、归档这类工作结束时,插件**自动出一份报告** —— 移动/改名/更新引用/待归档各多少篇、**正文有没有被动过**(逐篇前后指纹)、有没有残留的旧路径引用、体检红黄的前后对比。「已强制」(整理/归档结束时自动出,`dryRun` 给预演版)

## 遇到问题先看这里

| 现象 | 原因与处理 |
|---|---|
| 面板说「数据源待接(快照由旧版插件写入)」——快照就是面板读的那份生成文件 | 插件升级后首次启动会**自动重写并补跑一次审计**,点「↻ 刷新」即可;若仍为空,让主代理**跑一次审计** |
| 面板审计区说「尚无结论」 | 面板数据只在**有动作**时重算。点面板上的**「强制刷新」**即恢复(= 跑一次审计 + 重写面板数据,不必等主代理);也可以让主代理跑一次 `audit_scan`(或派一次活)。「↻ 刷新」只是重读文件,救不回陈旧快照 |
| 重启后面板说「快照由旧版插件写入」,重启了也没恢复 | 正常启动**会自动补写**(扫全部已登记工作区,只重写旧版写的那份快照);若仍提示,说明自愈失败 —— 让主代理跑一次 `contract_status`,回执里的「启动自愈」行会写出失败原因 |
| 所有契约工具突然一起报错 / 面板不再更新 | 先看 `contract_status` 首几行有没有「**版本漂移**」:升级插件后**必须完整重启应用**(只刷新窗口/页面不算,进程里跑的还是旧代码) |
| 面板顶上出现红字「插件自检异常:…」 | 插件自检没过(典型:台账领域打不开)—— 按那句提示**完整重启应用**;重启后仍报就把原因贴出来(多半是某条记录不合 schema,宿主会把它挪去备份) |
| 面板整块「加载失败」 | 应用没挂 better-sidebar,或面板拿不到数据通道;按提示信息处理 |
| 后台子代理起不来、报 `unknown tool` | Windows 上终端工具叫 `pwsh`(见下一节) |
| 应用提示「组件启用失败」 | 第 2 节的“第一步”没做(依赖没装) |
| 想要对抗审查真的“对抗” | 给 `modelRoutes.adversary` 配一个不同来源的模型 |
| 换了个新文件夹当仓库,要改配置吗 | **不用**。插件跟着工作区走,会自己找/建目录;想先看它打算建什么,让主代理调 `project_init`(默认只预览) |
| 面板说「数据源待接」但项目里明明有档 | 面板按**会话目录**找 `panel.json`。若你把 `project.root` 指到了别处,面板找不到属正常(见「已知限制」第 8 条);跑一次审计或点「↻ 刷新」会重写快照 |
| 审计报一堆黄 | 大多是“文档放错目录”或“旧文档缺头部信息”,让图书管理员跑一轮即可 |

---

## 已知限制

以下是随版本发布的已知边界,都有明确原因,不是待修的 bug:

1. **哪些键在「设置」页改、哪些仍在配置文件里**:
   - **设置页管**(`设置 → 多智能体契约`):模型路由 `modelRoutes`(每个角色用哪个模型)+ 五个面板开关(隐藏已完成的一次性节点 / 自动刷新 / 轮询间隔 / 默认视图 / 徽章文字标签)。这些是**运行时可变**的字段(宿主叫 volatile),改完**立即生效、重启后保持**;
   - **仍归 `cordis.patch.yml`**:`project.*` / `paths.*`(含 `panel.todoFile`)/ `delegation.*` / `roles` / `budgets` / `audit.*` —— 改这些要重建数据,所以设置页不给写;
   - **提醒**:配置文件里那几个被设置页接管的键**只作示例**(写了不生效,文件里已注释标注)。密钥永远不写在这里(由宿主/provider 账户持有)。
2. **对抗审查生效 = 两件事都到位**:① 配好 `modelRoutes.adversary`(本仓库默认已配 `glm-5.3-flash`,也可以在设置页的「调用 JSON」里改)+ ② **宿主里有那个 provider 的 key**(key 由宿主 provider 账户持有,插件不碰、也不会写进任何文件或设置)。缺任一样时「异源」徽章会显示 `unknown`(**不是“合格”**),审计也会给提醒;补齐后徽章应变成 ✓、审计不再报 `cross_vendor`。
   - **怎么判"是不是真异源"**:派活时会记下**这次实际跑在哪个模型上**(配了路由用路由;继承默认的也会解析出实际模型:宿主解析后的子智能体选项 → 子会话请求头 → 父路由 → 部署默认模型,回执里会写「模型:xxx(来源 …)」)。审计把**对抗审查与实现者两边的模型名**都写出来对比:相同 ⇒ 报黄;不同 ⇒ 不报。
   - **"没报"不等于"合格"**:如果任一侧的模型**拿不到**(宿主没给出模型信息),审计不会静默——它会给一条**观察项**「无法判定(缺模型数据):…」,明说这一条**判不了**,而不是假装通过了。
3. **图书管理员是「一个会话一个」的常驻成员**:宿主不允许跨会话给子代理投递消息,所以**每个会话有自己的常驻馆员**;
   换一个新对话再派馆员时,插件会**在本会话新建一个**,并把旧的标记为 `retired`(记录保留、写明原因与时间,不删)。
   同一个会话里再次派给它是**续派**(复用同一个,不新建)。项目里同一角色的活跃常驻成员**最多一个**。
   —— 顺带一句:它动的全是**全局共享文件**(坑库索引 / 派生态索引 / 核心数据库 / 归档目录 / 面板数据),
   所以角色卡与契约里都写着「写全局文件前先查占用」;跨会话并存时占用冲突会被体检报出来。
3. **归档 / 归位是“人或馆员触发”**:没有后台自动任务;审计只**建议**归档,写入文件由图书管理员执行(写之前会留一份旧文件,并记录改了什么)。
4. **面板数据来自生成文件 `panel.json`**:它由应用在审计或数据变更后自动写出,**不是真相**(真正的文档在项目目录里);可以随时删除、会自动重建,建议加进 `.gitignore`。
5. **Windows 的终端工具名是 `pwsh`,不是 `bash`**:插件会按系统自动选对名字再下发给子代理,配置里两种都写上即可。
6. **面板依赖 `betterSidebar`**:应用没挂 better-sidebar 时,面板**静默降级**(不注册页面、不报错、不影响其它功能);如果面板拿不到数据,它会显示“加载失败 + 原因”,不会给你一片空白。
7. **面板默认只读,唯一可写目标是待办文件**:`panel.todoFile`(默认 `<项目根>/待办.md`)里那份清单可以**勾选**、也可以**编辑后保存**;写入必须经过应用自带的写通道——只认这一个路径、每次写前留一份旧版、文件若已被别处改过则**拒绝覆盖并提示刷新**。除它之外(成员树、`agent 待办(执行队列)`、审计清单、所有文档)面板**一个字都不写**。
8. **零配置自适应(换仓库不用改配置)**:项目根默认**跟着当前工作区/会话**走(显式 `project.root` 优先),结构按候选清单探测既有目录、探不到才在项目根内新建默认结构(**只新建不覆盖**);一个插件实例因此可以同时服务多个项目,账本按项目名分域,两个项目来回切不会串。面板数据(`panel.json`)**由应用在会话出现时自动补写**——不需要你先跑一次审计;若它仍显示「数据源待接」,点面板的「↻ 刷新」或让主代理跑一次审计即可。三点边界:① 想锁死某个项目时才需要写配置(写了就以配置为准);② 面板找 `panel.json` 是按**会话目录**推的,所以「会话目录 = 项目根」时最稳;若你手动把 `project.root` 指到别处,面板可能找不到那份快照(此时它会明说“数据源待接”,不会给你过期的数字);③ **建目录只有 `project_init` 会做**(显式动作)——别的工具只补自己写的那一个目录,缺整套结构时回执与面板会**主动提示**你调 `project_init`,不会悄悄替你建掉。
9. **图书管理员的能力与纪律由插件给,不靠任务单临时抄**:馆员角色卡里写着完整职责(巡检直修 / 回填 / 归档 / 一轮治理 / 术语表 / 关键词复核 / 归位建议)+ 通用纪律(先 dryRun 预演 · 判不准就上报 · 改了位置同步引用 · 归档边界 · 改动留痕)。任务单只需要写**范围 + 本次特有约束 + 验收**。
10. **馆员的活主代理不能直调(默认警告,可开严格)**:`librarian_*` 这些工具的描述里写明「面向图书管理员,主代理应通过 `contract_delegate_librarian` 委派」;主代理直调会在回执里附一条警告(**馆长自己调用不受影响**)。想让主代理**根本调不动**,把 `delegation.strictRoleGate` 设为 `true`(默认 `false` = 只警告)。
11. **git 集成:默认只提示,提交要你自己开**:会动文件的一轮活,插件只读 `git status` 给你一句「建议先提交一次基线:当前有 N 个未提交改动」;**默认不会替你提交**。想让它自动提交就打开 `git.autoCommit`(`cordis.patch.yml` 的 `git:` 段)——它**只 add 本次动到的路径**、工作区有范围外改动就**中止**、信息里带任务号与备份目录、可选 `git.autoTag` 打锚点、**永不 push**;失败会明说且不影响治理本身。
12. **治理结束自动出一份验收报告**:`librarian_sweep` 跑完会给出「动作清单 / 正文零改动逐篇前后指纹 / 引用残留 / 审计前后红黄对比」,`dryRun` 给同一份的预演版;正文指纹真不一致时会**单独点出来**(治理只承诺动元数据、命名与位置)。

---

## 开发与测试

```sh
npm test                      # 或 node scripts/verify-node.mjs cordis.patch.yml
```

测试是交付的一部分:**每修一个问题,都要补一条能自动跑出来的检查项**——这样同类问题再犯时会当场被测试抓住,而不是等用起来才发现。

详细设计、缺陷单、各轮核验报告都在 `docs/` 下(`DESIGN.md` 是设计总纲;`docs/FIX.md` 是缺陷单;`docs/EXECUTOR-RULES.md` 是执行方行为准则)。

版本号以 `package.json` 为准。

Install

dsh plugin --profile web add github:t2094308-star/dsh-agent-contract

Profile: web

  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source