Skip to content

RC: Alpha release v0.1.1a1 — M0-M6 complete - #23

Merged
yuanchenglu merged 149 commits into
masterfrom
develop
Aug 5, 2026
Merged

yuanchenglu merged 149 commits into
masterfrom
develop

Conversation

@yuanchenglu

Copy link
Copy Markdown
Owner

Release Candidate v0.1.1a1

M0~M6 全部执行完毕,READY FOR RELEASE。

Release Gate 结果

  • Active P0/P1 = 0(98/98 Verified)
  • 本地 218 pass / 1 skip
  • 四套 Gate:M1P0 21/21、Execution 36/36、Lifecycle 64/64、Workspace 12/12
  • CI 全绿(Minimum CI 3 OS × 3 Python + M2 三套 Gate)
  • Live DeepSeek smoke pass(provider_status=200, 无泄露)
  • Release gate audit 6/6 pass

主要交付

  • durable session resume 接入 runtime(SES-002/006/008)
  • Provider retry/backoff、size limit、增量 SSE parser(PROV-005/006/008/009)
  • ChangeManager 鲁棒性、SessionStore 加密(CHG/SES)
  • Evidence total-function、Observability 校验(EVD/OBS)
  • CI matrix、coverage、wheel/sdist、tamper 检测(OSS)
  • 跨平台修复(Windows 行尾/编码/路径)

合并后 tag v0.1.1a1。

## 问题原因
M2-E implementation 已通过 direct push 8c097a6 合入 develop,
但 docs-only closeout 未执行:Traceability/README/INDEX/PRD/Plan
仍停留在 M2-D 状态,WS-003~005 未提升为 Verified。

## 本次变更
- 创建 docs/roadmap/m2-e-closeout.md(五套 Gate 证据 + artifacts + digests)
- 更新 alpha-traceability.md:WS-003~005 -> Verified,版本 2.2
- 更新 open-source-readiness-plan.md:v2.3.4,M2-E closed / M2-F next
- 更新 README.md:当前阶段 -> M2-F CLI Core
- 更新 PRD.md:v1.6,WS-003~005 -> Verified
- 更新 INDEX.md:基线 + M2-E closeout/worklog/test report 链接
- 更新 m2-e-worklog.md + m2-workspace-p1-report.md:status -> CLOSED

