Skip to content

fix(periodic-report): reject Windows private references - #6363

Merged
huangruiteng merged 1 commit into
mainfrom
codex/periodic-report-private-paths-20261013
Oct 13, 2026
Merged

huangruiteng merged 1 commit into
mainfrom
codex/periodic-report-private-paths-20261013

Conversation

@loopx-agent

Copy link
Copy Markdown
Collaborator

Closes #6358.

Periodic-report's request gate rejects private references written with POSIX separators, but accepts the same roots in native Windows, UNC, rooted, mixed and escaped spellings. Those references can reach composed source evidence and other consumers of the shared validator.

Extend separator runs at every junction of the existing six roots, including both multi-component roots. Keep the root set, case policy, credential check and error category. Ordinary drive/UNC references, HTTPS URLs, compact tokens and existing placeholders retain their behavior. snapshot_ref is output evidence; it does not participate in run identity.

Validation

  • Pinned base 60d833b13c85135587b725013b247e827663ffb9: the 76 new synthetic cases produce 59 expected failures / 17 passes. The failures cover the separator bypass, recursive reference fields, and file/stdin CLI acceptance; POSIX and legal-reference controls pass.
  • Exact submitted head ab5c4b8c0080a6f97894777ec189aa1ff8cd1f31: 174 focused passes (5.71 seconds) across test_periodic_report{,_adapters,_profile,_audience,_triggers,_bindings}.py. This includes the six-root spelling matrix, unchanged successful run/sink identity, CLI refusal without raw-reference output and recovery, plus rejection before a synthetic Lark send callback.
  • A bounded long non-root separator test also reaches the original reference-length error. Independent static review caught and removed a redundant repeated search prefix that could rescan long runs; internal and trailing runs still cover the required spellings.
  • CI lint scope plus changed core: Ruff PASS. Python 3.11 syntax parse PASS. Candidate public-outbound scan: zero hits. Diff hygiene PASS.
  • Canonical loopx check did not pass: the TypeScript Effect runtime exited before readiness in this isolated checkout. No dependency bootstrap was run. The static public-outbound scan above passed independently.
  • Local runtime: macOS, Python 3.14.8. These are portable string/JSON tests, not native Windows filesystem qualification. Python 3.11 runtime, full-suite pytest and remote CI remain unqualified here; normal required CI must settle separately.

复现与修复均复用 periodic-report 现有 Python 校验 owner,没有新增规则源或改变生产任务状态。修复仅补齐既有私有根目录的分隔符拼写;文件与 stdin CLI 使用原错误类别拒绝并可恢复,合法引用保持成功回执和身份。合成投递测试确认拒绝发生在发送回调前,无外部投递。File/SQLite authority store 未改动;不需要为纯请求校验启动真实存储、模型或 fleet。相邻重构检查未发现需要额外抽象的边界,保持这项修复可独立审阅和回滚。

Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Reviewer: model_agent; model=gpt-6.1-sol; provider=OpenAI; runtime_reported; reasoning_effort=xhigh

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

动机

把本地资料引用加入定期报告、准备归档或发送的 Windows 操作人员。 同一私有路径用正斜杠写入时会被拒绝,改用 Windows 盘符、UNC 或转义反斜杠却进入报告结果,可能把本机资料位置带到后续归档和发送。 当前同一私有根的这些分隔符写法在组合报告前被拒绝,错误不回显原路径;替换为公共引用后可继续原报告,公共结果和去重身份保持不变。 本次只修复原六类私有根的字符串边界,不扩大根集合或大小写策略,不认证 Windows 文件系统扫描、真实飞书投递、完整桌面交互或其他模块的隐私扫描。

改动思路

复用现有递归请求校验,只统一既有私有根之间的分隔符;不把命名模式不同的公共扫描器强行合并,也不新增配置或共享状态 owner。 有界修复报告组合和现有发送前校验;归档、发送和调度仍由原 provider 与授权入口负责。 请求先经过原递归私有值校验,成功后才组合报告;发送适配器在调用 sender 前复用这条校验。没有本地文件读取、发送授权或新的任务状态。公共引用、原错误类别和去重身份都通过完整结果比较,不能仅用一个成功码证明保持行为。

具体改动

