<?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: Kaustubh Jogle</title>
    <description>The latest articles on DEV Community by Kaustubh Jogle (@kaustubhjogle).</description>
    <link>https://dev.to/kaustubhjogle</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%2F884076%2F0fe46396-7612-4832-806f-575ca4b6c934.jpeg</url>
      <title>DEV Community: Kaustubh Jogle</title>
      <link>https://dev.to/kaustubhjogle</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kaustubhjogle"/>
    <language>en</language>
    <item>
      <title>Uncommit the Dead: my unfinished side projects want one last commit</title>
      <dc:creator>Kaustubh Jogle</dc:creator>
      <pubDate>Wed, 28 Oct 2026 18:51:06 +0000</pubDate>
      <link>https://dev.to/kaustubhjogle/uncommit-the-dead-my-unfinished-side-projects-want-one-last-commit-1chn</link>
      <guid>https://dev.to/kaustubhjogle/uncommit-the-dead-my-unfinished-side-projects-want-one-last-commit-1chn</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;“I’ll finish it this weekend” sounds harmless until you find it attached to an old commit, sitting beneath a feature you still remember explaining enthusiastically to somebody who has probably forgotten the conversation.&lt;/p&gt;

&lt;p&gt;I wanted to give that particular kind of unfinished business somewhere to go, because an abandoned repository can still contain a useful idea even when nobody wants to rebuild the entire thing. Including its original developer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Uncommit the Dead&lt;/strong&gt; lets you choose a local Git repository and ask an open-weight model for a smaller next step, based on the limited evidence the application collects from its remains. The ghost is your code. And yes, it has pumpkins, because I apparently decided ordinary software maintenance needed seasonal produce.&lt;/p&gt;

&lt;h3&gt;
  
  
  One last commit
&lt;/h3&gt;

&lt;p&gt;Give the model a time budget and it proposes a small change with a suggested acceptance check, rather than treating your neglected weekend experiment as an invitation to design another startup. Twenty minutes counts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Donate its organs
&lt;/h3&gt;

&lt;p&gt;But perhaps the whole project should stay buried, while one useful component deserves an extraction plan that identifies what you would need to inspect before carrying it into a different codebase. Keep the good bit.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rest in peace
&lt;/h3&gt;

&lt;p&gt;Or ask for a farewell document based on the repository evidence, acknowledging the unfinished work without pretending every experiment needs to become a product before you are allowed to leave it behind. A dignified README funeral.&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%2Fozkl0s47ms9ttjjoja8f.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%2Fozkl0s47ms9ttjjoja8f.png" alt=" " width="761" height="742"&gt;&lt;/a&gt;&lt;/p&gt;

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


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://uncommit-the-dead.vercel.app/" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;uncommit-the-dead.vercel.app&lt;/span&gt;
          

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


&lt;p&gt;The application runs on your machine, where its server can read a selected repository and send the collected context to Ollama without requiring a hosted inference service to handle that evidence. Bring your own ghosts.&lt;/p&gt;

&lt;p&gt;After installing the project dependencies, start Ollama and download a model using the command below, then run the development server and open the local address printed in your terminal when it starts. The setup page helps.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ollama pull gemma3:4b
npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Inside the Graveyard, choose an installed model through the connection panel and use the folder picker to select a repository, or explore a fictional sample before inviting your own unfinished work inside. Samples are labelled clearly. The responses still come from a model request rather than a prerecorded script pretending to think.&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/Kaustubhjogle" rel="noopener noreferrer"&gt;
        Kaustubhjogle
      &lt;/a&gt; / &lt;a href="https://github.com/Kaustubhjogle/Uncommit-the-Dead" rel="noopener noreferrer"&gt;
        Uncommit-the-Dead
      &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;Uncommit the Dead&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;A little afterlife for the side projects you swore you would finish.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Run locally&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;Node 20.9+ and Git required.&lt;/p&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;npm install
npm run dev&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Open &lt;a href="http://127.0.0.1:3000" rel="nofollow noopener noreferrer"&gt;http://127.0.0.1:3000&lt;/a&gt;. The app intentionally binds to loopback and is designed for a trusted personal machine, not public hosting.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Ollama setup guide&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;Read &lt;a href="https://github.com/Kaustubhjogle/Uncommit-the-Dead/public/ollama/README.md" rel="noopener noreferrer"&gt;the Ollama README&lt;/a&gt; for installation, model downloads, usage, and troubleshooting. The same guide is available in the app at &lt;code&gt;/ollama&lt;/code&gt;, with copyable commands and a downloadable README.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Open AI at its core&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;Install Ollama, start it, and download an open-weight model:&lt;/p&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;ollama pull gemma3:4b&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Use &lt;strong&gt;Connect local AI → Check connection&lt;/strong&gt; and select an installed model. Model choice is yours; review its model licence. After dependencies and model weights are installed, the app does not need cloud inference. Ollama is fixed to 127.0.0.1:11434; no API key is required.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;What works&lt;/h2&gt;

&lt;/div&gt;


&lt;ul&gt;

&lt;li&gt;Three labelled fictional repositories to explore the interface…&lt;/li&gt;

&lt;/ul&gt;&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Kaustubhjogle/Uncommit-the-Dead" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


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

&lt;p&gt;The model receives a bounded collection of repository evidence, including README text and TODO lines alongside filenames and recent commit messages, rather than unrestricted access to whatever happens to be on your disk. It cannot inspect everything.&lt;/p&gt;

&lt;p&gt;That context goes to Ollama with a response schema, and the server checks returned evidence references against entries that were actually supplied, discarding unsupported references and rejecting a response if none survive. Matching is deliberately narrow.&lt;/p&gt;

&lt;h3&gt;
  
  
  The small model had opinions
&lt;/h3&gt;

&lt;p&gt;During testing with &lt;strong&gt;Gemma 3 1B through Ollama&lt;/strong&gt;, one supposedly short ghost introduction became a long monologue, while other responses offered plausible advice that still needed someone to inspect it carefully before doing anything. The ghost needed editing.&lt;/p&gt;

&lt;p&gt;I added response-length limits and kept the decorative voice short, while retaining the distinction between a proposed plan and something the application has actually executed or checked against a working implementation. It writes suggestions. You still have to decide whether they make sense for the project sitting in front of you.&lt;/p&gt;

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

&lt;p&gt;An unfinished repository can contain notes that were never intended for anyone outside the project, so using a downloaded local model lets the application send its evidence to Ollama on the same machine. No hosted-model key required.&lt;/p&gt;

&lt;p&gt;There are exclusions for obvious secret filenames and symlinks, although those exclusions are not a comprehensive secret scanner, and choosing a cloud model would undermine the local inference arrangement described here. Choose a local model.&lt;/p&gt;

&lt;p&gt;Once the application dependencies and model weights are installed, the generation path can work without internet.&lt;/p&gt;

&lt;p&gt;And open weights let me try a different installed model without replacing the product, while keeping the prompts and response schema available for inspection when the tiny model offers dubious advice about a CSV exporter. The medium is replaceable.&lt;/p&gt;

&lt;p&gt;A closed API could generate repository plans too, whereas the local open-weight approach lets this application keep its working evidence on the user’s computer and leaves the model choice under their control. That fits this project.&lt;/p&gt;

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

