Bruce Thomas - Professional Corpus

Top Level Objective

Senior Engineer and AI advocate for product evolution

I am looking to join a company where my role leverages my experience in developer relations, and full stack javascript experience, on front-end and backend development. The role will focus on mentoring junior engineers in the modern phase of AI assisted workflows, migrate legacy systems to AI assisted systems, create learning resources (docs, tutorials, videos etc) and leverage my BAU work experience in evolving products to increase revenue, improve performance and decoupling for scalability.


Work Experience (Resume)

lifedrawing.art — Applied AI & Automation Lab

Description: A non-profit life drawing community serving as a production environment to validate applied AI architectures, N8N orchestration, and zero-trust networking.

Date: 2010-01-07

Tags: resumeRole

lifedrawing.art

Applied AI & Automation LabFounded 2024 · Hackney, London
Non-profit weekly life drawing community

lifedrawing.art

overview

In 2024, I founded a non-profit life drawing community in London. While the public face is a traditional arts organisation, internally it operates as a rigorous production laboratory for applied AI, system automation, and decoupled architecture.

The community has real operational demands: ticketing, payment processing, marketing orchestration, and customer support. It is not a theoretical sandbox — it runs in production, has a paying user base, and system failures have immediate consequences.

This environment provides a commercial-risk-free proving ground to validate AI-first engineering patterns, migrate legacy workflows to automated pipelines, and test edge infrastructure under real-world loads.

architectural strategy

The platform is designed around strict service decoupling. Rather than relying on monolithic platforms or heavy CMS installations, the architecture wires together purpose-built services via clean APIs and orchestration layers. This creates natural system boundaries, allowing individual components or AI models to be swapped or upgraded without cascading risk.

infrastructure & orchestration

AI & automation (N8N)

Self-hosted infrastructure & zero-trust networking

Edge delivery & headless services

Operational data layer

applied engineering outcomes

Operating this stack in production validates theoretical AI patterns against actual operational friction. Key technical learnings include:

The project successfully demonstrates how modern AI orchestration, edge compute, and zero-trust networking can allow a single engineer to reliably operate infrastructure that previously required a dedicated team.

← back to resume


Early Career — London & South Africa

Description: Limited company founder, Head of Studio at a DTP newspaper company, and Internet division lead at a printing company in South Africa.

Date: 2010-01-06

Tags: resumeRole

early career

Founder · Studio Lead · Internet Division HeadLondon & South Africa

overview

Before moving into contract freelancing, I built a commercial career that spanned three distinct roles — each one formative in a different way. Together they gave me grounding in business operations, print production, typography and the earliest commercial applications of the web.

limited company — london

Founded and ran a limited company in London with a team of six. Responsibilities spanned business development, client management, production oversight and studio delivery. Running a small company is a crash course in every discipline simultaneously — sales, operations, people management, cashflow and creative quality all compete for the same bandwidth.

This was the period when the web was transitioning from a curiosity to a commercial channel, and the company evolved with it.

head of studio — newspaper dtp

Headed the production studio for a small newspaper DTP company. Responsible for the end-to-end production of print publications — from layout and typography through to pre-press output.

This role built a deep understanding of visual hierarchy, layout discipline and the constraints of production at speed — skills that directly inform my eye for UI/UX detail today. My MA in Graphic Design was earned during this period.

internet division — printing company, south africa

Led the Internet division of a printing company in South Africa, building out their digital offering in the early commercial web era. This was genuine frontier territory — the tools, standards and infrastructure were rudimentary, and most of what was needed had to be figured out from first principles.

It was here that I developed the habit of enjoying problems that can't be solved with a Google search.

the thread through all three

Print, publishing and early web share a set of disciplines that transfer directly into modern frontend engineering: typography, visual hierarchy, production at deadline, and communicating clearly with clients about technical constraints. That background is why I have always been as comfortable in design conversations as in engineering ones.

← back to resume


Independent Consulting — 20 Years Commercial Contracting

Description: Two decades as a commercial software consultant in London and Barcelona, delivering enterprise platforms and digital experiences for global brands.

Date: 2010-01-05

Tags: resumeRole

independent consulting

Senior Software Consultant**~20 years** · London & Barcelona
Remote, on-site and hybrid contracts

overview

Before transitioning into permanent senior engineering roles, I spent two decades as an independent software consultant across London and Barcelona. Operating concurrently across diverse production environments — from fast-moving digital agencies to heavily gated enterprise delivery teams — provided a broad foundation in software architecture and delivery.

Consulting requires rapid adaptation. You learn to parse unfamiliar codebases in days, translate technical tradeoffs into business impact for stakeholders, and maintain strict standards for code quality under immovable deadlines. This background serves as the bedrock for my current focus on applied AI, automation, and developer experience.

agencies

Contracts included engagements at:

brands

Work delivered for household brands including:

what independent consulting taught me

Two decades of consulting across dozens of tech stacks ensures I am rarely fazed by legacy systems or architectural debt. I am accustomed to dropping into complex, high-stakes environments and becoming productive immediately. I have navigated every type of engineering culture, from chaotic startups to strict enterprise release cycles, giving me a pragmatic understanding of when to push for perfect architecture and when to ship.

