feat: clawsync diff command + revision_page_entries API + CHANGELOG

diff command:
  clawsync diff <file.h5> <rev1> [rev2]
  - compares page-level metadata between two revisions (or rev1 vs HEAD)
  - ~modified / +added / -removed output per page
  - --porcelain: tab-separated machine-readable output
  - detection via data_offset equality (append-only sidecar invariant)

clawhdf5-onion:
  OnionFile::revision_page_entries(rev) -> &[PageTableEntry]
  - zero-copy access to page table entries for diff and analytics

4 subprocess tests: identical/changed/head-default/porcelain

CHANGELOG.md: Keep-a-Changelog v0.1.0 entry covering all 8 crates,
all CLI commands, and benchmark numbers.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
This commit is contained in:
osobh
2026-04-06 09:36:23 -05:00
co-authored by Claude Sonnet 4.6
parent 5a5fecf374
commit 11f946a608
4 changed files with 370 additions and 0 deletions
+16
View File
@@ -199,6 +199,22 @@ impl OnionFile {
/// callers that intend to send the data over the network can ship the
/// compressed bytes directly and let the receiver decompress.
///
/// Returns the raw [`PageTableEntry`] slice for a revision.
///
/// Useful for comparing page metadata across revisions without loading the
/// actual page data. The `data_offset` field uniquely identifies the
/// stored content: two entries with the same `data_offset` contain identical
/// (compressed) bytes.
pub fn revision_page_entries(
&self,
rev: u64,
) -> Result<&[crate::format::PageTableEntry], OnionError> {
self.page_tables
.get(rev as usize)
.map(|v| v.as_slice())
.ok_or(OnionError::RevisionNotFound(rev))
}
/// Returns `(h5_offset, compressed_data, codec_byte, orig_size)`.
pub fn revision_pages_raw(&self, rev: u64) -> Result<Vec<RawPage>, OnionError> {
let table = self