@mars.liu/dsh-cybernetics 0.2.0 → 0.7.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/docs/protocol.md CHANGED
@@ -1,7 +1,225 @@
1
- # Cybernetics 工作协议 v0.3
1
+ # Cybernetics 工作协议 v0.7(设计稿)
2
2
 
3
3
  目标-行动-测量-校准的迭代回路,构建在 DSH 的 `dsh-workflow` 编排与 `dsh-goal` 持久目标之上。
4
4
 
5
+ ## v0.7 已实现:全量 goal 模式(allGoalsMode)
6
+
7
+ 配置项 `allGoalsMode`(默认 **false**——关闭时注入的提示段、revise 行为与 v0.6 完全一致)。
8
+ 开启后在隐式触发段后追加「ALL-GOALS MODE ACTIVE」路由协议,四条路由规则:
9
+
10
+ > 配置入口(v0.7.1):插件导出 schemastery `Config` schema,`allGoalsMode` 为 volatile 字段——
11
+ > 在 DSH Web 编辑器 Settings → Plugins 的本插件条目面板上直接切换,保存后 loader 把新值
12
+ > 提交进运行实例(不 remount),提示段即时重挂。无需再手改 profile JSON。
13
+
14
+ 1. **全量进 goal**:任何用户请求(问题、检索、分析、改动)一律先建 goal(action `'start'` +
15
+ title/brief)再由 task agent 执行;session agent 禁止用读工具就地完成任务——哪怕单文件
16
+ 查询或一次计算也走回路。硬门关闭时协议同样禁止就地改动:必须委派。
17
+ 2. **简单只读请求 → depth `'quick'`**:单 task agent 一轮,跳过 verify/triage,结果直接反馈
18
+ (有界查询、单文件读取、小型统计)。
19
+ 3. **复杂分析 / 写任务 → depth `'full'` 多轮渐进**:action `'start'` 异步启动,逐轮 `'collect'`
20
+ 收敛,controller 按轮推进 subgoal(task → verify → triage)。分析型 = 取数落盘、数据集、
21
+ 统计、多步查询规划;写任务额外依赖硬门——session agent 永不亲自执行改动,goal 回路是
22
+ 唯一路径,改动再小也一样。
23
+ 4. **revise 自动决策树**:修订仍是 append-only(新 goal + `parentGoalId`,旧 goal 置
24
+ `superseded`,`'revise'` 是唯一目标变更动词),但 `abortPrevious` 缺省时按旧 task agent
25
+ 状态自动决策(数据来自现有 goal 板 running 状态,不新增编排机制):
26
+ - (a) 旧轮**在跑**且修订改写目标本身(传入 `objective`,或 `depth` 变化)→ 目标矛盾/
27
+ 写域冲突 → **自动中止旧轮**(复用 cancel 路径),等价 `abortPrevious: true`;
28
+ - (b) 旧轮**在跑**但目标不变(仅 brief/title/role 修正),旧工作仍可复用/可并行 →
29
+ **等待旧轮自然结束**,等价 `abortPrevious: false`;
30
+ - (c) 旧 task agent **已结束**(goal 板上该 goal 非 running)→ **直接启动新 goal**,
31
+ 不做任何中止动作。
32
+ 显式传 `abortPrevious: true/false` 保持 v0.6 人工控制语义(决策树让位)。每次修订的
33
+ `.cybernetics/revisions-<新goalId>.jsonl` 审计行新增 `abort` 字段
34
+ `{abort, mode: 'auto'|'explicit', basis}`,记录选择的分支与依据;`revise` 返回值同样携带。
35
+
36
+ 实现落点:`src/controller.ts` 的纯函数 `decideAbort`(决策树 + basis 文案);
37
+ `src/index.ts` 的 `ALL_GOALS_GUIDANCE` 提示段与 revise 路径接线。`src/` 改动需宿主重载生效。
38
+
39
+ ## v0.6 设计:与 Agent Teams 集成
40
+
41
+ 2026-11-02 与用户逐条定稿的设计决策。第 0 步验证实验已完成(见文末);执行者适配层
42
+ `executor: 'ephemeral' | 'persistent'` 已实现(见下方「已实现」小节)。
43
+
44
+ 1. **双层修正回路**。内环(行动修正):本轮 subgoal / 委托书,由 session agent 依据 verdict
45
+ 自动调整,每轮记账(现有)。外环(目标修正):goal 的 objective / 范围,**agent 只能提案,
46
+ 用户确认后才生效**——与 dsh-goal「edit 需直接人类输入」的权柄设计一致;修订记录版本号、
47
+ 原因、前后对比、触发轮次。多轮迭代中 goal 保持稳定身份,迭代细化的是 subgoal;
48
+ 仅当反馈证明目标本身错误时才走外环。目标被悄悄改写会摧毁「经 goal 跟踪 agent」的价值。
49
+ (2026-11-02 追加定稿:外环改为 **append-only**——修订创建新 goal 并取代旧 goal,不再原地
50
+ 改 objective、不再用版本号记账;见下文「v0.6 已实现:只新增目标模型」。)
51
+ 2. **委托书修订协议**(持久执行者的消息语义):`send_message` 只允许投递**委托书修订**
52
+ (新增约束 / 验收标准变化 / 范围收窄),禁止开放式对话;每条修订同样进入 round 日志。
53
+ 3. **控制页签合并,不替换**:保留 goal 板作为控制面——外环入口(对某 goal 提交修订意见 →
54
+ 提案 + 确认)与内环观察面(每轮 subgoal 变化与 verdict)。执行者作为 goal 下的行展示
55
+ (状态 running / 静默 / persistent),数据源为 Lead 会话日志的 `team/member` 事件;
56
+ 团队面板是执行者视角,两者互补。
57
+ 4. **上下文不变量(核心)**:所有二级上下文都是**被配给**的,不是被继承的——
58
+ task agent 只拿委托书;verify agent 只拿 goal + 任务报告 + 证据(绝不拿 task agent 的叙述,
59
+ 否则验证被污染);triage 只拿 verdict;持久队员必须 `context: 'fresh'` 投生、消息只许携带
60
+ 委托书修订。**cybernetics 永远不使用 `context: 'fork'`**。持久的是身份和 goal 边界,不是会话历史。
61
+ 5. **执行者基质二选一**(`executor: 'ephemeral' | 'persistent'`,与 depth 正交):
62
+ 一次性/变更类 goal → workflow 临时 agent(schema 校验报告、最省、已验证);
63
+ 迭代型(多轮分析)goal → 持久 teammate(记忆是特性),verify 仍每轮临时、独立。
64
+ 6. **软集成**:运行时优先用 Cordis 的无注入反射读 **`ctx.reflect.get('agentTeams')`**(返回服务值或
65
+ `undefined`,不需要 `inject`,因此既不让 boot pend 也不抛代理异常);没有反射缝的宿主/测试替身
66
+ 回退到 **try/catch 安全访问器**读 `ctx.agentTeams`(Cordis 的 context 代理在读取未注入的服务属性时
67
+ 会直接抛错,不能当成「服务不存在」)。两者都取不到则回退 workflow(不硬绑实验包)。
68
+ `spawnTeammate` 仅 Team Lead 可调——cybernetics 作为 Lead 的工具调用天然满足;
69
+ goal 板保持唯一真相,不双写 team task 板;每 goal 至多一个执行者;
70
+ goal 完成/cancel 时 `interrupt` + 清理常驻队员。
71
+ 7. **分步**:第 0 步(验证):allowlist 加入 `spawn_teammate`/`send_message`/`interrupt_agent`,
72
+ 手工养一名分析师跑真实多轮知识库分析,验证协作形态;通过后再实现 Executor 适配层
73
+ (`LoopState.executor` + 外环 revision 记账 + 控制页签执行者行)。
74
+
75
+ ### v0.6 已实现:执行者适配层(Executor)
76
+
77
+ - `executor: 'ephemeral' | 'persistent'`(与 depth 正交):ephemeral 仍是 v0.5 的 workflow
78
+ 临时 agent;persistent 用 Agent Teams 的持久 teammate 执行 task 工作。
79
+ - `src/executor.ts` 的 `startTeamRound`:首轮 `spawnTeammate(context:'fresh')`,后续轮
80
+ `sendMessage` 投递「委托书修订」;用宿主 `subagent/end` 事件(info.id = 子会话 id,
81
+ info.output = ContentBlock[])捕获每轮最终输出;被取消的轮会先摘除自己的等待者,
82
+ 不会抢走后继轮的 settle 事件。
83
+ - quick:由 teammate 输出派发 verdict(输出契约要求最后一行
84
+ `{"done": bool, "summary": "...", "evidence": "..."}`,缺失标记即视为未完成)。
85
+ - full:teammate 的文本报告按 task 报告结构交给 `workflows/round.js` 的 `args.taskReport`,
86
+ task agent 被跳过,verify/triage 仍以临时 agent 独立运行——验证不继承任务叙述。
87
+ - 软集成:运行时探测用 `agentTeamsOf()`——优先 `ctx.reflect.get('agentTeams')`(Cordis 的无注入反射读,
88
+ 取不到返回 `undefined`,不抛错、不需 `inject`),再回退 try/catch 读 `ctx.agentTeams`(旧宿主/测试
89
+ 替身;Cordis 未注入时会抛错,安全访问器把它折叠成 `undefined`)。任何一路都取不到即回退;因此
90
+ persistent 报的是结构化错误(`needs Agent Teams … fall back to executor "ephemeral"`),
91
+ 不是 Cordis 代理异常。
92
+ - 审计:round 日志记录 `executor`;goal 板记录 `memberName`(跨轮复用同一 teammate)。
93
+
94
+ ### v0.6 已实现:多 goal 投影与页签
95
+
96
+ dsh-goal 的 `goal` 投影每 session 只有一个焦点槽,`cyb-*` 多 goal 板在「目标」页签里不可见。
97
+ 本版新增插件自有 session 投影 `cyberneticsGoals`:每个写点(goal 创建、轮次启动、轮次结算决策、
98
+ cancel)把该 session **全部 goal 的整值快照** append 成一条 `cybernetics/goals` 事件,
99
+ projection 纯折叠后由宿主把整值推给客户端,页签按**两段顺序**渲染每个 goal
100
+ (未完成组在前、已完成组在后,组内 `updatedAt` 倒序;见下节「只新增目标模型」)
101
+ (标题 / 状态徽标 / 第 N 轮 / 当前 subgoal / depth、executor 小标签)并就地更新;
102
+ 空板回退到原有单 goal `goal` 投影渲染。`GoalView` 已预留 `executor` 与 `revisions` 字段(当前
103
+ 固定 ephemeral / 空数组):`executor` 待 Executor 适配层接入,`revisions` 在下面的 append-only
104
+ 模型下仅作兼容占位。
105
+
106
+ 已知边界:goal 板是**进程内存态**(`boards`),所以每个写点同时把整板快照到
107
+ `<workspace>/.cybernetics/board-<sessionId>.json`,首次触碰空板时再 rehydrate(见下节
108
+ 「板持久化与 rehydrate」);重启后「目标」页签与 controller 板由此重新一致。
109
+
110
+ ### v0.6 已实现:板持久化与 rehydrate
111
+
112
+ 问题:`boards` 是进程内存态,而 projection 只能重放**某个进程写过**的
113
+ `plugin:cybernetics/goals` 事件。宿主重启后(尤其旧进程从未写过事件时)controller 板为空、
114
+ 页签也没有历史,用户无法再「分别跟踪」各 goal。
115
+
116
+ - **快照文件**:`<workspace>/.cybernetics/board-<sessionId>.json`,每 session 一份,JSON 为
117
+ `{ version, sessionId, savedAt, goals: LoopState[] }`,`version` 当前为 `1`。
118
+ `sessionId` 取 `exec.agent.session.id`;文件名只保留 `[A-Za-z0-9._-]`(其余替换为 `_`),
119
+ 避免任何路径逃逸。`LoopState` 的 `goalId`/`title`/`objective`/`round`/`doneSummary`/
120
+ `subgoal`/`role`/`depth`/`executor`/`memberName`/`status`/`paused`/`parentGoalId`/
121
+ `supersededBy`/`revisions`(以及 `brief`)都随快照保存。
122
+ - **写点**:所有 board 变更(goal 创建、adopt dsh-goal 焦点 goal、`revise`/`supersede`、
123
+ `cancel`、`round`/`start` 启动前、`collect`/阻塞轮结算决策后)都经过
124
+ `publishBoard()`:先推 projection 事件,再原子落盘(同目录临时文件 + `rename`,
125
+ 读方永远看不到半截 JSON)。落盘失败只吞掉(`try/catch`),只读工作区照样能跑轮次。
126
+ - **读点**:工具 `execute` 首次拿到某个 session 的空内存板时,从快照恢复;文件不存在 /
127
+ 非法 JSON / `version` 不符 / sessionId 不符 / goal 记录不可用 → 一律视为空板,绝不抛错
128
+ (半手改或半写入的快照只丢坏记录)。恢复成功后立即 `publishBoard()` 一次,把整板作为一条
129
+ `plugin:cybernetics/goals` 事件写回——页签不用等下一轮就显示历史 goal。
130
+ - 边界:快照是**当前状态**,不是事件日志(事件日志仍在 session 里);`updatedAt` 不持久化,
131
+ 恢复后按本次 publish 重新计时,因此跨进程的组内排序在时间戳相同时按 `goalId` 兜底。
132
+ 中途被杀死的轮会以 `status: 'running'` 恢复但已无运行句柄(`list` 的 `running` 为 false),
133
+ 下一次 `round`/`start` 会正常重新启动。
134
+
135
+ ### v0.6 已实现:控制页签执行者行
136
+
137
+ 「控制 / Control」页签保留原有的 agent 树(主控 + subagent catalog 的运行状态与各自
138
+ dsh-goal 视图),并在顶部新增 **goal 执行者行**:每个 goal 显示 状态徽标 + 标题 +
139
+ 执行者(临时/持久)+ 持久 teammate 名称(`GoalView.memberName`,仅 `executor: 'persistent'`
140
+ 且已投生时出现)+ 第 N 轮。顺序与「目标」页签同一规则:未完成组在前、已完成组
141
+ (met/cancelled/superseded)在后;组内保持服务端投影顺序,客户端只做一次稳定分组、
142
+ 不重排。数据源就是同一份 `cyberneticsGoals` 整值投影(实时推送),没有第二套状态。
143
+ `GoalView.memberName` 为可选字段,投影 `normalizeGoal` 折叠时保留,无成员时不出现在
144
+ wire 上。
145
+
146
+ ### v0.6 已实现:只新增目标模型(append-only goals)
147
+
148
+ 2026-11-02 用户定稿,替代设计稿第 1 条中「多轮迭代 goal 保持稳定身份、修订记录版本号」的做法:
149
+ **goal 一旦存在就不再被原地修改**。目标变了就换一个新 goal,旧 goal 保留其最终状态。身份与历史
150
+ 由 goal 链表达,而不是由同一 goal 的可变字段表达。
151
+
152
+ - **修订 = 新建**。`cybernetics { action:'revise', goalId, reason, objective?, title?, depth?,
153
+ executor?, abortPrevious? }`:新 goal 继承旧 goal 的 `depth`/`executor`/`role`/`objective`
154
+ (`objective`/`title`/`depth`/`executor` 可用参数覆盖),写入 `parentGoalId = 旧goalId`,
155
+ 状态 `running` 并**立即启动第 1 轮**(后台语义,返回值 `goalId` 为新 goal,`started: true`);
156
+ 旧 goal 状态置 `superseded`、写 `supersededBy = 新goalId`,此后不再是可驱动的 goal。
157
+ 对**已完成(met/cancelled)的 goal 修正是同一条路径**——同样生成新 goal,旧 goal 被取代。
158
+ - **`revise` 是唯一的改目标动词**,只有 session agent 在用户确认后调用;`reason` 必填。
159
+ 工具不会原地改写 objective;被取代的 goal 再次 revise 会被拒绝(`already superseded`),
160
+ 以免谱系分叉。
161
+ - **旧轮是否中止由 session agent 裁定**:`abortPrevious: true` 时复用 cancel 路径中止旧 goal
162
+ 在跑的 task agent 轮并释放句柄,`false`(默认)时让旧轮跑完——它结算后不再产生 collect
163
+ 通知(该 goal 已被取代),句柄由结算回调清理。
164
+ - **审计**:每次修订追加一行到 `<workspace>/.cybernetics/revisions-<新goalId>.jsonl`:
165
+ `{from, to, reason, at}`。旧 goal 的 per-round 日志(`round-<旧goalId>-<N>.json`)原样保留,
166
+ 谱系两侧都能追溯。写审计失败不影响修订(只读工作区也不阻断)。
167
+ - **页签排序(两段)**:未完成组(running/paused/pending/failed)在前,已完成组
168
+ (met/cancelled/superseded)在后;组内按 `updatedAt` 降序,`goalId` 兜底打破同毫秒平局。
169
+ 排序在服务端 `goalsFromBoard` 完成,客户端按投影顺序渲染、不重排。
170
+ - **派生的展示关系**:goal 有 `supersededBy` 时显示「已被 <新标题> 取代」小字;有
171
+ `parentGoalId` 时显示「修订自 <旧标题>」。`GoalView` 的 `parentGoalId`/`supersededBy` 是可
172
+ 选字段(无谱系时不出现),`GoalStatus` 增加 `'superseded'`,投影 `stateVersion` 升到 2。
173
+ - **`revisions` 字段**:保留在 `LoopState`/`GoalView` 作兼容占位,append-only 模型下不再写入
174
+ (修订历史在 goal 链 + revisions jsonl 里)。
175
+
176
+ 已知边界:`superseded` 只发生在插件自有 goal 板上;dsh-goal 的单槽焦点 goal 不会随之迁移
177
+ (新建普通 goal 时的焦点同步逻辑未改),焦点槽里的旧 goal 需由 session agent 另行处理。
178
+
179
+ ## v0.5 变化:双档轮次(depth)——分析任务分级
180
+
181
+ 分析/查询类任务按复杂度分两级进入 goal 体系(用户 2026-11-02 定稿):
182
+
183
+ - **琐碎只读问答**(读工具一步可答的事实,无计算)→ session agent 直接答,不建 goal。
184
+ - **轻量分析**(边界清晰、无需多步规划的查询)→ 建 goal,`depth: 'quick'`:
185
+ 只跑 task agent 单 agent,一轮出结果直接反馈;跳过 verify/triage,成本约 1/3。
186
+ verdict 由 task report 派生(done → met),controller 决策逻辑不变。
187
+ - **复杂分析与一切变更**(取数到本地、数据集统计、多步查询规划、任何状态改变)→
188
+ 建 goal,`depth: 'full'`(默认):完整 工作→验证→分诊 循环,验收通过才交付。
189
+ 指导段明令禁止用 quick 轮抄近路做变更或复杂分析。
190
+
191
+ 实现:round.js 按 `args.depth` 分支(热生效);`LoopState.depth` 逐轮可覆盖;
192
+ 工具参数 `depth` 枚举 quick/full。
193
+
194
+ ## v0.4 变化:硬门(hard gate)——编排从劝告变成结构
195
+
196
+ v0.3 及以前,「session agent 不亲自执行」是系统提示里的劝告,模型可自行判断绕过
197
+ (琐碎任务直接内联完成)。v0.4 增加可选的**硬门**(`hardGate: true`):
198
+
199
+ - 实现:插件注册 `system-prompt/assemble` waterfall 监听器(dsh-system-prompt 的官方扩展点,
200
+ 每个模型步触发,可变 assembly、返回值权威),在装配期把执行类工具
201
+ (默认 `bash`/`edit`/`write`,可用 `gatedTools` 覆盖)从**顶层 session agent** 的
202
+ 工具清单中物理移除——模型根本看不到这些工具,无法调用。
203
+ - 判定顶层 agent 用 `ctx.agents.roots()`(与 dsh-tool-goal 同一 API);
204
+ workflow 子 agent(task/verify/triage)与 team 成员从不在 roots() 里,
205
+ 它们的装配原样通过,保留全部工具——执行能力只属于被编排的执行者。
206
+ - 配套提示段追加 HARD GATE ACTIVE 声明,防止模型把「没有 bash」误读为环境故障。
207
+ - 默认关闭,部署侧通过 `cordis.patch.yml` 的 `config.hardGate: true` 开启。
208
+ - 设计动机(用户 2026-11-02):思考与行动分离;人类经 goal 跟踪/解释 agent 行为;
209
+ 每个 task agent 在有限 goal 上紧凑运行;修正任务(cancel/重启)更自由。
210
+ - 已知边界:门在装配层(模型看不见工具),不在执行层(无公开拦截缝);
211
+ `subagent`/`workflow` 等其他派发工具默认不在门禁清单,如需收口加入 `gatedTools`。
212
+
213
+ ### v0.4.1:allowlist 模式(denylist 的覆盖缺口修复)
214
+
215
+ 实机暴露的缺口:denylist 默认只挡 bash/edit/write,session agent 用 `farm_unregister`
216
+ 直接删了服务而未建 goal——变更类工具是长尾(farm_*/taskboard_*/knowledge_save/schedule_*/uno_*…),
217
+ 逐名封堵永远补不完。`gateMode: 'allowlist'` 反转语义:顶层 agent 只保留
218
+ **读 + 对话 + 展示 + goal/编排动词**(内置 DEFAULT_GATE_ALLOWLIST,可 `gateAllowlist` 覆盖),
219
+ cybernetics 工具自身始终豁免。语义随之明确:**只读问答无需 goal 直接答;
220
+ 任何「改变世界」的请求——无论多小——都是委派信号**(找不到工具即硬门在起作用)。
221
+ 本部署 cordis.patch.yml 已启用 allowlist 模式。
222
+
5
223
  ## v0.3 变化:多 goal + 编排者 session agent
6
224
 
7
225
  - **同一 session 支持多个并发 goal**:插件维护自己的 goal 板(`boards: session -> goalId -> loop`)。
@@ -40,8 +258,10 @@
40
258
 
41
259
  1. **新任务** → `cybernetics { action:'start', title, brief }` 建 goal 并后台启动 task agent;
42
260
  `brief` 是完整工作委托书(背景、路径、约束、验收标准),详细到 subagent 无需对话历史即可完成。
43
- 2. **已有任务的修正** → 裁决打断或等待:打断 = `cancel` 该 goalId 后以修正内容重写 brief 重启一轮;
44
- 等待 = `collect` 收完当轮后,以 verdict gaps + 修正内容构造新一轮。
261
+ 2. **已有任务的修正** → `revise`(append-only):`{ action:'revise', goalId, reason, objective?,
262
+ brief?, title?, depth?, executor?, abortPrevious? }` 创建新 goal(`parentGoalId`=旧)并立即启动
263
+ 第 1 轮,旧 goal 置 `superseded`;`abortPrevious` 由 session agent 裁定是否中止旧轮(默认 false)。
264
+ 仅想中止当前轮而不改目标时用 `cancel`,再对同一 goal 开修正轮。
45
265
  3. **反馈到达**(`round` 的返回值,或异步轮完成通知后的 `collect`)→ 三选一或组合:
46
266
  向用户总结;启动验证轮;以缺口为 brief 启动修正轮。
47
267
 
@@ -63,6 +283,8 @@
63
283
  1. `met=true` → 报告完成,**等用户确认**;controller 不自行宣告、不代改 goal phase。
64
284
  2. `goalItselfQuestionable=true` 或存在 human 类目 → 暂停,回对话。
65
285
  3. 连续迭代上限(默认 3 轮/子目标,总轮数由 dsh-goal round cap 兜底)→ 暂停并汇报。
286
+ 4. goal 被修订取代(`superseded`)是 dsh-goal 视角之外的终态:该 goal 不再被驱动、不再收轮,
287
+ 后续工作属于 `supersededBy` 指向的新 goal。
66
288
 
67
289
  ## 角色化 sub agent
68
290
 
@@ -83,6 +305,34 @@ Config `roles` 表把角色名映射到 `{provider, model}` 覆盖,round 脚
83
305
 
84
306
  - 每轮结构化结果落 `<workspace>/.cybernetics/round-<goalId>-<N>.json`(追加式审计日志;
85
307
  goalId 进文件名,防止多 goal 各自从 1 计轮互相覆盖——v0.3 实机实测发现并修复)。
308
+ - v0.6 追加式目标模型:每次修订落 `<workspace>/.cybernetics/revisions-<新goalId>.jsonl`,
309
+ 一行 `{from, to, reason, at}`;旧 goal 的 round 日志保持不变,修订前后都可追溯。
310
+ - v0.6 板持久化:每个 session 的 goal 板整值快照落
311
+ `<workspace>/.cybernetics/board-<sessionId>.json`(`{version, sessionId, savedAt, goals}`),
312
+ 重启后首次工具调用即 rehydrate 并重推 projection(见「板持久化与 rehydrate」)。
86
313
  - goal 状态由 dsh-goal 的 session projection(`goal` 投影)承载,客户端「目标 / Goal」页签
