fix(truth): stop resolving redacted worktree labels as filesystem paths - #228
Merged
Conversation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Truth validation no longer calls
Path.resolve()on values it cannot treat as filesystempaths. 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
FileNotFoundErrorandno 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-2and so on, deliberately, so paths outside the workspace never reachpublished output. The duplicate-path check then handed every recorded worktree path to
Path.resolve(), labels included. In the last published snapshot 98 of 434 worktreeentries 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:
directory the process started in, so the dedup comparison was comparing fabrications.
FileNotFoundErrorinstead. That is the crash.The traceback bottoms out at
posixpath.py:412, which iscwd = 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 theidentical 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
907780d, which predates the packagenamespace change. This fix does not reach production until that pin moves, and moving it
is a separate governed step.
_is_withinhas the same shape of exposure but only ever receives real paths, so it isleft alone rather than pre-emptively widened.