Portfolio · October 2026
Colours
← All work Research · 8 projects

AI tools and research

Tools for working with AI agents and reading arguments, plus research and reference works: a Byzantine atlas, a medical evidence map and two evidence checks.

AI tools and experiments

Small tools that put AI reasoning on display.

Case study 26 · Native Mac app · Developer tool

BLACKBOX

A flight recorder for AI coding agents. It captures what Claude Code actually did, prompts, tool calls, file edits, failures and subagent handoffs, and lets you replay a session, trace a file change back to the agent that made it, and see how a failure was recovered. Nothing leaves the Mac.

The BLACKBOX flight recorder replaying a synthetic session: tracks for prompts, main agent, subagents, tools, files, build and test, errors, context and tokens on one timeline, with an event inspector showing a failed test run.
The flight recorder. Every track of a session on one timeline, played back at up to 20x, with the inspector showing what led to a failed test and what came next.

The problem

AI coding agents now run for long stretches, start subagents and edit dozens of files. When something breaks, the only record is a scrolling transcript. There is no way to see the session as a whole, ask which agent changed a file, or tell what was observed from what someone guessed afterward.

What it does

  • Capture, local only: opt-in hooks and transcript import into a local database, with privacy levels and redaction.
  • Replay on a single timeline, with an inspector that links each event to its cause and result.
  • File forensics, agent topology and a failure observatory that groups repeated failures and reconstructs recovery.
  • A safe installer that shows a line-by-line diff of the Claude settings file and backs it up before changing anything.
The failure observatory: groups of repeated failing commands on the left, and on the right the chain from prompt to failure to an edit, a retry and recovery, with a separate space for hypotheses.
The failure observatory. Observed events and inferred steps are marked differently, and your own hypotheses are kept apart from both.
The same flight recorder in a white skin.
The same recorder in a white skin. Nine skins are available, chosen in Settings rather than in the working screens.
How it was built

A native macOS app in SwiftUI over SQLite with full-text search. I wrote the specification package and asked for it to be as sleek as a flight instrument; Claude Code built the app, the hook relay and the synthetic sessions, and ran the builds on my Mac through Remote Control.

Case study 38 · Native Mac app · Local AI

AgentForge

A Mac app for running AI agents on models that live on your own computer. You point an agent at a project folder, choose how much it may touch, and approve each change. It also covers chat, chat with your documents and visual agent workflows, all inside a retro terminal look built from text characters.

Lines of Swift
10,442
Pages
19
Agent harnesses
3
Automated checks
32
Releases shipped
4
Cloud accounts required
0
AgentForge Mission Control: a green phosphor terminal dashboard with the AGENTFORGE title in block letters, an ASCII-art globe, model and agent counts, a pixel clock and a live hardware bar across the top.
Mission Control. The bar across the top tracks processor, graphics, memory, disk, network, temperature and battery in real time.

What it does

Agents on your own models

A built-in agent lists, reads, searches, writes and edits files and runs commands, using a model running locally through Ollama. Access is chosen per session: read only, ask before each change, or auto-approve edits. Every change is checkpointed and can be undone.

Three harnesses

The same launcher also drives Claude Code and Codex, either on the user's own cloud account or pointed at a local model. Skills and MCP tools plug in, and a timed-out run can be continued, with the agent told which files the last attempt already changed.

Model Lab

Grades each installed model on whether it can drive an agent: does it make real tool calls, how fast does it write, and how long does it take to wake. The agent picker defaults to the best-graded model.

Flows

A drag-and-drop canvas for wiring agents, prompts, routers, human approval gates and shell steps into a workflow, with zoom, fit, a minimap and ten starter templates. One template has an agent edit AgentForge itself, rebuild it and relaunch it.

Library

Chat with your own documents. PDFs, Word files and code are split up and indexed with a local embedding model, and answers cite the passage they came from. Agents can search the library too.

The fun parts

Idea Forge, a slot machine that rolls a project idea; ASCII Studio with effects and 24 animated creatures; Sprite Lab, where a model can draw a sprite from a prompt; a music visualizer; and an Agent Theater where running agents appear as characters.

The Agents page: on the left, harness, brain and access settings; on the right, a completed read-only session whose timeline shows the objective, list_files and read_file tool calls with their output, and the agent's written answer.
A real read-only run on gemma4:12b: the agent lists the folder, reads the README and the code, then explains the project. It took about six minutes on a base M2.

Making small local models usable as agents

Local models fail as agents in quiet ways. Some write a tool call as text instead of making it, some announce the next step and then stop, and some repeat the same action forever. The harness recovers tool calls written as text, nudges a model that promised an action it did not take, redirects and then stops repeat loops, and frees memory and reloads the model onto the graphics chip before a long run. Model Lab measures which models need this help, so the default is one that does not.

How it was built

Built with Claude Code as a native SwiftUI app with no third-party code apart from the Sparkle updater. Every animation is plain text redrawn by a capped clock, and everything pauses when the window is in the background. Releases are signed with my Apple Developer ID, notarized by Apple and served from a Cloudflare Worker that also hosts the update feed. A feedback button attaches diagnostics and recent crash reports, with personal paths removed.