87
314
  (`lib/client.js`,conversation.view slot)实时读取渲染:objective 文本 + phase + rounds。
88
315
  v0.2 为纯文本渲染;后续演进:任务分解、状态跟踪、verdict 历史可视化(参照 dsh-context 范式)。
316
+ - v0.6 起该页签优先读插件自有投影 `cyberneticsGoals`:一个 session 的全部 goal(含 `cyb-*`)
317
+ 逐条展示并就地更新(被取代的 goal 标注后继标题,修订来的 goal 标注来源标题);
318
+ `goal` 投影保留为无多 goal 数据时的回退渲染。
319
+
320
+ ## 第 0 步实验记录(2026-11-02)
321
+
322
+ 配置:teammate `analyst`,`context: 'fresh'`,provider `spawn`;两轮真实知识库分析:
323
+ 首轮委托书(talent_portrait/profile 数据质量评估),次轮委托书修订(423 份 11-01 后刷新批次的
324
+ delta 对比 + 压缩为 3 条决策要点)。
325
+
326
+ 观察:
327
+ 1. **持久记忆生效**:次轮引用了首轮自身结论(「陈志波 92 vs 24」不一致案例、student/researcher
328
+ 分面基线),未重做首轮工作;次轮墙钟约为首轮一半。持久身份 + goal 边界成立,
329
+ 会话历史只在本队员内累积,符合上下文不变量。
330
+ 2. **委托书修订语义可行**:只收到增量要求,按约定三段式(分布表/对比结论/3 条要点)交付,
331
+ 无开放式对话漂移。
332
+ 3. **自主分析质量超出委托书要求**:自行发现 PII 入正文、markdown↔JSON 漂移、4% null 维度、
333
+ 测试与规范节点混入、1.71 节点/人等——fresh 上下文 + 详细委托书足以支撑高质量领域判断。
334
+ 4. **只读约束被遵守**:仅写 `.cybernetics/tmp/probe.json`;报告明确说明 401 后未去读取凭据。
335
+ 5. 成本未精确计量;墙钟首轮约 4 分钟、次轮约 3 分钟。
336
+
337
+ 结论:支持 v0.6 `executor: 'persistent'` 方向。下一步:Executor 适配层(workflow/team 两种传输)
338
+ + 外环 revision 记账 + 控制页签执行者行。