<?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: Nayananshu Garai</title>
    <description>The latest articles on DEV Community by Nayananshu Garai (@ngarai).</description>
    <link>https://dev.to/ngarai</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%2F3964950%2F3401bc07-7936-4788-a822-066adf4f65f0.png</url>
      <title>DEV Community: Nayananshu Garai</title>
      <link>https://dev.to/ngarai</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ngarai"/>
    <language>en</language>
    <item>
      <title>Phantom Troupe: Ghost in the Machine — Haunted Shell Autopsy</title>
      <dc:creator>Nayananshu Garai</dc:creator>
      <pubDate>Sat, 31 Oct 2026 15:52:56 +0000</pubDate>
      <link>https://dev.to/ngarai/phantom-troupe-ghost-in-the-machine-haunted-shell-autopsy-49p3</link>
      <guid>https://dev.to/ngarai/phantom-troupe-ghost-in-the-machine-haunted-shell-autopsy-49p3</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 built Phantom Troupe, a command-line tool that treats every failed terminal command like a corpse that deserves an autopsy. When you mistype a command, fat-finger a flag, or hit a permission denied error, Phantom Troupe captures it, files it in a local morgue, and dispatches a small team of AI agents to figure out what killed it and how to bring it back.&lt;/p&gt;

&lt;p&gt;The theme — Ghost in the Machine — is literal here. Your shell is haunted by every command that died mid-execution. Phantom Troupe makes those ghosts visible: the Coroner writes cause-of-death reports, the Interpreter explains what a command does and when it's dangerous, the Exorcist guards against destructive commands, the Medium inventories dead scripts, and the Understudy proposes resurrections. It's a séance for your terminal, running entirely on your machine with open-weight models.&lt;/p&gt;

&lt;p&gt;It works offline. There's no cloud round-trip for every typo, no account to create, and nothing phones home unless you opt into crash telemetry. You can run it with Gemma 3 through Ollama locally, or point it at the Gemma API if you'd rather not run anything locally. It hooks into zsh, bash, and PowerShell so it catches failures the moment they happen, then keeps a graveyard of dead scripts, aliases, and scheduled tasks you can resurrect or retire later.&lt;/p&gt;

&lt;p&gt;The idea came from watching how many commands fail and vanish without a trace. We mistype, we forget, we repeat the same mistake an hour later. Phantom Troupe makes those failures stick around long enough to learn from them.&lt;/p&gt;

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

&lt;p&gt;The live site is at &lt;a href="https://phantom-troupe.onrender.com/" rel="noopener noreferrer"&gt;https://phantom-troupe.onrender.com/&lt;/a&gt;. It's a static landing page with a creepy horror theme — dark forests, roaming spirits, bats diving toward the viewer, a pockmarked moon, and a zombie hand clawing out of its grave. It walks through what the tool does, shows the architecture, and lets you try a browser-based simulation of the séance table.&lt;/p&gt;

&lt;p&gt;The real tool runs locally on your machine. Install it with one command, and &lt;code&gt;phantom graveyard&lt;/code&gt; opens a local UI at &lt;a href="http://127.0.0.1:7313" rel="noopener noreferrer"&gt;http://127.0.0.1:7313&lt;/a&gt; where you can execute real commands and watch the troupe autopsy failures in real time. Failed commands trigger the Coroner automatically; dangerous commands are stopped by the Exorcist before they run; idle brains are released by the Reaper with a spirit ascending from the side of the screen.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://github.com/N-Garai/Phantom-Troupe" rel="noopener noreferrer"&gt;https://github.com/N-Garai/Phantom-Troupe&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;The backbone is a small fleet of specialist agents built with the Mastra framework. Each failure routes to the right agent: the Coroner writes cause-of-death reports, the Interpreter explains what a command does and when it's dangerous, the Exorcist guards against destructive commands, the Medium inventories dead scripts, and the Understudy proposes resurrections. Every response passes through an evaluator that scores it for confidence and safety before it reaches your screen.&lt;/p&gt;

&lt;p&gt;For memory, it uses LibSQL to store long-term context about your graveyard, so the troupe remembers what died last week and what cured it. The shell hooks are native — zsh preexec/precmd, bash DEBUG traps, and PowerShell prompt hooks — so capture happens without you thinking about it. Nightly sweeps run through systemd on Linux, launchd on macOS, and schtasks on Windows.&lt;/p&gt;

&lt;p&gt;Everything is local-first. If you use Ollama, the model never leaves your machine. If you prefer the Gemma API, you provide your own key and it's stored in your config file, not ours. Sentry telemetry is opt-in only — without a DSN, nothing is sent anywhere. When you do configure a DSN, agent invocations are traced with spans so latency, token cost, failures, and fallback routing are visible in Sentry's trace view.&lt;/p&gt;

&lt;p&gt;This is grounded in research on how developers actually use the command line and where they stumble. Work like &lt;a href="https://doi.org/10.1145/357417.357421" rel="noopener noreferrer"&gt;Fischer et al. on UNIX command use&lt;/a&gt;, &lt;a href="https://dl.acm.org/doi/10.1109/ICSME.2014.31" rel="noopener noreferrer"&gt;Potdar and Shihab on developer debt patterns&lt;/a&gt;, and &lt;a href="https://www.usenix.org/system/files/conference/hotos13/hotos13-final9.pdf" rel="noopener noreferrer"&gt;Luo et al. on failure recovery&lt;/a&gt; informed how we capture and categorize what goes wrong.&lt;/p&gt;

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

&lt;p&gt;Closed APIs turn every failed &lt;code&gt;git push&lt;/code&gt; into a data point for someone else's model. Open weights and local inference flip that: your typos stay yours, your command history stays on your disk, and nobody builds a product from your mistakes without asking.&lt;/p&gt;

&lt;p&gt;Open innovation made this possible because we could build on open frameworks, open models, and open standards without asking permission. It also means anyone can fork Phantom Troupe, add their own agents, or rewire the hooks for a shell we haven't touched yet. The graveyard format is plain text — you own the bones. And because it runs offline, it works with the lights — and the internet — off.&lt;/p&gt;

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

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

&lt;p&gt;Día de los Muertos is about the line between past and present feeling a little thinner — about remembering what's gone and keeping it close. That's the spirit of Phantom Troupe. Every failed command, every dead script, every alias that stopped working — they're not just errors. They're moments where something didn't go as expected, and they deserve to be remembered.&lt;/p&gt;

&lt;p&gt;I built this because I was tired of watching my own mistakes vanish without a trace. You type the same wrong command three times and realize you've forgotten why it broke the first time. That frustration is a ghost haunting your shell. Phantom Troupe makes those ghosts visible, files them in a morgue, and lets you decide which ones to resurrect and which ones to lay to rest.&lt;/p&gt;

