<?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: DESAR DEV RAJEEV</title>
    <description>The latest articles on DEV Community by DESAR DEV RAJEEV (@desar_devrajeev).</description>
    <link>https://dev.to/desar_devrajeev</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%2F3902282%2F041d1ef2-8478-4b41-8c10-2d7eae6836f9.png</url>
      <title>DEV Community: DESAR DEV RAJEEV</title>
      <link>https://dev.to/desar_devrajeev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/desar_devrajeev"/>
    <language>en</language>
    <item>
      <title>How I Traced Investigation Context Across Incidents With Hindsight</title>
      <dc:creator>DESAR DEV RAJEEV</dc:creator>
      <pubDate>Tue, 29 Sep 2026 16:30:29 +0000</pubDate>
      <link>https://dev.to/desar_devrajeev/how-i-traced-investigation-context-across-incidents-with-hindsight-cg6</link>
      <guid>https://dev.to/desar_devrajeev/how-i-traced-investigation-context-across-incidents-with-hindsight-cg6</guid>
      <description>&lt;h1&gt;
  
  
  &lt;strong&gt;# How I Traced Investigation Context Across Incidents With Hindsight&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;A security alert is rarely interesting in isolation. The useful question is usually, “Have I seen this pattern before, and what happened when I did?”&lt;/p&gt;

&lt;p&gt;That question became the design constraint behind CyberMemory AI. I built the system around a simple idea: an incident-response agent should not have to rediscover the same investigation every time an alert arrives. It should be able to retain what happened, retrieve the parts that matter to a new alert, and use that history when deciding what to investigate next.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdkdlso19tqcr94x3y83k.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdkdlso19tqcr94x3y83k.jpeg" alt=" " width="800" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CyberMemory&lt;br&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F71rdje9d4xycoh0ifpy8.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F71rdje9d4xycoh0ifpy8.jpeg" alt=" " width="800" height="384"&gt;&lt;/a&gt; AI takes security alerts such as repeated failed logins, suspicious activity, or a potential malware detection and turns them into an investigation workflow.&lt;/p&gt;

&lt;p&gt;The application has three important paths.&lt;/p&gt;

&lt;p&gt;First, an alert enters the investigation layer. The agent normalizes the event, identifies the important entities and signals, and asks what context is available from previous incidents.&lt;/p&gt;

&lt;p&gt;Second, the memory layer searches historical incidents. I use Hindsight as persistent memory rather than treating the language model's context window as the application's memory. Hindsight exposes three core operations that fit this workflow well: retain information, recall relevant memories, and reflect over those memories to produce a contextual answer. Its recall path combines multiple retrieval strategies, including semantic, keyword, graph, and temporal retrieval.&lt;/p&gt;

&lt;p&gt;Third, the investigation result is presented as a report. The report includes a summary of the alert, related incidents, possible causes, and recommended investigation or remediation steps. When the incident is resolved, I write the outcome back to memory.&lt;/p&gt;

&lt;p&gt;That last step is the part that changes the system over time.&lt;/p&gt;

&lt;p&gt;The application is not simply doing retrieval-augmented generation over a static knowledge base. The incident itself becomes part of the future investigation context.&lt;/p&gt;
&lt;h2&gt;
  
  
  The important boundary: an alert is not a memory
&lt;/h2&gt;

&lt;p&gt;One of the design decisions I cared about early was separating the current alert from historical experience.&lt;/p&gt;

&lt;p&gt;Suppose I receive this:&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;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"failed_login"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"alex"&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_ip"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"10.20.14.8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"attempts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"window"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"4 minutes"&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;The alert is evidence about something happening now. It should not automatically become a conclusion.&lt;/p&gt;

&lt;p&gt;I first turn it into an investigation query that contains the signals that matter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
Investigate this security alert.

Type: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
User: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
Source IP: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;source_ip&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
Attempts: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;attempts&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
Time window: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;

Find previous incidents with similar authentication behavior,
including their root causes, investigation steps, and outcomes.
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That distinction sounds small, but it keeps the memory layer from becoming a dumping ground for raw alerts. Hindsight's &lt;code&gt;retain&lt;/code&gt; operation is designed to process content into structured memories rather than merely storing text verbatim, which is useful here because an incident contains facts, observations, entities, and experience that may be useful in different future investigations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why persistent memory changed the investigation flow
&lt;/h2&gt;

&lt;p&gt;Without persistent memory, an LLM-based incident assistant has a familiar failure mode: every investigation starts from the same blank page.&lt;/p&gt;

