问题
默认 explicit discovery 下,/goal <objective> 创建 Goal、或恢复已有 active Goal 后,Runtime 可以开始续跑,但模型完成或报告阻塞所需的 get_goal / update_goal 仍可能被 capability gate 隐藏。
这使 Goal 的执行状态与模型可用工具脱节:模型已经收到“完成后调用 update_goal”的续跑指令,却没有这个工具。
价值
让用户已经明确启动的 Goal 能正常查看状态、报告阻塞并完成收尾,避免工作完成后仍继续消耗回合;普通新 Session 继续保持零常驻 OpenPI 工具。
审计边界
触发方式
- 使用默认
capabilities.discovery = explicit,进入未加载 session 能力组的新 Session。
- 执行
/goal 修复 README 的一个拼写错误;或者重新打开具有相同 objective 的 active Goal Session。
- Goal 创建/恢复后启动 continuation;
session 能力组仍未加载,get_goal / update_goal 不在活动工具面。
如果当前 Session 已经通过自然语言请求或 gateway 加载 session 组,这个前提不成立;adaptive 下模型也可能通过 gateway 自行恢复工具面。
根因证据
最小机制复现
在上述源码 checkout 运行,不需要安装依赖或调用模型:
node --experimental-strip-types --input-type=module <<'JS'
import { resetOpenPiToolSurface, patchOwnedTools,
getLoadedOpenPiCapabilities, OPENPI_TOOL_SURFACE
} from './extensions/shared/tool-surface.ts';
import { capabilitiesRequestedByPrompt } from './extensions/shared/capability-intent.ts';
import { continuationPrompt } from './extensions/goal/prompts.ts';
const listeners = new Map();
const registered = ['read','bash','edit','write','openpi_load_tools',
'create_goal','get_goal','update_goal'];
let active = [...registered];
const pi = {
events: {
on(name, fn) { const all = listeners.get(name) ?? []; all.push(fn); listeners.set(name, all); },
emit(name, data) { for (const fn of listeners.get(name) ?? []) fn(data); }
},
getActiveTools: () => [...active],
getAllTools: () => registered.map(name => ({ name })),
setActiveTools: next => { active = [...next]; }
};
resetOpenPiToolSurface(pi);
patchOwnedTools(pi, 'goal', { disable: OPENPI_TOOL_SURFACE.goal.deferred });
patchOwnedTools(pi, 'goal', { enable: OPENPI_TOOL_SURFACE.goal.deferred });
const prompt = continuationPrompt({
objective:'修复 README 的一个拼写错误', tokensUsed:0, timeUsedSeconds:0
});
console.log(JSON.stringify({ loaded:getLoadedOpenPiCapabilities(pi), active,
continuationClassified:capabilitiesRequestedByPrompt(prompt),
canComplete:active.includes('update_goal') }, null, 2));
JS
已得到:loaded=[]、active=[read,bash,edit,write]、continuationClassified=[]、canComplete=false。
这证明两道工具门的组合结果;不把该纯机制复现当作完整 Pi 集成验收。
为什么当前测试没有拦住
Goal 的 extensionHarness 没有提供 pi.events。
共享工具面的 stateFor fallback 在缺少 event bus 时把所有组视为已加载,所以单独测试 Goal extension 无法覆盖真实 capability gate。
已有保护与建议范围
用户仍可通过 /goal pause / /goal clear 停止目标;token budget(若设置)与 1000 次 emergency continuation breaker 仍有效。问题是模型正常完成/阻塞路径不可达,并非这些保护失效。
建议从 Goal owner 的已授权生命周期恢复正确工具投影,保留 explicit 默认和普通 Session 的零工具面。不要通过在 continuation 文案中塞入某个匹配词来绕过 gate。
验收
Related: #192 Goal 生命周期文档、#194 模型上下文边界。本 Issue 跟踪具体运行时缺陷,不替代这两项文档工作。
问题
默认
explicitdiscovery 下,/goal <objective>创建 Goal、或恢复已有 active Goal 后,Runtime 可以开始续跑,但模型完成或报告阻塞所需的get_goal/update_goal仍可能被 capability gate 隐藏。这使 Goal 的执行状态与模型可用工具脱节:模型已经收到“完成后调用
update_goal”的续跑指令,却没有这个工具。价值
让用户已经明确启动的 Goal 能正常查看状态、报告阻塞并完成收尾,避免工作完成后仍继续消耗回合;普通新 Session 继续保持零常驻 OpenPI 工具。
审计边界
触发方式
capabilities.discovery = explicit,进入未加载session能力组的新 Session。/goal 修复 README 的一个拼写错误;或者重新打开具有相同 objective 的 active Goal Session。session能力组仍未加载,get_goal/update_goal不在活动工具面。如果当前 Session 已经通过自然语言请求或 gateway 加载
session组,这个前提不成立;adaptive下模型也可能通过 gateway 自行恢复工具面。根因证据
goal/index.ts:137-146:创建 Goal 时调用showLifecycleTools()后直接kickoff()。goal/index.ts:403-418:恢复 active Goal 时走相同路径。goal/index.ts:99-102:showLifecycleTools()只更新 owner 的 desired tools,不加载 capability。tool-surface.ts:89-93与241-243:Goal 属于session组,owner 的可见性仍要求该组已加载。capabilities/index.ts:123-132与tool-surface.ts:370-381:Session 启动把 capability 状态重置为loaded=[]。最小机制复现
在上述源码 checkout 运行,不需要安装依赖或调用模型:
已得到:
loaded=[]、active=[read,bash,edit,write]、continuationClassified=[]、canComplete=false。这证明两道工具门的组合结果;不把该纯机制复现当作完整 Pi 集成验收。
为什么当前测试没有拦住
Goal 的
extensionHarness没有提供pi.events。共享工具面的
stateForfallback 在缺少 event bus 时把所有组视为已加载,所以单独测试 Goal extension 无法覆盖真实 capability gate。已有保护与建议范围
用户仍可通过
/goal pause//goal clear停止目标;token budget(若设置)与 1000 次 emergency continuation breaker 仍有效。问题是模型正常完成/阻塞路径不可达,并非这些保护失效。建议从 Goal owner 的已授权生命周期恢复正确工具投影,保留 explicit 默认和普通 Session 的零工具面。不要通过在 continuation 文案中塞入某个匹配词来绕过 gate。
验收
/goal <objective>。get_goal/update_goal,不依赖 objective 命中词法规则。update_goal({status:"complete"})后不再追加 continuation;blocked 路径仍保留三回合审计。Related: #192 Goal 生命周期文档、#194 模型上下文边界。本 Issue 跟踪具体运行时缺陷,不替代这两项文档工作。