&lt;p&gt;The feature I care about most is &lt;strong&gt;Rest in peace&lt;/strong&gt;, because learning from an experiment should not oblige you to maintain it forever just to justify having spent a few weekends building it. Some projects can end.&lt;/p&gt;

&lt;p&gt;Maybe the useful outcome was discovering a framework you enjoyed, or discovering that you did not actually want to operate a social network for houseplants after the initial excitement wore off. The plants will recover.&lt;/p&gt;

&lt;p&gt;So the app gives unfinished work a manageable ending, whether that means making one tiny change or finally writing the goodbye that lets you keep the lesson without keeping the entire project alive indefinitely. No streak to protect. There is already enough guilt in an untouched repository without me adding a leaderboard to it.&lt;/p&gt;

&lt;p&gt;An old project does not need to become your next company to have mattered, and I wanted this little Halloween application to make revisiting one feel less like being handed another obligation. Just unfinished business.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Best Use of Gemma&lt;/strong&gt; applies to the local Gemma 3 1B generation used in the measured sample above, with support for switching installed Ollama models and Gemma 3 4B documented as a starting option. Open weights, actual ghosts.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>Next of Care: from discharge papers to a plan the family can share</title>
      <dc:creator>Kaustubh Jogle</dc:creator>
      <pubDate>Sat, 24 Oct 2026 12:19:21 +0000</pubDate>
      <link>https://dev.to/kaustubhjogle/next-of-care-from-discharge-papers-to-a-plan-the-family-can-share-2eip</link>
      <guid>https://dev.to/kaustubhjogle/next-of-care-from-discharge-papers-to-a-plan-the-family-can-share-2eip</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;The day after a hospital visit, somebody usually ends up hunting through a discharge letter again, looking for the one line that says whether a tablet belongs before breakfast or after dinner. Then they do it again. Next of Care turns selected care documents into an editable plan that can be read at a glance, so the family does not have to repeat that search every day. A small relief.&lt;/p&gt;

&lt;p&gt;The person using the app selects PDFs, images, or text files in their browser, then reviews and corrects the proposed medicine schedule before taking a copy away. Nothing is silently prescribed. From that reviewed plan, they can make a PDF summary with a compact dosage table, a formatted Excel tracker, a weekly view, or a WhatsApp message for someone helping at home.&lt;/p&gt;

&lt;p&gt;Language matters here. A medicine plan written in English may reach a parent who reads Hindi more comfortably, or an elder who would rather receive a Marathi WhatsApp message than open another spreadsheet. So the same plan can be exported in English, Hindi, or Marathi, including the message that is ready to share with a deliberate tap.&lt;/p&gt;

&lt;p&gt;Imagine this message arriving after a relative gets home: “Take one tablet after breakfast. Take the second after dinner.” Simple words help. The medicine name and dose still deserve a check against the original instruction, but a readable message means the recipient can see the day’s plan without asking someone to photograph the prescription yet again.&lt;/p&gt;

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


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://next-of-care.vercel.app/" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;next-of-care.vercel.app&lt;/span&gt;
          

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



&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://drive.google.com/file/d/1E_eTsXMfpjbWCBZI5jHT8er0QkbsYt_J/view?usp=sharing" rel="noopener noreferrer" class="c-link"&gt;
            Next-Of-Care Demo.mov - Google Drive
          &lt;/a&gt;
        &lt;/h2&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fssl.gstatic.com%2Fdocs%2Fdoclist%2Fimages%2Fdrive_favicon_2026_32dp.png" width="32" height="32"&gt;
          drive.google.com
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&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/Kaustubhjogle" rel="noopener noreferrer"&gt;
        Kaustubhjogle
      &lt;/a&gt; / &lt;a href="https://github.com/Kaustubhjogle/Next-Of-Care" rel="noopener noreferrer"&gt;
        Next-Of-Care
      &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;Next of Care&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Next of Care is a browser-based, local-first care handoff tool. People select discharge letters, prescriptions, follow-up schedules, and other care documents on their own device. An open-weight model drafts an editable plan, with original wording available where a match is found. The app can create a PDF summary, an Excel medicine tracker, a weekly schedule, and a WhatsApp-ready message.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Run locally&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Requires Node.js 20.19+ or 22.12+.&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;npm install
npm run dev&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Open the address printed by Vite. For a static production build:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;npm run build
npm run preview&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;dist/&lt;/code&gt; directory can be hosted as static files. There are no application API routes.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Try a fictional sample&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Select &lt;a href="https://github.com/Kaustubhjogle/Next-Of-Care/output/pdf/sample-medicine-instructions.pdf" rel="noopener noreferrer"&gt;&lt;code&gt;output/pdf/sample-medicine-instructions.pdf&lt;/code&gt;&lt;/a&gt; in the app. It has a twice daily medicine at 7:00 AM and 7:00 PM, a medicine on Monday/Wednesday/Friday after breakfast, an as-needed medicine, and a follow-up example. All names and instructions are synthetic test data.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;How privacy&lt;/h2&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/Kaustubhjogle/Next-Of-Care" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


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

&lt;p&gt;The interface is a React and TypeScript app built with Vite, while PDF.js reads text from PDFs and Tesseract.js handles image text in the browser. Files stay on the device. For the AI step, Transformers.js runs the open-weight &lt;a href="https://huggingface.co/onnx-community/Qwen3-0.6B-ONNX" rel="noopener noreferrer"&gt;Qwen3 0.6B ONNX model&lt;/a&gt; in a browser worker with WebGPU, turning extracted instructions into a draft that the user can edit. Then it is theirs.&lt;/p&gt;

&lt;p&gt;The model is downloaded on first use and cached by the browser, so “local” describes where inference happens rather than promising that a new visitor can start with no internet connection at all. That distinction matters. Once the plan is reviewed, browser-side code produces the PDF, Excel tracker, and share text; the WhatsApp action opens a prepared message only when the user chooses it. Their tap, their choice.&lt;/p&gt;

&lt;p&gt;I kept the generated plan editable because a neat-looking medicine schedule can still be wrong, especially when source documents contain unusual wording or text recognition misses a line. The source stays close. The language option also applies across the summary, PDF, tracker, and WhatsApp text, with medicine names and source wording kept visible where possible so a family can compare them. Everyone can check.&lt;/p&gt;

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

&lt;p&gt;Medical paperwork can be intimate, and I wanted this tool's ordinary path to work without sending selected files to an application server for processing. The browser does the work. Because the model and inference stack are open, the project can be inspected, changed, and run without a paid inference API sitting between a family and its documents. That feels right.&lt;/p&gt;

&lt;p&gt;Another benefit: a developer can swap the model or redesign the export for a household that needs larger type. And they can share it. Open source does not make extraction perfect, but it lets people see how a suggestion was produced and improve the tool instead of treating a black box as the final word.&lt;/p&gt;

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

&lt;p&gt;This is the kind of laziness I wanted to reward: after doing the careful review once, a caregiver can leave a tracker on the fridge and send the same readable schedule to the person taking the medicine. The papers can rest. Tomorrow’s routine starts from a plan that is easier to find than a folded discharge letter, while the original instructions remain close enough to check when anything is unclear. One less search.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Want to Improve Next
&lt;/h2&gt;

