# CRIEW 回信格式规范（Kernel 风格）

本文档定义 CRIEW 在 patch review 场景下的回信格式、自动填充规则与发送策略。
目标是让回复行为与内核社区邮件习惯保持一致，并与 `Patch Preview + Vim` 工作流无缝衔接。

## 文档导航

1. 范围与前置条件
2. 触发与面板行为
3. 头部默认填充与规范化规则
4. 正文格式规范
5. 发送策略
6. 发送结果与审计
7. 合规检查清单（MVP）

## 1. 范围与前置条件

- 本规范仅覆盖“回复已有邮件（reply）”场景，不覆盖“发起全新线程”。
- 前置能力：
  - VM1 已完成（`Patch Preview` 可进入 Vim 模式）。
  - SMTP 发送链路可用（MVP 阶段允许直接调用 `git send-email`）。
- 成熟版本会替换为 CRIEW 自实现 SMTP，但保持相同的回信格式与字段语义。

## 2. 触发与面板行为

在 `Patch Preview` 视图进入 Vim 模式后，自动弹出 `Reply Panel`。
发送动作必须经过 `Send Preview -> Confirm -> Send` 三步，不允许直接跳过确认。

`Reply Panel` 至少展示以下字段并允许编辑；这些字段打开时会先自动填充默认值，
但用户可在发送预览前修改：

- `From`
- `To`
- `Cc`
- `Subject`
- `Body`（Vim 编辑区）

并自动注入线程字段（只读）：

- `In-Reply-To`
- `References`

界面必须清楚区分可编辑头部字段与只读线程字段，
避免用户把 `To` / `Cc` 误认为不可修改的固定元数据。
打开 `Reply Panel` 时，初始焦点应落在 `From`，
方便用户按 Vim-like 方式向下移动并修改头部字段。

`Reply Panel` 发送区最小交互：

- `Send Preview`：生成并展示最终待发送邮件（头部 + 正文）
- 若正文里没有任何“非空、非引用、非 `On ... wrote:`”的 authored reply line，仍允许打开预览，但必须显示显著警告
- 预览中的 authored reply line 需要用明显不同于引用内容的视觉样式展示，方便最终人工检查
- `Send Preview` 复用 `Reply Panel` 的同一块界面区域做视图切换，不额外再叠一个新的对话框
- `Confirm Send`：用户确认无误后触发实际发送
- `Cancel`：取消本次发送，保留当前编辑内容

## 3. 头部默认填充与规范化规则

### 3.1 Subject（内核风格 `Re:`）

- 对原邮件 `Subject` 做规范化：
  - 若已是 `Re:`（忽略大小写），不重复添加。
  - 否则自动前置 `Re: `。
- 保留原有 `[PATCH ...]`、`[RESEND ...]` 等标签顺序，不改写主题主体。
- 该值作为 `Reply Panel` 初始值展示，用户仍可编辑；`Send Preview` 时会再次规范化为单一 `Re: ...`。

示例：

- 原标题：`[PATCH v3 2/7] mm: fix foo`
- 回信标题：`Re: [PATCH v3 2/7] mm: fix foo`

### 3.2 To / Cc（继承并排除自己）

- 默认直接继承被回复邮件中的 `To:` 与 `Cc:`。
- 上述值仅作为 `Reply Panel` 初始值；用户可改写最终收件人列表。
- 地址归一化后去重（按邮箱地址大小写不敏感比较）。
- 若 `To` / `Cc` 中包含“自己”的地址，自动移除。

“自己”地址来源（用于过滤）：

1. 当前回信 `From` 地址
2. 配置中声明的别名地址（若存在）

兜底规则：

- 若移除自己后 `To` 为空，且原邮件 `From` 不是自己，则将原邮件作者加入 `To`。
- 若仍无法得到有效收件人，则阻止发送并给出错误提示。

### 3.3 From（来自 git email 身份）

`From` 按以下优先级自动获取，作为 `Reply Panel` 初始值：

1. `git config sendemail.from`
2. `git config user.name` + `git config user.email`

用户可在 `Reply Panel` 中改写 `From`，但预览/发送前必须仍能解析出有效邮箱地址。
若无法解析有效发件身份，阻止发送并提示先配置 git email 信息。

