<?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: Kushaal Kankane</title>
    <description>The latest articles on DEV Community by Kushaal Kankane (@kushaalk).</description>
    <link>https://dev.to/kushaalk</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%2F4167192%2Fc952186e-fbb0-41c6-88fc-1c8561c11ef6.jpg</url>
      <title>DEV Community: Kushaal Kankane</title>
      <link>https://dev.to/kushaalk</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kushaalk"/>
    <language>en</language>
    <item>
      <title>The Room That Forgot You: A Museum Mystery with an Archivist That Runs in Your Browser</title>
      <dc:creator>Kushaal Kankane</dc:creator>
      <pubDate>Sat, 31 Oct 2026 19:10:24 +0000</pubDate>
      <link>https://dev.to/kushaalk/the-room-that-forgot-you-a-museum-mystery-with-an-archivist-that-runs-in-your-browser-2jkm</link>
      <guid>https://dev.to/kushaalk/the-room-that-forgot-you-a-museum-mystery-with-an-archivist-that-runs-in-your-browser-2jkm</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;The museum knows every donor's name. It cannot tell you who washed the cups.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Room That Forgot You&lt;/strong&gt; is a first-person browser mystery set in a railway museum after closing. Its archivist remembers important visitors and celebrated events. Someone else survives only in the margins: an extra cup, repeated return tickets, handwriting beneath an official signature.&lt;/p&gt;

&lt;p&gt;You enter with a flashlight and a handheld receiver. Your job is to give that person a place in the record.&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%2F4q0cxmb1qxufajoeypz4.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%2F4q0cxmb1qxufajoeypz4.png" alt="The title screen: a rain-dark railway gallery, a clock above the arch, and a single Continue investigation button" width="800" height="820"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The main mechanic is &lt;strong&gt;evidence changing the room&lt;/strong&gt;. Finding a document is only the beginning. Connect it to another record, establish what happened, and confirm the connection. A distorted space regains its sounds, shape, and meaning.&lt;/p&gt;

&lt;p&gt;There are three galleries, eighteen records, and nine connections:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Gallery&lt;/th&gt;
&lt;th&gt;What the room seems to say&lt;/th&gt;
&lt;th&gt;What the records reveal&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Departures&lt;/td&gt;
&lt;td&gt;Someone abandoned the station.&lt;/td&gt;
&lt;td&gt;They kept coming back.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shelter&lt;/td&gt;
&lt;td&gt;Knocking and overturned furniture suggest danger.&lt;/td&gt;
&lt;td&gt;The station sheltered people during a flood.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Names&lt;/td&gt;
&lt;td&gt;Prominent townspeople did everything worth remembering.&lt;/td&gt;
&lt;td&gt;The caretaker's ordinary work kept the doors open.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A presence approaches from blind spots. Hold the flashlight steadily on it to drive it back; wet footprints briefly point toward an unexamined exhibit. Discoveries affect the encounters, and restored galleries become quiet. There is no loss of collected evidence when you make a mistake.&lt;/p&gt;

&lt;p&gt;The horror begins with an unexplained absence. The ending is an act of remembrance.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;&lt;a href="https://the-room-that-forgot-you.givingegret8192.chatgpt.site/" rel="noopener noreferrer"&gt;Enter the museum&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The game is public and needs no account. Use a desktop browser with a keyboard and mouse; Chrome or Edge with compatible WebGPU hardware is the intended setup for the live archivist.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;WASD / arrows:&lt;/strong&gt; move; &lt;strong&gt;Shift:&lt;/strong&gt; hurry.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mouse:&lt;/strong&gt; look; &lt;strong&gt;F:&lt;/strong&gt; flashlight; &lt;strong&gt;E:&lt;/strong&gt; inspect a nearby object.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;J:&lt;/strong&gt; field notes and connections; &lt;strong&gt;R:&lt;/strong&gt; receiver; &lt;strong&gt;Esc:&lt;/strong&gt; pause.&lt;/li&gt;
&lt;li&gt;If mouse capture is unavailable, hold the left mouse button and drag to look.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Enter, approach the return ticket, inspect it, and choose &lt;strong&gt;Keep record&lt;/strong&gt;. Find another supporting record before proposing a connection. Progress is saved in this browser.&lt;/p&gt;

&lt;p&gt;To test the AI, open the receiver and explicitly download the models. The first load is substantial and requires internet access. After collecting the relevant records, try: &lt;strong&gt;“Did A.V. leave the station forever?”&lt;/strong&gt; The answer should reference discovered records and offer a connection for confirmation. Asking ahead of the evidence should not unlock anything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://raw.githubusercontent.com/Kushaal-k/the-room-that-forgot-you/main/public/walkthrough.webm" rel="noopener noreferrer"&gt;Watch the two-minute captioned walkthrough&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That silent recording shows an earlier presentation of the investigation and is labeled &lt;strong&gt;AI inactive&lt;/strong&gt; throughout. It demonstrates authored scenes and transformations; it does not demonstrate live inference or the latest flashlight encounters. The playable link is the current hosted build.&lt;/p&gt;

&lt;p&gt;If live inference cannot load, the authored field notes support manual investigation, and the recorded walkthrough remains available. Those are explicitly separate from a generated answer.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/Kushaal-k/the-room-that-forgot-you" rel="noopener noreferrer"&gt;Source on GitHub — MIT license&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The submission's game snapshot is &lt;a href="https://github.com/Kushaal-k/the-room-that-forgot-you/tree/64ad8d6546f15ab7c528b1c6e9ad52e1a107abac" rel="noopener noreferrer"&gt;commit 64ad8d6&lt;/a&gt;. The repository includes the evidence graph, model worker, tests, dependency notices, and actual model-evaluation outputs.&lt;/p&gt;

&lt;p&gt;To run locally with Node.js 22.21+:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/Kushaal-k/the-room-that-forgot-you.git
&lt;span class="nb"&gt;cd &lt;/span&gt;the-room-that-forgot-you
npm ci
npm run build
npm run preview
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open the localhost address printed by the preview server. On Windows, &lt;strong&gt;Start Museum.cmd&lt;/strong&gt; handles installation, building, and opening the production preview.&lt;/p&gt;

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

&lt;p&gt;React 19, React Three Fiber, Three.js, TypeScript, and Vite render a procedural museum. Rain-dark windows and faded exhibits gradually give way to warmer light. A separate worker runs the archivist.&lt;/p&gt;

&lt;p&gt;Two open-weight models do different jobs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://huggingface.co/Xenova/all-MiniLM-L6-v2" rel="noopener noreferrer"&gt;MiniLM&lt;/a&gt;&lt;/strong&gt;, quantized and run through Transformers.js, matches a freeform question to discovered evidence and eligible conclusions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://huggingface.co/Qwen/Qwen2.5-1.5B-Instruct" rel="noopener noreferrer"&gt;Qwen2.5-1.5B-Instruct&lt;/a&gt;&lt;/strong&gt;, in WebLLM's &lt;code&gt;q4f16_1-MLC&lt;/code&gt; format, resolves an ambiguous shortlist of up to three candidates locally through WebGPU.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Both model cards list Apache 2.0 licensing. The app's own code and fictional story are MIT licensed; model weights are separate downloads.&lt;/p&gt;

&lt;p&gt;The first small-language-model-only approach missed too many paraphrases. Adding neural retrieval gave the language model a smaller decision to make.&lt;/p&gt;

&lt;p&gt;The more important boundary is what happens afterward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Question + discovered archive
        → local neural retrieval
        → Qwen when ambiguous
        → structured record / connection IDs
        → evidence validation
        → player's confirmation
        → room transformation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The worker never receives undiscovered records. The game rejects nonexistent references and incomplete supporting evidence. It renders factual clue text from the authored archive, rather than treating generated prose as canonical history. The model cannot directly open a door or write a save.&lt;/p&gt;

&lt;p&gt;A valid-looking answer can still be wrong. &lt;a href="https://dev.to/theaicommit/why-forced-json-output-is-always-valid-and-sometimes-wrong-2jc8"&gt;The AI Commit's “Why Forced JSON Output Is Always Valid and Sometimes Wrong”&lt;/a&gt; makes the same distinction between parseable output and correct meaning. Here, source validation and an explicit uncertainty response are part of the game rules.&lt;/p&gt;

&lt;h3&gt;
  
  
  What actually passed
&lt;/h3&gt;

&lt;p&gt;The recorded game snapshot passed &lt;strong&gt;21 unit tests&lt;/strong&gt; and its production build. Those checks cover evidence validation, save recovery, controls, and encounter logic.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/Kushaal-k/the-room-that-forgot-you/blob/64ad8d6546f15ab7c528b1c6e9ad52e1a107abac/validation/real-model-evaluation.json" rel="noopener noreferrer"&gt;real-model development evaluation&lt;/a&gt; passed &lt;strong&gt;29/30 development paraphrases, four negative cases, and ten additional checks: 43/44 overall&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The mixed pipeline's median response was about 12 ms, mostly from neural retrieval. Ambiguous Qwen decisions took up to 4.59 seconds. Those timings exclude model download and initialization; they are not a claim that Qwen generates answers in 12 ms.&lt;/p&gt;

