仓库分析迭代演练可复用模板
iii:让 AI 持续完成
功能迭代与文档维护
从真实 PR、产品文档和 Linkly 教程,理解上下文如何被组织、传递、验证与更新。
仓库:iii-hq/iii · 分析日期:2026-09-15
代码快照:01b15b77f2aefa37b7d3742fc699e0b10750e2ff
文档标签:Latest 0.23.x / Next 0.24.x
01
先理解它解决了什么
iii 的启发:把“AI 需要知道的事”保存为有边界、有版本、能验证的工程资产。稳定规则放在入口文件,能力知识随模块维护,任务只加载相关材料;功能变化同时更新代码、使用文档和 AI 可读产物,再由测试和生成一致性检查形成反馈。
从 Vibe Coding 的角度看,iii 值得学习的地方是把一次自然语言需求,逐步收敛成接口契约、局部代码改动和可观察结果。它自身提供统一的 Worker、Function、Trigger 模型;仓库同时维护供开发者和 AI 使用的知识。两者共同减少模型每轮重新猜测系统结构的成本。
| 关键问题 | 仓库已有做法 | 实际边界 |
|---|
| AI 如何认识项目? | 根目录 AGENTS.md、README、按主题拆分的 Skills、产品文档索引。 | 文件存在不等于所有 AI 工具都自动读取;仍需工具适配或显式引用。 |
| 文档怎么随功能更新? | 同 PR 修改实现、测试、docs/next 与对应 .skill.md;生成器和 CI 检查部分漂移。 | 语义正确性仍需运行验收;并非所有资料都强制同步。 |
| 长任务如何持续? | Linkly 教程逐章推进,每章给出目标、接口、实现范围和验收动作。 | 没有证据表明整个 iii 仓库已统一采用任务状态文件或跨会话交接协议。 |
| 是否自动解决了 AI 记忆? | 有运行期 context-manager 设计,处理 token 预算、裁剪和摘要。 | 这与开发文档治理是两个层次;该设计不能证明仓库上下文会自动、完整地加载。 |
依据:[S01] [S02] [S03] [S08] [S20] [S24] [S25] [S27]
阅读边界
分析基于 main@01b15b77f2ae 的目录、关键源码、工作流,以及四个已合并 PR 的正文和文件差异。核对日期为 2026-09-15。文档导航标记 Latest 为 0.23.x、Next 为 0.24.x;这只是文档标签,不能直接当成每个二进制和 SDK 的发布版本。[S04] [S32]
仓库事实:可定位证据机制分析:基于证据解释模拟方案:为实践补充
这里没有运行 iii 全套产品测试,也没有复现作者的私有开发会话。后面的模拟不会被描述成作者实际使用过的提示词、内部流程或已上线能力。
02
当前产品与功能边界
iii 是一个以 Rust 引擎为核心的后端组合运行系统。Worker 连接引擎,注册可调用的 Function,再声明什么事件通过 Trigger 触发函数。HTTP、队列、状态、定时任务等能力可以由不同 Worker 提供;开发者、CLI、控制台和 Agent 使用共同的功能调用面。[S01]
| 组成 | 当前作用 | 对 AI 开发的价值 |
|---|
| Engine | 维护注册、路由、命名空间及运行期基础能力。 | 把服务交互收敛到少量稳定概念。 |
| Compose | 读取 worker-compose.yaml,管理项目 Worker 的启动、停止、依赖顺序和运行状态。 | AI 可逐步增加 Worker,不必重建整个系统。 |
| Function / Trigger | 函数使用稳定 ID;触发器绑定调用来源与处理函数。 | 明确调用名称、参数和触发条件,便于局部实现与验证。 |
| SDKs | README 列出 Node.js、Python、Rust、Go;另有浏览器 SDK。 | 语言可以不同,但需遵守同一协议与数据契约。 |
| Console / 可观测性 | 查看 Worker、函数、触发器、日志、追踪和状态等。 | AI 的“已完成”能被具体调用与 trace 核实。 |
| Worker Registry / Skills | 按能力查找 Worker;Worker 可以携带自己的使用知识。 | 先发现现成能力,再实现业务差异。 |
| Agentic 教程 | 使用 harness、llm-router 等 Worker 搭建编码环境,逐章构建 Linkly。 | 给出一次可执行的增量开发路径。 |
必须区分仓库内部与生态能力
当前 README 将 HTTP、cron、queue、state、pubsub、bridge 描述为独立 Compose Worker,来源在 iii-hq/workers;引擎自有的配置、管理和部分基础能力留在 iii 仓库。分析某个 Worker 的完整行为时,必须继续读取其对应版本的实现与文档。仅阅读当前仓库,不能推定所有生态组件的实现细节。[S01] [S03]
功能开发有两个不同场景:修改 iii 平台本身,要读 Rust 实现、SDK 协议、内部测试和 tech-specs;使用 iii 开发应用,重点是相关 Worker 的技能、函数契约和业务代码。后者通常不需要把整个引擎源码放入模型上下文。
03
真实迭代:从设计到运行反馈
下面是与本次主题最相关的迭代样本,不代表完整发布史。设计文档日期、PR 合并时间和正式发布状态分别记录。
2026-07-14 · 设计包Worker Compose 分解为六个契约
设计包解释为什么要把 Worker 生命周期从引擎所在机器解耦,再拆成 compose 文件、脚本、命名空间、配置、CLI、生命周期六份文档。每个子文件有明确负责的问题,避免一个超长说明承担全部设计。README 的状态仍为 draft。[S17]
0.22 → 0.23 · 迁移文档架构变化同时产生迁移要求
升级指南说明迁移到 Compose、采用命名空间,以及 RabbitMQ durable subscriber 队列名称改变后的处理。它把“新功能是什么”落实为“已有用户要改什么”,包括保留队列存储路径与处理旧队列。[S23]
2026-09-10 · PR #2146重启不应悄悄换掉依赖
可变版本选择器可能在重启时指向新内容。PR 引入 worker-compose.lock,保存解析后的依赖图、版本、下载地址和摘要,并加入 frozen 模式。23 个变更文件覆盖实现、测试、CLI 文档、使用文档及两类文档的 Skill 产物。[S25]
2026-09-10 · PR #2134容错策略转化为明确的状态契约
新增可选容器、required_default 和重启策略。可选启动失败通过 not_required_failures 表达;重启等待期间没有活动 PID。该 PR 同时更新架构说明、使用说明、Skill 和回归测试。[S26]
2026-09-11 · PR #2173继续收敛命令与环境变量的行为
提交记录显示 Compose 修复 III_URL 的引擎选择行为。大功能合并后,仍需要通过小补丁修正具体使用路径的一致性。[S31] [S32]
2026-09-10 / 09-14 · PR #2160 / #2181AI 实际生成的偏差反过来修正文档
表名与脚本参数都曾因提示词不够具体而漂移。修复针对源教程及其生成 Skill,说明提示词本身也是需要迭代的产品资产。[S27] [S28]
可以确认的闭环是:问题 → 契约变化 → 实现与测试 → 人类文档 → AI 文档 → 使用反馈。公开材料足以支持这一模式,但不足以证明所有功能都严格按相同顺序完成。
把 #2146 还原成一个可学习的开发切面
| 阶段 | 公开证据 | 如果交给 AI,必须明确什么 |
|---|
| 问题 | 普通启动重新解析 next 等可变选择器。 | 重启应复用既有解析,显式更新才允许移动。 |
| 数据设计 | lockfile.rs 的 ComposeLock、LockedContainer、PreparedLock。 | 声明与解析结果分离;先准备候选,再原子写入。 |
| 实现影响 | build、daemon、registry、dependencies、remote、CLI 等文件。 | 所有生命周期入口必须遵守同一锁文件语义。 |
| 失败行为 | 下载或解析失败保留旧 lock 与运行中的 Worker。 | 失败不能留下半套持久状态。 |
| 验证 | PR 报告单元、CLI、端到端、格式和静态检查。 | 需要覆盖缺失锁、过期锁、缓存缺失、升级失败与并发修改。 |
| 文档传播 | 两份 Next 文档及对应 Skill 同 PR 更新。 | CLI 参数、行为说明和 AI 指引必须一致。 |
PR 报告 iii-compose 测试 391 通过、1 忽略;这是作者记录的验证结果,并非本次分析重新执行的结果。[S19] [S25]
04
文档各管什么:上下文地图
这里的“产品文档”包含不同生命周期的知识。混在同一个上下文窗口里,AI 容易把草案、已实现行为和历史兼容策略同时当成当前事实。
| 位置 / 载体 | 应当回答的问题 | AI 的读取时机 |
|---|
AGENTS.md | 在仓库里怎么构建、测试、命名;哪些变更需要讨论。 | 修改 iii 仓库前,先读取适用规则。 |
README.md、STRUCTURE.md | 项目定位、模块边界和入口。 | 第一次进入项目或跨模块变更。 |
tech-specs/<日期-主题>/ | 为什么这么设计;跨组件契约与取舍。 | 方案规划与架构变更;核对 draft 等状态。 |
docs/next/ | 即将发布的用法、概念、教程、API 与迁移说明。 | 开发 main 上的新能力时,按主题加载。 |
docs/ 根目录内容 | 当前 Latest 的使用面。 | 对已安装稳定版本开发时,先匹配版本。 |
docs/0-22-0/ 等归档 | 过去版本的行为。 | 排查旧系统或编写迁移时。 |
docs/**/*.mdx.skill.md | 同源文档的 AI 可读生成产物。 | 工具支持这一入口时,加载相关页。 |
skills/*/SKILL.md | 跨功能可复用的核心用法和实践。 | 按当前任务需要选择,避免全量注入。 |
| Worker 内的 Skills | 某个具体能力如何调用及其边界。 | 选定 Worker 后,读取匹配版本的材料。 |
| Issue / PR / commit / 测试 | 这次为什么改、改了哪里、如何证明。 | 迭代实施、集成和历史追溯。 |
目录与职责依据:[S01] [S02] [S03] [S04] [S10] [S17] [S20] [S25]
文档分类用来降低检索歧义
.cursor/rules/docs.mdc 按路径匹配 docs/**/*.mdx 与 docs/**/*.md,声明 alwaysApply: false。它先把任务归入教程、操作指南、参考、原理说明,再指向对应写作 Skill。全局写作规则鼓励通过链接引用已有概念,避免在每份文档里重复维护相同知识。[S05] [S06]
| 类别 | 适合包含 | AI 应如何使用 |
|---|
| 教程 Tutorial | 有顺序的学习任务、预期结果。 | 跟随一次完整场景,避免把示例直接当通用规范。 |
| 操作指南 How-to | 完成特定目标的操作步骤。 | 当前问题对应哪条操作路径。 |
| 参考 Reference | 参数、类型、返回值、错误与默认值。 | 确定接口契约;优先核对生成参考或源码。 |
| 原理 Explanation | 设计原因、限制和取舍。 | 判断方案是否符合系统设计。 |
这些规则描述的是仓库中的文档工作流。它们不会自动替代用户要求,也不能保证每个 AI 工具都识别 Cursor 的匹配机制。
05
AI 上下文怎样被组织与读取
第一层:稳定规则,让模型知道怎么参与
AGENTS.md 给出构建和测试命令、目录地图、函数 ID 使用 ::、HTTP 路径带前导斜杠、cron 字段使用 expression 等约束。它还要求 Skill 具备用途与边界部分。这类高复用规则适合常驻入口。功能细节应由入口链接到专门文件,避免入口无限膨胀。[S02]
第二层:能力知识,让模型知道可以复用什么
当前顶层目录是 6 个 iii 核心知识 Skills,加一个 presentation 工具。Worker 专有能力知识尽量留在 Worker 文档,减少同一队列、状态或 pubsub 用法在多个目录中重复维护。引擎 Worker 的发布载荷生成器还接收版本参数,并把选中的 Skill 内容作为发布数据。[S03] [S16]
第三层:任务上下文,让模型知道这轮改什么
Linkly 每章提示词指定函数名、文件位置、数据约定和预期结果;并行工作前先约定 topic 或 payload,最后由主任务集成。在这一层,最重要的是明确继承哪些行为、改变哪些行为、必须通过哪些验收。[S20]
第四层:代码与运行证据,让模型校正理解
当描述与实现不一致时,应定位目标版本的实现、测试和 PR。例如 Compose 的 schema 查询可以暴露请求响应结构,Console 与 trace 可以观察真实调用。检索得到的说明负责导航,执行证据负责验证具体假设。[S18] [S20] [S25]
上下文管理至少需要四个动作:定位 → 筛选 → 注入 → 回写。iii 的公开仓库提供了大量可定位、可生成、可校验的知识;“把哪些文件放入这次模型请求”仍依赖所用 Agent、技能系统或任务提示。
| 容易误解的文件 | 实际含义 | 不能直接推导的能力 |
|---|
仓库 AGENTS.md | 开发此 monorepo 的入口规则。 | 网站上的 AGENTS.md 与它完全相同。 |
iii.dev/AGENTS.md | 由网站脚本生成,包含产品介绍、首页提取和构建指南附录。 | 它是仓库规则文件的简单复制。 |
llms.txt | 提供产品概览、文档与博客入口。 | 模型一定自动加载,或加载后信息必然完整。 |
*.mdx.skill.md | 单页文档对应的派生产物。 | 它都能作为任意工具的可安装 SKILL.md;它已被压缩到很小。 |
context-manager.md | 运行期 token 预算、裁剪、摘要的设计。 | 它已经统一管理了仓库 PRD、ADR 与任务交接。 |
网站生成器明确从构建后的首页、固定 overview、博客索引和 appendix 生成两个公开文件。它不是扫描整个代码库后生成所有事实的知识引擎。[S15]
一份更可靠的读取顺序(实践建议)
- 锁定目标代码提交、产品版本和依赖版本。
- 读取适用的仓库入口与当前任务契约。
- 按修改路径加载必要的模块说明、Skill、接口参考。
- 检索对应实现、调用者和回归测试;形成影响范围。
- 出现冲突时记录冲突,按任务目标澄清期望,再通过测试确认实际行为。
- 每完成一个可验收切片,将决定、验证和剩余工作写回任务记录。
这是一套基于仓库机制整理的操作建议,不是声称 iii 已经实现了统一的自动上下文调度器。
06
文档怎样变成 AI 可用资产
最值得复用的是编辑源内容,再生成多个消费入口。不要让“给人看的文档”和“给 AI 的文档”独立演化成两套事实。
参考生成、Skill 生成和版本发布是不同步骤,需要分别检查。
1. MDX → 对应的 .skill.md
.skill-check.yaml 采用 version: 2、mode: docs,匹配 docs/next/**/*.md 和 docs/next/**/*.mdx,排除该路径下的 changelog 与 Linkly 测试工作区。单页转换生成同目录的 <source>.skill.md。例如教程源与产物分别为 agentic.mdx、agentic.mdx.skill.md。[S07] [S20] [S21] [S29]
仓库已有的生成与核对方式
# 已安装项目使用的 render/check 工具后,在仓库根目录执行
iii-skill-render --write docs/next/tutorials/linkly/agentic.mdx
iii-skill-check verify-rendered docs/next
# 然后同时查看源文档和派生文件的 diff
git diff -- docs/next/tutorials/linkly/agentic.mdx docs/next/tutorials/linkly/agentic.mdx.skill.md
产物首行明确说明由生成器产生,并指回编辑源。转换主要解决同源输出,不保证 token 压缩:本次读取的 Linkly Skill 仍保留大量 provider 选择界面的 JSX。不能仅凭扩展名就认定内容已经适合小上下文模型。[S21]
2. 校验 → PR 反馈
主工作流设置 write: false、scope: pr-diff:常规运行负责校验与报告,不自动替开发者提交。外部 Action 包含结构、Vale 和 AI 三层;没有 AI key 时会跳过 AI 层并警告。该版本的 Action 对本 PR 范围内的生成漂移报错,对范围外已有漂移给出警告。另一个 workflow 允许有权限的维护者通过指定评论复选框触发重新生成。[S08] [S09] [S29] [S30]
这些检查能发现结构、文风和源文件与产物不一致;无法替代 API 调用测试、数据迁移测试和业务验收。也不能仅凭 workflow 文件存在就声称它是仓库分支保护中必需通过的检查。
3. 源码 → SDK / CLI 参考
SDK 流程使用 TypeDoc、griffe 与 rustdoc JSON 提取资料,再生成 docs/next/reference/sdk-*.mdx 和 helpers-*.mdx。CLI 文档由命令定义生成,主 CI 重建后检查提交的 CLI reference 是否过期。API 工作流在 main 相关源文件变动后运行,不等于所有 API 文档都在 PR 合并前完成一致性验证。[S12] [S13] [S14]
4. Next → Latest → 历史版本
稳定 minor / major 发布会归档旧 Latest,并把 Next 复制到根目录;patch 更新根目录内容,不新增归档、不提升 Next 标签;预发布不轮转文档。源码、Next、Latest 和安装版本因此可能处于不同阶段。AI 开发前必须先选版本,再选材料。[S10] [S11]
07
两个真实失败:缺的不是更多文字
真实案例 · PR #2160
“按天统计”没有定义表契约
教程要求 Python Worker 统计每天的链接数,验收 SQL 却固定查询 daily_link_counts。PR 说明第三次试跑时,Agent 生成了 links_per_day,于是查询报“表不存在”。
| 原先留下的自由度 | 修复后补齐的约束 |
|---|
| 只描述“按天计数”。 | 明确使用 daily_link_counts。 |
| 实现者自行决定字段。 | 明确 day TEXT PRIMARY KEY、count INTEGER NOT NULL。 |
| 子任务可能只读自己的任务描述。 | 总提示词和 analytics 子任务描述都携带表名约定。 |
| 人类教程与 AI 产物可能不同步。 | 同 PR 更新 MDX,并重新生成对应 Skill。 |
启示:凡是验收、调用者或另一位开发者依赖的名称与结构,都属于契约。必须在相关执行任务的上下文里出现,不能寄希望于模型猜中。[S27]
真实案例 · PR #2181
“做一个 CSV 客户端”没有定义默认调用方式
教程演示直接执行 node channel-client/import-links.js,提示词却没有规定参数是否必填。一次生成的脚本要求传入 CSV 路径,教程的命令因此无法执行。
修复将路径明确为可选参数,缺省读取 test.csv,并同步 Skill。PR 也指出同一无参数命令被相关检查调用,所以这是功能演示与验收共同依赖的行为。[S28]
把问题写成一条工程规则:提示词中的成功条件,必须能一一对应验收命令、固定输入和预期输出。发现偏差后,修复任务契约与源文档;只在聊天中解释一次,会让下一轮重新犯错。
建议使用“闭环记录”,而不是复制整段聊天
问题修复记录示例(整理建议)
偏差:无参数执行导入客户端时退出并打印 Usage。
原因:任务只要求支持 CSV,没有定义默认文件。
决策:CSV 路径为可选参数;默认 test.csv。
影响:客户端、教程命令、测试夹具、AI Skill。
验收:不传参数仍可运行;显式路径仍被支持;读不到文件时明确报错。
持久化:修改源说明 → 重新生成 → 核对 diff → 记录验证结果。
08
Linkly:七轮增量开发演练
仓库已有 Linkly 的 Agentic 路径:每章提供一段任务提示,让 Agent 修改 Worker,再由使用者通过控制台、CLI 或客户端检查结果。下方“功能增量、契约、验收”提炼自教程;“建议写回”是为了跨会话开发补充的管理动作。[S20]
第 01 轮 · 短链基础
建立可调用的最小业务
| 维度 | 这一轮应看到的内容 |
|---|
| 功能增量 | link::create / link::resolve;状态存储;HTTP 创建与跳转。 |
| 读取上下文 | HTTP、state Worker 用法;link/src/index.ts;输入输出与错误状态码。 |
| 契约与边界 | 请求的短码重复要拒绝;自动短码碰撞要重试;未知短码返回空结果。 |
| 验收结果 | POST /links → 201;重复指定 code → 409;已知 code → 302;未知 code → 404。 |
| 建议写回 | 记录函数契约和 HTTP 映射;这些是后续章节需要继承的行为。 |
第 02 轮 · 可观测性
先验证系统发生了什么
| 维度 | 这一轮应看到的内容 |
|---|
| 功能增量 | 创建或复用 home 链接,发出五次跳转,读取过滤后的 trace 与 span tree。 |
| 读取上下文 | 上一轮路由约定;engine::traces::list / tree 的用法。 |
| 契约与边界 | 按 GET /s/:code 过滤,避免把 Console 自身请求当业务证据。 |
| 验收结果 | 可给出真实 trace_id,并展示一次跳转的调用树。 |
| 建议写回 | 记录可复现查询和 trace 证据,避免仅写“功能正常”。 |
第 03 轮 · 持久化
让重启后数据仍可用
| 维度 | 这一轮应看到的内容 |
|---|
| 功能增量 | SQLite primary 保存链接和点击;state 作为读缓存。 |
| 读取上下文 | 数据库 Worker;现有 link 函数;缓存与存储的数据结构。 |
| 契约与边界 | 数据库稍晚注册时重试建表;缓存 miss 读数据库后回填。 |
| 验收结果 | 创建并访问短链;查询点击数据;重启后继续解析。 |
| 建议写回 | 补数据模型、初始化顺序和缓存行为,保留前一轮外部接口。 |
第 04 轮 · 异步处理与统计
缩短跳转关键路径
| 维度 | 这一轮应看到的内容 |
|---|
| 功能增量 | clicks 队列;link.created 事件;Python analytics;durable 更新与缓存刷新。 |
| 读取上下文 | 队列、pubsub、数据库 Skill;事件载荷;链接与统计两个存储域。 |
| 契约与边界 | 固定 daily_link_counts 表及字段;先约定共享依赖,再拆分文件任务。 |
| 验收结果 | 统计库能查询;PUT 更新后 link::resolve 返回新 URL;检查事件路径。 |
| 建议写回 | 记录 topic、表结构、交付语义和消费者约定;不能把重试等同于无重复。 |
第 05 轮 · 实时点击流
把点击变化持续送出
| 维度 | 这一轮应看到的内容 |
|---|
| 功能增量 | 新增 click-streamer;每次点击写入 clicks stream。 |
| 读取上下文 | 发布者与消费者约定;stream::set / list;必要业务字段。 |
| 契约与边界 | 先确定 topic;只取 code、clicked_at 等业务字段,避免透传运行期附加字段。 |
| 验收结果 | 发出多次跳转后,stream::list 能查到新增点击项。 |
| 建议写回 | 补事件与流结构;保持每条数据的含义一致。 |
第 06 轮 · 批量导入
让外部客户端通过 channel 传入数据
| 维度 | 这一轮应看到的内容 |
|---|
| 功能增量 | bulk-importer 消费 CSV;Node 客户端上传。 |
| 读取上下文 | channel 操作;import_csv payload;重复短码的业务错误。 |
| 契约与边界 | 客户端默认 test.csv;重复短码可跳过,超时或 Worker 不可用应继续抛错。 |
| 验收结果 | 无参数命令可运行;根据已有数据得到合理的 imported / skipped;查询导入链接。 |
| 建议写回 | 保存默认参数、夹具、错误分类与重跑行为。 |
第 07 轮 · 浏览器应用
把前端接入同一调用面
| 维度 | 这一轮应看到的内容 |
|---|
| 功能增量 | React 前端、auth Worker、rbac-proxy、删除确认。 |
| 读取上下文 | 允许调用的函数;browser- 命名空间;前端与服务端约定。 |
| 契约与边界 | 每个 tab 独立 namespace;未配置 token 时拒绝;命名空间字符串只构造一次。 |
| 验收结果 | 多个 tab 不冲突;可创建短链;删除先确认;权限按预期生效。 |
| 建议写回 | 补鉴权配置、跨端契约和使用说明;示例 dev-token 不作为生产方案。 |
为什么分轮开发有效
每一轮都让系统保留可运行状态,再增加一项能力。数据从状态存储发展到数据库,点击处理从同步调用发展到异步队列,再扩展到实时流与浏览器。模型只需处理这轮的增量、既有契约和回归条件,不需要重新设计所有组件。
教程也展示了并行任务:先约定共享 topic 或 payload,再划分文件和目录,最后集成。第一章虽然最终合并到同一 link/src/index.ts,但提示词要求主任务负责合并;在实际团队中仍应安排单一文件写入者或隔离分支,避免覆盖。
_workspace/run.sh 会从模板创建临时项目、按章节启用代码并执行断言,依赖外部 templates checkout。它体现了教程可执行化,但它测试的是模板章节路径,不能直接推断为对所有自由生成结果做了自动评测。[S22]
09
完整模拟:给短链增加过期时间
模拟方案新增应用功能未在仓库实施
假设 Linkly 已完成第 3 轮,具备数据库和缓存。用户提出:“活动短链可以设置失效时间,过期后不要继续跳转,旧链接仍然可用。”这个功能能同时检验需求上下文、接口、存储、缓存、测试以及会话恢复。
轮次 A:把需求改写为可验证契约
先固定行为:新增可选 expires_at,只接受带时区的 ISO 8601 时间,内部归一化 UTC;字段缺省或 null 代表永不过期;设置值必须晚于当前时间;解析时满足 now >= expires_at 即失效。对外 HTTP 跳转统一返回 404,以保留“不可解析”的简单语义;是否需要 410 是另一项产品选择,不能由模型自行决定。
旧 link::resolve 的输出继续保持 {url} 或 {url:null};新字段放在内部数据记录以及创建接口的输入中。数据库 links 增加可空字段;迁移必须保留已有数据。这里的 SQL 列类型与迁移实现应在读取现有 schema 后确定。
轮次 B:整理本次需要的上下文
| 必须读 | 用途 |
|---|
| 当前应用 AGENTS.md + 本功能 spec | 确认命令、约束、需求与完成条件。 |
| link/src/index.ts + 当前测试 | 找到 create、resolve、HTTP handler 和错误映射。 |
| 现有 links schema、数据库 Worker 对应版本资料 | 选择安全的可重跑迁移方式。 |
| state Worker 的 get / set / delete 契约 | 确认缓存记录能携带 expires_at。 |
| 已完成章节的接口记录 | 保持旧调用者和旧数据兼容。 |
本轮通常不需要整个引擎源码、全部 SDK、其他产品的历史归档或前端第 7 章。若项目已经完成全部七章,则必须扩展范围:CSV 导入、更新接口和前端表单都要明确是否支持该字段。
轮次 C:先定位影响,再实施最小切片
- 检查 schema 与数据初始化逻辑,加入可重跑的迁移,旧行保留 null。
- 创建路径校验时间;数据库记录与缓存记录都携带过期信息。
- 解析路径对缓存命中和数据库回源使用同一套过期判定。
- HTTP handler 保持既定输出;过期短链与不存在短链均返回 404。
- 如果存在更新路径,明确“未传字段保持原值,null 清除过期时间”的额外契约后再实现;不要让这部分隐含混入首个切片。
最常见漏项是只在数据库查询时过滤过期时间,导致缓存命中仍然跳转。缓存里的数据也必须经过相同业务判定;缓存 TTL 可以优化,不能替代正确性条件。
轮次 D:用验收矩阵替代“看起来能用”
| 场景 | 输入或前置条件 | 预期 |
|---|
| 旧链接 | 没有 expires_at 的已有数据库行 / 缓存项 | 原 URL 仍可解析。 |
| 未到期 | 当前时间小于 expires_at | 解析成功,HTTP 302。 |
| 恰好到期 | 当前时间等于 expires_at | 解析为空,HTTP 404。 |
| 缓存热数据 | 先缓存,随后推进时钟到失效点 | 仍然失效,不继续跳转。 |
| 缓存 miss | 数据库中已有过期行 | 不回填成可用链接,返回不可解析。 |
| 非法时间 | 缺少时区、不可解析、过去时间 | 按 spec 拒绝,HTTP 400。 |
| 重复运行迁移 | 已增加字段后重新启动 | 不损坏数据,不因重复 schema 操作崩溃。 |
| 重启与回归 | 创建未来过期链接后重启;重复 code | 字段保留;重复 code 仍遵守原有拒绝规则。 |
测试使用可注入时钟或现有测试框架的时钟替身,避免真实等待与时间临界点抖动。这里列的是模拟任务应执行的测试,不是已运行结果。
轮次 E:同一功能完成时写回哪些文件
源代码与测试进入同一变更;更新创建与解析的参考说明、迁移说明和受影响的教程。如果开发的是 iii 仓库文档,编辑 Next 后重新生成对应 Skill;如果开发的是自己的 Linkly 应用,使用自己项目的文档生成规则。不要把应用 PRD 写进上游 iii 仓库的产品文档。
轮次 F:新会话接手,不重新猜测
假设迁移与创建逻辑已完成,缓存测试尚未完成。交接记录必须包含实际提交 SHA、未提交改动、已通过和未执行的测试、最后一个失败、下一步命令。新会话先验证记录对应的代码状态,再做缓存边界测试。聊天摘要负责导航,spec 和代码负责精确事实。
功能真正完成的标准:行为符合契约,回归条件通过,使用文档与 AI 材料一致,下一位接手者能从文件恢复当前状态。
10
可直接使用的上下文与交接模板
下列文件是建议为自己的项目补充的最小组织方式;它们不代表 iii 已经存在相同目录。重点是每份文件只承担一种职责。小改动可合并在一个任务文件里,不必为了形式创建很多空文档。
| 建议文件 | 只保存什么 | 更新时机 |
|---|
AGENTS.md | 项目规则、常用命令、索引、禁止踩的坑。 | 稳定工作规则改变时。 |
docs/features/link-expiry/spec.md | 用户行为、数据与接口契约、验收编号。 | 需求或已接受契约变化时。 |
docs/features/link-expiry/plan.md | 任务分解、影响文件、顺序、状态与验证。 | 每个可验收切片完成或失败时。 |
docs/features/link-expiry/handoff.md | 短期进度、代码状态、阻塞与下一步。 | 切换会话、切换执行者或暂停前。 |
docs/decisions/NNN-expiry-response.md | 影响多个模块的决策及被替代关系。 | 404 / 410 等选择需要长期保留原因时。 |
模板 1:本轮上下文清单
建议模板 · context.md,可合并进 plan.md
# LINK-EXPIRY 上下文清单
## 基线
base_commit: <实际读取 git rev-parse HEAD 后填入>
target_release: <应用版本>
worker_versions: <锁文件中的实际版本>
status: planned
## 本轮目标
让短链支持可选过期时间,保留旧链接与原 resolve 输出。
## 权威材料
- 行为与验收:docs/features/link-expiry/spec.md
- 当前实现:link/src/index.ts
- 现有 schema / 测试:<定位后填写真实路径>
- Worker 能力:<数据库与 state 的版本化资料>
## 读取范围
必须:上述材料 + 适用 AGENTS.md。
按需:创建、解析、缓存、HTTP 的调用者和测试。
本轮不加载:无关引擎模块、所有历史归档。
## 冲突处理
列出“目标契约 / 代码实际行为 / 文档说法”的差异。
不要自行把草案或旧版本描述提升为当前事实。
## 输出
改动文件、验收编号与结果、剩余风险、下一步。
模板 2:功能契约与验收
建议模板 · spec.md
# LINK-EXPIRY 功能契约
status: accepted
owner: <负责人>
last_verified_commit: <实际 SHA 或 unknown>
## 目标
活动链接到期后不可继续跳转;旧链接保持可用。
## 接口
create 输入新增 expires_at?: string | null。
string 必须为带时区的 ISO 8601,归一化 UTC,晚于当前时间。
resolve 输出保持 {url} 或 {url:null}。
到期边界为 now >= expires_at;HTTP 返回 404。
## 数据与兼容
links 增加可空字段;旧行与旧缓存缺省视为永不过期。
缓存记录保留 expires_at;每次 resolve 都判断是否过期。
迁移可重复执行,不清空已有数据。
## 非目标
本切片不实现自动物理删除、不增加按用户时区的输入界面。
如需支持修改过期时间,另行明确更新接口语义。
## 验收
AC-01 旧链接可用。
AC-02 未来时间可跳转。
AC-03 恰好到期不可跳转。
AC-04 缓存命中不能绕过过期判定。
AC-05 非法时间拒绝。
AC-06 迁移可重跑、重启后数据保留。
AC-07 原有短码重复处理不退化。
模板 3:发给编码 AI 的任务提示
建议模板 · 一次有边界的编码任务
实现 LINK-EXPIRY 的第二个切片:创建与解析路径。
先读取:
1. 适用的 AGENTS.md;
2. docs/features/link-expiry/spec.md;
3. plan.md 与 handoff.md;
4. link/src/index.ts、现有测试与实际 schema。
先报告你定位到的入口、影响范围和契约冲突,再完成实现。
如果所需数据库或 state 调用尚未确认,读取对应版本资料,
不要根据其他语言 SDK 或旧教程猜方法名。
保持 resolve 的原输出;缓存命中和数据库回源都检查过期。
覆盖 AC-01 至 AC-07 中本切片涉及的用例。
遵循项目已有错误模型与测试框架,不引入无关重构。
完成后:
- 汇总实际修改的文件;
- 逐项记录执行过的命令、结果和未执行项;
- 更新 plan.md、handoff.md 和受影响的源文档;
- 有派生产物时重新生成,核对与源文件一致。
没有实际执行的测试不得写成通过。
模板 4:会话交接与重开
建议模板 · handoff.md
# LINK-EXPIRY 交接
updated_at: <时间>
branch: <实际分支>
head_commit: <实际 SHA>
working_tree: <干净 / 实际未提交文件列表>
## 已接受决定
- expires_at 缺省为永不过期。
- now >= expires_at 失效;外部返回 404。
- 缓存和数据库读取都执行同一判定。
## 已完成
<填写实际任务、文件与提交;不要复制计划当完成记录>
## 验证
<命令> -> <通过 / 失败 / 未运行>,对应 AC-xx。
## 未完成与阻塞
<例如:缓存热数据跨越失效点的测试尚未完成>
## 下一步
1. 校验当前 HEAD / working tree 与记录相符。
2. 阅读 spec 和相关 diff。
3. 执行或补齐明确的下一项测试。
## 必要证据
<PR、失败日志的精简定位、有效 trace_id;不写入密钥>
模板里的版本号、SHA 和验证结果都必须由执行者读取真实环境后填写。摘要要保留决定、约束和定位信息,详细日志用路径引用;不要把完整聊天无限追加进 AGENTS.md。
11
让文档随迭代持续有效
按信息类型选择维护方式
| 信息类型 | 主要来源 | 派生与验证方式 |
|---|
| 用户需求与验收 | 功能 spec,由产品与开发共同确认。 | 代码与验收编号建立对应关系。 |
| 接口签名与 CLI 参数 | 类型、schema、命令定义。 | 生成参考;重新生成后检查差异。 |
| 设计理由 | tech-spec / 决策记录。 | 记录状态、日期和替代文档;不要悄悄重写历史理由。 |
| 使用流程 | 手写操作说明和教程。 | 执行示例命令;核对输入、默认值、预期结果。 |
| AI 能力知识 | 同源文档、模块 Skill。 | 重新生成或同步更新,检查范围与版本。 |
| 当前任务进度 | plan / handoff。 | 完成一个切片即更新;合并后归档或结束状态。 |
每类修改对应哪些文档
| 变更 | 应检查的材料 |
|---|
| 新增 Function / 修改 payload | 接口参考、调用示例、相关 Worker Skill、生产者与消费者测试。 |
| 修改默认值或错误行为 | 参考、操作指南、教程提示词、默认命令与错误分支断言。 |
| 新增 CLI 参数 | 命令定义 → 生成 CLI reference → 对应 Skill → 使用示例。 |
| 破坏兼容 / 数据迁移 | 版本说明、升级步骤、数据保留条件、回滚或恢复方案。 |
| 调整跨模块边界 | 架构说明、决策记录、入口索引及受影响的任务上下文。 |
| 修复 AI 常犯偏差 | 源契约与对应任务 brief;更新派生材料并复跑失败场景。 |
建议加到自己的完成条件
- 每条验收均有实际结果,未执行项明确标记。
- 实现、调用者与测试使用同一字段名、默认值和错误语义。
- 人工资料只编辑权威源;生成产物已刷新。
- Next、稳定版和归档的修改范围符合版本策略。
- PR 写清为什么改、行为怎样变、如何验证。
- 长期规则进入入口或决策文件;临时进度留在任务记录。
- 完成后任务标记结束,取消过时的未完成提示。
iii 的实际证据覆盖了同 PR 更新、生成一致性、文档分类与发布轮转;上面的任务状态和验收编号机制是建议补强的部分。[S08] [S10] [S12] [S14] [S25] [S26]
12
已有机制的不足与改进方向
这个仓库已具备很好的工程化基础,但公开材料也暴露出上下文漂移。使用它的经验时,应该同时借鉴它的机制和失败样本。
| 观察到的事实 | 会给 AI 带来什么问题 | 建议改进 |
|---|
| AGENTS.md 仍称顶层有 26 个 Skills;当前目录为 6 个核心知识 Skills 加 1 个展示工具。 | 入口中的数量与布局信息过期,影响检索与判断。 | 从目录生成清单,或在入口只保留目录链接。 |
| Compose 设计包仍标 draft,且使用较早设计时的路径与背景。 | 模型可能把历史提案当成当前契约。 | 补实现状态、对应 PR 和 superseded / implemented 链接。 |
| docs/RELEASING.md 仍写生成到 api-reference;当前生成器实际写 reference。 | Agent 根据运行手册检查了错误的目录。 | 由工作流或生成器导出路径;加入链接与路径验证。 |
| Linkly 生成 Skill 仍带大量界面 JSX。 | 生成文件更适合复用,但未必更节省上下文。 | 按章节提取任务材料,测量生成噪声;为复杂 UI 明确文本替代。 |
| Skill 检查只覆盖指定的 Next 文档范围;主 CI 忽略纯 docs/skills/website 变更。 | 一个检查通过不能推出整个知识体系一致。 | 显式显示检查范围;对关键入口、索引和任务契约补轻量检查。 |
| API 生成在 main 变更后触发;Rust 提取允许继续,生成器会跳过缺失 JSON。 | 流水线成功不必然等于所有语言资料都已刷新。 | 在需发布的语言范围内把缺失输入设为失败,并显示每个目标产物状态。 |
| 未发现统一的任务交接文件规范;逐章提示依赖执行环境保留状态。 | 会话切换后可能重复实现或遗忘未完成测试。 | 为长期功能增加 spec / plan / handoff,保存实际版本与验证结果。 |
对应证据:[S02] [S03] [S07] [S10] [S12] [S13] [S14] [S17] [S20] [S21]
不要混淆两类“上下文管理”
开发文档上下文解决项目事实放哪里、何时加载、谁更新、哪个版本有效。模型运行期上下文解决当前调用装得下多少消息、哪些输出裁剪、如何摘要旧历史。
tech-specs/2026-06-08-agentic/context-manager.md 描述后者:assemble 按计数、裁剪、压缩的顺序整理消息;强调工具调用与结果成对保留;会话持久化由调用者负责。该文件是设计材料,本次没有核对外部 Worker 的完整实现,不能宣称它已经自动完成开发文档检索或跨会话任务恢复。[S24]
“有文档”“能被 AI 读取”“与代码一致”“被这次任务正确使用”是四个不同条件。工程体系需要分别验证它们。
13
迁移到自己的 Agent / Java 项目
对于已经有 Java 项目和线上 Agent 的团队,可以先迁移这套文档管理方法。它不要求先迁移语言、框架或业务运行架构。
| 落地顺序 | 具体产物 | 完成标准 |
|---|
| 第 1 步:整理入口 | 一个简短 AGENTS.md,链接构建、测试、模块地图与文档规则。 | 新会话能找到正确模块与命令。 |
| 第 2 步:挑一个真实功能 | 一份 spec + plan,写清输入输出、错误、兼容与验收。 | 能把模糊需求转成不依赖口头解释的任务。 |
| 第 3 步:实现按切片推进 | 实现、回归测试、实际运行证据。 | 每个切片都可独立判断是否完成。 |
| 第 4 步:接口参考来自代码 | 使用项目已有 OpenAPI、schema、Javadoc 或其他生成流程。 | 修改接口后能发现参考或示例过期。 |
| 第 5 步:试一次会话交接 | handoff 记录版本、已完成项和下一步。 | 另一个新会话能恢复任务,不必读全部聊天。 |
| 第 6 步:逐步加入自动检查 | 先做路径、链接、生成差异和必要契约测试,再考虑 AI 文档检查。 | 检查能阻止已发生过的真实问题,不制造无效流程。 |
最小上下文组合
项目入口 + 功能契约 + 相关模块知识 + 目标代码与测试 + 最近交接。优先保证这五部分准确,再扩大知识库。RAG、向量检索和自动摘要可以作为规模变大后的手段;这个仓库样本并不能证明它们是启动阶段的必需条件。
衡量有没有改善
- 恢复成本:新会话找到正确文件和下一步需要多长时间。
- 契约返工:字段、默认值、表名、事件名不一致导致的返工次数。
- 文档漂移:已改实现但尚未更新源文档或派生产物的数量。
- 验收真实性:完成记录中有多少条具备实际执行证据。
这些指标是建议的内部观察方式,没有假设 iii 团队已经采用,也没有虚构效率提升比例。
14
证据索引与继续阅读
仓库文件链接固定到本次读取的提交;PR 链接用于查看真实讨论与差异。外部文档转换工具读取的是 v0.4 标签,该标签可能移动。技术建议与模拟内容已在对应章节标明。
S11文档轮转脚本.github/scripts/pin_docs.py
S13SDK 文档生成器docs/next/scripts/generate-api-docs.mts
S32本次分析的提交快照https://github.com/iii-hq/iii/commit/01b15b77f2aefa37b7d3742fc699e0b10750e2ff
建议先读 S02、S03、S20 理解 AI 怎样获得知识;再读 S27、S28 理解提示词为什么也需要迭代;最后看 S08、S10、S25,理解生成、发布和功能 PR 如何衔接。