Skip to content

fix(truth): stop resolving redacted worktree labels as filesystem paths - #228

Merged
saagpatel merged 1 commit into
mainfrom
fix/opaque-worktree-path-identity
Aug 11, 2026
Merged

fix(truth): stop resolving redacted worktree labels as filesystem paths#228
saagpatel merged 1 commit into
mainfrom
fix/opaque-worktree-path-identity

Conversation

@saagpatel

Copy link
Copy Markdown
Owner

What

Truth validation no longer calls Path.resolve() on values it cannot treat as filesystem
paths. A redacted worktree label compares as itself; an absolute path still compares by
resolved location.

Why

The nightly portfolio job failed twice on 2026-08-11, at 12:39Z and 15:20Z, after
succeeding at 09:03Z. It died inside truth validation with a bare FileNotFoundError and
no message naming a file, so the receipt recorded only that generation had failed.

A worktree outside the observed workspace is recorded as an opaque label,
external-worktree-2 and so on, deliberately, so paths outside the workspace never reach
published output. The duplicate-path check then handed every recorded worktree path to
Path.resolve(), labels included. In the last published snapshot 98 of 434 worktree
entries are labels rather than paths
.

Resolving a value that is not absolute makes Python ask the operating system for the
process's working directory so it can build an absolute path. Two consequences, and the
first one was true every single day:

  • For a label the answer is meaningless. It silently invents a path under whatever
    directory the process started in, so the dedup comparison was comparing fabrications.
  • Once that directory has been deleted underneath the process, the same call raises
    FileNotFoundError instead. That is the crash.

The traceback bottoms out at posixpath.py:412, which is cwd = os.getcwd().

How

One helper decides identity: absolute values resolve, everything else is compared
literally. Applied at the dedup check and at _same_repository_path, which had the
identical exposure.

Behaviour for real paths is unchanged. Two spellings of one directory still compare equal,
including through a symlink, and a label never compares equal to a real path.

Testing

Full suite: 3513 passed, 2 skipped. ruff check src/ tests/ clean.

The regression test deletes the process's working directory and asserts both halves: that
the standard library really does raise under that condition, and that the guarded
comparison does not. That first assertion is the point of the test rather than decoration.
Without it a later reader cannot tell whether the guard is load-bearing or a leftover, and
the test would keep passing if the guard were removed.

Risk / Notes

  • The nightly job runs a pinned checkout, currently 907780d, which predates the package
    namespace change. This fix does not reach production until that pin moves, and moving it
    is a separate governed step.
  • _is_within has the same shape of exposure but only ever receives real paths, so it is
    left alone rather than pre-emptively widened.

The nightly portfolio job failed twice on 2026-08-11, at 12:39Z and 15:20Z,
after succeeding at 09:03Z. It died inside truth validation with a bare
FileNotFoundError and no message naming a file, so the receipt recorded only
that generation had failed.

A worktree outside the observed workspace is recorded as an opaque label,
"external-worktree-2" and so on, deliberately, so that paths outside the
workspace never reach published output. The duplicate-path check then handed
every recorded worktree path to Path.resolve(), labels included. In the last
published snapshot 98 of 434 worktree entries are labels rather than paths.

Resolving a value that is not absolute makes Python ask the operating system for
the process's working directory so it can build an absolute path. For a label
that answer is meaningless: it silently invents a path under whatever directory
the process happened to start in. Once that directory has been deleted
underneath the process, the same call raises FileNotFoundError instead, which is
what took the job down.

So the check no longer resolves a value it cannot treat as a path. A label
compares as itself, an absolute path still compares by resolved location, and
the same guard is applied to the other comparison site that had the identical
exposure.

The regression test deletes the process's working directory and asserts both
halves: that the standard library really does raise under that condition, and
that the guarded comparison does not. The first assertion is the point rather
than decoration, since without it a later reader cannot tell whether the guard
is load-bearing or a leftover.

Full suite 3513 passed, 2 skipped. Lint clean.
@saagpatel
saagpatel merged commit 55c7c46 into main Aug 11, 2026
4 checks passed
@saagpatel
saagpatel deleted the fix/opaque-worktree-path-identity branch August 11, 2026 19:15
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.

1 participant