fix: refresh delegation permissions and report Reasoner task outcomes
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
| B-007 | 推理强度 | provider_default 或 low/medium/high;非默认值要求模型资源显式声明 supportsReasoningEffort,按 reasoning_effort 参数发送,不支持时拒绝 | semantic | default |
|
||||
| B-008 | 技能 | Reasoner 使用后端资源中的命名技能正文;OpenCode 使用远端原生技能/agent,平台仅保存说明,不伪装远程安装或权限隔离 | semantic | default |
|
||||
| B-009 | 外部选择 | OpenCode保留地址/目录/服务鉴权,新增可选 agent 与 modelProviderId/modelId;推理强度及沙箱由远端管理 | interface | default |
|
||||
| B-010 | 执行结果 | Reasoner通过明确完成/提问控制函数返回业务结果;idle、普通文本、接收回执不能直接证明成功 | semantic | default |
|
||||
| B-010 | 执行结果 | Reasoner通过complete_task(status,result)明确报告目标成功或失败;部分完成记为failed并说明限制。该状态是执行模型的报告,非平台独立验证;idle、普通文本、接收回执不证明成功 | semantic | sweep |
|
||||
| B-011 | 生命周期与取消 | 语音断线继续;取消停止当前任务;原生取消不代表外部工具或远端副作用被回滚,需核查远端停止 | semantic | user |
|
||||
| B-012 | 恢复 | OpenCode只观察已有句柄;内置Reasoner重启标记中断,不自动重放工具;历史任务保留旧恢复语义 | semantic | default |
|
||||
| B-013 | 时限与并发 | 新任务保存截止时间,排队和执行均计时;全局原生串行并发1,保留远端状态未确认时阻止新提交策略 | semantic | default |
|
||||
@@ -22,6 +22,8 @@
|
||||
| B-017 | F0过渡 | Walking skeleton短暂兼容旧tool提交入口以保持累计检查;迁移阶段移除该过渡入口,不保留为新产品接口 | interface | default |
|
||||
| B-018 | 回退迁移 | 0027为数据语义迁移,downgrade明确拒绝,需备份恢复;不能把新的Reasoner配置静默回退成旧task工具 | semantic | default |
|
||||
| B-019 | 切换Realtime | 已绑定任务后端时复用现有配置移除确认交互,确认切换后解除绑定,后端资源保留 | semantic | default |
|
||||
| B-020 | 配置有效性 | 后端配置拒绝未知字段;资源编辑验证已绑定助手,模型/工具失效时阻止保存和执行,不静默漏掉能力 | semantic | default |
|
||||
| B-020 | 配置有效性 | 后端配置拒绝未知字段;启用资源的编辑验证已绑定助手,模型/工具失效时阻止保存和委派;停用资源允许保留结构合法但引用失效的配置 | semantic | sweep |
|
||||
| B-021 | 类型与凭据 | 后端资源可切换类型,但必须提交完整合法配置;OpenCode转Reasoner清除服务凭据,同类型空值/掩码保留原凭据 | interface | default |
|
||||
| B-022 | 指令模板 | 助手绑定 instructions 的 {{变量}} 使用任务接受时冻结的变量单次渲染;资源 instructions 和技能正文按字面使用,不访问密钥变量 | semantic | default |
|
||||
| B-022 | 指令模板 | 助手绑定 instructions 的业务变量使用接受时冻结的值单次渲染;system__time/system__time_utc沿用共享渲染器执行时刷新。资源 instructions 和技能正文按字面使用,不访问密钥变量 | semantic | sweep |
|
||||
| B-023 | 通话内更新 | 每次Speaker委派前重新读取后端、模型、工具和MCP启用状态及凭据;绑定或任务参数来源改变时要求重新连接。接受后的任务继续用快照,不因配置编辑撤销已有副作用 | semantic | sweep |
|
||||
| B-024 | 停用影响 | 允许停用仍被引用的后端并保留绑定;新助手会话因配置校验失败不能启动,需先解绑或启用。已有Speaker通话保留,但新委派会重新校验并拒绝停用资源 | semantic | sweep |
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"undeclared": [
|
||||
{
|
||||
"site": "backend/services/brains/prompt_tasks.py:29; backend/services/brains/prompt_tasks.py:55; backend/services/background_tasks/service.py:62",
|
||||
"decision": "语音会话建立时解析的后端配置会用于该连接随后提交的所有任务;提交时复制该运行时对象,不重新读取后端、模型、工具或 MCP Server 的启用状态、配置与凭据。",
|
||||
"why_it_matters": "管理员在通话期间修改配置、停用能力或轮换凭据后,该通话仍可使用旧配置创建新任务。B-004 声明任务提交后的快照冻结,但没有声明提交前配置已经固定于语音连接;B-020 也未说明有效性检查只在解析时进行。",
|
||||
"class": "semantic"
|
||||
},
|
||||
{
|
||||
"site": "backend/services/task_backend_resources.py:135; backend/services/config_resolver.py:328; backend/routes/task_backends.py:82",
|
||||
"decision": "允许停用仍被助手引用的后端并保留绑定;此后解析该助手的完整运行配置会失败,因此新的 Speaker 会话也不能启动。",
|
||||
"why_it_matters": "停用任务后端的影响范围是整个已绑定助手的新会话,而不仅是任务委派。规格和假设记录没有声明这一影响范围。",
|
||||
"class": "semantic"
|
||||
},
|
||||
{
|
||||
"site": "backend/services/background_tasks/reasoner.py:148; backend/services/background_tasks/reasoner.py:174",
|
||||
"decision": "complete_task 只接收结果文本,并将任何被接受的结果统一记为 succeeded;没有让 Reasoner 显式返回业务失败或部分完成状态的控制参数。",
|
||||
"why_it_matters": "模型即使通过结果文本说明目标无法完成,调用 complete_task 后任务卡片仍显示成功。B-010 声明了显式完成控制,但未定义 succeeded 表示结束执行还是业务目标达成。",
|
||||
"class": "semantic"
|
||||
}
|
||||
],
|
||||
"stale_rows": [
|
||||
{
|
||||
"id": "B-020",
|
||||
"site": "backend/routes/task_backends.py:37; backend/routes/task_backends.py:82",
|
||||
"stated": "资源编辑验证已绑定助手,模型/工具失效时阻止保存。",
|
||||
"actual": "enabled=false 时跳过模型和工具资源有效性检查,也跳过已绑定助手检查;结构合法但引用失效的停用配置可以保存。启用状态下的检查与记录一致。",
|
||||
"why_it_matters": "记录没有声明停用资源的保存例外,因此描述的配置有效性保证强于实际代码。",
|
||||
"class": "semantic"
|
||||
},
|
||||
{
|
||||
"id": "B-022",
|
||||
"site": "backend/services/background_tasks/reasoner.py:107; backend/services/background_tasks/opencode.py:91; backend/services/runtime_variables.py:155",
|
||||
"stated": "助手绑定 instructions 的变量使用任务接受时冻结的变量单次渲染。",
|
||||
"actual": "业务变量使用冻结快照并单次展开;但共享渲染器在执行时刷新 system__time 和 system__time_utc,因此这两个变量使用渲染时刻。最新 OpenCode 可选变量修复正确保留了既有可选变量语义,不改变此时钟行为。",
|
||||
"why_it_matters": "任务排队后,包含系统时间的指令会得到执行时刻,而不是接受任务时刻;记录需要明确这个例外。",
|
||||
"class": "semantic"
|
||||
}
|
||||
],
|
||||
"semantic_undeclared": 3,
|
||||
"verdict": "gaps"
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
{
|
||||
"status": "passed_with_limitations",
|
||||
"method": "Headless Google Chrome via temporary Playwright Core; built Next frontend at localhost:3217",
|
||||
"mock_boundary": "Every /api request intercepted with explicit in-memory fixtures; non-local requests aborted. No backend, real model, OpenCode, database or real credentials contacted.",
|
||||
"prior_attempts": [
|
||||
{
|
||||
"outcome": "Reasoner and OpenCode saves passed; narrow resource row edit was obstructed with existing expanded sidebar at390px. Repeated using existing sidebar collapse control; no application code changed."
|
||||
}
|
||||
],
|
||||
"fixtures": {
|
||||
"models": [
|
||||
"UI Strong Model: supportsReasoningEffort=true",
|
||||
"UI Basic Model: supportsReasoningEffort=false"
|
||||
],
|
||||
"tools": [
|
||||
"UI HTTP Tool",
|
||||
"UI Client Tool (must be excluded from Reasoner picker)"
|
||||
]
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"name": "Render dedicated resources page and open Reasoner form",
|
||||
"status": "passed",
|
||||
"details": {
|
||||
"desktop_layout": {
|
||||
"viewport": 1440,
|
||||
"width": 751.712158203125,
|
||||
"left": 344.1438903808594,
|
||||
"right": 1095.8560485839844,
|
||||
"scrollWidth": 768,
|
||||
"clientWidth": 768,
|
||||
"horizontalOverflow": false,
|
||||
"outsideViewport": false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Configure Reasoner model, high effort, inline skill and server-only tool",
|
||||
"status": "passed",
|
||||
"details": {
|
||||
"captured_payload": {
|
||||
"name": "UI Reasoner Smoke",
|
||||
"description": "",
|
||||
"enabled": true,
|
||||
"type": "reasoner",
|
||||
"secrets": {},
|
||||
"config": {
|
||||
"instructions": "",
|
||||
"timeoutSeconds": 600,
|
||||
"maxConcurrency": 1,
|
||||
"modelResourceId": "ui_model_strong",
|
||||
"reasoningEffort": "high",
|
||||
"toolBindings": [
|
||||
{
|
||||
"toolId": "ui_http",
|
||||
"argumentBindings": {
|
||||
"query": {
|
||||
"source": "model"
|
||||
}
|
||||
},
|
||||
"templateBindings": {},
|
||||
"resultAssignments": {}
|
||||
}
|
||||
],
|
||||
"skills": [
|
||||
{
|
||||
"name": "UI Analysis",
|
||||
"content": "Analyze constraints before proposing a result."
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Edit preserves Reasoner values; unsupported model disables nondefault effort",
|
||||
"status": "passed"
|
||||
},
|
||||
{
|
||||
"name": "Configure OpenCode connection, agent, paired model and remote skill note",
|
||||
"status": "passed",
|
||||
"details": {
|
||||
"captured_payload": {
|
||||
"name": "UI OpenCode Smoke",
|
||||
"description": "",
|
||||
"enabled": true,
|
||||
"type": "opencode",
|
||||
"secrets": {
|
||||
"password": "<fake fixture credential>"
|
||||
},
|
||||
"config": {
|
||||
"instructions": "",
|
||||
"timeoutSeconds": 600,
|
||||
"maxConcurrency": 1,
|
||||
"url": "http://127.0.0.1:9",
|
||||
"directory": "/test-fixture/repo",
|
||||
"username": "opencode",
|
||||
"agent": "build",
|
||||
"modelProviderId": "ui-provider",
|
||||
"modelId": "ui-model",
|
||||
"skillsNote": "Installed remotely; fixture note only."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Responsive resource page and OpenCode modal fit a 390px viewport",
|
||||
"status": "passed",
|
||||
"details": {
|
||||
"page_layout": {
|
||||
"viewport": 390,
|
||||
"width": 390,
|
||||
"left": 0,
|
||||
"right": 390,
|
||||
"scrollWidth": 390,
|
||||
"clientWidth": 390,
|
||||
"horizontalOverflow": false,
|
||||
"outsideViewport": false
|
||||
},
|
||||
"dialog_layout": {
|
||||
"viewport": 390,
|
||||
"width": 340.0999755859375,
|
||||
"left": 24.950002670288086,
|
||||
"right": 365.0499782562256,
|
||||
"scrollWidth": 358,
|
||||
"clientWidth": 358,
|
||||
"horizontalOverflow": false,
|
||||
"outsideViewport": false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Prompt binds backend independently and sends taskBackend without ToolBinding",
|
||||
"status": "passed",
|
||||
"details": {
|
||||
"captured_task_backend": {
|
||||
"backendId": "ui_backend_1",
|
||||
"instructions": "Return clear evidence and limitations.",
|
||||
"instructionSource": {
|
||||
"source": "model"
|
||||
}
|
||||
},
|
||||
"ordinary_tool_bindings": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Migrated variable instruction source survives fetch/edit/save unchanged",
|
||||
"status": "incomplete",
|
||||
"error": "Optional legacy-variable fetch/edit/save follow-up timed out waiting for the task-instruction editor after page reload. Not diagnosed; this browser run does not claim to verify that scenario."
|
||||
}
|
||||
],
|
||||
"console_errors": [],
|
||||
"page_errors": [],
|
||||
"unexpected_requests": [],
|
||||
"captures": [
|
||||
"/private/tmp/ai-video-browser-smoke/reasoner-desktop.png",
|
||||
"/private/tmp/ai-video-browser-smoke/opencode-desktop.png",
|
||||
"/private/tmp/ai-video-browser-smoke/expanded-sidebar-mobile-limitation.png",
|
||||
"/private/tmp/ai-video-browser-smoke/opencode-mobile.png",
|
||||
"/private/tmp/ai-video-browser-smoke/prompt-binding-desktop.png"
|
||||
],
|
||||
"limitations": [
|
||||
"Browser smoke verifies rendered client behavior and request payloads against mocked APIs, not backend validation or genuine model/coding execution.",
|
||||
"No microphone/WebRTC connection was started.",
|
||||
"Responsive checks cover new resource page/dialog with the existing sidebar manually collapsed. Existing AppShell does not auto-collapse its252px sidebar on resize; the expanded sidebar obstructed row edit at390px.",
|
||||
"Optional migrated variable instructionSource reload was not verified in this browser run; no backend or migration behavior is inferred from it.",
|
||||
"Screenshots are diagnostic captures; mobile capture occurred during modal transition. Geometry checks, not pixel comparison, established the responsive result."
|
||||
],
|
||||
"completed_at": "2026-10-24T01:25:20.247Z",
|
||||
"acceptance": "Core frontend browser smoke passed against explicitly mocked APIs; optional legacy variable reload remains unverified.",
|
||||
"cleanup": {
|
||||
"temporary_browser_closed": true,
|
||||
"local_next_server_stopped": true,
|
||||
"project_dependencies_changed": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"review_independence": "same-family",
|
||||
"acceptance_status": "provisional",
|
||||
"round_limit": 2,
|
||||
"rounds_completed": 1,
|
||||
"first_round_semantic_undeclared": 3
|
||||
}
|
||||
Reference in New Issue
Block a user