task-journal

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Task 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
journal.md
file.
The 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
    journal.md
    (see Tier table)
  • 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
    done:
    entry; do not move the directory)
Do NOT use this skill when:
  • the user wants to create a new task — that is
    task-brief
    's job
  • the user is asking a historical question about
    task-state-management
    (the retired state machine)
  • 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:
    <repo>/.agents/tasks/
    . Flat — no
    active/
    or
    completed/
    partitions.
  • Git tracking: default off.
    .gitignore
    includes
    .agents/tasks/
    . The user may
    git add
    an individual file deliberately.
  • .current
    pointer
    : optional single-file pointer with the active task id (no newline required, trailing newlines tolerated). Written by
    task-brief
    on creation. Other skills may read it as a fallback when no task id was passed explicitly.
<repo>/.agents/tasks/
├── .current                       # 单行指针:<task-id>
└── <task-id>/
    ├── brief.md                   # 首个日志条目写入后不可修改
    ├── journal.md                 # 仅追加式日志
    └── artifacts/                 # 任务私有目录;长内容存于此
  • 位置
    <repo>/.agents/tasks/
    。扁平化结构——无
    active/
    completed/
    分区。
  • Git追踪:默认关闭。
    .gitignore
    包含
    .agents/tasks/
    。用户可手动
    git add
    单个文件。
  • .current
    指针
    :可选的单行文件指针,存储活跃任务ID(无需换行,允许尾随换行)。由
    task-brief
    在任务创建时写入。当未显式传入任务ID时,其他skill可读取此文件作为 fallback。

Task ID Format

任务ID格式

YYYY-MM-DD-<slug>-<rand>
  • YYYY-MM-DD
    : ISO date of creation.
  • <slug>
    : ASCII kebab-case, ≤ 6 words, ≤ 60 characters. Proposed by
    task-brief
    from the user goal; the user may override.
  • <rand>
    : 2 lowercase hex characters (
    00
    ff
    ), generated via
    random.randint(0, 255)
    then formatted as
    %02x
    . Re-roll on directory collision. Never reused after deletion (collisions are rare and easy to detect).
Example:
2026-04-26-task-journal-redesign-a3
.

YYYY-MM-DD-<slug>-<rand>
  • YYYY-MM-DD
    :任务创建的ISO日期。
  • <slug>
    :ASCII短横线命名格式,≤6个单词,≤60字符。由
    task-brief
    根据用户目标生成;用户可覆盖。
  • <rand>
    :2位小写十六进制字符(
    00
    ff
    ),通过
    random.randint(0, 255)
    生成后格式化为
    %02x
    。若目录冲突则重新生成。任务删除后永不复用(冲突概率极低且易于检测)。
示例:
2026-04-26-task-journal-redesign-a3

Brief Immutability

任务摘要不可变性

brief.md
is frozen the moment the first journal entry is written.
  • Before the first entry: the brief may be overwritten freely (the "uncommitted brief" window).
  • After the first entry: do not edit
    brief.md
    . Record any goal drift, scope change, or refinement as a new journal entry, e.g.:
    markdown
    ## 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.md
    。将任何目标偏移、范围变更或细化内容记录为新的日志条目,例如:
    markdown
    ## 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
key: value
lines and an optional short body.
markdown
undefined
每个条目由二级Markdown标题、一行或多行
key: value
以及可选的简短正文组成。
markdown
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.
KeyMeaningTypical writer
saved
A persistent artifact was written or updated. Value names what was saved.
design-structure
,
writing-plans
,
executing-plans
decision
A bounded design decision was made. Value names the decision; body may carry rationale.
decision-evaluation
,
design-decision-audit
readiness
Readiness status of the design or plan. Value is
ready
or
not-ready
; body explains gaps.
design-readiness-check
blocker
A blocker was raised. Value is a short label; body describes what is blocked and why.any skill
done
The task reached its completion state. Value names the result (
merged
,
shipped
,
cancelled
, …).
finishing-a-development-branch
, user-initiated close
Other keys (
refined
,
note
,
handoff
,
link
, …) are free-form. The linter does not check them.

以下五个键为预留键且受linter检查。若符合其含义则使用——请勿创造同义词。
含义典型写入者
saved
持久化工件已写入或更新。值为保存的工件名称。
design-structure
,
writing-plans
,
executing-plans
decision
已做出明确的设计决策。值为决策名称;正文可包含理由。
decision-evaluation
,
design-decision-audit
readiness
设计或计划的就绪状态。值为
ready
not-ready
;正文说明差距。
design-readiness-check
blocker
已提出阻塞问题。值为简短标签;正文描述被阻塞的内容及原因。任意skill
done
任务已达到完成状态。值为结果名称(
merged
,
shipped
,
cancelled
, …)。
finishing-a-development-branch
, 用户发起的关闭操作
其他键(
refined
,
note
,
handoff
,
link
, …)为自由格式。linter不检查这些键。

Completion Semantics

完成语义

