修复链路上存在的若干阻塞性漏洞 (#199)
Reviewed-on: http://192.168.35.82/git/GenarrativeAI/Genarrative/pulls/199 Co-authored-by: Linghong <ink29535@proton.me> Co-committed-by: Linghong <ink29535@proton.me>
This commit was merged in pull request #199.
This commit is contained in:
@@ -16,6 +16,23 @@
|
||||
|
||||
---
|
||||
|
||||
## 2026-08-27 `plan.submit_gdd` 拒绝无审批决定的 `user_revision`
|
||||
|
||||
- 背景:结构校验允许 `round=0 + user_revision + confirmed`,提交闸原先只做结构、身份和 Session CAS。Provider 可在首次 collecting、澄清续跑或提交前质量返工里把未确认项标成用户审批修改,审批卡显示「已确认」。
|
||||
- 决策:新版本 create 时,payload 含 `user_revision` 则当前 session 的 `lastDecisionRef.action` 必须是 `revise` 或 `reject`;否则 `PLAN_INVALID_REQUEST`。同 `submissionId` replay 不重判。不恢复 session 前缀逐项相等,不把 `user_revision` 与审批意见正文对齐,也不在这次处理 `round≥1` 的 `user_option` 伪造。
|
||||
- 影响范围:`planning_submit.rs` 提交闸;Fast GDD 技术方案第 5.1 / 8.2 / 12 节。
|
||||
- 验证方式:首次 collecting 带 invented-confirmation 必须拒绝且不落 GDD;reject continuation 再交 `user_revision` 的 v2 仍成功。
|
||||
- 关联文档:`docs/technical/【技术方案】立项策划Agent(Fast GDD)-2026-08-10.md`。
|
||||
|
||||
## 2026-08-28 planning continuation 必须沿当前 delivery 游标推进
|
||||
|
||||
- 背景:`lastDecisionRef.action=revise/reject` 在用户修订后的质量返工中必须继续有效,但仅凭该历史指针无法证明当前 `agent.delegate` 选择的是本次 planning session 的当前分支。
|
||||
- 决策:不新增用户修订授权字段,也不在 `plan.submit_gdd` 重复遍历 approval receipt/GDD lineage。已有 planning session 创建新 child 时,`repairOfDelegationId` 必须直接等于旧 session 的 `latestDelegationId`;不一致即在 Provider 启动前以 `PLAN_NEEDS_RECONCILIATION` 拒绝。合法用户修订及其后质量返工继续保留 `lastDecisionRef`,成功提交新的 GDD 后仍由 submit successor 清理该指针。
|
||||
- 影响范围:`planning_coordinator.rs` continuation 投影门;Fast GDD 技术方案第 8.2 节和提交步骤;不改变静态委派通用返工合同或 `PlanSessionV1` schema。
|
||||
- 验证方式:新增当前游标 continuation 正向/旧 delivery 负向回归;CI 继续验证首次伪造 `user_revision` 拒绝、用户修订后质量返工提交成功及现有澄清/返工 lineage。
|
||||
- 关联文档:`docs/technical/【技术方案】立项策划Agent(Fast GDD)-2026-08-10.md`、`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/planning_coordinator.rs`。
|
||||
|
||||
## 2026-08-27 退款 emergency spool 容量溢出保持可恢复
|
||||
## 2026-08-27 退款 emergency spool 容量溢出保持可恢复
|
||||
|
||||
- 背景:本机 emergency spool 仅作为 SpacetimeDB 完全不可达时的最后恢复路径,原有 `MAX_BYTES` 分支会直接返回 `Dropped`,导致扣费已经完成但没有可重放记录。
|
||||
@@ -48,6 +65,15 @@
|
||||
- 验证方式:核对 CLI 版本和 commit,重新生成 Rust bindings,运行 `npm run check:spacetime-schema`、相关 Cargo check / tests、server provision 工具测试、dev 调度测试、encoding 和 diff 门禁。
|
||||
- 关联文档:`docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md`、`docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`。
|
||||
|
||||
## 2026-08-26 Fast GDD 修订后先取证再允许再次委派
|
||||
|
||||
- **现象**:GDD v1 经用户选择“修改”后,策划子 Agent 正确提交 v2,但 plan 根 Supervisor 的 `Delegated` 阶段仍同时广告 `agent.delegate` 与审批前置工具;模型可能在 Acceptance Graph 重新取证前重复创建修订 delivery,随后被 `PLAN_PROVIDER_USAGE_DEFERRED` 拦停。
|
||||
- **决策**:plan 根阶段增加轻量的 `AwaitingAcceptanceEvidence` 状态。当前根最新 GDD 无 approval receipt/pending、session `latestSubmittedRef` 精确指向该提交、delivery 已由根认领且 Acceptance Graph 返回 `NeedsEvidence` 时,只广告 `file.read`、`agent.acceptance_update`、`agent.run_status`;只有用户真正对最新审批卡选择修改/退回后,才恢复 `agent.delegate`。
|
||||
- **边界**:不放宽 Provider usage 门禁,不重构 delegation/repair lineage,不自动生成证据或审批 pending;审批 pending 仍只由既有 acceptance gate 在 `agent.acceptance_update` 成功后创建。
|
||||
- **验证**:新增一条阶段工具面回归,并通过 15 条 M1C-2a acceptance gate 定向测试、plan root 原生工具目录测试、`cargo check --all-targets`、格式与 diff 检查。
|
||||
- **锁边界修正(2026-08-27)**:阶段判定拆为 `plan_root_supervisor_stage_at_locked` 与负责取得一次项目锁的外层入口;Provider tool-plan builder 已持有项目锁时直接复用 locked 入口。Acceptance Evidence 判据和阶段工具面不变,禁止在持锁调用链中再次获取 `.agent/project.lock`。
|
||||
- **回归验证**:planning submit 定向测试 68 passed、Provider request builder 定向测试 17 passed、Tauri `cargo check` 与 `cargo fmt --check` 通过。
|
||||
|
||||
## 2026-08-24 AGC Direct 媒体能力只通过客户端语义工具开放
|
||||
|
||||
- 背景:资源页已经补齐视频、角色动画、音效和背景音乐的 create/derive 能力,但 Direct Codex 只能准备标准美术包,无法查询已登记源资源或表达新增媒体意图。直接开放 Tauri invoke 会把项目路径、revision、operation、幂等键、登录态和事务权力交给模型。
|
||||
@@ -7769,6 +7795,20 @@ CI 上 `background_agent_runtime_recovers_stale_running_before_pending_task` 在
|
||||
- 安全:DirectProject 使用真实 `game/` writable root、`approvalPolicy=never`,原生命令网络保持关闭,联网资料继续走受控 `agc_web_search`;Codex 子 Agent、Apps、插件、hooks、图片生成、Goals、Workspace Dependencies、Tool Suggestion 与未审计浏览器/电脑控制继续关闭。配置了 AGC LLM Key 或可解析的 `OPENAI_API_KEY` 登录态时,真实 provider 凭据只留在 AGC 本地代理;前者仍走已配置上游,后者只走 OpenAI 官方 API,Codex 仅获得连接级随机代理令牌。无法安全代理的 OAuth `auth.json` 继续关闭原生 shell/unified exec。app-server 使用隔离 `CODEX_HOME`,shell 用 `shell_environment_policy` glob 排除 provider key、proxy、loopback bridge 和受控开关。
|
||||
- 上下文:Direct 系统提示词只保留身份、cwd、边界和 Skill 索引;不再预注入项目源码快照、项目提示词或 Skill 正文。浏览器工具回传结构化事实,不强制固定三次整改循环;Codex 自行解释证据并决定是否继续。sandbox writableRoots 不提供 deny-read,`.agent`/`../assets` 的不可读约束需靠行为合同和真实 smoke 验证。
|
||||
|
||||
## 2026-08-27 GDD 修改后历史 receipt 不得污染当前审批恢复
|
||||
|
||||
- 现象:GDD“修改”已成功生成下一版本且当前 pending 身份正确,但 hydrate 持续返回 `recoveryPending=true`,审批卡显示“审批状态正在恢复”。
|
||||
- 原因:恢复扫描会重放全部历史 approval receipt;旧版本 receipt 仍拿当前单例 approval pending 做 identity 比对。修改后当前 pending 已属于新版本,旧 receipt 的 identity 不同是正常状态,却被误记为投影缺口。
|
||||
- 决策:receipt 的 index、Markdown、audit、submit observation、session 等投影继续允许全量恢复;approval pending 只由 lineage 最新 GDD 的 receipt 读取、更新和清理。历史 receipt 不得检查或改写当前 pending,也不得因此提升 `recoveryPending`。
|
||||
- 审批意见消息按 receipt 的 `rootRunId` 解析到原 Supervisor task 所属会话恢复;不会按当前 active session 重新路由。已存在于归档会话的幂等消息允许重放且不新增消息,缺失消息仍保持恢复失败,不静默写入其他会话。
|
||||
- 验证:沿用现有审批恢复与 planning submit 定向测试;未新增独立测试,避免为非代表性 fixture 引入额外状态构造。
|
||||
|
||||
## 2026-08-27 审批修订以最新用户意见更新 GDD 决定快照
|
||||
|
||||
- `decisions` 表示当前 GDD 版本的决定快照,不再作为新提交必须逐项复制的 session 历史前缀。审批修订可以修改、推翻、删除或新增决定;Runtime 只校验结构、身份、CAS、版本和原型验证项双射,不做自然语言修改范围门禁。
|
||||
- 新增 `answerSource=user_revision`,用于标记来自审批修改意见的当前决定,按 `round=0` 记录;`default` 仍只表示未提问的默认建议,澄清来源仍使用 `user_option` / `user_freeform`。
|
||||
- planning Prompt 约束为:以当前 GDD 为基线,仅修改用户意见明确涉及的内容及保持内部一致性所必需的派生内容,未涉及内容保持不变;意见与旧决定冲突时以最新意见为准。
|
||||
|
||||
## 2026-08-24 AGC UI 原型桥接与自主 UI workflow
|
||||
|
||||
- 决策:`ui-prototype` 图片与 `UI` JSON 编辑资源保持两种正式类型。Agent 通过受控 `ui.workflow.run` 按 `prepare -> recognize -> status -> finalize` 创建页面资源、关联源图、持久化 UI State 和 manifest 阶段;`recognize` 直接复用 UI Editor 的 provider-backed 结构识别、多树合并与组件绑定命令,按 `reference-ready -> structure-ready -> merge-ready -> binding-ready` 逐阶段写入并推进项目 revision。页面可显式关联已登记图片/图标和字体,图片/图标按 5 项一批绑定,字体安全元数据进入绑定上下文且未知引用失败关闭。Runtime 回执携带 `revisionAdvanceCount`;Provider 未配置、请求失败、工具调用缺失、结果不匹配、未产出可渲染组件或仍有待审节点时保留最近真实阶段,禁止用 deterministic seed 冒充语义处理完成。
|
||||
|
||||
@@ -2,6 +2,27 @@
|
||||
|
||||
> 当前口径:本文件保留可复用的排障经验;历史条目的旧路由、旧版本和已删除文档仅作根因背景,不得据此恢复退役入口。当前命令、路由和 schema 以代码与 `docs/README.md` 为准。
|
||||
|
||||
## 2026-08-27 Provider 成功 handoff 失败时需要保留本地私有原始响应
|
||||
|
||||
- **现象**:Provider 已返回响应,但 tool-plan handoff 因绝对路径或其它内容安全校验失败,Runtime 只留下 `failureKind`、哈希和被压平的 JSON pointer;排障时无法确认实际工具名和完整 arguments。
|
||||
- **处理**:项目 `.agent`、Agent DB 和公共 event 继续只写安全摘要;额外在应用私有配置目录的 `diagnostics/provider-reconciliation/<projectHash>/<requestHash>.json` 保存本次响应、tool calls 和校验错误,供本机人工排障。该文件不参与恢复/重试、不复制到项目、不进入 Git,单文件限制 1 MiB,写入失败不改变 reconciliation 语义。
|
||||
- **排查顺序**:先读 Runtime 状态里的 `localDiagnostic` 相对引用,再在应用私有目录读取诊断,核对 requestId、requestSlot、tool name 和失败 pointer;不要为了取得原文而放宽 handoff 的安全门。
|
||||
|
||||
## 2026-08-27 阶段判定不能在持锁的 Provider builder 中再次获取项目锁
|
||||
|
||||
- **现象**:GDD 修订取证阶段新增后,重新启动策划时前两步表面成功,但父 Supervisor 在收到 `project-planning` 回执、生成下一轮工具计划时失败:`项目正在被其他写操作占用:$PROJECT_ROOT\\.agent\\project.lock`。
|
||||
- **原因**:`provider_tool_plan` 在构建请求前已持有 `.agent/project.lock`;`plan_root_supervisor_stage_at` 又调用会自行取锁的 Acceptance Evidence 包装入口。同一进程的文件锁不可重入,持锁调用被误判为外部竞争,等待约 10 秒后失败。问题与 Provider、代理端口或 GDD 内容无关。
|
||||
- **处理**:所有需要一致快照的状态读取保留在项目锁内;阶段判定提供明确的 `*_locked` 内部入口,外层入口仅供未持锁调用方取得一次锁。Provider builder 显式接收并校验当前锁后调用 locked 阶段判定,不引入可重入锁,也不移除 Acceptance Evidence 门禁。
|
||||
- **排查顺序**:先看失败 Run 的事件顺序是否为 `delegate receipt ready → 生成工具计划 → 阶段判定项目锁失败`,再检查调用方是否已持有 Provider plan project lock;不要因为错误文案包含“其他写操作”就先扩大锁等待或放宽 Provider usage。
|
||||
- **验证**:`cargo check`、`cargo fmt --check`、planning submit 68 passed、Provider request builder 17 passed;阶段测试同时覆盖未持锁包装入口和持锁 locked 入口。
|
||||
|
||||
## 2026-08-26 GDD 新版本提交后不能沿用“已有委派”工具面
|
||||
|
||||
- **现象**:`plan_root_supervisor_stage_at` 只按是否存在 delivery 判定 `Delegated`。用户修订产生的新 GDD 仍未完成当前根 Run 的 `file.read → agent.acceptance_update` 取证时,模型会看到 `agent.delegate`,可能重复派发同一条策划链。
|
||||
- **原因**:自然语言 playbook 已规定“证据不足先取证、用户修改后才返工”,但阶段工具白名单没有把这条 durable 状态固化。
|
||||
- **处理**:阶段判定复用现有 acceptance gate 的 GDD/session/delivery/graph identity 检查,增加无副作用的 `AwaitingAcceptanceEvidence` 阶段;`PLAN_PROVIDER_USAGE_DEFERRED` 保持 fail-closed,不通过放宽 Provider 使用量门禁解决。
|
||||
- **排查顺序**:先看最新 `gdd.vN.json`、`session.latestSubmittedRef`、delivery 是否 `ClaimedByParent`,再看 Acceptance Graph 是否 `NeedsEvidence`;若仍可见 `agent.delegate`,优先检查 plan root 阶段快照,而不是修改 acceptance gate 或 Provider 门禁。
|
||||
|
||||
## 2026-08-15 把校验往链路前面挪,改的不是严格程度而是作用域
|
||||
|
||||
- 现象:CI 全量 5 条失败,看上去毫不相干(两条 Goal 续跑停在 `needs-reconciliation`、一条交接用例断言错误文案、一条恢复用例把不可读 state 的错误抛了出来、一条 Linux-only 用例错误码对不上),实际只有 3 个根因,且三者是**同一个形状**:新增或既有的检查被放在了链路更靠前的位置,于是它的语义作用域被悄悄放大或提前,而不是「变严」。
|
||||
@@ -4940,6 +4961,12 @@
|
||||
- 部分旧包补充:rollback 的规范图/背景图必须保存旧字节与旧 manifest entry,不能把这两项缺失隐式当成空内容;显式 `regenerate` 因此只在这两项可信可回滚时开放。历史主图集、私有回执、公开清单或 canonical 切片可以缺失,但八个严格路径与受管顶层 asset identity 必须逐项冻结其真实 `Present/Some` 或 `Missing/None` 状态,补偿也必须恢复相同存在性。不要因为旧美术包缺切片而阻断重生成,也不要把本轮新建的严格文件误记成旧文件。
|
||||
- 对话扫描与 claim 补充:历史中出现 `User A / User B / Assistant B` 时,B 已回答不代表 A 已回答,扫描必须继续寻找 A。成功 Direct 回复在 Rust 返回前已经落盘,前端冗余 append 失败不能据此重跑;普通错误回复的显式落盘失败时,恢复 claim 要保持到 React fallback writer 的同一 messageId append 明确收敛。writer 成功或明确失败后才释放;失败路径要停止该消息的自动迟到重试,再由显式 `/history` 复用原 stable turn。终态后及时删除 claim,避免 Set 无界增长。
|
||||
|
||||
## GDD 历史审批回执误触发当前恢复提示(2026-08-27)
|
||||
|
||||
- 现象:修改 GDD 后新版本标题和内容已正确落盘,但审批卡一直显示“审批状态正在恢复”。
|
||||
- 原因:`approval pending` 是当前 lineage 最新 GDD 的单例投影;恢复扫描却让每个历史 receipt 都拿它做 identity 比对。旧 receipt 与新 pending 不同并不表示损坏。
|
||||
- 处理:历史 receipt 只修复自身投影;只有最新 GDD 的 receipt 才能校验、更新或清理当前 approval pending。不要在前端隐藏 `recoveryPending`,也不要取消最新版本的 identity fail-closed 检查。
|
||||
|
||||
## Native shell CI 不能在测试阶段重新解析 Cargo registry(2026-08-26)
|
||||
|
||||
- 现象:原生壳 job 的依赖预取成功后,AGC 检查仍在 `platform-llm` 测试阶段重新更新 registry index,并因 `symphonia` 下载的 TLS EOF 失败。
|
||||
|
||||
Reference in New Issue
Block a user