### 3.4 线程头

- `In-Reply-To` = 当前被回复邮件的 `Message-ID`
- `References` = 原 `References` + 当前被回复邮件 `Message-ID`（去重后保序）

## 4. 正文格式规范

### 4.1 模板

回信正文默认使用纯文本模板：

```text
On <date>, <author> wrote:
> <quoted line 1>
> <quoted line 2>
```

- 使用 `>` 进行逐行引用，符合内核邮件常见 inline reply 习惯。
- 保留原文段落结构；空行引用为 `>`。

### 4.2 Enter 行为与引用层级

在 `Reply Panel` 中：

- Vim `NORMAL` 模式下，`Enter` 与 `o` 都在当前行下方新起一个空白回复行，并切入 `INSERT`。
- Vim `INSERT` 模式下，`Enter` 只执行普通换行，不自动在新行补 `>`。
- 用户自己的回复内容应写在不带 `>` 的空白行中。
- `>` / `>>` / `>>>` 等引用层级来自保留的历史引用内容，而不是编辑器自动续写。
- 若需要继续保留某段引用，用户可显式编辑对应引用行。

### 4.3 文本约束

- 纯文本（`text/plain; charset=UTF-8`）。
- 推荐软换行列宽：72（patch/diff 行不强制折行）。
- 不自动插入 HTML 或富文本结构。

## 5. 发送策略

### 5.1 MVP（必须）

MVP 通过 CRIEW 内部发送适配层完成发送：

- 用户侧仅暴露统一动作：`Send Preview`、`Confirm Send`、`Send`。
- 底层实现默认适配 `git send-email`，但实现细节对用户透明。
- CRIEW 负责生成待发送内容、拼装参数、捕获退出码与错误输出。

MVP 发送时序：

1. 用户在 `Reply Panel` 点击或触发 `Send Preview`。
2. 系统渲染最终邮件快照（`From/To/Cc/Subject/In-Reply-To/References/Body`），并在 authored reply content 为空时显示 warning。
3. 用户执行 `Confirm Send` 后，CRIEW 调用底层发送器（MVP 为 `git send-email`）。
4. 若发送失败，停留在 `Reply Panel` 并保留内容，允许重试。

底层命令形态（示意）：

```bash
git send-email \
  --from "<from>" \
  --to "<to1>" --to "<to2>" \
  --cc "<cc1>" \
  --subject "<subject>" \
  --in-reply-to "<message-id>" \
  --confirm=never \
  <reply-file>
```

### 5.2 成熟版（增强）

- 在保持同一回信格式构造器前提下，替换为 CRIEW 自实现 SMTP 发送器。
- 支持认证、重试、连接池、错误分类与发送状态追踪增强。
- 继续沿用 `Send Preview -> Confirm -> Send` 的用户交互，不改变前端行为。

## 6. 发送结果与审计

每次发送至少记录：

- `Message-ID`（若可获取）
- `thread_id` / `mail_id`
- 发送时间
- 发送器类型（`git-send-email` / `smtp-native`）
- 发送命令或 SMTP 通道
- 预览确认时间（`preview_confirmed_at`）
- 成功/失败状态
- 错误摘要（退出码、stderr 或 SMTP 错误码）

## 7. 合规检查清单（MVP）

以下条件全部满足才算回信格式合规：

1. `Subject` 为单一规范 `Re: ...`（无重复前缀）。
2. `To/Cc` 默认继承原邮件，允许用户修改，并在预览时完成去重、去自己。
3. `From` 默认来自 git email 身份，允许用户修改，但必须保持有效邮箱地址。
4. `In-Reply-To` / `References` 构造正确。
5. 正文为 `>` 引用风格；用户回复写在不带 `>` 的空白行中，引用层级由保留的历史引用体现。
6. `Send Preview` 能明确区分 authored reply line 与引用内容；若没有 authored reply line，会显示 warning，但不阻止用户完成预览确认。
7. 用户必须先完成 `Send Preview` 确认，才允许正式发送。
8. MVP 路径可通过底层 `git send-email` 完成实际发送并留存结果。
