<?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: Rakshith Reddy</title>
    <description>The latest articles on DEV Community by Rakshith Reddy (@rakshith_reddy_02).</description>
    <link>https://dev.to/rakshith_reddy_02</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4150435%2F399c112c-f34d-49aa-b19b-5147c9f760c7.jpg</url>
      <title>DEV Community: Rakshith Reddy</title>
      <link>https://dev.to/rakshith_reddy_02</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rakshith_reddy_02"/>
    <language>en</language>
    <item>
      <title>I Stored Lessons, Not Incidents, in Hindsight</title>
      <dc:creator>Rakshith Reddy</dc:creator>
      <pubDate>Tue, 29 Sep 2026 17:03:47 +0000</pubDate>
      <link>https://dev.to/rakshith_reddy_02/i-stored-lessons-not-incidents-in-hindsight-684</link>
      <guid>https://dev.to/rakshith_reddy_02/i-stored-lessons-not-incidents-in-hindsight-684</guid>
      <description>&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our worst Friday deploys all had the same shape, and nobody noticed until we made a memory system say it out loud. The postmortems were fine. The problem was that nobody rereads a postmortem before the next risky change.&lt;/p&gt;

&lt;p&gt;So I built Preflight, a service that sits in front of risky changes (deploys, migrations, architecture changes) and checks the plan against what the organization has already learned the hard way. The memory layer is &lt;a href="https://github.com/vectorize-io/hindsight" rel="noopener noreferrer"&gt;Hindsight&lt;/a&gt;, an open-source agent memory system. This post is about the one design decision that shaped everything else: the unit of memory is the lesson extracted from an experience, not the raw incident.&lt;/p&gt;

&lt;p&gt;What Preflight does&lt;/p&gt;

&lt;p&gt;You describe a plan in plain text: "Friday deploy of Billing API + 3 dependency updates." Preflight then does the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Extracts two to six short trigger conditions from the plan (&lt;code&gt;Friday deploy&lt;/code&gt;, &lt;code&gt;dependency updates&lt;/code&gt;, &lt;code&gt;bundled changes&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Builds three or four recall queries from the plan and those conditions, and runs them against Hindsight.&lt;/li&gt;
&lt;li&gt;Merges and de-dupes what comes back.&lt;/li&gt;
&lt;li&gt;Asks an LLM to judge the plan using &lt;em&gt;only&lt;/em&gt; the recalled memories, and to return a structured verdict with cited event IDs.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The backend is a small Node/TypeScript Express app. It holds every Hindsight and Groq call, and the frontend only talks to my own &lt;code&gt;/api/*&lt;/code&gt; routes, so no key ever reaches a browser. There is no database. Hindsight is the only place anything is remembered, and the &lt;a href="https://hindsight.vectorize.io/" rel="noopener noreferrer"&gt;Hindsight docs&lt;/a&gt; describe the three operations I lean on: &lt;code&gt;retain&lt;/code&gt; to write, &lt;code&gt;recall&lt;/code&gt; to search, and &lt;code&gt;reflect&lt;/code&gt; to reason across what's stored.&lt;/p&gt;

&lt;p&gt;Alongside the preflight check, the app has an Ask History tab that reconstructs what happened in past events, a Patterns tab that surfaces recurring failures, and a form for adding new experiences.&lt;/p&gt;

&lt;p&gt;The through-line: what is a memory?&lt;/p&gt;

&lt;p&gt;The first version of my design retained postmortems verbatim. It failed quickly, and the reason is instructive.&lt;/p&gt;

&lt;p&gt;A postmortem is written for people who were there. It has a timeline, quoted chat messages, and three paragraphs of context that only make sense if you remember the week. If you retain that as-is and later ask whether a Friday deploy with dependency bumps is risky, retrieval has to find the one sentence that matters inside a wall of narrative. The memory that does surface is whichever document happened to use similar words, not whichever one carries the relevant insight.&lt;/p&gt;

&lt;p&gt;The useful part of an incident is what the organization learned. So I extract that first, in a fixed shape, and retain &lt;em&gt;that&lt;/em&gt;:&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lessonRecord&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Ev&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="s2"&gt;`LESSON RECORD &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;x&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; | Type: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; | Date: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
Situation: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;situation&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; | Believed: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;what_people_believed&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; | Decision: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;decision&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; | What happened: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;what_happened&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; |
Root cause: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;root_cause&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; | Recovery: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;recovery&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; | LESSON: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lesson&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; | Trigger conditions: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trigger_conditions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;; &lt;/span&gt;&lt;span class="dl"&gt;"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two fields carry most of the weight.&lt;/p&gt;

&lt;p&gt;Believed records what people thought at the time. For the dependency incident it reads roughly "minor version bumps are safe; one release is cheaper than four." That belief is what a new plan is most likely to repeat, so it deserves to be recalled on its own terms, separate from the outcome.&lt;/p&gt;

&lt;p&gt;Trigger conditions are short phrases: &lt;code&gt;Friday deploy&lt;/code&gt;, &lt;code&gt;dependency updates&lt;/code&gt;, &lt;code&gt;batch window 01:00-04:00&lt;/code&gt;, &lt;code&gt;shared IOPS&lt;/code&gt;. At check time, I extract the same kind of phrases from the incoming plan and use them as recall queries. The plan and the memory end up described in the same vocabulary, which does more for retrieval quality than any amount of prompt tuning on the judge.&lt;/p&gt;

&lt;p&gt;Counter-examples are memories too&lt;/p&gt;

&lt;p&gt;If you only retain failures, the judge can only say "this resembles a past failure." That yields a system that refuses to let anyone do anything on a Friday, and people stop reading it within a week.&lt;/p&gt;

&lt;p&gt;So I also retain the cases where the scary-looking thing went fine. One record is a Friday deploy behind a feature flag with no dependency changes. Another is a Saturday migration that ran outside the batch window after a load test. They use the same lesson format, with &lt;code&gt;Type: COUNTER-EXAMPLE&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The payoff is in the recommendations. For the Friday plan above, the verdict cites two independent failures (E002 and E003) and points at E010, the flagged deploy that went fine. The advice becomes "separate the dependency update and put the change behind a flag," not "don't deploy on Fridays."&lt;/p&gt;

&lt;p&gt;Recall: several small queries, merged&lt;/p&gt;

&lt;p&gt;One query is rarely enough to cover a plan that touches several risk factors, so each request builds a handful of targeted queries and merges the results:&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="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;recallMany&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;queries&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="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;t0&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;per&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;queries&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="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;q&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;q&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;recall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;q&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;seen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;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;merged&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="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="k"&gt;for &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;p&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;per&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for &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;t&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&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;seen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;seen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="nx"&gt;merged&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&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="na"&gt;queries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;per&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;merged&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;latencyMs&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;t0&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;The raw queries, the raw recalled text and the latency all show up in a permanent Memory panel next to every verdict. When the judge says something surprising, I can open the panel and see whether the memory was missing or the reasoning was wrong. Those are very different bugs, and without the panel they look identical.&lt;/p&gt;

&lt;p&gt;Retain is asynchronous on the server side, so newly written records may not be searchable immediately. After loading history, the UI polls recall for a known seeded fact every five seconds, up to a configured timeout, and shows a progress bar. I would rather show a loading state than let someone run a check against a half-indexed bank and conclude the system is broken.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keeping the judge honest
&lt;/h2&gt;

&lt;p&gt;The judge prompt is where the discipline lives. These are the rules that matter:&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="nx"&gt;Verdicts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;RED&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;plan&lt;/span&gt; &lt;span class="nx"&gt;matches&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="nx"&gt;conditions&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;past&lt;/span&gt; &lt;span class="nx"&gt;failure&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;or&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="nx"&gt;independent&lt;/span&gt; &lt;span class="nx"&gt;failures&lt;/span&gt; &lt;span class="nx"&gt;share&lt;/span&gt; &lt;span class="nx"&gt;one&lt;/span&gt; &lt;span class="nx"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="nx"&gt;YELLOW&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;partial&lt;/span&gt; &lt;span class="nx"&gt;match&lt;/span&gt; &lt;span class="nx"&gt;or&lt;/span&gt; &lt;span class="nx"&gt;mixed&lt;/span&gt; &lt;span class="nx"&gt;outcomes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="nx"&gt;GREEN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;nothing&lt;/span&gt; &lt;span class="nx"&gt;relevant&lt;/span&gt; &lt;span class="nf"&gt;recalled &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="nx"&gt;that&lt;/span&gt; &lt;span class="nx"&gt;absence&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;memory&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;not&lt;/span&gt; &lt;span class="nx"&gt;proof&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;safety&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;
&lt;span class="nx"&gt;Always&lt;/span&gt; &lt;span class="nx"&gt;look&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;explain&lt;/span&gt; &lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nf"&gt;evidence &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;similar&lt;/span&gt; &lt;span class="nx"&gt;situations&lt;/span&gt; &lt;span class="nx"&gt;that&lt;/span&gt; &lt;span class="nx"&gt;went&lt;/span&gt; &lt;span class="nx"&gt;fine&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;
&lt;span class="nx"&gt;Treat&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;PREFLIGHT OUTCOME&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;records&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;evidence&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model may use only what recall returned and must cite event IDs. GREEN is deliberately worded as "nothing relevant was recalled," never "this is safe." A memory system can only warn you about what it has seen, and the output should say so.&lt;/p&gt;

&lt;p&gt;There is also a Memory OFF switch. With it off, the same plan goes to the LLM with no recall and comes back as a generic "looks reasonable" answer, labeled as using no organizational memory. That comparison is the fastest way I know to show a skeptical teammate what the memory is contributing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Warnings that got ignored become evidence
&lt;/h2&gt;

&lt;p&gt;The part I care about most is the feedback loop. Under every verdict there are buttons: "We changed the plan" or "We're proceeding anyway," and later "It went fine" or "It failed." Each click retains a record:&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;const&lt;/span&gt; &lt;span class="nx"&gt;rec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`PREFLIGHT OUTCOME | Plan: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;plan&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; | Verdict: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;verdict&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; | Cited: &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;cited&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="p"&gt;[]).&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; | Action: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;not recorded&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; | Result: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pending&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; | Note: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;note&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; | Date: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;slice&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="mi"&gt;10&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;hs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;retain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rec&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`outcome-&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="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because these land in the same bank as the lessons, later recalls can surface them, and the judge prompt treats them as evidence. If someone overrode a RED and the deploy failed, the next similar plan gets a higher-confidence warning that cites that outcome. If a warning was overridden and things went fine, that shows up too, and it should temper the next verdict.&lt;/p&gt;

&lt;p&gt;I picked this design so the memory bank wouldn't stay frozen at whatever I seeded on day one. The system's own track record goes into the same store as everything else, and I didn't have to build a second store for it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Patterns: asking the memory instead of counting
&lt;/h2&gt;

&lt;p&gt;The Patterns tab asks one question: what mistakes are we at risk of repeating? I send that to Hindsight's &lt;code&gt;reflect&lt;/code&gt;, then convert the result into structured patterns with a title, supporting event IDs, a failure count and a preventive rule.&lt;/p&gt;

&lt;p&gt;If &lt;code&gt;reflect&lt;/code&gt; errors or returns nothing useful, the server falls back to broad recall plus LLM clustering by shared trigger condition, and the UI states which path ran. I didn't want a silent fallback to make one path look like the other.&lt;/p&gt;

&lt;p&gt;On our history, three clusters emerge: Friday deploys that change dependencies, datastore work without rehearsal or a load test, and architecture changes that shipped without documenting an operational constraint such as ordering, a shared transaction or an eviction policy. The last one now has a concrete rule attached: write an ADR before the change, not after the revert.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd tell someone building this
&lt;/h2&gt;

&lt;p&gt;Decide what a memory is before you write to the store. Everything downstream (recall quality, judge reasoning, the Patterns view) got easier once each record was a lesson with explicit trigger conditions.&lt;/p&gt;

&lt;p&gt;Retain the boring cases and the near-misses. Counter-examples are what make warnings specific enough to act on.&lt;/p&gt;

&lt;p&gt;Make memory visible. A panel showing raw queries, recalled text and latency turns "the AI said something odd" into a debuggable problem.&lt;/p&gt;

&lt;p&gt;Let your own outputs become memories. Outcome records cost almost nothing to write and change how the next judgment goes.&lt;/p&gt;

&lt;p&gt;Refuse to fake the memory layer.If a call fails, the UI shows the real error. There are no canned verdicts anywhere in the codebase. That rule caught integration problems early, because there was nothing to hide them.&lt;/p&gt;

&lt;p&gt;If you're thinking about agent memory more broadly, Vectorize's overview of &lt;a href="https://vectorize.io/what-is-agent-memory" rel="noopener noreferrer"&gt;agent memory&lt;/a&gt; is a good place to see how retain, recall and reflect fit together. The &lt;a href="https://github.com/vectorize-io/hindsight" rel="noopener noreferrer"&gt;Hindsight GitHub repository&lt;/a&gt; has the client library and self-hosting instructions, which I'd look at if you'd rather keep the memory bank in your own environment.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>llm</category>
      <category>antigravity</category>
    </item>
  </channel>
</rss>
