2025 Advent of Agentic Humps: Building a useful O(x)Caml library every day / Dec 2025

Agentic programming has been getting a hilariously bad rap in the OCaml community recently, but it's definitely here to stay despite the security and legal concerns. I realised that to form a useful opinion on all this, I needed to really get into using Claude with OCaml for real outputs and not just toy code. So this holiday month, I'm going to release a new useful OCaml library per day until Christmas using Claude Code: the advent of agentic humps is here!

Read full note... (1594 words)

# 26th Dec 2025agents, ai, aoah, llms, ocaml, oxcaml

AoAH Day 25: Claude OCaml Marketplace for all your festive coding needs / Dec 2025

I'm somewhat frazzled after managing to get through 25 days of agentic coding. It hasn't actually been that much physical work, but I underestimated just how much my brain would be in full gear multitasking across so many terminal windows and ideas. My outbound queue that I didn't manage to write up is enormous: I have sessions running with OxCaml experiments, io_uring webservers, implementations of ATProto, a pure OCaml Parquet, and some even stranger ideas I won't go into now!

In the past, my computer systems brain was limited by the speed of coding, but now it feels like we're entering a different age. I'll reserve my longform thoughts on all of this for the new year as I need to head into Christmas festivities, but I wanted to leave you all with my Claude Code OCaml marketplace in case you want to try this stuff for yourself!

Read full note... (283 words)

# 25th Dec 2025ai, aoah, llms, ocaml, oxcaml

AoAH Day 24: Tuatara, an evolving Atom aggregator that mutates / Dec 2025

My original purpose for starting this AoAH series was to build a feed aggregator for my group website, so I had to finish up with something to show!

I'm not sure if taking the longest way around was wise here but I ended up building tuatara, an aggregator to pull together all my colleagues' writing into one place. They're a quirky bunch with many diverse homegrown feeds in various states of brokenness, so it's difficult to build a one-size-fits-all tool.

So given it's the end of the year and I'm sozzled on Christmas eve on mulled wine, I decided to make Tuatara mutate its own code by linking with my Claudeio library to force it to evolve and modify itself as it runs across feed errors. Every deployment of Tuatara is meant to be slightly different.

Read full note... (1126 words)

# 24th Dec 2025ai, aoah, llms, networks, ocaml, oxcaml

AoAH Day 23: Unpac unifies git branching with package management / Dec 2025

Yesterday's monopam workflow used git submodules to combine vendored packages, but was awkward to use for crosscutting changes involving lots of vendored git repositories. Today I asked what agentic code development would look like if we could unify all code into a single git repository, where upstream packages become branches instead of submodules. I've open-sourced the unpac CLI to explore this, and have begun using it myself.

Coding agents work best when all relevant code is locally available so they can grep and make cross-cutting changes. I first noticed this when building Bonsai terminal UIs and Mosaic, where I had to manually assemble monorepos just to get the agent working. Things come to a crashing halt when package management gets involved; the tool calls for web search are far slower and unreliable. This means that the agent doesn't really have a good view on what third-party packages might be useful to solve a problem, leading to the common complaint that LLMs reinvent the wheel.

To fix this, unpac parses package metadata and materialises it into a git branch structure in a single repository to make vendoring, patching, and updating a native git workflow. Local changes can later be exported into git patches for sending upstream, but in the meanwhile our agents can work on a single repository.

The secret sauce to working on so many branches is to use git worktrees, which allow multiple branches to be checked out simultaneously from one git repo! I'll explain how unpac works next, and you can browse a working unpac tree. You do end up with a lot of git branches, which got me banned from GitHub back when I announced Docker DataKit. Luckily this time around I am hosting on Tangled where I host my own Git remotes and so don't have to worry about third-party SLAs!

All the dependent code is in separate branches in the git repo, managed by unpac
All the dependent code is in separate branches in the git repo, managed by unpac

Read full note... (2271 words)

# 23rd Dec 2025ai, aoah, llms, ocaml, oxcaml

Dear ACM, you're doing AI wrong but you can still get it right / Dec 2025 / DOI

There's outrage in the computer science community over a new feature rolled out by the ACM Digital Library that generates often inaccurate AI summaries. To make things worse, this is hidden behind a 'premier' paywall, so authors without access (for example, having graduated from University) can't even see what is being said.

Read full note... (2046 words)