当前精确头部 ab5c4b8c0080a6f97894777ec189aa1ff8cd1f31,实际基线 60d833b13c85135587b725013b247e827663ffb9,全部 3 文件 +229/-3 已读。先按改动前 docs/reference/protocols/periodic-report-v0.md 的 The core rejects raw content, messages, logs, transcripts, credentials, secret fields, and private paths. 判断;该条在原六类根/原大小写策略的等价分隔符边界 implemented,归档/发送授权和 Windows 文件系统全面隐私识别 out_of_scope。Issue #6358 的同路径不同写法漏检由实际 base/head 失败归因核实。

关键代码讲解

  • _LOCAL_PATH_SURFACE_PATTERN:把根前、根之间和根后分隔符扩展为正/反斜杠。根前只吃一个分隔符,search 可从分隔符长串的最后位置开始,避免重复前缀导致反复扫描;六类根、case 和 credential 规则保留。
  • _reject_raw_keys:原递归遍历整个请求,source、profile、artifact 和 sink 引用都先校验;错误只含字段标签,既不回显路径也不返回看似合法的 run 记录。
  • build_periodic_report_run:通过校验才计算原 run/sink identity 和状态。公开引用替换后的完整 packet 相等,snapshot_ref 不进入去重身份。
  • 现有 compose-run 与 LarkReportSink.publish:file/stdin 的拒绝和公共引用修复沿原入口,Lark 卡片在 sender 调用前拒绝;这只是 synthetic sender 门禁证明,没有向实际账号发送。

对主干的风险

本轮独立六个完整相关模块 174 passed。将同样新增矩阵放在冻结 base,仅调整测试 subprocess 的选定 source cwd:59 failed、19 passed、25 deselected;59 项都属于原 native/UNC/escaped/mixed 私有值漏拒绝,当前全部通过。48 个根/写法组合、三个递归字段、14 个 file/stdin 修复流程、三个 Lark sender 前拒绝和两个 65,536 分隔符长串均覆盖;11 个公共控制比较完整结果和原 run/sink identity。

正常前端构建和 wheel 构建后,在独立 Python 环境安装;三个 core/CLI/adapter owner SHA 与当前头部一致,实际安装命令 29 项通过:16 私有 file/stdin 拒绝、11 公共成功、两项超长输入按原 500 字符限制拒绝。初始构建工作目录、探针假设输出顺序及错误文本的失败保留为 setup 证据;按原 source_id 排序合同和原精确错误修正探针后才记通过,未改产品或放宽校验。

语义与 CI 对齐

advisory 后 5 direct、2 selected native premerge、完整 semantic/architecture 与 Ruff 全通过,无 manual hold。复用原 vocabulary,没有新的闭集或配置开关;这条原有机器 privacy gate 不是建议。未查询或等待 CI,未借用作者测试数量。正常报告成功/重试状态和原公共去重语义保持;根外盘符/UNC、URL、token 和 placeholder 控制保留。范围仍是原 case-sensitive 根集合,不能宣称已经检查所有 Windows 私有文件。

相关 #6362 也修复 #6358,owner 相同,但其重复根前分隔符写法与当前不同;本 PR 的长串负例资格应保留。维护者应选定一个交付批次,避免叠加两份相同目的修复。更宽公共扫描器的 lookbehind 会改变原 embedded-path 拒绝规则,强行共用会松动边界;该合并仍由既有 #5136 处理。

我的整体评价

APPROVE。long_horizon 和 user_experience 均 improved:同一私有根不再因写法变化被带入成功报告,操作人员可用原命令替换公开引用并继续,原结果身份和 retry 行为保留。复用现有递归请求校验,只统一既有私有根之间的分隔符;不把命名模式不同的公共扫描器强行合并,也不新增配置或共享状态 owner。 有界修复报告组合和现有发送前校验;归档、发送和调度仍由原 provider 与授权入口负责。 相邻前瞻检查未发现值得新增的抽象,保留已有 owner 并让更大语义合并按原 #5136 资格推进。本批准只绑定当前头部,不认证实际 Windows OS/Lark 投递或全桌面流程,也不授予 merge 权限。

English verdict: APPROVE — ab5c4b8. The existing six-root privacy boundary now rejects equivalent Windows/UNC/escaped separators without echoing private values or changing public run/sink identity. Independent 174 source cases, paired baseline failures, normal-wheel 29 CLI cases and 5 direct/2 selected checks pass; native OS and live delivery remain unverified.

@huangruiteng
huangruiteng merged commit 17bc011 into main Oct 13, 2026
30 of 32 checks passed
@huangruiteng
huangruiteng deleted the codex/periodic-report-private-paths-20261013 branch October 13, 2026 09:27
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.

[Bug]: periodic-report run core rejects POSIX private paths but not the native Windows spelling

2 participants