<?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: Sadhir Razaak</title>
    <description>The latest articles on DEV Community by Sadhir Razaak (@sadhir).</description>
    <link>https://dev.to/sadhir</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%2F4145865%2Ff8b68084-14c1-4f0d-8f29-673b5e440c77.png</url>
      <title>DEV Community: Sadhir Razaak</title>
      <link>https://dev.to/sadhir</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sadhir"/>
    <language>en</language>
    <item>
      <title>HydroLocal: a private water coach I built for a friend on the production line</title>
      <dc:creator>Sadhir Razaak</dc:creator>
      <pubDate>Sun, 04 Oct 2026 06:35:49 +0000</pubDate>
      <link>https://dev.to/sadhir/hydrolocal-a-private-water-coach-i-built-for-a-friend-on-the-production-line-2b6j</link>
      <guid>https://dev.to/sadhir/hydrolocal-a-private-water-coach-i-built-for-a-friend-on-the-production-line-2b6j</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;/p&gt;

&lt;h2&gt;
  
  
  What I built, and who it's for
&lt;/h2&gt;

&lt;p&gt;A friend of mine works on a production line. He finds it hard to keep track of how much water he drinks during a shift, and he gets dehydrated quickly. When the work is busy, it's easy for a glass of water to slip down the list, and the day goes by without it.&lt;/p&gt;

&lt;p&gt;I see something similar closer to home. My sister needs my mom to remind her to drink water, again and again. That got me thinking: what if the reminder could come from something that isn't a person?&lt;/p&gt;

&lt;p&gt;So this weekend I built &lt;strong&gt;HydroLocal&lt;/strong&gt;, a hydration coach for my friend that runs entirely on a laptop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Watch or listen to the story&lt;/strong&gt; (narration and visuals made with ElevenLabs):&lt;/p&gt;

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

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Shift at work:&lt;/strong&gt; you enter your shift times, your breaks, how warm and physical the work is, and whether you can keep water at your station. It builds a drinking schedule around your breaks. Night shifts that cross midnight work too.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Phone alarms:&lt;/strong&gt; every plan downloads as a calendar file (.ics). Open it on a phone and the schedule becomes alarms, with no internet needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Everyday reminders:&lt;/strong&gt; gentle reminders through the day for anyone who forgets to drink.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trek pacing:&lt;/strong&gt; a bonus mode that spreads the water you carry across a whole walk and keeps a reserve.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;HydroLocal runs on your own computer, so there is no hosted link. Here is what it looks like.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Enter your shift.&lt;/strong&gt; Times, breaks, how warm and physical the work is, and whether water can be kept at the station. Note the "No internet access" message in the corner: the app is running with the internet off.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fprtgly7pza2gpnt55hao.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%2Fprtgly7pza2gpnt55hao.png" alt="The Shift at work tab with the inputs filled in, and a " width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Get a schedule.&lt;/strong&gt; The amounts and times are worked out by plain Python, so they appear straight away. Here, the app is waiting for Gemma's note.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F24mghqq03csn9ghbwdk4.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%2F24mghqq03csn9ghbwdk4.png" alt="The schedule table: 400 ml before clocking in, then 200 ml every 30 minutes, with a top-up at each break" width="800" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Read Gemma's note, and take the plan to your phone.&lt;/strong&gt; The note is written by Gemma on my own laptop, and the download button turns the plan into phone reminders.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frc7s8lvtgm9zuom5u10u.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%2Frc7s8lvtgm9zuom5u10u.png" alt="Gemma's short note under the schedule, and the button to download reminders for your phone" width="800" height="501"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://github.com/sadhirr1/Hydrolocal" rel="noopener noreferrer"&gt;github.com/sadhirr1/Hydrolocal&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The README has the setup steps. In short: install Python, install LM Studio, download &lt;code&gt;google/gemma-4-e4b&lt;/code&gt; (about 6 GB), start LM Studio's server, then run two commands.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I built it
&lt;/h2&gt;

&lt;p&gt;I worked with Claude. I described what I wanted, tested it, and kept feeding it the errors to fix until the application worked.&lt;/p&gt;

&lt;p&gt;The design choice I'm proudest of is splitting the work in two:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Plain Python does the maths.&lt;/strong&gt; The amounts and times come from a small, readable file (&lt;code&gt;hydration.py&lt;/code&gt;). The numbers are rule-of-thumb estimates, not medical advice, and the app says so.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemma does the words.&lt;/strong&gt; An open-weight model, Gemma 4 (the e4b version), running locally in LM Studio, writes a short friendly note around the numbers it's given. It is told not to diagnose anything, not to invent places or brands, not to recommend salt, supplements or food, and to say that anyone who feels dizzy or faint should stop, sit down and get help.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I split it that way on purpose. For something health-adjacent, I wanted a small model to be good at friendly wording, and I didn't want it guessing at numbers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where the numbers come from
&lt;/h3&gt;

&lt;p&gt;My first version used amounts I couldn't point to a source for, and I didn't want to publish that. So I rebuilt them around two public sources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hot work:&lt;/strong&gt; the US CDC/NIOSH guidance, about one cup (8 oz) every 15 to 20 minutes, which is 24 to 32 oz (roughly 710 to 950 ml) per hour, and never more than 48 oz per hour. HydroLocal never suggests more than the top of that range. &lt;a href="https://www.cdc.gov/niosh/mining/UserFiles/works/products/training/keepingcool/2017-126_hydration.pdf" rel="noopener noreferrer"&gt;CDC/NIOSH hydration guide (PDF)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comfortable conditions:&lt;/strong&gt; the US National Academies adequate intake for total water, about 2.7 L a day for women and 3.7 L for men, with roughly 80% coming from drinks. &lt;a href="https://www.nationalacademies.org/news/report-sets-dietary-intake-levels-for-water-salt-and-potassium-to-maintain-health-and-reduce-chronic-disease-risk" rel="noopener noreferrer"&gt;National Academies report&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything in between is my own estimate, and both the app and the code say so. That covers the "warm" level, scaling by body weight, the drinks before and after a shift, and the trek reserve.&lt;/p&gt;

&lt;h3&gt;
  
  
  What went wrong
&lt;/h3&gt;

&lt;p&gt;My first test came back with an empty note. Gemma 4 is a "thinking" model. It reasons silently first, and that reasoning counts toward the answer's length limit, so my limit was too low and it ran out of room before writing anything. Raising the limit fixed it. Figuring out how token limits affect silent reasoning was a huge learning moment for me.&lt;/p&gt;

&lt;p&gt;Gemma also once suggested a pinch of salt in a note. I never told it to say that, and I didn't want a small model giving that kind of advice, so I added a rule against it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Privacy, all the way down
&lt;/h3&gt;

&lt;p&gt;Streamlit, the library behind the interface, sends anonymous usage statistics by default. I turned that off and made the app reachable only from my own computer, so the privacy claim is true all the way down.&lt;/p&gt;

&lt;p&gt;A small set of automated tests checks the schedule logic, the calendar file, and what happens when the local model isn't running. In that case the app still shows the schedule and skips only the note.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why open innovation mattered
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Privacy.&lt;/strong&gt; Body weight, shift patterns and health habits never leave the laptop. There is no account and nothing is saved.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No running cost.&lt;/strong&gt; There is no per-message fee. It's an open model on hardware I already own.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Swappable.&lt;/strong&gt; The app asks LM Studio which model is loaded, so Gemma can be replaced by another open model without changing the code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Offline.&lt;/strong&gt; I made a plan with the internet switched off, and the schedule and Gemma's note still appeared. The first screenshot above shows Windows reporting "No internet access".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An honest limit.&lt;/strong&gt; Running a local model takes a bit of patience. In my last test on my laptop, Gemma 4 E4B took about 35 to 40 seconds to write the note. A small model on an ordinary laptop is slower than a cloud service, but the schedule appears straight away, and for this use case I think the privacy tradeoff is worth it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Categories I'm entering
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Gemma:&lt;/strong&gt; Gemma 4 runs locally and writes the coaching note.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of ElevenLabs:&lt;/strong&gt; the story video at the top was made with ElevenLabs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Honest limits
&lt;/h2&gt;

&lt;p&gt;HydroLocal is a general guide, not medical advice, and it can't tell anyone why they feel unwell. Anyone who feels dizzy, faint or confused should stop, sit down, tell someone and get medical help. People with kidney, heart or other medical conditions should follow their doctor's advice about fluids.&lt;/p&gt;

&lt;p&gt;My friend hasn't used it on the line yet. I built it for him, and I hope it helps.&lt;/p&gt;

&lt;p&gt;Thank you for reading, and thanks to my friend for letting me build this for him.&lt;/p&gt;

</description>
      <category>hf26challenge</category>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
    </item>
    <item>
      <title>The bugs that don't crash</title>
      <dc:creator>Sadhir Razaak</dc:creator>
      <pubDate>Sun, 27 Sep 2026 18:27:52 +0000</pubDate>
      <link>https://dev.to/sadhir/the-bugs-that-dont-crash-i9l</link>
      <guid>https://dev.to/sadhir/the-bugs-that-dont-crash-i9l</guid>
      <description>&lt;p&gt;The worst bug I found in my bank statement parser didn't raise an exception, fail a test, or log a warning. It quietly recorded every credit card bill I paid as income.&lt;/p&gt;

&lt;p&gt;The numbers looked fine. The totals were plausible. Spending was down, which was nice. It was all wrong, and nothing anywhere said so.&lt;/p&gt;

&lt;p&gt;I've been building LedgerLens, a tool that reads bank and credit card statements — CSV or PDF — and makes them queryable. Three bugs cost me real time. All three produced confident wrong answers rather than errors. That turns out to be the whole story.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;03/04/2026&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Is that March 4th or April 3rd?&lt;/p&gt;

&lt;p&gt;You can't tell. Nobody can. It depends entirely on which country produced the file, and the file rarely says.&lt;/p&gt;

&lt;p&gt;The obvious approach is to parse each row as you meet it — try a few formats, take the first that works. It runs clean on every input. It also means a single statement can end up with some transactions in March and some in April, silently, depending on the day-of-month of each row. Your "spending by month" chart is then wrong in a way that looks entirely reasonable.&lt;/p&gt;

&lt;p&gt;The fix is to stop treating the question as per-row. A file has one date format, so use the whole column as evidence:&lt;/p&gt;

&lt;p&gt;03/04/2026   ← ambiguous&lt;br&gt;
05/06/2026   ← ambiguous&lt;br&gt;
25/03/2026   ← not ambiguous. 25 can't be a month.&lt;br&gt;
07/08/2026   ← ambiguous&lt;/p&gt;

&lt;p&gt;One row settles the entire file. Day-first parses everything; month-first can't parse row three at all. So every other row in that file is day-first too — including the ones that were ambiguous in isolation.&lt;/p&gt;

&lt;p&gt;Where no row disambiguates, there's still a signal: a statement covers a contiguous period. If one reading puts the transactions inside two months and the other scatters them across nine, the tight one is right.&lt;/p&gt;

&lt;p&gt;And when the column is genuinely undecidable — every value has both components under 13 — the honest move is to pick a default and say so:&lt;/p&gt;

&lt;p&gt;ambiguous_dates.csv   4 imported, 0 skipped&lt;br&gt;
  ! date format: %m/%d/%Y (confidence 0.50): genuinely ambiguous (no component&lt;br&gt;
    exceeds 12); defaulting to month-first. Set day_first in ledgerlens.yaml&lt;/p&gt;

&lt;p&gt;A guess announced is a different thing from a guess buried.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Credit cards run the signs backwards&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is the one that recorded my bill payments as income.&lt;/p&gt;

&lt;p&gt;On a current account, money out is negative. Obvious. On a credit card statement, a purchase prints as positive and your monthly payment prints as negative — because the statement is tracking what you owe, not what you hold.&lt;/p&gt;

&lt;p&gt;Read a card statement with bank-account assumptions and every number inverts. Spending becomes income, payments become purchases. Nothing errors. The totals still balance. The report is simply a mirror image of reality.&lt;/p&gt;

&lt;p&gt;The fix seemed easy: a statement states the direction in its section headings. "New Charges" is money out, "Payments and Credits" is money in. Use those.&lt;/p&gt;

&lt;p&gt;Then I got it wrong a second time, and this one is more interesting.&lt;/p&gt;

&lt;p&gt;I used the heading and the printed sign — reasoning that a minus inside "New Charges" meant a refund, so the sign should flip the heading's direction. But in the Payments section, every amount is already printed negative. That minus isn't modifying the heading. It is the heading, restated. Applying both flipped everything back:&lt;/p&gt;

&lt;p&gt;Payments&lt;br&gt;
  08/03/26   Mobile Payment - Thank You   -$20.12   →  recorded as -20.12  ✗&lt;/p&gt;

&lt;p&gt;The rule that actually works: each section prints its ordinary case with a consistent sign, so learn that section's majority sign as its normal, and flip only the minority rows. A refund among the charges is the minority. A payment in the payments section is not.&lt;/p&gt;

&lt;p&gt;Both versions produced clean output. Both were wrong. The difference was only visible if you knew what the answer should be.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The skip that never stopped&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Statements are laid out in a way that's obvious to a human and a trap for a parser:&lt;/p&gt;

&lt;p&gt;New Charges&lt;br&gt;
  Summary&lt;br&gt;
    Total New Charges          $587.10&lt;br&gt;
  Detail&lt;br&gt;
    08/16/26  AMAZON PRIME       $1.09&lt;br&gt;
    08/16/26  GROCERY STORE     $11.01&lt;br&gt;
    ...&lt;/p&gt;

&lt;p&gt;The summary block repeats the section's total. You don't want that total imported as if it were a transaction, so you skip the summary.&lt;/p&gt;

