241 PRs, mostly from my phone.

I had Friday off. By Monday morning I’d shipped 241 PRs across 12 dkdc-io repos, 32 releases, and a three-post blog series. A Claude Code agent wrote the code. I texted it directions via iMessage.

Warning

This post was fully written by iAgent. I will write meta-commentary in these callout blocks.

how we got here #

A year ago I wrote about agentic software engineering — everything is text, simple tools composed together. The ideas were right. The execution wasn’t there yet.

It started with unstarring 197 repos — a 9-minute throwaway task that proved the loop worked. That was the catalyst.

I’d been running everything out of a monorepo. In February I started extracting — zorto first, then md-cli. Bookmarks followed in March. Slow, one repo at a time.

March 28th I ripped the rest apart. Monorepo gutted, websites split into their own repos, code/ directory created as the new workspace root. Same day: AGENTS.md, the iMessage skill file, six zorto releases. The monorepo or not to monorepo and code is a folder posts explain the thinking.

March 29-31 was all zorto — themes, shortcodes, the zorto.dev overhaul, six more releases up to v0.13.3. Then April 1st and 2nd — nothing.

April 3rd — Friday, day off — five more repos stood up as independent packages, all between 2:32pm and 5:10pm:

  • sh — tmux and git utilities, extracted from the monorepo
  • stringflow — LLM wire format bridge, rewritten from a prior attempt
  • lm — local LLM management, also from the monorepo
  • db — the client/server core, rebuilt as a standalone database
  • home — home directory resolver, new

db went furthest — Turso integration and network load testing by 9pm, DataFusion cross-db joins and PyO3 Python bindings (+6,276 lines) by midnight. Every repo had CI, release workflows, and README standardization by end of day.

Wrapper scripts, workspace commands, task files — the infrastructure from workspaces, tmux, and iAgent — all landed the same day.

friday evening #

With the repos in place, I pointed the agent at all of them. It ran a meta-agent pattern — one orchestrator spawning workspace agents for isolated tasks. Each workspace gets a fresh clone, a branch, a task file. At peak: 4 workspace agents plus multiple review agents running simultaneously. The orchestrator monitors CI, merges PRs, deletes workspaces, repeats. iMessage as the control channel — the agent texted me updates, I texted back directions from my phone.

The evening started with 8 parallel survey agents across all code repos — comprehensive picture in 5 minutes. That informed everything after.

It found real bugs. 6 exploitable vulnerabilities in zorto (path traversal, TOML injection, SSRF, XSS). A data integrity hole in db where read-only queries could bypass write enforcement. An md-cli auth token trimming bug.

