Dev Diary #13
Built anti-hallucination core to prevent AI-generated diary entries from inventing facts.
May 1, 2026

Started the week fighting hallucinations. The agent-blog module kept generating diary entries with details it invented—Linear ticket refs that didn't exist, commit messages it reconstructed instead of using actual ones. Built an anti-hallucination core that runs classification on sensitive data (ticket IDs, file paths, error messages) before the LLM ever sees it, then verifies the output against what we actually have in the git history. Ended up with three migration files just for the schema changes: 0003_anti_hallucination_core.sql, 0005_add_magnitude_algo_version.sql, 0006_blog_publish_log.sql.
The notes-pipeline needed rewiring. Instead of feeding raw commit data to the generator and hoping it wouldn't confabulate, we now extract structured facts first—repo names, actual file lists, message content verbatim. A ticket-translation module maps Linear refs if they exist, but crucially, doesn't create them if they don't. The pipeline still generates drafts in pending-review, but now with a word-diff layer that flags where the output diverges from source material. That's imperfect and I hate it, but it catches the worst cases.
Wired up cross-agent enrichment via RPC. The agent-blog can now ask service-director and service-linear for context without hallucinating their responses. Built bus-rpc in shared/core to handle the back-and-forth. It's synchronous, which feels wrong for distributed systems, but we're not distributed yet—we're monorepo'd and the latency is negligible.
Got bitten by a partial unique index issue in the autonomous-tick handler. The ON CONFLICT clause wasn't matching because the index covered fewer columns than the insert. Spent an hour debugging why the same record kept getting reinserted. Fixed it in 0009_blog_stats_snapshots_uniq.sql but now I'm paranoid about other indexes doing the same thing silently.
Also spent time on terminal colors. Didn't plan to, but .tmux.conf and the new Alacritty config needed Gruvbox Material palettes to match the iTerm2 presets. Small win—environment consistency, but completely orthogonal to the core work.
Still unclear: whether the engagement learning loop in stats-ingestion is actually learning anything useful, or just recording noise. The preference-scores table exists, but I haven't built the feedback path yet. That's next.