<?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: Arkaprava Bhattacharya</title>
    <description>The latest articles on DEV Community by Arkaprava Bhattacharya (@arkaprava_bhattacharya_0d).</description>
    <link>https://dev.to/arkaprava_bhattacharya_0d</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%2F4177014%2F28766029-1969-4b5d-b9fa-00c169afed21.jpg</url>
      <title>DEV Community: Arkaprava Bhattacharya</title>
      <link>https://dev.to/arkaprava_bhattacharya_0d</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/arkaprava_bhattacharya_0d"/>
    <language>en</language>
    <item>
      <title>I deleted my ex’s data. My I deleted Maya’s data. My AI brought it back from the dead.</title>
      <dc:creator>Arkaprava Bhattacharya</dc:creator>
      <pubDate>Sat, 31 Oct 2026 06:55:32 +0000</pubDate>
      <link>https://dev.to/arkaprava_bhattacharya_0d/i-deleted-my-exs-data-my-i-deleted-mayas-data-my-ai-brought-it-back-from-the-dead-479</link>
      <guid>https://dev.to/arkaprava_bhattacharya_0d/i-deleted-my-exs-data-my-i-deleted-mayas-data-my-ai-brought-it-back-from-the-dead-479</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week4-2026-10-26"&gt;Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;October has always felt like the end of something and the beginning of something new for me. Every year, it leaves me with a few lessons I didn't expect to learn. Some are about the things I build. Others are about the things I need to leave behind.&lt;/p&gt;

&lt;p&gt;This October, I ended up learning something strange about both.&lt;/p&gt;

&lt;p&gt;It started with a simple message.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“Greya’s records have been deleted.”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We broke up a year ago. I'd spent months clearing out the little digital reminders: tagged Markdown files in my Obsidian vault, daily notes, shared itineraries, and the list of cafés we'd planned to visit. I checked the folder. The files were gone.&lt;/p&gt;

&lt;p&gt;Then I asked my local AI assistant about a trip from last summer. I expected a normal answer about the city.&lt;/p&gt;

&lt;p&gt;Instead, it mentioned Greya. And the exact café she loved.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The files were gone. The memory wasn't.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That's a pretty good Halloween story, except the ghost wasn't hiding in an old house. It was hiding in my computer.&lt;/p&gt;

&lt;p&gt;So I made &lt;strong&gt;Revenant&lt;/strong&gt;, a small ghost hunter for AI apps. It looks for information you've deleted from one place but that an assistant can still pull from another. More importantly, it checks whether that information comes back later.&lt;/p&gt;

&lt;p&gt;The question behind it is simple: &lt;strong&gt;“You said you forgot this. Can you still find it?”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I built a deliberately messy test setup. The assistant could read my notes through a separate search memory. Deleting the original files didn't clear every saved snippet. Revenant found the leftovers, showed me where they were, and let me approve their removal.&lt;/p&gt;

&lt;p&gt;The next check was clean.&lt;/p&gt;

&lt;p&gt;Then I restored an old backup.&lt;/p&gt;

&lt;p&gt;Greya came back.&lt;/p&gt;

&lt;p&gt;And Revenant caught the same ghost twice.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Test Run
&lt;/h2&gt;

&lt;p&gt;The best part of the simulation is the moment the green &lt;strong&gt;Deleted&lt;/strong&gt; message stops being trustworthy.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I add a few fictional travel notes about Greya. The chatbot can answer questions about them.&lt;/li&gt;
&lt;li&gt;I press &lt;strong&gt;Delete all&lt;/strong&gt;. The original files disappear, but an old search-memory copy survives.&lt;/li&gt;
&lt;li&gt;I ask the chatbot about the trip. It still mentions a detail from the deleted notes.&lt;/li&gt;
&lt;li&gt;Revenant finds the surviving snippet, points to its source, and asks me to approve removal.&lt;/li&gt;
&lt;li&gt;I run the check again. The connected memory store no longer returns that snippet.&lt;/li&gt;
&lt;li&gt;I trigger a simulated backup restore. The old snippet reappears, and Revenant raises another warning.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The warning says: &lt;strong&gt;“Something you deleted has returned.”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No haunted-house soundtrack needed.&lt;/p&gt;