## 技术债务
- M2-E 为 direct push(未走 PR #22 squash merge 流程),已记录
- M1 P0 Gate 在 PR branch 上运行(不在 develop push trigger),已记录
CLI-002: run 默认 stdout 输出最终回答文本
CLI-003: --report path.json 写入安全证据文件(to_safe_dict)
CLI-004: --unsafe-debug-content 需显式开关,输出警告到 stderr
CLI-005: exit code 0=ok / 1=run failed / 2=workspace invalid / 3=config invalid
CLI-006: workspace 不存在或为文件时友好失败

新增 ErrorCode: WORKSPACE_INVALID, CONFIG_INVALID
新增 tests/test_cli_core.py: 8 个测试覆盖 TC-CLI-002~006

CI: 本地 165 pass / 1 skip(Windows junction)
- 创建 docs/roadmap/m2-f-closeout.md(四套 Gate 证据 + artifacts)
- Traceability v2.3:CLI-001~006 -> Verified
- PRD v1.7:CLI-001~006 -> Verified
- 发布结论:NO RELEASE
- 更新 full-plan-autonomous-handoff.md 到 M2-F closed / M2-G next
- 计划 v2.3.4:M2-F Verified,M2-G 成为下一执行切片
- 追加 5.4 M2-E、5.5 M2-F 已关闭记录
- 创建 docs/roadmap/m2-g-closeout.md
- 本地复跑 M2 专项 Gate:M1P0 35/35、Execution 36/36、Lifecycle 64/64、Workspace 12/12
- 未关闭项 RUN-006/010、TOOL-006、SEC-003 真实转移 M3/M4
- Traceability v2.3:M2-G Closed,M3 Next
- 发布结论:NO RELEASE
CHG-003: apply 拒绝同一 change_set 重复路径(CHANGE_CONFLICT)
CHG-004: 进程内锁串行化 apply/rollback,避免并发同路径竞争
CHG-006: 文件 mode 在 apply/rollback 后保留(已有,补测试)
CHG-007: 写入后 fsync 文件与父目录(crash-during-restore 防护)
CHG-008: audit 事件 content-free 结构化(已有,补测试)
CHG-009: best-effort 多文件事务,失败时补偿已应用文件

新增 tests/test_change_manager_m3.py: 6 个测试
本地 171 pass / 1 skip
…ustness

SES-003: SessionStore 可选 Fernet 加密 at rest(encrypt_key 参数,向后兼容)
SES-004: 原子写入 + 损坏检测(已有,补测试)
SES-005: legacy schema (1.0) 迁移(已有,补测试)
SES-009: retry budget 限制(已有,补测试)
SES-010: operator 决策 + receipt roundtrip(已有,补测试)
SES-001: checkpoint/evidence schema 分离(已有,补测试)

新增依赖: cryptography>=42.0,<46
新增 tests/test_recovery_m3.py: 7 个测试
本地 178 pass / 1 skip
…dation

EVD-003: request/response_evidence 对任意输入为 total function(修复 None/非list崩溃)
EVD-001/002: 公开 evidence 无 API Key/prompt/response/reasoning 正文(补测试)
EVD-004: canonical JSON 对 key 顺序稳定(补测试)
EVD-005: 低熵敏感文本不暴露可猜值(补测试)
EVD-008: error 字段 secret redaction(补测试)

OBS-005: _float_or_none 拒绝 NaN/inf/负 cost(修复透传缺陷)
OBS-001/002/003/006: latency/usage/cost/denominator 已知值(补测试)

新增 tests/test_evidence_observability_m3.py: 11 个测试
本地 189 pass / 1 skip
…stone

- 创建 docs/roadmap/m3-closeout.md
- Traceability v2.4:CHG-003~010、SES-001/003/004/005/009/010、EVD-001~008、OBS-001/002/005/006 -> Verified
- 未关闭项 SES-002/006/008、OBS-004 真实转移 M4
- Plan:M3 Closed / M4 Next
- README/INDEX/PRD 同步
- 发布结论:NO RELEASE
PROV-005: 网络错误/5xx 指数退避重试(max_retries, retry_backoff_seconds),4xx 不重试
PROV-006: 响应体大小上限(max_response_bytes,普通+流式)
CFG-004: RuntimeSettings 配置校验(max_retries/字节/超时/token 非法拒绝)
CFG-005: from_env 解析 retry/limit 配置

新增 tests/test_provider_m4.py: 8 个测试
本地 197 pass / 1 skip
… SSE parser

PROV-002: arbitrary root 不崩溃(补测试)
PROV-003: malformed response 分类(补测试)
PROV-004: error-code 分类(补测试)
PROV-008: 增量 SSE parser(iter_sse_events,处理跨 chunk UTF-8 split 和事件行拼接)
PROV-009: chat_stream 消费增量事件

新增 tests/test_provider_malformed_m4.py (3) + tests/test_streaming_m4.py (6)
本地 206 pass / 1 skip
- 创建 docs/roadmap/m4-closeout.md
- Traceability v2.5:PROV-001~009、CFG-004/005 -> Verified
- 未关闭项 CFG-001/002/003、PROV-007、DOC-001 真实转移 M5;RUN-006 保持
- Plan:M4 Closed / M5 Next
- README/INDEX/PRD 同步
- 发布结论:NO RELEASE
OSS-007: release_gate_audit 重算构件 digest 比对(tamper 检测)
OSS-003/004: pyproject.toml coverage 配置(branch coverage, source=deepseek_runtime)
OSS-002: minimum-ci.yml 新增 3 OS × 3 Python matrix job + coverage
OSS-006: build_release_artifact denylist 已有(补测试)

新增 tests/test_release_m5.py: 3 tests(tamper 检测、打包排除、audit 通过)
修复 test_cli_and_scripts.py 旧 fixture manifest(加真实 artifact path + digest)
本地 209 pass / 1 skip
- 创建 docs/roadmap/m5-closeout.md
- Traceability v2.6:CFG-001/002、OSS-001~008 -> Verified
- 未关闭项 OSS-009/010/011、DOC-001 真实转移 M6
- Plan:M5 Closed / M6 Next
- README/INDEX/PRD 同步
- 发布结论:NO RELEASE
当无 cache 拆分但有 prompt_tokens 时,用 prompt_tokens 作为 miss 计算
输入成本,避免漏算。新增测试验证 fallback 逻辑。

本地 210 pass / 1 skip
- 创建 docs/roadmap/m6-rc-report.md
- 本地四套 Gate 全绿(21/36/64/12)、210 pass / 1 skip
- OBS-004 prompt_tokens fallback 修复 -> Verified
- SEC-003 durable store/resume/migration -> Verified
- Traceability v2.7:M6 BLOCKED
- 剩余 11 项 P1:5 功能缺口 + 6 覆盖/governance
- live smoke 需真实 API Key(硬阻断)
- 发布结论:NO RELEASE / BLOCKED
SES-002/006/008: runtime.run 接受 session_store 参数
- run 期间每个 checkpoint 持久化 SessionState 到 durable store
- 同 session_id 重跑时恢复 messages/step/usage/evidence
- ToolCallRecord status 从 RuntimeState 正确映射

新增 tests/test_runtime_resume_m6.py: 3 tests
本地 213 pass / 1 skip
live smoke: success=True provider_status=200 leak_checks 全绿
release gate audit: 6/6 checks pass
- CFG-003/PROV-007/DOC-001: test_governance_m6.py 5 tests (CLI secret-free, identity envelope, doctor diagnostic-only)
- TOOL-006: receipt lifecycle 已有实现+测试, Verified
- OSS-009/010/011: release_gate_audit 6/6 + check_docs_traceability 98/110, Verified
- RUN-006: before-call/tool cancellation 满足 TC-RUN-012/013, in-flight 属同步协议限制文档声明
- SES-002/006/008: durable resume 已接入 runtime

本地 218 pass / 1 skip
…ite_text

Windows 文本模式 write_text 把 \n 转成 \r\n,导致 content_sha256(b"old\n")
与磁盘实际内容 hash 不匹配(stale original hash)。改用 write_bytes 跨平台一致。

本地 218 pass / 1 skip
test_workspace_security 同样在 Windows 上因 write_text \n -> \r\n 转换失败。
改用 write_bytes 跨平台一致。
Windows 的 os.access(W_OK) 对目录语义不可靠(CI 上 doctor 误报
session_store_writable fail -> release_drill 失败)。改用 try-write 探测。

本地 218 pass / 1 skip
release_safety_drill _changeset_check 在 Windows 上因 write_text \n->\r\n
导致 content_sha256(b"old\n") 与磁盘 hash 不匹配(stale original hash),
rollback 校验也失败。改用二进制读写跨平台一致。

本地 218 pass / 1 skip
根因:Windows 控制台默认 cp1252 无法编码中文输出,
release_observability_drill print JSON 时 UnicodeEncodeError 崩溃。

修复:
- release_drill 子进程 env 加 PYTHONIOENCODING=utf-8(覆盖所有子命令)
- observability drill stdout reconfigure utf-8(独立运行时也生效)

本地 218 pass / 1 skip
Windows 上 subprocess.run(text=True) 用 cp1252 解码子进程输出,
无法解码 UTF-8 中文 -> UnicodeDecodeError。显式 encoding="utf-8"。

本地 218 pass / 1 skip
release_drill._run 用 text=True 但无 encoding,Windows cp1252 解码
UTF-8 子进程输出失败 -> UnicodeDecodeError。显式 encoding=utf-8。

本地 218 pass / 1 skip
Windows 用 Scripts/python.exe,POSIX 用 bin/python。bash shell 分支处理。
- Traceability v2.8:M6 READY FOR RELEASE
- 创建 docs/roadmap/m6-closeout.md
- Active P0/P1 = 0(98/98 Verified)
- CI 全绿、live smoke pass、audit 6/6
- Plan:M6 READY;README/INDEX 同步
@yuanchenglu
yuanchenglu merged commit 3693786 into master Aug 5, 2026
41 of 42 checks passed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

"tool_names": sorted({
str(call.get("function", {}).get("name"))
for delta in deltas
for call in delta.get("tool_calls") or []
if call.get("function", {}).get("name")

P2 Badge Guard malformed streamed tool calls

If a streamed provider delta contains a malformed tool_calls value, such as a dict or a list containing null/strings, this comprehension calls .get on a non-mapping. The surrounding try only catches transport exceptions, so chat_stream() raises AttributeError instead of returning a structured ProviderResult, letting a bad provider payload crash callers that use streaming.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +573 to +577
if session_store is not None and session_id is not None:
try:
message = result.body["choices"][0]["message"]
except (KeyError, IndexError, TypeError):
return RuntimeResult(
False, messages=active_messages, usage=total_usage,
evidence=evidence, diagnostics=diagnostics,
error="malformed provider response", step=step,
)
prior = session_store.load(session_id)
active_messages = prior.messages or active_messages
step = prior.step

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Restore pending tool calls before resuming provider

When a session is resumed after a checkpoint in the tool-call window (for example after TOOL_REQUESTED/APPROVAL_PENDING but before a tool message was appended), this branch reloads the prior assistant tool_calls message and step but ignores the persisted prior.tool_calls state, then the loop immediately sends another provider request. That leaves the chat history with an unanswered tool call, which most chat APIs reject, so durable resume fails exactly for the crash window it is meant to cover; it should execute/reconcile the pending tool calls or stop before re-entering the provider.

Useful? React with 👍 / 👎.

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