docs(subsystems): open core.md on agent creation/ownership and the Agent contract; enforce a complete folder index

core.md claimed to be the packages/core reference but opened on repo-wide type patterns and never documented the ownership vocabulary: AgentHandle, CreateAgentOptions, ResumeAgentOptions, and AgentFactory were TYPE_LINK_EXEMPTIONS pointing at a package README, invisible to the folder that calls itself the type reference. The page now reads spine map -> creation and ownership (AgentHandle pasted; the options and factory summarized with links into the generated registry section) -> the Agent handle (AgentStatus, AgentOptions, SteeringOutcome, SteeringReceipt, and SettleReason now pasted; the one settlement prose wall split by topic; delivery vocabulary ordered as a message travels) -> initiator -> interception -> a Sessions summary -> the ToolDefinition pointer -> an explicitly framed repo-wide patterns tail (the ...Map pattern, branded ids). The duplicate SessionEvent paste is gone -- session.md owns it and LINK_MAP follows -- the four ownership types moved from TYPE_LINK_EXEMPTIONS into LINK_MAP -> core.md, and three dead LINK_MAP entries (ContinuationDecision, ContinuationStop, HookContext) no longer name types absent from the source tree. The "what this page owns" meta-section folds into the intro.

The subsystems README index silently lost tasks.md and session-reference.md on both language sides during a base absorption; the rows are restored and scripts/project-doc-site.spec.ts now fails when any page misses either side of the index (proven red on a removed row). tools.md links ToolSchema to its llm-streaming.md declaration instead of calling it core; subagent.md links AgentHandle and CreateAgentOptions.seed to the new section. A new Agent Note records the package-anchored page-scoping decision; the 2026-06-20 catalog note marks its spine-vs-seam rule superseded as the page-scoping rule while keeping the type-equiv mechanism current, and docs/AGENTS.md cites the new note.
This commit is contained in:
Tianyi Cui
2026-08-03 16:34:00 +08:00
parent aa0ca6c836
commit a2aa567371
46 changed files with 1126 additions and 1034 deletions

View File

@@ -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/process/2026-06-20-core-data-structures-catalog.md
2026-06-20-core-data-structures-catalog.md: b358ad54652e5b16ae90037c128cf756bcfdaed3
2026-06-20-core-data-structures-catalog.zh.md: d84c2befaee4c2032b358ed1a7949ac0151ae74c
2026-06-20-core-data-structures-catalog.md: 9a3f80df592f28adc365d5e64cc15516d92b47b5
2026-06-20-core-data-structures-catalog.zh.md: 96c606a3d65a67e757960c5cbc997e717f11e8d5

View File

