Sulaiman Dauda

I build production software with AI agents, and I measure whether it actually works.

Customer-facing AI whose rules are enforced in code rather than in a prompt, MCP servers that propose changes for a person to approve, and evals that run in CI. Underneath that, API integrations and self-hosted infrastructure in Go.

Nine years shipping to production, an MSc in Applied Data Science, and a habit of not believing a change works until something has measured it.

Essex, EnglandOpen to senior and lead engineering roles

AI in production

Built with agents, held to the same standard

Most of my code is now written with Claude Code and Codex. That makes code cheap to write, not cheap to be wrong, so the work is in what surrounds the model. That means rules it cannot break, approvals it cannot skip, and checks that say whether it was right.

A customer assistant that cannot be talked into a price

ElixirPhoenixPostgreSQLpgvectorLive

I replaced LiveChat at Sportsafe UK with an in-house live chat and AI support assistant. It has answered customers on its own since August 2026 and hands over as soon as someone asks for a person. Retrieval is PostgreSQL full-text search with pgvector, so there is no separate search service.

The rule that matters is enforced in code. The assistant never states a price, stock level, lead time or delivery date from its own knowledge. That check runs before the model is called, so no prompt can argue it out of the rule. The scope guard's vocabulary came from ten years of real customer chats, 11,606 conversations, measured both ways, for what it would wrongly refuse as well as what it catches. The AI agent it replaced got 4 of its 14 refusals wrong, and that was the bar.

An eval suite runs in CI. Its judge model sees the facts the assistant was entitled to use but not the rules that shaped the reply, and it was checked in both directions before its scores were trusted, scoring 5 out of 5 for a known-good reply and 1 out of 5 for a known-bad one. It is also my first Elixir project.

An MCP server that proposes and never commits

TypeScriptNext.jsPostgreSQLMCPLive

I built the product and supplier-pricing system behind the shop, covering 4,268 products and kept in sync with WooCommerce, then added an MCP server so Claude can work with the catalogue directly. Its five tools search products, read one in full, list what is waiting for review, summarise the catalogue and propose changes.

The write tool cannot write. Every change it is given, whether a cost, a price, a stock level or a status, becomes a draft that waits in the system's own review screens for a person to approve. The model does the tedious part, such as finding every product with no supplier cost, and a person still owns the decision that reaches a trading shop.

A business platform built by a governed team of agents

GoPostgreSQLReactTypeScriptIn progress

I am designing an operations platform that covers quoting, field service with an offline engineer app, purchasing, a double-entry ledger with VAT, HR and marketing email. It is one Go application on one PostgreSQL database with a React front end, so every piece of data has exactly one owner. Before any business code there was a register of 101 problems it has to solve, 29 architecture decision records, and an architecture map that CI enforces with 23 fitness rules.

It is built by agents I direct, with a principal-engineer agent as technical lead and specialist agents for backend, frontend, QA, data and operations, each with its own model and brief. Review is in proportion to risk. Anything touching money, VAT, permissions, security or a database migration gets a design review before it is built, then QA, a code review and a fresh verifier, and only I can merge it. The agents run under a separate account with no keys or secrets, and records from the most sensitive customer accounts are filtered out before any data reaches an AI tool. The foundations phase merged 49 pull requests in its first eight days.

One working setup for Claude Code and Codex

BashPowerShellGitClaude CodeCodex

2,241 of my 2,937 commits across 44 repositories carry a Claude co-author line, and that undercounts, because Codex adds none. Work at that volume needs the discipline of a team, so I built the setup both agents run inside and keep it in version control, with 1,000 commits since July 2026.

Both CLIs load the same written standards, the same six skills I wrote (about 2,100 lines, from Cloudflare deploys to WordPress builds), the same per-project memory and a shared worklog, so either one picks up where the other stopped. Every sync ends in a secret scan that blocks the commit if anything resembling a key is in the repository, and the settings deny the commands that would make a repository or gist public. A review by a second model found two ways the sync could lose data, and both are fixed. The first test I wrote for one of them passed on the broken code, so I ran old and new against the same fixture until the old one actually failed.

Choosing a model gets measured too. I scored Claude Code running on Z.ai's GLM models across five tasks, three attempts each, with every check proven to fail before it was trusted. GLM-5.3-Flash passed all 15 attempts for $0.09. The free GLM-4.7-Flash passed 3 of 5 tasks and produced a false pass that sent me back to fix the check. I still keep employer and client code off it, because the provider's parent company is on the US Entity List and where inference actually runs could not be confirmed.

Open source

What I'm building

Four projects, all self-hosted, all running code rather than prototypes. Each one ships with its own documentation, security model and CI.

Slipstream

GoAGPL-3.0nginxPHP-FPMMariaDB

A hosting control panel that treats slow as broken. Sites arrive cached, tuned and isolated, and a deployment that measurably slows a site is refused rather than shipped. It runs as two processes, an unprivileged API and a root agent, talking over a typed RPC on a Unix socket. Released binaries carry signed build provenance, because the installer runs as root.

Gresbase

GoMITPostgreSQL