&lt;p&gt;One failure remains in the report: &lt;strong&gt;“Who actually opened the station during the flood?”&lt;/strong&gt; retrieves the general refuge connection rather than the actor-specific credit. These are development checks, not a held-out benchmark.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/Kushaal-k/the-room-that-forgot-you/blob/64ad8d6546f15ab7c528b1c6e9ad52e1a107abac/VERIFICATION.md" rel="noopener noreferrer"&gt;verification log&lt;/a&gt; records the limits too. A full investigation was exercised before the latest horror pass; that pass received targeted controls checks. Fresh-player pacing, the intended 25–35 minute duration, sustained frame rate, and a complete disconnected model investigation still need verification.&lt;/p&gt;

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

&lt;p&gt;The archivist runs on the visitor's computer. Questions go to a local worker, with no hosted model endpoint, inference account, or API key.&lt;/p&gt;

&lt;p&gt;For this project, the benefit over a closed hosted API is control over the experience's continued existence. The model, retrieval catalogue, prompts, and evidence rules can be inspected and changed. A developer can replace the model while keeping the story and saves understandable. The museum need not lose its archivist because an inference provider changes pricing or retires an endpoint.&lt;/p&gt;

&lt;p&gt;That fits the subject: preserving someone's place in history should not depend entirely on a service continuing to sell access.&lt;/p&gt;

&lt;p&gt;Local inference also avoids a hosted per-question inference charge. It still costs hardware, electricity, storage, and an initial download. WebGPU compatibility and shared graphics memory are real constraints.&lt;/p&gt;

&lt;p&gt;The app and model runtimes include caching, but &lt;strong&gt;complete offline play has not been verified&lt;/strong&gt;. I am not claiming that this release already works through a disconnected reload and full investigation. A closed model could perform the reasoning; the open approach makes the reasoning setup and its dependencies available to the person preserving the game.&lt;/p&gt;

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

&lt;p&gt;The final reveal is deliberately modest: a workroom, a repaired clock, a kettle, a blue cup, and Ada Vale's name.&lt;/p&gt;

&lt;p&gt;The apparent haunting resolves into traces of someone keeping a place safe for other people. The ending asks you to leave a light burning.&lt;/p&gt;

&lt;p&gt;That is the intended emotional turn. I do not yet have three fresh-player sessions showing that it lands. The next useful test is watching someone discover the connections without help.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I Built Just Upload Because the Upload Box Shouldn't Be the Final Boss</title>
      <dc:creator>Kushaal Kankane</dc:creator>
      <pubDate>Sat, 24 Oct 2026 21:18:37 +0000</pubDate>
      <link>https://dev.to/kushaalk/i-built-just-upload-because-the-upload-box-shouldnt-be-the-final-boss-1948</link>
      <guid>https://dev.to/kushaalk/i-built-just-upload-because-the-upload-box-shouldnt-be-the-final-boss-1948</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;You finished the application.&lt;/p&gt;

&lt;p&gt;You found the certificates. You checked the dates. You are one click away from being done.&lt;/p&gt;

&lt;p&gt;Then the upload box speaks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;One PDF. Under 1 MB. Application first. Certificates oldest to newest. No instruction pages.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Apparently, the final stage of applying for anything is becoming a part-time PDF technician.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Just Upload&lt;/strong&gt; is my attempt to make that stage smaller: drop in the paperwork, paste the requirements, review a proposed plan, and take away one PDF.&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%2Fndz8pnji0auyhxckkslk.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%2Fndz8pnji0auyhxckkslk.jpg" alt="Just Upload's dark interface, with a document dropzone and a panel for upload requirements" width="800" height="821"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The local MVP. All documents shown below are fictional samples.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The idea grew out of the &lt;strong&gt;Slow and Steady&lt;/strong&gt; theme: make a tool that handles a chore so someone can get on with their day.&lt;/p&gt;

&lt;p&gt;This is for the person assembling an application, a workshop registration, or a bundle of supporting documents. They already have the information. The annoying part is packaging it.&lt;/p&gt;

&lt;p&gt;Just Upload brings page selection, ordering, rotation, PDF creation, and file-size checks into one review flow. It accepts static PDFs and JPG, PNG, or WebP images. The output is a PDF.&lt;/p&gt;

&lt;p&gt;The current app runs on the user's computer. No account is needed in the app, and there is no cloud AI upload step.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd4kojor8lxzhegtwgo32.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd4kojor8lxzhegtwgo32.gif" alt="Animated walkthrough of the real Basic-mode sample: home, proposed plan, page inspection, and completed PDF" width="760" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A paced slideshow of actual browser captures, not a real-time performance recording. This demo uses Basic mode, not Gemma inference.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The sample starts in an inconvenient order:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Original position&lt;/th&gt;
&lt;th&gt;Page&lt;/th&gt;
&lt;th&gt;What should happen&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Instructions&lt;/td&gt;
&lt;td&gt;Leave out&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Certificate dated 2025-06-18&lt;/td&gt;
&lt;td&gt;Put last&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Application&lt;/td&gt;
&lt;td&gt;Put first&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Certificate dated 2024-03-12&lt;/td&gt;
&lt;td&gt;Put second&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Paste this requirement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;One PDF under 1 MB. Application first, then certificates
oldest to newest. Exclude instruction pages.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The app proposes application → 2024 certificate → 2025 certificate. The instruction page stays visible in an excluded section, where it can be restored.&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%2Fpqwsk6us91tk6xqch0cf.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%2Fpqwsk6us91tk6xqch0cf.jpg" alt="Review plan showing three included pages in order and the instruction page excluded" width="800" height="821"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That review step matters. A label is a suggestion. You can open the page, move it, rotate it, or change whether it belongs in the output.&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%2Fappi78fxph9yq3k141jz.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%2Fappi78fxph9yq3k141jz.jpg" alt="The fictional application opened for page-by-page inspection" width="800" height="821"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;Create my PDF&lt;/strong&gt;, and the sample becomes a three-page file displayed as &lt;strong&gt;5.6 KB&lt;/strong&gt;, below its 1 MB cap. In this run, the original page content was preserved; stronger scan compression was unnecessary.&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%2F5pjcraca23pbpsab9h7w.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%2F5pjcraca23pbpsab9h7w.jpg" alt="Completed PDF with its measured size, page count, and download button" width="800" height="821"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I haven't measured time saved across users. The concrete payoff demonstrated here is narrower: one interface handles the ordering, exclusion, assembly, and size check that would otherwise require several manual steps.&lt;/p&gt;

&lt;h3&gt;
  
  
  What happens when the limit is impossible?
&lt;/h3&gt;

&lt;p&gt;I gave the same package a deliberately unrealistic cap: &lt;strong&gt;0.001 MB&lt;/strong&gt;, or 1 KB.&lt;/p&gt;

&lt;p&gt;The output was still 5.6 KB. The app reported it as oversized and changed the download label accordingly.&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%2Fnpts4b9uttzoxjpzhcx6.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%2Fnpts4b9uttzoxjpzhcx6.jpg" alt="An intentionally impossible size limit produces an oversized-file warning rather than a success claim" width="800" height="821"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The check is ordinary code:&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;passed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max_bytes&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max_bytes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A plausible-looking PDF is not evidence that it fits. Measuring the actual output is.&lt;/p&gt;

&lt;p&gt;Stronger compression is opt-in because it turns pages into images and can sacrifice selectable text and small-print readability. The user should make that tradeoff knowingly.&lt;/p&gt;

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

&lt;p&gt;The project currently lives in a local Python application; the repository has not been published yet. The stack is FastAPI, PyMuPDF, Pillow, and a plain HTML/CSS/JavaScript interface, with Ollama for the optional local vision path.&lt;/p&gt;

&lt;p&gt;The model gets a limited vocabulary. Here is the actual page-finding schema from the app:&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Finding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Literal&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;application&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;certificate&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;instructions&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;other&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ISO YYYY-MM-DD only if explicitly visible; otherwise null&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;suggested_include&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
    &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;needs_review&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response is validated before it becomes a proposal. That catches malformed output; it cannot prove that a model read a date correctly. Human review remains part of the product.&lt;/p&gt;

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

&lt;p&gt;During planning, a fair objection came up:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Doesn't most of this just need ordinary algorithms?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. Merging PDFs does. Rotating a page does. Counting bytes definitely does.&lt;/p&gt;

&lt;p&gt;The useful place for AI is the interpretation before those operations: reading a portal's wording, examining a scanned page, and suggesting what the document is and where it belongs.&lt;/p&gt;

&lt;p&gt;So the app has two explicit modes:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Mode&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;th&gt;What it doesn't establish&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Basic&lt;/td&gt;
&lt;td&gt;Reads selectable PDF text and explicit phrases; uses keyword and date rules to suggest a plan&lt;/td&gt;
&lt;td&gt;Understanding of photographed text or arbitrary instructions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Local AI&lt;/td&gt;
&lt;td&gt;Calls an installed Ollama vision model to interpret requirements and propose page labels, dates, inclusion decisions, and reasons&lt;/td&gt;
&lt;td&gt;Correctness of those suggestions or acceptance by a portal&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Both lead to the same human review and deterministic PDF builder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Files + portal instructions
             |
    Basic rules OR local vision model
             |
       Structured proposal
             |
       Your page-by-page review
             |
    Merge / rotate / compress in code
             |
    Check actual output -&amp;gt; Download
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The small details that earned their place
&lt;/h3&gt;

&lt;p&gt;Two early mistakes were surprisingly instructive. An “oldest to newest” instruction could be mishandled by looking for the word “newest” alone. An application mentioning supporting certificates could be mislabeled as a certificate.&lt;/p&gt;

&lt;p&gt;Those became reasons to make ordering explicit and prioritize document headings in the Basic classifier. They also reinforced why the review screen should stay.&lt;/p&gt;

&lt;p&gt;The current verification run passes &lt;strong&gt;25 tests&lt;/strong&gt;, covering the sample flow and cases such as ambiguous dates, invalid files, page order, rotations, impossible size limits, session restoration, and the local-model API contract.&lt;/p&gt;

&lt;p&gt;There are intentional limits: 12 files, 30 pages, 40 MB per package, and 12 pages per local AI request. Form/signature-widget PDFs and encrypted PDFs are rejected. Photo-dimension rules, form filling, and guaranteed portal acceptance are outside this MVP.&lt;/p&gt;

&lt;p&gt;Files stay in the local server's memory. Start over clears the package; inactive sessions expire after an hour; restarting the server clears all sessions. The original files are unchanged.&lt;/p&gt;

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

&lt;p&gt;Documents can contain information you would rather keep on your own machine. That makes the location of inference a product decision.&lt;/p&gt;

&lt;p&gt;The local AI path targets &lt;strong&gt;Gemma 3 4B through Ollama&lt;/strong&gt;. A downloaded, compatible vision model can run on the user's machine; the app's AI endpoint is fixed to the local Ollama service. It checks vision capability and rejects cloud model configurations.&lt;/p&gt;

&lt;p&gt;That approach gives this project three useful properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Control over the data path.&lt;/strong&gt; Page images go to a local model process rather than a hosted AI API.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Control over the model and behavior.&lt;/strong&gt; A compatible installed vision model can be selected, and the prompts and validation rules can be changed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No hosted inference fee per document.&lt;/strong&gt; Local hardware, electricity, setup, and model downloads still have costs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once the app dependencies and model are installed, the design does not require a cloud inference service. That is an architectural advantage here, not a claim that local inference is faster or more accurate than a hosted model.&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%2Ftstvs0k8comk8we5594j.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%2Ftstvs0k8comk8we5594j.jpg" alt="Local AI settings showing the model setup instructions and the honest offline status" width="800" height="821"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Current status:&lt;/strong&gt; the Ollama integration is implemented and tested with simulated model responses. A real Gemma model was not running during these demos. I have not measured its document accuracy or inference latency yet. The working demo above proves the Basic-mode workflow, not the AI path.&lt;/p&gt;

&lt;p&gt;The next useful milestone is running the vision path on real, consented document examples: phone photos, rotated scans, faint dates, and confusing headings. I want to record which suggestions people correct, along with latency on actual hardware.&lt;/p&gt;

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

&lt;p&gt;The fictional sample was exercised in the running app: four input pages became three selected pages in the requested order, with the instruction page excluded and the finished PDF measured at 5.6 KB.&lt;/p&gt;

&lt;p&gt;That puts page review, reordering, exclusion, merging, and size checks into one place. The intended payoff is fewer tools to juggle when preparing an application or registration packet. I have not measured time saved with real users, and this is not yet a field-tested AI workflow.&lt;/p&gt;

&lt;p&gt;Two DEV reads helped frame the engineering choices: &lt;a href="https://dev.to/iterationlayer/the-hidden-failure-modes-of-pdf-processing-2kmh"&gt;The Hidden Failure Modes of PDF Processing&lt;/a&gt; and &lt;a href="https://dev.to/iterationlayer/building-reliable-file-processing-pipelines-without-glue-code-4i97"&gt;Building Reliable File Processing Pipelines without Glue Code&lt;/a&gt;, both by &lt;a href="https://dev.to/iterationlayer"&gt;@iterationlayer&lt;/a&gt;. They emphasize early validation, explicit outputs, and visible uncertainty. These are vendor-authored perspectives, not independent validation of this app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the most ridiculous upload requirement you've had to satisfy?&lt;/strong&gt; A tiny file-size limit? A photo with exact dimensions? Five documents that somehow have to become one?&lt;/p&gt;

&lt;p&gt;That last mile is the part I want to make easier.&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; Just Upload integrates Gemma 3 4B through Ollama to interpret upload requirements and suggest document labels, dates, page order, and exclusions locally. Users review the suggestions before ordinary code builds and checks the PDF. The integration has been tested with simulated model responses; real Gemma inference remains to be verified.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>ScopeKit: Turn a Messy Client Brief into a Quote with Local Gemma</title>
      <dc:creator>Kushaal Kankane</dc:creator>
      <pubDate>Thu, 15 Oct 2026 20:14:27 +0000</pubDate>
      <link>https://dev.to/kushaalk/scopekit-turn-a-messy-client-brief-into-a-quote-with-local-gemma-3fj0</link>
      <guid>https://dev.to/kushaalk/scopekit-turn-a-messy-client-brief-into-a-quote-with-local-gemma-3fj0</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week2-2026-10-12"&gt;Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;“Just a simple website” can hide a surprisingly long conversation: Which pages? Who supplies the photos? Does “contact form” include email delivery? Are payments part of this phase?&lt;/p&gt;

