Voice planning carried a blog feature to review; production imports still needed keyboard work
Voice planning carried a blog feature to review; production imports still needed keyboard work
Question and answer (October 9, 2026). A maintained-feature trace can begin in speech, but it does not end when the page first looks right. Simon Willison describes building a newsletter archive by speaking with Codex while cooking, then inspecting the PR and switching to typed prompts for the import mechanism and final display before merging. This is a one-maintainer shipped feature, not evidence that voice is faster than typing or that an unattended agent shipped it.
Primary trail. Willison’s first-person account; voice session transcript; merged PR #719 and a linked public-archive date fix; deployed index and public monthly issue. The article was published October 9; the PR lists commits October 8–9 across time zones, and the Gist was created October 9. Treat this as one continuous episode, not a week-later repair.
Need→plan. Willison wanted Substack listings linked out but public monthly sponsor letters hosted locally; a private latest letter could be listed, with its contents still gated by GitHub. In the transcript the agent explicitly distinguishes sent date from public release date so a sponsor letter does not jump the timeline when opened. He revises his own archive decision mid-sentence: newsletters should appear on day/month pages, not the blog homepage or tag pages; only the published, unique monthly content goes into site search, not the duplicate Substack entries. The agent turns the rules into a table. This is a trace of shared planning and an explicit visibility distinction, not proof all routes stayed correct.
Delegate→preview→repair. The session built a Django model, migration, admin, importers, tests and archive/search templates. The transcript says an RSS feed exposed only recent Substack issues; a subagent used an undocumented archive endpoint for history, while the monthly content came from a public repository. The agent did local dry runs and tests and Willison glanced at a live development preview while giving visual corrections. The transcript records ten targeted newsletter tests passing and an unrelated failure in a broader test invocation; do not report a clean full suite. PR #719 has eight commits, three passed checks and no other named reviewer. On reviewing the patch, Willison flagged a subprocess-based Git importer that would need extra Heroku setup and would be awkward for the private repo, had it changed to HTTP/API imports, removed the legacy Git checkout path and created a read-only private-repo token in the deployment secret store. A separate archive-repo commit adds explicit send dates to its index. He also annotated the archive API as undocumented and acceptable for a one-time historical import. These are owner-authored corrections to deployability and source facts, not automatic review success.
Release and limits. The public index loads with Substack entries, a sponsor-only September letter and a public August letter; the August content has its own published page. That independently verifies a rendered index and a public detail page, not the entire historical import, search policy for all cases, authenticated privacy behavior or month-later maintenance. Willison reports about half an hour of voice interaction while cooking and another half hour of typed prompting/review; neither is zero-attention work, and there is no token bill, baseline typed implementation, reader-use measure, external requester or subsequent repair ledger. He himself says voice helps multitasking, but typed examples/errors and code selection win on detailed changes. The generalizable test is whether an interactive plan records audience, publication and import permissions before implementation, then routes preview, PR correction, owner acceptance and later failures into a durable change ledger.
Open follow-up. At a later date, inspect whether a new monthly publication imports without manual data repair, whether search hides duplicates and private content, and how much operator time it takes. Compare the accepted-warning→release gate: here the owner caught and fixed a deployment blocker before merge, unlike SQLFluff’s next-day follow-up. Link back to agent interface versus maintenance and status versus acceptance.