# 证据质量与决策复盘

LLMS 索引： [llms.txt](/llms.txt)

---

复盘拥有响应时没有的时间、权限和上下文，因此最容易犯 hindsight bias：把后来才知道
的答案投射给当时的人。决策质量必须按**当时可用信息**评估，结果质量则按后来完整
证据评估。

## 36.3.1 哪些事实当时可见，哪些后来才知道 {#item-36-3-1}

### 建 knowledge timeline

普通 timeline 记录系统事件；knowledge timeline 记录响应者何时获得什么信息：

```yaml
knowledge_id: K-...
observed_at: ...
available_to_roles: [...]
statement: ...
kind: observation | inference | report
source:
  system: ...
  object_identity: ...
  query_or_artifact_hash: ...
quality:
  directness: direct | derived | hearsay
  completeness: ...
  clock_uncertainty_ms: ...
interpretation_at_the_time: ...
decision_ids_informed: [...]
later_evidence: ...
correction: ...
```

后来发现原告警是 replica、不是 primary，不要覆盖旧记录。追加：

```text
T1 observed: endpoint E reports recovery=true
T1 inference: E is believed to be current primary
T2 correction: inventory and DCS show E was a replica
```

这样才能问：“在 T1，接受写流量是否合理？”而不是用 T2 的答案责怪 T1。

### 四栏复盘表

| 当时可见事实 | 当时假设 | 后来证据 | 当前结论 |
|---|---|---|---|
| client timeout 上升 | primary 过载 | proxy backend errors + DB 正常 | 故障在 route |
| WAL 目录增长 | WAL 生成太快 | slot restart LSN 不动 | retention owner 阻塞 |
| 新节点可写 | failover 成功 | 旧主仍可接受直连 | authority 尚未安全 |
| checksum clean | 数据无损坏 | 业务 digest 漂移 | page 完整性与语义不同 |

要求每个结论能回指源证据，并明确 source identity。截图可帮助人理解，但通常缺查询、
时间窗、变量、完整返回和 hash；关键结论保留机器可读原始投影。

### 决策日志与复盘文档分离

响应期间的 decision record 应 append-only：

```yaml
decision_id: D-...
at: ...
objective: ...
known_evidence: [K-...]
hypotheses_considered: [...]
chosen_action:
expected_observation:
stop_condition:
rollback:
authority:
```

复盘可以评价该决定，却不能重写当时输入。若事故中没有决策日志，这本身就是一个证据
缺口；不要靠会后记忆补成精确逐分钟事实。访谈内容标记为 recollection，并与日志、
审计、metric 和 trace 交叉验证。

### 证据保真与最小披露

raw evidence 可能包含 query text、角色、IP、token、客户标识或 payload。采用两层：

```text
restricted original
  immutable/retained/access-audited

review projection
  redacted, source-bound, sufficient for the claim
```

去敏不应破坏关联键；可用 stable pseudonymous token、区间、计数与 hash。复盘仓库只放
projection 和原件位置/权限，不复制 secret 或个人数据。

## 36.3.2 哪些假设被验证，哪些动作靠运气 {#item-36-3-2}

### 好结果不能证明好决策

四种组合都值得复盘：

| 决策过程 | 结果 | 判断 |
|---|---|---|
| 证据充分、边界清楚 | 成功 | 机制候选，仍需复验 |
| 证据充分、边界清楚 | 失败 | 模型或实现有缺口 |
| 猜测、无 stop/rollback | 成功 | near miss / luck |
| 猜测、无 stop/rollback | 失败 | 显性事故 |

“重启后好了”只证明重启与恢复同时发生。它可能清掉等待队列、终止事务、触发 failover、
刷新 cache 或碰巧等到下游恢复；没有前后证据就无法选出机制，也无法知道丢了什么。

### 为每个关键动作做机制审计

```text
preconditions
  执行前必须为真的事实是否被验证？

scope
  作用到 exact object/session/node/cluster 吗？

mechanism
  为什么它应改变目标症状？

expected
  多久、在哪个观察面看到什么？

stop / rollback
  哪个信号表明应停止或撤回？

result
  预期与实际是否一致？

repeatability
  在隔离环境重演后仍成立吗？
```

例如取消 exact `application_name` 会话后 lock waiters 清零，可以支持“这些 fixture
session 构成 flow pressure”；它不能证明任意高连接事故都应取消会话。又如从
known-good snapshot 恢复后业务 digest 匹配，支持该 fixture 恢复路线；它不能证明
生产 backup 覆盖同一范围。

### 验证假设，而不是验证故事

每个 hypothesis 写：

```yaml
hypothesis: H-...
prediction:
  if_true: ...
  if_false: ...
test:
  isolation: ...
  changed_variable: ...
  independent_observations: [...]
result:
alternative_explanations:
status: supported | weakened | rejected | unresolved
```

