<?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: Koushik Deb</title>
    <description>The latest articles on DEV Community by Koushik Deb (@debk).</description>
    <link>https://dev.to/debk</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%2F3955865%2Fe9795256-e08f-4d82-bb63-8a7e1bb253d7.png</url>
      <title>DEV Community: Koushik Deb</title>
      <link>https://dev.to/debk</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/debk"/>
    <language>en</language>
    <item>
      <title>Proof of Breath: Your AI Agent Can't Run DROP TABLE Until You Breathe</title>
      <dc:creator>Koushik Deb</dc:creator>
      <pubDate>Tue, 10 Nov 2026 17:12:57 +0000</pubDate>
      <link>https://dev.to/debk/proof-of-breath-your-ai-agent-cant-run-drop-table-until-you-breathe-1c13</link>
      <guid>https://dev.to/debk/proof-of-breath-your-ai-agent-cant-run-drop-table-until-you-breathe-1c13</guid>
      <description>&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%2Fy0rpllau1cbrpi4hxx6a.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%2Fy0rpllau1cbrpi4hxx6a.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/presage-2026-11-04"&gt;Presage SmartSpectra SDK Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Proof of Breath&lt;/strong&gt; is an approval gate for dangerous commands.&lt;/p&gt;

&lt;p&gt;AI coding agents are fast. Sometimes they are too fast. They have run commands like &lt;code&gt;DROP TABLE&lt;/code&gt; or &lt;code&gt;terraform destroy&lt;/code&gt; and wiped real data. The usual "Are you sure? [y/N]" prompt does not help much. We press "y" without thinking.&lt;/p&gt;

&lt;p&gt;So I replaced the "y" with a breath.&lt;/p&gt;

&lt;p&gt;Here is how it works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Normal commands run as usual. Nothing changes.&lt;/li&gt;
&lt;li&gt;When an agent tries something it cannot undo, the command is held.&lt;/li&gt;
&lt;li&gt;A window opens with a breathing pattern. The pattern is new every time.&lt;/li&gt;
&lt;li&gt;You follow it with your breath, in front of your webcam.&lt;/li&gt;
&lt;li&gt;The Presage SmartSpectra SDK reads your breathing and your pulse.&lt;/li&gt;
&lt;li&gt;If your breath follows the pattern and a live pulse is there, the command runs. If not, it stays blocked.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An agent cannot breathe for you. A photo cannot breathe. A recording of an old check will not match a new pattern. And you cannot follow a breathing pattern on autopilot. You have to pay attention for a few seconds.&lt;/p&gt;

&lt;p&gt;To be clear: this checks that a live person is paying attention. It does not check who you are.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/UIOzlm62KMA" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Live app:&lt;/strong&gt; &lt;a href="https://pob.koushikdeb.com" rel="noopener noreferrer"&gt;https://pob.koushikdeb.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The login page is already filled in for judges. Just press &lt;strong&gt;Sign in&lt;/strong&gt;. You get your own private sandbox. It can never approve a real command.&lt;/p&gt;