@@ -16,6 +16,8 @@ A new `docs/subsystems/` folder catalogs the vocabulary, with a new `verify-type
### What counts as "core" — the spine-vs-seam line
> **Superseded as the page-scoping rule** by [package-anchored subsystem pages](2026-08-03-package-anchored-subsystem-pages.md): each page now anchors to the package group that declares its vocabulary. The `ts type-equiv` mechanism below remains current.
The scoping line was not picked top-down; it was discovered by testing candidate definitions against concrete borderline types until one rule survived every case. The decisive test was `BashExecRequest`/`BashExecSpec`/`BashRunResult`: bash is a capability *seam*, not part of the agent-loop spine, so if those are "core" then "core" means *all cross-package vocabulary* and the catalog is a flat dump; if they are not, "core" means *the central spine* and bash vocabulary belongs on its own seam page. The latter won, which set the whole structure: a **tiered folder**, not a flat document.
The rule that settled the remaining cases: ***the type you write, hold, or receive is core; the machinery that types it, renders it, or persists it is a seam-page detail.*** Worked through:

View File

@@ -16,6 +16,8 @@ Status: implemented
### 何为「核心」——主干与 seam 的分界线
> **作为页面范围界定规则已被取代**,见[按包锚定的子系统页面](2026-08-03-package-anchored-subsystem-pages.md):每页现在锚定到声明其词汇的包分组。下文的 `ts type-equiv` 机制仍然有效。
范围界定并非自上而下拍定,而是将候选定义逐一对照具体的边界类型反复测试,直到一条规则在所有案例中都成立。决定性的测试是 `BashExecRequest`/`BashExecSpec`/`BashRunResult`bash 是一个能力 *seam*,不属于 agent loop智能体循环主干如果这些算「核心」那么「核心」就意味着*所有跨包词汇*,目录沦为平铺罗列;如果不算,「核心」就意味着*中央主干*bash 词汇归入子页面。后者胜出,由此确定了整体结构:一个**分层文件夹**,而非一份平铺文档。
确定其余案例的规则是:***你编写、持有或接收的类型是核心;为其提供类型推导、渲染或持久化的机制是子页面细节。*** 逐一验证如下:
@@ -25,7 +27,7 @@ Status: implemented
- `ToolSchema` 是核心(它是流经每个步骤的模型请求 `GenerateOptions` 的一个字段),即使它在概念上属于工具流水线——当*流经主干*与*概念归属*冲突时,前者胜出。
- 工具展示词汇(`ToolCallView`/`ToolResultView` 等)、`SessionPersistence` 持久性 seam 以及 bash 词汇是子页面。
`core.md` 是一份**自包含的主干文档**:它给出每个主干结构的确切类型定义,辅以最少的行文,并链接到页面获取各 seam 的细节。子页面包括 `llm-streaming.md``session.md``persistence.md`(沿内存模型与持久性 seam 的分界线从会话页面拆出)、`tools.md``bash.md`
`core.md` 是一份**自包含的主干文档**:它给出每个主干结构的确切类型定义,辅以最少的行文,并链接到同级 seam 页面获取各 seam 的细节;目录的 [README](../../../../docs/subsystems/README.md) 索引全部页面。最初的 seam 页面包括 `llm-streaming.md``session.md``persistence.md`(沿内存模型与持久性 seam 的分界线从会话页面拆出)、`tools.md``bash.md`
### `ts type-equiv` 机制——既逐字又防漂移

View File

@@ -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 .agents/notes/implemented/process/2026-08-03-package-anchored-subsystem-pages.md
2026-08-03-package-anchored-subsystem-pages.md: 5ba7937f0c142727d343a107a3ff87f5f337931e
2026-08-03-package-anchored-subsystem-pages.zh.md: 27d56158a69a8144b0915054032fb3b54493bd0b

View File

@@ -0,0 +1,34 @@
# Agent Note: Package-anchored subsystem pages and thin group READMEs
Status: implemented
English | [中文](2026-08-03-package-anchored-subsystem-pages.zh.md)
## Problem
The [subsystems catalog](2026-06-20-core-data-structures-catalog.md) scoped its front page by the spine-vs-seam rule: a type was "core" if the loop holds, derives, streams, or logs it on every turn. That rule selected types, not packages, so as the folder grew to forty-plus pages the front page became a cross-package grab-bag: LLM conversation vocabulary sat above the agent contracts, the creation/ownership vocabulary (`AgentHandle`, `CreateAgentOptions`, `ResumeAgentOptions`, `AgentFactory`) was documented nowhere in the folder because the generator exempted it to a package README, and a reader could not predict which page documents a type from where the type lives. Package-group READMEs meanwhile had no common shape — some carried sectioned tables, stray design essays, or trailing paragraphs that belonged on a subsystem page.
## Decision
Every `docs/subsystems/` page anchors to the package or package group that declares its vocabulary, and page membership follows the repository layout: [core.md](../../../../docs/subsystems/core.md) is the `packages/core` page (creation and ownership, the `Agent` handle with its delivery/cancellation/interception contracts, pointers to the group's dedicated pages), [llm-streaming.md](../../../../docs/subsystems/llm-streaming.md) owns `packages/llm` end-to-end, and so on. Repo-wide type patterns (`…Map → derived-union`, branded ids) stay on core.md in an explicitly framed closing section rather than interleaved with the package content. This supersedes the spine-vs-seam rule *as the page-scoping rule*; the placement heuristic that survives is simpler: a type is documented where its declaring package's page is, and machinery keeps living with its machinery.
Every type a generated signature references must resolve somewhere in the folder: the agent ownership vocabulary moved from the generator's `TYPE_LINK_EXEMPTIONS` into `LINK_MAP → core.md`, so exemptions are reserved for genuinely service-local or vendored shapes. Each pasted declaration has one home (`SessionEvent` lives on [session.md](../../../../docs/subsystems/session.md); core.md summarizes and links).
Every `packages/<group>/README.md` pair is a thin front door in one shape: a why-first intro paragraph, a package table (Package / Role / ctx key), and a closing pointer to the owning subsystems page. Load-bearing prose that outgrows that shape relocates to the owning subsystems page rather than being deleted.
The [subsystems README](../../../../docs/subsystems/README.md) indexes every page in the folder on both language sides; `scripts/project-doc-site.spec.ts` enforces one table row per page, so a page added by a later PR (or absorbed in a merge) cannot silently miss the index.
## Alternatives considered
**Keep the spine-vs-seam scoping rule.** It answered "is this type core?" per type, which is why the front page accumulated types from four packages while missing half of `packages/core/agent`'s public surface. Predictability by repository layout won.
**A flat single-document catalog.** Already rejected in the [original catalog note](2026-06-20-core-data-structures-catalog.md); the growth to forty-one pages confirmed that verdict.
**Document ownership vocabulary only in package READMEs (the exemption status quo).** This left `AgentHandle` and the create/resume options invisible to the folder that claims to be the type reference, and the generated `Types:` footers could not link them.
## Consequences
- Which page documents a type is predictable from `packages/<group>/`; the subsystems README is a complete index enforced by test.
- Generated signature footers link the agent ownership vocabulary instead of silently exempting it.
- `verify-type-equiv`'s 1:1 manifest keeps each paste single-homed; the duplicate `SessionEvent` paste is gone.
- The [original catalog note](2026-06-20-core-data-structures-catalog.md) remains the owner of the `ts type-equiv` drift-gate mechanism; only its page-scoping rule is superseded here.

View File

@@ -0,0 +1,34 @@
# Agent Note按包锚定的子系统页面与轻薄的分组 README
Status: implemented
[English](2026-08-03-package-anchored-subsystem-pages.md) | 中文
## Problem
[子系统目录](2026-06-20-core-data-structures-catalog.md)最初用主干-vs-seam 规则界定首页范围如果循环在每个轮次都持有、派生、流式传输或记录某个类型它就是「核心」。该规则选择的是类型而非包因此当目录增长到四十多页后首页变成了跨包大杂烩LLM 对话词汇排在 agent 契约之前,创建/所有权词汇(`AgentHandle``CreateAgentOptions``ResumeAgentOptions``AgentFactory`)在目录中无处记录(生成器把它们豁免给了某个包 README读者无法根据类型所在位置预测哪一页记录它。与此同时各包分组 README 没有统一形状——有的带分节表格、游离的设计短文,或本应属于子系统页面的尾部段落。
## Decision
每个 `docs/subsystems/` 页面锚定到声明其词汇的包或包分组,页面归属跟随仓库布局:[core.md](../../../../docs/subsystems/core.md) 是 `packages/core` 的页面(创建与所有权、`Agent` 句柄及其投递/取消/拦截契约、指向该组专属页面的指针),[llm-streaming.md](../../../../docs/subsystems/llm-streaming.md) 端到端拥有 `packages/llm`,依此类推。全仓通用类型模式(`…Map → 派生联合`、品牌化 id保留在 core.md 一个明确标注的收尾小节中,而不是与包内容交错。这在*页面范围界定规则*的意义上取代了主干-vs-seam 规则;存活下来的放置启发式更简单:类型记录在其声明包对应的页面,机制仍与其机制放在一起。
生成签名引用的每个类型都必须能在目录中某处解析agent 所有权词汇从生成器的 `TYPE_LINK_EXEMPTIONS` 移入 `LINK_MAP → core.md`,因此豁免只留给真正服务本地或 vendored 的形状。每个粘贴的声明只有一个家(`SessionEvent` 位于 [session.md](../../../../docs/subsystems/session.md)core.md 概括并链接)。
每个 `packages/<group>/README.md` 配对都是统一形状的轻薄门面:一段以「为什么」开头的介绍、一张包表格(包 / 角色 / ctx 键)、一个指向拥有方子系统页面的收尾指针。超出该形状的承重散文迁移到拥有方子系统页面,而非删除。
[子系统 README](../../../../docs/subsystems/README.md) 在两个语言侧索引目录中的每一页;`scripts/project-doc-site.spec.ts` 强制每页一行表格,因此后续 PR 新增(或合并吸收)的页面无法悄悄缺席索引。
## Alternatives considered
**保留主干-vs-seam 界定规则。**它逐类型回答「这个类型是核心吗?」,这正是首页积累了四个包的类型、却缺失 `packages/core/agent` 一半公开 surface 的原因。按仓库布局可预测性胜出。
**扁平的单文档目录。**在[原目录 note](2026-06-20-core-data-structures-catalog.md) 中已被否决;增长到四十一页证实了该结论。
**只在包 README 中记录所有权词汇(豁免的现状)。**这让 `AgentHandle` 与 create/resume 选项在自称类型参考的目录中不可见,生成的 `Types:` 页脚也无法链接它们。
## Consequences
- 哪一页记录某类型可由 `packages/<group>/` 预测;子系统 README 是由测试强制的完整索引。
- 生成的签名页脚链接 agent 所有权词汇,而不是静默豁免。
- `verify-type-equiv` 的 1:1 manifest 保证每个粘贴单一归属;重复的 `SessionEvent` 粘贴已移除。
- [原目录 note](2026-06-20-core-data-structures-catalog.md) 仍拥有 `ts type-equiv` 漂移检查机制;此处仅取代其页面范围界定规则。