对话笔记直发:8.12 任务分层v5.1扩展落地。分类:AI工程。


date: 2026-08-12 tags: [任务分层, vikunja, 规则, 工作台, Hermes, 截止日期, SavedFilter]

8.12 任务分层 v5.1 扩展落地(P0+P1+P2 + 时序竞态修复)

本会话在 v5 任务分层(8-12 已端到端验收跑通)基础上,按子代理评审通过的 v5.1 扩展方案完成 P0/P1/P2 及 push 时序竞态修复。全程走「评审→修正→复审PASS→实施→代码复核→测试验收」流程。

一、背景与前置

  • 用户偏好:说大白话、少术语;删除/归档类先问;单选默认推荐。
  • 前置验证:用 Vikunja token 写任务 due_date/start_date 持久化成功(受控任务 id=134 PATCH→回读一致后删除,并清理,无残留)。
  • 关键确认:.apitoken(tk_ 前缀)对 labels/filters/user 端点全 401,作用域受限;/api/v2/filters 仅支持 POST;分页响应是 {items:[...]} 结构。
  • 竞态实锤:8-12 凌晨 push.log 末行 [push] note not found: 000_Raw/00_plan/01_工作台/2026-08-12.md (True) —— 03:40 push 先跑,聚合 03:49 才写完工作台,导致当天任务一个都没推 (=空推)。

二、评审结论(子代理 PASS,采纳 5 条注意项)

  1. P0 走 Web UI 手建 4 个 Saved Filter(token 对 filters 401,改 Web UI 避开 token 权限)。
  2. P1 @due 解析顺序:inbox → due → 时间块 → 标注;daily @due<today 丢弃并告警;rng 时间块优先于 @due;默认 due=today 23:59 仅限 typ!=项目(项目绝不套默认,防覆盖用户/@due 的远期 due)。
  3. P2:新段「值得关注/项目状态」进 _SKIP_SECTIONS(防被误推成任务);习惯只补排近 5 天打卡的。
  4. push 时序:crontab 03:40→04:05;并给 note_get 加存在性重试护栏。
  5. 规则唯一权威 = FNS,本地为可读镜像;规则经 Hermes/FNS 单写者改。

三、实施明细

规则文件对齐(v2.1)

  • 本地 D:\Program\feng\000_Raw\200_Rules\工作流\工作台聚合规则.md 重写为 v2.1(旧 v1 备份为 .v1.bak),融合:@due 语法 §六、输出模板 §七(含「项目状态/值得关注」段,声明用 - 观察:/- 下一步: 不带 - [ ])、习惯补排 §十、@inbox §十一、push 时间 04:05。
  • 关键:Obsidian 插件未自动把本地改动推上服务器(等了很久 n_2719 仍是旧 v2)。改走 FNS MCP note_create_or_update(用 Hermes token,与 Hermes 同通道)确定性写入,返回 Version 3、contentHash=771094187(与本地 fileHashMap 完全一致),Hermes 现在可读 v2.1。

P0:Saved Filter(4 个,Web UI/登录 JWT 建)

  • 用.userpass 用户密码登录 /api/v2/login 拿完整 JWT(用后即弃不存),POST /api/v2/filters 建 4 个,测试 filter(id=1) 已删:
    • id=2 ⭐ 今日 = done = false && due_date >= now/d && due_date < now+1d/d
    • id=3 🔥 重要 = done = false && priority >= 3
    • id=4 📅 本周 = done = false && due_date < now+7d
    • id=5 ⏳ 待办中 = done = false
  • 语法验证:🔥重要→3 条 P1(正确)、⏳待办→3 条;⭐今日/📅本周暂 0 条(任务尚无 due,等 P1 默认 due 填充,正是 P0↔P1 耦合点)。

P1:push_tasks.py(备份为 push_tasks_v3.bak.py)

  • 加 _DUE_RE = r"@due\s*[::=]\s*([^\s))]+)"(宽匹配,日期单独校验)。
  • parse_task_line 顺序:@inbox → @due → 时间块 → 标注;@due 剥离后不进标题/UID。
  • 修过一个命名 bug:脚本用的是 import datetime as dt,我初版补丁误用 _dt/_time 别名,已改 dt./time. 并补 import time。
  • upsert_task 新增 due_str=None, default_due=False:
    • rng 有→ 时间块末日作 due(优先)
    • elif due_str → 该日 23:59
    • elif default_due(typ!=项目)→ today 23:59
    • 项目不套默认。
  • main 循环:due_str = parsed.get("due_str");default_due = typ != "项目";past@due(daily) 丢弃告警(防止被 writeback 立即封存);invalid@due 丢弃告警。
  • note_get 重试护栏:最多 11 轮×90s≈15min,覆盖聚合未完成时段。
  • 受控 e2e(用到 2099-08-13 假工作台,验证后已全删):
    • 无@due daily → due=today ✓
    • @due=未来 → 按日期 ✓
    • @due=过去(daily) → WARN+丢弃+默认 today ✓
    • @due 非法 → WARN+剥离标题 ✓
    • due_date 落库验证:测试任务A/B/E/F 均正确(id 135-139 已删)。

P2:_SKIP_SECTIONS

  • 由 ("昨日结转","灵感清单","回写记录","回收记录") 增补 "值得关注","项目状态"。

时序修复

  • crontab push 由 40 3 * * *(03:40)→ 5 4 * * *(04:05);writeback */8 不变;改前已备份。

最终验收

  • 真实 8-12 工作台推:首跑 created=5 updated=7(那 5 条正是今早竞态空推漏掉补建的,非重复);再跑 created=0 updated=11 skipped=2(幂等,无重复)。
  • SyncClipboard(daily) → due=2026-08-12T23:59:00+08:00 正确。

四、待办

  • 观察 8-13 / 8-14 两天凌晨自然 cron:确认 push 04:05 准时、不再空推(看 /opt/vikunja/logs/push.log)。
  • 用户在 Vikunja Web UI 确认 4 个 Filter 视角符合预期(⭐今日/📅本周 有 due 后数据是否正常填充)。
  • (可由用户选)如不希望 Push 真推产生首日 backfill,可复盘 8-13 上午任务完整度。

五、关键路径/文件

  • 规则:本地 000_Raw/200_Rules/工作流/工作台聚合规则.md(v2.1,已同步 FNS n_2719/Version 3);备份 .v1.bak。
  • 脚本:/opt/vikunja/scripts/push_tasks.py(含 @due/默认 due/重试护栏);备份 push_tasks_v3.bak.py。
  • 配置:/opt/vikunja/config/.apitoken(tk_,受限)、.userpass(用户密码,勿外泄)。
  • Vikunja:https://vikunja.unixcs.eu.org/(登录 JWT 建 Filter 通道)。
  • 日志:/opt/vikunja/logs/push.log(竞态空推证据)、writeback.log;crontab(push 04:05 + writeback */8)。


相关: 00-索引-AI工程索引 8.12 任务分层v5端到端实施与Hermes对齐