目标: 完成 skill_log_compact_csv.

需求背景:
电梯场景对比分析时, 已知每次进出电梯的时刻, 需要分析在特点时间点或时间段内, DUT 和竞品机的网络特征差异.
现在的日志分析工具可以将不同特征分别从aplog 或 mdlog 里提取出来, 但是呈现的结果是多个零散的txt 或 csv 文件. 缺少了一个聚合的过程. 因此考虑设计统一的 compact csv 文件, 以便模板化检查不同问题时间点上发生的关键事件, 参数特征.

需求描述:
skill_log_compact_csv 是 skill_log_workflow 日志分析流程的一部分.
在完成skill_filter_aplog 和 skill_filter_mdlog 之后触发 skill_log_compact_csv 的处理.
处理目的是, 根据问题类型, 选择特定的 compact csv header, 生成默认1s时间戳的 compact csv 文件.

补充需求1:
 elevator 场景的 key event 需要扩展到包含关键的AP优化动作, 包括  {before_elevator,enter_elevator, inner_elevator,exit_elevator,predict fail/success, bad cell cause, 各种优化动作trigger, set 动作,  elevatorIdentity 记录}

补充需求2:
电梯进出 KEY_EVENT 的时间归属不能只依赖人工记录的严格起止窗口. 测试记录通常是手动记录, MD 侧 `ELEVATOR_STATUS` 与 AP 侧 `EVENT_ELEVATOR_ENTER/EXIT` 都可能提前或滞后几十秒. 做进出电梯识别时, 必须按人工记录前后至少 1~2 分钟放宽窗口, 且先从 MD `ELEVATOR_STATUS` 结果找 KEY_EVENT, 再从 AP filter 原始事件源中补充:
- `opt_elevator_event.txt`
- `opt_networkbrain_statemachine.txt`
- `opt_elevator_fencestore.txt`

如果放宽窗口互相重叠, 不要简单按窗口包含关系重复归属. 应按最近人工阶段、`ENTER -> EXIT -> OUT_OPT/RESULT` 序列完整性、nearElevatorId/elevatorIdentity 连续性综合归属. 若重新生成 widened compact 与原始 AP filter 的 KEY_EVENT 不一致, 以 AP filter 原始行作为事实源, 并记录 compact 聚合差异.

补充需求3:
电梯 widened compact 默认按人工记录前后 `±120s` 生成. 该窗口必须同时用于 MD 解析、AP 事件补充和 compact 聚合. 不能只放宽 AP 事件窗口, 也不能因为某设备缺 AP filter 就跳过 MD `ELEVATOR_STATUS` 的 KEY_EVENT 提取.

参考设计:
- /home/bytedance/disk4T/jieli/modem_proc_ext/skills/log_workflow/skill_code_ai_md_power/scripts/2_data_process_tool 这里有将modem 参数按照 1s 整理的方法. 可以参考.
- 以电梯分析为例, 电梯需要的 compact csv header 文件参考 /home/bytedance/disk4T/jieli/modem_proc_ext/skills/log_workflow/skill_log_compact_csv/resources/compact_csv_elevator/modem_last_1s_avg_elevator.csv

当前最小可执行脚本:
- `scripts/transpose_compact_rules.py`
  - 作用: 把电梯场景的两列表头映射文件转成 merger/脚本可直接消费的横向规则表.
- `scripts/convert_compact_rules_to_markdown.py`
  - 作用: 把电梯场景的两列 CSV/TSV 规则表转成 Markdown 规则文档, 便于按 header 补充说明.
- `scripts/compact_rule_utils.py`
  - 规则输入兼容: `generate_elevator_compact_csv.py` 的 `--transposed-rules` 可直接传入两列 CSV/TSV, 也可传入 Markdown 规则文档.
  - Markdown 约定: 每个字段使用 `#### HeaderName` 起一个 section; section 的首段作为脚本规则文本. 如需补充说明, 建议从第二段开始写, 避免污染横向规则表.
