Skip to main content

max / goingson

Assert SyncKit bookkeeping tables stay out of the sync manifest The conflict stash SyncKit now writes holds the plaintext of edits last-write-wins discarded on this device. It is local-only purely by virtue of not being listed here, so syncing it would push one member's rejected values into a shared group log. That makes "not listed" a property worth asserting rather than remembering.
Co-Authored-By
Claude Opus 5 (1M context) <noreply@anthropic.com>
Author: Max Johnson <me@maxj.phd> · 2026-08-03 18:47 UTC
Signed with PGP, not checked
Commit: f9c4a3c5917f819634f64a063ff611582c77b5e7
Parent: 46ddc1d
1 file changed, +23 insertions, -0 deletions
@@ -472,6 +472,29 @@
472 472 }
473 473 }
474 474
475 + /// SyncKit's own bookkeeping tables must never appear in the manifest. The
476 + /// conflict stash is the one that would hurt: it holds the plaintext of edits
477 + /// last-write-wins discarded on *this device*, so syncing it would push one
478 + /// member's rejected values into a shared group log. Local-only is a property
479 + /// of not being listed here, which makes it a property worth asserting.
480 + #[test]
481 + fn synckit_bookkeeping_tables_are_not_in_the_manifest() {
482 + const NEVER_SYNCED: &[&str] = &[
483 + "sync_conflict_stash",
484 + "sync_changelog",
485 + "sync_state",
486 + "sync_committed_hlc",
487 + "sync_scope_cursor",
488 + ];
489 + for table in goingson_schema().tables() {
490 + assert!(
491 + !NEVER_SYNCED.contains(&table.name()),
492 + "{} is SyncKit bookkeeping and must not be synced",
493 + table.name()
494 + );
495 + }
496 + }
497 +
475 498 #[test]
476 499 fn every_manifest_table_has_a_description() {
477 500 for name in EXPECTED_TABLES {