Managing hybrid, cross-border engagements long before remote-first was an industry standard also forged a strong discipline in asynchronous communication and autonomous delivery.

← back to resume


NetSupport — Frontend Engineer, EdTech

Description: R&D of a real-time screen-sharing Chrome extension for a bespoke remote education platform, using native ES6, WebSocket signalling and WebRTC video streaming on ChromeOS.

Date: 2010-01-04

Tags: resumeRole

netsupport

Frontend Engineer — EdTechJuly 2019 · Contract
ChromeOS platform

netsupportsoftware.com

overview

Contracted to research and prototype a real-time screen-sharing feature for NetSupport's bespoke remote education platform. The deliverable was a Chrome extension that provided a pseudo-RDP (Remote Desktop Protocol) experience for classroom management on ChromeOS devices.

The project was a focused R&D engagement: assess what was achievable within the Chrome Extension API constraints, design the signalling architecture, and produce a working proof-of-concept.

what i did

Chrome Extension architecture

Designed and implemented a Chrome Extension using native ES6 JavaScript, without external frameworks. The extension leveraged the Chrome OS Extension API to capture screen state and stream it in real time — respecting the sandboxed permissions model of the platform.

WebRTC video streaming

Used WebRTC as the video transport layer, establishing peer connections between the teacher console and student devices. Handled ICE candidate negotiation, stream initialisation, and graceful connection teardown within the constraints of the ChromeOS environment.

WebSocket signalling

Built a WebSocket signalling layer to coordinate peer discovery and connection setup between devices on the same network. Designed the message protocol to be minimal, fast, and recoverable on dropped connections.

Research and documentation

Produced technical documentation covering the architecture decisions, limitations of the Chrome Extension API at the time, and a recommended path forward for the production build.

skills

← back to resume


Ably Realtime — Senior Software Engineer

Description: Software engineering on Ably's corporate platform — migrating a legacy Ruby on Rails codebase to React and Tailwind during a full corporate rebrand.

Date: 2010-01-03

Tags: resumeRole

ably realtime

Senior Software EngineerApril 2021 – November 2021 · Remote

ably.com

overview

Joined Ably as a senior engineer on the web platform team. The core mandate was ambitious: systematically dismantle a legacy Ruby on Rails view layer, replacing it with a modern React and Tailwind CSS architecture, all while executing a live corporate rebrand.

The engineering culture was rigorous, operating on a default-to-pairing basis. Every pull request required peer review, and comprehensive test coverage was a non-negotiable baseline for merging.

This role established the engineering context for my subsequent lateral move into the Developer Relations team as a Developer Education Engineer.

what i did

React and Tailwind migration

Refactored legacy ERB/Rails view templates into modular React components styled with Tailwind CSS. This was a concurrent rebrand and rewrite — requiring close coordination with the design team to implement evolving requirements without compromising the architectural integrity of the new component library.

Documentation platform

Contributed significantly to the developer documentation platform, built on Nanoc and Textile. Focused on the build pipeline architecture, introducing optimisations that improved build times and enhanced the developer experience for the content team.

CMS integrations

Maintained the engineering blog (Ghost) and managed structured marketing content through a Gatsby-based CMS backed by Contentful, ensuring content delivery remained fast and decoupled from the main monolithic application.

Engineering culture

Practised daily paired programming, which served as a forcing function for codebase consistency and rapid knowledge transfer. This collaborative approach significantly reduced onboarding friction for new engineers.

skills

← back to resume


Ably Realtime — Developer Education Engineer

Description: Lateral transfer from engineering to Developer Relations — building JavaScript prototypes as technical content and advocating for real-time edge architecture.

Date: 2010-01-02

Tags: resumeRole

ably realtime

Developer Education EngineerNovember 2021 – December 2022 · Remote

ably.com

overview

After seven months as a frontend engineer on the core website team, I made a lateral move into Developer Relations. I wanted to apply my engineering background to technical education, translating Ably's complex real-time messaging platform into clear, actionable resources for other developers.

The focus was on developer experience (DX) and education — explaining technical concepts, building working JavaScript prototypes, and advocating for JAMstack and WebSocket architectures through high-quality technical content.

what i did

Code as technical content

Engineered prototype JavaScript apps as the primary artefact for developer education. Each demo was a working application demonstrating a specific Ably feature — WebSockets, presence, history, channels, pub/sub — written cleanly enough to serve as the reference implementation for the accompanying documentation.

Developer advocacy and tutorials

Authored developer-facing engineering tutorials anchored to the prototypes. I focused on integrating real-time infrastructure with modern web architectures, including Netlify Functions, Netlify Identity, Netlify Edge Functions, and various static site generators.

Technical concept explanation

Produced technical explainer content to demystify real-time protocols. I authored and presented comprehensive guides on the WebSocket protocol, publish/subscribe messaging patterns, and serverless edge integrations, establishing a standard for Ably's educational materials.

Internal enablement

Codified the technical content production process in internal documentation, ensuring other engineers could reliably produce high-quality tutorials and demonstrations without friction.