&lt;p&gt;I built &lt;strong&gt;ScopeKit&lt;/strong&gt;, a small local AI workbench for freelancers who need to turn those informal messages into something they can review and quote.&lt;/p&gt;

&lt;p&gt;Paste the client's brief, let Gemma suggest a scope, review the deliverables and hours, set your rate, and export a Markdown proposal with a client reply. Source passages sit beside the suggested tasks so you can trace them back to the request.&lt;/p&gt;

&lt;p&gt;The intended customer is an independent web designer or small freelance studio. A possible paid offering is installation and customization of a branded proposal workflow. &lt;strong&gt;That business idea is still a hypothesis: I have not tested willingness to pay or claimed customers or revenue.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The project is deliberately small. There is no account system or client database. Working content stays in memory; only the appearance preference is saved in the browser.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;&lt;a href="https://raw.githubusercontent.com/Kushaal-k/ScopeKit/main/evidence/scopekit-demo.mp4" rel="noopener noreferrer"&gt;Watch the 28-second ScopeKit walkthrough (MP4)&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The video is an edited sequence of actual UI steps using a fictional florist brief and real local Gemma inference. Its pauses do not represent inference timings.&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%2Fzcgndbfkdtzxnnh7fmnk.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%2Fzcgndbfkdtzxnnh7fmnk.png" alt="ScopeKit showing a real local Gemma generation and source-linked deliverables" width="800" height="723"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The test brief asks for a one-page florist website, wedding bouquet gallery, contact form, and phone compatibility. Gemma identifies the website, gallery, and contact form, then proposes questions, assumptions, and exclusions.&lt;/p&gt;

&lt;p&gt;It also suggests only &lt;strong&gt;two hours of work in total&lt;/strong&gt;. That is why review is part of the workflow. In the demonstration, the hours are manually changed to 5, 3, and 3. At $50/hour with a 15% contingency, the example estimate becomes &lt;strong&gt;$632.50&lt;/strong&gt;, with a &lt;strong&gt;$316.25&lt;/strong&gt; deposit. These are illustrative planning numbers, not validated effort predictions.&lt;/p&gt;

&lt;p&gt;The model also puts “Mobile Responsiveness beyond basic phone compatibility” in its suggested exclusions. The client explicitly requested phone support, so that wording needs clarification before sharing. The tool does not establish that a scope is complete or that its proposed terms are appropriate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try it locally:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/Kushaal-k/ScopeKit.git
&lt;span class="nb"&gt;cd &lt;/span&gt;ScopeKit
ollama pull gemma3:1b
python app.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install &lt;a href="https://ollama.com/download" rel="noopener noreferrer"&gt;Ollama&lt;/a&gt; and Python 3.10+ first. Keep Ollama running, then open &lt;code&gt;http://127.0.0.1:8765&lt;/code&gt;. Windows users can use &lt;code&gt;start.cmd&lt;/code&gt;. The hand-written &lt;strong&gt;Try an example&lt;/strong&gt; option lets you explore editing and exporting without a model; it is clearly labeled as a sample.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/Kushaal-k/ScopeKit" rel="noopener noreferrer"&gt;ScopeKit on GitHub&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The MIT-licensed repository includes setup instructions, 19 automated tests, a cross-platform CI workflow, the demo video, a real model response, and a reviewed proposal export.&lt;/p&gt;

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

&lt;p&gt;The frontend is plain HTML, CSS, and JavaScript. A Python standard-library server handles validation, quoting, and the local Ollama connection. There are no Python application dependencies or frontend build tools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gemma 3 1B&lt;/strong&gt; performs the core extraction through Ollama's schema-constrained chat API. Instructions and the brief use a user turn, consistent with &lt;a href="https://ai.google.dev/gemma/docs/core/prompt-structure" rel="noopener noreferrer"&gt;Gemma's prompt structure&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The most useful lesson came from source evidence. An early approach asked the model to produce supporting quotes. It sometimes invented them. Constraining the available quotes still allowed it to select an unrelated passage.&lt;/p&gt;

&lt;p&gt;The final approach gives that mechanical step to code: Gemma proposes tasks, then the server attaches exact passages using task-word overlap and a few aliases, such as phones/mobile. It rejects unmatched task names and duplicate task anchors. One correction attempt is allowed before an error is surfaced.&lt;/p&gt;

