This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle.
What I Built
I once sent two security reports to the same program eleven days apart. They concerned different pages, so the titles looked different. Reading them together later, I could see that they described the same underlying mistake. The second investigation should have stopped before submission.
That is a peculiar problem for an independent bug bounty researcher. A program's public issue tracker cannot show you the reports you sent privately. Your own archive can, but a quick keyword search misses cases described through different symptoms, and reading every old report before every new one takes time.
I built BeforeReport, a small, local second look for that moment before sending. Give it a draft and a CSV or JSON export of your own previous cases. It compares the draft with earlier cases for the same program, asks a local Gemma 3 4B model whether the root cause repeats, and returns a caution with exact excerpts from both records. It does not decide whether a bounty program has already received the issue from somebody else.
The intended customer is a solo researcher or a small security team with a private report archive. The CLI is open source. A possible paid service would be helping a team convert its archive and wire this check into its submission workflow, while leaving its report data on its own machines. I have not sold that service or measured demand for it yet.
Demo
Watch the 27-second MP4 or view the animated replay above. It is built from a real local scan of invented cases, not footage of a live terminal. The full captured CLI/model run shows the actual command, UTC timing, exit code, and unedited output.
In the example, a draft says a revoked share still exposes a PDF thumbnail. An earlier case describes the same missing share-state check in a document preview. Gemma flags that pair as related, quoting the exact passages that led it there. Another earlier case concerns HTML escaping in an export; it correctly marks that one distinct. A third case belongs to another program and is skipped.
I also tried a private retrospective using short summaries of the two real reports behind this project. BeforeReport marked the later one likely_repeat. I have not published those reports or their excerpts. This was a check against a known mistake, not a prospective customer trial, but it shows how the tool could have interrupted that send.
Code
BeforeReport on GitHub is MIT-licensed. The scanner is Python standard library code; the optional demo renderer needs Pillow and ffmpeg. The README has a quick start with Ollama and an alternative local llama-server setup. The repository contains only synthetic cases.
How I Built It
The interesting part is what doesn't become a green light. The scanner first groups by program name or a stable program ID, then checks every matching prior case by default. Similarity only changes the order. If there are no comparisons, the model errors, or its answer is malformed, the scanner returns review_needed. It cannot silently turn one of those conditions into โnew finding.โ
For each pair, Gemma must return a decision and verbatim excerpts from the draft and the prior case. The program checks that both excerpts really occur in the supplied descriptions. Unsupported model prose is labeled unverified. A distinct decision still means โno repeat identified among these cases,โ not โsafe to submit.โ That difference matters when the history is incomplete or the model is wrong. A close name match among skipped programs produces review_needed; a more distant rebrand needs the same program_id in both records.
I ran Gemma 3 4B locally through an OpenAI-compatible llama-server, with a downloaded model file. The CLI accepts only a loopback HTTP endpoint and refuses redirects, so it will not itself send report text to an external model URL. A local server could still forward requests elsewhere; anyone using private reports should verify the server they run.
The reproducible smoke test contains 15 hand-written synthetic pairs. The complete workflow matched 14 cautious-versus-distinct labels; a fixed token-overlap baseline matched 11. There were no false clearances in that tiny set and one false alarm from an instruction planted in an old case. The last seven pairs were added after I settled the prompt and cutoff, and matched 7/7 versus 4/7 for the baseline. These are invented examples, not a field accuracy rate. Ten unit tests cover parsing, grounding, program aliases, model failures, and the loopback/redirect boundary. The real retrospective above is one additional known-positive example, not an accuracy study.
Why Does Open Innovation Matter?
The most valuable input here is a researcher's unpublished report history. Using an open-weight model on the researcher's own computer makes a check possible without uploading that archive to a general-purpose AI API. It also lets another researcher swap the model, inspect the prompt and decision rules, and run the test without a per-report inference bill. My run used Gemma, but the interface is deliberately an ordinary local chat-completions endpoint.
There is a trade-off: a 4B model still needs a capable local machine, its answers can be wrong, and no local tool can search a bounty program's private duplicate queue. I would rather have an explicit review_needed than a confident-looking sentence that disguises one of those limits.
My First User
Me, retrospectively. It caught a repeat pattern in summaries of my own older reports. I have not put it in front of an external researcher or collected payment yet. The next useful test is a prospective trial: run it before a real send, record whether it changes the decision, and ask another researcher whether the excerpts save them time.
Prize Categories
Best Use of Gemma. Gemma 3 4B supplies the pairwise root-cause judgment that keyword overlap alone cannot reliably make. The surrounding code constrains and checks its answer so a plausible paragraph is not mistaken for proof.

Top comments (0)