---
template: sheet
theme: shadcn
title: am 0.5.7 升级核验 + 复盘 md 写法审计
subtitle: 结构已合规，文字未合规 —— 65 条 STE 警告的来历与改法
cols: 3
source: am v0.5.7 · 样本 report_20261023.am.md
---
结论：am 已经在 v0.5.7（与发布包字节一致）。复盘 md 的**结构**完全符合插件；**文字**不符合，现在靠 `--style off` 屏蔽掉 65 条警告。

## A 升级核验

```kv cols=2
本地 am 版本: 0.5.7
发布包 sha256: 26d2d886…83fd8（一致）
源码仓 /root/tools: 0.5.0 → v0.5.7
最新发布: v0.5.7（10-21）
main 分支未发版提交: 1 条（am serve --tailscale）
```

v0.5.7 的核心变更是**「一次列全错误」**。实测通过：给一份故意写坏三处的草稿，返回 3 条错误，一次全给。

```text
✗ L6  kv: 键值必须用冒号
✗ L9  table has no delimiter row
✗ L13 flow: unclosed shape bracket
✗ 3 errors in the draft; no page was written
```

从 stdin 渲染失败时草稿会存到 `~/.answer-me-with-html/drafts/`，路径直接打印出来。以后修错＝改那个文件再 `am render <path>`，不用整篇重写。

## B 结构审计：已合规

样本 `report_20261023.am.md`，32 KB，7 面板。

| 检查项 | 结果 | 证据 |
|---|---|---|
| 面板形态 `##` | ok | 7 个面板标题 |
| 多 H1 | ok | 正文 H1 数量 0 |
| 正文 `---` 分隔线 | ok | 仅 frontmatter 两条 |
| 「模块 N:」双编号 | ok | 0 处 |
| `####` 孤儿级 | ok | 0 处，只有 `###` |
| `kv` 用冒号 | ok | 1 块，13 行全冒号 |
| 表格分隔行 `\|---\|` | ok | 17 张表全部齐 |
| 模板选择 | ok | `doc` 适合七模块顺序长文 |
| 摘要卡片 | ok | `callout info 复盘摘要` |
| 文字 STE 合规 | no | 65 条警告 |

结论：能正常出页、组件不报错、版式正确。问题全部在最后一行。

## C 65 条警告的分布

```chart bar horizontal unit=条
| 警告数
消息面与驱动归因 | 17
正确率验证与自我迭代 | 16
资金行为与主线因果链 | 12
明日交易计划 | 12
市场状态与多日趋势 | 6
双轨判断 | 2
涨停结构与主线真假 | 0
```

警告只有两类，都不在结构上：

- `sentence-length`：编号列表项超过 35 字，普通句子超过 45 字。消息面 12 条新闻每条约 60–119 字，全部按「步骤」判定。
- `word`：`以内`、`多次`、`大幅` 这类模糊词。

涨停结构那一块 0 警告——因为它本来就是表格。

## D 为什么现在不出警告

`/root/web_reports/am_bridge.py` 第 182 行 `def render(..., style="off")`。所有生产页（复盘、早盘、LXXG）都走这个默认值。

这是**主动关掉的**，不是没检查过。关掉的好处是页面能出；代价是文字规范没人守，45 字长句一路写下去，页面上就变成一坨。

注意：警告不拦渲染。就算开 `--style 80`，今天这份 md 照样出 7 面板页，只是会打出 65 行提示。`--style strict` 才是真拦。

## E 插件吃的写法：形状对组件

不是「写得好看」，是「选对组件」。同一份内容换个形状，警告就没了。

