I'm a staff engineer at @userledio, based in the UK, where I lead AI initiatives across the product. I'm passionate about infrastructure, developer experience, system design and agentic technologies, and about building tools and systems that make engineering more sustainable, safe and fun. In my spare time, I'm building Hash, a programming language and tooling ecosystem.
-
🧭 Zenith: an experimental architecture linter for TypeScript and JavaScript monorepos, written in
. It enforces rules about which parts of a codebase may import which, such as layers and forbidden dependencies. Work in progress.
-
Graphika: a toy graphing library written in pure , as an alternative to
Chart.jsand other charting libraries. -
Durachok: an online game for playing Durak, a popular Russian card game. Built with
+
, including some cool libraries:
@tanstack/router,@tanstack/react-query,socket.io. -
Bracketlint: a simple HTML/Django template linter that checks brackets are correctly matched, written in
.
-
teamsearch: a
CODEOWNERS-aware code search tool, written in.
I lead developer experience at @userledio, and I build tools on the side to make engineering faster and safer:
- Zenith: an architecture linter that enforces import boundaries in TypeScript and JavaScript monorepos (work in progress)
- prbot: a Slack and Discord bot that reacts to GitHub PR links with emoji showing each PR's live status
- teamsearch: a
CODEOWNERS-aware code search tool - bracketlint: an HTML/Django template linter that checks brackets are correctly matched
- Agentic AI: LLM agents, tool calling, evals and MCP servers (Mastra, Vercel AI SDK)
- Retrieval: embeddings, vector search and RAG pipelines
- Infrastructure as code: Terraform, CI/CD design and cloud-native patterns
🔒 PGP Public Key
-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEZp1C6BYJKwYBBAHaRw8BAQdAbmZl2T8wr8K+FtvXsGgD3+bOBxJf99twYgie
9js1JKa0MkFsZXhhbmRlciBGZWRvdG92IDxhbGV4YW5kZXIuZmVkb3Rvdi51a0Bn
bWFpbC5jb20+iJMEExYKADsWIQSsi4t4Az9AkaW7dFKtGxvm5K2JQAUCZp1C6AIb
AwULCQgHAgIiAgYVCgkICwIEFgIDAQIeBwIXgAAKCRCtGxvm5K2JQDZVAP94bpZC
ffX2e64qqvOyP50GqMWPE0iK5s6Ka8D9P9KqhgEAlJIVCSSX9yEhplx0zfy4sqcX
meu1H6WSE5MWpQXZ2gi4OARmnULoEgorBgEEAZdVAQUBAQdAjA60vQ4kEdaz5s/c
8UQ2qnXQjLdpwahRQKCT7t2McBoDAQgHiHgEGBYKACAWIQSsi4t4Az9AkaW7dFKt
Gxvm5K2JQAUCZp1C6AIbDAAKCRCtGxvm5K2JQDymAPwOS5+7n4I3sL2XK9mj4JT5
HkhIjEj145OpvhXIDk+YwgD8CV4LjAlioR6U930Alf9XZw1nKDLLhUoPB3vD9VT5
RQc=
=rbOz
-----END PGP PUBLIC KEY BLOCK-----