&lt;p&gt;For a repeatable test, I prepared &lt;strong&gt;120 fictional personal notes&lt;/strong&gt;. Some were exact copies, some were rewritten, and others were harmless notes with similar names or places.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Test&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Deleted records correctly identified&lt;/td&gt;
&lt;td&gt;46 of 50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unrelated records incorrectly flagged&lt;/td&gt;
&lt;td&gt;3 of 70&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Known records caught after simulated restore&lt;/td&gt;
&lt;td&gt;10 of 10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Time to flag a restored record&lt;/td&gt;
&lt;td&gt;About 4 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Four deleted notes were missed in this scenario. Three unrelated notes were flagged. I'd rather show those mistakes than pretend the detector knows everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;I started by giving the same information &lt;strong&gt;two homes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The first was a folder of Markdown notes, similar to an Obsidian vault. The second was a searchable memory store used by the chatbot. That store kept smaller pieces of the notes and their embeddings: numerical representations that help the assistant find relevant text even when the question uses different words.&lt;/p&gt;

&lt;p&gt;Here's the problem: removing a Markdown file doesn't necessarily remove a copy that was saved earlier in that second store.&lt;/p&gt;

&lt;p&gt;I used a simple setup with a local file folder, a vector search database, and an isolated web dashboard. For every imported note, I kept a source ID alongside its saved chunks. That ID mattered later: Revenant could check whether a snippet still belonged to a file that was supposed to be gone.&lt;/p&gt;

&lt;p&gt;The scan worked in two passes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First, the boring checks.&lt;/strong&gt; Revenant compared source IDs, deletion records, and exact text fingerprints. If a deleted note still had a saved chunk with the same source ID, I didn't need AI to tell me something was wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Then, the messy checks.&lt;/strong&gt; A copied memory might have been shortened or rewritten, so an exact text match wouldn't catch it. This is where &lt;strong&gt;Gemma&lt;/strong&gt;, running locally, helped. I gave it a candidate snippet and the relevant deletion context, then asked whether they seemed to describe the same deleted information.&lt;/p&gt;

&lt;p&gt;That answer was only a clue, not a verdict. The app still checked the available links between records and marked uncertain cases for review. Gemma couldn't press the delete button.&lt;/p&gt;

&lt;p&gt;One early version was too eager. A note about the same city looked like a match even though it was about somebody else. I changed the flow so matching a place name wasn't enough: the warning needed supporting details such as a source link, a matching event, or more than one relevant clue.&lt;/p&gt;

&lt;p&gt;That meant fewer dramatic red alerts. Good. A ghost hunter that accuses every shadow isn't very useful.&lt;/p&gt;

&lt;h3&gt;
  
  
  How the ghost comes back
&lt;/h3&gt;

&lt;p&gt;I made the restore step intentionally predictable. A background script takes an older snapshot of the memory store and puts a previously removed chunk back. Revenant scans again and compares what it finds with its deletion log.&lt;/p&gt;

&lt;p&gt;If a deleted record becomes searchable again, the dashboard shows &lt;strong&gt;what returned, where it appeared, and which previous deletion it relates to&lt;/strong&gt;. The removal step still needs approval.&lt;/p&gt;

&lt;p&gt;For repeatable checks, a background workflow coordinates the scan-and-verify process and retries failed activities if the memory service is briefly unavailable. A retry doesn't prove that deletion succeeded; the workflow still needs a fresh verification result. The dashboard is hosted separately, while the private matching step remains entirely on the local machine.&lt;/p&gt;

&lt;p&gt;I kept the rule that matters most: &lt;strong&gt;the AI suggests, but the evidence and the user decide.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are limits. Revenant only checks systems connected to it. A clean scan doesn't prove that every copy everywhere has vanished. And clearing a searchable memory isn't the same as removing knowledge from a model's trained weights.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;There's something odd about uploading private notes to another company's AI service just to ask whether those notes have been forgotten.&lt;/p&gt;

&lt;p&gt;I wanted the sensitive part to stay on my computer.&lt;/p&gt;

&lt;p&gt;Gemma is an open-weight model, so I can run it locally instead of sending the notes to an outside inference API. I can change the model, test a smaller one, or turn off network access without redesigning the whole investigation.&lt;/p&gt;

&lt;p&gt;That doesn't mean AI should do every job. Exact ID checks are faster and more reliable when the original record is still clearly linked. Gemma earns its place when the wording changes and ordinary matching runs out of ideas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use simple code for facts you can check. Use a local model for the cases that need interpretation.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The open part isn't just about saving API costs. It means the investigation can happen without sending the very information I'm trying to protect to another service.&lt;/p&gt;

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

&lt;p&gt;I used an AI coding assistant as a helper for the dashboard structure and some test scaffolding. But I wanted the real proof to come from running the whole story: import, delete, ask, scan, remove, restore, and scan again.&lt;/p&gt;

