• v7.2.0 c58ba559df

    v7.2.0
    All checks were successful
    CI / App — typecheck, test & build (push) Successful in 2m25s
    CI / API — typecheck & tests (push) Successful in 3m53s
    CI / Images — production build (push) Successful in 4m18s
    Stable

    claude-bot released this 2026-07-17 16:37:36 +00:00 | 100 commits to main since this release

    Tea Leaves v7.2.0 — Reliability, Data Integrity & Docs

    Released 2026-07-17

    The Medium/Low remainder of the 2026-07-15 codebase audit — the things that rot quietly rather than break loudly — plus two bonus features and a long-standing CI flake finally root-caused. All 13 milestone issues, no breaking changes. Migrations 044046 (additive; 046 renames one column).

    🛡️ Data integrity

    • Deleting a user no longer strips attachments off the entries it preserves (#98). media.user_id was still ON DELETE CASCADE while entries.user_id is SET NULL — so a departed collaborator's media was hard-deleted (and files orphaned on disk) even on entries the schema intends to keep. Migration 044 makes it SET NULL; entry_id remains the lifecycle anchor.
    • Soft-deleted content no longer leaks (#93, #94). The legacy motif share query served trashed motifs and entries; export leaked trashed rows across four queries (including one that embedded a trashed entry's content via a connection to a live one). CSV export cells starting = + - @ are now neutralised against spreadsheet formula injection.
    • Federation optimistic-lock TOCTOU (#96). The lock read happened on the pool before the write transaction, so a concurrent local edit could be silently clobbered by a stale remote update. Now SELECT … FOR UPDATE inside the transaction; regression-tested with a real concurrent-edit race.
    • Media access is project-scoped, not uploader-scoped (#135). Every media route keyed off media.user_id, so a collaborator's uploads were invisible to the project owner today, and (post-#98) a deleted uploader's preserved media was unreachable. Reads now scope to the entry's project; delete is stricter (uploader or project owner only). Multi-user tested.

    ⚙️ Reliability & ops

    • /health probes its dependencies (#97). It returned ok the moment the event loop was alive; now it runs SELECT 1 + Redis PING (each bounded) and returns 503 when either is down. Added a container HEALTHCHECK and gated app on service_healthy. (Note: Docker Compose doesn't restart on healthcheck failure — that's tracked in #137 → monitoring.)
    • CI builds the production images (#103) and asserts the migrations copy landed — a Dockerfile/peer-dep regression can no longer ship unverified.
    • Bounded Redis job retention (#100), top-level crash handlers (#101), a project-scoped entry-list index (#95), and the AP signature freshness window widened 30 s → 5 min (#102) so clock-skewed federated peers stop being rejected as invalid.

    Features

    • Semantic dedup Pass 2 is real (#99). It was documented as active but never existed — the duplicate-review queue could never fill. Now cosine similarity over text_embedding flags near-duplicate imports, with imports embedding inline (one AI call per post) and a dedicated import.dedupThreshold (default 0.95) so a themed archive doesn't flag itself.
    • Real perceptual image dedup (#136). media.phash held a SHA-256 of the bytes (matches only byte-identical files) under a misleading name. Renamed to content_sha256; added a 64-bit dHash so re-encoded/resized copies are caught. Threshold set from measurement — re-encodes 0–7 bits apart, distinct images ≥24, default 10 in the gap.

    📚 Docs

    • README documents v6.2 and v7 (#104) — it trailed the code by a major version; the federation trust model is now written down for a new operator. Categories/Insights added; two further stale claims fixed.

    🧪 Internal

    API suite grew to 268 tests (from 232). And the API — typecheck & tests CI flake is root-caused and fixed: with no AI configured the app defaults to ollama at localhost:11434, so every entry-write test fired a fire-and-forget embedding fetch that piled up inside CI's Docker-in-Docker and starved the pg pool, pushing analytics.test.ts past its 15 s timeout. test/setup.ts now takes the suite off the network for AI. It was never the runner.

    Upgrading: migrations 044046 apply on boot; no config changes. 046 renames media.phashmedia.content_sha256 and adds media.dhash.

    Downloads