Wires the publish side of FoF Layer 1 vouch distribution:
- VouchGrantBatch gains bio_pub_nonce (32B random per batch). Replaces
the spec's circular "bio_post_id in HKDF info" — BLAKE3(post)
depends on vouch_grants, so we need a content-independent binder.
Recipient-free per HPKE key-privacy; serves the same anti-replay
purpose as bio_post_id would have.
- profile::build_vouch_grant_batch reads current_own_vouch_key +
list_current_vouch_targets, generates eph keypair + bio_pub_nonce,
seals V_me for each target, bucket-pads with random 48B dummies,
and shuffles. Returns None when there are no targets.
- next_vouch_batch_bucket implements the FoF Layer 3 padding rule:
minimum bucket 8, power-of-2 up to 256, then linear +128 steps.
Bucket-padding-tests verifies all boundaries.
- Storage gains next_bio_epoch_for(persona_id): monotonic counter
per persona, used by receivers' scan cache. Stored in settings.
- build_profile_post signature extended to take Option<VouchGrantBatch>
+ bio_epoch: u32. Both publish_profile_post_as (initial post) and
set_profile (subsequent edits) build the batch and bump the epoch
on every publish.
- Test sites updated to pass None/0 for the new args.
Receive-side scan (next commit) reads VouchGrantBatch + bio_pub_nonce
to trial-decrypt wrappers and populate vouch_keys_received.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>