docs: update roadmap

This commit is contained in:
Microindole 2026-05-08 21:26:30 +08:00
parent e3782144b8
commit dbbae27de7
No known key found for this signature in database
GPG Key ID: 22FB34CD2133ACA1
13 changed files with 540 additions and 159 deletions

View File

@ -7,12 +7,18 @@
建议内容:
- `session-notes/`:实现日志和阶段结论。
- `tasks/`:适合 agent 执行的边界清晰任务。
- `tasks/`:适合 agent 执行的边界清晰任务,按路线阶段拆分
- `prompts/`:可复用提示词和约束。
- `checklists/`:启动、验证、回归检查单。
正式架构决策仍然放在 `docs/`,然后在 agent 任务文档里引用它们。
当前任务入口:
- `tasks/README.md`agent 任务索引。
- `tasks/01-early-debug.md`:下一阶段,早期串口和 panic。
- `../roadmap.md`:总路线和阶段依赖。
当 agent 修改代码且影响下列内容时,应该同步更新这里或 `docs/`
- 架构边界

View File

@ -0,0 +1,39 @@
# 01 早期调试输出
## 目标
建立 firmware 之外的稳定日志能力,作为后续 CPU、内存、调度和驱动开发的基础。
## 前置条件
- bootloader 已能进入 kernel。
- kernel 已在 `ExitBootServices` 后运行。
- 当前已有 QEMU debug port 输出。
## 建议边界
- `arch/x86/`COM1、I/O port、架构相关 early log backend。
- `kernel/`:通用 early log 前端和 panic/oops 入口。
- `scripts/`QEMU 串口参数和日志验证。
## 实现内容
- 初始化 COM1。
- 增加串口输出 backend。
- 保留 QEMU debug port backend。
- 统一 `early_log_puts()` 一类前端接口。
- 增加最小 `panic()`panic 后停止 CPU。
- 为后续 printk、oops、内核符号和 crash dump 预留接口边界。
## 非玩具化约束
- 日志前端不能直接绑定 COM1。
- COM1 端口号要集中定义,不能散落在业务代码。
- panic 路径不能依赖动态内存。
- 输出接口要允许后续接 framebuffer console。
## 验收方式
- QEMU 日志中能看到 bootloader 和 kernel 输出。
- 串口或 debug log 中能看到 `boot services exited`
- 人为触发 panic 时能看到 panic 信息并停止。

View File

@ -0,0 +1,41 @@
# 02 CPU、异常与中断
## 目标
建立 x86_64 CPU 基础设施,让 kernel 能捕获异常并接入后续硬件中断。
## 前置条件
- early log 可在 firmware 退出后稳定输出。
- panic 路径可用。
## 建议边界
- `arch/x86/`GDT、TSS、IDT、异常入口、IRQ 入口。
- `kernel/`:通用 trap 分发、panic 策略、调试输出。
- `include/tianole/`:必要的通用 trap 数据结构。
## 实现内容
- 建立 x86_64 GDT。
- 建立最小 TSS。
- 建立 IDT。
- 增加异常入口汇编。
- 保存寄存器到统一 trap frame。
- C 层分发 exception。
- 之后再接 PIC/APIC 和 IRQ。
- 异常路径输出异常栈、寄存器现场和符号化所需信息。
## 非玩具化约束
- 汇编入口只保存现场和跳转,不写策略。
- C handler 接收统一 trap frame。
- exception 和 IRQ 的入口可共享框架,但语义要区分。
- 不把中断处理写进 `kernel/main.c`
- oops/panic 策略要和 trap 分发分离。
## 验收方式
- 主动触发 invalid opcode 或 divide error。
- 日志输出 vector、rip、rsp、error code。
- 未处理异常进入 panic。

View File

@ -0,0 +1,44 @@
# 03 内存管理
## 目标
从 boot memory map 建立 kernel 自己的内存模型,提供物理页、虚拟地址和内核堆能力。
## 前置条件
- 异常处理可用,尤其是 page fault 路径。
- early log 和 panic 可用。
## 建议边界
- `kernel/mm/`:架构无关内存管理。
- `arch/x86/mm/`页表格式、地址空间切换、TLB 操作。
- `include/tianole/`:通用内存接口。
## 实现内容
- 解析 boot memory map。
- 归一化可用/保留/固件/内核占用区域。
- 建立物理页分配器。
- 建立内核虚拟地址布局。
- 建立页表 map/unmap 接口。
- 建立最小内核堆。
- 为后续匿名页、缺页加载、COW、`mmap`、page cache、换页预留接口。
## 非玩具化约束
- 不写死物理内存大小。
- 不把 UEFI memory type 作为长期内核内存类型。
- allocator 接口要允许后续替换为 buddy/slab。
- 小对象分配要允许后续演进到 slab/slub 或等价缓存分配器。
- 地址空间布局要文档化。
- 用户地址空间和内核地址空间的边界不能依赖调用方自觉遵守。
- 不能把 page cache 和匿名页排除在长期模型之外。
## 验收方式
- 能分配和释放多个物理页。
- 能建立和删除虚拟映射。
- page fault 能输出有效诊断。
- 内核堆能分配小对象。
- 后续能在此基础上加入 COW、`mmap`、换页和内存回收。

View File

@ -0,0 +1,43 @@
# 04 时钟、内核线程与调度
## 目标
建立 kernel 内部并发执行能力,为驱动等待、异步 I/O、进程和用户态做准备。
## 前置条件
- 中断入口可用。
- 内存分配可用。
- 至少一个 timer 可接入。
## 建议边界
- `kernel/sched/`:线程、调度器、等待队列。
- `kernel/time/`:通用时间与 timer 抽象。
- `arch/x86/`:具体 timer、上下文切换。
## 实现内容
- 建立 kernel thread。
- 建立上下文切换。
- 建立 run queue。
- 建立 sleep/wakeup。
- 建立基础 spinlock 或 interrupt-safe lock。
- 接入 timer tick 或 one-shot timer。
- 为 workqueue、deferred work、completion、引用计数生命周期管理预留位置。
## 非玩具化约束
- 调度器不能直接绑定某一种硬件 timer。
- 线程数量不能固定写死。
- 等待队列要能被驱动、文件系统和进程等待复用。
- 日志只能辅助观察,不能成为调度逻辑的一部分。
- 内核对象不能依赖“永不释放”的假设。
- 任何可睡眠路径和不可睡眠路径要从接口上区分。
## 验收方式
- 两个以上 kernel thread 能轮转。
- 线程可以 sleep 并被 timer 唤醒。
- 调度现场保存和恢复稳定。
- 基础对象生命周期规则有文档和调用约束。

View File

@ -0,0 +1,39 @@
# 05 输入事件与键盘
## 目标
建立输入事件模型,让键盘成为输入设备的一种,而不是直接绑定 shell 的特殊逻辑。
## 前置条件
- 中断可用。
- 等待队列或事件队列可用。
- early log 可用于调试。
## 建议边界
- `drivers/input/`:通用输入事件。
- `drivers/input/keyboard/`:键盘设备。
- `arch/x86/`PS/2 控制器相关 I/O。
## 实现内容
- 接入 PS/2 keyboard。
- 解码 scancode。
- 生成标准 key event。
- 建立输入事件队列。
- 为终端输入提供读取接口。
## 非玩具化约束
- 键盘驱动只产生事件,不直接操作 shell。
- 键盘布局要可替换。
- 输入队列接口要允许未来接 USB HID。
- 中断 handler 中不要做复杂处理。
## 验收方式
- 按键触发中断。
- kernel 能读取 key event。
- 后续 shell 可复用同一输入接口。

View File

@ -0,0 +1,44 @@
# 06 存储、缓存与 VFS
## 目标
建立文件访问路径:块设备或 initramfs 提供数据VFS 提供统一文件接口。
## 前置条件
- 内存管理可用。
- 锁和等待机制可用。
- 用户态之前可以先由 kernel 测试 VFS。
## 建议边界
- `drivers/block/`:块设备抽象和具体设备。
- `kernel/fs/`VFS。
- `kernel/mm/`:页缓存或块缓存。
- `fs/`:具体文件系统实现。
## 实现内容
- 建立 block device 接口。
- 初期支持 initramfs/ramdisk。
- 建立 inode、dentry、file 等 VFS 对象。
- 建立路径解析。
- 支持 open/read/close/readdir。
- 后续再加入 write 和持久化文件系统。
- 为 page cache、block cache、writeback 和崩溃一致性预留边界。
## 非玩具化约束
- VFS 不依赖某个具体文件系统。
- 文件系统不直接依赖 shell 或进程加载器。
- 路径解析和引用计数要从一开始有边界。
- 缓存层不能和具体磁盘驱动耦合。
- VFS 对象生命周期必须明确,不能靠全局静态对象规避释放问题。
- 文件权限、时间戳、inode 编号等 POSIX 语义要保留位置。
## 验收方式
- kernel 可通过 VFS 打开并读取文件。
- 可列出目录。
- 替换具体 FS 不影响 VFS 调用方。
- 后续能加入可写缓存和 writeback而不重写 VFS 调用层。

View File

@ -0,0 +1,46 @@
# 07 用户态、系统调用与进程
## 目标
让 Tianole 从只运行 kernel 代码,进入可运行用户程序的阶段。
## 前置条件
- 虚拟内存可用。
- VFS 可读取 ELF 文件或 init 程序。
- 异常和 syscall 入口可用。
## 建议边界
- `kernel/syscall/`:系统调用入口和分发。
- `kernel/process/`:进程、线程、地址空间。
- `kernel/elf/`:用户 ELF 加载。
- `arch/x86/`ring 3 切换和 syscall 指令支持。
## 实现内容
- 建立用户地址空间。
- 建立 syscall ABI。
- 建立用户指针检查。
- 加载用户 ELF。
- 支持进程退出和等待。
- 早期可先实现 `spawn/exit/wait`,再演进到 `fork/exec`
- 为 POSIX syscall、`fcntl/stat/chmod`、signal、pipe、socket、eventfd、futex、共享内存、poll/select 和 IPC 预留 ABI 边界。
- 为 uid/gid、用户/组、文件权限、进程权限、capability 或等价隔离模型预留进程凭据结构。
## 非玩具化约束
- syscall 表要稳定记录。
- 用户指针不能直接信任。
- 进程、线程、地址空间结构不要混成一个对象。
- 用户态崩溃不能直接拖垮 kernel。
- syscall 不能只按当前 demo 程序硬编码。
- 进程资源释放必须有明确所有权和引用计数规则。
- `fork/exec/wait`、signal、pipe、poll/select 是运行复杂 Unix 程序的关键路径,不能被路线遗漏。
## 验收方式
- 最小用户程序可以输出并退出。
- kernel 能回收用户进程资源。
- 非法用户访问能进入异常处理并终止进程。
- syscall ABI 文档化,后续可以被 libc 绑定。

View File

@ -0,0 +1,45 @@
# 08 init、shell 与工具
## 目标
建立可交互系统入口并用用户态工具验证进程、VFS、输入和输出路径。
## 前置条件
- 用户态可运行程序。
- VFS 可读目录和文件。
- 输入事件和终端输出可用。
## 建议边界
- `user/init/`:第一个用户态进程。
- `user/shell/`shell。
- `user/bin/`:基础命令。
- `lib/``user/lib/`:最小 libc。
## 实现内容
- 启动第一个 `init`
- 启动 shell。
- 实现 `echo`、`pwd`、`ls`、`cat` 等基础命令。
- 增加查看 kernel 状态的调试接口。
- 规划最小 libc、errno、环境变量、时间接口、路径接口和 `stat/chmod` 类文件接口。
- 为 tty、session、job control 留出后续位置。
- 为 procfs/sysfs/debugfs、ftrace、perf、crash dump 类可观测接口预留路径。
## 非玩具化约束
- shell 必须运行在用户态。
- shell 不能直接调用 kernel 内部函数。
- 调试信息通过 syscall 或虚拟文件接口暴露。
- 工具能力应服务于后续 git 移植。
- shell 不是内核调试器,不能用 shell 规避系统调用和 VFS 的缺失。
- `git` 目标至少需要可用 libc、文件状态、权限、时间、路径、进程等待等接口。
## 验收方式
- 启动后进入 shell。
- shell 能读取键盘输入。
- shell 能执行至少两个外部命令。
- 命令可访问 VFS。
- 基础用户空间接口能支撑后续移植更复杂工具。

View File

