<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: thebasedcapital</title>
    <description>The latest articles on DEV Community by thebasedcapital (@thebasedcapital).</description>
    <link>https://dev.to/thebasedcapital</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3784949%2F74b67061-660f-40d5-a598-e795f5f78598.png</url>
      <title>DEV Community: thebasedcapital</title>
      <link>https://dev.to/thebasedcapital</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thebasedcapital"/>
    <language>en</language>
    <item>
      <title>Why Your Overnight AI Agent Fails (And How Episodic Execution Fixes It)</title>
      <dc:creator>thebasedcapital</dc:creator>
      <pubDate>Mon, 23 Feb 2026 04:12:14 +0000</pubDate>
      <link>https://dev.to/thebasedcapital/why-your-overnight-ai-agent-fails-and-how-episodic-execution-fixes-it-2g50</link>
      <guid>https://dev.to/thebasedcapital/why-your-overnight-ai-agent-fails-and-how-episodic-execution-fixes-it-2g50</guid>
      <description>&lt;h1&gt;
  
  
  Why Your Overnight AI Agent Fails (And How Episodic Execution Fixes It)
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;How I built Nightcrawler -- an autonomous agent loop that runs Claude Code for 12+ hours with structured handoffs, crash recovery, and 8 termination conditions.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;You go to bed. Claude Code is humming along, refactoring your test suite. You set it loose with &lt;code&gt;--dangerously-skip-permissions&lt;/code&gt; and a prayer. You wake up 8 hours later.&lt;/p&gt;

&lt;p&gt;What do you find?&lt;/p&gt;

&lt;p&gt;If you are lucky: a completed task. If you are unlucky -- and I was unlucky many times -- you find one of these six disasters.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 6 Death Spirals of Long-Running AI Agents
&lt;/h2&gt;

&lt;p&gt;Every developer who has tried to run an AI coding agent overnight has hit at least one of these:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The Context Cliff
&lt;/h3&gt;

&lt;p&gt;After 30-60 minutes of work, the model's effective context fills up. It starts forgetting what it did earlier. It re-reads files it already processed. It contradicts decisions it made 20 minutes ago. Eventually it starts undoing its own work.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The Hallucinated Handoff
&lt;/h3&gt;

&lt;p&gt;The agent writes "I completed tasks 1-5" in its output. You check git. Tasks 2 and 4 were never actually done. The agent's self-assessment diverged from reality because it lost track of what it actually committed versus what it planned to do.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. The Budget Inferno
&lt;/h3&gt;

&lt;p&gt;You wake up to a $200 API bill. The agent hit a hard problem, generated massive prompts trying to solve it, and burned through your budget in a single multi-turn loop. No circuit breaker. No budget cap per work unit.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. The Infinite Retry Loop
&lt;/h3&gt;

&lt;p&gt;The agent encounters a flaky test. It tries to fix it. The fix breaks something else. It tries to fix that. The original test fails again. Three hours later, it is still cycling between the same two broken states with zero net progress.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. The Silent Crash
&lt;/h3&gt;

&lt;p&gt;The process dies at 2 AM -- an OOM kill, a network timeout, a macOS sleep event. Nobody notices. When you wake up, you find a half-finished refactor with uncommitted changes and no record of what was accomplished.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. The Drift Spiral
&lt;/h3&gt;

&lt;p&gt;The agent starts with clear intent. By hour 3, it has wandered so far from the original mission that it is adding features nobody asked for, refactoring code that was fine, and creating documentation files for a project that does not exist.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Simple Loops Do Not Work
&lt;/h2&gt;

&lt;p&gt;The most popular approach to overnight agents is some variant of this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;claude &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"Continue working on the project. If done, output DONE."&lt;/span&gt;
  &lt;span class="c"&gt;# check for DONE, maybe sleep, repeat&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the &lt;a href="https://ghuntley.com/loop/" rel="noopener noreferrer"&gt;Ralph Wiggum technique&lt;/a&gt;, popularized by Geoffrey Huntley. It is elegant. It works for short tasks. But it has a fundamental assumption that breaks down overnight: &lt;strong&gt;it assumes each iteration starts fresh and can pick up from filesystem state alone.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For a 30-minute task, that is fine. For a 12-hour mission, you need more:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What was the agent working on when it stopped?&lt;/li&gt;
