11A PRESET / GENERATIONS

同一个 id,为什么保留两棵树?

从替换 standard 声明后的时点开始,比较旧 Agent A、继承旧代的子 Scope C,以及新 Agent B。

01 / 沿退出过程检查

A 与 C 都保留 G1

A 仍使用 old-tool,子 Scope C 继承 G1;新 Agent B 使用 G2 的 new-tool。

旧 G1:users = 2 · retired = true | 新 G2:users = 1 · retired = false

C 继续保留 G1

A 的引用已经释放;C 仍持有 G1,旧树继续存在。

旧 G1:users = 1 · retired = true | 新 G2:users = 1 · retired = false

G1 可以回收

旧代已退役且没有使用者,Scope 退出;G2 和 B 继续运行。

旧 G1:users = 0 · retired = true | 新 G2:users = 1 · retired = false

同名 Preset 的两代 Scope 与使用者G1 由旧 Agent A 和子 Scope C 保留,G2 由新 Agent B 保留。退出对象以虚线保留位置,表示历史关系而非仍然存活;G1 只有退役且使用者为零时回收。A 的绑定继承同一代新建时绑定G1 · standard已退役 · users = 2已退役 · users = 1已退役 · users = 0G2 · standard当前声明 · users = 1旧 Agent Aold-tool已退出已退出子 Scope C保留 G1保留 G1已退出新 Agent Bnew-tool
Preset 修订Agent / Scope虚线:已退出对象或历史绑定

旧 G1 → A、Cusers = 2,retired = true;A 与 C 都保留 G1。

新 G2 → B当前 standard 声明指向 G2,B 看到 new-tool。

旧 G1 → A、Cusers = 1,retired = true;C 继续保留 G1。

新 G2 → B当前 standard 声明指向 G2,B 看到 new-tool。

旧 G1 → A、Cusers = 0,retired = true;G1 可以回收。

新 G2 → B当前 standard 声明指向 G2,B 看到 new-tool。

02 / 声明、工具与回收分别检查

A: old-tool
C: 继承 G1 的 old-tool
B: new-tool

根作用域没有这两套 Preset 工具。
A: 已退出
C: 继承 G1 的 old-tool
B: new-tool

根作用域没有这两套 Preset 工具。
A: 已退出
C: 已退出
B: new-tool

根作用域没有这两套 Preset 工具。
当前声明列表: standard → G2
实际保留修订: G1、G2

list() 读声明;inspectCompositions() 读保留代。
当前声明列表: standard → G2
实际保留修订: G1、G2

list() 读声明;inspectCompositions() 读保留代。
当前声明列表: standard → G2
实际保留修订: G2

list() 读声明;inspectCompositions() 读保留代。
G1.retired = true
G1.users = 2
collect: 等待最后一个使用者退出

图中 users 只统计 A、C 和 B;只读租约也可以持有引用。
G1.retired = true
G1.users = 1
collect: 等待最后一个使用者退出

图中 users 只统计 A、C 和 B;只读租约也可以持有引用。
G1.retired = true
G1.users = 0
collect: 释放 G1 Scope

图中 users 只统计 A、C 和 B;只读租约也可以持有引用。
查看实验依据与边界

来自本文真实 AgentLoop 与 Preset Registry 的修订实验。C 是通过 composeFrom 加入旧代的子 Scope,未执行子 Agent 的模型任务。G1/G2 为解释用代号;图中没有画临时 retain 引用和读取租约。

composeFrom 继承父 Scope 实际加入的代,不按 id 重新选择最新声明。Scope 父链表示贡献可见性,不能据此推断 parentAgent 或调用方 Fiber 所有权。