Skip to content

v0.5.2 — scope 生产者落地 + P2 硬化 + 失败可逆

Choose a tag to compare

@Zi-Yi-Ming Zi-Yi-Ming released this 15 Sep 06:45
· 29 commits to master since this release

[0.5.2] - 2026-09-15

Fixed(P2 小裂缝批量清理,均有证据)

  • shell=True 执行 test_command(注入面):验证器用 shell 跑来自 LLM planner 的
    test_command,P19 明令禁止。改为:默认 pytest 调用以安全 argv 列表下发(同时在 Windows 上
    避开带空格的 sys.executable 被切碎的问题),自定义命令经 shlex.split(..., posix=True)
    转为 argv 且 shell=False → ;、&&、| 退化为字面参数而非被执行。
    注:曾用 posix=False 保 Windows 反斜杠,实测引号不被剥离导致
    python -c "…" 变成空转的字符串表达式、瞬时"通过",改回 posix=True。
  • 产物 id 复用导致重试覆盖:{task_id}_output 等固定 id 让同一任务的多次尝试只留最后一份,
    历史丢失。改为 {task_id}_{kind}_{token_hex(4)}——保留 {task_id}_ 前缀以兼容
    ArtifactStore.list_for_task,多次尝试各自成档。
  • validated_at 恒为空:写入 ISO-8601 UTC 时间戳,P19 的 validation_duration 才可计算。
    (顺带:test_deterministic_validator_deterministic 的全量 dump 对比排除该时间戳。)
  • 自测超时 120s 硬编码:改为 DeterministicValidator(self_test_timeout=...) 构造参数,默认仍 120s。
    并接上 --timeout 体系:ProjectService._build_executor 现在把解析后的 task_timeout
    注入验证器,即 --timeout / PROJECTFORGE_TASK_TIMEOUT_SECONDS 同时管住"任务内所有子进程"
    (含自测)。(注:经 service 走的自测预算随之由 120s 变为配置的 task_timeout,默认 300s。)

Added

  • 检查点回滚(让"失败"真正可逆):git checkpoint 原已建好基线/逐任务提交/validator GIT 判据,
    但失败后工作区仍躺着半成品,后续任务在污染的地基上继续。现在任务判 FAILED 时
    (执行异常 / 执行结果非 IMPLEMENTED / 验证 FAIL 三条路径)回到该任务开始前的 HEAD:
    git reset --hard <head_before> + git clean -fd -e artifacts(保留审计产物)。
    因属破坏性操作,默认关闭:ExecutionOrchestrator(rollback_on_failure=True) 或
    env PROJECTFORGE_ROLLBACK_ON_FAILURE=1|true|yes 显式启用。
  • EventStore 去掉 O(n²):append 原每次重读整个 jsonl 建 id 集(n 大时 O(n²)),
    改为惰性 id 缓存 + 增量更新。保留幂等去重,并补测"换实例重开仍能对既有事件去重"。
  • 事件日志滚动:活跃文件超过 max_file_bytes 即切为 events-<时间戳>-<hex>.jsonl 分片,
    活跃文件重新起头;get_events 会读取全部分片,故滚动不会隐藏历史。
    同样默认关闭(会改变磁盘布局):EventStore(max_file_bytes=...) 或
    env PROJECTFORGE_EVENT_MAX_FILE_BYTES。(日志按 run 分片未做,留待后续。)
  • 主循环加全局时长预算:ExecutionOrchestrator(max_run_seconds=...),主循环以
    time.monotonic() 卡预算,超限即以 TIME_BUDGET_EXCEEDED 收束(与用户 CANCELLED 区分)。
    默认 None 维持原不受限行为,属显式启用;配套 env PROJECTFORGE_MAX_RUN_SECONDS
    (resolve_max_run_seconds(),未设/非法值即不受限),无需改代码即可打开闸门。

Fixed(自查中揪出的回归)

  • 事件 id 缓存跨项目串味:上一项把 id 集做成实例级单集,虽换掉了 O(n²),
    却引入新 bug——同一实例先碰项目 A 再碰 B 时,B 不会加载自己的磁盘事件,
    导致 B 既有的 event_id 被重复写入。改为按项目键控 dict[project_id, set]。
    已补针对性测试,并做 RED 校验(还原旧行为时该测试确实失败,报错为 2 == 1)。

核实后未改动的项

  • ArtifactStore.list_for_task 的"T1 匹配 T10_x"实测不重现:现有实现用
    startswith(f"{task_id}_") 的 _ 边界,T10_output 对 T1_ 为假。
    不改生产代码,补一条 T1/T10 回归测试锁定该边界行为。