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
+4 -3
View File
@@ -337,12 +337,13 @@ def validate_manifest(root: Path) -> list[str]:
git_native = require_string_list(
tracker.get("git_native_fields"), "tracker.git_native_fields", errors
)
# write_paths 与边界章节的权威必须留在 git,否则安全边界被放宽时 git diff 看不出来。
for required in ("write_paths", "boundaries_section"):
# 这三项的权威必须留在 git:status 与 write_paths 是本脚本判定并行安全的输入,
# 权威搬到远端就等于让离线门禁依赖网络;边界章节搬走则切断安全边界的审计链。
for required in ("status", "write_paths", "boundaries_section"):
if required not in git_native:
errors.append(
f"tracker.git_native_fields 必须包含 {required}:"
"该项迁往 Vikunja 会切断安全边界的审计链。"
"该项迁往 Vikunja 会让离线门禁失去判定依据或切断审计链。"
)
refresh = require_mapping(root_object.get("refresh"), "refresh", errors)