&lt;p&gt;The model may know general security practices. It may even produce a reasonable checklist. But it does not automatically know that our environment has already seen this exact combination of signals three times, that two cases were caused by a misconfigured identity provider, and that another was a compromised credential.&lt;/p&gt;

&lt;p&gt;That information lives in incident history.&lt;/p&gt;

&lt;p&gt;I use a dedicated Hindsight memory bank for the incident-response context:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;hindsight_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Hindsight&lt;/span&gt;

&lt;span class="n"&gt;memory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Hindsight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;HINDSIGHT_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;HINDSIGHT_API_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;BANK_ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cybermemory-incidents&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a new investigation, I can recall historical experience before asking the reasoning layer to produce its report:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;memories&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;bank_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;BANK_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&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="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;memories&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is where Hindsight is more useful to me than simply putting embeddings into a vector database and doing one nearest-neighbor search.&lt;/p&gt;

&lt;p&gt;Security incidents have relationships that are not purely semantic.&lt;/p&gt;

&lt;p&gt;A previous incident may involve the same user, source IP range, hostname, malware family, authentication provider, or sequence of events. It may also matter because it happened recently, or because it represents a repeated operational pattern. Hindsight's multi-strategy recall is designed to combine semantic, keyword, graph, and temporal signals before returning a ranked result set.&lt;/p&gt;

&lt;p&gt;For incident response, that combination is a much better fit than assuming “similar wording” means “similar incident.”&lt;/p&gt;

&lt;h2&gt;
  
  
  I also wanted the reasoning to stay grounded
&lt;/h2&gt;

&lt;p&gt;Retrieval gives me evidence. It does not, by itself, give me an investigation.&lt;/p&gt;

&lt;p&gt;That is where Hindsight's &lt;code&gt;reflect&lt;/code&gt; operation becomes interesting.&lt;/p&gt;

&lt;p&gt;Instead of manually concatenating every recalled memory into a huge prompt, the system can ask Hindsight to reason over the memory bank:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;report&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reflect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;bank_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;BANK_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    Analyze this security alert using relevant historical incidents.

    Current alert:
    &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;

    Explain:
    1. Which previous incidents are relevant
    2. What patterns are repeated
    3. What possible causes should be investigated
    4. What evidence should be collected next
    5. What remediation actions were effective previously
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The distinction between &lt;code&gt;recall&lt;/code&gt; and &lt;code&gt;reflect&lt;/code&gt; is useful architecturally. Recall gives the application retrieved memory results; reflect synthesizes an answer from the memory context. Hindsight documents reflect as an agentic reasoning operation that searches memory and produces a grounded response.&lt;/p&gt;

&lt;p&gt;I use that distinction deliberately.&lt;/p&gt;

&lt;p&gt;When I need to show an analyst the underlying historical evidence, I want recall. When I need a coherent investigation narrative, I want reflection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing the loop after remediation
&lt;/h2&gt;

&lt;p&gt;The most important write happens after the alert is resolved.&lt;/p&gt;

&lt;p&gt;An incident record contains more than the initial detection. It has the root cause, investigation path, actions taken, and outcome.&lt;/p&gt;

&lt;p&gt;I retain that resolved experience as a single incident context:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;incident_memory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
Incident ID: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;incident&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
Alert type: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;incident&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;alert_type&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
Observed behavior: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;incident&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;summary&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;

Root cause:
&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;incident&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;root_cause&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;

Investigation:
&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;incident&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;investigation_steps&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;

Actions taken:
&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;incident&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;actions_taken&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;

Outcome:
&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;incident&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;outcome&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

&lt;span class="n"&gt;memory&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="n"&gt;bank_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;BANK_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;incident_memory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;resolved security incident&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;incident_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;incident&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;alert_type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;incident&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;alert_type&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;This is the part I consider the real feedback loop.&lt;/p&gt;

&lt;p&gt;If a failed-login incident is eventually confirmed as an identity-provider synchronization problem, I do not want the next investigation to see only the original alert. I want it to have access to the resolution.&lt;/p&gt;

&lt;p&gt;That makes the historical record operationally useful.&lt;/p&gt;

&lt;p&gt;I also keep the incident identity and metadata separate from the prose itself. The prose gives Hindsight enough context to extract meaningful memories, while the metadata gives the application stable identifiers for tracing the result back to the incident record.&lt;/p&gt;

&lt;h2&gt;
  
  
  A concrete investigation
&lt;/h2&gt;

&lt;p&gt;Imagine the first incident contains 17 failed logins from one source address. The analyst investigates the identity provider and finds that a synchronization job repeatedly retried an expired credential. The incident is resolved by fixing the service credential and restarting the affected synchronization process.&lt;/p&gt;

&lt;p&gt;Two weeks later, another alert arrives with a similar pattern.&lt;/p&gt;

&lt;p&gt;A stateless assistant might produce a generic list:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;check whether the account is compromised&lt;/li&gt;
&lt;li&gt;inspect source IP reputation&lt;/li&gt;
&lt;li&gt;review authentication logs&lt;/li&gt;
&lt;li&gt;reset credentials&lt;/li&gt;
&lt;li&gt;check for lateral movement&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those are reasonable checks, but they are not particularly specific.&lt;/p&gt;

&lt;p&gt;With persistent incident memory, the investigation can surface the earlier resolution and say, in effect: this pattern resembles a previously resolved authentication incident; that incident was traced to a synchronization credential rather than interactive credential abuse; inspect the corresponding identity-provider logs and service-account activity before treating this as an account compromise.&lt;/p&gt;

&lt;p&gt;That is the behavior I was aiming for.&lt;/p&gt;

&lt;p&gt;The memory does not replace evidence collection. It changes the order in which I look for evidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  The dashboard is deliberately boring
&lt;/h2&gt;

&lt;p&gt;The dashboard is organized around the things an incident responder actually needs to see: current alerts, investigation reports, resolved incidents, and incident history.&lt;/p&gt;

&lt;p&gt;I did not want the UI to become another abstraction over the investigation. A responder should be able to open an alert, see the current analysis, inspect related historical incidents, and understand what was eventually recorded as the resolution.&lt;/p&gt;

&lt;p&gt;The most useful screen is therefore not “AI output.” It is the chain connecting:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;alert → investigation → historical context → resolution → retained experience&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That chain is what makes the system inspectable.&lt;/p&gt;

&lt;p&gt;It also makes mistakes easier to correct. If the agent recommends the wrong next step, I can trace whether the problem came from the alert normalization, historical retrieval, or reasoning over the retrieved context.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I learned
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Memory quality matters more than memory volume
&lt;/h3&gt;

&lt;p&gt;My first instinct was to retain everything. That is the wrong abstraction.&lt;/p&gt;

&lt;p&gt;An incident contains lots of operational noise: repeated log lines, temporary identifiers, routine status messages, and details that are irrelevant outside the original investigation.&lt;/p&gt;

&lt;p&gt;The useful memory is the part that explains what happened and why.&lt;/p&gt;

&lt;p&gt;That is why I treat a resolved incident as a structured experience with context, cause, actions, and outcome rather than blindly storing every event.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Retrieval should be part of the investigation, not an afterthought
&lt;/h3&gt;

&lt;p&gt;It is tempting to generate the LLM report first and attach memory afterward.&lt;/p&gt;

&lt;p&gt;I found the opposite architecture more useful.&lt;/p&gt;

&lt;p&gt;The investigation should start by asking what the system already knows. Historical context can change which hypotheses are worth investigating, which logs deserve attention, and which remediation actions have already worked.&lt;/p&gt;

&lt;p&gt;Memory therefore belongs before reasoning, not after it.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. &lt;code&gt;recall&lt;/code&gt; and &lt;code&gt;reflect&lt;/code&gt; solve different problems
&lt;/h3&gt;

&lt;p&gt;I do not treat them as interchangeable.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;recall&lt;/code&gt; is useful when I need evidence: which previous incidents were related, what facts were stored, and what context was attached.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;reflect&lt;/code&gt; is useful when I need synthesis: given the available experience, what should I understand about this case?&lt;/p&gt;

&lt;p&gt;Keeping those responsibilities separate also makes the application easier to debug.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. The resolution is often more valuable than the alert
&lt;/h3&gt;

&lt;p&gt;An alert tells me what the detector noticed.&lt;/p&gt;

&lt;p&gt;A resolved incident tells me what the organization learned.&lt;/p&gt;

&lt;p&gt;That distinction is why the write-back path is a first-class part of CyberMemory AI rather than an optional analytics feature.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Persistent memory changes what an agent can be
&lt;/h3&gt;

&lt;p&gt;The interesting part of an incident-response agent is not that it can summarize a log file. LLMs are already good at summarization.&lt;/p&gt;

&lt;p&gt;The harder engineering problem is continuity.&lt;/p&gt;

&lt;p&gt;I want the system to be able to say, “We have seen something like this before,” and then make that statement useful by pointing to what happened, what was learned, and what should be checked now.&lt;/p&gt;

&lt;p&gt;That is the role I am using Hindsight for.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/Vedanth-Rach/Cybermemory" rel="noopener noreferrer"&gt;Hindsight GitHub repository&lt;/a&gt; and &lt;a href="https://hindsight.vectorize.io/" rel="noopener noreferrer"&gt;Hindsight documentation&lt;/a&gt; are useful references for the underlying memory model and API. The broader idea is also captured well in Vectorize's explanation of &lt;a href="https://vectorize.io/what-is-agent-memory" rel="noopener noreferrer"&gt;agent memory for persistent context&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For CyberMemory AI, persistent memory is not a feature bolted onto an otherwise stateless chatbot. It is the mechanism that connects one incident to the next.&lt;/p&gt;

&lt;p&gt;That connection is where the system becomes substantially more useful: not because it remembers everything, but because it can remember the parts of previous investigations that change how I investigate the next one.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Building Neuro-Morph: A Python Full-Stack AI App Using MongoDB</title>
      <dc:creator>DESAR DEV RAJEEV</dc:creator>
      <pubDate>Thu, 30 Apr 2026 14:26:16 +0000</pubDate>
      <link>https://dev.to/desar_devrajeev/building-neuro-morpha-python-full-stack-ai-app-using-mongodb-fdj</link>
      <guid>https://dev.to/desar_devrajeev/building-neuro-morpha-python-full-stack-ai-app-using-mongodb-fdj</guid>
      <description>&lt;p&gt;Written By &lt;a href="https://dev.to/mahendra_1907"&gt;Mahendra&lt;/a&gt;, &lt;a href="https://dev.to/desar_devrajeev"&gt;Dev Rajeev&lt;/a&gt;, &lt;a href="https://dev.to/nihal_max"&gt;Nihal&lt;/a&gt;&lt;br&gt;
Guided By &lt;a href="https://dev.to/chanda_rajkumar"&gt;Chanda Rajkumar&lt;/a&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%2Fionoh28n0f49zazvlcd8.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%2Fionoh28n0f49zazvlcd8.jpg" alt=" " width="800" height="383"&gt;&lt;/a&gt;&lt;br&gt;
**&lt;/p&gt;

&lt;h2&gt;
  
  
  WHY PYTHON END-TO-END?
&lt;/h2&gt;

&lt;p&gt;**&lt;/p&gt;

&lt;p&gt;When the Neuro-Morph team chose their language, the answer was deliberate: Python end-to-end. Python sits at a rare intersection — dominant in machine learning, mature in web frameworks, and deeply integrated with container orchestration tooling. A single language across every layer means minimal glue code, zero context-switching overhead, and a unified type system from the API boundary all the way down to the RL training loop.&lt;/p&gt;

&lt;p&gt;**&lt;/p&gt;

&lt;h2&gt;
  
  
  TECH STACK OVERVIEW
&lt;/h2&gt;

&lt;p&gt;**&lt;/p&gt;

&lt;p&gt;API — FastAPI&lt;br&gt;
Async REST endpoints, Pydantic validation, zero-config OpenAPI docs&lt;/p&gt;

&lt;p&gt;ML — PyTorch&lt;br&gt;
DQN RL agent training &amp;amp; inference with dynamic computation graphs&lt;/p&gt;

&lt;p&gt;QUEUE — Celery + Redis&lt;br&gt;
Async mutation task dispatch, retry logic, result backend&lt;/p&gt;

&lt;p&gt;OPS — Docker + K8s&lt;br&gt;
Minimal multi-stage images, Python operators via kopf&lt;/p&gt;

&lt;p&gt;OBS — Prometheus + Grafana&lt;br&gt;
Metrics scraping, alerting rules, real-time dashboards&lt;/p&gt;

&lt;p&gt;CI/CD — GitHub Actions&lt;br&gt;
Lint → test → build → push in under four minutes&lt;/p&gt;

&lt;p&gt;TEST — Pytest + Hypothesis&lt;br&gt;
**&lt;/p&gt;

&lt;h2&gt;
  
  
  [API LAYER] FastAPI in Production
&lt;/h2&gt;

&lt;p&gt;**&lt;/p&gt;

