Inspiration
Working in bitcoin open-source protocol development, I've seen firsthand how much bandwidth maintainers dedicate to triaging issues and reviewing code. Recently, a new threat has emerged: AI-generated pull request spam.
The root of this problem isn't technical; it's economic. Bad actors can script an LLM to hallucinate and submit thousands of PRs across GitHub at near-zero marginal cost. Maintainers, however, pay a heavy price in time and energy to review them. Traditional text-detectors fail because they often flag genuine boilerplate code or non-native English speakers as "AI."
Drawing inspiration from Bitcoin's consensus mechanisms, I realized the solution was to introduce a micro-economic toll. If we could force a contributor to spend a small, verifiable amount of computational energy—Proof-of-Work—we could entirely bankrupt the spam botnets while keeping the doors wide open for genuine human developers.
What it does
HashGuard acts as a decentralized, computational tollbooth for GitHub repositories. It requires new contributors to perform a micro-Proof-of-Work (computing a SHA-256 hash to a specific difficulty) before their pull request is accepted. It consists of a blazing-fast local Rust CLI for the contributor to generate the cryptographic nonce, and a serverless GitHub Action that validates the math in milliseconds. Genuine contributors wait a few seconds/minutes (depending on the difficulty) to process the hash, while automated botnets attempting to spam the repository instantly burn through their CPU budgets.
How we built it
HashGuard is built around a lightweight monorepo architecture comprising two distinct parts:
- The Miner (
pow-cli): A high-performance CLI tool written in Rust. I chose Rust for its bare-metal execution speed and its robustsha2cryptographic crate. - The Validator: A serverless GitHub Action written in bash and YAML that intercepts new PRs and verifies the cryptographic payload in milliseconds.
The Mathematical Core The system relies on the cryptographic properties of the SHA-256 hash function. The Rust miner iteratively increments a nonce until the resulting hash satisfies a specific difficulty condition set by the maintainer.
Formally, the condition to be met is:
SHA256(Repo + Branch + Nonce) <= Target
Where the Target is defined by the required number of leading hexadecimal zeros, d. Because SHA-256 outputs uniformly distributed hashes, the probability P of any single hash satisfying a difficulty d is:
P = (1/16)^d = 16^(-d)
Therefore, the expected number of hash operations E[N] required to find a valid nonce grows exponentially with the difficulty:
E[N] = 16^d
This math is the shield. A difficulty of d = 10 takes a human a fraction of a second. But if a repository is under attack, the maintainer can bump the difficulty to d = 7.
Challenges we ran into
Balancing Friction and Security: The biggest challenge was ensuring that the tool didn't become a barrier to entry for genuine developers. Initially, I considered a financial escrow system, but realized that requiring a monetary stake (even micro-transactions) would alienate students or first-time contributors. Pivoting to a purely computational tollbooth solved the economic asymmetry without requiring contributors to open their wallets.
Decentralized Configuration:
I wanted to ensure maintainers didn't have to log into a third-party SaaS dashboard or manage API keys. Engineering the .github/pow_difficulty.txt file as a decentralized "dial" was a breakthrough. It allows the system to remain entirely self-contained within the user's repository.
Accomplishments that we're proud of
Coming from a background in protocol-level development, keeping this system decentralized and frictionless was a massive priority. I am incredibly proud that HashGuard requires absolutely zero third-party SaaS dashboards, API keys, or database hosting. The entire configuration is managed via a single text file in the repository, making it completely self-contained. I'm also proud of seamlessly bridging a bare-metal Rust application with cloud-native GitHub Actions to create an elegant, instant validation loop.
What we learned
Building HashGuard deepened my understanding of how to seamlessly integrate local, compiled binaries (the Rust CLI) with cloud-native CI/CD environments (GitHub Actions). I also learned a tremendous amount about the exact API payloads GitHub webhooks deliver during the Pull Request lifecycle, and how to safely extract and validate metadata from a PR description without exposing the repository to injection attacks.
What's next for HashGuard
This hackathon prototype proves the economic model works, but there is a lot of room to optimize the contributor experience and enterprise scalability:
Dynamic Difficulty Adjustment (DDA): Instead of maintainers manually turning the difficulty dial, the GitHub Action could automatically calculate PR velocity and increase the difficulty if a sudden spike in submissions is detected.
Reputation Whitelisting: Integrating GitHub's API so the Action automatically bypasses the Proof-of-Work requirement for contributors who already have previously merged PRs in the repository.
WebAssembly (WASM) Miner: Compiling the Rust CLI into WASM so contributors who don't want to use the terminal can click a link, mine the hash directly in their browser, and copy the nonce seamlessly.
Built With
- github-ci
- github-jobs
- rust
Log in or sign up for Devpost to join the conversation.