From 8f5caa0924a3c17b7f95349677838059a4e2ac33 Mon Sep 17 00:00:00 2001 From: iomgaa Date: Tue, 11 Aug 2026 00:12:46 -0400 Subject: [PATCH] =?UTF-8?q?docs:=20CLAUDE.md=20=E8=A1=A5=E4=B8=8A=E5=8F=91?= =?UTF-8?q?=E5=B8=83=E7=9A=84=E5=88=A4=E6=8D=AE=E4=B8=8E=E4=BB=A3=E7=90=86?= =?UTF-8?q?=E8=BF=99=E6=9D=A1=E7=8E=AF=E5=A2=83=E4=BA=8B=E5=AE=9E=EF=BC=8C?= =?UTF-8?q?=E6=B8=85=E6=8E=89=E4=B8=89=E5=A4=84=E8=BF=87=E6=9C=9F=E8=AE=B0?= =?UTF-8?q?=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit §1.10 那条指向的发布指南现在有了,同时补两件调研 PolyGateway 时核实到的:它当年那次 补救只写了文档没有回补上传,所以 1.0.6 与 1.1.0 到今天仍然不在 registry 上,而 dissect 的依赖恰好钉在那个空区间里装不上——记下教训不等于修好问题;以及发布完成的判据是外部可见 结果不是本地步骤跑通,1.1.2 三步全绿而包页面是空白的。 §4 新增一条:这台机器的代理到不了外面,访问实验室 Gitea 的命令都要绕开,否则失败看起来 像服务器挂了。过期记载三处:conda 环境早就建了、契约测试早就写了、十个模块早就不是空骨架。 Co-Authored-By: Claude Opus 5 (1M context) --- CLAUDE.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index be0ba2d..464aa8d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -56,7 +56,8 @@ **公共 Protocol 的签名是例外**:它本身就是对下游的承诺,不是实现细节,所以 `tests/contract/` 断言它是应该的。判据是这个名字有没有对外承诺过——承诺过的改名是破坏性变更(§1.3),断言它就是在守那条承诺;没承诺过的改名只是重构,断言它就是在拖后腿。 **断言某个名字「不存在」也是允许的**,用来守住一次删除决策。一个已经被删掉的字段没法被重命名,拖不动测试。代价是它守的只是名字不是概念——换个名字把同一个概念加回来,测试照样绿,所以理由必须同时写在被删字段所在类型的 docstring 里。 9. **测试分层按「依赖什么」定,不按「叫什么」定。** 用测试替身的是 unit,连真 PolyGateway 的是 integration,打真实模型网关的是 e2e,验证公共 Protocol 行为一致性的是 contract。按名字分层的话,改个函数名就要挪测试文件;按依赖分,只要这个测试还是不连外部服务,它就一直待在原地。四层之间更细的界线在搭测试框架那个阶段定,现在不必较真。 -10. **发布 = 合并 + push + tag + 构建 + 上传 registry + 验证已发布。只 bump 版本号不叫发布。** 教训来自 PolyGateway:1.0.6 与 1.1.0 都完成了版本号 bump 与 CHANGELOG,却从未上传,registry 长期停在 1.0.5——下游 `pip install` 拿不到任何修复,且无人发现。完整步骤见 `research-wiki/guides/`(还没写)。 +10. **发布 = 合并 + push + tag + 构建 + 上传 registry + 验证已发布。只 bump 版本号不叫发布。** 教训来自 PolyGateway:1.0.6 与 1.1.0 都完成了版本号 bump 与 CHANGELOG,却从未上传,registry 长期停在 1.0.5——下游 `pip install` 拿不到任何修复,且无人发现。**那次的补救只写了文档、没有回补上传,所以那两个版本到今天仍然不在 registry 上**,而 dissect 的依赖恰好钉在那个空区间里、装不上。这说明记下教训不等于修好问题。完整步骤与全部已知的坑见 `research-wiki/guides/releasing.md`。 + **判据是外部可见结果,不是本地步骤跑通**:收尾要以下游视角逐一打开产物——registry 包页面的正文与仓库链接、仓库的 Releases 页、装完之后包里的文件。PolyGateway 的 1.1.2 三步全绿,包页面却是空白的。 11. **动手前先看 README 的阶段清单。** 不要为了还没到的阶段提前写大量代码,也不要为假设中的工作量预先埋好一堆结构——这就是 §6 YAGNI 的意思,只是在阶段这个尺度上再说一次。 ## 2. 人类门(仅以下需要用户批准,其余自行判断) @@ -99,7 +100,8 @@ Codex 是 OpenAI 的编码模型,本仓库通过 `codex` 插件调用它。** ## 4. 环境与运行 -- Conda 环境 `PolyLoop`(**还没建**),Python 3.11。3.11 不是选出来的,是被下游钉死的:dissect 和 GovDoc-SaaS 都跑在 3.11,一个库不能要求比它的消费者更高的版本。 +- **这台机器设了 `http_proxy` / `https_proxy`,指向一个到不了外面的本地代理。** 凡是访问实验室 Gitea 的命令(上传发布产物、验证已发布、从私有源装包)都得绕开它,否则失败的形态是网关错误而不是「代理有问题」,很容易被当成服务器挂了。具体命令在 `research-wiki/guides/releasing.md` 与 `README.md` 的安装一节。 +- Conda 环境 `PolyLoop`,Python 3.11。3.11 不是选出来的,是被下游钉死的:dissect 和 GovDoc-SaaS 都跑在 3.11,一个库不能要求比它的消费者更高的版本。 - **Python 命令一律用这个形状**:`PYTHONUNBUFFERED=1 conda run --live-stream -n PolyLoop `。conda 和 Python 各缓冲一层,两层都得拆:只加 `--live-stream` 或只加 `-u` / `PYTHONUNBUFFERED` 都仍然全程无输出,直到进程结束才一次性吐出。六种组合的实测与原理见 `reference/CHSAnalyzer/research-wiki/explanation/conda-run-output-buffering.md`(同一台机器、同一套 conda,结论直接适用)。 - **超过约一分钟的命令(测试套件、压测、真实网关回归)必须放进 tmux 跑**,不要阻塞在前台,也不要只丢进后台。tmux 会话人和 AI 都能 attach,可以一起看同一份实时输出、随时中断。会话按用途命名(如 `polyloop-e2e`),跑完不要急着 kill,留着给人复查。 - **长跑命令末尾不得接管道。** `pytest ... | tail` 的退出码来自管道最后一节,于是失败的测试跑会报成 exit 0。要判断完成用 `wait` 或轮询 PID,**不要用 `pgrep -f "<完整命令串>"`**——它会匹配到自己,形成永不结束的等待。这两条是 PolyGateway 实测撞出来的,两种失败都以「看起来还在跑」的形态呈现,从外部区分不了。 @@ -121,8 +123,9 @@ Codex 是 OpenAI 的编码模型,本仓库通过 `codex` 插件调用它。** (公共类型和枚举取值不在这里,权威见 §0 表格) ★ research-wiki/scratch/ 一次性草稿。进 git,但由人在每轮工作会话结束前清理(AI 不要自动删) ★ tests/contract/ 公共 Protocol 的行为一致性套件,是那份契约的权威(§0), - 也是任何新适配器的准入标准。目录已建、测试还没写 -★ src/polyloop/ 库本体。十个模块的空骨架已建,内容还没写 + 也是任何新适配器的准入标准 +★ tests/e2e/ 打真实模型网关,会产生真实费用。默认不跑,两道闸见 .env.example +★ src/polyloop/ 库本体,十个模块 ``` 常青层与记录层的分界、各类的更新触发点、`scratch/` 那条人工清理规则的已知风险,都在 `research-wiki/README.md`。