&lt;li&gt;What decisions did it make and why?&lt;/li&gt;
&lt;li&gt;What did it try that failed?&lt;/li&gt;
&lt;li&gt;How much budget has been spent?&lt;/li&gt;
&lt;li&gt;Is the agent still making progress, or is it spinning?&lt;/li&gt;
&lt;li&gt;Did git actually change, or did the agent just claim it did?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A simple loop cannot answer these questions. That is the gap Nightcrawler fills.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Solution: Episodic Execution
&lt;/h2&gt;

&lt;p&gt;Nightcrawler does not try to keep one session alive forever. It accepts that sessions will end and builds reliability around that inevitability.&lt;/p&gt;

&lt;p&gt;The core idea: &lt;strong&gt;bounded episodes with structured handoffs.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Mission.md
    |
    v
[Orchestrator] -----&amp;gt; [Episode 1: claude -p] -----&amp;gt; HANDOFF.md
    |                                                    |
    |  &amp;lt;-- read state, check termination conditions --   |
    |                                                    v
    +----------------&amp;gt; [Episode 2: claude -p] -----&amp;gt; HANDOFF.md
    |                                                    |
    |  &amp;lt;-- read state, check budget, detect stalling --  |
    |                                                    v
    +----------------&amp;gt; [Episode 3: claude -p] -----&amp;gt; HANDOFF.md
    |                                                    |
    ...                                                  |
    v                                                    v
COMPLETION_REPORT.md                              STATE.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each episode is a fresh &lt;code&gt;claude -p&lt;/code&gt; session that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Reads the mission (what to do)&lt;/li&gt;
&lt;li&gt;Reads the handoff from the previous episode (what was done, what is next)&lt;/li&gt;
&lt;li&gt;Verifies via &lt;code&gt;git log&lt;/code&gt; and &lt;code&gt;git diff&lt;/code&gt; that the handoff is truthful&lt;/li&gt;
&lt;li&gt;Works on the highest-priority incomplete task&lt;/li&gt;
&lt;li&gt;Writes a structured handoff for the next episode&lt;/li&gt;
&lt;li&gt;Updates state (progress, errors, budget)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The orchestrator sits between episodes and decides: continue, or stop?&lt;/p&gt;




&lt;h2&gt;
  
  
  Architecture: ~500 Lines of TypeScript
&lt;/h2&gt;

&lt;p&gt;Nightcrawler is a single TypeScript file (&lt;code&gt;nightcrawler.ts&lt;/code&gt;, ~500 LOC) that orchestrates everything:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// The main loop is deceptively simple&lt;/span&gt;
&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;cont&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reason&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;shouldContinue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;cont&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Write completion report and exit&lt;/span&gt;
    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;buildEpisodePrompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;episodeNum&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;exitCode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;runEpisode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;episodeNum&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Re-read state (agent may have updated it)&lt;/span&gt;
  &lt;span class="c1"&gt;// Track episode in history&lt;/span&gt;
  &lt;span class="c1"&gt;// Handle errors&lt;/span&gt;
  &lt;span class="c1"&gt;// Checkpoint&lt;/span&gt;
  &lt;span class="c1"&gt;// Cooldown&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Episode Prompt
&lt;/h3&gt;

&lt;p&gt;Each episode receives a carefully constructed prompt that includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The skill instructions (how to behave as an autonomous agent)&lt;/li&gt;
&lt;li&gt;The mission (what to accomplish)&lt;/li&gt;
&lt;li&gt;The current state (progress, budget, errors)&lt;/li&gt;
&lt;li&gt;The previous handoff (what was done, what is next)&lt;/li&gt;
&lt;li&gt;The git context (recent commits, diff)&lt;/li&gt;
&lt;li&gt;A task tracker (immutable tasks.json the agent can only mark complete)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;buildEpisodePrompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;State&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;episodeNum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mission&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;readText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MISSION_PATH&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handoff&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fileExists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;HANDOFF_PATH&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nf"&gt;readText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;HANDOFF_PATH&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Include git context for truth-checking&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;gitLog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;execSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;git log --oneline -10&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;diff&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;execSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;git diff --stat HEAD~1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// Build structured prompt with all context&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The 8 Termination Conditions
&lt;/h3&gt;

&lt;p&gt;The orchestrator checks these before every episode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;shouldContinue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;State&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// 1. Human stop flag (touch ~/.nightcrawler/state/STOP)&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fileExists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;STOP_FLAG&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;cont&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;human_stop_flag&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="c1"&gt;// 2. Agent said stop (mission complete or blocked)&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;termination_check&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;should_continue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;cont&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;agent_terminated&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="c1"&gt;// 3. Episode limit (default: 24)&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current_episode&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;max_episodes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;cont&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;episode_limit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="c1"&gt;// 4. Duration limit (default: 12 hours)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;elapsed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;started&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;elapsed&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;max_duration_hours&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;cont&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;duration_limit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="c1"&gt;// 5. Budget limit (default: $50)&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;budget_spent_usd&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;max_budget_usd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;cont&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;budget_limit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="c1"&gt;// 6. Error threshold (default: 10 errors)&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error_threshold&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;cont&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;error_threshold&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="c1"&gt;// 7. Fatal error&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fatal&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;cont&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fatal_error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="c1"&gt;// 8. Diminishing returns (&amp;lt; 0.5 tasks/episode for 3 consecutive)&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;avgCompleted&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;cont&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;diminishing_returns&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;cont&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That eighth condition -- diminishing returns detection -- is the one that prevents death spiral #4 (the infinite retry loop). If the agent completes less than half a task per episode for three episodes in a row, something is wrong and Nightcrawler stops.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Handoff Protocol
&lt;/h3&gt;

&lt;p&gt;Every episode must write a structured &lt;code&gt;HANDOFF.md&lt;/code&gt; before finishing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Episode 3 Handoff&lt;/span&gt;

&lt;span class="gu"&gt;## Summary&lt;/span&gt;
Implemented the authentication middleware and wrote 12 tests.
All tests passing. Rate limiting is next.

&lt;span class="gu"&gt;## Work Completed&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Created auth/middleware.ts with JWT validation
&lt;span class="p"&gt;-&lt;/span&gt; Added 12 test cases in auth/middleware.test.ts
&lt;span class="p"&gt;-&lt;/span&gt; Updated routes/api.ts to use the middleware

&lt;span class="gu"&gt;## In-Progress Work&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; File: auth/rate-limiter.ts
&lt;span class="p"&gt;-&lt;/span&gt; What's left: Implement sliding window rate limiting

&lt;span class="gu"&gt;## Key Context for Next Episode&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; JWT secret is loaded from env var AUTH_SECRET
&lt;span class="p"&gt;-&lt;/span&gt; The middleware expects Bearer tokens, not Basic auth
&lt;span class="p"&gt;-&lt;/span&gt; rate-limiter.ts exists but is empty scaffolding

&lt;span class="gu"&gt;## Files Modified&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; auth/middleware.ts: new file, JWT validation
&lt;span class="p"&gt;-&lt;/span&gt; auth/middleware.test.ts: new file, 12 tests
&lt;span class="p"&gt;-&lt;/span&gt; routes/api.ts: added authMiddleware to all /api/&lt;span class="err"&gt;*&lt;/span&gt; routes

&lt;span class="gu"&gt;## Decisions Made&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Used jose library over jsonwebtoken: async-first, better types

&lt;span class="gu"&gt;## Errors Encountered&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; None this episode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This handoff is not optional. The skill instructions loaded into every episode enforce it. And the orchestrator cross-checks it against &lt;code&gt;git log&lt;/code&gt; in the next episode's prompt -- the agent cannot claim it changed files that git says were not modified.&lt;/p&gt;

&lt;h3&gt;
  
  
  Process Supervision with launchd
&lt;/h3&gt;

&lt;p&gt;Nightcrawler runs under macOS launchd, which provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Crash recovery:&lt;/strong&gt; If the process dies, launchd restarts it (with a 30-second throttle)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sleep/wake handling:&lt;/strong&gt; launchd manages macOS sleep events correctly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Background execution:&lt;/strong&gt; Runs with &lt;code&gt;Nice: 5&lt;/code&gt; (lower priority) and &lt;code&gt;ProcessType: Background&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hard timeout:&lt;/strong&gt; 12-hour maximum via &lt;code&gt;TimeOut: 43200&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Logging:&lt;/strong&gt; stdout/stderr redirected to log files
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;KeepAlive&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;Crashed&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;true/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;SuccessfulExit&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;false/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The process also uses a PID-based lockfile to prevent duplicate instances:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;acquireLock&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fileExists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;LOCK_PATH&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;readText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;LOCK_PATH&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
      &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;kill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Check if still alive&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Still running&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;STALE_LOCK | Removing stale lockfile&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nf"&gt;writeFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;LOCK_PATH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Task Immutability: Preventing Cheating
&lt;/h2&gt;

&lt;p&gt;One subtle but critical design decision: &lt;code&gt;tasks.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When a mission starts, the orchestrator extracts all &lt;code&gt;- [ ]&lt;/code&gt; checkboxes from &lt;code&gt;MISSION.md&lt;/code&gt; and writes them to &lt;code&gt;tasks.json&lt;/code&gt;. The agent may ONLY change the &lt;code&gt;passes&lt;/code&gt; field from &lt;code&gt;false&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt;. It cannot delete tasks, reorder them, rename them, or add new ones.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Create auth middleware"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"passes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Write auth tests"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"passes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Implement rate limiting"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"passes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Add API documentation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"passes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why? Because overnight agents will try to redefine the mission to match what they actually accomplished. Task immutability prevents that.&lt;/p&gt;




&lt;h2&gt;
  
  
  Comparison: Nightcrawler vs Ralph Loop vs Continuous Claude
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Nightcrawler&lt;/th&gt;
&lt;th&gt;Ralph Loop&lt;/th&gt;
&lt;th&gt;Continuous Claude&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Core approach&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Bounded episodes&lt;/td&gt;
&lt;td&gt;Infinite loop&lt;/td&gt;
&lt;td&gt;CI/CD loop&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Context management&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Structured handoffs&lt;/td&gt;
&lt;td&gt;Filesystem only&lt;/td&gt;
&lt;td&gt;PR-based&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Crash recovery&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;launchd + checkpoints&lt;/td&gt;
&lt;td&gt;Manual restart&lt;/td&gt;
&lt;td&gt;GitHub Actions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Budget tracking&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Per-episode + total cap&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Cost limit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Stall detection&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Diminishing returns algo&lt;/td&gt;
&lt;td&gt;Completion promise&lt;/td&gt;
&lt;td&gt;Iteration limit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Termination&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;8 conditions&lt;/td&gt;
&lt;td&gt;2 conditions&lt;/td&gt;
&lt;td&gt;3 conditions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Truth checking&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Git diff vs handoff&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;PR review&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Process supervision&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;launchd (macOS native)&lt;/td&gt;
&lt;td&gt;tmux/screen&lt;/td&gt;
&lt;td&gt;Cloud CI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Notifications&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Mobile push (Moshi)&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;GitHub notifications&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Task immutability&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;tasks.json (flip-only)&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Ralph Loop&lt;/strong&gt; is perfect for tasks that fit in a single session with a few retries. If your task is "fix this bug and run tests until they pass," Ralph is the right tool.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nightcrawler&lt;/strong&gt; is for when you want to hand the machine a 12-hour research mission or a 50-task implementation plan and walk away. The episodic architecture handles all the failure modes that destroy simple loops over extended runs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Continuous Claude&lt;/strong&gt; sits between them -- it is a CI/CD-style loop that creates PRs, waits for checks, and merges. It is great for teams that want autonomous contributions that go through their normal review process.&lt;/p&gt;




&lt;h2&gt;
  
  
  Mission Templates
&lt;/h2&gt;

&lt;p&gt;Nightcrawler ships with two mission templates:&lt;/p&gt;

&lt;h3&gt;
  
  
  Research Mission (breadth -&amp;gt; depth -&amp;gt; synthesis)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Mission: [Research Topic]&lt;/span&gt;

&lt;span class="gs"&gt;**Type:**&lt;/span&gt; research
&lt;span class="gs"&gt;**Max Duration:**&lt;/span&gt; 12 hours
&lt;span class="gs"&gt;**Max Episodes:**&lt;/span&gt; 24

&lt;span class="gu"&gt;## Depth Targets&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Survey the landscape: identify all major players and approaches
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Deep-dive: [subtopic 1]
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Deep-dive: [subtopic 2]
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Cross-reference: identify contradictions between sources
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Synthesize: write final analysis with confidence levels
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Bibliography: all sources cited with URLs

&lt;span class="gu"&gt;## Source Requirements&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Minimum 10 unique sources
&lt;span class="p"&gt;-&lt;/span&gt; At least 3 academic papers
&lt;span class="p"&gt;-&lt;/span&gt; Flag any claim with only 1 source as [UNVERIFIED]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Implementation Mission
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Mission: [Feature Name]&lt;/span&gt;

&lt;span class="gs"&gt;**Type:**&lt;/span&gt; implementation
&lt;span class="gs"&gt;**Max Duration:**&lt;/span&gt; 12 hours
&lt;span class="gs"&gt;**Max Episodes:**&lt;/span&gt; 24

&lt;span class="gu"&gt;## Tasks&lt;/span&gt;
&lt;span class="p"&gt;1.&lt;/span&gt; - [ ] [Task 1]
&lt;span class="p"&gt;   -&lt;/span&gt; Files: [likely files]
&lt;span class="p"&gt;   -&lt;/span&gt; Success criteria: [how to verify]
&lt;span class="p"&gt;
2.&lt;/span&gt; - [ ] [Task 2]
&lt;span class="p"&gt;   -&lt;/span&gt; Files: [likely files]
&lt;span class="p"&gt;   -&lt;/span&gt; Success criteria: [how to verify]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Claude Code CLI installed (&lt;code&gt;claude&lt;/code&gt; command available)&lt;/li&gt;
&lt;li&gt;macOS (for launchd supervision) or any Unix system (run directly)&lt;/li&gt;
&lt;li&gt;Node.js 18+ (for tsx)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Clone&lt;/span&gt;
git clone https://github.com/thebasedcapital/nightcrawler.git ~/.nightcrawler
&lt;span class="nb"&gt;cd&lt;/span&gt; ~/.nightcrawler

&lt;span class="c"&gt;# Install dependencies&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt;

&lt;span class="c"&gt;# Write your mission&lt;/span&gt;
&lt;span class="nb"&gt;cp &lt;/span&gt;templates/MISSION-research.md missions/active/MISSION.md
&lt;span class="c"&gt;# Edit MISSION.md with your actual mission&lt;/span&gt;

&lt;span class="c"&gt;# Configure (optional -- defaults are sane)&lt;/span&gt;
&lt;span class="c"&gt;# Edit config.json to set budget, duration, model, etc.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Run
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Direct run (stays in terminal)&lt;/span&gt;
npx tsx nightcrawler.ts

&lt;span class="c"&gt;# Dry run (see what would happen without spending money)&lt;/span&gt;
npx tsx nightcrawler.ts &lt;span class="nt"&gt;--dry-run&lt;/span&gt;

&lt;span class="c"&gt;# With launchd (survives terminal close, crash recovery)&lt;/span&gt;
&lt;span class="nb"&gt;cp &lt;/span&gt;com.user.nightcrawler.plist ~/Library/LaunchAgents/
launchctl load ~/Library/LaunchAgents/com.user.nightcrawler.plist
launchctl start com.user.nightcrawler
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Monitor
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Watch logs&lt;/span&gt;
&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; ~/.nightcrawler/logs/orchestrator.log