Only code tasks have a real notion of completion (Option 2 from the design):
  • Primary path:
    finishing-a-development-branch
    appends
    done: <result>
    after a successful merge/ship.
  • Fallback: the user states the task is done; the next skill (often
    task-brief
    ) appends the
    done:
    entry.
Non-code tasks never get a
done:
entry. Activity is judged by the timestamp of the last entry; the linter may flag long-stale tasks as a soft hint.
Do not migrate the directory when a task is done. The task stays under
.agents/tasks/<task-id>/
. The presence of a
done:
entry is the marker.
Reopen is just appending a new entry after a
done:
entry. The linter detects this pattern and emits a warning so the human notices it.

只有代码任务具备真正的完成概念(设计中的选项2):
  • 主路径
    finishing-a-development-branch
    在成功合并/发布后追加
    done: <result>
    条目。
  • ** fallback**:用户声明任务完成;下一个skill(通常是
    task-brief
    )追加
    done:
    条目。
非代码任务永远不会有
done:
条目。通过最后一个条目的时间戳判断活动状态;linter可能会将长期停滞的任务标记为软提示。
任务完成时请勿迁移目录。任务仍保留在
.agents/tasks/<task-id>/
下。
done:
条目的存在即为完成标记。
重新开启只需在
done:
条目后追加新条目即可。linter会检测到此模式并发出警告,以便人类注意到。

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.
TierSkillsBehavior
A — creates tasks
task-brief
(only on user confirmation)
Sole entry point that creates
.agents/tasks/<id>/
. Writes
brief.md
and the first journal entry (
task_created: …
).
B — appends on milestones
design-structure
,
design-refinement
,
design-decision-audit
,
decision-evaluation
,
design-readiness-check
,
writing-plans
,
executing-plans
,
subagent-driven-development
,
verification-before-completion
,
finishing-a-development-branch
Append entries at meaningful lifecycle moments (saved, decision, readiness, done).
C — appends conditionally
bug-investigation
,
systematic-debugging
,
requesting-code-review
Append only when a task id is in scope.
D — never appends
design-orchestrator
,
dispatching-parallel-agents
,
using-git-worktrees
,
test-driven-development
,
writing-clearly-and-concisely
,
receiving-code-review
Methodology / routing / meta layer. They do not own task state.

这是关于哪些skill应追加日志、哪些不应追加的约定。可交叉参考每个skill自身SKILL.md中的“日志集成”部分以获取确切的条目格式。
层级技能行为
A — 创建任务
task-brief
(仅在用户确认时)
唯一创建
.agents/tasks/<id>/
的入口。写入
brief.md
和首个日志条目(
task_created: …
)。
B — 里程碑时追加
design-structure
,
design-refinement
,
design-decision-audit
,
decision-evaluation
,
design-readiness-check
,
writing-plans
,
executing-plans
,
subagent-driven-development
,
verification-before-completion
,
finishing-a-development-branch
在重要生命周期节点(saved、decision、readiness、done)追加条目。
C — 条件性追加
bug-investigation
,
systematic-debugging
,
requesting-code-review
仅当任务ID在范围内时追加。
D — 永不追加
design-orchestrator
,
dispatching-parallel-agents
,
using-git-worktrees
,
test-driven-development
,
writing-clearly-and-concisely
,
receiving-code-review
方法论/路由/元层技能。它们不负责任务状态。

Task ID Propagation Between Skills

技能间的任务ID传递

Pick the first that applies:
  1. Explicit parameter — the caller (user or upstream skill) names the task id directly. Preferred.
  2. .current
    pointer
    — read
    <repo>/.agents/tasks/.current
    ; if it names an existing directory, treat that as the active task.
  3. 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.

按以下优先级选择:
  1. 显式参数 — 调用者(用户或上游skill)直接指定任务ID。优先选择。
  2. .current
    指针
    — 读取
    <repo>/.agents/tasks/.current
    ;若指向存在的目录,则将其视为活跃任务。
  3. 其他情况 — 请勿猜测。询问用户,或跳过本次日志追加操作。
请勿为此引入环境状态、环境变量、守护进程或文件锁。

Helper Script:
journal.py

辅助脚本:
journal.py

