fix(tasks): make status git-authoritative, not Vikunja

修掉一处会让并行保护失效的设计缺口:AGENTS.md 声明「状态」权威在 Vikunja,
但离线门禁的检查 1 读的是 frontmatter 的 status,两者之间没有任何同步。
有人在看板上拖了卡片,frontmatter 不变,门禁就用过期数据放行了。

status 的权威定为 git frontmatter,理由与 write_paths 相同:它是判定
「两个活跃任务不得写同一路径」的输入,而门禁必须离线可跑;status 变更
决定谁能碰哪些文件,本来就该产生 commit。

- AGENTS.md:把 status 从 Vikunja 权威列表移入 git 原生表,并说明 bucket
  与 done 仅为人类视图,不一致时以 git 为准
- agent-context.json:tracker.git_native_fields 增加 status
- validate_agent_context.py:强制 git_native_fields 必须含 status,
  已用反例验证缺失时报错
- vikunja_export.py:新增只读漂移检测,导出时比对 frontmatter status 与
  Vikunja done,不一致则提示;只提示不修正,不反向写回
- docs/tasks/README.md、T-008 方案第 1/2 节:同步口径

顺带解决了窄 token 时期的 bucket 401 遗留问题——status 权威在 git,
agent 不再依赖 bucket 移动来表达状态。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
QiuSW
2026-08-03 17:17:35 +08:00
co-authored by Claude Opus 5
parent ed489bd13e
commit 3c458bcf5b
6 changed files with 78 additions and 12 deletions
+7 -5
View File
@@ -25,7 +25,7 @@ write_paths:
- docs/tasks/_template.md
---
<!-- BEGIN VIKUNJA EXPORT id=15 synced=2026-08-03T09:13:45Z sha256=12b35fc74d559e5b15884fd223785c35ef08fa1750042d442dbb888e9ceb059b -->
<!-- BEGIN VIKUNJA EXPORT id=15 synced=2026-08-03T09:16:43Z sha256=5caf1f2f9a0bf1d5dc78c3fe5f3cbd83789585c8fa2af7d03828140d00fc663e -->
## 问题 / 背景
多 agent 并行时任务文档会互相覆盖。已观测到的事实:T-005 与 T-006 同时为 `DOING`,
@@ -64,8 +64,9 @@ frontmatter 拼凑。
`/projects/{id}/views/{view_id}/tasks` 正常。任务一旦分散到多个项目,agent 就无法一次
取全。
状态用 Kanban bucket 表达,不另造字段。实测该 MCP 没有 bucket 改名工具,因此沿用
Vikunja 自动创建的英文名,不为了对齐中文表述去动 API:
`status` 的权威在 git 的 frontmatter,**不在 Vikunja**。离线门禁 `validate_agent_context.py` 靠它判定「两个活跃任务不得写同一路径」,权威放到远端就等于让唯一能跑的校验命令依赖网络;status 变更本身也决定谁能碰哪些文件,本来就该产生 commit。
Kanban bucket 与 `done` 标志是**人类视图**,不是判定依据,两者不一致时以 git 为准。导出脚本只读比对并提示漂移,不反向写回。实测该 MCP 没有 bucket 改名工具,因此沿用 Vikunja 自动创建的英文名:
| frontmatter `status` | bucket |
| --- | --- |
@@ -81,14 +82,15 @@ Vikunja 自动创建的英文名,不为了对齐中文表述去动 API:
| 内容 | 权威 | 载体 |
| --- | --- | --- |
| 标题、状态、标签、依赖关系 | Vikunja | task 字段 / bucket / label / relation |
| 标题、标签、依赖关系 | Vikunja | task 字段 / label / relation |
| **`status`** | **git** | frontmatter(bucket / `done` 仅为人类视图) |
| 问题 / 背景、方案、验收要点 | Vikunja | task `description` |
| 执行记录 | Vikunja | task comments |
| **`write_paths`** | **git** | frontmatter |
| **边界与安全边界条目** | **git** | 正文 `## 边界` |
| `context_ref`、`work_branch` | git | frontmatter |
`write_paths` 与安全边界留在 git 是本任务的核心约束。理由:`AGENTS.md` 第 2 条规定安全
`status`、`write_paths` 与安全边界留在 git 是本任务的核心约束。理由:`AGENTS.md` 第 2 条规定安全
边界只能收紧,而收紧与否靠 `git diff` 逐条复核。若这两项的权威在 Vikunja,agent 放宽一条
闸门时改的是远端字段,本地文件下次同步才变,diff 里只呈现为「导出内容更新」,看不出是谁
在什么理由下放宽了边界——**审计链在此断裂**。任何后续任务不得把这两项迁往 Vikunja。