Skip to content

Commit 178110b

Browse files
committed
docs(craft): state the partial-metadata contract on the file signal
An adapter that omits size or mtime for an unhashed file degrades change detection to the field it did supply. The docstring says so and a test pins the degradation, since no metadata-only signal can see a change in data it was never given.
1 parent 2d9d8eb commit 178110b

2 files changed

Lines changed: 12 additions & 1 deletion

File tree

backend/onyx/server/features/build/artifact_classifier.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,10 @@ def _is_visible(path: str) -> bool:
117117

118118
def _file_signal(entry: OutputEntry) -> str | None:
119119
"""Change signal for a file: its hash, or a size-and-mtime surrogate for
120-
files past the hash ceiling, shaped so it can never read as a real sha."""
120+
files past the hash ceiling, shaped so it can never read as a real sha.
121+
The manifest carries fstat size and mtime for every file it lists. An
122+
adapter omitting one degrades detection to the other field alone, which
123+
still beats no signal, so partial metadata is accepted."""
121124
if entry.sha256 is not None:
122125
return entry.sha256
123126
if entry.size is None and entry.mtime_ns is None:

backend/tests/unit/onyx/server/features/craft/test_artifact_classifier.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,14 @@ def top(entry: OutputEntry) -> str | None:
158158
assert top(base) != top(OutputEntry("big.bin", False, size=10, mtime_ns=2))
159159
assert top(OutputEntry("big.bin", False)) is None
160160

161+
# Partial metadata degrades to what is present, never to no signal.
162+
assert top(OutputEntry("big.bin", False, size=10)) != top(
163+
OutputEntry("big.bin", False, size=20)
164+
)
165+
assert top(OutputEntry("big.bin", False, mtime_ns=1)) != top(
166+
OutputEntry("big.bin", False, mtime_ns=2)
167+
)
168+
161169
# The same surrogate drives the directory hash for nested unhashed files.
162170
def nested(entry: OutputEntry) -> str | None:
163171
return derive_artifacts([OutputEntry("d", True), entry])[0].content_hash

0 commit comments

Comments
 (0)