release: v1.9.0#211
Merged
Merged
Conversation
…) (#203) A crash between the atomic publish claim and delivery left a scheduled post published-but-unfederated forever (no marker, no retry). Also: the scheduler's publish path never persisted blueskyUri, so scheduled posts never got Bluesky reply-syncing. - Post.federatedAt records a completed delivery attempt; Post.threadsPostId + blueskyUri are persisted by the shared publisher (reply-sync + retry idempotency markers). - Retry sweep: published scheduled posts with no completed delivery get ONE retry after a 10-minute QUIET period anchored to updatedAt (the claim bumps it) — anchoring to scheduledFor would make a post claimed late (downtime over its slot) retry-eligible instantly, the exact scenario adversarial review reproduced as a double-post. - Double-post defenses (adversarially verified, reproduced race fixed): publishPost re-reads the crosspost markers just before posting (stale snapshot guard), publish ticks never overlap in-process (in-flight guard), the retry claim is an atomic federatedAt compare-and-swap, and AP redelivery reuses the same activity id (remote dedupe). - Migration backfills federatedAt for scheduler-published posts predating the markers (they'd otherwise re-crosspost once) — db push alone is NOT sufficient this time; npm run update applies the SQL first (CHANGELOG says so explicitly). - Tests: 313 total. Hermetic publish-post tests (the old ones hit a live localhost Postgres via the unmocked db import — caught in review), pinned claim WHERE clauses, pinned deliver-before-mark ordering, marker re-read + fallback, tick-overlap guard. Closes #195 Co-authored-by: Samuel Lison <samuel@slcolonies.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ice) (#204) The scheduler's cadences/toggles were env-only (SCHEDULER_*, read at boot). First slice of the in-app admin/config panel (#59): - scheduler-config: getEffectiveSchedulerConfig() overlays admin-saved SiteSetting overrides (scheduler.* keys) on the env defaults; 60s cache, invalidated on save; DB-down falls back to env (uncached). Intervals clamped to 10s-24h so a typo can't wedge the scheduler. No schema change (SiteSetting already exists). - scheduler: one self-scheduling master loop (15s) dispatches jobs by elapsed-vs-configured cadence, re-reading the effective config each tick — toggles AND cadence changes apply within a minute, no restart. Loop is serialized by construction; runPublishTick keeps its in-flight guard (flag now claimed synchronously — an await before it opened a suspension window two callers could pass, caught by the overlap test). - /api/admin/settings (GET/POST): owner-cookie only (verifyOrigin + await verifyAdmin, no bearer path — an app token must not reconfigure the instance, same stance as /admin/apps). Key allowlist, validate-all- before-write-any, null value deletes the override (revert to env). - /admin/settings UI: Scheduler card (toggles + cadence inputs + "Use env defaults"), linked from the timeline header. Tests: 325 total (12 new: overrides/clamp/cache/fallback, route gates + allowlist + upsert/delete + cache invalidation, live-toggle + live-cadence + overlap-guard scheduler tests). Smoke-tested on a built server: page login-gated, API 401/403 unauthenticated, scheduler boots + logs. Co-authored-by: Samuel Lison <samuel@slcolonies.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… dropped (#205) (#208) The inbox switch had no Update branch, so edits made on the origin instance (Mastodon sends Update(Note|Article)) fell to default and were silently ignored — the stored copy kept pre-edit text forever. - New handleUpdateNote: matches the stored FediPost by the object's apId, re-derives content exactly like Create ingest (escaped Article title + sanitizeHtml + processAttachments), stamps FediPost.editedAt (new nullable column + manual migration), and keeps FediInteraction reply rows (the bell/thread copy — the ONLY copy for non-followed repliers) in sync. Unknown objects are ignored (no create-from-Update, matching Mastodon). - Ownership gate: the transport check binds the signature to the actor's HOST, not the actor — the handler additionally requires the Update's actor to BE the stored author, closing a same-host rewrite of another actor's cached post. (The residual same-host limitation is transport- wide and pre-existing; tracked separately.) - editedAt is clamped to <= now (remote-controlled value) and flows through the feed/conversation payloads automatically (full-row spread). - Tests: 9 new (first inbox route tests) — edit applied + sanitized on BOTH storage paths (script/onerror payloads pinned), Article title escaping, wrong-actor rejection, unknown-object ignore, future-date clamp, non-Note/Article ignore. Adversarially reviewed: the handler's own authz/sanitization held; findings were pre-existing transport context + the two polish items applied here. Closes #205 Co-authored-by: Samuel Lison <samuel@slcolonies.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
prepare-release.mjs minor: CHANGELOG '## Unreleased' → '## 1.9.0 (2026-07-06)', package.json + lock bumped. Co-authored-by: Samuel Lison <samuel@slcolonies.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Release v1.9.0 — dev → main (merge commit, per the branch model).
Highlights
Updateis applied instead of silently dropped — your feed reflects the current text, with aneditedAtmarker. Ownership-gated and re-sanitized./admin/settingsscreen toggles the scheduler's jobs and changes their cadences with no restart, no env editing.Schema (operators — read this)
Additive only, but use
npm run update(not baredb push): it applies the manual migrations in order, and #195's migration includes a backfill that plaindb pushskips — without it, pre-1.9.0 scheduled posts would be re-crossposted once. Migrations:2026-07-03-post-delivery-markers.sql,2026-07-06-fedipost-edited-at.sql.Ops note
If you ever deployed the short-lived dev
fedihome-schedulerPM2 process:pm2 delete fedihome-scheduler && pm2 savebefore updating.Full notes: the
## 1.9.0 (2026-07-06)section of CHANGELOG.md.