&lt;p&gt;I skipped it. I never stopped skipping. The detail rows came after, and on later pages under "Detail Continued", so the flag stayed set and swallowed them all.&lt;/p&gt;

&lt;p&gt;My parser returned 4 transactions out of 35. It reported success. The four it found were correct, correctly dated, correctly signed. There was no error to notice and no reason to look, other than a vague feeling that my statement seemed quiet.&lt;/p&gt;

&lt;p&gt;The pattern&lt;/p&gt;

&lt;p&gt;Three bugs, one shape: plausible output, no error.&lt;/p&gt;

&lt;p&gt;That inverts the usual intuition about robustness. I'd been thinking about malformed input — what if the file's truncated, what if a cell is empty, what if the encoding's wrong. Those cases are easy. They throw. You see them immediately and fix them in minutes.&lt;/p&gt;

&lt;p&gt;The expensive failures were all inputs my code handled perfectly, and got wrong.&lt;/p&gt;

&lt;p&gt;In parsing, a crash is the good outcome. It's the case where the system tells you it failed. The dangerous case is the one that succeeds at producing something that looks like an answer.&lt;/p&gt;

&lt;p&gt;Which leads to the actually useful question: if failures don't announce themselves, what makes them announce themselves?&lt;/p&gt;

&lt;p&gt;Three things that helped&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Find the document's own checksum.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This one turned out to be the single most valuable change, and it generalises further than I expected.&lt;/p&gt;

&lt;p&gt;A statement tells you what it adds up to. It prints "Total New Charges $587.10" right there above the rows. So: sum what you extracted, compare to what the document claims, and report the result.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;amex_2026-09.pdf   35 imported, 0 skipped
  ✓ reconciles against the statement's own printed totals
    (in statement 340.68, extracted 340.68; out statement 587.10, extracted 587.10)

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

&lt;/div&gt;



&lt;p&gt;That line is worth more than any amount of careful parsing, because it's not a claim about my code — it's arithmetic against the issuer's own figures. When it matches, the extraction isn't merely plausible, it's consistent with the source. When it doesn't, you get told by exactly how much, instead of a confident wrong number.&lt;/p&gt;

&lt;p&gt;Every one of my three bugs would have been caught by this on the first run. The missing-31-transactions bug would have failed it by $580.&lt;/p&gt;

&lt;p&gt;And most documents have something like this. Invoices have totals. Statements have opening and closing balances. Payroll files have gross-to-net. Exports sometimes carry row counts. If the thing you're parsing states a fact about itself, check it. It's the cheapest correctness signal available and it's usually sitting right there in the document, ignored.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Test against planted ground truth, not observed output.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The tempting way to write a test for messy parsing is to run the code, eyeball the result, and assert that. But that only locks in whatever the code did on the day — including the bugs.&lt;/p&gt;

&lt;p&gt;So the test fixtures are generated by a seeded script that plants known facts: statements with subscriptions at a specified cadence, amount and cancellation date. The tests assert the detector finds those. When I broke the summary skipping, the test failed because it knew there should be fourteen charges, not because anything crashed.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Make low confidence visible.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Where the code has to guess, it reports the guess and how sure it is:&lt;/p&gt;

&lt;p&gt;! amount direction: assume_outflow (confidence 0.55): amounts are unsigned with&lt;br&gt;
    no type column; assuming a card-style spend-only export&lt;/p&gt;

&lt;p&gt;That's not an error. The import worked. But it's the difference between a program that quietly decided something on your behalf and one that told you it had to.&lt;/p&gt;

&lt;p&gt;The thing I'd tell myself at the start&lt;/p&gt;

&lt;p&gt;I spent my defensive effort on the inputs I imagined would break things — truncated files, weird encodings, empty cells. All of those threw immediately and cost me nothing.&lt;/p&gt;

&lt;p&gt;Everything that actually hurt was a file my code parsed successfully and interpreted wrongly. And the only reliable defence against that class of bug isn't more careful code. It's finding something external to check the code against — ideally something the input itself already tells you.&lt;/p&gt;

&lt;p&gt;The parser that proves its own work beats the parser that's merely careful, because carefulness is invisible when it fails and proof isn't.&lt;/p&gt;

&lt;p&gt;LedgerLens is a local-first MCP server that reads bank and card statements, finds subscriptions you've forgotten about, and makes no network calls at all. Code and a longer write-up of the design trade-offs: github.com/sadhirr1/ledgerlens&lt;/p&gt;

</description>
      <category>python</category>
      <category>testing</category>
      <category>programming</category>
      <category>debugging</category>
    </item>
  </channel>
</rss>