&lt;p&gt;Some devices cannot run the browser model comfortably, so I want to offer an explicitly optional hosted model for people who prefer a smaller first download or lack WebGPU support. The app should explain clearly when documents would leave the device, and the local route should remain available for people who want their processing to stay with them. A real choice.&lt;/p&gt;

&lt;p&gt;I also want broader OCR language support, stronger checks for translated dose instructions, and an installable offline package that includes what a household needs before the next hospital visit. None of that replaces review. It would make the handoff gentler for more families, especially when the person reading the plan is far from the person who first brought the papers home.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>PayUnfold: the line in your job offer worth reading twice</title>
      <dc:creator>Kaustubh Jogle</dc:creator>
      <pubDate>Sun, 18 Oct 2026 19:44:43 +0000</pubDate>
      <link>https://dev.to/kaustubhjogle/payunfold-the-line-in-your-job-offer-worth-reading-twice-1dbi</link>
      <guid>https://dev.to/kaustubhjogle/payunfold-the-line-in-your-job-offer-worth-reading-twice-1dbi</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;The offer promises ₹1,20,000 in annual variable pay. A few lines later, it says that payment is subject to company discretion and performance criteria.&lt;/p&gt;

&lt;p&gt;That second sentence is the one I want a person to notice &lt;strong&gt;before&lt;/strong&gt; they reply, “I accept.”&lt;/p&gt;

&lt;p&gt;I built &lt;strong&gt;PayUnfold&lt;/strong&gt; for people navigating a new job. Give it an offer letter and it points to clauses worth clarifying: conditional pay, notice and buyout, bonds or repayment, probation, and work restrictions. Each finding includes the page, the quoted wording, a plain-English explanation, and a neutral question to ask HR. It does not call a clause illegal or tell you to reject an offer.&lt;/p&gt;

&lt;p&gt;After joining, you can optionally add a full-month payslip. PayUnfold reads the figures, lets you correct them, and compares monthly &lt;strong&gt;basic pay, HRA, and fixed gross&lt;/strong&gt; with the offer. It keeps CTC, variable pay, joining bonuses, and one month's fixed pay separate. A ₹3,000 gap becomes a question for payroll, not an accusation: was this proration, leave, a changed structure, or something else?&lt;/p&gt;

&lt;p&gt;The side-hustle customer I want to test is an independent career coach who reviews offers for clients. A private, source-linked first pass could save them time and help them deliver a better conversation. The current app is a free prototype.&lt;/p&gt;

&lt;p&gt;A paid coach workflow is a hypothesis, not a feature I am claiming to have shipped.&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%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F01q84szntz40bbmn0usb.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%2F01q84szntz40bbmn0usb.png" alt=" " width="800" height="381"&gt;&lt;/a&gt;&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/Kaustubhjogle" rel="noopener noreferrer"&gt;
        Kaustubhjogle
      &lt;/a&gt; / &lt;a href="https://github.com/Kaustubhjogle/pay-unfold" rel="noopener noreferrer"&gt;
        pay-unfold
      &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;PayUnfold&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Know what you are signing, then check what you are paid.&lt;/strong&gt; PayUnfold reviews an Indian job offer for terms worth asking about before signing. After joining, you can add a payslip, correct extracted pay amounts, and compare monthly fixed pay.&lt;/p&gt;
&lt;p&gt;This is a local prototype for Indian salaried workers. It suggests questions; it does not decide whether a clause is legally valid, whether an employer made an error, or what financial decision you should make.&lt;/p&gt;
&lt;p&gt;Use the theme toggle in the header to switch between light and dark mode. PayUnfold starts with your system preference and remembers a choice made in the toggle when browser storage is available.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Try the fictional example&lt;/h2&gt;
&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;Install &lt;a href="https://nodejs.org/en/download" rel="nofollow noopener noreferrer"&gt;Node.js&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Open a terminal in this folder and run &lt;code&gt;npm install&lt;/code&gt;, then &lt;code&gt;npm run dev&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Open &lt;a href="http://localhost:3000" rel="nofollow noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Try a fictional example&lt;/strong&gt;. This works without any AI setup.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Use your own&lt;/h2&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/Kaustubhjogle/pay-unfold" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


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

&lt;p&gt;PayUnfold is a Next.js app with PDF.js for preparing document pages and Ollama for local inference.&lt;br&gt;
The browser renders the selected pages. The local Next.js server talks to Ollama at &lt;code&gt;127.0.0.1:11434&lt;/code&gt;; there is no account or document database.&lt;/p&gt;

&lt;p&gt;I split the job deliberately:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The model reads messy documents.&lt;/strong&gt; Offer letters and payslips do not share one layout or vocabulary. An image-capable open-weight model extracts pay fields and suggests clauses worth clarifying.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The person checks the source.&lt;/strong&gt; Extracted amounts stay editable. Findings from selectable-text PDFs are shown only when the quote can be matched to the page text; image-read quotes are marked for manual checking.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code does the arithmetic.&lt;/strong&gt; TypeScript compares only reviewed monthly fixed-pay amounts. The model never decides whether an employer underpaid someone.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The offer review covers the first six PDF pages or one image. Pay-field extraction uses the page, so a salary annexure farther back needs manual correction. The app says how much it read instead of pretending it saw the whole contract.&lt;/p&gt;

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

&lt;p&gt;A calculator can subtract ₹45,000 from ₹48,000. It cannot tell which number is monthly basic pay, which is annual CTC, or why a variable-pay clause deserves a question. That interpretation is why an open-weight model sits at the centre of PayUnfold. The arithmetic stays ordinary code because it should be inspectable and predictable.&lt;/p&gt;

&lt;p&gt;Running the model on the same computer as the app changes the privacy story. An offer letter and payslip can contain salary, address, and employer details. In the local setup, they pass between the browser, the local Next.js process, and local Ollama—not to a third-party AI API. This promise depends on running &lt;strong&gt;both&lt;/strong&gt; programs locally; hosting the app elsewhere would send the document to that host. There are no per-document API charges, although the model still uses your own hardware and electricity.&lt;/p&gt;

&lt;p&gt;Open weights also let a user switch models when one struggles with a scan, a layout, or their laptop. I have not shown that a local model is more accurate than a closed API. The advantage I can demonstrate today is control over where the document goes, which model reads it, and whether an API price change breaks the workflow.&lt;/p&gt;

&lt;p&gt;The business test comes next: put PayUnfold in front of a career coach and a job switcher, watch where the questions help or fail, and ask whether either would pay for a polished private review. Until then, the most honest line in this submission is that &lt;strong&gt;the product works as a prototype; the side hustle is still being tested.&lt;/strong&gt;&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Best Use of Gemma
&lt;/h2&gt;

&lt;p&gt;Gemma has a clear role. PayUnfold’s beginner setup recommends Gemma 3 4B as the local image-reading model for offer letters and payslips&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>I Prefer Alarms Over Reminders, But Hated the Clutter. So I automated it - IOS.</title>
      <dc:creator>Kaustubh Jogle</dc:creator>
      <pubDate>Sat, 10 Oct 2026 22:37:06 +0000</pubDate>
      <link>https://dev.to/kaustubhjogle/i-prefer-alarms-over-reminders-but-hated-the-clutter-so-i-automated-it-ios-1abp</link>
      <guid>https://dev.to/kaustubhjogle/i-prefer-alarms-over-reminders-but-hated-the-clutter-so-i-automated-it-ios-1abp</guid>
      <description>&lt;p&gt;I have a habit of setting alarms for almost everything I need to remember.&lt;/p&gt;

