Skip to content

id(encryption): bound Session held messages at 1024 / 16 MiB (#186) - #2216

Merged
dezren39 merged 5 commits into
mainfrom
queue/2976-186-held-caps
Oct 30, 2026
Merged

dezren39 merged 5 commits into
mainfrom
queue/2976-186-held-caps

Conversation

@dezren39

@dezren39 dezren39 commented Oct 29, 2026 •

Copy link
Copy Markdown
Member

Fixes #186 (queue task 2976), implementing the design pinned by triage task 2031.

Change

Session in pkgs/id/src/encryption/scheme.rs held every unreadable application message until its group secret arrived — no count cap, no byte cap, no expiry — so a removed or stalled peer could grow the held set without bound.

  • MAX_HELD_MESSAGES = 1024 and MAX_HELD_BYTES = 16 MiB (sum of CBOR-encoded envelope lengths via encode_cbor, as Envelope::new encodes; the total is tracked on the session as messages are held/released, never re-encoded per arrival).
  • Session::process() enforces both caps after the existing id-dedupe and before the push — and before any crate call, so a refusal never poisons the session — refusing a new arrival with the new SchemeError::HeldFull { count, bytes, cap_count, cap_bytes }, styled on TooManyParents and wired into SchemeError::reason() the same way (None).
  • No eviction, no time-based expiry (pinned decision): already-held messages leave only via release() when their secret arrives; the held field's doc comment states this.

Tests (new in encryption::tests)

  • Count cap: 1024 unreadable messages held; the 1025th refused with HeldFull naming the caps and not held (second delivery refuses again); re-delivery of a held message at the cap still returns Withheld.
  • Byte cap: a >half-cap message held; a second one refused even at count 1, with the tracked byte total in the error; re-delivery does not double-count bytes.
  • Release: re-add with the full bundle releases the held message (read on the welcome), a fresh message then reads normally (not poisoned), and after a second removal a new big message is held again — the tracked totals dropped on release.

Verification is CI on this PR (fleet CI-first rule; no sandbox/laptop builds).


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

Branch hygiene (2026-10-29, queue task 2976 resume)

origin/main merged in at e00154d1. main is red on cargo-fmt/rustfmt/treefmt/clippy (#2151), which made every PR's checks fail; commit 0556d2ba carries the identical two-file fix from #2335 (byte-for-byte the same diff) so this PR is verifiable on its own. When #2335 lands from the merge queue those hunks become a no-op.

Local (laptop) verification on this head:

  • cargo fmt --all -- --check — clean
  • cargo test --lib encryption:: — 74 passed, 0 failed (includes the three new held-cap tests)
  • cargo test --lib tags:: — 68 passed, 0 failed
  • local cargo clippy could not run (stale target/ built with rustc 1.98.1 vs toolchain 1.99.0 — E0514, an environment artifact, not a code finding); CI's clippy-lint covers it, and the previous run's only clippy failures were main's tags.rs expects, fixed here.

Session held every unreadable application message until its group secret arrived, with no cap: a removed or stalled peer could grow the held set without bound. Per the pinned design from triage task 2031: MAX_HELD_MESSAGES = 1024 and MAX_HELD_BYTES = 16 MiB (sum of CBOR-encoded envelope lengths, tracked on the session as messages are held and released). process() checks the caps after the id-dedupe and before the push - and before any crate call, so a refusal never poisons the session - and refuses a new arrival past either cap with the new SchemeError::HeldFull { count, bytes, cap_count, cap_bytes }, wired into reason() as None like TooManyParents. Already-held messages are never evicted or expired in-session; they leave only via release() when their secret arrives, and the tracked totals drop there.

Tests (encryption::tests): count cap (1024 held, the 1025th refused and not held, re-delivery at the cap still Withheld), byte cap (two >half-cap messages cannot both be held; refusal names count/bytes/caps; re-delivery does not double-count), and release (re-add welcome releases the held message, fresh messages read normally, and after a second removal a new big message is held again, proving the totals dropped).
@dezren39
dezren39 requested a review from a team as a code owner October 29, 2026 09:41
@coderabbitai

coderabbitai Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 17 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: b0ca7acd-1f8e-4b0f-b5e0-3944e69c9dcb
Commits

Reviewing files that changed from the base of the PR and between 5a34fa7 and 95a21b0.

Files selected for processing: 5
  • pkgs/id/src/encryption/mod.rs
  • pkgs/id/src/encryption/scheme.rs
  • pkgs/id/src/encryption/tests.rs
  • pkgs/id/src/meta_client.rs
  • pkgs/id/src/tags.rs
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-29T17:07:08.652393Z 0556d2b New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 74c91b7bf9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread pkgs/id/src/encryption/scheme.rs Resolved
Comment thread pkgs/id/src/encryption/tests.rs Resolved
@dezren39

Copy link
Copy Markdown
Member Author

Agent note — queue task 2976, Lane D, 2026-10-29: CI diagnosis for head 74c91b7b

Not mergeable. CI failures triaged:

  1. test-unit — 2 real failures, both this PR's new tests (1877 passed): test_held_messages_are_refused_past_the_byte_cap panics at tests.rs:2352 — processing the FIRST 9 MiB message returns HeldFull { count: 0, bytes: 0, cap_bytes: 16777216 }, i.e. one message's held_len (CBOR-encoded envelope length, scheme.rs:786) already exceeds the 16 MiB cap, or the accounting over-counts. test_a_release_frees_the_held_budget_and_the_session_is_not_poisoned fails the same way (same 9 MiB fixture). This matches the Codex P2 on tests.rs:2352 (size byte-cap fixtures by their encoded envelopes) — start there: print the encoded length of one fixture envelope and fix either the accounting or the fixture sizes.
  2. rustfmt-check — real: scheme.rs:174, the long #[error(...)] string on HeldFull needs wrapping; cargo fmt fixes it.
  3. clippy / cargo-fmt / treefmt / flake-check: not individually diagnosed; several jobs show infra noise (FlakeHub auth failure, Magic Nix Cache throttling, HTTP 418 narinfo downloads). Re-check after the fixes above land.
  4. Codex P2 on scheme.rs:589 also open: release() re-encodes the whole waiting set to recompute held_bytes; retain per-message sizes instead.

Task 2976 is parked with this resume brief. Worktree (laptop): ~/git/fleet/2976-186-held-caps, branch queue/2976-186-held-caps.

…length (#186)

release() re-encoded the whole waiting set to recompute held_bytes on every readable message (Codex P2): held entries now carry the CBOR-encoded length recorded when the message was held, and release() re-sums those retained sizes. The byte-cap test fixtures used 9 MiB plaintext, whose ciphertext CBOR-encodes as an integer array at ~1.9 bytes/byte (~17 MiB) - over the 16 MiB cap for a single message (Codex P2); fixtures are now 6 MiB plaintext (~12 MiB encoded, over half the cap). Also wraps the HeldFull error string per rustfmt.
main is red on cargo-fmt/rustfmt/treefmt/clippy (issue #2151, PR #2335), so
every open PR inherits failing checks. This carries the identical two fixes
(byte-for-byte the #2335 diff) on this branch:

- meta_client.rs: rustfmt the capped_response_error match arm.
- tags.rs: the two clippy::expect_used errors in parse_search_query become
  let-else breaks; the loops guard on i < input.len().

Once #2335 lands, these hunks are a merge no-op.
@dezren39

Copy link
Copy Markdown
Member Author

🤖 Agent note · parked

@dezren39
dezren39 added this pull request to the merge queue Oct 29, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to Branch Protection failures Oct 29, 2026
You're not authorized to push to this branch. Visit "About protected branches" for more information.
@dezren39
dezren39 added this pull request to the merge queue Oct 29, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to Branch Protection failures Oct 29, 2026
You're not authorized to push to this branch. Visit "About protected branches" for more information.
@dezren39
dezren39 added this pull request to the merge queue Oct 30, 2026
Merged via the queue into main with commit c5fa1d1 Oct 30, 2026
32 checks passed
@dezren39
dezren39 deleted the queue/2976-186-held-caps branch October 30, 2026 01:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Phase 4: held application messages need a bound

1 participant