&lt;p&gt;This is a traceability heuristic. It cannot prove semantic correctness, completeness, or the absence of overlapping work.&lt;/p&gt;

&lt;p&gt;The separation continues with money: &lt;strong&gt;Python's Decimal arithmetic calculates the quote.&lt;/strong&gt; The model suggests hours; the user reviews them. Manually edited replies survive price changes, with a reminder to check their numbers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client brief → local Gemma → validation and source linking
             → human review → decimal quote → Markdown proposal
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The interface has Light, Dark, and System themes, matching dropdowns, keyboard navigation, and responsive layouts. Briefs and proposals clear when the page reloads.&lt;/p&gt;

&lt;p&gt;All 19 local validation and HTTP integration tests passed. The adapter tests use a mock Ollama server; separate real Gemma runs verify actual inference. &lt;a href="https://github.com/Kushaal-k/ScopeKit/actions/runs/38799480217" rel="noopener noreferrer"&gt;GitHub Actions also passed&lt;/a&gt;, running Python checks on Windows and Linux and JavaScript syntax validation.&lt;/p&gt;

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

&lt;p&gt;Local open-weight inference fits the material this tool handles: client messages, project details, and draft commercial terms.&lt;/p&gt;

&lt;p&gt;Once the model is downloaded, ScopeKit's inference workflow can work offline. It needs no hosted inference account, API key, or per-request payment. Hardware and electricity still have costs, and a small model still makes mistakes.&lt;/p&gt;

&lt;p&gt;Open weights also let the user choose a different local model independently of the application. The model is a replaceable part of a workflow whose validation, calculations, and export format are inspectable.&lt;/p&gt;

&lt;p&gt;The application uses the MIT license. Gemma weights have their own &lt;a href="https://ai.google.dev/gemma/terms" rel="noopener noreferrer"&gt;Google Gemma Terms&lt;/a&gt;; they are a separate download and are not bundled with the source.&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; Gemma 3 1B runs locally through Ollama and extracts the tasks, questions, assumptions, and exclusions at the center of the product. The repository includes real inference evidence and the walkthrough above.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of GitHub Copilot — through GitHub Actions automation:&lt;/strong&gt; The challenge explicitly includes GitHub Actions in this category. ScopeKit uses Actions for its Windows/Linux test matrix and JavaScript checks, with a &lt;a href="https://github.com/Kushaal-k/ScopeKit/actions/runs/38799480217" rel="noopener noreferrer"&gt;successful run&lt;/a&gt;. This entry is based on Actions automation; the app was built with Codex assistance.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Community research
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://dev.to/aiexplore369zoho/structured-output-gives-you-syntax-it-doesnt-give-you-semantics-3c13"&gt;AI Explore's “Structured Output Gives You Syntax. It Doesn't Give You Semantics”&lt;/a&gt; informed the distinction between parseable output and trustworthy suggestions. ScopeKit's invented-quote failures made that distinction concrete.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I Built a Pokédex for Real Nature -Take Photos Offline, Identify Them on Your Laptop</title>
      <dc:creator>Kushaal Kankane</dc:creator>
      <pubDate>Thu, 08 Oct 2026 11:22:03 +0000</pubDate>
      <link>https://dev.to/kushaalk/naturedex-a-little-less-scrolling-a-little-more-exploring-69i</link>
      <guid>https://dev.to/kushaalk/naturedex-a-little-less-scrolling-a-little-more-exploring-69i</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;I built &lt;strong&gt;NatureDex&lt;/strong&gt;, a pocket field guide for the things you notice outside.&lt;/p&gt;

&lt;p&gt;You don’t need a planned hike or a rare discovery. Start with the tree beside your house, a flower along your usual route, or an unfamiliar leaf. Take a picture, keep walking, and learn about it when you get back.&lt;/p&gt;

&lt;p&gt;NatureDex is for curious beginners, casual walkers, and anyone who wants a reason to look more closely at their surroundings.&lt;/p&gt;

&lt;p&gt;The experience follows a simple rhythm:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Capture:&lt;/strong&gt; photograph something that catches your eye.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep walking:&lt;/strong&gt; save photos and notes in Walk mode, even without internet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reconnect:&lt;/strong&gt; when your laptop is available, the open phone app automatically sends waiting photos for identification.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Discover:&lt;/strong&gt; review possible matches and save sightings to your personal Field Guide.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Explore again:&lt;/strong&gt; choose easy, medium, or hard expeditions and earn achievements along the way.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your Field Guide grows from your discoveries, with photos, notes, a sighting timeline, and optional map locations.&lt;/p&gt;

