Skip to content

feat(email): add Mailbox inbound ledger CAS RPCs - #1156

Merged
kody-bot merged 65 commits into
mainfrom
cursor/mailbox-do-810a
Aug 2, 2026
Merged

kody-bot merged 65 commits into
mainfrom
cursor/mailbox-do-810a

Conversation

@kentcdodds

@kentcdodds kentcdodds commented Aug 2, 2026 •

Copy link
Copy Markdown
Owner

Summary

Adds the complete owner-bound Mailbox inbound delivery/effect CAS surface and schema-v2 indexes without changing live authority:

  • dedupe/window claim, charged pending insert, storage lease, reject/finalize, prune/defer/due
  • usage/subscription effect leases, complete/fail/retry/dead-letter transitions
  • finalization-token fences prevent stale effect workers after reclaim/re-finalization
  • legacy null leases remain claimable; re-finalization resets subscription work to pending
  • system:email remains D1; no live call site flipped
System recap — extends Mailbox (medium risk)

Mode: recap · Base: main @ 68028d74 · Head: a6fd1ad2

Classification: extends — adds atomic inbound ledger/effect state-machine contracts to the existing per-user Mailbox primitive; live authority remains unchanged.

Primitives touched

Primitive Group Impact
mailbox storage extends — schema-v2 indexes and owner-bound inbound CAS RPCs

System map

Inbound transition callers can use atomic owner-bound Mailbox RPCs in the next deploy; this PR only establishes the storage contract.

Legend: green = composes (wiring only) · amber = extended by this PR · red = new primitive · gray = context (unchanged, included only when an edge crosses it).

flowchart LR
  inbound["Inbound orchestration<br/>future caller"]:::untouched
  mailbox["mailbox<br/>Mailbox"]:::extended
  d1["d1-app-db<br/>Current D1 authority"]:::untouched
  inbound -->|"future owner-bound CAS RPCs"| mailbox
  inbound -->|"live authority unchanged"| d1
  classDef touched fill:#1a7f37,color:#fff
  classDef extended fill:#9a6700,color:#fff
  classDef added fill:#cf222e,color:#fff
  classDef untouched fill:#57606a,color:#fff
Loading

Invariants

  • Every RPC is owner-bound before reading or mutating per-user data.
  • Effect completion/failure requires an exact finalization token and received state.
  • No external effect runs inside the Durable Object.
  • system:email remains D1-only.

Verification

  • Focused node/workers transition matrices: pass
  • PR and post-merge validation: all required jobs pass
  • Production deploy: success
  • Production mailbox status at 2026-08-02T15:06:16Z: 3/3 matching, 0 mismatch/error/incomplete; provider index 105/105, zero drift
  • Fresh whole-diff review + Bugbot/CodeRabbit substantive findings addressed; no unresolved blockers

Conductor report

  • STATUS: done
  • Sequence step: 2a additive inbound ledger/effect RPC surface
  • Backup gate: verified R2 metadata backup + D1 Time Travel
  • Authority: D1 remains live until 2b deploy
  • Risk: medium — extends an unused CAS contract; no routing or authority change
  • Merged/deployed: yes — PR #1156, deploy
  • Next: separate high-risk user inbound authority flip PR; UserMeter-first charging and system:email D1 branch
Open in Web Open in Cursor 

Summary by CodeRabbit

  • New Features

    • Added foundational support for tracking inbound email delivery, deduplication, storage processing, retries, and reconciliation.
    • Added safeguards against duplicate deliveries, stale processing attempts, and repeatedly failed subscription effects.
    • Added non-destructive schema updates and compatibility support for inbound delivery workflows.
  • Documentation

    • Updated Mailbox architecture and storage documentation for the new schema and processing safeguards.
  • Tests

    • Expanded coverage for retries, deduplication, recovery, isolation, migrations, and stale-worker protection.

cursoragent and others added 30 commits August 1, 2026 07:25
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Restore deleteEmailMessageById to D1 batch then immediate R2 cleanup with
no Mailbox env/waitUntil/mirror. Restore insertEmailMessageWithAttachments
signature without mirror forwarding. Drop PR-only delete mirror tests and
update data-storage.md: live explicit/retention deletes are repaired by
parity purge/rebuild; direct delete wiring remains pending.

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
cursoragent and others added 10 commits August 2, 2026 02:33
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
@coderabbitai