# 22nd Dec 2025DOI: 10.59350/c84g4-5zt58ai, policy, publishing

AoAH Day 22: Assembling monorepos for agentic OCaml development / Dec 2025

Over the past three weeks, I've accumulated dozens of OCaml repositories as part of this series. Keeping them coordinated has become a real challenge; when I fix something in one library, dependent packages need updating, and agents working on one repo have no visibility into related code. Ideally, I could have all my code in one place and see what agents can do with a lot of local context.

Today I'm switching tacks to address this with a monorepo workflow built around dune's excellent vendoring support. I last visited this when building RWOv2 and its monorepo when I built a duniverse tool that turned into the opam-monorepo plugin that MirageOS now uses. Let's see what happens in today's agentic world instead!

I also wanted to explore the small group dynamic around vibecoding tools. For today's tool, I first asked Mark Elvers to spend a few hours sketching out the sort of tool he might want, and then Jon Ludlam has been using Claude to build up complex odocv3 rules. The way we work together with agentic code is quite different from when we've handcrafted a project, with the code itself now being more throwaway as we pass the baton among each other. I'm lightheartedly calling this 'vibrating' amongst each other to reflect the new speed of agentic iterations, and to differentiate from the more thoughtful process of pair programming. Today's tool monopam helps to manage OCaml monorepos for cross-cutting code and documentation.

Read full note... (1855 words)

# 22nd Dec 2025ai, aoah, llms, ocaml, oxcaml

AoAH Day 21: Complete dynamic HTML5 validation in OCaml and the browser / Dec 2025

With language detection now working in OCaml, I completed vibespiling the Nu HTML Validator from Java to OCaml. This is the official W3C validator used to check HTML5 conformance, and it's a substantial codebase with thousands of validation rules. I set out to see what a few days of agentic processing would do to transform the complex Java codebase into a more functionally structured pure OCaml codebase.

The result is a pure OCaml HTML5 conformance checker that integrates with the parser I built last week, all published as ocaml-html5rw. Having the logic in pure OCaml meant that I could also compile it into standalone JavaScript and WASM. Dynamic conformance checking works even better than server-side filtering since live JavaScript executing on the page (and modifying the DOM) can also be checked. I published this to NPM using a new Claude skill, and coded a live panel overlay to live debug HTML5 issues that I use on my own website now.

Read full note... (1656 words)

# 21st Dec 2025agents, ai, aoah, llms, ocaml, web

AoAH Day 20: Human language detection in native code, JS and wasm / Dec 2025

I took a break from yesterday's bot hacking to continue the HTML5 parsing in OCaml adventure. Vibespiling seems to have taken off, with Simon Willison reporting that there's a Swift version now as well. I got curious about how far I could push the vibespiling support: could we go beyond "just" parsing to also do complete HTML5 validation? The Nu HTML Validator is where I went next, which is a bunch of Java code used by the W3C to apply some seriously complex rules for HTML5 validation.

I decided to split this work into two days, and started with a simple problem: HTML5 validation includes the need for automated language detection to validate that the lang attribute on HTML elements matches the actual content. This is important for accessibility, as screen readers use language hints to select the correct pronunciation.

The W3C validator uses the Cybozu langdetect algorithm, so I vibespiled this into pure OCaml code as ocaml-langdetect. However, I decided to push harder by compiling this to three different backends: native code OCaml, JavaScript via js_of_ocaml and then into modern WebAssembly using wasm_of_ocaml. As a fun twist, I got the regression tests running as interactive "vibesplained" online notebooks that can do language detection in the browser.

Read full note... (1445 words)

# 20th Dec 2025agents, ai, aoah, llms, ocaml, wasm, web

AoAH Day 19: Zulip bot framework to bring Vicuna the friendly camel back / Dec 2025

After building tomlt yesterday for TOML 1.1 parsing, I proceeded to integrate it with my group's Zulip chat server. I then discovered that Zulip actually uses Python's configparser INI format for its .zuliprc files rather than TOML, woops! But this gave me the perfect opportunity to attempt to quickly replicate the tomlt experience with a third config format codec library for Windows-style INI files as well.

So today I released both ocaml-zulip for Zulip API integration and ocaml-init for INI file codecs that are compatible with Pythonic features such as variable interpolation. Along the way, I developed a new regression test mechanism by writing a Zulip bot that tests the Zulip API using OCaml Zulip!