&lt;span class="c"&gt;# Check state&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; ~/.nightcrawler/state/STATE.json | jq &lt;span class="s1"&gt;'.progress'&lt;/span&gt;

&lt;span class="c"&gt;# Emergency stop&lt;/span&gt;
&lt;span class="nb"&gt;touch&lt;/span&gt; ~/.nightcrawler/state/STOP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configuration
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Setting&lt;/th&gt;
&lt;th&gt;Default&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;max_duration_hours&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;Hard time limit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;max_episodes&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;td&gt;Maximum episode count&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;max_budget_usd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;td&gt;Total cost cap&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;budget_per_episode_usd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Per-episode cost cap&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;episode_timeout_seconds&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;3600&lt;/td&gt;
&lt;td&gt;Single episode timeout&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;model&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;claude-opus-4-6&lt;/td&gt;
&lt;td&gt;Model for episodes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;error_threshold&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;Max errors before stopping&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cooldown_between_episodes_seconds&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;Pause between episodes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  What Happens When You Wake Up
&lt;/h2&gt;

&lt;p&gt;When Nightcrawler finishes (by any of the 8 termination conditions), it writes a completion report:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Nightcrawler Completion Report&lt;/span&gt;

&lt;span class="gs"&gt;**Mission:**&lt;/span&gt; auth-system-implementation
&lt;span class="gs"&gt;**Status:**&lt;/span&gt; COMPLETED
&lt;span class="gs"&gt;**Reason:**&lt;/span&gt; mission_complete
&lt;span class="gs"&gt;**Started:**&lt;/span&gt; 2026-02-21T23:00:00Z
&lt;span class="gs"&gt;**Ended:**&lt;/span&gt; 2026-02-22T06:45:00Z
&lt;span class="gs"&gt;**Episodes:**&lt;/span&gt; 8
&lt;span class="gs"&gt;**Budget:**&lt;/span&gt; $18.50 of $50.00
&lt;span class="gs"&gt;**Tasks:**&lt;/span&gt; 6/6 completed

&lt;span class="gu"&gt;## Episode History&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Episode 1: exit=0, tasks_completed=1, duration=45m
&lt;span class="p"&gt;-&lt;/span&gt; Episode 2: exit=0, tasks_completed=1, duration=38m
&lt;span class="p"&gt;-&lt;/span&gt; Episode 3: exit=0, tasks_completed=1, duration=52m
&lt;span class="p"&gt;-&lt;/span&gt; Episode 4: exit=1, tasks_completed=0, duration=12m (flaky test, recovered)
&lt;span class="p"&gt;-&lt;/span&gt; Episode 5: exit=0, tasks_completed=1, duration=41m
&lt;span class="p"&gt;-&lt;/span&gt; Episode 6: exit=0, tasks_completed=1, duration=35m
&lt;span class="p"&gt;-&lt;/span&gt; Episode 7: exit=0, tasks_completed=1, duration=28m
&lt;span class="p"&gt;-&lt;/span&gt; Episode 8: exit=0, tasks_completed=0, duration=15m (final verification)

&lt;span class="gu"&gt;## Errors&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Total: 1
&lt;span class="p"&gt;-&lt;/span&gt; Recovered: 1
&lt;span class="p"&gt;-&lt;/span&gt; Fatal: 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You also get a push notification on your phone (via Moshi) when it completes, errors, or stops.&lt;/p&gt;