coderabbitai Bot commented Aug 2, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds Mailbox inbound delivery and effect ledgers with owner-bound CAS RPCs, lease fencing, reconciliation, retry handling, and schema v2 indexes. It retains D1 authority and compatibility paths while adding worker and node test coverage.

Changes

Mailbox inbound ledger

Layer / File(s) Summary
Ledger contracts and schema migration
packages/worker/src/email/mailbox-inbound-ledger-shared.ts, packages/worker/src/email/mailbox-inbound-ledger.ts, packages/worker/src/email/mailbox-inbound-effect-ledger.ts, packages/worker/src/email/mailbox-types.ts, packages/worker/src/email/mailbox-schema.ts
Defines delivery snapshots, validation helpers, CAS result types, combined RPC contracts, schema version 2, and five additive indexes.
Inbound delivery CAS operations
packages/worker/src/email/mailbox-inbound-ledger.ts, packages/worker/src/email/mailbox-do.ts
Adds deduplication, charged insertion, storage leases, rejection, receipt finalization, pruning, reconciliation deferral, and stale-delivery queries.
Usage and subscription effect processing
packages/worker/src/email/mailbox-inbound-effect-ledger.ts, packages/worker/src/email/mailbox-do.ts
Adds leased effect claims, completion and suppression handling, retry scheduling, dead-lettering, and due-work listing.
Ledger validation and compatibility coverage
packages/worker/src/email/*test.ts, packages/worker/src/email/mailbox-store.ts, docs/contributing/architecture/data-storage.md
Covers migrations, leases, fencing, retries, ownership, compatibility mirrors, export, purge, numeric validation, and the non-live-wired state.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant MailboxBase
  participant InboundDeliveryLedger
  participant InboundEffectLedger
  participant SqlStorage
  MailboxBase->>InboundDeliveryLedger: claim storage lease
  InboundDeliveryLedger->>SqlStorage: update delivery with CAS
  MailboxBase->>InboundDeliveryLedger: finalize received delivery
  InboundDeliveryLedger->>SqlStorage: store finalization and effect state
  MailboxBase->>InboundEffectLedger: claim effect
  InboundEffectLedger->>SqlStorage: update effect lease with CAS
  InboundEffectLedger-->>MailboxBase: complete, retry, or dead-letter result
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.41% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly identifies the main change: adding Mailbox inbound ledger compare-and-swap RPCs.
Description check ✅ Passed The description covers the change summary, testing evidence, intent, system impact, authority boundaries, and deployment status, despite using alternative section headings.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cursor/mailbox-do-810a

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.

cursoragent and others added 3 commits August 2, 2026 13:52
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
@kody-bot
kody-bot marked this pull request as ready for review August 2, 2026 14:19
@github-actions

github-actions Bot commented Aug 2, 2026 •

Copy link
Copy Markdown
Contributor

🔎 Preview deployed: https://kody-pr-1156.kody-a99.workers.dev

Worker: kody-pr-1156
D1: kody-pr-1156-db
KV: kody-pr-1156-oauth-kv

Mocks:

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🧹 Nitpick comments (3)
packages/worker/src/email/mailbox-schema.ts (1)

334-338: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Tie the dedupe-provider literal to the shared constant.

The predicate hard-codes 'cloudflare-email-routing-dedupe'. The same value is defined as mailboxInboundDedupeProvider in packages/worker/src/email/mailbox-inbound-ledger-shared.ts (Line 16). If the constant changes, this partial index stops matching the prune and window queries, and the change is silent. A SQLite partial-index predicate cannot be parameterized, so interpolate the constant into the DDL string instead.

♻️ Proposed change
 	sql.exec(
 		`CREATE INDEX IF NOT EXISTS idx_email_delivery_events_dedupe_provider_expires
 		ON email_delivery_events(provider, dedupe_expires_at ASC, id ASC)
-		WHERE provider = 'cloudflare-email-routing-dedupe'
+		WHERE provider = '${mailboxInboundDedupeProvider}'
 			AND dedupe_expires_at IS NOT NULL`,
 	)

Add the import at the top of the file:

import { mailboxInboundDedupeProvider } from './mailbox-inbound-ledger-shared.ts'
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/worker/src/email/mailbox-schema.ts` around lines 334 - 338, Update
the partial-index DDL in the mailbox schema setup to interpolate the shared
mailboxInboundDedupeProvider constant instead of hard-coding the provider
literal. Import mailboxInboundDedupeProvider from
mailbox-inbound-ledger-shared.ts and preserve the existing SQL predicate and
index behavior.
packages/worker/src/email/mailbox-inbound-ledger.workers.test.ts (1)

71-96: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Both schema-v2 index checks verify only part of the index set. The tests query or drop the full set of v2 indexes but assert a subset, so a partial regression in initializeMailboxSchema can pass.

  • packages/worker/src/email/mailbox-inbound-ledger.workers.test.ts#L71-L96: add toContain assertions for idx_email_delivery_events_state_created and idx_email_delivery_events_dedupe_expires, which the query already selects.
  • packages/worker/src/email/mailbox-inbound-ledger.workers.test.ts#L826-L833: widen the lookup to all five dropped v2 index names and assert a count of five.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/worker/src/email/mailbox-inbound-ledger.workers.test.ts` around
lines 71 - 96, Strengthen the schema-v2 index coverage in
packages/worker/src/email/mailbox-inbound-ledger.workers.test.ts:71-96 by
asserting the queried indexes include idx_email_delivery_events_state_created
and idx_email_delivery_events_dedupe_expires. At
packages/worker/src/email/mailbox-inbound-ledger.workers.test.ts:826-833, update
the dropped-index lookup to include all five v2 index names and assert that five
indexes are found.
packages/worker/src/email/mailbox-inbound-ledger.ts (1)

419-422: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Reject non-finite numeric inputs before binding them to SQL.

Math.floor(NaN) returns NaN, and Math.max(0, NaN) also returns NaN. The value is then bound to expected_attachment_count. The same pattern exists in markMailboxInboundDeliveryReceived for usageDurationMs and usageBytes (Lines 664-665). Every other input in this file is validated with an explicit assertion. Add a finite-number assertion for parity.

♻️ Proposed guard
+function assertMailboxFiniteNumber(value: number, label: string): number {
+	if (typeof value !== 'number' || !Number.isFinite(value)) {
+		throw new Error(`Mailbox ${label} must be a finite number.`)
+	}
+	return value
+}
+
 	const expectedAttachmentCount = Math.max(
 		0,
-		Math.floor(input.expectedAttachmentCount),
+		Math.floor(
+			assertMailboxFiniteNumber(
+				input.expectedAttachmentCount,
+				'expectedAttachmentCount',
+			),
+		),
 	)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/worker/src/email/mailbox-inbound-ledger.ts` around lines 419 - 422,
Add explicit finite-number assertions before normalizing numeric inputs in the
inbound ledger flow: validate input.expectedAttachmentCount before
Math.floor/Math.max, and validate usageDurationMs and usageBytes in
markMailboxInboundDeliveryReceived before their normalization or SQL binding.
Use the file’s existing assertion pattern and preserve the current clamping
behavior for finite values.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/worker/src/email/mailbox-inbound-effect-ledger.ts`:
- Around line 155-180: Nullable lease and state predicates exclude eligible rows
due to SQL three-valued logic. In
packages/worker/src/email/mailbox-inbound-effect-ledger.ts lines 155-180, update
the usage lease guard to admit NULL lease timestamps; in lines 366-372, let the
subscription processing arm claim rows with NULL subscription_effect_lease_at;
and in lines 629-632, explicitly admit NULL subscription_effect_state and
subscription_effect_lease_at while preserving the existing due-work conditions.

---

Nitpick comments:
In `@packages/worker/src/email/mailbox-inbound-ledger.ts`:
- Around line 419-422: Add explicit finite-number assertions before normalizing
numeric inputs in the inbound ledger flow: validate
input.expectedAttachmentCount before Math.floor/Math.max, and validate
usageDurationMs and usageBytes in markMailboxInboundDeliveryReceived before
their normalization or SQL binding. Use the file’s existing assertion pattern
and preserve the current clamping behavior for finite values.

In `@packages/worker/src/email/mailbox-inbound-ledger.workers.test.ts`:
- Around line 71-96: Strengthen the schema-v2 index coverage in
packages/worker/src/email/mailbox-inbound-ledger.workers.test.ts:71-96 by
asserting the queried indexes include idx_email_delivery_events_state_created
and idx_email_delivery_events_dedupe_expires. At
packages/worker/src/email/mailbox-inbound-ledger.workers.test.ts:826-833, update
the dropped-index lookup to include all five v2 index names and assert that five
indexes are found.

In `@packages/worker/src/email/mailbox-schema.ts`:
- Around line 334-338: Update the partial-index DDL in the mailbox schema setup
to interpolate the shared mailboxInboundDedupeProvider constant instead of
hard-coding the provider literal. Import mailboxInboundDedupeProvider from
mailbox-inbound-ledger-shared.ts and preserve the existing SQL predicate and
index behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4189b4a4-0c74-4866-8d79-1c4cdae2a7fb

📥 Commits

Reviewing files that changed from the base of the PR and between 68028d7 and 1e14bb0.

📒 Files selected for processing (11)
  • docs/contributing/architecture/data-storage.md
  • packages/worker/src/email/mailbox-do.ts
  • packages/worker/src/email/mailbox-inbound-effect-ledger.ts
  • packages/worker/src/email/mailbox-inbound-ledger-shared.ts
  • packages/worker/src/email/mailbox-inbound-ledger.node.test.ts
  • packages/worker/src/email/mailbox-inbound-ledger.ts
  • packages/worker/src/email/mailbox-inbound-ledger.workers.test.ts
  • packages/worker/src/email/mailbox-reconcile.node.test.ts
  • packages/worker/src/email/mailbox-schema.ts
  • packages/worker/src/email/mailbox-store.ts
  • packages/worker/src/email/mailbox-types.ts

Comment thread packages/worker/src/email/mailbox-inbound-effect-ledger.ts
cursoragent and others added 2 commits August 2, 2026 14:29
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🧹 Nitpick comments (3)
packages/worker/src/email/mailbox-inbound-ledger.node.test.ts (1)

49-62: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Exercise the production lease path in this test.

This test rebuilds the timestamp comparison instead of calling the Mailbox lease predicate or a public lease-claim operation. A regression in the production lease logic can pass. Test the actual operation, including the exact expiry boundary, or rename this test to document that it covers only timestamp arithmetic.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/worker/src/email/mailbox-inbound-ledger.node.test.ts` around lines
49 - 62, Update the test around “storage lease takeover predicate matches D1
stale window” to invoke the production Mailbox lease predicate or public
lease-claim operation rather than comparing timestamps directly. Cover fresh,
exactly-expired, and stale lease timestamps, asserting the operation’s actual
takeover behavior; otherwise rename the test to explicitly describe timestamp
arithmetic only.
packages/worker/src/email/mailbox-inbound-ledger.workers.test.ts (2)

826-853: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

This block repeats the same schemaV2Indexes array and hardcoded SQL IN (...) clause as Line 71-96. See that comment for the shared root cause and proposed fix; this instance will be listed in the consolidated comment.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/worker/src/email/mailbox-inbound-ledger.workers.test.ts` around
lines 826 - 853, Reuse the shared index-name definition and query helper
established for the earlier schema validation instead of redeclaring
schemaV2Indexes and repeating the hardcoded SQL IN clause in this test block.
Keep the existing sorted-order and duplicate-count assertions using the shared
result.

71-96: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Parameterize the schema-v2 index check instead of duplicating index names.

schemaV2Indexes (Line 71-77) lists the five expected index names, and the SQL IN (...) clause repeats the same five literal strings again. If a future migration adds a sixth index, an update to schemaV2Indexes without a matching update to the SQL string leaves the query silently excluding the new index from the uniqueness and presence check, instead of failing loudly.

Bind the query directly from the array to keep the two lists from drifting apart.

♻️ Proposed fix to bind index names from the array
+			const placeholders = schemaV2Indexes.map(() => '?').join(', ')
 			const indexes = state.storage.sql
 				.exec<{ name: string }>(
 					`SELECT name FROM sqlite_master
 					WHERE type = 'index'
-						AND name IN (
-							'idx_email_delivery_events_reconcile_after',
-							'idx_email_delivery_events_usage_effect_retry',
-							'idx_email_delivery_events_subscription_effect_retry',
-							'idx_email_delivery_events_stale_state',
-							'idx_email_delivery_events_dedupe_provider_expires'
-						)
-					ORDER BY name ASC`,
+						AND name IN (${placeholders})
+					ORDER BY name ASC`,
+					...schemaV2Indexes,
 				)
 				.toArray()
 				.map((row) => row.name)

The identical duplication also exists at Line 826-853; this comment will be consolidated with that occurrence.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/worker/src/email/mailbox-inbound-ledger.workers.test.ts` around
lines 71 - 96, Update both schema-v2 index checks to build the SQL IN-clause
placeholders and bound parameters directly from the corresponding index-name
arrays, including the occurrence near the later migration test. Remove
duplicated index literals from the SQL so adding an index to the array
automatically includes it in the query and presence/uniqueness assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/worker/src/email/mailbox-inbound-ledger-shared.ts`:
- Around line 378-385: Update assertMailboxInboundNonNegativeFiniteNumber to
reject values less than zero alongside non-number and non-finite inputs, and
report that the value must be a non-negative finite number. Remove the Math.max
clamping so valid inputs are returned unchanged.

---

Nitpick comments:
In `@packages/worker/src/email/mailbox-inbound-ledger.node.test.ts`:
- Around line 49-62: Update the test around “storage lease takeover predicate
matches D1 stale window” to invoke the production Mailbox lease predicate or
public lease-claim operation rather than comparing timestamps directly. Cover
fresh, exactly-expired, and stale lease timestamps, asserting the operation’s
actual takeover behavior; otherwise rename the test to explicitly describe
timestamp arithmetic only.

In `@packages/worker/src/email/mailbox-inbound-ledger.workers.test.ts`:
- Around line 826-853: Reuse the shared index-name definition and query helper
established for the earlier schema validation instead of redeclaring
schemaV2Indexes and repeating the hardcoded SQL IN clause in this test block.
Keep the existing sorted-order and duplicate-count assertions using the shared
result.
- Around line 71-96: Update both schema-v2 index checks to build the SQL
IN-clause placeholders and bound parameters directly from the corresponding
index-name arrays, including the occurrence near the later migration test.
Remove duplicated index literals from the SQL so adding an index to the array
automatically includes it in the query and presence/uniqueness assertions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 14b324b1-15be-45ab-93ec-2d57bca9d37d

📥 Commits

Reviewing files that changed from the base of the PR and between 1e14bb0 and 40904d9.

📒 Files selected for processing (6)
  • packages/worker/src/email/mailbox-inbound-effect-ledger.ts
  • packages/worker/src/email/mailbox-inbound-ledger-shared.ts
  • packages/worker/src/email/mailbox-inbound-ledger.node.test.ts
  • packages/worker/src/email/mailbox-inbound-ledger.ts
  • packages/worker/src/email/mailbox-inbound-ledger.workers.test.ts
  • packages/worker/src/email/mailbox-schema.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/worker/src/email/mailbox-schema.ts
  • packages/worker/src/email/mailbox-inbound-effect-ledger.ts
  • packages/worker/src/email/mailbox-inbound-ledger.ts

Comment thread packages/worker/src/email/mailbox-inbound-ledger-shared.ts Outdated

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🧹 Nitpick comments (2)
packages/worker/src/email/mailbox-inbound-effect-ledger.workers.test.ts (2)

371-395: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add the fresh-lease with stale-token case to complete the fence matrix.

The test covers stale-lease/stale-token and stale-lease/fresh-token. It does not cover fresh-lease/stale-token. A regression that drops the expectedFinalizationToken check but keeps the lease check would still pass this test. Add one assertion that uses freshUsageClaim.delivery.usageEffectLease with staleToken and expects a rejection status.

♻️ Proposed addition after the fresh usage claim
 	if (freshUsageClaim.status !== 'claimed') {
 		throw new Error('expected fresh usage claim')
 	}
+	// Fresh lease + stale token must also lose.
+	expect(
+		(
+			await mailbox.completeInboundUsageEffect({
+				ownerId,
+				deliveryId: delivery.deliveryId,
+				usageEffectLease: freshUsageClaim.delivery.usageEffectLease!,
+				expectedFinalizationToken: staleToken,
+				mode: 'recorded',
+				usageMonth: '2026-07',
+				usageBytes: 16,
+				usageDurationMs: 9,
+				now: '2026-07-22T00:01:03.000Z',
+			})
+		).status,
+	).toBe('lease-lost')
 	expect(
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/worker/src/email/mailbox-inbound-effect-ledger.workers.test.ts`
around lines 371 - 395, Add a completion assertion after the fresh claim in the
test covering the fresh-lease/stale-token combination: call
completeInboundUsageEffect with freshUsageClaim.delivery.usageEffectLease and
staleToken, preserving the existing completion parameters, and assert the
returned status is the expected rejection status. Keep the subsequent
fresh-token completion assertion unchanged.

463-488: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Both legacy-row SQL setups can match zero rows without failing. Each test mutates a row with raw SQL and then asserts ledger behavior. If WHERE id = ? AND provider = ? matches no row, the UPDATE succeeds silently and the test asserts against a normal received row instead of the legacy or stale row it intends to create. Capture the cursor from state.storage.sql.exec and assert the rows-written count at both sites.

  • packages/worker/src/email/mailbox-inbound-effect-ledger.workers.test.ts#L463-L488: assert that the UPDATE which nulls usage_effect_lease_at, subscription_effect_state, and subscription_effect_lease_at wrote exactly one row.
  • packages/worker/src/email/mailbox-inbound-effect-ledger.workers.test.ts#L563-L581: assert that the UPDATE which sets subscription_effect_state = 'processing' with a null subscription_effect_lease_at wrote exactly one row.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/worker/src/email/mailbox-inbound-effect-ledger.workers.test.ts`
around lines 463 - 488, Both raw SQL legacy-row setups must verify that exactly
one row was updated; in
packages/worker/src/email/mailbox-inbound-effect-ledger.workers.test.ts lines
463-488 and 563-581, capture the cursor returned by state.storage.sql.exec and
assert its rows-written count is one after each UPDATE.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/worker/src/email/mailbox-inbound-ledger-test-helpers.ts`:
- Around line 4-20: Update insertInput so the returned rawMimeKey uses
overrides.rawMimeKey when provided, falling back to emailRawMimeKey(ownerId,
messageId) otherwise. Preserve the existing derived-key behavior when no
override is supplied.

---

Nitpick comments:
In `@packages/worker/src/email/mailbox-inbound-effect-ledger.workers.test.ts`:
- Around line 371-395: Add a completion assertion after the fresh claim in the
test covering the fresh-lease/stale-token combination: call
completeInboundUsageEffect with freshUsageClaim.delivery.usageEffectLease and
staleToken, preserving the existing completion parameters, and assert the
returned status is the expected rejection status. Keep the subsequent
fresh-token completion assertion unchanged.
- Around line 463-488: Both raw SQL legacy-row setups must verify that exactly
one row was updated; in
packages/worker/src/email/mailbox-inbound-effect-ledger.workers.test.ts lines
463-488 and 563-581, capture the cursor returned by state.storage.sql.exec and
assert its rows-written count is one after each UPDATE.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 50385b20-303d-4ace-ab5d-3e2e5dc9613b

📥 Commits

Reviewing files that changed from the base of the PR and between 40904d9 and 2248adf.

📒 Files selected for processing (3)
  • packages/worker/src/email/mailbox-inbound-effect-ledger.workers.test.ts
  • packages/worker/src/email/mailbox-inbound-ledger-test-helpers.ts
  • packages/worker/src/email/mailbox-inbound-ledger.workers.test.ts

Comment thread packages/worker/src/email/mailbox-inbound-ledger-test-helpers.ts Outdated
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 36c1370. Configure here.

Comment thread packages/worker/src/email/mailbox-inbound-ledger.ts
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
@kody-bot
kody-bot merged commit 7d762da into main Aug 2, 2026
10 checks passed
@kody-bot
kody-bot deleted the cursor/mailbox-do-810a branch August 2, 2026 14:55
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.

3 participants