&lt;p&gt;I know the Reminders app exists, but I've always preferred alarms.&lt;/p&gt;

&lt;p&gt;The reason is simple. I find it too easy to ignore a reminder notification. It pops up, I dismiss it, and sometimes I end up forgetting about the task altogether.&lt;/p&gt;

&lt;p&gt;An alarm, on the other hand, actually rings. It grabs my attention and makes it harder for me to ignore whatever I was supposed to do.&lt;/p&gt;

&lt;p&gt;For me, that's a much better way to remember things or make sure I get something done.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But there's one problem with this habit.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After creating alarms for different tasks, my iPhone's Clock app starts filling up with alarms I no longer need.&lt;/p&gt;

&lt;p&gt;And then comes the most annoying part: &lt;strong&gt;deleting those alarms, one by one.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Opening the Clock app, finding the old alarms, and manually deleting them gets tiring pretty quickly.&lt;/p&gt;

&lt;p&gt;I wanted to keep using alarms without having to deal with the clutter.&lt;/p&gt;

&lt;p&gt;That's when I decided to try something with &lt;strong&gt;Apple's Shortcuts app&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It's one of those built-in iPhone apps that I feel is seriously underrated. You can automate quite a few things without installing another app or writing code.&lt;/p&gt;

&lt;p&gt;So I created &lt;strong&gt;four iOS Shortcuts&lt;/strong&gt; to make managing my alarms easier.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Set Alarm Pro: Create an Alarm Without Opening the Clock App &lt;a href="https://www.icloud.com/shortcuts/0f1952d0eae2413fa3a9eb50a92b7a5a" rel="noopener noreferrer"&gt;Link&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;The first shortcut is called &lt;strong&gt;Set Alarm Pro&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It's pretty straightforward.&lt;/p&gt;

&lt;p&gt;When the shortcut is clicked, it asks for two questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What time should the alarm be set for?&lt;/li&gt;
&lt;li&gt;What is the alarm for?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But before creating it, the shortcut adds the &lt;code&gt;&amp;amp;:&lt;/code&gt; prefix to the title. So every alarm created through Set Alarm Pro follows the same naming convention.&lt;/p&gt;

&lt;p&gt;The alarm appears in the Clock app like any other alarm. The difference is that my other shortcuts can now identify it.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Delete Alarm Pro: The Shortcut I Actually Needed &lt;a href="https://www.icloud.com/shortcuts/ba8c6e5c92ea4b20bcf1a321926b4b7c" rel="noopener noreferrer"&gt;Link&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;This is the main reason I started building the whole thing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I was tired of manually deleting alarms that I had already used.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And when you create a lot of alarms for different tasks, that cleanup becomes unnecessarily repetitive.&lt;/p&gt;

&lt;p&gt;When the shortcut is clicked, it gives two options:&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 1: Delete Specific Alarm
&lt;/h3&gt;

&lt;p&gt;Sometimes you want to delete only one alarm while keeping the others.&lt;/p&gt;

&lt;p&gt;Instead of scrolling through the entire alarm list, the shortcut:&lt;/p&gt;

&lt;p&gt;Finds alarms whose labels contain &lt;code&gt;&amp;amp;:&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This makes it much easier to find and remove an alarm without going through the Clock app.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 2: Delete All
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;This is my favourite part.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's say we've created several task-related alarms for a day and no longer need them or want to clear today's alarms.&lt;/p&gt;

&lt;p&gt;Normally, we'd have to open the Clock app and delete each one individually.&lt;/p&gt;

&lt;p&gt;With Delete Alarm Pro, We can simply select &lt;strong&gt;Delete All&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The shortcut uses the &lt;strong&gt;Find Alarms&lt;/strong&gt; action to find alarms containing &lt;code&gt;&amp;amp;:&lt;/code&gt; in their labels and deletes them.&lt;/p&gt;

&lt;p&gt;And because my regular alarms don't use this identifier, they aren't included in the cleanup.&lt;/p&gt;

&lt;p&gt;This was the biggest improvement for me.&lt;br&gt;
A small thing, perhaps, but it solves an annoyance I kept running into.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. View Alarms Pro: Check All The Task-Related Alarms &lt;a href="https://www.icloud.com/shortcuts/c5d853c2bc7844e3bae5678edf13e5cf" rel="noopener noreferrer"&gt;Link&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Sometimes we want to see which task-related alarms we've created without searching through the entire alarm list.&lt;/p&gt;

&lt;p&gt;The shortcut gives a quick overview.&lt;/p&gt;

&lt;p&gt;If no matching alarms are found, it simply shows:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;No alarms found.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Nothing complicated, but it's convenient when we just want to check my alarms.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Alarms Pro: Bringing Everything Together &lt;a href="https://www.icloud.com/shortcuts/ea25b50be5f54e379d62ddc681f05f64" rel="noopener noreferrer"&gt;Link&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;After creating the three shortcuts, I thought it would be better to have everything accessible from one place.&lt;/p&gt;

&lt;p&gt;That's how the fourth shortcut, &lt;strong&gt;Alarms Pro&lt;/strong&gt;, came about.&lt;/p&gt;

&lt;p&gt;It combines the functionality of the other three shortcuts.&lt;/p&gt;

&lt;p&gt;From a single shortcut, One can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Set an alarm&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Delete an alarm or clear matching alarms&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;View existing task-related alarms&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of running three separate shortcuts, We can use one entry point for the entire workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Making It More Convenient with a Home Screen Widget
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbw5cnsubfiwcg1t43e8q.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%2Fbw5cnsubfiwcg1t43e8q.PNG" alt=" " width="800" height="1620"&gt;&lt;/a&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%2Fr6ca8wt7laghnoayzev3.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%2Fr6ca8wt7laghnoayzev3.PNG" alt=" " width="800" height="1620"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There's another thing I like about this setup.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I don't even have to open the Shortcuts app to use it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Apple lets you add shortcuts to your iPhone's Home Screen through a Shortcuts widget.&lt;/p&gt;

&lt;p&gt;So I can keep the shortcuts accessible directly from my Home Screen.&lt;/p&gt;

&lt;p&gt;It's a small convenience, but it makes the whole workflow much more practical for everyday use.&lt;/p&gt;




&lt;p&gt;Here's how they work.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Idea: Give Alarms a Unique Identifier
&lt;/h2&gt;

&lt;p&gt;Before explaining the four shortcuts, there's one small detail that makes everything work.&lt;/p&gt;

&lt;p&gt;Whenever I create an alarm using my shortcut, it automatically adds &lt;code&gt;&amp;amp;:&lt;/code&gt; to the beginning of the alarm title.&lt;/p&gt;

&lt;p&gt;For example, the format looks like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;amp;: [Alarm Title]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Why &lt;code&gt;&amp;amp;:&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;There's nothing special about these characters themselves. I just needed a consistent way to identify alarms created through my shortcut.&lt;/p&gt;

&lt;p&gt;This prefix acts like a tag.&lt;/p&gt;

&lt;p&gt;Later, when I want to view or delete those alarms, my other shortcuts search for alarms whose labels contain &lt;code&gt;&amp;amp;:&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That way, I can manage my task-related alarms separately from my regular alarms.&lt;/p&gt;

&lt;p&gt;It's a simple naming convention, but it's the most important part of the whole setup.&lt;/p&gt;

&lt;p&gt;I used &lt;code&gt;&amp;amp;:&lt;/code&gt;, but you can change the prefix if you prefer.&lt;/p&gt;

&lt;p&gt;Just make sure it doesn't already appear in the titles of alarms you want to keep, since the filter searches for matching text in the alarm label.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;I still prefer alarms over reminders.&lt;/p&gt;

&lt;p&gt;Maybe it's because an alarm is harder for me to ignore, or maybe I've just become used to relying on them.&lt;/p&gt;

&lt;p&gt;Either way, alarms work better for the way I remember things.&lt;/p&gt;

&lt;p&gt;What I didn't like was how cluttered my alarm list became and how tedious it was to delete the alarms afterwards.&lt;/p&gt;

&lt;p&gt;These four shortcuts let me keep using alarms the way I like, without the manual cleanup every time.&lt;/p&gt;

&lt;p&gt;And that's what I enjoy about the Shortcuts app. Sometimes you don't need a complicated solution. A few built-in actions and a simple idea can solve a surprisingly annoying problem.&lt;/p&gt;

&lt;p&gt;If you haven't explored Apple Shortcuts yet, I'd definitely recommend giving it a try.&lt;/p&gt;

&lt;p&gt;Links:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Set Alarm Pro: &lt;a href="https://www.icloud.com/shortcuts/0f1952d0eae2413fa3a9eb50a92b7a5a" rel="noopener noreferrer"&gt;Link&lt;/a&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  2. Delete Alarm Pro: &lt;a href="https://www.icloud.com/shortcuts/ba8c6e5c92ea4b20bcf1a321926b4b7c" rel="noopener noreferrer"&gt;Link&lt;/a&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  3. View Alarms Pro: &lt;a href="https://www.icloud.com/shortcuts/c5d853c2bc7844e3bae5678edf13e5cf" rel="noopener noreferrer"&gt;Link&lt;/a&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  4. Alarms Pro: &lt;a href="https://www.icloud.com/shortcuts/ea25b50be5f54e379d62ddc681f05f64" rel="noopener noreferrer"&gt;Link&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;I'm curious: do you prefer alarms or reminders for remembering tasks?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ios</category>
      <category>automation</category>
      <category>productivity</category>
      <category>iosshortcuts</category>
    </item>
    <item>
      <title>Escaping the Mumbai Local: I built an AI app to give commuters outdoor side quests (and literally "touch grass")</title>
      <dc:creator>Kaustubh Jogle</dc:creator>
      <pubDate>Fri, 09 Oct 2026 23:02:43 +0000</pubDate>
      <link>https://dev.to/kaustubhjogle/escaping-the-mumbai-local-i-built-an-ai-app-to-give-commuters-outdoor-side-quests-and-literally-3ln9</link>
      <guid>https://dev.to/kaustubhjogle/escaping-the-mumbai-local-i-built-an-ai-app-to-give-commuters-outdoor-side-quests-and-literally-3ln9</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;In Mumbai, we know our stations. We know which train to catch, where to change, and which platform gets us home. But ask what grows a short walk outside that station, and the answer gets less certain.&lt;/p&gt;

&lt;p&gt;That gap became &lt;strong&gt;Platform to Park&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It turns a Mumbai railway or metro stop into a small outdoor mission: find a nearby mapped green space, discover what people have observed around it, and leave with one thing to notice. Choose a station. Generate a mission. Pocket the phone.&lt;/p&gt;

&lt;p&gt;The idea started with station connections—those awkward gaps between a railway station and a metro stop with a similar name. Then I found a question I liked more: &lt;em&gt;What if the space outside a station was somewhere worth spending a little time?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Platform to Park is for the commuter who has room for a small detour. You don’t need hiking gear, a weekend plan, or a trip out of the city. You can start at a station you already use.&lt;/p&gt;

&lt;p&gt;The mission gives that detour a purpose. Look closely at a leaf. Listen for a bird. Notice something you normally pass at commuter speed. There’s also an optional &lt;strong&gt;Pocket Mode&lt;/strong&gt;, which uses ElevenLabs to read the mission aloud. It’s a simple interaction with a specific job: help you stop looking at the app.&lt;/p&gt;

&lt;p&gt;My favourite line in the interface is what appears when you take a mission:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Phone down. Eyes up.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s the intended outcome.&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%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyc4buxfv36cyvn1541fl.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%2Fyc4buxfv36cyvn1541fl.png" alt=" " width="799" height="460"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://platform-to-park.onrender.com/" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;platform-to-park.onrender.com&lt;/span&gt;
          

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


&lt;p&gt;The quickest way to explore it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Search for a supported Mumbai railway or metro station.&lt;/li&gt;
&lt;li&gt;Generate an outdoor mission.&lt;/li&gt;
&lt;li&gt;Check the mapped green space and the linked observation sources.&lt;/li&gt;
&lt;li&gt;Take the mission with you.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For the Gemma experience, run the project locally with Ollama. The mission card identifies when Gemma generated the text, so it’s clear which mode you’re seeing.&lt;/p&gt;

&lt;p&gt;The hosted app also works when local inference isn’t available, using a mission assembled from the retrieved open data.&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/Kaustubhjogle" rel="noopener noreferrer"&gt;
        Kaustubhjogle
      &lt;/a&gt; / &lt;a href="https://github.com/Kaustubhjogle/platform-to-park" rel="noopener noreferrer"&gt;
        platform-to-park
      &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;Platform to Park&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Turn a Mumbai train stop into one small reason to go outside.&lt;/p&gt;
&lt;p&gt;Platform to Park combines verified community data with optional local open-weight generation:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;OpenStreetMap supplies the station and nearby public green space.&lt;/li&gt;
&lt;li&gt;iNaturalist supplies research-grade observations around that space.&lt;/li&gt;
&lt;li&gt;The app always creates a grounded outdoor mission from those facts.&lt;/li&gt;
&lt;li&gt;If Ollama is available, a local model rewrites it into a more distinctive mission.&lt;/li&gt;
&lt;li&gt;The user closes the screen and takes the detour.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Pocket Mode can optionally read the finished mission aloud with ElevenLabs, so the user can put their phone away sooner. The app still works fully without it.&lt;/p&gt;
&lt;p&gt;The model is deliberately prevented from inventing routes, access information, or species. It writes only from the open data supplied in its prompt.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why open innovation matters&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;The selected station and generated mission never need to be sent to a proprietary AI provider. The core open-data…&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/Kaustubhjogle/platform-to-park" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


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