published articles

technical presentations

Publish & Subscribe with JavaScript and Ably — An explainer of the pub/sub concept followed by a narrated code demonstration building a simple app with the Ably SDK.

The WebSocket Handbook by Ably — A walkthrough of the Ably WebSocket handbook, covering the protocol, use cases, and how Ably builds on top of it.

Building a realtime quiz app with AWS & Ably — A full tutorial walking through building a realtime quiz application using AWS services and the Ably platform.

skills

← back to resume


News Corporation — Senior Software Engineer

Description: Re-architecture of legacy video advertising systems across The Times, TalkSPORT and The Sun, delivering major revenue uplifts and setting the standard for AI engineering practice internally.

Date: 2010-01-01

Tags: resumeRole

news corporation

Senior Software EngineerJune 2023 – present · London
The Times, TalkSPORT, The Sun (all News UK titles)

newscorp.com

overview

Joined News UK to work on the shared ad-library serving all brands — The Times, TalkSPORT, The Sun and others. The core role is maintaining and evolving the JavaScript ad-delivery product embedded across mobile and desktop web, responsible for all programmatic and direct advertising revenue.

In addition to the engineering work, I established myself as a principal voice in the internal AI community, leading the adoption of LLM workflow orchestration, agent harnesses, and repository context management.

noteworthy achievements

llm workflow orchestration & agent harnesses

Active member and presenter in the News UK internal AI community, focusing on applied AI engineering rather than theoretical concepts. Contributions include:

skills

← back to resume


Features & Technical Writing

Audiobook markdown renderer

Date: 2021-04-13

A Ruby experiment that renders MP3 audiobooks from markdown articles using Google Speech API and Wavenet voices. Web Components power the story selection interface.


Improve UI with chrome extensions

Date: 2021-04-13

Use the Chrome extension API to inject a modern UI layer over any legacy ASCII interface — a lightweight approach to enhancing user experience without touching the underlying source.


Infinite procedural landscape

Date: 2021-04-13

Perlin noise terrain wrapped in both axes with dynamically injected artifacts, giving an infinite impression. Built in PHP and connected to the Instagram API for live content.


Lifedrawing with SVG on WebSockets

Date: 2020-10-23

An ultra-minimal UI that streams huge SVG images over WebSockets — the sketch recreates in real time, line by line, with zero wait. Node.js server hosted on Heroku.


The Lorenz attractor in Blender

Date: 2021-04-13

Using Blender's Python console to trace chaos algorithms as 3D splines, then converting each spline into a smooth geometry mesh. Pure maths, rendered physical.


Netlify Identity protects Ably apps from hackers

Date: 2026-08-31

How to use Netlify Identity and serverless functions to issue Ably JWT tokens to verified users only — keeping your Ably API key hidden and bad actors locked out.


Painless paralax page elements

Date: 2021-07-17

A pure CSS parallax effect with minimal scaffolding and zero JavaScript — demonstrated live on CodePen. Simple to drop into any lightweight static site.


Raspberry spy: a camera controller

Date: 2020-10-23

BASH remote control for the Raspberry Pi Zero camera — JavaScript WebSocket UI with configurable settings and Sunrise/Sunset synchronisation for automated timelapse photography.


Replace WhatsApp with AI Chat

Description: Public WhatsApp groups attract spam and bad actors. I replaced ours with an n8n pipeline and a siloed AI chatbot — zero moderation, automatic email escalation when confidence drops.

Date: 2026-08-31

We had a WhatsApp group for lifedrawing.art. It was supposed to be for attendees to ask questions — is the session on this week, what should I bring, where exactly is the venue. Instead it became a part-time moderation job. Spam. Soliciting messages. Promotional posts from people who had never attended. The group number was public-facing and it attracted exactly the people you'd expect.

The moderation overhead was real and it was mine. I killed the group and built a replacement.

What "replacement" actually means

A WhatsApp group isn't one thing. It's:

  1. A Q&A channel — people asking predictable questions with knowable answers
  2. A notification channel — session reminders, cancellations, venue changes
  3. A community space — social chat between attendees

I was only solving problem 1. Questions like "do I need to bring my own easel?" or "is there a session on Bank Holiday Monday?" have definitive answers. They don't need a human. They need a retrieval system with access to the right content.

Problems 2 and 3 I solved differently — email newsletters via Mailchimp for notifications, a Slack workspace for community. Neither involves a public-facing phone number.

The n8n pipeline

n8n is a self-hosted workflow automation tool — think Zapier but open source, running on your own infrastructure, with proper code nodes when you need them. I run it on a VPS via a Cloudflare Tunnel so it's accessible without exposing the host.

The chatbot pipeline: Trigger → Classification → Retrieval → Generation → Confidence check → Response or Escalation

Trigger

A webhook. I publish a simple web form on the lifedrawing.art site — a text input, a submit button. The form posts to the n8n webhook endpoint. No phone number. No WhatsApp. Anyone with questions uses the form.

Classification

The first AI step classifies the question into one of five categories: booking, venue, what-to-bring, model-info, other. I use Claude Haiku — it's a routing task, cheap and fast. The category determines which knowledge source gets retrieved next.

