Things I’ve said on Bluesky in August 2025. On Event Sourcing, Domain-Driven Design, Ruby, and software architecture.

2025-08-01

I like Rails but I’m frustrated by how it shapes what Ruby devs consider “good code.” Ruby mixes OOP and FP nicely, but a lot of idiomatic Ruby gets overlooked because Rails rarely uses it — we literally have function composition built-in.

2025-08-02

I sketched a small demo idea combining Event Sourcing and LLMs to let an LLM dynamically change UI focus based on conversation context — a simple concept but with a few interesting possibilities.

2025-08-02

I started a tiny Sinatra chat app that asks an LLM to create topics on the fly and categorises in a background thread, pushing updates with Datastar. Data started in PStore but I moved to SQLite. I linked the Datastar Ruby SDK I wrote: https://github.com/starfederation/datastar-ruby.

2025-08-03

Watching silent 1950s home footage of my mum and family — tiny glimpses of another world. It made me think about how future descendants will watch our lives in far higher fidelity.

2025-08-04

Short Claude anecdote: I asked how to do X and Y, got four options, then when I questioned each one Claude conceded flaws and moved to the remaining options — an amusing loop. Also spent an hour on the wrong Git branch that day.

2025-08-04

I spent a day improving the runtime’s separation of infrastructure and app code: reactors are now simple interfaces the runtime fetches and acknowledges events for, and they can return types that tell the runtime what to do next. Commands/events are just messages in streams, and the runtime guarantees in-order processing per stream. The change should make reactors easier to test and let higher-level DSLs be built on top.

2025-08-05

I showed a tiny logger reactor that catches up on existing events and then logs new ones, with the runtime guaranteeing per-stream ordering while allowing parallel stream processing. I also shared short demo videos and a one-liner Rack dashboard.

2025-08-05

I re-implemented Decide/Evolve/React actors on top of my messaging runtime and it works: the DSL compiles down to the two-method interface the runtime expects, and message correlation is automatic. The backend now uses a claim strategy to ensure per-stream ordering and concurrency while doing event handling outside transactions, which helps avoid connection pool contention.

2025-08-06

I argued that both sides of the “Service Objects in Ruby” debate miss the point — it’s mostly Rails-isms vs non-Rails-isms. A procedure can be an object just as much as a domain entity; good code is about clear information flow, not dogma.

2025-08-07

I made the runtime inject dependencies into consumers based on handle(event, **args) signatures.

2025-08-07

I noted that a messaging-centric architecture tends to push you away from Object Orientation as an architectural style. You can still use OOP tactically, but messaging often becomes the dominant pattern at the architecture level.

2025-08-07

Shared a link to Ralf Westphal’s Killing the Entity! essay on Event Sourcing. I’m following the ES discourse — interesting ideas about doing ES the “epistemic” way.

2025-08-22

I talked about how event sourcing makes it easier to track and assert software behaviour: the event schemas are the single artefact you need to understand end-to-end behaviour (logs, DB rows, API calls are all just side effects).

2025-08-23

I had an hour to hack and Claude was surprisingly productive when tasks were well-scoped and I knew when to stop it. LLMs are good at summarisation and small test-driven tasks: have it write tests for an implementation or vice-versa to surface whether it really understood the intent.

2025-08-24

Most software doesn’t “model” the real world. It TRACKS whatever set of metrics of it that are useful for the domain. Start looking at it this way and you’ll think differently about code, data and error cases.

2025-08-26

Familiarity and simplicity aren’t the same.

2025-08-27

I sketched a small Rating struct in Ruby using my Plumb gem with structural validation, then showed it as a pipeline with custom steps and function-composition syntax. The examples demonstrate simple, composable validation pipelines for multi-attribute rules.

2025-08-27

There’s only structural/input errors and true exceptions that should retry or crash; everything else is a valid domain scenario. This is easier to see once you accept eventual consistency — many “validations” are just domain outcomes, not runtime errors.

2025-08-28

I argued for organising code by verb-oriented capabilities — vertical slices — illustrated by some screenshots. I’ve used this approach in Ruby for years: it centres design on what the app does rather than on data structures, which I find makes workflows and side-effects clearer than scattering behavior across CRUD endpoints.

2025-08-28

Good talk on durable execution and Ruby (Temporal). I linked the talk: https://youtu.be/IMAABWxnbUM?t=462. What I’m building does the same durable-workflow stuff but exposes event sourcing as a modelling tool for your domain, not just resilient workflows — a whole programming model with plain Ruby + SQLite/PG.

2025-08-28

I showed a tiny example of a stateless API in my Ruby event-sourcing code that enforces a rule (three unsuccessful attempts fail a delivery) purely from past events. I also argued that stateless class methods don’t mean “not OOP” — allocation can be a separate concern and .new is just a factory unless managing instance lifecycle matters to the caller.

2025-08-29

I spent an hour adding durable-execution semantics (think Temporal or Restate) to my Ruby event-sourcing runtime.

You declare an execute method and mark “durable” methods. The system decomposes calls into started/failed/complete events, retries failures, and records the execution history.

Work is done by worker processes (not just threads), so workflows resume after reboots and can be distributed across workers while preserving order.