Anubis is a Web AI Firewall Utility (WAIFU) written in Go. It uses sha256 proof-of-work challenges to protect upstream HTTP resources from scraper bots. This is security software -- correctness matters.
Prerequisites: Go 1.24+, Node.js (any supported version), esbuild, gzip, zstd, brotli. Install all with brew bundle if you are using Homebrew.
npm ci # install node dependencies
npm run assets # build JS/CSS (required before any Go build/test)
npm run build # assets + go build -> ./var/anubis
npm run dev # assets + run locally with --use-remote-address
# Run all unit tests (assets must be built first)
npm run test # or: make test
# Run a single test by name
go test -run TestClampIP ./internal/
# Run a single test file's package
go test ./lib/config/
# Run tests with verbose output
go test -v -run TestBotValid ./lib/config/
The tests folder contains "smoke tests" that are intended to set up Anubis in production-adjacent settings and testing it against real infrastructure tools. A smoke test is a folder with test.sh that sets up infrastructure, validates the behaviour, and then tears it down. Smoke tests are run in GitHub actions with .github/workflows/smoke-tests.yaml.
go vet ./...
go tool staticcheck ./...
go tool govulncheck ./...
The project uses go generate for templ templates and stringer. Always run npm run generate (or make assets) before building or testing. Generated files include:
web/*.templ -> templ-generated Go codeweb/static/ -> bundled/minified JS and CSS (with .gz, .zst, .br variants)Important folders:
cmd/anubis: Main entrypoint for the project. This is the program that runs on servers.lib/*: The core library for Anubis and all of its features. This is internal code that is made public for ease of downstream consumption. No API stability is guaranteed. Use at your own risk.internal/*: Actual internal code that is private to the implementation of Anubis. If you need to use a package in this, please copy it out and manually vendor it in your own project.test/* Smoke tests (see dedicated section for details).web: Frontend HTML templates.xess: Frontend CSS framework and build logic.This project follows the idioms of the Go standard library. Generally follow the patterns that upstream Go uses, including:
goimports to format code. Run with npm run format.Err (such as ErrBotMustHaveName). Wrap with fmt.Errorf("package: small message giving context: %w", err).log/slog for structured logging. Pass loggers as arguments to functions. Use lg.With to preload with context. Prefer using slog.Debug unless you absolutely need to report messages to users, some users have magical thinking about log verbosity.URL, HTTP, IP, DNS, etc.)json and yaml struct tags. Use pointer values for optional configuration values.t.Helper() in helper code (setup/teardown scaffolding).t.Cleanup() to tear down per-test or per-suite scaffolding.errors.Is for validating function results against sentinel errors._test packages).web/js/. Built with esbuild, bundled and minified.const by default.Anubis uses Templ for generating HTML on the server.
.templ files in web/ generate Go code. Run go generate ./... (or npm run assets) after modifying them.Commit messages follow the Conventional Commits format:
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
Types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert
! after type/scope for breaking changes or include BREAKING CHANGE: in the footer.--signoff. This is mandatory.AI agents must disclose what tool and model they are using in the "Assisted-by" commit footer:
Assisted-by: [Model Name] via [Tool Name]
Example:
Assisted-by: GLM 4.6 via Claude Code
[Unreleased] in docs/docs/CHANGELOG.md.npm run test:integration.Valid() error methods returning sentinel errors.lib/store.Interface abstracts key-value storage.flagenv. Use .env files locally (loaded by godotenv/autoload). Never commit .env files.npm run assets before go test or go build.lib/policy/expressions/.