trellisx-workspace — .trellis/task.md 任务看板维护
trellis 原生有每任务 task.json, 但无跨任务总览。本 skill 维护 .trellis/task.md 作为人类可读的任务看板 —— 一个表格, 一行一个任务 (6 列: ID/名称/描述/状态/worktree/前置), 并保证它随 task 生命周期及时更新 (不是写一次就烂掉)。前置列承载 task 级 DAG —— 该 task 依赖哪些前置 task 先完成 (多个逗号分隔, 无依赖填 —), flow/go 据此排调度前后序。无活动详情块、无子任务树、无归档分区。
文件定位
- 路径:
.trellis/task.md(仓库内, 随 git 版本化) - 角色: 单表格任务看板, 每行一个 task (含已完成, 用状态列区分) + 两个脚本自动维护的 section:
## 依赖关系图 (DAG)(从前置列自动渲染的 mermaid 图, 无依赖边则不出段) +## Worktree ↔ Task 映射(一对多: 一行一 worktree, 同 task 可多行; 见references/dimensions.md) - 数据源:
task.py list/ 各 task 的task.json—— task.md 是其人类可读投影, 冲突时以 task.json 为准 - 维护者 (按列分工, 不冲突):
- ① trellis 生命周期 hook (
trellisx-taskmd.py, 由 trellisx-apply 注入 config.yaml): 自动维护确定性列 (ID/名称/描述/状态基础态) + 前置列 (从 task.jsondepends_on渲染) + create/start/archive 时 upsert + archive 时7 天清理。这是硬保障, 不靠 AI 记。 - ② AI (本 skill): 细化状态列 (阶段: 实施中→检查中→收尾) + worktree 路径, 在阶段推进时更新; 设/改 task 依赖时
update <tid> --deps "a,b"(写回 task.jsondepends_on真值源 + 前置列, 二者恒一致)。 - hook upsert 时保留 AI 列, AI 更新时保留 hook 列 —— 同行不同列, 互不覆盖。冲突规则: 若 AI 已写细分 (实施中/检查中/收尾) 且 task 仍 in_progress, hook sync 不覆 AI 细分。前置列: task.json
depends_on非空时 hook sync 优先渲染, 否则保留 AIupdate --deps写的值。 - 项目未跑 apply (无 hook) 时, AI 全列维护 (含清理)。
- ① trellis 生命周期 hook (
维护时机 (及时更新, 不可滞后)
一律经 .trellis/scripts/trellisx-taskmd.py 脚本操作, 禁直接 Edit/Write task.md 文件 (settings.json permissions.deny + guard-taskmd.sh PreToolUse hook 双保险硬阻 —— 直接编辑会被 deny 拦 + hook exit 2 block; 保证格式一致 + hook/AI 列分工不打架)。
检查点 (每个生命周期节点后): create / start / 阶段推进 / archive 任一发生 → 立即
update或sync对应行, 才算节点完成。task.md 落后于 task.json = 看板失效, 视为流程缺陷, 不准放任滞后到下一步。硬停 — 删行前 (AI 手动 cleanup / del / clean): 三者均永久删除看板行, 属破坏性操作。执行前 MUST 经 AskUserQuestion 工具确认删除范围 (
cleanup列天数阈值 + 将删 tid;del列目标 tid;clean列将删的孤儿 tid), 用户批准后才删。禁默认静默删除, 禁用"建议清理"软措辞替代确认。(hook 触发的 archive 内 7 天清理是确定性流程, 不走此门。)
| 触发 | 命令 (脚本) | 谁执行 |
|---|---|---|
task.py create |
taskmd.py sync create |
hook (after_create) 自动 |
task.py start |
taskmd.py sync start |
hook (after_start) 自动 |
| 阶段推进 (实施→检查→收尾) | taskmd.py update <tid> --status 检查中 |
AI |
| worktree 建好 (主表列) | taskmd.py update <tid> --worktree <路径> |
AI |
| 设/改 task 依赖 (前置列, task 级 DAG) | taskmd.py update <tid> --deps "<前置id>,..." (写回 task.json depends_on + 前置列; 无依赖不设, 留 —) |
AI (规划出依赖时) |
| worktree 创建 (subagent isolation / 手动 git worktree add) | taskmd.py map-add <worktree> <tid> [创建源] |
WorktreeCreate hook 自动按当前活动 task 登记 (无活动 task → ?, 由 UserPromptSubmit 提醒补登) |
| worktree 销毁 | taskmd.py map-remove <worktree> |
hook (WorktreeRemove / archive) 自动 |
| 查映射 / 查归属 | taskmd.py map-list / map-get <worktree> |
AI / 用户 |
task.py archive |
taskmd.py sync archive (含 7 天清理 + 清该 task 映射) |
hook (after_archive) 自动 |
| 查看看板 / 某任务 | taskmd.py show [tid] |
AI / 用户 |
| 格式校验 (结构自洽) | taskmd.py lint (主表 6 列 / 映射区 3 列 / 状态 / ID 不重复 / DAG 图 ↔ 前置列一致) |
AI (FileChanged hook 自动提醒) |
| 真值校验 (跨源一致) | taskmd.py check (每 task.json 有主表行 / 前置列 == task.json depends_on) |
AI / pre-commit |
| 手动清理 (超 N 天已完成行) | taskmd.py cleanup [--days N] |
AI (先 AskUserQuestion 确认) |
| 删单个 task 行 (误建/放弃) | taskmd.py del <tid> (删主表行 + 其映射, 不动 task.json) |
AI (先 AskUserQuestion 确认) |
| 对账删孤儿行 (task.json 已删的残留) | taskmd.py clean (删主表 + 映射孤儿, ? 保留) |
AI (先 AskUserQuestion 确认) |
原则: task.md 落后于 task.json = 看板失效。hook 自动管确定性列, AI 在阶段推进时
update状态细分 + worktree。 无 hook 的项目 (未跑 apply): AI 用sync create/start/archive手动触发同步 +cleanup清理。
用法
- 查看 —
python3 .trellis/scripts/trellisx-taskmd.py show [tid]。 - 细化状态 + worktree (阶段推进) —
python3 .trellis/scripts/trellisx-taskmd.py update <tid> --status <检查中|收尾|实施中> --worktree <W>。 - 确定性列 + 清理 — 由 hook 的
sync自动 (apply 已注册 config.yaml hooks); 无 hook 时 AI 显式调sync/cleanup。 - worktree↔task 映射 (一对多) —
map-add <worktree> <tid> [创建源]登记 (按规范化 abspath upsert, 同 task 可多 worktree 各占一行) /map-remove <worktree>移除 /map-get <worktree>查 (命中→打印 tid 退 0, 无→退 1) /map-list列全部。WorktreeCreatehook 创建时按当前活动 task 自动登记 (无活动 task →?),UserPromptSubmithook 对?/缺登记提醒补全,WorktreeRemove/archive 自动清。 - 规范校验 —
lint校验 task.md 结构自洽 (主表 6 列 / 映射区 3 列 / 状态值合法 / ID 不重复 / DAG 图 ↔ 前置列一致);check校验 task.md ↔ task.json 跨源真值 (前置列 == depends_on / 每 task.json 有主表行);FileChangedhook 在 task.md 变更时自动跑 lint, 不合规 → 提醒修 (可跑fix机械修复)。手动:python3 .trellis/scripts/trellisx-taskmd.py lint|check。
脚本是 task.md 唯一写入口。脚本不存在 (项目未跑 apply 复制脚本) → 提示用户先
/trellisx-apply, 或按references/模板临时手维护。
参考集
| 文件 | 用途 |
|---|---|
references/task-md-template.md |
task.md 单表格模板 (一行一任务) |
references/dimensions.md |
表格各列字段定义、取值、来源、更新时机 |
references/maintenance.md |
幂等更新算法 (按 id 定位表行, 从 task.json 同步, 不堆叠) |
失败模式 (触发 → 一线修复 → 仍失败兜底)
与下方「反例黑名单」区别: 黑名单是不要做什么, 本表是 skill 跑起来卡壳时怎么办。
| 触发 | 一线修复 | 仍失败兜底 |
|---|---|---|
| hook 与 AI 同行争列 (状态/前置被互覆) | 按列分工规则: AI 细分 (实施中/检查中/收尾) 不被 hook 覆, 前置列以 task.json depends_on 为准 |
仍打架 → check 对账后以 task.json 真值 sync 重建该行, 禁手改 |
check 报跨源不一致 (前置列 ≠ depends_on / task.json 无对应主表行) |
跑 taskmd.py fix 机械修复 + 缺行 sync 补 |
fix 修不动 (结构性冲突) → 以 task.json 为准手动 update --deps 校正, 禁反向回填 task.json |
map-add 无当前活动 task (登记为 ?) |
待 UserPromptSubmit 提醒时 map-add <worktree> <tid> 补登真实归属 |
归属仍不明 → 保留 ? 占位不臆测, 标「待确认」, 禁瞎绑 task |
lint 不合规 (列数/状态值/DAG↔前置漂移) |
跑 taskmd.py fix 机械修复 |
fix 后仍 fail → 报具体行给用户, 禁带病 commit 看板 |
| 脚本不存在 (项目未跑 apply) | 提示用户先 /trellisx-apply 复制脚本 |
用户暂不跑 → 按 references/ 模板临时手维护, 标「apply 后转脚本管」 |
反例黑名单 (禁做)
| # | 反模式 | 为什么禁 | 替代 |
|---|---|---|---|
| 1 | 手改 task.md 文件 (绕过脚本) | hook/AI 列分工被打乱 + 格式漂移; 且 settings.json deny + PreToolUse hook 双保险硬阻, 直接编辑必被拦 | 一律经 trellisx-taskmd.py (show/update/sync/cleanup/map-*) |
| 2 | 节点完成不同步看板 | task.md 落后 task.json = 看板失效 | 每个生命周期节点后立即 update/sync (见 检查点) |
| 3 | 拿 task.md 当真值源改它再回填 task.json | 投影反向污染真值 | task.json 是真值, 冲突时以它重建 task.md |
| 4 | AI 覆盖 hook 维护的确定性列 (ID/名称/描述/状态基础态) | 同行列分工冲突, 互相覆盖 | AI 只细化状态 (阶段: 检查中/收尾) + worktree, 保留 hook 列 (ID/名称/描述/状态基础态) |
| 5 | 加活动详情块 / 子任务树 / 归档分区 (DAG 图段 + 映射区除外) | 偏离"一表一行一任务"单表设计 | 单表格 + 两个脚本维护段: ## 依赖关系图 (DAG) (自动渲染) + ## Worktree ↔ Task 映射 (map-* 维护) |
| 6 | 脚本缺失时硬编看板格式 | 无脚本手维护易格式不一 | 提示用户先 /trellisx-apply 复制脚本, 或按 references/ 模板临时维护 |
边界
- 只维护
.trellis/task.md, 不改 task.json / 源码 - 与 trellis 原生不冲突: task.json 是真值, task.md 是投影; 二者不一致时以 task.json 重建 task.md
- 看板文案 + 状态枚举固定中文 (状态: 规划中/实施中/检查中/收尾/已完成/已归档)