Design doc: engagement security section, updated propagation description
- New "Engagement security" section documenting reaction signatures, comment signature verification, removal authorization, edit/delete auth, and BlobHeader author verification - Updated engagement propagation to reflect tiered pull frequency, multi-upstream (3 max), and batched lock writes - Documented BlobHeader as derived snapshot with tables as source of truth Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
bb6f2b64b0
commit
79922a9208
1 changed files with 14 additions and 3 deletions
|
|
@ -1034,13 +1034,24 @@ FAILURE: C → B → A: AnchorProbeResult { reachable: false }</code></pre
|
|||
<h3>Engagement propagation</h3>
|
||||
<p>Reactions, comments, and policy changes propagate via <code>BlobHeaderDiff</code> (0xD0) through the CDN tree:</p>
|
||||
<ul style="padding-left: 1.25rem; margin: 0.5rem 0; color: var(--text-muted);">
|
||||
<li><strong>Push (real-time)</strong>: On react/comment, the diff is sent to both <strong>downstream</strong> peers (CDN tree children) and the <strong>upstream</strong> peer (who we got the post from). Each intermediate node re-propagates both directions, excluding sender. This flows the diff up to the author and down to all holders.</li>
|
||||
<li><strong>Push (real-time)</strong>: On react/comment, the diff is sent to both <strong>downstream</strong> peers (CDN tree children) and all <strong>upstream</strong> peers (up to 3, who we got the post from). Each intermediate node re-propagates both directions, excluding sender. This flows the diff up to the author and down to all holders.</li>
|
||||
<li><strong>Auto downstream registration</strong>: Nodes that receive a post via pull sync or push notification automatically send <code>PostDownstreamRegister</code> (0xD3) to the sender, ensuring bidirectional diff flow.</li>
|
||||
<li><strong>Pull (safety net)</strong>: Every 5 minutes, the pull cycle requests <code>BlobHeaderRequest</code> (0xD1) with the local header timestamp. Peers respond with the full header only if theirs is newer. Additive merge — <code>store_reaction</code> upserts, <code>store_comment</code> inserts with ON CONFLICT DO NOTHING.</li>
|
||||
<li><strong>Tombstones</strong>: Deleted reactions and comments are not hard-deleted. Instead, a <code>deleted_at</code> timestamp is set on the record. Tombstones propagate via pull sync headers — when a peer receives a header with a tombstoned entry, it applies the deletion locally. This prevents deleted engagement from being re-introduced by peers that haven't yet received the deletion.</li>
|
||||
<li><strong>Pull (safety net)</strong>: Tiered frequency based on content age: 5min (<72h), 1hr (3-14d), 4hr (14-30d), 24hr (>30d). Requests <code>BlobHeaderRequest</code> (0xD1) with local header timestamp. Peers respond with full header only if newer. Additive merge — <code>store_reaction</code> upserts, <code>store_comment</code> inserts with ON CONFLICT DO NOTHING. Writes batched per chunk (single lock acquisition).</li>
|
||||
<li><strong>Tombstones</strong>: Deleted reactions and comments are not hard-deleted. Instead, a <code>deleted_at</code> timestamp is set on the record. Tombstones propagate via pull sync headers. Prevents deleted engagement from being re-introduced by peers that haven't yet received the deletion.</li>
|
||||
<li><strong>Planned</strong>: Pull engagement from both upstream and downstream peers to catch missed diffs from either direction.</li>
|
||||
</ul>
|
||||
|
||||
<h3>Engagement security <span class="badge badge-complete">Complete</span></h3>
|
||||
<p>Engagement operations are cryptographically verified on receipt to prevent forgery and unauthorized modification:</p>
|
||||
<ul style="padding-left: 1.25rem; margin: 0.5rem 0; color: var(--text-muted);">
|
||||
<li><strong>Reaction signatures</strong>: Each reaction carries an ed25519 signature over <code>BLAKE3(reactor || post_id || emoji || timestamp_ms)</code>. Verified before storing. Unsigned reactions from older nodes accepted for backward compatibility (<code>#[serde(default)]</code> on signature field).</li>
|
||||
<li><strong>Comment signatures</strong>: Comments carry an ed25519 signature (existing field). <code>verify_comment_signature()</code> now called on receipt via <code>BlobHeaderDiff</code>. Forged comments rejected.</li>
|
||||
<li><strong>Reaction removal</strong>: Only the reactor (original author of the reaction) or the post author can remove a reaction. Sender verified against <code>reactor</code> and <code>payload.author</code>.</li>
|
||||
<li><strong>Comment edit/delete</strong>: Only the comment author can edit; comment author or post author can delete. Sender identity verified via QUIC transport authentication (iroh ed25519).</li>
|
||||
<li><strong>BlobHeader author</strong>: When rebuilding headers after engagement diffs, the author is verified against the stored post’s actual author, not trusted from the payload. Prevents relay nodes from misattributing headers.</li>
|
||||
<li><strong>BlobHeader source of truth</strong>: The <code>reactions</code> and <code>comments</code> tables are authoritative. The <code>blob_headers</code> JSON is a derived snapshot rebuilt after each engagement operation. When they diverge (e.g., after a <code>BlobHeaderResponse</code> with a newer snapshot), the next engagement op rebuilds from tables.</li>
|
||||
</ul>
|
||||
|
||||
<h3>Device roles & bandwidth budgets <span class="badge badge-complete">Complete</span></h3>
|
||||
<p>Each node advertises its device role in <code>InitialExchange</code>, which determines its bandwidth budgets for replication (pulling posts to cache) and delivery (serving requests from peers):</p>
|
||||
<table>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue