> **发布元数据**：Kimi Code · Kimi K3（评测者确认）· R01
> **来源**：`kimi-code/输出/kimi-code/T12/R01/BENCHMARK_RESULT.md`
> **归属更正**：此批结果由 Kimi Code 执行；历史输出 slug `zcode` 为命名错误，原始报告 SHA-256 留存。
> **原始文件 SHA-256**：`0192f35c43ff7f1fbaf69b52735f08368cf1b50210925dbf69e3c510f33fbe5e`
> 本公开副本已将评测机绝对路径归一化；下文 PASS/FAIL/BLOCKED 是执行报告自述状态，不等同于独立验收结论。

---

PASS

# BENCHMARK_RESULT — T12 R01(两轮全部完成)

- 题目:T12 多轮约束保留(第一轮 `--by-category`;第二轮 casefold 合并)
- 冻结提交:ed2390f2df8252f062abd9123e20f6fffca7e5ed(`ed2390f Freeze ledger benchmark fixture v1`)
- 运行 ID:BENCH-RUN T12 R01
- 会话隔离:本题为独立子会话(subagent)执行,两轮读取与修改均限定在 `输出/kimi-code/T12/R01/workspace` 内;行序验证用临时 CSV 写在 `/tmp/t12_shuffled.csv`(题目明确要求写 /tmp);结果文件为 `输出/kimi-code/T12/R01/BENCHMARK_RESULT.md`;未触碰题目源文件、基准仓库及其他运行目录。

## 耗时

- 第一轮:开始 Thu Sep 24 10:41:02 CST 2026 → 结束 Thu Sep 24 10:44:07 CST 2026(约 3 分钟)。
- 第二轮:开始 Thu Sep 24 10:46:37 CST 2026 → 结束 Thu Sep 24 10:48:22 CST 2026(约 2 分钟)。

## 实际改动(两轮累计,均在 workspace 内)

1. `ledger/summary.py`
   - 新增 `summarize_by_category(transactions)`:以 `category.casefold()` 为分组键合并大小写不同的类别;返回 `{显示拼写: 整数分}`,显示拼写取组内最小 `id`(Python str 默认码点比较)记录的原始类别文本;对相同 `id` 加按类别拼写的确定性决胜(仅在 id 重复这一题面未定义情形下生效),保证结果与输入行序完全无关。求和为整数累加,本身与行序无关。
   - 新增 `format_by_category(totals)`:按 `str.casefold` 键升序逐行输出 `类别: 金额`,金额经 `format_money`;空输入返回空串。
   - `summarize` / `format_summary` 未改动。
   - (第一轮时该函数曾按原始文本精确分组、按码点排序;第二轮按约束调整为上述语义。)
2. `ledger/cli.py`(第一轮改动,第二轮无需变动)
   - `summary` 子命令新增 `--by-category` 开关(`store_true`,选项名两轮未变);启用时输出 `format_by_category(summarize_by_category(transactions))`,不启用时仍走原 `format_summary(summarize(transactions))`;`list` 子命令及 `--start-date`/`--end-date` 原样保留。
3. `tests/test_by_category.py`(新增;第二轮更新为 8 个用例)
   - casefold 合并(Food/food/FOOD 合并为一组)、显示拼写取最小 `id` 记录、最小 id 显示与行序无关、空输入、按 casefold 键升序格式化(含 display 码点序与 casefold 序不同的区分用例:`food` 排在 `Transit` 前)、默认 fixture 合计(`Food` 组合计 1196,显示 `Food` 因最小 id 为 `A-01`)。
   - CLI 级:`summary --by-category` 完整输出断言;`summary` 默认输出逐字节断言。
4. `docs/usage.md`:"汇总"一节新增/更新 `--by-category` 用法说明(casefold 分组、最小 id 拼写、casefold 键升序)。

未修改/未删除 `tests/test_baseline.py`(两轮 `git status` 均确认其无改动)。

## 第二轮实际运行的命令及原始结果

cwd 均为 workspace 根目录(临时 CSV 在 /tmp)。

### 1. `python3 -m unittest discover -s tests -v`

```
test_default_fixture_loads (test_baseline.BaselineSmokeTests) ... ok
test_default_summary_shape (test_baseline.BaselineSmokeTests) ... ok
test_list_command_runs (test_baseline.BaselineSmokeTests) ... ok
test_valid_money_inputs (test_baseline.BaselineSmokeTests) ... ok
test_default_summary_unchanged (test_by_category.ByCategoryCliTests) ... ok
test_summary_by_category_output (test_by_category.ByCategoryCliTests) ... ok
test_casefold_merges_case_variants (test_by_category.SummarizeByCategoryTests) ... ok
test_default_fixture_totals (test_by_category.SummarizeByCategoryTests) ... ok
test_display_spelling_comes_from_min_id_record (test_by_category.SummarizeByCategoryTests) ... ok
test_empty_input (test_by_category.SummarizeByCategoryTests) ... ok
test_format_by_category_sorts_by_casefold_key (test_by_category.SummarizeByCategoryTests) ... ok
test_min_id_display_does_not_depend_on_input_order (test_by_category.SummarizeByCategoryTests) ... ok

----------------------------------------------------------------------
Ran 12 tests in 0.002s

OK
unittest exit=0
```

### 2. `python3 -m ledger summary --by-category`

```
Food: $11.96
Transit: $2.00
Travel: $100.10
家庭: $3.50
exit=0
```

说明:`Food`(A-02, 12.00)+ `Food`(A-01, -0.05)+ `food`(C-01, 0.01)按 casefold 合并为 1196 分;组内最小 id 为 `A-01`,其拼写为 `Food`,故显示 `Food: $11.96`。排序按 casefold 键:`food` < `transit` < `travel` < `家庭`。

### 3. `python3 -m ledger summary`(默认输出回归)

```
exit=0
Transactions: 6
Total: $117.56
```

与第一轮改动前留档 `diff` 结果:`BYTE-IDENTICAL`(逐字节一致)。

### 4. 行序无关性验证(临时 CSV 写 /tmp)

`/tmp/t12_shuffled.csv` 为默认 fixture 的数据行整体倒序(表头相同)。执行:

```
$ python3 -m ledger summary --by-category > /tmp/t12_bycat_default.txt
default exit=0
$ python3 -m ledger --data-file /tmp/t12_shuffled.csv summary --by-category > /tmp/t12_bycat_shuffled.txt
shuffled exit=0
```

打乱后输出:

```
Food: $11.96
Transit: $2.00
Travel: $100.10
家庭: $3.50
```

`diff` 两份输出结果:`ROW-ORDER-INDEPENDENT`(逐字节一致,含显示拼写 `Food`)。

### 5. `python3 -m ledger list`(顺带回归)

```
list exit=0
```

### 6. `git status --short`(两轮累计改动清单)

```
 M docs/usage.md
 M ledger/cli.py
 M ledger/summary.py
?? tests/test_by_category.py
```

## 未完成项

- 无。第一轮与第二轮题面要求均已完成并验证。
- 已知但属其他题目范围、本题未动:`format_money` 负金额格式(T10)、`cli.py` 与 `query.py` 日期解析重复(T07)。
- 其他未知元数据:UNKNOWN。
