task-framework
Skill2 starsChanged 45 days agoMITView on GitHub
Three-layer task system: (1) methodology — decompose complex work into
- Deletes or force-pushes
- Installs packages
- Commits and pushes
In this repository15 other files it gives its agents.
- compact-directory-memorySkill
- task-archaeologySkill
- task-artifact-integritySkill
- task-aware-project-workSkill
- task-context-storageSkill
- task-cross-machine-syncSkill
- task-external-repos-patternSkill
- task-lifecycle-disciplineSkill
- task-lifecycle-edge-casesSkill
- task-lifecycle-portabilitySkill
- task-nested-subtask-lifecycleSkill
- task-requirement-intakeSkill
- task-root-git-operationsSkill
- task-timestamp-conventionSkill
- task-trackerSkill
The file
We split this skill into the rules it gives an agent
3 rules. About 0 are common, 1 is distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 129
When you receive a task request:
- Very specific: line 151
Usage rule: All inline shell examples in this SKILL.md use $HERMES_TASKS_ROOT instead of bare tasks/ paths.
- Very specific: line 171
Delete-and-recreate is forbidden for this case: it mints a NEW hash, and any reference already emitted against the old hash (issue …
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Task Framework
A three-layer system covering the full task lifecycle:
| Layer | What | Examples |
| Methodology | 如何拆解复杂工作为可组合的操作 | operation catalog (info-search, code-write…), composite patterns (software-dev), decomposition guide |
| Container | 如何组织任务的物理文件 | tasks/<ts>.<name>-<hash6>/ with TASK.md, README.md, logs/, docs/, scripts/ |
| Tooling | 执行任务的复用工具 | scripts/task-runner.sh (日志封装), md→pdf 转换(优先复用 convert-markdown-to-pdf skill,见下), templates/TASK.md |
The Model
A task is a goal with structured tracking (directory, checklist, logs). An operation is a unit of work with a defined input, process, and output. Complex tasks decompose into multiple operations; simple tasks may be a single operation.
Task: "复现这篇论文的实验结果"
└── Operation: paper-reproduce (environment → run → compare)
Task: "开发用户登录功能"
├── Operation: info-search (调研认证方案)
├── Operation: code-write (写后端+前端)
└── Operation: code-review (审查)Task Types
每个任务都有类型,类型决定了生命周期(创建、执行、清理)和目录结构。类型定义在 references/task-types/ 下。
类型注册表
| 类型 | 说明 | 目录结构 | 生命周期参考 |
analysis | 文档分析/调研:从源文件提取信息,产出分析文档 | input/(源文件) + output/docs/(产出) | references/task-types/analysis.md |
external-audit | 外部项目审计:读取外部路径下的文件,产出分析报告,不复制源文件、不修改外部路径 | output/docs/(无 input/) | references/task-types/external-audit.md |
video-production-pipeline | 视频生产流水线:根据 REQUIREMENTS.md 自动化录屏配音,由 video-production-pipeline skill 驱动 | input/ (REQUIREMENTS.md + images/) + output/ (各 phase 目录) | references/task-types/video-production-pipeline.md |
添加新类型
当发现一种新的任务模式(比如代码开发、数据库迁移等),需要:
- 在
references/task-types/下创建<新类型>.md - 在类型参考中写明完整生命周期:创建 → 执行 → 修改 → 清理 → 完成
- 更新本注册表,加入新类型
- 如果新类型需要特殊的
create行为,创建scripts/create_task.py(参考manage_task.py create接口)
生命周期文档模板:
# <类型名> 任务生命周期
## 创建
创建时生成哪些目录和文件?
## 执行
执行时有哪些步骤?产物放在哪?
## 修改
如何安全地修改已有任务?
## 清理
如何清理产物?`task_reset --hard` 做了什么?
## 完成
完成时有什么收尾工作?When you receive a task request:
0. Determine task type — lookup in the task types registry, load references/task-types/<type>.md for lifecycle guidance
- Identify the operation pattern — single-operation or composite? Check the task type's lifecycle doc for the standard workflow
- If composite — break into operations, sequence in TASK.md
- For each operation — follow the standard workflow in its reference
- Choose execution strategy — by complexity
Environment Variables
This skill uses environment variables for portability across machines. Set
HERMES_TASKS_ROOT in the process environment or profile configuration. On
POSIX shells, an optional ~/.hermes/env.sh may be sourced; Windows users
should set the variable in PowerShell or the environment and invoke the Python
entrypoints directly.
| Variable | Default | Purpose |
HERMES_TASKS_ROOT | $HERMES_TASKS_ROOT | Task container root (recognised task directories, inbox/, declined/, and optional archive/) |
HERMES_PROJECTS_ROOT | $HERMES_PROJECTS_ROOT | Project repos root |
Usage rule: All inline shell examples in this SKILL.md use
$HERMES_TASKS_ROOT instead of bare tasks/ paths. Sourcing an env file is
optional and POSIX-only; the Python entrypoints work directly on Windows.
source ~/.hermes/env.shRoot resolution order is HERMES_TASKS_ROOT, HERMES_TASKS_DIR compatibility alias, active-profile tasks.data_dir, global tasks.data_dir, then ~/studio/hermes/tasks. The historical ~/.hermes/tasks directory is compatibility-only: never create, mirror, populate, or symlink task directories there. When a custom tasks.data_dir is configured, it is the only task root used.
🔴 Wrong-root creation: recover by move, never delete-and-recreate. When
manage_task.py create lands a task in the wrong root (e.g. a project's work
task created under ~/studio/hermes/tasks/ because the shell did not export
HERMES_TASKS_ROOT), the directory is self-contained (.hermes-task.json
stores no absolute paths), so recovery is:
mv <wrong-root>/<ts>.<name>-<hash6>/ <correct-root>/- Re-run
update-index.py --tasks-diron BOTH roots (old root drops the stale index entry, new root gains it).
Delete-and-recreate is forbidden for this case: it mints a NEW hash, and any
reference already emitted against the old hash (issue comments, parent
manifests, ref:<hash6>/... links, delegation briefs) silently breaks. The
"never raw mv on task dirs" rule targets lifecycle semantics (renaming,
deleting, restructuring); relocating an intact directory between roots
preserves identity and is the correct fix. Prevention: verify the target root
(echo $HERMES_TASKS_ROOT, or pass it explicitly) before create.
Task Directory Structure
The canonical tasks root is defined by $HERMES_TASKS_ROOT or configuration (default: ~/studio/hermes/tasks/). All relative paths (e.g. tasks/YYYYMMDD-*) in documentation are relative to this root. When the user says "tasks" without qualification, this directory is the default reference — not the abstract concept of "任务". "创建一个任务" means creating a YYYYMMDD-HHMMSS.<name>-<hash6>/ structure here using this skill. Task directories must be real directories; do not create task-root or task-directory symlinks.
🔴 Semantic disambiguation (important): When the user says "任务" or "task", first determine whether they mean (a) a task-framework managed task (in tasks/YY.../ directories) or (b) a generic concept. Clues: specific name/timestamp, operating on a task directory → (a); abstract discussion → (b). For (a), always use task-framework tools (task_create, task_set_status, etc.) — never raw mv/cp/rm on task directories. For (b), handle as normal conversation.
│ ├── tmp/ ← **task-local scratch** — the ONLY sanctioned place for temporary files created while working this task
│ ├── input/ ← **source files** — NEVER deleted by cleanup operations\n│ │ (PDF, DOCX, images, REQUIREMENTS.md declared by the task)\n│ ├── output/ ← **generated files** — CAN be safely deleted entirely\n│ │ ├── docs/ ← analysis documents, reports (for analysis tasks)\n│ │ ├── logs/ ← execution logs\n│ │ ├── tts-<hash6>/ ← pipeline phase dirs (for pipeline tasks)\n│ │ ├── RECORDING.md ← pipeline generated specs\n│ │ ├── COMPOSITING.md\n│ │ └── ...\n├── archive/ ← optional completed task directories\n```
**`input/` 目录** — 存放任务声明的源文件(可由 `tasks/inbox/` 中的文件或目录复制而来),包括 PDF、DOCX、图片、REQUIREMENTS.md 等。**核心规则:所有删除操作不得触及 `input/`。**
**`output/` 目录** — 存放所有生成文件(分析文档、执行日志、pipeline 产物如 tts-*/RECORDING.md/COMPOSITING.md 等)。**核心规则:所有删除操作只针对 `output/`。**
**`cache/` 目录** — 存放需在任务内保留、可再生成但必须可追溯的工作状态(例如构建缓存、烧录页、Flash read-back、收据)。`cache/` 不是交付目录,正式交付物仅能放在任务明确的 `deliveries/`。
**`runtime/` 目录** — 可恢复执行状态。每个新需求、bug 修复等小任务(粒度=phase/步骤,不构成 subtask)在 `runtime/` 下建自己的子目录,内含 `TODO.md`(要完成的事项)、`LOG.md`(执行日志)、`MEMORY.md`(执行时的发现);subtask 同样可以有自身的 `runtime/` 子目录。`runtime/INDEX.md` 是总索引:逐项标记 完成 / 未完成 / blocked(含 blocked 原因)。目的:机器重启或上下文压缩后,按索引即可恢复到最接近最后状态的完整任务快照——不依赖聊天记录和对话内"记忆"。执行新工作前先读 `runtime/INDEX.md` 定位未完成项;状态变化(完成/阻塞)须同步回写索引。
`task_reset --hard` 默认清空 `output/`,不动 `input/` 或 `cache/`。
### Default filesystem boundary
The task directory is the default filesystem boundary for every operation:
reading, writing, building, caching, creating a worktree, logging, packaging,
Git operations, cleanup, and temporary artifacts. Do not use an external path
unless the current user instruction explicitly names the target or `TASK.md`
lists it under `## Authorized External Targets` with the exact absolute path or
concrete external object, allowed operations, and authorization source.
Related project names, sibling directories, previous task context, environment
variables, and convenient home-cache or `/tmp` paths never grant external
scope. When no target is explicitly listed, all work remains in the task
directory.
🔴 **临时文件边界(task tmp/ rule)** — 任务执行期间产生的所有临时文件(中间产物、pytest/构建缓存、探测脚本输出、下载的临时件、任何非交付物)必须创建在该任务自己的 `tmp/` 目录下(`<task>/tmp/`;子代理在该任务内工作同样受此约束)。禁止写到任务目录之外的任何位置——包括 `$HOME` 顶层、`/tmp`、系统 temp、repo 根或其他任务目录。工具自带路径参数的优先重定向到 `<task>/tmp/`(例:pytest `--basetemp=<task>/tmp/pytest`);无法重定向的工具产物在运行后立即清理。`tmp/` 不进 git(tasks repo `.gitignore` 已忽略),`task_reset --hard` 与自定义 `scripts/clean.sh` 一并清空它——需要留档的内容放 `output/`,不要放 `tmp/`。
### 自定义清理脚本
部分 task 有需要特殊保护的目录(如 clone 的仓库、大文件等),可以在 `scripts/clean.sh` 中定义自定义清理行为:
**查找顺序:**
1. 检查 `tasks/<ts>.<name>-<hash6>/scripts/clean.sh` — 存在则执行它(替代默认行为)
2. 不存在 → 回退到默认 `rm -rf output/`
**clean.sh 模板:**
```bash
#!/usr/bin/env bash
set -euo pipefail
TASK_DIR="$(cd "$(dirname "$0")/.." && pwd)"
# 明确声明要保留的路径
echo "[clean] repos/ — PRESERVED (cloned repos)"
echo "[clean] input/ — PRESERVED (source materials)"
# 只清理 output/
rm -rf "$TASK_DIR/output"
mkdir -p "$TASK_DIR/output"/{docs,logs}
echo "[clean] output/ cleaned"设计原则:
- clean.sh 只控制"删什么不删什么",不修改 TASK.md 或状态
- 输出中列出保留路径方便审计
- 没有 clean.sh 时回退到默认行为,不破坏现有任务
scripts/task-runner.sh 是一个可复用的执行日志封装脚本,使用方式:
bash scripts/task-runner.sh <task-dir> <command...>
# 自动创建 logs/output.<ts>.log + logs/error.<ts>.logOperation Catalog
Each operation has a reference under references/operations/<name>.md.
Current Operations
| Operation | When to Use | Ref |
file-concat | 拼接多个源文件为一个 | references/operations/file-concat.md |
file-convert | 文件格式转换(docx→md, xlsx→csv, pdf→md) | references/operations/file-convert.md |
info-search | 多源信息搜索和抓取(竞品分析、政策调研) | references/operations/info-search.md |
code-write | 写代码:单一功能实现,含测试 | references/operations/code-write.md |
paper-reproduce | 论文代码复现:环境搭建、跑 pipeline、对比 | references/operations/paper-reproduce.md |
document-write | 编写结构化文档(产品需求、产品设计、技术需求、技术设计) | references/operations/document-write.md ✅ |
code-review | 代码审查:diff 分析、安全扫描 | references/operations/code-review.md |
data-analysis | 数据分析:探索、统计、可视化 | references/operations/data-analysis.md |
task-overview-discovery | 扫描 tasks/ 目录、读取 README.md 生成概览表 | references/task-overview-discovery.md |
web-research | 网页调研:读取 URL、OCR 截图、生成 summary + discuss | references/operations/web-research.md |
New operation types discovered during real tasks should be added here.
Composite Task Patterns
Recurring multi-operation patterns. Each has a reference under references/composites/<name>.md.
Software Development
0. [git] Pre-Change Sync → fetch + cherry + ff-only / rebase
1. info-search → 调研现有方案/技术选型
2. document-write → 写产品需求/产品设计/技术需求/技术设计四份文档
3. code-write → 实现(TDD)
4. code-review → 审查
5. [git] Post-Change Workflow → commit → quality-gate → re-sweepStep 0 loads GIT.md's Pre-Change Sync (fetch → cherry → ff-only → rebase → verify). Step 5 runs GIT.md's Post-Change Workflow (sweep → commit → quality-gate → fix → re-sweep).
Common loops: 需求讨论 (2↔用户), review→fix (3↔4).
Research Task
For open-ended investigation (competitor analysis, policy study, tech feasibility):
1. info-search → 多源搜索
2. data-analysis → 整理发现
3. document-write → 写出调研报告Code Review Session
For a batch review of changes:
1. 加载 TASK.md,确认审查范围
2. code-review → 逐个文件审查
3. document-write → 写 review/SUMMARY.md
4. 更新 TASK.md 状态Cross-Skill Composite Tasks
Some tasks span multiple tools/skills. For example: generate TTS audio → record browser video → composite audio onto video.
How composite tasks work:
- TASK.md includes a
## Skillssection listing all required skills - Each phase in the checklist is prefixed with the skill that handles it
- Each phase can declare execution mode: default (sequential),
和 Phase X 同步进行(parallel), or等待 Phase X 完成(dependency) - When executing, phases run according to their dependency graph
- Pass outputs between phases (file paths, durations, timestamps)
Phase isolation directories
每个 phase 使用独立的子目录,防止文件互相覆盖:
tasks/<ts>.<name>-<hash6>/
├── TASK.md
├── RECORDING.md
├── COMPOSITING.md
├── README.md
├── tts-a3f8c2/ ← text-to-speech 的工作目录
│ ├── audio_000001.mp3
│ ├── audio_000002.mp3
│ └── audio_manifest.json
├── recording-bd71ef/ ← browser-video-recording 的工作目录
│ ├── video.mp4
│ └── timeline.txt
├── compositing-c9f3a2/ ← <domain-skill> 的工作目录
│ └── output.mp4
├── docs/ ← 共享文档(timestamps.json、多 phase 共用文件等)
└── logs/规则:
- 目录命名:
<short-name>-<hash6>/,短名用-连接,尾部加 6 位 hash。不用phase_NN_前缀,避免步骤顺序变化时目录名需要改动。 - hash 用随机字符串(如
a3f8c2),不是顺序编号,避免对顺序的隐含依赖 - 每个 phase 执行时,CWD 切换到自己的子目录
- phase 间的文件传递通过
docs/或通过## Data Flow表中明确定义的路径进行 - 跨 phase 引用的文件使用相对路径(从任务根目录出发)或绝对路径
- 合成类 phase(如 compositing)需要读取其他 phase 的输出时,通过 Data Flow 表的路径定位文件
命名示例:
- [ ] Phase 2 (browser-video-recording) — 录制视频
→ 目录 browser-video-recording-a3f8c2/两条命名线: Checklist 的 () 与目录名是不同的东西,不要混淆:
| 位置 | 内容 | 规则 |
Checklist (Phase 名) | 描述性 phase 名称 | 完整词、无 hash、无缩写,如 (text-to-speech) |
| 实际目录 | <short-name>-<hash6>/ | 短名 + hash,如 tts-a3f8c2/ |
| Data Flow 表 | 实际路径 | 目录名 + 文件名,如 tts-a3f8c2/audio_000001.mp3 |
() 里的内容是给人读的 phase 标识,目录名是给机器用的存储位置。两者可以不同——(text-to-speech) 表示"这是 TTS 阶段",但目录可以是 tts-a3f8c2/。不要照搬目录名到 () 中,也不要照搬 () 中的名称到目录名中。
好处:增删、重排步骤时,hash 不变,目录名不变,不会导致步骤对应的目录错乱。
Execution Model:
Execution Model (unified runner)
When a task has a run.py at its root, use it as the single entry point. The
auto-runner reads TASK.md, ignores the literal optional template BREAK, and
executes dependency-ready phases until a concrete BREAK or the end of the
list. It never completes a concrete BREAK automatically. See auto-runner
pattern.
| 标注 | 行为 | 示例 |
| (无标注) | 按顺序串行,在前一阶段之后执行 | Phase 2 — 录制视频 |
和 Phase X 同步进行 | 和 Phase X 并行执行 | Phase 2 (browser-video-recording) — 和 Phase 1 同步进行, 录制视频 |
等待 Phase X 完成 | Phase X 完成后才执行,不关心其他阶段 | Phase 3 (<domain-skill>) — 等待 Phase 1 完成, 等待 Phase 2 完成, 合成 |
Implementation: 并行阶段通过 delegate_task() 启动子代理执行。等待阶段通过 process(action='wait') 或检查输出产物来判断完成。
Format:
# Task: <Name>
## Goal
## Skills
- `text-to-speech` — 生成语音音频
- `browser-video-recording` — 录制浏览器操作视频
- `<domain-skill>` — 合成音视频
## 环境要求
## Data Flow
| 文件 | 来源 Phase | 被消费 Phase | 格式说明 |
|------|-----------|-------------|---------|
| `{file_path}` | {phase} | {phase} | {格式文档路径} |
## Checklist
- [ ] Phase 1 (text-to-speech) — 根据解说脚本生成 N 段音频
- [ ] Phase 2 (browser-video-recording) — 和 Phase 1 同步进行, 录制浏览器操作视频
- [ ] Phase 3 (<domain-skill>) — 等待 Phase 1 完成, 等待 Phase 2 完成, 将音频合成到视频的正确时间点
- [ ] BREAK: 检查最终视频效果Execution rule for cross-skill tasks:
- Read
## Skillsto know which skills to load - For each checklist item, identify the skill from the parenthesized prefix
- Load that skill and follow its workflow for the phase
- Consult
## Data Flow— before writing or reading a file listed in the Data Flow table, find its格式说明column. That column tells you which skill's reference contains the file's schema. Load that skill and read its reference to understand the format before producing or consuming the file. - Pass file paths, durations, and metadata between phases via the task's
docs/directory - On
task_reset, re-run all phases in order
执行方式(uv run): 如果 task 目录下有 .venv/(即创建了 ## Venv),所有脚本必须通过 uv run 执行:
cd "$HERMES_TASKS_ROOT"/<ts>.<name>-<hash6>/
uv run python scripts/do_something.py脚本内引用 skill 通用代码(scripts/utils/)的方式:
#!/usr/bin/env python3
import sys, os
# 按需添加 skill utils 路径
sys.path.insert(0, os.path.expanduser(
"~/.hermes/skills/<category>/<skill>/scripts"))
from utils.xxx import ...选择依据: 有外部依赖的 skill → uv pip install -r requirements.txt(装进 task .venv)
纯 stdlib 的 utils/ → sys.path 引用,无需 pip install。
Unified Runner (run.py)
When a task has multiple phases, add a run.py at the task root. Copy from templates/run.py.
./run.py — auto: find first unchecked item & execute until next BREAK
./run.py phase<N> — run specific phase
./run.py list — show checklist statusThe auto mode:
- Reads TASK.md checklist, finds first
[ ]item - Ignores the literal optional template BREAK; stops at any concrete BREAK
- Executes phases until the next concrete BREAK or end of list
- Marks each completed phase as
[x]
Unimplemented phases (5-7 in the template) return True (skip, don't fail).
Current Composite Pattern: Video Recording with Audio
支持两种初始化方式:
方式 A:从 VIDEO_PRODUCTION.md 统一规格生成(推荐)
用一个文件描述完整流水线,generate_all() 自动拆解生成各子 spec。
参考 standards/video-production-spec.md,工具入口 <domain-skill>/scripts/utils/production_spec.py:
from utils.production_spec import generate_all
results = generate_all("VIDEO_PRODUCTION.md", task_dir, video_path, tts_dir)
# → RECORDING.md, SCRIPT.txt, COMPOSITING.md, SUBTITLE_SPEC.md, IMAGE_SLIDESHOW.md方式 B:手工编写各子 spec 文件
分别编写 RECORDING.md + SCRIPT.txt + COMPOSITING.md。
通用执行流程(Phase 1~7):
Phase 1 (text-to-speech):
├── 工作目录: tts/
├── 根据 SCRIPT.txt 逐行生成 audio_NNNNNN.mp3
└── 输出 audio_manifest.json(增量模式:已有 manifest 时只更新改动的行)
Phase 2 (browser-video-recording):
├── 工作目录: recording/
├── 读取 RECORDING.md(用户编写的操作指令,timeline-spec 格式)
├── 时间驱动:在 [HH:MM:SS.mmm] 指定的时间点执行操作
├── 输出 video.mp4 + timestamps.json
└── 写入 timeline.txt(含事件点和空白行)
Phase 3 (timeline-chart-preview):
├── 工作目录: timeline-chart-<hash6>/
├── 读取 COMPOSITING.md
├── 运行 generate_timeline_chart(format='both') — 默认生成 .txt + .png
├── 输出 timeline_chart.txt(文本条形图)
└── 输出 timeline_chart.png(图片版,暗色主题)Data Flow: 每个 phase 在自己的子目录中独立工作。跨 phase 引用使用相对路径(从 task 根目录出发)或 COMPOSITING.md 定义的路径。
Every file cross between phases must be documented in the task's ## Data Flow table with a 格式说明 column pointing to the standard or skill reference that defines its schema. The executing agent reads this table to know which skill's reference to load before producing or consuming each file.
TASK.md Template
Always read the actual template at templates/TASK.md when creating a task.
Every TASK.md uses:
TODO intake and scope routing
The primary owner is the suite skill task-requirement-intake; load it for
intake and classification. For a nested decision, load the optional
task-nested-subtask-lifecycle skill. This core skill keeps only the
container/index hooks and invariants below.
## TODO records undecomposed requirements discovered during execution. Each row must include an ID, requirement, source, timestamp, status, scope decision, and outcome/reference. At intake, post-flight, and phase transitions classify each TODO:
continuous: strongly overlaps existing work; append/refine one or more Checklist phases and markdecomposed.nested: related but independently deliverable; create a first-class child withmanage_task.py create <name> --parent <parent>and markrouted.top-level: unrelated to the parent; create an independent task and markrouted.
A TODO may instead be cancelled or blocked only with an explicit outcome. An open TODO is not complete and must not be silently ignored.
Use scripts/todo_lifecycle.py <task-dir> add|route|terminal for deterministic table updates. For orchestrated L1 work, reconcile exactly once per returned result with task_api.py reconcile <task> '<json payload>'; stable result_id makes retries idempotent and outcomes are CONTINUE, CONTINUE_WAITING, COMPLETE, or HARD_BLOCK. Validate with validate_todos() before completion.
# Task: <Name>
## Status
active — <brief description>
## Goal
<one-liner>
## Affinity (cluster task)
`local` | `any` | `<hash6>` | `<tag>,<tag>`
## Skills (用于跨 skill 组合任务)
- `<skill-name>` — <该 skill 在本任务中的用途>
## 环境要求
| 项目 | 最低要求 | 说明 |
|------|---------|------|
## Pre-checks (optional)
*Resolve before main checklist.*
- [ ] Investigate X
## Checklist
- [ ] Phase 1 — <understanding / research>
- [ ] Phase 2 — <execution / writing / coding>
- [ ] BREAK: <optional — delete if no pause needed here>
- [ ] Phase 3 — <verification / review / cleanup>
<!-- The optional BREAK above is a template placeholder, not a planned
breakpoint. During concrete planning, delete it or replace it with a
specific pause request; it must not stop the first concrete,
dependency-ready checklist item. -->
## Tracking
<!-- 可选。每个 phase 完成后加载 `task-tracker` skill 回写状态。
编排者读到此段后自动注入到各 phase 的 card/worker brief 中。 -->
| 参数 | 说明 |
|------|------|
| `task_dir` | 本 TASK.md 所在目录的绝对路径 |
| `phase` | 当前 phase 标识,如 `Phase 0: scrutiny-pipeline` |
| `executor` | 执行者名称 |
| `findings` | 关键发现(每行一条)|
| `outputs` | 产出文件路径(相对 task_dir)|
| `next` | 下一个 phase |
## NotesExecution Logic
第 0 步:验证 TASK.md 格式
TASK.md 关键字段规范(新 task 必须遵守):
| 字段 | 格式 | 用途 | 解析 fallback |
# Task: <Name> | 英文标题 | 任务标题(索引展示) | 任意 # 中文标题 |
## Status | 英文 | 任务状态(active/completed/—) | ## 状态 |
## Goal | 英文 | 一行描述任务目标 | ## 目标 / ## 概述 |
## Checklist | 英文 | - [ ] 步骤清单 | ## 步骤 |
## Notes | 英文 | 备注信息 | ## 备注 |
## Related Tasks | 英文 | 关联任务关系表(可选) | — |
update-index.py 优先解析英文关键字段,中文字段为向下兼容而支持。
新 task 一律用英文关键字段。
每次执行的第一步,检查 TASK.md 的结构:
## Status是否存在,值是否合法(active / completed / paused / cancelled / failed)## Checklist是否存在- 每个 checklist 项是否为
[ ]或[x]开头 - BREAK 行是否放在正确的上下文位置
发现问题时不自动修正,先问你"TASK.md 第 X 行有问题,建议改为 YYY,可以吗?",得到确认后再改。
硬性规则:没有 BREAK 就不停
两个 checklist 项之间如果没有 [ ] BREAK: 行,执行完前一项后直接执行下一项,不问"要不要继续"。[ ] BREAK: 是唯一合法的暂停信号。以下情况都不需要停下来问:
- Phase X 完成之后
和 Phase X 同步进行标注的依赖满足后- 看到 "等待 Phase X 完成" 但产物已存在时
执行逻辑:
The agent reads TASK.md from top to bottom:
逐行读取:
[x] DONE* → 跳过(用户已确认的断点)
[x] → 跳过(已完成)
[ ] BREAK:* → 输出已完成摘要,退出等待
[ ] → 执行此项Pre-checks section (如果存在) → execute only its dependency-ready [ ]
items. Continue into the Checklist without routine confirmation unless a
concrete BREAK follows, an action is destructive or irreversible, a material
decision lacks a safe default, or execution has genuinely failed or blocked.
BREAK 行 → 执行到此时暂停,输出内容给用户。用户确认后将 [ ] BREAK: 改成 [x] DONE:,下次自动跳过。
🔴 执行纪律:非 BREAK 不停 — 完成一个 [ ] 项后,立即找到下一个未完成的 [ ] 项。如果中间没有 [ ] BREAK:,直接执行,绝不询问"要不要继续"。Frequent confirmation prompts disrupt workflow.
Approved execution continuity
After the user approves an active task or says “continue”, “继续”, or “不要停”,
that authorization covers ordinary dependency-ready work: inspection,
reversible edits, tests, task logging, and scoped commits (never push). Do not
ask again between normal layers or after a background worker returns. Continue
until an explicit BREAK, a hard tool/environment block, a destructive action,
or a material decision with no safe default.
Operations Reference
task_list
List all recognised tasks and task-framework input items:
python3 scripts/manage_task.py listtasks/inbox/ is the task-framework input staging area for source files,
directories, and complete task briefs. tasks/declined/ retains rejected
input with evidence. These are not task directories and are not expanded into
TASKS.md.
For the full generated index (README.md + TASKS.md), see Root Index Files.
task_create <name> [description] [--skill <skill-name>] [--ticket <ticket-id>]
Create a new task with timestamped directory. After creation, report a concise created-task summary (directory/name, status, and next checklist item). Do NOT fill in placeholder content based on prior conversation.
Before creation, load task-lifecycle-discipline and use task_api.py search to confirm an equivalent task does not already exist. Do not hand-generate directories, hashes, or metadata. The former task-initialization-sequence and task-create-first rules are absorbed here and are no longer standalone workflows.
Base flow (scripted):
# Create task with directory + hash + meta + templates + auto index update
python3 scripts/manage_task.py create <name> [--desc "<goal text>"]
# Create task and copy one task-framework inbox file or directory into input/
python3 scripts/manage_task.py create <name> --from-inbox <inbox-file-or-dir>The script handles directory creation, task metadata, templates, optional
consumption of one item from tasks/inbox/, and index regeneration. An inbox
item may be a file or directory, including a complete task brief. The item is
copied and verified into the new task's input/ before the source is removed;
REQUIREMENTS.md remains user-owned and is never rewritten.
Creation-to-execution continuity
Task creation is not a routine approval boundary. After the concise
created-task summary, locate and execute the first dependency-ready,
non-BREAK checklist item when the task has a concrete, actionable execution
point. Continue through later dependency-ready non-BREAK items under the
normal execution rules.
Stop and wait only when the same creation request explicitly says not to execute
after creation, or when no concrete dependency-ready item exists. In the latter
case, ask for the missing execution point. Do not invent a concrete plan from
earlier conversation merely because a task was created: creation-only requests
without a user-provided plan or actionable scope retain template placeholders.
A default template literal such as BREAK: <optional — delete if no pause needed
here> is not a concrete BREAK and must be ignored for pause purposes.
During normal execution, pause only for a concrete TASK.md BREAK, a
destructive or irreversible action, a material decision without a safe default,
or a genuine blocking failure. Neither Git/push, deployment, nor clone
authorization changes under this rule.
Post-create steps (agent-driven, not scripted):
- 确定任务类型 — 根据任务目标判断属于哪种类型(
analysis、video-pipeline等),加载references/task-types/<类型>.md - 如果传了
--ticket <id>— 将 ticket 信息写入 TASK.md 的## Related Tickets节,并将 task hash 写回 ticket 的task_id字段(实现双向关联) 检查
--skill指向的 skill 是否有scripts/create_task.py:~/.hermes/skills/<category>/<skill-name>/scripts/create_task.py有则委托其覆写 TASK.md 和其他模板文件(skill 自己决定要生成什么)。 没有则使用 task-framework 的默认 TASK.md 模板(已被脚本写入)。
extra_references_dir合并: 如果--skill的 SKILL.md frontmatter 中声明了extra_references_dir,将目录下所有文件复制到新任务目录:# SKILL.md frontmatter extra_references_dir: "references/task-template/"复制规则:不覆盖已存在的同名文件(TASK.md 等由 create_task.py 先写)。
Venv 管理(按需创建): 遍历
--skill涉及的 skills(或 TASK.md## Skills中列出的),如果任意 skill 有scripts/目录(含代码),执行:cd "$HERMES_TASKS_ROOT"/<ts>.<name>-<hash6>/ uv venv然后对每个有代码的 skill:
# 如果 skill 有外部依赖 [ -f ~/.hermes/skills/<category>/<skill>/scripts/requirements.txt ] && \ uv pip install -r ~/.hermes/skills/<category>/<skill>/scripts/requirements.txt # 如果 skill 有 scripts/utils/(通用代码),在 task 执行脚本中通过 sys.path 引用 # 不需要 pip install,详见执行模型章节如果没有任何 skill 有代码 → 跳过 venv 创建,TASK.md 中不写
## Venv。按需追加
## Venv节到 TASK.md: 如果创建了 venv,在 TASK.md 末尾(Checklist 之前)追加:## Venv 路径: `.venv/` 创建: `uv venv` 依赖: - <skill> (<外部包>) 执行: `uv run python <script>`- (Optional) External task manager card — if using an external task manager (kanban board, issue tracker, etc.), create a card/issue with title
<task-name> [task:<目录名>]and store its ID in.hermes-task.json.
Skill 的 scripts/create_task.py 接口约定:
#!/usr/bin/env python3
"""create_task.py — 由 task-framework 调用。
参数: <task_dir> <task_name> <task_hash>
返回: 0 (成功) 或非0 (失败)
职责: 覆写 TASK.md、写 REQUIREMENTS.md、或其他模版文件、创建所需目录。
"""
import sys, os
task_dir = sys.argv[1]
task_name = sys.argv[2]
task_hash = sys.argv[3]
# ... skill 自己的逻辑示例: 创建带 <custom-skill> 模板的任务:
# Step 1: script creates base structure
python3 scripts/manage_task.py create demo-video
# Step 2: agent handles --skill (load skill, run create_task.py, venv, kanban)Skill-specific templates: If this task belongs to a specific skill (e.g., browser-video-recording), load that skill to get its template. Use manage_task.py create for the directory structure, then apply the skill's templates on top.
RECORDING.md dual-file pattern: Some skills (e.g., browser-video-recording) use two files: a standard TASK.md plus a skill-specific spec file (e.g., RECORDING.md). When creating a task for such skills, generate BOTH files from the skill's templates directory.
task_view <name-or-hash>
python3 scripts/manage_task.py view <hash6-or-dir-or-name>Resolves hash6 → directory path → prints README.md + TASK.md.
task_set_status <name> <status> [reason]
python3 scripts/manage_task.py status <hash_or_dir> <status> [--reason "<text>"]
# Auto-updates index files after status change.Valid statuses:
| Status | Context | Description |
active | Solo | Task is actively being worked on (non-cluster) |
paused | Solo | Temporarily paused |
completed | Solo | Finished (legacy, prefer done) |
cancelled | Solo | Abandoned |
failed | Solo/Cluster | Unrecoverable error; reset to active or pending to retry |
pending | Cluster | Waiting to be claimed by a node |
claimed:<node_id> | Cluster | Claimed by a node, not yet started |
in_progress | Cluster | Being executed by the claiming node |
pending_review | Cluster | Execution complete, awaiting creator confirmation |
done | Cluster | Confirmed complete |
failed用于执行过程中遇到不可恢复的错误(如未找到特殊操作条目),中止执行等待修复。Cluster 中可重置为pending重新分发。
task_inbox
tasks/inbox/ is task-framework input staging. It accepts either a single
source file or a directory. A directory may contain REQUIREMENTS.md, a
complete task brief, and supporting files. The contents remain outside the
active task set until explicitly accepted.
tasks/inbox/
├── source.pdf
├── task-brief/
│ ├── REQUIREMENTS.md
│ └── supporting-file.md
└── complete-task-brief.mdTask-framework does not rewrite REQUIREMENTS.md or any other user-owned
source file.
task_inbox_accept <inbox_item> [--name <task-name>]
Accept one task-framework input item into a new task:
python3 scripts/manage_task.py accept <inbox_item> [--name <task-name>]For a file, the script creates the task and copies the file into input/.
For a directory, it copies the directory into input/. Each copy is verified
before the original inbox item is removed. The generated task receives its
own TASK.md, CHANGELOG.md, README.md, MEMORY.md, metadata, and indexes.
If --name is omitted, the task name is derived from the input item name.
task_inbox_decline <inbox_item> [reason]
Reject one task-framework input item while retaining evidence:
python3 scripts/manage_task.py decline <inbox_item> [--reason "<text>"]The item is moved to tasks/declined/ with a DECLINED.md record. This is
an input decision, not a task status and not an active task directory.
task_run <name> <command...>
Execute a command within the task context with logging.
task_submit <name>
Delegate to subagent via delegate_task() — reads TASK.md, works through checklist.
task_reset <name> [--hard]
将任务重置到初始状态,支持从头重新执行。
# Reset (default --hard): clear output/, reset checkboxes, set status active
python3 scripts/manage_task.py reset <hash_or_dir>
# Soft reset: only reset checkboxes + status, keep output/
python3 scripts/manage_task.py reset <hash_or_dir> --no-hardThe script handles:
- 清空 output/ —
rm -rf output/+ recreate empty subdirs(仅 --hard 模式;input/ 不动) - 重置 TASK.md — 将所有手写的
[x]改为[ ](保留[x] DONE:断点) - 重置状态 —
status <dir> active - 更新索引 — 自动调用 update-index.py
注意:
rm -rf output/是最安全的通用清理方式。input/中的源文件(PDF、REQUIREMENTS.md、images/ 等)不受影响。不需要按任务类型区分清理策略。
使用场景: 任务执行后需要修改操作步骤并重新从头开始执行。
Root Index Files
For the complete nested-subtask contract and compatibility behavior, see
docs/SUBTASKS.md.
Two auto-generated root index files live in tasks/:
| File | Purpose | Content |
tasks/README.md | Directory contract | Task-framework-owned tree and file responsibilities |
tasks/TASKS.md | Generated summary | Per-task status, goal, and checklist counts only; details remain in TASK.md |
Both become stale when tasks are created, updated, or change status — always regenerate after any task operation.
Regeneration
Use the unified script to rebuild both files:
python3 scripts/update-index.py # from the skill directoryOutput:
Updated:
$HERMES_TASKS_ROOT/README.md (1464B)
$HERMES_TASKS_ROOT/TASKS.md (6912B)
Found 9 active tasksThe script recognises only valid timestamp/name/hash task directories directly under the configured root (and direct children of an existing archive/). It reads each task's TASK.md for status, goal, and checklist count, then atomically writes only the task-framework-owned README.md and TASKS.md; inbox/ and declined/ are task-framework input areas and are not expanded into the summary.
🔴 Pitfall: forgot to update indexes
A recurring issue — after creating, modifying, renaming, or deleting any task, always run the script above. This is now a mandatory post-operation step (see post-flight skill).
Execution Strategies
| Strategy | When | How |
| A — Inline | Simple, <5 tool calls | Execute directly in conversation |
| B — Script | Well-defined steps, repeatable | Write run.sh, execute with task_run |
| C — Subagent | Needs reasoning, composite | delegate_task() with TASK.md as context |
| D — Cron job | Independent, outlive session | cronjob(action='create', schedule='now') |
Choose the lightest strategy that fits. Prefer A→B→C→D in that order.
Script vs LLM Boundary
If an operation has a well-defined, deterministic workflow (file conversion, data transform, paper run, formatting), write a script — don't have the LLM re-reason through the same steps each time. The script is:
- Faster (no LLM latency)
- Deterministic (same input → same output)
- Auditable (check into git, review the logic)
If the operation needs open-ended reasoning (investigating a bug, designing a feature, evaluating results), use Strategy C (Subagent) — it brings the LLM's judgment to bear where it adds value.
Scripts/ Directory Layout
Scripts/ Directory Layout
Simple scripts go directly under scripts/:
scripts/
├── manage_task.py ← 生命周期管理(create/accept/decline/status/view/reset + init/export/import/rebuild/reindex/list)
├── task_api.py ← stable JSON interface for PS/Kanban/ticket/project adapters
├── task-runner.sh ← logging wrapper
├── update-index.py ← regenerate README.md + TASKS.md
├── task_ref.py ← ref: 解析 + 循环依赖检测
└── convert_md_to_pdf.py ← doc converter (fallback, weasyprint)🔴 md→PDF 转换的查找顺序:
- 优先复用
convert-markdown-to-pdfskill(如可用)——Chrome headless 方法,CJK + 表格渲染最佳:python <skill>/scripts/md2pdf.py <input.md> <output.pdf> - skill 不可用时回退到本目录
scripts/convert_md_to_pdf.py(weasyprint 方法)
执行转换前先 skill_graph_search(query="markdown to pdf") 确认 skill 是否存在,存在则直接使用其脚本,不要重复发明轮子。
For complex tools that span multiple files (a multi-step data pipeline, a paper reproduction suite), create a subdirectory:
├── run.sh ← entry point
├── download-data.py ← data preparation
├── run-experiment.py ← experiment execution
└── compare-results.py ← output comparisonThe entry point (run.sh or main.py) should be the only file referenced from the operation's section in SKILL.md. The supporting files live alongside it.
Stable Adapter API (task_api.py)
External project/ticket/Kanban/profile adapters must use the JSON API instead of parsing task directory names or editing .hermes-task.json directly:
python3 scripts/task_api.py describe <hash-or-name>
python3 scripts/task_api.py search "<terms>"
python3 scripts/task_api.py get-meta <task> [key]
python3 scripts/task_api.py get-extension <task> <namespace> [key]
python3 scripts/task_api.py set-extension <task> <namespace> <key> '<json-value>'Core metadata is read-only through this adapter surface. Writes are namespaced under .hermes-task.json.extensions.<namespace> to prevent PS/Kanban/ticket integrations from overwriting lifecycle fields.
Task Lifecycle Management (manage_task.py)
scripts/manage_task.py 管理任务的完整生命周期。所有文件直接存放在任务目录下($HERMES_TASKS_ROOT/<ts>.<name>-<hash6>/),单一存储,无镜像目录,无 symlink。
命令
# ── 任务创建与 task-framework input ──
# 创建新任务(目录 + hash + 元数据 + 模板)
python3 scripts/manage_task.py create <name> [--desc "<goal>"] [--from-inbox <file-or-dir>]
# 从 task-framework inbox 条目创建任务
python3 scripts/manage_task.py accept <inbox_item> [--name <task-name>]
# 拒绝 task-framework inbox 条目并保留证据
python3 scripts/manage_task.py decline <inbox_item> [--reason "<text>"]
# ── 任务操作 ──
# 更新任务状态
python3 scripts/manage_task.py status <hash_or_dir> <status> [--reason "<text>"]
# 查看 README.md + TASK.md
python3 scripts/manage_task.py view <hash_or_dir>
# 重置任务(默认 --hard: 清 output/、重置 checkbox、重设状态)
python3 scripts/manage_task.py reset <hash_or_dir> [--no-hard]
# ── 底层操作 ──
# 初始化一个任务(创建目录 + TASK.md + CHANGELOG.md + .hermes-task.json)
python3 scripts/manage_task.py init <hash6>
python3 scripts/manage_task.py init tasks/<ts>.<task-name>-<hash6>/
# 导出任务(tar.gz)
python3 scripts/manage_task.py export <hash6>
# 导入任务
python3 scripts/manage_task.py import tasks/<ts>.<task-name>-<hash6>.tar.gz
# 按 hash 重建(查找最近 tar.gz)
python3 scripts/manage_task.py rebuild <hash6>
# 全量注册所有现有任务
python3 scripts/manage_task.py ensure-all
# 重建索引(README.md + TASKS.md)
python3 scripts/manage_task.py reindex
# 列出所有任务(直接扫描目录,实时)
python3 scripts/manage_task.py listtar.gz 格式
<ts>.<name>-<hash6>.tar.gz
└── <ts>.<name>-<hash6>/ ← 任务目录(含 input/ + output/ + TASK.md + CHANGELOG.md + .hermes-task.json)跨机器迁移流程
# 源机器:导出
cd "$HERMES_TASKS_ROOT"
python3 scripts/manage_task.py # from the skill directory export <hash6>
git add tasks/*<hash6>*.tar.gz
git commit -m "export <hash6>"
git push
# 目标机器:拉取 + 导入
git pull
python3 scripts/manage_task.py # from the skill directory rebuild <hash6>旧任务(无 hash)的管理
无 hash 的任务(目录名不以 -<hash6> 结尾)需先重命名目录追加 hash 才能使用 manage_task.py。
How to Decompose a Task
When the user says "do X" and X is complex:
- Decompose the work into concrete operations; ask only if a material decision lacks a safe default or the required scope is missing.
- List the operations with brief description
- Sequence them with dependencies
- For each operation, note which strategy fits
- Write TASK.md with operations as checklist items
- Execute the first dependency-ready non-BREAK item when the task has a concrete actionable execution point, unless the user explicitly requested not to execute after creation; otherwise wait for the missing execution point.
Quality-Gate Integration
After modifying any TASK.md, README.md, or log file inside a task directory, run quality-gate before reporting done.
Task Tracking (automatic phase completion log)
When TASK.md includes a ## Tracking section, orchestrators
inject tracking instructions into each dispatched card. The executor loads
task-tracker skill after each phase to:
- Mark the phase checkbox
[x]in TASK.md - Append a structured entry to CHANGELOG.md
- Run
update-index.py
See skills/task-tracker/SKILL.md for the parameter interface.
Skill 架构规范
所有 skill 应遵循 通用工具 + 临时脚本生成 模式:
skill-name/
├── SKILL.md ← 规则文档 + API 文档
├── scripts/
│ ├── utils/ ← 通用工具方法(可复用,不含任务逻辑)
│ │ ├── __init__.py
│ │ ├── module_a.py
│ │ └── module_b.py
│ ├── requirements.txt ← Python 依赖声明
│ └── setup_venv.sh ← 创建 .venv + 安装依赖
├── .venv/ ← 技能独立虚拟环境(gitignore)
├── templates/ ← 骨架模板
└── references/ ← 参考文档规则:
.venv/在 skill 目录内 — 每个 skill 独立管理依赖,setup_venv.sh一键安装- 通用方法放
scripts/utils/— 不包含任何任务特定逻辑,纯工具函数 - 任务特定逻辑写临时脚本 — 执行时生成
task_script.py到任务目录,执行完后可清理 - 临时脚本 import 通用方法 —
sys.path.insert(0, skill_scripts_path)→from utils.xxx import ... - SKILL.md 是唯一定义规则的地方 — 通用方法不包含业务规则,规则在 SKILL.md 中,由 LLM 读取后生成临时脚本
Phase Directory Rename Procedure
When renaming phase directories (e.g. tts/ → tts-a3f8c2/), the change cascades across multiple files. Do not just rename the directory — update all cross-references:
Files to update
| # | File | What to check |
| 1 | TASK.md — Data Flow table | All source/consumer phase paths |
| 2 | TASK.md — Checklist | Phase names in parentheses (phase-name) — descriptive, no hash |
| 3 | COMPOSITING.md — Video header | video.mp4 path |
| 4 | COMPOSITING.md — Timeline | Every audio_*.mp3 / video.mp4 path |
| 5 | COMPOSITING.md — Output | ## Output section path |
| 6 | RECORDING.md — Output line | output: path |
| 7 | scripts/composite.py | OUTPUT = "..." + timeline_chart.txt path |
| 8 | All .py scripts | Hardcoded paths to renamed dirs |
| 9 | generate_timeline_chart() calls | Text + image output paths, if format='both' |
Step-by-step
- Plan the mapping — which old dir → which new dir (with hash)
- Rename dirs —
mv old/ new-hash6/ - Update spec files (COMPOSITING.md, RECORDING.md) — all paths
- Update TASK.md —
## Data Flowtable (use actual dir paths with hashes) + checklist()(descriptive phase names, no hash) - Update scripts — any hardcoded paths (composite.py is the most common offender)
- Verify — grep for old path names across all task files; nothing should match except venv references and intended coincidences
Best practice: avoid the need for rename
Generate hash suffixes at task creation time, not post-hoc. When task_create detects this is a multi-phase task, pre-assign hashes to all anticipated phase directories and bake them into TASK.md from the start. In the () use only the descriptive phase name (no hash) — the hash lives only in the directory name and Data Flow table paths.
Timeline chart images also need update
If Phase 3 uses generate_timeline_chart(..., format='both'), the PNG output path is derived from the text output path ({stem}.png). Renaming the text path's directory automatically renames the image path too — no separate update needed, as long as both file paths share the same directory stem. If you override the output path in composite.py, update both the text and image generation paths there.
Task Identity (.hermes-task.json)
每个任务在创建时生成 .hermes-task.json,作为任务的唯一标识和接口声明。
{
"hash": "a3f8c2",
"name": "任务名",
"created_at": "2026-06-05T23:00:00",
"outputs": {},
"dependencies": [],
"related": [],
"supersedes": [],
"affinity": "any",
"claimed_by": null,
"requires": [],
"required_by": [],
"priority": 2
}| 字段 | 说明 |
hash | 6 位随机字符串,全局唯一 |
name | 任务名(目录名 ts.name 中的 name 部分) |
outputs | 命名输出,key 是输出名,value 是路径。由各 phase 填充 |
dependencies | 依赖的其他任务 hash 列表(硬依赖,本任务开始前 must 完成) |
related | 主题相关/互为参考的其他任务 hash 列表(无硬依赖) |
supersedes | 本任务替代/废弃的旧任务 hash 列表 |
affinity | Cluster 亲和性:local / any / <hash6> / <capability-tag> |
claimed_by | 认领此任务的节点 hash6,未认领为 null |
requires | 硬依赖:这些 task hash 必须 done 后才能认领 |
required_by | 反向依赖:哪些 task 依赖本 task(下游创建时回写) |
priority | 优先级:0 (最高) ~ 3 (最低),默认 2 |
See task-hash-naming.md for the complete naming convention rationale.
Named Outputs
Phase 完成后将产物路径注册为 named output:
# Via task_ref.py helper:
python3 -c "
import sys; sys.path.insert(0, 'scripts')
from task_ref import set_output
set_output('.', 'video', 'compositing-a3f8c2/output.mp4')
"其他任务通过 ref:hash/output_name 引用:
ref:a3f8c2/video → 解析为 compositing-a3f8c2/output.mp4依赖声明
任务创建时或手动在 .hermes-task.json 中声明 dependencies:
{
"hash": "def456",
"name": "下游任务",
"dependencies": ["a3f8c2", "b7e9d1"],
"outputs": {}
}ref: 解析
🔴 IMPORTANT: resolve_ref globs *{hash_id}* against directory names. The hash MUST be part of the task directory name for ref: resolution to work. Directory naming convention: YYYYMMDD-HHMMSS.<name>-<hash6>/. If the hash is only in .hermes-task.json and not the dir name, ref: lookups will return FileNotFoundError.
pipeline 或任意 skill 遇到 ref: 前缀时,调用 scripts/task_ref.py 的 resolve_ref():
from task_ref import resolve_ref
path = resolve_ref('ref:a3f8c2/video') # → /path/to/task/compositing-a3f8c2/output.mp4完整实现见 scripts/task_ref.py。
循环依赖检测
创建/更新依赖时验证(scripts/task_ref.py 的 check_cycles()):
from task_ref import check_cycles
check_cycles(meta) # raises ValueError on cycle完整实现见 scripts/task_ref.py。
Task Changelog (CHANGELOG.md)
每个任务目录下有一个 CHANGELOG.md,用于在跨 session 操作同一任务时保持上下文连贯性。
定位
| 文件 | 用途 | 谁写 | 生命周期 |
TASK.md | checklist、状态、要求 | 创建时填充 | 手动维护 |
CHANGELOG.md | 操作记录、决策、发现、阻塞原因 | 自动追加 | 按时间追加,永不删除 |
MEMORY.md | 跨阶段的硬事实(端口、规则、公约) | 手动维护 | §-delimited, compact format; MUST use your memory management skill (if available) for format and trigger rules. Review after every phase completion or session that changes task state. |
logs/ | 命令输出 | 自动生成 | 可清理 |
.hermes-task.json | hash、outputs、依赖 | 自动维护 | 随任务更新 |
Hierarchical Task Memory(多子系统任务)
当长期任务跨多个仓库、服务或子系统时:
- 加载
task-context-storage,判断信息应进入全局 memory、任务 MEMORY 还是任务 CHANGELOG。 - 加载
compact-directory-memory,按其 hierarchical layout 创建、读取、更新和验证根级及memories/<sub-system>/上下文。 - 在
.hermes-task.json中声明"memory_layout": "hierarchical"和"memory_root": "memories"。 - task-framework 只负责编排读写时机和重建任务索引,不复制目录记忆 skill 的格式规则或实现脚本。
读写规则
每次操作任何 task 之前:
- 检查该 task 目录下是否存在
CHANGELOG.md - 如果存在 → 读到最后 50 行,了解最近的上下文(做了什么、卡在哪、有什么发现)
- 如果不存在 → 从
templates/CHANGELOG.md复制模板后写入第一条记录
每次操作之后(特别是跨 session 时):
在 CHANGELOG.md 末尾追加一条新记录。
记录格式
## 2026-06-06 13:00
**操作:** 重命名 task 目录 <old-name> → <task-name>-<hash6>
**原因:** 遵循新命名规则,目录名需包含 hash
**改动:**
- 目录改名
- .hermes-task.json name 字段更新
- TASK.md 执行入口路径更新
- tasks/README.md 索引重建
**状态:** 完成,等待用户确认下一步
**素材状态:** tts-a2c2bc(17段音频✅) image-slideshow-a2c2bc(封面✅) subtitle-gen-a2c2bc(字幕✅) browser-video-recording-a2c2bc(上次中断⚠️)
## 2026-06-06 14:00
**操作:** 准备运行 Phase 3 录制
**问题:** dev server 端口 5173 不可达
**解决:** tmux 重新启动 dev server
**结果:** Phase 3 录制成功(138s, 1.8MB)
**下一步:** Phase 4 合成记录什么
- ✅ 发生了什么 — 文件名改动、pipeline 阶段、关键命令
- ✅ 为什么 — 决策理由(避免下次不知道为什么这么做)
- ✅ 问题与解决方案 — 踩过的坑和怎么解决的
- ✅ 素材状态清单 — 什么有了、什么没有、哪个坏了
- ✅ 下一步 — 这个 session 结束时停在哪
- ❌ 纯命令输出(放 logs/)
- ❌ checklist 勾选状态(放 TASK.md)
- ❌ 详细的技术规范(放 docs/)
task_reset 时
task_reset --hard 不清除 CHANGELOG.md,只清 logs/ 和 docs/。重置后追加一条"任务已重置"记录。
注意:CHANGELOG.md 是持久化的操作日志,NOT cleared by task_reset。
跨 session 价值
当新 session 打开这个任务时,CHANGELOG.md 让 agent 立刻知道:
- 上次做到哪一步
- 为什么停下来
- 有什么已知问题
- 哪个素材能复用、哪个要重做
不需要翻整段对话历史来找上下文。
Nested Tasks(子任务)
当主任务拆分为多个子任务时,每个子任务也必须遵守完整的任务规则:
- 每个子任务目录下必须创建
CHANGELOG.md - 记录根因、修复方案、验证状态
- 遵循相同的 task-framework 生命周期(创建 → 执行 → CHANGELOG 日志 → 完成)
- 子任务的 CHANGELOG.md 格式与主任务一致(日期标题 + 操作/发现/决策/下一步)
主动创建触发信号
CHANGELOG.md 不仅属于 task_create 创建的任务。当会话从简单询问演化为复杂工作时,应当主动创建 task 目录和 CHANGELOG.md。
触发信号(任一达到即触发):
| 信号 | 说明 | 示例 |
| 5+ 工具调用 | 本轮已调用了 5 次以上 terminal/write_file/patch | 修 bug → 发现新问题 → 讨论方案 → 实施 → 验证 |
| 跨子系统变更 | 改动了两个以上独立子系统 | service-manager + doc server + registry |
| 设计讨论 | 出现了多方案对比、取舍、决策记录 | 方案 A/B/C 对比 → 选定一个 |
| 文件系统结构性变更 | 创建文件、迁移数据、改 schema | registry 格式迁移、新增 skill 目录 |
| 用户明确要求 | 用户说"列个清单"、"动手吧"、"继续完善" |
触发后的操作:
# 1. 创建 task 目录(不打断当前工作流)
python3 scripts/manage_task.py create <task-name> # from the skill directory
# 2. 在 task 的 CHANGELOG.md 里写首条记录(操作/发现/决策/下一步)
# 3. 索引由 create 命令自动更新追溯创建
如果 post-flight 检查发现本轮达到了触发条件但没有 task 目录,应当事后补建:
- 扫描本轮所有操作记录(memory、终端输出、文件修改)
- 按时间顺序提炼关键节点
- 每个节点写一条 CHANGELOG.md 记录(操作/发现/决策/下一步)
- 创建目录、写入、更新索引
补建时不需要写满全部细节——每个决策点提炼 2-5 行即可,重点是"为什么选了这个方案"和"踩了哪些坑"。
与 post-flight 联动
post-flight 的 Integrity Check 会检查"本轮的复杂程度是否达到了触发条件", Pending Action Scan 会处理"达到了但没有 task 目录 → 立即补建"。 CHANGELOG.md 的创建和维护是 post-flight 后置链的固定组成部分。 同样,当 your memory management skill 可用时,post-flight 应触发 MEMORY.md 的审查:检查现有事实是否过时、本 session 是否产生了需要记录的新事实。
.hermes-task.json必须在任务根目录 — 和 TASK.md 同级- 任务被删除后引用断掉 —
resolve_ref会抛异常,上游任务要考虑重建 - 循环依赖在写入时检测 — 不要在运行时才发现
| Pitfall | Correction | |||
| Treating a composite task as a single operation | Always decompose. Complex tasks benefit from separation. | |||
| Skipping decomposition for "simple" coding | Even a simple feature needs: research → design → code → review. | |||
| Choosing wrong strategy | 5+ tool calls or reasoning → don't use A (Inline), use C (Subagent). | |||
| Operation catalog out of date | Add new operations as they're discovered. | |||
| 🔴 Never fill task placeholders from conversation history | When user says "create a task named X", create an empty template with all {placeholder} intact. Do NOT infer URL, steps, or operations from earlier chat context unless user explicitly says "根据上面的对话" or similar. Corrected multiple times — the user will delete and re-create if you guess. | \n | 🔴 File moves must be ln/cp + verify + rm | Never mv. Use ln <src> <dst>, verify with ls -la, then rm <src>. |
🔴 Missing ## 环境要求 in TASK.md | Executor pre-flight forces this check. Always include it. | |||
| 🔴 Confirm CWD before creating tasks | Project root must have tasks/ dir. If not, confirm user expects $HERMES_TASKS_ROOT/ as base. | |||
| 🔴 "tasks" naming ambiguity + no manual management | When the user says "tasks" or "task", first disambiguate: (a) task-framework managed → use task_create/task_set_status/etc., never raw mv/cp/rm on task dirs; (b) generic concept → normal conversation. Corrected: manual mv on a task dir instead of using framework. Exception — wrong-root relocation IS a raw mv: when a task was created under the wrong tasks-root, moving the intact directory to the correct root (then re-indexing both roots) preserves the hash/identity and is the correct fix; see "Wrong-root creation" under Environment Variables. Delete-and-recreate mints a new hash and breaks every emitted reference. | |||
| 🔴 Log accumulation | Clean old logs with rm tasks/*.<name>/logs/*.YYYYMMDD-*.log. | |||
| 🔴 Root index files stale | After creating/updating/deleting any task, run python3 scripts/update-index.py # from the skill directory to regenerate both tasks/README.md and tasks/TASKS.md. Users rely on these indexes for overview. | |||
| 🔴 Data Flow table not consulted | In cross-skill composite tasks, a phase that produces a file (e.g. TTS → audio_manifest.json) must write it in the format expected by the consumer phase. The ## Data Flow table's 格式说明 column tells you where to find that format spec. Don't guess the schema — load the referenced skill/reference file and read it. Corrected in discussion about how compositing finds audio manifest format. | |||
| Task directory recognition is explicit | Only valid timestamp/name/hash task directories are indexed; inbox/ and declined/ remain task-framework input areas and are not expanded into the task summary. | |||
## Status empty line matters | grep -A2 not -A1 to skip blank line after header. | |||
| LLM reasoning where a script would do | If you've repeated the same manual sequence twice, write a script. The LLM should handle judgment, not memorized mechanical steps. | |||
| 🔴 Don't stop & ask between checklist items unless there's a BREAK | Execution Logic says: [ ] BREAK: → pause; [ ] → execute immediately. After completing one item, scan for the next unchecked [ ]. If there's no BREAK between them, execute it right away — do NOT ask 'do you want to continue?'. Parallel dependencies (e.g. 'and Phase 1 同步进行') don't imply you should wait for instructions — check if the dependency is already resolved and act. | |||
| 🔴 Never modify REQUIREMENTS.md | REQUIREMENTS.md is user-owned. If changes are needed, tell the user what to change and let them do it themselves. Do NOT edit it directly — the user won't know what changed. Corrected twice in one session. | |||
| 🔴 Input source files go in input/, output/ is for generated files | task_reset --hard does rm -rf output/. Any source file (PDF, DOCX, images, REQUIREMENTS.md) placed in output/ will be lost. Always put source material in input/. | |||
| 🔴 Declared source files must be copied to task | When a task uses a source file (PDF/DOCX/etc.), copy it into the task's input/ directory. Do not reference an unrelated sibling path; the task must be self-contained. | |||
| 🔴 Design discussion ≠ execution signal | When the user makes observations, suggestions, or asks how a system/skill/process should work (e.g. "在从 REQUIREMENTS.md 生成 RECORDING.md 的时候,xxx 应该 yyy"), they are in design/discussion mode. Do NOT start executing pipeline steps or making code changes based on a design opinion. Wait for explicit go-ahead. This pattern has caused confusion in practice. |
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

