---
description: harness-submit 的确定性提交协议。用于避免 blocking user confirmation 参数错误、中文 commit message 失败、Co-Authored-By 违规和先 commit 后 amend。
---

# Submit Protocol

## 交互模板固定化

提交方式选择必须使用固定选项，不临场拼复杂参数：

```text
请选择提交方式：
1. commit + push 到当前 upstream
2. 仅本地 commit，不 push
3. 取消提交
```

commit message 确认必须展示：staged 文件、diff stat、完整 commit message、是否 push。
用户未明确确认前不得 commit。

## commit message 文件流程

中文 commit message 永远写入临时文件，再用 `git commit -F`：

```powershell
powershell.exe -NoProfile -Command "git -C '<项目路径>' commit -F '.harness/changes/<change>/runtime/commit-message.txt'"
```

禁止：

- 命令行内联长中文 message；
- 先英文 commit 再 `git commit --amend` 成中文；
- 使用 `--no-verify` / `--no-gpg-sign`；
- 生成 `Co-Authored-By`、`Generated by`、`AI generated` 等 footer。

## commit message 内容

格式：

```text
<type>(<scope>): <中文摘要>

- 变更点 1
- 变更点 2

验证：
- <复用 ledger 或重跑验证摘要>
```

footer 默认为空。确需 issue footer 时必须由用户明确要求。

## 远端检查

push 前必须：

```powershell
powershell.exe -NoProfile -Command "git -C '<项目路径>' fetch"
powershell.exe -NoProfile -Command "git -C '<项目路径>' log HEAD..@{u} --oneline"
```

远端有新提交时，不得直接 push。必须让用户选择：rebase 后重验 / 停止 push。

## 提交状态映射

submit 阶段的最终状态必须按以下映射落到三态标记，与 `evidence-based-reporting-protocol.md` 的 Git 操作状态对齐。不得用"提交成功"这类模糊表述，必须带状态标记和具体原因。

| 提交结果 | 状态标记 | 报告表述 |
|----------|:--------:|----------|
| commit 成功且 push 成功（git push 输出含 `To <remote>` + 实际推送范围） | ✅OK | ✅OK 已提交并推送：commit `<hash>`，push 到 `<upstream>` |
| 远端有新提交需 pull/rebase 后重验，或用户选择仅本地 commit 不 push | 🟡WARN(原因) | 🟡WARN(仅本地 commit，未 push) / 🟡WARN(远端有新提交，需 rebase 后重验) |
| push 失败 / 被远端拒绝 / commit 失败 / pre-commit hook 拒绝 / exit code 非 0 | ❌FAIL(原因) | ❌FAIL(push 失败：`<原因>`) / ❌FAIL(commit 失败：`<原因>`) / ❌FAIL(hook 拒绝：`<原因>`) |

说明：

- **✅OK** 必须同时具备 commit 与 push 的成功证据；仅本地 commit 成功不算 ✅OK。
- **🟡WARN** 是"提交动作完成但未达到完整推送"的中间态：用户主动选择仅本地 commit，或远端领先需 rebase。必须在原因中写明是"用户选择仅本地"还是"远端领先"。
- **❌FAIL** 涵盖所有硬失败：push 被拒绝（含非 fast-forward 未处理）、commit 命令失败、hook 拒绝。出现时不得宣称"已提交"，必须停止并请求用户介入。
- 与 `evidence-based-reporting-protocol.md` 的 Git 操作状态映射一致：`To <remote>` + 推送范围 → ✅；无输出/状态未知 → ❌；被 hook 拒绝 → ❌。