如果测试同时改变配置、版本、流量和拓扑，即使问题消失也无法归因。生产不能安全复现
时，在 clone、replay、模型或历史数据上验证，并把外推边界写清。

### near miss 也进入控制系统

这些情况值得和事故一样记录：

- 错命令被 safeguard 阻止；
- 误切换前发现 system identifier 不符；
- dangerous parameter 在唯一副本执行前被 review 拒绝；
- restore candidate 偶然正确，但 target 没有审计来源；
- unknown request outcome 恰好没有重复副作用。

near miss 提供了低损失的失效路径证据。若只统计造成用户影响的事件，平台会忽略已经
穿透多层防线、仅靠最后运气没有出事的路径。

## 36.3.3 告警、日志和时间同步缺口 {#item-36-3-3}

### 从问题反推 observation contract

不要以“多收日志”为默认行动。先列事故中无法及时回答的问题：

| 问题 | 所需信号 | identity/维度 | retention |
|---|---|---|---|
| 谁受影响 | user SLI / request outcome | service、operation、segment | 至少覆盖 SLO 窗口 |
| 查询为何慢 | wait、plan、query ID、I/O | cluster、db、role、query | 覆盖发布与周期负载 |
| 谁保留 WAL | slot/subscriber/archive | system id、timeline、slot owner | 覆盖恢复窗口 |
| 谁拥有写权威 | DCS、Patroni、timeline、route | cluster/member/endpoint | 覆盖 failover 前后 |
| 数据何时变化 | audit/WAL/business event | transaction/token/object | 由 RPO、合规决定 |
| 恢复是否可信 | backup/restore/business manifest | source/cutoff/candidate | 覆盖证据保留期 |

每个信号写 producer、collector、query、labels、刷新周期、缺失语义、owner、retention、
权限与成本。missing value 不能默认解释成 zero/healthy。

### PostgreSQL 证据的时效与局限

PostgreSQL cumulative statistics、`pg_stat_activity`、`pg_stat_replication`、
`pg_stat_replication_slots`、`pg_stat_wal`、`pg_stat_io` 等提供不同观察面，但要记录：

- counter 是累计值还是当前 gauge；
- stats reset、server restart 和 failover 是否改变基线；
- 读取 snapshot、事务和刷新延迟；
- query text 是否截断或因权限不可见；
- standby 与 primary 的语义差异；
- extension/版本是否改变列和统计；
- `NULL`、空行与零值分别意味着什么。

日志应使用可解析格式（如 `csvlog`/`jsonlog`）和稳定关联字段，但 `log_statement=all`
可能暴露敏感数据并产生高开销。优先记录必要 identity、duration、SQLSTATE、query ID、
application/client context；query 参数和 payload 按数据分类处理。

### 指标、日志与告警要能互相落点

一条值班告警（page）应先表达 user impact 或 error-budget threat，再链接诊断上下文：

```text
alert
  exact service + SLI window + burn/severity
  -> dashboard
     user outcome + dependency + PostgreSQL/host
  -> runbook
     evidence requests + route predicates + stop line
  -> raw source
     reproducible query/log projection
```

按每个 instance 发 30 条 alert 通常不如按 service impact 聚合一次，再保留 instance
分解。告警规则也需要单元/合成 time series 测试：正常、阈值边界、缺失数据、抖动和
长期低速 burn 都要覆盖。

### 时间同步是证据基础设施

至少监控：

```text
clock source and synchronization state
offset / frequency error
last successful sync
host suspend/resume or VM migration
timezone configuration
collector ingestion delay
```

数据库 `now()` 是事务开始时间；`statement_timestamp()` 与
`clock_timestamp()` 语义不同。应用、PostgreSQL log、systemd journal、proxy 和
monitoring timestamp 还可能分别来自 event time 与 ingest time。复盘合并前先统一
UTC 展示、保留原时区，并标注误差；不能靠肉眼把相近 timestamp 当因果顺序。

### 缺口行动要可验收

不要写：

```text
增加更多监控。
完善日志。
保证时间准确。
```

写成：

```text
owner: observability-platform
artifact: pg36_service user-SLI rule revision 3
test: synthetic 5% failure over declared windows
pass: fast window pages; slow burn records ticket; zero/missing remain distinguishable
clock test: inject collector offset fixture and reject order claims below uncertainty
evidence: rule test output + notification trace + dashboard link
revalidate: 30 days
```

观察能力只有在问题发生前存在、事件中可访问、事件后可重放时，才是一项控制。

---

[上一节：从时间线建立因果链](../02/) · [返回本章目录](../) · [下一节：把行动项变成控制](../04/) ·
[查看全书目录](/toc/) · [查看索引中心](/indexes/)