&lt;p&gt;Things to try:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Accept the consent notice.&lt;/li&gt;
&lt;li&gt;Open &lt;strong&gt;Live reading&lt;/strong&gt;. Keep your face and upper chest in view. Press start. Your pulse shows up after about 12 seconds.&lt;/li&gt;
&lt;li&gt;Press &lt;strong&gt;Run it through the gate&lt;/strong&gt;. Pick &lt;strong&gt;Your camera&lt;/strong&gt; and follow the circle with your breath.&lt;/li&gt;
&lt;li&gt;Pick &lt;strong&gt;Simulated&lt;/strong&gt; to see attacks fail: a photo, a replayed session, or someone who ignores the pacer.&lt;/li&gt;
&lt;li&gt;Open &lt;strong&gt;Case study&lt;/strong&gt;. It shows the SDK reading a real recorded person. You can test that trace against new patterns.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For the recording, I used the &lt;strong&gt;Easy demo&lt;/strong&gt; setting. It still needs a live pulse and a rough follow of the pattern, but it turns off the stricter checks. The default settings are stricter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/DevDaring" rel="noopener noreferrer"&gt;
        DevDaring
      &lt;/a&gt; / &lt;a href="https://github.com/DevDaring/Proof_of_Breath" rel="noopener noreferrer"&gt;
        Proof_of_Breath
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Proof of Breath&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A physiological approval gate for destructive developer commands. Routine commands pass untouched. When an AI coding agent tries something it cannot undo, such as &lt;code&gt;terraform destroy&lt;/code&gt; or &lt;code&gt;DROP TABLE&lt;/code&gt;, the command is held and a window opens with a breathing pattern that is different every time. It runs only if a live person's breathing, measured from a webcam by the Presage SmartSpectra SDK, follows that pattern and a live pulse is present.&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/DevDaring/Proof_of_Breath/assets/generated/art/hero.webp"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fraw.githubusercontent.com%2FDevDaring%2FProof_of_Breath%2FHEAD%2Fassets%2Fgenerated%2Fart%2Fhero.webp" alt="Abstract waves of light"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Live demo:&lt;/strong&gt; &lt;a href="https://pob.koushikdeb.com" rel="nofollow noopener noreferrer"&gt;https://pob.koushikdeb.com&lt;/a&gt;. The login page is filled in with jury details: press &lt;strong&gt;Sign in&lt;/strong&gt;. You get a private sandbox that can never approve a real command. In it you can use &lt;strong&gt;your own webcam&lt;/strong&gt; for a real Presage SDK reading, or the clearly labelled simulated sensor.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Case study.&lt;/strong&gt; Open &lt;strong&gt;Case study&lt;/strong&gt; for real SDK output from a recorded person (numbers only, no frames), challenged with fresh patterns by the real verifier…&lt;/p&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/DevDaring/Proof_of_Breath" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Repository: &lt;a href="https://github.com/DevDaring/Proof_of_Breath" rel="noopener noreferrer"&gt;https://github.com/DevDaring/Proof_of_Breath&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The README has the full setup steps. You need PostgreSQL, Python, Node and a Presage API key.&lt;/p&gt;

