save! returns the digest of the bytes it wrote and mark_done! accepts it, and the call between them drops it. So no sweep this runner has ever driven can say that what a later reader loaded is what the computation produced.
Where
src/Run.jl (0.6.2), in the work pipeline:
DataVault.save!(vault, key, payload)
DataVault.mark_done!(vault, key)
save! returns (; file, sha256) (DataVault/src/io/data.jl), and mark_done! takes result= and observation=, writing result_sha256 / result_file / observation and done_version=2 when given them (DataVault/src/io/status.jl). Without them every field falls back to unknown.
What it costs downstream
A .done from a sweep driven by this runner is 60 bytes and carries no digest:
jobid=633855
completed=2026-09-26T16:36:33
git_hash=unknown
Pinax.report hashes each result as it reads it (read_sha256, via DataVault.load_recorded), and Archeion.provenance_from compares that against what the computation recorded. With the computation's side missing, a deposited revision's provenance.toml reads
[counts]
read_differs_from_result = 0
read_matches_result = 0
result_unknown = 12
i.e. 12 points read and hashed, and nothing to check them against. Both ends of the chain are implemented — DataVault writes the field, Archeion checks it — and only the middle does not pass it along. The check that would catch a data file edited or truncated between computing and reporting is the one that cannot run.
Fix
saved = DataVault.save!(vault, key, payload)
DataVault.mark_done!(vault, key; result=saved)
observation= too, where the runner has the computing process's source-observation token; if it does not have one, that part is a separate question and this one stands on its own.
Needs a [compat] floor on DataVault for the version where mark_done!(; result) exists (0.8.5 writes done_version=2), and it is worth a test that asserts the written .done has a result_sha256 that is not unknown — the current behaviour is invisible from inside the runner, which is presumably why it lasted.
Retroactive fix is not possible: existing .done files cannot learn the digest of a file whose computation is over.
save!returns the digest of the bytes it wrote andmark_done!accepts it, and the call between them drops it. So no sweep this runner has ever driven can say that what a later reader loaded is what the computation produced.Where
src/Run.jl(0.6.2), in the work pipeline:save!returns(; file, sha256)(DataVault/src/io/data.jl), andmark_done!takesresult=andobservation=, writingresult_sha256/result_file/observationanddone_version=2when given them (DataVault/src/io/status.jl). Without them every field falls back tounknown.What it costs downstream
A
.donefrom a sweep driven by this runner is 60 bytes and carries no digest:Pinax.reporthashes each result as it reads it (read_sha256, viaDataVault.load_recorded), andArcheion.provenance_fromcompares that against what the computation recorded. With the computation's side missing, a deposited revision'sprovenance.tomlreadsi.e. 12 points read and hashed, and nothing to check them against. Both ends of the chain are implemented — DataVault writes the field, Archeion checks it — and only the middle does not pass it along. The check that would catch a data file edited or truncated between computing and reporting is the one that cannot run.
Fix
observation=too, where the runner has the computing process's source-observation token; if it does not have one, that part is a separate question and this one stands on its own.Needs a
[compat]floor on DataVault for the version wheremark_done!(; result)exists (0.8.5 writesdone_version=2), and it is worth a test that asserts the written.donehas aresult_sha256that is notunknown— the current behaviour is invisible from inside the runner, which is presumably why it lasted.Retroactive fix is not possible: existing
.donefiles cannot learn the digest of a file whose computation is over.