Read full note... (1591 words)

# 19th Dec 2025agents, ai, aoah, functional, llms, ocaml

AoAH Day 18: TOML 1.1 codecs directly from the spec and paper / Dec 2025

After getting my email interfaces automated yesterday, I turned my attention to Zulip integration. But first, I took a segway into another format that it required known as TOML. I noticed TOML 1.1.0 was released today and so I built ocaml-tomlt today.

What I wanted to explore with this library is whether I could use a coding agent to build a complex functional abstraction from scratch. After building yamlrw and yamlt, I settled on the technique Daniel Bünzli developed with jsont in his paper.

Read full note... (1136 words)

# 18th Dec 2025agents, ai, aoah, functional, llms, ocaml

AoAH Day 17: OCaml JMAP to plaster my painful email papercuts / Dec 2025

After building a JSON Pointer library yesterday, I proceeded to complete my OCaml JMAP library today so that I could wrestle my overflowing email inbox under control. Email is central to our digital lives and yet we have mostly ceded control to third-party services for something that unlocks access to almost any service we use.

Luckily, I've been self-hosting my own email for some time, so I do have full local access to about three decades worth of messages. However, I've been hampered by existing email clients which are mostly geared towards a temporal view and not towards easy programmability. So today's exercise has been to build an ocaml-jmap that lets me write little agentic programs to help me manage my ever overflowing inbox!

Read full note... (1707 words)

# 17th Dec 2025agents, ai, aoah, email, llms, ocaml

AoAH Day 16: Vibesplaining JSON Pointers using OCaml/Javascript / Dec 2025

After the successful HTML5 translation yesterday, I realised that I know next to nothing about HTML5 parsing and had leant extremely heavily on agentic coding. This approach has also been useful to help me explore diverse codebases in a combination of languages. So today I set my sights on understanding the pedagogical impacts of agentic coding a bit more. Can we use coding agents to help us iteratively explore complex protocols?

I decided to build a JMAP email client implementation in OCaml that I need for myself but with the added twist of seeing how I could engineer agents to "vibesplain" a protocol to me that I'm unfamiliar with.

OCaml has superb tooling to help with this; it can not only compile to efficient native code but also to JavaScript and WASM that runs standalone in the browser. I turned to my colleagues Jon Ludlam, Patrick Ferris and Arthur Wendling for help with the tooling, since they've been leading the way on scientific programming, visualisations and webcomponents in OCaml.

Today's work resulted in an ocaml-json-pointer (RFC6901) implementation along with an interactive notebook tutorial that bundles the entire OCaml compiler toolchain alongside it. There's even another one for Yaml just to illustrate how easy this is to replicate once we've built the first one.

Read full note... (1573 words)

# 16th Dec 2025agents, ai, aoah, email, llms, ocaml

AoAH Day 15: Porting a complete HTML5 parser and browser test suite / Dec 2025

After my success with Yaml 1.2 in pure OCaml, I found JustHTML, a new Python library for parsing HTML5 by Emil Stenström (via Simon Willison posting about it). Emil wrote JustHTML using coding agents as well, and then Simon ported it to JavaScript in a few hours.

My question, though, is how difficult is to go in the other direction and move towards a strongly typed interface like OCaml's. Could we ultimately distill down the extremely complex set of rules around parsing HTML all the way into a proof assistant like Lean, but hopping via OCaml and Haskell to provide convenient executable pitstops?

Today's task was to vibespile the Python into ocaml-html5rw, a pure OCaml HTML5 parser and serialiser that passes the browser test suite 100%.

Read full note... (1387 words)

# 15th Dec 2025agents, ai, aoah, llms, ocaml, web

AoAH Day 14: Debugging a Karakeep CLI against the live service / Dec 2025

With the Requests library under my belt, I finally got to what I actually need for myself: vibe coding OCaml library interfaces to my #selfhosted services that contain most of my data.

To start with, I use Karakeep across all my devices to bookmark things, and I'd like to be able to programmatically search through tags, for example by taking all outbound links from the blogs that I read and autosynching them with my remote service. Karakeep on the server side does some cool things like screenshot links and create local webarchives.

Unfortunately, Karakeep doesn't publish an OCaml interface. Fortunately, my new bestie Claude helped me build ocaml-karakeep without much input from me!