&lt;p&gt;The control plane backbone is FastAPI, chosen over Flask for three non-negotiable reasons: native async/await, automatic request validation via Pydantic, and zero-effort OpenAPI documentation. For a system that dispatches mutation commands with millisecond responsiveness, synchronous WSGI was simply not an option.&lt;br&gt;
Mutation Endpoint&lt;/p&gt;

&lt;p&gt;Below is the core endpoint that receives a trigger from the RL engine and dispatches it as an async Celery task:&lt;br&gt;
from fastapi import FastAPI, HTTPException&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`from pydantic import BaseModel
from app.tasks import dispatch_mutation

app = FastAPI(title='Neuro-Morph Control API', version='1.0')

class MutationRequest(BaseModel):
    action: str          # e.g. 'rotate_port', 'redeploy_container'
    target_service: str
    priority: int = 1

@app.post('/mutations/dispatch')
async def trigger_mutation(req: MutationRequest):
    if req.priority not in range(1, 4):
        raise HTTPException(status_code=422, detail='Priority must be 1-3')
    task = dispatch_mutation.delay(req.action, req.target_service)
    return {'task_id': task.id, 'status': 'queued'}`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Pydantic's BaseModel validates incoming JSON, converts types, and returns structured 422 errors — all with zero boilerplate. The endpoint is a pure async function, freeing the event loop while Celery handles the heavy lifting in the background worker pool.&lt;/p&gt;

&lt;p&gt;**&lt;/p&gt;

&lt;h2&gt;
  
  
  [ML LAYER] The PyTorch RL Agent
&lt;/h2&gt;

&lt;p&gt;**&lt;/p&gt;

&lt;p&gt;The Reinforcement Learning engine is Neuro-Morph's most Python-native component. Built in PyTorch with a Deep Q-Network (DQN) architecture, the agent continuously learns the optimal mutation policy from environment interactions. PyTorch was chosen over TensorFlow for its dynamic computation graph, which makes rapid policy experimentation significantly easier.&lt;/p&gt;

&lt;p&gt;RL Module Structure&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;neuro_morph/rl/
  ├── agent.py         # DQN: select_action(), learn(), update_target()
  ├── environment.py   # Gym-compatible: step(), reset(), observation_space
  ├── replay_buffer.py # Experience replay: push(), sample(batch_size)
  ├── reward.py        # Shaping: attack_blocked, service_uptime
  ├── train.py         # Episode runner, checkpoint saving
  └── serve.py         # Inference server: load model, expose predict(state)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The DQN Agent Core&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`import torch, torch.nn as nn

class DQNAgent(nn.Module):
    def __init__(self, state_dim: int, action_dim: int):
        super().__init__()
        self.net = nn.Sequential(
            nn.Linear(state_dim, 128), nn.ReLU(),
            nn.Linear(128, 128),       nn.ReLU(),
            nn.Linear(128, action_dim)
        )

    def forward(self, state: torch.Tensor) -&amp;gt; torch.Tensor:
        return self.net(state)   # Q-values for each action

    def select_action(self, state, epsilon=0.05):
        if torch.rand(1).item() &amp;lt; epsilon:
            return torch.randint(self.net[-1].out_features, (1,)).item()
        with torch.no_grad():
            return self.forward(state).argmax().item()`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The state vector encodes real-time metrics: connection anomaly scores, port scan frequency, CPU/memory deltas, and recent mutation history. The action space maps to concrete operations — port rotation, container redeploy, IP swap, API key refresh, TLS certificate cycle. Rewards balance two competing objectives: maximize attack disruption while minimizing legitimate traffic latency.&lt;/p&gt;

&lt;p&gt;Dev Tip: Use torch.jit.script() to compile your trained DQN to TorchScript before serving — it cuts inference latency by 30–40% and removes the Python GIL bottleneck in high-throughput environments.&lt;/p&gt;

&lt;p&gt;[TASK QUEUE] Celery + Redis&lt;/p&gt;

&lt;p&gt;Mutation operations are never executed synchronously inside the API request lifecycle. Redeploying a container or rotating a port can take several seconds — blocking an async FastAPI handler would be wasteful and unpredictable. The solution: a Celery task queue backed by Redis, which decouples command dispatch from command execution.&lt;/p&gt;

&lt;p&gt;` # app/tasks.py&lt;br&gt;
    from celery import Celery&lt;br&gt;
    from app.orchestrator import KubernetesOrchestrator&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;celery_app = Celery('neuro_morph', broker='redis://redis:6379/0')