scripts/journal.py
is a thin Python helper for skills that prefer a function call over hand-writing markdown. It is optional — appending markdown directly is equally valid.
bash
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
resolves to wherever this skill is installed (
~/.claude/skills/task-journal
or the repo
skills/task-journal
). Both paths work.
The helper is stdlib-only, ~100 lines, and never blocks. It does not validate keys (that is the linter's job).

scripts/journal.py
是一个轻量Python辅助工具,供偏好函数调用而非手动编写Markdown的skill使用。它是可选的——直接追加Markdown同样有效。
bash
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
指向本skill的安装目录(
~/.claude/skills/task-journal
或仓库中的
skills/task-journal
)。两个路径均有效。
该辅助工具仅依赖标准库,约100行代码,且永远不会阻塞。它不验证键(这是linter的职责)。

Linter:
lint_tasks.py

检查工具:
lint_tasks.py

scripts/lint_tasks.py
walks
.agents/tasks/
and reports drift. Severity rules:
  • error — corrupt heading, missing
    key: value
    line, malformed reserved-key value, unparseable timestamp, missing
    brief.md
    . Returns exit code 1.
  • warn — body > 15 lines, entry written after a
    done:
    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.
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/tasks
Flags:
  • --tasks-dir <path>
    : required; path to the tasks root.
  • --strict
    : treat warnings as errors (exit 1 on any warning).
  • --task-id <id>
    : lint a single task instead of the whole tree.

scripts/lint_tasks.py
遍历
.agents/tasks/
并报告偏离约定的情况。严重程度规则:
  • 错误 — 标题损坏、缺少
    key: value
    行、预留键值格式错误、时间戳无法解析、缺少
    brief.md
    。返回退出码1。
  • 警告 — 正文超过15行、
    done:
    条目后写入新条目但无明确重新开启标记、任务超过30天无条目、未知skill名称(仅启发式判断)。若无错误则返回退出码0。
该检查工具永远不会阻塞LLM的实时写入。loom仓库的预推送钩子是否调用它是独立决策,不属于本约定的一部分。
bash
python3 ${SKILL_DIR}/scripts/lint_tasks.py --tasks-dir .agents/tasks
参数:
  • --tasks-dir <path>
    :必填;任务根目录路径。
  • --strict
    :将警告视为错误(任何警告均返回退出码1)。
  • --task-id <id>
    :仅检查单个任务而非整个目录树。

Anti-Patterns

反模式

These are the failure modes the design explicitly rejects. Avoid them.
  • Do not edit
    brief.md
    after the first journal entry.
    Record changes as a
    refined:
    entry.
  • Do not move task directories on completion. A
    done:
    entry is the marker.
  • 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
    ,
    blocker
    ,
    done
    fit, use them.
  • 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
docs/design-decisions/2026-04-26-task-journal-replaces-task-state-management.md
for the canonical list.
Failure scenarioSignalUpgrade direction
Concurrent writers from multiple agentsinterleaved or lost entries observedfile lock or single-writer protocol
Frequent cross-task index queries> 50 tasks and weekly "which tasks reference X?" needsindex file or SQLite
Single task with very long journal> 200 lines or reading feels slowrolling archive (
journal-2026-Q1.md
)
Frequent status grep queriessame grep ≥ 5×/weekstructured summary command
Real second-person collaborationa second human starts using itswitch to git-tracked + add an ownership field
Actual journal corruption≥ 1 corruption incident in practicebackup / checkpoint mechanism
Stable automated invocation needsrecurring CI/hook integration demandsthin CLI, one command at a time
Meta-gate. Any PR that proposes "add the state machine back" must:
  1. point to one of the seven scenarios above,
  2. cite the number of times the signal has fired, and
  3. limit the upgrade to a single failure scenario.
Otherwise the PR is rejected. This rule exists because the previous design (
task-state-management
) was built without observed failures.

本设计有意保持精简。以下每个失败场景都有明确的信号和升级方向。详见ADR文档
docs/design-decisions/2026-04-26-task-journal-replaces-task-state-management.md
中的完整列表。
失败场景信号升级方向
多agent并发写入观察到条目交错或丢失文件锁或单写入者协议
频繁跨任务索引查询任务数>50且每周需要多次“哪些任务引用了X?”查询索引文件或SQLite
单个任务日志过长超过200行或读取缓慢滚动归档(
journal-2026-Q1.md
频繁状态 grep 查询同一grep操作≥5次/周结构化摘要命令
真实的多人协作第二位人类开始使用切换为Git追踪 + 添加所有权字段
实际日志损坏实际发生≥1次损坏事件备份/检查点机制
稳定的自动化调用需求持续集成/钩子集成的重复需求轻量CLI,一次执行一个命令
元规则。任何提议“恢复状态机”的PR必须:
  1. 指向上述七个场景之一
  2. 引用信号触发的次数
  3. 将升级限制为单个失败场景
否则PR将被拒绝。此规则的存在是因为之前的设计(
task-state-management
)是在未观察到失败的情况下构建的。

Examples

示例

Tier B append (design-structure has just saved a design tree)

B层级追加(design-structure刚保存了设计树)

markdown
undefined
markdown
undefined

2026-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
undefined
saved: docs/design-tree/2026-04-26-task-journal-redesign.md expanded the core branches; pending refinement on linter contract
undefined

Tier C conditional append (systematic-debugging on a tracked task)

C层级条件性追加(systematic-debugging处理追踪中的任务)

markdown
undefined
markdown
undefined

2026-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
undefined
note: reproduced the lost-entry case under concurrent appends linked artifact: artifacts/concurrent-append-trace.md
undefined

Reserved decision key

预留decision键

markdown
undefined
markdown
undefined

2026-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
undefined
decision: stdlib-only helper, no third-party deps considered ruamel.yaml for richer parsing; rejected for footprint and YAGNI
undefined

Done marker (does not move directory)

完成标记(不移动目录)

markdown
undefined
markdown
undefined

2026-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
undefined
done: merged PR #142 merged into main; cleanup branch deleted
undefined