# 可行动 Agent 可见性提示

> Canonical path: `specs/message/actionable-agent-visibility-hints.md`
> Related specs: [`scope-model.md`](scope-model.md), [`delivery-runtime.md`](delivery-runtime.md), [`delivery-ledger-optimization.md`](delivery-ledger-optimization.md)

日期：2026-05-12
状态：current
范围：默认消息流里的 agent 可见性提示、composer / thread 的轻量受众预览、`Inspect delivery` 按需诊断入口，以及读路径成本约束。
非目标：替代 `Inspect delivery`；改变 runtime wake 语义；新增默认使用的 full diagnostics batch endpoint；为 broad delivery policy 展示精确在线快照。

## 1. 产品原则

默认消息流表达 **可行动的 agent 可见性**，不是 **诊断型 delivery outcome**。

- 正常消息不常驻展示 received / skipped / active delivery count；
- inline 提示只在用户能理解或能行动时出现；
- 完整 per-agent diagnostics 只通过 `Inspect delivery` 按需加载；
- private-agent delivery 必须解释为 scope visibility / authorization / owner-private routing，不展示成普通 public channel recipient count；
- row 和 composer 提示不得为了渲染默认可见性额外查询 delivery、agent roster、permission 或 private-share tables。

## 2. Private-agent 语义

Private agents 是 owner-private authority 下的 agent 成员，不是普通 public scope recipients。

### 2.1 Public target 是用户意图目标

当 private agent 被要求围绕 `#channel` / `#channel:thread` / task 行动时，public target 表示用户意图中的可见目标。它不代表 private agent 自动获得 raw public backlog。

后端必须用 scope membership、private grant、source refs、membership/private grant/source/task-native visibility、task-native ingress 和 shared SQL readable predicate / visible-row mapper 判定 private agent 可读输入。

### 2.2 普通 shared message 不是 private raw history

普通 public channel / thread message 不会自动成为该 surface 上所有 owner-private agents 的 raw history。

Private-agent 可见性来自明确边界：

- owner-private membership / author interval；
- owner-authorized direct private-agent mention；
- explicit source refs；
- task/execution context ingress；
- authorized non-message activity or task-native ingress；
- same-owner private collaboration within the scope.

未授权的 private-agent token 不能通过默认 delivery counts 看起来像成功 delivery；完整原因应通过 `Inspect delivery` 或已有权限提示排查。

## 3. Composer 和 header

发送前受众预览必须克制：

- 默认隐藏或弱显示；
- 只有 draft 即将跨边界、private share 状态会影响 agent 可见性、用户进入 private/task 特殊 surface、或 scope 与用户预期可能不一致时才提示；
- 提示必须短、可折叠、可隐藏；
- 不枚举 recipients；
- 不为了提示发起 backend request；
- 缺数据时不提示或显示保守入口；
- 不阻塞输入和移动端布局。

可展示的短文案示例：

- `Visible to this thread`
- `Private authorization required`
- `Visible to selected task`

更长解释应放在 tooltip、可展开详情、`Inspect delivery` 或 help entry 中。

## 4. Message row

### 4.1 正常情况保持安静

默认应保持安静的例子：

- 没有显式 agent action 的普通 public channel message；
- 没有 private share 或 agent mention 的普通 thread reply；
- private-visible message 对已授权 viewer 正常可读；
- 不承诺精确 per-agent outcome 的 broad policy message。

消息行菜单仍可提供 `Inspect delivery`。

### 4.2 只展示已有可行动状态

Inline 状态只允许使用已随 message payload、viewer context、cached capability 或 realtime/activity state 到达的数据。

约束：

- 只给能够行动的人展示；
- private 信息不外泄；
- 普通 info 默认不常驻；
- warning 可以 inline，但必须短、低视觉权重、可点击进入对应动作或 diagnostics；
- 不产生通知、unread、toast 或自动展开；
- 不因为 row 进入视口而改变其他人的阅读状态；
- 不做后台补查。

## 5. Inspect delivery

`Inspect delivery` 是完整诊断 surface。它可以按需查询并展示：

- dense scope readability；
- included / excluded wake candidates；
- owner-private authorization state；
- source refs；
- task/execution ingress；
- runtime lifecycle state；
- wake / deferred / replay / failure details；
- 单条消息解释所需的历史事实。

该 panel 只能由用户主动打开，不能在每个 visible row 上自动 fetch。

## 6. 数据契约

默认 message list 不要求返回 per-recipient delivery preview counts。

允许默认 row 使用：

- message payload；
- current viewer context；
- cached surface capability；
- existing realtime / activity state；
- current draft / mention local parsing result。

不允许默认 row 使用：

- per-message delivery diagnostics batch；
- agent roster scan；
- permission/private-share scan；
- recipient count source；
- hidden delivery materialization。

Private 相关状态必须 viewer-safe，不能让 public thread 成员通过 payload 推断 owner-private agent 活动。

## 7. 数据库访问约束

Happy path message list 为默认 row 可见性 UI 增加的后端查询必须是：

```text
0
```

不得增加：

```text
O(messages * agents)
O(messages * participants)
O(messages) full diagnostics requests
background permission / roster / recipient-count queries solely for default row visibility UI
side-table joins solely for default row visibility UI
```

`/api/messages/:id/delivery` 可以相对昂贵，因为它是用户主动触发的 diagnostic drill-down。它不能成为默认 mount / scroll / first paint 的一部分。

## 8. 验收标准

- normal message rows 不展示常驻 delivery counts；
- 普通 channel/thread 页面不发默认 per-message delivery diagnostics 请求即可渲染；
- message list 不为了默认可见性 UI join/query delivery diagnostics、agent roster、permission/private-share tables 或 recipient counts；
- composer/header visibility helper 不发 backend request；
- `Inspect delivery` 按需展示完整 diagnostics、scope membership / notification state、outbox status 和 runtime lifecycle state；
- private-agent 可见性提示不泄露 owner-private state；
- tests 覆盖 quiet normal rows、diagnostics fetch gating、reply-thread 不强制 delivery snapshot，以及 message list 默认不附带 delivery summary preview。