Read full note... (813 words)

# 14th Dec 2025agents, ai, aoah, llms, ocaml

AoAH Day 13: Heckling an OCaml HTTP client from 50 implementations in 10 languages / Dec 2025

Now I had some prerequisite libraries, I turned my attention to having a batteries-included OCaml HTTP tool with features like request throttling and redirect loop detection. I've hacked on OCaml HTTP protocol libraries since 2011, but these higher level features weren't necessary in things like Docker's VPNKit. The problem with building one now is that there are loads of random quirks needed in real-world HTTP, which would take ages to figure out if I start from scratch.

Luckily, there's an entire ecology of HTTP clients built in other languages that could use for inspiration as well! Today, I gathered fifty open-source HTTP clients from a variety of other language ecosystems, and agentically synthesised a specification across all of them into one OCaml client using Eio.

I'm not sure what the collective verb is for a group of HTTP clients, so dubbed this whole process a 'heckle' of HTTP coding!

Read full note... (2006 words)

# 13th Dec 2025agents, ai, aoah, ecology, llms, ocaml

AoAH Day 12: Eio Connection pooling and event tracing / Dec 2025

After yesterday's library bonanza for HTTP cookie handling, I implemented a TCP/TLS connection pooling library. This is useful for an HTTP client as it provides the network-level mechanisms for keeping track of outgoing network connections by their DNS name. This allows for more flexible outgoing connection management without worrying about overloading remote endpoints.

For example, github.io has four A records:

> host github.io
github.io has address 185.199.110.153
github.io has address 185.199.109.153
github.io has address 185.199.108.153
github.io has address 185.199.111.153

With this new connection pooling library, my application should be able to connect to the github.io name and keep track of all the outgoing connections on the basis of it being called github.io and load balance the number of outgoing connections accordingly.

In the interests of exploring something new, I also decided to add in visualisation support to figure out what the library is spending its time on. I decided to generate self-contained visualisations, inspired by Jon Ludlam rediscovering the joy of SVGs yesterday!

Read full note... (792 words)

# 12th Dec 2025agents, ai, aoah, llms, ocaml

AoAH Day 11: HTTP Cookies and vibing RFCs for breakfast / Dec 2025

I'm switching focus for a few days to build a complete HTTP(S) client to use in my literature downloader. This requires building a few support libraries before we build the full client, so I figured I'd dive in them in the next few days. First up is RFC6264 HTTP Cookie support. There are some excellent existing cookie libraries already on opam, notably http-cookie and ocaml-cookie, but I wasn't sure what their coverage of the protocol is, and there's no Eio serialisation support.

So I thought I'd have a go at a different approach today using agentic coding: can we synthesise a complete HTTP Cookie implementation purely from the RFC 6265 prose itself, and then differentially compare this OCaml implementation against the others? In theory, running a single test suite across all three libraries might be a good way of discovering how to improve the existing implementations. In the long-term, http-cookie is probably the upstream library I want to use, but I don't want to generate a giant diff against it today due to my groundrules of not disturbing other maintainers.

Read full note... (1631 words)

# 10th Dec 2025agents, ai, aoah, llms, ocaml, rfcs

AoAH Day 10: Building a TUI for Sortal using Mosaic / Dec 2025

After building a reasonably complete Sortal contacts manager and trying out OxCaml's Bonsai_term, I thought I'd have a second go at a terminal UI using a newly announced Mosaic library by Thibaut Mattio.

I first noticed this library when Thibaut presented his OCaml coding with AI talk at FunOCaml. It's quite different from Bonsai in that Mosaic uses OCaml's effects to provide a more direct-style API, and so seems worth experimenting with. So today's task is to port Sortal to use Mosaic and see what this terminal UI looks like!

Read full note... (653 words)

# 10th Dec 2025agents, ai, aoah, llms, ocaml

AoAH Day 9: Adding a Bonsai terminal UI to Sortal / Dec 2025

After building a reasonably complete Sortal contacts manager, I decided to try to do a proper job of a terminal user interface. The first option for a modern UI is something that Yaron Minsky announced last week: bonsai_term, which also gives me a chance to dip into the OxCaml ecosystem with my agentic hacking!

Read full note... (1040 words)

# 9th Dec 2025agents, ai, aoah, llms, ocaml, oxcaml