Case study 06 · Reading tool

Argument X-ray

Persuasive writing hides its structure. This tool maps a text into its thesis, claims, evidence, unstated assumptions and objections, then flags the weak links so you can see what is actually supported.

What it does

  • A clickable map of each text: thesis, reasons, evidence, unstated assumptions, objections and replies. Selecting a box highlights its passage, and selecting a passage selects its box.
  • A verdict with a grade, the weak points ranked by how serious they are, and suggested fixes. Typical findings are false dilemmas, one-off costs passed off as yearly ones, and contract clauses that conflict.
  • A rule-based scan beside it, so you can see what plain pattern matching catches and what takes real reading.
How it was built

Claude Code wrote the page, the sample texts and each analysis. The look is deliberately separate from this portfolio: a dark radiology light box, where the examples are plates and the fixes are recommendations.

Case study 07 · Decision tool

Boardroom of One

Ask one AI for advice and you tend to get one balanced, agreeable answer that hides the real disagreement. This tool seats five advisers with fixed temperaments and lets them argue your decision, then vote.

How a meeting runs

  • Five temperaments: Skeptic, Optimist, CFO, Future You and Contrarian, each with a different worldview.
  • Openings, cross-examination and a vote on a five-point scale, which you can replay turn by turn around an animated table.
  • The chair's resolution: the crux, the tradeoffs, when to say yes or no, and a first step for this week.
How it was built

Claude Code built the page and wrote the four example debates. It has its own look, an after-hours boardroom with a brass-nameplate table and a chair's resolution sealed in wax, so it reads as a separate product.

Research and history

Reference works and original research, including medical research.

Case study 03 · Reference work

Byzantium

An illustrated encyclopedia of the Eastern Roman Empire, 324 to 1453, built around a mosaic atlas you can drag through 1,129 years and watch the borders move.

Dated territory snapshots
200
Map features
11,850
Encyclopedia entries
464
Licensed images
1,174
Podcast episodes indexed
440
Invalid geometries / overlaps
0 / 0
The Byzantium atlas set to the year 1025: the empire laid out in purple mosaic tiles edged in gold, a blue tessera sea, a year slider with dynasty bands, and a panel describing what was happening in 1025.
The atlas at 1025, near the empire's height. Every tile is a tessera; the panel says who was on the throne and who held what that year.

The atlas

Drawn as a mosaic

Territory is one fixed grid of tesserae, each slightly varied in shade, with grout between them. The empire is imperial purple edged in gold; the sea is blue tile. A Borders mode switches to clean outlines, and light and dark themes each have their own palette.

Conquest you can watch

When borders change, only the tiles that changed owner turn over, in a wave that starts from the conqueror's side, so territory is taken rather than repainted. Cities that change hands send out a ripple.

Built for scrubbing

Drag, click or use the keyboard; play at 1 to 50 years a second; or press Next change to jump to the next year the map moves. Ownership is cached per snapshot and neighbours precomputed, so fast scrubbing stays smooth.

Contested land stays contested

Overlapping claims of more than about 500 km² become hatched contested land instead of being handed to one side. Five places where the source disagrees with history, from Manzikert to 1453, are corrected and explained on the map.

Checked against the source

An automated check confirms zero invalid geometries and zero overlaps across all 200 snapshots, and ten key years match the source to within 1% of land area. Five other map sources were evaluated and rejected, each with a written reason.

More ways in

Compare two years side by side with a draggable divider, switch to a table of powers, toggle cities, battles and campaign routes, and share any view by its URL. Patterns stand in for colour, and reduced motion swaps flips for fades.

Atlas compare mode: two years of the empire side by side, split by a draggable divider.
Compare mode: two years side by side with a divider you can drag or move by keyboard.
The atlas at 1025, with the empire at its height under Basil II. The atlas in dark mode at 1204, with former imperial land hatched as contested after the Fourth Crusade.
Drag the divider, or use the arrow keys, to go from 1025 to 1204. After the Fourth Crusade the empire's land is hatched as contested rather than simply recoloured.

The encyclopedia around it

  • 464 entries pinned to fixed Wikipedia revisions with restored footnotes, plus 168 original introductions labelled as such.
  • 1,174 Commons images with author and licence; 41 were left out because their licence couldn't be confirmed.
  • A guide to all 440 episodes of The History of Byzantium podcast. The build fails if any 12-word run matches the podcast's pages.
  • 87 battle entries, a people index of 1,765, a gazetteer, coins, a primary-source reader for Procopius and Anna Komnene, and a timeline that shares its playhead with the atlas.

Built and verified

React, TypeScript and d3-geo, with Python pipelines for the map geometry: borders from the Seshat Cliopatria dataset, coastlines from Natural Earth, and 96 cities and 71 battles from Wikidata. It ships with 20 slider tests, 60 screenshot checks across phone and desktop, and Lighthouse mobile scores of 93 to 96.

