DSH E2E Dev SDD 架构
September 6, 2026 · View on GitHub
产品边界
插件提供五个独立阶段工作台,不提供自动跑完全流程的流水线。每次运行只处理一个阶段:选择输入、对话迭代、生成交付件、人工接受、Git 提交。
| 阶段 | 默认必选输入 | 默认可选输入 | 标准输出 |
|---|---|---|---|
| 需求讨论 | 无 | 对话、文件、外部来源 | requirement-spec |
| 原型输出 | 需求 | 外部设计资料 | prototype-spec |
| 系统设计 | 需求 | 原型 | architecture-spec |
| 规格设计 | 需求、系统设计 | 原型 | implementation-spec |
| 开发测试 | 规格设计 | 需求、原型、系统设计 | development-delivery、代码、测试证据 |
依赖规则是项目配置,不写死在 Client 页面。
项目真源
一个 DSH Workspace 对应一个项目 Git 仓库。一个主业务编号形成需求包,每个可独立交付的子需求形成工作单元;工作单元共享项目配置,但拥有独立五阶段交付件和开发空间。.sdd/ 保存研发过程和运行状态,项目根目录的 product/ 与 deliveries/ 保存可以脱离插件阅读和移交的长期产品资产:
.sdd/
├── project.yaml
├── templates/<stage>/
│ ├── template.yaml
│ └── deliverable.md
├── artifacts/<stage>/<artifact>/
│ ├── manifest.yaml
│ ├── deliverable.md
│ └── .template/ # 创建交付件时固定的模板快照
├── sources/
├── imports/pending/<preview>.yaml
├── work-items/<uid>/
│ ├── work-item.yaml
│ └── artifacts/<stage>/<artifact>/
├── business/
│ ├── README.md
│ ├── connectors/
│ └── adapters/
├── runs/
├── development/
├── openspec/<work-item-uid>/ # 开发前的 OpenSpec 规划工作区
└── events/
product/
├── feature-catalog.md # 全部特性索引
├── product-specification.md # 当前有效产品规格
└── features/<feature>/ # FEAT 生命周期与当前规格
deliveries/<delivery>/ # DLV 不可变交付归档、转测报告与邮件稿
Host 通过 DSH Workspace registry 校验 workspaceId,浏览器不能直接指定任意宿主路径。浏览器只发送 Workspace ID 和领域动作。
跨阶段 OpenSpec 工作区
OpenSpec 是内部实现机制,不是普通用户需要理解的产品概念。首次启动某需求的阶段会话时,插件在后台尽力于 .sdd/openspec/<work-item-uid>/ 创建项目管理的规划工作区和规划单元;不可用时退回内置的同构结构化引导。需求、原型、架构和规格会话对内部规划文件拥有受控写权限,并在形成确定结论时同时更新 SDD 阶段成果和对应规划产物。正常阶段页面不展示启用、Schema、Change 或 CLI 操作。
规划阶段仍将目标代码仓作为只读参考。开发阶段创建配置仓库的隔离 Worktree 后,插件将规划工作区的 openspec/ 复制到该特性分支;此后隔离代码仓中的副本成为权威工作副本。已有仅在开发 Worktree 中使用 OpenSpec 的项目继续按原路径解析,旧 action 和 Work Item 字段保持兼容。
底层 OpenSpec 配置、Schema 和文件管理 action 保留为管理员与后续高级设置能力,不进入日常需求路径。Source Provider、Connector、Adapter 与 source-bundle@1 协议不参与此过程,协议和调用方式保持不变。
SDD 项目仓库协作
外层 Workspace Git 仓库负责共享 .sdd/ 过程数据以及根目录 product/、deliveries/ 产品资产,与开发阶段绑定的目标代码仓库相互独立。project.yaml 的 collaboration 配置 remote、协作基线、同步策略和提交范围。页面读取本地分支、upstream、ahead/behind、暂存、未跟踪和冲突文件;Fetch 可以直接执行,自动同步只使用干净工作区上的 merge --ff-only。分支分叉和 Git 冲突不会被自动合并。默认项目提交范围暂存 .sdd/、product/、deliveries/ 与 .gitignore,Push 必须由用户显式确认。
交付件关系始终使用 UUID,REQ/UX/ARCH/SPEC/DEV key 只是显示编号。并行分支合并后若不同 UID 血缘使用同一 key,项目状态会报告编号冲突:尚未绑定会话、开发空间或修订血缘的草稿可以保留原前缀并追加 UID 短后缀;任何已验收血缘冲突都需要人工决定,不能静默重编号。
身份与编号
编号分为三层,不能相互替代:
uid是插件生成的不可变技术身份。- 交付件
key是插件生成的阶段编号,固定采用REQ/UX/ARCH/SPEC/DEV前缀和项目内四位递增序号。 - 企业需求号、子需求号、缺陷号是 Source/Work Item 的外部编号,由人工录入或 Source Provider 原样返回。
企业编号通过来源引用和追踪关系关联到工作单元及交付件,不参与交付件编号分配。父子关系和追踪关系必须引用 UID 或带命名空间的外部引用,禁止从编号字符串推导领域关系。project.key 只是当前本地 SDD 工作空间的标识,初始化时默认取目录名,也不是企业需求编号。
Git-only 的并行分支无法安全分配全局连续序号,所以模板序号只是便捷显示值;冲突由校验器拒绝,内部 UUID 不受影响。
来源归一化
所有对话、文件、CLI、MCP 和外部系统内容统一转换成 dsh-sdd/source-bundle@1,其中 items 至少包含一个 source@1:
manual/CLI/MCP provider -> Source/Bundle -> change preview -> work item -> AI synthesis -> draft artifact -> human acceptance
Connector 只提供来源,不直接创建 accepted 交付件。命令型 Connector 使用 stdin JSON / stdout JSON,命令以 argv 数组存储,凭证只从声明的环境变量读取。统一目录解析器合并插件 business/ 与项目 .sdd/business/,两处使用相同 Connector 和 Adapter 文件格式;项目同名配置覆盖插件配置,并在页面标明来源。
内置 manual Provider 不需要 Connector。用户只填写标题、初始描述和可选的多行子项,Provider 将其归一化为同一个 source-bundle@1 协议;信息不完整是允许的,需求讨论阶段的 Agent 负责追问并把确认结论写入正式交付件。
再次导入同一需求包即为同步。核心按 provider + kind + externalKey 匹配工作单元,比较来源内容、标题、状态和版本,预览新增、修改、移除、无变化四类结果。应用变更会新增来源快照而不覆盖历史版本;已有 accepted 交付件保持冻结,工作单元进入 change-pending,相关阶段必须使用最新来源和重新接受的上游交付件完成评审。外部移除进入 removed-pending,负责人可以保留本地继续推进或归档工作单元;两种操作都不会删除历史文件。
导入预览正文按条目从 .sdd/imports/pending/ 延迟读取,避免大需求包一次性进入浏览器响应。缺陷执行归属不由 Provider 推断:项目看板入口写入 executionMode: standalone;需求内入口写入 executionMode: attached 和 parentWorkItemUid。旧工作单元没有 executionMode 时按 standalone 读取,因此旧项目和旧适配器无需迁移。需求内缺陷仍拥有独立 Source 和 Work Item,用于外部编号、状态与再次同步,但不进入五阶段交付矩阵;其当前来源会自动加入父需求的候选输入和修订差异。
企业通用业务代码和配置统一位于插件 business/,项目专用代码和配置统一位于 .sdd/business/。两处都把 Connector YAML 放入 connectors/,被调用的脚本及其内部模块放入 adapters/;Connector 中的 .sdd/business/adapters/ 是逻辑路径,运行时映射到实际生效范围。项目代码不得再散落到 .sdd/scripts/、仓库根目录或其他 SDD 状态目录。
阶段对话
Client 根据用户为当前工作单元自由选择的来源和 accepted 交付件向 Host 请求阶段输入。默认灵活模式把五个阶段视为可选能力,只有严格模式才应用项目声明的 required 依赖;不需要的阶段记录为 not-applicable,不生成占位交付件。Host 读取固定版本内容并生成阶段提示;StageRun 固定绑定 Session、目标交付件及实际依赖,Agent scope 安装阶段 System Prompt 和工具 Guard。
交付件生命周期
draft -> in-review -> accepted -> superseded
交付件目录是一个多文件包。accepted 时冻结除 Manifest 外的全部文件清单和整包哈希;从 accepted 创建修订前先比较来源、上游交付件和模板的版本及哈希。上游无差异时必须提供用户主动调整原因,不能创建无证据修订。新修订复制完整目录,记录 supersedes、结构化 revision 和 previousRunUid;新版本验收后旧版本进入 superseded,引用旧上游哈希的下游版本自动进入待重审状态。详细规则见 docs/artifact-package.md。
Agent 可以创建和修改 draft;接受动作必须由用户从阶段页面触发。接受时 Host 校验 manifest 和入口文件,并记录内容哈希。accepted 版本需要修订时创建新版本,不能原地覆写。
产品基线与交付收口
需求工作单元描述一次研发变更,FEAT 描述跨需求长期存在的产品能力,产品当前规格描述此刻有效的产品事实。开发交付已验收、来源无待处理变化且没有遗留草稿时,用户可以执行交付收口:创建新特性,或把当前需求作为一次更新/废弃记录追加到现有特性生命周期。
收口在项目根目录的 deliveries/ 生成一个 DLV 不可变归档,复制当前需求全部 accepted/superseded 阶段成果、当前来源快照和项目管理的内部规划副本,并记录目标仓库分支、基线提交、交付提交及有效测试证据。相同结构化数据同时渲染为 transfer-test-report.md 和 transfer-test-email.md。归档 Manifest 最后写入,未完成的中间目录不会进入项目快照。
每次收口都会在根目录的 product/ 重建 feature-catalog.md 和 product-specification.md。前者用于定位所有有效或已废弃特性,后者只汇总当前有效特性的最新规格;历史事实从特性 feature.md 生命周期和 DLV 归档追溯,不能把旧需求正文简单追加为当前规格。工作单元和其需求内缺陷在成功归档后进入 completed。
需求开发空间
阶段代码目录统一收束在已加入 .gitignore 的 .sdd-workspaces/:
.repositories/<repository-id>.git保存远程仓库唯一一份 bare 对象缓存;本地仓库不复制对象。.references/<repository-id>/<commit>/保存非开发阶段按需复用的 Detached 只读参考。<artifact-key>/<repository-id>/保持现有开发目录,使用特性分支 Worktree。
需求、原型、系统设计和规格设计会话默认获得项目登记的全部仓库,不再逐阶段选择。每次运行在 .sdd/runs 固定记录仓库、基线 Commit、实际路径和可用状态;无仓库时不生成 codeReferences,旧项目运行逻辑不变。远程参考准备失败不会阻止非开发阶段,开发目标仓库不可用仍按开发门禁阻止。
- 一个开发单元可以包含多个仓库。
- Agent Session 保持项目空间 cwd;代码工具的
workdir被 Guard 限定到绑定的隔离 checkout。 - 开发会话显式获得每个仓库的根目录和开发目标,并在修改前读取仓库内
AGENTS.md、构建/CI 配置及匹配的.agents/skills/*/SKILL.md;嵌套 Skill 不依赖自动出现在外层会话目录。 - 同一工作单元的开发交付件修订复用物理 checkout 和特性分支,但创建新的 artifact 注册并使旧测试证据失效。
- 代码提交到目标仓库;SDD 仓库只保存 commit、PR、merge commit 和测试证据。
合并策略支持 pull-request、local-merge 和 manual,默认 pull-request。
UI 兼容性
DSH 当前侧边栏没有第三方多入口导航 slot。插件采用 dsh-web 已验证的 DOM 注入和独立中央面板模式,集中管理项目看板、五阶段工作台和项目设置入口。所有 DOM 写入都有插件属性标识并随 Cordis effect 卸载。后续 DSH 提供正式导航 slot 时,应迁移到 slot,而不改变领域协议。
导入预览、预览项正文和应用前校验只读取项目配置、来源、工作单元以及必要的轻量 Artifact Manifest,不执行完整 Snapshot 中的交付包哈希、质量评估、Git、OpenSpec、运行绑定和看板计算。应用成功后只生成一次完整 Snapshot;客户端预览期间原位更新忙碌提示,不重建整个看板 DOM。
来源 JSON 的预览采用受限深度和数组分页,深层节点由用户按需展开。疑似 HTML 字段只允许文本排版、列表、表格、链接和代码等白名单标签与属性,通过 DOMPurify 净化;脚本、内嵌页面、表单、事件属性和远程图片不会进入预览 DOM。源码模式始终保留原始 JSON/HTML 文本供核对。
已实现的运行层
StageRun持久绑定阶段、交付件、输入和 DSH Session。- Agent scope System Prompt 和工具执行 Guard。
- 阶段输入门禁、结构质量报告、人工验收清单和 accepted 哈希冻结。
- 开发阶段 Worktree/clone、AI 驱动测试、真实执行证据与本地提交门禁。
- 项目看板与 append-only 事件日志。
- 产品特性生命周期、产品当前规格、不可变需求交付归档及转测材料生成。
- 看板统计以独立交付工作单元为五阶段分母;需求内缺陷只进入父需求的缺陷覆盖指标。服务端按工作单元、阶段和来源建立内存索引,客户端对交付矩阵先筛选再限制为 200 行,避免项目规模增长后重复全表扫描和过量 DOM 渲染。
后续边界
- Git push、PR/MR 与 merge gate 需要独立的、带用户确认的远程写能力。
- MCP Source Provider 和可写外部系统能力。
- 交付件显式 superseded 关系和业务侧变更回写。
- 基于事件日志的按日趋势图和周期时间统计。