| 内容形状 | 该用的组件 | 硬性写法 |
|---|---|---|
| 当日状态、行情定级 | ` ```kv cols=3 ` | `键: 值`，必须冒号 |
| 结论、风险、验证条件 | ` ```callout info\|warn\|ok\|err 标题 ` | 正文按段写，枚举必须 `- ` 成条 |
| 事件列表（消息面、政策） | Markdown 表 | 必须 `\|---\|`；状态词 `ok/no/warn` 打头 |
| 多场景路由（场景 A/B/C） | 表格 4 列：场景、概率、触发、应对 | 别用「**场景A** …」整段 |
| 排名对比（资金、涨停梯队） | ` ```chart bar horizontal ` + 表 | 数字裸值、无千分位 |
| 计数对比上限（家数、占比） | ` ```limits ` | `标签 \| 值 / 上限 \| 单位` |
| 因果链、主线传导 | ` ```flow LR ` | 节点写文字，不写 `A[文字]` |
| 规则池健康度 | 表格 | 准确率单独成列 |

三条最容易犯的：

- **编号列表是 35 字硬限**。`1. 隔夜美股纳指-2.60%…` 这种一长条必然报警。事实类改表格，结论类拆成 `- ` 短句。
- **表格单元格里不写句号**。实测：单元格内用顿号、逗号罗列数字（不加句号）不触发句长检查，加了句号就按句子算。48 个数字全在、0 警告。
- **`以内` 写「不超过」，`多次` 写次数**。这是词级检查，两个字的改动。

## F 实证：消息面面板 17 → 0

同一批 12 条消息，同一批数字，只改形状。

```diff
- 1. 隔夜美股纳指-2.60%(创6月以来最大单日跌幅)、标普-1.21%、道指+0.02%,Meta-6.98%、芯片设备泛林-11.76%,10年美债收益率降19bp至4.953% → A股三大指数全线低开…
+ | 隔夜美股大跌 | 纳指-2.60%，标普-1.21%，道指+0.02% | 三大指数全线低开 |
+ | 芯片设备杀跌 | 泛林-11.76%，Meta-6.98% | 盘初科技承压 |
+ | 美债利率回落 | 10年美债降19bp至4.953% | 成长估值压制缓释 |
```

结果：

```kv cols=3
STE 警告: 17 → 0
内容覆盖: 48/48 项数字
标的/规则号: 0 缺失
```

覆盖核对跑的是 `coverage_check.py`，48 个关键数字一个没丢。改写结果是 `/root/web_reports/demo_news_am_20261023.md`，可直接对照。

这一步证明的不是「我删了几句话」，而是**内容全留、警告归零**。剩下 6 个面板（共 48 条警告）用同一套办法。

## G 怎么转化：三条路径

| 路径 | 做法 | 代价 |
|---|---|---|
| 改生成侧（正解） | 在 `build_report.py` 里把消息面、场景路由、教训三块直接输出表格与短句 | 改动大，需回归核对 |
| 加规整层 | `am_md_norm.py` 增一道句长拆句 | 机械拆句易出碎片，风险中 |
| 维持现状 | 继续 `--style off` | 零成本，文字永远不达标 |

推荐第一条 + 闸门验收：改完把 `style` 从 `off` 提到 `80`，**验收标准是 `STE ✓ 0 warnings`**，不是「页面能打开」。

```flow LR
(引擎 md) -> (am_md_norm 结构规整) -> (生成侧短句/表格) -> (am render style 80)
(am render style 80) -> {0 warnings?}
{0 warnings?} -> (发布 qpyjs) : ok
{0 warnings?} -> (回改草稿) : no
```

## H 每次渲染前的自检

- 面板数 3–8，结论在第一个面板，字母 ID 不重。
- 表数 == `\|---\|` 行数：`grep -c '^|' / grep -c '^|---'`。
- `kv` 全冒号，`limits` 全带 `/ 上限`，`limits` 值列纯数字。
- 编号列表项 ≤35 字，普通句 ≤45 字，无 `以内/多次/大幅`。
- 渲染输出必须是 `✓` + `STE ✓ 0 warnings`，不是只有 `✓`。
- 用了 `-o` 就回读文件内关键值；渲染失败时旧页不会消失，`curl -sI` 照样 200。
