Captures the decisions from the Layer 4 conversation with Scott:
Default narrowing on a single post = Layer 2 revocation (existing).
Advanced narrowing of read access = full re-issue with optional
supersedes_post_id link (network-heavy, opt-in).
V_me rotation = the persona-wide revocation primitive. Generate new
V_me, distribute to non-revoked vouchees via next bio-post batch.
Receiver-chain model: receivers append new V_me alongside old (not
overwrite). Trial-unwrap iterates the chain.
Grandfather by default: CDN is V_me-blind, so rotation does NOT
auto-cascade comment deletions. Revoked vouchee retains comment
authority on old posts unless author opts to cascade per-pub_x
revocations.
Per-post cascade is opt-in. Local-only own_post_slot_provenance
table lets author query "which pub_x's in my posts were sealed
under V_me_old?" and publish per-pub_x RevocationEntries.
New optional KeyBurnDiff primitive (signed header-diff) swaps a
V_me_old wrap_slot for a V_me_new one in-place on a specific post.
For the leaked-V_me scenario. Body CEK unchanged.
Skeleton's PostKeyRotation record removed entirely.
Layer 1 updated: rotation is append-only at receivers; pointer to
Layer 4. Multi-epoch bio-post-batch toggle hook added.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Resolve the two remaining Layer 3 open questions:
- Access-grant ordering: append at tail. pub_x_index values in
already-stored comments stay valid; no write amplification. Tail-
is-recent positional leak is the accepted cost (vs re-shuffle which
would force comments to reference signers by 32B pub_x bytes).
- Minimum slot bucket: 8. Singleton posts pad up to 8 so brand-new
personas don't publish "no vouchees" headers.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Prior round misread Opus's recommendation: I wrote "rand(0..=256) above
256" for slots and "round up to nearest 256KB above 256KB" for body.
Body was right; slots were wrong. Correct rule: bucketed throughout.
Slot buckets: 8, 16, 32, 64, 128, 256 (power-of-2 sub-256), then
384, 512, 640, 768, ... (+128 steps above).
Body buckets: 1KB, 2KB, ..., 256KB (power-of-2 sub-256KB), then 512KB,
768KB, 1024KB, ... (+256KB steps above; aligns with future chunk size).
Stronger privacy than random: observer learns bucket, never position
within it. Stable across posts; no min-over-many-posts floor attack.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Hybrid padding rule (slots + body, same shape):
- <=256 real units: pad to next power of 2 (8, 16, ..., 256)
- >256 real units: pad to real + rand(0..=256) / nearest 256KB
Replaces Layer 2 round 2's rand(32..=128). Small authors/posts get
strong bucket-grouping; large authors/posts get probabilistic noise
without 2x bandwidth waste of pure power-of-2 at scale.
Layer 3 resolutions:
- Custom mode deferred; v1 ships Public / Friends-only / FoF only
- Slot dedup at V_x byte level (one slot per unique key)
- Body-length padding adopted
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Fold in Scott's answers:
- Per-post (pub_x, priv_x); confirmed.
- Random rand(32..=128) dummy padding replaces power-of-2 buckets;
dummy pubkeys in pub_post_set so .len() == wrap_slots.len(). Floor
count is unrecoverable across multiple posts.
- Non-FoF UX: "Comments are private" + optional "Request access via
DM" button. No count leak.
- Author's own (pub_me, priv_me) in pub_post_set; confirmed.
- Revocation is retroactive delete + forward: file-holders delete
locally-stored comments signed by revoked pub_x on diff arrival,
then propagate. Stronger than stop-forwarding.
New primitive: access-grant author comment. Author appends a
WrapSlot + pub_post_set entry for a newly-vouched persona via a
signed special comment — retroactive read widening without republish.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace single per-post priv_post with per-V_x (pub_x, priv_x). Post
header publishes pub_post_set; comments declare pub_x_index; CDN
propagation nodes verify group_sig + identity_sig against named pubkey
before forwarding. Kills bandwidth-amplification DoS from admitted-but-
malicious FoF members.
Dual-derivation wrap slot (read → CEK, sign → priv_x) with shared
structure Layer 3 inherits. Comments encrypted under CEK_comments so
Mode 2 comments are genuinely FoF-read-gated, not just FoF-sign-filtered.
Author-signed revocation diff appended to post; CDN honors per-chain
revocation. Tradeoff: pub_x_index is a per-post voucher-chain pseudonym,
re-randomized across posts. Accepted.
Layer 3 banner added noting wrap-slot structure is now superseded by
Layer 2's canonical form; full reconciliation deferred.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace DM-wrapped VouchGrant with HPKE (RFC 9180) per-recipient
wrappers in the voucher's bio post. Recipient anonymity via HPKE key
privacy; readers trial-decrypt per persona. 48B per wrapper, one
ephemeral pubkey per batch. Scan gated to follows + manual gesture.
Bucket padding + per-publish shuffle for size/position opacity.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>