This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle
What I Built
In India, a lot of government exam applications are not filled in by the candidate. They're filled in at the cyber café down the road, by the guy everyone calls "form bhaiya", who charges a fee per form. SSC, UPSC, railways, state commissions: he does them all, often for a queue of people in the last week before a deadline.
Every one of those exams comes with a notice. The SSC CGL 2026 notice is 132 pages. Somewhere in there is the last date, the fee and who's exempt from it, the age limit as a pair of birth dates, a table of age relaxations by category, and the exact size the signature has to be (10 to 20 KB, about 6 × 2 cm). Get one of those wrong and the form is rejected, and the candidate comes back to the café, not to the commission.
Form Bhaiya is a tool for that café. Drop in the notice PDF and it reads it once, with open-weight models, into the things a café actually needs at the counter. Every answer has a little rubber stamp next to it: ✓ P.13. Tap it and you see the exact line from the notice it came from. Then:
- Check the candidate. Date of birth, category, sex, disability, ex-serviceman. Out comes "Eligible", or "Not eligible: born 1 day after the last allowed date", or "Eligible only because of the 3-year OBC relaxation", plus the fee they pay.
- Hand them a slip. In Hindi or English: what they're eligible for, the fee, the dates still ahead, the documents to keep ready. Print it or send it on WhatsApp.
- Fix the photo and signature. Crop it, whiten the paper, trim to the ink, print the name and date under the photo if the notice asks, and squeeze the JPG into the KB range. In the browser, so the candidate's photo never leaves the café.
Who pays: the café. It already earns per form, and a rejected form costs it a customer. A notice only has to be read once, by anyone, and then it opens instantly for every café, so it's cheap enough to sell as a small monthly subscription per café.
Demo
That's the real SSC CHSL 2026 notice, whose correction window happens to be open this week. The app ships with three real notices already read: SSC CHSL 2026 (88 pages), SSC CGL 2026 (132 pages) and UPSC CDS II 2026 (35 pages). All 116 answers in them carry a green stamp.
Try it: form-bhaiya.onrender.com
It's on a free plan, so the first load after a quiet spell takes about half a minute. Open the CHSL notice, tap a stamp, type a date of birth. Or download any exam notice PDF from an official site and drop it in to watch it get read.
Code
Form Bhaiya
A second pair of eyes for the cyber café that fills government exam forms.
Across India, a lot of exam applications (SSC, UPSC, railways, state commissions) are filled in by the person at the local cyber café, the "form bhaiya", for a fee per form. Every exam comes with a 30 to 130 page notice, and every notice has its own last dates, fee exemptions, age windows, relaxations and photo and signature sizes. A wrong guess means a rejected form and a candidate who comes back angry.
Drop the notice PDF in. Form Bhaiya reads it once with open-weight models and shows the line in the notice behind every answer. Then the café checks each candidate at the counter, prints a Hindi slip for them to take home, and fixes their photo and signature to the exact size, all in the browser.
Try it: form-bhaiya.onrender.com. It's on…
How I Built It
Next.js 16 with plain CSS. Three open-weight models do the reading, all served free on Groq:
- GPT-OSS 120B reads dates, fees, age limits and the relaxation table.
- GPT-OSS 20B reads photo and signature sizes and the document list, and writes the Hindi for the slip.
- Qwen 3.8 27B reads who can apply.
The free tier shaped everything
A 132-page notice is about 55,000 tokens. Groq's free tier gives each model 8,000 tokens a minute, and it counts the reply's budget against that up front. So the notice is never sent whole. It's split into overlapping windows, and each of five questions (dates and fees, age, uploads, who can apply, documents) gets only the passages that rank best for it with BM25, about 3,000 tokens' worth.
Since the limit is per model, the questions run in three lanes at once, one model each. A fresh notice takes about a minute. The page shows each question ticking off while you wait, and after that the notice is in the library for everyone.
No stamp without a quote
Every answer has to come back with a quote and a page number. Before anyone sees it, code checks two things: the quote is actually in the PDF's text (exactly, or word for word allowing for line breaks), and every date and number in the answer appears on that page. Pass both and the stamp is green. Fail either and it's red, with the reason.
That check earned its place on day one. On the UPSC CDS notice, GPT-OSS 20B said the live photo had to be "10 to 20 KB, 6 × 2 cm". The CDS notice gives no photo size at all; it sends candidates to UPSC's website for that. Red stamp: "The number 20 isn't on page 2." Those numbers happen to be the SSC signature size.
Then the same model did the same thing on the SSC notice, and that time the numbers were on the page, in the signature sentence, so the stamp went green. That's the honest limit of checking numbers alone. Now an upload's quote also has to be about that kind of upload, and a "photo" whose only evidence is the signature sentence gets dropped.
Everything else that broke
- Half a relaxation table. GPT-OSS 120B at medium reasoning effort sometimes spent its whole reply budget thinking, and Groq rejected the cut-off JSON. At low effort it returned all 12 rows every time I tried, faster.
- A page break in the middle of a rule. One SSC age rule reads "born not earlier than 02-08-1996 and not later", then "Page 6 of 132", then "than 01-08-2008". The model never saw both halves. Now a passage that ends at a page break brings the start of the next page with it, and quotes can span the break.
- Quotes with "..." in them. Told not to, models still write "Women candidates ... are exempted". Each piece now has to be found, close together.
- Birth dates in "who can apply", with the wrong year. GPT-OSS 20B kept mixing them in. I gave the same question to Qwen 3.8 with thinking switched off and every answer verified, in under 3 seconds. But Groq caps Qwen at 1,000 output tokens a minute and refuses any request that asks for more, so it only gets the one short question.
- "Admission Certificate" in Hindi came back as भर्ती प्रमाणपत्र, a recruitment certificate. Candidates call it प्रवेश पत्र. The translation prompt now carries a small glossary.
The arithmetic is code
Ages, birth windows, relaxations and fees are plain functions with unit tests, exact to the day. One thing I didn't expect: SSC prints "age limit 18–27 years as on 01-08-2026" as "born not earlier than 02-08-1999". A plain reading of "not more than 27" would let in someone a year older. So printed birth dates always win, and a window the code has to work out from an age range says so on screen.
The photo fixer
A phone photo of a signature comes out grey and unevenly lit. My first version whitened the paper with one global threshold, and half the paper stayed grey and got trimmed as ink. Now the paper's brightness is measured block by block and each pixel is compared with the paper around it.
The next surprise: a clean signature at 472 × 157 pixels is only 7.7 KB as a JPEG even at full quality, under SSC's 10 KB minimum. When a notice gives centimetres, the same print size at a higher dpi has more pixels, so the fixer steps the dpi up until the file lands in the range, and says it did.
Tests
33 unit tests, 9 API tests and 15 browser tests in real Chrome. The browser tests load every screen at 320 to 1280 pixels wide in light and dark with the longest data I could make up, then upload a notice, open stamps, check candidates at the edges of the window, make slips in both languages, and fix a signature and a photo, checking the downloaded files' pixels and bytes.
They run against a made-up "Demo Recruitment Board" notice that a stand-in reader answers with one deliberate mistake, so the red stamp is tested too. GitHub Actions runs everything on every push.
Why Does Open Innovation Matter?
It makes the business work. A café earns a small fee per form. With open models on a free tier, reading a notice costs nothing, and since one read serves every café, the cost per form rounds to zero even on a paid key. A per-page price from a closed API would eat the margin of a business this small.
I could pick the model per question. The 120B is the careful reader for the age table. Qwen kept "who can apply" clean when the 20B didn't. Each is one setting, and I only found out which was better by running the same question through all three on real notices.
The candidate's data stays in the café. The server only ever sees the public notice. Date of birth, category, disability status and the photo stay in the browser. And because the app only speaks the OpenAI-compatible API, a café chain that doesn't want even the notice going out can point it at Ollama or vLLM on its own machine by changing a base URL.
Prize Categories
-
Best Use of Render: the app runs on Render's free tier from a Blueprint (
render.yaml), set to deploy only commits that pass CI. - Best Use of GitHub Copilot, for the GitHub Actions part: every push runs lint, unit tests, API tests and the real-Chrome tests, uploads screenshots when a layout breaks, and gates the Render deploy.
I haven't put it in front of a café yet, so there's no first-user story here. That's the next step, and the stamps are what I'll be watching: whether someone at a busy counter actually taps them.


Top comments (2)
Showing the source page next to every answer is a sensible choice for a tool where one wrong date means a rejected form, because the person at the counter can check the line in seconds. Resizing the photo and signature in the browser so the images never leave the café is a thoughtful privacy decision as well. Do you keep the eligibility rules as structured data per exam, so someone can review them before a new notice goes live?
Thanks! Yeah, every notice gets saved as data: age limits, fees, photo sizes, each with the line it came from. But nobody reviews it right now. Once it's read, it's live. Having someone check it first is a really good idea, gonna add that.