# Build artefacts
.obj/
*.o
*.so
*.so.*
*.a
*.dylib
*.dll
*.exe

# Test binaries
# Compiled test / fuzz binaries and their signing artifacts. Sources keep
# their extension; the built binaries have none, so ignore the extensionless
# form and re-include the sources explicitly. The previous list named each
# binary individually, which meant every new test silently got committed --
# tests/test_integrity and its .sha256 were added that way (#125). A signed
# binary in a repo that advertises reproducible builds is a supply-chain
# smell: it bloats clones, can be run by accident, and nobody can tell what
# it was built from. `make` regenerates all of them.
# Compiled test and benchmark binaries. Shape-based: a rule that lists names
# stops covering the next file someone adds. tests/bench_capacity was committed
# as a 1.7 MB binary because the earlier rule only matched tests/test_*.
# Shape-based, third attempt. The two before it enumerated prefixes --
# tests/test_*, then tests/bench_* -- and each stopped covering the next binary
# someone added: tests/bench_capacity went in as a 1.7 MB blob because the rule
# only knew about test_*, and tests/tpm_hw_probe went in because the rule only
# knew about test_* and bench_*. A list of names cannot cover a file that does
# not exist yet.
#
# The invariant that actually holds: every source in tests/ has an extension
# (.c .h .sh .py .json ...), and every compiled binary has none. So ignore
# everything in tests/ and re-admit anything with a dot. The one tracked
# extensionless file, tests/wycheproof/VECTORS_SHA, is re-admitted by name --
# and subdirectories must be re-admitted explicitly or their contents are
# unreachable.
tests/*
!tests/*.*
!tests/*/
!tests/wycheproof/VECTORS_SHA

# Fourth attempt. `!tests/*.*` above re-admits anything with a dot, and an
# object file has a dot -- so tests/fhsm_tpm_testhooks.o was committed as a
# 382 KB blob despite the `*.o` rule at the top of this file. The shape
# invariant "sources have an extension, binaries do not" is false for
# compiler artefacts, which have both. Re-exclude them by extension, after
# the negation so these win.
tests/*.o
tests/*.a
tests/*.so
tests/*.d
tests/*.gcno
tests/*.gcda
tests/*.gcov
tests/*.sha256
tests/*.tampered
tests/fuzz/
fuzz/fuzz_*
!fuzz/fuzz_*.c
!fuzz/fuzz_*.h

# libFuzzer harness binaries (built by fuzz/Makefile.fuzz, never committed)
fuzz/fuzz_ecdsa_raw
fuzz/fuzz_pq_params
fuzz/fuzz_attr_template
fuzz/fuzz_create_attrs
fuzz/crash-*
fuzz/leak-*
fuzz/oom-*
fuzz/timeout-*
fuzz/artifacts/

# Stale backups (rename/refactor leftovers)
*.bak

# Coverage
*.gcno
*.gcda
*.gcov
coverage.info
lcov-report/

# Tools --- by shape, for the same reason tests/ is.
#
# This was a list of one name, tools/freehsm-audit, and it stayed correct
# exactly as long as there was one tool. Adding fhsm-csr and fhsm-ca to the
# Makefile did not add them here, so 093ad70 committed both as ELF blobs,
# 1.8 MB together. That is the sixth time in this file that a control was
# wired to some of the paths reaching a state and not the rest -- the commit
# immediately before it is titled "the fifth entry, one commit after
# predicting it". Enumeration keeps losing to the next file that does not
# exist yet.
#
# Same invariant as tests/: every source in tools/ has an extension, every
# built binary has none. Ignore everything, re-admit anything with a dot,
# then re-exclude compiler artefacts by extension -- an object file has a dot
# too, which is how tests/ was caught out on its fourth attempt.
tools/*
!tools/*.*
!tools/*/
tools/*.o
tools/*.a
tools/*.so
tools/*.d
tools/*.gcno
tools/*.gcda
tools/*.gcov

# The seventh, and the comment above predicted it in as many words:
# "enumeration keeps losing to the next file that does not exist yet."
# service/ did not exist when that was written. fhsm-service was built,
# `git status` showed it as untracked, and nothing stopped it being added --
# 2.4 MB of ELF, the same mistake as 093ad70 in a directory the rule had
# never been extended to.
#
# Same invariant, same shape: every source in service/ has an extension,
# every built binary has none.
service/*
!service/*.*
!service/*/
service/*.o
service/*.a
service/*.so
service/*.d
service/*.gcno
service/*.gcda
service/*.gcov

# Reproducible-build outputs.
#
# This said `dist/` for six tagged releases, and that one line is why the
# reproducibility anchor never existed. docs/ROADMAP.md has asked since
# 2026-08-15 for a reference digest at dist/refs/vX.Y.Z.sha256; the file was
# always going to be silently ignored, so the request could not be satisfied
# even by someone trying to satisfy it. The requirement was real, the
# mechanism was written, and the door was locked.
#
# `dist/` excludes the DIRECTORY, and git will not descend into an excluded
# directory -- so `!dist/refs/*.sha256` on its own does nothing. This is the
# same trap the tests/ block above was rewritten four times for. Exclude the
# contents instead, then re-admit the path down to the references.
dist/*
!dist/refs/
dist/refs/*
!dist/refs/*.sha256
!dist/refs/.gitkeep
*.tar.xz
*.tar.xz.asc
*.tar.xz.sha256

# Distributed artefacts (signed at release time)
libfreehsm.so.sha256

# Editor / IDE
.vscode/
.idea/
*.swp
*~

# OS
.DS_Store
Thumbs.db

# Operator-side data (must NEVER be in git)
/var/lib/freehsm/
/etc/freehsm/freehsm.conf
*.tok
*.tok.tpm
audit.log

# GPG / secrets
*.asc.tmp
.gnupg/
secrets/

# Generated by make integrity
.fhsm_digest.bin

# Local test scaffolding
/tmp/freehsm-*

# Local secrets (NEVER commit)
CODEBERG_SSH_KEY
GITLAB_SSH_KEY
RELEASE_GPG_PASSPHRASE
RELEASE_GPG_KEY
*.gpg.key
deploy-key*
build.log
tests/test_smoke.sha256
tests/test_smoke.tampered

# sign_module.sh test artifacts
tests/test_smoke.sha256
tests/test_smoke.tampered

# test binaries (#110)
tests/test_token_capacity
tests/test_decrypt_null_args

# pkcs11-check runtime artifacts (#125)
reports/
.pkcs11-check-isolation-*.json
.pkcs11-check-isolation-*.report-records/
..pkcs11-check-isolation-*.report-records/
tests/test_mech_advertise
tests/test_legacy_digest
tests/test_legacy_cipher
tests/test_legacy_rsa
src/gen/.profile.stamp

# Commit-message drafts, never repository content.
# One of these went into b8ee63a for want of this line.
.commit-msg-*.txt

# Measurement probes: the sources are tracked, the binaries are not.
probes/*/0[0-9]_*
!probes/*/0[0-9]_*.c