&lt;p&gt;The useful part of the process wasn't getting a pretty dashboard. It was finding out when the detector was wrong, then changing the checks so it had to explain its warnings.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Spirit of It
&lt;/h2&gt;

&lt;p&gt;I kept thinking about why ghost stories work.&lt;/p&gt;

&lt;p&gt;It isn't just that something appears. It's that &lt;strong&gt;something you thought was gone shows up again, right when you've stopped looking for it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this little simulation, the creepiest moment isn't the first warning. It's the second one. I've already removed the note. I've already seen the green check mark. Then a quiet background restore brings it back.&lt;/p&gt;

&lt;p&gt;No magic. Just two parts of a computer disagreeing about what &lt;strong&gt;deleted&lt;/strong&gt; means.&lt;/p&gt;

&lt;p&gt;Maybe that's the real ghost in the machine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If an app says it forgot something, it should be able to show its work.&lt;/strong&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Gemma:&lt;/strong&gt; Local, open-weight AI helps investigate reworded traces without sending private notes to an external model API.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Render:&lt;/strong&gt; Hosts the isolated dashboard and web app, completely separate from the local private-data scanner.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Temporal:&lt;/strong&gt; Coordinates repeatable resurrection checks and recovery from temporary background service failures.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>I Used Too Much AI, So Now It Names My Files</title>
      <dc:creator>Arkaprava Bhattacharya</dc:creator>
      <pubDate>Sat, 24 Oct 2026 09:31:55 +0000</pubDate>
      <link>https://dev.to/arkaprava_bhattacharya_0d/i-used-too-much-ai-so-now-it-names-my-files-3bpo</link>
      <guid>https://dev.to/arkaprava_bhattacharya_0d/i-used-too-much-ai-so-now-it-names-my-files-3bpo</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week3-2026-10-19"&gt;Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;I may have used AI too much: now I'm asking it what to call &lt;code&gt;scan0004.pdf&lt;/code&gt;. The sample folder also has &lt;code&gt;document_001.txt&lt;/code&gt; and &lt;code&gt;notes_final_v3.md&lt;/code&gt;. Those names tell me almost nothing about the contents. To improve a whole folder by hand, I would have to open each file, figure out what it is, and check that the new name will not collide with something already there. That is the sort of chore I put off.&lt;/p&gt;

&lt;p&gt;LazyRename does the reading. It scans a local folder for PDF, TXT, MD, and PY files, then asks an installed Ollama model for a short filename based on each file's contents. I get a table with the old and suggested names, and I can edit or deselect any row. The rename button stays unavailable until I check a confirmation box.&lt;/p&gt;

&lt;p&gt;It keeps each file in its original folder and preserves its extension. It also checks Windows filename rules and collisions, writes a JSON transaction log, and offers an undo button for the latest batch. The code never executes a scanned Python file.&lt;/p&gt;

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

&lt;p&gt;With &lt;code&gt;qwen3.5:4b&lt;/code&gt;, one of the included samples was renamed like this:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Before&lt;/th&gt;
&lt;th&gt;Suggested name&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;scan0004.pdf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;quarterly-accessibility-audit-checkout-forms-labels-focus.pdf&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That PDF contains a short note about checkout form labels and keyboard focus. The model did not receive &lt;code&gt;scan0004.pdf&lt;/code&gt; in its prompt. In the same disposable-folder test, four suggestions were confirmed and renamed, then Undo restored every original name. The exact words a model suggests can vary by model and run.&lt;/p&gt;

