task-journal
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseTask Journal
任务日志(Task Journal)
Overview
概述
This skill is a convention reference, not a tool. It defines how every task in this repository records its life as an append-only journal of plain markdown. There is no slash command, no CLI, and no central writer process — every skill that touches a task appends entries directly to the same file.
journal.mdThe job of this skill is to give other skills (and humans reading the file) a stable contract about:
- where task records live,
- what an entry looks like,
- which keys are reserved,
- what the linter enforces,
- what completion means,
- and what signals justify upgrading away from this design.
Truth lives in the file system + git + memory. The convention exists to keep that truth readable.
本skill是一份约定参考文档,而非工具。它定义了本仓库中每个任务如何以纯Markdown格式的仅追加式日志记录其生命周期。这里没有斜杠命令、没有CLI,也没有中央写入进程——所有涉及任务的skill都会直接向同一个文件追加条目。
journal.md本skill的作用是为其他skill(以及阅读文件的人类)提供一份稳定的约定,涵盖:
- 任务记录的存储位置
- 日志条目的格式
- 哪些键是预留的
- linter会强制执行的规则
- 任务完成的定义
- 哪些信号表明需要升级此设计
真实状态存储在文件系统 + git + 内存中。本约定的存在是为了让这些真实状态具备可读性。
When to Use
使用场景
Use this skill when:
- a skill is at a lifecycle milestone and needs to append to (see Tier table)
journal.md - the user asks about an existing task's status, progress, or recent activity
- the user wants to check task records for drift (run the linter)
- you are about to mark a task done (write a entry; do not move the directory)
done:
Do NOT use this skill when:
- the user wants to create a new task — that is 's job
task-brief - the user is asking a historical question about (the retired state machine)
task-state-management - the request is about general docs, design, or planning that has no task directory
- the request is a one-off action that does not warrant a task at all (e.g., "rename this variable")
在以下场景使用本skill:
- 某个skill处于生命周期里程碑节点,需要向追加条目(参见技能层级表)
journal.md - 用户询问现有任务的状态、进度或近期活动
- 用户想要检查任务记录是否偏离约定(运行linter)
- 你即将标记任务完成(写入条目;请勿移动目录)
done:
请勿在以下场景使用本skill:
- 用户想要创建新任务——这是的职责
task-brief - 用户询问关于(已停用的状态机)的历史问题
task-state-management - 请求涉及无对应任务目录的通用文档、设计或规划
- 请求是无需创建任务的一次性操作(例如:"重命名这个变量")
Data Layout
数据结构
<repo>/.agents/tasks/
├── .current # single-line pointer: <task-id>
└── <task-id>/
├── brief.md # immutable after first journal entry
├── journal.md # append-only log
└── artifacts/ # private to this task; long bodies go here- Location: . Flat — no
<repo>/.agents/tasks/oractive/partitions.completed/ - Git tracking: default off. includes
.gitignore. The user may.agents/tasks/an individual file deliberately.git add - pointer: optional single-file pointer with the active task id (no newline required, trailing newlines tolerated). Written by
.currenton creation. Other skills may read it as a fallback when no task id was passed explicitly.task-brief
<repo>/.agents/tasks/
├── .current # 单行指针:<task-id>
└── <task-id>/
├── brief.md # 首个日志条目写入后不可修改
├── journal.md # 仅追加式日志
└── artifacts/ # 任务私有目录;长内容存于此- 位置:。扁平化结构——无
<repo>/.agents/tasks/或active/分区。completed/ - Git追踪:默认关闭。包含
.gitignore。用户可手动.agents/tasks/单个文件。git add - 指针:可选的单行文件指针,存储活跃任务ID(无需换行,允许尾随换行)。由
.current在任务创建时写入。当未显式传入任务ID时,其他skill可读取此文件作为 fallback。task-brief
Task ID Format
任务ID格式
YYYY-MM-DD-<slug>-<rand>- : ISO date of creation.
YYYY-MM-DD - : ASCII kebab-case, ≤ 6 words, ≤ 60 characters. Proposed by
<slug>from the user goal; the user may override.task-brief - : 2 lowercase hex characters (
<rand>–00), generated viaffthen formatted asrandom.randint(0, 255). Re-roll on directory collision. Never reused after deletion (collisions are rare and easy to detect).%02x
Example: .
2026-04-26-task-journal-redesign-a3YYYY-MM-DD-<slug>-<rand>- :任务创建的ISO日期。
YYYY-MM-DD - :ASCII短横线命名格式,≤6个单词,≤60字符。由
<slug>根据用户目标生成;用户可覆盖。task-brief - :2位小写十六进制字符(
<rand>–00),通过ff生成后格式化为random.randint(0, 255)。若目录冲突则重新生成。任务删除后永不复用(冲突概率极低且易于检测)。%02x
示例:。
2026-04-26-task-journal-redesign-a3Brief Immutability
任务摘要不可变性
brief.md- Before the first entry: the brief may be overwritten freely (the "uncommitted brief" window).
- After the first entry: do not edit . Record any goal drift, scope change, or refinement as a new journal entry, e.g.:
brief.mdmarkdown## 2026-04-26T11:20:00+08:00 — task-brief refined: goal narrowed to logging-only path scope was widening to cover dashboards; user confirmed pulling that out
This rule exists so the brief stays a stable reference point. The journal is where evolution lives.
brief.md- 首个条目写入前:摘要可自由覆盖("未提交摘要"阶段)。
- 首个条目写入后:请勿编辑。将任何目标偏移、范围变更或细化内容记录为新的日志条目,例如:
brief.mdmarkdown## 2026-04-26T11:20:00+08:00 — task-brief refined: goal narrowed to logging-only path scope was widening to cover dashboards; user confirmed pulling that out
此规则的目的是让摘要保持为稳定的参考基准。任务的演变记录在日志中。
Journal Entry Format
日志条目格式
Each entry is a level-2 markdown heading followed by one or more lines and an optional short body.
key: valuemarkdown
undefined每个条目由二级Markdown标题、一行或多行以及可选的简短正文组成。
key: valuemarkdown
undefined<ISO8601-timestamp> — <skill-name>
<ISO8601-timestamp> — <skill-name>
<key>: <value>
[<additional key>: <value>]
[free-form markdown body, ≤ 15 lines]
Rules:
- **Heading** must start with `## `, then an ISO 8601 timestamp (date+time, with timezone or `Z`), then ` — ` (em dash, space-padded), then the skill name.
- **At least one** `key: value` line is required immediately under the heading.
- Keys are lowercase ASCII, may contain hyphens and underscores. Values are free text on the same line.
- **Body** is optional, ≤ 15 lines. If you need more, write to `artifacts/` and reference it in the body.
- Entries are appended only. Never rewrite existing entries.
- Entries should be separated by a blank line for readability (the linter does not require it).<key>: <value>
[<additional key>: <value>]
[自由格式Markdown正文,≤15行]
规则:
- **标题**必须以`## `开头,后跟ISO 8601时间戳(日期+时间,带时区或`Z`),然后是` — `(空格包裹的破折号),最后是skill名称。
- 标题下**至少需要一行**`key: value`。
- 键为小写ASCII,可包含连字符和下划线。值为同一行的自由文本。
- **正文**可选,≤15行。若内容过长,请写入`artifacts/`并在正文中引用。
- 条目仅可追加。绝不可重写现有条目。
- 条目之间建议空一行以提升可读性(linter不强制要求)。Reserved Core Keys
预留核心键
These five keys are reserved and linted. Use them when their meaning fits — do not invent synonyms.
| Key | Meaning | Typical writer |
|---|---|---|
| A persistent artifact was written or updated. Value names what was saved. | |
| A bounded design decision was made. Value names the decision; body may carry rationale. | |
| Readiness status of the design or plan. Value is | |
| A blocker was raised. Value is a short label; body describes what is blocked and why. | any skill |
| The task reached its completion state. Value names the result ( | |
Other keys (, , , , …) are free-form. The linter does not check them.
refinednotehandofflink以下五个键为预留键且受linter检查。若符合其含义则使用——请勿创造同义词。
| 键 | 含义 | 典型写入者 |
|---|---|---|
| 持久化工件已写入或更新。值为保存的工件名称。 | |
| 已做出明确的设计决策。值为决策名称;正文可包含理由。 | |
| 设计或计划的就绪状态。值为 | |
| 已提出阻塞问题。值为简短标签;正文描述被阻塞的内容及原因。 | 任意skill |
| 任务已达到完成状态。值为结果名称( | |
其他键(, , , , …)为自由格式。linter不检查这些键。
refinednotehandofflinkCompletion Semantics
完成语义
Only code tasks have a real notion of completion (Option 2 from the design):
- Primary path: appends
finishing-a-development-branchafter a successful merge/ship.done: <result> - Fallback: the user states the task is done; the next skill (often ) appends the
task-briefentry.done:
Non-code tasks never get a entry. Activity is judged by the timestamp of the last entry; the linter may flag long-stale tasks as a soft hint.
done:Do not migrate the directory when a task is done. The task stays under . The presence of a entry is the marker.
.agents/tasks/<task-id>/done:Reopen is just appending a new entry after a entry. The linter detects this pattern and emits a warning so the human notices it.
done:只有代码任务具备真正的完成概念(设计中的选项2):
- 主路径:在成功合并/发布后追加
finishing-a-development-branch条目。done: <result> - ** fallback**:用户声明任务完成;下一个skill(通常是)追加
task-brief条目。done:
非代码任务永远不会有条目。通过最后一个条目的时间戳判断活动状态;linter可能会将长期停滞的任务标记为软提示。
done:任务完成时请勿迁移目录。任务仍保留在下。条目的存在即为完成标记。
.agents/tasks/<task-id>/done:重新开启只需在条目后追加新条目即可。linter会检测到此模式并发出警告,以便人类注意到。
done:Skill Tiers
技能层级
This is the contract for which skills should append to journal and which should not. Cross-reference each skill's own SKILL.md "Journal Integration" section for exact entry shape.
| Tier | Skills | Behavior |
|---|---|---|
| A — creates tasks | | Sole entry point that creates |
| B — appends on milestones | | Append entries at meaningful lifecycle moments (saved, decision, readiness, done). |
| C — appends conditionally | | Append only when a task id is in scope. |
| D — never appends | | Methodology / routing / meta layer. They do not own task state. |
这是关于哪些skill应追加日志、哪些不应追加的约定。可交叉参考每个skill自身SKILL.md中的“日志集成”部分以获取确切的条目格式。
| 层级 | 技能 | 行为 |
|---|---|---|
| A — 创建任务 | | 唯一创建 |
| B — 里程碑时追加 | | 在重要生命周期节点(saved、decision、readiness、done)追加条目。 |
| C — 条件性追加 | | 仅当任务ID在范围内时追加。 |
| D — 永不追加 | | 方法论/路由/元层技能。它们不负责任务状态。 |
Task ID Propagation Between Skills
技能间的任务ID传递
Pick the first that applies:
- Explicit parameter — the caller (user or upstream skill) names the task id directly. Preferred.
- pointer — read
.current; if it names an existing directory, treat that as the active task.<repo>/.agents/tasks/.current - Otherwise — do not guess. Ask the user, or skip the journal append for this turn.
Do not introduce ambient state, environment variables, daemons, or file locks for this purpose.
按以下优先级选择:
- 显式参数 — 调用者(用户或上游skill)直接指定任务ID。优先选择。
- 指针 — 读取
.current;若指向存在的目录,则将其视为活跃任务。<repo>/.agents/tasks/.current - 其他情况 — 请勿猜测。询问用户,或跳过本次日志追加操作。
请勿为此引入环境状态、环境变量、守护进程或文件锁。
Helper Script: journal.py
journal.py辅助脚本:journal.py
journal.pyscripts/journal.pybash
python3 ${SKILL_DIR}/scripts/journal.py append \
--tasks-dir .agents/tasks \
--task-id <task-id> \
--skill <skill-name> \
--kv saved=design-tree.md \
--body "expanded core branches"bash
python3 ${SKILL_DIR}/scripts/journal.py read \
--tasks-dir .agents/tasks \
--task-id <task-id> \
[--last N]SKILL_DIR~/.claude/skills/task-journalskills/task-journalThe helper is stdlib-only, ~100 lines, and never blocks. It does not validate keys (that is the linter's job).
scripts/journal.pybash
python3 ${SKILL_DIR}/scripts/journal.py append \
--tasks-dir .agents/tasks \
--task-id <task-id> \
--skill <skill-name> \
--kv saved=design-tree.md \
--body "expanded core branches"bash
python3 ${SKILL_DIR}/scripts/journal.py read \
--tasks-dir .agents/tasks \
--task-id <task-id> \
[--last N]SKILL_DIR~/.claude/skills/task-journalskills/task-journal该辅助工具仅依赖标准库,约100行代码,且永远不会阻塞。它不验证键(这是linter的职责)。
Linter: lint_tasks.py
lint_tasks.py检查工具:lint_tasks.py
lint_tasks.pyscripts/lint_tasks.py.agents/tasks/- error — corrupt heading, missing line, malformed reserved-key value, unparseable timestamp, missing
key: value. Returns exit code 1.brief.md - warn — body > 15 lines, entry written after a entry without a clear reopen marker, task with no entry for > 30 days, unknown skill name (heuristic only). Returns exit code 0 if no errors.
done:
The linter never blocks LLM real-time writes. Whether the loom repo's pre-push hook calls it is a separate decision and not part of this contract.
bash
python3 ${SKILL_DIR}/scripts/lint_tasks.py --tasks-dir .agents/tasksFlags:
- : required; path to the tasks root.
--tasks-dir <path> - : treat warnings as errors (exit 1 on any warning).
--strict - : lint a single task instead of the whole tree.
--task-id <id>
scripts/lint_tasks.py.agents/tasks/- 错误 — 标题损坏、缺少行、预留键值格式错误、时间戳无法解析、缺少
key: value。返回退出码1。brief.md - 警告 — 正文超过15行、条目后写入新条目但无明确重新开启标记、任务超过30天无条目、未知skill名称(仅启发式判断)。若无错误则返回退出码0。
done:
该检查工具永远不会阻塞LLM的实时写入。loom仓库的预推送钩子是否调用它是独立决策,不属于本约定的一部分。
bash
python3 ${SKILL_DIR}/scripts/lint_tasks.py --tasks-dir .agents/tasks参数:
- :必填;任务根目录路径。
--tasks-dir <path> - :将警告视为错误(任何警告均返回退出码1)。
--strict - :仅检查单个任务而非整个目录树。
--task-id <id>
Anti-Patterns
反模式
These are the failure modes the design explicitly rejects. Avoid them.
- Do not edit after the first journal entry. Record changes as a
brief.mdentry.refined: - Do not move task directories on completion. A entry is the marker.
done: - Do not use journal as RPC between skills. The journal is write-many, read-rarely. If skill B needs a value from skill A, pass it as a parameter or read the underlying artifact (plan file, design tree, etc.), not by parsing journal entries.
- Do not invent synonyms for reserved keys. If ,
saved,decision,readiness,blockerfit, use them.done - Do not embed long bodies in the journal. > 15 lines goes to .
artifacts/ - Do not rewrite or delete past entries. Append a correction entry instead.
- Do not introduce ambient state (env vars, daemons, locks). Pass the task id explicitly or use .
.current
以下是本设计明确拒绝的失败模式。请避免。
- 首个日志条目写入后请勿编辑。 将变更记录为
brief.md条目。refined: - 任务完成时请勿移动目录。 条目即为完成标记。
done: - 请勿将日志用作技能间的RPC机制。 日志是多写少读的。若skill B需要skill A的值,请将其作为参数传递或读取底层工件(计划文件、设计树等),而非解析日志条目。
- 请勿为预留键创造同义词。 若、
saved、decision、readiness、blocker符合需求,请使用它们。done - 请勿在日志中嵌入长内容。 超过15行的内容请写入。
artifacts/ - 请勿重写或删除过往条目。 追加修正条目替代。
- 请勿引入环境状态(环境变量、守护进程、锁)。显式传递任务ID或使用。
.current
Upgrade Signals
升级信号
This design intentionally stays small. Each of the failure scenarios below has a documented signal and a documented upgrade direction. See the ADR for the canonical list.
docs/design-decisions/2026-04-26-task-journal-replaces-task-state-management.md| Failure scenario | Signal | Upgrade direction |
|---|---|---|
| Concurrent writers from multiple agents | interleaved or lost entries observed | file lock or single-writer protocol |
| Frequent cross-task index queries | > 50 tasks and weekly "which tasks reference X?" needs | index file or SQLite |
| Single task with very long journal | > 200 lines or reading feels slow | rolling archive ( |
| Frequent status grep queries | same grep ≥ 5×/week | structured summary command |
| Real second-person collaboration | a second human starts using it | switch to git-tracked + add an ownership field |
| Actual journal corruption | ≥ 1 corruption incident in practice | backup / checkpoint mechanism |
| Stable automated invocation needs | recurring CI/hook integration demands | thin CLI, one command at a time |
Meta-gate. Any PR that proposes "add the state machine back" must:
- point to one of the seven scenarios above,
- cite the number of times the signal has fired, and
- limit the upgrade to a single failure scenario.
Otherwise the PR is rejected. This rule exists because the previous design () was built without observed failures.
task-state-management本设计有意保持精简。以下每个失败场景都有明确的信号和升级方向。详见ADR文档中的完整列表。
docs/design-decisions/2026-04-26-task-journal-replaces-task-state-management.md| 失败场景 | 信号 | 升级方向 |
|---|---|---|
| 多agent并发写入 | 观察到条目交错或丢失 | 文件锁或单写入者协议 |
| 频繁跨任务索引查询 | 任务数>50且每周需要多次“哪些任务引用了X?”查询 | 索引文件或SQLite |
| 单个任务日志过长 | 超过200行或读取缓慢 | 滚动归档( |
| 频繁状态 grep 查询 | 同一grep操作≥5次/周 | 结构化摘要命令 |
| 真实的多人协作 | 第二位人类开始使用 | 切换为Git追踪 + 添加所有权字段 |
| 实际日志损坏 | 实际发生≥1次损坏事件 | 备份/检查点机制 |
| 稳定的自动化调用需求 | 持续集成/钩子集成的重复需求 | 轻量CLI,一次执行一个命令 |
元规则。任何提议“恢复状态机”的PR必须:
- 指向上述七个场景之一
- 引用信号触发的次数
- 将升级限制为单个失败场景
否则PR将被拒绝。此规则的存在是因为之前的设计()是在未观察到失败的情况下构建的。
task-state-managementExamples
示例
Tier B append (design-structure has just saved a design tree)
B层级追加(design-structure刚保存了设计树)
markdown
undefinedmarkdown
undefined2026-04-26T10:42:11+08:00 — design-structure
2026-04-26T10:42:11+08:00 — design-structure
saved: docs/design-tree/2026-04-26-task-journal-redesign.md
expanded the core branches; pending refinement on linter contract
undefinedsaved: docs/design-tree/2026-04-26-task-journal-redesign.md
expanded the core branches; pending refinement on linter contract
undefinedTier C conditional append (systematic-debugging on a tracked task)
C层级条件性追加(systematic-debugging处理追踪中的任务)
markdown
undefinedmarkdown
undefined2026-04-26T14:05:00+08:00 — systematic-debugging
2026-04-26T14:05:00+08:00 — systematic-debugging
note: reproduced the lost-entry case under concurrent appends
linked artifact: artifacts/concurrent-append-trace.md
undefinednote: reproduced the lost-entry case under concurrent appends
linked artifact: artifacts/concurrent-append-trace.md
undefinedReserved decision key
预留decision键
markdown
undefinedmarkdown
undefined2026-04-26T15:30:00+08:00 — decision-evaluation
2026-04-26T15:30:00+08:00 — decision-evaluation
decision: stdlib-only helper, no third-party deps
considered ruamel.yaml for richer parsing; rejected for footprint and YAGNI
undefineddecision: stdlib-only helper, no third-party deps
considered ruamel.yaml for richer parsing; rejected for footprint and YAGNI
undefinedDone marker (does not move directory)
完成标记(不移动目录)
markdown
undefinedmarkdown
undefined2026-04-26T18:12:00+08:00 — finishing-a-development-branch
2026-04-26T18:12:00+08:00 — finishing-a-development-branch
done: merged
PR #142 merged into main; cleanup branch deleted
undefineddone: merged
PR #142 merged into main; cleanup branch deleted
undefined