itsgoin/sessions.md
Scott Reimers 9040d70bf6 docs: correct padding rule — bucketed throughout, not random above 256
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>
2026-05-12 21:47:44 -04:00

14 KiB
Raw Blame History

Contributor Sessions Log

Rolling log of active sessions on the ItsGoin repository. Every contributor — Lead or Jr — appends an entry on session start and updates it on session end. Newest entries at the top.

See CONTRIBUTING.md for the protocol. See AGENTS.md for the Claude-specific session-start checklist.


2026-04-24 — primary Claude (Lead) — docs/fof-spec-layer1-bio-grants

Started: April 24 UTC Instance: Scott's primary Claude (Lead) Issue: none (spec refinement) Branch: docs/fof-spec-layer1-bio-grants Scope: Fold Scott + Opus's Layer 1 design answer into the spec. Vouch distribution moves from DM-wrapped VouchGrant to HPKE-sealed per-recipient wrappers carried in the voucher's bio post, leveraging existing bio-post CDN propagation and HPKE (RFC 9180) key privacy for recipient anonymity.

Key design commitments added to Layer 1:

  • HPKE RFC 9180 (DHKEM X25519 + HKDF-SHA256 + ChaCha20Poly1305) for per-recipient wrappers; one ephemeral pubkey per batch; 48B per wrapper.
  • HKDF info = "itsgoin/vouch-grant/v1/" || bio_post_id — recipient-free (non-negotiable for key privacy).
  • No prefilter tag on grants (no prior shared secret); full X25519 trial at ~60µs per wrapper per persona is tolerable (≤90ms even at 512×3 worst case).
  • Scan policy: auto-scan bio posts of followed personas; manual "check bio" gesture for non-followed; scan cache keyed by (scanner_persona, bio_author, bio_epoch).
  • Bucket-padding (64/128/256/512) and per-publish wrapper shuffle for size/position opacity.
  • No separate vouches_issued table on the wire; bio post IS the authoritative record. Local-only own_vouch_targets tracks what the persona has granted.
  • Incremental grant-as-comment path (Scott's suggestion for avoiding full republish) deferred; v1 ships with full republish per change.

Completed:

  • Rewrote docs/fof-spec/layer-1-vouch-primitive.md end-to-end.
  • README updated: Layer 1 scope line + added bio-post integration bullet.
  • Self-merged to master.

Pending:

  • Opus confirmation passes still open on other layers (WrapSlot byte layout, AEAD choice for body, padding schemes).
  • Layer 26 untouched in this pass.

Stopping point: Scott asked to hold merges until Layers 26 iterations complete. Branch stays open locally and on Forgejo; continuing to stack commits on it.

Update 2026-04-24 — Layer 2 rewrite (CDN-level verification)

Scope: Scott shared Opus's Layer 2 design answer. Folded in.

Design commitments added:

  • Per-V_x signing keypair (pub_x, priv_x) — replaces single per-post pub_post/priv_post. CDN can now verify comment signatures against a published pub_post_set before forwarding, killing the bandwidth-amplification DoS an admitted FoF member could otherwise mount.
  • Dual-derivation wrap slot: read_slot → CEK, sign_slot → priv_x. One unwrap yields both capabilities. Slot structure is shared with Layer 3 (canonical form lives here).
  • Comment body encrypted under CEK_comments = HKDF(CEK, "comments") — Mode 2 comments are genuinely FoF-read-gated now, not just FoF-sign-filtered at render (strengthening vs skeleton).
  • Propagation-node four-check accept rule: valid pub_x_index, not in revocation_list, group_sig verifies, identity_sig verifies. Any fail → drop without forwarding.
  • Author-signed revocation diff appended to post header; CDN honors on next sync. Per-chain revocation at propagation layer.
  • pub_x_index is a per-post pseudonym — leaks "these N comments came through the same chain" within a single post; re-randomizes across posts. Accepted tradeoff for CDN-level DoS resistance.
  • v1 ships Ed25519 inline (~77KB header at 500 vouchees). PQ future requires Merkle-commit over pub_post_set with per-comment inclusion proofs; deferred but spec shape doesn't preclude.

Files touched:

  • docs/fof-spec/layer-2-mode2-fof-comments.md — rewritten end-to-end.
  • docs/fof-spec/layer-3-mode1-fof-closed.md — prominent "partially superseded" banner added; body retained pending reconciliation when Scott + Opus review Layer 3.
  • docs/fof-spec/README.md — glossary updated (pub_x/priv_x, pub_post_set, revocation_list); integration bullet updated for new InlineComment fields + CDN accept rule.

Open questions I raised back to Scott (awaiting his answer before finalizing):

  1. (pub_x, priv_x) lifecycle: generated at V_x genesis (Layer 1) and stable across posts, vs regenerated per-post by author. Lead leaning per-post. Needs confirmation.
  2. pub_post_set padding vs wrap_slots padding — real/dummy alignment when dummies shouldn't be indexable by pub_x_index.
  3. Non-FoF rendering of comment count (reveal engagement? suppress?).
  4. Who holds priv_me (author) — generated alongside V_me at Layer 1, vs per-post regeneration. Same as #1 but for author's own entry.

Pending:

  • Scott reviews / answers open questions.
  • Layer 3 reconciliation when Scott + Opus get to Mode 1.
  • Layers 46 iterations.

Stopping point: commit b8b38a6 (Layer 1) + new commit for Layer 2 both on branch; not merged. Awaiting Scott.

Update 2026-04-24 — Layer 3 round 1 + cross-cutting padding rule (corrected)

Scott talked to Opus and resolved Layer 3 open questions + introduced a unified padding rule that supersedes Layer 2 round 2's rand(32..=128).

First-pass misread (corrected by Scott): I initially wrote the rule as "power-of-2 up to 256, then real + rand(0..=256) above." That's wrong — the rule is bucketed throughout, not random above the threshold.

Bucketed padding rule (applies to both slot count and body size):

  • ≤256 real units → next power-of-2 bucket (8, 16, 32, 64, 128, 256).
  • 256 real units → next linear-step bucket: +128 step for slots (384, 512, 640, …), +256KB step for body bytes (512KB, 768KB, 1024KB, …).

  • Deterministic. Author publishes next_bucket(real); dummies fill the gap.

Why this is stronger than random: observers learn the bucket but never the position within it. Across multiple posts from the same author, the bucket is stable until the author crosses a boundary — so no "min over many posts" attack converges tighter than the bucket bound. Random padding would have leaked min(observed) - max_noise as a floor.

Linear-step above 256 vs pure power-of-2: avoids the 2× waste of jumping 256→512 for an author with 257 vouchees. Above 256, step buckets are 128 (slots) or 256KB (body) so worst-case in-bucket overhead is bounded (~33% at the worst spot).

Applies uniformly to slot count and body size.

Other resolved Layer 3 questions:

  • Custom mode UI deferred. v1 ships three presets only: Public / Friends-only / FoF.
  • Slot dedup at V_x byte level. One slot per unique key.
  • Body-length padding adopted.

Files touched:

  • docs/fof-spec/layer-3-mode1-fof-closed.md: Lead decisions updated (hybrid padding, dedup, three-preset UI); open questions split into still-open + Resolved; ship criteria updated.
  • docs/fof-spec/layer-2-mode2-fof-comments.md: padding rule promoted to hybrid scheme; size budget rewritten with three regime examples; privacy section rewritten for two-regime analysis; Resolved bullet superseded with pointer.
  • sessions.md: this entry.

Still-open Layer 3 questions worth flagging to Scott:

  1. Access-grant ordering — does appending a new slot re-shuffle the full wrap_slots / pub_post_set (preserves the random-order privacy property but invalidates pub_x_index values in already-stored comments), or is it append-only (pub_x_index is stable but tail-positional leak says "these are recent grants")? Lead leaning: append-only; index stability matters for revocation and stored-comment verification.
  2. Minimum slot-count floor for tiny authors. Power-of-2-of-1 = 1, which leaks "this persona has one vouch (probably just themselves)." Lead leaning: minimum bucket of 8.

Pending: Layers 46 iterations. Scott to confirm two flagged questions.

Update 2026-04-24 — Layer 2 round 2 (Scott answers all 5 questions)

Scott resolved all five open questions:

  1. Per-post (pub_x, priv_x) — confirmed.
  2. Random-count dummy padding (rand(32..=128)) replaces power-of-2 buckets, with dummy pubkeys in pub_post_set so .len() == wrap_slots.len(). Across multiple posts from the same author, an observer cannot even establish a reliable floor for the real vouch-set size.
  3. Non-FoF comment UX: "Comments are private" affordance with optional "Request access via DM" button. No count leak.
  4. Author's own entry in pub_post_set — confirmed.
  5. Revocation is retroactive delete + forward. File-holders delete locally-stored comments signed by the revoked pub_x, then propagate the diff. Stronger than stop-forwarding — prior garbage is cleaned up as the diff sweeps the mesh.

New primitive: access-grant author comment. Author can retroactively widen a post's read-set by publishing an author-signed special comment appending a new WrapSlot + pub_post_set entry. Lets a newly-vouched persona gain read + comment access without republishing the whole post. Answers the "non-FoF requests access via DM, author approves" UX loop.

Files touched:

  • docs/fof-spec/layer-2-mode2-fof-comments.md — updated Lead decisions, post-header, revocation flow (retroactive), added Access-grant author comment section, updated Privacy tradeoff (size-leak analysis with random padding), Open questions split into unresolved + Resolved, size budget, ship criteria.
  • sessions.md — this entry.

Commit pending.


2026-04-23 — primary Claude (Lead) — docs/fof-spec-skeleton

Started: late April 23 UTC Instance: Scott's primary Claude (Lead role) Issue: none (spec-drafting work; hand-off to Opus for crypto fill-in) Branch: docs/fof-spec-skeleton Scope: Skeleton spec for Friend-of-Friend (FoF) post gating. Lays out the per-person vouch-key (V_me) primitive, four visibility levels (Public / Friends-only / FoF / Custom), Mode 1 (FOF_CLOSED) and Mode 2 (public post + FoF comments), and a six-layer implementation plan. Crypto byte layouts and algorithm specifics are marked TBD — OPUS for Opus to fill in.

Completed in this session:

  • docs/fof-spec/README.md — top-level overview, user-facing model, design properties, layering plan, out-of-scope, glossary, integration with existing primitives.
  • docs/fof-spec/layer-1-vouch-primitive.mdV_x keys, per-persona keyring, VouchGrant wire format (DM-wrapped).
  • docs/fof-spec/layer-2-mode2-fof-comments.mdCommentPolicy::FriendsOfFriends, pub_post / priv_post / wrap-slot primitives, group_sig + vouch_mac on comments.
  • docs/fof-spec/layer-3-mode1-fof-closed.mdPostVisibility::FoFClosed, wrap-slot byte layout, anonymous 2B prefilter, power-of-2 slot padding.
  • docs/fof-spec/layer-4-keypair-rotation.mdPostKeyRotation record, explicit pub_post_index on comments, per-post re-gating.
  • docs/fof-spec/layer-5-prefilter-and-cache.mdvouch_unlock_cache, vouch_unreadable_posts, author-direct fast path, keyring-change retry sweep.
  • docs/fof-spec/layer-6-revocation.md — stub; candidate designs AD; Lead leaning is coarse-rotation with UX polish (Candidate D); revisit after 30 days of production data.

Pending after this PR merges:

  • Opus review pass: fill in TBD — OPUS markers (AEAD specifier, key sizes, WrapSlot byte layout, prefilter tag algorithm confirmation, epoch granularity, etc.).
  • Lead re-review after Opus fills in crypto.
  • Per-layer branch schedule for implementation (Layer 1 ships first, independently exercised).

Stopping point: session ending after Lead self-merges docs/fof-spec-skeleton to master. Branch to be deleted locally + remote.


2026-04-23 — primary Claude (Lead) — chore/workflow-adoption

Started: late April 23 UTC Instance: Scott's primary Claude (Lead role per feedback_senior_role.md) Issue: none yet (inaugural PR; this is the chicken-and-egg case noted in CONTRIBUTING.md) Branch: chore/workflow-adoption Scope: Introduce the multi-contributor workflow to the repo. Creates CONTRIBUTING.md, AGENTS.md, and this file (sessions.md) with a seed entry.

Pre-existing state at session start:

  • v0.6.2 shipped end-to-end earlier today: APK, AppImage, CLI, anchor (PID 3475521, up since ~17:39 UTC).
  • Last merged-to-master commit before this branch: 2ce668a — People-tab rewrite (recency sort, profile-post Discover, bio modal, ignore primitive, per-author feed filter).
  • Active artifacts on itsgoin.com/public_html/: itsgoin-0.6.2.apk (183.7 MB), itsgoin_0.6.2_amd64.AppImage (177.7 MB), itsgoin-cli-0.6.2-linux-amd64 (40.8 MB).
  • No other contributors active.

Completed in this session (before this commit):

  • Designed the Lead role + amendments to the base workflow (hotfix carve-out, partnered build/deploy go-no-go, Lead-pulls-queue review pattern, re-evaluation triggers, Scott's contributor-alignment role, Lead self-merge authority).
  • Saved feedback_senior_role.md to instance memory.
  • Wrote CONTRIBUTING.md, AGENTS.md, sessions.md (this file). Originally drafted the agent guide as CLAUDE.md but that filename is .gitignored at the repo root because it has historically been a credential-leak vector; switched to AGENTS.md with an explicit security banner.
  • Iterated on Scott's role: initial draft put him in the PR-routing / build-authorizer position; revised to watch contributor alignment + partner on ship, Lead self-merges.

Pending after this PR merges:

  • Phase 0 prereqs from CONTRIBUTING.md: Forgejo CI (cargo check --workspace + cargo test -p itsgoin-core on push + PR), branch protection on master (require PR + 1 review + green CI), second Forgejo account + SSH key for Jr Claude(s). Scott coordinates.

Stopping point: session ending — Lead self-merged this PR to master (inaugural exercise of the self-merge authority the PR itself establishes, per Amendment 6). Branch chore/workflow-adoption deleted locally + remote.