&lt;p&gt;The loading screen plays like a rite — a dark forest, smoke everywhere, bats diving toward the screen, the name materializing from mist before dissolving back into it. Then the séance begins. It gives me chills every time, because it turns something ordinary — a typo at the command line — into something worth keeping.&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; — the landing page and demo are hosted as a static site on Render&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Mastra&lt;/strong&gt; — the agent network, structured outputs, LibSQL memory, and séance workflow are built on Mastra&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Sentry Agent Tracing&lt;/strong&gt; — agent invocations are traced with spans in Sentry (opt-in), showing latency, token cost, failures, and fallback routing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Gemma&lt;/strong&gt; — Gemma 3 runs locally through Ollama, with a Gemma API option for remote inference&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>DocDrift: Your Code Drifted. Your Docs Didn't Have To.</title>
      <dc:creator>Nayananshu Garai</dc:creator>
      <pubDate>Mon, 26 Oct 2026 05:06:29 +0000</pubDate>
      <link>https://dev.to/ngarai/docdrift-your-code-drifted-your-docs-didnt-have-to-g05</link>
      <guid>https://dev.to/ngarai/docdrift-your-code-drifted-your-docs-didnt-have-to-g05</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;DocDrift — a background watcher that keeps your docs honest, powered entirely by open-source AI. &lt;/p&gt;

&lt;h3&gt;
  
  
  The Problem-----
&lt;/h3&gt;

&lt;p&gt;Here's the loop it breaks. You ship a feature. An env var gets renamed, a default port changes, an endpoint moves to &lt;code&gt;/v2&lt;/code&gt;. Your README is now quietly fiction, and somewhere between "I'll update it in the next commit" and "the next commit turned into 40," the docs die. Empirical research backs the feeling — the ICSME 2023 study on outdated documentation references (&lt;a href="https://arxiv.org/abs/2212.01479" rel="noopener noreferrer"&gt;"Detecting Outdated Code Element References in Software Documentation"&lt;/a&gt;) found docs routinely pointing at code elements deleted many revisions ago. And notably, string-matching tools can only flag references whose occurrences drop to zero — a changed default like &lt;code&gt;PORT 3000 → 8080&lt;/code&gt; sails straight past them, because the string still exists. DocDrift compares &lt;em&gt;values and shapes&lt;/em&gt;, not just string existence.&lt;/p&gt;

&lt;p&gt;What it actually does:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Parses the real AST, not vibes.&lt;/strong&gt; tree-sitter WASM grammars extract exported functions, classes, interfaces, routes and config keys from your TypeScript and Python files, each with line-precise evidence. If a grammar chokes on exotic syntax, a structural fallback extractor takes over and the miss lands in a queryable failure ledger. On the docs side, your README tables, setup guides and &lt;code&gt;.env.example&lt;/code&gt; are parsed into typed targets with the same rigor — so both sides of the comparison speak the same language.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runs a nine-step agent crew with two validation gates.&lt;/strong&gt; A Mastra workflow (&lt;code&gt;doc-drift-sync&lt;/code&gt;) chains intake → extract → docs → synthesize → gate-1 → patch → gate-2 → tone → emit into one typed, inspectable graph. Gemma drafts the findings; Gate 1 then drops every claim the AST can't prove — no phantom links survive — and Gate 2 applies the proposed patch to a shadow copy of your docs, re-parses it, and refuses edits that would break a markdown table.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gives you a reviewable PR, not a robot merge.&lt;/strong&gt; The output is a unified diff, a humanized PR title and body, and a full step trace with timings. You review. That is the whole job. PRs open from a &lt;code&gt;docdrift/docs-sync-&amp;lt;timestamp&amp;gt;&lt;/code&gt; branch against your default branch — never auto-merged.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are two ways to use it. The &lt;strong&gt;Studio&lt;/strong&gt;: sign in with GitHub (your own account, your own token — DocDrift never holds an org-wide key), pick a repo, branch and doc file, and watch the whole pipeline run live. Or the &lt;strong&gt;autopilot&lt;/strong&gt;: install a push webhook on your repo, and every push that drifts the docs opens a docs-sync PR without you opening anything. HMAC-SHA256 verified, scoped to the installer's session, one user can't trigger another's webhook.&lt;/p&gt;

&lt;p&gt;The three sloth-things baked in: it waits for &lt;em&gt;your push&lt;/em&gt; (webhook events, not cron polling), it does the boring comparison work, and it stops before the risky part — merging is your call.&lt;/p&gt;

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

&lt;p&gt;Try it in about 30 seconds at &lt;strong&gt;&lt;a href="https://docdrift-rfjj.onrender.com" rel="noopener noreferrer"&gt;https://docdrift-rfjj.onrender.com&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;Repo: &lt;a href="https://github.com/N-Garai/DocDrift" rel="noopener noreferrer"&gt;https://github.com/N-Garai/DocDrift&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;DocDrift was built by pair-programming with a rotating cast of AI coding agents — DeepSeek, Kilo Code, GitHub Copilot and opencode — each picked for what it was good at: DeepSeek for heavy reasoning and big-picture design, Kilo Code and opencode for rulebook-driven implementation sprints, and Copilot for inline completions and roadmap development. But the code generation was never the interesting part — the discipline was. &lt;/p&gt;

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

&lt;p&gt;The constraint I set from day one: &lt;strong&gt;the open pieces have to be what makes the project work&lt;/strong&gt; — not a coat of paint over a proprietary core. Everything below is verifiable in the repo, file by file.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mastra as the agent harness.&lt;/strong&gt; Four specialized Mastra &lt;code&gt;Agent&lt;/code&gt; instances share one job: extraction, validation (Gate 1), patching (Gate 2) and tone. They're wired into a real Mastra workflow via &lt;code&gt;createWorkflow&lt;/code&gt;/&lt;code&gt;createStep&lt;/code&gt; — nine typed steps chained with &lt;code&gt;.then()&lt;/code&gt; and committed as one graph. Every step's input and output is a Zod schema, so an LLM can't sneak a malformed finding past the type system, and every run produces a replayable step trace.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;tree-sitter as the compiler for prose.&lt;/strong&gt; &lt;code&gt;web-tree-sitter&lt;/code&gt; with prebuilt grammars from &lt;code&gt;@repomix/tree-sitter-wasms&lt;/code&gt; gives line-precise symbol extraction for TypeScript and Python. Parser failures are recorded in an in-memory ledger (last 50, surfaced at &lt;code&gt;GET /api/health&lt;/code&gt;) &lt;em&gt;and&lt;/em&gt; shipped to Sentry with a redacting &lt;code&gt;beforeSend&lt;/code&gt; — cookies, tokens and session IDs never leave the machine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemma as the prose engine, in a provider chain.&lt;/strong&gt; The reasoning layer resolves per request, with a 15-second cached verdict: local Ollama Gemma (default &lt;code&gt;gemma3:4b&lt;/code&gt; at &lt;code&gt;localhost:11434&lt;/code&gt;) → the free Gemini API tier serving the open-weight &lt;code&gt;gemma-4-31b-it&lt;/code&gt; → and finally a &lt;strong&gt;deterministic comparator engine&lt;/strong&gt; — a rule-based drift detector (changed defaults, missing symbols, rename detection via similarity scoring ≥ 0.62, orphaned doc targets, env keys, stale routes) that produces the same artifact with &lt;em&gt;zero&lt;/em&gt; network calls. Temperature 0.2, explicit timeouts and retries — and the chain is one env var to reconfigure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The two gates are the anti-hallucination core.&lt;/strong&gt; The design leans on the documentation-drift literature, all annotated in &lt;a href="https://github.com/N-Garai/DocDrift/blob/main/docs/RESEARCH.md" rel="noopener noreferrer"&gt;&lt;code&gt;docs/RESEARCH.md&lt;/code&gt;&lt;/a&gt;: Ratol &amp;amp; Robillard's DOCREF ("&lt;a href="https://dl.acm.org/doi/10.1145/2509136.2509523" rel="noopener noreferrer"&gt;Detecting API Documentation Errors&lt;/a&gt;", OOPSLA 2014) and the 2025 Concordia LLM traceability study (&lt;a href="https://arxiv.org/abs/2506.16440" rel="noopener noreferrer"&gt;"Evaluating the Use of LLMs for Documentation-to-Code Traceability"&lt;/a&gt;) both document how "phantom links" pervade LLM-linked docs. So Gate 1 re-checks every Gemma finding against the extracted symbols and drops anything the AST cannot prove &lt;em&gt;before&lt;/em&gt; a patch is built. Gate 2 does the mirror check on the docs side: apply the edit to a snapshot, re-parse it, confirm tables stay well-formed and the symbol is genuinely documented now. Broken edits get repaired once, then flagged — never silently merged.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The whole stack is Bun + TypeScript, Express on the engine, Next.js front end, a zero-dependency JSON store for sessions and webhook registrations (no database required — swap in Postgres later behind the same interface), &lt;code&gt;node:test&lt;/code&gt; for the test suite, and a multi-stage Dockerfile whose single Node process serves the API &lt;em&gt;and&lt;/em&gt; the static-exported frontend on one port. On the building side, I pair-programmed the codebase with agentic coding tools — DeepSeek, Kilo Code, GitHub Copilot and opencode — under a rulebook the whole team (human included) had to follow.&lt;/p&gt;

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

&lt;p&gt;DocDrift reads code, docs and env files from your repository — the payload a closed tool would demand you upload somewhere. Open makes the trust question easy to answer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Your repos stay local.&lt;/strong&gt; The default inference path is Ollama on localhost; the deterministic engine doesn't even open a socket. Anyone can verify that by reading &lt;code&gt;core/llm/provider.ts&lt;/code&gt; — which is exactly the point. Closed-source doc tools ask you to &lt;em&gt;trust&lt;/em&gt; the pipeline; open-source lets you &lt;em&gt;audit&lt;/em&gt; the pipeline.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It costs nothing to run, forever.&lt;/strong&gt; Every component — Mastra, tree-sitter, Gemma weights, the Ollama runtime — is free, and the free Gemini tier is a fallback, not a crutch. The landing page's live demo runs with &lt;strong&gt;zero providers configured&lt;/strong&gt; (the deterministic engine powers it). There's no paid plan to outgrow, no credit card, no trial clock.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The brain is swappable by config, not migration.&lt;/strong&gt; Set &lt;code&gt;OLLAMA_MODEL&lt;/code&gt;, point at another local model, or drop the key and use the deterministic engine. Fine-tuning how your agent behaves is an env edit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Honest intelligence.&lt;/strong&gt; The similarity thresholds, the evidence rules, the gate behavior — it's all in plain TypeScript with 36 tests over it rather than a marketing page. That transparency is only possible when the core is open.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;The build was pair-programmed with a rotating cast of AI coding agents — &lt;strong&gt;DeepSeek Harness, Kilo Code, GitHub Copilot and opencode&lt;/strong&gt; — different tools for different jobs, and the interesting part was the &lt;em&gt;discipline&lt;/em&gt;, not the code generation. &lt;/p&gt;

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

&lt;p&gt;The honest math: every time you ship anything, keeping your own backlog of docs consistent is a 20–30 minute guilt-tax — reread the README, scan your config keys against &lt;code&gt;.env.example&lt;/code&gt;, and see if the endpoints match. Most weeks, the honest answer is that nobody does it, and the tables fall behind. DocDrift does not ask you to remember anything.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Studio path:&lt;/strong&gt; click through the repo picker, hit "Run drift analysis," get the diff. The demo runs on the landing page in a browser with no API key of any kind, so the price of admission to "my docs are freshly audited" is one click.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Webhook path:&lt;/strong&gt; install once, forget. Every push lands a review PR whenever your docs fall out of date with the code. You review and merge whenever you want — DocDrift will never merge for you, which is exactly the design decision you want from a tool handling your README.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;When it's wrong, it fails loudly:&lt;/strong&gt; the mandatory evidence rules mean the diff is a real diff with real files, and the failure ledger at &lt;code&gt;/api/health&lt;/code&gt; shows you exactly what the parser missed instead of hiding it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The sloth wins because I only do the part that needs a human: deciding whether the new table row reads well.&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's open weights are the reasoning engine at the center of the synthesize step, with a provider chain covering both real deployment modes: local via Ollama (default &lt;code&gt;gemma3:4b&lt;/code&gt;) on the laptop path and the open-weight &lt;code&gt;gemma-4-31b-it&lt;/code&gt; on the hosted free tier (temperature 0.2, explicit timeouts, structured Zod outputs), plus a deterministic fallback so the pipeline never stalls without a provider.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Mastra&lt;/strong&gt; — the entire brain runs on the open Mastra harness: four specialized &lt;code&gt;Agent&lt;/code&gt; instances wired into one production &lt;code&gt;createWorkflow&lt;/code&gt; graph (&lt;code&gt;doc-drift-sync&lt;/code&gt;) of nine typed &lt;code&gt;createStep&lt;/code&gt;s (&lt;code&gt;intake → extract → docs → synthesize → gate-1 → patch → gate-2 → tone → emit&lt;/code&gt;), all with Zod-typed step boundaries and per-step traces replayable in the Studio.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Render&lt;/strong&gt; — DocDrift is deployed on Render's free tier (&lt;a href="https://github.com/N-Garai/DocDrift/blob/main/render.yaml" rel="noopener noreferrer"&gt;render.yaml&lt;/a&gt;, Docker service): health check on &lt;code&gt;/api/health&lt;/code&gt;, auto-deploy, production env wiring for the GitHub OAuth app and webhook secret — and a custom keep-warm service that self-pings only in production (every 13.5 minutes, cancellable with &lt;code&gt;KEEP_WARM=off&lt;/code&gt;) so the free instance doesn't nap through its own ~15-minute idle window.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Sentry Agent Tracing&lt;/strong&gt; — the engine instruments its failure paths with &lt;code&gt;@sentry/node&lt;/code&gt; (&lt;code&gt;captureParserFailure&lt;/code&gt;, &lt;code&gt;captureWorkflowError&lt;/code&gt; in &lt;a href="https://github.com/N-Garai/DocDrift/blob/main/src/backend/src/core/sentry.ts" rel="noopener noreferrer"&gt;&lt;code&gt;core/sentry.ts&lt;/code&gt;&lt;/a&gt;): every tree-sitter grammar failure and workflow error is captured with a redacting &lt;code&gt;beforeSend&lt;/code&gt; that scrubs cookies, GitHub tokens and session IDs before anything leaves, and the same failures surface live in &lt;code&gt;GET /api/health&lt;/code&gt;'s parser-failure ledger — the observability story includes what &lt;em&gt;you&lt;/em&gt; can see without an account.
&amp;lt;!-- Team Submissions: Please pick one member to publish the submission and credit teammates by listing their DEV usernames directly in the body of the post. --&amp;gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Git-Voice: Twenty Seconds of Client Voice into One Filed GitHub Issue</title>
      <dc:creator>Nayananshu Garai</dc:creator>
      <pubDate>Sun, 18 Oct 2026 15:16:28 +0000</pubDate>
      <link>https://dev.to/ngarai/git-voice-twenty-seconds-of-client-voice-into-one-filed-github-issue-4349</link>
      <guid>https://dev.to/ngarai/git-voice-twenty-seconds-of-client-voice-into-one-filed-github-issue-4349</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 recurring pain behind client work isn't the bugs — it's the dispatch cost. A client sees something broken on their staging site, describes it in one emotional sentence ("the checkout is broken, fix it ASAP"), and the freelancer spends the next unpaid hour reverse-engineering the sentence: which browser, which route, what console said, whether the coupon even reached the server. Neither side is having a good time. I've been on both sides of that email.&lt;/p&gt;

&lt;p&gt;Git-Voice is a small embeddable widget that replaces the sentence with twenty seconds of speech. The developer drops one &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag on the staging site. The client clicks a floating mic button, talks while clicking around the broken page, and the system:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;captures the audio plus real browser telemetry (console output, route, viewport, clicks),&lt;/li&gt;
&lt;li&gt;locates the suspicious files by searching an architecture index built from the client's repo,&lt;/li&gt;
&lt;li&gt;drafts an engineering-grade GitHub issue — title, severity, expected vs. actual, numbered reproduction steps, suspected file — and files it, labels included,&lt;/li&gt;
&lt;li&gt;reads a short spoken confirmation back to the client in their own browser, so they finish feeling heard instead of handed a form.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No forms, no severity dropdowns, no "which browser are you using?" — the telemetry already answers that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who would pay for it:&lt;/strong&gt; freelance developers and tiny agencies juggling 2–10 client staging sites. The pricing is honest about its audience: Hobby (free, public repos, one project — the whole pipeline still runs), Freelancer at $15/mo (private repos, hosted drafting and premium voice, auto-reindex), Agency at $60/mo (ten projects). One recovered debugging hour a month pays for it.&lt;/p&gt;

&lt;p&gt;One thing I refused to fake: the billing. Checkout is a clearly-labelled simulation (card digits pass a Luhn check, invoices are issued, nothing touches a real processor). The pricing page says exactly which capabilities the server enforces, and the server actually enforces them — the plan gates in this post are code, not copy.&lt;/p&gt;




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

&lt;p&gt;The deployed app (Render-web service with docker):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Live app: &lt;strong&gt;&lt;a href="https://git-voice-sh7k.onrender.com" rel="noopener noreferrer"&gt;https://git-voice-sh7k.onrender.com&lt;/a&gt;&lt;/strong&gt; — try the landing-page demo store widget, sign in with GitHub, create a project from your own repos, watch a report end-to-end.&lt;/li&gt;
&lt;li&gt;Video walkthrough: &lt;a href="https://youtu.be/8Tlg2ZnWJKw%E2%80%8B%E2%80%8C" rel="noopener noreferrer"&gt;Demo&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;Node + Hono backend, React dashboard, one install-anywhere site widget built as a separate ~21 KB bundle, and a Postgres/pgvector-backed index. Apache-2.0 licensed, no payment processor and no stored card data — the simulated checkout says so plainly in its own UI — and 145 backend tests across 18 files.&lt;/p&gt;

&lt;p&gt;Repo:- &lt;a href="https://github.com/N-Garai/Git-Voice" rel="noopener noreferrer"&gt;Git-Voice&lt;/a&gt;&lt;/p&gt;




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

&lt;p&gt;The brain is &lt;strong&gt;Gemma (&lt;code&gt;gemma-4-26b-a4b-it&lt;/code&gt; on the Gemini API, open-weight)&lt;/strong&gt;. Every issue that leaves the pipeline is drafted by it — but deliberately at temperature 0, with a hand-rolled JSON extraction step instead of prompt-and-pray parsing. Transcription of uploaded audio uses the free &lt;code&gt;gemini&lt;/code&gt; tier, and embeddings (&lt;code&gt;gemini-embedding-001&lt;/code&gt;, 768 dims, batched with exponential backoff) build the retrieval layer. I chose Gemini's free tier for the model side and kept every piece I could running locally so the whole thing costs $0 to operate.&lt;/p&gt;

&lt;p&gt;The pipeline is a seven-station engine I wrote myself — &lt;code&gt;ingest → transcribe → locate → correlate → draft → publish → confirm&lt;/code&gt; — instead of pulling in a workflow framework, because the failure behavior matters more than the orchestration syntax: each station holds its own typed result, the whole run is bounded by a 90-second timeout, and (this is the part I'm most attached to) &lt;strong&gt;a deterministic offline triage engine runs first and stays as the final draft&lt;/strong&gt;. If the model is unreachable, rate-limited, or not configured, a working, honest issue still gets drafted and filed from a rule-based synthesizer. The spoken confirmation reads through the browser's own speech synthesis on every plan — nothing to configure — and spaces out to a server-rendered voice on paid tiers when the deployment carries a speech API key. Every station's state ends up visible in the dashboard; nothing disappears into a spinner.&lt;/p&gt;

&lt;p&gt;Retrieval is hybrid on purpose: keyword scoring over a curated "signature" per file — path, exports, error strings, class names — fused with cosine-similarity over their embeddings using Reciprocal Rank Fusion (Cormack et al. 2009, SIGIR), with BM25 weighting underneath (Robertson &amp;amp; Zaragoza 2009). The index itself comes from the repo tarball (public via codeload, private via the owner's own OAuth token), capped at 800 files, chunked into signatures, and stored in Postgres with pgvector.&lt;/p&gt;

&lt;p&gt;For agent observability I wired &lt;code&gt;@sentry/node&lt;/code&gt; with OpenInference's &lt;code&gt;gen_ai&lt;/code&gt; semantic conventions — one span per pipeline station (&lt;code&gt;gen_ai.execute_tool&lt;/code&gt;), one for the model call (&lt;code&gt;gen_ai.chat&lt;/code&gt; with real token usage), one per agent run — enabled by nothing more than a &lt;code&gt;SENTRY_DSN&lt;/code&gt; environment variable, with a strict gate that strips report content from spans by default. Reports belong to the client; telemetry should collect clicks, not conversations.&lt;/p&gt;




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

&lt;p&gt;Three concrete reasons this is an open-weights project and not a wrapper on some closed API's free credits:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It survives without the vendor.&lt;/strong&gt; The offline triage engine plus the browser's Web Speech APIs mean the $0 Hobby tier is a complete product, not a teaser. When the model quota runs dry, drafts and file matching keep working; when a paid feature is missing, the UI says so — the plan gates are server-side checks. A closed-API-first product would have been a demo that dies in a cold aisle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It costs exactly nothing to run honestly.&lt;/strong&gt; Gemma via the free Gemini tier, Render's free Docker web service, browser TTS/STT, open-source pgvector. Being able to build a purchasable product (the actual "side hustle" test) on top of open infrastructure is the difference between a hobby and a hustle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Users keep their data and their identity.&lt;/strong&gt; Issues are filed into the developer's own repo under their own GitHub OAuth token — the deployment's credentials never write to a client repo. The embeddings layer searches a curated signature index, not raw source code, so a client's project is never shipped wholesale to a third-party service. Open stores (plain GitHub issues, Postgres + pgvector) mean no lock-in: stop using Git-Voice and your issues, your repo, and your index stay right where they are.&lt;/p&gt;




&lt;h2&gt;
  
  
  My First User
&lt;/h2&gt;

&lt;p&gt;The first real user was my freelancer friend — someone who has lived through exactly the "client sends one angry sentence" scenario Git-Voice is built for. He got no instructions beyond a link. What he did in his first session: signed in with GitHub, picked a repository from the picker, upgraded the plan to Agency through the simulated checkout (no money moves, by design), created a project, filed reports through the widget, and replayed the spoken confirmations.&lt;/p&gt;

&lt;p&gt;He reported back with screenshots and three bugs (which I'd have shipped to production) saying "It was so helpful for me to save time,I've attached the link my client sent me to my copilot but it didn't understand the proper issue and mangled the whole code,took too much time,with your app it creates a cited issue and my coding agent easily patched the bug,now i am just reviewing the changes". Would he pay? Not yet, and I won't pretend otherwise: the checkout is simulated, so no money has moved. What the session did settle is the value pitch — a twenty-second voice report that lands as a labelled, reproducible issue beats the "which browser is this on?" email every week. I'll take the bug list as the more honest compliment.&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; (featured) — the open-weight &lt;code&gt;gemma-4-26b-a4b-it&lt;/code&gt; model drafts every single issue at temperature 0, with a deterministic offline synthesizer underneath it so the product never dead-ends.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Render&lt;/strong&gt; — the whole thing is one Dockerfile: Hono serves the React dashboard, the widget bundle, the API, and the Postgres/pgvector index from a single free-tier web service, deployed from &lt;code&gt;main&lt;/code&gt; with health checks and keep-warm.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Sentry Agent Tracing&lt;/strong&gt; — the pipeline's work is inspectable, not a spinner: &lt;code&gt;@sentry/node&lt;/code&gt; emits &lt;code&gt;gen_ai&lt;/code&gt; spans for every station run, for the Gemma call (real token usage and finish reasons), and for the agent run itself, with a content gate that keeps report text out of spans by default. Enabling it is one &lt;code&gt;SENTRY_DSN&lt;/code&gt; environment variable, and the trace reads like the dashboard's run log.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of ElevenLabs&lt;/strong&gt; — the confirmation voice is plan-aware: paid tiers render an ElevenLabs mp3 server-side when the deployment carries a key, Hobby always speaks through the browser's native speech synthesis, and any failure falls back gracefully — the client always hears their confirmation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of GitHub Copilot&lt;/strong&gt; — Copilot handled editor-side work (completions, small refactors, test scaffolding) alongside the milestone-driven agent sessions described above; the odd pairing of a fast autocomplete brain and a slow milestone brain turned out to fit how I actually work.Also github cron jobs plays a significant role of my site(preventing render site getting idle after 15min).&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>ai</category>
      <category>github</category>
    </item>
    <item>
      <title>Sky-Whisper</title>
      <dc:creator>Nayananshu Garai</dc:creator>
      <pubDate>Sun, 11 Oct 2026 14:49:34 +0000</pubDate>
      <link>https://dev.to/ngarai/sky-whisper-550k</link>
      <guid>https://dev.to/ngarai/sky-whisper-550k</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;SkyWhisper turns stargazing from a looking activity into a listening one. You open the app at home, it computes exactly what's over your sky tonight, writes you a ~90-second narrated guide, and synthesizes it into audio you download. Then you go outside, put the phone face-down, lock the screen — and just listen through your earbuds, with lock-screen controls handling the rest.&lt;/p&gt;

&lt;p&gt;It's for everyone who has ever held a glowing phone up to the night sky and ruined the very thing they went out to see: your eyes need 20–30 minutes of darkness to fully adapt, and one glance at a bright screen resets that clock to zero. Every other stargazing app is the screen. SkyWhisper's entire thesis is that in the field, the screen's only job is to stay off — if you never unlock your phone, you used the product perfectly. That's about as "touch grass" as software gets: the output isn't content to consume, it's instructions to look up.&lt;/p&gt;

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

&lt;p&gt;Live: &lt;a href="https://sky-whisper.onrender.com" rel="noopener noreferrer"&gt;https://sky-whisper.onrender.com&lt;/a&gt; (free tier — first load after idle takes ~30–60s while the container wakes)&lt;/p&gt;

&lt;p&gt;The 60-second try-it script:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Allow location (or type coordinates) → Prepare My Sky → watch the ritual stages light up with real server progress, not a fake timer.&lt;/li&gt;
&lt;li&gt;Press play on the countdown → flip your phone face-down → control it from the lock screen.&lt;/li&gt;
&lt;li&gt;Tap the 🎙 button and say "describe the sky" — or "where can I find Vega?" — and hear the agent answer from live data.&lt;/li&gt;
&lt;li&gt;Open any pack's "Tonight's Narration" card: it tells you exactly which model narrated it — or precisely why the template did instead. No black boxes.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;&lt;a href="https://github.com/N-Garai/Sky-Whisper" rel="noopener noreferrer"&gt;https://github.com/N-Garai/Sky-Whisper&lt;/a&gt; &lt;/p&gt;

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

&lt;p&gt;The one architectural decision everything hangs on: coordinates are computed, never generated. A deterministic ephemeris stack (Skyfield + JPL data, CelesTrak + SGP4 for satellites) calculates Sun, Moon, 5 planets, 18 named stars, and 12 constellations for your exact spot and second. The language model only ever receives those finished facts — and every number it utters is checked against them before audio renders. A closed model guessing "what's above you" would be unfalsifiable and occasionally confidently wrong; open math can be diffed against Stellarium by anyone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The model chain is built for a world where model IDs die&lt;/strong&gt;. During this build, Groq retired one default ID and NIM returned 410 Gone on another — I watched it happen in the logs. So each rung carries a fallback ID (switched only on 404/410-class errors), each rung gets 55 seconds, the whole walk gets 150, every failure is recorded with its reason, and the deterministic template always answers. The pack JSON — and the UI badge on it — names the winning rung or explains exactly why the template did. Model rot can't silently break this product.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mastra (@mastra/core, Apache-2.0)&lt;/strong&gt; orchestrates narration: a docent agent with real tools (get-sky-snapshot over localhost, get-body-direction for any named body), a facts → narrate → validate workflow, per-rung endpoint pinning, and a zod narration envelope — with the Python validator re-gating everything as the final word. Voice questions ride the same chain with conversation memory, answered as speech.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Free-tier engineering&lt;/strong&gt;: the whole serving footprint peaks around ~320MB of 512MB; the Node harness spawns only when a model rung actually runs and is kill-guarded so hung runs can't orphan processes into an OOM; packs cache on 15-minute sky buckets so retries serve instantly; the kernel and satellite data warm at boot.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The frontend&lt;/strong&gt;: (React 19, Vite, Tailwind v4, Framer Motion, Three.js living starfield, installable PWA with offline pack cache) also ships two things I'm proud of: a drag-to-turn 360° sky map with a live facing readout, and a blackout pointer mode — pure-black OLED overlay where compass, vibration, and rising pitch guide your aim onto a star without emitting a photon that matters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Testing&lt;/strong&gt;: 136 automated tests, hermetic (no network, no keys) — ephemeris math, anti-hallucination rejection (including a test pinned from a real production failure where a model emitted raw altitudes), chain fallthrough, kill-on-timeout, and full HTTP integration.&lt;/p&gt;

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

&lt;p&gt;Four concrete ways, all demonstrated in code rather than claimed in prose:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open coordinates are a correctness feature. My cross-check table (in docs/accuracy.md) diffs Skyfield against astropy's independent implementation: 0.00° across the board except a 0.64° lunar-elongation residual I document and explain. Try auditing a closed API's sky positions that way.&lt;/li&gt;
&lt;li&gt;Swap-ability is a one-line demo. Hosted Gemma via free key → local Ollama via one variable. A closed-API product cannot offer "run my narrator on your laptop with zero code changes"; the open-weight one does, and location history ("where you stargaze") never has to leave your machine.&lt;/li&gt;
&lt;li&gt;It costs nothing to run. Free Render + free model tiers + free TTS tier + free data sources = $0/month, every line auditable. Open is what makes the hobby budget possible.&lt;/li&gt;
&lt;li&gt;It survives the real world. When providers retired model IDs mid-build, the open, inspectable stack meant I could see exactly what broke (HTTP 404/410 in plain text) and route around it in the open — instead of a black-box outage I couldn't diagnose.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;ul&gt;
&lt;li&gt;Best Use of Render — single free web service serving API + PWA; cold-start honesty, ephemeral-by-design storage, measured 320MB footprint on 512MB.&lt;/li&gt;
&lt;li&gt;Best Use of Gemma — open-weight Gemma narrates from computed facts only (never coordinates), hosted free-tier path plus one-variable local Ollama swap, model recorded per pack.&lt;/li&gt;
&lt;li&gt;Best Use of ElevenLabs — pre-trip TTS rendering with an honest transcript-only mode when unkeyed; short voice replies synthesized on demand.&lt;/li&gt;
&lt;li&gt;Best Use of Mastra — docent agent with snapshot/direction tools, facts→narrate→validate workflow, per-rung orchestration, memory-carrying voice loop.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>Bill-Bhasa</title>
      <dc:creator>Nayananshu Garai</dc:creator>
      <pubDate>Sun, 04 Oct 2026 14:54:36 +0000</pubDate>
      <link>https://dev.to/ngarai/bill-bhasa-5c78</link>
      <guid>https://dev.to/ngarai/bill-bhasa-5c78</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;&lt;strong&gt;BillBhasha&lt;/strong&gt; — a privacy-first bill scanner that reads any paper receipt, prescription, or invoice out loud in my parents' own language.&lt;/p&gt;

&lt;p&gt;My mother is 62, hindi-first, and has low vision. She still handles every household bill, medicine strip, and ration document by hand. Right now that means either squinting at faded paper or asking someone else to read it for her — and neither option lets her stay independent.&lt;/p&gt;

&lt;p&gt;BillBhasha lets her simply &lt;strong&gt;take a photo&lt;/strong&gt; of any document. The app cleans the image, reads the text with open-source OCR, understands it with an open-weight language model, and then &lt;strong&gt;speaks the explanation back&lt;/strong&gt; in warm, simple Hindi or Bengali. It also watches her spending history and speaks a gentle warning when an amount jumps unusually.&lt;/p&gt;

&lt;p&gt;Everything runs inside a single free-tier web service. No app store, no login, no credit card. She opens the site, snaps a photo, and listens.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live link:&lt;/strong&gt; &lt;a href="https://billbhasha.onrender.com" rel="noopener noreferrer"&gt;https://billbhasha.onrender.com&lt;/a&gt; (first visit may take ~40s to wake the free service)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How it feels for her:&lt;/strong&gt; open the page → tap the camera → snap a bill → hear a 30-second Hindi explanation → see a plain ₹ amount and a simple "check this" warning if something looks off&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub repo:&lt;/strong&gt; &lt;a href="https://github.com/N-Garai/Bill-Bhasa" rel="noopener noreferrer"&gt;https://github.com/N-Garai/Bill-Bhasa&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stack:&lt;/strong&gt; FastAPI backend · Tesseract OCR · SmolLM2-360M (GGUF, Apache-2.0) · Piper Hindi/Bengali voice · Neon Postgres · vanilla JS frontend with GSAP + Three.js&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;BillBhasha is not a wrapper around a closed API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Open-weight model at the core&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The default brain is &lt;strong&gt;SmolLM2-360M&lt;/strong&gt; in GGUF format (&lt;code&gt;LLM_MODEL&lt;/code&gt; env var). It turns raw OCR text into a simple Hindi/Bengali explanation with amount, date, and action items.&lt;/li&gt;
&lt;li&gt;It runs locally inside the same container via &lt;code&gt;llama.cpp&lt;/code&gt; subprocess isolation, so there is no external inference bill and no data leaves the box.&lt;/li&gt;
&lt;li&gt;The model is swappable in one config line: Qwen2.5-0.5B, Phi-3, or any GGUF-compatible model. I started with Phi-3 Mini but it OOM'd on the 0.1 CPU free tier, which is why SmolLM2-360M became the default.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Open harness + local inference&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;FastAPI + Uvicorn serve the app. Tesseract (&lt;code&gt;pytesseract&lt;/code&gt;) does the OCR. Both are open source.&lt;/li&gt;
&lt;li&gt;Heavy work runs in subprocesses with a sequential in-process lock, keeping peak memory under 512 MB on a single CPU.&lt;/li&gt;
&lt;li&gt;Piper provides an offline Hindi/Bengali voice on-device, so the app still speaks when the network is down.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Open vision fallback&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When Tesseract returns nothing (faded print, bad light), &lt;strong&gt;Gemma&lt;/strong&gt; (&lt;code&gt;gemma-4-26b-a4b-it&lt;/code&gt;) reads the photo directly through the free Google AI Studio API and returns structured JSON.&lt;/li&gt;
&lt;li&gt;The vision prompt is locked to the user's chosen language, and the response is schema-validated before it reaches the TTS stage.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why this architecture&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;My parents' data never needs to leave the server. On the SQLite profile, the app runs fully offline.&lt;/li&gt;
&lt;li&gt;Every behavior swaps via environment variables: &lt;code&gt;LLM_PROVIDER&lt;/code&gt;, &lt;code&gt;LLM_MODEL&lt;/code&gt;, &lt;code&gt;TESS_LANG&lt;/code&gt;, &lt;code&gt;ELEVENLABS_API_KEY&lt;/code&gt;, &lt;code&gt;GEMINI_API_KEY&lt;/code&gt;. No code changes required.&lt;/li&gt;
&lt;li&gt;The monthly receipt is $0: Render free web service + Neon free Postgres + zero closed-API spend.
## Why Does Open Innovation Matter?
&amp;lt;!-- Why does open innovation matter for what you built?  What did it make possible that a closed API wouldn't? --&amp;gt;
For my parents, "open" is not a buzzword — it is the only reason this exists at all.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Privacy without trust in a closed server&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;My parents' prescriptions, bank statements, and hospital bills never leave our infrastructure. With SQLite + local inference, the app works with the cable pulled. A closed API would require sending those papers to someone else's server, with no guarantee they won't train on them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Model swap = accessibility swap&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hindi-first, Bengali-first, and English-first users all need the same app, but different voices and different LLMs. Open-weight GGUF models let me swap the brain in one line. Closed APIs would lock me into their pricing, their accents, and their privacy policy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cost = access&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;My parents are retired. A $20/month closed-API bill is not a viable long-term plan. SmolLM2-360M, Tesseract, Piper, Render free tier, and Neon free tier together cost $0. Open innovation made this project actually sustainable for the person it was built for.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What failed and what open alternatives made possible&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Phi-3 Mini: 2.5 GB, OOM on 0.1 CPU. SmolLM2-360M: 360 MB, runs comfortably.&lt;/li&gt;
&lt;li&gt;EasyOCR: pulled from the box for memory. Tesseract with sparse passes stayed under budget.&lt;/li&gt;
&lt;li&gt;Render Postgres 30-day reset trap → Neon free Postgres, no reset.&lt;/li&gt;
&lt;li&gt;Closed TTS APIs sounded robotic in Hindi/Bengali. ElevenLabs multilingual v2 + Piper on-device gave us a warm, female voice that sounds like home.&lt;/li&gt;
&lt;/ul&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; — deployed on Render free web service with Neon Postgres&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Gemma&lt;/strong&gt; — Gemma 4 vision fallback via Google AI Studio free API (&lt;code&gt;gemma-4-26b-a4b-it&lt;/code&gt;) with schema-locked JSON output&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of ElevenLabs&lt;/strong&gt; — ElevenLabs multilingual v2 TTS for Bengali/Hindi with Piper offline fallback&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>Cifrasync</title>
      <dc:creator>Nayananshu Garai</dc:creator>
      <pubDate>Sun, 07 Jun 2026 14:12:41 +0000</pubDate>
      <link>https://dev.to/ngarai/cifrasync-3n06</link>
      <guid>https://dev.to/ngarai/cifrasync-3n06</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/github-2026-05-21"&gt;GitHub Finish-Up-A-Thon Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;CifraSync&lt;/strong&gt; — a zero-dependency encrypted incremental backup tool written in C from scratch (200 KB binary, 31 source files, ~5000 lines). No Python, no Go, no npm. Just a single binary with chunk-based deduplication, RLE compression, HMAC stream cipher v2 (key separation, CSPRNG, 600K PBKDF2), incremental snapshots, remote sync, file-based mutual exclusion locks, and a colored interactive TUI.&lt;/p&gt;

&lt;p&gt;The project started as a partially-built C backup scaffold with stubs and unfinished wiring. I completed all 7 commands (init, backup, restore, list, verify, prune, sync), added a server mode, wired compression and encryption end-to-end with key separation and cryptographically secure randomness, built an interactive menu, added file-based locking, and wrote a comprehensive README and docs. All 14 tests pass with zero compiler warnings.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key technical features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Chunk-level deduplication&lt;/strong&gt; — identical data across files/snapshots stored once&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RLE compression&lt;/strong&gt; — per-chunk, auto-decompressed on restore/verify&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HMAC stream cipher v2&lt;/strong&gt; — Blob version 2 with key separation (enc_key ≠ mac_key), cryptographically random salt/nonce (CryptGenRandom / /dev/urandom), 600K PBKDF2 iterations, constant-time tag verification&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key cache&lt;/strong&gt; — In-memory PBKDF2 cache eliminating redundant per-chunk derivation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Masked passphrase input&lt;/strong&gt; — No echo on terminal (SetConsoleMode / getpass)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File-based mutual exclusion&lt;/strong&gt; — flock/LockFileEx locks (EXCLUSIVE for writes, SHARED for reads)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Atomic manifest writes&lt;/strong&gt; — &lt;code&gt;.tmp&lt;/code&gt; + &lt;code&gt;rename()&lt;/code&gt; crash safety&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Journal replay&lt;/strong&gt; — interrupted backups auto-resume&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-platform&lt;/strong&gt; — same codebase compiles on Windows (MinGW), Linux, macOS&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interactive TUI&lt;/strong&gt; — colored numbered menu, no flags needed for daily use&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;wake up cifra&lt;/code&gt;&lt;/strong&gt; — one-command launcher after one-time &lt;code&gt;setup.ps1&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;h3&gt;
  
  
  Build &amp;amp; Test
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;git&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;clone&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;https://github.com/N-Garai/CifraSync.git&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;CifraSync&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;mingw32-make&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;release&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c"&gt;# builds bin/cifrasync.exe (200 KB)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;mingw32-make&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="c"&gt;# 14/14 tests pass&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Quick Demo (interactive mode)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create test data&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;mkdir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;C:\demo\source&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;C:\demo\repo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;C:\demo\restored&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;"Hello world"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C:\demo\source\file1.txt&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;"Another file"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;C:\demo\source\file2.txt&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;mkdir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;C:\demo\source\sub&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;"Deep file"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C:\demo\source\sub\deep.txt&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# Launch interactive menu&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;cifrasync&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  CLI Usage
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cifrasync init &lt;span class="nt"&gt;--repo&lt;/span&gt; PATH
cifrasync backup &lt;span class="nt"&gt;--source&lt;/span&gt; PATH &lt;span class="nt"&gt;--repo&lt;/span&gt; PATH &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;--compress&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;--encrypt&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;--label&lt;/span&gt; TEXT]
cifrasync list &lt;span class="nt"&gt;--repo&lt;/span&gt; PATH
cifrasync restore &lt;span class="nt"&gt;--repo&lt;/span&gt; PATH &lt;span class="nt"&gt;--snapshot&lt;/span&gt; ID &lt;span class="nt"&gt;--out&lt;/span&gt; PATH &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;--source-file&lt;/span&gt; PATH]
cifrasync verify &lt;span class="nt"&gt;--repo&lt;/span&gt; PATH
cifrasync prune &lt;span class="nt"&gt;--repo&lt;/span&gt; PATH &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;--keep-last&lt;/span&gt; N] &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;--older-than&lt;/span&gt; DAYS]
cifrasync &lt;span class="nb"&gt;sync&lt;/span&gt; &lt;span class="nt"&gt;--repo&lt;/span&gt; PATH &lt;span class="nt"&gt;--remote&lt;/span&gt; HOST:PORT   &lt;span class="c"&gt;# pushes manifests + chunks to remote&lt;/span&gt;
cifrasync serve &lt;span class="nt"&gt;--bind&lt;/span&gt; HOST:PORT &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;--repo&lt;/span&gt; PATH]   &lt;span class="c"&gt;# receives &amp;amp; stores sync data&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;&lt;strong&gt;Before&lt;/strong&gt; : The project had the CLI scaffold, core storage and chunking layers, basic tests, and tools. But 3 of 7 commands were stubs (verify, prune, sync returned "unsupported"). Compression and encryption were logged but not applied. Snapshot listing showed bare filenames only. No journal replay, no atomic writes, no config auto-load, no single-file restore, no interactive mode, no launcher. The project needed documentation, polish, and a clear demo path.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After&lt;/strong&gt; : Every command is fully implemented. Compression and encryption are wired end-to-end (RLE before store, HMAC seal v2 with key separation, auto-decompress on restore/verify). Encryption uses cryptographically random salt+nonce, 600K PBKDF2 iterations, masked passphrase input, and key separation (enc_key ≠ mac_key). File-based mutual exclusion locks prevent concurrent corrupting writes. Journal replay resumes interrupted backups. Atomic &lt;code&gt;.tmp&lt;/code&gt; + &lt;code&gt;rename()&lt;/code&gt; prevents partial snapshots. Config auto-loads on startup. The snapshot list shows rich details (ID, timestamp, file count, size, label). There's a colored interactive TUI, a &lt;code&gt;serve&lt;/code&gt; command for remote sync, and a &lt;code&gt;wake up cifra&lt;/code&gt; one-command launcher. The README is comprehensive with a full interactive mode reference table. All 14 tests pass with zero warnings.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sync Protocol (full data transfer)
&lt;/h3&gt;

&lt;p&gt;The sync now implements bidirectional chunk transfer via a custom TCP frame protocol:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;HELLO&lt;/strong&gt; — client announces itself, server responds with repo path&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MANIFEST&lt;/strong&gt; — client sends full snapshot metadata + serialized manifest file (all file/chunk references)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Missing chunk negotiation&lt;/strong&gt; — server compares manifest chunk hashes against its local chunk store, returns list of only the missing hashes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CHUNK&lt;/strong&gt; — client reads each missing chunk from local store and sends it as binary frame (64-byte SHA-256 hash + raw data)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BYE&lt;/strong&gt; — clean disconnect&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Only chunks the server doesn't already have are transferred, making re-syncs incremental. The server writes &lt;code&gt;.snapshot&lt;/code&gt; metadata files, &lt;code&gt;.manifest&lt;/code&gt; files, and stores chunks using the existing repository format. The client reads manifests from its local repo and sends chunk data on demand.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key changes made:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implemented verify (chunk re-hash), prune (snapshot deletion + orphan GC), sync (full manifest + chunk data transfer), serve (server mode with --repo for storage)&lt;/li&gt;
&lt;li&gt;Wired RLE compression and HMAC encryption into the backup pipeline&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blob v2 with key separation&lt;/strong&gt; — enc_key/mac_key derived via HMAC-SHA256 from master key; authentication tag computed with mac_key, stream cipher uses enc_key&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cryptographically secure randomness&lt;/strong&gt; — replaced &lt;code&gt;time()+clock()&lt;/code&gt; salt/nonce with CryptGenRandom (Windows) / /dev/urandom (POSIX)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PBKDF2 iterations: 10K → 600K&lt;/strong&gt; — OWASP 2023 recommendation for SHA-256&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wired in key cache&lt;/strong&gt; — per-session static cache avoids recomputing PBKDF2 per chunk&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Masked passphrase input&lt;/strong&gt; — SetConsoleMode disables echo on Windows; getpass on POSIX&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Passphrase zeroization&lt;/strong&gt; — passphrase buffer cleared in backup cleanup path&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wrong-passphrase now fails loudly&lt;/strong&gt; — restore/verify previously silently produced garbage; now they return errors with log messages&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File-based mutual exclusion&lt;/strong&gt; — EXCLUSIVE lock for backup/prune/server-sync, SHARED lock for restore/verify/client-sync; cross-platform via flock / LockFileEx&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fixed Windows shared lock&lt;/strong&gt; — LockFileEx now called for shared mode too (was a no-op)&lt;/li&gt;
&lt;li&gt;Added journal replay on backup start&lt;/li&gt;
&lt;li&gt;Added atomic manifest writes&lt;/li&gt;
&lt;li&gt;Added rich snapshot listing with formatted columns&lt;/li&gt;
&lt;li&gt;Added single-file restore (&lt;code&gt;--source-file&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Added config auto-load&lt;/li&gt;
&lt;li&gt;Built interactive TUI with colored ASCII menu&lt;/li&gt;
&lt;li&gt;Created &lt;code&gt;wake up cifra&lt;/code&gt; launcher (&lt;code&gt;wake_up_cifra.cmd&lt;/code&gt; + &lt;code&gt;setup.ps1&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Fixed platform detection (dynamic &lt;code&gt;#ifdef&lt;/code&gt; instead of hardcoded)&lt;/li&gt;
&lt;li&gt;Fixed verify with compressed chunks (decompress before hash check)&lt;/li&gt;
&lt;li&gt;Added POSIX fallbacks for cross-platform support&lt;/li&gt;
&lt;li&gt;Deduplicated 5 copies of &lt;code&gt;path_join&lt;/code&gt; into shared &lt;code&gt;cs_path_join&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Fixed &lt;code&gt;\r&lt;/code&gt; carriage return bug in interactive input (was corrupting paths on Windows)&lt;/li&gt;
&lt;li&gt;Fixed NULL callback crash in journal.c&lt;/li&gt;
&lt;li&gt;Wrote comprehensive README, after.md, and submission docs&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;I used GitHub Copilot throughout the completion process. Copilot was most helpful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Boilerplate code generation&lt;/strong&gt; — writing repetitive CLI option parsing, path joining, and error handling patterns&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test writing&lt;/strong&gt; — generating test cases and edge cases for unit tests&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Documentation&lt;/strong&gt; — drafting README sections, the submission post, and code comments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bug finding&lt;/strong&gt; — suggesting fixes for the &lt;code&gt;\r&lt;/code&gt; carriage return issue and the verify decompression logic&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Refactoring&lt;/strong&gt; — suggesting how to deduplicate the &lt;code&gt;path_join&lt;/code&gt; functions across 5 files into a single shared implementation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every suggestion was reviewed, adjusted for the project's coding style and safety constraints, and validated against the test suite before being committed.&lt;/p&gt;




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

&lt;p&gt;&lt;a href="https://youtu.be/IqonIOfXhFs" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgv46o87hlvtggapfalww.jpg" alt="CifraSync Demo" width="480" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Watch the full walkthrough: &lt;a href="https://youtu.be/IqonIOfXhFs" rel="noopener noreferrer"&gt;https://youtu.be/IqonIOfXhFs&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Repository: &lt;a href="https://github.com/N-Garai/CifraSync" rel="noopener noreferrer"&gt;N-Garai/CifraSync&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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