&lt;p&gt;I built Platform to Park with Next.js, TypeScript, Gemma 3 through Ollama, OpenStreetMap, and iNaturalist. Each piece has a deliberately small role.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;OpenStreetMap supplies the place:&lt;/strong&gt; The app uses mapped green spaces near supported stations. It links back to the source so users can inspect the place themselves.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;iNaturalist supplies the observation context:&lt;/strong&gt; Nearby research-grade observations give the mission something concrete to draw from. They describe what has been recorded around the area—not what the app can promise you’ll see today.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Gemma supplies the invitation:&lt;/strong&gt; I use &lt;code&gt;gemma3:1b&lt;/code&gt; locally through Ollama to turn those facts into a short headline, an outdoor action, and a noticing prompt.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The model receives the station, green-space name, straight-line distance, and available observation names. Its instructions ask it to stay within those facts and avoid inventing routes, opening hours, access information, or species. That boundary matters. A pleasant sentence is useful. A confidently invented shortcut is not.&lt;/p&gt;

&lt;p&gt;The distance display is also labelled as a straight-line map estimate. Mumbai’s streets, entrances, crossings, and access rules deserve more respect than a line between two coordinates.&lt;/p&gt;

&lt;p&gt;One lesson from building this was that open data still needs checking. Some station queries worked while others failed. I added discovery and verification scripts to check candidates against the data sources rather than filling the dropdown with names that looked convincing.&lt;/p&gt;

&lt;p&gt;On the deployment side, the repository includes a Render Blueprint for the Next.js service, with environment configuration and a health-check endpoint. Gemma runs in the local setup. The public deployment uses the open-data fallback unless a reachable Ollama service is configured. I wanted visitors to be able to try the idea without installing a model first.&lt;/p&gt;

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

&lt;p&gt;For this project, openness affects what I can build and what someone else can change.&lt;/p&gt;

&lt;p&gt;The map comes from community mapping. The biodiversity context comes from people recording the living world around them. Gemma lets me work with an open-weight model on my own machine. Together, those pieces let me connect a familiar station to a place and an observation without asking a model to make up the city.&lt;/p&gt;

&lt;p&gt;Local inference also means the mission-generation step can run without sending its prompt to a proprietary AI provider. I can inspect the prompt, change the instructions, or swap the model through configuration. That flexibility is useful for a small project. I can experiment with how a mission sounds without making every rewrite a paid API call. Someone extending the app can try another model or adapt the experience for another city.&lt;/p&gt;

&lt;p&gt;There are limits worth being clear about: the app fetches map and observation data online, so it isn’t an offline trail guide. Optional ElevenLabs narration sends the finished mission text to that service.&lt;/p&gt;

&lt;p&gt;But the central idea remains portable: community data gives the model its grounding, and local open-weight inference turns that grounding into something a person might actually want to do.&lt;/p&gt;

&lt;p&gt;The data tells me what’s nearby. Gemma helps me find a reason to notice it.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Best Use of Gemma
&lt;/h3&gt;

&lt;p&gt;Platform to Park uses Gemma 3 through Ollama to generate concise outdoor missions grounded in retrieved map and biodiversity data. Its role is to turn a place and a set of observations into a small, specific invitation to go outside. The local setup makes that generation inspectable, replaceable, and runnable without a proprietary inference API.&lt;/p&gt;

&lt;h3&gt;
  
  
  Best Use of Render
&lt;/h3&gt;

&lt;p&gt;Platform to Park includes a Render Blueprint for hosting the Next.js application and its server routes, with environment configuration and a deployment health check. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deployment:&lt;/strong&gt; &lt;a href="https://platform-to-park.onrender.com/" rel="noopener noreferrer"&gt;platform-to-park.onrender.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>My Colleague Was Tired of Saying “Paneer Bhaji Again” to His Maid. So I Built a Local AI Menu Planner.</title>
      <dc:creator>Kaustubh Jogle</dc:creator>
      <pubDate>Sun, 04 Oct 2026 19:36:27 +0000</pubDate>
      <link>https://dev.to/kaustubhjogle/my-colleague-was-tired-of-saying-paneer-bhaji-again-to-his-maid-so-i-built-a-local-ai-menu-4n1m</link>
      <guid>https://dev.to/kaustubhjogle/my-colleague-was-tired-of-saying-paneer-bhaji-again-to-his-maid-so-i-built-a-local-ai-menu-4n1m</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-weekend-2026-10-01"&gt;Hacktoberfest Weekend Challenge: Build for a Friend&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;A colleague from my office lives alone and has a maid who cooks at home.&lt;br&gt;
The problem was not that food was unavailable. His fridge usually had eggs, paneer, spinach, chicken, onions, tomatoes, and the usual basics. The problem was deciding what to make.&lt;/p&gt;

&lt;p&gt;Most evenings ended the same way:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Paneer bana dete hain.”&lt;br&gt;
“Egg bhurji kar lete hain.”&lt;br&gt;
“Chicken curry?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After a few weeks, even good food starts feeling repetitive.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;Aaj Kya Banega&lt;/strong&gt;, a local AI kitchen companion that recommends meals based on what is already in the fridge, what you've cooked recently, and how much time you have.&lt;/p&gt;

&lt;p&gt;The app lets him:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Track ingredients currently available at home&lt;/li&gt;
&lt;li&gt;Add common items or custom ingredients&lt;/li&gt;
&lt;li&gt;Get recipe suggestions ranked by ingredient match&lt;/li&gt;
&lt;li&gt;Ask a local AI model for fresh meal ideas&lt;/li&gt;
&lt;li&gt;Avoid repeating recently cooked dishes&lt;/li&gt;
&lt;li&gt;Save recipes and mark meals as cooked&lt;/li&gt;
&lt;li&gt;Keep fridge data, preferences, and cooking history&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The core question is simple:&lt;br&gt;
What can I make today without getting bored of eating the same thing again?&lt;/p&gt;
&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://aaj-kya-banega-steel.vercel.app/" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;aaj-kya-banega-steel.vercel.app&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&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/Kaustubhjogle" rel="noopener noreferrer"&gt;
        Kaustubhjogle
      &lt;/a&gt; / &lt;a href="https://github.com/Kaustubhjogle/AajKyaBanega" rel="noopener noreferrer"&gt;
        AajKyaBanega
      &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;Aaj Kya Banega?&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A local-first meal planner for the daily question: &lt;strong&gt;what should we cook today?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Built for a colleague who lives alone and was tired of deciding what to tell his maid to cook every day. With a full fridge but the same paneer bhaji appearing again and again, he needed more than another recipe website. He needed a simple, private way to decide tomorrow's meal.&lt;/p&gt;
&lt;p&gt;Add what is in the fridge, explore recipes that fit, shuffle tomorrow's menu, and keep a lightweight record of what was cooked.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;What it does&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Search common ingredients or add any custom item&lt;/li&gt;
&lt;li&gt;Track available fridge items and quantities&lt;/li&gt;
&lt;li&gt;Rank recipes by ingredient match&lt;/li&gt;
&lt;li&gt;Shuffle tomorrow's menu for fresh options&lt;/li&gt;
&lt;li&gt;Save recipes, view cooking steps, and log cooked meals&lt;/li&gt;
&lt;li&gt;Keep data in browser localStorage, with no account required&lt;/li&gt;
&lt;li&gt;Support light and dark themes&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Run locally&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;npm install
npm run dev&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Open &lt;a href="http://localhost:3000" rel="nofollow noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;.&lt;/p&gt;
&lt;div class="markdown-heading"&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/Kaustubhjogle/AajKyaBanega" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


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

