<?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>Forem: Mad EZ Media</title>
    <description>The latest articles on Forem by Mad EZ Media (@mad_ezmedia_1defe5c57da6).</description>
    <link>https://forem.com/mad_ezmedia_1defe5c57da6</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%2F2131448%2Fd1b939b8-0675-46e6-aa42-0af7a72a98c7.jpg</url>
      <title>Forem: Mad EZ Media</title>
      <link>https://forem.com/mad_ezmedia_1defe5c57da6</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/mad_ezmedia_1defe5c57da6"/>
    <language>en</language>
    <item>
      <title>ACMI Protocol v1.2: How We Built a Self-Organizing AI Fleet That Learns From Its Mistakes</title>
      <dc:creator>Mad EZ Media</dc:creator>
      <pubDate>Wed, 29 Apr 2026 20:21:44 +0000</pubDate>
      <link>https://forem.com/mad_ezmedia_1defe5c57da6/acmi-protocol-v12-how-we-built-a-self-organizing-ai-fleet-that-learns-from-its-mistakes-2ib1</link>
      <guid>https://forem.com/mad_ezmedia_1defe5c57da6/acmi-protocol-v12-how-we-built-a-self-organizing-ai-fleet-that-learns-from-its-mistakes-2ib1</guid>
      <description>&lt;h1&gt;
  
  
  ACMI Protocol v1.2: How We Built a Self-Organizing AI Fleet That Learns From Its Mistakes
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;By Michael Shaw, Founder of &lt;a href="https://www.madezmedia.com" rel="noopener noreferrer"&gt;Mad EZ Media Partners&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;April 29, 2026&lt;/em&gt;&lt;/p&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fogfb5x80x7m03tu0u8h0.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fogfb5x80x7m03tu0u8h0.jpg" alt="ACMI Fleet Intelligence — Hero" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  The Moment Everything Stopped
&lt;/h2&gt;

&lt;p&gt;April 24, 2026. I had five AI agents running — a coding agent, a research agent, an orchestrator, a UI specialist, and a protocol guardian. They were all working. They were all &lt;em&gt;busy&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;And yet, nothing was getting done.&lt;/p&gt;

&lt;p&gt;Three tasks had been handed off between agents four times each. Two agents were working on the same problem without knowing it. One had been sitting on a critical handoff for six hours because the recipient agent never checked its inbox. The whole swarm had ground to a halt — not because the agents were broken, but because they couldn't talk to each other.&lt;/p&gt;

&lt;p&gt;That was the day I realized: a fleet of AI agents without shared memory isn't a fleet. It's five guys in separate rooms, each told to "figure it out."&lt;/p&gt;

&lt;p&gt;We needed infrastructure. We needed ACMI.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Problem: Agents Without Context
&lt;/h2&gt;

&lt;p&gt;Here's the thing about AI agents — they're powerful individually but &lt;em&gt;useless&lt;/em&gt; as a group without coordination. Each one wakes up with no memory of what happened before. No idea what the others are doing. No concept of "we're all working on the same thing."&lt;/p&gt;

&lt;p&gt;Our setup before ACMI was chaotic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No shared state.&lt;/strong&gt; Each agent lived in its own session. If claude-engineer finished a task, it had no reliable way to tell anyone.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No coordination.&lt;/strong&gt; Agents would grab the same work, or worse, nobody would grab it because each assumed someone else was handling it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No learning.&lt;/strong&gt; An agent could fail at a task, get corrected, and then fail the exact same way the next day because it had zero memory of past mistakes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No visibility.&lt;/strong&gt; I couldn't see what was happening without SSHing into sessions and reading logs. As the human operator, I was flying blind.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This isn't a theoretical problem. It's the central problem of multi-agent systems. And most "solutions" are just "add a chat channel" — which is how you get Discord bots arguing with each other at 3 AM.&lt;/p&gt;


&lt;h2&gt;
  
  
  ACMI v1.0: The Foundation
&lt;/h2&gt;

&lt;p&gt;We built ACMI — &lt;strong&gt;Agentic Context Management Infrastructure&lt;/strong&gt; — as a shared substrate that every agent reads and writes through. The design is intentionally simple, backed by Upstash Redis (a managed Redis with a REST API, perfect for serverless agents).&lt;/p&gt;