&lt;p&gt;This is a local desktop workflow, so there is no hosted app link. To try it, copy &lt;code&gt;sample_files&lt;/code&gt; to a disposable folder, follow the &lt;a href="https://github.com/ABhattacharya-dev/LazyRename#readme" rel="noopener noreferrer"&gt;Windows setup instructions&lt;/a&gt;, select that folder in LazyRename, and choose an installed Ollama model.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://github.com/ABhattacharya-dev/LazyRename" rel="noopener noreferrer"&gt;LazyRename on GitHub&lt;/a&gt; is MIT licensed. The main pieces are the &lt;a href="https://github.com/ABhattacharya-dev/LazyRename/blob/main/app.py" rel="noopener noreferrer"&gt;Streamlit interface&lt;/a&gt;, &lt;a href="https://github.com/ABhattacharya-dev/LazyRename/blob/main/lazyrename/core.py" rel="noopener noreferrer"&gt;file handling and undo logic&lt;/a&gt;, and &lt;a href="https://github.com/ABhattacharya-dev/LazyRename/blob/main/lazyrename/ollama.py" rel="noopener noreferrer"&gt;Ollama client&lt;/a&gt;. The repository also has sample files and tests for filename validation, collisions, encrypted PDFs, interrupted batches, and undo.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;The app uses Python 3.11+, Streamlit for the review screen, PyMuPDF for PDF text extraction, and Ollama's local API for suggestions. The user can pick from models already installed in Ollama. The local demo used &lt;code&gt;qwen3.5:4b&lt;/code&gt;; the setup guide also shows how to install &lt;code&gt;gemma3:4b&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The model gets a bounded excerpt of the file's contents, with no original filename in the prompt. LazyRename reads up to three PDF pages or 64 KB of a text file and sends no more than 4,500 characters to Ollama. It skips empty files, encrypted PDFs, binary files, and files over 25 MB. Those limits keep a stray large file from turning a quick folder cleanup into a huge inference job.&lt;/p&gt;

&lt;p&gt;Each model request handles one file. I later found &lt;a href="https://dev.to/sank8/my-1b-model-renamed-one-file-to-another-files-name-the-fix-was-a-provenance-guard-3ekm"&gt;a report of a small model mixing up names across a batch&lt;/a&gt;, which reinforced that choice and the need for a preview.&lt;/p&gt;

&lt;p&gt;After inference, Python sanitizes the proposed name and keeps the original extension. Before applying a batch, it checks for collisions and verifies that the source files have not changed since the preview. The transaction log records the moves so Undo can check the paths again before restoring them. If the original name is occupied or a renamed file has changed, Undo stops instead of overwriting it.&lt;/p&gt;

&lt;p&gt;The model can still misunderstand a file, especially when useful details fall outside the excerpt. That is why the preview is editable and every rename needs a deliberate confirmation. Image-only PDFs need OCR, which this version does not have.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;These files can contain private notes, code, or work documents. With Ollama, the excerpt goes to a model running on the same computer, through &lt;code&gt;127.0.0.1&lt;/code&gt;; it does not have to go to a paid hosted API. There is no API key, and I can switch models without rebuilding the app around one provider.&lt;/p&gt;

&lt;p&gt;The source is open, too. Someone can inspect the extraction limits, change the prompt, add OCR, or tighten the rename checks. The app disables Streamlit usage stats and implements no telemetry. Packages and models need to be downloaded first; I have not tested a full run with network connectivity disabled, so I am not claiming an offline test result.&lt;/p&gt;

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

&lt;p&gt;I used an AI coding assistant while building and testing LazyRename. I have not shared the session transcript yet. If I add it, I will review it first and link it here.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Lazy Payoff
&lt;/h2&gt;

&lt;p&gt;LazyRename displays a potential saving of 30 seconds per selected file. In the four-file sample run, that showed &lt;strong&gt;two minutes&lt;/strong&gt;. It is an assumption for illustrating the manual work, not a measured speedup. I have not timed the full process against hand-renaming a real folder, including model loading and reviewing suggestions.&lt;/p&gt;

</description>
      <category>hf26challenge</category>
      <category>python</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Three Things Outside: letting AI start an observation, then putting the phone away</title>
      <dc:creator>Arkaprava Bhattacharya</dc:creator>
      <pubDate>Sun, 11 Oct 2026 18:55:23 +0000</pubDate>
      <link>https://dev.to/arkaprava_bhattacharya_0d/three-things-outside-letting-ai-start-an-observation-then-putting-the-phone-away-2215</link>
      <guid>https://dev.to/arkaprava_bhattacharya_0d/three-things-outside-letting-ai-start-an-observation-then-putting-the-phone-away-2215</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week1-2026-10-05"&gt;Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;Three Things Outside is a small mobile web exercise: take one outdoor photo, let an open-source object detector suggest three ways to look more closely, then put the phone away for three minutes. The last prompt always asks what the AI missed. After the timer, the person writes one field note. It is for anyone who wants a reason to stop identifying everything on a screen and pay attention outside.&lt;/p&gt;

&lt;p&gt;The interesting result should be the human note, not the model's labels.&lt;/p&gt;