Publish, Review, Curate to upend scholarly publishing / Dec 2025 / DOI

I was not expecting to find a bunch of activist librarians at the lovely spires of King's College Chapel last week, but I was very glad that I did! I gave a talk to the Confederation of Open Access Repositories group that was having a meeting about "Turning scholarly publishing on its head". Luckily, I had my budding Four Ps for Collective Intelligence fresh on my brain, so I discussed it with the assembled librarians. The crowd was a really interesting mix of the open research team at Cambridge, their French equivalents in CNRS, academic researchers like myself and Albert Cardona interested in non-traditional outputs, and of course digital librarians from all over the world.

Read full note... (1562 words)

# 8th Dec 2025DOI: 10.59350/fpc9w-ccj82ai, atproto, networks, opensource, publishing

AoAH Day 8: Building a contacts CLI manager with Sortal / Dec 2025

I've been accumulating a lot of contacts that I use to write cross references on my website. This works by using Cmarkit to parse my custom Markdown, and spot entries like [@sadiqj] and convert those into a full reference like Sadiq Jaffer.

Today, I want to build a full CLI application that stores all my contacts as Yaml files in my home directory using XDG conventions, and give me a simple search interface so I can quickly autocomplete these posts from my editor. I call this little application "Sortal".

Read full note... (915 words)

# 8th Dec 2025agents, ai, aoah, llms, ocaml

AoAH Day 7: Converting between JSON and Yaml with yamlt / Dec 2025

After the excitement of building an entire Yaml 1.2 parser yesterday, I began to put it to use. Since I've been steadily converting all my JSON parsers to use jsont codecs, it would be convenient if a single JSONt codec definition could also convert that schema to Yaml. In theory, Yaml is a superset of JSON, except it isn't actually. But it's close enough that we should be able to build a yamlt library that can accept a jsont codec and spit out Yaml (or the reverse).

Read full note... (706 words)

# 7th Dec 2025agents, ai, aoah, llms, ocaml

AoAH Day 6: Getting a Yaml 1.2 implementation in pure OCaml / Dec 2025

I did the palate cleanser of Bytesrw-eio yesterday for a good reason. Back in 2017, I wrote the OCaml Yaml bindings that a lot of projects use in the OCaml ecosystem, and I'm having trouble maintaining it.

Since Yaml is an monstrously convoluted spec, I opted back then to bind to the C libyaml using ocaml-ctypes. This was a good decision a decade ago, but maintaining this has been a nightmare due to the complexity of vendoring the C library, dealing with security issues there, and exposing a reasonable OCaml interface. The ocaml-yaml implementation also doesn't pass the full Yaml test suite.

And the worst thing is, I cannot find the motivation to figure out how Yaml really works. It's the world's worst serialisation format, with lots of corner cases and memory blowups inherent in how it works. So I decided to dive in and see if I could build a pure OCaml Yaml 1.2 implementation using bytesrw and the source spec.

TL;DR: it worked. It actually seems to have come up with a reasonable, pure OCaml implementation that I'm now using! It needs more validation and external code review, but this has been on my TODO list for years now.

Read full note... (897 words)

# 6th Dec 2025agents, ai, aoah, llms, ocaml, opam

AoAH Day 5: Bytesrw Eio adapters and automating opam metadata / Dec 2025

After the Claude exertions of yesterday, I needed something easier to cool my laptop down. I wanted to learn how to use another new library from Daniel Bünzli called Bytesrw, which provides composable byte stream readers and writers. It supplies ways to serialise Bytesrw to Unix file descriptors, so I figured I'd add in an Eio library for this. Along the way though, I was generating a growing number of opam packages, so I also learnt how to use Claude Skills to automate my opam metadata on Tangled as well.

Read full note... (941 words)

# 5th Dec 2025agents, ai, aoah, llms, ocaml, opam

AoAH Day 4: Going recursive with Claudeio for Claude / Dec 2025

By this point, I've got three useful libraries and my use of Claude is getting better. So naturally I want to automate my invocations of the claude CLI, but I hit a roadblock: there are no OCaml SDK bindings! However, there appear to be SDKs in Python, Go and many others. So today will involve having a stab at generating Claude OCaml bindings using Eio, so I can use Claude to write more OCaml!

Read full note... (745 words)

# 4th Dec 2025agents, ai, aoah, llms, ocaml
Loading recent items...