How it was built

One long Claude Code session took it from an empty folder to a verified site. Claude evaluated map sources and their licences, built three data pipelines and the renderer, and wrote its own reports on what failed, what was skipped and where the sources disagree, for me to review.

Case study 15 · Medical research

ME/CFS and Long COVID evidence map

Thousands of small studies have measured something in people with ME/CFS or Long COVID, and few results have been checked against each other. This project read the whole PubMed literature, pulled out every measured finding with its quote, and graded which ones independent labs have actually replicated.

Abstracts screened
15,923
Studies in the database
1,981
Findings, each with its source quote
7,337
Findings graded strong (ME/CFS / Long COVID)
17 / 33
Brain tissues enriched in the genetics test
11 of 13

The problem

ME/CFS has been studied for decades and Long COVID has added thousands of papers in a few years, but most studies are small and many contradict each other. Nobody had pulled the whole literature into one table that says which findings hold up across independent labs and which do not.

What it does

  • Extracts every finding from each abstract: what was measured, in whom, against which comparison group, and in which direction, with the sentence it came from.
  • Grades replication by lab, not by paper, so a group publishing the same cohort five times counts once. Replicated nulls are kept too, such as the 11 of 11 labs that found no XMRV.
  • Compares the two illnesses side by side. Both show the same circulation and exercise picture: a racing heart on standing, a lower stroke volume and reduced peak oxygen uptake.

Predictions written down first

The replicated findings suggested an immune, vascular and autonomic chain. Before opening any genetic data, the predictions were written down and locked with a file hash, then tested against the open DecodeME genome study with MAGMA gene-set and tissue analysis. The signal sat in the brain: 11 of 13 brain tissues and the pituitary were enriched, which agrees with what the DecodeME team reported themselves.

How it was built

Built with Claude, under my direction, across several long Claude sessions. Claude wrote the search and grading code, ran the extraction in batches of 100 abstracts, audited its own output and ran the genetics pipeline. I directed the work and made the calls along the way, including writing the genetics predictions down before the test.

Case study 16 · Patient tool

Clear Aftercare

Discharge papers are written in abbreviations and handed to people who are tired, unwell or 80 years old. Paste them in and get a plain-language care sheet plus a calendar reminder for every dose, task and appointment, with anything unclear marked instead of guessed.

Clear Aftercare input screen with an emergency department discharge note pasted in, full of abbreviations such as PO BID x 7 days and PRN, and a visit date.
The input: an emergency department discharge for an 81-year-old with pneumonia, as it would be printed.
The resulting care sheet: a plain-language summary of the visit, a red box of reasons to go back to the emergency room, and the first medicine card showing what it is for, how much and when.
The care sheet. Eleven gaps, such as "2 times a day" with no clock times, are marked for the patient to fill in or ask about.

What it does

  • Rewrites, never adds. Abbreviations become plain words, but the prompt forbids adding any medicine, dose, time, duration or advice that is not on the paper.
  • Flags the gaps: twice a day with no times, a dose in mg with no pill strength, "continue home meds" with no list, a follow-up nobody booked.
  • Turns on reminders only when they are complete. Calendar buttons switch on once times, start date and number of days are set, with one-click presets such as 8 AM and 8 PM.
  • Built for the reader: a large-text toggle, a dose checklist, a print view and a rough reading-grade score.
How it was built

Built with Claude as a single page that calls Claude to read the instructions. Claude wrote the page, the prompt, the calendar files and the example, and checked prior work in the field, under my direction.

Case study 17 · Medical evidence check

Trauma guideline citation audit

Military trauma guidelines tell medics and surgeons what to do, and each recommendation cites a paper. This audit checked whether the cited papers say what the guidelines claim, and found reference lists whose numbers had slipped out of line.

What it found

  • Shifted reference numbers. In the pain, anxiety and delirium guideline, 24 of 27 wrong-topic citations fit the entry two numbers later, so the in-text numbers look keyed to a different list. The TBI neurosurgery guideline shows a shift of one in its later references.
  • Smaller slips elsewhere: two swapped references in one guideline and a reference reused for every cross-reference in another.
  • 56 specific citations are listed for a person to confirm by opening the PDF and reading the two entries.

Decisions behind it

  • Lead with what anyone can check. A shifted reference number is verifiable in minutes, so it is the headline, not a subjective "does this paper support it" grade.
  • Distrust the big number. AI grading flagged about 38% of citations as unsupported, but that fell to 18% when the full paper was available instead of the abstract, so it is reported as a likely overestimate.
  • Second opinion, labelled as such. ChatGPT re-graded 150 items and agreed closely with Claude (kappa 0.76).
How it was built

Built with Claude under my direction. Claude downloaded the guidelines, extracted every cited statement, matched each reference to PubMed, graded support and ran the reference-shift test; ChatGPT did the second-model check. The result is a list of specific, correctable errors in these guidelines.

More work

Which AI for what by project