Compiled entirely from public activity on meta.discourse.org, X, and GitHub.
💬 meta.discourse.org
Sam focused on improving Discourse’s AI-driven daily summary system, porting it to workflows to make prompt engineering and iteration easier. He also experimented with small UX enhancements, sharing an unofficial theme component that previews larger emoji on hover.
🐦 On social
No X activity captured this week.
🛠️ GitHub — Sam’s Commits
samsaffron/term-llm
Sam focused on making term-llm more robust as a served, multi-agent system: he added a substantial serve hub control plane with delegation, reverse connections, node handling, proxying, UI, docs, and tests. Alongside that, he hardened runtime behavior around streaming, cancellation, queues, SQLite persistence, session metadata, and async job notifications, suggesting a push toward reliable long-running agent/server workflows. He also improved user-facing controls with mid-run effort changes, a --no-search flag, safer incremental markdown streaming, and richer model object configuration support.
Key commits:
ef9fec4— remove noisea72d209— fix(jobs): serialize sqlite writes and async notificationsf3baaaa— feat: add serve hub control plane2ef2245— feat: support model object configse2f254d— feat: add –no-search flag to disable web search
discourse/discourse
Sam focused heavily on AI-assisted Discourse Workflows, landing a large AI authoring interface and backend, then extending it with agent workflow uploads/runners, better node filtering, whisper post creation, validation, and extensive tests. He also improved adjacent AI/admin tooling with a better AI usage report, added Google Meet oneboxes, and fixed chat read-state behavior so reads respect browser attention. Outside feature work, he addressed a stored XSS issue in user suspension/silencing reasons and briefly updated then reverted mini_racer, suggesting dependency caution after validation.
Key commits:
313f8e7— FEATURE: Support AI agent workflow uploads and runner (#41042)329d677— Revert “DEV: update mini_racer dependency (#41015)” (#41047)69a9cf4— DEV: update mini_racer dependency (#41015)6502432— FEATURE: Add AI authoring to Discourse Workflows (#40504)4ed12be— FEATURE: Add workflow whisper post creation (#41017)
discourse/dv
Sam focused on adding host lifecycle hooks to discourse/dv, giving the CLI a more extensible way to run custom actions around environment/container startup and related workflows. The work touched core CLI commands, configuration, serve behavior, and onboarding docs, with a strong emphasis on test coverage—suggesting the intent was to make dv more automation-friendly and safer to customize.
Key commits:
567c923— feat(hooks): add host lifecycle hooks
rubyjs/mini_racer
Sam focused on hardening MiniRacer’s :single_threaded execution path around tricky lifecycle edges: forking, disposal, Ruby thread interruption, and callbacks into Ruby. The work appears aimed at preventing hangs, crashes, and heap corruption by making inherited fork state recoverable or safely abandoned, making busy V8 execution interruptible, and making disposal during callbacks fail safely instead of deadlocking. He also expanded regression coverage for these concurrency/fork cases, fixed a flaky datetime assertion, and bumped the gem to 0.21.3.
Key commits:
0d76e94— FIX: harden single-threaded fork, dispose, and interrupt handling
discourse/safe_image
Sam spent the last week hardening and restructuring safe_image around sandboxed image processing: adding a native VIPS sandbox helper, moving toward Landlock/public sandbox APIs, and splitting the operation layer from sandbox execution. A major API cleanup required explicit output paths and reorganized metadata/transform concerns, suggesting a push for safer, clearer file handling and a more maintainable public interface. He also removed SVG sanitization support from the gem, likely narrowing scope to focus on secure raster/image operations rather than owning complex SVG sanitization logic.
Key commits:
261e477— refactor(sandbox): use public Landlock APIc116868— refactor: split operation and sandbox layers13c35c9— feat(api)!: require explicit output paths561cf0a— fix(sandbox): handle worker errors and outputs0a2f082— DEV: remove svg sanitization for safe_image
SamSaffron/emoji-hover-preview
In the last 7 days, Sam Saffron created the initial version of emoji-hover-preview, a Discourse theme component for showing larger emoji previews on hover or focus. The work focused on a global delegated implementation that handles dynamically added emoji across posts, titles, statuses, and the emoji picker, with accessibility-minded labeling and positioning. He also added styling, metadata, localization, and a substantial integration test suite to make the component shippable from the start.
Key commits:
a761c69— Initial commit
tmm1/rbtrace
Sam focused on stabilizing rbtrace’s interactive IRB mode and test workflow. He merged a fix for --interactive so IRB eval results print correctly, along with a regression test and release metadata updates, then followed up by making the project’s test-running instructions clearer in the Rakefile.
Key commits:
4b556ec— make running tests clearer753fe9d— Merge pull request #108 from OsamaSayegh/fix-irb-output-release
discourse/ruby-landlock
Sam focused on turning ruby-landlock into a more capable and production-ready sandboxing library. The main work added a new Landlock.capture API and reorganized the execution stack around reusable policy, environment, rlimit, process I/O, and runner components, with a stronger native helper path plus fork fallback. He also hardened the helper with fd cleanup, seccomp network denial, stricter parsing, and improved tests/docs for the 0.3 release, while earlier trimming unnecessary Ruby library linkage to speed up the safe-exec helper.
Key commits:
5145486— FEATURE: add Landlock.capture API (#2)1417676— PERF: drop Ruby libs from safe-exec build (#1)
discourse/discourse_docker
Sam Saffron focused on keeping discourse_docker’s runtime foundation current and more self-contained. The week’s work updated the default Discourse base image across launcher/templates and changed the base image build to install VIPS from source, likely improving control over image-processing dependencies and compatibility.
Key commits:
568b689— Bump default base image to discourse/base:2.0.20260617-0053 (#1080)c0fff3f— DEV: install VIPS from source (#1076)
SamSaffron/dotfiles
Sam made a focused dotfiles maintenance update: modernizing his desktop/window-manager setup by adding a Lua-based Hyprland config for newer Hyprland releases. He also refreshed Neovim’s coding setup, migrating nvim-treesitter to its newer main-branch API, replacing the archived playground workflow with built-in InspectTree, preserving textobject navigation, and making the local term-llm plugin load more safely only when present.
Key commits:
7e93de0— config: update Hyprland and treesitter
🤖 Jarvis — Public Repo Work
Agent-authored public commits, typically guided by Sam during implementation work.
SamSaffron/term-llm
Sam-directed Jarvis work over the last 7 days focused on hardening and polishing the new hub experience in term-llm: browser-based authentication, clearer token terminology, login UX, tab/favicon polish, and extensive regression tests. The larger theme was enabling more robust hub deployment patterns, especially reverse node registration with tokens and making the hub prefix-aware for hosting behind path-prefixed proxies. In total, this was a concentrated push to make the hub easier to operate, document, and securely connect nodes to.
Key commits:
9ce0880— feat: make hub prefix aware (#850)b846daa— feat: document reverse node registration in hub UI (#849)b6cec81— feat: register reverse hub nodes with token (#846)801f317— fix: polish hub tab title and favicon (#845)035918b— fix: call hub auth credential a token (#844)
⤴️ GitHub — Pull Requests
23 PRs this week:
- ✅ SamSaffron/term-llm#841 (diff) — fix: Jobs SQLite database uses the default unbounded connection pool despite con closed
- capped the jobs v2 SQLite pool at a single connection immediately after
sql.Open- set the idle limit to match so the jobs manager does not keep extra idle SQLite connections around - updated the jobs v2 manager test to assert that file-backed da…
- capped the jobs v2 SQLite pool at a single connection immediately after
- ✅ SamSaffron/term-llm#801 (diff) — feat: add term-llm Hub and delegation closed
Adds term-llm Hub as a single dashboard/proxy over multiple term-llm web nodes, plus opt-in cross-node delegation. Hub v1 includes: -
term-llm serve hub- Hub bearer auth (--auth bearer,--token,TERM_LLM_HUB_TOKEN) with--auth nonerestric… - ✅ discourse/discourse#41047 (diff) — Revert “DEV: update mini_racer dependency (#41015)” opened
This reverts commit 69a9cf4f92c2e6cf2f447422fbc0da653c702aab.
- 🟢 rubyjs/mini_racer#430 (diff) — feat: add global MiniRacer pause gate opened
Add MiniRacer.pause/resume to quiesce operations process-wide with timeout handling and nested pauses. Expose PauseTimeoutError and opt-in Process._fork hooks so fork can wait for MiniRacer to drain before parent and child continue. Document the fork…
- ✅ discourse/discourse#41042 (diff) — FEATURE: Support AI agent workflow uploads and runner opened
Allow workflow AI agent nodes to run as a configured actor and attach visible uploads to prompts. Expose post upload IDs to workflows and update AI authoring/catalog metadata so generated workflows can use runner_username and upload_ids. Show selecte…
- ✅ discourse/discourse#41015 (diff) — DEV: update mini_racer dependency merged
resolves some stability issues with single threaded mode
- ✅ SamSaffron/term-llm#836 (diff) — fix: snapshot persistence rewrites transcripts without updating user-turn/activi closed
- Updated
internal/session.SQLiteStore.ReplaceMessagesto recompute and persist session metadata in the same transaction as the transcript rewrite. - The replace path now refreshes: -user_turns-last_user_message_at-last_message_at…
- Updated
- ✅ SamSaffron/term-llm#837 (diff) — fix: serve/web runs never persist turn metrics or context estimates closed
- Updated
cmd/serve_runtime.goso the existingSetTurnCompletedCallbacknow persists per-turn metrics for serve/web runs viastore.UpdateMetrics(...). - Persisted the engine context-estimate baseline on normal turn completion via `store.UpdateC…
- Updated
- ✅ SamSaffron/term-llm#838 (diff) — fix: Responses tool continuations rescan the entire session history to recover t closed
- Changed
populateResponsesToolResultNamesto prefer reverse-paged store lookups when the session store supportssession.MessagesDescendingPager. - The lookup now scans recent persisted messages in descending sequence order and stops as soon as a…
- Changed
- ✅ discourse/discourse#40504 (diff) — FEATURE: Add AI authoring to Discourse Workflows merged
Previously, admins could only build Discourse Workflows by manually adding and connecting every trigger, condition, and action node on the canvas. This change adds an AI authoring assistant, gated behind
discourse_workflows_ai_authoring_enabledand… - 🟢 discourse/discourse#41019 (diff) — FEATURE: Add sub workflow call support opened
Add validation, dependency indexing, and execution metadata for workflows that call other workflows. Prevent invalid targets, cycles, recursive calls, and deletion of workflows still referenced by callers. Expose caller details to workflow call trigg…
- ✅ discourse/discourse#41017 (diff) — FEATURE: Add workflow whisper post creation merged
Allow the workflows post node to create whisper replies when the author has whisper permissions, and expose post_type in serialized results so callers can identify whisper posts. Fix the boolean expression configurator to preserve boolean values when…
- ✅ discourse/discourse#41018 (diff) — FEATURE: add Google Meet oneboxes opened
Render Meet links as static onebox cards instead of generic embeds. Include localized labels, styling, SVG icon support, lookup-link handling, and specs for matching and rendering.
- ✅ SamSaffron/term-llm#834 (diff) — fix: WebRTC data-channel requests keep running after disconnect and can hang pee closed
- created a data-channel-scoped request context in
runDataChanneland cancel it before waiting for in-flight handlers during disconnect, idle-timeout, and reader-exit teardown paths - made data-channel send failures stop the channel so all in-fligh…
- created a data-channel-scoped request context in
- ✅ discourse/ruby-landlock#2 (diff) — FEATURE: add Landlock.capture API merged
Expose capture/capture! as the supported subprocess capture interface and replace the legacy SafeExec facade with shared execution, policy, environment, rlimit, and process I/O helpers. Route exec, spawn, and capture through the packaged native helpe…
- ✅ discourse/discourse#40963 (diff) — SECURITY: Stored XSS in suspension and silencing reasons on user profiles and ca merged
On sites with CSP disabled Staff could enter HTML as a suspension of silencing issue which would show up in HTML Security hardening Co-authored-by: discourse-patch-triage <272280883+discourse-patch-triage[bot]@users.noreply.github.com>
- ✅ discourse/discourse#40977 (diff) — FEATURE: Improve workflow node filtering merged
Expand post listing filters to support regular/all post types, action posts, whispers, and additional topic statuses while preserving guardian visibility. Allow AI agent workflow nodes to choose an LLM override, fall back to agent/site defaults, and …
- 🟢 discourse/discourse#40976 (diff) — POC: safe image integration into discourse opened
do not merge POC for now
- ✅ discourse/discourse_docker#1080 (diff) — Bump default base image to discourse/base:2.0.20260617-0053 merged
- ✅ discourse/discourse_docker#1076 (diff) — DEV: install VIPS from source merged
Debian vips depends on image magick core, by using it we end up shipping 2 versions of image magick in our base image. This compiles vips library without any image magick sidestepping the problem. Additionally ensures ghostscript is never installed…
- ✅ discourse/ruby-landlock#1 (diff) — PERF: drop Ruby libs from safe-exec build merged
Build landlock-safe-exec without Ruby extension LIBS to avoid unnecessary runtime library dependencies and improve helper startup time. Bump version to 0.2.1 and update the changelog.
- ✅ discourse/discourse#40864 (diff) — FIX: gate reads on browser attention merged
Track browser focus and visibility separately from user presence so chat panes only mark messages read for active readers. Keep visible unfocused panes live-following at the bottom, leave hidden tabs pending, and preserve own-message auto-scroll beha…
- ✅ discourse/discourse#40865 (diff) — FIX: Improve AI report implementation merged
Keep the admin AI usage period, date, feature, and model filters in query params so filtered reports can be reloaded or shared. Preserve unfiltered option lists while filters are active, honor exact datetime report ranges, and normalize chart buckets…
🐛 GitHub — Issues
No issue activity this week.
👀 GitHub — Reviews
7 reviews this week:
- discourse/discourse#41018 — FEATURE: add Google Meet oneboxes commented
- discourse/discourse#41008 — SECURITY: Stored XSS in suspension and silencing reasons on user profiles and ca approved
- discourse/discourse#41007 — SECURITY: Stored XSS in suspension and silencing reasons on user profiles and ca approved
- discourse/discourse#40632 — DEV: Add per-test SQL/Redis/network capture RSpec formatter approved
- discourse/discourse#40632 — DEV: Add per-test SQL/Redis/network capture RSpec formatter commented
- discourse/discourse_docker#1076 — DEV: install VIPS from source commented
- discourse/discourse_docker#1076 — DEV: install VIPS from source commented