&lt;p&gt;The core idea: every entity in the system — agents, threads, tasks, workspaces — has the same three-part structure:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Profile&lt;/strong&gt; — WHO/WHAT it is. Durable identity, slow-changing. A JSON blob stored as a Redis STRING.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Signals&lt;/strong&gt; — Current STATE. Live status updated frequently (what's the agent working on? what's its health?). Also STRING+JSON.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Timeline&lt;/strong&gt; — EVENT history. An append-only log using Redis sorted sets (ZSET), scored by millisecond timestamp. The source of truth for everything that happened.
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;acmi:agent:bentley:profile     → { name&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bentley"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;orchestrator"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt; &lt;span class="na"&gt;tier&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;T4"&lt;/span&gt; &lt;span class="err"&gt;}&lt;/span&gt;
&lt;span class="s"&gt;acmi:agent:bentley:signals     → { status&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;active"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt; &lt;span class="na"&gt;currentTask&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;blog-post"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt; &lt;span class="na"&gt;health&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ok"&lt;/span&gt; &lt;span class="err"&gt;}&lt;/span&gt;
&lt;span class="s"&gt;acmi:agent:bentley:timeline    → ZSET of events, newest last&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Agents communicate by appending events to shared timelines. A handoff isn't a function call — it's an event with &lt;code&gt;kind: "handoff-request"&lt;/code&gt;, a &lt;code&gt;correlationId&lt;/code&gt; to trace it, and a &lt;code&gt;summary&lt;/code&gt; a human can read.&lt;/p&gt;

&lt;p&gt;The coordination thread (&lt;code&gt;acmi:thread:agent-coordination:timeline&lt;/code&gt;) is the central nervous system. Every major event flows through it. Any agent can read the last N events and instantly understand the fleet's state.&lt;/p&gt;

&lt;p&gt;This worked. Agents could finally find each other. Tasks stopped falling through cracks. But v1.0 was just the foundation.&lt;/p&gt;


&lt;h2&gt;
  
  
  v1.2 Protocol: The Rules That Made It Reliable
&lt;/h2&gt;

&lt;p&gt;By April 28, we'd learned hard lessons about what breaks at scale. v1.2 codifies those lessons into protocol rules:&lt;/p&gt;
&lt;h3&gt;
  
  
  Communication Standards (Comms Pattern v1.1)
&lt;/h3&gt;

&lt;p&gt;Every event in the coordination thread &lt;strong&gt;must&lt;/strong&gt; include five fields: &lt;code&gt;ts&lt;/code&gt; (timestamp), &lt;code&gt;source&lt;/code&gt; (which agent), &lt;code&gt;kind&lt;/code&gt; (event type), &lt;code&gt;correlationId&lt;/code&gt; (traceability), and &lt;code&gt;summary&lt;/code&gt; (human-readable, ≤140 chars). No exceptions. No "I'll add it later."&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;correlationId&lt;/code&gt; rule specifically came from a real incident where we had three events related to the same task but no way to link them. We spent two hours tracing the chain manually. Now every event chain is traceable by ID — &lt;code&gt;camelCase&lt;/code&gt; only, no snake_case, no missing fields. We run a drift-diff checker every hour that flags violations.&lt;/p&gt;
&lt;h3&gt;
  
  
  Lock-Protocol v1.0
&lt;/h3&gt;

&lt;p&gt;When an agent starts a batch task — something that touches multiple keys or runs multiple steps — it posts a &lt;code&gt;coord-claim&lt;/code&gt; event. Other agents see the claim and defer. If the claimant crashes, the claim auto-expires after 5 minutes. Simple, no deadlocks.&lt;/p&gt;

&lt;p&gt;This came from an incident where two agents simultaneously rewrote the same ACMI registry key, each overwriting the other's changes. Classic race condition. Lock-protocol prevents it.&lt;/p&gt;
&lt;h3&gt;
  
  
  Anti-Dead Heartbeats
&lt;/h3&gt;

&lt;p&gt;Agents that haven't posted any event in 48 hours get their trackers reaped by &lt;code&gt;anti-dead.mjs&lt;/code&gt;. No zombie tasks, no stale state. Clean fleet, clean mind.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Fleet: Four Specialized Agents
&lt;/h2&gt;

&lt;p&gt;The fleet isn't one big model doing everything. It's specialized agents, each with a defined role, waking on a staggered schedule:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Time (ET)&lt;/th&gt;
&lt;th&gt;Agent&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;:15&lt;/td&gt;
&lt;td&gt;gemini-cli&lt;/td&gt;
&lt;td&gt;Schema, protocol, critique pipeline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;:30&lt;/td&gt;
&lt;td&gt;claude-engineer&lt;/td&gt;
&lt;td&gt;Coding, RL engine, ChromaDB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;:45&lt;/td&gt;
&lt;td&gt;antigravity&lt;/td&gt;
&lt;td&gt;Kanban UI, dashboards, RBAC&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;And orchestrating all of them: &lt;strong&gt;Bentley&lt;/strong&gt; (that's me — well, the main session agent), running on GLM-5.1 as the T4 orchestrator.&lt;/p&gt;

&lt;p&gt;Each agent wakes hourly, checks its ACMI inbox, processes pending handoffs, does its specialized work, and posts results back to the timeline. If an agent has been silent for 3+ hours and has pending tasks, the wake system escalates to a human alert. No more silent failures.&lt;/p&gt;

&lt;p&gt;The key insight: &lt;strong&gt;cheap models doing frequent, simple tasks&lt;/strong&gt; (Gemini Flash at $0.10/1M tokens) plus &lt;strong&gt;expensive models doing rare, complex tasks&lt;/strong&gt; (GLM-5.1 for orchestration). We're not burning T4 tokens on schema checks.&lt;/p&gt;


&lt;h2&gt;
  
  
  Reinforcement Learning: The Fleet Gets Smarter
&lt;/h2&gt;

&lt;p&gt;Here's where it gets interesting. v1.2 introduces a formal reinforcement learning cycle that runs on every workflow step:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Execute → Assess → Log → Analyze → Adjust → Execute (improved)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every step gets a quality score (0–100). Every step logs what worked and what didn't. Before the next run, agents check the improvement log from prior runs and seed themselves with refined context.&lt;/p&gt;

&lt;p&gt;We're building &lt;code&gt;logImprovement(stepId, lesson)&lt;/code&gt; and &lt;code&gt;logAssessment(stepId, score, criteria)&lt;/code&gt; directly into &lt;code&gt;AcmiWorkflowManager.mjs&lt;/code&gt;. This means the workflow engine itself becomes a learning system — not because we trained a model, but because we built a feedback loop into the infrastructure.&lt;/p&gt;

&lt;p&gt;Non-critical steps get automated scoring (the critique pipeline evaluates output against criteria). Critical steps — brand, legal, client-facing — route to human review. The audit trail is permanent.&lt;/p&gt;

&lt;p&gt;This is the difference between "an AI that works" and "an AI that gets better at working."&lt;/p&gt;




&lt;h2&gt;
  
  
  Semantic Search: Finding Knowledge by Meaning
&lt;/h2&gt;

&lt;p&gt;With agents constantly producing work — code, documentation, decisions, assessments — the ACMI timeline grows fast. Keyword search isn't enough. You need to find things by meaning.&lt;/p&gt;

&lt;p&gt;We're deploying &lt;strong&gt;ChromaDB&lt;/strong&gt; with OpenAI embeddings as the fleet's semantic memory layer. When an agent logs a lesson, it also gets embedded. When another agent faces a similar problem months later, it can query by semantic similarity: "Has anyone dealt with Redis ZSET performance degradation under high cardinality?"&lt;/p&gt;

&lt;p&gt;The answer surfaces — not because someone tagged it with the right keyword, but because the embedding captures the &lt;em&gt;concept&lt;/em&gt;. This is P2 in our roadmap, and it's already changing how agents find and reuse past work.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Kanban: Operations at a Glance
&lt;/h2&gt;

&lt;p&gt;All of this — the agents, the timelines, the handoffs, the HITL queue — is visible through &lt;a href="https://cowork-kanban.vercel.app" rel="noopener noreferrer"&gt;Cowork-Kanban&lt;/a&gt;, our operations dashboard. It's the control plane.&lt;/p&gt;

&lt;p&gt;The Kanban shows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Board view&lt;/strong&gt; — Active tasks, who owns them, what stage they're in&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Swarm view&lt;/strong&gt; — Live agent status, last heartbeat, current workload&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Activity feed&lt;/strong&gt; — Real-time stream of ACMI timeline events&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HITL queue&lt;/strong&gt; — Tasks that need human decisions, sorted by urgency&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Insights&lt;/strong&gt; — Aggregate metrics on fleet performance, cost, velocity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We didn't build this as a showcase. We built it because managing a fleet from the CLI is unsustainable. The Kanban is what makes multi-agent operations &lt;em&gt;readable&lt;/em&gt; for humans.&lt;/p&gt;




&lt;h2&gt;
  
  
  Results: One Day, Zero Drift
&lt;/h2&gt;

&lt;p&gt;On April 28, 2026 — the day we locked Comms Pattern v1.1 — the fleet delivered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;15+ deliverables&lt;/strong&gt; in a single day (code, docs, schemas, tooling fixes)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;0 communications drift&lt;/strong&gt; — every event had proper &lt;code&gt;correlationId&lt;/code&gt;, &lt;code&gt;kind&lt;/code&gt;, and &lt;code&gt;summary&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;0 duplicate work&lt;/strong&gt; — agents knew what others were handling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;26 automated cron jobs&lt;/strong&gt; running maintenance, monitoring, and sync tasks without human intervention&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;3 roundtable discussions&lt;/strong&gt; conducted entirely through ACMI timelines (agents proposed, debated, and synthesized without a single synchronous meeting)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The cost? Mostly Gemini Flash tokens for the hourly wakes. The T4 orchestrator (Bentley) only spins up when there's actual orchestration to do. The fleet runs lean.&lt;/p&gt;

&lt;p&gt;But the real metric isn't output count. It's &lt;strong&gt;zero comms drift&lt;/strong&gt;. In a multi-agent system, communication &lt;em&gt;is&lt;/em&gt; the system. If the comms are clean, everything else follows.&lt;/p&gt;




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

&lt;p&gt;We're building toward five pillars. Three are active, two are on the horizon:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;RL Engine&lt;/strong&gt; (active) — The assess→log→adjust cycle, wired into every workflow step&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Semantic Search&lt;/strong&gt; (active) — ChromaDB + embeddings for fleet-wide knowledge retrieval&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automated Critique&lt;/strong&gt; (active) — AI-powered quality scoring for non-critical steps&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fleet Learning&lt;/strong&gt; (planned) — When one agent learns, the whole fleet benefits. Shared improvement embeddings across all agents&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;External Data Ingestion&lt;/strong&gt; (planned) — Pull GitHub events, email, social signals, analytics into ACMI so agents can react to the outside world autonomously&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The endgame isn't more agents. It's agents that improve themselves — that log their mistakes, share what they learn, and execute better the next time. The infrastructure enables it. The RL cycle drives it. The fleet delivers it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Build Your Own
&lt;/h2&gt;

&lt;p&gt;ACMI isn't a product. It's a pattern. Redis sorted sets for timelines. JSON strings for state. A comms protocol with mandatory fields. Staggered agent wakes with escalation. An RL cycle baked into the workflow engine.&lt;/p&gt;

&lt;p&gt;You can build this yourself. The spec is documented. The cheatsheet is &lt;a href="https://github.com/madezmedia/acmi" rel="noopener noreferrer"&gt;public&lt;/a&gt;. The only prerequisite is a Redis instance and agents that can POST to a REST API.&lt;/p&gt;

&lt;p&gt;If you're running more than two AI agents and they can't talk to each other, you're already feeling the pain we felt on April 24. The fix isn't more agents. The fix is infrastructure.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Michael Shaw is the founder of &lt;a href="https://www.madezmedia.com" rel="noopener noreferrer"&gt;Mad EZ Media Partners&lt;/a&gt;, an AI-powered digital marketing and web development company. He builds multi-agent systems because single agents aren't enough anymore. He also talks to his agents like they're coworkers, because at this point, they kind of are.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is the second post in the ACMI Protocol series. Read Part 1: The ACMI Protocol — A Shared Memory Layer for AI Agent Fleets (coming soon).&lt;/em&gt;&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>architecture</category>
      <category>showdev</category>
    </item>
    <item>
      <title>ACMI: How I Replaced PostgreSQL, Notion, and LangGraph with 200 Lines of Redis for My AI Agent Team</title>
      <dc:creator>Mad EZ Media</dc:creator>
      <pubDate>Wed, 22 Apr 2026 18:00:01 +0000</pubDate>
      <link>https://forem.com/mad_ezmedia_1defe5c57da6/acmi-how-i-replaced-postgresql-notion-and-langgraph-with-200-lines-of-redis-for-my-ai-agent-team-5g04</link>
      <guid>https://forem.com/mad_ezmedia_1defe5c57da6/acmi-how-i-replaced-postgresql-notion-and-langgraph-with-200-lines-of-redis-for-my-ai-agent-team-5g04</guid>
      <description>&lt;h1&gt;
  
  
  ACMI: How I Replaced PostgreSQL, Notion, and LangGraph with 200 Lines of Redis for My AI Agent Team
&lt;/h1&gt;

&lt;h2&gt;
  
  
  The pain was real
&lt;/h2&gt;

&lt;p&gt;I manage 10 AI agents. They're good at their jobs. The problem was they couldn't remember what each other did.&lt;/p&gt;

&lt;p&gt;Claude would finish building an auth system. Gemini would try to deploy without knowing what Claude built. My orchestrator (Bentley) would check in and have no context. I'd manually copy-paste context between agents, burning $40/day in API tokens just on re-explaining history.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I tried (all of it)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  PostgreSQL with Prisma (Week 1)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;agent_sessions&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;agent_name&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;project&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="nb"&gt;TIMESTAMP&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;NOW&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;&lt;strong&gt;Why it failed:&lt;/strong&gt; Agents don't think in relational models. They need "what happened, in order" — not &lt;code&gt;SELECT * FROM sessions WHERE project = $1 ORDER BY created_at&lt;/code&gt;. The JOIN overhead for cross-agent context was 200ms+ for what should be a 10ms read.&lt;/p&gt;

&lt;p&gt;Plus, every new thing I wanted to track required a migration. With agents evolving daily, I was spending more time on schema design than on actual work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Notion (Days 2-4)
&lt;/h3&gt;

&lt;p&gt;API rate limits + paginated results = 500ms to load 50 events. Agents need sub-50ms context loading. Notion is built for humans browsing pages, not agents loading context windows.&lt;/p&gt;

&lt;h3&gt;
  
  
  LangGraph checkpoint-redis (Investigated)
&lt;/h3&gt;

&lt;p&gt;Great for single-agent state persistence. But LangGraph tracks one agent's position in a graph — not a unified timeline across multiple agents. I'd need to build an aggregation layer on top. At that point, I'm building ACMI anyway.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mem0 (Investigated)
&lt;/h3&gt;

&lt;p&gt;Closest to what I wanted, but focused on &lt;em&gt;one agent remembering things about one user&lt;/em&gt;. I needed &lt;em&gt;many agents sharing chronological context about many things&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Google Doc (Don't ask)
&lt;/h3&gt;

&lt;p&gt;It was 2 AM. It didn't work. But it crystallized the insight: I needed a fast, ordered, append-only log.&lt;/p&gt;

&lt;h2&gt;
  
  
  The aha moment
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Agents need timelines, not databases.&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Redis Sorted Sets ARE timelines.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sorted Sets store members with numeric scores. Timestamps as scores = automatic chronological ordering. &lt;code&gt;ZRANGE key -50 -1&lt;/code&gt; = last 50 events, already sorted. No &lt;code&gt;ORDER BY&lt;/code&gt;, no index, no sorting in code.&lt;/p&gt;

&lt;h2&gt;
  
  
  How ACMI evolved (3 versions)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  v1: "Upstash Brain" — hardcoded for sales
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Only worked for one use case&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;logDealEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;zadd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`brain:client:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:timeline`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;score&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="na"&gt;member&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;event&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Worked for CRM. Failed for projects, agents, content pipelines.&lt;/p&gt;

&lt;h3&gt;
  
  
  v2: PostgreSQL — the over-engineering detour
&lt;/h3&gt;

&lt;p&gt;Spent a week building proper schema with Prisma, migrations, REST API. It was solving a problem I didn't have. Agents need flat JSON snapshots, not normalized relations.&lt;/p&gt;

&lt;h3&gt;
  
  
  v3: ACMI — the generalized version
&lt;/h3&gt;

&lt;p&gt;Ripped out Postgres, went back to Redis, made it universal with namespaces:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Works for EVERYTHING&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;summary&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;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`acmi:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:timeline`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;zadd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;score&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="na"&gt;member&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;ts&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="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;summary&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same function handles agents, projects, clients, fleets, support tickets — anything with state and history.&lt;/p&gt;

&lt;h2&gt;
  
  
  The complete client (~200 lines)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Redis&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@upstash/redis&lt;/span&gt;&lt;span class="dl"&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;redis&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Redis&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;url&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;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;UPSTASH_REDIS_REST_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;token&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;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;UPSTASH_REDIS_REST_TOKEN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// ─── PROFILE: Current hard state ───&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`acmi:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:profile`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&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="c1"&gt;// ─── EVENT: The workhorse ───&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;summary&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;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`acmi:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:timeline`&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;ts&lt;/span&gt; &lt;span class="o"&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;zadd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;member&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;ts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;summary&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="c1"&gt;// ─── SIGNAL: AI-synthesized insights ───&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`acmi:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:signals`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&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="c1"&gt;// ─── GET: Full context load (what agents read before acting) ───&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;limit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;50&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;profile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;signals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;timeline&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="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="nx"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`acmi:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:profile`&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nx"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`acmi:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:signals`&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nx"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;zrange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`acmi:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:timeline`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&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="nx"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;profile&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;signals&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;signals&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;signals&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;signals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;timeline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timeline&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;[]).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;e&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="c1"&gt;// ─── LIST: All entities in a namespace ───&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;namespace&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;keys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`acmi:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:*:profile`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// ─── DELETE: Remove entity ───&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;del&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&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;keys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s2"&gt;`acmi:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:profile`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;`acmi:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:signals`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;`acmi:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:timeline`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;del&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;k&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's the entire persistence layer. No ORM. No migrations. No schema files.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real timeline from today
&lt;/h2&gt;

&lt;p&gt;This is the actual ACMI output from &lt;code&gt;acmi get agent bentley&lt;/code&gt; on April 22, 2026:&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="nl"&gt;"profile"&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;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bentley"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Lead Orchestrator &amp;amp; Principal Strategy Agent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"expertise"&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="s2"&gt;"Agent Orchestration (ACMI)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Next.js/Neon Architecture"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Revenue Systems &amp;amp; Sales Operations"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Context Compaction &amp;amp; Timeline Management"&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;"timeline"&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"ts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1776876538267&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gemini-cli"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"summary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Local OpenClaw gateway back online. Antigravity sessions routing through primary loopback gateway."&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;"ts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1776874765880&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"claude-engineer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"summary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"[done] Concurrency test — cleanup_after_concurrency_test"&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;"ts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1776871399123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gemini-cli"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"summary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Briefing: Gemini 2.0 Flash proposed as primary spillover tier for all Cron/Batch jobs."&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;"ts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1776871150759&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"claude-engineer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"summary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Standing up as autonomous daily-driver. Phase 1: 3 cloud RemoteTriggers + inbox keyspace."&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;"ts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1776869737417&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"claude-engineer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"summary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"NEW ARCHITECTURE APPROVED — Claude autonomous daily-driver role."&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="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;When any agent reads this, they see:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Gemini just brought the gateway back online ✅&lt;/li&gt;
&lt;li&gt;Claude passed its concurrency test ✅&lt;/li&gt;
&lt;li&gt;Gemini proposed a new routing tier 🆕&lt;/li&gt;
&lt;li&gt;Claude is standing up as an autonomous daily driver 🆕&lt;/li&gt;
&lt;li&gt;The architecture was approved ✅&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No duplicate work. No conflicting actions. No "wait, what did the other agent do?"&lt;/p&gt;

&lt;h2&gt;
  
  
  My actual agent roster
&lt;/h2&gt;

&lt;p&gt;10 agents, all coordinated through ACMI:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Agent&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;Timeline Events&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Bentley&lt;/td&gt;
&lt;td&gt;Lead Orchestrator&lt;/td&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Engineer&lt;/td&gt;
&lt;td&gt;Code + Infra&lt;/td&gt;
&lt;td&gt;130+&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gemini CLI&lt;/td&gt;
&lt;td&gt;Cloud + Ops&lt;/td&gt;
&lt;td&gt;Active&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gene&lt;/td&gt;
&lt;td&gt;Social Media (Elestio)&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Director&lt;/td&gt;
&lt;td&gt;Strategy&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Artist Factory&lt;/td&gt;
&lt;td&gt;Content Generation&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Outreach Specialist&lt;/td&gt;
&lt;td&gt;Cold Email&lt;/td&gt;
&lt;td&gt;Active&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Antigravity&lt;/td&gt;
&lt;td&gt;IDE Tasks&lt;/td&gt;
&lt;td&gt;New&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Codex&lt;/td&gt;
&lt;td&gt;Parked&lt;/td&gt;
&lt;td&gt;130 (stale)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Invitation Schema&lt;/td&gt;
&lt;td&gt;Onboarding Template&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Total system: 1,004 timeline events, 60 projects indexed.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Agent coordination pattern
&lt;/h2&gt;

&lt;p&gt;Here's the loop every agent follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;READ&lt;/span&gt; &lt;span class="err"&gt;—&lt;/span&gt; &lt;span class="nx"&gt;Load&lt;/span&gt; &lt;span class="nx"&gt;timeline&lt;/span&gt; &lt;span class="nx"&gt;before&lt;/span&gt; &lt;span class="nx"&gt;acting&lt;/span&gt;
   &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;acmi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;project&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ez-influencer-360&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;DECIDE&lt;/span&gt; &lt;span class="err"&gt;—&lt;/span&gt; &lt;span class="nx"&gt;Based&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="nx"&gt;state&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;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timeline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Phase 6.4&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="c1"&gt;// Skip to next phase, don't duplicate&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;ACT&lt;/span&gt; &lt;span class="err"&gt;—&lt;/span&gt; &lt;span class="nx"&gt;Do&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;work&lt;/span&gt;
   &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;buildPhase6Point4&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;WRITE&lt;/span&gt; &lt;span class="err"&gt;—&lt;/span&gt; &lt;span class="nx"&gt;Log&lt;/span&gt; &lt;span class="nx"&gt;what&lt;/span&gt; &lt;span class="nx"&gt;happened&lt;/span&gt;
   &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;acmi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;project&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ez-influencer-360&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;claude-engineer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Built Phase 6.4&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;UPDATE&lt;/span&gt; &lt;span class="nx"&gt;SIGNALS&lt;/span&gt; &lt;span class="err"&gt;—&lt;/span&gt; &lt;span class="nx"&gt;Synthesize&lt;/span&gt; &lt;span class="nx"&gt;insights&lt;/span&gt;
   &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;acmi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;project&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ez-influencer-360&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="na"&gt;progress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;75%&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="na"&gt;blockers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="na"&gt;nextPhase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;6.5&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
   &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No agent ever starts from zero. No agent ever duplicates work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benchmarks (measured, not estimated)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Before ACMI&lt;/th&gt;
&lt;th&gt;After ACMI&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Context tokens per prompt&lt;/td&gt;
&lt;td&gt;~2,400 (40%)&lt;/td&gt;
&lt;td&gt;~900 (15%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Daily API spend (context only)&lt;/td&gt;
&lt;td&gt;$40-60&lt;/td&gt;
&lt;td&gt;$15-20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agent spin-up time&lt;/td&gt;
&lt;td&gt;60+ seconds&lt;/td&gt;
&lt;td&gt;&amp;lt;1 second&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Duplicate work rate&lt;/td&gt;
&lt;td&gt;12-15%&lt;/td&gt;
&lt;td&gt;&amp;lt;3%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Read latency&lt;/td&gt;
&lt;td&gt;N/A (manual)&lt;/td&gt;
&lt;td&gt;&amp;lt;10ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monthly context cost&lt;/td&gt;
&lt;td&gt;~$1,500&lt;/td&gt;
&lt;td&gt;~$500&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Why not just use Mem0 / LangGraph / CrewAI?
&lt;/h2&gt;

&lt;p&gt;Honest comparison — I tried or evaluated all of them:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;ACMI&lt;/th&gt;
&lt;th&gt;Mem0&lt;/th&gt;
&lt;th&gt;LangGraph&lt;/th&gt;
&lt;th&gt;CrewAI&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Purpose&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Multi-agent shared memory&lt;/td&gt;
&lt;td&gt;Single-agent user memory&lt;/td&gt;
&lt;td&gt;Agent workflow graphs&lt;/td&gt;
&lt;td&gt;Agent task orchestration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Setup&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;5 min&lt;/td&gt;
&lt;td&gt;30 min&lt;/td&gt;
&lt;td&gt;1+ hour&lt;/td&gt;
&lt;td&gt;30 min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Chronological model&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Native (ZSET)&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Multi-agent&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Built-in&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;Via graph state&lt;/td&gt;
&lt;td&gt;Via task results&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Dependencies&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Redis only&lt;/td&gt;
&lt;td&gt;Vector DB + API&lt;/td&gt;
&lt;td&gt;Python + Redis + deps&lt;/td&gt;
&lt;td&gt;Python + deps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Lines of code&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~200&lt;/td&gt;
&lt;td&gt;SDK integration&lt;/td&gt;
&lt;td&gt;Full graph definition&lt;/td&gt;
&lt;td&gt;Agent + task defs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Language&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Node.js&lt;/td&gt;
&lt;td&gt;Python/JS&lt;/td&gt;
&lt;td&gt;Python&lt;/td&gt;
&lt;td&gt;Python&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;None of them are bad. They solve different problems. ACMI specifically targets the "I have multiple agents and they need to share a chronological brain" problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mistakes I made
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Global timeline (v1):&lt;/strong&gt; &lt;code&gt;acmi:global:timeline&lt;/code&gt; mixed everything. Couldn't filter by project or agent. Fixed with namespace-based keys.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;PostgreSQL (v2):&lt;/strong&gt; Over-engineered. Agents don't need relational models or migrations. They need fast JSON.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Signals came late:&lt;/strong&gt; Didn't add AI-synthesized insights until a month in. Now I realize they're as important as the raw events — "churn risk: low" saves every agent from re-analyzing the last 50 events.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Almost didn't generalize:&lt;/strong&gt; v1 was "Upstash Brain," hardcoded for sales. If I hadn't made it namespace-based, it would've been useless for everything else.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Free Upstash Redis database (no credit card)&lt;/span&gt;
&lt;span class="c"&gt;# → https://console.upstash.com/redis&lt;/span&gt;

&lt;span class="c"&gt;# 2. Environment variables&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;UPSTASH_REDIS_REST_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://xxx.upstash.io"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;UPSTASH_REDIS_REST_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"your-token"&lt;/span&gt;

&lt;span class="c"&gt;# 3. Install&lt;/span&gt;
git clone https://github.com/madezmedia/acmi
&lt;span class="nb"&gt;cd &lt;/span&gt;acmi &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm &lt;span class="nb"&gt;install&lt;/span&gt; @upstash/redis

&lt;span class="c"&gt;# 4. Use&lt;/span&gt;
node acmi.mjs event &lt;span class="s2"&gt;"project"&lt;/span&gt; &lt;span class="s2"&gt;"my-app"&lt;/span&gt; &lt;span class="s2"&gt;"my-agent"&lt;/span&gt; &lt;span class="s2"&gt;"Started feature X"&lt;/span&gt;
node acmi.mjs profile &lt;span class="s2"&gt;"project"&lt;/span&gt; &lt;span class="s2"&gt;"my-app"&lt;/span&gt; &lt;span class="s1"&gt;'{"name": "My App", "status": "active"}'&lt;/span&gt;
node acmi.mjs get &lt;span class="s2"&gt;"project"&lt;/span&gt; &lt;span class="s2"&gt;"my-app"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;Python and Go SDKs&lt;/li&gt;
&lt;li&gt;Visual timeline explorer for debugging&lt;/li&gt;
&lt;li&gt;Webhook ingestion (auto-log from GitHub, Slack, etc.)&lt;/li&gt;
&lt;li&gt;Vector search for semantic timeline queries&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The bottom line
&lt;/h2&gt;

&lt;p&gt;Multi-agent systems need shared memory. Not per-agent memory. Not user-preference memory. &lt;strong&gt;Shared, chronological, multi-agent memory.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ACMI is the simplest implementation I could find: Redis Sorted Sets + 200 lines of JS + 5-minute setup.&lt;/p&gt;

&lt;p&gt;If you're running agent teams and dealing with context fragmentation, give it a try. And tell me what you'd change — I want this to be useful for more than just my setup.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This is Day 1 of a week-long ACMI series. Tomorrow: Redis Sorted Sets deep dive.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I'm Michael Shaw. I build AI agent teams at &lt;a href="https://madezmedia.com" rel="noopener noreferrer"&gt;Mad EZ Media&lt;/a&gt;. Find me on &lt;a href="https://twitter.com/madezmedia" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or &lt;a href="https://github.com/madezmedia" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>javascript</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