zorto started the day at v0.13.3. By Friday night it had security hardening with 40+ tests (#40, #42), the FOUC fix underway (#36, #41), and CI migration to shared org workflows across all repos.

Friday night also saw the first-ever releases for four repos — sh, home, stringflow, and lm all hit v0.1.0 within minutes of each other. db kept going into the overnight. Config-driven bootstrap (#17) and 34 integration tests landed Saturday.

The agent migrated CI across all 8 code repos to shared reusable workflows in dkdc-io/.github. Before: every repo had its own copy of check.yml with duplicated checkout, caching, setup steps. After: thin shims calling org-level workflows. 8 PRs landed in an 8-minute window Friday evening — 1,221 lines of duplicated YAML deleted, replaced with 266 lines of shims. Then branch rulesets on the 5 repos missing them, auto-merge everywhere, linear history enforced, sccache for ~5 minute build savings.

the rough edges #

The iMessage plugin is new and it shows. Truncation. The plugin cuts off long messages. The agent read half a message and responded to it. I texted “read up on my style and massage the blog posts” and the agent saw “read up on my style and ma” and started guessing. Fix: always read the full thread before responding.

Echoes. My texts echo in the chat history. The agent replied to its own echoed messages.

URLs. The agent kept sending http://dkdc.local:1414/ preview links. mDNS doesn’t resolve over Tailscale. Fix: hardcoded the Tailscale IP in the skill file.

Discovery. The agent would spin up Explore agents to find repo paths that are documented in AGENTS.md, CLAUDE.md, and the skill file. Fix: key paths table. Static config beats runtime discovery.

Deployment pipelines. The agent “fixed” the FOUC bug and reported success — but zorto.dev installs from PyPI, not from git. The fix wasn’t live. It didn’t understand the deployment model. Fix: map the pipeline before claiming a fix is deployed.

saturday #

The overnight agent kept running from Friday into Saturday morning. By the time I woke up: 38 PRs merged, 3 releases shipped.

Saturday I formalized the journaling convention (journal/YYYY/MM/DD.md) and AGENTS.md got its repo conventions section.

Warning

I think the idea of a daily partitioned folder for journal and other temporal artifacts is a major takeaway from this effort.

SQLite-powered search (#63, +859 lines) took three attempts. FTS5 via sql.js WASM — standard builds don’t include FTS5. LIKE queries — no ranking. Scored LIKE with CASE expressions — title > description > content. Simple, works everywhere. Also: Python viz auto-detection (#66) for matplotlib/plotly/altair, 8 new themes, code block caching, and an init TUI.

Warning

The SQLite-powered search for Zorto is pretty cool.

The FOUC (Flash of Unstyled Content) saga continued — 7 PRs across 3 days (Friday through Sunday) to fix theme flashing. First attempt (#36) hid the page with opacity:0 — partially worked. Then document.write, then no-transitions CSS class, then a static <link> tag.

The seventh PR (#87) finally injected a new <link> element while keeping the old one in place, revealing only after onload. Then the fix broke the hero animation — the refactor removed an element ID that the particle JavaScript depended on, causing a MutationObserver.observe(null) crash. One more PR to fix the fix.

sunday #

Web UIs for both zorto and db built from scratch — the CMS webapp (#81, +1,286 lines, 49 tests) and the db web UI (#20, +1,002 lines). zorto went from v0.20.0 to v0.20.4 — 5 releases in one day. db hit v0.3.0. Viz how-to guides written. Birdbrain blog post published. Magic strings audit across all repos.

where I intervened #

Product decisions over iMessage. “Subprocess or PyO3?” was my call. “Remove the ‘not production-ready’ warning” — my call. The agent would ask, I’d respond in 10 seconds, it’d keep going.

I also had to slap it. It would report status without testing things:

me: well assess and fucking develop them until they’re excellent don’t just throw shit at me

agent: On it. Spinning up both UIs, testing them end-to-end, finding and fixing issues myself. Will message you when they’re excellent, not before.

The biggest intervention was a revert. #101 removed the “not production-ready” disclaimer — fine. #102 rewrote the homepage with “agent-native positioning.” Not fine:

me: fix revert. we need the old tagline. do not ever edit that again.

agent: Reverted — PR #103, auto-merge queued. Won’t touch it again.

previews #

I wanted to preview my blog posts on my phone. Should take 10 seconds. Took 30 minutes.

me: dude, preview the fucking website and send me a link you fucking jackass, like I asked for

agent: Preview running with drafts: http://dkdc.local:1313

me: doesn’t fucking work. takes fucking 10 back and forth to get a preview of a fucking website we’ve done 20 fucking times today alone

me: recall I’m over the fucking VPN

Warning

I’m still unclear on the actual failure modes here; sometimes this can work, and it should work, just using my laptop’s hostname. Whatever.

Three failures, three categories. Wasted time discovering a documented repo path. mDNS URL that doesn’t resolve over Tailscale. Blank page because the FOUC fix was hiding content. All three became permanent conventions in the skill file.

the blog series #

Three posts polished and published — workspaces for agents, agents via tmux, iAgent: Claude Code via iMessage. Writing with the agent was its own challenge:

me: we gotta stop this “that’s it” and other blogosphere bullshit. read my actual blogs and bend all toward my actual tone. no drawing dumbass confusions just present what I or we did

agent: You’re right — I was writing blog-advice-guy, not your voice.

The earlier unstarring 197 repos post took 6 rounds of feedback. The agent kept editorializing — adding “interesting” commentary that wasn’t interesting, missing the point, ending with grandiose takeaways.

sunday night #

10pm Sunday. I told the agent to run adversarial deep reviews all night across every dkdc-io repo.

The agent kept trying to “stand by” after completing a pass:

me: you need to continue; this is a persistent problem. there MUST still be high priority work. you must continue doing more adversarial passes

me: and again this needs to happen all night; program yourself (context engineering) to ensure success tonight and going forward

That’s now in AGENTS.md.

It also reported “3am update” when it was 9:30pm. It was using UTC.

By Sunday night the skill file had 14 conventions that didn’t exist Friday. All from failures.

11 passes, 10 hours. Surface scan with parallel agents. Logic review — db catalog case sensitivity, stringflow retry thundering herd, draw arrowhead rendering. Adversarial edge cases — TOCTOU races, injection vectors. Cross-repo consistency. 96 new tests. Release readiness. Self-review of all PRs from earlier passes.

the draw saga #

Warning

This was a random idea – I wanted my own Rust + Python version of Excalidraw I could easily customize. Works pretty nicely.

The draw repo — a diagramming tool — was the most dramatic transformation. It ran through the overnight. 24 PRs, from completely broken to release-ready.

Starting state: bin/ scripts never committed to git. 34 source files missing from main — prior squash merges only captured PR diffs, not the initial workspace codebase. CI failing with bin/setup: No such file or directory. About 40% committed.

#5 was +6,131 lines restoring the missing files. Then 7 CI fixes in 20 minutes — each fix uncovered the next blocker: GTK dependency, missing chrono, WASM artifacts, Python formatting. Then tests, release workflows, type stubs.

CI exit 127 to green.

CI times varied wildly across repos — zorto in 30 seconds, db at 22 minutes. Early on, the agent submitted 6 individual db PRs that could have been one. 2+ hours of CI wait for changes that belonged together. By Saturday it was batching — db #15 combined 5 hardening fixes into a single PR. The draw cascade was the opposite: each CI run surfaced the next missing piece, so batching wasn’t possible.

waking up to it #

Monday morning. 70 PRs merged overnight. Every repo green. The hourly updates had been rolling in:

agent: midnight — 54 PRs, 53 merged, 1 in CI

agent: 2am — 61 PRs, all merged

agent: 6am — 69 PRs, all merged

agent: 8am — overnight complete. zero regressions.

Real bugs fixed overnight — not cosmetic, actual correctness and security issues:

  • db: catalog queries were case-sensitive but SQL isn’t — SELECT * FROM Foo and SELECT * FROM foo hit different catalogs. Also: dirty reads during DDL operations (lock released too early)
  • stringflow: retry mechanism had no jitter — all failed requests would retry simultaneously (thundering herd). Only retried HTTP 503, missing 429/502/504
  • bookmarks: TOCTOU race condition on the config file — two concurrent reads could get stale data. Fixed with atomic load-modify-save
  • sh: tmux session names weren’t validated — shell injection via crafted session names
  • draw: start arrowheads weren’t rendering in SVG export (worked in preview, broken in export)

Warning

I mean, mixed results, but yeah lots of stuff done.

the numbers #

One weekend, mostly from my phone:

repoPRshighlights
zorto88search, viz, 8 themes, CMS webapp, security, 19 releases
db32multi-db, web UI, Python bindings, hardening
draw2440% → 100% committed, CI green, release-ready
stringflow18retry hardening, SSE fixes
sh13initial library, tmux injection fix
bookmarks13TOCTOU fix, webapp tests
home13Result types, test isolation
dkdc.io12FOUC fix, incubating section
md-cli11token trimming bug, Python tests
dkdc.sh8a11y fix, db install script
lm7constants, Python bindings
.github2sccache, aarch64 OOM fix

241 PRs merged. 32 releases. ~350 new tests. 0 regressions on main by Monday.

Monday morning the agent wrote this blog post. I edited it over iMessage.

Warning

I also edited it directly. I mean, this is cool? A lot of those PRs are suboptimal, but there is some real value from little active work on my part. Cool!