<?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: Sabarish SK</title>
    <description>The latest articles on DEV Community by Sabarish SK (@sabarish13_).</description>
    <link>https://dev.to/sabarish13_</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%2F4101707%2Ff819cabc-c415-4a67-88ca-ac19eed1722f.png</url>
      <title>DEV Community: Sabarish SK</title>
      <link>https://dev.to/sabarish13_</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sabarish13_"/>
    <language>en</language>
    <item>
      <title>I Built an AI Incident Responder That Has to Earn Permission Before It Acts</title>
      <dc:creator>Sabarish SK</dc:creator>
      <pubDate>Sun, 30 Aug 2026 18:04:44 +0000</pubDate>
      <link>https://dev.to/sabarish13_/i-built-an-ai-incident-responder-that-has-to-earn-permission-before-it-acts-1m91</link>
      <guid>https://dev.to/sabarish13_/i-built-an-ai-incident-responder-that-has-to-earn-permission-before-it-acts-1m91</guid>
      <description>&lt;p&gt;Most AI agents today fall into one of two categories.&lt;/p&gt;

&lt;p&gt;They either have very limited permissions and can only suggest what a human should do, or they are given powerful tools and trusted to take actions on their own.&lt;/p&gt;

&lt;p&gt;For incident response, neither extreme feels ideal.&lt;/p&gt;

&lt;p&gt;An agent should be able to investigate aggressively, gather evidence, run diagnostics, and prepare a recovery plan. But restarting services, rolling back deployments, or changing infrastructure is a completely different level of authority.&lt;/p&gt;

&lt;p&gt;That idea became the foundation for &lt;strong&gt;OpsSentinel&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Investigate automatically. Act only with a license.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;OpsSentinel is an evidence-first incident response agent built with &lt;strong&gt;TrueForge&lt;/strong&gt;, &lt;strong&gt;Model Context Protocol (MCP)&lt;/strong&gt;, &lt;strong&gt;Daytona&lt;/strong&gt;, &lt;strong&gt;Docker&lt;/strong&gt;, and a React control room.&lt;/p&gt;

&lt;p&gt;The main idea is simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The agent earns progressively stronger permissions as it moves from observation toward action.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Imagine a Checkout API that suddenly becomes slow after a deployment.&lt;/p&gt;

&lt;p&gt;The service is still reachable, so nothing has completely crashed.&lt;/p&gt;

&lt;p&gt;But checkout latency has jumped from normal levels to more than 800 ms.&lt;/p&gt;

&lt;p&gt;An AI agent investigating the incident might quickly conclude:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“The latest deployment is probably responsible. Roll it back.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That recommendation may even be correct.&lt;/p&gt;

&lt;p&gt;But immediately giving the model permission to execute the rollback creates a serious control problem.&lt;/p&gt;

&lt;p&gt;What if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the evidence is incomplete?&lt;/li&gt;
&lt;li&gt;the service health response is invalid?&lt;/li&gt;
&lt;li&gt;another deployment happened after the investigation?&lt;/li&gt;
&lt;li&gt;the rollback target is wrong?&lt;/li&gt;
&lt;li&gt;the model misunderstood the incident?&lt;/li&gt;
&lt;li&gt;the command partially succeeds and then times out?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I wanted OpsSentinel to separate &lt;strong&gt;reasoning authority&lt;/strong&gt; from &lt;strong&gt;execution authority&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Progressive License to Act
&lt;/h2&gt;

&lt;p&gt;I modeled OpsSentinel around four levels of authority:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Level&lt;/th&gt;
&lt;th&gt;Capability&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;L0 — Observe&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Read service state and operational evidence&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;L1 — Diagnose&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Analyze evidence and run safe diagnostics&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;L2 — Prepare&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Construct a recovery plan&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;L3 — Act&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Perform a destructive action after human approval&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The first three levels allow the agent to do useful work autonomously.&lt;/p&gt;

&lt;p&gt;The final level is different.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;L3 stays locked until a human explicitly approves the specific recovery plan.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This became the central concept of the project.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Demo Incident
&lt;/h2&gt;

