Phase 1
MOSS v2 详细实施方案
MOSS v2 详细实施方案
状态:已实施并通过 v2 验收
范围:Today、Knowledge、Governance、Calibration,以及支撑它们的数据模型、规则引擎和审计能力 本文保留实施工作包、顺序和回滚基线;运行结果见 10-v2-acceptance-report.md
一、目标
本轮交付把当前本地 X Bookmarks 校准工具演进为可运行的 MOSS v2 子集:
- 使用通用
content_items模型承载多来源内容。 - 保留已有 996 条内容、Feedback 和导入历史。
- 通过规则引擎生成可追溯的 Today 信号。
- 提供 Today、Knowledge、Governance 和 Calibration 四个路由。
- 让导入、Feedback、信号发布与 Audit Event 保持事务一致。
- 在任何迁移或信号发布失败时保留上一个稳定状态。
二、交付边界
2.1 本轮包含
bookmarks到content_items的一次性迁移。- 内部 ID 与
(source, source_id)分离。 - X 日期严格解析。
- Feedback 外键迁移和现有 API 兼容更新。
signal_runs、signals、audit_events。- 5 条本地声明式规则。
- generation key 和 append-and-publish 信号发布。
- Today、Knowledge、Governance、Calibration。
- 共享 Sidebar、Topbar、Inspector 和移动端导航。
- 迁移、回滚、故障注入、视觉和回归测试。
2.2 本轮不包含
- X.com 在线采集和浏览器自动化。
- RSS、Pocket 等第二个真实连接器。
- 云端模型、摘要、向量数据库或语义搜索。
- Action、Context、Self、Asset 的真实业务功能。
- 多用户、远程访问、账号系统和公网部署。
- 自动执行外部写操作。
- 对真实订阅、支付、日程或账号进行修改。
三、实施原则
3.1 数据优先
路由和界面开始前,必须先完成数据迁移、类型兼容、查询层和规则发布机制。UI 不得依赖临时 mock 数据掩盖底层缺口。
3.2 每个提交都可构建
架构步骤编号不等于提交顺序。实施必须使用下列原子交付顺序:
基线冻结
→ 1 + 2 + 9A + 10A
→ 4
→ 3 + 10B
→ 5 + 9B
→ 6
→ 7
→ 8
→ 加固与文档3.3 失败不破坏稳定状态
- 数据迁移失败:旧表和旧数据保持不变。
- Feedback 审计失败:Feedback 不落库。
- 导入审计失败:内容、导入批次和审计记录全部回滚。
- 信号发布失败:旧 active run 和旧 signals 继续可读。
- 路由迁移失败:不删除当前可工作的入口。
3.4 不扩大安全边界
当前 API 仍以个人本机运行作为前提。实施不能把服务暴露到公网,也不能新增外部数据发送或账号写操作。运行手册必须使用 loopback 地址;没有认证前不得绑定公网网卡、反向代理或隧道。
四、角色与责任
| 角色 | 责任 |
|---|---|
| 实施者 | 按工作包实现、补测试、保存证据,不跳过原子提交边界 |
| 审查者 | 审查 schema、迁移、事务、缓存失效和 API 兼容 |
| 验收者 | 按 09-v2-acceptance-standard.md 独立执行验收 |
| 数据所有者 | 确认备份、数据可见范围和最终迁移窗口 |
同一人可以承担多个角色,但验收记录必须区分“实施结果”和“验收结论”。
五、开始实施前的基线冻结
5.1 前置条件
- 当前分支工作区干净。
npm test和npm run build在现有实现上通过。data/moss.sqlite可以正常打开。- 当前 996 条 X Bookmarks 和现有 Feedback 数量已记录。
- 当前页面、API 和导入脚本的行为已有基线截图或日志。
5.2 必须保存的基线证据
| 证据 | 内容 |
|---|---|
| Git 基线 | 分支、commit SHA、Node 和 npm 版本 |
| 数据基线 | bookmarks、feedback_events、import_runs 数量 |
| 数据完整性 | PRAGMA integrity_check 和 PRAGMA foreign_key_check |
| 功能基线 | Calibration 打开、Feedback 提交、画像与历史页面 |
| 文件基线 | SQLite 文件大小和校验值 |
5.3 备份要求
- 停止所有写入。
- 使用 SQLite 安全备份方式生成快照。
- 对备份执行完整性检查。
- 记录备份时间、大小、校验值和原数据库路径。
- 在数据库副本上完成第一次迁移演练。
- 未完成恢复演练前,不允许在唯一数据副本上执行迁移。
六、工作包 A:数据模型与现有闭环原子升级
对应步骤:1 + 2 + 9A + 10A。
6.1 目标
在不改变现有根页面结构的情况下,完成数据模型、类型、现有 UI 引用和 Feedback API 的同步升级,并恢复可构建状态。
6.2 前置条件
- 基线冻结完成。
- 数据备份已验证。
- 严格日期解析器已使用全部 996 条现有日期样本验证。
6.3 实施任务
数据 schema
- 创建
content_items目标表。 - 使用
PRAGMA user_version标记 schema;v2 目标版本为 2。 id作为 MOSS 内部身份。- 新内容内部 ID 使用 UUID。
source_id必须非空且在同一 source 内稳定。- 建立
(source, source_id)唯一约束。 - 无原生 ID 的 fallback 使用统一、带版本的 URL 规范化与 SHA-256 契约;本期用单元测试验证,不要求接入第二个真实连接器。
- 创建新版 Feedback、Signal 和 Audit 相关表。
- 开启 WAL 和 foreign keys,并保留单例数据库连接。
日期与解析器
- 新增共享 X 日期解析模块。
- 迁移和新导入必须调用同一实现。
- 解析必须同时验证格式、真实日历日期、时间、星期和时区偏移。
- 解析失败必须携带 content ID 和原始日期。
- 禁止使用当前时间代替无法解析的原始时间。
数据迁移
- 在单个事务中复制旧内容。
- 构造 X metadata。
- 重建 Feedback 外键。
- 校验缺失内容、Feedback 数量和孤儿外键。
- 校验通过后再删除旧表。
- 回填历史导入和 Feedback 的 Audit Event。
- 仅在全部校验和回填成功后,于同一事务中写入目标 schema 版本。
- 高于当前应用支持范围的 schema 版本必须拒绝打开,禁止猜测或自动降级。
导入事务
- 按
(source, source_id)upsert。 - 重复导入不得改变内部 ID。
- 内容、Import Run 和 Audit Event 在同一事务提交。
- URL 缺失时写入数据库 NULL,不传递未定义值。
现有页面兼容
- 当前根页面切换为 ContentItem 类型。
- Calibration、画像、历史、筛选和上下文面板保持原功能。
- 暂时保留当前 app shell 和根路由。
- 此阶段不创建新的 workbench route group。
Feedback API
- 请求字段由
bookmarkId改为contentId。 - 保留
{ event }响应 envelope。 - Feedback Event 与 Audit Event 在同一事务提交。
- 审计写入必须复用同一数据库连接和外层事务,不能通过独立连接或事后任务补写。
- API 层不得在业务写入成功后再单独补写审计。
脚本和测试
- 新增通用导入脚本名。
- 旧导入命令保留兼容别名。
- 更新解析测试、类型名称和 UI 测试数据。
- 增加非法日期、同源重复和跨源同 ID 测试。
6.4 完成条件
- 旧数据库副本可一次迁移成功。
- 再次启动不会重复迁移或重复回填。
- 996 条内容、现有 Feedback 和历史记录完整。
- 当前根页面及 Feedback 闭环可用。
- 构建和测试通过。
6.5 回滚
工作包 A 失败时不得尝试“修补已经迁移一半的数据库”。应停止应用,保存失败副本用于分析,恢复已验证的基线备份,再修正迁移逻辑并重新演练。
七、工作包 B:查询层
对应步骤:4。
7.1 目标
提供规则引擎和四个页面所需的稳定数据库查询,不创建 UI。
7.2 查询契约
| 查询 | 契约 |
|---|---|
| Latest Signals | 只读取唯一 active run,不使用最大 ID 猜测 |
| Domain Coverage | 固定返回 6 个域,即使某域数量为 0 |
| Audit Events | 按时间和 ID 稳定倒序,支持 limit |
| Content Flow Stats | 总内容、Feedback、覆盖率、来源分布、最近导入 |
| Category Breakdown | 只统计 X Bookmark 的 category metadata |
7.3 实施要求
- 所有 JSON 字段在数据库边界完成解析。
- TypeScript 不得使用未约束的隐式
any。 - 空库、无 active run、无 Feedback 时返回明确空值。
- 查询不得产生业务写入。
- 规则引擎开始前,
getLatestSignals()必须已经可用。
7.4 完成条件
- 每个查询都有正常、空数据和边界测试。
- 同一数据快照重复查询结果稳定。
- 查询结果满足页面需要,不要求页面做二次 SQL 语义推断。
八、工作包 C:规则引擎与刷新接口
对应步骤:3 + 10B。
8.1 目标
实现可追溯、可缓存、失败可回退的本地规则引擎。
8.2 generation key
先计算不含强制刷新随机量的 base_key:
- 本地日期。
- 最近 Import Run ID。
- 最近 Feedback Event ID。
- 集中维护的规则版本。
普通访问只要 active run 的 base_key 一致就直接命中。强制刷新绕过该命中,并用 base_key + refresh nonce 生成唯一 generation_key。新批次发布后,随后的普通访问仍应按相同 base_key 命中,不得重复评估。
规则逻辑发生变化时必须提升规则版本。代码审查需把“规则变更但版本未提升”视为阻塞问题。
8.3 发布流程
- 读取当前 active run。
- 非强制请求且
base_key一致时直接返回当前 signals。 - 强制刷新或
base_key变化时,在事务外评估规则。 - 任一规则失败时保留旧 active run。
- 在事务内再次检查相同 generation key 是否已发布。
- 将旧 active run 标记为 superseded。
- 写入新 active run、signals 和 Audit Event。
- 任一步失败时整个事务回滚。
- 页面只读取 active run。
8.4 初始规则
| Rule ID | 输入 | 输出域 | 主要阈值 |
|---|---|---|---|
| uncalibrated-categories | 分类总数与 Feedback 覆盖 | Knowledge | 总数大于 20 且覆盖低于 10% |
| stale-import | 最近 Import Run | Knowledge | 超过 7 天 warn,超过 30 天 danger |
| feedback-coverage | 总内容与已反馈内容 | Governance | 覆盖低于 10% |
| author-review | 作者内容与正向 Feedback | Knowledge | 至少 5 条且无正向 Feedback |
| category-skew | X 分类占比 | Governance | 单分类超过 30% |
8.5 刷新接口
- 只接受 POST。
- 使用 nonce 创建新的 generation key。
- 不得先删除当前 active run。
- 返回新 active run 的信号数量。
- 失败时返回错误,但旧信号仍可读取。
- 当前仍是本地未认证接口,不得暴露到公网。
8.6 完成条件
- 缓存命中不创建新 run。
- Import 或 Feedback 变化自动生成新 run。
- 强制刷新生成新 run。
- 故障注入后旧 active run 保持可用。
- 任一时刻最多一个 active run。
九、工作包 D:共享壳与 Calibration 搬迁
对应步骤:5 + 9B,必须作为一个原子提交。
9.1 目标
创建 workbench route group,并在同一提交中把 Calibration 从根页面迁移到 /calibration,避免路由冲突和双重外壳。
9.2 实施任务
- 创建共享 Layout。
- 提取 Sidebar、Topbar、Inspector 和移动端导航。
- 创建根路由到
/today的重定向。 - 创建
/calibration。 - 从 MossWorkbench 移除旧 Sidebar、Topbar、Inspector 和最外层 grid。
- 保留 Calibration 内部的校准、画像、历史 tab。
- 删除旧根
page.tsx。 - 使用 pathname 驱动导航高亮。
9.3 响应式要求
- 桌面显示 Sidebar、主内容和 Inspector。
- 中等宽度隐藏 Inspector 时,页面仍有直接进入对象详情的路径。
- 移动端使用单列内容和可访问导航。
- 不允许出现双重导航、隐藏死路或横向溢出。
9.4 完成条件
/重定向到/today。/calibration保留现有闭环。- 四个目标路由共享单一外壳。
- 构建阶段不存在重复根路由。
十、工作包 E:Today
对应步骤:6。
10.1 数据
- 页面请求触发或读取 active signal run。
- Focus 只显示 warn 和 danger。
- Signal Cards 显示全部 active signals。
- Coverage 固定展示 6 个域。
- 日期按本机时区显示。
10.2 状态
- 有信号。
- 无信号。
- 无导入数据。
- 规则失败但存在旧 active run。
- 规则失败且从未有成功 run。
- 手动刷新进行中、成功和失败。
10.3 完成条件
- 页面信息完全来自查询和规则层。
- 不使用原型中的静态业务数字冒充真实数据。
- 点击刷新失败不会清空现有信号。
十一、工作包 F:Knowledge
对应步骤:7。
11.1 实数据模块
Content Flow 必须显示:
- 内容总数。
- Feedback 总数和覆盖率。
- 来源分布。
- 最近导入。
- X 分类分布。
11.2 占位模块
其他模块必须明确标记“尚未实现”或“待接入”,不能展示伪造指标。
11.3 完成条件
- 统计与数据库快照一致。
- 空数据时说明如何导入。
- 不将 placeholder 表述成已交付能力。
十二、工作包 G:Governance
对应步骤:8。
12.1 策略
首版策略可以是静态说明,但必须区分:
- 当前已执行约束。
- 仅有设计但尚未强制执行的约束。
- 本地运行前提。
不得把应用层 append-only 约束描述成数据库绝对不可变。
12.2 审计列表
- 显示 Import、Feedback 和 Signal Run。
- 显示 kind、title、body、时间和引用对象。
- 新 Feedback、导入和信号发布完成后可在刷新页面后看到。
- Audit Event 不提供 UI 更新或删除入口。
12.3 完成条件
- 审计列表来自真实表。
- 业务写入和对应审计数量可核对。
- 失败事务不产生孤立业务事件或孤立审计事件。
十三、工作包 H:加固与交付
13.1 自动化检查
- TypeScript 严格构建。
- 全部单元和集成测试。
- SQLite integrity 和 foreign key 检查。
- HTML/React 可访问性基础检查。
- 桌面和移动端响应式检查。
- 深色和浅色主题检查。
13.2 手工回归
- 全新空数据库启动。
- 旧数据库迁移启动。
- 重复启动。
- 重复导入。
- Feedback 提交。
- Today 自动失效。
- 强制刷新成功与失败。
- 四个路由导航。
- 备份恢复。
13.3 文档更新
- README 当前能力边界。
- 本地运行手册。
- schema 和架构图。
- 迁移与恢复步骤。
- 已知限制。
- 验收证据链接。
十四、风险登记
| 风险 | 影响 | 预防 | 触发后的处理 |
|---|---|---|---|
| 日期解析失败 | 迁移中断 | 全量样本预检 | 回滚并记录异常 ID |
| 源 ID 不稳定 | 重复内容 | 连接器契约和幂等测试 | 修正 source_id 生成后重导 |
| Feedback 与审计分裂 | Governance 不可信 | 单事务 | 回滚并阻止 API 成功响应 |
| 信号刷新先删旧数据 | Today 空白 | append-and-publish | 保留旧 active run |
| 规则修改未提升版本 | 缓存陈旧 | 集中版本常量和审查项 | 提升版本并重新发布 |
| 路由迁移顺序错误 | 构建失败或双重壳 | Step 5 + 9B 原子提交 | 回退整个提交 |
| SQLite 文件并发写 | busy 或锁竞争 | 同步事务、合理 busy timeout | 保留旧状态并重试 |
| 文档与实现偏移 | 错误验收 | 每个工作包同步文档 | 阻止最终验收 |
十五、提交与审查边界
推荐提交序列:
feat(moss): migrate content model and existing feedback loopfeat(moss): add v2 database queriesfeat(moss): add signal engine and refresh endpointfeat(moss): add workbench shell and move calibrationfeat(moss): add today viewfeat(moss): add knowledge viewfeat(moss): add governance viewtest(moss): add migration and failure-path coveragedocs(moss): update v2 runbook and acceptance evidence
每个提交必须:
- 能构建。
- 能运行对应测试。
- 不包含无关格式化。
- 描述迁移和回滚影响。
- 附带与本工作包匹配的证据。
十六、实施完成定义
只有同时满足以下条件,才能标记实施完成:
- 所有工作包完成。
09-v2-acceptance-standard.md中所有 Blocker 和 Major 验收项通过。- 没有未解释的数据数量差异。
- 没有孤儿外键。
- 没有业务事件与审计事件分裂。
- 旧数据库迁移和恢复演练均成功。
- 四个路由在桌面和移动端可用。
- 当前能力与未实现能力在 UI 和文档中准确区分。
- 最终工作区、commit 和验收证据可复现。