fix(event-dispatcher): 权限可观测性——无权限不再静默、解析失败可观测、跨 app ou_ 校验、改名防抖 - #1006
fix(event-dispatcher): 权限可观测性——无权限不再静默、解析失败可观测、跨 app ou_ 校验、改名防抖#1006ITcathyh wants to merge 4 commits into
Conversation
p2p 私聊被挡时硬静默丢弃(注释自认待修);群聊授权申请卡被节流/ 禁用/无 owner 抑制时发送者也无感知。本次修复: - p2p 被挡:给发送者发通用无权限提示(per-(bot,sender) 10min 节流, 文案中性不泄露 owner 身份),同时把授权申请发到 owner DM (per-(bot,owner) 24h 节流,复用 dmAdmin + getOwnerOpenId) - 群聊节流窗口内:授权卡被抑制时给发送者发「已提交/冷却中」提示 (per-(bot,chat,sender) 10min 节流) - autoGrantRequestCards=false:发通用提示但不发授权卡 - maybeSendGrantRequestCard 返回判别结果(sent/throttled/disabled/ no_owner/no_requester),3 处调用点据此补发提示 - grant-pending 新增通用轻量节流 shouldThrottleNotice(独立表 + 定期 prune,不会无限增长) 所有提示/DM 均 fire-and-forget,失败只 debug 日志,不影响消息主流程。 Co-Authored-By: Claude <noreply@anthropic.com>
B-2 确定性解析失败静默:email/mobile code-0 批量响应缺失条目只标 definitive 丢弃,连 WARN 都没有;启动路径只在瞬态 failed 时通知。 - resolveAllowedUsersWithMap 返回值加 definitiveMisses(从 entryStatus 派生,ou_ 字面量恒为 resolved 不出现,transient 不列入) - email/mobile 确定性 miss 处补 WARN 日志 - 启动路径:definitiveMisses 非空时 DM owner 列出无法解析的条目 (不拒绝启动,可能是临时不可见) - setBotAllowedUsers:definitiveMisses 非空时返回 warnings 但仍写入 B-3 运行时写入不校验跨 app ou_:Dashboard onboarding 和 scripted setup 已用 detectUnusableOwnerEntries,但运行时 setBotAllowedUsers 无校验,粘贴别的 Bot 的 ou_ 被接受后静默失效。 - setBotAllowedUsers 写入前用本 bot 凭证跑 detectUnusableOwnerEntries, 确定性不可用(99992361/41012/40001/code-0 无 user)拒绝写入并返回 unusable_owner_entries + entries;inconclusive(网络/scope/无 secret) 不拒绝,fail-closed 仍由 resolver 瞬态路径兜底 - 启动路径:detectUnusableOwnerEntries 巡检 ou_/on_ 条目,跨 app ou_ DM owner 警告(不拒绝启动,fire-and-forget 不阻塞启动) 瞬态路径(缓存兜底/重试/DM)一行未动。 Co-Authored-By: Claude <noreply@anthropic.com>
proactive 标志由 CLI 自报,缺省 false → trigger=user_explicit 完全跳过 10 分钟防抖。Agent 误判「用户要求改名」时省略 --proactive,服务端无核验。 翻转信任模型: - 声明 proactive=false(user_explicit)时,要求请求携带与 ds.managedTurnOrigin 匹配的当前 turn origin 凭证 (authorizeSessionScopedIpc,固定 trustedHost=false——本机 HMAC 签名只证明「本机进程」,不绑定具体用户 turn) - 无凭证或不匹配 → 强制 proactive=true 走防抖(fail-closed: 宁防抖勿绕过) - 有有效 turn origin → user_explicit 不防抖(保留合法路径) - 显式 --proactive 仍正常走防抖,行为不变 Co-Authored-By: Claude <noreply@anthropic.com>
contact API 挂起时不得阻塞消息分发关键路径——超时后按无名处理, 与 daemon.ts notifyAllowedUsersResolveFailure 的 untimed SDK 纪律一致。 Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fcfec65987
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (!effectiveProactive) { | ||
| const originDecision = proveCurrentTurnOrigin(ds, params.sessionId, body); | ||
| if (!originDecision.ok) { | ||
| effectiveProactive = true; | ||
| trigger = 'ai_proactive'; |
There was a problem hiding this comment.
Attach the turn proof on trusted-host rename requests
For normal non-relayed CLI sessions, postSessionCliIpc loads the host secret and only reads originCapability when that secret is absent (src/cli.ts:6722-6737). Consequently, an ordinary botmux chat rename issued during a valid user turn reaches this branch without a claim and is reclassified as proactive; after one rename, a second user-requested correction within ten minutes receives rate_limited, despite the skill promising direct execution for explicit requests. The CLI needs to attach the available turn proof even when it also authenticates with HMAC.
Useful? React with 👍 / 👎.
| sessionId, | ||
| liveOrigin: ds?.managedTurnOrigin, | ||
| claimedCapability: typeof body?.originCapability === 'string' ? body.originCapability : undefined, | ||
| claimedTurnId: typeof body?.originTurnId === 'string' ? body.originTurnId : undefined, | ||
| claimedDispatchAttempt: claimedAttempt, |
There was a problem hiding this comment.
Do not treat a turn capability as proof of explicit rename intent
In read-isolated sessions, every action performed during an active user-triggered turn can present this same managed-origin capability, including an AI-initiated rename that should have used --proactive (the rename skill explicitly permits such proactive decisions). Therefore an agent that omits the flag still passes this check and bypasses the cooldown—the credential proves which current turn/process made the call, not that the user explicitly requested a rename. The exemption needs an intent-specific signal, or it should not be granted solely from the generic turn capability.
Useful? React with 👍 / 👎.
| return warnings.length > 0 | ||
| ? { ok: true, raw: rawEntries, resolved, warnings } | ||
| : { ok: true, raw: rawEntries, resolved }; |
There was a problem hiding this comment.
Surface allowed-user diagnostics through the command handler
When /config allow includes a valid owner plus an unresolvable email or phone, this function returns success with warnings, but its sole production caller in src/core/command-handler.ts:997-1004 always replies with the generic success count and discards those warnings. That leaves the operator unaware that an entry was persisted but did not take effect; the new entries detail on unusable_owner_entries is similarly reduced to a generic reason. Propagate these result details into the command reply so the runtime mutation path actually gains the intended observability.
Useful? React with 👍 / 👎.
|
CI 失败的 |
|
感谢这个 PR,权限可观测性的四个方向都切中了真实痛点,B-1/B-2/B-3 的核心机制、owner 身份边界与 fail-closed 处理经核对都没有问题。以下是一条自动评审的初步意见,仅供参考,最终以维护者审阅为准;提出一个建议合入前处理的问题和几个次要建议。 建议合入前处理1.(较重要)改名信任翻转对「默认非隔离部署」构成回归
后果:master 上 补充一点:新增的 建议修法:把信任翻转的前提改为「会话确实具备 origin-capability 传输」——即 同一个门校验的是「传输/当前轮」而非「用户意图」,所以隔离会话里若 AI 自主改名且漏传 次要建议(可同 PR 处理)
关于 CI当前 CI 失败在 再次感谢贡献。以上是自动评审的初步意见,可能有误,最终以维护者审阅为准。 |
PR 2: sprint-permission(权限可观测性 4 项)
改了什么
来自「Botmux 交流群」近 7 天用户反馈的权限专项,4 个修复:
fix(event-dispatcher): 无权限消息不再静默丢弃fix(allowed-users): 确定性解析失败可观测resolveAllowedUsersWithMap返回definitiveMisses,启动时 DM owner 列出无法解析的条目,setBotAllowedUsers返回 warnings(不拒绝写入,可能是临时不可见)。fix(allowed-users): 运行时写入校验跨 app ou_setBotAllowedUsers写入前用detectUnusableOwnerEntries校验 ou_/on_ 条目,跨 app ou_(app-scoped,对目标 Bot 无效)确定性不可用时拒绝写入并返回明确错误;inconclusive(网络/scope 错误)不拒绝(fail-closed 原则保持)。启动期巡检跨 app ou_ 并 DM owner 警告。fix(dashboard-ipc): chat-rename user_explicit 豁免防抖须持 turn origin 凭证chat rename缺省proactive=false被记为user_explicit完全跳过 10 分钟防抖。翻转信任模型:声明 user_explicit 须持有效 turn origin 凭证,否则强制 proactive 防抖。影响面
BOTMUX_OWNER_OPEN_ID注入冻结语义;p2p 提示文案不含 owner 任何身份信息测试验证
pnpm build通过pnpm test全量:18173 passed;3 个失败(bwrap/dsh 沙箱环境问题)已在干净基线复现确认预存