@ -0,0 +1,52 @@
# 09 驱动扩展
## 目标
在基础内核可用后扩展真实设备支持,逐步从 QEMU 环境走向真机。
## 前置条件
- 中断、内存、调度和锁可用。
- 基础输入、输出、存储路径可用。
## 建议边界
- `drivers/`:通用驱动。
- `drivers/pci/`PCI。
- `drivers/acpi/`ACPI。
- `drivers/gpu/``drivers/video/`:显示。
- `drivers/net/`:网络。
- `drivers/sound/`:音频。
## 实现内容
- 建立 bus/device/driver/resource 模型。
- PCI 枚举。
- ACPI 表解析。
- Device Tree 作为非 ACPI 平台的后续入口。
- IRQ routing。
- CPU topology。
- NUMA 拓扑。
- 电源管理。
- 热插拔。
- APIC/HPET 等平台设备。
- virtio、AHCI 或 NVMe 存储。
- framebuffer console。
- 后续再做网络和音频。
- 规划 socket API 和网络栈接入点,但本地 git 阶段不要求网络。
## 非玩具化约束
- 设备发现、驱动 probe、资源分配要分层。
- MMIO、PIO、IRQ、DMA 访问要有统一接口。
- 音频不是早期目标,不应阻塞内核主线能力。
- 新驱动不能要求修改 shell、VFS、调度器等无关层。
- 硬件发现、资源分配和驱动绑定必须从设备模型进入,不能由单个驱动私自扫描全部硬件。
- ACPI/PCI/Device Tree 类平台信息要隔离在平台层,不能泄漏到通用子系统。
## 验收方式
- 至少一种总线可以枚举设备。
- 至少一种块设备可接入 VFS。
- 新驱动加入时只影响对应驱动和通用驱动框架。
- 后续可接入网络、USB、音频而不重写已有核心子系统。

View File

@ -0,0 +1,38 @@
# 10 真机启动
## 目标
在不破坏现有系统启动链的前提下,让 Tianole 在真实 UEFI x86_64 机器上启动。
## 前置条件
- QEMU + OVMF 启动稳定。
- 串口、屏幕或其他早期输出路径可用。
- 内存 map、ExitBootServices、异常处理稳定。
## 建议边界
- `docs/host-machine.md`:本机硬件和启动记录。
- `scripts/`:制作 U 盘镜像和验证脚本。
- `arch/x86/`UEFI 与平台差异处理。
## 实现内容
- 制作 UEFI FAT 启动盘。
- 记录 OVMF 与真机 UEFI 差异。
- 验证 Secure Boot、启动项、磁盘枚举等风险。
- 先从 U 盘启动,再考虑本机启动项。
## 非玩具化约束
- 早期不修改本机现有启动链。
- 真机相关信息只放在 `docs/host-machine.md`
- 真机失败必须能通过日志定位到阶段。
- 不能把某台机器的硬件假设写进通用代码。
## 验收方式
- U 盘可进入 Tianole bootloader。
- kernel 能启动并输出阶段日志。
- 失败时能判断停在 bootloader、ExitBootServices、kernel entry 还是异常路径。

View File