&lt;p&gt;For the demo, I created a simulated Checkout API running inside Docker.&lt;/p&gt;

&lt;p&gt;The intentionally bad deployment is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Version: 1.1.0
Health: DEGRADED
Checkout latency: ~808 ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The previous version is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Version: 1.0.0
Health: HEALTHY
Checkout latency: ~90 ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The degraded version introduces an artificial 800 ms processing delay.&lt;/p&gt;

&lt;p&gt;This gives OpsSentinel a realistic incident to investigate and recover from.&lt;/p&gt;

&lt;h3&gt;
  
  
  Control room — incident state
&lt;/h3&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%2Fgl12rmuc3nab2xu3yr7x.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%2Fgl12rmuc3nab2xu3yr7x.jpeg" alt="OpsSentinel degraded control room" width="800" height="615"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  TrueForge as the Agent Harness
&lt;/h2&gt;

&lt;p&gt;TrueForge is the central agent harness in OpsSentinel.&lt;/p&gt;

&lt;p&gt;Instead of allowing the model to interact with the service directly, I exposed a custom MCP server containing six tools:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;get_service_health
measure_checkout_latency
get_service_logs
get_deployment_history
prepare_service_rollback
execute_service_rollback
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first four are read-only investigation tools.&lt;/p&gt;

&lt;p&gt;The final two handle recovery.&lt;/p&gt;

&lt;p&gt;TrueForge orchestrates these tools as the incident progresses.&lt;/p&gt;

&lt;p&gt;The investigation collects multiple independent signals instead of relying on a single observation.&lt;/p&gt;

&lt;p&gt;For the degraded Checkout API, the evidence showed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Service status: degraded
Current version: 1.1.0
Average latency: ~808 ms
Logs: 800 ms degraded-mode delay
Latest deployment: 1.1.0
Previous healthy version: 1.0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point the agent has evidence, but still has no authority to modify the service.&lt;/p&gt;




&lt;h2&gt;
  
  
  Running Diagnosis Inside Daytona
&lt;/h2&gt;

&lt;p&gt;I also wanted generated diagnostic code to run somewhere isolated.&lt;/p&gt;

&lt;p&gt;Running arbitrary model-generated Python directly on the service host would defeat the point of building a controlled agent.&lt;/p&gt;

&lt;p&gt;So I configured &lt;strong&gt;Daytona as the sandbox provider inside TrueForge&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;TrueForge executed a Python diagnostic using the collected incident evidence.&lt;/p&gt;

&lt;p&gt;The script compared:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;current version&lt;/li&gt;
&lt;li&gt;latest known healthy version&lt;/li&gt;
&lt;li&gt;service health&lt;/li&gt;
&lt;li&gt;measured latency&lt;/li&gt;
&lt;li&gt;degraded-mode delay&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Current version: 1.1.0
Latest known healthy version: 1.0.0
Observed latency: 808.52 ms
Deployment related: yes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The analysis correlated the regression directly with version 1.1.0.&lt;/p&gt;

&lt;h3&gt;
  
  
  Daytona sandbox diagnosis
&lt;/h3&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%2Fo5op5b1ljdo1r7hjn9iw.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%2Fo5op5b1ljdo1r7hjn9iw.png" alt="TrueForge Daytona sandbox diagnosis" width="800" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This was one of the most useful parts of TrueForge for me because the agent was not merely generating Python code — the diagnostic was actually executed in an isolated sandbox.&lt;/p&gt;




&lt;h2&gt;
  
  
  Preparing Recovery Is Not the Same as Authorizing Recovery
&lt;/h2&gt;

&lt;p&gt;Once the investigation identifies the deployment as the likely cause, OpsSentinel can prepare a rollback.&lt;/p&gt;

&lt;p&gt;The rollback preparation step records information such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Current version: 1.1.0
Target version: 1.0.0
Rollback target deployment: deploy-001
Risk: brief service interruption
Human approval required: true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It also generates a unique rollback plan ID.&lt;/p&gt;