&lt;p&gt;Aaj Kya Banega is built with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Next.js&lt;/li&gt;
&lt;li&gt;TypeScript&lt;/li&gt;
&lt;li&gt;Tailwind CSS&lt;/li&gt;
&lt;li&gt;localStorage for local app data&lt;/li&gt;
&lt;li&gt;Ollama for local AI inference&lt;/li&gt;
&lt;li&gt;Gemma 3 as the open-weight recommendation model&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The app has two layers of recommendation.&lt;br&gt;
First, it uses a regular ingredient-matching system to identify recipes that already fit what is in the fridge. This is quick, predictable, and useful even without generating anything.&lt;br&gt;
Then, Ollama runs Gemma 3 locally to make the recommendations more personal. The model receives a focused kitchen context:&lt;br&gt;
Available ingredients:&lt;br&gt;
Eggs, paneer, spinach, onion, tomatoes, green chillies&lt;/p&gt;

&lt;p&gt;Recently cooked:&lt;br&gt;
Egg bhurji, paneer butter masala&lt;/p&gt;

&lt;p&gt;Preferences:&lt;br&gt;
Quick Indian home-style dinner for two people.&lt;br&gt;
Avoid repeating recent meals.&lt;/p&gt;

&lt;p&gt;Suggest exactly three meal ideas.&lt;br&gt;
Clearly mention what is already available and what needs to be bought.&lt;br&gt;
Keep the cooking instructions simple.&lt;br&gt;
Return structured JSON only.&lt;/p&gt;