&lt;p&gt;Stack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Backend:&lt;/strong&gt; FastAPI and PostgreSQL&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; React&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sensor:&lt;/strong&gt; &lt;code&gt;@smartspectra/node-sdk&lt;/code&gt;, running in a camera relay on the server or in a desktop bridge on your own machine&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hooks:&lt;/strong&gt; Claude Code, a git pre-push hook, and a small CLI (&lt;code&gt;pob run -- &amp;lt;command&amp;gt;&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How It Responds to Human Signals
&lt;/h2&gt;

&lt;p&gt;I use these live signals from the SDK:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Signal&lt;/th&gt;
&lt;th&gt;What the app does with it&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Breathing trace&lt;/td&gt;
&lt;td&gt;Checks that your breath follows the pattern&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pulse rate and confidence&lt;/td&gt;
&lt;td&gt;Checks that a live pulse is present&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Arterial pressure trace&lt;/td&gt;
&lt;td&gt;Research score only. It never decides&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Validation status&lt;/td&gt;
&lt;td&gt;Tells you if your face is out of view or the light is bad&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Breathing rate&lt;/td&gt;
&lt;td&gt;Shown to you. Never used to decide&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;What happens in real time:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A circle grows and shrinks. You breathe in as it grows and out as it shrinks.&lt;/li&gt;
&lt;li&gt;Your own breathing curve is drawn live, right next to the target curve.&lt;/li&gt;
&lt;li&gt;Your pulse appears on screen once the SDK is confident.&lt;/li&gt;
&lt;li&gt;If you move out of frame, a hint tells you right away.&lt;/li&gt;
&lt;li&gt;When the window ends, the server scores your breath. The browser only shows things. It never decides.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The checks:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Does your breath match the pattern?&lt;/li&gt;
&lt;li&gt;Do your inhales and exhales line up with the circle?&lt;/li&gt;
&lt;li&gt;Did you take the right number of breaths?&lt;/li&gt;
&lt;li&gt;Was a live pulse there for most of the window?&lt;/li&gt;
&lt;li&gt;Does your breath match &lt;em&gt;this&lt;/em&gt; pattern better than 20 other random patterns? This stops replays.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A pass gives a one-time token. It works for 30 seconds, and only for that exact command. Every decision goes into a receipt chain that shows if anyone edits it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How I integrated the SDK:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The browser sends camera frames to a small Node relay on the server. The relay feeds them to the SDK with &lt;code&gt;useCustomInput&lt;/code&gt; and &lt;code&gt;sendFrame&lt;/code&gt;. The SDK streams breathing, pulse and status back. The backend scores them.&lt;/p&gt;

&lt;p&gt;Things I learned the hard way:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The SDK needs your chest in view.&lt;/strong&gt; With only a face, you get no readings at all, not even pulse.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The frame rate matters.&lt;/strong&gt; Below about 20 frames a second, the SDK stopped with a processing error. I now fill small gaps by repeating the last frame to keep the rate steady.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The frame size must not change.&lt;/strong&gt; A size change in the middle of a capture crashed the SDK. Every frame is now cropped to a fixed 640x480.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Errors can be retried.&lt;/strong&gt; If the SDK reports a temporary error, the relay restarts it quietly, up to two times.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is also a desktop bridge. It runs the SDK on your own computer, so video never leaves your machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Best Thoughtful Real-World Use&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The need:&lt;/strong&gt; AI agents now run real commands on real systems. One wrong command can delete a database. A yes/no prompt turns into a habit, and habits don't protect anyone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who it's for:&lt;/strong&gt; developers who let AI agents work in their terminal, and teams who want a real pause before destructive actions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How I made it usable:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It only steps in for dangerous commands. Your normal work is not slowed down.&lt;/li&gt;
&lt;li&gt;A check takes a few seconds.&lt;/li&gt;
&lt;li&gt;The rules that decide what is dangerous are plain, fixed patterns. No AI makes that call.&lt;/li&gt;
&lt;li&gt;There is a fallback for people who can't do paced breathing or don't want to use a camera. You type the exact name of the target, like the database name, and wait 20 seconds. The receipt records that the fallback was used.&lt;/li&gt;
&lt;li&gt;The circle, sound cues and on-screen hints guide you, so you don't need to read instructions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To be honest about where it stands: I have not run formal trials with many people yet. The thresholds are a first guess and will need tuning.&lt;/p&gt;

&lt;h2&gt;
  
  
  Consent and Data Handling
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Proof of Breath does not diagnose, treat or monitor anything, and makes no medical claims.&lt;/strong&gt; It only checks presence and attention before a destructive command runs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Consent.&lt;/strong&gt; Before the camera starts for the first time, a screen explains what is measured, what is stored, and how to delete it. You press "I agree". The app saves the date and the version you agreed to. You can withdraw consent in Settings at any time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Camera.&lt;/strong&gt; The camera only runs during a check or a reading that you started. You can see when it is on. It stops when the window ends. Nothing runs in the background.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Video.&lt;/strong&gt; Video is never saved. Not on the server, not anywhere.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Browser camera:&lt;/strong&gt; frames go over an encrypted connection to the relay. Each frame is read in memory, given to the SDK, and thrown away.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Desktop bridge:&lt;/strong&gt; video never leaves your computer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simulated mode:&lt;/strong&gt; no camera at all.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What is stored.&lt;/strong&gt; One receipt per decision. It has the time, the scores, the decision, and a hash of the command. The command text itself is only stored if you turn that on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deleting.&lt;/strong&gt; Settings has "Export receipts" and "Delete all data". Judge sandboxes are deleted after 7 days without use. Database backups are kept for 14 days.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sharing.&lt;/strong&gt; Your data is never shared or sold.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SDK telemetry.&lt;/strong&gt; The SDK can send a small summary per session. It never includes video, measurements or identity. I turned it off by default. You can turn it on in Settings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI services.&lt;/strong&gt; No user data goes to any AI service by default. One optional feature can explain a blocked command in plain words using NanoGPT. It is off by default and needs its own opt-in. The voice cues (ElevenLabs) and images (NanoGPT) were made once, at build time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Agent Session
&lt;/h2&gt;

&lt;p&gt;I built this with Claude Code.&lt;/p&gt;

&lt;p&gt;The session shows the part I found most interesting: tracking down why the SDK failed on a real webcam. It turned out to be the frame rate and the frame size, not the camera.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>presagechallenge</category>
      <category>ai</category>
    </item>
    <item>
      <title>Claim Attention</title>
      <dc:creator>Koushik Deb</dc:creator>
      <pubDate>Sat, 06 Jun 2026 18:04:58 +0000</pubDate>
      <link>https://dev.to/debk/claim-attention-3m58</link>
      <guid>https://dev.to/debk/claim-attention-3m58</guid>
      <description>&lt;p&gt;This is a submission for the &lt;a href="https://dev.to/challenges/github-2026-05-21"&gt;GitHub Finish-Up-A-Thon Challenge&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Claim-Attention is a real-time attention compass. It takes one webcam frame every two seconds, finds your face with MediaPipe, and places your attention as a moving dot on a five-point compass:  present  at the centre, with  internal thought ,  external distraction ,  past memory  and  future planning  pulling outward.&lt;/p&gt;

&lt;p&gt;Two ideas sit underneath it. MCASE (Multi-Cue Attention State Estimation) reads eye-aspect ratio, gaze, head pose, blink rate and small expression cues, then scores the five states. TADV (Temporal Attention Drift Vector) treats the dot as a spring-damper particle, so the motion stays smooth instead of jittery.&lt;/p&gt;

&lt;p&gt;The project began as a small experiment around a personal question: where does my mind actually go when I believe I am focused? It grew into something I wanted other people to try, which is why it now runs in the browser, on Windows and on mobile against one shared backend.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/D86gQQjUh9c"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub Repo
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/DevDaring" rel="noopener noreferrer"&gt;
        DevDaring
      &lt;/a&gt; / &lt;a href="https://github.com/DevDaring/Claim-Attention" rel="noopener noreferrer"&gt;
        Claim-Attention
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Claim-Attention&lt;/h1&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;Real-time &lt;strong&gt;Attention Compass&lt;/strong&gt; powered by the MCASE algorithm
Built for the GCP Gemini 2.0 Hackathon.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;📁 Folder Structure&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;Code/
├── cloud_functions/    # GCP Cloud Functions (Python) — backend
├── terraform/          # Infrastructure-as-Code (Terraform)
├── web_app/            # React web application (Vite)
├── windows_app/        # Python Windows desktop app (CustomTkinter)
├── mobile_app/         # Flutter mobile app (iOS + Android)
├── .env                # Your secrets (gitignored)
└── .env.example        # Template — copy to .env and fill in
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🚀 Quick Start Order&lt;/h2&gt;

&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;Before running anything, copy &lt;code&gt;.env.example&lt;/code&gt; → &lt;code&gt;.env&lt;/code&gt; and fill in your GCP keys.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;1. Deploy Backend (when ready)&lt;/h3&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c1"&gt;cd&lt;/span&gt; Code/terraform
cp terraform.tfvars.example terraform.tfvars   &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; fill in project_id&lt;/span&gt;
terraform init
terraform apply                                 &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; creates GCS buckets + Functions&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;2. Run Web App (local dev)&lt;/h3&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c1"&gt;cd&lt;/span&gt; Code/web_app
cp .env.example .env                            &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; add VITE_CLOUD_FUNCTION_URL&lt;/span&gt;
npm install
npm run dev                                     &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; → http://localhost:3000&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;3. Run Windows App&lt;/h3&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c1"&gt;cd&lt;/span&gt; Code/windows_app
cp .env.example .env                            &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; add CLOUD_FUNCTION_URL&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/DevDaring/Claim-Attention" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Live Software Link
&lt;/h2&gt;


&lt;div class="ltag__cloud-run"&gt;
  &lt;iframe height="600px" src="https://claim-attention-400984956590.asia-south1.run.app"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  The Comeback Story
&lt;/h2&gt;

&lt;p&gt;I had left this half-finished few months ago. The backend and the React web app ran on my machine, but everything else had drifted out of sync:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The   Windows   and   Flutter   clients were stale and would not run against the current backend.&lt;/li&gt;
&lt;li&gt;  Calibration ran forever   — it never completed, so you could never start a session.&lt;/li&gt;
&lt;li&gt;The   "Hide Camera"   toggle did nothing.&lt;/li&gt;
&lt;li&gt;Nothing was deployed, so there was no link to share.&lt;/li&gt;
&lt;li&gt;The code map describing the project was out of date.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the Finish-Up-a-thon I closed each gap:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Replaced the old Gemini-Vision validation with a provider-agnostic LLM second opinion (DeepSeek and Gemini through OpenAI-compatible APIs).&lt;/li&gt;
&lt;li&gt;Added   FocusWell  , a predictive layer that estimates drift  before  it happens — a drift-risk gauge, a time-to-drift estimate, flow-streak detection and a pre-emptive nudge — then ported the same engine into the Windows (Python) and mobile (Dart) clients so all three behave alike.&lt;/li&gt;
&lt;li&gt;Fixed the calibration hang (a renamed camera method that threw inside the capture loop) and the hide-camera binding.&lt;/li&gt;
&lt;li&gt;Rewrote the Windows camera handling as a single reader to remove a frame race.&lt;/li&gt;
&lt;li&gt;Deployed the whole project to   Google Cloud Run   as one small, scale-to-zero service that serves both the API and the web UI, which keeps the running cost close to nothing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It now has a public URL and a working demo path: calibrate, start a session, watch the compass move, and get nudged just before you drift.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Experience with GitHub Copilot
&lt;/h2&gt;

&lt;p&gt;I built the original version with GitHub Copilot, and I finished it with Copilot too.&lt;/p&gt;

&lt;p&gt;The part where it earned its place was porting FocusWell across three languages. The maths had to stay identical between the JavaScript reference, the Python desktop port and the Dart mobile port — same weights, same thresholds, same prediction steps. Copilot held the structure steady as I moved function by function, which is exactly the kind of careful, repetitive translation that is easy to get subtly wrong by hand.&lt;/p&gt;

&lt;p&gt;It also carried the unglamorous finishing work: tracing the calibration bug back to a renamed camera method, writing the multi-stage Dockerfile that builds the React app and serves it from Flask, and settling the Cloud Run flags so the service scales to zero.&lt;/p&gt;

&lt;p&gt;What I took from the finish-up is simple. The last ten percent of a project is mostly small, fiddly corrections across many files, and that is where an assistant which holds context across the whole codebase actually saves time.&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%2Fbycn3fw91j47wfqxs4s9.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.amazonaws.com%2Fuploads%2Farticles%2Fbycn3fw91j47wfqxs4s9.png" alt=" " width="800" height="514"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Details
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Frontend: React (Vite) web app, Flutter mobile, and a Python CustomTkinter desktop app. Each runs a 2-second capture loop with client-side TADV smoothing and the FocusWell overlay.&lt;/li&gt;
&lt;li&gt;Backend: Python Flask on Google Cloud Run, exposing six REST endpoints: /capture, /history, /latest, /sessions, /calibrate, /cleanup.&lt;/li&gt;
&lt;li&gt;Vision and scoring: MediaPipe Face Mesh (478 landmarks) feeds MCASE features (eye-aspect ratio, gaze, head pose, blink rate, expression cues), which score the five states; TADV applies spring-damper physics for smooth motion.&lt;/li&gt;
&lt;li&gt;Prediction: the FocusWell engine (drift risk, time-to-drift, flow streak, predicted path) is ported across JavaScript, Python and Dart with identical maths.&lt;/li&gt;
&lt;li&gt;LLM check: every tenth frame, numeric features (not the image) go to an OpenAI-compatible model (DeepSeek via NanoGPT, Gemini via linkapi) and blend 70/30 with the local score.&lt;/li&gt;
&lt;li&gt;Storage: sessions and readings as CSV plus JPEG media on the container disk (LOCAL_DEV); no external database.&lt;/li&gt;
&lt;li&gt;Deployment: one Cloud Run service serves both the API and the built web app via a multi-stage Dockerfile (Node build, Python serve), scaling to zero when idle.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Koushik Deb&lt;br&gt;
&lt;a class="mentioned-user" href="https://dev.to/debk"&gt;@debk&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>githubchallenge</category>
    </item>
  </channel>
</rss>
