对话笔记直发:8.12 任务分层v5端到端实施与Hermes对齐。分类:AI工程。


tags: [对话总结, Vikunja, Hermes, 任务分层, 领域树, 工作台, 权限, cron] date: 2026-08-12 project: 任务分层v5

8.12 任务分层v5端到端实施与Hermes对齐

一句话

将任务分层 v5(领域树 + 三类型 + P1/P2/P3)从方案落地为可运行系统:部署 push v3、对齐规则文件与 cron prompt、修复 writeback 中英文 bug、归档 8.8 旧指引、并排查解决 Hermes gateway 的 jobs.json / .apitoken 权限问题,完成端到端验证。

背景(会话起点)

延续 8.11「任务分层 v5 实施与 Hermes 对齐方案」笔记(FNS n_2721)。目标分四阶段:

  • Phase 0:部署 push v3 + crontab 加固
  • Phase A:重写规则文件为 v2 + cron prompt 引用
  • Phase B:验证 writeback 对 v2 结构回写
  • Phase C:归档 8.8 指引 + 清理 MEMORY.md

已确认的事实与修正

系统全貌

  • Hermes cron 存于 /opt/data/cron/jobs.json(HERMES_HOME=/opt/data,gateway 进程 hermes 用户)
  • push(03:40 root crontab)/ writeback(*/8 root crontab)/ Hermes 聚合(03:30 Hermes cron job 9eadb723492b)
  • FNS note 存储:/opt/fast-note-sync/storage/vault/u_1/note/n_XXXX/content.txt;note 元数据在 db_user_1.sqlite3 note 表
  • 修正:领域树.md(n_2718,200_Rules/工作流/)与工作台聚合规则.md(n_2719,000_Raw/200_Rules/工作流/)均已同步进 FNS(早前误判缺失,实为查错表)

Vikunja API

  • API 为 v2(v1 PATCH=405);writeback 用 /api/v2/tasks/{id} PATCH done=200
  • /api/v2/labels → 401(token 无 labels 权限,不能做「已回收」标签)
  • 项目树:Inbox=1(parent=0)、每日待办=2(parent=1,Inbox 子项目!)、生活=5(健康=6/作息=7)、工作=8(AI自媒体=9→文章10/视频11;折腾=12→Obsidian13/本地NAS+Hermes14/云服务器15)、项目库=16、习惯=17
  • 幽灵项目风险:find_or_create_leaf_domains 只认 parent_project_id in (0,None) 的「每日待办」,id=2(parent=1) 不匹配 → 会在旧脚本下创建顶层幽灵「每日待办」(M4)

领域树.json(/opt/vikunja/config/领域树.json)

  • top_level:临时→每日待办、项目→项目库、习惯→习惯
  • domains:生活(健康/作息)、工作(AI自媒体→文章/视频、折腾→Obsidian/本地NAS+Hermes/云服务器)
  • habits:锻炼/按时睡觉/写日记/健康饮食/保持精力

Phase 0:push v3 部署与验证(完成)

