Skip to main content
This guide covers commit message format, code style, and the PR submission process.

Commit Message Format

All commits must follow Conventional Commits format:

Commit Types

  • feat: New feature
  • fix: Bug fix
  • docs: Documentation changes
  • style: Code style changes (formatting, no logic changes)
  • refactor: Code refactoring (no behavior changes)
  • perf: Performance improvements
  • test: Adding or updating tests
  • build: Build system or dependency changes
  • ci: CI/CD configuration changes
  • chore: Maintenance tasks
  • revert: Revert a previous commit

Examples

Commit Rules

  • Keep descriptions concise
  • Use imperative mood (“add feature” not “added feature”)
  • Use lowercase for descriptions
  • No trailing period
  • Add ! after type/scope for breaking changes
  • Use BREAKING CHANGE: in footer for breaking changes
  • Reference issues/PRs in footer when applicable

Signed Commits (REQUIRED)

ALL commits MUST be signed with --signoff. This is mandatory and enforced by commitlint.

Sign Your Commits

Every commit must include a Signed-off-by line:
Or use the -s shorthand:

AI Agent Attribution

If you’re using an AI coding tool, you must disclose it in the commit footer:
Format:

Automatic Signoff

Configure Git to sign off commits automatically:
Or use a Git hook (see .husky/commit-msg in the repository).

Code Style

Go

Anubis follows Go standard library idioms:
  • Formatting: Use goimports (run npm run format)
  • Package aliases: Only when names collide
  • Naming:
    • PublicFunctionsAndTypes in PascalCase
    • privateFunctionsAndTypes in camelCase
    • Acronyms stay uppercase (URL, HTTP, IP, DNS)
  • Errors:
    • Sentinel errors as package-level Err prefixed variables
    • Wrap with fmt.Errorf("package: context: %w", err)
    • Use errors.Is for validation
  • Logging:
    • Use log/slog for structured logging
    • Pass loggers as function arguments
    • Prefer slog.Debug unless users need to see the message
  • Configuration:
    • Use both json and yaml struct tags
    • Use pointer values for optional fields
    • Validate with Valid() error methods
  • Tests:
    • Use table-driven tests
    • Use t.Helper() in helper functions
    • Use t.Cleanup() for teardown
    • Prefer same-package tests over _test packages

JavaScript/TypeScript

  • Source in web/js/
  • Built with esbuild
  • Uses Preact (not React)
  • Use const by default
  • Keep functions small
  • No linter config - rely on code review

Templ Templates

  • .templ files in web/ generate Go code
  • Run npm run assets after modifying
  • Keep logic in Go, not templates
  • Templates receive typed Go parameters

Pull Request Process

Before Submitting

  1. Build assets:
  2. Run tests:
  3. Run linting:
  4. Format code:
  5. Update CHANGELOG: Add your changes to [Unreleased] in docs/docs/CHANGELOG.md

PR Checklist

  • All commits follow Conventional Commits format
  • All commits are signed with --signoff
  • All commits have verified (signed) signatures
  • Tests added for bug fixes and new features
  • Integration tests pass (npm run test:integration)
  • CHANGELOG updated in docs/docs/CHANGELOG.md
  • AI tool attribution added if applicable
  • Code follows project style guidelines

Creating the PR

  1. Push your branch:
  2. Open PR on GitHub
  3. Fill out template (see .github/PULL_REQUEST_TEMPLATE.md)
  4. Request review

PR Review

Anubis is security software - code reviews are strict:
  • Security implications are carefully evaluated
  • Test coverage is required
  • Adversarial inputs are considered
  • Breaking changes require discussion

Security Considerations

Anubis is security software. All contributions must consider adversarial scenarios.

Security-First Principles

  • Input validation: Validate all external input
  • Error handling: Don’t leak internal state in error messages
  • Rate limiting: Consider DoS scenarios
  • Cryptography: Use standard library crypto packages
  • Dependencies: Minimize external dependencies

Reporting Security Issues

See SECURITY.md for the security policy and reporting process.

Key Conventions

Configuration

  • YAML-based policy files
  • Config structs validate via Valid() error returning sentinel errors
  • See lib/config/ for examples

Store Interface

  • lib/store.Interface abstracts key-value storage
  • Implementations in lib/store/
  • Always handle errors from Store operations

Environment Variables

  • Parsed from flags via flagenv
  • Use .env files locally (loaded by godotenv/autoload)
  • NEVER commit .env files

Asset Building

  • JS/CSS assets embed into Go binary
  • Always run npm run assets before go test or go build
  • Generated files are committed to the repo

CEL Expressions

  • Policy rules support Common Expression Language
  • See lib/policy/expressions/ for implementation
  • Use for advanced bot matching rules

Project Layout

Key directories:
  • cmd/anubis/ - Main entrypoint
  • lib/*/ - Public library code (no API stability guarantees)
  • internal/*/ - Private implementation code
  • test/*/ - Smoke tests
  • web/ - Frontend templates
  • xess/ - CSS framework

Getting Help