A backend platform in a single binary, with collections, auth, realtime and file storage, and PostgreSQL as the only infrastructure. Collections are locked when you create them, and access rules are checked on every read path including file downloads and realtime delivery. A rule enforced on four paths out of five is not enforced.

Windlass

GoApache-2.0DockerCaddy

A Docker Compose control plane that wraps the real docker compose instead of replacing it. The project filesystem stays authoritative, so editing compose.yaml by hand keeps working. Your containers keep running if Windlass stops or is removed, and a lint rule enforces the privilege boundary at build time rather than in review.

Tidetime

TypeScriptNext.jsMITPostgreSQL

Self-hosted appointment scheduling with services, providers, booking pages, calendar conflict checks and email. Authentication is written rather than imported, with revocable session rows, scrypt password hashing in application code, and TOTP to RFC 6238.

Evidence

Measured, on the same box, one at a time

Slipstream benchmarked against CloudPanel on the same physical server, with the OS reinstalled between runs and both panels tuned to their best. The trap in any comparison like this is hardware. Two supposedly identical servers of the same spec measured 2.5 times apart for me on the same fixed workload. Measured on 3 September 2026, Slipstream v0.2.0 against CloudPanel CE 2.5.4.

MetricSlipstreamCloudPanel
Cached throughput, 500 connections9,280 req/s2,259 req/s
p99 at that load85.5 ms, 1 timed out385.9 ms, 319 timed out
2,000-connection flood8,018 req/s, 0 errors455 req/s, 1,619 timeouts
Install, bare server to running panel105 s460 s
Uncacheable WooCommerce shop listing5.48 req/s10.75 req/s

The last row is the one Slipstream loses, by 2 times on the same machine and 4 times when the load comes over a network, and it stays on the page. The cause is measured rather than guessed. Every site runs inside an open_basedir jail, which cost 72 ms of a 301 ms render when I removed it and put it back. CloudPanel sets no open_basedir and isolates tenants by Unix user alone. A panel that is faster on uncached renders and lets one compromised site read another's files is not a trade worth making, so the jail stays. Full method.

Commercial work

What it did for a business

Leading technical delivery on sportsafeuk.com, a national B2B supplier selling sports, PE, gym and playground equipment to schools, clubs and councils. It is live and trading, so the work is open to inspection rather than described.

£3,000a yearin subscriptions for 11 paid tools, replaced by code the business owns, at list price
134of 134web orders checked reaching the CRM through the in-house service that replaced Zapier
288mstime to first byte on a cache miss, down from 983 ms; 110 to 160 ms on a hit

Eleven paid tools became software the business owns. LiveChat and its AI agent gave way to the in-house live chat and assistant, and Zapier to an in-house integration service that connects the shop, forms, chat and booking to SugarCRM and Sugar Market through their APIs, both self-hosted on Windlass, my open-source deploy panel, alongside an in-house quoting tool, the product and supplier-pricing system, and call booking on Tidetime, my open-source scheduler. On the shop, our own code replaced the Pro plugins for product add-ons, table-rate shipping, discount rules, cookie consent, page caching, analytics, permalinks, admin enhancements and user roles.

Before anyone acts on a number, I check where it came from. GA4, Tag Manager and Google Ads conversion tracking are audited against the order database through their APIs, with Google Ads API access granted after Google reviewed the design, and the store's own reporting reconciles with the orders to the penny in every month. The speed came from resizing and retuning the page cache in front of the shop.

Client work

Small local businesses, and usually the whole of it, meaning the site, the analytics behind it, and the Google Ads account that feeds it. The ads work runs through Perch Solution, my own Google Ads manager account, so search terms, negative keywords, ad schedules and conversion tracking sit in one place and get audited rather than left to drift.

Home care, Canada

novuslifecare.ca

Built on a custom WordPress theme rather than a page builder, which is why the home page is twelve requests and ready in 166 ms. Block editor for content, so the client edits pages without touching the layout.

Product

Sticky Tasks, on the Microsoft Store

A Windows desktop app written in C#. It gives you sticky notes with real checkboxes rather than fake bullets, and deliberately nothing else. It passed Microsoft Store certification in April 2026. Across April, May and June it took 321 installs from 498 listing views, with no launch post, landing page or advertising behind it. About two thirds of the people who open the listing install it, and it is the only figure on this site that somebody else measured for me. Store listing.

Method

How I work

Put the rule where the model cannot argue with it

An instruction in a prompt is weighed against everything else the model reads, including a persuasive customer. The chat assistant's ban on quoting prices runs in code before the model is called, and an agent's ban on making a repository public is a deny rule in its settings, not a sentence in its instructions.

Verify on the wire, not in the file

A directive present in a config is not a directive in effect. I have shipped nginx security headers that were silently dropped by inheritance rules, and a capability probe that read stdout for a tool that writes to stderr. Both looked correct in review and were wrong in production.

Change one variable at a time

Copying someone else's tuning is a hypothesis, not an improvement. Kernel TLS is standard advice and cost 28% of cached throughput on a page-cache workload, so it is not shipped.

Say what did not work

Flattening the release docroot gained about 8% on uncacheable renders and was declined, because the risk to the rollback model was not worth it. Experiments that failed get published with their numbers, next to the ones that worked.