Phase 1

MOSS v2 详细实施方案

MOSS v2 详细实施方案

状态:已实施并通过 v2 验收

范围:Today、Knowledge、Governance、Calibration,以及支撑它们的数据模型、规则引擎和审计能力 本文保留实施工作包、顺序和回滚基线;运行结果见 10-v2-acceptance-report.md

一、目标

本轮交付把当前本地 X Bookmarks 校准工具演进为可运行的 MOSS v2 子集:

  1. 使用通用 content_items 模型承载多来源内容。
  2. 保留已有 996 条内容、Feedback 和导入历史。
  3. 通过规则引擎生成可追溯的 Today 信号。
  4. 提供 Today、Knowledge、Governance 和 Calibration 四个路由。
  5. 让导入、Feedback、信号发布与 Audit Event 保持事务一致。
  6. 在任何迁移或信号发布失败时保留上一个稳定状态。

二、交付边界

2.1 本轮包含

  • bookmarkscontent_items 的一次性迁移。
  • 内部 ID 与 (source, source_id) 分离。
  • X 日期严格解析。
  • Feedback 外键迁移和现有 API 兼容更新。
  • signal_runssignalsaudit_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 testnpm run build 在现有实现上通过。
  • data/moss.sqlite 可以正常打开。
  • 当前 996 条 X Bookmarks 和现有 Feedback 数量已记录。
  • 当前页面、API 和导入脚本的行为已有基线截图或日志。

5.2 必须保存的基线证据

证据 内容
Git 基线 分支、commit SHA、Node 和 npm 版本
数据基线 bookmarks、feedback_events、import_runs 数量
数据完整性 PRAGMA integrity_checkPRAGMA foreign_key_check
功能基线 Calibration 打开、Feedback 提交、画像与历史页面
文件基线 SQLite 文件大小和校验值

5.3 备份要求

  1. 停止所有写入。
  2. 使用 SQLite 安全备份方式生成快照。
  3. 对备份执行完整性检查。
  4. 记录备份时间、大小、校验值和原数据库路径。
  5. 在数据库副本上完成第一次迁移演练。
  6. 未完成恢复演练前,不允许在唯一数据副本上执行迁移。

六、工作包 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 发布流程

  1. 读取当前 active run。
  2. 非强制请求且 base_key 一致时直接返回当前 signals。
  3. 强制刷新或 base_key 变化时,在事务外评估规则。
  4. 任一规则失败时保留旧 active run。
  5. 在事务内再次检查相同 generation key 是否已发布。
  6. 将旧 active run 标记为 superseded。
  7. 写入新 active run、signals 和 Audit Event。
  8. 任一步失败时整个事务回滚。
  9. 页面只读取 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 保留旧状态并重试
文档与实现偏移 错误验收 每个工作包同步文档 阻止最终验收

十五、提交与审查边界

推荐提交序列:

  1. feat(moss): migrate content model and existing feedback loop
  2. feat(moss): add v2 database queries
  3. feat(moss): add signal engine and refresh endpoint
  4. feat(moss): add workbench shell and move calibration
  5. feat(moss): add today view
  6. feat(moss): add knowledge view
  7. feat(moss): add governance view
  8. test(moss): add migration and failure-path coverage
  9. docs(moss): update v2 runbook and acceptance evidence

每个提交必须:

  • 能构建。
  • 能运行对应测试。
  • 不包含无关格式化。
  • 描述迁移和回滚影响。
  • 附带与本工作包匹配的证据。

十六、实施完成定义

只有同时满足以下条件,才能标记实施完成:

  • 所有工作包完成。
  • 09-v2-acceptance-standard.md 中所有 Blocker 和 Major 验收项通过。
  • 没有未解释的数据数量差异。
  • 没有孤儿外键。
  • 没有业务事件与审计事件分裂。
  • 旧数据库迁移和恢复演练均成功。
  • 四个路由在桌面和移动端可用。
  • 当前能力与未实现能力在 UI 和文档中准确区分。
  • 最终工作区、commit 和验收证据可复现。

十七、相关文档