diff --git a/docs/tasks/T-005.md b/docs/tasks/T-005.md index d8a87c1..43299b4 100644 --- a/docs/tasks/T-005.md +++ b/docs/tasks/T-005.md @@ -3,8 +3,9 @@ id: T-005 title: 网页端 MVP 交互原型 phase: 0 deps: [] -status: DOING +status: DONE created: 2026-08-03 +vikunja_task_id: 12 context_ref: 79a2767 work_branch: task/t-005-web-brand-name needs_device: false @@ -268,3 +269,8 @@ web 端尚无生产代码。若直接实现 SSR 页面,登录、建单、三 - 复核时补上四页 `data:,` favicon,消除 HTTP 打开时浏览器自动请求 `/favicon.ico` 的 404; 同时把失败态的「新建重试任务」改为「由人工决定重新试选或结束任务」,避免发明 API。 - 自动验证已完成,仍未获得人工设计确认,任务继续保持 `DOING`。 +- 2026-08-03 人工确认:6 个原型(web 登录 / 建单 / 工作台 / 详情,desk 执行 / 设备参数) + 已由人浏览确认,布局、信息层级、主动作与安全文案通过。`needs_human_review` 满足, + 状态改为 `DONE`。Vikunja 对应任务 #12。 +- 本任务未迁入导出区块:内容已冻结,转换只增加往返风险而无收益;仅回填 `vikunja_task_id` + 作为连接键。门禁对无导出区块的文件豁免检查 4。 diff --git a/docs/tasks/T-006.md b/docs/tasks/T-006.md index 20035c3..d13e252 100644 --- a/docs/tasks/T-006.md +++ b/docs/tasks/T-006.md @@ -3,8 +3,9 @@ id: T-006 title: 桌面端 MVP 交互原型 phase: 0 deps: [] -status: DOING +status: DONE created: 2026-08-03 +vikunja_task_id: 13 context_ref: 235abb4 work_branch: task/t-006-desk-inline-detail-revision needs_device: false @@ -356,3 +357,8 @@ View 只渲染;I/O 离开 GUI 线程,通过 PySide6 `Signal` / `Slot` 回到 「订单可能已创建」和禁止再次点击的层级清楚。 - HTML → PySide6 映射覆盖壳、页签、状态、表单、日志、对话框、焦点与线程边界;未把 DOM / CSS 当成 Qt 实现。仍需人工设计确认及后续原生 Qt / Narrator / DPI / 真机验收,任务保持 `DOING`。 +- 2026-08-03 人工确认:6 个原型(web 登录 / 建单 / 工作台 / 详情,desk 执行 / 设备参数) + 已由人浏览确认,布局、信息层级、主动作与安全文案通过。`needs_human_review` 满足, + 状态改为 `DONE`。Vikunja 对应任务 #13。 +- 本任务未迁入导出区块:内容已冻结,转换只增加往返风险而无收益;仅回填 `vikunja_task_id` + 作为连接键。门禁对无导出区块的文件豁免检查 4。 diff --git a/docs/tasks/T-008.md b/docs/tasks/T-008.md index 9197471..5941fd1 100644 --- a/docs/tasks/T-008.md +++ b/docs/tasks/T-008.md @@ -25,7 +25,7 @@ write_paths: - docs/tasks/_template.md --- - + ## 问题 / 背景 多 agent 并行时任务文档会互相覆盖。已观测到的事实:T-005 与 T-006 同时为 `DOING`, @@ -146,7 +146,7 @@ Vikunja 网络,服务不可达时连校验都做不了: - 人工确认 6 个原型后将两任务改为 `DONE`(`DONE` 不参与相交判定);或 - 收窄两者的 `write_paths`,把共享文档移出,改为产出建议由任务所有者合入。 -在此之前 T-008 保持 `BLOCKED`,不得标 `DONE`。 +存量违规已于 2026-08-03 消解:T-005 与 T-006 经人工确认 6 个原型后转 `DONE`,不再参与相交判定,门禁转绿。T-008 自身因 `needs_human_review: true`,按 `docs/tasks/README.md` 硬规则保持 `DOING`(不是 `BLOCKED`):工作可继续推进,只是未获人工确认前不得标 `DONE`。 `docs/agent-context.json` 相应新增 `shared_documents` 与 `tracker` 两个顶层键。该 schema 的 `additionalProperties` 为 `false`,必须同步修改 `agent-context.schema.json` 并将 @@ -221,6 +221,26 @@ Vikunja 网络,服务不可达时连校验都做不了: **新发现的 API 陷阱**:Vikunja 的 `POST /tasks/{id}` 是**整体替换**,不是部分更新。只发 `{"id":15}` 会把 description 清空;只发 `{id, description}` 会把 `done` 重置。本轮因此误清过 #15 的 description(已用源文件恢复,本地投影未受损,sha256 校验反而验证了这一点),并把 #14 的 `done` 重置为 false(已修回 true)。今后任何字段更新必须携带完整对象。 **当前状态**:#12 / #13 / #15 done=false 带 needs_human_review 标签;#14 done=true。四个任务 description 完整。 + +### 2026-08-03T09:05:50Z · ila + +**2026-08-03 · 重启验证与存量违规消解** + +**已完成** + +- 重启后 `.mcp.json` 的相对路径 `./scripts/vikunja-mcp.sh` 生效,会话内 `ping` 正常。(`claude mcp list` 显示 Pending 是那条独立 CLI 进程不共享会话批准状态,非连接问题。) +- 人工确认 6 个原型通过,T-005 与 T-006 转 `DONE`,并回填 `vikunja_task_id` 12 / 13。两者内容已冻结,不迁入导出区块——转换只增加往返风险无收益,门禁对无区块文件豁免检查 4。 +- **门禁转绿**:`validate_agent_context.py` exit=0。检查 1 报出的存量违规按规定路径消解,未放宽任何检查。 +- T-008 状态口径统一为 `DOING`(`needs_human_review` 硬规则优先于草稿里的 `BLOCKED` 表述),description 已更新并重新导出。 + +**新发现:窄 token 无法移动 kanban bucket** + +`POST /projects/{p}/views/{v}/buckets/{b}/tasks` 返回 401——bucket 操作需要 project 级权限,而窄 token 只有 tasks / comments / labels。这与方案第 1 节「状态用 Kanban bucket 表达」冲突: + +- `DONE` 不受影响:置 `done=true` 后 Vikunja 自动归入 `done_bucket_id`。 +- `TODO` / `DOING` / `BLOCKED` 三者的区分,agent 目前**无法**驱动。首次播种时用的是旧全量 token,所以现有卡片位置正确,但后续状态流转会停滞。 + +三条出路待决策:用 label 表达 status(agent 可写 labels,最稳,但看板泳道失去意义);给 token 加开 project 读与 bucket 写(削弱收窄);或接受卡片位置由人维护、agent 只维护 `done`。**未决策前不修改方案第 1 节**,避免边写边改造成文档与实现不一致。 ## 边界 diff --git a/scripts/vikunja_export.py b/scripts/vikunja_export.py index d78acff..9913c8b 100644 --- a/scripts/vikunja_export.py +++ b/scripts/vikunja_export.py @@ -427,6 +427,13 @@ def export_file(path: Path, apiurl: str, apikey: str, check_only: bool) -> bool: if task_id is None: return False + # 有连接键但没有区块 = 刻意未迁移(例如内容已冻结的 DONE 任务)。 + # 与门禁的检查 4 保持一致:豁免而非报错。先判再联网,避免无谓请求。 + if not EXPORT_BEGIN_RE.search(text) and EXPORT_END not in text: + print(f"跳过 {path.resolve().relative_to(REPO_ROOT)}" + f"(vikunja#{task_id},无导出区块,未迁移)") + return False + task = http_get(apiurl, apikey, f"/tasks/{task_id}") comments = http_get(apiurl, apikey, f"/tasks/{task_id}/comments") or [] body = build_block_body(task, comments)