&lt;h2&gt;
  
  
  Design Principles
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Sessions will end. Build around that.&lt;/strong&gt; Do not fight context limits. Embrace bounded episodes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Verify, do not trust.&lt;/strong&gt; Cross-check handoffs against git. The agent's self-report is evidence, not truth.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Fail safely.&lt;/strong&gt; 8 termination conditions, budget caps, error thresholds, human stop flag. The default behavior on any unexpected state is to stop, not to continue.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Immutable contracts.&lt;/strong&gt; The agent cannot redefine the mission. tasks.json is a one-way ratchet: tasks can be completed, never removed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Observable at all times.&lt;/strong&gt; STATE.json, PROGRESS.jsonl, per-episode logs, per-episode checkpoints. If something goes wrong at 3 AM, you can reconstruct exactly what happened.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Native OS integration.&lt;/strong&gt; launchd is not just a convenience -- it is a reliability mechanism. It handles crashes, sleep/wake, and process lifecycle better than any userspace solution.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Credits and Acknowledgments
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Geoffrey Huntley&lt;/strong&gt; (&lt;a href="https://x.com/GeoffreyHuntley" rel="noopener noreferrer"&gt;@GeoffreyHuntley&lt;/a&gt;) for creating the &lt;a href="https://ghuntley.com/loop/" rel="noopener noreferrer"&gt;Ralph Wiggum technique&lt;/a&gt; that proved autonomous agent loops are useful and inspired this project.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Boris Cherny&lt;/strong&gt; (&lt;a href="https://x.com/bcherny" rel="noopener noreferrer"&gt;@bcherny&lt;/a&gt;) for building Claude Code and the &lt;code&gt;-p&lt;/code&gt; flag that makes headless operation possible.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anthropic&lt;/strong&gt; for Claude and the Claude Code CLI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anand Chowdhary&lt;/strong&gt; (&lt;a href="https://github.com/AnandChowdhary" rel="noopener noreferrer"&gt;@AnandChowdhary&lt;/a&gt;) for &lt;a href="https://github.com/AnandChowdhary/continuous-claude" rel="noopener noreferrer"&gt;Continuous Claude&lt;/a&gt;, which showed the CI/CD approach to autonomous loops.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Multi-model support:&lt;/strong&gt; Use different models for different episode types (Sonnet for simple tasks, Opus for complex ones)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linux systemd support:&lt;/strong&gt; Equivalent to launchd for Linux servers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Web dashboard:&lt;/strong&gt; Real-time monitoring of mission progress in the browser&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mission chaining:&lt;/strong&gt; Output of one mission feeds into the next&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost estimation:&lt;/strong&gt; Predict budget usage before starting based on mission complexity&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Nightcrawler is open source. If you run Claude Code for more than an hour at a time, give it a try.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you have questions or want to share how your overnight mission went, find me on &lt;a href="https://github.com/thebasedcapital/nightcrawler" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; or &lt;a href="https://x.com/thebasedcapital" rel="noopener noreferrer"&gt;X/Twitter&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; #claude #ai #agents #automation #typescript #devtools&lt;/p&gt;

</description>
      <category>claude</category>
      <category>ai</category>
      <category>agents</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Why I Ditched RAG for Hebbian Synapses (and My Agent Actually Got Faster)</title>
      <dc:creator>thebasedcapital</dc:creator>
      <pubDate>Sun, 22 Feb 2026 11:32:55 +0000</pubDate>
      <link>https://dev.to/thebasedcapital/why-i-ditched-rag-for-hebbian-synapses-and-my-agent-actually-got-faster-22f3</link>
      <guid>https://dev.to/thebasedcapital/why-i-ditched-rag-for-hebbian-synapses-and-my-agent-actually-got-faster-22f3</guid>
      <description>&lt;p&gt;Every agent memory system I tried follows the same playbook: embed text into vectors, store them in a database, cosine search on recall. It works for storing facts. But my Claude Code agent kept doing the same dumb thing — grepping for &lt;code&gt;auth.ts&lt;/code&gt; every single session, even though I open it 10 times a day.&lt;/p&gt;

&lt;p&gt;The problem: RAG gives agents &lt;em&gt;declarative&lt;/em&gt; memory (facts). It doesn't give them &lt;em&gt;procedural&lt;/em&gt; memory (learned behavior). No amount of vector embeddings will teach an agent that &lt;code&gt;auth.ts&lt;/code&gt; and &lt;code&gt;session.ts&lt;/code&gt; always go together.&lt;/p&gt;

&lt;h2&gt;
  
  
  The neuroscience answer
&lt;/h2&gt;

&lt;p&gt;Real brains don't embed memories into vectors. They form synaptic connections through repeated co-activation. Donald Hebb described this in 1949: "neurons that fire together wire together."&lt;/p&gt;

