Four Alarm Slots, Three Failure Modes: Building a Nightly Drain That Survives Sleep, Races, and Timeouts A developer built an automated nightly pipeline that drains Claude Code conversation logs into an Obsidian vault, creating an external long-term memory for AI-assisted development. The system survived three real outages—sleep freezes, double-execution races, and timeouts—leading to a design with multi-slot re-firing, caffeinate sleep prevention, and idempotent retry via step markers. Every night my Mac quietly rewrites my long-term memory. Not metaphorically — a shell script drains that day's Claude Code conversation logs into an Obsidian vault, commits them to a private repo, and leaves a briefing on my desktop. It took three real outages to make it reliable. This is the script, the three failures, and the design that came out of them. Claude Code sessions are independent of one another. The root cause of a bug you found during a long working session today, the reason you settled on a particular architecture after trial and error, the accumulated knowledge that "this direction already failed once" — none of it is available in the next conversation once you close the session. Even on a paid plan, even with the most capable model available, if context isn't carried over you have to explain everything from scratch every time. Many people have had the experience of thinking "I already looked this up before" or "I should have failed at this once already, and yet here I am heading down the same road again." In a phase where you're shipping personal projects in volume, this problem is fatal. Once three or four projects are running in parallel, tracking "where each project currently stands" by hand hits a wall fast. And Claude, unable to reference previous conversations, repeats the same deliberations. My first attempt at this problem was "I'll write up a summary by hand every day." It didn't last. When work has momentum you don't feel like writing a summary, and when you're tired you can write even less. A system that depends on human willpower doesn't function during a high-volume solo-dev phase. The answer was to build an environment that automatically drains Claude's conversation logs into Obsidian every night. Once the environment is in place, willpower and motivation are irrelevant. The Mac just does it. The reason I chose Obsidian is simple. The files are local Markdown, so Claude Code can read and write them directly. They can be version-controlled with Git. The link syntax lets you connect pieces of knowledge to each other. Logs flow in every morning and cross-project links grow naturally — from the moment this started functioning as an "external brain," the quality of my work changed. Simply "running a script at 4:55 every day" produced three distinct kinds of failure once I actually ran it. Each one only became apparent after it caused real damage. Sleep freeze : If you close the lid on the Mac and go to bed, caffeinate -s which only takes effect on AC power can't prevent sleep. The script stops partway through, and that day's processing hangs in limbo until the next slot fires. Double-execution race : An actual incident on 2026-06-10. A scheduled launchd firing overlapped with a manual run. Both tried to operate on the same vault with Git, and the result was a conflict. Timeout : On 2026-06-13, every slot failed for the entire day. Digesting 28 hours' worth of logs via claude -p didn't fit within the 40-minute timeout window and all of it got culled. In the logs, the pattern started 04:55:00 → step2 timeout at 05:40:01 lines up across all four slots, completely uniform. These three real failures are what forced the triple-layered structure of "multi-slot re-firing," "caffeinate sleep prevention," and "idempotent retry via step markers." It didn't come out of a design document; it accumulated from things that actually broke. Once the system started running stably, logs pile up in Obsidian every morning. Claude reads those logs, updates per-project articles, and this week's talking points accumulate in hot.md a summary of recent context . When Claude reads hot.md and wiki/ in the next conversation, it can start working already knowing "last week's decisions," "the approach that failed once," and "the current state of the three projects running in parallel." That's an external long-term memory that doesn't forget when the conversation ends — a prerequisite for getting Claude Code to perform at its actual potential. The data the script handles flows through the following four layers. 【層1】Claude Code セッションログ(セッション終了時にStop hookが書き出し) ↓ extract conversations.py(step1: 最新化) 【層2】~/Documents/my-knowledge-base/raw/conversations/ ↓ claude -p(step2a: Claude由来ログを消化, timeout 1500s) ~/Documents/my-knowledge-base/raw/codex-conversations/ ↓ claude -p(step2b: Codex由来ログを消化, timeout 1500s) 【層3】Obsidian Vault(~/Documents/claude-obsidian/wiki/) ├── hot.md(直近サマリ) ├── index.md(全体目次) ├── projects/ / learning/ / career/ ... (ドメイン別記事) └── today-brief.md(step2.5: 今日の行動提案) ↓ git add -A && git commit && git push 【層4】private repo(安全網: 荒れてもrevert可能) Splitting layer 2 into two lines, "Claude-derived" and "Codex-derived," is a change made on or after 2026-06-11. Originally one line processed everything, but on high-activity days it stopped fitting into the 40-minute timeout window. After the split, each has an independent 1500-second 25-minute timeout, and if one fails the next slot can retry only what's left. Four slots defined in a launchd plist ~/Library/LaunchAgents/com.shun.vault-auto-ingest.plist spend the day repeatedly "retrying until success."