EC 2026 Reviewable Code Notes
Session Observations
AI-assisted development failure modes mentioned by session attendees.
Issues seen
- Defensive, redundant checks and unnecessarily complex implementations
- Side effects leaking into the functional core
- Duplicated code or near-duplicate functions instead of reusing existing functions and modules (especially as public functions, not just those private within the functional core)
- Repeated setup and variables within individual tests instead of shared test setup
- Starting implementation before enough context is available
- Losing context as work progresses, exacerbated by token limits that disrupt programming flow
- Missing failure modes such as
nilexceptions, requiring secondary review - Difficulty reasoning about real-time state transitions across elements and users
- Non-idiomatic Elixir, including generally a lack of pipelines
- Nested
caseexpressions and deep indentation instead of clearer constructs such aswith - Inappropriate preference for LiveComponents
- Output that is difficult to trust without close validation
Bad Wordle
For the session we're trying to build a (or multiple) "bad" version of Worlde not by prompting for bad code directly but rather prompting poorly, generally. We won't use usage_rules or tidewave, and we'll be using a lesser model for the work.
We'll work in pull requests to encourage good practice around reviewable (open source especialy) code!
Notes from the first game / before the break
First prompt to Haiku 4.5:
create a wordle game in phoenix liveview?
Bob's skills will be loaded and used (issues with getting Claude Code to not present them!); we'll see how this impacts the "conveyor belt of words" mental model we've discussed. Skills may make this worse, counterintuitively!
A few red/green indicators we'll be looking for:
- functional core/imperative shell
- managing dictionaries
- LiveComponents used?
After the initial game was created and ran, we immediately saw the score disappear as new guesses were made! So we have a few things we'll be looking for e.g.
- Supervision/OTP usage (blast radius for failures)
- GenServer for every game (wrong, because already one under the LiveView!)
- Functional Core/Imperative Shell
- CRC pattern (idiomatic Phoenix)
- Browser elements vs. API elements
We saw:
- Random generator within functional core (Prevents us from testing predicably)
- A six letter word!
- @impl true instead of @impl Phoenix.LiveView (not explicit)
- No keyboard
- Can't see past guesses
- Limited/poor dictionary abstraction
Some breakthroughs to help us so far:
- Better tooling for the agent
- Be defensive, especially good review independent of the current conversation
- Keep some red/green indicators to yourself until review (symptoms rather than problems)
- Throw away, re-prompt! Even for seniors supporting juniors, throw away whole pull requests
- Help them look at e.g. accuracy and portion control
CRC & Functional Core
Two premises from Bruce: "If you build your core with the functional core in mind first (put code there when you can), your agents will be more accurate & you'll spend fewer tokens."
- Even Haiku will be suitable for code generation within the functional core!
- Elixir having bindings instead of mutable variables is part of what makes the language extraordinarily accurate.
- You'll want to generally be doing a different kind of testing, with this approach: property-based testing.
Construct-Reduce-Convert (CRC):
- "Tokenizing Reducer Pattern" is the academic name for CRC!
- Most Elixir functional cores are designed this way.
- pipe operator, first argument as the generic data type for the module
- See: https://grox.io/blog/36-design-for-ai-why-pure-functions-make-better-ai-partners
- Build the simplest business model you understand, which shows the structure of what you want to design, then generalize it.
Teaching & Changes in our Work
Some of the teaching method behind this session, per Bruce:
Anchor
- issues we see
- why is elixir good at this
- will we still have a job, especially with Elixir?
Add
- CRC
- Do Fun Things with Big Loud Worker Bees
- Cost flow in agentic loop
Apply
- the different people driving the session
Away
- breakthroughs
Techniques
- throw away and start over
- focus agent on the area that's breaking (ask questions to teach)
- ask questions based on patterns we know e.g. CRC, FC/IS
- prime with example
Breakthroughs
Generally we agree: do what you can to add determinism to the process of working with agents!
- better tools (e.g. Tidewave, usage_rules)
- SKILLs to guide work and provide domain perspective
- plan!
Misc notes from the session
- LLMs are pattern amplification engines
- Bob's skills & dotifles https://github.com/bnadlerjr/dotfiles/tree/main/claude
- Resources to consider:
Ash (Shawn & Bruce discussion):
- Ash has well-reasoned trapdoors which allow you to look at lower layers, so there's a flexible API where Ash doesn't have to solve everything.
- BUT if you layer on a set of skills that use Ash to solve a problem and you don't HAVE to use ash to solve the problem, you're often coming up with code that "works around" the framework.
- An issue seen is agents using ash functions instead of domain functions; generally the wrong way to do it.