<?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: Kane</title>
    <description>The latest articles on DEV Community by Kane (@comzzycomzzy).</description>
    <link>https://dev.to/comzzycomzzy</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%2F4078652%2F402d0c65-31a6-4713-950d-8ff8c985d116.png</url>
      <title>DEV Community: Kane</title>
      <link>https://dev.to/comzzycomzzy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/comzzycomzzy"/>
    <language>en</language>
    <item>
      <title>I fine-tuned an open model to be the front desk at my friend's nail studio</title>
      <dc:creator>Kane</dc:creator>
      <pubDate>Sun, 04 Oct 2026 17:52:11 +0000</pubDate>
      <link>https://dev.to/comzzycomzzy/i-fine-tuned-an-open-model-to-be-the-front-desk-at-my-friends-nail-studio-3an0</link>
      <guid>https://dev.to/comzzycomzzy/i-fine-tuned-an-open-model-to-be-the-front-desk-at-my-friends-nail-studio-3an0</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu0b8yo9mrdoutcqc0yln.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu0b8yo9mrdoutcqc0yln.jpg" alt=" " width="800" height="1733"&gt;&lt;/a&gt;&lt;br&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%2F5cx3asiv6xfomi9gu26v.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5cx3asiv6xfomi9gu26v.jpg" alt=" " width="800" height="1733"&gt;&lt;/a&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;Meet Sugar&lt;br&gt;
Sugar is my friend. She does nails in GRA, Port Harcourt: gel, acrylic, Gel-X, BIAB, French tips, chrome, little hand-painted flowers. She's good at it, so she's busy.&lt;br&gt;
I've watched the same thing happen at her station many times. She has a client's hand in one hand and a brush in the other. Her phone keeps lighting up: "Hi dear, are you free today? How much is acrylic?" Someone walks in and asks how long the wait is. She can't stop to reply, she can't write down who came first, and she can't ask the next person if they want coffin or almond, nude or wine, or whether they're allergic to anything.&lt;br&gt;
So people wait, some leave, and the order of who's next lives in her head.&lt;br&gt;
She doesn't need salon software. She needs a front desk: someone to greet people, write down exactly what they want, tell them the price, take payment and give her a clean list of who's next. So I built one.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;p&gt;Two screens.&lt;br&gt;
The customer site. Customers open it on their phone, from a link Sugar shares or a QR code she can print for her station. The front desk greets them and asks for their name and number, then the service, style, colours, length, shape, allergies and a time. They can tap the options or type the way they talk, in English or Pidgin. They see the full order and the total in naira, pay, and get a ticket that updates on its own: "You're #2 · 1 person ahead of you."&lt;br&gt;
Sugar's queue. A PIN-protected page on her phone or tablet. It shows who's in the chair, who's next, and each person's order: services, style, colour swatches, length, shape, any allergy note (highlighted), the price and whether they've paid. She taps Start when someone sits down and Done when they leave. New bookings chime and slide in by themselves.&lt;br&gt;
The front desk is Qwen3-8B, an open-weight model I fine-tuned with LoRA on Tinker. It talks like Sugar's front desk, knows her menu and prices, and ends every booking with a structured order the app can check.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://sugar-nails-nine.vercel.app" rel="noopener noreferrer"&gt;https://sugar-nails-nine.vercel.app&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://youtu.be/ZyzuW1q0ZAE?si=SgPEC1N9pV0yKqDI" rel="noopener noreferrer"&gt;https://youtu.be/ZyzuW1q0ZAE?si=SgPEC1N9pV0yKqDI&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://github.com/comzzy/sugar-frontdesk" rel="noopener noreferrer"&gt;https://github.com/comzzy/sugar-frontdesk&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Sugar doesn't need a chatbot that sounds smart. She needs one that gets the order right: the correct service, the correct price, and the correct time, in the way her customers actually talk, which is often Pidgin.&lt;/p&gt;

&lt;p&gt;A general model couldn't do that well. When I tested base Qwen3-8B on her menu, it made up prices, forgot to ask about allergies, and sounded nothing like her. So I trained it on Tinker.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How I used Tinker:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I wrote about 1,750 booking chats in Sugar's voice, in English and Pidgin. Each one ends with a clean order card: name, phone, service, style, colours, length, shape, allergies, time and naira total.&lt;/li&gt;
&lt;li&gt;I fine-tuned Qwen3-8B with LoRA on Tinker. I didn't have to set up any GPUs. The training took under 5 minutes and cost about $1.65.&lt;/li&gt;
&lt;li&gt;I tested the base model and my trained model on 40 chats neither had seen before.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The results:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Orders that came out fully correct went from 22.5% to 95%.&lt;/li&gt;
&lt;li&gt;Prices that were right went from 35% to 92.5%.&lt;/li&gt;
&lt;li&gt;Order cards the app could actually read went from 72.5% to 100%.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The live chat runs on that trained checkpoint through Tinker. Each reply costs about ₦0.31, and a full booking comes to roughly ₦2.80.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The rest of the app:&lt;/strong&gt; The site is a FastAPI app on Vercel. When a customer finishes booking, the order card lands in Sugar's queue, a PIN-protected page where she taps Start when she begins a set and Done when she finishes. The payment step is simulated for now.&lt;/p&gt;

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

&lt;p&gt;Sugar is one person with one phone, working out of GRA, Port Harcourt. She's never going to pay for an enterprise AI subscription, and no big company is building a booking assistant that speaks Pidgin and knows her prices.&lt;/p&gt;

&lt;p&gt;Open models change that. Because Qwen3-8B is open-weight, I could take it and shape it to fit her exact menu, her customers and the way she talks. Tinker made the training part easy: I didn't need a GPU or a big budget, just good data and a few minutes. The whole fine-tune cost less than a plate of food.&lt;/p&gt;

&lt;p&gt;That's what open innovation means to me. The tools aren't only for big tech anymore. Anybody who knows a small business well enough can build something that actually fits it, and keep full control of it. The code is open too, so another nail tech, barber or caterer can fork it, swap in their own menu, and have their own front desk.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://dev.to/agent_sessions/building-sugar-nails-nocuim"&gt;https://dev.to/agent_sessions/building-sugar-nails-nocuim&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Best Use of Tinker.&lt;br&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%2Fx7rz9l6vhnjazpzanvi6.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%2Fx7rz9l6vhnjazpzanvi6.png" alt=" " width="512" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>I Built My Best Friend a Wedding Planner She Can Talk To</title>
      <dc:creator>Kane</dc:creator>
      <pubDate>Fri, 02 Oct 2026 22:20:40 +0000</pubDate>
      <link>https://dev.to/comzzycomzzy/i-built-my-best-friend-a-wedding-planner-she-can-talk-to-2ceb</link>
      <guid>https://dev.to/comzzycomzzy/i-built-my-best-friend-a-wedding-planner-she-can-talk-to-2ceb</guid>
      <description>&lt;p&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;br&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%2Fg1iiygg4qt1b0e14q099.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg1iiygg4qt1b0e14q099.jpg" alt=" " width="800" height="1733"&gt;&lt;/a&gt;&lt;br&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%2Feqstpdyi64z1067oo53d.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feqstpdyi64z1067oo53d.jpg" alt=" " width="800" height="1733"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Cynthia is my best friend, and she's getting married.&lt;br&gt;
Her wedding plans are spread across voice notes. The budget is in one, a vendor's price is in another, and the list of things still to book is mostly in her head. When she wants to know what's left, she scrolls back and listens again.&lt;br&gt;
Her guests are the same. Most of them won't fill in a form. They'll send a voice note saying "I go come with my husband" and expect someone to remember that he doesn't eat pepper.&lt;br&gt;
So I built Cynthia's Wedding Plans: a wedding planner she can talk to, and an RSVP her guests can talk to.&lt;br&gt;
The planner. Cynthia taps the mic and talks the way she already does in voice notes. For example: "Budget is five million naira, we're thinking December, and we've booked the photographer." The planner keeps four things up to date from what she says:&lt;br&gt;
a checklist with due dates that fit the time she has left&lt;br&gt;
a budget split across venue, food, outfits, decor and the rest&lt;br&gt;
a timeline for the day itself&lt;br&gt;
a vendor list showing who's booked, who's quoted and who she still has to find&lt;br&gt;
It answers her out loud, in a short reply that confirms what it understood and asks for one missing thing at most. One tap gives her a briefing: how many days are left, what's overdue and the next three things to do. Download plan saves the whole plan as a PDF she can share with her family.&lt;br&gt;
The planner, filled in with example numbers.&lt;br&gt;
Voice RSVP. A guest opens the link and just speaks, in English or Pidgin: "Na Funmi. I go come with my husband. Abeg no add pepper for am." The site turns that into a card with name, coming or not, how many people, food needs and a message. The guest checks it, fixes anything that's wrong and sends it. Then they hear a thank-you that says their name.&lt;br&gt;
Voice guestbook. Guests record a wish of up to a minute, or type one, then tap Send wish. Each wish is transcribed and sorted into blessings, advice, funny ones and memories. Cynthia ends up with a keepsake page that has the words and the original voices.&lt;br&gt;
Cynthia's guest list. Only Cynthia can open it. She types her password once, and her phone remembers it for 30 days. It shows the headcount, every reply and the food needs. There's also a CSV download she can send straight to the caterer. Nothing on the site links to the list, and search engines are told to skip it. --&amp;gt;&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://cynthias-wedding.vercel.app" rel="noopener noreferrer"&gt;https://cynthias-wedding.vercel.app&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://youtu.be/UDY3teDsXlo?si=s5e9bhlEeyu58eWm" rel="noopener noreferrer"&gt;https://youtu.be/UDY3teDsXlo?si=s5e9bhlEeyu58eWm&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://github.com/comzzy/cynthias-wedding-plans" rel="noopener noreferrer"&gt;https://github.com/comzzy/cynthias-wedding-plans&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;The planning runs on gpt-oss-120b, OpenAI's open-weight model (Apache 2.0), served by Groq. If it's slow, the app retries once on gpt-oss-20b.&lt;br&gt;
Every time Cynthia speaks, the app sends the model a short summary of her current plan and what she just said. The model sends back JSON: a short spoken reply, any facts she gave (budget, guest count, date), new tasks, tasks she's finished, budget changes, the order of the day and vendor updates. The app merges that into her plan. Models are bad at working out what day of the week a date falls on, so the prompt includes the real Saturdays for the next 14 months, and the model chooses a wedding date from that list. If no model is reachable, a small rule-based parser still picks up budgets, guest counts, dates and lines like "we booked the venue".&lt;br&gt;
The same model reads guests' RSVPs and wishes. The prompt gives it examples of how people really talk: "I go come" means attending, "me and my wife" means two people, "I no dey chop meat" means vegetarian. It also sorts each wish into one of the four guestbook groups.&lt;br&gt;
ElevenLabs does everything to do with voice:&lt;br&gt;
Scribe (speech-to-text) transcribes Cynthia's planner notes, guests' RSVPs and guestbook wishes. It copes with Nigerian names and with Pidgin, which mattered more than anything else here. If the transcript is wrong, nothing after it works.&lt;br&gt;
Voice Design made the planner's voice. I described a young Nigerian woman with a calm, warm voice, someone who sounds like home, and saved the result as "Cynthia Planner".&lt;br&gt;
Text-to-speech in that voice reads the planner's replies and the daily briefing.&lt;br&gt;
The RSVP thank-you is spoken to each guest, using their name.&lt;br&gt;
My note to Cynthia on the home page has a button to hear it read aloud. I generated the audio once and saved it as a file, so playing it costs nothing.&lt;br&gt;
The API keys stay on the server, and the browser only talks to the app's own routes.&lt;br&gt;
Stack: Next.js, Tailwind and Framer Motion on Vercel. RSVPs, wishes and recordings go into a private Vercel Blob store, or into a local folder when it runs on a laptop. Cynthia's plan is saved in her own browser. The guest list sign-in uses a signed, httpOnly cookie, with a limit on how many wrong passwords can be tried. The flowers are hand-drawn SVG, and the look is based on a save-the-date card Cynthia liked.&lt;/p&gt;

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

&lt;p&gt;This is a guest list and a wedding budget. It's family money, and it has her guests' names and what they can and can't eat. I didn't want that tied to one company's API that she has no control over.&lt;br&gt;
Because the model is open-weight, the model is just a setting. The app talks to any OpenAI-compatible endpoint, and changing LLM_BASE_URL and LLM_MODEL in the env file swaps it out. I don't have to rewrite anything if a price changes or a model is retired.&lt;br&gt;
It can also run on her laptop. Point it at Ollama with a small open model (I tested it with gemma3:1b) and keep storage on the local folder. Then the planning model runs on her machine, and her guest list and budget stay there too. To be clear, the voice parts still go through ElevenLabs, so audio is sent to them to be transcribed and spoken. Everything else stays on her laptop.&lt;br&gt;
And it costs almost nothing. Each planner message is one small JSON request to an open model on Groq, which comes to a fraction of a cent. A friend's wedding planner shouldn't come with a monthly bill.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://dev.to/agent_sessions/building-cynthias-wedding-plans-khyaox"&gt;https://dev.to/agent_sessions/building-cynthias-wedding-plans-khyaox&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Best Use of ElevenLabs: Scribe speech-to-text for English and Pidgin, Voice Design for the planner's voice, text-to-speech for spoken replies, the daily briefing and the RSVP thank-you, and my note read aloud.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>It didn't crash. It just wouldn't wait.</title>
      <dc:creator>Kane</dc:creator>
      <pubDate>Thu, 20 Aug 2026 09:14:48 +0000</pubDate>
      <link>https://dev.to/comzzycomzzy/it-didnt-crash-it-just-wouldnt-wait-2pl6</link>
      <guid>https://dev.to/comzzycomzzy/it-didnt-crash-it-just-wouldnt-wait-2pl6</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for &lt;a href="https://dev.to/bugsmash"&gt;DEV's Summer Bug Smash: Smash Stories&lt;/a&gt; powered by &lt;a href="https://sentry.io/" rel="noopener noreferrer"&gt;Sentry&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;StableRoute is a liquidity router on Stellar. The frontend is a Next.js app: quotes, pairs, admin controls, webhooks, audit logs. Most of it is forms and lists. The stats page is different. It is the room where you look at the protocol and ask a simple question: is it alive?&lt;/p&gt;

&lt;p&gt;That page used to look like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;refetch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;POLL_MS&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;clearInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;refetch&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Five seconds. Hit &lt;code&gt;/api/v1/stats&lt;/code&gt;. Paint the pair count. Paint whether the router is paused. Do it forever. It is the kind of code you write when you want the dashboard to feel live, and you do not yet know what "live" costs.&lt;/p&gt;

&lt;p&gt;I found out on a bad afternoon, not a dramatic one. The backend got slow. Not down, just sick. Latency climbed past five seconds. The stats page did not wait. &lt;code&gt;setInterval&lt;/code&gt; does not care whether the last request came home. It fires on the clock.&lt;/p&gt;

&lt;p&gt;Every five seconds &lt;code&gt;refetch&lt;/code&gt; bumped a reload key. The fetch effect tore down the previous request, marked it cancelled, and started another. If the server needed eight seconds, the client never kept a request long enough to finish. The dashboard sat there asking, cancelling, asking again. From the server's side it looked like a client that would not stop poking a bruise.&lt;/p&gt;

&lt;p&gt;When the API actually failed, it got worse. A 500 came back fast. The interval did not slow down. It kept hitting every five seconds. The UI flipped from error to loading to error. The alert unmounted and remounted. The page flickered. Anyone with the tab open became part of the outage.&lt;/p&gt;

&lt;p&gt;That is the bug. It did not throw. It did not panic a contract. It just refused to be kind when the system needed kindness.&lt;/p&gt;

&lt;p&gt;The fix was to stop treating time as the thing that drives the network.&lt;/p&gt;

&lt;p&gt;I threw out &lt;code&gt;setInterval&lt;/code&gt; and wrote &lt;code&gt;useBackoffInterval&lt;/code&gt;. The idea is small enough to hold in your head. A poll is allowed to schedule the next poll only after the current one has settled. Settled means &lt;code&gt;success&lt;/code&gt; or &lt;code&gt;error&lt;/code&gt;. While status is &lt;code&gt;idle&lt;/code&gt; or &lt;code&gt;loading&lt;/code&gt;, nothing is scheduled. One request in flight. No pile-up. No cancelled work eating the only response you were going to get.&lt;/p&gt;

&lt;p&gt;Failures remember themselves. A ref counts them, not React state, so counting a failure does not itself retrigger the effect. First error waits ten seconds. Then twenty. Then forty. Then it stops at sixty. The formula is the boring one everyone should have used from the start:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;delay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;baseMs&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;failureCount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;maxMs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first success zeros the counter. The cadence comes back to five seconds without anyone pressing Retry. The page still has a Retry button, because a human should be able to say "try now" without waiting for the backoff clock. Automatic recovery is not the same as trapping someone in a delay.&lt;/p&gt;

&lt;p&gt;There was a quieter bug inside the quieter bug. If you put &lt;code&gt;callback&lt;/code&gt; in the effect deps, every new function identity kills the timer and starts another. Polling becomes jitter. If you freeze the callback, you poll with a stale closure. The way through is the unfashionable one: keep the latest callback in a ref, update it every render, and let the effect depend on status and timing, not on the function you plan to call.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;callbackRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;callbackRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;success&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// ... count, compute delay, schedule callbackRef.current&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timeoutId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;baseMs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;maxMs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;schedule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unmount clears the timeout. I tested that by leaving, advancing fifteen seconds, and counting fetch calls. It stayed at one. That is the whole point of cleanup. Most people write it. Fewer people prove it.&lt;/p&gt;

&lt;p&gt;The tests are the part I am actually proud of. I did not want to sit in a browser and wait for a minute of backoff. The hook takes &lt;code&gt;schedule&lt;/code&gt; and &lt;code&gt;cancel&lt;/code&gt; as arguments. In production those are &lt;code&gt;setTimeout&lt;/code&gt; and &lt;code&gt;clearTimeout&lt;/code&gt;. In Jest they are mocks. The test can say: you were told to wait 10,000ms, then 20,000, then 40,000, then 60,000, then 60,000 again. It can say: after an error, a success puts you back on 5,000. It can say: if the callback identity changes before the timeout fires, you call the new one, not the old one. It can say: idle and loading schedule nothing.&lt;/p&gt;

&lt;p&gt;That is how the page stopped being a liability.&lt;/p&gt;

&lt;p&gt;When the router is healthy, the tiles still update every five seconds. The "Updated just now" label still ticks. When the router is not healthy, the page tells you so once, holds the alert still, and backs away. The copy is honest: retrying automatically, with a longer delay, while the service is unavailable. It is not pretending everything is fine. It is also not kicking the thing that is already down.&lt;/p&gt;

&lt;p&gt;I would not call this legendary. I would call it the work that makes software feel like it was written by someone who has been on both sides of a slow endpoint. The stats page is a small surface. It is also the first place an operator looks when they are worried. If that page panics, the rest of the product feels like it is panicking with it.&lt;/p&gt;

&lt;p&gt;The win was not a clever algorithm. The win was that the dashboard learned how to wait.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>bugsmash</category>
    </item>
    <item>
      <title>PawGuard: A platform responsible for instant Abuse reporting and Community for Dogs in danger</title>
      <dc:creator>Kane</dc:creator>
      <pubDate>Sun, 16 Aug 2026 18:19:45 +0000</pubDate>
      <link>https://dev.to/comzzycomzzy/pawguard-a-platform-responsible-for-instant-abuse-reporting-and-community-for-dogs-in-danger-5b8g</link>
      <guid>https://dev.to/comzzycomzzy/pawguard-a-platform-responsible-for-instant-abuse-reporting-and-community-for-dogs-in-danger-5b8g</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for &lt;a href="https://dev.to/challenges/weekend-2026-08-13"&gt;Weekend Challenge: Dog Days Edition&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;PawGuard is a community web platform built to help protect dogs from abuse, severe neglect, and abandonment. When someone spots a dog in danger—whether chained without water, hit by a car, or dumped—they can submit a report in seconds with their GPS location, photos, urgency level, and even stay anonymous if needed. Those alerts are routed directly to local rescue contacts and volunteers via WhatsApp and email so someone can respond quickly.&lt;/p&gt;

&lt;p&gt;In addition to emergency reports, the platform includes a noticeboard for lost and found pets (with instant printable flyers), an adoption and foster board, and practical guides on animal welfare.&lt;/p&gt;

&lt;p&gt;My main goal with PawGuard was to remove the friction between seeing an animal suffering on the street and actually getting help to them. Too often, people don't know who to call or where to report neglect. PawGuard gives everyday people a direct, fast way to speak up and connects them with volunteers who can step in.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://paw-guard-two.vercel.app" rel="noopener noreferrer"&gt;https://paw-guard-two.vercel.app&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://github.com/comzzy-comzzy/PawGuard" rel="noopener noreferrer"&gt;https://github.com/comzzy-comzzy/PawGuard&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;I built PawGuard as a responsive single-page web application using React 18, TypeScript, and Vite, styled with Tailwind CSS and custom CSS animation keyframes.&lt;/p&gt;

&lt;p&gt;A few key technical decisions shaped the build:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Zero-Delay Emergency Dispatch: Instead of locking emergency reports behind authentication or waiting on slow backend pipelines, I built client-side triage and routing that immediately bundles report details (GPS coordinates, urgency classification, incident notes) into structured WhatsApp and email dispatch links. Rescuers get the exact location and photos sent directly to their phones in real time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dynamic Audio &amp;amp; Custom Animations: Animal rescue platforms can often feel bleak and heavy. I used the Web Audio API for lightweight synthesized sound effects and custom keyframe animations for our canine mascots, creating an engaging, welcoming experience without bloating page load times.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Instant Printable Flyer Generation: For lost and abandoned dogs, we implemented client-side flyer generation directly in the browser so community members can print or share high-visibility search notices immediately.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Guided Intake Companion ("Picky"): I implemented an interactive conversation flow that walks stressed witnesses step-by-step through capturing the essential details needed for a rescue (exact landmarks, condition of the dog, immediate threats).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Best Use of Google AI — Antigravity with Gemini 3.7 (High Reasoning)&lt;/p&gt;

&lt;p&gt;I leveraged Google Antigravity powered by Gemini 3.7 (High reasoning mode) as our core development and architectural copilot throughout the project.&lt;/p&gt;

&lt;p&gt;With Gemini 3.7's deep multi-step reasoning:&lt;/p&gt;

&lt;p&gt;• I architected resilient state flows for complex multi-module forms (abuse intake, foster applications, and lost pet postings).&lt;/p&gt;

&lt;p&gt;• I rapidly designed and refined the interactive triage logic and geolocation fallbacks, ensuring reports are formatted accurately even when network conditions or location services are spotty.&lt;/p&gt;

&lt;p&gt;• Antigravity helped me implement clean, fully typed TypeScript schemas and custom UI micro-interactions, cutting development time drastically while keeping the codebase modular and maintainable.&lt;/p&gt;

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

&lt;p&gt;Best Use of Google AI.&lt;/p&gt;

&lt;p&gt;Team Submissions: Hi I'm a Solobuilder i havent added anyone yet to my team&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
    </item>
    <item>
      <title>StableRoute Frontend: Resilient Polling with Adaptive Exponential Backoff</title>
      <dc:creator>Kane</dc:creator>
      <pubDate>Sat, 15 Aug 2026 10:30:04 +0000</pubDate>
      <link>https://dev.to/comzzycomzzy/stableroute-frontend-resilient-polling-with-adaptive-exponential-backoff-40g7</link>
      <guid>https://dev.to/comzzycomzzy/stableroute-frontend-resilient-polling-with-adaptive-exponential-backoff-40g7</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for &lt;a href="https://dev.to/bugsmash"&gt;DEV's Summer Bug Smash: Clear the Lineup&lt;/a&gt; powered by &lt;a href="https://sentry.io/" rel="noopener noreferrer"&gt;Sentry&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Overview
&lt;/h2&gt;

&lt;p&gt;StableRoute Frontend is the web interface for StableRoute, an open-source decentralized liquidity routing protocol built on the Stellar network. The application is built with Next.js (App Router), React, and TypeScript.&lt;br&gt;
The platform provides a comprehensive suite of tools for traders, liquidity providers, and developers:&lt;br&gt;
Payment and Liquidity Routing: An interactive interface for querying optimal swap and cross-currency path routing quotes across Stellar asset pools.&lt;br&gt;
Liquidity Pool Management: Workflows to register, inspect, and configure supported asset pairs.&lt;br&gt;
Real-Time Protocol Monitoring: A live status dashboard that polls protocol health, operational state (active vs. paused), and liquidity pool counts.&lt;br&gt;
Developer and Infrastructure Controls: Management consoles for generating and revoking API keys, registering webhook event subscribers, viewing immutable system audit logs, and inspecting OpenAPI documentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bug Fix or Performance Improvement
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The Bug&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In src/app/stats/Client.tsx, dashboard statistics were updated using a raw setInterval:useEffect(() =&amp;gt; {&lt;br&gt;
  const id = setInterval(refetch, POLL_MS);&lt;br&gt;
  return () =&amp;gt; clearInterval(id);&lt;br&gt;
}, [refetch]);&lt;/p&gt;

&lt;p&gt;This caused three critical issues:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Overlapping In-Flight Requests (Race Conditions)
setInterval fired strictly on a 5-second timer regardless of how long the network request took. If a request stalled or took 6 seconds due to network lag, a second request was fired before the first one finished. This created stacked concurrent requests where an older, delayed response could overwrite newer data in React state.&lt;/li&gt;
&lt;li&gt;Backend Hammering During Outages (Thundering Herd)
When the backend experienced downtime, high load, or returned errors (500s/429s), the frontend never backed off. It continued hammering the failing endpoint every 5 seconds unabated, causing rate limits and thrashing the UI with re-rendering error alerts.&lt;/li&gt;
&lt;li&gt;Timer Churn on Re-render
Because refetch was in the dependency array, whenever parent component updates created a new function reference, the old interval was cleared and a new one started from scratch, disrupting regular polling cadence.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;How I Fixed It&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I replaced setInterval with a custom, lifecycle-aware scheduling hook called useBackoffInterval:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Settled-State Scheduling
Instead of a blind clock, the hook waits for the request to settle into either 'success' or 'error' before scheduling the next timer. While a request is in the 'loading' state, no timers run, completely eliminating overlapping requests.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Exponential Backoff on Failures&lt;br&gt;
We track consecutive failures using a ref (failureCountRef). When errors occur, the delay doubles progressively:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    ⎛          failures      ⎞
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;delay = min ⎝baseMs × 2        ,maxMs⎠&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This increases the retry delay from 5s to 10s, 20s, 40s, and caps at 60s, giving backend services breathing room to recover.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Instant Cadence Recovery
On the very first successful response (status === 'success'), the failure counter resets to 0 and the polling interval immediately returns to the standard 5-second cadence without requiring user intervention.&lt;/li&gt;
&lt;li&gt;Ref-Stabilized Callback
We stored the callback in useRef(callback) and synced it on every render (callbackRef.current = callback). This guarantees that the timer always executes the freshest callback closure without tearing down and restarting the active timer on unrelated UI re-renders.&lt;/li&gt;
&lt;li&gt;Clean Unmount Teardown
Each scheduled timer returns a cleanup function calling clearTimeout(timeoutId), preventing memory leaks and state updates on unmounted components.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Pull Request / Branch: &lt;a href="https://github.com/comzzy-comzzy/Stableroute-frontend/tree/performance/stats-polling-backoff" rel="noopener noreferrer"&gt;https://github.com/comzzy-comzzy/Stableroute-frontend/tree/performance/stats-polling-backoff&lt;/a&gt;&lt;br&gt;
Target Repository: &lt;a href="https://github.com/StableRoute-Org/Stableroute-frontend" rel="noopener noreferrer"&gt;https://github.com/StableRoute-Org/Stableroute-frontend&lt;/a&gt;&lt;br&gt;
Commit: 786106d62e4697aa4a9b536ab75bb320101edd9b (perf(stats): back off polling interval after repeated failures)&lt;/p&gt;

&lt;p&gt;// Custom hook in src/app/stats/Client.tsx&lt;/p&gt;

&lt;p&gt;export function useBackoffInterval(&lt;br&gt;
  status: PollStatus,&lt;br&gt;
  callback: () =&amp;gt; void,&lt;br&gt;
  options: BackoffIntervalOptions = {}&lt;br&gt;
): void {&lt;br&gt;
  const {&lt;br&gt;
    baseMs = POLL_MS,          // 5,000ms&lt;br&gt;
    maxMs = MAX_POLL_MS,        // 60,000ms&lt;br&gt;
    schedule = scheduleTimeout,&lt;br&gt;
    cancel = cancelTimeout,&lt;br&gt;
  } = options;&lt;/p&gt;

&lt;p&gt;const callbackRef = useRef(callback);&lt;br&gt;
  const failureCountRef = useRef(0);&lt;br&gt;
  callbackRef.current = callback;&lt;/p&gt;

&lt;p&gt;useEffect(() =&amp;gt; {&lt;br&gt;
    // Only schedule next tick after a request settles&lt;br&gt;
    if (status !== 'success' &amp;amp;&amp;amp; status !== 'error') return;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (status === 'success') {
  failureCountRef.current = 0;
} else {
  failureCountRef.current += 1;
}

const delayMs =
  status === 'success'
    ? baseMs
    : Math.min(baseMs * 2 ** failureCountRef.current, maxMs);

const timeoutId = schedule(() =&amp;gt; callbackRef.current(), delayMs);
return () =&amp;gt; cancel(timeoutId);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}, [baseMs, cancel, maxMs, schedule, status]);&lt;br&gt;
}&lt;/p&gt;

&lt;h2&gt;
  
  
  My Improvements
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Custom useBackoffInterval Hook: Instead of hacking state inside the UI component, I decoupled retry scheduling into a reusable, lifecycle-aware hook.&lt;/li&gt;
&lt;li&gt;Settled-State Gating: Scheduling only runs when the request status reaches 'success' or 'error'. While the status is 'idle' or 'loading', no timers are scheduled, strictly preventing concurrent in-flight requests.&lt;/li&gt;
&lt;li&gt;Deterministic Exponential Backoff with Upper Bound: Consecutive failures increase the delay exponentially (baseMs * 2^failures), progressing from 10s to 20s, 40s, and capping at 60s (maxMs). As soon as an update succeeds, failureCount resets to 0 and normal 5-second polling immediately resumes.&lt;/li&gt;
&lt;li&gt;Ref-Stabilized Callback Execution: Storing the refetch callback in a ref (callbackRef.current = callback) prevents timer teardown and re-creation when parent component props change across renders.&lt;/li&gt;
&lt;li&gt;Inversion of Control for Deterministic Testing: The hook accepts optional schedule and cancel functions. This allowed writing deterministic unit tests that execute synchronously without flakey time-dependent assertions.&lt;/li&gt;
&lt;li&gt;Comprehensive Unit and Integration Test Suite: Added comprehensive test coverage in src/app/stats/page.test.tsx verifying:
.Base 5-second cadence on consecutive successful responses.
.Delay doubling under network failures up to the 60-second limit.
Immediate delay reset to 5 seconds upon recovery.
.Prevention of duplicate alert renders during error backoff.
.Clean timer cancellation on component unmount.&lt;/li&gt;
&lt;li&gt;Contract Documentation: Documented the behavior, parameter options, and lifecycle guarantees in docs/hooks.md.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Best Use of Google AI
&lt;/h2&gt;

&lt;p&gt;Throughout the development, architecture design, debugging, and testing phases of this project and related protocol repositories, I utilized Google Antigravity paired with the Gemini 3.5 Flash (High) model as a primary engineering assistant across multiple tech stacks (React/TypeScript, Rust Soroban, Solidity, and Node.js microservices).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Primary Project: Frontend Exponential Backoff &amp;amp; Lifecycle Safety (Stableroute-frontend)
PR / Branch: performance/stats-polling-backoff (Commit 786106d)
How Google AI Was Used:
Root-Cause Diagnosis: Analyzed client network waterfall logs to isolate why client browsers flooded backend endpoints with requests during API degradation. Gemini 3.5 Flash (High) identified the unmanaged setInterval concurrency hazard.
Hook Architecture: Formulated the useBackoffInterval pattern. The model advised storing active callbacks in useRef to prevent timer re-creation on renders while gating execution strictly to settled status states ('success' | 'error').
Deterministic Test Harness: Generated the Jest mock-timer test suite (src/app/stats/page.test.tsx), verifying exact progressive delay doubling (10s, 20s, 40s, 60s cap) and unmount cleanups.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>bugsmash</category>
      <category>devchallenge</category>
      <category>performance</category>
      <category>debugging</category>
    </item>
  </channel>
</rss>