k8s = KubernetesOrchestrator()

@celery_app.task(bind=True, max_retries=3, default_retry_delay=5)
def dispatch_mutation(self, action: str, service: str):
    try:
        if action == 'redeploy_container':
            k8s.rolling_restart(service)
        elif action == 'rotate_port':
            k8s.patch_service_port(service)
        return {'status': 'success', 'action': action}
    except Exception as exc:
        raise self.retry(exc=exc)`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Celery's bind=True pattern gives the task access to its own context for retry logic. With max_retries=3 and exponential backoff, transient Kubernetes API errors are handled gracefully without manual intervention. Redis serves double duty — broker for task messages and result backend for task status queries from the monitoring dashboard.&lt;/p&gt;




&lt;p&gt;**&lt;/p&gt;

&lt;h2&gt;
  
  
  [INFRA] Docker, Kubernetes &amp;amp; Python Operators
&lt;/h2&gt;

&lt;p&gt;**&lt;/p&gt;

&lt;p&gt;Every Neuro-Morph service is packaged as a minimal Docker image built from python:3.11-slim. Multi-stage builds keep production images under 180 MB — the build stage installs all dependencies; the runtime stage copies only the compiled application.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`# Stage 1 — Build
FROM python:3.11-slim AS builder
WORKDIR /build
COPY requirements.txt .
RUN pip install --prefix=/install --no-cache-dir -r requirements.txt

# Stage 2 — Runtime
FROM python:3.11-slim
WORKDIR /app
COPY --from=builder /install /usr/local
COPY . .
EXPOSE 8000
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Kubernetes mutations are applied via a custom operator written in Python using the kopf framework. The operator watches for MutationEvent custom resources and applies rolling restarts, network policy patches, and config map updates. It runs as a standard Deployment using in-cluster service account credentials — no external access required. Kopf handles leader election, retry logic, and structured logging, keeping the operator code focused purely on business logic.&lt;/p&gt;




&lt;p&gt;**&lt;/p&gt;

&lt;h2&gt;
  
  
  [TESTING] Pytest, Fixtures &amp;amp; Mocking
&lt;/h2&gt;

&lt;p&gt;**&lt;/p&gt;

&lt;p&gt;Neuro-Morph uses Pytest as the sole test runner across all layers, with four distinct test categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unit Tests — individual RL agent methods, reward functions, and API validators in isolation using mock Kubernetes clients and synthetic state tensors.&lt;/li&gt;
&lt;li&gt;Integration Tests — spin up a test FastAPI app with TestClient, verify that POST /mutations/dispatch correctly enqueues a Celery task and returns the expected task ID.&lt;/li&gt;
&lt;li&gt;Property-Based Tests — use Hypothesis to generate random state vectors and verify that the DQN agent always returns a valid action index.&lt;/li&gt;
&lt;li&gt;End-to-End Tests — a Docker Compose environment with a stubbed Kubernetes API server runs full mutation cycles, verifying observable state changes within defined time bounds.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# tests/test_api.py
&lt;/span&gt;    &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fastapi.testclient&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TestClient&lt;/span&gt;
    &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;unittest.mock&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;patch&lt;/span&gt;
    &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;app.main&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;

    &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;TestClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nd"&gt;@patch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;app.tasks.dispatch_mutation.delay&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_mutation_dispatch_queues_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mock_delay&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;mock_delay&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;return_value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;abc-123&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
        &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/mutations/dispatch&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;action&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;rotate_port&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;target_service&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;api-gateway&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;priority&lt;/span&gt;&lt;span class="sh"&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="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;
        &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;task_id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;abc-123&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
        &lt;span class="n"&gt;mock_delay&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assert_called_once_with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;rotate_port&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;api-gateway&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Coverage Target: 90% on API and task layers, 80% on the RL module. Use pytest-cov with --fail-under=80 in CI to enforce the floor and prevent regressions from sneaking into main.&lt;/p&gt;

&lt;p&gt;Github Repository:-&lt;a href="https://github.com/N1hal-tech/Neuro-Morph" rel="noopener noreferrer"&gt;https://github.com/N1hal-tech/Neuro-Morph&lt;/a&gt;&lt;/p&gt;

</description>
      <category>edgecomputing</category>
      <category>backend</category>
      <category>systemdesign</category>
      <category>mongodb</category>
    </item>
  </channel>
</rss>
