# DSH E2E Dev SDD 架构 ## 产品边界 插件提供五个独立阶段工作台,不提供自动跑完全流程的流水线。每次运行只处理一个阶段:选择输入、对话迭代、生成交付件、人工接受、Git 提交。 | 阶段 | 默认必选输入 | 默认可选输入 | 标准输出 | | --- | --- | --- | --- | | 需求讨论 | 无 | 对话、文件、外部来源 | `requirement-spec` | | 原型输出 | 需求 | 外部设计资料 | `prototype-spec` | | 系统设计 | 需求 | 原型 | `architecture-spec` | | 规格设计 | 需求、系统设计 | 原型 | `implementation-spec` | | 开发测试 | 规格设计 | 需求、原型、系统设计 | `development-delivery`、代码、测试证据 | 依赖规则是项目配置,不写死在 Client 页面。 ## 项目真源 一个 DSH Workspace 对应一个项目 Git 仓库。一个主业务编号形成需求包,每个可独立交付的子需求形成工作单元;工作单元共享项目配置,但拥有独立五阶段交付件和开发空间。`.sdd/` 保存研发过程和运行状态,项目根目录的 `product/` 与 `deliveries/` 保存可以脱离插件阅读和移交的长期产品资产: ```text .sdd/ ├── project.yaml ├── templates// │ ├── template.yaml │ └── deliverable.md ├── artifacts/// │ ├── manifest.yaml │ ├── deliverable.md │ └── .template/ # 创建交付件时固定的模板快照 ├── sources/ ├── imports/pending/.yaml ├── work-items// │ ├── work-item.yaml │ └── artifacts/// ├── business/ │ ├── README.md │ ├── connectors/ │ └── adapters/ ├── runs/ ├── development/ ├── openspec// # 开发前的 OpenSpec 规划工作区 └── events/ product/ ├── feature-catalog.md # 全部特性索引 ├── product-specification.md # 当前有效产品规格 └── features// # FEAT 生命周期与当前规格 deliveries// # DLV 不可变交付归档、转测报告与邮件稿 ``` Host 通过 DSH Workspace registry 校验 `workspaceId`,浏览器不能直接指定任意宿主路径。浏览器只发送 Workspace ID 和领域动作。 ## 跨阶段 OpenSpec 工作区 OpenSpec 是内部实现机制,不是普通用户需要理解的产品概念。首次启动某需求的阶段会话时,插件在后台尽力于 `.sdd/openspec//` 创建项目管理的规划工作区和规划单元;不可用时退回内置的同构结构化引导。需求、原型、架构和规格会话对内部规划文件拥有受控写权限,并在形成确定结论时同时更新 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`: ```text 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。 ## 交付件生命周期 ```text 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/.git` 保存远程仓库唯一一份 bare 对象缓存;本地仓库不复制对象。 - `.references///` 保存非开发阶段按需复用的 Detached 只读参考。 - `//` 保持现有开发目录,使用特性分支 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 关系和业务侧变更回写。 - 基于事件日志的按日趋势图和周期时间统计。