docs: ADR-0001 contract sharding architecture#21
Conversation
Records the decision to partition contracts by (write-authority × churn × audience) into three types — user shard, thread shard, inbox shard — resolving the per-user-vs-global question (#16) and thread-storage question (#18). Leaves fanout strategy (#19) open. https://claude.ai/code/session_01BkBKy3SfhdwqFMrv9KGnmr
|
Some feedback on the ADR. The (write-authority × churn × audience) framing is good, and the inbox/thread split it produces is the right call. The framing of "authority enforcement isn't the reason to split, coupling of replication/subscription/churn/migration is" is the load-bearing insight and worth defending. Three substantive pushbacks and a few smaller things. 1. Make the archival scope split explicit"Dated archive shards... possible later addition, not part of v1" reads as deferred Raven work, which invites the question "what happens to my old posts?" Cleaner framing: durable long-term history is not Raven's job. It's handled by an external discovery/indexing layer (Atlas-style, https://github.com/freenet/atlas/blob/main/PROPOSAL.md). The user shard's ~200-post window is the steady state, not a placeholder until archive shards arrive. One sentence saying so in the ADR closes the question. A constraint follows for #11/#12 if we take this route: post objects need stable, externally-referenceable IDs, and need to be self-contained signed records. Not because Atlas specifically needs them, but because the pattern of (owner-writes producer contract) → (external indexer / archiver / aggregator) is going to recur across Raven, Atlas, and probably future apps. If Raven posts are self-contained signed records with stable IDs, every downstream consumer benefits; if they're internal-only embedded objects, every downstream consumer has to scrape and rehydrate. The cost of getting this right at #11/#12 time is much lower than fixing it later. 2. Likes belong on the thread shard, not the user shardThe ADR currently puts likes in both places: "likes-given" in the user shard, and "likes... targeting that post" in the thread shard. That's double-bookkeeping, with consistency risk if one write succeeds and the other doesn't. The thread shard is the right home by the ADR's own axis. A like is "anyone-writes, signed, targets a post," which is exactly the shape used to justify thread-shard storage for replies and quote refs. Removing likes-given from the user shard also cleanly resolves a churn mismatch I was about to flag (high-frequency likes alongside near-static profile data) without needing to introduce a new split. The "what posts has X liked?" view, if wanted, is a natural delegate-local materialized view (the same pattern the ADR already uses for the timeline) or an Atlas-style discovery query over public thread-shard data. It doesn't need to be replicated state on the user shard. 3. "Anyone-writes with a valid signature" needs a Sybil-resistance storyA signature authenticates the writer but doesn't constrain who can be a writer. With cheap keypair generation, "valid signature" is a placeholder, not a policy: thread shards and inbox shards are both wide open to Sybil flooding. Per-writer rate limits in GhostKey (https://freenet.org/ghostkey/) is the natural Freenet-ecosystem fit. Blind-signed credentials backed by a donation, anonymous-at-issuance and pseudonymous-at-use, contract-verifiable. The thread shard's The ADR doesn't have to pick the final mechanism, but it should name the abuse model and identify a candidate defense. Otherwise "anyone-writes with valid signature" is hiding the most important unresolved design question in the public-write surfaces. This applies equally to thread and inbox shards, and the answer should be consistent. Smaller things
Not raisingBundling profile + recent posts + follows together in the user shard genuinely does fit the axis (owner-writes, low-churn, follower-audience), so that part stands. And the deferral of #19 (fanout-on-read vs. fanout-on-write) is reasonable; the mechanism is in place either way. [AI-assisted - Claude] |
Incorporates sanity's review on PR #21: - likes live only on the thread shard (drop user-shard double-bookkeeping) - name the Sybil abuse model for public-write surfaces; GhostKey candidate - durable history is an external indexer's job (Atlas), not Raven; add stable-ID / self-contained-signed-record constraint for #11/#12 - thread shard created lazily on first reply, not on a bare like - window enforcement as post-merge truncation, not pre-write check - quote back-references delivered via inbox shard instead of skipped https://claude.ai/code/session_01BkBKy3SfhdwqFMrv9KGnmr
|
Thanks — all six taken, pushed in d025d5d.
Profile+posts+follows bundling and the #19 deferral left as-is, per your note. Generated by Claude Code |
Summary
docs/adr/and adds ADR-0001: Contract sharding architecture.Decisions recorded
Notes
This is a documentation-only change (no code). It front-runs the schema-changing workstreams under #8 (#11/#12/#13) so they build against a recorded architecture, and it pairs with the migration system in #20.
Closes #16
Closes #18
https://claude.ai/code/session_01BkBKy3SfhdwqFMrv9KGnmr
Generated by Claude Code