# macOS
.DS_Store
._*
.Spotlight-V100
.Trashes
.claude

tests/fixtures/extract/*-extracted.xlsx

# Java / Maven
target/
*.class
*.jar
*.war
*.ear
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
.mvn/wrapper/maven-wrapper.jar

# Python
__pycache__/
.pytest_cache/
.coverage
*.py[cod]
*$py.class

# Per-run OOS test report (regenerated each pytest invocation).
tests/oos/test_report.json
*.egg-info/
dist/
# build/ — Python wheel build artifacts (top-level convention). Anchored to the
# repo root so it does NOT also match dev/build/ (handled separately below).
/build/
# dev/build/ — UofA pipeline outputs. Per-run/regenerable trees stay ignored,
# EXCEPT the Phase 2/2.5/3 adversarial artifacts (dev/build/adversarial/ +
# dev/build/phase2_5/), which are force-tracked — large/binary files via Git
# LFS (see .gitattributes) — to preserve the non-reproducible LLM corpus +
# judge outputs as a defense audit trail. Decision: 2026-06-09. Other
# dev/build/* trees (airfrans, …) remain ignored as regenerable.
dev/build/*
!dev/build/adversarial/
!dev/build/phase2_5/
# dev/build/pilot-johnson/ — the Johnson (NTRS 20200002832) encoding pilot.
# Force-tracked for the same reason as the two above: the run log, the DRAFT
# dispositions and the ambiguity log are a record of what a session decided and
# when, and a rerun would not reproduce them. The findings memo is the input the
# author writes Encoding_Protocol_v0_1 from, so it has to be citable by commit.
# Decision: 2026-08-20, per UofA_Encoding_Pilot_Spec_v1_0_Johnson.md §5-§6.
!dev/build/pilot-johnson/
# dev/build/encoding-prep/ — the author's review packets, the Bologna investigation and
# the author queue, produced under UofA_Protocol_Draft_and_Encoding_Prep_Spec_v1_0.md.
# Tracked for the same reason as the pilot tree: these are the inputs to author acts, and
# a packet that is not citable by commit cannot be referenced by the sign-off it leads to.
!dev/build/encoding-prep/
# The unpacked aero evidence folders are byte-identical to the committed
# packs/nasa-7009b/examples/aerospace/aero-evidence-cou*.zip and are regenerable from
# them, so the encoding tree carries the outputs and not a second copy of the inputs.
dev/build/encoding-prep/aero-cou*/aero-evidence-cou*/
# Never OS/editor/Python junk, even inside the tracked trees.
dev/build/**/.DS_Store
dev/build/**/._*
dev/build/**/__pycache__/
dev/build/**/*.py[cod]
*.egg
.eggs/
*.whl
.venv/
venv/
env/

# IDE
.idea/
*.iml
# .vscode/ stays ignored -- it holds per-machine state. The tracked
# exception is the checked-in example contributors copy from.
.vscode/*
!.vscode/settings.json.example
*.swp
*.swo
*~
.project
.classpath
.settings/

# Keys (private keys must NOT be committed)
# `*.key` matters as much as `*.pem`: uofa keygen writes PKCS8 PEM to whatever
# path it is handed, and the repo's own convention is the .key suffix. Listing
# only *.pem is why keys/research.key sat committed for 692 commits despite the
# rule above it. The un-ignore keeps public halves -- research.pub (the default
# trust anchor), REVOKED-*.pub, and demo.pub (the Space's issuer) -- addable.
keys/*.pem
keys/*.key
!keys/*.pub

# Secrets by env file. The demo issuer's signing key is delivered as
# UOFA_DEMO_SIGNING_KEY; a local .env holding it must never be committed, and
# space/deploy_to_hf.py separately refuses to upload one to the public Space.
.env
.env.*

# OS
Thumbs.db
ehthumbs.db
Desktop.ini

# Logs
*.log
hs_err_pid*

# Temp
*.tmp
*.bak
*.orig

# Generated test fixtures (regenerated at test time from generator.py)
tests/fixtures/import/e2e-*.xlsx

# Extracted xlsx files from score_extraction_batch.py runs (regenerated each
# run; tied to a specific (model, prompt-version, timestamp), so committing
# them couples a fixture to one run).
tests/fixtures/extract_corpus/**/extracted.xlsx

# Eval run artifacts (per-run JSON + markdown outputs)
runs/

# Wheel-bundled artifacts (populated by hatch_build.py at wheel build time).
# .jar is already covered by *.jar above; listed explicitly so the location
# is documented and so the .gitkeep placeholder is preserved.
src/uofa_cli/_engine/*.jar
!src/uofa_cli/_engine/.gitkeep
# JRE tree downloaded by hatch_build.py when UOFA_BUNDLE_PLATFORM is set.
src/uofa_cli/_runtime/jre/
src/uofa_cli/_runtime/PLATFORM
src/uofa_cli/_runtime/JRE_VERSION

# Phase 2/2.5/3 run logs are tracked artifacts — re-included AFTER the global
# *.log rule above so they win (preserve the run audit trail). Decision 2026-06-09.
!dev/build/adversarial/**/*.log
!dev/build/phase2_5/**/*.log

# Solver-artifact fixtures are byte-exact by contract and must never be filtered
# by a general rule. The global *.log above silently swallowed
# tests/fixtures/solver/.../optiSLang_protocol.log — a deliberately UTF-16LE
# file — when the tree was staged with `git add <dir>`, which skips ignored
# paths without a word. The fixture then built from 10 files locally and 10 in
# CI but 11 on the author's machine, and only the digest-pinning test noticed.
!tests/fixtures/solver/**
