docs: fold the Codex review into the issue #7 design and register it
Pins the ARCHITECTURE section 6.1 revision to land before or with the implementation, since the new scope reason contradicts the current single source of truth. Documents why SourceNotConfiguredError may sit outside the four-way classification: that rule governs transport-translated call failures, and the GatewayUnavailableError family already lives outside it. Also collapses the ten per-field response ternaries in emit_attempt into an _AttemptUsage view. They all expressed the same decision and pushed the method to cyclomatic complexity C, which blocked the commit gate.
This commit is contained in:
@@ -68,6 +68,8 @@ Issue 建议取 0。**否决**:下游 `schedule_retry(after_s=0)` 会立刻重
|
||||
|
||||
**选定**:`errors.py` 模块级常量 `GOVERNANCE_BACKEND_RETRY_AFTER_S = 5.0`,作为构造默认值,docstring 写明理由——后端恢复时间物理上不可知(不同于熔断冷却有确定到期时刻),取一个保守固定值;下游若有自己的退避策略可忽略此值。本库对 scope 级异常硬编码语义值已有先例(`retry.py:206` 的 `no_sources` 取 `0.0`)。
|
||||
|
||||
它**不是环境配置项**,故不落 CLAUDE.md §4.5「严禁硬编码默认值」的论域——§4.5 约束的是 `pydantic-settings` + `.env` 管辖的工程配置(超时、并发、限额),而本常量是异常自身携带的语义默认值,与 `no_sources` 取 `0.0` 同性质。docstring 需显式写明这一点,避免后来者误加环境键。
|
||||
|
||||
### 3.3 `scope` 的三层来源
|
||||
|
||||
| 层 | 构造点数 | scope 来源 | 改动 |
|
||||
@@ -122,7 +124,9 @@ Issue 建议取 0。**否决**:下游 `schedule_retry(after_s=0)` 会立刻重
|
||||
|
||||
## 7. 错误处理与测试策略
|
||||
|
||||
新失败面只有一个:`SourceNotConfiguredError`,落在四分类之外(它是装配缺陷而非调用失败),这是有意的——四分类描述"一次调用如何失败",装配缺陷不属于该论域。
|
||||
新失败面只有一个:`SourceNotConfiguredError`,它落在四分类之外。这**不违反** CLAUDE.md §4.2「一切失败必须落入四分类」——该铁律的论域是 **transport 层翻译的调用失败**(`ARCHITECTURE.md` §6.2 的翻译规则表逐条对应 HTTP 状态码与解析失败),而本库已有一整族异常合法地处在四分类之外:`GatewayUnavailableError` / `CircuitOpenError` / `AllSourcesExhausted` 都不是四分类之一,`ARCHITECTURE.md` §6.1 把它们单列一行,因为它们回答的是另一个问题——"整个 scope 还能不能用",而非"这一次调用怎么失败的"。
|
||||
|
||||
`SourceNotConfiguredError` 属于第三个论域:**装配缺陷**(配置与治理循环不一致,正常不可达)。四分类决定重试/换源/熔断,而装配缺陷根本不该进入治理循环去被"决定",它应当立刻失败并让人看见。将其塞进四分类中的任何一类都会赋予它一份不该有的治理语义(如 `RequestRejectedError` 会让下游以为请求本身有问题、去修请求)。§9 Q1 保留了"复用 `RequestRejectedError`"作为备选供人类权衡。
|
||||
|
||||
| 测试 | 位置 | 先失败后通过的证据 |
|
||||
|---|---|---|
|
||||
@@ -142,18 +146,34 @@ Issue 建议取 0。**否决**:下游 `schedule_retry(after_s=0)` 会立刻重
|
||||
| **版本** | **1.1.0**。有行为变更(下游对后端故障的处置路线改变)但无 API 破坏(加父类是扩大),按语义化版本走 minor |
|
||||
| **下游** | CHSAnalyzer3 当前在 1.0.1。升级后 `except GatewayUnavailableError` 即覆盖后端故障,其现有 `except GovernanceBackendError`(若有)继续有效,无需改代码即可获得修复 |
|
||||
|
||||
### 8.1 执行顺序(单一事实源纪律)
|
||||
|
||||
`ARCHITECTURE.md` 是架构单一事实源,`SCOPE_REASONS` 新增值域与 `GovernanceBackendError` 的归位都与其 §6.1 现状冲突。因此 **§6.1 的修订必须先于或同批于代码实现落地**,不得"先改代码、事后补文档"。具体为:人类批准本设计后,`writing-plans` 的第一项任务即为修订 `ARCHITECTURE.md` §6.1(补 `GovernanceBackendError` 与 `SourceNotConfiguredError` 行、scope 级 reason 值域增 `governance_backend_down`、记录本次归位的理由与日期),与实现同一分支、同批提交。
|
||||
|
||||
## 9. 待人类确认的决策点
|
||||
|
||||
| # | 决策 | 本文的选择 | 若你倾向不同 |
|
||||
(编号用 Q 前缀,避免与 `ARCHITECTURE.md` 的架构决策 D1–D14 混淆)
|
||||
|
||||
| # | 决策 | 本文的选择 | 备选 |
|
||||
|---|---|---|---|
|
||||
| D1 | "未知源"归到哪 | 拆为 `SourceNotConfiguredError`,**不**在 `GatewayUnavailableError` 之下(§3.4) | 若认为它该沿用 `GovernanceBackendError`,则 §3.4 整节作废,但需接受"配置写错永不进死信" |
|
||||
| D2 | `retry_after_s` 取值 | 常量 `5.0`(§3.2) | 可改为配置项或其他常量值;不建议取 0 |
|
||||
| D3 | 新类是否公共导出 | 是(进 `__init__.py`) | 若只作内部诊断可不导出 |
|
||||
| Q1 | "未知源"归到哪 | 拆为 `SourceNotConfiguredError`,**不**在 `GatewayUnavailableError` 之下(§3.4) | ① 沿用 `GovernanceBackendError`——需接受"配置写错永不进死信";② 复用 `RequestRejectedError`——留在四分类内、治理行为(不重试不换源快速失败)恰好正确,但语义错位会引下游去修请求 |
|
||||
| Q2 | `retry_after_s` 取值 | 常量 `5.0`(§3.2) | 可改为配置项或其他常量值;不建议取 0 |
|
||||
| Q3 | 新类是否公共导出 | 是(进 `__init__.py`) | 若只作内部诊断可不导出 |
|
||||
|
||||
## 10. 审批记录
|
||||
|
||||
| 阶段 | 状态 |
|
||||
|---|---|
|
||||
| Claude 自审 | 已完成(全部结论对应本会话内 grep/read 输出) |
|
||||
| Codex 独立审 | 待执行 |
|
||||
| Claude 自审 | 已完成(全部结论对应本会话内 grep/read 输出;§3.5 的 `self.args` 保全机制经 conda 环境实跑验证) |
|
||||
| Codex 独立审 | 已完成(2026-08-06),4 条意见逐条核验见下 |
|
||||
| 人类审批 | **待执行**(强制档:变更 `errors.py` 公共错误类型树) |
|
||||
|
||||
### 10.1 Codex 意见的核验结果
|
||||
|
||||
| 意见 | 判定 | 处置 |
|
||||
|---|---|---|
|
||||
| ARCHITECTURE §6.1 未同步前实施违反单一事实源(判为阻塞) | **实质成立**,但性质是执行顺序而非设计缺陷——§8 本已把 §6.1 回补列入影响面 | 新增 §8.1 明确"架构文档修订先于/同批于实现" |
|
||||
| §6.1 错误分类表未承认 `GovernanceBackendError`(判为阻塞) | **与上条同源**,且 §1.1 已自陈此为根因 | 同上,由 §8.1 覆盖 |
|
||||
| `SourceNotConfiguredError` 落在四分类外违反 §4.2 铁律(判为阻塞) | **部分成立**:铁律论域被误读——`GatewayUnavailableError` 族本就合法处在四分类之外(§6.1 单列一行)。但原文表述确会引起该疑虑 | §7 补写三个论域的划分论证;§9 Q1 增列"复用 `RequestRejectedError`"备选交人类权衡 |
|
||||
| 硬编码常量与 §4.5 存在张力(建议性) | **成立** | §3.2 补写"非环境配置项"及 docstring 要求 |
|
||||
| Q 编号与架构 D1–D14 混淆(建议性) | **成立** | §9 决策点编号由 `D` 改为 `Q` |
|
||||
|
||||
Reference in New Issue
Block a user