Compiled entirely from public activity on meta.discourse.org, X, and GitHub.
💬 meta.discourse.org
Sam’s visible Meta activity this week was light and centered on housekeeping around resolved support/bug topics. He appears to have been responding to or closing out reports involving SVG badge display issues and missing validation for survey plugin min/max settings, with both threads automatically closed shortly afterward.
🐦 On social
No X activity captured this week.
🛠️ GitHub — Sam’s Commits
discourse/discourse
Sam focused on authentication/API access, landing a substantial User API key device authorization flow with new backend services, frontend routes, activation UX, expiry handling, and broad test coverage. He also advanced AI infrastructure in discourse-ai by expanding vLLM reasoning controls and tightening provider parameter handling. A smaller thread improved automation reliability and flexibility, allowing nested automation triggers within a configurable recursion limit to prevent infinite loops while supporting more complex workflows.
Key commits:
43cd7ec— DEV: Make automation recursion depth configurable (#40778)2caa675— FEATURE: expand vLLM reasoning controls (#40727)5458a5f— FEATURE: User API key device authorization flow (#40189)c04933d— FEATURE: Allow nested automation triggers up to a recursion limit (#40672)
discourse/discourse-kanban
Sam Saffron spent the last week tightening Discourse Kanban’s permission and privacy boundaries, especially around restricted tags, inaccessible topics, hidden cards, and private card metadata. The work appears focused on preventing unauthorized data exposure in board/card payloads and oneboxes while ensuring mutations like board updates, topic moves, constraint fixes, and column clears respect visibility and edit permissions. He also backed these fixes with broad spec coverage across controllers, serializers, and services.
Key commits:
fcfd5fc— fix: preserve hidden cards when clearing columns32888be— fix: enforce floater tag visibility3743528— fix: hide restricted tags in board payloads6dc94c7— fix: hide restricted topic card oneboxese616094— FIX: hide inaccessible topic card data
SamSaffron/dotfiles
Sam made a small dotfiles maintenance pass this week, focused on keeping his development environment current and smoothing a workflow rough edge. He refreshed several Neovim plugin lockfile pins and adjusted the Hyprland screen-recording script to pass the selected geometry directly to gpu-screen-recorder, likely fixing or simplifying region capture behavior.
Key commits:
2943b34— updates
discourse/safe_image
Sam spent the week pushing safe_image toward a more hardened, release-ready image pipeline: tightening SVG sanitization/metadata parsing against namespace, encoding, <use>, marker, and render-bomb attacks, with extensive regression and fuzz-style coverage. He also broadened image handling capabilities—JXL, ICO, dominant color extraction, letter avatars, orientation fixes—and reworked internals around libvips/native bindings, sandboxing, and pooled zygote workers for safer/faster execution. Alongside that, he cleaned up tests, CI, release workflow, docs, changelog, and configuration so the gem is easier to ship and integrate with Discourse.
Key commits:
6220c76— fix: harden image validation pathsc36b6ba— Version bump5d3f2a8— CI issue5ebba40— FEATURE: allow textPath elements0884976— fix(svg): scan metadata with Nokogiri SAX
discourse/discourse_docker
Sam focused on modernizing and hardening Discourse’s Docker build foundation. He added newer image-processing capabilities like libvips/cjpegli support for faster, better compression, then tightened the supply chain by pinning external dependencies, vendoring signing keys, and refreshing core build components such as ImageMagick, jemalloc, oxipng, Redis, Chrome, and Firefox. He also bumped the default base image so the updated dependency stack becomes the standard path for deployments.
Key commits:
a778ee9— Bump default base image to 2.0.20260611-0330 (#1074)1f3580b— DEV: pin external dependencies and update (#1073)7f038d6— FEATURE: add image handling libraries (#1072)
rubyjs/mini_racer
Sam focused on hardening MiniRacer’s native boundary with V8, especially around edge-case data handling: preserving embedded NUL bytes, callback exception payloads, and preventing large JavaScript integers from wrapping incorrectly. He also addressed memory/resource safety by releasing heap snapshot buffers, tightened test stability/noise, and corrected TruffleRuby support before cutting a version bump.
Key commits:
a9a874d— test: stabilize heap stats warmup215889b— version bump4fd4229— Correct truffle implementationa69e832— reduce noise in tests4469082— FIX: preserve embedded NUL bytes
🤖 Jarvis — Public Repo Work
Agent-authored public commits, typically guided by Sam during implementation work.
discourse/safe_image
Over the last 7 days, Sam-directed Jarvis work in discourse/safe_image focused on rapidly building and hardening a Ruby image-processing gem: starting from libvips-based processing, then adding ImageMagick compatibility, Discourse parity, optimization, SVG/ICO handling, metadata helpers, and safer remote image probing. A major theme was security hardening—sandboxing, fail-closed behavior, path and remote-fetch protections, blocked special-use IP ranges, stricter SVG sanitization, and ImageMagick policy controls. The work also polished packaging, CI, documentation, licensing/security posture, and added optional cjpegli JPEG encoding support.
29 commits by [email protected].
Key commits:
1a04c12— Harden SVG sanitizer against active content172fdfb— Polish README for encoder docs65babd8— Add optional cjpegli JPEG encoding35c9d30— Document license and security posture403f741— Add explicit convert API
⤴️ GitHub — Pull Requests
10 PRs this week:
- ✅ SamSaffron/term-llm#821 (diff) — fix: Widget processes can start after shutdown begins and leak past CloseContext closed
- added a manager shutdown flag and shutdown context so widget startup can see when
CloseContext()has begun - reject new widget starts inensureRunning()once shutdown starts, including requests that were already waiting onstartMu- run widge…
- added a manager shutdown flag and shutdown context so widget startup can see when
- ✅ SamSaffron/term-llm#819 (diff) — fix: Telegram session shutdown can block forever waiting for a stuck stream closed
- changed Telegram session shutdown to use a bounded wait instead of blocking forever on
replyDone- reused the manager timeout setting for this shutdown wait, with a 5s fallback when no timeout is configured - logged when a stuck stream does not s…
- changed Telegram session shutdown to use a bounded wait instead of blocking forever on
- ✅ SamSaffron/term-llm#820 (diff) — fix: Shell tool does a full /proc descendant scan after every command closed
- Added a shell-specific cleanup path that skips the expensive nonce-based
/procdescendant scan after ordinary foreground shell commands. - Kept the cheap process-groupSIGKILLcleanup in place for every shell invocation. - Still run the nonce s…
- Added a shell-specific cleanup path that skips the expensive nonce-based
- ✅ SamSaffron/term-llm#797 (diff) — fix: Telegram stream persistence can stall event ingestion and trip the watchdog closed
- moved Telegram response/turn callback persistence off the callback hot path into a small per-stream async queue - kept callback writes serialized so assistant/tool-result message ordering is preserved - retained bounded
runStoreOpWithoutCancelpe…
- moved Telegram response/turn callback persistence off the callback hot path into a small per-stream async queue - kept callback writes serialized so assistant/tool-result message ordering is preserved - retained bounded
- ✅ SamSaffron/term-llm#798 (diff) — fix: AddMessage still loses messages on concurrent sequence conflicts closed
- changed
SQLiteStore.AddMessageso auto-sequenced appends run insideBEGIN IMMEDIATEon a pinned connection before readingMAX(sequence)- factored the shared insert/session-timestamp logic into a small helper used by both the auto-sequence an…
- changed
- ✅ SamSaffron/term-llm#804 (diff) — fix: serve shutdown timeout is bypassed by unbounded waits in jobs/response-run/ closed
- Made serve shutdown teardown context-aware for jobs, response runs, and widgets by adding bounded close helpers that stop waiting when the serve shutdown context expires. - Updated
serveServer.Stopto start those teardown steps in parallel instea…
- Made serve shutdown teardown context-aware for jobs, response runs, and widgets by adding bounded close helpers that stop waiting when the serve shutdown context expires. - Updated
- ✅ SamSaffron/term-llm#805 (diff) — fix: serve shutdown timeout is bypassed by unbounded waits in manager teardown closed
- started
serveServer.Stopshutdown and manager teardown concurrently soserver.Shutdown(ctx)is no longer blocked behind synchronous subsystem cleanup - added context-aware teardown paths forjobsV2Manager,responseRunManager, and `widgets.M…
- started
- ✅ SamSaffron/term-llm#806 (diff) — fix: Sidebar session listing does a full sort on every web refresh because the O closed
- Added two dedicated SQLite expression indexes for the sidebar list orders: -
idx_sessions_sidebar_activityon(archived, COALESCE(pinned, FALSE) DESC, COALESCE(last_message_at, last_user_message_at, created_at) DESC)- `idx_sessions_sidebar…
- Added two dedicated SQLite expression indexes for the sidebar list orders: -
- 🟢 discourse/discourse_docker#1076 (diff) — DEV: speed up base image builds opened
Add registry-backed BuildKit cache support and cache mounts for apt, asset downloads, npm, and compiled builder stages so fresh CI runners can reuse expensive base image work. Build libvips from source without the ImageMagick fallback loader and add …
- ✅ discourse/discourse_docker#1074 (diff) — Bump default base image to 2.0.20260611-0330 merged
🐛 GitHub — Issues
No issue activity this week.
👀 GitHub — Reviews
No reviews this week.