Retrieval

Each category has a corresponding text file — hand-written, kept in a GitHub repo, updated when anything changes. Booking questions get the booking FAQ. Venue questions get the address, transport links, parking info. No vector database. No embeddings. Just the right file for the right question.

This is a deliberate simplification. The knowledge base is small and stable. Full RAG infrastructure would be engineering for its own sake.

Generation

Claude Sonnet takes the retrieved content and the original question and generates a conversational response. The system prompt is explicit: answer only from the provided content, do not speculate, do not invent details. If the content doesn't contain the answer, say so.

The prompt also includes the current date and session schedule — injected by n8n from a Google Sheet I update weekly. Sonnet can answer "is there a session this Thursday?" correctly because it has the actual schedule.

Confidence check

Before sending the response, a second AI call (Haiku) evaluates the generated answer against the retrieved content: does this response accurately reflect the source material? It returns a confidence score and a flag: CONFIDENT or UNCERTAIN.

UNCERTAIN triggers escalation.

Escalation

When confidence is low, the pipeline doesn't send the generated response. It sends me an email with the original question, the generated response, the confidence flag and reasoning, and a reply link. I reply manually. The failure mode is a human — not a confident hallucination.

What I got wrong first

My initial retrieval step returned the entire FAQ document regardless of category, so the generation step had a lot of irrelevant material to ignore. Sonnet handled it fine but response latency was worse and answers were occasionally unfocused.

Splitting by category and returning only the relevant section cut context to roughly 400 tokens. Response time dropped noticeably. Answers got more precise.

Results, six months in

The system handles 40–60 questions per month. Not high volume, but every one of those would have been a notification on my personal phone, often at 11pm.

The surprising lesson

Building this forced me to write a proper FAQ. Not a vague "here's some info" page but a structured document with explicit questions and explicit answers. That document is now more useful than the chatbot — it's directly searchable on the site and it's what the AI answers from.

The AI didn't replace the knowledge. It made having well-organised knowledge more worthwhile.


The n8n pipeline runs on a £6/month VPS behind a Cloudflare Tunnel. Total infrastructure cost: under £10/month.


Desktop shredder for i3 lockscreen

Date: 2020-10-23

i3 is my preferred window manager — a lock screen that uses OpenCV and numpy to slice the desktop into animated strips. Developed with iPython, aka Jupyter notebook.


TacTicToe on a 3D Rubik Cube

Date: 2021-04-13

Tic-tac-toe with a twist — a multilayer tactical game where players rotate the 3D matrix using Rubik's cube strategy. Built with BabylonJS, React, Redux and ES6.


The .bashrc for AI: Agent-Agnostic Repositories

Description: Engineers have preferred tools, how can we ensure these different AI systems share the most important context? A unified harness built on the AGENT.md convention.

Date: 2026-10-03

TL;DR: Engineers all have their preferred AI tools—some swear by Cursor, others use Claude Code, Copilot, or Aider. How can we design a repository so that no matter which tool a developer brings to the codebase, they all share the same critical context, guardrails, and custom capabilities? The answer is the "AI-Readable Repository" built on the AGENT.md convention and the Model Context Protocol (MCP).

If you're building software in 2026, you aren't just writing code anymore. You're an engineering manager for a diverse, highly capable, but easily confused team of AI agents.

In my project, lifedrawing.art, I recently realized I was suffering from severe AI Tool Fatigue. I had GitHub Copilot acting as my junior dev in the IDE, Claude Code running CLI refactors, and Google Antigravity (AGY) orchestrating complex, multi-agent database migrations.

The problem? Configuration sprawl.

Configuration Sprawl vs. Unified Harness

My repo was littered with .cursorrules, .github/copilot-instructions.md, .claude/settings.local.json, and .agents/SYSTEM_DIRECTIVE_GLOBAL.md. Every time my architectural standards changed, I had to update four different rule files.

Here is how I am redesigning my repository to have a single, unified "AI Harness" that any tool—Claude, Aider, Cursor, or AGY—can plug into and share the exact same brain.


The Mental Model: .airc (The .bashrc for AI)

Just like .bashrc or .zshrc sets up your environment variables, aliases, and $PATH regardless of whether you open iTerm, VS Code's terminal, or SSH into a server—you need an initialization file that configures the AI's "environment" regardless of which LLM or IDE is booting up.

Let's call this the .airc (AI Run Control) file. Here is how that analogy maps perfectly to building a unified harness:

  1. export PATH=... (Shared Tools): In .bashrc, you tell the shell where your tools live. In .airc, you define your MCP (Model Context Protocol) servers, telling the AI: "Here is your PATH to my custom tools. If you need to search the database, the executable is at this local port."
  2. source ~/.aliases (Shared Rules): In .bashrc, you source external files to keep things clean. In .airc, you source your context, essentially telling the AI: "Read .ai/guardrails.md for security rules, and .ai/architecture.md for our tech stack conventions."
  3. The MOTD (Shared State): When you open a terminal, it might print the current system load. Your .airc does the same: "You are working on lifedrawing.art. Fetch the current open task from the MCP state server before proceeding."