&lt;p&gt;I gave the app a retro, pixel-art look to make collecting discoveries feel playful. The goal is to make the screen a small part of the outing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Take a photo. Pocket the phone. Keep walking.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcas7b4byej7eckkq6q2v.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%2Fcas7b4byej7eckkq6q2v.jpg" alt="NatureDex home screen with a pixel forest and Capture a discovery button" width="378" height="818"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;&lt;a href="https://naturedex.onrender.com/" rel="noopener noreferrer"&gt;Open NatureDex&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;NatureDex has an installable mobile web interface. Set up the laptop companion and scan its private QR code once to pair your phone. After that, you keep using the same app address.&lt;/p&gt;

&lt;p&gt;Load the app before heading outside so offline Walk mode is ready. Identification uses your own laptop; the hosted site provides the interface.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcc558m7f5j7korec3w7w.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%2Fcc558m7f5j7korec3w7w.jpg" alt="NatureDex Field Guide showing pixel illustrations from the sample collection" width="378" height="818"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The sample collection shows NatureDex’s pixel illustrations. Your own Field Guide grows from the sightings you save.&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/Kushaal-k/NatureDex" rel="noopener noreferrer"&gt;NatureDex on GitHub&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The repository includes the app, model setup, and &lt;a href="https://github.com/Kushaal-k/NatureDex/blob/main/docs/direct-sync.md" rel="noopener noreferrer"&gt;phone-to-laptop connection instructions&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;NatureDex’s identification engine uses Imageomics’ open-weight &lt;strong&gt;&lt;a href="https://huggingface.co/imageomics/bioclip-2" rel="noopener noreferrer"&gt;BioCLIP 2&lt;/a&gt;&lt;/strong&gt; through &lt;strong&gt;&lt;a href="https://github.com/Imageomics/pybioclip" rel="noopener noreferrer"&gt;pybioclip&lt;/a&gt;&lt;/strong&gt;. A model built for biological images gives the app its core recognition capability.&lt;/p&gt;

&lt;p&gt;The frontend uses &lt;strong&gt;React, TypeScript, and Vite&lt;/strong&gt;, hosted on &lt;strong&gt;Render&lt;/strong&gt;. A &lt;strong&gt;FastAPI&lt;/strong&gt; backend runs on the laptop, with &lt;strong&gt;SQLite&lt;/strong&gt; storing saved sightings. Offline captures stay in browser storage on the phone until they can be processed.&lt;/p&gt;

&lt;p&gt;The most important design decision was separating &lt;strong&gt;taking a photo&lt;/strong&gt; from &lt;strong&gt;identifying it&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You can walk somewhere with no signal and collect photos without waiting for the model. Later, when your phone and laptop are connected, reopen NatureDex and the queued photos transfer to the laptop. Results come back to the phone for review.&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%2Fchz0hb8irfhc42w41iev.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%2Fchz0hb8irfhc42w41iev.jpg" alt="NatureDex Walk mode for collecting photos offline" width="378" height="818"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;No signal needed to collect a discovery. Identification happens when you reconnect.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The laptop companion starts at Windows sign-in. &lt;strong&gt;Tailscale Funnel&lt;/strong&gt; provides its HTTPS connection without requiring a custom domain, so pairing doesn’t mean entering a new link every session. Photos travel to the laptop through that connection; there is no cloud photo queue.&lt;/p&gt;

&lt;p&gt;My GPU has gone bad, so I ran BioCLIP on my laptop’s &lt;strong&gt;CPU&lt;/strong&gt;. To avoid holding several gigabytes of RAM all day, the model runs in a separate worker that exits after three idle minutes. The connection stays available, and the next photo automatically reloads the model.&lt;/p&gt;

&lt;p&gt;NatureDex also treats identification as a suggestion. It shows alternative matches, makes uncertainty visible, and provides photo-quality hints. Walk results need review before joining the Field Guide.&lt;/p&gt;

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

&lt;p&gt;Open weights let me build the experience around a model I can run myself.&lt;/p&gt;

&lt;p&gt;I don’t need a third-party AI API for every photograph or a per-identification payment. Once the weights are downloaded, inference can run locally without internet access. The remote phone connection still needs internet, but capturing photos outside does not.&lt;/p&gt;

&lt;p&gt;That freedom shaped NatureDex: the phone handles the outdoor moment, while a laptop handles the large model. I can choose where inference happens, experiment with other models, and change how predictions are presented.&lt;/p&gt;

&lt;p&gt;It also meant a broken GPU didn’t end the project. I could keep building with the CPU I already had.&lt;/p&gt;

&lt;p&gt;For NatureDex, open innovation made this workflow possible: &lt;strong&gt;go outside without a connection, collect what catches your eye, and come home to learn about it using a model you control.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A little less scrolling. A little more exploring.&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 Render:&lt;/strong&gt; Render hosts NatureDex’s mobile web interface, while the open-weight identification model runs on the user’s own laptop.&lt;/li&gt;
&lt;/ul&gt;

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