Skip to content

fix(capability): detect native and escaped Windows private paths in public-safe-outbound - #6223

Merged
huangruiteng merged 1 commit into
loopx-project:mainfrom
JasonBuildAI:codex/public-safe-outbound-windows-path-v5r2
Oct 12, 2026
Merged

huangruiteng merged 1 commit into
loopx-project:mainfrom
JasonBuildAI:codex/public-safe-outbound-windows-path-v5r2

Conversation

@JasonBuildAI

@JasonBuildAI JasonBuildAI commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Goal And Delivered Outcome

Author Declaration

Implemented against

Criterion (spec clause) Disposition Symbol / path Test or command
Native drive-letter spelling is a hit and fails the scan implemented loopx/capabilities/public_safe_outbound/scanner.py (private_abs_path) loopx/capabilities/public_safe_outbound/tests/test_scanner.py::test_detects_native_windows_private_path
UNC spelling is a hit and fails the scan implemented same same
Escaped serialized spelling (C:\\Users\\<name>\\...) is a hit implemented same ...::test_detects_escaped_and_mixed_windows_private_path
Mixed and drive-rooted separator spellings are hits implemented same same
A drive path outside the private roots stays clean implemented same ...::test_native_windows_path_outside_the_private_roots_stay_clean
Case-insensitive Windows spellings (C:\users\...) deferred — Unchanged; disclosed in #6220
Non-ASCII user names (/home/<non-ASCII-name>/) out_of_scope — Pre-existing name class shared by every spelling; separate decision
  • Self-check before submission: ran the module tests, ruff check on the capability, and examples/capability-extension-registry-smoke.py, and compared the old and new rule on a 16-case matrix (POSIX hits and clean inputs unchanged). An independent review round reproduced one escaped-spelling miss in the first revision; this head fixes it and pins it with tests. Two environment-level issues are disclosed rather than hidden: tests/capabilities/test_capability_extension_registry.py::test_installed_runtime_is_catalog_truth_and_cli_default fails identically on the unmodified baseline (entrypoint_missing), and a host route conflict makes loopx check unavailable in this checkout; neither is touched by this change.

Scope And Continuation

  • Completed scope and remaining work: reduce private_abs_path to one separator-run pattern that keeps the existing root keywords and covers the POSIX, native Windows, mixed, rooted and escaped spellings, plus tests; 60 lines added, 2 removed. Remaining: case-insensitive spellings and non-ASCII user names stay out of scope as disclosed above.
  • Slice boundary / successor: complete within this scope; no successor task needed. Those two gaps change every spelling class and should be decided together with the sibling boundary scan.

Validation

  • Tested revision: ce83ba927ddc27954ba3ae444f0bc452d6d86d29
  • Run state: finished
  • Input classes: synthetic
Check kind Result Public-safe evidence / limitation
regression_parity passed Old vs new rule on the same inputs: native, escaped (JSON), mixed and rooted spellings ok=False + private_abs_path hit after being ok=True/0 hits on the old rule; all four POSIX spellings and the clean inputs unchanged (16-case matrix). Pre-fix test run: 1 failed / 5 passed (AssertionError: drive); after: 7 passed.
real_entrypoint passed Shipped scan_cli (python -m loopx.capabilities.public_safe_outbound.scan_cli --scan-root ... --format json): a .json file with the escaped path and a .md with the native path exit 0 / hit_count 0 → exit 1 / hit_count 3 (escaped + native + POSIX control); a clean file is not hit.
unit passed loopx/capabilities/public_safe_outbound/tests/test_scanner.py: 7 passed.
static passed ruff check loopx/capabilities/public_safe_outbound: clean.
integration passed examples/capability-extension-registry-smoke.py: ok (capability registry unchanged).
real_backend not_applicable Pure text rule table; no backend or persisted state involved.
  • Coverage and gaps: The tests cover every new spelling class plus the negative drive-path case; the POSIX arm and clean input keep their existing tests. Not run: full CI here (first-time workflow approval may hold checks), plus the two pre-existing environment issues above. Case-insensitive spellings, non-ASCII user names and the trailing-separator requirement remain outside the rule as before (disclosed above; the trailing separator matches the POSIX spelling). The separator-run class widens the conservative surface exactly as the sibling fix(contract): block native, mixed and escaped Windows private paths in the boundary scan #6161 rule does: a separator run plus a private root segment is a hit, consistent with the capability's documented preference for false positives over misses; an ordinary drive path still stays clean.

Frontend / Visual Evidence

  • UI impact: none

Type of Change

  • Bug fix

LoopX Area

  • Capability or extension (providers, adapters, skills)

Technical Direction

  • Direction / acceptance reference, when applicable: N/A — ordinary capability bug fix; no roadmap/RFC claim.

Shared-authority RFC fixture impact

  • Production-scale fixture schema: N/A
  • Semantic dimensions changed, or reviewed no-impact rationale: N/A — no RFC claim
  • Provider conformance arms run: N/A
  • Read-only legacy/file/PostgreSQL three-arm rehearsal: N/A

Boundary Checklist

  • Neither the diff nor this PR body/comments/attachments disclose private state, credentials, raw traces or verifier output, internal links, or local machine paths (including .loopx/, .codex/goals/, and live ACTIVE_GOAL_STATE.md).
  • I did not duplicate maintainer-owned benchmark work unless a maintainer split out a public issue for it.
  • I kept the change scoped to the linked issue/task.
  • I completed the visual evidence section for UI changes, or marked UI impact none.
  • Every commit includes a DCO Signed-off-by trailer (git commit -s).

JasonBuildAI added a commit to JasonBuildAI/loopx that referenced this pull request Oct 11, 2026
… for agent-v5r2 claim

Signed-off-by: JasonBuildAI <jasonbuildai@gmail.com>
@JasonBuildAI
JasonBuildAI force-pushed the codex/public-safe-outbound-windows-path-v5r2 branch from 1f8b351 to a5de384 Compare October 11, 2026 10:04
…ublic-safe-outbound

The builtin fail-closed pre-submission scrub only recognized the POSIX spelling
of a private absolute path. On a Windows host the same private path written as
C:\Users\<name>\... or \\server\Users\<name>\..., and the escaped form a
serialized string produces (C:\\Users\\<name>\\...), passed the scan with
hit_count 0 while its POSIX spelling was blocked. loopx-project#6161 repaired the same
spelling class in the public/private boundary scan and names this rule as its
deliberately deferred successor owner.

Match a separator run at every junction of private_abs_path, covering the POSIX,
native Windows, mixed, rooted and escaped spellings of the same roots, and pin
the native, escaped and mixed forms with tests.

Closes loopx-project#6220
Follow-up to loopx-project#6161

Signed-off-by: JasonBuildAI <jasonbuildai@gmail.com>
@JasonBuildAI
JasonBuildAI force-pushed the codex/public-safe-outbound-windows-path-v5r2 branch from a5de384 to ce83ba9 Compare October 11, 2026 10:27
@JasonBuildAI JasonBuildAI changed the title fix(capability): detect native Windows private paths in public-safe-outbound fix(capability): detect native and escaped Windows private paths in public-safe-outbound Oct 11, 2026

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

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

详细中文评审 — #6223,exact head ce83ba927ddc27954ba3ae444f0bc452d6d86d29

动机

需要在公开发送前检查文本的操作者,尤其是从 Windows 源码环境导出内容的人。

同一份文档中的 POSIX 私人目录会被拦下,Windows 原生或 JSON 转义路径却会漏过,造成误以为扫描通过的风险;修复后这些拼写在原扫描入口被检出,普通公开路径仍可通过。

真实扫描目录中检出项由1项变成3项;仅含转义路径的 diff 从通过变成拒绝,扫描前后文件哈希保持一致。

本次只补齐分隔符拼写;不证明所有 Windows 路径形式均已覆盖,不改变发送权限,也不执行发送。

规格依据:loopx/capabilities/public_safe_outbound/README.md,pre-change adb247e5f3fac8e2e3f7152239955b49480d0b9f;映射项 existing-caller-invariant(本次评审标签,不是新增协议)。相关 issue/maintainer frame 与当前 caller 一并核对,PR 自述不是独立 oracle。

改动思路

继续复用既有 public_safe_outbound 扫描规则、配置和遮罩输出,只扩大同一私人根目录规则支持的分隔符;这是文本词法检测,不能当作操作系统路径或授权判断。

这项PR完成 issue #6220 的分隔符漏检修复;大小写、非 ASCII 用户名及末尾缺分隔符仍是原有边界,未宣称完成全部路径隐私检测。

具体改动

两处文件合计 +60/-2:scanner.py 保留私人根目录和用户名字符集合,把两侧分隔符改为 slash/backslash 的连续段;test_scanner.py 添加原生、转义与 UNC 回归。既有 _match_rule → scan_texts → scan_paths/scan_git_diff → scan_cli.main 仍负责命中、遮罩和退出码,没有发送动作或新权限。

独立检查13种拼写,并实际执行目录扫描和 stdin diff:目录正例包含原有 POSIX 控制,因此 base 是 exit1/hit1、head 是 exit1/hit3;单独转义 diff 才是 exit0→exit1。公开目录、普通文本和原 POSIX 行为保持。7项源码测试、Ruff、capability-extension-registry smoke、先 advisory 后全量 semantic 检查均通过。

对主干的风险

非阻塞 P2:词法规则也会拦截相对目录中同名的 Users 段,符合既有保守、宁可多报的扫描约定,操作者仍需要复核命中。issue #6220 明确把大小写兼容排除;非 ASCII 用户名、末尾缺分隔符也没有扩大覆盖。我在 macOS 上检查的是 Windows 文本拼写,未宣称 Windows 宿主实测。无配置、存储、quota 或生命周期改动,回滚不需要迁移。

我的整体评价

通过本次 exact-head 评审。长期效果正向证据是重复导出时同类私人路径不再静默漏检;体验收益是复用原命令即可发现问题,文件不被修改。保守匹配会增加部分人工复核,未测自然使用中的总成本。前瞻重构检查:当前单规则修复足够,若后续扩展规范化,可再与既有同类扫描共享一个有回归覆盖的词法 owner;本次不加框架。

English verdict: APPROVE — #6223 at ce83ba9. private_abs_path separator runs accept slash/backslash, escaped runs and mixed spelling; POSIX and public text preserved. Independently checked real source callers, negative/base-head controls and native validation; read-only actual CLI verified. No merge, release, authority or natural model-utility claim.

@huangruiteng
huangruiteng merged commit 323c305 into loopx-project:main Oct 12, 2026
30 of 34 checks passed
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]: builtin public-safe-outbound scanner misses native Windows private paths (C:\Users\... and UNC)

3 participants