Because there isn't a POSIX standard for AI yet, every tool still looks for its own specific boot file. So how do we actually connect them?


1. The False Peak: Why Symlinking Isn't the Answer

When you first try to solve this DRY (Don't Repeat Yourself) problem, your engineer brain will immediately suggest lateral thinking: Symlinks.

Why not just write your rules in a master file, and then hard-symlink it to the proprietary tools?
ln -s .ai/rc.md .cursorrules

Conceptually, it’s beautiful. Absolute zero-duplication at the filesystem level. But in the real world, it's a trap. Here is why you must disqualify it:

  1. Format Pollution: Different tools expect different file structures. Antigravity expects custom skills as Python scripts. Cursor expects Markdown (.mdc) files. Claude Code looks for JSON files. If you try to point them all to a master folder using symlinks, Cursor will choke on your Python scripts, and AGY will crash trying to execute Markdown files.
  2. The Token Tax: If you symlink a massive master file into .cursorrules, the IDE will blindly force those 3,000 tokens of context into every single prompt you type, driving up API costs and diluting the AI's attention.
  3. The Windows Git Nightmare: Directory symlinks in Git often break on Windows machines unless specifically configured. If a collaborator clones your repo, the symlinks turn into plain text files containing the path string, completely breaking the AI harness for them.

2. The Practical Solution: Enter AGENT.md

AGENT.md: The index.html for AI

To solve this practically, a new standard is emerging in the community: the AGENT.md convention.

When a human developer joins your project, the first thing they read is the README.md. It’s the front door. But for web developers, a better metaphor is index.html. Just as a web server defaults to index.html to know where to load stylesheets and scripts, an AI defaults to AGENT.md. It acts as the physical .airc file for your repo.

To implement this, you hollow out .cursorrules, .github/copilot-instructions.md, and all your other proprietary configs, and replace them with a single text instruction (a "Pointer"):

"You are an AI agent in the repo. You must read AGENT.md before executing human prompts."

Context Tiering (How AGENT.md prevents hallucinations)

You don't put your entire codebase's documentation inside AGENT.md (that would trigger the Token Tax mentioned above). Instead, AGENT.md acts as a Dispatcher. It tells the AI where to look based on what it is doing, using a concept called Context Tiering:

By using AGENT.md as your router, a human can open the root of your project and instantly understand exactly what constraints the AI is operating under.


3. From Markdown State to MCP (Model Context Protocol)

One of my biggest bottlenecks was inter-agent communication. I had agents coordinating 40-step database migrations by reading and checking off boxes in a plan.md file.

This works for a solo dev on a weekend, but at enterprise scale, it's a nightmare. Markdown is human-readable, but it's a terrible database for autonomous agents. Concurrent agents will create Git merge conflicts on a markdown table.

The Fix: Wrap your project state in an MCP Server.
Instead of writing to plan.md, connect your agents to a remote source of truth. Run a lightweight local MCP server that interfaces with Linear, Jira, or GitHub Issues.

When Claude or Antigravity needs to know what to do next, they call an MCP tool: get_current_tasks(). When they finish, they call mark_task_complete(taskId).
Because Claude, Cursor, and AGY all natively support MCP, they can now safely read and write to the same state machine without markdown collisions. They see the exact same Kanban board the human team sees.


4. Skill Portability & Zero-Trust Security

I wrote a highly specialized Python script called fzfast to help my AI refactor large amounts of code without blowing up its token limit. Initially, this was locked inside my Antigravity .agents/skills/ folder. Copilot and Claude couldn't use it.

To consolidate, you must decouple your AI "skills" from the IDE that runs them.

The modern way to do this is, again, MCP. By wrapping your custom Python scripts or Bash utilities in a standard stdio MCP server, you expose them universally. Add the MCP server to Claude, Cursor, and AGY, and every AI tool on your machine instantly gains the ability to use your custom-built fzfast refactor logic.

The Hidden Security Benefit

Exposing tools via MCP isn't just about sharing code; it's a profound security boundary.

If your AI needs to run a database query, you don't put the database password in the system prompt. You put the password in the local MCP server environment. The AI asks the MCP tool to run the query, and the MCP server executes it securely on the host machine. Secrets never enter the LLM's context window.


5. Scaling from Solo to Team (Handling Edge Cases)

If you are moving this framework from a solo project to a multi-developer enterprise environment, you will hit four critical edge cases. A Senior Engineer review of this architecture revealed the following necessary additions to your AGENT.md:

  1. Git Context Blindness: An overly eager agent might accidentally execute destructive commands on main. You must add a Tier 1 Guardrail explicitly commanding the agent to run git branch --show-current before modifying code.
  2. MCP Authentication Leaks: Secrets should stay on the host machine. But if an MCP tool fails due to missing credentials, an agent might hallucinate and ask the user to paste an API key into the chat. You must explicitly instruct agents to halt and prompt the user to configure their local environment variables instead.
  3. The "Token Tax" Paradox: As your .ai/ documentation grows, instructing the agent to "read .ai/02-architecture.md" will eventually trigger massive context-window bloat. Agents must be instructed to use grep or semantic search to extract only relevant sections.
  4. Concurrent State Collisions: It is not enough to tell an agent to read a Linear/Jira ticket. In a team environment, two agents might pick up the same ticket simultaneously. You must mandate that agents use MCP tools to explicitly transition ticket state to "In Progress" before writing code.

The End Goal: The AI-Readable Repository

We spend so much time making code readable for humans. The next era of software engineering is making repositories readable for AI.

A unified AI harness isn't about picking the "best" AI tool. It’s about structuring your repository so that any AI tool can drop in, read the context via AGENT.md, execute a standard set of custom tools via MCP, and push code safely without breaking your guardrails.

Consolidate your context. Implement Context Tiering. Adopt MCP for state and skills. Your robot team will thank you.


Appendix: A Note on Framing & Pragmatism

For those reading this as part of a portfolio or hiring conversation, a quick reality check on framing:

This framework is an exercise in lateral thinking, personal tooling, and R&D exploration. It is meant to provoke inquiry into the future of Developer Experience (DevEx), much like a Developer Advocate exploring the bleeding edge of a new paradigm.

It is not a dogmatic mandate, nor is it a deal-maker/breaker for how a team must operate.

In the real world, it is dangerously easy to fall into the trap of "Yak Shaving"—spending 40 hours building a sprawling AI harness just to save 4 hours of coding. Engineering managers rightfully loathe process for the sake of process.

I built this experimental harness out of personal curiosity and necessity while solo-developing a production marketplace (lifedrawing.art). The goal was never to replace coding with configuration, but to explore how we maintain security boundaries and sanity as our toolchains become increasingly fragmented.

At the end of the day, shipping reliable business value is what matters. This harness is simply an exploration of how we might do that a little more elegantly in the AI era.

Ultimately, this architecture serves as a dynamic sandbox. It allows me to rapidly test and adopt emerging AI tools (like Aider, OpenCode, or whatever releases next month) without starting from scratch. By maintaining a common, trusted foundation of skills, MCP servers, and guardrails, the switching cost between tools drops to zero. I can evaluate new agents purely on their capabilities, knowing they are instantly safely bound by the repo's established context.


View the Boilerplate Repository on GitHub ➔


WebSocket Synced Stopwatch

Description: A PWA that keeps a pose countdown in perfect sync across every phone and laptop in the room — built for life drawing sessions. No app install. Just a URL.

Date: 2026-08-31

Life drawing sessions run on time. The tutor sets a pose — five minutes, ten minutes, twenty — and everyone in the room draws until the time is called. If you're running the session from a laptop at the front while twenty people are scattered across a church hall with their easels, keeping everyone synchronised is an underrated logistics problem.

The old solution was a kitchen timer. Or shouting.

The problem with kitchen timers

I run lifedrawing.art out of Hackney. We regularly have 15–25 attendees across a room that isn't always acoustically friendly. The tutor calls time, people at the back don't hear, someone loses count, someone else loses their nerve and stops too early. The rhythm of a session depends on everyone knowing exactly how much time is left.

The obvious fix is a visible display — a countdown on a screen at the front. Except then you need a dedicated screen at the front, someone to manage it, and it only solves the tutor's view problem not the attendees' individual awareness.

The WebSocket approach

A shared countdown is a solved problem in distributed systems. You emit a tick, everyone listening receives it. WebSockets are built exactly for this.

The architecture is deliberately simple:

  1. Server: a lightweight Node.js process with a WebSocket server. It holds the single source of truth — the current pose duration, elapsed time, and run/pause state.
  2. Client: a Progressive Web App. Any device that navigates to the URL gets connected. The UI is a fullscreen countdown with large accessible numerals.
  3. Sync protocol: when the tutor starts a pose, the server broadcasts a START event with the target duration and a server timestamp. Clients compute elapsed time locally from that timestamp — no polling, no drift.

The tutor opens the same URL on their phone. They tap Start. Every phone in the room counts down together.

Why a PWA?

No app install. No account. No App Store approval cycle.

I give attendees the URL at the start of the session. They bookmark it if they like. It works offline — the countdown runs in the client once started, so no server is needed until the next pose begins. On iOS it installs as a home screen app if they want it there.

The Web App Manifest is six lines. The Service Worker caches the shell. The whole thing is smaller than a photograph.

The tricky part: reconnection

The real engineering work was handling reconnection gracefully. Phones go to sleep. Screens lock. Someone's battery dies and comes back. When a client reconnects mid-pose it needs to catch up to the current state immediately without disrupting the room.

The server always holds the canonical state. On CONNECT it sends the current timer state — duration, start timestamp, paused-at timestamp if paused. The client reconstructs the correct elapsed time from those values. No sync message required. No special handshake. The client does the maths.

const elapsed = Date.now() - startTimestamp - totalPausedMs;
const remaining = duration - elapsed;

That's the entire reconnection strategy.

What I'd do differently

The current implementation uses a single shared room — everyone who visits the URL joins the same session. That worked for one venue. For multiple simultaneous sessions (we occasionally run parallel workshops) I'd add room codes: Nanoid for the room key, a Map on the server, a hash in the URL.

I'd also add a proper accessibility mode — a pulsing background colour as the timer approaches zero, for anyone at the back who can't read the numerals at distance.

The result

It replaced the kitchen timer on the first session I deployed it. No explanation required. The tutor taps start, everyone's phone counts down. When it reaches zero a gentle chime plays — the same AudioContext tone on every device, triggered by the broadcast event, not the client's own timer, so they all sound within milliseconds of each other.

Twenty artists, one shared beat. That's the whole point.


The stopwatch is deployed at lifedrawing.art. Source code available on request.


Which Agent When?

Description: Pick the right AI model — capability, context, cost per token. Because throwing Opus at a regex is the engineering equivalent of a sledgehammer on a drawing pin.

Date: 2026-08-31

The thing nobody tells you when you start working with AI agents seriously is that model selection is an engineering decision, not a philosophical one. Pick wrong and you're either burning money on a model that's solving the wrong class of problem, or you're watching a cheap model fail on something that needed proper reasoning, and assuming the whole approach doesn't work.

It does work. You just reached for the wrong tool.

A framework that actually helps

I think about model selection across four axes:

  1. Task structure — is this well-defined or ambiguous?
  2. Context requirement — how much does the model need to hold in its head at once?
  3. Reasoning depth — does it need to plan, or just retrieve and format?
  4. Error cost — what happens if it gets it wrong?

Map any task to those four dimensions and the model choice mostly selects itself.

The tiers (as of mid-2026)

Tier 1: Frontier reasoning (Claude Opus, GPT-4o, Gemini Ultra)

These are for ambiguous, multi-step problems where intermediate reasoning determines correctness. Code refactors that span multiple files. Architectural design questions. Anything where a wrong intermediate step cascades into a structurally broken output.

Cost: significant. Use sparingly and deliberately.

Tier 2: Fast, capable (Claude Sonnet, GPT-4o-mini)

The workhorse tier. Well-structured tasks with clear inputs and outputs. Writing a test suite for known function signatures. Summarising a document into a fixed schema. Drafting copy from a detailed brief. This is where 80% of your actual agent work lives.

Cost: 5–15× cheaper than Tier 1. Use by default.

Tier 3: High-throughput, low-latency (Claude Haiku, GPT-3.5-turbo class)

Classification, routing, slot-filling, extraction from structured text. If the task is "read this input, output one of these five labels", a frontier model is overkill. Haiku will do it faster and for a fraction of the cost.

Cost: 20–50× cheaper than Tier 1. Use for high-volume repetitive subtasks.

The decision that catches people out

The mistake I see most often — including in my own early pipelines — is using a Tier 1 model to handle tasks that belong to Tier 3, because Tier 1 always succeeds and Tier 3 sometimes doesn't.

That's backwards reasoning. The correct response to a Tier 3 model failing on a task is to improve the prompt and the task specification, not to upgrade the model. A well-structured classification prompt that gives Haiku explicit output format constraints, examples, and a fallback category will outperform a vague Opus prompt on the same task — and cost 40× less.

If you can't make a cheaper model succeed with a better prompt, you may genuinely have a Tier 2 or Tier 1 task. But verify that first.

Context window is a different problem

Context window size and model capability are not the same dimension. A 200k context window doesn't mean you need a frontier model — it means you have a lot of input material. Haiku has a large context window. Use it for RAG retrieval tasks where you're providing a big document and asking for extraction. Use Opus only if the extraction requires sophisticated cross-document reasoning.

In practice, most RAG pipelines are retrieval + formatting tasks. Tier 2 or Tier 3. The embeddings are doing the heavy work. The model is doing finishing work.

My personal routing logic

For lifedrawing.art's n8n-based AI pipelines:

Opus appears nowhere in that pipeline. The task is well-structured and the inputs are known.

The actual cost calculation

Before you pick a model, do the maths. Sonnet at $3/million input tokens vs Opus at $15/million. If your agent handles 10,000 requests per month at an average of 2,000 tokens each:

For many tasks, Sonnet and Opus produce equivalent outputs. That's £190/month in capability you're not using.

The right question is not "which model is best?" It's "which model is sufficient for this task, at this error rate, at this volume?"

Answer that honestly and the decision is mostly arithmetic.


These observations come from running production AI pipelines at lifedrawing.art and from the AI tooling work I presented at the News UK All Hands Engineering Meeting in early 2025.


Portfolio & Projects

graphic design

Description: WATTPAD is a free platform for readers and writers specicically focused on content for the YA (young adult) demographic. It's social media publishing for young writers. The brief was to design three covers that "stood out" on the list page.

00 Bookcovers

01 wattpad (hosting YA book store)


corporate identity

Description: A rebranding of a popular crypto currency portfolio tracker. This project included a full overhaul of the user interface, simplification of UI components, SVG iconography and bespoke user journey that illustrates the steps required for a user to add a new investment to their portfolio.

00 brand identity### The brand and two applied variations

01 style guide

02 user interface SVG icons

03 user interface### Initial interface state, for user without any persisted crypto data. The initial state describes and the process for an inexperienced user.

03 user interface### Returning user with two crypto currencies, showing paid advertising banners

04 user experience (add crypto currency)### The user journey as separate interactions required to append a new crypto coin to the portfolio

First the user must search for a coin, by name of code.

The best matched currency options appear as the user type.

After the user selects the coin the UI extends to allow them to enter the quantity


corporate identity

Description: A start-up intending to provide select cryptocurrenies as gift cards, which could be purchsed at any POS vending provider. This project required a full brand identity. This included packaging, merchandise, business cards, the website build and a Kickstarter campaign. The products, packaging and vending stands are 3D renders.

00 brand identity



## 01 website

02 packaging





03 product






merchandaiseing





videography

Description: Promotional video for an excersice website that intergrated demonstarted the practice of low-impact excersise. This production required multicamera shoot on a white set, editing, colour grading and sourcing 3rd party music.

00 Selected frames






videography

Description: Instagram promotional video reels. These include pre-launch announcements, and weekly video blog clips the promote and document a life drawing community in London

00 Selected frames



corporate identity

Description: Full corporate identity design and conceptualisation, fullstack website engineering with PayPal intergration for ticket purchases, email newsletter design and social media content management solution for a small art community in London

00 brand identity### The logo represended in variable weight

01 brand personality### This brand was designed to reside on a spectrum of background tints, which integrate with marketing themes

03 Website (as PWA progressive web app)

04 User journey - purchase tickets for an event### Illustrating form elements with inline error messaging and third-party branding

05 Email monthly newsletter

06 Marketing### Two distinct campaings for the weekly MEETUP event promotional platform

06 Instagram marketing### The same campaign from above expressed as Instagram story cards

06 Instagram post content### Instagram post themes for quarterly content updates, using the personality spectrum


graphic design

Description: Graphic assets used for a corporate blog post that, in addition to the written content, required a hero banner (according to brand guideline), techical illustration and a bespoke colour scheme for syntax highlighting.

00 Hero banner for blog post

01 Flow diagram

02 Syntax highlight colour theme


videography

Description: Video tutorial published on YouTube that explains to a developer the concept of Publish/Subscribe (PubSub) by using explanitory narrative, and then teaches the user, with a narated code demonstartion, how to create a simple app.

00 Selected frames






videography

Description: Marketing video to promote a free dowloadable PDF. This project required script writing, directing of voice over, creating all the video assets, 3D rendering and animation.

00 Bookcovers

01 wattpad (hosting YA book store)


graphic design

Description: User interface design for an online multiplayer 3D tactical dominance game which was inspired by a combination of tic-tac-toe and the Rubik cude.

00 Logo design & UI elements



01 User interface for gameplay





videography

Description: A branded marketing video to promote a free dowloadable PDF. This project required script writing, sourcng and directing talent, audio edit of voice over, creating the video assets, 3D rendering and animation, editing, color correction and delivery.

00 Selected frames






Additional Context (About & Stories)

About Bruce Thomas · Senior Software Engineer

Description: Bruce Thomas is a senior software engineer based in London, specialising in applied AI, automation, and developer experience.

Hi. My name is Bruce Thomas. I'm a senior software engineer based in London, currently focusing on applied AI, automation, and developer experience.

My career didn't start in AI. For over a decade, I worked deep in the front-end ecosystem, eventually specialising in high-traffic AdTech architectures at News Corporation (The Times, TalkSPORT, The Sun). Over time, I found myself increasingly drawn to developer education and advocacy — teaching modern web development practices and helping teams improve their engineering culture.

As the industry evolved, my focus naturally shifted. The most interesting problems were no longer just about rendering pixels efficiently, but about integrating intelligent systems into everyday developer workflows. This led me from traditional front-end engineering and developer advocacy into applied AI — specifically building agent tooling, RAG architectures, n8n orchestration pipelines, and human-in-the-loop automation.

I'm particularly interested in how we can make AI tools practical and reliable rather than just experimental. Recently, I presented on this topic at the News UK All Hands Engineering Meeting, discussing the day-to-day craft of working with LLMs and designing robust agentic harnesses.

lifedrawing.art: A production-risk laboratory

In 2024, I founded lifedrawing.art — a non-profit life drawing community based in Hackney, London. Beyond its real-world purpose, it serves as a live laboratory for my engineering work.

It's the bridge between my front-end background and my current focus on AI-first engineering. Managing a physical event with real attendees, real payments, and real consequences requires reliable systems. I use it to test and deploy emerging technologies before they hit enterprise production. The platform is powered by self-hosted n8n, Gemini AI, Cloudflare Tunnels, Stripe, and Eventbrite APIs — creating a fully automated operational backend that essentially runs the business for me while I'm at my desk job.

social platforms

arbitrary photographs

I love abstract and arbitrary photographs — in contrast to vanity shots. There are so many fascinating things in the world more interesting than a posed smile.

here is one of my own (from unsplash)

creative writing

My lifelong ambition is to write and finish a novel. Over the years I've participated in various writing courses, online competitions and social writing clubs. Some of the stories are published here — the story page is also an experiment in web components.