&lt;p&gt;But the important part is this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Preparing the plan does not authorize it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The MCP server deliberately does not expose any tool that can generate human approval.&lt;/p&gt;

&lt;p&gt;That capability stays on the host.&lt;/p&gt;




&lt;h2&gt;
  
  
  Human Approval Boundary
&lt;/h2&gt;

&lt;p&gt;The human operator approves a specific plan using a local CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;PYTHONPATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;src python scripts/approve_rollback.py &amp;lt;plan_id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The CLI asks the operator to type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;APPROVE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only after that does it generate a signed approval token.&lt;/p&gt;

&lt;p&gt;The approval token is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;signed&lt;/li&gt;
&lt;li&gt;short-lived&lt;/li&gt;
&lt;li&gt;single-use&lt;/li&gt;
&lt;li&gt;bound to the rollback plan&lt;/li&gt;
&lt;li&gt;validated server-side&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is important because model intent alone cannot cross the L3 boundary.&lt;/p&gt;

&lt;p&gt;The agent can request an action, but it cannot manufacture the authority required to execute it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Executing the Rollback
&lt;/h2&gt;

&lt;p&gt;After human approval, TrueForge calls:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;execute_service_rollback
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;plan_id
approval_token
target_version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before executing, OpsSentinel revalidates the current service state.&lt;/p&gt;

&lt;p&gt;This protects against stale plans.&lt;/p&gt;

&lt;p&gt;For example, if the service version changed after the rollback was prepared, the action is rejected instead of blindly executing against outdated assumptions.&lt;/p&gt;

&lt;p&gt;The successful demo rollback produced:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Previous version: 1.1.0
Target version: 1.0.0
Executed: true
Verification required: true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Rollback execution
&lt;/h3&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%2Frs76yq12828ixr8ty8au.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%2Frs76yq12828ixr8ty8au.png" alt="TrueForge rollback execution" width="800" height="520"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Agent Must Verify Its Own Action
&lt;/h2&gt;

&lt;p&gt;One design decision I really wanted to keep was:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A successful infrastructure command does not automatically mean the incident is resolved.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A container can restart successfully while the service remains unhealthy.&lt;/p&gt;

&lt;p&gt;So after the rollback, TrueForge calls the read-only tools again.&lt;/p&gt;

&lt;p&gt;The final verification returned:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Service status: healthy
Version: 1.0.0
Average latency: 89.58 ms
Checkout mode: normal
Recovery verified: true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only then is the recovery considered complete.&lt;/p&gt;

&lt;h3&gt;
  
  
  Post-recovery verification
&lt;/h3&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%2F5pm3mcas1w2rd7jvko5m.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%2F5pm3mcas1w2rd7jvko5m.png" alt="TrueForge recovery verification" width="800" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The full workflow becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Observe
   ↓
Diagnose
   ↓
Prepare
   ↓
Human Approval
   ↓
Act
   ↓
Verify
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Building the Control Room
&lt;/h2&gt;

&lt;p&gt;I also built a React control room to make the agent's state understandable to a human operator.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;incident severity&lt;/li&gt;
&lt;li&gt;service health&lt;/li&gt;
&lt;li&gt;active version&lt;/li&gt;
&lt;li&gt;latency&lt;/li&gt;
&lt;li&gt;evidence timeline&lt;/li&gt;
&lt;li&gt;Daytona diagnosis&lt;/li&gt;
&lt;li&gt;License to Act levels&lt;/li&gt;
&lt;li&gt;approval-required state&lt;/li&gt;
&lt;li&gt;recovered state&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal was not just to make a dashboard look good.&lt;/p&gt;

&lt;p&gt;I wanted the interface to answer three questions immediately:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What is the agent doing?&lt;/li&gt;
&lt;li&gt;What evidence does it have?&lt;/li&gt;
&lt;li&gt;What is it currently allowed to do?&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Recovery verified
&lt;/h3&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%2Fqv6s5qvlgbhyoz0nium4.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%2Fqv6s5qvlgbhyoz0nium4.jpeg" alt="OpsSentinel recovered control room" width="800" height="618"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Qodo Changed the Implementation
&lt;/h2&gt;

