muse-agent-example/docs/plans/2026-08-24-双底座适配接缝.md

305 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 双底座适配接缝 plan
日期:2026-08-24
范围:`agent-example/`;父仓仅改仍指向本仓旧路径的活文档。
状态:取代 [2026-08-23-目录分层改造](2026-08-23-目录分层改造.md),作为当前执行入口;阶段 0、阶段 1 与阶段 2 的无宿主门禁已落地,DSH 配置与无凭据失败闭环已核实,真实模型、只读工具闭集和 Muse 业务旅程仍未验收。
架构事实:[DSH / Pi 与 Muse 的框架业务分离研究](../../../docs/research/dsh-pi-muse-framework-business-separation-2026-08-23.md)(2026-08-23;DSH 上游 `0.1.1-rc.2` / Pi 本机 `0.84.2`)。
---
## 1. 意图
上一轮目录分层抓住了主权边界,但不能再按「把 58 个 Skill 搬进嵌套目录」当主路径执行。
正确合同:
> **DSH / Pi 负责一次 Agent 如何运行;Muse 负责作品现在是什么、候选能否进正典、用户做了什么决定。**
> 代码上可以只有 `muse/` 与 `framework/`,中间必须有一条适配接缝。适配器不是第三个业务所有者。
目标结构:
```text
Muse 业务层
作品 / 正文 / 实体 / 范式
Context Freeze / asOf / 候选 CAS / 人闸 / 额度 / 证据
Studio / 决策通道
│
│ FrameworkPort
▼
framework/
RoleTaskRequest 由 Muse 解析之后,只进下面三类对象:
FrameworkExecutionRequest / FrameworkEvent / FrameworkExecutionResult
┌────┴────┐
▼ ▼
adapters/pi adapters/dsh
│ │
Pi DSH + Cordis
```
本改造先把**依赖方向**拆开,再用同一份冻结任务接 DSH 最小切片。不再把剩余 `git mv` 当主工单。
---
## 2. 对上一份 plan 的修正
| 旧 plan 假设 | 核对后的事实 |
|---|---|
| `framework/` 还不存在,从拆 dispatch 五文件开始 | `framework/primitives/agent` 与 `framework/adapters/pi` 已在盘上 |
| 目录分开 ≈ 框架业务分开 | 目录已分开;`runner.py` 仍 `import agent_trace`,`agent_task.py` 仍加载 Muse 角色合同,`dispatch_agent_task.py` 仍做 `fixed-opus` 检查 |
| 方法 Skill 沉到 `.agent/skills/{planning,writing,diagnosis}/` 即可被任何宿主发现 | 嵌套已经发生。DSH 默认 Skill Provider **不支持**递归 `**/SKILL.md`。不能回滚嵌套,必须加扁平投影或自定义 `SkillProvider` |
| 「插件 / Skill / Agent」是 DSH 原生三层 | DSH 原生是 Cordis service、scope、event waterfall、Session、Agent preset、subagent provider。Muse 的三层是上层约定,不能把 Skill 文本当权限 |
| `dsh-llm-pi-ai` 能复用 Pi coding agent | 它只用 `@earendil-works/pi-ai`。DSH 与 Pi coding agent 仍是两个适配器 |
| session log 投影进库可以当原子审计 | DSH `session/event` 观察与持久化异步分开;session log 是执行事实,不是内容权威 |
| 用 `agent/turn-stopping` 当 JSON Schema 门 | 结构化输出由 Muse 任务宿主或明确声明该能力的 Provider 校验 |
旧 plan 第 8 节映射表描述的 **muse/ 落点大体已经在盘上**。剩余缺口是 SoT 仍在 `muse/sot/`、入口文档目录树仍写旧根、以及框架反向依赖业务。
---
## 3. 当前磁盘(执行起点,不是目标)
根上已是 `framework/` + `muse/` + `.agent/`(方法 Skill 嵌套)+ `docs/` + `tests/`。`requirements.txt` 已指向 `muse/platform/*` 与 `muse/lifecycle/quality/humanization`。
仍未拆开的耦合(本轮已读源码,不是推断):
| 位置 | 问题 |
|---|---|
| `framework/adapters/pi/runner.py` | `from agent_trace import AgentTraceWriter` |
| `framework/primitives/agent/agent_task.py` | `import muse_role` / `muse_role_contract`;`SUPPORTED_AGENT_ROLES` 绑死五个 Muse 角色 |
| `muse/lifecycle/dispatch/skills/dispatch-agent-task/scripts/dispatch_agent_task.py` | 在派发前做 `fixed-opus` 模型策略检查 |
| `tests/architecture/test_import_boundaries.py` | 适配器白名单已是 `framework/adapters/pi/runner.py`,**不**禁止框架 import 业务证据脚本 |
Skill 发现:
- Muse harness 已扫 `.agent/skills` 与 `muse` 下 `**/SKILL.md`,以 `skills.json` 的 `skill_path` 为位置 SoT。
- 15 个方法 Skill 已在 `.agent/skills/{planning,writing,diagnosis}/<name>/`。
- 编排 Skill 已在 `muse/**/skills/<name>/`。
- DSH 默认发现器对这套嵌套布局会漏掉方法 Skill,除非自定义 Provider 或生成扁平投影。
本机运行基线(2026-08-24)已核实:`dsh --version` 为 `0.1.1-rc.2`;`dsh --profile web --dump-config` 与 `dsh --profile headless --dump-config` 退出码为 0;无 API key 的 headless 任务按 `MISSING_CREDENTIAL` 失败关闭。该事实只证明 profile 可组合和错误路径可达,不证明真实模型或 Muse 业务旅程可用。`framework/adapters/dsh/` 已补无工具 fresh 对照适配器与 session JSONL 归一测试,生产默认仍是 Pi。
Skill strict 门禁在研究采样点为 9 个 `blocking` + 2 个 `major`,迁移稳定后必须重跑;采样数字不构成当前完成证据。
---
## 4. 稳定对象(先固化,再写适配器)
```text
Muse RoleTaskRequest
角色、业务任务、冻结上下文、模型策略、输出 Schema
│ Muse 解析(角色合同、额度、fixed-opus / governed-chain)
▼
FrameworkExecutionRequest
system prompt、user content、工具闭集、已解析模型、超时、会话模式
│ 适配器
▼
FrameworkEvent
framework、session、sourceSeq、kind、payload hash
│
▼
FrameworkExecutionResult
final output、actual model、usage、stop reason、artifact locator
│ 回到 Muse
▼
Schema 门 → 一致性检测 → 质量审核 → 人闸
```
框架只处理后三类。`workId` / `targetChapter` / `candidateStatus` / `acceptanceEligible` 不得成为框架判断条件。
插件可以做:只读 Context Tools、角色 Prompt Provider、工具准入与 asOf 防护、事件观察与 raw 导出、可选 Trajectory / TUI。
不得做成模型可喊 Skill:`decide-candidate`、`confirm-knowledge-draft`、`record-run-evidence`、`freeze-context`、`assemble-context`、Canonical 写入、CAS、人闸、额度结算。
---
## 5. Skill 挂载:不回滚嵌套,补发现投影
方法 Skill 的**所有权**留在 `.agent/skills/{planning,writing,diagnosis}/`(Muse 源)。
DSH / Pi 只消费同一源的**扁平投影**,禁止复制第二份正文:
```text
.agent/skills/planning/scene-craft/SKILL.md # 源(已在盘上;scene-craft 实际在 writing/)
framework/catalog/dsh/skills/scene-craft/SKILL.md # 生成物:单层 <name>/SKILL.md
framework/catalog/pi/… # 若 Pi 也需要显式 override,同样生成
```
生成器读 `skills.json` 里 `invocation=model_routed` 的条目,写出 DSH 能发现的 `<name>/SKILL.md`(链接或渲染,不是手改副本)。编排 Skill 不进该投影。
机械门:
- `model_routed` 必须在 `.agent/skills/` 下;`orchestrated` 必须在 `muse/` 下。
- 业务 manifest、Pi catalog、DSH catalog 三方对账。
- DSH 默认发现器扫到的名字集合 = `model_routed` 闭集;漏发现失败关闭。
二选一实现,阶段三开工前裁定,不允许「嵌套了就算 DSH 能用」:
1. 生成扁平投影(推荐,零运行时插件)。
2. 自定义 DSH `SkillProvider` 读 `skills.json`。
---
## 6. 阶段
依赖:0 可与 1 并行;2 依赖 1;3 依赖 0+1+2 且本机有可执行 `dsh`(或 CI 固定版本);4 依赖 3 的同源对照证据。
```text
0 活文档与 Skill 门禁基线
1 收紧 Pi 接缝(对象拆分 + 依赖方向)
2 跨框架协议、工件与门禁
3 DSH 最小切片:writer / planner
4 detector / extractor / judge → 再决定生产主宿主
```
不把「迁完剩余目录 / 把 SoT 搬到 muse/sot」做成前置。那些跟提交走,不单独开搬家阶段。
### 阶段 0:活文档与 Skill 门禁基线
意图:入口文档不再描述已不存在的根目录;Skill strict 失败项先清成后续迁移基线。
改:
- `AGENTS.md` §3 目录树改成当前 `framework/` + `muse/` + `.agent/skills/{planning,writing,diagnosis}`。
- `README.md`、`.agent/_index.md` 同步。
- 研究采样点的 9 个 `blocking` + 2 个 `major`:先重跑 `muse/lifecycle/quality/harness/skill_harness.py --strict`,按**当场输出**修 invocation / 死链,不沿用采样数字。
- `test_import_boundaries.py` 扫描范围去掉已不存在的根(若仍列 `dashboard/` 作 ACTIVE root,改成 `muse/authority/studio` 或删除空根)。
验证:
```bash
.venv/bin/python muse/lifecycle/quality/harness/skill_harness.py --strict
.venv/bin/python tests/architecture/test_skills_index.py
.venv/bin/python tests/architecture/test_import_boundaries.py
```
文档:本阶段只改入口树与发现合同表述,不改领域 SoT 正文。
### 阶段 1:收紧当前 Pi 接缝
意图:Pi 行为与回执字段不变;框架不再拥有 Muse 合同。
改:
1. 拆 `AgentTaskSpec`:
- Muse:`RoleTaskRequest`(角色、冻结输入、`modelPolicyRef`、`outputSchemaRef`、`toolPolicyRef`、`contextRef`)。
- framework:`FrameworkExecutionRequest`(已拼好的 system/user、工具闭集、已解析 model id、超时、`fresh|continue`、仅 `runId` 关联)。
2. `AgentTraceWriter` 改为注入的 `TraceSink` 协议;`framework/adapters/pi/runner.py` 删除 `import agent_trace`。
3. `fixed-opus` / `governed-chain` 校验移出 dispatch 里「看起来像框架」的位置,回到 Muse 角色策略(dispatch 在调用 adapter **之前**解析模型;adapter 只记账 requested/actual)。
4. `agent_task.py` 不再 `import muse_role_contract`。角色文件与角色合同的装配留在 `muse/lifecycle/dispatch/`。
5. 端口纯度门:`framework/` 不得 import `agent_trace`、Postgres、候选状态机、`muse_role_contract`、额度常量。
验证(必须证明「重构不改业务结果」):
```bash
.venv/bin/python tests/architecture/test_import_boundaries.py
.venv/bin/python tests/skills/dispatch-agent-task/test_dispatch_agent_task.py
.venv/bin/python tests/skills/record-run-evidence/test_agent_trace.py
```
新增:`tests/architecture/test_framework_port_purity.py`(扫描 `framework/` 的 forbidden import)。现有 dispatch 离线项全绿;不把真实模型调用算完成。
文档:`framework/README.md`、`dispatch-agent-task/SKILL.md`、`边界合同.md` 结构列、`07` §2 执行底座——写明三类框架对象与 Muse 解析职责。
### 阶段 2:跨框架协议与真实工件
意图:Pi 与未来 DSH 共用同一套 Event / Result,而不是各自发明业务含义。
改:
- 固化 `FrameworkExecutionRequest` / `FrameworkEvent` / `FrameworkExecutionResult` Schema(Draft 2020-12),放 `framework/primitives/`。
- 事件必须带 `framework`、`frameworkVersion`、`sessionId`、`sourceSeq`、`payloadSha256`;未知事件进 raw,不得丢弃后声称轨迹完整。
- 定义 Pi JSONL / 运行目录 transcript 与(预留)DSH session artifact 的定位、hash、flush 规则。flush 前 = live view;flush 后完整工件 = 审计证据。投影幂等、可检测 seq gap。
- 只读五工具输出保持结构化 JSON;Pi 与 DSH 只做工具适配,SQL 仍在 `muse/authority/tools/read/`。
- Skill 扁平投影生成器(或记录「阶段 3 用自定义 Provider」的书面裁定)落地,并加三方对账测试。
验证:flush / 崩溃重放 / seq gap / 重复投影的离线测试;catalog 对账测试。无 `dsh` 二进制时,DSH artifact 规则用夹具,不假装跑过 DSH。
文档:协议 Schema 本身是合同;`08` 只引用「执行日志 ≠ 正典」,不复制字段。
### 阶段 3:DSH 最小切片(writer / planner)
前置:本机或 CI 有**可执行**的固定版本 `dsh`。本机已满足该安装前置(`0.1.1-rc.2`),但真实模型、只读工具插件和同源业务旅程仍未验收;没有这些证据不得把阶段 3 或 DSH 生产接入标记完成。
只做:
- `framework/adapters/dsh/`:唯一碰 `dsh` 二进制/SDK 的位置,列入适配器白名单。
- 一个 profile:只读工具插件 + 角色 preset/prompt section + `tools.guard` + 事件观察 + 最终工件导出。
- 自定义 `SkillProvider` **或**消费阶段 2 的扁平投影。
- 能力矩阵:角色 × 场景 × Provider 声明 `toolFilter` / `persona` / `outputSchema` / continuable;不支持则**启动前失败**,禁止静默降级。
- 评委不在本阶段。子代理默认 `spawn` 新会话。
对照:
```text
同一 RoleTaskRequest(冻结输入 + 角色合同 + 模型策略)
├── Pi Adapter
└── DSH Adapter
↓
同一 Schema 门 / 一致性检测 / 质量审核 / 人闸
```
对照指标:Schema 合规、工具越权、asOf 泄漏、超时与恢复、轨迹完整性。质量分数是观察项,不代替机械门。
不做:迁 58 个 Skill、DSH 内嵌正文台、Canonical 写入插件、detector/extractor/judge。
文档:`framework/adapters/dsh/README.md`、`docs/research/2026-08-24-dsh-local-runtime-baseline.md`;`07` 补「双适配器、单一业务门」;AGENTS.md 写明生产默认仍是 Pi,直到阶段 4 有证据。
### 阶段 4:其余角色与生产主宿主
- 先 detector / extractor,再 judge。评委必须 fresh spawn,禁止 fork 父历史;进程外 Provider 缺能力则启动失败。
- Trajectory / Conversation Node 只投影执行;Studio 仍读库。节点必须带稳定业务 ID。
- 以同源对照的机械指标 + 标注为 external-live 的旅程证据,决定 DSH 是否成为默认执行宿主。没有回放和失败恢复证据前,Pi 保留为可用适配器。
- 两者都不得写 Canonical。
---
## 7. 机械门(阶段 1 起逐条装,阶段 3 齐)
1. **端口纯度**:`framework/` 不得 import 业务证据、库、候选状态机、角色合同、额度。
2. **能力矩阵**:Provider 不支持的能力启动前失败。
3. **Canonical 写入**:模型可见工具闭集无写正典动作;写者白名单。
4. **冻结与泄漏**:只读工具核验 `workId` / `asOf`;未来章、oracle、其他评委结果不可见。
5. **结构化输出**:Draft 2020-12,不用 turn-stopping 冒充。
6. **轨迹完整性**:源 session、sourceSeq、hash;flush 后才算审计;投影幂等。
7. **Skill 发现**:manifest / Pi 投影 / DSH 投影对账;嵌套源不得被当成 DSH 已发现。
8. **双框架黄金旅程**:同一冻结任务两臂,后续统一进 Muse 门。adapter fake 不算宿主证据。
9. **版本**:DSH、Pi、业务合同、角色合同、输出 Schema 各有版本和哈希。
---
## 8. 文档同步(跟阶段走,不是收尾)
| 阶段 | 必须改的活文档 |
|---|---|
| 0 | `AGENTS.md` §3 树、`README.md`、`.agent/_index.md` |
| 1 | `framework/README.md`、`dispatch-agent-task/SKILL.md`、`边界合同.md`、`07` §2 |
| 2 | 框架 Schema 文件本身;`08` 仅引用执行日志边界 |
| 3 | DSH adapter README、`07` 双适配器、AGENTS.md 默认宿主 |
| 4 | 角色合同里评委 spawn 纪律(若尚未写死为机械门) |
仍被 SoT 引用、路径会随阶段 0 入口树一起对账的:`创作周期与Skill导读.md`、`可视化模块合同.md`、`muse/authority/db/表映射.md`、父仓 `design-docs/流程-02B`(若仍指向 `muse/sot`)。死链失败关闭;不改 `docs/write-chapter/artifacts/` 与本文件对照用的旧路径。
SoT 已位于 `muse/sot/`:**不阻塞**阶段 1–3。后续若调整归属需单独提交,并同步 `ROLE_CONTRACT_RELATIVE_PATH` 与相对链接。
---
## 9. 明确不做
- 不把业务做成 DSH 插件全集。
- 不回滚方法 Skill 嵌套;用投影或自定义 Provider 兼容 DSH。
- 不把 `dsh-llm-pi-ai` 当成 Pi coding agent 适配器。
- 不把 session log 当正典,不把 DSH Session 与 PostgreSQL 当同一事务。
- 不先做 DSH 正文台、不先接评委、不先让两个框架各写一套写作逻辑。
- 无独立可执行 `dsh` 时,不声称 DSH 集成完成。
- 不改候选状态机、CAS、人闸通道、表结构。
---
## 10. 完成的定义
- 阶段 0:入口文档与磁盘一致;当场 `skill_harness.py --strict` 绿。
- 阶段 1:端口纯度门绿;既有 Pi 派发离线测试绿;框架不再 import `agent_trace` / `muse_role_contract`。
- 阶段 2:三类对象有 Schema 与离线重放测试;Skill 投影或 Provider 裁定已落盘并有对账测试。
- 阶段 3:可执行 DSH 上 writer/planner 与 Pi 同源对照有机械证据(Schema / 越权 / asOf / 轨迹)。
- 阶段 4:未获对照证据前,生产默认宿主不得改口。
无自动化绿证据不得声称阶段完成。研究记录里的采样数字只证明当时,不构成本 plan 的完成证据。