- `scripts/generate_elevator_compact_csv.py`
  - 作用: 复用已有 `aplog_filter` 与 `mdlog_filter/auto_analysis` 产物, 按 1 秒时间轴生成电梯 compact csv.
  - 当前优先覆盖电梯场景最关键字段: `Date/Time/sub/KEY_EVENT/Performance/Search_Scan/RAT/BAND/Freq_DL/SCS/Pci/DL_CC_num/SRV_STATUS/RSRP_0~3/SSB_SNR_0~3`.
  - `Performance` 来自可选 `--performance-csv` 指定的 `mp4_SmoothedTestSummary.csv`, 按 1 秒时间轴把上游 `label` 归一化为带来源和含义的字符串: `douyin_live_stutter` / `douyin_live_smooth`; 若同一秒覆盖多个区间, `douyin_live_stutter` 优先. 后续接入其它卡顿源时, 不直接透传局部枚举值.
  - `KEY_EVENT` 必须同时保留人工测试记录事实: 调用方传入的人工进/出电梯窗口起止秒要标注 `manual_enter_elevator` / `manual_exit_elevator`. 即使 MD/AP 日志没有识别到电梯进出, compact CSV 也不能丢失人工记录的进出时刻.
  - 字段来源不变量: compact csv 所有字段都优先使用 `mdlog_filter/auto_analysis` 的结构化结果, 包括 `KEY_EVENT`. 只有 MD 结果缺字段、缺时间点或缺可用值时, 才允许使用 `aplog_filter` 结果补充. AP 不能覆盖 MD 已经给出的字段值或事件归属.
  - 输出必须包含 `source_manifest.txt`, 记录 MD/AP 输入目录、规则文件、窗口列表、`KEY_EVENT` 与字段来源 policy.
  - 交付前必须校验 compact CSV 列数与 coverage summary. 电梯标准表头当前为 50 列; 生成文件存在但列数不对或 `summary.md` 缺列未解释时, 不得视为完成.
  - 对于当前复用产物里不存在的 mask/字段, 输出留空, 由 summary 明确给出缺口, 不做猜测填充.

测试示例:

```bash
python3 /home/bytedance/disk4T/jieli/modem_proc_ext/skills/log_workflow/skill_log_compact_csv/scripts/generate_elevator_compact_csv.py \
  --transposed-rules /home/bytedance/disk4T/jieli/modem_proc_ext/skills/log_workflow/skill_log_compact_csv/resources/compact_csv_elevator/modem_last_1s_avg_elevator_lines1_4_transposed.csv \
  --ap-dir /path/to/aplog_filter \
  --md-dir /path/to/mdlog_filter/auto_analysis \
  --date 2026-06-24 \
  --windows 1601_1602,1604_1605 \
  --output-dir /path/to/runs/<timestamp>_compact_csv_test/analysis/compact_csv
```

单窗口直接写入已有窗口目录:

```bash
python3 /home/bytedance/disk4T/jieli/modem_proc_ext/skills/log_workflow/skill_log_compact_csv/scripts/generate_elevator_compact_csv.py \
  --transposed-rules /home/bytedance/disk4T/jieli/modem_proc_ext/skills/log_workflow/skill_log_compact_csv/resources/compact_csv_elevator/modem_last_1s_avg_elevator_lines1_4_transposed.csv \
  --ap-dir /path/to/aplog_filter \
  --md-dir /path/to/mdlog_filter/auto_analysis \
  --date 2026-06-24 \
  --windows 1601_1602 \
  --window-output-dir /path/to/log/1601_1602
```

Markdown 规则维护示例:

```bash
python3 /home/bytedance/disk4T/jieli/modem_proc_ext/skills/log_workflow/skill_log_compact_csv/scripts/convert_compact_rules_to_markdown.py \
  --input /home/bytedance/disk4T/jieli/modem_proc_ext/skills/log_workflow/skill_log_compact_csv/resources/compact_csv_elevator/modem_last_1s_avg_elevator_lines1_4_transposed.csv \
  --output /home/bytedance/disk4T/jieli/modem_proc_ext/skills/log_workflow/skill_log_compact_csv/resources/compact_csv_elevator/compact_csv_rules.md
```

使用 Markdown 作为规则输入:

```bash
python3 /home/bytedance/disk4T/jieli/modem_proc_ext/skills/log_workflow/skill_log_compact_csv/scripts/generate_elevator_compact_csv.py \
  --transposed-rules /home/bytedance/disk4T/jieli/modem_proc_ext/skills/log_workflow/skill_log_compact_csv/resources/compact_csv_elevator/compact_csv_rules.md \
  --ap-dir /path/to/aplog_filter \
  --md-dir /path/to/mdlog_filter/auto_analysis \
  --date 2026-06-24 \
  --windows 1601_1602 \
  --window-output-dir /path/to/log/1601_1602
```