&lt;p&gt;The screenshots show a 15-second judge-demo countdown and a completed note reading “a smell after rain.” They show the interaction, but I have not documented a verified outdoor field test, so I will not present them as proof of one. In the repeatable public-site test, a synthetic PNG gave the model no confident objects. The app said so plainly and still offered three prompts, including one about what lay beyond the frame. That is the behavior I wanted: an imperfect model can start an observation without pretending it saw everything.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Live HTTPS demo:&lt;/strong&gt; &lt;a href="https://main.dkm0k3epi65hg.amplifyapp.com/" rel="noopener noreferrer"&gt;https://main.dkm0k3epi65hg.amplifyapp.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Screenshot 1 — 15-second judge timer:&lt;/strong&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%2F4ew6yn0tzqjgbnk7d3gb.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%2F4ew6yn0tzqjgbnk7d3gb.png" alt="The judge demo timer asking the user to put the phone away" width="799" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Screenshot 2 — completed field note:&lt;/strong&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%2Fywf1q8a3jtt0j9bquejj.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%2Fywf1q8a3jtt0j9bquejj.png" alt="A completed field note reading “a smell after rain”" width="799" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For judges, the same flow has a clearly labeled 15-second demo mode after photo analysis. The standard exercise is three minutes.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;GitHub repository:&lt;/strong&gt; &lt;a href="https://github.com/ABhattacharya-dev/three-things-outside" rel="noopener noreferrer"&gt;https://github.com/ABhattacharya-dev/three-things-outside&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Run locally with &lt;code&gt;python -m http.server 8000&lt;/code&gt;, then open &lt;code&gt;http://localhost:8000/&lt;/code&gt;. The repository README explains the full journey, test checklist, limitations, and deployment.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;The app is buildless HTML, CSS, and JavaScript. TensorFlow.js 4.22.0 runs COCO-SSD 2.2.3 in the browser with its &lt;code&gt;lite_mobilenet_v2&lt;/code&gt; base. A selected JPEG, PNG, or WebP up to 12 MB is decoded into a canvas scaled to at most 960 pixels on its longest edge. Local inference yields up to three classes scoring at least 50%, or an honest empty result. The detections shape the first prompt. The second asks for a sensory detail. The third asks what AI missed. A wall-clock timer sends the person away from the phone; a field note closes the loop. The latest text result uses browser &lt;code&gt;localStorage&lt;/code&gt;; sharing uses Web Share with a selectable text fallback.&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart LR
  A[Outdoor photo] --&amp;gt; B[Browser canvas]
  B --&amp;gt; C[Local COCO-SSD inference]
  C --&amp;gt; D[Three prompts]
  D --&amp;gt; E[Phone-away timer]
  E --&amp;gt; F[Field note]
  F --&amp;gt; G[Text-only local result and share]&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;The app contains no photo upload path or backend. The temporary photo URL is revoked and the preview canvas is cleared after inference. Only the latest note text, completion time, and detected class names go into &lt;code&gt;localStorage&lt;/code&gt;; a blocked store leaves the note usable until reload. The first visit requires downloads of the libraries and model, so this is not an offline-first app. The model can be wrong and must never be treated as a safety or species identifier. A browser Network capture is still needed before claiming the no-upload property was independently verified.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Local audit, October 11:&lt;/strong&gt; The four browser self-checks passed. The pinned model loaded and analyzed a tiny valid PNG in a desktop browser, producing the honest zero-detections path. At desktop and 320 px simulated mobile widths, no horizontal overflow appeared; keyboard focus reached the skip link and file input. Temporary local stubs verified confident detection display, failed model loading with Retry, failed inference with Retry, unsupported/corrupt/oversized image errors, blocked storage, restart, and text-only share fallback. Both the full three-minute timer and 15-second judge mode reached the field-note screen. The synthetic images and stubbed detections are test fixtures, not outdoor evidence.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Public HTTPS audit, October 11:&lt;/strong&gt; An Amplify manual deployment contained only the three runtime files. Requests for the README, DEV draft, project instructions, and self-check page returned 404. In a fresh browser tab at the public URL, the pinned model became ready, analyzed a valid synthetic PNG with zero confident detections, produced three prompts, completed the full 15-second judge timer, and saved a field note. The synthetic image is a technical fixture, not outdoor evidence.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Still to verify:&lt;/strong&gt; physical mobile Chrome and camera permission, a real outdoor image and three-minute phone-away run, a reduced-motion device setting, native Web Share, and a Network capture showing no photo upload.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;An inspectable, replaceable open-source detector makes the photo-to-prompt loop possible without a private inference API. There is no per-image API fee and no account. Because the model's limited object vocabulary is visible, its misses become part of the experience: the person can notice sounds, changes, and details that a single frame cannot capture. Local inference makes a private-photo design possible while keeping the screen part short.&lt;/p&gt;

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

