8c9e1179bc
The independent verifier found 15 more checks still living only in from_env: six enum domains, seven conditional-required pairs and two scalar ranges. More severe than round one because client.py has five asserts that claim config already validated the redis_url and telemetry paths, which is false on the from_settings path. Also records a normalisation gap the verifier missed: _load_pg_dsn strips the SQLAlchemy +asyncpg suffix, so a hand-built DSN reaches asyncpg unstripped.
1.7 KiB
1.7 KiB
type, node_id, title, date
| type | node_id | title | date |
|---|---|---|---|
| design | design:settings-invariants-round-2 | GatewaySettings 装配校验补齐(第二轮) | 2026-07-30 |
GatewaySettings 装配校验补齐(第二轮)
全文见 2026-07-30-settings-invariants-round-2-design.md。第一轮见 settings-invariant-guards。
- 缘起: 第一轮交付后独立 verifier 发现
from_env上还留着 15 条同族校验(枚举合法域 6、条件必填 7、标量域 2),from_settings与直接构造全部放行。 - 严重性高于第一轮:
client.py:262/282/302/312/316有 5 处assert ... # 内部不变量: config 已校验明文依赖这个前提;实测断言开启抛裸AssertionError,python -O下退化为 redis 库天书。 - 方案: 沿用第一轮已批准的方案 A,不重新论证;新增
_validate_backends/_validate_cache/_validate_telemetry,枚举合法域上提为模块级常量供_load_pgw与构造期共用。 - assert 处置: 保留不改——前提一旦由构造期保证,它就是 CLAUDE.md §4.3 认可的内部不变量用法且给类型检查器收窄
str | None;只改那句会变成谎言的注释,点明由哪个方法保证。 - 本轮唯一新决策:
_load_pg_dsn剥+asyncpg驱动后缀是规范化不是校验,直接构造那条路不会剥。选校验拒绝(显式)而非构造期object.__setattr__剥后缀(在用户背后改 frozen 字段)。两条路接受度不同是有意的:env 路要吃三项目历史遗留的 SQLAlchemy DSN 写法,代码构造路没有历史包袱。 - 版本: 1.0.2(patch),CHANGELOG 单列"行为收紧"小节。