Skip to content

feat(cas_types): report the stored shard hash from a shard upload - #1003

Merged
sirahd merged 1 commit into
mainfrom
sirahd/shard-hash-in-upload-response
Oct 9, 2026
Merged

sirahd merged 1 commit into
mainfrom
sirahd/shard-hash-in-upload-response

Conversation

@sirahd

@sirahd sirahd commented Oct 5, 2026 •

Copy link
Copy Markdown
Collaborator

The server re-serializes an uploaded shard and keys the object on the result, so the uploader's own hash is a prediction rather than a fact. This returns the stored hash so a caller that records it can use what was actually written.

  • UploadShardResponse::shard_hash is Option, omitted by servers predating it.
  • Client::upload_shard returns Option<MerkleHash> rather than inventing one: a dry run stores nothing, and the V2 NDJSON stream carries no hash.
  • The simulation's /v1/shards reports the hash LocalClient stored under, so downstream tests exercise the real path.

Not a wire break: UploadShardResponse has no deny_unknown_fields, so a client compiled before this field keeps parsing responses that carry it — pinned by test_upload_shard_response_is_readable_without_the_new_field.

🤖 Generated with Claude Code


Note

Medium Risk
Changes a core Client trait signature and upload response parsing; callers must handle Option and V2 having no hash, but wire format remains backward compatible.

Overview
Shard uploads now surface the authoritative stored hash from the server instead of treating the client’s pre-upload hash as ground truth.

Wire / API: UploadShardResponse gains an optional shard_hash (HexMerkleHash), omitted for older servers and when absent. Serde tests lock backward/forward compatibility.

Client contract: Client::upload_shard returns Result<Option<MerkleHash>> instead of Result<()>. V1 /v1/shards JSON supplies Some(hash); V2 NDJSON and dry-run return None. V2→V1 fallback forwards the V1 hash.

Simulations: LocalClient returns Some after CAS-style re-serialize; MemoryClient returns None (merged shard). Local /v1/shards handler echoes shard_hash in the JSON response.

Reviewed by Cursor Bugbot for commit 5ea99da. Bugbot is set up for automated code reviews on this repo. Configure here.

@sirahd
sirahd force-pushed the sirahd/shard-hash-in-upload-response branch 3 times, most recently from 54f91f7 to fb1b5f6 Compare October 5, 2026 15:55
@sirahd
sirahd requested a review from seanses October 5, 2026 16:02
@sirahd
sirahd force-pushed the sirahd/shard-hash-in-upload-response branch from fb1b5f6 to cc5d7d7 Compare October 5, 2026 16:14
}

Ok(())
Ok(shard_hash)

@seanses seanses Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: You mentioned GC uses its own client, so you probably only need the interface and simulations changes. So let's not change this function or upload_shard_with_version_override

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good. I went ahead with your suggested change, with a caveat that it results in SimulationControlClient unable to reuse RemoteClient upload shard implementation and having to re-implement the upload. It's not a big deal, just something to be aware of.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah.. sorry I didn't realize that SimulationControlClient depends on RemoteClient. Then for your convenience I think it's Ok to have RemoteClient actually returning the value you need

let forced_version = self.ctx.config.client.shard_api_version;
self.upload_shard_with_version_override(shard_data, upload_permit, forced_version, progress_callback)
.await
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead, just Ok(None) here

@sirahd
sirahd force-pushed the sirahd/shard-hash-in-upload-response branch 2 times, most recently from ba7af41 to 13959f8 Compare October 8, 2026 15:15
The server re-serializes an uploaded shard and keys the object on the result,
so the uploader's own hash is a prediction, not a fact. Return the stored hash
so a caller that records it can use what was actually written rather than
inferring it from bytes it hopes the server reproduced.

`UploadShardResponse::shard_hash` is optional for servers predating the field,
and `Client::upload_shard` returns `Option<MerkleHash>` rather than inventing
one: the V2 NDJSON stream carries no hash and a dry run stores nothing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@sirahd
sirahd force-pushed the sirahd/shard-hash-in-upload-response branch from 13959f8 to 5ea99da Compare October 8, 2026 15:26
@sirahd
sirahd merged commit 355e1b1 into main Oct 9, 2026
10 checks passed
@sirahd
sirahd deleted the sirahd/shard-hash-in-upload-response branch October 9, 2026 06:10
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.

2 participants