Skip to content

test(deps): D1 把 launcher/requirements-small.txt 一起纳入「钉版 vs 声明」核对 - #106

Merged
ReSerendipity merged 1 commit into
mainfrom
test/d1-covers-launcher-small
Sep 21, 2026
Merged

ReSerendipity merged 1 commit into
mainfrom
test/d1-covers-launcher-small

Conversation

@ReSerendipity

Copy link
Copy Markdown
Owner

为什么

Dependabot 抬 Python 依赖时只改两份钉版文件、不碰声明#88 改的正是
requirements-lock.txt + launcher/requirements-small.txt。而 tests/test_dependency_consistency.py
的 D1 原先只核对锁 ↔ 声明,小清单那半边没人看。

check_pin_crossconflicts.py 能抓到 #88,但它用的是另一套判据("被钉住的包自己的 PyPI 元数据
互相冲突"),跟"声明写着 <4.53"不是同一件事。两套判据都该在本地跑得出同样的结论 ——
这条就是把缺的那半补齐,12 行改动。

#81 的关系

#81 带的 scripts/check_pin_floors.py(+185 行)做的就是这件事(声明下界 vs 两份钉版集,
外加 --allow-debt 棘轮)。它有两处不好照单收:前提写在错误的 transformers>=4.57.0
#103 已推翻),以及同一分支还带着 app_server.py + security/integrity_manifest.json(.sig)
两处按约定归所有者的改动。所以这里用一条测试覆盖同一判据,#81 的处置另在该 PR 里给结论。

改动与验证

  • D1 的核对目标从 1 份变 2 份(requirements-lock.txt + launcher/requirements-small.txt),
    违规消息带文件名前缀。
  • 防空转断言加强:小清单实测能对上 21 个声明包(门槛 ≥20),并合成一次 build(deps): bump transformers from 4.52.1 to 5.17.0 #88 的形状
    (小清单里 transformers=5.17.0 + tokenizers=0.23.1)——必须报错。
  • 本机:tests/test_dependency_consistency.py 11 passedruff check / format --check 全绿;
    scripts/check_pin_crossconflicts.py冲突 0 条 → PASS(exit 0);
    两文件共享的 92 个包当前版本零差异(所以本条不会让 CI 变红,只是把判据补全)。

排查过程中我一度以为锁里有真冲突(transformers==4.52.1 vs huggingface-hub==0.36.2),
复核后是我的读输出串了行:PyPI 元数据显示 4.52.1 要 huggingface-hub>=0.30.0,<1.0
0.36.2 在区间内,检查器也判 0 冲突 —— 记在这里是为了说明"锁可安装"这条结论仍然是绿的。

理由不是补齐对称性,而是 Dependabot 抬依赖时**只改两份钉版文件、不碰声明**:#88
(transformers 4.52.1→5.17.0)改的就是 `requirements-lock.txt` + `launcher/requirements-small.txt`。
原先 D1 只看锁,小清单那半边的漂移没人核对;而 #88 在 CI 上红,红的是
`check_pin_crossconflicts.py` 那条"钉版包自身元数据互相冲突"的路径 —— 与"声明说 <4.53"
这件事是两套判据,本地缺一套。

顺带把 #81 里 `scripts/check_pin_floors.py` 的意图收进来:那个检查器做的事与 D1 高度重合
(声明下界 vs 两份钉版集,含 `--allow-debt` 棘轮),但它的前提写在错误的 `>=4.57.0` 上,
而且随分支还带着 `app_server.py` + `security/integrity_manifest.json(.sig)` 这两处禁区改动。
用 20 行测试覆盖同一判据,比整分支合进来干净。

防空转断言同步加强:小清单实际能对上 **21 个**声明包(≥20 才放行),并把小清单里的
transformers 改成 5.17.0 + tokenizers 0.23.1 造一次 #88 的形状,必须报错。
当前两文件共享 92 个包、版本零差异。

Signed-off-by: ReSerendipity <zengyangc@outlook.com>
@ReSerendipity
ReSerendipity merged commit 41f5a12 into main Sep 21, 2026
29 checks passed
ReSerendipity added a commit that referenced this pull request Sep 21, 2026
现状(`app_server.py:808-821`,本仓自 CSRF 落地起一直如此):读 `data/.csrf_secret` 抛 OSError
时只 `logger.warning("回退到无签名模式")`,服务照常起、照常接请求 —— 只是 CSRF token 从此没有
HMAC 绑定。目录只读 / 磁盘满 / 权限被改任一情况都会静默削弱一道安全机制,与"前置条件不满足要
硬失败并给可操作建议"的口径相反(同一形状的静默降级在 #132、OpenAI 口 500 上都复现过)。
这也是 #81 唯一还留着的实质内容(它的地板棘轮部分已被 check_pin_crossconflicts 进 CI +
tests/test_dependency_consistency.py 的 D1/D2 + #106 取代)。

改动:
- `app_server`:密钥解析抽成 `_load_or_create_csrf_secret(path)`,任何失败一律 `RuntimeError`,
  消息点名路径并给排查方向(目录可写 / 磁盘 / 容器只读根 fs 时 data 要走卷)。
- `CSRFMiddleware.__init__`:空 `secret_key` 直接 `ValueError`,装配期就拦,防止别处 new 一个
  空密钥把这条规矩绕过去。
- 清单与签名已重生成/重签(`generate_integrity_manifest.py` → `sign_integrity_manifest.py`),
  `--verify` 通过、`check_integrity_manifest_sync.py` exit 0。

一个必须记下来的坑(第一版就踩了):**清单要在行尾归一化之后生成**。
`git add` 时按 `.gitattributes`(`*.py text eol=lf`)把 CRLF 归一化成 LF,而我第一次是在还带
CRLF 的工作树上生成清单的 → 清单里存的是"CRLF 字节"的哈希,签名对这份清单本身**完全有效**
(`--verify` PASS!),但运行时自检按 LF 检出结果比哈希 → `run_startup_selfcheck(enforce=True)`
判定 `app_server.py`、`middleware/csrf.py` 校验失败。也就是说"验签通过"不等于"清单是对的",
两者要分别验。修法是归一化后重新生成再签。

顺带更正一处测试里的错前提:`test_csrf_integration.py` 两个用例拿裸字符串 "x" 同时当 cookie 和
header,那只对"空密钥=不签名"的旧行为成立;配了密钥之后中间件确实会做 HMAC 校验,于是改成先
GET 取一枚中间件自己签发的 token —— 这同时证实签名校验这条链路是生效的,不是摆设。

验证:新增 `tests/test_csrf_secret_hardfail.py` 5 条(生成并落盘 / 空白文件重生成 / 不可写位置
硬失败且文案含出路 / 空密钥装配期拒绝 / 有密钥仍可装配=防空转);`test_csrf_integration.py` 13 条;
`test_secret_key_and_manifest_signature.py` 12 条全过;**全量 2094 passed / 0 failed**;
ruff / format 干净,mypy 维持 103 = 基线。

Signed-off-by: ReSerendipity <zengyangc@outlook.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant