Skip to content

[Bug]: test home guard treats '..name' children of protected trees as outside them #7853

Closed

Description

@lidge-jun

Client or integration

Other

Area

Other

Summary

src/lib/test-home-guard.ts protects the developer's real OpenCodex, Codex, Claude and LaunchAgents trees from test writes and removals. Its isInside(parent, child) helper, used by protectedRemovalReason() and therefore by assertRemovalOutsideProtectedTrees(), decides containment with !rel.startsWith("..") on the relative path. That is a string-prefix test, not a path-component test. A direct child of a protected tree whose name begins with two dots, such as ~/.opencodex/..backup, has the relative path ..backup. It is therefore judged outside the tree, and the removal guard does not refuse it. The neighbouring isSameOrInsideIgnoringPlatformCase() already does this correctly: it splits on the separator and only treats a leading .. component as leaving the root.

Separately, the equality comparisons for the OpenCodex and Codex homes (canonicalize(dir) === PROTECTED_HOME) are case-sensitive. On Windows and macOS, a not-yet-existing case variant such as .OPENCODEX canonicalizes through its parent and does not compare equal, although the filesystem treats it as the same directory.

Expected: protected-tree containment and equality use component-aware comparison, with case folding on case-insensitive platforms, as the Claude tree checks already do.

Found while reviewing the test-only fixture preload in #7852, which now carries its own component-aware checks.

Reproduction

With the guard armed and a synthetic real home: protectedRemovalReason(join(protectedHome, "..backup")) returns null, while protectedRemovalReason(join(protectedHome, "backup")) refuses.

Version

dev (2.94.0 line)

Operating system

All (case folding: Windows and macOS)

Provider and model

No response

Logs or error output

n/a

Screenshots and supporting files

No response

Redacted configuration

n/a

Checks

  • I searched existing issues and documentation.
  • I removed secrets, tokens, account details, request credentials, and personal data.

Activity

  1. lidge-jun commented on Oct 30, 2026

    @lidge-jun
    OwnerAuthor

    Resolved on dev by #7884 (463a0ee0b7). PRs into dev do not auto-close linked issues, so this was closed manually. The fix ships with the next release cut from dev; please reopen if it still reproduces on a build that contains it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions