> **发布元数据**：ZCode · Kimi K3（评测者确认）· R01
> **来源**：`zcode/输出/zcode/T05/R01/BENCHMARK_RESULT.md`
> **原始文件 SHA-256**：`986ffd9beb3004fd2eef6d289d9c3de9341a6acd65dcd810287f892a0ba1a411`
> 本公开副本已将评测机绝对路径归一化；下文 PASS/FAIL/BLOCKED 是执行报告自述状态，不等同于独立验收结论。

---

# BENCHMARK_RESULT

状态：PASS

## 任务

T05 R01：为 `python3 -m ledger summary` 增加精确选项 `--format json`；默认输出保持基准行为；JSON 含 `count`、`total_cents`、`by_category` 三字段，`by_category` 键按 Unicode 码点升序；新增测试与简短用法说明；不删改已有测试、不加运行时依赖。

## 实际改动（均在 workspace 内）

1. `ledger/summary.py`
   - 新增 `import json`。
   - 新增 `summarize_by_category(transactions)`：按原始类别文本精确分组（不 casefold），累加整数分。
   - 新增 `format_summary_json(transactions)`：构造 `{"count", "total_cents", "by_category"}`，用 `json.dumps(..., ensure_ascii=False, sort_keys=True)` 序列化（Python 字典排序按键的 Unicode 码点升序）。
2. `ledger/cli.py`
   - summary 子命令新增 `--format` 参数：`summary_cmd.add_argument("--format", choices=["json"], ...)`，非法值由 argparse 以非零状态（exit 2）拒绝。
   - `main` 中 summary 分支：`--format json` 时输出 `format_summary_json(transactions)`，否则仍走原 `format_summary(summarize(transactions))`；输出路径仍为单次 `print`，stdout 无其他内容。
3. `tests/test_summary_json.py`（新文件，未改动 `tests/test_baseline.py`）
   - 5 个测试：JSON 可解析且字段/数值正确（count=6、total_cents=11756、by_category 分组精确到分）；by_category 键顺序等于码点升序 `["Food", "Transit", "Travel", "food", "家庭"]`；两次运行输出稳定一致；默认输出不是 JSON 且保持基准文本；非法 `--format yaml` 以非零 SystemExit 拒绝。
4. `docs/usage.md`
   - 在"汇总"小节下追加"### JSON 输出"简短说明；原有内容未删除。

未联网、未安装任何包、仅使用标准库 `json`。

## 实际运行的命令及原始输出

均在 workspace 目录下运行（python3 标准库，无第三方依赖）。

### 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_is_not_json (test_summary_json.SummaryJsonTests) ... ok
test_invalid_format_rejected (test_summary_json.SummaryJsonTests) ... usage: ledger summary [-h] [--format {json}]
ledger summary: error: argument --format: invalid choice: 'yaml' (choose from 'json')
ok
test_json_by_category_keys_sorted_by_codepoint (test_summary_json.SummaryJsonTests) ... ok
test_json_summary_output_is_stable (test_summary_json.SummaryJsonTests) ... ok
test_json_summary_parses_with_expected_fields (test_summary_json.SummaryJsonTests) ... ok

----------------------------------------------------------------------
Ran 9 tests in 0.003s

OK
```

（其中 usage/error 两行是 argparse 对非法值用例的正常 stderr 输出，对应测试断言其非零退出。）

### 2. 手动验证

```
$ python3 -m ledger summary
Transactions: 6
Total: $117.56

$ python3 -m ledger summary --format json
{"by_category": {"Food": 1195, "Transit": 200, "Travel": 10010, "food": 1, "家庭": 350}, "count": 6, "total_cents": 11756}

$ python3 -m ledger summary --format json | python3 -m json.tool
{
    "by_category": {
        "Food": 1195,
        "Transit": 200,
        "Travel": 10010,
        "food": 1,
        "\u5bb6\u5ead": 350
    },
    "count": 6,
    "total_cents": 11756
}

$ python3 -m ledger summary --format yaml
usage: ledger summary [-h] [--format {json}]
ledger summary: error: argument --format: invalid choice: 'yaml' (choose from 'json')
exit=2
```

确认：默认输出与基准一致；JSON stdout 仅一行 JSON（无日志混入）；`json.tool` 解析通过；by_category 键码点升序（Food < Transit < Travel < food < 家庭）；非法格式退出码 2。

## 耗时

约 5 分钟（实现 + 测试 + 手动验证）。

## 尚未完成的要求

无。

## 会话隔离状态

- 所有读写均在本次运行目录 `<评测根目录>/zcode/输出/zcode/T05/R01/` 内的 workspace 中完成，未访问其他路径。
- 未修改题目源文件、基准仓库或其他运行目录；未改动冻结提交内容（`git status` 仅显示本次改动：`M docs/usage.md`、`M ledger/cli.py`、`M ledger/summary.py`、`?? tests/test_summary_json.py`）。
- 未联网、未新增任何依赖（仅标准库 json）。
