fix(security): round-64 批1——edge 人工审批门属主化(非属主 404 同形 / pending 按属主过滤) + hub health 兜底不再撒谎(nil handler → 503+ready:false) (#2241) - #2242
Merged
Conversation
…份、单租户三类用例 (#2241) Co-authored-by: Cursor <cursor@vectorcontrol.tech>
…acle 用例 (#2241) Co-authored-by: Cursor <cursor@vectorcontrol.tech>
…按属主过滤 (#2241) Co-authored-by: Cursor <cursor@vectorcontrol.tech>
…/pending 按属主过滤 (#2241) Co-authored-by: Cursor <cursor@vectorcontrol.tech>
…se (#2241) Co-authored-by: Cursor <cursor@vectorcontrol.tech>
…y 均 503+ready:false,/health/live 保持 200,openapi 补 503 (#2241) Co-authored-by: Cursor <cursor@vectorcontrol.tech>
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Team Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This was referenced Sep 2, 2026
DeliciousBuding
added a commit
that referenced
this pull request
Sep 2, 2026
…tionUnavailable zh/en 键落地(未接入动作不再谎称「请重试」) + 消息动作 port 假注释订正 (#2241) round-64 wave 批 2(tracker #2241),lane B。批 1(#2242)已合入 master `4a7af8c6`;本分支已 rebase 到该 master,无冲突(批 1 只碰 Go 与 `api/openapi.yaml`,本批只碰 `app/**`)。 原 commit 粒度(均带 (#2241)): - fix(i18n): 补 toast.actionUnavailable zh/en 键,未接入动作的提示不再说"请重试" - docs(workbench): 订正消息动作 port 的 doc 注释——#2238 之后它已是假话 - feat(desktop): 接上 Hub 转发 mutation,desktop 右键"转发"条目重新渲染并真派发 三件事的因果链:`workbenchTranscriptChromeActionMappers.ts:545` 早已导出 `UNAVAILABLE_ACTION_TOAST_KEY = 'toast.actionUnavailable'` 并在 7 个调用点使用,但 chatview bundle 里没有这个键 ⇒ i18next 回落判据 `resolved !== KEY` 不成立 ⇒ `announceUnavailableAction` 落到 `effect.failureMessage`,用户看到「…失败,请重试」这句对「这个端根本没接线」的错误指导(#2238 登记的尾巴 ①)。补键后,其中 desktop 的 forward 不再属于「未接线」——因为本批同时补上了 `useHubForwardMessage` port 并接线(#2238 当初是按 handler 存在性 fail-closed 关掉的,缺的正是这个 port,尾巴 ③)。`AgentHubWorkbenchTypes.ts:165-171` 的 doc 注释在 #2238 之后已是假话(尾巴 ②),一并订正。 **`regenerate` 明确不接线**:`regenerateAgentTask` 在 Desktop 的 `DesktopHubTaskBridge` / agent task 语义下未经验证,接了等于把未证语义推给用户 ⇒ 保持 fail-closed,`onRegenerate` / `onAddMessageReaction` 的 undefined 断言原样保留。 两处需要 reviewer 知情的取舍: 1. 删了一条既有断言 `expect(props.onForwardMessage).toBeUndefined()`——它的前提写在它自己的注释里("forward needs a `useHubForwardMessage` port"),本批交付物正是补上该 hook,接线后该断言与事实相反。只删这一条;同 test 内 `onRegenerate`/`onAddMessageReaction` 两条 fail-closed 断言原样保留,另在「chatActions 缺失」test 里新增 `expect(props.onForwardMessage).toBeUndefined()` 保住 #2154 不变量。测试数只增不减(3 → 4)。 2. `App.v4.test.tsx` 加了 1 行 `vi.mock` 夹具导出(白名单式 mock 不提供新 hook 会直接红)——**该文件任何断言一字未改**;抽掉这 1 行实测 12+ 用例全红,补回 14 passed。 证据与未验证项详见 PR #2249 描述(含红→绿双向证据、主机侧 rebase 后独立复跑 desktop 18 passed / workbench 5 passed、3 个 i18n 门禁数值、tsc×4 = 0 error、eslint 0 新增 problem 且 2 条 pre-existing 经 master blob 探针确认、以及 `real_tested=false` 的明确标注)。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
这是什么
round-64 wave 的集成分支(tracker #2241)。为压缩 CI 等待(本仓 required checks
strict: true+ runner 账号级串行 + 单次checks≈8min),本轮把已验收的 lane 堆到一个分支、只跑一次 CI,而不是每 lane 一个 PR 各跑一轮、且每合一个就让后面的分支变陈旧重跑。含 2 条 lane / 6 个 commit,均带
(#2241):lane A — edge 人工审批门属主化(安全 P1)
PostPermissionDecide/PostPlanDecide:在任何副作用(broker decide / registry consume / event publish)之前加属主门,非属主一律 404。ErrPermissionRequestNotFound/ErrPlanNotFound,与「本来就找不到」路径逐字节同形 ⇒ 不成为 runId 存在性 oracle。GetPlansPending:过滤而非 404(同GetArtifacts/GetPreviews/GetDeliveryJournal房型),新增filterPendingPlansByOwner;单租户哨兵看全部,空身份 fail-closed(AH-SR-045)。handlers_artifacts.go:77的属主-only 写法,不照抄diff_apply.go的!ok ||存在性分支——否则既有断言RejectsUnknownRequest/RejectsWrongRun/RejectsSecondDecision/RejectsExpiredRequest的 errcode 会被改写(禁止改既有断言)。api/openapi.yaml三段 description 同步(措辞照抄/v1/delivery-journal)。lane C — hub health 兜底分支诚实化(可观测性)
SetupRoutes的healthHandler == nil兜底原先对/health与/health/ready都答200 + ready:true,而该分支下没有任何依赖探测。改为两者均503 + status:"unavailable" + ready:false,镜像已接线HealthHandler.Ready的降级信封。/health/live保持200 + live:true:能应答探针的进程本身就是存活证据,503 会让编排器重启一个只是缺 health 接线的进程。App.Run在监听前无条件接线HealthHandler(internal/app/wiring.go);已接线的/health即使依赖降级仍答 200(body 带 status/ready 供调用方区分)。api/openapi.yaml给hubHealth补503响应 + 说明 200/503 的分界。证据(本机实测,非推断)
lane A(
.worktrees/approval-owner):LEAK: user-b sees user-a's pending plan);上门后internal/api全绿,测试数 274 → 287(只增不减)。go test ./internal/api/ -race -count=2→ ok 26.5s;gofmt -l空;golangci-lint run ./internal/api/...→ 0 issues。if false && …、过滤器还原broker.ListPending()→ 8 红;还原后grep -c REVERSE-VERIFY= 0。{"code":"ok","data":{"status":"ok"}}+run.agent.permission_decided事件 + 二次决定 404 单次消费语义)⇒ desktop 活体调用方不受影响。lane C(
.worktrees/health-version):先落红测试router_health_fallback_test.go(120 行)再修实现;已接线/health/ready在依赖坏时仍 503。集成分支(本 PR 树,cherry-pick 后复跑):
api/openapi.yaml被两条 lane 同时改(A 在/v1/permissions|plans/*段、C 在/health段),cherry-pick 自动合并且契约校验逐项回到干净树基线。不在本 PR 内(明确边界)
App.Version注入(app.go:58注释声称 "settable via -ldflags / Defaults to dev",实测全仓-ldflags只有-s -w、无-X,且Version是结构体字段 ⇒ 语言层面不可能被-X赋值,生产实际值是""):lane C 的第二半,涉及release.yml7 处 build 行 + 新增包级 var,属发布管线风险面,另开切片。toast.actionUnavailablei18n key + forward 接线):仍在途,若在本 PR CI 结束前验收完会 cherry-pick 追加(concurrency: cancel-in-progress按 PR 号分组 ⇒ 追加只会取消在跑的那次,不额外付一轮完整 CI)。handlers_agents.go×6 /handlers_runtime_sessions.go×1 /handlers_settings.go×4 /model_catalog.go×1):其中 settings/health/runners/model-catalog 是 Edge 节点级配置面而非 run-scoped,是否属主化需产品裁决;agent-profiles 与 runtime-sessions 更像真缺口 → 另开 issue。验收口径
L0(单测/vet/gofmt/lint)+ L1(契约/文档 SSOT 校验)本机已跑;L2/L3 未跑(本 PR 不含需要真实 Edge→Hub 回调或浏览器登录的改动)。不声称生产就绪、不声称真实 E2E。