From 582108a8e3af375e993fee305ac1c7d1711d6d15 Mon Sep 17 00:00:00 2001 From: Julien Herr Date: Fri, 22 May 2026 10:31:41 +0200 Subject: [PATCH] docs: move Durable Objects migration from TECH_DEBT to TODO The race condition is an accepted limitation of KV; the DO migration is a future feature rather than active tech debt to remediate. Co-Authored-By: Claude Sonnet 4.6 --- TECH_DEBT.md | 15 +++++++-------- TODO.md | 2 ++ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/TECH_DEBT.md b/TECH_DEBT.md index b8658a4..ca77eda 100644 --- a/TECH_DEBT.md +++ b/TECH_DEBT.md @@ -27,13 +27,12 @@ Generated: 2026-05-22 ## Phase 3 — Ongoing / Infrastructure -| # | Task | Priority | -| ----- | ---------------------------------------------------------- | -------- | -| P1-4 | Structured logging + error aggregation | 36 | -| P1-5 | Rate limiting (Cloudflare WAF rules) | 24 | -| P1-1 | Migrate feed metadata to Durable Objects for atomic writes | 36 | -| P2-10 | Extract constants module (`src/config/constants.ts`) | 12 | -| P2-11 | Split `admin.ts` into sub-modules | 8 | +| # | Task | Priority | +| ----- | ---------------------------------------------------- | -------- | +| P1-4 | Structured logging + error aggregation | 36 | +| P1-5 | Rate limiting (Cloudflare WAF rules) | 24 | +| P2-10 | Extract constants module (`src/config/constants.ts`) | 12 | +| P2-11 | Split `admin.ts` into sub-modules | 8 | --- @@ -52,7 +51,7 @@ Generated: 2026-05-22 **Race condition in KV metadata updates** (`src/lib/email-processor.ts`) Two concurrent emails to the same feed read-modify-write the metadata non-atomically. The second writer silently overwrites the first's changes. Accepted limitation of KV; -long-term fix is Cloudflare Durable Objects for serialised writes. +see TODO.md for the Durable Objects migration roadmap item. **Email ingest path has zero tests** (`src/routes/inbound.ts`) The most critical path in the system is entirely unguarded. Required: happy path, diff --git a/TODO.md b/TODO.md index 58fcffb..34392af 100644 --- a/TODO.md +++ b/TODO.md @@ -23,3 +23,5 @@ Feature gaps identified by comparing with [kill-the-newsletter](https://github.c - [x] **Email attachments as RSS enclosures** — store attachments in Cloudflare R2 and expose them as `` elements in the feed. kill-the-newsletter serves them at `/files/{enclosureId}/{filename}`. - [ ] **WebSub (PubSubHubbub) push notifications** — notify subscribers in real time when a new email arrives, instead of requiring them to poll the feed. Requires either integrating a public WebSub hub or implementing the hub protocol directly. + +- [ ] **Migrate feed metadata to Durable Objects for atomic writes** — the current KV-based metadata store has a read-modify-write race condition: two concurrent emails to the same feed can silently overwrite each other's changes. Cloudflare Durable Objects serialise access per feed and eliminate the race entirely. Requires replacing `feed::metadata` KV writes in `src/lib/email-processor.ts` with a Durable Object that exposes an `appendEmail()` RPC, updating `wrangler.toml` with a DO binding, and migrating existing metadata at deploy time.