<?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: Sahil Rakhaiya </title>
    <description>The latest articles on DEV Community by Sahil Rakhaiya  (@sahilrakhaiya).</description>
    <link>https://dev.to/sahilrakhaiya</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%2F960113%2F944feec7-7b95-47d1-92aa-67e02affbc58.png</url>
      <title>DEV Community: Sahil Rakhaiya </title>
      <link>https://dev.to/sahilrakhaiya</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sahilrakhaiya"/>
    <language>en</language>
    <item>
      <title>A cure is not a cure until SigNoz proves it</title>
      <dc:creator>Sahil Rakhaiya </dc:creator>
      <pubDate>Sun, 19 Jul 2026 12:37:37 +0000</pubDate>
      <link>https://dev.to/sahilrakhaiya/a-cure-is-not-a-cure-until-signoz-proves-it-5gjf</link>
      <guid>https://dev.to/sahilrakhaiya/a-cure-is-not-a-cure-until-signoz-proves-it-5gjf</guid>
      <description>&lt;p&gt;In my Tool Sepsis test, an agent can keep serving work while one of its tools fails half the time. The health endpoint stays green. Behind it, retries grow, latency stretches, and tokens pay for calls that never had a chance.&lt;/p&gt;

&lt;p&gt;I built Agency Immune around that gap. It watches a LangGraph workload in SigNoz, diagnoses one of six named failure modes, checks a small policy file, applies an allowed response, then runs the detection query again. I only call the incident healed when the measured signal recovers.&lt;/p&gt;

&lt;p&gt;That last query became the part of the system I care about most.&lt;/p&gt;

&lt;h2&gt;
  
  
  The loop I ended up with
&lt;/h2&gt;

&lt;p&gt;The first version of the idea fit in a line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DETECT -&amp;gt; DIAGNOSE -&amp;gt; DECIDE -&amp;gt; HEAL -&amp;gt; VERIFY -&amp;gt; REPORT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The real system needed sharper boundaries. SigNoz owns the evidence. The Chief, a diagnostic agent connected to the SigNoz MCP server, can read that evidence. A deterministic policy owns permission. The field-agent control API owns the action. SigNoz gets the final vote through a second measurement.&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%2F6lvtwe0ytsy07nm80tnn.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6lvtwe0ytsy07nm80tnn.jpg" alt="DETECT -&gt; DIAGNOSE -&gt; DECIDE -&gt; HEAL -&gt; VERIFY -&gt; REPORT" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The workload exports OTLP/gRPC traces, metrics, and logs using one resource identity. SigNoz alert webhooks start the supervisor. During diagnosis, the Chief can make at most six read-only MCP tool calls. Approved cures return through an authenticated API; the supervisor never mounts the Docker socket.&lt;/p&gt;

&lt;p&gt;I kept the recovery engine headless. The HQ interface can disappear and the alert-to-verification path still runs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Instrumenting the organism
&lt;/h2&gt;

&lt;p&gt;The test workload has an orchestrator, searcher, critic, and summarizer. Each case produces nested agent, LLM, and tool spans. I added metrics for case duration, retries, token use, estimated cost, tool errors, and tool latency. Python logs use the active trace context, which lets me move from a slow span to the relevant exception in SigNoz.&lt;/p&gt;

&lt;p&gt;The initialization is ordinary OpenTelemetry code. The useful decision was giving every signal the same resource:&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;resource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Resource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;service.name&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;field-agents&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;service.version&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SERVICE_VERSION&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;0.1.0&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;deployment.environment&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DEPLOYMENT_ENVIRONMENT&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;production&lt;/span&gt;&lt;span class="sh"&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;LLM spans carry &lt;code&gt;gen_ai.request.model&lt;/code&gt;, input tokens, and output tokens. Tool spans carry &lt;code&gt;agent.name&lt;/code&gt;, &lt;code&gt;tool.name&lt;/code&gt;, duration, status, and retry links. I use &lt;code&gt;hq.*&lt;/code&gt; attributes only for data that does not have an appropriate standard field.&lt;/p&gt;

&lt;p&gt;One small readiness rule saved me from fooling myself: HQ shows &lt;code&gt;3 SIGNALS LIVE&lt;/code&gt; only when the trace, metric, and log queries all return data. A reachable SigNoz endpoint with an empty result is still unready.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reproducing Tool Sepsis
&lt;/h2&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%2F3ocra0bu5bcm5yyoame5.png" 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%2F3ocra0bu5bcm5yyoame5.png" alt="Reproducing Tool Sepsis" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;make chaos-sepsis&lt;/code&gt; recreates the field-agent workload with &lt;code&gt;FAIL_RATE=0.5&lt;/code&gt;. This is fault injection in the running service. Browser fixtures play no part in that path.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;hq-tool-sepsis&lt;/code&gt; alert uses two trace queries grouped by &lt;code&gt;tool.name&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A  = count(tool.exec where has_error = true)
B  = count(tool.exec)
F1 = (A / B) * 100
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The rule fires when &lt;code&gt;F1&lt;/code&gt; exceeds 30 percent over five minutes. Its webhook carries the &lt;code&gt;tool_sepsis&lt;/code&gt; disease label into the supervisor.&lt;/p&gt;

&lt;p&gt;The Chief then queries SigNoz for bounded evidence and returns strict JSON. It may recommend &lt;code&gt;circuit_break_tool&lt;/code&gt;, &lt;code&gt;prompt_rollback&lt;/code&gt;, or &lt;code&gt;page_human&lt;/code&gt;. The recommendation itself has no authority. This policy does:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dry-run&lt;/span&gt;
&lt;span class="na"&gt;maxHealsPerHour&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
&lt;span class="na"&gt;confidenceThreshold&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.6&lt;/span&gt;

