Phase 1
MOSS v2 本地工作台运行手册
MOSS v2 本地工作台运行手册
状态:当前可运行实现 更新:2026-07-24 适用范围:本地内容导入、旧库迁移、Calibration、Feedback、Today 信号、Knowledge、Governance、备份与恢复
本文描述仓库中已经交付的能力。长期规划不等于当前代码能力。
1. 运行链路与边界
data/phase-1a-input/*.md
→ npm run import:content
→ content_items + import_runs + audit_events
→ Calibration + Feedback
→ signal_runs + signals
→ Today / Knowledge / Governance当前应用不会读取浏览器登录态、请求 X、调用云端模型、创建定时任务或执行外部写操作。RSS、统一搜索、语义关系和其他业务域仍明确标记为待接入。
标准启动命令绑定 127.0.0.1。当前 API 没有认证、用户隔离或公网防护,不得改为 0.0.0.0,也不要通过反向代理或隧道公开。
2. 运行前提
- Node.js 20 LTS 或更高;本次验收使用 Node.js
v24.14.0。 - npm 与 Git。
- 可选 SQLite CLI,用于人工检查、备份和恢复。
- 原生依赖
better-sqlite3的 ABI 必须与当前 Node 版本一致;切换 Node 大版本后若出现NODE_MODULE_VERSION错误,应在该 Node 版本下重新安装或 rebuild 依赖。
所有命令从仓库根目录执行。默认路径:
data/phase-1a-input/ Markdown 输入
data/moss.sqlite SQLite 数据库测试副本可通过环境变量隔离:
MOSS_DATABASE_PATH=/absolute/path/to/moss-copy.sqlite npm run dev3. 从零启动
git clone <repository-url> moss
cd moss
npm ci
npm test
npm run import:content
npm run dev打开 http://127.0.0.1:3000。根路由会重定向到 /today。
若 3000 端口被占用:
npm run dev -- --port 3001生产验证:
npm run build
npm run start不要在开发服务器使用同一 .next/ 目录时并行执行生产构建。
4. 导入协议
通用入口:
npm run import:content兼容入口:
npm run import:bookmarks两者执行同一逻辑。解析器扫描 data/phase-1a-input/ 中匹配 NN-*.md 的文件,README.md 不导入。当前受控样本是 996 条内容;测试会验证样本总量和日期协议。
每条 X Bookmark 格式:
# 分类名称
## 1. 标题
- 作者:[显示名 (@handle)](https://x.com/handle)
- 时间:Wed Jul 22 12:57:33 +0000 2026
- 原帖:[在 X 上打开](https://x.com/handle/status/1234567890)
- ID:`1234567890`
正文。
---日期解析会验证格式、真实日历日期、时间、星期和时区偏移。非法值会报告内容 ID 与原始日期,并阻止整次导入或迁移;不会使用当前时间代替。
导入语义:
source = x_bookmark。- X ID 写入
source_id。 - 新内容
id使用 UUID。 (source, source_id)唯一;重复导入更新原对象但不改变内部 ID。- URL 缺失时写入 SQL
NULL。 - 内容 upsert、Import Run 和 Audit Event 在同一事务中提交。
- 导入不会删除数据库中已存在、但输入文件已移除的内容。
5. schema v2
PRAGMA user_version = 2。主要表:
| 表 | 作用 |
|---|---|
content_items |
通用内容;内部 ID 与来源身份分离,tags/metadata 为 JSON。 |
feedback_events |
追加式 Feedback 事件,外键指向 content_items.id。 |
import_runs |
每次导入批次。 |
signal_runs |
信号生成版本、输入版本与 active/superseded 状态。 |
signals |
某个 Signal Run 生成的可追溯信号。 |
audit_events |
Import、Feedback、Signal Run 的应用级审计事件。 |
SQLite 启用 WAL、foreign keys 和 5 秒 busy timeout。audit_events 没有 UI 更新或删除入口,但这只是应用约束,不是数据库层绝对不可变。
检查数据库
sqlite3 data/moss.sqlite "PRAGMA user_version;"
sqlite3 data/moss.sqlite "PRAGMA integrity_check;"
sqlite3 data/moss.sqlite "PRAGMA foreign_key_check;"
sqlite3 data/moss.sqlite "SELECT source, COUNT(*) FROM content_items GROUP BY source;"
sqlite3 data/moss.sqlite "SELECT status, COUNT(*) FROM signal_runs GROUP BY status;"预期 schema 版本为 2、完整性为 ok、外键检查无输出、active Signal Run 最多一条。
6. 旧数据库迁移
应用打开未标记版本且存在 bookmarks 表的旧库时,会自动执行一次事务化迁移:
- 创建 v2 目标表。
- 严格解析全部旧 X 日期。
- 保留旧内容内部 ID,并把旧 X ID 同时写入
source_id。 - 把作者、分类和 ordinal 写入 metadata。
- 重建 Feedback 外键,保留事件 ID、value 和时间。
- 校验内容数、Feedback 数和孤儿外键。
- 回填 Import 与 Feedback Audit Event。
- 校验成功后删除
bookmarks,最后写入 schema 版本 2。
任何一步失败都会回滚,旧表和版本保持不变。高于版本 2 的数据库会被拒绝打开,不做猜测式降级。
迁移必须先在副本上演练:
sqlite3 data/moss.sqlite ".backup 'backups/moss-before-v2.sqlite'"
sqlite3 backups/moss-before-v2.sqlite "PRAGMA integrity_check;"
cp backups/moss-before-v2.sqlite backups/moss-migration-drill.sqlite
MOSS_DATABASE_PATH="$PWD/backups/moss-migration-drill.sqlite" npm run dev如果备份本身是旧 schema,最后一条命令会在演练副本上触发迁移。不要在唯一数据副本上做故障注入。
7. 页面行为
| 路由 | 真实能力 |
|---|---|
/today |
读取或生成 active Signal Run;Focus 仅显示 warn/danger;显示全部信号与固定六域覆盖。 |
/knowledge |
显示内容总数、Feedback 覆盖率、来源、最近导入和 X 分类分布;未实现模块明确标注。 |
/governance |
展示本地策略与真实 Audit Event,不提供审计修改或删除。 |
/calibration |
浏览、筛选内容,提交 Feedback,查看画像和历史,并打开 X 原帖。 |
桌面使用 Sidebar、主内容、Inspector 三栏;中等宽度用 Sheet 打开 Inspector;移动端使用单列、可打开/关闭的主导航 Sheet 和上下文 Sheet。四个路由共享一套外壳。
主题选择保存在浏览器本地偏好中。浅色和深色都使用同一组设计 token。
8. Feedback API
POST /api/feedback
Content-Type: application/json
{
"contentId": "<MOSS internal id>",
"value": "worth_following"
}允许值:
worth_following | deep_dive | read_later | not_interested | duplicate_or_known- 合法请求返回
200和{ "event": ... }。 - 非法 JSON、字段或 value 返回
400。 - 内容不存在返回
404。 - Feedback 与 Audit Event 同事务写入;审计失败时两者都回滚。
- 对同一内容可连续反馈,历史全部保留,页面和画像使用最新事件作为当前值。
9. Today 规则与刷新
五条规则:
| Rule | 条件 |
|---|---|
uncalibrated-categories |
X 分类总数大于 20 且 Feedback 覆盖低于 10%。 |
stale-import |
最近导入超过 7 天为 warn,超过 30 天为 danger。 |
feedback-coverage |
全部内容的唯一 Feedback 覆盖低于 10%。 |
author-review |
X 作者至少 5 条内容且没有正向 Feedback。 |
category-skew |
单个 X 分类占 X 来源内容超过 30%。 |
普通访问按“本机日期 + 最新 Import Run ID + 最新 Feedback ID + 规则版本”命中缓存。Import、Feedback、日期或规则版本变化会自动失效。
强制刷新:
POST /api/signals/refresh成功返回 { "signalCount": number }。新候选在事务外计算,发布采用 append-and-publish;规则或发布失败时旧 active run 继续可读。规则逻辑修改时必须提升 signalRuleVersion。
10. 备份与恢复
数据库、Feedback、信号和审计都属于敏感个人数据。备份不进入 Git,不提供公网 URL,权限只授予本机用户。
运行中一致性备份
umask 077
mkdir -p backups
sqlite3 data/moss.sqlite ".backup 'backups/moss-backup.sqlite'"
sqlite3 backups/moss-backup.sqlite "PRAGMA integrity_check;"
sqlite3 backups/moss-backup.sqlite "PRAGMA foreign_key_check;"WAL 模式下不要只复制 moss.sqlite 主文件;可能遗漏 WAL 中已提交数据。应用停止后可复制主文件及同名 -wal、-shm,但 .backup 更适合可重复操作。
恢复演练
不要覆盖当前库。先把快照恢复到隔离路径:
cp backups/moss-backup.sqlite backups/moss-restore-drill.sqlite
sqlite3 backups/moss-restore-drill.sqlite "PRAGMA integrity_check;"
sqlite3 backups/moss-restore-drill.sqlite "PRAGMA foreign_key_check;"
MOSS_DATABASE_PATH="$PWD/backups/moss-restore-drill.sqlite" npm run dev -- --port 3001确认四个路由、Feedback、active Signal Run 和 Audit Event 可读后停止演练服务。
实际恢复时:
- 停止 MOSS,阻止所有写入。
- 保留故障数据库及 WAL/SHM 作为隔离副本。
- 将已验证快照放到新的目标路径。
- 运行 integrity 与 foreign key 检查。
- 原子切换数据库路径或文件。
- 启动后再次检查数量与四个路由。
恢复会回退到快照时间点;之后的 Feedback、Import Run、Signal Run 和 Audit Event 会丢失,因此必须先记录差异。
11. 验证与排障
自动化验证:
npm test
npm run verify:v2
npm run build
git diff --check测试覆盖解析、严格日期、来源身份、迁移与回滚、schema 版本、导入/Feedback/信号事务、API 契约、规则阈值、空库查询和在线备份。
最小手工回归:
- 打开
/,确认重定向/today。 - 导航四个路由,确认高亮正确且没有双重外壳。
- 在 Calibration 提交 Feedback,刷新后确认卡片与历史一致。
- 回到 Today,确认输入变化发布一个新 active run。
- 点击“刷新信号”,确认成功反馈且随后普通刷新不重复创建 run。
- 在 Governance 确认新 Feedback 与 Signal Run Audit Event。
- 在 1440、1024、768 和 390 宽度检查无页面级横向滚动,窄屏可通过 Sheet 打开 Inspector。
- 切换浅色/深色主题,确认可读且控制台无 error。
常见问题:
| 现象 | 处理 |
|---|---|
| 页面提示没有内容 | 在仓库根目录执行 npm run import:content。 |
NODE_MODULE_VERSION 不一致 |
使用当前 Node 版本重新安装或 rebuild better-sqlite3。 |
| 数据库版本高于 2 | 使用匹配该 schema 的新版应用;不要修改版本号伪装降级。 |
| 迁移报告日期错误 | 修正对应源 Markdown 或旧库副本后重新演练;不要写入伪造时间。 |
| 刷新信号失败 | 旧 active 信号应继续显示;查看服务日志并修复失败原因后重试。 |
SQLITE_BUSY |
确认没有多个写进程或人工长事务;不要删除 WAL 文件强制解锁。 |
12. 代码地图
| 位置 | 职责 |
|---|---|
scripts/import-content.ts |
通用导入 CLI。 |
scripts/import-bookmarks.ts |
兼容入口。 |
src/lib/parsers/x-bookmarks.ts |
X Markdown 解析。 |
src/lib/parsers/x-date.ts |
迁移与导入共用的严格日期解析。 |
src/lib/db.ts |
schema、迁移、事务、查询与审计。 |
src/lib/rules/ |
五条规则与信号发布引擎。 |
src/app/(workbench)/ |
四个共享外壳路由。 |
src/app/api/feedback/route.ts |
Feedback Route Handler。 |
src/app/api/signals/refresh/route.ts |
强制刷新 Route Handler。 |
tests/ |
解析、数据库、规则和 API 自动化验收。 |
正式退出标准与编号项见 MOSS v2 验收标准。