-
Notifications
You must be signed in to change notification settings - Fork 0
04 roadmap 02 minimum skeleton
← 返回 Wiki 首页 | 四、项目排期 · 02 最小可运行骨架 | 上一篇:关键操作状态矩阵 | 下一篇:迭代计划 P0–P4 →
本文档属于排期层。下列 14 步是 P0 完成的判定标准:全部通过才算 P0 完成,任何一步未通过都不得宣布交付。
14 步分两个验收关口交付:
P0-a验证架构是否成立,P0-b补齐完整安全路径。关口顺序不可颠倒,且P0-a未全绿不得进入P0-b。 两个关口合计仍是完整的 14 步,范围没有缩减。
只有两台 DSH Web 实例和一个持久化 relay 完成以下 14 步流程时,P0 才算完成。
14 步按证伪能力分为两个关口。划分依据是:一步若失败会推翻架构层的结构承诺,则属 P0-a;若只影响单条安全路径的完整性而不动摇架构,则属 P0-b。
| 关口 | 步骤 | 验证目标 | 准出条件 |
|---|---|---|---|
| P0-a | 1、3、5、6、7、8、9、11、14 | 写入协议、投递语义、审计同事务三项架构承诺成立 | 9 步全绿 |
| P0-b | 2、4、10、12、13 | 第二因素、恢复、在线可见范围、本地搜索、协议协商五条路径完整 | 余下 5 步全绿 |
P0-a不是「P0 的简化版」,而是 P0 的第一个验收关口。 只完成P0-a不得对外宣布 P0 交付,也不得进入 P1。
本关口的每一步失败都直接证伪一项架构承诺,因此必须最先跑通、最早获得反馈。
- 管理员创建两个一次性注册邀请码。
- (属 P0-b)
- 用户 A 创建组织、工作区和项目,并把用户 B 以开发者角色邀请进项目。
- (属 P0-b)
- 用户 A 创建一个工作项并分派给用户 B;用户 B 在收件箱看到持久化通知。
- 用户 A 发送联系人请求,用户 B 接受。
- 用户 A 在用户 B 离线时发送一条中文文本消息。
- relay 重启,队列、通知、工作项和组织切换状态不丢失。
- 用户 B 启动 DSH,持久化消息并 ACK,重启 DSH 后仍只看到一条消息和一条已读通知。
- (属 P0-b)
- 收件人队列满时,新发送被明确拒绝,已接收的早期消息不被删除。
- (属 P0-b)
- (属 P0-b)
- 上述每一步在审计表中都有对应事件,且被拒绝的越权尝试同样留下记录;审计表中不含任何消息正文。
这九步分别证伪的架构承诺:
| 步骤 | 若失败则推翻 |
|---|---|
| 1、3、6 | 身份、组织与成员关系的授权链(§32) |
| 5、7 | 单事务 + outbox 写入协议(§26.1) |
| 8、9 | 至少一次投递语义与 ACK 幂等(§28) |
| 11 | 队列不淘汰已接收消息的容量语义(§28) |
| 14 | 审计与领域写入同事务、拒绝亦留痕(§37) |
本关口补齐 P0-a 未覆盖的完整安全路径。这些步骤实现成本较高但不动摇架构结构,因此后置以换取更早的架构反馈。
- 两位用户各注册一个设备、设置密码或设备登录方式、登记
totp与一次性备用码、导出恢复包或配置恢复守护人,并经其他渠道交换公开联系人地址。 - 两人启动 DSH 后互相看到
online;用户 B 改为隐藏在线状态后,用户 A 只看到unknown,但消息投递仍正常。 - 用户 A 模拟丢失唯一设备后,使用恢复包或守护人阈值注册新设备;旧设备无法继续访问,仍在保留期内的非 E2E 数据可读取。
- 用户 A 在本地搜索到该条私聊;服务端搜索、线程与转发入口显示为未安装。
- 用旧协议版本的 host 连接 relay 时返回
PROTOCOL_VERSION_UNSUPPORTED并停止组织写入,不进入部分可用状态。
P0-a期间的过渡约束:第 2 步的完整认证材料尚未就绪时,注册流程仍必须创建RecoveryKit记录并落库(§7.2 要求首次注册必须创建),只是守护人阈值拆分与恢复演练推迟到P0-b验收。不得为赶P0-a而删除 schema 中的恢复字段,否则P0-b将变成破坏性表结构重写,违反§29.1 迁移策略。同理,第 13 步的
ProtocolVersion协商字段在P0-a即写入协议与数据库,只是拒绝路径的验收推迟。
dsh-chat/
DESIGN.md
packages/
chat/
contract/ @dsh-chat/contract:共享品牌 ID、命令、事件、错误码、schema 与 SPI
kernel/ @dsh-chat/kernel:L1 插件 bundle 与社区默认配置
cordis.patch.yml 本 bundle 向 profile 插入的 loader 条目(见 §6.2)
team/ @dsh-chat/team:L2 provider 覆盖与团队 bundle
enterprise/ @dsh-chat/enterprise:L3 provider 覆盖与企业 bundle
host/ dsh-chat host 插件:本地数据库、relay 客户端、同源路由、事件发布
client/ dsh-chat client 插件:DSH slot 注册、页面、store、CSS Modules
identity/ 身份、设备、恢复、会话与风险管制插件
organization/ 组织、成员、角色、ACL、项目与策略插件
workitem/ 工作项状态机、依赖、签收、评审与评论插件
presence/ 心跳、在线可见范围与订阅插件
messaging/ 私聊、群日志、编辑、撤回、ACK、游标与投递插件
content/ 附件、资源库、扫描、授权、保留与对象存储插件
notification/ 收件箱、邮件、SSE 与 outbox 消费插件
collaboration/ 共享、协作会话、执行租约与执行 provider 插件
repository/ 仓库、受控出站、webhook 与提交归因插件
bot/ 隔离群 Bot、公共工具目录与能力租约插件
search/ 索引管线、查询授权复检与设备侧索引插件
analytics/ 用量、预算、报告、排行与计费插件
compliance/ 数据导出、账号注销、组织删除与保留合规插件
audit/ 审计事件、哈希链、迁移、水位恢复、缓存失效与运维插件
examples/
two-users/ 两个 host、一个组织、一个项目和一个 relay 配置
注:上述结构中的
DESIGN.md现已重构为docs/Wiki,原文件保留为历史归档。详见原文档映射表。
@dsh-chat/contract 是唯一的共享协议包;kernel、team 和 enterprise 只选择其服务提供者,不重新定义命令或权限语义。
kernel 同时是 DSH 的安装入口:它以 dsh.bundle.patch 指向自身的 cordis.patch.yml,宿主 profile 在 dsh.profile.bundles 中登记该包名后才会装载 dsh-chat 的各插件。装载形态与版本锚定要求见插件化架构 §6.2。这不改变 kernel 既有的职责边界 —— 它仍然只排列插件与提供默认配置,不承载业务单例。
client 绝不访问 relay 凭证或数据库。
host 是浏览器面向组织、relay、协作、Bot、插件目录、分析和账单服务的唯一入口。
各目录对应的插件能力与提供者,见插件化架构 §6.1 能力与提供者矩阵。
上表列出全部 19 个包,但两个关口各自只需其中一部分。未装载的包必须显式返回 NOT_IMPLEMENTED,不得伪装为可用。
| 包 | P0-a | P0-b | 说明 |
|---|---|---|---|
contract |
✅ | ✅ | 含 ProtocolVersion 与恢复相关类型,两关口均需完整定义 |
kernel |
✅ | ✅ | L1 bundle,仅排列插件与默认配置 |
host / client
|
✅ | ✅ | 三层入口 |
identity |
✅ | ✅ |
P0-a 只需注册与设备签名;P0-b 补第二因素与恢复 |
organization |
✅ | ✅ | 组织、工作区、项目、成员、角色、ACL |
workitem |
✅ | ✅ | 工作项状态机、依赖、签收、评审与评论 |
messaging |
✅ | ✅ | 私聊队列、ACK、游标、容量语义 |
notification |
✅ | ✅ | 持久化收件箱与 outbox 消费 |
audit |
✅ | ✅ | 审计与领域写入同事务 |
presence |
— | ✅ | 心跳与在线可见范围(第 4 步) |
search |
— | ✅ | 仅 host 本地私聊与联系人查找(第 12 步) |
content、repository、collaboration、bot、analytics、compliance
|
— | — | P0 全程不装载,返回 NOT_IMPLEMENTED
|
team、enterprise
|
— | — | 属 L2/L3,P0 不涉及 |
P0-a 需装载 10 个包;P0-b 增加 presence 与 search,共 12 个包。 其余 7 个包在整个 P0 阶段均不装载。