Agentic programming case study
Learning agentic programming by shipping something real
I used this project to learn how to direct an AI coding agent while building a useful e-reader dictionary people could actually install.
What this project was really about
The visible product is a Dungeon Crawler Carl e-reader dictionary. The deeper project was learning how to collaborate with an AI coding agent on a real, messy software project: ambiguous requirements, changing direction, format-specific constraints, release packaging, tests, documentation, and user support.
I did not want a toy demo. I wanted something useful enough to sideload onto a Kindle, share with other readers, and maintain over time. That made the agentic workflow more interesting: the work had to survive contact with real devices, real content, real licensing questions, and real users.
The useful thing we built
Dungeon Crawler Carl has many characters, factions, items, spells, races, achievements, and other references that readers may want to check without leaving the book. Web searches and wiki browsing are slower and can expose spoilers. E-readers already have lookup interfaces, but fictional proper nouns usually are not covered by normal dictionaries.
Approach
The project fetches selected MediaWiki/Fandom pages into SQLite, extracts conservative entry summaries, and emits multiple dictionary formats from the same stored source data. The current release flow builds Kindle, StarDict for KOReader and BOOX, and Kobo editions.
How the agentic workflow changed
At the beginning, I was learning how to use Codex at all: what files were needed, whether an empty repo mattered, how to ask for architecture before implementation, and how much context to provide. Over time, the interaction became more precise. I started giving explicit goals, constraints, acceptance criteria, commit boundaries, and verification steps.
That shift mattered. The agent could do a lot of implementation work, but the best results came when I stayed responsible for product direction: what counted as useful, what was too noisy, what should be automated, what should stay simple, and when a technically plausible answer did not match the reader experience I wanted.
Where I pushed back
Several important decisions came from disagreeing with the agent's first direction or revisiting a decision after testing.
- Aliases: the project moved from direct duplicate Kindle entries, to hidden Kindle inflections, to a shared lookup model that can also represent duplicate meanings such as a canonical entry plus a matching box or spell alias.
- Manual cleanup: I rejected a manually curated alias list as the default path and pushed for automatic discovery from wiki text, bold intro names, parentheticals, sidebar aliases, and conservative human-name rules.
- Badges and automation: I chose local tracked badge JSON over a GitHub Actions workflow that would create badge-only commits, because clean history mattered more for this solo project.
- Scope control: I repeatedly split large work into separate commits, especially when release packaging, output formats, and architecture changes could otherwise have become one hard-to-revert change.
- User support: the docs grew from installation instructions into reader-focused support paths, including BOOX notes and a help page for non-technical users.
Pipeline
- Fetch: collect selected wiki pages through the MediaWiki API into
data/characters.sqlite. - Extract: preserve safe inline emphasis, strip or escape unsafe HTML, and build concise definition bullets.
- Resolve lookups: discover aliases and handle duplicate lookup names without randomly choosing one meaning.
- Build: generate Kindle XHTML/OPF, StarDict files, and Kobo dictionary source/output.
- Release: package tested output files, checksums, attribution, and a manifest into GitHub Release assets.
The commit history tells the story
The commit history starts with a single Kindle builder, then adds licensing, tests, extraction quality, inline formatting, spoiler notes, sidebar metadata, and release packaging. Later commits add KOReader/StarDict, local badge management, Kobo support, GitHub Pages documentation, BOOX support, help links, and a more robust lookup model.
That history is not perfectly linear, and that is part of the point. I changed my mind after testing. I backed out of overly broad aliasing. I moved from "make this work" to "make this releasable." The final project is better because the workflow treated the agent as a capable collaborator, not an autopilot.
Format constraints
Kindle dictionaries use XHTML with Amazon-specific idx:* tags plus an OPF package file. KOReader and BOOX use a StarDict bundle with files kept together in one folder. Kobo uses a compiled custom dictionary ZIP. Each target has different lookup behavior, packaging expectations, and UI limitations.
Reliability work
The test suite covers extraction, SQLite loading, Kindle XHTML/OPF generation, StarDict binary generation and inspection, aliases, release packaging, and compiler wrapper behavior. Release builds also generate checksums and a manifest so users can verify artifacts.
Responsible crawling
The crawler checks robots.txt by default, sleeps between requests with jitter, retries temporary failures with exponential backoff, records errors, and resumes previous successful fetches. The README documents that the Fandom API route is disallowed for crawlers and requires an explicit user-triggered override for this project.
What this demonstrates
This project demonstrates more than code generation. It shows product judgment, human-in-the-loop AI direction, source attribution and licensing care, practical data extraction, intermediate storage design, format conversion, binary release packaging, e-reader platform constraints, automated tests, and user-facing documentation.