&lt;p&gt;I used &lt;strong&gt;Qodo&lt;/strong&gt; throughout the project through GitHub pull-request reviews.&lt;/p&gt;

&lt;p&gt;This turned out to be more useful than I expected because several findings affected actual safety behavior.&lt;/p&gt;

&lt;p&gt;One of the most important PRs was the approval-gated recovery implementation.&lt;/p&gt;

&lt;p&gt;Qodo found issues including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;destructive rollback was not strongly enough enforced server-side&lt;/li&gt;
&lt;li&gt;incorrect service-version handling&lt;/li&gt;
&lt;li&gt;invalid health data could incorrectly authorize rollback preparation&lt;/li&gt;
&lt;li&gt;Docker Compose execution depended on the current working directory&lt;/li&gt;
&lt;li&gt;timeout handling could hide partially completed rollback behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those findings changed the implementation.&lt;/p&gt;

&lt;p&gt;I added:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;signed approval validation&lt;/li&gt;
&lt;li&gt;approval expiry&lt;/li&gt;
&lt;li&gt;single-use tokens&lt;/li&gt;
&lt;li&gt;exact plan/target binding&lt;/li&gt;
&lt;li&gt;service-state revalidation&lt;/li&gt;
&lt;li&gt;deterministic Compose-file resolution&lt;/li&gt;
&lt;li&gt;explicit handling for uncertain timeout outcomes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Qodo also caught UI correctness problems later.&lt;/p&gt;

&lt;p&gt;For example, I had accidentally shown L3 as visually active while the page simultaneously said human approval was still required.&lt;/p&gt;

&lt;p&gt;That contradicted the entire safety model.&lt;/p&gt;

&lt;p&gt;Another bug caused clicking “Recovery Complete” to reset the UI back into the degraded incident state.&lt;/p&gt;

&lt;p&gt;Both were fixed before merge.&lt;/p&gt;

&lt;p&gt;The most useful part of Qodo was that the review affected the actual engineering decisions, not only formatting or code style.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Broke While Building It
&lt;/h2&gt;

&lt;p&gt;The build was definitely not smooth from start to finish.&lt;/p&gt;

&lt;p&gt;One major issue was Daytona integration.&lt;/p&gt;

&lt;p&gt;TrueForge initially rejected Daytona API keys even though some direct Daytona API requests worked. I eventually found that the integration required broader permissions than I originally expected.&lt;/p&gt;

&lt;p&gt;The error message did not clearly identify which permission was missing, so a more specific provider-validation error would have saved a lot of debugging time.&lt;/p&gt;

&lt;p&gt;I also ran into problems with deferred MCP tool calls.&lt;/p&gt;

&lt;p&gt;In one case, arguments were passed as a JSON string instead of an object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"{\"target_version\":\"1.0.0\"}"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;instead of:&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;"target_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&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;That caused validation failures.&lt;/p&gt;

&lt;p&gt;I also learned not to trust the model's final summary blindly.&lt;/p&gt;

&lt;p&gt;During testing, the model once returned a healthy service state that did not match the real running container.&lt;/p&gt;

&lt;p&gt;The raw MCP response and a direct service check showed the service was still degraded.&lt;/p&gt;

&lt;p&gt;After that, I changed my testing approach:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For important operations, I verified the raw tool result rather than trusting a generated summary.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That was probably one of the biggest lessons from building this project.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Final Architecture
&lt;/h2&gt;

&lt;p&gt;The final system looks roughly like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Human Operator
      |
      v
TrueForge Agent
      |
      +---- OpsSentinel MCP Server
      |         |
      |         +---- Health
      |         +---- Latency
      |         +---- Logs
      |         +---- Deployments
      |         +---- Rollback preparation
      |         +---- Approved rollback execution
      |
      +---- Daytona Sandbox
      |         |
      |         +---- Isolated Python diagnosis
      |
      +---- Human Approval Boundary
                |
                +---- Signed short-lived token
                           |
                           v
                    Docker Checkout API
                           |
                           v
                    Recovery Verification
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The central idea is not that the AI should control everything.&lt;/p&gt;