@ -0,0 +1,57 @@
# Agent 任务索引
这个目录保存适合 agent 分阶段执行的任务说明。每个任务文档都应该说明:
- 目标
- 前置条件
- 建议目录边界
- 非玩具化约束
- 验收方式
当前推荐顺序:
1. `01-early-debug.md`串口、panic、早期日志。
2. `02-cpu-interrupts.md`CPU 基础、GDT、IDT、异常、中断入口。
3. `03-memory.md`:物理页分配、虚拟内存、内核堆。
4. `04-time-scheduler.md`:时钟、内核线程、调度与等待。
5. `05-input-events.md`:键盘输入、事件队列、终端输入模型。
6. `06-storage-vfs.md`块设备、页缓存、VFS、基础文件系统。
7. `07-user-mode.md`用户态、系统调用、进程、ELF 程序加载。
8. `08-shell-tools.md`init、shell、调试命令、最小工具集。
9. `09-driver-expansion.md`PCI/ACPI/更完整设备驱动,音频等后期设备。
10. `10-real-machine.md`:真机启动、安全验证、硬件差异处理。
## Linux 级能力缺口路由
这些能力不一定马上实现,但必须在路线中占位,避免后续走偏。
- 硬件发现、平台层、总线、资源分配:`09-driver-expansion.md`
- ACPI、Device Tree、PCI、USB、IRQ routing`09-driver-expansion.md`
- NUMA、CPU topology、电源管理、热插拔`09-driver-expansion.md`
- 内核对象生命周期、引用计数、资源释放:`04-time-scheduler.md`、`06-storage-vfs.md`、`07-user-mode.md`
- 锁、等待队列、workqueue、timer、延迟执行`04-time-scheduler.md`
- 完整虚拟内存、匿名页、缺页加载、COW、mmap、换页、内存回收`03-memory.md`、`07-user-mode.md`
- page cache、block cache、writeback、文件一致性`06-storage-vfs.md`
- slab/slub、小对象缓存`03-memory.md`
- POSIX syscall、`fork/exec/wait`、`fcntl/stat/chmod`、`errno`、路径语义:`07-user-mode.md`、`08-shell-tools.md`
- uid/gid、文件权限、进程权限`07-user-mode.md`、`08-shell-tools.md`
- signal、pipe、socket、eventfd、futex、共享内存、poll/select、IPC`07-user-mode.md`
- tty、session、job control`05-input-events.md`、`08-shell-tools.md`
- libc、动态链接、用户空间工具链`08-shell-tools.md`
- printk、panic/oops、异常栈、内核符号`01-early-debug.md`、`02-cpu-interrupts.md`
- ftrace、perf、procfs、sysfs、debugfs、crash dump`08-shell-tools.md`、`09-driver-expansion.md`
- 用户/组、权限、capability、隔离模型`07-user-mode.md`
- 网络栈和 socket API`09-driver-expansion.md`
当前不进入实现队列,但不能遗忘:
- NUMA
- CPU topology
- 电源管理
- 热插拔
- cgroup/namespace
- LSM 类安全框架
- swap
- 完整 USB 栈
- 完整图形栈
- 音频

View File