&lt;p&gt;I built &lt;a href="https://github.com/thebasedcapital/brainbox" rel="noopener noreferrer"&gt;BrainBox&lt;/a&gt; to apply this to coding agents.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;BrainBox has three primitives:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Neurons&lt;/strong&gt; — represent files, tools, and errors. Created automatically when your agent interacts with them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Synapses&lt;/strong&gt; — connections between neurons. When you access &lt;code&gt;auth.ts&lt;/code&gt; then &lt;code&gt;session.ts&lt;/code&gt; within the same session, a synapse forms. Access them together 10 more times and the synapse strengthens.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Myelination&lt;/strong&gt; — real neurons wrap frequently-used axons in myelin sheaths for faster signal propagation. BrainBox does the same: once a synapse crosses a threshold, it becomes a "superhighway" — instant recall, maximum confidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  The math (simplified)
&lt;/h2&gt;

&lt;p&gt;Synapse strengthening uses &lt;strong&gt;SNAP sigmoid plasticity&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;delta = learning_rate * sigmoid_gain(current_weight)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where &lt;code&gt;sigmoid_gain&lt;/code&gt; makes strong synapses resist further strengthening (prevents any single connection from dominating). This mirrors real synaptic saturation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Spreading activation&lt;/strong&gt; (Collins &amp;amp; Loftus, 1975):&lt;/p&gt;

&lt;p&gt;When you recall &lt;code&gt;auth.ts&lt;/code&gt;, BrainBox activates it, then propagates activation to connected neurons through 2-hop BFS. Each hop decays by &lt;code&gt;1/sqrt(degree)&lt;/code&gt; (Anderson's fan effect). Files 2 hops away get weaker activation than direct neighbors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Decay&lt;/strong&gt; follows Ebbinghaus forgetting curves — unused connections weaken naturally:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Activation: -15% per cycle&lt;/li&gt;
&lt;li&gt;Synapses: -2% per cycle&lt;/li&gt;
&lt;li&gt;Myelination: -0.5% per cycle&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Results from production
&lt;/h2&gt;

&lt;p&gt;After 5 hours of real Claude Code usage:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;79 neurons&lt;/strong&gt;, 3,554 synapses formed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;67% top-1 recall accuracy&lt;/strong&gt; (the first file recalled was the right one)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;8.9% gross token savings&lt;/strong&gt; (fewer grep/search operations)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;lt;5ms recall latency&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;3 superhighways formed naturally&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;brainbox-hebbian
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Auto-configures Claude Code hooks. Works with any MCP agent. Full whitepaper in the repo.&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/thebasedcapital/brainbox" rel="noopener noreferrer"&gt;github.com/thebasedcapital/brainbox&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not both?
&lt;/h2&gt;

&lt;p&gt;BrainBox is &lt;em&gt;complementary&lt;/em&gt; to RAG, not a replacement. RAG handles L2 (declarative facts). BrainBox handles L3 (behavioral patterns). The 4-layer memory model:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;What&lt;/th&gt;
&lt;th&gt;Examples&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;L1&lt;/td&gt;
&lt;td&gt;Buffer&lt;/td&gt;
&lt;td&gt;Context window, chat history&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;L2&lt;/td&gt;
&lt;td&gt;Declarative&lt;/td&gt;
&lt;td&gt;Mem0, Zep, SuperMemory (facts/conversations)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;L3&lt;/td&gt;
&lt;td&gt;Procedural&lt;/td&gt;
&lt;td&gt;BrainBox (behavior patterns, muscle memory)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;L4&lt;/td&gt;
&lt;td&gt;Identity&lt;/td&gt;
&lt;td&gt;Personal style, values, habits&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;L3 was empty until now. That's the gap BrainBox fills.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Full algorithm details in &lt;a href="https://github.com/thebasedcapital/brainbox/blob/main/WHITEPAPER.md" rel="noopener noreferrer"&gt;WHITEPAPER.md&lt;/a&gt; — covers SNAP plasticity, BCM theory, spreading activation, error-fix learning, and production benchmarks.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>machinelearning</category>
      <category>agents</category>
    </item>
  </channel>
</rss>