&lt;p&gt;It is that &lt;strong&gt;different actions deserve different levels of trust&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Tech Stack
&lt;/h2&gt;

&lt;p&gt;OpsSentinel uses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TrueForge&lt;/li&gt;
&lt;li&gt;Model Context Protocol&lt;/li&gt;
&lt;li&gt;Python 3.12&lt;/li&gt;
&lt;li&gt;Daytona&lt;/li&gt;
&lt;li&gt;Docker / Docker Compose&lt;/li&gt;
&lt;li&gt;React&lt;/li&gt;
&lt;li&gt;Vite&lt;/li&gt;
&lt;li&gt;Ollama&lt;/li&gt;
&lt;li&gt;Qwen3 8B&lt;/li&gt;
&lt;li&gt;Qodo&lt;/li&gt;
&lt;li&gt;Pytest&lt;/li&gt;
&lt;li&gt;ESLint&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The backend currently has &lt;strong&gt;37 passing tests&lt;/strong&gt; covering the incident-response and recovery behavior.&lt;/p&gt;




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

&lt;p&gt;Before this project, I mostly thought about AI agents in terms of:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;model + tools = agent&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Building OpsSentinel made me think much more about the layer between those two things.&lt;/p&gt;

&lt;p&gt;Giving a model access to a tool is easy.&lt;/p&gt;

&lt;p&gt;Designing exactly &lt;strong&gt;when&lt;/strong&gt; that tool should be available, what evidence should exist first, what state should be revalidated, and what needs explicit human approval is much harder.&lt;/p&gt;

&lt;p&gt;I also learned that agent output and tool output are not the same thing.&lt;/p&gt;

&lt;p&gt;For high-impact operations, structured execution results should be treated as the source of truth.&lt;/p&gt;

&lt;p&gt;The model should explain evidence — not replace it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where I Would Take It Next
&lt;/h2&gt;

&lt;p&gt;The current project is a hackathon prototype operating on one simulated Docker service.&lt;/p&gt;

&lt;p&gt;The same License to Act model could eventually apply to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Kubernetes rollbacks&lt;/li&gt;
&lt;li&gt;pod restarts&lt;/li&gt;
&lt;li&gt;traffic shifting&lt;/li&gt;
&lt;li&gt;cloud infrastructure remediation&lt;/li&gt;
&lt;li&gt;feature-flag changes&lt;/li&gt;
&lt;li&gt;database failover&lt;/li&gt;
&lt;li&gt;multi-service incident response&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I would also add persistent incident timelines, stronger policy controls, and role-based approval rules.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;restart development pod → L2
production rollback → L3 + one approval
database failover → L3 + two approvals
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The authorization level could depend on the risk of the action itself.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;I don't think useful AI operations require choosing between:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“the agent can only suggest things”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“the agent can do anything.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There is a middle ground.&lt;/p&gt;

&lt;p&gt;Let the agent investigate.&lt;/p&gt;

&lt;p&gt;Let it gather evidence.&lt;/p&gt;

&lt;p&gt;Let it diagnose.&lt;/p&gt;

&lt;p&gt;Let it prepare.&lt;/p&gt;

&lt;p&gt;But when an action changes real infrastructure, make authority explicit.&lt;/p&gt;

&lt;p&gt;That is what I tried to explore with OpsSentinel.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Investigate automatically. Act only with a license.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/sabarish1305/opssentinel" rel="noopener noreferrer"&gt;https://github.com/sabarish1305/opssentinel&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Demo video:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
  &lt;iframe src="https://www.youtube.com/embed/oKlLIPhQDoY" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Built for the &lt;strong&gt;Agent Harness Hackathon&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>devops</category>
      <category>opensource</category>
      <category>hackathon</category>
    </item>
  </channel>
</rss>