@ -1,177 +1,64 @@
# Tianole 路线图
## 总原则
这个文件只做路线入口,不承载详细设计。详细任务放在
`docs/agents/tasks/`,避免每次修改都把长期上下文塞进总路线。
这个项目按“可中断、可回坑、每一阶段都能单独验收”的方式推进。
## 当前状态
目标不是只在虚拟机里亮屏,而是
已经完成
- 在 `UEFI x86_64` 真机上独立启动
- 逐步具备完整内核基础设施
- 逐步具备运行本地 `git` 的能力
- 最小 `UEFI -> bootloader -> kernel` 启动链。
- bootloader 与 kernel 拆分。
- 独立 `kernel.elf` 加载。
- 进入 kernel 前调用 `ExitBootServices`
- `memory map` 通过 `boot_info` 传入 kernel。
- kernel 能统计 memory map 描述符数量和 conventional memory 页数。
- x86 早期日志接口已集中到 `arch/x86/include/tianole/early_log.h`
- 构建系统已拆成根 Makefile、`arch/x86/Makefile` 和目录 Makefile。
- `scripts/check.sh` 和 GitHub Actions 已接入。
- `.clang-format` 已用于强制当前 C 代码风格。
这里参考 Linux 的是分层思路和演进顺序,不是照搬早期 Linux 的启动方式或目录树。
还没有完成:
## 推荐开发顺序
- COM1 串口日志。
- panic/oops 早期错误路径。
- GDT/IDT/异常/中断。
- 物理页分配器、虚拟内存和内核堆。
- 调度、进程、文件系统、用户态和 shell。
### 1. 启动链
## 当前下一步
- 跑通 `UEFI app -> bootloader -> kernel`
- 保证 `kernel_main()` 真正开始执行
- 保证最小可见输出
下一步执行:
完成标志:
- `docs/agents/tasks/01-early-debug.md`
- `bootloader` 成功把控制权交给独立 `kernel`
- `kernel` 能输出第一行字并停住
目标:
### 2. 早期调试输出
- 加入 COM1 串口 backend。
- 保留当前 QEMU debug port backend。
- 提供统一 early log 前端。
- 增加最小 `panic()`
- 让启动日志可以通过 firmware 之外的路径稳定输出。
- 保留当前 `debug` 输出路径
- 增加 early serial log
- 为后续脱离固件后的调试做准备
这一步完成后进入:
完成标志:
- `docs/agents/tasks/02-cpu-interrupts.md`
- 内核在更早阶段也能稳定输出日志
## 任务路由
### 3. 内存与异常基础
按顺序推进:
- 获取 `UEFI memory map`
- 正确执行 `ExitBootServices`
- 建立 `GDT/IDT`
- 增加基础异常处理
- 建立物理页分配器
- 建立内核堆
- 增加定时器
1. `docs/agents/tasks/01-early-debug.md`
2. `docs/agents/tasks/02-cpu-interrupts.md`
3. `docs/agents/tasks/03-memory.md`
4. `docs/agents/tasks/04-time-scheduler.md`
5. `docs/agents/tasks/05-input-events.md`
6. `docs/agents/tasks/06-storage-vfs.md`
7. `docs/agents/tasks/07-user-mode.md`
8. `docs/agents/tasks/08-shell-tools.md`
9. `docs/agents/tasks/09-driver-expansion.md`
10. `docs/agents/tasks/10-real-machine.md`
完成标志:
Linux 级长期能力缺口和对应阶段,见
- 退出 UEFI 后内核仍稳定运行
- 关键异常能进入处理路径
- 内核能稳定分配页和堆内存
### 4. 执行流与调度
- 建立内核线程
- 建立调度器
- 建立上下文切换
- 增加睡眠/唤醒与同步原语
完成标志:
- 可以同时运行多个内核线程
- 调度由时钟驱动
### 5. 用户态入口
- 建立用户地址空间
- 增加系统调用入口
- 增加 ELF 用户程序加载
- 增加进程创建和等待
完成标志:
- 能加载并运行最小用户程序
- 用户程序能调用系统调用输出
### 6. 文件系统与存储
- 建立块设备层
- 建立 `VFS`
- 接入一个实际文件系统
- 实现路径解析、文件读写、目录操作
完成标志:
- 能挂载文件系统
- 能打开、读取、写入文件
### 7. shell 与基础工具
- 增加 `init`
- 增加简单 shell
- 增加基础命令
- 补最小 `libc` 能力
完成标志:
- 启动后能进入 shell
- 能执行几个基础程序
### 8. 面向 git 的补齐
- 优先支持本地 `git`
- 不先碰网络协议栈
- 补足 `git` 依赖的文件、进程、时间、路径等接口
- 先以 `git init / status / add / commit` 为目标
完成标志:
- 能运行本地仓库的基础 `git` 操作
### 9. 真机落地
- 先 `QEMU + OVMF`
- 再 `U 盘 UEFI` 启动
- 最后再考虑加入本机启动项
完成标志:
- 不破坏现有本机启动链
- 能在真机上独立启动并进入系统
## 当前进度
当前已经完成:
- 最小 `UEFI` 启动链
- `bootloader + kernel` 拆分
- 独立 `kernel.elf` 加载
- `kernel_main()` 实际执行
- `memory map` 已通过 `boot_info` 传递,并能在 kernel 中统计描述符与可用页数
- `ExitBootServices` 已在进入 kernel 前执行
- x86 早期日志接口已集中到 `arch/x86/include/tianole/early_log.h`
- 构建布局已改为接近 Linux 的目录 Makefile 组织方式
- 本地检查脚本和 GitHub Actions 已接入
当前还没有完成:
- early serial log
- framebuffer console
- 真正的内存管理和异常子系统
## 当前代码组织原则
当前先不直接复制 Linux 的完整目录树,但开始采用接近 Linux 的分层方向:
- `arch/`:架构相关实现,目前只放 `x86`
- `kernel/`:未来放架构无关的内核主体
- `include/tianole/`:内核与 bootloader 共享的项目自有接口
- `docs/`:正式设计与路线图
- `docs/agents/`agent 协作文档
当前这样拆分的目的不是过早抽象,而是先把边界立住:
- `UEFI` 相关定义留在 `arch/x86/`
- 通用交接结构放在 `include/tianole/`
- 以后新增架构时,优先新增新的 `arch/<name>/`
## 最近里程碑
### 里程碑 1退出 UEFI 前的最后准备
- 获取并保存完整 `memory map`
- 扩展 `boot_info`
- 建立 early serial log
### 里程碑 2退出 UEFI
- 正确执行 `ExitBootServices`
- `kernel` 在退出固件服务后继续稳定运行
### 里程碑 3早期内核基础设施
- 增加 framebuffer console
- 建立物理页分配器
- 建立基础异常处理
- `docs/agents/tasks/README.md`