Inspiration
I started research on fraud detection in November 2025. So far, reports show that B2B invoice fraud costs the EU over €50B a year, and this year the people fighting it got a second problem. Starting this year (2026), the EU AI Act now treats every system that is built to automatically flag invoice fraud as a high risk fraud detection platform.
For these platforms this means that every decision has to be explainable, auditable, and documented and the challenge is that most teams treat compliance as paperwork bolted on after the model works, not at the start.
This is the entire premise of this project. The idea behind eu-comply came when I wanted to see what it looks like when compliance is a property of the core architecture. In simple terms, the question was instead of quarterly scramble before any audit can "prove this decision wasn't tampered with" and "show me the model card and bias report" be API calls?
What eu-comply does
eu-comply is one service with three components that share a single decision record:
- InvGuard scores an invoice against a versioned rule engine and returns the outcome (
approve/review/block), the rules that fired with their weights, and a plain-language explanation. - rify-AI signs and anchors each decision so it can be verified later. You can submit a decision, get back a signed proof; ask the API to verify it and a tampered record is caught immediately
- The AI Act Compliance Toolkit turns the accumulated decisions into the artifacts an auditor actually asks for: a model card generated from the live pipeline, a bias report grouped by proxy attributes, and a combined audit report, none of which is hand maintained.
Every number in the compliance reports traces back to real decisions the user just watched being made.
How I built it
A single FastAPI service, deliberately boring where boring is correct and interesting only where it has to be:
- Domain-first layering: pure business logic in
services/anddomain/, isolated from transport and persistence, so the three components are testable without a database or a web server. - Async SQLAlchemy 2.0 + Alembic, SQLite for zero-config local dev and Postgres in production, behind one settings switch. Migrations run on deploy.
- Production hardening as table stakes: API-key auth, per-client rate limiting, structured JSON request logging with request IDs, CORS, a production config guard, non-root multi-stage Docker image, health/readiness probes, and a CI lint/type/test gate.
- Honest stand-ins behind narrow interfaces. The heavy v2 infrastructure which include Neo4j graph analysis, IPFS pinning, on-chain anchoring, SHAP, LLM extraction are represented by deterministic local implementations behind the same interfaces the real versions will implement. This would be swapped in in a v2 of eu-comply.
Challenges I experienced
- Verifiable" is a stronger word than it looks. Our first cut signed decisions with a symmetric HMAC, which means only we can verify them, so the auditor still has to trust our database. Naming that honestly (and scoping asymmetric, third-party-checkable signatures as the real fix) taught us more than shipping it quietly would have.
- Compliance numbers have to be true, not just present. It's easy to render a confident-looking "100% verified" count that's really just "a proof object exists." Getting the reports to mean what they say was harder and more important than making them look good.
- Config that survives real deployment. Environment variables that parse fine as JSON locally crash a container when someone passes a plain comma-separated value. The gap between "works on my machine" and "boots on Render" was its own small education.
- Deciding what NOT to build. The temptation in a compliance demo is to fake the blockchain and the trained model. We drew a line: stand-ins are fine if the interface is real and the scope cut is stated out loud.
Accomplishments that we're proud of
- A working tamper demo. Change one field of an anchored decision and the verification endpoint catches it live. It makes an abstract compliance promise physical.
- Reports that regenerate from real data with no manual editing, the model card, bias report, and audit report all trace to the decisions on screen.
- A genuinely production-shaped service: including migrations, auth, rate limiting, structured logs, containerization, and CI.
- Honesty as a design constraint. The README and this playbook name every stand-in and every scope cut. For a product whose entire value is trustworthiness, we're proud that the pitch itself is trustworthy.
What we learned
- In a regulated domain, the honest version is the more impressive version.
- Compliance-by-design is an architecture decision, not a feature. Because the decision record was the center of the system from the start, the audit artifacts fell out of it almost for free.
- Cryptographic claims deserve real skepticism. The difference between "we signed it" and "anyone can verify it without trusting us" is the difference between a checkbox and the actual product.
- Anyone can score an invoice; the work that makes it defensible in front of a regulator is the persistence, the verification, and the documentation pipeline underneath.
Built With
- nextjs
- postgresql
- python
Log in or sign up for Devpost to join the conversation.