Sign in

Almir Sarajčić

@almirsarajcic.bsky.social
30 followers 118 following 42 posts

Elixir & Phoenix consultant. Founder of Optimum Tech. Kogen, Combobulate, ElixirDrops, Skeptic.bot and elixir.menu. Writing about Elixir and how we build software. Consulting: consulting@optimum.ba almirsarajcic.com

PostsRepliesMedia
Almir Sarajčić @almirsarajcic.bsky.social · 05/10/2026
DHH's Campfire benchmarks should make us review our assumptions about Elixir, including how much help agents need to write it properly. I want better implementations and room to conclude that another stack works better. elixirdrops.net/d/rNXGVxhW #Elixir
elixirdrops.net
Elixir Drops
Admit when you’re wrong — People in the Elixir community shouldn't be butthurt about DHH's Campfire benchmarks. We should use them as an opportunity to look ...
000
Almir Sarajčić @almirsarajcic.bsky.social · 01/10/2026
Jev helps me read a coding agent's handoff and spot gaps in the requirements before coding starts. Asking it to judge whether the code was finished went poorly in a trial; I still need the reviewer. kogen.dev/notes/2026-10-01/jev-this…
kogen.dev
Jev this, Jev that
The boring Jev uses I've found in Kogen: reading an agent's notes and checking requirements before coding.
000
Almir Sarajčić @almirsarajcic.bsky.social · 28/09/2026
On supervisor shutdown, a GenServer that traps exits can run terminate/2 to flush its buffer. Without it, :shutdown kills the process first. The callback still has to finish within the child's shutdown timeout. elixirdrops.net/d/ZFDbvCtx
elixirdrops.net
Trapping exits so terminate/2 actually runs
A GenServer that flushes buffered work in terminate/2 loses it when its supervisor shuts it down, unless the process traps exits:
010
Almir Sarajčić @almirsarajcic.bsky.social · 24/09/2026
Application.compile_env/3 bakes a value in when the module compiles. If config/runtime.exs sets the same key, mix run quietly keeps the compiled value and a release refuses to boot. Read values that runtime.exs owns with Application.fetch_env!/2. #ElixirLang elixirdrops.net/d/sLV42DYt
elixirdrops.net
Keeping compile_env values out of runtime.exs
Application.compile_env/3 bakes a value into the module when it compiles. If config/runtime.exs sets the same key, the two can disagree without anyone noticing:
000
Almir Sarajčić @almirsarajcic.bsky.social · 23/09/2026
Enum.sort/1 orders DateTime values by day of the month: without a sorter, Elixir compares the structs as maps, and :day comes before :month. Enum.sort(dates, DateTime) uses DateTime.compare/2. Date, NaiveDateTime and Time need the same fix. #ElixirLang elixirdrops.net/d/fFwUcmbe
elixirdrops.net
010
Almir Sarajčić @almirsarajcic.bsky.social · 22/09/2026
In Optimum Codegen, 31 rules we had written for our build agents reached them as one. A missing role name and an escaped underscore in a rule import did it. How to check what your agent receives: kogen.dev/notes/2026-0...
kogen.dev
Check what your agent actually receives — Kogen
In Optimum Codegen, 31 rules we had written for the build agents reached them as one. Here is what broke the delivery, why nothing caught it, and how to check your own setup.
000
Almir Sarajčić @almirsarajcic.bsky.social · 22/09/2026
Bulk updates in Ecto don't touch updated_at. Repo.update_all/3 runs one UPDATE with exactly the columns you pass, so timestamps() never gets a new value. If anything syncs, caches or sorts by updated_at, set it in the same call. elixirdrops.net/d/eGNMsW1q
elixirdrops.net
Elixir Drops
Setting updated_at yourself in Repo...
000
Almir Sarajčić @almirsarajcic.bsky.social · 22/09/2026
Some of our Elixir and Phoenix work is now public: ElixirDrops, Skeptic․bot and OptimumGenInfra. I wrote about the code and what we cleaned up before opening it: optimum.ba/blog/opening...
optimum.ba
Opening up our code
We’ve made the code for ElixirDrops, Skeptic.bot, and OptimumGenInfra public, along with several older projects. If you’ve used these applications or…
000
Almir Sarajčić @almirsarajcic.bsky.social · 21/09/2026
Calling Repo from a doctest? Put the doctest module under DataCase and create the record inside the example. It gets a sandbox connection, proves the documented result, then rolls back without leaking data into another test. elixirdrops.net/d/xemXGQJq #Elixir #Ecto
elixirdrops.net
Elixir Drops
Running doctests against the database...
000
Almir Sarajčić @almirsarajcic.bsky.social · 21/09/2026
Kogen depends on Codex for every Build. Supporting another coding agent means rebuilding the Codex-specific parts without giving up Kogen’s checks, independent review, recovery or evidence. kogen.dev/notes/2026-0...
kogen.dev
Replacing Codex without replacing Kogen — Kogen
I want to try other coding agents without handing them Kogen's checks, review, history, and definition of finished.
010
Almir Sarajčić @almirsarajcic.bsky.social · 20/09/2026
Claude Code added AGENTS.md support. I understand why people wanted it, but I’m against one repository-wide instruction file for planning, implementation and review agents with different jobs. kogen.dev/notes/2026-0...
kogen.dev
I don't want AGENTS.md — Kogen
One repository-wide instruction file cannot fit agents with different jobs, and sharing its filename does not standardize how tools interpret it.
020
Almir Sarajčić @almirsarajcic.bsky.social · 20/09/2026
Oban’s Lifeline and Pruner treat raw integers differently: rescue_after is milliseconds, while max_age is seconds. Reuse the same timer value and a seven-day pruning window can become roughly 19 years. Use period tuples to keep the units explicit. elixirdrops.net/d/kz7648Vu #elixir #oban
elixirdrops.net
Elixir Drops
Keeping Oban's time units explicit...
000
Almir Sarajčić @almirsarajcic.bsky.social · 20/09/2026
Coding agents are good at carrying out decisions. They’re a poor place to make product decisions by accident. Kogen’s shaping step turns those decisions into an Intent before Build begins. kogen.dev/notes/2026-0...
kogen.dev
Make no mistakes — Kogen
Preventable mistakes enter an agent-led Build through ambiguity. Make the decisions explicit enough to inspect and check.
002
Almir Sarajčić @almirsarajcic.bsky.social · 19/09/2026
GenServer.call/3 exits the caller when it misses its deadline; it does not return `{:error, :timeout}`. The exit contains the call tuple, so a bare `:timeout` catch will never match. Catch the real exit shape when a timeout belongs in your client API. elixirdrops.net/d/zFC2h9WN #elixir #otp
elixirdrops.net
Elixir Drops
Catching GenServer...
110
Almir Sarajčić @almirsarajcic.bsky.social · 18/09/2026
Slow checks get skipped. Some of Kogen's tests mutated global state, unsafe to run concurrently — isolating just those let the suite run in parallel again, no lost coverage. kogen.dev/notes/2026-0...
kogen.dev
Making the offline check fast enough to keep running — Kogen
A slow verification step gets deferred or skipped. Here's how Kogen kept its check fast without cutting what it verifies.
000
Almir Sarajčić @almirsarajcic.bsky.social · 18/09/2026
An ExUnit on_exit callback runs in another process, so self() inside it is not the test PID. Capture the original PID when cleanup uses it as an ownership key. The test process will already be gone when the callback runs. elixirdrops.net/d/i4LKDQFf #elixir #exunit
elixirdrops.net
Elixir Drops
Keeping self() straight in on_exit callbacks...
021
Almir Sarajčić @almirsarajcic.bsky.social · 17/09/2026
I don’t think “run the checks before you finish” is enough for an agent. That’s prose. A Stop hook makes the check part of stopping. We saw Codex return exit 0 after verification had already exhausted. kogen.dev/notes/2026-0...
kogen.dev
The agent said it ran the checks — Kogen
A Stop hook makes declared checks part of finishing instead of trusting an agent to report that it ran them.
100
Almir Sarajčić @almirsarajcic.bsky.social · 17/09/2026
When a command should not inherit a credential, `env: []` is a no-op. `System.cmd/3` keeps the parent environment unless you change a named key. Pass `{\"VENDOR_TOKEN\", nil}` to clear it before the child starts. elixirdrops.net/d/KpFePAjf #ElixirLang #Testing
elixirdrops.net
Elixir Drops
Clearing inherited variables in System...
020
Almir Sarajčić @almirsarajcic.bsky.social · 16/09/2026
Kogen installs the Codex version it was tested with. It uses its own settings and login too. Updating my Codex no longer changes Kogen's runtime. kogen.dev/notes/2026-0...
kogen.dev
My Codex is not Kogen's Codex — Kogen
Kogen pins a tested Codex version and runs it with its own settings and login, separate from mine.
000
Almir Sarajčić @almirsarajcic.bsky.social · 16/09/2026
`Task.async_stream/3` returns a lazy stream. Calling it does not start any tasks; the work begins only when something enumerates the stream. Use `Stream.run/1` when you need the side effects but not the results. elixirdrops.net/d/HjTWfkFL #elixir #otp
elixirdrops.net
Elixir Drops
Running Task...
000
Almir Sarajčić @almirsarajcic.bsky.social · 15/09/2026
`codex exec` exited 0 in two runs: one exhausted three attempts with its check still failing; the other passed on attempt three. Only the separate verification result distinguished them. kogen.dev/notes/2026-0...
kogen.dev
codex exec can exit 0 after failed checks — Kogen
Codex can exhaust its attempts to fix a failing check while the surrounding codex exec process still exits successfully.
000
Almir Sarajčić @almirsarajcic.bsky.social · 15/09/2026
`mix test --trace` can make an ExUnit timeout failure disappear because trace mode sets test timeouts to infinity. Use `--max-cases 1` when you need serial execution without disabling timeouts. elixirdrops.net/d/zBackG2b #elixir #exunit
elixirdrops.net
Elixir Drops
Keeping timeouts active while tracing tests...
000
Almir Sarajčić @almirsarajcic.bsky.social · 14/09/2026
The LiveView hook was fixed. The browser kept running the old JavaScript. We had left app.js.gz from mix phx.digest beside a new app.js. Plug.Static correctly served the stale compressed file. The bug was ours. elixirdrops.net/d/j1f6rgYb
elixirdrops.net
Elixir Drops
Keeping stale gzip assets out of Phoenix tests...
000
Almir Sarajčić @almirsarajcic.bsky.social · 14/09/2026
A few months ago, HTML reports looked like a waste of tokens. Now I almost can’t work without them. Agents write Markdown. Astro renders HTML for humans. The repetitive tags live in the template. kogen.dev/notes/2026-0...
kogen.dev
Markdown for agents. HTML for humans. — Kogen
The source stays Markdown. Astro templates turn it into a website, so I don't hand-write HTML on every report.
000
Almir Sarajčić @almirsarajcic.bsky.social · 14/09/2026
You don't need Astra for all of this. You need to organize the work better. I ran the same Kogen build with Astra, Sol and Terra. All three passed. kogen.dev/notes/2026-0...
kogen.dev
You don’t need Astra — Kogen
I tried cheaper models on the same Kogen build. They finished the job too.
000
Almir Sarajčić @almirsarajcic.bsky.social · 14/09/2026
FLAME starts your whole application on a remote runner, so your supervision tree has to decide what belongs there. ElixirDrops uses always, parent and flame tags, with a LocalBackend detail that is easy to miss. elixirdrops.net/d/fjeqAM8C #Elixir #Phoenix
elixirdrops.net
Elixir Drops
Starting only what a FLAME runner needs...
000
Almir Sarajčić @almirsarajcic.bsky.social · 12/09/2026
A coding agent should be able to run focused tests while it works. But its own success report shouldn’t be the evidence that the work is finished. In Kogen, final verification belongs to the machinery, and Review belongs to a fresh agent. kogen.dev/notes/2026-0...
kogen.dev
Don’t let the coding agent grade its own work — Kogen
Why Kogen lets the Developer run focused tests but reserves final verification for automated machinery.
010
Almir Sarajčić @almirsarajcic.bsky.social · 15/11/2024
optimum_gen_infra version 0.1.2 was released. #Elixir #ElixirLang
elixirdrops.net
Elixir Drops
optimum_gen_infra v0...
020
Almir Sarajčić @almirsarajcic.bsky.social · 14/11/2024
If you're using `refute_has/2` to assert some element has disappeared in your Wallaby tests, you're doing it wrong. Here's a better approach. #Elixir #ElixirLang
elixirdrops.net
Elixir Drops
Reduce waiting time for refute_has in Wallaby tests...
010
Almir Sarajčić @almirsarajcic.bsky.social · 14/11/2024
Cancel culture is strong with this one :/ bsky.app/profile/did:...
000
Almir Sarajčić @almirsarajcic.bsky.social · 13/11/2024
Speed up your Erlang installation and development using this ~/.kerlrc file. #Elixir #ElixirLang
elixirdrops.net
Elixir Drops
Fine-tuning Erlang build on macOS using ...
000
Almir Sarajčić @almirsarajcic.bsky.social · 12/11/2024
optimum_gen_infra version 0.1.1 was released. #Elixir #ElixirLang
elixirdrops.net
Elixir Drops
optimum_gen_infra v0...
010
Almir Sarajčić @almirsarajcic.bsky.social · 11/11/2024
Wouldn’t it be great if it was possible to write GitHub Actions workflows in #Elixir? elixirdrops.net/d/vyMZznTp
elixirdrops.net
Elixir Drops
Writing GitHub Actions workflows in Elixir...
010
Almir Sarajčić @almirsarajcic.bsky.social · 08/11/2024
We've released a nice little platform for sharing knowledge with the rest of the Elixir community. #Elixir
optimum.ba
Dripping Elixir knowledge
I started the first draft of this blog post by describing my Elixir journey and how I always felt a good place for sharing bits of Elixir knowledge was missing...
0145
Almir Sarajčić @almirsarajcic.bsky.social · 08/11/2024
Set up: - CI/CD pipeline running in GitHub Actions - staging and production environment on Fly - PR review (preview) apps on Fly using infrastructure generator
elixirdrops.net
Elixir Drops
Generate CI/CD and more for Elixir apps...
010
Almir Sarajčić @almirsarajcic.bsky.social · 07/11/2024
Twitter's better
100
Almir Sarajčić @almirsarajcic.bsky.social · 07/11/2024
Install Erlang, Elixir, PostgreSQL, and Phoenix with one command
elixirdrops.net
Elixir Drops
Install Erlang, Elixir, PostgreSQL, and Phoenix with one command...
000
Almir Sarajčić @almirsarajcic.bsky.social · 07/11/2024
You can easily enable setting a new AppSignal revision every time you commit and deploy your Elixir application.
elixirdrops.net
Elixir Drops
Setting AppSignal revision...
010
Almir Sarajčić @almirsarajcic.bsky.social · 07/11/2024
Here are 3 simple commands to free up your disk space as an Elixir developer. Disclaimer: I’m not suggesting you stop Elixir development. Instead, this will provide you more space to start even more apps 🤠
elixirdrops.net
Elixir Drops
Freeing up storage in a dev machine...
130