WorkBuddy「空间」历史任务归档
> 由真实场景实证产出。本 skill 的每一步机制都有运行期证据链(见 references/机制证据.md),禁止凭猜测改库。
一、一句话定位
把「面板左侧『空间』下各工作空间里已运行的历史任务」批量归档,今日/运行中的不动。
| 维度 | 定论 |
|---|---|
| 任务实体 | ~/.workbuddy/workbuddy.db 的 sessions 表 |
| 归档动作 | status 置 'archived'(面板「归档」按钮的等价操作) |
| 取消归档 | status='active'(⚠️ 不保留原状态,故必须另存回滚清单) |
| 生效条件 | 需重启或刷新 WorkBuddy 面板,侧栏方可见 |
| 本 skill 脚本 | scripts/archive_space_tasks.py(归档)/ scripts/rollback_space_tasks.py(回滚) |
二、🔴 三条铁律(先读,再动手)
-
不要猜实体。 面板「空间」下的历史任务 =
sessions表,不是automation_runs。
-automation_runs(ACCEPTED / PENDING_REVIEW / ARCHIVED)是「任务待查看」流,其thread_id与sessions.id联结命中 0(实测数千条全不命中)。
- 判据法见references/机制证据.md§2「交叉校验」。 -
不要动错对象。 面板「空间」≠
资料库。
- 资料库是云端 node(走 library skill 的云端空间能力,move-node等),与本地 sessions 毫无关系。
- 历史上曾因二者混淆误移资料库节点(已回滚),勿再犯。 -
改活库前必先一致性备份。 单拷
.db会漏-wal(本库 WAL 常驻数 MB),必须用 SQLite Online Backup。
脚本已内置,勿绕过。
三、标准流程(四步)
步骤 0 · 预演(必做,只读)
python scripts/archive_space_tasks.py --dry-run
输出:候选总数、按工作空间分组、样本明细。先看清打谁,再动刀。
常用变体:
# 只归档某个工作空间
python scripts/archive_space_tasks.py --dry-run --workspace <工作空间名>
# 指定基准日(归档此日之前的;默认=今天)
python scripts/archive_space_tasks.py --dry-run --before 2026-09-20
# 仅体检(不改任何东西)
python scripts/archive_space_tasks.py --verify
# 显式指定库路径(默认自动探测 ~/.workbuddy/workbuddy.db)
python scripts/archive_space_tasks.py --dry-run --db /path/to/workbuddy.db
步骤 1 · 施加归档
python scripts/archive_space_tasks.py --apply
脚本自动完成:① Online Backup 快照 → ② 逐行写回滚清单 JSON → ③ 单事务 BEGIN IMMEDIATE UPDATE → ④ 复验并打印。
步骤 2 · 复验
python scripts/archive_space_tasks.py --verify
看 status 分布 + 各工作空间非归档计数 + 今日会话数(应保持不变)。
步骤 3 · 生效
重启或刷新 WorkBuddy 面板,侧栏方可见。
四、归档谓词(唯一口径,勿擅改)
created_at < <before> 00:00 (本地时间戳)
AND (updated_at IS NULL OR updated_at < <before> 00:00) -- 🔴 今日仍活跃者一律不动
AND status NOT IN ('archived','working','active') -- 已归档 / 运行中 一律不动
AND cwd IS NOT NULL AND cwd <> '' -- 仅「有工作空间归属」者
AND (<可选> cwd LIKE '%<workspace>%')
设计理由:
| 条件 | 为什么 |
|---|---|
status<>'archived' |
幂等,重跑无副作用 |
status<>'working'/'active' |
运行中会话归档会打断在役任务 |
updated_at < before(🔴 关键) |
防「昨日创建、今日仍活跃」误伤:后台自动化会话在轮次间隙 status 可能回落为 completed,working/active 闸拦不住。血案示例:某任务 created 昨日、今日仍在对话,status 在轮次间隙回落为 completed,被误归档致在役任务从侧栏消失(已依 manifest 还原,面板随后自动认回 working 状态)。「今日任务不归档」的口径 = created 与 updated 双闸 |
cwd <> '' |
cwd 为空的云端历史会话,归档走云端 HTTP 通道;本地单改 status 恐被云端同步回滚 ⇒ 如实排除 |
created_at < before |
「今日任务不归档」 |
五、安全物(每次 --apply 必产)
| 物 | 落点 | 用途 |
|---|---|---|
| 一致性备份 | ~/.workbuddy/backup/workbuddy.db.bak_arch_<ts> |
整库还原(Online Backup,含 WAL) |
| 回滚清单 | --manifest 指定,默认 <skill>/runs/rollback_manifest_arch_<ts>.json |
逐行还原 id / old_status / old_updated_at |
回滚:
python scripts/rollback_space_tasks.py \
--manifest <manifest.json> --apply
(不加 --apply 只预演。)
六、常见坑
- 「改完面板没变化」 → 正常。改的是磁盘库,运行中进程内存未刷新,须重启/刷新面板。
- 「侧栏计数对不上」 → 用交叉校验法复核(见
references/机制证据.md§2)。侧栏「查看更多(N)」= 屏显条数 + N = 该 workspace 的status<>'archived'计数。 - 「库写入被锁」 → 脚本已设
busy_timeout=30000;若仍失败,说明面板正持写锁,稍后重试即可,勿强杀进程。 - 「
--apply报 0 候选」 → 大概率已归档过(幂等)或before设得太早。先用--verify看实际状态。 - 本机 Python → 需 3.8+,纯标准库(
sqlite3/os/json/argparse/datetime/time/sys),零第三方依赖。
七、边界(本 skill 不做)
- ❌ 不删会话(只改状态,数据全留)
- ❌ 不碰
automations表(自动化定义本身) - ❌ 不碰资料库 / 云端 node
- ❌ 不归档今日任务与运行中任务
- ❌ 不处理
cwd为空的云端会话(如需,另行走云端通道)
八、资产清单
workbuddy-space-task-archive/
├── SKILL.md # 本文件
├── scripts/
│ ├── archive_space_tasks.py # 归档(dry-run / apply / verify)· 裁决真源
│ └── rollback_space_tasks.py # 按回滚清单还原
└── references/
└── 机制证据.md # 面板实体反查原文 + DB schema + 交叉校验法
九、审计与验收凭据
| 项 | 结果 |
|---|---|
| 安全审计 | ✅ P2 无投毒风险(0×P0 / 0×P1) |
| 零依赖 | 仅标准库(sqlite3/os/json/argparse/datetime/time/sys),零供应链暴露 |
| 语法校验 | py_compile rc=0 |
实测 · --verify |
✅ 正常(本谓词下 0 残留) |
实测 · --dry-run(before=今日) |
✅ 0 候选(幂等验证通过) |
实测 · --dry-run --before 次日 |
✅ 正确识别今日任务(排除 working/active) |
实测 · --workspace 过滤 |
✅ 命中正确 |
| 实测 · 回滚器预演 | ✅ 逐行全定位、0 缺失 |
| 首战记录 | 归档数千行,archived 计数翻倍,备份与原库等大 |
无破坏性操作:无 DELETE/DROP,无文件删除;唯一写操作 UPDATE sessions SET status 具备完整回滚链路。
十、快速分诊(先跑脚本再讲话)
本 skill 是确定性 DB 状态改写器,任何「归档 / 清理侧栏」诉求都必须先 --dry-run 看清候选,再 --apply。禁止跳过预演直接写库。
十一、输出契约
成功产物 = ① 备份文件(Online Backup 整库)② 回滚清单 JSON ③ 写入 rowcount 与复验报告。三者缺一不可,缺任意一项视为未达标。
十二、边界话术
- 用户要「删任务」→ 明确告知本 skill 只改状态不删数据,数据全留可回滚。
- 用户要「清资料库」→ 告知这是云端 node,走 library 技能,不在本 skill 范围。
- 用户要「归档今日/运行中任务」→ 明确拒绝,谓词天然排除,强改会打断在役任务。
十三、完整示例
# 1) 预演:看清今日之前有哪些候选
python scripts/archive_space_tasks.py --dry-run --before 2026-10-01
# 2) 施加:自动备份 + 写回滚清单 + 单事务写入
python scripts/archive_space_tasks.py --apply --before 2026-10-01
# 3) 复验:确认 status 分布与今日计数未变
python scripts/archive_space_tasks.py --verify
# 4) 若需撤销:用第 2 步产出的清单回滚
python scripts/rollback_space_tasks.py --manifest runs/rollback_manifest_arch_<ts>.json --apply