&lt;p&gt;The model returns structured recipe data that the app can display cleanly:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;{&lt;br&gt;
  "title": "Palak Paneer with Roti",&lt;br&gt;
  "whyItFits": "Uses spinach and paneer already available at home.",&lt;br&gt;
  "availableIngredients": ["spinach", "paneer", "onion", "garlic"],&lt;br&gt;
  "missingIngredients": ["cream"],&lt;br&gt;
  "prepTime": "30 minutes",&lt;br&gt;
  "maidInstruction": "Make palak paneer with roti for two people. Keep it mildly spicy."&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This keeps the AI useful without letting it become a vague chat interface.&lt;/p&gt;

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

&lt;p&gt;For this project, open innovation matters because a kitchen is personal.&lt;/p&gt;

&lt;p&gt;A fridge inventory may sound harmless, but it can reveal habits, food preferences, budgets, dietary restrictions, and daily routines. My colleague should not need to send all of that to a cloud API just to decide dinner.&lt;br&gt;
With Ollama and Gemma 3 running locally:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The meal recommendation flow works without an API key.&lt;/li&gt;
&lt;li&gt;Fridge data and cooking history stay on the user’s machine.&lt;/li&gt;
&lt;li&gt;The model can run without depending on an internet connection.&lt;/li&gt;
&lt;li&gt;The recommendation behavior can be changed by editing a prompt.&lt;/li&gt;
&lt;li&gt;A different open-weight model can be swapped in later.&lt;/li&gt;
&lt;li&gt;There is no per-request cost for every dinner decision.
A closed API would have been faster to connect, but it would make the product dependent on a provider, a network connection, and recurring usage costs.
For a small tool built for one person, local AI felt like the better fit.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What’s Next
&lt;/h2&gt;

&lt;p&gt;The next feature is a WhatsApp or SMS handoff.&lt;/p&gt;

&lt;p&gt;Once a recipe is selected, Aaj Kya Banega should create a short cooking message that can be sent directly to the maid:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Today: Palak Paneer with Roti&lt;br&gt;
For: 2 people&lt;br&gt;
Use: spinach, paneer, onion, garlic&lt;br&gt;
Buy: cream&lt;br&gt;
Please make it mildly spicy.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The current version already supports generating this instruction locally. The next step is connecting it to a messaging provider.&lt;/p&gt;

&lt;p&gt;I also plan to add:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Allergy and dietary preference support&lt;/li&gt;
&lt;li&gt;Better ingredient substitutions&lt;/li&gt;
&lt;li&gt;Weekly meal variety planning&lt;/li&gt;
&lt;/ul&gt;

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

&lt;h3&gt;
  
  
  Best Use of Gemma
&lt;/h3&gt;

&lt;p&gt;Aaj Kya Banega uses Gemma 3 running locally through Ollama to recommend practical meals from ingredients already available at home. The model considers fridge inventory, recently cooked meals, cooking time, and dietary preferences while keeping the recommendation flow private and local.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>hf26challenge</category>
      <category>hacktoberfest</category>
    </item>
    <item>
      <title>My Portfolio Site Was Invisible to AI. Here's What Fixed It.</title>
      <dc:creator>Kaustubh Jogle</dc:creator>
      <pubDate>Sun, 28 Jun 2026 17:17:15 +0000</pubDate>
      <link>https://dev.to/kaustubhjogle/my-portfolio-site-was-invisible-to-ai-heres-what-fixed-it-hjg</link>
      <guid>https://dev.to/kaustubhjogle/my-portfolio-site-was-invisible-to-ai-heres-what-fixed-it-hjg</guid>
      <description>&lt;p&gt;I built my portfolio site as a slick React SPA with a hero section, smooth scroll-spy navbar, the works. Looked great in a browser. Then I ran an framer AEO report.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;27 out of 100.&lt;/strong&gt; Bottom 25%.&lt;/p&gt;

&lt;p&gt;The diagnosis was blunt: &lt;em&gt;"AI can't understand this site yet. The site lacks essential text content."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Turns out, I'd built a site that was beautiful to humans and completely invisible to machines. Here's how I took it from 27 to ~85 in a single afternoon and what I wish I'd known before I started.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wait, What's AEO?
&lt;/h2&gt;

&lt;p&gt;AEO stands for &lt;strong&gt;AI Engine Optimization&lt;/strong&gt;, think of it as SEO that specifically cares about how AI systems (ChatGPT, Gemini, Perplexity, Claude) understand and cite your content. It scores across four categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Findable&lt;/strong&gt; — Can crawlers discover your pages?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quotable&lt;/strong&gt; — Is there enough real text to quote?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Understandable&lt;/strong&gt; — Does the page have structured meaning?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trustworthy&lt;/strong&gt; — Does the content link to credible sources?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My site was mediocre on the first two and &lt;em&gt;zeroed out&lt;/em&gt; on the last two. Cool.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Root Problem: SPAs Are Invisible by Default
&lt;/h2&gt;

&lt;p&gt;Here's the thing nobody tells you when you ship a Vite + React SPA: AI crawlers don't execute JavaScript. They see your &lt;code&gt;index.html&lt;/code&gt;, which in my case looked like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"root"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/src/main.tsx"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. That's what GPTBot, ClaudeBot, and PerplexityBot see in an empty div. My entire portfolio experience, projects, skills, and education existed only in a JavaScript-rendered DOM. To a crawler, my site was a blank page with a title.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fixes, Category by Category
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Findable: The Low-Hanging Fruit (+14 points)
&lt;/h3&gt;

&lt;p&gt;Two files I simply didn't have:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;sitemap.xml&lt;/code&gt;&lt;/strong&gt; — A single-page portfolio only needs one &lt;code&gt;&amp;lt;url&amp;gt;&lt;/code&gt; entry. Took 30 seconds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Canonical URL&lt;/strong&gt; — One &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt; tag in &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;. Without it, AI treats &lt;code&gt;kaustubhjogle.site&lt;/code&gt;, &lt;code&gt;www.kaustubhjogle.site&lt;/code&gt;, and &lt;code&gt;kaustubhjogle.site/&lt;/code&gt; as three different pages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"canonical"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://kaustubhjogle.site/"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I also updated &lt;code&gt;robots.txt&lt;/code&gt; to explicitly welcome AI crawlers. The default &lt;code&gt;User-agent: * / Allow: /&lt;/code&gt; technically works, but naming them directly &lt;code&gt;GPTBot&lt;/code&gt;, &lt;code&gt;ClaudeBot&lt;/code&gt;, &lt;code&gt;PerplexityBot&lt;/code&gt;, &lt;code&gt;Google-Extended&lt;/code&gt; signals intent.&lt;/p&gt;

&lt;h3&gt;
  
  
  Quotable: The Big One (+14 points)
&lt;/h3&gt;

&lt;p&gt;This was the category that hurt the most, because the fix forced me to confront an uncomfortable truth: &lt;strong&gt;my entire site had zero words of readable text as far as crawlers were concerned.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The solution? A &lt;code&gt;&amp;lt;noscript&amp;gt;&lt;/code&gt; block. I wrote 500+ words of semantic HTML that mirrors my portfolio content, full of sentences about my experience, skills, projects, and education. It's invisible to JavaScript-enabled browsers but fully readable by crawlers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;noscript&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;main&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Kaustubh Jogle — Software Engineer&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;section&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Professional Experience&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
      &lt;span class="c"&gt;&amp;lt;!-- ... Portfolio content --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- ... full portfolio content continues --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/noscript&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This felt redundant. It is redundant. But it's also the difference between "AI can't understand this site" and "AI can quote you accurately."&lt;/p&gt;

&lt;p&gt;I also added a FAQ section, both as a React component and in the &lt;code&gt;&amp;lt;noscript&amp;gt;&lt;/code&gt; fallback. Questions like &lt;em&gt;"What technologies does Kaustubh work with?"&lt;/em&gt; with proper answers. This maps directly to how people ask AI assistants about developers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Understandable: Structure Over Style (+18 points)
&lt;/h3&gt;

&lt;p&gt;My hero section had &lt;em&gt;two&lt;/em&gt; &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; tags, one for "KAUSTUBH", one for "JOGLE". Looked sick visually. Terrible semantically. Merged them into a single &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; with &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; children:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"display-giant ..."&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;KAUSTUBH&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;JOGLE&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same visual result. Correct heading hierarchy.&lt;/p&gt;

&lt;p&gt;The biggest win here was &lt;strong&gt;JSON-LD structured data&lt;/strong&gt;. I added three schemas to &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Person&lt;/code&gt;&lt;/strong&gt; — name, jobTitle, worksFor, alumniOf, sameAs (GitHub, LinkedIn), knowsAbout&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;WebSite&lt;/code&gt;&lt;/strong&gt; — basic site metadata&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;FAQPage&lt;/code&gt;&lt;/strong&gt; — all my FAQ question-answer pairs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the most reliable way for AI to understand &lt;em&gt;what&lt;/em&gt; your page is about, not just &lt;em&gt;that&lt;/em&gt; it exists.&lt;/p&gt;

&lt;p&gt;I also filled in the OG tags I'd left empty: &lt;code&gt;og:description&lt;/code&gt;, &lt;code&gt;og:url&lt;/code&gt;, &lt;code&gt;og:image&lt;/code&gt;. These weren't just empty strings; they were literally &lt;code&gt;content=""&lt;/code&gt;. Cringe.&lt;/p&gt;

&lt;h3&gt;
  
  
  Trustworthy: Links Actually Matter (+25 points)
&lt;/h3&gt;

&lt;p&gt;This was the category I was scoring &lt;strong&gt;0/25&lt;/strong&gt; on. The fix was straightforward but required touching almost every component.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Internal contextual links&lt;/strong&gt; (nav and footer links don't count):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hero tagline → "See my work experience →" linking to &lt;code&gt;#experience&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Experience description → "View my full tech stack →" linking to &lt;code&gt;#tech&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Skills section → "explore my projects →" linking to &lt;code&gt;#projects&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;External citation links:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Education institutions → linked to &lt;code&gt;tsec.edu&lt;/code&gt; and &lt;code&gt;sbmp.ac.in&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Project links changed from icon-only to visible text: "View Source" and "Try it Live"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key insight: &lt;strong&gt;body links signal authority, nav links don't.&lt;/strong&gt; The AEO checker specifically ignores navigation and footer links.&lt;/p&gt;

&lt;p&gt;Finally, I created an &lt;code&gt;llms.txt&lt;/code&gt; file, an emerging standard (like &lt;code&gt;robots.txt&lt;/code&gt; but for AI) that describes your site in plain markdown. It's a bonus check that won't penalize you if missing, but adds points if present.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd Do Differently
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Start with the &lt;code&gt;&amp;lt;noscript&amp;gt;&lt;/code&gt; block.&lt;/strong&gt; If you're building a client-rendered SPA, write your noscript fallback &lt;em&gt;first&lt;/em&gt;. It forces you to think about your content as plain text before you think about animations and layouts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't treat meta tags as an afterthought.&lt;/strong&gt; Those &lt;code&gt;content=""&lt;/code&gt; empty strings? They shipped to production. For months. Embarrassing in retrospect, but incredibly common.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JSON-LD is not optional anymore.&lt;/strong&gt; It used to feel like bonus points for SEO nerds. Now it's the primary way AI systems categorize your content. For a portfolio site, the &lt;code&gt;Person&lt;/code&gt; schema alone does heavy lifting.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Scorecard
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Before&lt;/th&gt;
&lt;th&gt;After&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Findable&lt;/td&gt;
&lt;td&gt;11/25&lt;/td&gt;
&lt;td&gt;25/25&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Quotable&lt;/td&gt;
&lt;td&gt;11/25&lt;/td&gt;
&lt;td&gt;25/25&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Understandable&lt;/td&gt;
&lt;td&gt;5/25&lt;/td&gt;
&lt;td&gt;25/25&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trustworthy&lt;/td&gt;
&lt;td&gt;0/25&lt;/td&gt;
&lt;td&gt;10/25&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;27/100&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;85+/100&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  The Takeaway
&lt;/h2&gt;

&lt;p&gt;AEO isn't some mystical new discipline. It's the stuff we've always known we &lt;em&gt;should&lt;/em&gt; do: semantic HTML, proper meta tags, structured data, meaningful links, but skip because "it works in the browser."&lt;/p&gt;

&lt;p&gt;The browser isn't the only consumer of your HTML anymore. AI is reading your markup right now, and it's grading you on whether you made it easy or impossible to understand.&lt;/p&gt;

&lt;p&gt;For SPAs specifically, your framework renders beautiful UI. Your &lt;code&gt;index.html&lt;/code&gt; renders nothing.&lt;br&gt;
Bridge that gap, and you'll go from invisible to quotable.&lt;/p&gt;




</description>
      <category>portfolio</category>
      <category>seo</category>
      <category>aeo</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