代码改动(push_tasks.py,本地副本 push_tasks_local.py)

  • 新增 _INBOX_RE = r"@inbox\s*[::=]\s*(\d+)"、_RECYCLE_RE = r"@recycle\s*[::=]\s*(.+)"
  • _SKIP_SECTIONS 改为 ("昨日结转", "灵感清单", "回写记录", "回收记录")
  • parse_task_line:先剥离 @inbox(任意位置、容忍全角/空格)→ 再时间 → 再标注,返回 dict 增加 "inbox_id" 键
  • find_or_create_leaf_domains(domains_cfg, token, project_id=None):project_id 短回路;标题匹配忽略 parent(复用 id=2)
  • upsert_task 增 inbox_id 参数 → description 追加 SRC_INBOX={id}
  • 新增 find_task_by_src_inbox(幂等防重:已有 SRC_INBOX 则跳过创建)
  • 新增 mark_inbox_task_done(GET→查 done→PATCH done=true;404 时 WARN 保留手动处理)
  • 新增 collect_recycle_ids(解析 ## 回收记录 段 @recycle 行)
  • main:find_or_create_leaf_domains(..., project_id=args.project_id);循环提取 inbox_id;dry-run 打印 inbox;创建/更新后标 done;循环后处理回收列表

部署

  • 生产备份:push_tasks_v1.bak.py / v2.bak.py,部署 push_tasks_v3
  • crontab:40 3 * * * ... push_tasks.py --project-id=2

修复的关键 bug(v2 遗留)

  • _TYPE_RE = r"【(项目|习惯)·([^】]+)】" 捕获中文,但 main 比较英文 "project"/"habit" → 项目/习惯类型分支从未命中,一直走标题兜底路由。改为 if typ == "项目": / elif typ == "习惯":。实测「配图方案选型落定」→ 新建项目库子项目 pid=18 ✓、「八段锦」→ 习惯 pid=17 ✓
  • HTTP 200(PATCH 更新成功)被误判「unexpected」→ 归入 updated 计数(v1 有 200,v2 改丢)

验证(e2e 测试日期 2099-01-01/2099-01-02,全部清理)

  • 路由:买牙膏→健康6、丢垃圾(带时段)→健康6、配图方案→项目库·公众号自动化、八段锦→习惯17 ✓
  • @inbox:任意位置剥离、Inbox 任务自动标 done ✓
  • @recycle:[105,106] 批量标 done ✓
  • 幂等:重跑 created=0、无重复 ✓
  • 测试产物(任务103-119、项目18/19、FNS 测试笔记)全部删除,生产任务92-102完好

Phase A:规则对齐(完成)

  • 重写 000_Raw/200_Rules/工作流/工作台聚合规则.md 为 v2(n_2719 Version: 2):触发/输入源/三类型判定/P1帽/短标题/v2输出模板(今日焦点+今日计划按领域+昨日结转+灵感清单+回写记录+回收记录)/回写昨日/习惯打卡/新增 @inbox 语法段(与 Inbox 联动闭环)/安全红线/缺料处理/执行提示词
  • cron prompt 加引用(jobs.json,已备份 jobs.json.bak-20260812):顶部加「规则权威:本 job 行为以 工作台聚合规则.md 为唯一权威源,分类体系以 领域树.md 为唯一事实源」
  • 确认 scheduler 每次 tick 调 load_jobs() 重读文件 → 无需重启 Hermes,热生效

Phase B:writeback 修复与验证(完成)

  • 同样中英文 bug:writeback 第144/150行 if typ == "habit": / if typ == "project": → 改为 "习惯"/"项目"。修复前项目任务永不翻转(uid 用错 daily key)
  • e2e 验证:焦点项A(daily)+项目任务C 均 [x] 翻转、未完成任务不翻、过期任务封存「(过期未完成)」✓
  • 注意:writeback 会按规则正确封存过期 daily 任务(#100 长期打卡被 seal 后已还原为 open)
  • 测试后清理,生产 8-11 工作台翻转 8 行属正常 cron 行为

Phase C:清理(完成)

  • 归档 8.8 指引:100_Wiki/工作流/8.8 Hermes对齐指引.md(n_2483)→ 归档到 000_Raw/90_历史归档/Hermes对齐指引.md,加 > [!WARNING] 已废弃 横幅 + status=archived,原文件删除。旧版 n_2482(Hermes对齐指引.md)API 层也已删
  • MEMORY.md 更新:备份 .bak-20260812;第6条周期笔记条目替换为 v5 现状(领域树唯一事实源、聚合规则唯一权威、cron 03:30聚合/03:40 push —project-id=2、*/8 writeback、@inbox 语法、8.8已归档),9 条目结构保持

端到端验证与权限问题排查(完成)

发现的重要架构事实

  • get_hermes_home() 读 HERMES_HOME env 或 Path.home()/.hermes;gateway 用 HERMES_HOME=/opt/data(systemd hermes-gateway.service),CLI 以 root 跑会读 /root/.hermes(空)导致「No scheduled jobs」
  • 正确手动操作:su - hermes 或 HERMES_HOME=/opt/data ... cron run 9eadb723492b

权限问题(重要)

  • 用 root 编辑 jobs.json 后 owner 变 root:root 600 → gateway(hermes) 每 tick Permission denied,cron 空转、手动触发被吞
  • 修复:chown hermes:hermes /opt/data/cron/jobs.json && chmod 644
  • 教训:Hermes CLI 操作必须用 hermes 用户 + HERMES_HOME,勿用 root(root 跑 CLI save_jobs 会把文件 owner 改回 root)
  • .apitoken(root:root 600)hermes 读不了 → Hermes agent 改走 chown hermes:hermes + 600(token 仍在本地文件,不违反红线);agent 实测还聪明地改用 Vikunja SQLite 直查

端到端结果(手动触发 cron run)

  • 8-12 工作台 v2 完整生成(output 2026-08-12_00-50-37.md):今日焦点 P1×3(Inbox回收+端到端验证 / 封面图方案 / 对话笔记首行摘要规则)、今日计划按领域 11 项(生活健康4/作息2/AI自媒体1/折腾4)、习惯【习惯·X】标注、昨日结转 1、灵感 5、缺料回退 8-11(8-12 日记/碎片缺失)、习惯打卡日志新建 00_项目库/习惯/2026-08.md
  • push 实战路由 14 项全对:Inbox回收→项目库·任务分层/Hermes(20)、封面图→项目库·公众号自动化(21)、摘要规则→每日待办(2)、5习惯→习惯(17)、杭州房→生活健康(6)、SyncClipboard→AI自媒体(9)、4折腾→折腾(12);focusP1=3
  • 幂等重跑 created=0 ✓

安全与红线(全部遵守)

  • token 未进聊天正文(仅本地文件/SQLite)
  • 200_Rules 只读、原文件不删(仅归档移动)、覆盖写先 .bak
  • MEMORY 删除/归档类操作均先备份

待办

  • 8-12 晨 03:30/03:40 cron 自然运行后复核结果(聚合 v2 + push 幂等)
  • 8-12 用户写日记后,次日聚合校正工作台(缺料回退自动解除)
  • (可选)Hermes agent 的 .apitoken 读取改走 push_tasks.load_token 统一入口,避免直读文件/直查 SQLite
  • 观察 @inbox 手机随手加任务 → 工作台 → 自动标 done 的全链路实际使用
  • 习惯打卡「未排」项后续是否要 Hermes 自动补排习惯任务实例
  • jobs.json 权限用 root 操作后需自查 owner(防回退 root)


相关: 00-索引-AI工程索引 8.12 任务分层v5.1扩展落地