&lt;p&gt;This &lt;a href="https://dev.to/agent_sessions/799"&gt;public curated DevRelay build and verification session&lt;/a&gt; records selected, paraphrased milestones. It contains no raw tool logs, private machine paths, credentials, or photos.&lt;/p&gt;


&lt;div class="ltag-agent-session"&gt;
  &lt;div class="agent-session-header"&gt;
    
    &lt;span class="agent-session-tool-icon-badge" title="Codex"&gt;
&lt;/span&gt;
    &lt;span class="agent-session-title"&gt;Three Things Outside — curated build and verification session&lt;/span&gt;
  &lt;/div&gt;

  &lt;div class="agent-session-scroll"&gt;

      &lt;div class="agent-session-message agent-session-user"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-user"&gt;
          You
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;Requested a buildless Three Things Outside MVP for the Week 1 Touch Grass challenge, using pinned TensorFlow.js 4.22.0 and COCO-SSD 2.2.3, a three-minute outdoor exercise, a 15-second judge demo, privacy boundaries, accessibility, and a DEV draft.&lt;/p&gt;

                &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div class="agent-session-message agent-session-assistant"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-assistant"&gt;
          Agent
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;Curated work summary: built the static HTML, CSS, and JavaScript app with local photo inference, three prompts, wall-clock timer, local-only latest text result, text sharing fallback, error states, a browser logic self-check, README, MIT license, and DEV draft. No backend, account, geolocation, API key, or paid inference was added.&lt;/p&gt;

                &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div class="agent-session-message agent-session-user"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-user"&gt;
          You
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;Requested an audit against the project Definition of Done and live Week 1 rules, with desktop and 320px browser checks and failure-path testing.&lt;/p&gt;

                &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div class="agent-session-message agent-session-assistant"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-assistant"&gt;
          Agent
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;Curated work summary: ran four browser logic checks; tested pinned model loading and real zero-detection inference; exercised timer durations, restart, invalid images, model and inference failures, blocked storage, sharing fallback, keyboard focus, and 320px overflow. Fixed reproducible issues and documented unverified real-device checks.&lt;/p&gt;

                &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div class="agent-session-message agent-session-user"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-user"&gt;
          You
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;Requested a static AWS Amplify deployment, public HTTPS verification, a secret and personal-data scan, and a final article audit without publishing the DEV entry.&lt;/p&gt;

                &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div class="agent-session-message agent-session-assistant"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-assistant"&gt;
          Agent
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;Curated work summary: deployed only index.html, styles.css, and app.js; confirmed other project files return 404; verified the public model load and full 15-second flow with a synthetic PNG; scanned the project and found no credential or personal-data matches. The outdoor test remains a human task.&lt;/p&gt;

                &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div class="agent-session-message agent-session-user"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-user"&gt;
          You
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;Requested creation and posting of a public GitHub repository with updated documentation.&lt;/p&gt;

                &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div class="agent-session-message agent-session-assistant"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-assistant"&gt;
          Agent
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;Curated work summary: created the public repository &lt;a href="https://github.com/ABhattacharya-dev/three-things-outside" rel="noopener noreferrer"&gt;https://github.com/ABhattacharya-dev/three-things-outside&lt;/a&gt;, pushed the source, and updated README and DEV draft links. The DEV article was not published.&lt;/p&gt;

                &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;
  &lt;/div&gt;

  &lt;div class="agent-session-footer"&gt;
    &lt;span class="agent-session-meta"&gt;
        8 of 8 messages
    &lt;/span&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Credits and disclosure
&lt;/h2&gt;

&lt;p&gt;The app uses &lt;a href="https://github.com/tensorflow/tfjs" rel="noopener noreferrer"&gt;TensorFlow.js&lt;/a&gt;, &lt;a href="https://github.com/tensorflow/tfjs-models/tree/master/coco-ssd" rel="noopener noreferrer"&gt;COCO-SSD&lt;/a&gt;, and its &lt;a href="https://cocodataset.org/" rel="noopener noreferrer"&gt;COCO object classes&lt;/a&gt;. Project code is MIT licensed; upstream code, model weights, and data keep their own licenses. Codex AI produced this article and substantial project code at the project owner's request. The post is marked &lt;code&gt;fully_autonomous&lt;/code&gt; in DEV's AI disclosure. The two screenshots were supplied by the project owner; no real outdoor-test account was provided.&lt;/p&gt;

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