fix(cli): destination link_count is observed, not constrained — completes d75f50d5 - #176
Merged
marlon-costa-dc merged 2 commits intoSep 20, 2026
Merged
Conversation
added 2 commits
September 19, 2026 19:23
…ink-safe reads and replaces complete d75f50d d75f50d relaxed the OSError law (hardlinked destinations are safe to read and replace) but the typed AtomicFileState model still pinned link_count <= 1, so any read of a package-manager-hardlinked file died in pydantic ('Input should be less than or equal to 1') — the gen bootstrap splice over uv-hardlinked wheel content. The model now records the observed link count (>= 1); staged-temp exclusivity stays enforced by _validate_exclusive_link, and the physical-tree inventory keeps its cleanup-authority refusal — now as a causal typed failure instead of a pydantic accident. Contract tests updated to the law: hard destinations read (link_count=2 captured) and replace (pathname-only), symlinks still rejected.
|
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.



Problem (measured in ai-hub CI)
d75f50d relaxed the OSError law — hardlinked destinations are safe to read and replace — but the typed
AtomicFileStatemodel still pinnedlink_count: ge=1, le=1. Any read of a package-manager-hardlinked file (uv hardlinks wheel content) then died in pydantic:link_count: Input should be less than or equal to 1, input_value=2. Symptom:gen fixed pointred for every ai-hub PR (Binary read failed … templates/bootstrap/mise).Change
AtomicFileState.link_count:ge=1(observed reality) — staged-temp exclusivity stays enforced by_validate_exclusive_link(OSError, EMLINK).st_nlink > 1now fail the cleanup-authority verb as a causal typed failure (cleanup authority refused: … another physical name owns the same inode) instead of a pydantic accident — the documented refusal, preserved.Evidence
Atomic suite: 65 passed (contract + physical-tree + directory suites); ruff check/format clean.
Summary by cubic
Fixes
gen fixed pointfailures from hardlinked destinations: reading a package-manager-hardlinked file previously crashed in pydantic becauseAtomicFileState.link_countwas capped at 1, but the model now records the observed count (>= 1). Cleanup authority over multi-link files is still refused, now as an explicitOSError(EMLINK) instead of an incidental pydantic error._validate_exclusive_link.link_count=2; replacing a hardlinked destination swaps only that pathname, leaving the owner inode and bytes intact.Written for commit 5e44283. Summary will update on new commits.