Codex 本地中转 v1.8.1
Codex Provider Hub v1.8.1
本版本由已验证的功能变更说明自动生成。
2026-09-03-hook-encoding
- 类型:fix
- 发布级别:none
- 目标:git-bash 下触发门禁失败时,中文 policy 报错在终端清晰可读,不再显示
����。 - 实际改动:-
.githooks/commit-msg、pre-commit、pre-push:各加export PYTHONIOENCODING=utf-8+export LC_ALL=C.UTF-8。 scripts/team_policy.py:新增_ensure_utf8_stdio()并在main()入口调用,stdio 重配 UTF-8(backslashreplace,异常吞掉降级)。- 新增本说明
docs/changes/2026-09-03-hook-encoding.md。 proxy_static/dist/index.html:归一 #74 带入的 CRLF(含 1 行\r\r\n)为 LF。- 兼容性:无。仅输出编码,行为与接口不变;
none不触发发版。 - 风险:- 老环境 Python 若不支持
reconfigure:已 try 包裹降级,无影响。 - 缓解:回归跑
tests/test_team_policy.py。 - 验证结果:- A/B 对照(同终端同坏消息):旧代码输出
policy error: commit �������ʹ��ǰ�� emoji��Conventional Commit �ͼ�����������;新代码经钩子输出policy error: commit 标题必须使用前置 emoji、Conventional Commit 和简体中文描述,清晰可读。 python -m unittest tests.test_team_policy:25 tests OK。- dist 归一验证:去 CR 后与基线字节完全一致(零语义);入库 blob CR=0。
- 编辑后全文件换行符检查通过(
team_policy.py还原为 LF,diff 仅 +20 行)。 - PR:pending
2026-09-03-usage-timeline-server-route
- 类型:fix
- 发布级别:patch
- 目标:让"用量趋势"视图在正式启动的服务(
/control/{codex|claude}/)下正常返回数据,消除GET /control/codex/api/usage-timeline → 404 Not Found。 - 实际改动:-
local_proxy/server.py:- 从
local_proxy.core导入TIMELINE_MAX_CUSTOM_SECONDS; _register_control_routes新增control_usage_timeline处理器(usage_window默认24h、custom 上限 90 天、可选provider_id不存在 404、usage_store缺失 503、参数错误 422、数据库错误 503、Cache-Control: no-store,与core.py端点及 usage-history 口径一致);- 注册
GET {prefix}/api/usage-timeline(紧跟 usage-history 之后)。
- 从
tests/test_server.py:新增test_usage_timeline_is_served_per_service_console——直接请求/control/codex/api/usage-timeline与/control/claude/api/usage-timeline,断言 200、按小时分桶、桶求和与 total 一致、双服务数据隔离(7/14 tokens)、跨服务 provider 404、Cache-Control: no-store。- 兼容性:- 纯补注册,无行为迁移;
create_proxy_app单应用端点保持不变。 - 风险:- server.py 处理器与 core.py 端点行为不一致:通过镜像 usage-history 的实现方式并新增双服务隔离测试控制。
- 验证结果:-
python -m unittest tests.test_server→ 18 项全部通过(含新增 1 项,2026-09-03 16:30)。 python -m unittest tests.test_proxy_core→ 144 项全部通过(既有 timeline 用例无回归)。python -m unittest discover -s tests -p "test_*.py"→ 555 项全部通过(2026-09-03 16:31)。node --test tests/*.test.js、node --check(classic/src/provider_status)、npm ci+npm run build --prefix proxy_static→ 全部通过(2026-09-03 16:31)。- PR:#78
2026-09-03-verification-baseline-manual-release
- 类型:chore
- 发布级别:none
- 目标:降低交付门禁的时间与 Agent token 成本,并让发版回归人工确认:
- 删除依赖真实桌面环境的 GUI 冒烟测试(
GuiSmokeTests)。 - pre-push 全量验证改为基线对比:失败集合是 merge-base(origin/main)基线子集时放行、不排查;只拦截本次改动新增的失败。
- 发版从合并后自动触发改为人工确认:Agent 汇总待发布内容并向用户确认后,手动触发发版协调工作流创建标签并派发双平台发布。
- 实际改动:-
scripts/team_policy.py:- 新增失败解析(
UNITTEST_FAILURE_RE、NODE_FAILURE_RE、parse_unittest_failures、parse_node_failures)与哨兵常量(套件非零退出但解析不到失败 ID 时保守拦截); run_full_verification()重构:npm ci、npm run build、node --check全部为硬门禁;Python unittest 与逐文件node --test改为"可比对套件",失败集合与 merge-base 基线比对,子集放行(打印忽略数量),新增失败复跑一次确认后仍失败才阻止;- 新增基线设施:
run_comparable_suites、diff_new_failures、_baseline_cache_path(.git/policy-baselines/<merge-base>.json)、read_baseline_cache/write_baseline_cache(写入时清理旧缓存)、collect_baseline(临时 worktree 检出 merge-base 跑可比对套件,不跑 npm)、load_or_build_baseline、_confirm_new_failures。
- 新增失败解析(
tests/test_probe_codex_gui.py:删除GuiSmokeTests及其专用 import(json/os/subprocess/sys/Path/ROOT/GUI_SCRIPT);保留两个纯单元测试类。.github/workflows/auto-release.yml重命名为release.yml:名称改为 Manual Release,触发改为workflow_dispatch;计划计算、标签创建与双平台派发逻辑不变。AGENTS.md:Git 与 PR 增加基线对比条款;"自动版本与自动发版"改为"版本与人工确认发版"(合并后不自动发版,Agent 汇总并向用户确认后触发release.yml);硬停止条件改为"本地全量验证未运行,或出现基线之外的新增失败"。.agents/skills/git-commit-helper/SKILL.md:第 8/9/10 步与停止条件同步新口径(基线对比、无自动发版、用户同意后gh workflow run release.yml --ref main)。tests/test_team_policy.py:治理断言更新(AGENTS/skill 新文案、release.yml 手动触发且 auto-release.yml 不存在);新增VerificationBaselineTests6 项(unittest/TAP 失败解析、去重、子集放行与新增项判定、哨兵、基线缓存 roundtrip 与旧缓存清理)。- 兼容性:- 无产品运行时影响,仅改交付工具链;
release_bump = "none",不产生产品版本发布。 - 基线缓存位于
.git/(不提交、不进版本库),旧缓存条目在写入新基线时清理。 - 已有
release-plan/release-notesCLI 与函数不变,发版工作流复用。 - 风险:1. 基线对比对偶发失败(flaky)不免疫:新增失败复跑一次确认后仍失败才拦截;基线侧偶发失败会进缓存导致放行偏松(可接受方向:宁松勿卡)。
- node 逐文件失败按测试名集合比对,个别 reporter 格式变化可能解析不到 → 解析为空集合等同"无既有失败",退化为严格模式(安全方向)。
- 基线在临时 worktree 跑 Python 套件依赖本机环境(如 fake-IP DNS):基线与 HEAD 在同一台机器运行,环境性失败同时出现在两侧,自动对消——这正是本设计要解决的问题。
- 自动发版取消后,若 Agent 忘记询问用户,改动会滞留在 main 未发布:由 skill 步骤强制要求合并后必须给出"发版或跳过"的提议收尾。
- 验证结果:-
python -m unittest tests.test_team_policy tests.test_probe_codex_gui tests.test_project_documentation→ 39 项全部通过(2026-09-03)。 - 端到端演练基线机制(2026-09-03 15:10):HEAD 可比对套件 18.6s 失败 0;merge-base(5f06e6e)基线 17.9s 失败 1(main 上仍存在的冒烟测试在本机 cc-switch 无供应商时失败);
diff_new_failures为空 → 按新规则应放行且无需排查,行为符合设计;基线缓存已写入.git/policy-baselines/。 python -m unittest discover -s tests -p "test_*.py"→ 554 项全部通过(2026-09-03)。node --test tests/*.test.js、node --check(classic/src/provider_status)、npm ci+npm run build --prefix proxy_static→ 全部通过(2026-09-03)。- 实际推送本分支时由新版 pre-push 钩子执行真实基线对比(见 PR 与推送记录)。
- PR:#76