&lt;span class="na"&gt;diseases&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;tool_sepsis&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;actions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;circuit_break_tool&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;prompt_rollback&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;page_human&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;actions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;circuit_break_tool&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;revertAfterMs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;600000&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dry-run is the default. Live actions need a disease/action match, enough confidence, room in the hourly budget, and valid credentials. The circuit reverts after ten minutes. Any rejected decision pages a person.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the system can recognize
&lt;/h2&gt;

&lt;p&gt;I resisted adding a general “fix whatever is wrong” tool. Agency Immune has six known diseases with named queries and short response lists.&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%2F17864gz8d29979jave4k.png" 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%2F17864gz8d29979jave4k.png" alt="What the system can recognize" width="800" height="503"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The six alerts are provisioned as typed SigNoz v2 rules with Terraform. Four dashboards cover the agent fleet, token economics, the recovery loop, and signal integrity. HTTP Query Builder v5 payloads live in one TypeScript package with snapshot tests.&lt;/p&gt;

&lt;p&gt;That shared query package prevents an awkward class of bugs. Persisted dashboard panel JSON and the &lt;code&gt;/api/v5/query_range&lt;/code&gt; request body look related, but they are different contracts. The dashboards keep their own schema; runtime code imports tested builders.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bug hiding in absence detection
&lt;/h2&gt;

&lt;p&gt;Five diseases improve when a measured value drops. Telemetry Necrosis behaves in the opposite direction. It fires when no &lt;code&gt;field-agents&lt;/code&gt; spans arrive for three minutes, so recovery means the span count rises above zero.&lt;/p&gt;

&lt;p&gt;I made the inversion visible in code:&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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;disease&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;telemetry_necrosis&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="nx"&gt;outcome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;after&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;threshold&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;healed&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="s2"&gt;failed&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="k"&gt;else&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;after&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;threshold&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;outcome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;healed&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="k"&gt;else&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;after&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;before&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;outcome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;improved&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="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;outcome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;failed&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A generic “lower is healthier” helper would have marked a dead telemetry stream as recovered. This four-line branch is more valuable than making the abstraction look tidy.&lt;/p&gt;

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

&lt;p&gt;An accepted control request proves that the control API answered. It says nothing about the agent workload.&lt;/p&gt;

&lt;p&gt;Agency Immune stores a baseline before the cure. After the action, it waits 90 seconds and rebuilds the query for that disease. The second SigNoz window receives one of the verdicts shown below.&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%2Fw9r689d486k0ayadaz6i.png" 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%2Fw9r689d486k0ayadaz6i.png" alt="How VERIFY works" width="799" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;healed&lt;/code&gt; means the value crossed the healthy threshold. &lt;code&gt;improved&lt;/code&gt; means it dropped by at least 30 percent and remains outside the threshold. Anything else fails. Telemetry Necrosis uses the inverted comparison described above.&lt;/p&gt;

&lt;p&gt;The supervisor allows one more verification attempt. A second failure escalates. Every action also emits an &lt;code&gt;immune.heal&lt;/code&gt; span, so the cure, its incident, and the recovery window can share one traceable story.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running it on a clean checkout
&lt;/h2&gt;

&lt;p&gt;Foundry installs SigNoz and its MCP server from the committed &lt;code&gt;casting.yaml&lt;/code&gt; and &lt;code&gt;casting.yaml.lock&lt;/code&gt; files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;foundryctl cast &lt;span class="nt"&gt;-f&lt;/span&gt; casting.yaml
&lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env
docker compose &lt;span class="nt"&gt;-f&lt;/span&gt; docker-compose.hq.yaml up &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--build&lt;/span&gt;

&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;TF_VAR_signoz_endpoint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://localhost:8080
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;TF_VAR_signoz_api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SIGNOZ_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
terraform &lt;span class="nt"&gt;-chdir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;infra/signoz init
terraform &lt;span class="nt"&gt;-chdir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;infra/signoz apply
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I keep control, webhook, operator, and WebSocket credentials separate. The browser receives normalized telemetry and never receives the SigNoz API key.&lt;/p&gt;

&lt;p&gt;The current checkout passes 92 unit tests across the query package, supervisor, scale advisor, Python agents, and HQ. The test suite covers Query Builder payloads, policy decisions, authentication, verification math, restart-safe case records, tool failures, and UI transforms. A live SigNoz run remains a separate acceptance gate because unit tests cannot prove that telemetry was ingested.&lt;/p&gt;

&lt;p&gt;The six injected failures are known scenarios. Thresholds are tuned for a demonstration. A novel failure goes to a human. I have a time-to-answer study protocol in the repository, but I have left its results blank until I can record both arms on the same SigNoz instance.&lt;/p&gt;

&lt;p&gt;The same rule applies to autoscaling. The scale advisor implements the KEDA external-scaler contract and its decision logic is tested. I will describe live scaling only after I have captured KEDA polling, the scale event, cooldown, and the SigNoz source series from a Kubernetes run.&lt;/p&gt;

&lt;p&gt;The lesson I am taking forward is narrow: remediation needs an independent success condition. For Agency Immune, that condition is the same SigNoz query that identified the disease. If the number stays sick, the case stays open.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>signoz</category>
      <category>agents</category>
    </item>
  </channel>
</rss>
