Repository navigation
Conversation
The post-read fence in _rollout_activity evicted the cursor with RECORD_UNRECOGNIZED whenever two fstat observations of one open rollout descriptor showed the same size with a changed ctime. On Windows that is metadata noise, not a same-size rewrite. Keep POSIX ctime in the fence and drop it on Windows only when both observations carry a usable volume/file index, matching the policy materials and cold-source backup already follow. The rollout cursor's own cross-time and persisted ctime checks are deliberately unchanged; they remain mutation evidence per the loopx-project#8604 audit deferral. Signed-off-by: BigDataDZ <[email protected]>
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent · gpt-6.1-sol · OpenAI · runtime_reported · reasoning_effort=max
复审提交 7030348f3002890b92aeb7044e1f8616831b86f4,实际分叉 1cdd9bbefd1d849ac8aa733bd3d80bc13ad0b722,对照主干 74ca883d5bd3e4bc64671bac54210eac9e97ed05。
[P2] 放宽 ctime 后会把已改写的 rollout 报为空闲。 同一打开文件读出结束标记后,写入方等长替换为开始标记并恢复原来的 mtime,卷号、文件索引、大小与 mtime 保持,最后一次 ctime 不同。 本机真实文件与 SQLite 线程索引走同一个 Windows 比较分支。基线返回 unknown 并显示缺少观察,候选返回 idle 且交付窗口显示 fresh。恢复普通读取后,同一文件显示 turn_open。POSIX 与 mtime 确实改变的对照仍返回 unknown。 实现位置
动机 / Motivation
查看已绑定 Codex 线程活动和最近交付窗口的用户,需要可靠地区分空闲、运行中与无法观察。 Windows 上未改写的 rollout 出现纯 ctime 偏差时,原读取会返回 unknown。候选用完整卷和文件索引、大小及 mtime 保留可识别结果。 真实 rollout 和 SQLite 线程索引上,候选的 Windows 比较分支通过了只改变 ctime 的稳定文件。POSIX ctime、缺失文件身份、mtime 变化及未读的 append 均保持原判定。 变更限于 Codex 线程观察及其消费者看到的活动状态。跨观察游标、持久缓存格式和调度授权沿原合同。
改动思路 / Approach
把 Windows 元数据容差与本次已解析事实的复核放在同一次读取内。沿用读取预算、既有游标和原错误分类。 只有完整文件身份且本次用于状态的记录能在预算内复核时,才发布被放宽的状态观察。 materials 和 cold source backup 已按文件身份处理 Windows ctime 偏差。rollout 已有读取预算、记录锚点和基于解析事实的核验。其证据期与备份不同。 在忽略 Windows ctime 的分支发布结果前,在读取预算内用新鲜字节复验支撑本次状态的实际 marker 和最近事件,包含从 forward 游标选择的记录;无法证实时返回 unknown。用纯 ctime 偏差、等尺寸改写、mtime 变化及 append 作成对测试,并在受支持的 Windows 版本运行。
具体改动 / Changes
2 个文件,增加 57 行,删除 1 行。 本轮按主干的 docs/integrations/attached-agent-session-broker.md 核对「绑定线程活动的状态和证据」和「不确定观测保持 unknown」。后者的失败可与已通过的行为并存。#8604 审计 把 Codex rollout 单次读取判定和跨次游标列为两个处置边界。
- _rollout_activity负责决定进入该分支的条件。同尺寸 Windows 读取在完整身份时不再因单一 ctime 偏差退出。状态、游标与存储契约没有新增字段。
- observe_codex_threads 是本次实际验证的调用链,回读使用原结果类型。
- _verify_facts仍是原规则的一部分。materials 和 cold source backup 已按文件身份处理 Windows ctime 偏差。rollout 已有读取预算、记录锚点和基于解析事实的核验。其证据期与备份不同。 关联合同或实现
对主干的风险 / Risks
分叉基线 126 项通过,精确候选 138 项通过。Ruff、DCO、diff、双语检查及与当前主干的模拟合并通过。 本机真实文件与 SQLite 线程索引走同一个 Windows 比较分支。基线返回 unknown 并显示缺少观察,候选返回 idle 且交付窗口显示 fresh。恢复普通读取后,同一文件显示 turn_open。POSIX 与 mtime 确实改变的对照仍返回 unknown。 反例在 macOS 上用真实文件与 SQLite,通过注入平台选项走 Windows 比较分支。未独立验证原生 Windows、打包宿主或托管 CI。 原生 Windows 对照应记录 Python 版本和硬盘类型。Python 对 st_ctime 的 Windows 语义有版本限定,Win32 允许文件保存方设置时间戳。Python stat 文档 · Win32 SetFileTime
我的整体评价 / Verdict
请求修改。保留已验证的正向修复,同时补上上述反例。在真实观察快照形成后、最终 fstat 前,等长改写结束标记,恢复 mtime。对照稳定 ctime 偏差应读到 idle,而改写应使本轮退回 unknown。
English verdict: REQUEST_CHANGES at 7030348. Tolerating ctime-only skew fixes the stable-file case. With the Windows comparison selected on macOS, a real same-size rewrite that restores mtime can still publish the old idle state and a fresh delivery window. A subsequent read sees the open turn.
| # descriptor is metadata noise, not a same-size rewrite; drop | ||
| # ctime from this one-read fence only when both observations | ||
| # carry a usable volume/file index. | ||
| fence_ctime = os.name != "nt" or not (stat.st_dev and stat.st_ino and end.st_dev and end.st_ino) |
There was a problem hiding this comment.
[P2] 放宽 ctime 后会把已改写的 rollout 报为空闲。 本机真实文件与 SQLite 线程索引走同一个 Windows 比较分支。基线返回 unknown 并显示缺少观察,候选返回 idle 且交付窗口显示 fresh。恢复普通读取后,同一文件显示 turn_open。POSIX 与 mtime 确实改变的对照仍返回 unknown。 在忽略 Windows ctime 的分支发布结果前,在读取预算内用新鲜字节复验支撑本次状态的实际 marker 和最近事件,包含从 forward 游标选择的记录;无法证实时返回 unknown。用纯 ctime 偏差、等尺寸改写、mtime 变化及 append 作成对测试,并在受支持的 Windows 版本运行。
Motivation / 动机
#8604 审计将
codex_app_thread_activity.py:249列为 SUSCEPTIBLE(Deferred):_rollout_activity读取后在同一打开描述符的两次fstat之间,只要同 size 且 mtime 或 ctime 变化,就驱逐 cursor 并返回RECORD_UNRECOGNIZED。Windows 上未变更 rollout 的纯 ctime 偏差会因此被误判为同尺寸重写。Change / 变更
loopx/codex_app_thread_activity.py:该单次读取围栏沿用 materials 与 cold-source backup(PR #8599 — qualify Windows file identity and bind backup evidence #8599)已确立的政策——POSIX 保留 ctime;Windows 仅当两次观察都带有可用卷/文件索引时才将 ctime 排除出围栏。loopx/hosts/codex_rollout_cursor.py的跨时与持久化 ctime 检查有意不动:按 [Bug]: Windows ctime-only skew can falsely reject unchanged files in remaining identity checks #8604 审计的保守处置,它们是跨观察的变异证据,属独立政策边界。Regression / 回归
tests/test_host_thread_activity.py::test_same_size_read_fence_metadata_policy——真实observe_codex_threads路径、真实 rollout fixture,stat 边界注入单一字段偏移(2 平台 × 2 字段 × 3 身份可用性,12 例):last_turn_ended_at精确);RECORD_UNRECOGNIZED驱逐。Validation / 验证
基于
main1cdd9bbef,真实 Windows 运行:uv run --extra test python -m pytest -q tests/test_host_thread_activity.py -k same_size_read_fence_metadata_policy→ 12 passeduv run --extra test python -m pytest -q tests/test_host_thread_activity.py tests/test_codex_rollout_cursor.py→ 138 passed(确认未改动的 cursor 跨时政策行为不变)Addresses the
codex_app_thread_activitysite deferred by #8604. Same family as #8761 (authority_source_capture).