docs(todo): add the owning subsystem reference
This commit is contained in:
1 parent
b7dca9eb7e
commit
851eab756e
23 files changed
+102
-25
No files matched your search
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-20-todo-event-ownership.md
|
||||
2026-07-20-todo-event-ownership.md: 69ebba5c4cc5f58aa1dec7daa9e1dc22336ba36c
|
||||
2026-07-20-todo-event-ownership.zh.md: c22400a4f74749acdc748baf7cd8d582a39db7bf
|
||||
2026-07-20-todo-event-ownership.md: f3f7f872b24d8f20b6b9acb57710fae388c8b9d8
|
||||
2026-07-20-todo-event-ownership.zh.md: a05622dc39163c4f5b30a93190d9d56bb02cf29a
|
||||
@@ -14,7 +14,7 @@ English | [中文](2026-07-20-todo-event-ownership.zh.md)
|
||||
|
||||
Consumers that inspect todo records use type-only imports plus explicit package dependencies and TypeScript project references. The emitted JavaScript has no todo import, and a composition does not need to mount the todo tool merely to search, transmit, or render a log that may contain `todo/write`.
|
||||
|
||||
The todo invariant companion owns both the payload rules and the event's relationship to an open turn. Core session's merge-extensible switch falls through for `todo/write`, while the todo companion rejects malformed snapshots and snapshots outside an open turn before append, and validates the same rules when mounted over existing sessions. Todo-specific append, replay, projection, and enclosure tests live with the todo package. The model-facing behavior remains owned by the [`todo_write` feature decision](../feature/2026-06-29-todo-write-tool.md).
|
||||
The todo invariant companion owns both the payload rules and the event's relationship to an open turn. Core session's merge-extensible switch falls through for `todo/write`, while the todo companion rejects malformed snapshots and snapshots outside an open turn before append. It validates existing and newly announced sessions in one pass and advances a committed per-session turn trace for later events. Todo-specific append, replay, projection, and enclosure tests live with the todo package. The model-facing behavior remains owned by the [`todo_write` feature decision](../feature/2026-06-29-todo-write-tool.md).
|
||||
|
||||
## Verification
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ Status: implemented
|
||||
|
||||
检查 todo 记录的消费方使用仅类型导入,并声明显式包依赖与 TypeScript 项目引用。产出的 JavaScript 不含 todo 导入;组合仅为了搜索、传输或渲染可能含有 `todo/write` 的日志时,无需挂载 todo 工具。
|
||||
|
||||
todo 不变量配套插件同时拥有 payload 规则和事件必须位于开放轮次内的关系。核心会话的可合并扩展 switch 对 `todo/write` 走默认分支;todo 配套插件会在追加前拒绝格式错误或位于开放轮次之外的快照,并在挂载到现有会话时校验相同规则。todo 专属的追加、回放、投影和轮次封闭测试与 todo 包放在一起。面向模型的行为仍由 [`todo_write` 功能决策](../feature/2026-06-29-todo-write-tool.zh.md)负责。
|
||||
todo 不变量配套插件同时拥有 payload 规则和事件必须位于开放轮次内的关系。核心会话的可合并扩展 switch 对 `todo/write` 走默认分支;todo 配套插件会在追加前拒绝格式错误或位于开放轮次之外的快照。它会单次校验现有会话与新发布的会话,并为后续事件推进逐会话的已提交轮次追踪状态。todo 专属的追加、回放、投影和轮次封闭测试与 todo 包放在一起。面向模型的行为仍由 [`todo_write` 功能决策](../feature/2026-06-29-todo-write-tool.zh.md)负责。
|
||||
|
||||
## 验证
|
||||
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write docs/event-producer-consumer.md
|
||||
event-producer-consumer.md: 1470d1002062b8283c08e9989e9bedf71a09f316
|
||||
event-producer-consumer.zh.md: c801ea16ec322c4a949a9e35c8e103dfb7e383f2
|
||||
event-producer-consumer.md: c3d476fed6e4878e10a81858f918368c75bf7523
|
||||
event-producer-consumer.zh.md: 82a754094d9bc2daa1fe585d7da5cb33d67aa0a6
|
||||
@@ -40,9 +40,9 @@ This matrix shows which packages dispatch each harness-owned event and which pac
|
||||
| `llm/adapters-updated` | `emit` | [`packages/llm/llm/src/types.ts:23`](../packages/llm/llm/src/types.ts) | [`llm`](../packages/llm/llm) (`events.dispatch`) | [`acp`](../packages/acp/acp), `apiproxy`, [`llm`](../packages/llm/llm) |
|
||||
| `llm/stream` | `waterfall` | [`packages/llm/llm/src/index.ts:65`](../packages/llm/llm/src/index.ts) | [`llm`](../packages/llm/llm) (`waterfall`) | [`agent-loop`](../packages/core/agent-loop), [`llm`](../packages/llm/llm), [`llm-replay`](../packages/test-support/llm-replay), [`session-checkpoint-policy`](../packages/session/session-checkpoint-policy), [`session-title`](../packages/session/session-title) |
|
||||
| `session-telemetry/record` | `waterfall` | [`packages/session/session-telemetry/src/index.ts:43`](../packages/session/session-telemetry/src/index.ts) | [`session-telemetry`](../packages/session/session-telemetry) (`waterfall`) | - |
|
||||
| `session/created` | `emit` | [`packages/core/session/src/index.ts:54`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | `apiproxy`, [`compaction`](../packages/compaction/compaction), [`goal`](../packages/goal/goal), [`hook-protocol`](../packages/hooks/hook-protocol), [`llm-retry`](../packages/llm/llm-retry), [`permission-presets`](../packages/interaction/permission-presets), [`plan-mode`](../packages/plan/plan-mode), [`schedule`](../packages/schedule/schedule), `server`, [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-telemetry`](../packages/session/session-telemetry), [`time-context`](../packages/context/time-context), [`tool-workflow`](../packages/workflow/tool-workflow), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval) |
|
||||
| `session/created` | `emit` | [`packages/core/session/src/index.ts:54`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | `apiproxy`, [`compaction`](../packages/compaction/compaction), [`goal`](../packages/goal/goal), [`hook-protocol`](../packages/hooks/hook-protocol), [`llm-retry`](../packages/llm/llm-retry), [`permission-presets`](../packages/interaction/permission-presets), [`plan-mode`](../packages/plan/plan-mode), [`schedule`](../packages/schedule/schedule), `server`, [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-telemetry`](../packages/session/session-telemetry), [`time-context`](../packages/context/time-context), [`tool-todo`](../packages/todo/tool-todo), [`tool-workflow`](../packages/workflow/tool-workflow), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval) |
|
||||
| `session/disposed` | `emit` | [`packages/core/session/src/index.ts:64`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`agent-loop`](../packages/core/agent-loop), `agent-team`, `apiproxy`, [`session-persistence`](../packages/session/session-persistence), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-title`](../packages/session/session-title) |
|
||||
| `session/event` | `emit` | [`packages/core/session/src/index.ts:76`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`acp`](../packages/acp/acp), [`agent-instructions`](../packages/context/agent-instructions), [`agent-loop`](../packages/core/agent-loop), [`agent-presets`](../packages/preset/agent-presets), `agent-team`, `apiproxy`, [`compaction`](../packages/compaction/compaction), [`compaction-basic`](../packages/compaction/compaction-basic), [`file-reference-local`](../packages/context/file-reference-local), [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`hook-protocol`](../packages/hooks/hook-protocol), [`loader-smoke`](../packages/test-support/loader-smoke), `server`, [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-telemetry-otel`](../packages/session/session-telemetry-otel), [`session-title`](../packages/session/session-title), [`token-meter`](../packages/llm/token-meter), [`tool-workflow`](../packages/workflow/tool-workflow), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval) |
|
||||
| `session/event` | `emit` | [`packages/core/session/src/index.ts:76`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`acp`](../packages/acp/acp), [`agent-instructions`](../packages/context/agent-instructions), [`agent-loop`](../packages/core/agent-loop), [`agent-presets`](../packages/preset/agent-presets), `agent-team`, `apiproxy`, [`compaction`](../packages/compaction/compaction), [`compaction-basic`](../packages/compaction/compaction-basic), [`file-reference-local`](../packages/context/file-reference-local), [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`hook-protocol`](../packages/hooks/hook-protocol), [`loader-smoke`](../packages/test-support/loader-smoke), `server`, [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-telemetry-otel`](../packages/session/session-telemetry-otel), [`session-title`](../packages/session/session-title), [`token-meter`](../packages/llm/token-meter), [`tool-todo`](../packages/todo/tool-todo), [`tool-workflow`](../packages/workflow/tool-workflow), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval) |
|
||||
| `session/flush` | `parallel` | [`packages/core/session/src/index.ts:85`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`session-persistence`](../packages/session/session-persistence), [`session-telemetry`](../packages/session/session-telemetry) |
|
||||
| `settings/document-updated` | `emit` | [`packages/settings/settings/src/types.ts:48`](../packages/settings/settings/src/types.ts) | [`settings`](../packages/settings/settings) (`events.dispatch`) | `apiproxy` |
|
||||
| `settings/updated` | `emit` | [`packages/settings/settings/src/types.ts:35`](../packages/settings/settings/src/types.ts) | [`settings`](../packages/settings/settings) (`events.dispatch`) | [`settings`](../packages/settings/settings) |
|
||||
|
||||
@@ -42,9 +42,9 @@
|
||||
| `llm/adapters-updated` | `emit` | [`packages/llm/llm/src/types.ts:23`](../packages/llm/llm/src/types.ts) | [`llm`](../packages/llm/llm) (`events.dispatch`) | [`acp`](../packages/acp/acp), `apiproxy`, [`llm`](../packages/llm/llm) |
|
||||
| `llm/stream` | `waterfall` | [`packages/llm/llm/src/index.ts:65`](../packages/llm/llm/src/index.ts) | [`llm`](../packages/llm/llm) (`waterfall`) | [`agent-loop`](../packages/core/agent-loop), [`llm`](../packages/llm/llm), [`llm-replay`](../packages/test-support/llm-replay), [`session-checkpoint-policy`](../packages/session/session-checkpoint-policy), [`session-title`](../packages/session/session-title) |
|
||||
| `session-telemetry/record` | `waterfall` | [`packages/session/session-telemetry/src/index.ts:43`](../packages/session/session-telemetry/src/index.ts) | [`session-telemetry`](../packages/session/session-telemetry) (`waterfall`) | - |
|
||||
| `session/created` | `emit` | [`packages/core/session/src/index.ts:54`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | `apiproxy`, [`compaction`](../packages/compaction/compaction), [`goal`](../packages/goal/goal), [`hook-protocol`](../packages/hooks/hook-protocol), [`llm-retry`](../packages/llm/llm-retry), [`permission-presets`](../packages/interaction/permission-presets), [`plan-mode`](../packages/plan/plan-mode), [`schedule`](../packages/schedule/schedule), `server`, [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-telemetry`](../packages/session/session-telemetry), [`time-context`](../packages/context/time-context), [`tool-workflow`](../packages/workflow/tool-workflow), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval) |
|
||||
| `session/created` | `emit` | [`packages/core/session/src/index.ts:54`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | `apiproxy`, [`compaction`](../packages/compaction/compaction), [`goal`](../packages/goal/goal), [`hook-protocol`](../packages/hooks/hook-protocol), [`llm-retry`](../packages/llm/llm-retry), [`permission-presets`](../packages/interaction/permission-presets), [`plan-mode`](../packages/plan/plan-mode), [`schedule`](../packages/schedule/schedule), `server`, [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-telemetry`](../packages/session/session-telemetry), [`time-context`](../packages/context/time-context), [`tool-todo`](../packages/todo/tool-todo), [`tool-workflow`](../packages/workflow/tool-workflow), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval) |
|
||||
| `session/disposed` | `emit` | [`packages/core/session/src/index.ts:64`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`agent-loop`](../packages/core/agent-loop), `agent-team`, `apiproxy`, [`session-persistence`](../packages/session/session-persistence), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-title`](../packages/session/session-title) |
|
||||
| `session/event` | `emit` | [`packages/core/session/src/index.ts:76`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`acp`](../packages/acp/acp), [`agent-instructions`](../packages/context/agent-instructions), [`agent-loop`](../packages/core/agent-loop), [`agent-presets`](../packages/preset/agent-presets), `agent-team`, `apiproxy`, [`compaction`](../packages/compaction/compaction), [`compaction-basic`](../packages/compaction/compaction-basic), [`file-reference-local`](../packages/context/file-reference-local), [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`hook-protocol`](../packages/hooks/hook-protocol), [`loader-smoke`](../packages/test-support/loader-smoke), `server`, [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-telemetry-otel`](../packages/session/session-telemetry-otel), [`session-title`](../packages/session/session-title), [`token-meter`](../packages/llm/token-meter), [`tool-workflow`](../packages/workflow/tool-workflow), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval) |
|
||||
| `session/event` | `emit` | [`packages/core/session/src/index.ts:76`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`acp`](../packages/acp/acp), [`agent-instructions`](../packages/context/agent-instructions), [`agent-loop`](../packages/core/agent-loop), [`agent-presets`](../packages/preset/agent-presets), `agent-team`, `apiproxy`, [`compaction`](../packages/compaction/compaction), [`compaction-basic`](../packages/compaction/compaction-basic), [`file-reference-local`](../packages/context/file-reference-local), [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`hook-protocol`](../packages/hooks/hook-protocol), [`loader-smoke`](../packages/test-support/loader-smoke), `server`, [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-telemetry-otel`](../packages/session/session-telemetry-otel), [`session-title`](../packages/session/session-title), [`token-meter`](../packages/llm/token-meter), [`tool-todo`](../packages/todo/tool-todo), [`tool-workflow`](../packages/workflow/tool-workflow), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval) |
|
||||
| `session/flush` | `parallel` | [`packages/core/session/src/index.ts:85`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`session-persistence`](../packages/session/session-persistence), [`session-telemetry`](../packages/session/session-telemetry) |
|
||||
| `settings/document-updated` | `emit` | [`packages/settings/settings/src/types.ts:48`](../packages/settings/settings/src/types.ts) | [`settings`](../packages/settings/settings) (`events.dispatch`) | `apiproxy` |
|
||||
| `settings/updated` | `emit` | [`packages/settings/settings/src/types.ts:35`](../packages/settings/settings/src/types.ts) | [`settings`](../packages/settings/settings) (`events.dispatch`) | [`settings`](../packages/settings/settings) |
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write docs/persistence-catalog.md
|
||||
persistence-catalog.md: 0240b368b874162e0b4eef51765a09e706297c98
|
||||
persistence-catalog.zh.md: 76215360c014433b5818091c9df078ca7b7e2df1
|
||||
persistence-catalog.md: b505bc4ce1c71198ffc316a4f06d3c00174f3fb7
|
||||
persistence-catalog.zh.md: 715ae6515f8e7c6df936229becc41d492425b1ef
|
||||
@@ -780,7 +780,7 @@ Source: [`packages/experimental/agent-team/src/types.ts:208`](../packages/experi
|
||||
'todo/write': { todos: TodoItem[] }
|
||||
```
|
||||
|
||||
Types: [TodoItem](../packages/todo/tool-todo/README.md)
|
||||
Types: [TodoItem](subsystems/todo.md)
|
||||
|
||||
Source: [`packages/todo/tool-todo/src/types.ts:31`](../packages/todo/tool-todo/src/types.ts)
|
||||
|
||||
|
||||
@@ -782,7 +782,7 @@ export type SessionEvent<T extends SessionEventType = SessionEventType> = {
|
||||
'todo/write': { todos: TodoItem[] }
|
||||
```
|
||||
|
||||
类型:[TodoItem](../packages/todo/tool-todo/README.zh.md)
|
||||
类型:[TodoItem](subsystems/todo.zh.md)
|
||||
|
||||
来源:[`packages/todo/tool-todo/src/types.ts:31`](../packages/todo/tool-todo/src/types.ts)
|
||||
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write docs/subsystems/README.md
|
||||
README.md: d926abac718ba14b0d50f27d7c00b421c8460352
|
||||
README.zh.md: 911d39a4ecb6c278b7bae2d28b493821435c3833
|
||||
README.md: a1316e79f1847aafe7779c5fe9e3da698c14dc99
|
||||
README.zh.md: fbe512cbf516d38f824ddeb01e3fae9eff92bcd3
|
||||
@@ -13,6 +13,7 @@ One page per subsystem of the DeepSeek Harness: what it is, the data structures
|
||||
| [typert.md](typert.md) | Remote invocation descriptors, lookup/Context declarations, Typert registries, and the Host Gateway/Client API boundaries |
|
||||
| [goal.md](goal.md) | persisted goal identity, lifecycle snapshots, activation, change records, and round attribution |
|
||||
| [schedule.md](schedule.md) | Session-local reminder records, durable transitions, active views, and ordinary-conversation delivery |
|
||||
| [todo.md](todo.md) | the todo package's whole-list item type, durable event ownership, projection, and open-turn invariant |
|
||||
| [commands.md](commands.md) | the human-command registry service: definitions, adapter discovery, direct invocation, results, and parsing views |
|
||||
| [session.md](session.md) | the full `SessionEventMap` variant catalog, `TurnTrigger`/`TurnEndReason`, `deriveMessages()`, execution enclosure, and standalone events |
|
||||
| [persistence.md](persistence.md) | the durability seam: `SessionPersistence`, JSONL + SQLite backends, `session/flush`, crash recovery, `SessionHeader` |
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
| [typert.md](typert.zh.md) | 远程调用描述符、lookup/Context 声明、Typert 注册表,以及 Host Gateway/Client API 边界 |
|
||||
| [goal.md](goal.zh.md) | 持久 goal 标识、生命周期快照、激活、变更记录与 Round 归属 |
|
||||
| [schedule.md](schedule.zh.md) | 仅限 Session 内的提醒记录、持久转换、活动视图与普通对话交付 |
|
||||
| [todo.md](todo.zh.md) | todo 包的整列表条目类型、持久事件所有权、投影和开放轮次不变量 |
|
||||
| [commands.md](commands.zh.md) | 人类命令注册表服务:定义、适配器发现、直接调用、结果与解析视图 |
|
||||
| [session.md](session.zh.md) | 完整的 `SessionEventMap` 变体目录、`TurnTrigger`/`TurnEndReason`、`deriveMessages()`、执行封闭与独立事件 |
|
||||
| [persistence.md](persistence.zh.md) | 持久性 seam:`SessionPersistence`、JSONL + SQLite 后端、`session/flush`、崩溃恢复、`SessionHeader` |
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write docs/subsystems/todo.md
|
||||
todo.md: 70eca60ff484572b6c1a62737816504830623726
|
||||
todo.zh.md: 74f76f59b6cd132bb1c3722c7fef7f554554b242
|
||||
@@ -0,0 +1,32 @@
|
||||
# Todo
|
||||
|
||||
English | [中文](todo.zh.md)
|
||||
|
||||
The durable todo vocabulary owned by [`@deepseek-ai/dsh-tool-todo`](../../packages/todo/tool-todo/README.md). The model-facing tool replaces one agent session's whole list; the package also owns the event declaration, replay projection, and invariant companion. Tool behavior and configuration are on the [package README](../../packages/todo/tool-todo/README.md).
|
||||
|
||||
Source: [`packages/todo/tool-todo/src/types.ts`](../../packages/todo/tool-todo/src/types.ts)
|
||||
|
||||
## `TodoItem` — one list entry
|
||||
|
||||
```ts type-equiv
|
||||
/**
|
||||
* One entry in an agent's todo list — the unit of the `todo/write`
|
||||
* whole-list snapshot declared by this package.
|
||||
*
|
||||
* Deliberately minimal: a human-readable `content` line and a three-state
|
||||
* `status`. No id, priority, or `activeForm` — the list is replaced wholesale
|
||||
* on every write (last-write-wins), so entries need no stable identity. The
|
||||
* three statuses describe the complete portable lifecycle needed by model and
|
||||
* UI consumers.
|
||||
*/
|
||||
interface TodoItem {
|
||||
/** What this task is — a short imperative line shown in the UI. */
|
||||
content: string
|
||||
/** Lifecycle state. `in_progress` marks a task being worked now; parallel work may mark several. */
|
||||
status: 'pending' | 'in_progress' | 'completed'
|
||||
}
|
||||
```
|
||||
|
||||
## Durable event and invariant
|
||||
|
||||
The package declaration-merges `todo/write: { todos: TodoItem[] }` into `SessionEventMap`. The event is log-only and carries the complete replacement list; the generated [persistence catalog](../persistence-catalog.md#todowrite--log-only) records its declaration site. The package's invariant companion validates existing and newly announced sessions in one pass, then tracks committed turn boundaries incrementally so every live `todo/write` is checked before append without rescanning the log.
|
||||
@@ -0,0 +1,32 @@
|
||||
# Todo
|
||||
|
||||
[English](todo.md) | 中文
|
||||
|
||||
本页记录 [`@deepseek-ai/dsh-tool-todo`](../../packages/todo/tool-todo/README.zh.md) 拥有的持久 todo 词汇。面向模型的工具会整体替换一个 agent(智能体)会话的列表;该包还拥有事件声明、回放投影和不变量配套插件。工具行为与配置见[包 README](../../packages/todo/tool-todo/README.zh.md)。
|
||||
|
||||
源码:[`packages/todo/tool-todo/src/types.ts`](../../packages/todo/tool-todo/src/types.ts)
|
||||
|
||||
## `TodoItem`:一条列表项
|
||||
|
||||
```ts type-equiv
|
||||
/**
|
||||
* One entry in an agent's todo list — the unit of the `todo/write`
|
||||
* whole-list snapshot declared by this package.
|
||||
*
|
||||
* Deliberately minimal: a human-readable `content` line and a three-state
|
||||
* `status`. No id, priority, or `activeForm` — the list is replaced wholesale
|
||||
* on every write (last-write-wins), so entries need no stable identity. The
|
||||
* three statuses describe the complete portable lifecycle needed by model and
|
||||
* UI consumers.
|
||||
*/
|
||||
interface TodoItem {
|
||||
/** What this task is — a short imperative line shown in the UI. */
|
||||
content: string
|
||||
/** Lifecycle state. `in_progress` marks a task being worked now; parallel work may mark several. */
|
||||
status: 'pending' | 'in_progress' | 'completed'
|
||||
}
|
||||
```
|
||||
|
||||
## 持久事件与不变量
|
||||
|
||||
该包通过声明合并把 `todo/write: { todos: TodoItem[] }` 加入 `SessionEventMap`。此事件仅写入日志,并携带完整替换列表;生成的[持久化目录](../persistence-catalog.zh.md#todowrite--log-only)会记录其声明位置。该包的不变量配套插件会单次遍历校验现有会话和新发布的会话,随后增量追踪已提交的轮次边界,使每个实时 `todo/write` 都能在追加前得到校验,而无需重新扫描日志。
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/todo/README.md
|
||||
README.md: 6bbc9fe4f04cc4a82573c643c5c00bbecde069ed
|
||||
README.zh.md: fa2bd8a6cde5c322151b37b066f0d718c52dfcd0
|
||||
README.md: 85499ac2382ec0f220a7fafda0acbbed369f9ca2
|
||||
README.zh.md: 9056208e82d4abc1db51bcae21205f4e5afd8bf9
|
||||
@@ -10,4 +10,4 @@ The model-facing todo capability. It is a single **product** package because one
|
||||
|
||||
The child README owns the tool, persistence, and rendering contract.
|
||||
|
||||
The event payload is documented on [docs/subsystems/session.md](../../docs/subsystems/session.md).
|
||||
The event payload is documented on [docs/subsystems/todo.md](../../docs/subsystems/todo.md).
|
||||
@@ -10,4 +10,4 @@
|
||||
|
||||
子级 README 负责工具、持久化和渲染约定。
|
||||
|
||||
事件载荷记录在 [docs/subsystems/session.md](../../docs/subsystems/session.zh.md)。
|
||||
事件载荷记录在 [docs/subsystems/todo.md](../../docs/subsystems/todo.zh.md)。
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/todo/tool-todo/README.md
|
||||
README.md: 7e236348432a5e428392d97fd74ec91cf1752de7
|
||||
README.zh.md: 60f799030cfe58a3c015cb9ebb1012808b28e9f4
|
||||
README.md: 498b817c3eacd1e56c6b1b72b4fb863018c2207b
|
||||
README.zh.md: 6c77e3c78e858d270a7764bfd82df2212cb31a69
|
||||
@@ -24,7 +24,7 @@ The flag moves the model-facing instruction and the accepted input together —
|
||||
|
||||
Beyond the schema's type/required/enum checks, `execute` rejects an empty or duplicate `content`, and any item key beyond `content`/`status` — an extended item shape (ids, nesting) fails loud instead of silently flattening, keeping the logged snapshot equal to what the model believes it wrote. How many tasks may be `in_progress` at once is the deployment's call (§ Configuration): a composition that chooses `true` permits parallel work (concurrent subagents, background commands) to mark several tasks simultaneously. Ordering and the discipline of keeping the list current are left to the model via the tool description.
|
||||
|
||||
This package's invariant companion validates every durable `todo/write` payload and requires the event to occur inside an open turn, both for live appends and for existing logs inspected at plugin load. Core session treats declaration-merged events generically; the producing package owns these todo-specific rules ([event ownership](../../../.agents/notes/implemented/architecture/2026-07-20-todo-event-ownership.md)).
|
||||
This package's invariant companion validates every durable `todo/write` payload and requires the event to occur inside an open turn. It validates existing and newly announced sessions once, then advances a committed per-session turn trace for live appends. Core session treats declaration-merged events generically; the producing package owns these todo-specific rules ([event ownership](../../../.agents/notes/implemented/architecture/2026-07-20-todo-event-ownership.md)).
|
||||
|
||||
## Rendering
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
除 schema 的类型/必填/枚举检查外,`execute` 还会拒绝空或重复的 `content`,以及 `content`/`status` 之外的任何条目键——扩展条目形状(id、嵌套)会明确报错而不是被静默压平,保证落日志的快照与模型自认为写入的内容一致。同时可以有多少任务处于 `in_progress` 由部署决定(见 § 配置):选择 `true` 的组合允许并行工作(并发 subagent、后台命令)同时将多个任务标记为 `in_progress`。列表的顺序及及时更新由模型依照工具描述负责。
|
||||
|
||||
本包的不变量配套插件会校验每个持久 `todo/write` payload,并要求事件位于开放轮次内;这些规则同时适用于实时追加和插件加载时检查的现有日志。核心会话只会通用处理声明合并事件,todo 专属规则由生产该事件的包负责(见[事件所有权](../../../.agents/notes/implemented/architecture/2026-07-20-todo-event-ownership.zh.md))。
|
||||
本包的不变量配套插件会校验每个持久 `todo/write` payload,并要求事件位于开放轮次内。它会各自单次校验现有会话与新发布的会话,随后为实时追加推进逐会话的已提交轮次追踪状态。核心会话只会通用处理声明合并事件,todo 专属规则由生产该事件的包负责(见[事件所有权](../../../.agents/notes/implemented/architecture/2026-07-20-todo-event-ownership.zh.md))。
|
||||
|
||||
## 渲染
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ const LINK_MAP: Record<string, string> = {
|
||||
ScheduleChange: 'subsystems/schedule.md',
|
||||
StreamChunk: 'subsystems/llm-streaming.md',
|
||||
TokenUsage: 'subsystems/llm-streaming.md',
|
||||
TodoItem: '../packages/todo/tool-todo/README.md',
|
||||
TodoItem: 'subsystems/todo.md',
|
||||
TurnTrigger: 'subsystems/session.md',
|
||||
TurnEndReason: 'subsystems/session.md',
|
||||
SessionTitleEventData: 'subsystems/session-title.md',
|
||||
|
||||
@@ -448,6 +448,11 @@
|
||||
"symbol": "RequestContext",
|
||||
"source": "packages/core/session/src/types.ts"
|
||||
},
|
||||
{
|
||||
"doc": "docs/subsystems/todo.md",
|
||||
"symbol": "TodoItem",
|
||||
"source": "packages/todo/tool-todo/src/types.ts"
|
||||
},
|
||||
{
|
||||
"doc": "docs/subsystems/session.md",
|
||||
"symbol": "SessionEvent",
|
||||
|
||||
Reference in new issue
Block a user