Skip to content
Engineering6 min readSeptember 2026
🛡️

Designing privacy-safe summaries across personal applications

Learn how the Significant Hobbies Hub connects independent personal apps with privacy-safe summaries, preserving local data authority.

Introduction

As our digital lives fragment across specialized tools, there is a desire to unify them into a cohesive dashboard. Historically, this integration happens through centralization: a master application consumes the data schemas of its satellite apps, absorbing their local stores into one monolithic database. While convenient, this strips individual applications of their local data authority and introduces privacy risks.

The Significant Hobbies Hub adopts a different mindset. Instead of pulling raw user data into a centralized monolith, the Hub serves as a front door and a privacy-safe control plane for independently useful personal applications: Live, Calorie, Setline, Kith, and Anchor. It provides a unified interface that displays privacy-safe status summaries and typed semantic actions. Crucially, every product retains its own native interface and immediate, sovereign data authority.

By avoiding the wholesale ingestion of local stores, the Hub demonstrates that it is possible to design interconnected user experiences without compromising the rigid product boundaries that keep data secure. We will explore the architectural principles behind the Hub, diving into the native sync commit contract, account isolation rules, and download recovery strategies that make privacy-safe summaries possible.

Preserving the Product Boundary

The core philosophy of the Hub is that applications should remain independently useful while cooperating at the edges. The Hub's canonical repository is responsible for the Hub UI, a shared Cloudflare Worker (personal-platform), a D1 database for routing, and the PersonalSyncKit Swift package. It explicitly does not absorb the local product source code or native databases of the connected applications.

Core apps like Live maintain their own independent product codebases, fully isolated environments, and repository histories. Their runtime environments and local data identities are not centralized into the Hub. When product structures evolve—such as Anchor absorbing the older Indulge/Habits product loop—the Hub’s backend retains the necessary habits records and typed contracts strictly for legacy compatibility. It purposefully does not perform a forced schema migration on the user's legacy local store.

This rigid product boundary ensures each native app acts as its own final data authority. The Hub relies entirely on these independent apps to push verified, privacy-safe summaries to the control plane and to accept documented semantic actions. If an app receives an instruction to update a record via the Hub, it processes that instruction according to its own local rules, decoupled from the shared routing layer. This separation prevents corrupt bookkeeping in the shared layer from discarding local data ownership.

The Native Sync Commit Contract

To safely facilitate communication between the Hub and independent apps, a resilient transport layer is required. PersonalSyncKit provides this layer through a native sync commit contract.

A common failure mode in synchronization architectures is the premature advancement of remote download cursors. If a client receives a batch of records, acknowledges the download, but crashes before writing to its local store, the data is lost. The Hub architecture mitigates this risk through a mandatory API standard: synchronize(applyChanges:).

When an app calls this API, it receives a bounded batch of downloaded records. The app is required to atomically save these changes in its local store before the closure returns. If the save fails, the app must throw an error. Only after the closure successfully completes will the sync framework advance the downloaded-record metadata and update the remote cursor.

This contract shifts the responsibility of durability down to the native app while guaranteeing the transport layer will not drop records. Because network failures can occur after the local save succeeds but before the server is notified, the app must tolerate replay. The exact same batch might arrive again, and the local store must handle this idempotently.

Concurrent synchronization attempts are serialized, ensuring the system waits for the current commit. If bookkeeping fails, the system retains its prior in-memory state. An older, return-only synchronize() API remains available for legacy compatibility but lacks the robust app-commit guarantees. Early adopters like Kith demonstrate the reliability of this synchronized boundary.

Identity Protection and Account Ownership

In an ecosystem where multiple apps sync to a shared hub, ensuring data is routed only to the correct user is paramount. The Hub implements durable account ownership and strict identity isolation rules to prevent cross-account contamination.

Before a native app performs its first synchronization, it must ask the user to approve which verified Hub account will own its local document. The app securely retrieves the identifier via identity.verifiedSyncAccount(). The choice must be saved atomically alongside the local application data, and the runtime must be formally bound using bindAccount(account, adoptingUnownedData: true).

This explicit binding introduces a critical safety property: existing local document ownership never transfers to another user. If a document is bound to User A, it cannot be reassigned to User B just because User B signs in. The app must provision a completely separate local document and sync storage infrastructure. Attempting to delete or reassign old data to make a new sign-in attempt succeed is prohibited.

The shared runtime enforces these rules with rigidity. It purposefully stores a stable account owner alongside its queue, demands explicit adoption of unowned data, and rejects any binding attempts from unmatching accounts. The shared runtime rechecks the captured session around transport actions and app commits. Any account changes instantly invalidate older grants, requiring a same-user token refresh to resume the queue. Furthermore, the private Hub UI destination is securely hosted on the Live app's authenticated origin (e.g., live.significanthobbies.com/hub), using private, no-store redirects to prevent caching of sensitive state, thus keeping access strictly isolated.

Opt-in Download Recovery

Data recovery scenarios present a formidable challenge to privacy-safe boundaries. When a user reinstalls an app or encounters local data corruption, they may need to recover records their client previously acknowledged. Triggering a remote recovery often implies resetting the client's local durable state, indiscriminately wiping out offline edits or tombstones.

The Hub introduces an opt-in native replay API to handle this gracefully: synchronize(account: account, replayFromStart: true, applyChanges: ...). When invoked, this API fetches historical data pages starting directly from zero without destructively resetting the local durable state.

Crucially, this replay process maintains the verified-owner lock and preserves existing outbox processing. It is highly reliable and resource-conscious: the replay is cancellable and strictly bounded by the server to 100 pages containing at most 500 records each. If the process encounters a limit, a partial network download, or an unexpected app-write failure, the cursor is intentionally left retryable, and never forcibly moves backwards.

To thoroughly prevent accidental destruction of user work, the replay callback delivers the latest replayed version of each record but strictly excludes versions older than the already-known metadata residing on the client. Native callers are required to preserve their own newer local edits and local tombstones. Replay is a supplementary recovery tool, not a permission slip to blindly replace the local store.

Conclusion

Designing a shared hub for independent personal applications requires navigating a delicate balance. It is understandably tempting to centralize data schemas for developer convenience, but doing so compromises the long-term autonomy, resilience, and privacy of the user's data.

The Significant Hobbies Hub decisively demonstrates a sustainable, privacy-safe alternative. By keeping product boundaries intact, utilizing a resilient native sync commit contract, enforcing strict account ownership, and providing bounded download recovery, the Hub successfully surfaces cross-app summaries and typed semantic actions without claiming ultimate, centralized data authority.

The result is a robust software ecosystem where applications remain fast, local, and sovereign, yet beautifully integrated at the overarching control plane—a strong blueprint for privacy-respecting personal software.

Practical next action

Evaluate your independent application's native integration with PersonalSyncKit. Ensure you have migrated away from the deprecated, return-only synchronize() API and have adopted the closure-based synchronize(applyChanges:) method to guarantee data is safely committed to your durable store before cursor advancement.

🗺️

Ready to map your own hobby journey?

Track your hobbies across life phases. Discover what rekindled, what persisted, and what to explore next.

Build your timeline →